; Race the Beam ; try for 40x192 15-color graphics on stock Apple II / Apple II+ ; this means, no double-hires ; by racing the beam we can possibly update at least 10 blocks ; per line to the 192-line resolution ; we can get 40x96 resolution simply by page flipping ; this all requires vapor lock cycle-counting ; by deater (Vince Weaver) ; Zero Page FRAMEBUFFER = $00 ; $00 - $0F YPOS = $10 YPOS_SIN = $11 CH = $24 CV = $25 GBASL = $26 GBASH = $27 BASL = $28 BASH = $29 FRAME = $60 WAITING = $62 LETTERL = $63 LETTERH = $64 LETTERX = $65 LETTERY = $66 LETTERD = $67 LETTER = $68 BLARGH = $69 HGR_COLOR = $E4 STATE = $ED DRAW_PAGE = $EE LASTKEY = $F1 PADDLE_STATUS = $F2 TEMP = $FA WHICH = $FB ; Soft Switches KEYPRESS= $C000 KEYRESET= $C010 SPEAKER = $C030 SET_GR = $C050 ; Enable graphics SET_TEXT= $C051 ; Enable text FULLGR = $C052 ; Full screen, no text TEXTGR = $C053 ; Split screen PAGE0 = $C054 ; Page0 PAGE1 = $C055 ; Page1 LORES = $C056 ; Enable LORES graphics HIRES = $C057 ; Enable HIRES graphics PADDLE_BUTTON0 = $C061 PADDL0 = $C064 PTRIG = $C070 ; ROM routines ;HGR = $F3E2 ;HPLOT0 = $F457 ;HGLIN = $F53A ;COLORTBL= $F6F6 TEXT = $FB36 ;; Set text mode HOME = $FC58 ;; Clear the text screen WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us ;================================== ;================================== setup_background: ;=================== ; init screen jsr TEXT jsr HOME bit LORES bit SET_GR bit FULLGR bit PAGE0 bit KEYRESET ;=================== ; init vars lda #0 sta DRAW_PAGE sta STATE sta WAITING ;============================= ; Load graphic page0 ; lda #$0c ; sta BASH ; lda #$00 ; sta BASL ; load image to $c00 ; lda #bg_final_low ; sta GBASH ; jsr load_rle_gr ; lda #4 ; sta DRAW_PAGE ; jsr gr_copy_to_current ; copy to page1 ; GR part ; bit PAGE1 ; bit LORES ; 4 ; bit SET_GR ; 4 ; bit FULLGR ; 4 ; jsr wait_until_keypressed ;============================= ; Load graphic page1 ; lda #$0c ; sta BASH ; lda #$00 ; sta BASL ; load image to $c00 ; lda #bg_final_high ; sta GBASH ; jsr load_rle_gr ; lda #0 ; sta DRAW_PAGE ; jsr gr_copy_to_current ; GR part ; bit PAGE0 ; jsr wait_until_keypressed ;============================== ; setup graphics for vapor lock ;============================== jsr vapor_lock ; 6 ; vapor lock returns with us at beginning of hsync in line ; 114 (7410 cycles), so with 5070 lines to go ; so we have 5070 + 4550 = 9620 to kill jsr gr_copy_to_current ; 6+ 9292 ; now we have 322 left ; GR part bit LORES ; 4 bit SET_GR ; 4 bit FULLGR ; 4 ; 322 - 12 = 310 ; - 3 for jmp ; 307 ; Try X=9 Y=6 cycles=307 ldy #6 ; 2 loopA: ldx #9 ; 2 loopB: dex ; 2 bne loopB ; 2nt/3 dey ; 2 bne loopA ; 2nt/3 jmp display_loop ; 3 .align $100 ;================================================ ; Display Loop ;================================================ ; each scan line 65 cycles ; 1 cycle each byte (40cycles) + 25 for horizontal ; Total of 12480 cycles to draw screen ; Vertical blank = 4550 cycles (70 scan lines) ; Total of 17030 cycles to get back to where was ; We want to alternate between page1 and page2 every 65 cycles ; vblank = 4550 cycles to do scrolling ; 2 + 48*( (4+2+25*(2+3)) + (4+2+23*(2+3)+4+5)) + 9) ; 48*[(6+125)-1] + [(6+115+10)-1] display_loop: ;=================================== ; 192 lines, alternate PAGE0/PAGE1 every 2 lines ;=================================== ldy #96 ; *2=192 lines ; 2 ; we set PAGE0 (4) then want to NOP (61) for a total of 65 bouter_loop: bit PAGE0 ; 4 ldx #12 ; 65 cycles with PAGE0 ; 2 bpage0_loop: ; delay 61+bit dex ; 2 bne bpage0_loop ; 2/3 ;============= ; 6+(12*5)-1=65 ; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55) ; bit PAGE1 ; 4 ldx #11 ; 65 cycles with PAGE1 ; 2 bpage1_loop: dex ; 2 bne bpage1_loop ; 2/3 ;============= ; 6+(11*5)-1=60 dey ; 2 bne bouter_loop ; 2/3 ;============== ; 5 to make 65 ;====================================================== ; We have 4550 cycles in the vblank, use them wisely ;====================================================== ; 4550 ; +1 fallthrough ; -2 for ldy in previous ; -35 call through jumptable ; -7 keyboard ; -3 jmp ; ======== ; 4504 ;======================== ; each subunit should take 4504 cycles firework_state_machine: check_keyboard: lda KEYPRESS ; 4 bpl no_keypress ; 3 jmp restart no_keypress: jmp display_loop ; 3 restart: jmp setup_background .include "gr_hline.s" ;.include "../asm_routines/gr_unrle.s" ;.include "../asm_routines/keypress.s" .include "gr_copy.s" ;.include "random16.s" .include "vapor_lock.s" .include "delay_a.s"