; Keen1 Story ; by deater (Vince Weaver) <vince@deater.net> ; Zero Page .include "zp.inc" .include "hardware.inc" .include "common_defines.inc" story_data = $7000 story_end = $83A0 keen_story_start: ;=================== ; init screen ;=================== bit KEYRESET bit SET_TEXT bit PAGE1 ; bit FULLGR bit HIRES ;=================== ; Load story data ;=================== lda #<compressed_story_data sta ZX0_src lda #>compressed_story_data sta ZX0_src+1 lda #>story_data ; decompress to story data location jsr full_decomp ;=================== ; Load hires graphics ;=================== load_background: lda #<story_bg sta ZX0_src lda #>story_bg sta ZX0_src+1 lda #$20 ; decompress to hgr page1 jsr full_decomp lda #<story_data sta START_LINE_L lda #>story_data sta START_LINE_H jsr vapor_lock ; in theory at roughly 7410 cycles here (line 114) ; we want to be at line 192 (12480) ; 12480 - 7410 = 5070 ; want to delay 5070 cycles ; experimentally want about 9 less? ; 5070 - 4 - 8 = 5058/9 = 562 -(9) = 561 ; 561 / 256 = 2 r 49 nop nop nop nop lda #2 ; 2 ldy #49 ; 2 jsr delay_loop ;=========================== ; main loop ;=========================== ; 14 + 16 * (16 + 40*(16) + 19 + 7) + 17 + 17*40 -1 ; 14 + 16 * ( 682 ) + 696 ; 14 + 10912 + 696 ; 11622 / 65 = ~179 lines test1: draw_loop: ldx #0 ; line counter ; 2 lda START_LINE_L ; load up input pointers ; 3 sta INL ; 3 lda START_LINE_H ; 3 sta INH ; 3 ;=========== ; 14 outer_text_loop: ; set up lo-res output pointers ; page aligned so no page-crossing issues lda gr_offsets_low,X ; 4+ sta OUTL ; 3 lda gr_offsets_high,X ; 4+ sta OUTH ; 3 ldy #39 ; line offset pointer ; 2 ;============ ; 16 inner_text_loop: input_smc: lda (INL),Y ; 5+ sta (OUTL),Y ; 6 dey ; 2 bpl inner_text_loop ; 2/3 ;============ ; 16 ; -1 ; increment ; we don't want to cross a page so if we are ; 200 then skip to next page ; -1 lda INL ; 3 cmp #200 ; 2 beq in_next_page ; 2/3 ; 6 ldy $0 ; nop3 ; 3 clc ; 2 adc #40 ; 2 bne in_done ; bra ; 3 ; 16 in_next_page: ; 7 inc INH ; 5 lda #0 ; 2 nop ; 2 ; 16 in_done: sta INL ; 3 ;============ ; 19 inx ; 2 cpx #16 ; 2 bne outer_text_loop ; 2/3 ;============ ; 7 ; -1 ;================== ; draw message ;================== ; -1 ldx #17 ; 2 lda gr_offsets_low,X ; 4+ sta OUTL ; 3 lda gr_offsets_high,X ; 4+ sta OUTH ; 3 ldy #39 ; 2 ;================== ; 17 message_text_loop: lda message,Y ; 4+ and #$3f ; 2 sta (OUTL),Y ; 6 dey ; 2 bpl message_text_loop ; 2/3 ;================== ; 17*40 ; -1 ; 11622 ;============================================== ; let's do the keyboard stuff in constant time ;============================================== check_keypress: lda KEYPRESS ; 4 bpl done_key7 ; 2/3 ; 6 bit KEYRESET ; 4 and #$7f ; clear high bit ; 2 and #$df ; change lower to upper ; 2 ; 14 cmp #13 ; 2 beq done_with_story ; 2/3 ; 18 cmp #27 ; 2 beq done_with_story ; 2/3 ; 22 cmp #'W' ; 2 beq do_up_w ; 2/3 ; 26 cmp #$0B ; 2 beq do_up_up ; 2/3 ; 30 cmp #'S' ; 2 beq do_down_s ; 2/3 ; 34 cmp #$0A ; 2 beq do_down_down ; 2/3 ; 38 bne done_key41 ; bra ; 3 done_with_story: jmp real_done_with_story done_key7: ; need to waste 34 cycles inc $00 ; 5 inc $00 ; 5 inc $00 ; 5 inc $00 ; 5 inc $00 ; 5 inc $00 ; 5 nop nop done_key41: inc $00 ; nop5 nop nop done_key_50: inc $00 ; nop5 lda $00 ; nop3 done_key_58: inc $00 ; nop5 inc $00 ; nop5 nop done_key_70: inc $00 ; nop5 inc $00 ; nop5 done_key_80: test2: ; 11622+80 = 11702 ;========================== ; measured: ???? = 11702 ;========================== ; want to delay total of 144+70 lines, 214 ; 214*65 = 13910 ; -11702 ; ========= ; 2208 ; want to delay 2208 - 4 = 2204 - 20 = 2184 ; need multiple of 9 nop nop nop ; 2178/9=242 ; 242/256= 0 r 242 ; lda #0 ; 2 ldy #242 ; 2 jsr delay_loop test3: ;================================ ; should be: 2212 ; measured: $8A4 = 2212 ;================================ at_set_gr: ;======================================= ; want to delay 6*8*65 = 3120 ; want to delay 3120 - 15 - 7 = 3098 - 20 = 3078/9 = 342 ; 342/256=1 r 86 inc $0 ; nop5 nop ; nop2 bit SET_GR ; 4 lda #1 ; 2 ldy #86 ; 2 jsr delay_loop bit SET_TEXT ; 4 ;======================= ; measured $c2f = 3117 ; expected = 3120-3 = 3117 test4: jmp draw_loop ; 3 ;================================= ; handle up pressed ;================================= do_up_w: ; 27 nop ; 2 nop ; 2 do_up_up: ; 31 lda START_LINE_H ; 3 cmp #>story_data ; 2 bne up_ok ; 2/3 ; 38 lda START_LINE_L ; 3 cmp #<story_data ; 2 beq up_done_47 ; 2/3 bne up_ok_ok ; bra ; 3 ; 48 .align $100 up_ok: ; 39+1 cross page = 40 inc $0 ; nop5 nop nop ; 48+1 cross page = 49 up_ok_ok: ; 49 sec ; 2 lda START_LINE_L ; 3 beq to_prev_page ; 2/3 ; 56 ldy $0 ; nop3 ; 3 sbc #40 ; 2 jmp up_done ; 3 ; 64 to_prev_page: ; 57 dec START_LINE_H ; 5 lda #200 ; 2 up_done: ; 64 / 64 sta START_LINE_L ; 3 jmp done_key_70 ; 3 up_done_47: ; 47 (crossed page) jmp done_key_50 ; 3 ;================================= ; handle down pressed ;================================= do_down_s: ; 35+1 (page cross) nop nop do_down_down: ; 39+1 (page cross) ; 40 lda START_LINE_H ; 3 cmp #>story_end ; 2 bne down_ok ; 2/3 ; 47 lda START_LINE_L ; 3 cmp #<story_end ; 2 beq early_down_done ; 2/3 ; 54 bne down_ok_ok ; bra ; 3 down_ok: ; 48 inc $0 ; nop5 nop ; nop2 nop ; nop2 down_ok_ok: ; 57 ; increment input row ; we don't want to cross a page so if we are ; 200 then skip to next page lda START_LINE_L ; 3 cmp #200 ; 2 beq to_next_page ; 2/3 ; 64 ldy $0 ; nop3 ; 3 clc ; 2 adc #40 ; 2 bne down_done ; bra ; 3 ; 74 to_next_page: ; 65 inc START_LINE_H ; 5 lda #0 ; 2 nop ; 2 down_done: ; 74 / 74 sta START_LINE_L ; 3 jmp done_key_80 ; 3 early_down_done: ; 55 jmp done_key_58 ; 3 real_done_with_story: lda #LOAD_TITLE sta WHICH_LOAD rts ;========================== ; includes ;========================== .include "gr_pageflip.s" .include "gr_copy.s" ; .include "wait_a_bit.s" .include "gr_offsets.s" .include "zx02_optim.s" .include "gr_fast_clear.s" .include "text_print.s" .include "vapor_lock.s" ; .include "lc_detect.s" story_bg: .incbin "graphics/keen1_story.hgr.zx02" compressed_story_data: .incbin "story/story_data.zx02" wait_until_keypress: lda KEYPRESS bpl wait_until_keypress bit KEYRESET rts .align $100 message: ; .byte " ",0 .byte " ESC TO EXIT / ARROWS TO READ ",0 .include "gr_offsets_split.s" ;===================================== ; short delay by Bruce Clark ; any delay between 8 to 589832 with res of 9 ;===================================== ; 9*(256*A+Y)+8 + 12 for jsr/rts ; A and Y both $FF at the end size_delay: delay_loop: cpy #1 dey sbc #0 bcs delay_loop delay_12: rts .include "delay_a.s"