CaptMatteus Posted February 3, 2021 Share Posted February 3, 2021 (edited) 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 February 3, 2021 by CaptMatteus 2 Quote Link to comment Share on other sites More sharing options...
sanny Posted February 3, 2021 Share Posted February 3, 2021 Which assembler is needed to compile? Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 I used atasm on the Mac (which is largely compatible with Mac/65). Quote Link to comment Share on other sites More sharing options...
sanny Posted February 3, 2021 Share Posted February 3, 2021 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). Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 Ooh, I like it. Always looking to eliminate some cycles. Quote Link to comment Share on other sites More sharing options...
ivop Posted February 3, 2021 Share Posted February 3, 2021 (edited) 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 February 3, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 (edited) That is a great idea! Not a huge time saver in this application, but when there is more going on, very useful both in cycle count and reduced page zero footprint. Edited February 3, 2021 by CaptMatteus misspelling Quote Link to comment Share on other sites More sharing options...
ivop Posted February 3, 2021 Share Posted February 3, 2021 Sizecoding is the opposite of sex. You want to reach the result as fast as possible, with the smallest size 4 Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 5 minutes ago, ivop said: Sizecoding is the opposite of sex. You want to reach the result as fast as possible, with the smallest size Indeed. ? Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 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 2 Quote Link to comment Share on other sites More sharing options...
ivop Posted February 3, 2021 Share Posted February 3, 2021 Nice improvements! 10 minutes ago, CaptMatteus said: LDA Counter CMP #$30 ; has half a second gone by? This is not half a second. $30 is 48 1 Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 Oops! Haha. It sure felt like it was a little slow... Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 3, 2021 Author Share Posted February 3, 2021 (edited) That should be #30...or #$1E. Edited February 3, 2021 by CaptMatteus Quote Link to comment Share on other sites More sharing options...
snicklin Posted February 6, 2021 Share Posted February 6, 2021 Any chance of an xex? Quote Link to comment Share on other sites More sharing options...
CaptMatteus Posted February 7, 2021 Author Share Posted February 7, 2021 Here you go! Bufferx2.xex Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.