From bb240f3c8840f08301af42474cfd1483e7afaa60 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 21 Sep 2024 01:34:05 -0400 Subject: [PATCH] peasant: initial work toward loading from hard disk image --- games/peasant/Makefile | 72 +++++- games/peasant/dts_block.c | 18 ++ games/peasant/hardware.inc | 15 +- games/peasant/proboothd.s | 142 +++++++++++ games/peasant/qload.inc | 73 +++--- games/peasant/qload.s | 260 ++------------------ games/peasant/qload_floppy.s | 198 +++++++++++++++ games/peasant/qload_hd.s | 203 +++++++++++++++ games/peasant/{ => qload_old}/drive2.s | 0 games/peasant/qload_old/qload.s | 325 +++++++++++++++++++++++++ games/peasant/vid_logo/vid_logo.s | 7 +- games/peasant/zp.inc | 18 +- 12 files changed, 1038 insertions(+), 293 deletions(-) create mode 100644 games/peasant/dts_block.c create mode 100644 games/peasant/proboothd.s create mode 100644 games/peasant/qload_floppy.s create mode 100644 games/peasant/qload_hd.s rename games/peasant/{ => qload_old}/drive2.s (100%) create mode 100644 games/peasant/qload_old/qload.s diff --git a/games/peasant/Makefile b/games/peasant/Makefile index c2aecd36..7ee48551 100644 --- a/games/peasant/Makefile +++ b/games/peasant/Makefile @@ -6,12 +6,12 @@ TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft LINKER_SCRIPTS = ../../linker_scripts EMPTY_DISK = ../../empty_disk ZX02 = ~/research/6502_compression/zx02.git/build/zx02 +PRODOSDIR = ../../utils/prodos-utils/ PRODOS = ../../utils/prodos-utils/prodos PRODOS_RAW = ../../utils/prodos-utils/prodos_raw -all: peasant_disk1.dsk peasant_disk2.dsk peasant_disk3.dsk -# peasant.2mg +all: peasant_disk1.dsk peasant_disk2.dsk peasant_disk3.dsk peasant.2mg submit: peasant_disk1.dsk peasant_disk2.dsk peasant_disk3.dsk zip peasant.zip peasant_disk1.dsk peasant_disk2.dsk peasant_disk3.dsk @@ -63,8 +63,67 @@ peasant_disk3.dsk: ./trogdor/TROGDOR ./ending/ENDING \ +peasant.2mg: dts_block PROBOOTHD QLOAD_HD \ + ./vid_logo/VID_LOGO ./title/TITLE ./intro/INTRO \ + ./music/MUSIC ./copy/COPY_CHECK ./inventory/INVENTORY \ + SAVE1 SAVE2 SAVE3 PARSE_INPUT.ZX02 ./game_over/GAME_OVER + $(PRODOSDIR)/mkprodosfs peasant.2mg -n PeasantsQ -b 2800 -2 + $(PRODOS_RAW) peasant.2mg 0 PROBOOTHD 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 1 0` QLOAD_HD 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 0 11` SAVE1 0 1 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 0 12` SAVE2 0 1 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 0 13` SAVE3 0 1 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 3 0` ./music/MUSIC 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 4 0` ./vid_logo/VID_LOGO 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 6 0` ./title/TITLE 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 9 0` ./intro/INTRO 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 13 0` PARSE_INPUT.ZX02 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 14 0` ./inventory/INVENTORY 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 15 0` ./game_over/GAME_OVER 0 0 + $(PRODOS_RAW) peasant.2mg `./dts_block 0 30 0` ./copy/COPY_CHECK 0 0 + ### +dts_block: dts_block.o + $(CC) $(LFLAGS) -o dts_block dts_block.o + +dts_block.o: dts_block.c + $(CC) $(CFLAGS) -c dts_block.c + +### + +PROBOOTHD: proboothd.o + ld65 -o PROBOOTHD proboothd.o -C $(LINKER_SCRIPTS)/apple2_800.inc + +proboothd.o: proboothd.s + ca65 -o proboothd.o proboothd.s -l proboothd.lst + +### + +QLOAD_HD: qload_hd.o + ld65 -o QLOAD_HD qload_hd.o -C $(LINKER_SCRIPTS)/apple2_b00.inc + +qload_hd.o: qload_hd.s qboot.inc \ + zx02_optim.s \ + hgr_font.s \ + draw_box.s \ + hgr_rectangle.s \ + hgr_1x28_sprite_mask.s \ + hgr_partial_save.s \ + hgr_input.s \ + hgr_tables.s \ + hgr_text_box.s \ + text/word_list.s \ + clear_bottom.s \ + hgr_hgr2.s \ + hgr_copy.s \ + gr_offsets.s \ + qkumba_popwr.s \ + random16.s + ca65 -o qload_hd.o qload.s -DFLOPPY=0 -l qload_hd.lst + +#### + QBOOT: qboot_sector.o ld65 -o QBOOT qboot_sector.o -C $(LINKER_SCRIPTS)/apple2_800.inc @@ -93,9 +152,8 @@ qload.o: qload.s qboot.inc \ hgr_copy.s \ gr_offsets.s \ qkumba_popwr.s \ - random16.s \ - drive2.s - ca65 -o qload.o qload.s -l qload.lst + random16.s + ca65 -o qload.o qload.s -DFLOPPY=1 -l qload.lst ### @@ -145,10 +203,8 @@ qboot.inc: generate_common QBOOT qload.inc: generate_common QLOAD ./generate_common -a 0xb00 -s load_file qload.lst > qload.inc ./generate_common -a 0xb00 -s sector_write qload.lst >> qload.inc - ./generate_common -a 0xb00 -s check_floppy_in_drive2 qload.lst >> qload.inc +# ./generate_common -a 0xb00 -s check_floppy_in_drive2 qload.lst >> qload.inc ./generate_common -a 0xb00 -s requested_sector qload.lst >> qload.inc -# ./generate_common -a 0xb00 -s decompress_lzsa2_fast qload.lst >> qload.inc -# ./generate_common -a 0xb00 -s getsrc_smc qload.lst >> qload.inc ./generate_common -a 0xb00 -s zx02_full_decomp qload.lst >> qload.inc ./generate_common -a 0xb00 -s zx_src_l qload.lst >> qload.inc ./generate_common -a 0xb00 -s zx_src_h qload.lst >> qload.inc diff --git a/games/peasant/dts_block.c b/games/peasant/dts_block.c new file mode 100644 index 00000000..8e274e9d --- /dev/null +++ b/games/peasant/dts_block.c @@ -0,0 +1,18 @@ +#include +#include + +int main(int argc, char **argv) { + + int disk,track,sector; + int block; + + disk=atoi(argv[1]); + track=atoi(argv[2]); + sector=atoi(argv[3]); + + block=((disk+1)<<9)|(track<<3)|(sector>>1); + + printf("%d",block); + + return 0; +} diff --git a/games/peasant/hardware.inc b/games/peasant/hardware.inc index 97d6d13b..9f18f23d 100644 --- a/games/peasant/hardware.inc +++ b/games/peasant/hardware.inc @@ -6,8 +6,14 @@ KEYRESET = $C010 ; SOFT SWITCHES CLR80COL = $C000 ; PAGE1/PAGE1 normal SET80COL = $C001 ; PAGE1/PAGE2 switches PAGE1 in Aux instead +READMAINMEM = $C002 ; (w) to read from main mem ($0200..$BFFF) +READAUXMEM = $C003 ; (w) to read from aux mem ($0200..$BFFF) +WRITEMAINMEM = $C004 ; (w) to write to main mem ($0200..$BFFF) +WRITEAUXMEM = $C005 ; (w)to write to aux mem ($0200..$BFFF) +SETSTDZP = $C008 ; (w) to use main mem stack/zp ($00FF-$01FF) EIGHTYCOLOFF = $C00C EIGHTYCOLON = $C00D +PRIMARYCHARSET = $C00E ; (w) to disable mousetext TBCOLOR = $C022 ; IIgs text foreground / background colors NEWVIDEO = $C029 ; IIgs graphics modes SPEAKER = $C030 @@ -51,6 +57,7 @@ HPLOT0 = $F457 ; plot at (Y,X), (A) ;CLRTOP = $F836 ; clear only top of low-res screen ;SETCOL = $F864 ; COLOR=A ;ROM_TEXT2COPY = $F962 ; iigs +INIT_TEXT = $FB2F ; set lo-res/page1 and call text TEXT = $FB36 ; qboot ;TABV = $FB5B ; VTAB to A ROM_MACHINEID = $FBB3 ; iigs @@ -60,12 +67,12 @@ ROM_MACHINEID = $FBB3 ; iigs HOME = $FC58 ; Clear the text screen ; qboot ;WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us ;CROUT1 = $FD8B -;SETINV = $FE80 ; INVERSE -;SETNORM = $FE84 ; NORMAL +SETINV = $FE80 ; INVERSE +SETNORM = $FE84 ; NORMAL COUT = $FDED ; output A to screen ; qboot COUT1 = $FDF0 ; output A to screen ; qload - - +SETKBD = $FE89 ; set input to keyboard +SETVID = $FE93 ; set output to video screen diff --git a/games/peasant/proboothd.s b/games/peasant/proboothd.s new file mode 100644 index 00000000..88d3a839 --- /dev/null +++ b/games/peasant/proboothd.s @@ -0,0 +1,142 @@ +;license:BSD-3-Clause + +; vaguely based on the minimal open/read binary file in ProDOS filesystem +; from 4cade +; +;copyright (c) Peter Ferrie 2016-2019 + +.include "hardware.inc" +.include "zp.inc" + + ; we want to load 10 blocks from 1024 to $0b00 +QLOAD_BLOCK = ((0+1)*512)+(1*8)+(0) ; D0 T1 S0 +QLOAD_ADDR = $0b00 +QLOAD_SIZE = 10 + + +; start of boot sector, presumably how many sectors to load +; 512 bytes on prodos/hard-disk(???) + +.byte 1 + +proboot_start: + txa + pha ; save slot for later + + ; init. is all this necessary? + ; originally "4cade.init.machine.a" + + cld ; clear direction flag + sta $C082 ; read rom / no write (language card) + sta PRIMARYCHARSET ; turn off mouse text + sta EIGHTYCOLOFF ; disable 80-col mode +h sta CLR80COL + sta READMAINMEM ; make sure not using aux mem + sta WRITEMAINMEM + sta SETSTDZP + + ; more init + ; originally "4cade.init.screen.a" + + ; initializes and clears screen using ROM routines + + jsr INIT_TEXT ; setup text mode + jsr HOME ; clear screen + jsr SETNORM ; normal text + jsr SETKBD ; keyboard input + jsr SETVID ; video output + + ; set up disk stuff? + + pla ; restore slot + sta UNIT ; save for later (also has meaning) + + tax + + ; 4cade calls a print-title routine here that exits with Y=0 + + + ldy #0 + + ; from IIgs smartport firmware manual + + ; prodos entry point is $CX00+($CXFF) + ; so if slot 7, $C700 + value in $C7ff (say, A) so $C70A + ; smartport entry point is $CX00+(CXFF)+3 + + +setup_loop: + txa + lsr + lsr + lsr + lsr + and #7 + ora #$c0 + sta slot_smc+2 + sta entry_smc+2 ; set up smartport/prodos entry point + +slot_smc: + lda $cfff + sta entry_smc+1 ; set up rest of smartport/prodos entry + + +;opendir: + + + ldy #>QLOAD_BLOCK ; high + ldx #QLOAD_ADDR ; high + sta ADRHI + lda #0 + sta ADRLO + + lda #QLOAD_SIZE + + jsr seekread + + +done: + jmp QLOAD_ADDR + + + ;================================ + ; seek + read blocks + ;================================ + ; this calls the smartport PRODOS entrypoint + ; command=1 READBLOCK + ; I can't find this documented anywhere + ; but the paramaters are stored in the zero page + ;================================ + ; Y:X = block number to load (???) + ; A = num blocks +seekread: + sta COUNT + + stx BLOKLO + sty BLOKHI + +seekread_loop: + lda #1 ; READBLOCK + sta COMMAND + lda ADRHI + pha +entry_smc: + jsr $d1d1 + pla + sta ADRHI + + inc ADRHI ; twice, as 512 byte chunks + inc ADRHI + + inc BLOKLO ; increment block pointer + bne no_blokloflo + inc BLOKHI +no_blokloflo: + + + dec COUNT + bne seekread_loop + + rts diff --git a/games/peasant/qload.inc b/games/peasant/qload.inc index 224466bb..3eb0f862 100644 --- a/games/peasant/qload.inc +++ b/games/peasant/qload.inc @@ -1,40 +1,39 @@ -load_file =$0b2a -sector_write =$0c85 -check_floppy_in_drive2 =$0de6 +load_file =$0b16 +sector_write =$0c61 requested_sector =$0d17 -zx02_full_decomp =$0e35 -zx_src_l =$0e37 -zx_src_h =$0e3b -hgr2 =$17bc -hgr_make_tables =$1530 -hgr_put_string =$0ec3 -restore_bg_1x28 =$13fb -hgr_draw_sprite_1x28 =$1394 -input_buffer =$1508 -hgr_text_box =$15a6 -hgr_text_box_nosave =$163d -hgr_partial_restore =$147e -clear_bottom =$1791 -hgr_input =$14ae -draw_box =$1245 -disp_put_string =$15e1 -disp_one_line =$15f5 -invert_smc1 =$0f3b -disp_put_string_cursor =$15f1 -hgr_put_char_cursor =$0eef -vgi_simple_rectangle =$12c6 -peasant_text =$1ef0 -save_menu =$186f -load_menu =$1864 -location_names_l =$1b9c -location_names_h =$1bbb -wait_until_keypress =$1ddb -random16 =$1de4 -score_points =$1e69 -print_score =$1e19 -update_score =$1e24 -speaker_beep =$1ed7 -speaker_duration =$1eee -speaker_frequency =$1eef +zx02_full_decomp =$0de6 +zx_src_l =$0de8 +zx_src_h =$0dec +hgr2 =$176d +hgr_make_tables =$14e1 +hgr_put_string =$0e74 +restore_bg_1x28 =$13ac +hgr_draw_sprite_1x28 =$1345 +input_buffer =$14b9 +hgr_text_box =$1557 +hgr_text_box_nosave =$15ee +hgr_partial_restore =$142f +clear_bottom =$1742 +hgr_input =$145f +draw_box =$11f6 +disp_put_string =$1592 +disp_one_line =$15a6 +invert_smc1 =$0eec +disp_put_string_cursor =$15a2 +hgr_put_char_cursor =$0ea0 +vgi_simple_rectangle =$1277 +peasant_text =$1ea1 +save_menu =$1820 +load_menu =$1815 +location_names_l =$1b4d +location_names_h =$1b6c +wait_until_keypress =$1d8c +random16 =$1d95 +score_points =$1e1a +print_score =$1dca +update_score =$1dd5 +speaker_beep =$1e88 +speaker_duration =$1e9f +speaker_frequency =$1ea0 hposn_high = $BA00 hposn_low = $BB00 diff --git a/games/peasant/qload.s b/games/peasant/qload.s index 5cdb0da6..6a831df0 100644 --- a/games/peasant/qload.s +++ b/games/peasant/qload.s @@ -1,251 +1,30 @@ ; Loader for Peasant's Quest +; Based on QLOAD by qkumba which loads raw tracks off of disks + +; This particular version only supports using a single disk drive +; (I have other versions that can look for disks across two drives) + +; it also loads the QLOAD paramaters from disk separately + + .include "zp.inc" -;LOAD_TEXT_TITLE = 16 ; ??? -LOAD_FIRST_SECTOR = 22 ; ??? - -tmpsec = $3C -;WHICH_LOAD=$80 -;WHICH_SLOT=$DA -;CURRENT_DISK=$DC -;OUTL = $FE -;OUTH = $FF - .include "hardware.inc" ;.include "common_defines.inc" + .include "qboot.inc" qload_start: - - - ; 0..$10? - ; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 - ; AA AA AA AA AA 07 05 40 20 01 01 01 00 0A 00 AA AA - ; 00 C6 00 00 ff 07 05 40 20 00 01 01 00 0a 00 00 AA - - - ; $300 - ; 80+OK, 40 bad, 60 bad, 70 good, 68=bad - - ; 0 1 2 3 4 5 6 7 8 9 A B C D - ; $360 = DC E0 00 E4 E8 EC F0 F4 00 00 00 00 = bad - ; $360 = dc e0 00 e4 e8 ec f0 f4 f8 fc 00 00 00 01 00 00 02 03 = good - ; boot = ff ff 00 00 ff ff 00 00 ff ff 00 00 00 01 00 00 02 03 - - ; preshift table is $300 - $369 - - ; $36C to $3D5 is used as decode table by disk II drive - -.if 0 - ldy WHICH_SLOT ; temporarily save - lda #$AA - ldx #$2 -zp_clear_loop: - sta $00,X - inx - bne zp_clear_loop - sty WHICH_SLOT +.if FLOPPY=1 +.include "qload_floppy.s" +.else +.include "qload_hd.s" .endif - ; init the write code - lda WHICH_SLOT - jsr popwr_init - - ; first time entry - ; start by loading text title - - lda #LOAD_VID_LOGO ; load intro - sta WHICH_LOAD - - lda #1 - sta CURRENT_DISK ; current disk number - sta DRIVE1_DISK ; it's in drive1 - sta CURRENT_DRIVE ; and currently using drive 1 - - lda #$FF - sta DRIVE1_TRACK - sta DRIVE2_TRACK - - jsr load_file ; actually load intro - - jsr $6000 ; run intro - - lda #LOAD_TITLE ; next load title - sta WHICH_LOAD - -main_game_loop: - jsr load_file - - jsr $6000 ; all entry points currently $6000 - jmp main_game_loop - - - ;==================================== - ; loads file specified by WHICH_LOAD - ;==================================== -load_file: - ldx WHICH_LOAD - - lda which_disk_array,X ; get disk# for file to load - cmp CURRENT_DISK ; if not currently using - bne change_disk ; need to 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 - ;=================================================== - ;=================================================== - ; WHICH_LOAD is still in X? - -change_disk: - - ; see if disk we want is in drive1 -check_drive1: - lda which_disk_array,X - cmp DRIVE1_DISK - bne check_drive2 - - jsr switch_drive1 ; switch to drive1 - jmp update_disk - -check_drive2: - cmp DRIVE2_DISK - bne disk_not_found - - jsr switch_drive2 ; switch to drive2 - jmp update_disk - -disk_not_found: - - ; check if disk in drive2 - ; carry clear if not - -; jsr check_floppy_in_drive2 - -; bcc nothing_in_drive2 - - ; a disk is in drive2, try to use it - -; bcs verify_disk - - -nothing_in_drive2: - - ; switch back to drive1 -; jsr switch_drive1 - - - ;============================== - ; print "insert disk" message - - lda #insert_disk_string - sta OUTH - - ldx WHICH_LOAD - lda which_disk_array,X - clc - adc #48 - - ; patch error string to say correct disk to insert - - ldy #27 - sta (OUTL),Y - - jsr hgr_text_box - -fnf_keypress: - lda KEYPRESS - bpl fnf_keypress - bit KEYRESET - - ;============================================== - ; actually verify proper disk is there - ; read T0:S0 and verify proper disk -verify_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 $BC00 - ; offset 5B - ; disk1 = $12 - ; disk2 = $32 ('2') - ; disk3 = $33 ('3') - - lda $BC5B - cmp #$12 - 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 ; bra - -is_disk2: - lda #2 - bne disk_compare ; bra - -is_disk3: - lda #3 - -disk_compare: - cmp which_disk_array,X - bne change_disk ; disk mismatch - - ;============================================== - ; all good, retry original load -update_disk: - - ldx WHICH_LOAD - lda which_disk_array,X - sta CURRENT_DISK - - ldx CURRENT_DRIVE - sta DRIVE1_DISK-1,X ; indexed from 1 - - jmp load_file - -; offset for disk number is 27 -insert_disk_string: -.byte 0,43,24, 0,240,74 -.byte 10,41 -.byte "PLEASE INSERT DISK 1",13 -.byte " THEN PRESS RETURN",0 - +.align $100 which_disk_array: .byte 1,1,1,1 ; VID_LOGO, TITLE, INTRO. COPY_CHECK @@ -292,13 +71,10 @@ length_array: .byte 1,1,1 ; SAVE1, SAVE2, SAVE3 .byte 1 ; disk detect + + .include "qkumba_popwr.s" - -.include "drive2.s" - .include "zx02_optim.s" -;.include "decompress_fast_v2.s" - .include "hgr_font.s" .include "draw_box.s" .include "hgr_rectangle.s" @@ -323,3 +99,7 @@ qload_end: ;.assert (>qload_end - >qload_start) < $e , error, "loader too big" .assert (>qload_end - >qload_start) < $15 , error, "loader too big" + + + + diff --git a/games/peasant/qload_floppy.s b/games/peasant/qload_floppy.s new file mode 100644 index 00000000..0518aeaa --- /dev/null +++ b/games/peasant/qload_floppy.s @@ -0,0 +1,198 @@ +qload_floppy: + + ; init the write code + lda WHICH_SLOT + jsr popwr_init + + ; first time entry + ; start by loading text title + + lda #LOAD_VID_LOGO ; load intro + sta WHICH_LOAD + + lda #1 + sta CURRENT_DISK ; current disk number + +main_game_loop: + + jsr load_file ; actually load intro + +entry_smc: + jsr $6000 ; run intro + +; lda #LOAD_TITLE ; next load title +; sta WHICH_LOAD + + +; jsr load_file + +; jsr $6000 ; all entry points currently $6000 + jmp main_game_loop + + + ;==================================== + ; loads file specified by WHICH_LOAD + ;==================================== +load_file: + ldx WHICH_LOAD + + lda which_disk_array,X ; get disk# for file to load + cmp CURRENT_DISK ; if not currently using + bne change_disk ; need to 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 + ;=================================================== + ;=================================================== + ; WHICH_LOAD is still in X? + +change_disk: + + ; see if disk we want is in drive1 +check_drive1: + lda which_disk_array,X + cmp DRIVE1_DISK + bne disk_not_found + +; jsr switch_drive1 ; switch to drive1 +; jmp update_disk + +;check_drive2: +; cmp DRIVE2_DISK +; bne disk_not_found + +; jsr switch_drive2 ; switch to drive2 +; jmp update_disk + +disk_not_found: + + ; check if disk in drive2 + ; carry clear if not + +; jsr check_floppy_in_drive2 + +; bcc nothing_in_drive2 + + ; a disk is in drive2, try to use it + +; bcs verify_disk + + +nothing_in_drive2: + + ; switch back to drive1 +; jsr switch_drive1 + + + ;============================== + ; print "insert disk" message + + lda #insert_disk_string + sta OUTH + + ldx WHICH_LOAD + lda which_disk_array,X + clc + adc #48 + + ; patch error string to say correct disk to insert + + ldy #27 + sta (OUTL),Y + + jsr hgr_text_box + +fnf_keypress: + lda KEYPRESS + bpl fnf_keypress + bit KEYRESET + + ;============================================== + ; actually verify proper disk is there + ; read T0:S0 and verify proper disk +verify_disk: + lda WHICH_LOAD + pha + +LOAD_FIRST_SECTOR = 22 + + 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 $BC00 + ; offset 5B + ; disk1 = $12 + ; disk2 = $32 ('2') + ; disk3 = $33 ('3') + + lda $BC5B + cmp #$12 + 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 ; bra + +is_disk2: + lda #2 + bne disk_compare ; bra + +is_disk3: + lda #3 + +disk_compare: + cmp which_disk_array,X + bne change_disk ; disk mismatch + + ;============================================== + ; all good, retry original load +update_disk: + + ldx WHICH_LOAD + lda which_disk_array,X + sta CURRENT_DISK + + ldx CURRENT_DRIVE + sta DRIVE1_DISK-1,X ; indexed from 1 + + jmp load_file + +; offset for disk number is 27 +insert_disk_string: +.byte 0,43,24, 0,240,74 +.byte 10,41 +.byte "PLEASE INSERT DISK 1",13 +.byte " THEN PRESS RETURN",0 + + diff --git a/games/peasant/qload_hd.s b/games/peasant/qload_hd.s new file mode 100644 index 00000000..a12e7470 --- /dev/null +++ b/games/peasant/qload_hd.s @@ -0,0 +1,203 @@ +qload_hd: + + ; set up prodos entry + + lda UNIT ; + ldy #0 + +setup_loop: + lsr + lsr + lsr + lsr + and #7 + ora #$c0 + sta slot_smc+2 + sta entry_smc+2 ; set up smartport/prodos entry point + +slot_smc: + lda $cfff + sta entry_smc+1 ; set up rest of smartport/prodos entry + + + ; init the write code if needed + ; ??? + + lda #0 + sta CURRENT_DISK + + lda #LOAD_VID_LOGO + sta WHICH_LOAD + +main_game_loop: + jsr load_file + +entry_point_smc: + jsr $6000 ; most entry points currently $6000 + + ; CHECK LEVEL_OVER + ; if high bit set, jump to change_disk + +; lda LEVEL_OVER +; bmi change_disk + + jmp main_game_loop + + + ;==================================== + ; loads file specified by WHICH_LOAD + ;==================================== +load_file: + ldx WHICH_LOAD + + lda load_address_array,X + sta ADRHI + sta entry_point_smc+2 + + lda CURRENT_DISK + sta BLOKHI + inc BLOKHI ; off by one + lda track_array,X ; track + asl + asl + asl + rol BLOKHI + sta BLOKLO + lda sector_array,X ; sector + lsr + clc + adc BLOKLO + sta BLOKLO + + + lda length_array,X + clc + adc #1 + lsr ; important! blocks=sectors/2 + ; need to round up if it was odd + ; careful: this could over-write if not careful + sta COUNT + + jsr seekread + + rts ; todo: tail call + + ;=================================================== + ;=================================================== + ; change disk + ;=================================================== + ;=================================================== + ; LEVEL_OVER bottom 4 bits hold which exit + +change_disk: + +; lda LEVEL_OVER +; and #$f +; sta LEVEL_OVER +; tax + + ; set up locations +; lda DISK_EXIT_DISK,X +; sta CURRENT_DISK + +; lda DISK_EXIT_LOAD,X +; sta WHICH_LOAD +; lda DISK_EXIT_LEVEL,X +; sta LOCATION +; lda DISK_EXIT_DIRECTION,X +; sta DIRECTION + +; lda DISK_EXIT_DNI_H,X +; sta NUMBER_HIGH +; lda DISK_EXIT_DNI_L,X +; sta NUMBER_LOW + + + ; see if disk we want is in drive + + + ;========================== + ; load QLOAD table + ; check if disk matches +;verify_disk: + +; jsr load_qload_offsets + + + + ;============================================== + ; all good, continue +update_disk: + + jmp main_game_loop + + + +.if 0 +load_qload_offsets: + lda #$12 + sta ADRHI + + lda CURRENT_DISK + sta BLOKHI + inc BLOKHI ; off by one + lda #0 ; track + asl + asl + asl + rol BLOKHI + sta BLOKLO + lda #$2 ; sector + lsr + clc + adc BLOKLO + sta BLOKLO + +; lda #$0 +; sta load_track + +; lda #$02 ; track 0 sector 2 +; sta load_sector + + lda #$1 + sta COUNT + + jmp seekread + +.endif + + ;================================ + ; seek + read blocks + ;================================ + ; this calls the smartport PRODOS entrypoint + ; command=1 READBLOCK + ; I can't find this documented anywhere + ; but the paramaters are stored in the zero page + ;================================ + ; BLOKHI:BLOKLO = block number to load (???) + ; COUNT = num blocks +seekread: + +seekread_loop: + lda #1 ; READBLOCK + sta COMMAND + lda ADRHI + pha +entry_smc: + jsr $d1d1 + pla + sta ADRHI + + inc ADRHI ; twice, as 512 byte chunks + inc ADRHI + + inc BLOKLO ; increment block pointer + bne no_blokloflo + inc BLOKHI +no_blokloflo: + + + dec COUNT + bne seekread_loop + + rts diff --git a/games/peasant/drive2.s b/games/peasant/qload_old/drive2.s similarity index 100% rename from games/peasant/drive2.s rename to games/peasant/qload_old/drive2.s diff --git a/games/peasant/qload_old/qload.s b/games/peasant/qload_old/qload.s new file mode 100644 index 00000000..5cdb0da6 --- /dev/null +++ b/games/peasant/qload_old/qload.s @@ -0,0 +1,325 @@ +; Loader for Peasant's Quest + +.include "zp.inc" + +;LOAD_TEXT_TITLE = 16 ; ??? +LOAD_FIRST_SECTOR = 22 ; ??? + +tmpsec = $3C +;WHICH_LOAD=$80 +;WHICH_SLOT=$DA +;CURRENT_DISK=$DC +;OUTL = $FE +;OUTH = $FF + +.include "hardware.inc" + +;.include "common_defines.inc" +.include "qboot.inc" + +qload_start: + + + + ; 0..$10? + ; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 + ; AA AA AA AA AA 07 05 40 20 01 01 01 00 0A 00 AA AA + ; 00 C6 00 00 ff 07 05 40 20 00 01 01 00 0a 00 00 AA + + + ; $300 + ; 80+OK, 40 bad, 60 bad, 70 good, 68=bad + + ; 0 1 2 3 4 5 6 7 8 9 A B C D + ; $360 = DC E0 00 E4 E8 EC F0 F4 00 00 00 00 = bad + ; $360 = dc e0 00 e4 e8 ec f0 f4 f8 fc 00 00 00 01 00 00 02 03 = good + ; boot = ff ff 00 00 ff ff 00 00 ff ff 00 00 00 01 00 00 02 03 + + ; preshift table is $300 - $369 + + ; $36C to $3D5 is used as decode table by disk II drive + +.if 0 + ldy WHICH_SLOT ; temporarily save + lda #$AA + ldx #$2 +zp_clear_loop: + sta $00,X + inx + bne zp_clear_loop + sty WHICH_SLOT +.endif + + ; init the write code + lda WHICH_SLOT + jsr popwr_init + + ; first time entry + ; start by loading text title + + lda #LOAD_VID_LOGO ; load intro + sta WHICH_LOAD + + lda #1 + sta CURRENT_DISK ; current disk number + sta DRIVE1_DISK ; it's in drive1 + sta CURRENT_DRIVE ; and currently using drive 1 + + lda #$FF + sta DRIVE1_TRACK + sta DRIVE2_TRACK + + jsr load_file ; actually load intro + + jsr $6000 ; run intro + + lda #LOAD_TITLE ; next load title + sta WHICH_LOAD + +main_game_loop: + jsr load_file + + jsr $6000 ; all entry points currently $6000 + jmp main_game_loop + + + ;==================================== + ; loads file specified by WHICH_LOAD + ;==================================== +load_file: + ldx WHICH_LOAD + + lda which_disk_array,X ; get disk# for file to load + cmp CURRENT_DISK ; if not currently using + bne change_disk ; need to 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 + ;=================================================== + ;=================================================== + ; WHICH_LOAD is still in X? + +change_disk: + + ; see if disk we want is in drive1 +check_drive1: + lda which_disk_array,X + cmp DRIVE1_DISK + bne check_drive2 + + jsr switch_drive1 ; switch to drive1 + jmp update_disk + +check_drive2: + cmp DRIVE2_DISK + bne disk_not_found + + jsr switch_drive2 ; switch to drive2 + jmp update_disk + +disk_not_found: + + ; check if disk in drive2 + ; carry clear if not + +; jsr check_floppy_in_drive2 + +; bcc nothing_in_drive2 + + ; a disk is in drive2, try to use it + +; bcs verify_disk + + +nothing_in_drive2: + + ; switch back to drive1 +; jsr switch_drive1 + + + ;============================== + ; print "insert disk" message + + lda #insert_disk_string + sta OUTH + + ldx WHICH_LOAD + lda which_disk_array,X + clc + adc #48 + + ; patch error string to say correct disk to insert + + ldy #27 + sta (OUTL),Y + + jsr hgr_text_box + +fnf_keypress: + lda KEYPRESS + bpl fnf_keypress + bit KEYRESET + + ;============================================== + ; actually verify proper disk is there + ; read T0:S0 and verify proper disk +verify_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 $BC00 + ; offset 5B + ; disk1 = $12 + ; disk2 = $32 ('2') + ; disk3 = $33 ('3') + + lda $BC5B + cmp #$12 + 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 ; bra + +is_disk2: + lda #2 + bne disk_compare ; bra + +is_disk3: + lda #3 + +disk_compare: + cmp which_disk_array,X + bne change_disk ; disk mismatch + + ;============================================== + ; all good, retry original load +update_disk: + + ldx WHICH_LOAD + lda which_disk_array,X + sta CURRENT_DISK + + ldx CURRENT_DRIVE + sta DRIVE1_DISK-1,X ; indexed from 1 + + jmp load_file + +; offset for disk number is 27 +insert_disk_string: +.byte 0,43,24, 0,240,74 +.byte 10,41 +.byte "PLEASE INSERT DISK 1",13 +.byte " THEN PRESS RETURN",0 + + +which_disk_array: + .byte 1,1,1,1 ; VID_LOGO, TITLE, INTRO. COPY_CHECK + .byte 2,2,2,2 ; PEASANT1, PEASANT2, PEASANT3, PEASANT4 + .byte 3,3,1,3 ; TROGDOR, ENDING, MUSIC, CLIFF + .byte 1,1,1,3 ; GAME_OVER, INVENTORY, PARSE_INPUT, INN + .byte 3,3,3 ; INSIDE, ARCHERY, MAP + .byte 1,1,1 ; SAVE1, SAVE2, SAVE3 + .byte $f ; disk detect + +load_address_array: + .byte $60,$60,$60,$60 ; VID_LOGO, TITLE, INTRO, COPY_CHECK + .byte $60,$60,$60,$60 ; PEASANT1, PEASANT2, PEASANT3, PEASANT4 + .byte $60,$60,$D0,$60 ; TROGDOR, ENDING, MUSIC, CLIFF + .byte $60,$D0,$20,$60 ; GAME_OVER, INVENTORY, PARSE_INPUT, INN + .byte $60,$60,$60 ; INSIDE, ARCHERY, MAP + .byte $BC,$BC,$BC ; SAVE1, SAVE2, SAVE3 + .byte $BC ; disk detect + +track_array: + .byte 4, 6, 9,1 ; VID_LOGO, TITLE, INTRO, COPY_CHECK + .byte 15,20,25,30 ; PEASANT1, PEASANT2, PEASANT3, PEASANT4 + .byte 19,24, 3,29 ; TROGDOR, ENDING, MUSIC, CLIFF + .byte 15,14,13,14 ; GAME_OVER, INVENTORY, PARSE_INPUT, INN + .byte 9,6,4 ; INSIDE, ARCHERY, MAP + .byte 0, 0, 0 ; SAVE1, SAVE2, SAVE3 + .byte 0 ; disk detect + +sector_array: + .byte 0, 0, 0, 0 ; VID_LOGO, TITLE, INTRO, COPY_CHECK + .byte 0, 0, 0, 0 ; PEASANT1, PEASANT2, PEASANT3, PEASANT4 + .byte 0, 0, 0, 0 ; TROGDOR, ENDING, MUSIC, CLIFF + .byte 0, 0, 0, 0 ; GAME_OVER, INVENTORY, PARSE_INPUT, INN + .byte 0, 0, 0 ; INSIDE, ARCHERY, MAP + .byte 11,12,13 ; SAVE1, SAVE2, SAVE3 + .byte 0 ; disk detect + +length_array: + .byte 32, 50, 60, 20 ; VID_LOGO, TITLE, INTRO, COPY_CHECK + .byte 80, 88, 88, 80 ; PEASANT1, PEASANT2, PEASANT3, PEASANT4 + .byte 80, 80, 16, 80 ; TROGDOR, ENDING, MUSIC, CLIFF + .byte 16, 16, 16, 80 ; GAME_OVER, INVENTORY, PARSE_INPUT, INN + .byte 80, 64, 16 ; INSIDE, ARCHERY, MAP + .byte 1,1,1 ; SAVE1, SAVE2, SAVE3 + .byte 1 ; disk detect + +.include "qkumba_popwr.s" + +.include "drive2.s" + +.include "zx02_optim.s" +;.include "decompress_fast_v2.s" + +.include "hgr_font.s" +.include "draw_box.s" +.include "hgr_rectangle.s" +.include "hgr_1x28_sprite_mask.s" +.include "hgr_partial_save.s" +.include "hgr_input.s" +.include "hgr_tables.s" +.include "hgr_text_box.s" +.include "clear_bottom.s" +.include "hgr_hgr2.s" ; this one is maybe only needed once? +.include "gr_offsets.s" +.include "loadsave_menu.s" +.include "wait_keypress.s" +.include "random16.s" +.include "score.s" +.include "speaker_beeps.s" + +peasant_text: + .byte 25,2,"Peasant's Quest",0 + +qload_end: + +;.assert (>qload_end - >qload_start) < $e , error, "loader too big" +.assert (>qload_end - >qload_start) < $15 , error, "loader too big" diff --git a/games/peasant/vid_logo/vid_logo.s b/games/peasant/vid_logo/vid_logo.s index b7d227b2..48dc6552 100644 --- a/games/peasant/vid_logo/vid_logo.s +++ b/games/peasant/vid_logo/vid_logo.s @@ -216,7 +216,7 @@ ssi_not_found: mockingboard_notfound: - +.if 0 ;================================== ; check if disk in drive #2 ;================================== @@ -245,7 +245,7 @@ yes_floppy_drive2: no_floppy_drive2: done_drive2_check: - +.endif skip_all_checks: @@ -372,6 +372,9 @@ done_loop: bit KEYRESET + lda #LOAD_TITLE ; next load title + sta WHICH_LOAD + rts ;forever: diff --git a/games/peasant/zp.inc b/games/peasant/zp.inc index 5c0d6b0d..c2ed8810 100644 --- a/games/peasant/zp.inc +++ b/games/peasant/zp.inc @@ -44,8 +44,6 @@ INSTRUMENT1 = $13 INSTRUMENT2 = $14 MADDRL = $15 MADDRH = $16 -LOC4E = $4E -COUNT256 = $4F HGR_BITS = $1C @@ -60,9 +58,25 @@ MASK = $2E MASK_COUNTDOWN = $2F PEASANT_PRIORITY = $30 +; this is the structure for a ProDOS smartport command, at least +; for a read (command=1) + tmpsec = $3c + + COMMAND = $42 ; ProDOS constant + UNIT = $43 ; ProDOS constant + ADRLO = $44 ; ProDOS constant + ADRHI = $45 ; ProDOS constant + BLOKLO = $46 ; ProDOS constant + BLOKHI = $47 ; ProDOS constant + + + SEEDL = $4E SEEDH = $4F +LOC4E = $4E ; electric duet +COUNT256 = $4F + INVENTORY_MASK = $60 INVENTORY_Y = $61