Jump to content
IGNORED

Simple Graphics Mode 6 Double Buffering with Modified Character Set


Recommended Posts

I built another simple double buffering scheme, this time in graphics mode 6 (BASIC GR.1).  Because the uppercase/lowercase restrictions and colors were annoying me, I moved the character set into RAM and stuffed the lower case bit maps into the corresponding upper case locations.  I added "tick" and "tock" sounds because, you know, why not?

 

Here is the code:

 

	.MACRO CopyChar
		LDY #0	
CharLp	LDA (SrcLO),Y
		STA (DestLO),Y
		INY
		CPY #8
		BNE CharLp
	.ENDM

        *= $3000
Counter		= $A2
ListInUse	= $A3
SrcLO		= $B0
SrcHI		= $B1
DestLo		= $B2
DestHi		= $B3

.include "hardware.s"

init		
		; load display list 0
		LDA #<dlist_0
		STA sdlstl
		LDA #>dlist_0
		STA sdlstl+1
		
		; Play first "Tick" sound.  After this, handled in VBI ISR
		LDX #$7F			
Click	STX CONSOL
		DEX
		BPL Click

		; If you want to use mixed lower and upper case characters in graphics mode 6, 
		; you have modify the character set
		
		; Copy character set
		LDA #0				; Atari character set starts on a 1K page boundary
		STA	SrcLO			; only get the high byte in CHBAS, $00 is assumed for lo byte
		STA DestLO
		LDA CHBAS			; Hi byte of character set location from OS
		STA SrcHI		
		LDA #$70
		STA	DestHI
		LDX	#4				; copying four pages
PageLp	LDY #0
ByteLp	LDA (SrcLO), Y
		STA (DestLO), Y
		DEY
		BNE	ByteLp
		INC	SrcHI
		INC DestHI
		DEX
		BNE PageLp	

		;Copy the four needed lower case characters into the upper case locations
		; move 'c' into 'C'
		LDA #$18
		STA SrcLO
		STA DestLO
		LDA #$71
		STA DestHI
		LDA #$73
		STA SrcHI
		CopyChar

		; move 'i' into 'I'
		LDA #$48
		STA SrcLO
		STA DestLO
		CopyChar

		; move 'k' into 'K'
		LDA #$58
		STA SrcLO
		STA DestLO
		CopyChar

		; move 'o' into 'O'
		LDA #$78
		STA SrcLO
		STA DestLO
		CopyChar

		; point to our modified charater set			
		LDA	#$70
		STA CHBAS

		; set graphics mode 6 (Basic GR.1_) colors
		LDA #$0				; black background
		STA COLOR4
		LDA #$0E			; white
		STA COLOR0

		LDA #0				
		STA Counter			; initialize half-second timer
		STA ListInUse		; start with display list 0
		LDY #<vbi_isr		; load registers to add vertical blank ISR
		LDX #>vbi_isr		; lo and hit address bytes go in Y and X
		LDA #6				; set in the immediate routine
		JSR SETVBV
		
forever
		JMP forever 

		* = $3500
vbi_isr	INC Counter			; increment timer by 1/60 sec
		LDA Counter
		CMP #$30			; has half a second gone by?
		BCS	SwapDL			; Yes -> so go swap the display lists
		JMP	SYSVBV			; no -> do nothing and return
SwapDL	LDA #0				; before swapping...
		STA Counter			; reset counter
		LDA ListInUse		; get current display list in use
		BEQ ToDL1			; LDX sets Z flag; if 0 -> switch to DL1
		LDA #0				; Currently using DL1 -> switch to DL0
		STA ListInUse
		LDA #<dlist_0		; point OS to DL0
		STA sdlstl
		LDA #>dlist_0
		STA sdlstl+1
		LDX #$7F			; Play "Tick" sound (loop takes ~1000 cycles, so safe here)
Click0	STX CONSOL
		DEX
		BPL Click0
		JMP	SYSVBV	
ToDL1	LDA #1				; Currently using DL0 -> switch to DL1
		STA ListInUse
		LDA #<dlist_1		; Point OS to DL1
		STA sdlstl
		LDA #>dlist_1
		STA sdlstl+1
		LDX #$3F			; Play "Tock" sound (loop takes ~500 cycles)
Click1	STX CONSOL
		DEX
		BPL Click1
		JMP	SYSVBV							
		
; mode 0 standard display list

		* = $7800
dlist_0
		.byte $70,$70,$70								; 24 blank scan lines
		.byte $46,$00,$90								; Line of mode 6, LMS @ $9000
		.byte $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,			; 11 lines of mode 6
		.byte $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,		; 12 lines of mode 6    
		.byte $41,<dlist_0,>dlist_0

		* = $7900
dlist_1
		.byte $70,$70,$70								; 24 blank scan lines
		.byte $46,$00,$95								; Line of mode 6, LMS @ $9500
		.byte $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,			; 11 lines of mode 6
		.byte $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,		; 12 lines of mode 6      
		.byte $41,<dlist_1,>dlist_1
		
		* = $90D0
		.sbyte "TICK"
		* = $95E4
		.sbyte "TOCK"
; tell DOS where to run the program when loaded
		* = $2e0
		.word init

 

Edited by CaptMatteus
  • Like 2
Link to comment
Share on other sites

I see.

 

Btw., this macro

	.MACRO CopyChar
		LDY #0	
CharLp	LDA (SrcLO),Y
		STA (DestLO),Y
		INY
		CPY #8
		BNE CharLp
	.ENDM

 

is better written like this:

	.MACRO CopyChar
		LDY #7
CharLp	LDA (SrcLO),Y
		STA (DestLO),Y
		DEY
		BPL CharLp
	.ENDM

 

One opcode less (the CPY).

Link to comment
Share on other sites

Once ListInUse is set, you can use INC and DEC to switch between 0 and 1.

 

You Display Lists are page aligned, so storing the LSB every VBI is not needed (it's always zero).

 

You can probably drop the ListInUse variable completely. Keep the display lists page aligned. One on an even page, the other on an odd page. LDA sdlstl+1 , AND #1, branch, set new sdlstl+1.

 

 

Edited by ivop
Link to comment
Share on other sites

Revised VBI.  Works perfect!

 

vbi_isr	INC Counter			; increment timer by 1/60 sec
		LDA Counter
		CMP #$30			; has half a second gone by?
		BCS	SwapDL			; Yes -> so go swap the display lists
		JMP	SYSVBV			; no -> do nothing and return
SwapDL	LDA #0				; before swapping...
		STA Counter			; reset counter
		LDA sdlstl+1		; get hi byte of current display list in use
		AND #1				; if odd, we are on DL1 and result of operation non-zero
		BEQ ToDL1			; If 0 -> switch to DL1
		DEC sdlstl+1		; using DL1, so switch to DL0
		LDX #$7F			; Play "Tick" sound (loop takes ~1000 cycles, so safe here)
Click0	STX CONSOL
		DEX
		BPL Click0
		JMP	SYSVBV	
ToDL1	INC sdlstl+1		; on DL0, switch to DL1
		LDX #$3F			; Play "Tock" sound (loop takes ~500 cycles)
Click1	STX CONSOL
		DEX
		BPL Click1
		JMP	SYSVBV							

 

 

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...