diff --git a/basic/tic/Makefile b/basic/tic/Makefile new file mode 100644 index 00000000..1fad52e1 --- /dev/null +++ b/basic/tic/Makefile @@ -0,0 +1,34 @@ +include ../../Makefile.inc + +DOS33 = ../../utils/dos33fs-utils/dos33 +TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft +EMPTY_DISK = ../../empty_disk/empty.dsk + +all: tic.dsk + +tic.dsk: HELLO PLASMA.BAS ROTOZOOM.BAS + cp $(EMPTY_DISK) tic.dsk + $(DOS33) -y tic.dsk SAVE A HELLO + $(DOS33) -y tic.dsk SAVE A PLASMA.BAS + $(DOS33) -y tic.dsk SAVE A ROTOZOOM.BAS + +#### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +#### + +PLASMA.BAS: plasma.bas + $(TOKENIZE) < plasma.bas > PLASMA.BAS + +#### + +ROTOZOOM.BAS: rotozoom.bas + $(TOKENIZE) < rotozoom.bas > ROTOZOOM.BAS + +#### + +clean: + rm -f *~ *.o *.lst HELLO PLASMA.BAS + diff --git a/basic/tic/hello.bas b/basic/tic/hello.bas new file mode 100644 index 00000000..133a44bb --- /dev/null +++ b/basic/tic/hello.bas @@ -0,0 +1,2 @@ +5 HOME +10 PRINT CHR$(4);"CATALOG" diff --git a/basic/tic/plasma.bas b/basic/tic/plasma.bas new file mode 100644 index 00000000..f8123d68 --- /dev/null +++ b/basic/tic/plasma.bas @@ -0,0 +1,21 @@ +'function TIC() +' t=time()/499 +' for i=0,32639 do +' x=i%240 +' y=i/240 +' v=s(x/50+t)+s(y/22+t)+s(x/32) +' poke4(i,v*2%8) +' end +'end +'s=math.sin + +5 HGR2 +10 FOR X=0 TO 279 +20 FOR Y=0 TO 191 +30 V=SIN(X/50+T)+SIN(Y/22+T)+SIN(X/32) +35 V=INT(V*3.5+3.5) +37 IF V>7 THEN V=V-7 +38 IF V<0 THEN V=V+7 +40 HCOLOR=V:HPLOT X,Y +50 NEXT Y,X +60 T=T+(1/499):GOTO 10 diff --git a/basic/tic/rotozoom.bas b/basic/tic/rotozoom.bas new file mode 100644 index 00000000..eec7b488 --- /dev/null +++ b/basic/tic/rotozoom.bas @@ -0,0 +1,23 @@ +'function TIC() +' t=time()/999 +' a=s(t-11) +' b=s(t) +' for i=0,32639 do +' x=i%240-120 +' y=i/240-68 +' u=a*x-b*y +' v=b*x+a*y +' poke4(i,(u//1~v//1)//16) +' end +'end +'s=math.sin +' // is floor division, ~ is bitwise XOR. That's hard in applesoft + +10 HGR2 +20 A=SIN(T-11) +30 B=SIN(T) +40 FOR X=-140 TO 139 +50 FOR Y=0 TO 192 +60 U=A*X-B*Y +70 V=B*X+A*Y + diff --git a/games/sb/Makefile b/games/sb/Makefile index b1ded929..68266bbe 100644 --- a/games/sb/Makefile +++ b/games/sb/Makefile @@ -4,6 +4,7 @@ ZX02 = ~/research/6502_compression/zx02.git/build/zx02 PNG_TO_HGR = ../../utils/hgr-utils/png2hgr LINKER_SCRIPTS = ../../linker_scripts DOS33 = ../../utils/dos33fs-utils/dos33 +DOS33_RAW = ../../utils/dos33fs-utils/dos33_raw EMPTY_DISK = ../../empty_disk/empty.dsk TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft @@ -11,18 +12,41 @@ all: sb.dsk #### -sb.dsk: HELLO TITLE DUCK_POND SB FN +sb.dsk: QBOOT QLOAD TITLE DUCK_POND SB FN cp $(EMPTY_DISK) sb.dsk - $(DOS33) -y sb.dsk SAVE A HELLO - $(DOS33) -y sb.dsk BSAVE -a 0x0c00 TITLE - $(DOS33) -y sb.dsk BSAVE -a 0x1000 DUCK_POND - $(DOS33) -y sb.dsk BSAVE -a 0x0c00 SB - $(DOS33) -y sb.dsk BSAVE -a 0x6000 FN + $(DOS33_RAW) sb.dsk 0 0 QBOOT 0 1 + $(DOS33_RAW) sb.dsk 0 2 QBOOT 1 1 + $(DOS33_RAW) sb.dsk 0 4 QBOOT 2 1 + $(DOS33_RAW) sb.dsk 1 0 QLOAD 0 0 + $(DOS33_RAW) sb.dsk 2 0 TITLE 0 0 + $(DOS33_RAW) sb.dsk 5 0 DUCK_POND 0 0 + $(DOS33_RAW) sb.dsk 8 0 SB 0 0 + $(DOS33_RAW) sb.dsk 11 0 FN 0 0 +# $(DOS33) -y sb.dsk BSAVE -a 0x1000 DUCK_POND +# $(DOS33) -y sb.dsk BSAVE -a 0x0c00 SB +# $(DOS33) -y sb.dsk BSAVE -a 0x6000 FN #### +QBOOT: qboot_sector.o + ld65 -o QBOOT qboot_sector.o -C $(LINKER_SCRIPTS)/apple2_800.inc + +qboot_sector.o: qboot_sector.s qboot_stage2.s + ca65 -o qboot_sector.o qboot_sector.s -l qboot_sector.lst + +#### + +QLOAD: qload.o + ld65 -o QLOAD qload.o -C $(LINKER_SCRIPTS)/apple2_1200.inc + +qload.o: qload.s qboot.inc + ca65 -o qload.o qload.s -l qload.lst + +#### + + SB: sb.o - ld65 -o SB sb.o -C $(LINKER_SCRIPTS)/apple2_c00.inc + ld65 -o SB sb.o -C $(LINKER_SCRIPTS)/apple2_6000.inc sb.o: sb.s zx02_optim.s \ zp.inc hardware.inc @@ -50,7 +74,7 @@ fn.o: fn.s zx02_optim.s duet.s hgr_sprite_mask.s hgr_sprite.s hgr_tables.s \ #### TITLE: title.o - ld65 -o TITLE title.o -C $(LINKER_SCRIPTS)/apple2_c00.inc + ld65 -o TITLE title.o -C $(LINKER_SCRIPTS)/apple2_6000.inc title.o: title.s zx02_optim.s \ zp.inc hardware.inc @@ -60,7 +84,7 @@ title.o: title.s zx02_optim.s \ #### DUCK_POND: duck_pond.o - ld65 -o DUCK_POND duck_pond.o -C $(LINKER_SCRIPTS)/apple2_1000.inc + ld65 -o DUCK_POND duck_pond.o -C $(LINKER_SCRIPTS)/apple2_6000.inc duck_pond.o: duck_pond.s zx02_optim.s \ zp.inc hardware.inc \ diff --git a/games/sb/duck_pond.s b/games/sb/duck_pond.s index a5fda648..97d2585f 100644 --- a/games/sb/duck_pond.s +++ b/games/sb/duck_pond.s @@ -59,7 +59,7 @@ title_screen: lda #>title_data sta ZX0_src+1 - lda #$C ; load at $c00 + lda #$c ; load at $C00 jsr full_decomp @@ -111,7 +111,7 @@ init_game: lda #>main_data sta ZX0_src+1 - lda #$C + lda #$c jsr full_decomp diff --git a/games/sb/qboot.inc b/games/sb/qboot.inc new file mode 100644 index 00000000..65fbf7dd --- /dev/null +++ b/games/sb/qboot.inc @@ -0,0 +1,8 @@ +seek = $1126 +driveon = $119D +driveoff = $1122 +load_new = $11AB +load_address=$11C4 +load_track=load_address+1 +load_sector=load_address+2 +load_length=load_address+3 diff --git a/games/sb/qboot_sector.s b/games/sb/qboot_sector.s new file mode 100644 index 00000000..2b3901b1 --- /dev/null +++ b/games/sb/qboot_sector.s @@ -0,0 +1,244 @@ +; fast seek/multi-read +; copyright (c) Peter Ferrie 2015-16 + + ; Paramaters for loading QLOAD + + sectors = 14 ; user-defined + firsttrk = 1 ; user-defined, first track to read + firstsec = 0 ; user-defined, first sector to read + address = $12 ; user-defined + entry = $1200 ; user-defined + version = 1 + + ;memory usage: + ;256 bytes ($200-2ff) static table + grouped = $200 + + ; stay away from interrupt vectors at $3fe !!! + + ;106 bytes ($300-369) static table + preshift = $300 + zvalue = $fd ; only during init + znibble = $fe ; only during init + zmask = $ff ; only during init + + WHICH_SLOT = $DA + +; $26/$27 sector read location (ROM) +; $3D sector number (ROM) + + +; at entry (at least on AppleWin) A=1, X=60 (slot<<4), Y=0 +; qkumba says cffa cards leave Y at $10 +; 26/27 = 00/09 +; 3D = 1 + + ; For Disk II booting, the firmware loads track0/sector0 + ; to $800 and then jumps to $801 + +.org $800 + .byte 1 ; number of sectors for ROM to load + +boot_entry: + ; this code loads two sectors up to $10/$11 + + ; assume A=1 coming in here + + lsr ; check sector number + ; A=0, carry=1 + tay ; Y=0 + adc #$0f ; A=$10 (destintation) + + sta $27 ; set or update address as needed + cmp #$12 + ; 10 11 12 (1 1 1) + ; be, bf, c0 (1011 1011 1100) + ; so if hit $c000 we are done + + beq done_load_2 ; branch if loaded 2 + + inc $3d ; increment sector (faster to find) + + ; call to the read routine in proper slot + ; using rts to jump indirect to + ; $CX5C + + ; this routine reads sector in $3D on track in $41 + ; to address in $26/$27 + ; when it's done it jumps back to $801 + stx WHICH_SLOT ; save for later + + txa ; x is slot# << 4 + lsr + lsr + lsr + lsr + ora #$c0 ; slot to PROM base + pha + lda #$5b ;read-1 + pha + rts ; return used to call $CX5C in DISK II ROM + +done_load_2: + + ; patch self modifying code for Q6L read + + txa + ora #$8c ; slot to Q6L + ; Q6L? + ; if slot 6, after this A is $EC + ; Y should be 2 here +patch_loop: + iny + ldx patchtbl-3, Y + sta code_begin, X ; replace placeholders with Q6L + ; BE02 = EC? lda c0ec + ; so sets to c08c (Q6L) + + bne patch_loop + + ; patch self-modifying code for turning motor off + + and #$f8 ; MOTOROFF (c088) -> c0e8 + sta slotpatch7+1 + + ; patch self-modifying code for turning motor on + clc + adc #1 ; MOTORON (c089) -> c0e9 + sta slotpatch9+1 + + ; patch self-modifying code for phase off + + eor #9 ; PHASEOFF (c080) + sta slotpatch8+1 + + ldx #$3f + stx zmask + inx + ldy #$7f + + bne skip_ahead ; branch always + + ; pad with zeros until $839 + ; $839 is the entry point + ; adjusts address at $8FE to be entry point + ; jumps to boot 2 +;.res $839-* + +; lda #>(entry-1) +; pha +; lda #<(entry-1) +; pha +; jsr preread +; jmp $1000 ; stage2 entry point + +patchtbl: + .byte <(slotpatch1+1), <(slotpatch2+1), <(slotpatch3+1) + .byte <(slotpatch4+1), <(slotpatch5+1), <(slotpatch6+1) +indextbl: ;the 0 also terminates the patchtbl list! + .byte 0, 2, 1, 3 + + + ;construct denibbilisation table + ;pre-shifted for interleave read + +skip_ahead: +loopaa: + sty znibble + tya + asl + bit znibble + beq loopz + ora znibble + eor #$ff + and #$7e +loopa: + bcs loopz + lsr + bne loopa + dex + txa + asl + asl + sta preshift-$16, Y +loopz: + dey + bne loopaa + + ;construct 2-bit group table + + sty zvalue +loopbb: + lsr zmask + lsr zmask +loopb: + lda indextbl, X + sta grouped, Y + inc zvalue + lda zvalue + and zmask + bne loopy + inx + txa + and #3 + tax +loopy: + iny + iny + iny + iny + cpy #3 + bcs loopb + iny + cpy #3 + bcc loopbb + lda #>(entry-1) + pha + lda #<(entry-1) + pha + jsr preread + + ; seek backward support +; sty startsec+1 +; sta tmpadr+1 +; stx total+1 + + jmp seekread + +preread: + +;copy post-read if necessary +;push post-read address here +; pla +; tax +; pla +; tay +; lda #>(postread-1) +; pha +; lda #<(postread-1) +; pha +; tya +; pha +; txa +; pha + + lda #<(firsttrk*2) + sta phase+1 + ldx #sectors + lda #address + ldy #firstsec + rts + + + +end_code: + +.res $8fe-* + +; traditionally, entry point to jump to at end of loading +; $1000 in this case +;*=$8fe + .byte $10, $00 + + +.include "qboot_stage2.s" diff --git a/games/sb/qboot_stage2.s b/games/sb/qboot_stage2.s new file mode 100644 index 00000000..6a38148f --- /dev/null +++ b/games/sb/qboot_stage2.s @@ -0,0 +1,382 @@ +; the following lives on sectors $0E and $0D +; why? +; request sector 2 and 4, and the interleave is + +; beneath apple dos (3-23) +; Physical (firmware) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +; DOS33 mapping : 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 + + +; Beneath Apple DOS +; p86 (dos reference) +; + +;WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us + +WAIT = norom_wait + +.org $1000 + +code_begin: + + .byte version + +readnib: +slotpatch1: ; smc + lda $c0d1 ; gets set to C08C (Q6L) read + bpl readnib + rts + + ;fill address array for one track +seekread: + sty startsec+1 + sta tmpadr+1 + stx total+1 + +inittrk: + sec + lda #$10 + sbc startsec+1 + cmp total+1 + bcs it_skip + + tax + +it_skip: + stx partial1 + stx partial2 + jsr seek + +startsec: + ldy #$d1 + +tmpadr: +tmpadr_loop: + lda #$d1 + sta addrtbl, y + inc tmpadr+1 + iny + dec partial1 + bne tmpadr_loop + + ;==================================== + ; read a sector + ;==================================== + ; first address field + ;==================================== + ; starts with $D5 $AA $96 + ; then XX YY volume + ; then XX YY track + ; then XX YY sector + ; then XX YY checksum + ; then ends with $DE $AA $EB + ;==================================== + ; data field + ;==================================== + ; starts with $D5 $AA $AD + ; 342 bytes of data + ; XX checksum + ; ends with $DE $AA $EB +read: + +outer_read: + jsr readnib +inner_read: + cmp #$d5 ; look for $D5 part of addr field + bne outer_read + + jsr readnib ; look for $D5 $AA + cmp #$aa + bne inner_read + + ; look for $D5 $AA $AD + + tay ; we need Y=#$AA later + jsr readnib + eor #$ad ; zero A if match + beq check_mode + + ; if not #$AD, then #$96 is assumed + ; so in address field + + ldy #2 ; volume, track, sector +another: + jsr readnib + rol ; set carry + sta sector+1 + jsr readnib + and sector+1 + dey + bpl another + + tay + ldx addrtbl, Y ; fetch corresponding address + beq read ; done? + + sta sector+1 ; store index for later + + stx adrpatch1+2 + stx adrpatch8+2 + stx adrpatch2+2 + stx adrpatch3+2 + stx adrpatch5+2 + stx adrpatch7+2 + + inx + stx adrpatch9+2 + dex + + dex + stx adrpatch4+2 + stx adrpatch6+2 + + ldy #$fe + +loop2: +adrpatch1: + lda $d102, Y + pha + iny + bne loop2 + +branch_read: + bcs read ; branch always + +check_mode: + cpx #0 + beq read ; loop if not expecting #$AD + +loop33: + sta tmpval+1 ; zero rolling checksum +slotpatch2: +loop4: + ldx $c0d1 + bpl loop4 + lda preshift-$96, X +adrpatch2: + sta $d102, Y ; store 2-bit array + +tmpval: + eor #$d1 + iny + bne loop33 + ldy #$aa +slotpatch3: +loop5: + ldx $c0d1 + bpl loop5 + eor preshift-$96, X +adrpatch3: + ldx $d102, Y ; bit2tbl + eor grouped+2, X ; first 86 nibbles use group bits 0-1 +adrpatch4: + sta $d156, y + iny + bne loop5 + and #$fc + ldy #$aa +slotpatch4: +loop6: + ldx $c0d1 + bpl loop6 + eor preshift-$96, X +adrpatch5: + ldx $d102, Y ; bit2tbl + eor grouped+1, X ; second 86 nibbles use group bits 2-3 +adrpatch6: + sta $d1ac, Y + iny + bne loop6 + and #$fc + ldx #$ac +slotpatch5: +loop7: + ldy $c0d1 + bpl loop7 + eor preshift-$96, Y +adrpatch7: + ldy $d100, X ; bit2tbl + eor grouped, Y ; last 84 nibbles use group bits 4-5 +adrpatch8: + sta $d100, x + inx + bne loop7 + and #$fc +slotpatch6: +loop8: + ldy $c0d1 + bpl loop8 + eor preshift-$96, Y + cmp #1 ; carry = !zero + ldy #1 +loop9: + pla +adrpatch9: + sta $d100, Y + dey + bpl loop9 +branch_read2: + bcs branch_read ; branch if checksum failure + +sector: + ldy #$d1 + txa + sta addrtbl, Y ; zero corresponding address + dec total+1 + dec partial2 ; adjust remaining count + ; (faster than looping over array) + sec + bne branch_read2 ; read all requested sectors in one track + + sta startsec+1 ; this was missing from original code + ; leading to trouble on wrap around + ; it not starting at sector0 +total: + ldx #$d1 + beq driveoff + inc phase+1 + inc phase+1 ; update current track + jmp inittrk + +driveoff: +slotpatch7: + lda $c0d1 + +seekret: + rts + +seek: + ldx #0 + stx step+1 +copy_cur: +curtrk: + lda #0 + sta tmpval+1 + sec +phase: + sbc #$d1 + beq seekret + + ; if seek backwards + bcs sback + + eor #$ff + inc curtrk+1 + + bcc ssback +sback: + adc #$fe + dec curtrk+1 +ssback: + cmp step+1 + bcc loop10 +step: + lda #$d1 +loop10: + cmp #8 + bcs loop11 + tay + sec +loop11: + lda curtrk+1 + ldx step1, Y + bne loop12 +loopmmm: + clc + lda tmpval+1 + ldx step2, Y +loop12: + stx sector+1 + and #3 + rol + tax +slotpatch8: + sta $c0d1, X +loopmm: + ldx #$13 +loopm: + dex + bne loopm + dec sector+1 + bne loopmm + lsr + bcs loopmmm + inc step+1 + bne copy_cur + +step1: .byte 1, $30, $28, $24, $20, $1e, $1d, $1c +step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c +addrtbl: .res 16 + +partial1: .byte $00 +partial2: .byte $00 +code_end: + + +;========================== +; enable drive motor +;========================== + +driveon: + +slotpatch9: + lda $c0d1 + + ; wait 1s + + ldx #6 +wait_1s: + lda #255 + jsr WAIT + dex + bne wait_1s + + rts + +load_new: + + jsr driveon + + lda load_track + asl ; track to start*2 + sta phase+1 + + lda load_sector + tay ; sector to start + + lda load_length ; length + tax + + lda load_address ; address to load + + jsr seekread + + rts + +load_address: + .byte $00 +load_track: + .byte $00 +load_sector: + .byte $00 +load_length: + .byte $00 + + + +; copy of ROM wait +; because we might disable ROM + +norom_wait: + sec +wait2: + pha +wait3: + sbc #$01 + bne wait3 + pla + sbc #$01 + bne wait2 + rts +wait_end: + diff --git a/games/sb/qload.s b/games/sb/qload.s new file mode 100644 index 00000000..29ee7daa --- /dev/null +++ b/games/sb/qload.s @@ -0,0 +1,192 @@ +; Loader for sb + +.include "zp.inc" +.include "hardware.inc" + +;.include "common_defines.inc" +.include "qboot.inc" + +qload_start: + + ; init the write code +; lda WHICH_SLOT +; jsr popwr_init + + ; first time entry + ; start by loading text title + + lda #0 ; load LEMM engine + sta WHICH_LOAD + + lda #1 + sta CURRENT_DISK ; current disk number + +forever_loop: + jsr load_file + + jsr $6000 ; jump to loaded file + + jmp forever_loop + + ;==================================== + ; loads file specified by WHICH_LOAD + ;==================================== +load_file: + ldx WHICH_LOAD + + lda which_disk_array,X + cmp CURRENT_DISK + bne change_disk + +load_file_no_diskcheck: + lda load_address_array,X + sta load_address + + lda track_array,X + sta load_track + + lda sector_array,X + sta load_sector + + lda length_array,X + sta load_length + + jsr load_new + + rts + + ;=================================================== + ;=================================================== + ; change disk + ;=================================================== + ;=================================================== + +change_disk: +.if 0 + ; turn off disk drive light + + jsr driveoff + + jsr TEXT + jsr HOME + + lda #error_string + sta OUTH + + ldx WHICH_LOAD + lda which_disk_array,X + clc + adc #48 + + ldy #19 + sta (OUTL),Y + + ldy #0 + +quick_print: + lda (OUTL),Y + beq quick_print_done + jsr COUT1 + iny + jmp quick_print + +quick_print_done: + +fnf_keypress: + lda KEYPRESS + bpl fnf_keypress + bit KEYRESET + + ;============================================== + ; actually verify proper disk is there + ; read T0:S0 and verify proper disk + + lda WHICH_LOAD + pha + + ldx #LOAD_FIRST_SECTOR ; load track 0 sector 0 + stx WHICH_LOAD + + jsr load_file_no_diskcheck + + pla + sta WHICH_LOAD + tax + + ; first sector now in $c00 + ; offset 59 + ; disk1 = $0a + ; disk2 = $32 ('2') + ; disk3 = $33 ('3') + + lda $c59 + cmp #$0a + beq is_disk1 + cmp #$32 + beq is_disk2 + cmp #$33 + beq is_disk3 + bne change_disk ; unknown disk + +is_disk1: + lda #1 + bne disk_compare + +is_disk2: + lda #2 + bne disk_compare + +is_disk3: + lda #3 + +disk_compare: + cmp which_disk_array,X + bne change_disk ; disk mismatch + + ;============================================== + ; all good, retry original load + + jsr HOME + + ldx WHICH_LOAD + lda which_disk_array,X + sta CURRENT_DISK + + jmp load_file + +; offset for disk number is 19 +error_string: +.byte "PLEASE INSERT DISK 1, PRESS RETURN",0 + +.endif + +which_disk_array: + .byte 1,1,1,1 ; TITLE, DUCK, SB, FN + .byte 1,1,1,1 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 + .byte 1,1,1,1 ; LEVEL8, LEVEL9, LEVEL10 + +load_address_array: + .byte $60,$60,$60,$60 ; TITLE, DUCK, SB, FN + .byte $90,$90,$90,$90 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 + .byte $90,$90,$90,$90 ; LEVEL8, LEVEL9, LEVEL10 + +track_array: + .byte 2, 5, 8,11 ; TITLE, DUCK, SB, FN + .byte 15,18,21,24 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 + .byte 27,30,33,33 ; LEVEL8, LEVEL9, LEVEL10 + +sector_array: + .byte 0, 0, 0, 0 ; TITLE, DUCK, SB, FN + .byte 0, 0, 0, 0 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 + .byte 0, 0, 0, 0 ; LEVEL8, LEVEL9, LEVEL10 + +length_array: + .byte 16, 16, 16, 32 ; TITLE, DUCK, SB, FN + .byte 46, 46, 46, 46 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 + .byte 46, 46, 32, 32 ; LEVEL8, LEVEL9, LEVEL10 + +qload_end: + +.assert (>qload_end - >qload_start) < $e , error, "loader too big" diff --git a/games/sb/sb.s b/games/sb/sb.s index 3610da80..9dd90a69 100644 --- a/games/sb/sb.s +++ b/games/sb/sb.s @@ -57,7 +57,10 @@ wait_until_keypress: bit KEYRESET ; clear the keyboard buffer which_ok: - jmp load_loop + lda #0 + sta WHICH_LOAD + rts + diff --git a/games/sb/title.s b/games/sb/title.s index 99d27777..802a41ee 100644 --- a/games/sb/title.s +++ b/games/sb/title.s @@ -56,11 +56,22 @@ wait_until_keypress: bpl wait_until_keypress ; 3 bit KEYRESET ; clear the keyboard buffer + and #$7f + cmp #'1' + bcc which_ok + cmp #'4' + bcs which_ok + + jmp done + which_ok: jmp load_loop - +done: + and #$f + sta WHICH_LOAD + rts .include "zx02_optim.s" diff --git a/games/sb/zp.inc b/games/sb/zp.inc index f427a02f..dbf7581c 100644 --- a/games/sb/zp.inc +++ b/games/sb/zp.inc @@ -10,6 +10,8 @@ ZX0_dst = ZP+4 bitr = ZP+6 pntr = ZP+7 +WHICH_LOAD = $09 + ;; Zero page monitor routines addresses WNDLFT = $20 @@ -124,6 +126,8 @@ LYRICS_ACTIVE = $9B ;FORTYCOL = $9C CURSOR = $9D +CURRENT_DISK = $DC + ; More zero-page addresses ; we try not to conflict with anything DOS, MONITOR or BASIC related