From 291a2f04611be7f0ed9d0a017f00d09e7a4f942d Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 19 Apr 2021 10:55:55 -0400 Subject: [PATCH] ootw: move to qboot for disk1 more or less seems to work --- games/ootw/Makefile | 45 +++- games/ootw/README | 39 +++ games/ootw/intro/Makefile | 2 +- games/ootw/ootw_c1/Makefile | 2 +- games/ootw/ootw_c2/Makefile | 2 +- games/ootw/ootw_c3/Makefile | 2 +- games/ootw/ootw_c4/Makefile | 2 +- games/ootw/ootw_c5/Makefile | 2 +- games/ootw/qboot/Makefile | 58 +++++ games/ootw/qboot/README | 18 ++ games/ootw/qboot/common_defines.inc | 30 +++ games/ootw/qboot/qboot.inc | 8 + games/ootw/qboot/qboot_sector.s | 243 +++++++++++++++++++ games/ootw/qboot/qboot_stage2.s | 363 ++++++++++++++++++++++++++++ games/ootw/qboot/qload.s | 231 ++++++++++++++++++ games/ootw/qboot/title.s | 309 +++++++++++++++++++++++ games/ootw/zp.inc | 13 +- linker_scripts/apple2_1600.inc | 12 + 18 files changed, 1360 insertions(+), 21 deletions(-) create mode 100644 games/ootw/qboot/Makefile create mode 100644 games/ootw/qboot/README create mode 100644 games/ootw/qboot/common_defines.inc create mode 100644 games/ootw/qboot/qboot.inc create mode 100644 games/ootw/qboot/qboot_sector.s create mode 100644 games/ootw/qboot/qboot_stage2.s create mode 100644 games/ootw/qboot/qload.s create mode 100644 games/ootw/qboot/title.s create mode 100644 linker_scripts/apple2_1600.inc diff --git a/games/ootw/Makefile b/games/ootw/Makefile index 155ac014..c647e3a8 100644 --- a/games/ootw/Makefile +++ b/games/ootw/Makefile @@ -2,23 +2,43 @@ include ../../Makefile.inc DOS33 = ../../utils/dos33fs-utils/dos33 TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft - +DOS33_RAW = ../../utils/dos33fs-utils/dos33_raw EMPTY_DISK = ../../empty_disk all: ootw.dsk ootw_side2.dsk ootw_side3.dsk -ootw.dsk: HELLO ./title/TITLE \ +#ootw.dsk: HELLO ./title/TITLE \ +# ./intro/INTRO ./ootw_c1/OOTW_C1 ./ootw_c2/OOTW_C2 \ +# ./ootw_c3/OOTW_C3 ./ootw_c4/OOTW_C4 ./ootw_c5/OOTW_C5 +# cp $(EMPTY_DISK)/empty.dsk ootw.dsk +# $(DOS33) -y ootw.dsk SAVE A HELLO +# $(DOS33) -y ootw.dsk BSAVE -a 0xd00 ./title/TITLE +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./intro/INTRO INTRO +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c1/OOTW_C1 OOTW_C1 +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c2/OOTW_C2 OOTW_C2 +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c3/OOTW_C3 OOTW_C3 +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c4/OOTW_C4 OOTW_C4 +# $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c5/OOTW_C5 OOTW_C5 + +ootw.dsk: ./qboot/QBOOT_DISK1 ./qboot/QLOAD \ ./intro/INTRO ./ootw_c1/OOTW_C1 ./ootw_c2/OOTW_C2 \ ./ootw_c3/OOTW_C3 ./ootw_c4/OOTW_C4 ./ootw_c5/OOTW_C5 cp $(EMPTY_DISK)/empty.dsk ootw.dsk - $(DOS33) -y ootw.dsk SAVE A HELLO - $(DOS33) -y ootw.dsk BSAVE -a 0xd00 ./title/TITLE - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./intro/INTRO INTRO - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c1/OOTW_C1 OOTW_C1 - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c2/OOTW_C2 OOTW_C2 - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c3/OOTW_C3 OOTW_C3 - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c4/OOTW_C4 OOTW_C4 - $(DOS33) -y ootw.dsk BSAVE -a 0x1700 ./ootw_c5/OOTW_C5 OOTW_C5 + $(DOS33_RAW) ootw.dsk 0 0 ./qboot/QBOOT_DISK1 0 1 + $(DOS33_RAW) ootw.dsk 0 2 ./qboot/QBOOT_DISK1 1 1 + $(DOS33_RAW) ootw.dsk 0 4 ./qboot/QBOOT_DISK1 2 1 + $(DOS33_RAW) ootw.dsk 1 0 ./qboot/QLOAD 0 14 + $(DOS33_RAW) ootw.dsk 2 0 ./intro/INTRO 0 137 + $(DOS33_RAW) ootw.dsk 11 0 ./ootw_c1/OOTW_C1 0 95 + $(DOS33_RAW) ootw.dsk 17 0 ./ootw_c2/OOTW_C2 0 125 + $(DOS33_RAW) ootw.dsk 25 0 ./ootw_c3/OOTW_C3 0 14 + $(DOS33_RAW) ootw.dsk 26 0 ./ootw_c4/OOTW_C4 0 62 + $(DOS33_RAW) ootw.dsk 30 0 ./ootw_c5/OOTW_C5 0 41 + + + + + ootw_side2.dsk: HELLO ./title/TITLE \ ./ootw_c6/OOTW_C6 ./ootw_c7/OOTW_C7 ./ootw_c8/OOTW_C8 \ @@ -47,6 +67,11 @@ ootw_side3.dsk: HELLO ./title/TITLE ./ending/ENDING \ #### +qboot/QBOOT: + cd qboot && make + +#### + intro/INTRO: cd intro && make diff --git a/games/ootw/README b/games/ootw/README index da2cb004..c8df23a2 100644 --- a/games/ootw/README +++ b/games/ootw/README @@ -240,3 +240,42 @@ In any case, I chose lo-res for the Another World conversion for 3 reasons The recent C64 Another World conversion looks much more impressive and hi-res, but I think they use a 1MB cartridge just for the intro movie alone (which is possible larger than the size of the original game for the Amiga). + + + +DISK: +~~~~~ + +DISK1: + TITLE 2540 10s 0T10S T1 + INTRO 35049 137s 8T9S T2..T10 + OOTW_C1 24094 95s 5T15S T11-T16 + OOTW_C2 31845 125s 7T13S T17-T24 + OOTW_C3 3420 14s 0T14S T25 + OOTW_C4 15643 62s 3T14S T26-T29 + OOTW_C5 10333 41s 2T9S T30-T32 + ==== + 484s = 121k + +DISK2: + TITLE 2540 10s 0T10S T1 + OOTW_C6 9605 38s 2T6S T2-T4 + OOTW_C7 9704 38s 2T6S T5-T7 + OOTW_C8 9823 39s 2T7S T8-T10 + OOTW_C9 9646 38s 2T6S T11-T13 + OOTW_C10 9646 38s 2T6S T14-T16 + ==== + 201s = 50k + +DISK3: + TITLE 2540 10s 0T10S T1 + OOTW_C11 9643 38s 2T6S T2-T4 + OOTW_C12 9707 38s 2T6S T5-T7 + OOTW_C13 9828 39s 2T7S T8-T10 + OOTW_C14 9749 38s 2T6S T11-T12 + OOTW_C15 24658 97s 6T1S T13-T18 + ENDING 22899 90s 5T10S T19-T24 + ==== + 350 = 87.5k + + diff --git a/games/ootw/intro/Makefile b/games/ootw/intro/Makefile index 7d24da2c..adcaa3b6 100644 --- a/games/ootw/intro/Makefile +++ b/games/ootw/intro/Makefile @@ -8,7 +8,7 @@ all: INTRO #### INTRO: intro.o - ld65 -o INTRO intro.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o INTRO intro.o -C $(LINKER_SCRIPTS)/apple2_1800.inc intro.o: intro.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/ootw_c1/Makefile b/games/ootw/ootw_c1/Makefile index 1bd369fb..e22a1fa4 100644 --- a/games/ootw/ootw_c1/Makefile +++ b/games/ootw/ootw_c1/Makefile @@ -9,7 +9,7 @@ all: OOTW_C1 #### OOTW_C1: ootw_c1.o - ld65 -o OOTW_C1 ootw_c1.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o OOTW_C1 ootw_c1.o -C $(LINKER_SCRIPTS)/apple2_1800.inc ootw_c1.o: ootw_c1.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/ootw_c2/Makefile b/games/ootw/ootw_c2/Makefile index 1acc2276..170be482 100644 --- a/games/ootw/ootw_c2/Makefile +++ b/games/ootw/ootw_c2/Makefile @@ -10,7 +10,7 @@ all: OOTW_C2 #### OOTW_C2: ootw_c2.o - ld65 -o OOTW_C2 ootw_c2.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o OOTW_C2 ootw_c2.o -C $(LINKER_SCRIPTS)/apple2_1800.inc ootw_c2.o: ootw_c2.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/ootw_c3/Makefile b/games/ootw/ootw_c3/Makefile index 06a717cc..d60c7e46 100644 --- a/games/ootw/ootw_c3/Makefile +++ b/games/ootw/ootw_c3/Makefile @@ -9,7 +9,7 @@ all: OOTW_C3 #### OOTW_C3: ootw_c3.o - ld65 -o OOTW_C3 ootw_c3.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o OOTW_C3 ootw_c3.o -C $(LINKER_SCRIPTS)/apple2_1800.inc ootw_c3.o: ootw_c3.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/ootw_c4/Makefile b/games/ootw/ootw_c4/Makefile index f5ff6751..8dbe0118 100644 --- a/games/ootw/ootw_c4/Makefile +++ b/games/ootw/ootw_c4/Makefile @@ -9,7 +9,7 @@ all: OOTW_C4 #### OOTW_C4: ootw_c4.o - ld65 -o OOTW_C4 ootw_c4.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o OOTW_C4 ootw_c4.o -C $(LINKER_SCRIPTS)/apple2_1800.inc ootw_c4.o: ootw_c4.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/ootw_c5/Makefile b/games/ootw/ootw_c5/Makefile index a37e2d6d..453c670b 100644 --- a/games/ootw/ootw_c5/Makefile +++ b/games/ootw/ootw_c5/Makefile @@ -9,7 +9,7 @@ all: OOTW_C5 #### OOTW_C5: ootw_c5.o - ld65 -o OOTW_C5 ootw_c5.o -C $(LINKER_SCRIPTS)/apple2_1700.inc + ld65 -o OOTW_C5 ootw_c5.o -C $(LINKER_SCRIPTS)/apple2_1800.inc ootw_c5.o: ootw_c5.s \ $(COMMON)/gr_copy.s \ diff --git a/games/ootw/qboot/Makefile b/games/ootw/qboot/Makefile new file mode 100644 index 00000000..676a218e --- /dev/null +++ b/games/ootw/qboot/Makefile @@ -0,0 +1,58 @@ +include ../../../Makefile.inc + +LINKER_SCRIPTS = ../../../linker_scripts + +all: QBOOT_DISK1 QBOOT_DISK2 QBOOT_DISK3 QLOAD + + +#TITLE: title.o +# ld65 -o TITLE title.o -C $(LINKER_SCRIPTS)/apple2_d00.inc +# +#title.o: title.s qload.s +# ca65 -o title.o title.s -l title.lst + +#### + +QBOOT_DISK1: qboot_sector_d1.o + ld65 -o QBOOT_DISK1 qboot_sector_d1.o -C $(LINKER_SCRIPTS)/apple2_800.inc + +qboot_sector_d1.o: qboot_sector.s qboot_stage2.s + ca65 -o qboot_sector_d1.o -DDISK=1 qboot_sector.s -l qboot_sector_d1.lst + +#### + +QBOOT_DISK2: qboot_sector_d2.o + ld65 -o QBOOT_DISK2 qboot_sector_d2.o -C $(LINKER_SCRIPTS)/apple2_800.inc + +qboot_sector_d2.o: qboot_sector.s qboot_stage2.s + ca65 -o qboot_sector_d2.o -DDISK=2 qboot_sector.s -l qboot_sector_d2.lst + +#### + +QBOOT_DISK3: qboot_sector_d3.o + ld65 -o QBOOT_DISK3 qboot_sector_d3.o -C $(LINKER_SCRIPTS)/apple2_800.inc + +qboot_sector_d3.o: qboot_sector.s qboot_stage2.s + ca65 -o qboot_sector_d3.o -DDISK=3 qboot_sector.s -l qboot_sector_d3.lst + + + +#### + +QLOAD: qload.o + ld65 -o QLOAD qload.o -C $(LINKER_SCRIPTS)/apple2_1600.inc + +qload.o: qload.s qboot.inc common_defines.inc + ca65 -o qload.o qload.s -l qload.lst + + +##### + +clean: + rm -f *~ *.o *.lst QBOOT_DISK1 QBOOT_DISK2 QBOOT_DISK3 QBOOT QLOAD TITLE + +##### + +distclean: + make clean + diff --git a/games/ootw/qboot/README b/games/ootw/qboot/README new file mode 100644 index 00000000..40bea2e8 --- /dev/null +++ b/games/ootw/qboot/README @@ -0,0 +1,18 @@ +Originally the way things worked: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ Regular DOS33 filesystem ++ Title BLOADed by HELLO to $D00, was big enough that + qkumba's code ended up at $1400-$1700 ++ Various levels loaded at $1700 ++ We never return to title, so have to reboot at end + +Qboot method +~~~~~~~~~~~~ ++ qboot_sector, 1 sector loads at $800 ++ Loads second stage (two sectors of disk routines) to + $1400/$1500 ++ Loads QLOAD (main disk routine) and TITLE to $1600 ++ disk routines fit in $1600/$1700 ++ All programs load at $1800 + + diff --git a/games/ootw/qboot/common_defines.inc b/games/ootw/qboot/common_defines.inc new file mode 100644 index 00000000..b704f60a --- /dev/null +++ b/games/ootw/qboot/common_defines.inc @@ -0,0 +1,30 @@ +;============================= +; common stuff + +;================================ +; Loader definitions + +LOAD_TITLE = 0 +LOAD_MIST = 1 +LOAD_MECHE = 2 +LOAD_SELENA = 3 +LOAD_OCTAGON = 4 +LOAD_VIEWER = 5 +LOAD_STONEY = 6 +LOAD_CHANNEL = 7 +LOAD_CABIN = 8 +LOAD_DENTIST = 9 +LOAD_ARBOR = 10 +LOAD_NIBEL = 11 +LOAD_SHIP = 12 +LOAD_GENERATOR = 13 +LOAD_DNI = 14 +LOAD_SUB = 15 +LOAD_TEXT_TITLE = 16 +LOAD_SAVE1 = 17 +LOAD_SAVE2 = 18 +LOAD_SAVE3 = 19 +LOAD_SAVE4 = 20 +LOAD_SAVE5 = 21 +LOAD_FIRST_SECTOR= 22 + diff --git a/games/ootw/qboot/qboot.inc b/games/ootw/qboot/qboot.inc new file mode 100644 index 00000000..83f4f0a3 --- /dev/null +++ b/games/ootw/qboot/qboot.inc @@ -0,0 +1,8 @@ +seek = $1526 +driveon = $159D +driveoff = $1522 +load_new = $15AB +load_address=$15C4 +load_track=load_address+1 +load_sector=load_address+2 +load_length=load_address+3 diff --git a/games/ootw/qboot/qboot_sector.s b/games/ootw/qboot/qboot_sector.s new file mode 100644 index 00000000..81772862 --- /dev/null +++ b/games/ootw/qboot/qboot_sector.s @@ -0,0 +1,243 @@ +; fast seek/multi-read +; copyright (c) Peter Ferrie 2015-16 + + ; Paramaters for loading QLOAD + ; want to load it at $1600 + + sectors = 14 ; user-defined + firsttrk = 1 ; user-defined, first track to read + firstsec = 0 ; user-defined, first sector to read + address = $16 ; user-defined + entry = $1600 ; 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 (memory destination) +; 3D = 1 (sector) + + ; 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 $14/$15 + + ; it's full of qkumba magic so be careful + + lsr ; check sector number + tay + adc #$13 ; start at sector $14 + + sta $27 ; set destination for read + cmp #$16 + ; OLD 10 11 12 (1 1 1) + ; OLD be, bf, c0 (1011 1011 1100) + ; OLD 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 + +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 +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 + +.byte DISK + +end_code: + +.res $8fe-* + +; traditionally, entry point to jump to at end of loading +; $1400 in this case +;*=$8fe + .byte $14, $00 + + +.include "qboot_stage2.s" diff --git a/games/ootw/qboot/qboot_stage2.s b/games/ootw/qboot/qboot_stage2.s new file mode 100644 index 00000000..5c3bd61a --- /dev/null +++ b/games/ootw/qboot/qboot_stage2.s @@ -0,0 +1,363 @@ +; 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 + +.org $1400 + +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 + diff --git a/games/ootw/qboot/qload.s b/games/ootw/qboot/qload.s new file mode 100644 index 00000000..12d271da --- /dev/null +++ b/games/ootw/qboot/qload.s @@ -0,0 +1,231 @@ +; Loader for ootw + +.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 + + jsr title + +; lda #LOAD_TEXT_TITLE ; load title +; sta WHICH_LOAD + + lda $8A5 ; from boot sector + sta CURRENT_DISK ; current disk number + +; jsr load_file + +; jsr $800 + +; lda #LOAD_TITLE ; load title +; sta WHICH_LOAD + +main_game_loop: + jsr load_file + +; lda WHICH_LOAD +; bne not_title + +;start_title: +; jsr $4000 +; jmp main_game_loop + +;not_title: + jsr $1800 + jmp main_game_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: + + ; 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 + + +which_disk_array: + .byte 1,1,1,1 ; INTRO,C1,C2,C3 + .byte 1,1,2,2 ; C4,C5,C6,C7 + .byte 2,2,2,3 ; C8,C9,C10,C11 + .byte 3,3,3,3 ; C12,C13,C14,C15 + .byte 3 ; ENDING + .byte $f,$f ; TITLE,FIRST_SECTOR + +load_address_array: + .byte $18,$18,$18,$18 ; INTRO,C1,C2,C3 + .byte $18,$18,$18,$18 ; C4,C5,C6,C7 + .byte $18,$18,$18,$18 ; C8,C9,C10,C11 + .byte $18,$18,$18,$18 ; C12,C13,C14,C15 + .byte $18 ; ENDING + .byte $18,$0C ; TITLE,FIRST_SECTOR + +track_array: + .byte 2,11,17,25 ; INTRO,C1,C2,C3 + .byte 26,30,99,99 ; C4,C5,C6,C7 + .byte 99,99,99,99 ; C8,C9,C10,C11 + .byte 99,99,99,99 ; C12,C13,C14,C15 + .byte 99 ; ENDING + .byte 99,99 ; TITLE,FIRST_SECTOR + + +sector_array: + .byte 0, 0, 0, 0 ; INTRO,C1,C2,C3 + .byte 0, 0, 0, 0 ; C4,C5,C6,C7 + .byte 0, 0, 0, 0 ; C8,C9,C10,C11 + .byte 0, 0, 0, 0 ; C12,C13,C14,C15 + .byte 0 ; ENDING + .byte 0, 0 ; TITLE,FIRST_SECTOR + + +length_array: + .byte 137, 95,125, 14 ; INTRO,C1,C2,C3 + .byte 62, 41, 0, 0 ; C4,C5,C6,C7 + .byte 0, 0, 0, 0 ; C8,C9,C10,C11 + .byte 0, 0, 0, 0 ; C12,C13,C14,C15 + .byte 0 ; ENDING + .byte 1, 1 ; TITLE,FIRST_SECTOR + + + + ; include common libraries... + + +.include "title.s" + +qload_end: + +.assert (>qload_end - >qload_start) < $e , error, "loader too big" diff --git a/games/ootw/qboot/title.s b/games/ootw/qboot/title.s new file mode 100644 index 00000000..7c9f99b4 --- /dev/null +++ b/games/ootw/qboot/title.s @@ -0,0 +1,309 @@ +; Title Screen / Menu for OOTW + +;.include "../zp.inc" +;.include "../hardware.inc" + +title: + lda #0 + sta MENU_BASE ; start at level0 by default + sta MENU_HIGHLIGHT + + bit TEXT + bit PAGE0 + jsr HOME + + lda #title_text + sta OUTH + jsr move_and_print_list + +title_loop: + clc + lda MENU_BASE + adc MENU_HIGHLIGHT + sta WHICH_LOAD + + + jsr draw_menu + +wait_for_keypress: + lda KEYPRESS + bpl wait_for_keypress + bit KEYRESET + + ; $15/$A = right/down + cmp #$15+$80 + beq down_pressed + cmp #$A+$80 + beq down_pressed + + ; 8/B = left/up + cmp #$8+$80 + beq up_pressed + cmp #$B+$80 + beq up_pressed + + ; Return = 13 + cmp #13+$80 + beq all_done + + ; unknown, ignore + jmp title_loop + +down_pressed: + lda MENU_HIGHLIGHT + cmp #2 + beq down_offset + inc MENU_HIGHLIGHT + bne title_loop ; branch always + +down_offset: + lda MENU_BASE + cmp #16-2 + beq title_loop ; don't increment if 16 + inc MENU_BASE + bne title_loop ; branch always + +up_pressed: + lda MENU_HIGHLIGHT + beq up_offset ; don't decrement if 0 + dec MENU_HIGHLIGHT + jmp title_loop +up_offset: + lda MENU_BASE + beq title_loop ; don't decrement if 0 + dec MENU_BASE + jmp title_loop + +all_done: + +print_help_and_go: + jsr HOME + + lda #directions_text + sta OUTH + jsr move_and_print_list + +ready_to_load: + jmp $1400 ; LOADER starts here + +.include "../text_print.s" +.include "../gr_offsets.s" + +draw_menu: + lda #menu_items + sta OUTH + + clc + ldy #0 +get_right_offset: + cpy MENU_BASE + beq get_right_offset_done + + lda OUTL + adc #23 + sta OUTL + lda OUTH + adc #0 + sta OUTH + + iny + + jmp get_right_offset + +get_right_offset_done: + + ldy #1 + lda #19 + sta (OUTL),Y + + jsr disable_highlight + lda MENU_HIGHLIGHT + bne no_highlight_line1 + jsr enable_highlight +no_highlight_line1: + + jsr move_and_print + + ldy #1 + lda #20 + sta (OUTL),Y + + jsr disable_highlight + lda MENU_HIGHLIGHT + cmp #1 + bne no_highlight_line2 + jsr enable_highlight +no_highlight_line2: + + jsr move_and_print + + ldy #1 + lda #21 + sta (OUTL),Y + + jsr disable_highlight + lda MENU_HIGHLIGHT + cmp #2 + bne no_highlight_line3 + jsr enable_highlight +no_highlight_line3: + + jsr move_and_print + + jsr disable_highlight + +draw_scrollbar: + lda #' '+$80 + sta $550+29 + sta $550+30 + ldx WHICH_LOAD + beq draw_line1 +draw_top: + lda #'/'+$80 + sta $550+29 ; line 18 + lda #'\'+$80 + sta $550+30 +draw_line1: + lda #'I'+$80 + cpx #5 + bcs draw_line1_I ; bge +draw_line1_X: + clc + adc #'X'-'I' +draw_line1_I: + sta $5d0+29 ; line 19 + sta $5d0+30 + +draw_line2: + lda #'I'+$80 + cpx #5 + bcc draw_line2_I ; blt + cpx #10 + bcs draw_line2_I ; bge + +draw_line2_X: + clc + adc #'X'-'I' +draw_line2_I: + sta $650+29 ; line 20 + sta $650+30 + +draw_line3: + lda #'I'+$80 + cpx #10 + bcc draw_line3_I ; blt + +draw_line3_X: + clc + adc #'X'-'I' +draw_line3_I: + sta $6d0+29 ; line 21 + sta $6d0+30 +draw_bottom: + lda #' '+$80 + sta $750+29 ; line 22 + sta $750+30 ; line 22 + cpx #16 + beq done_draw_bottom + lda #'\'+$80 + sta $750+29 ; line 22 + lda #'/'+$80 + sta $750+30 +done_draw_bottom: + + rts + + + +enable_highlight: + lda #$29 ; and + sta ps_smc1 + lda #$3f + sta ps_smc1+1 + rts + +disable_highlight: + lda #$49 + sta ps_smc1 ; eor + lda #$80 + sta ps_smc1+1 + rts + + + + + + + +;.byte 0,18," /\",0 +;.byte 0,19," CHECKPOINT 1 (IH8S) XX",0 +;.byte 0,20," CHECKPOINT 2 (RAGE) II",0 +;.byte 0,21," CHECKPOINT 3 (VENT) II",0 +;.byte 0,22," \/",0 + + +title_text: +.byte 1, 0, "//II II--\ II--\ II II-- ]][[ ]][[",0 +.byte 0, 1,"//_II II__/ II__/ II II- ][ ][",0 +.byte 0, 2,"II II II II II__ II__ ]][[ ]][[",0 +.byte 0, 3,"II II II _",0 +.byte 3, 4, "II II // //=I\ II==\ II II \\",0 +.byte 3, 5, "II II // // II II==/ II II //",0 +.byte 3, 6, "II II//\\// \===I/ II \\ II== II//",0 +.byte 0, 8,"OOTW PROOF-OF-CONCEPT V3.0 (19 APR 2021)",0 +.byte 0, 9,"CODE: DEATER DISK,LZ4: QKUMBA",0 +.byte 12,10, ",",0 +.byte 0,11,"ORIGINAL BY ERIC CHAHI",0 +.byte 0,12,"INSPIRED BY PAUL NICHOLAS PICO-8 VERSION",0 +.byte 12,13, "______",0 +.byte 10,14, "A \/\/\/ PRODUCTION",0 +.byte 12,16, "APPLE ][ FOREVER",0 + +.byte 1,23, "USE ARROWS TO SELECT, RETURN TO START",0 +.byte 255 + + + + +menu_items: ; 23 wide +.byte 8,0,"INTRO MOVIE ",0 +.byte 8,0,"CHECKPOINT 1 (IH8S)",0 ; LDKD +.byte 8,0,"CHECKPOINT 2 (RAGE)",0 ; HTDC +.byte 8,0,"CHECKPOINT 3 (VENT)",0 ; CLLD +.byte 8,0,"CHECKPOINT 4 (RCHG)",0 ; LBKG +.byte 8,0,"CHECKPOINT 5 (CAVE)",0 ; XDDJ +.byte 8,0,"CHECKPOINT 6 (CEIL)",0 ; FXLC +.byte 8,0,"CHECKPOINT 7 (RUNC)",0 ; KRFK +.byte 8,0,"CHECKPOINT 8 (ROLL)",0 ; KLFB +.byte 8,0,"CHECKPOINT 9 (SWIM)",0 ; TTCT +.byte 8,0,"CHECKPOINT 10 (GRND)",0 ; HRTB +.byte 8,0,"CHECKPOINT 11 (ABVE)",0 ; BRTD +.byte 8,0,"CHECKPOINT 12 (THRW)",0 ; TFBB +.byte 8,0,"CHECKPOINT 13 (ARMS)",0 ; TXHF +.byte 8,0,"CHECKPOINT 14 (TANK)",0 ; CKJL +.byte 8,0,"CHECKPOINT 15 (ANKD)",0 ; LFCK +.byte 8,0,"ENDING ",0 + + +directions_text: +.byte 8, 0,"LOADING (BE PATIENT...)",0 +.byte 0, 5,"CONTROLS:",0 +.byte 3, 6, "A OR <- : MOVE LEFT",0 +.byte 3, 7, "D OR -> : MOVE RIGHT",0 +.byte 3, 8, "W OR UP : JUMP",0 +.byte 3, 9, "S OR DOWN : CROUCH / PICKUP",0 +.byte 3,10, "SPACEBAR : KICK / SHOOT",0 +.byte 3,11, "L : CHARGE GUN",0 +.byte 3,12, "ESC : QUITS",0 +.byte 255 + +;.align $100 + +;.include "qload.s" + diff --git a/games/ootw/zp.inc b/games/ootw/zp.inc index ded53213..3d58f0c0 100644 --- a/games/ootw/zp.inc +++ b/games/ootw/zp.inc @@ -4,15 +4,18 @@ NIBCOUNT = $00 ;; LZ4 addresses +;LZ4_SRC = $00 +;LZ4_DST = $02 +;LZ4_END = $04 -LZ4_SRC = $00 -LZ4_DST = $02 -LZ4_END = $04 + +CURRENT_DISK = $03 +WHICH_SLOT = $04 WHICH_LOAD = $05 -COUNT = $06 +;COUNT = $06 MENU_BASE = $06 MENU_HIGHLIGHT = $07 -DELTA = $08 +;DELTA = $08 ;; Zero page monitor routines addresses diff --git a/linker_scripts/apple2_1600.inc b/linker_scripts/apple2_1600.inc new file mode 100644 index 00000000..7b71f4c4 --- /dev/null +++ b/linker_scripts/apple2_1600.inc @@ -0,0 +1,12 @@ +MEMORY { + ZP: start = $00, size = $1A, type = rw; + RAM: start = $1600, size = $AC00, file = %O; +} + +SEGMENTS { +CODE: load = RAM, type = ro, align=$100; +RODATA: load = RAM, type = ro; +DATA: load = RAM, type = rw; +BSS: load = RAM, type = bss, define = yes; +ZEROPAGE: load = ZP, type = zp; +}