From 4a32b31c4df1cab0bb8ee8c45a3309e6a8afaa8f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 29 Sep 2021 00:17:39 -0400 Subject: [PATCH] peasant: save almost works well it does but there's a weird bug when loading it back --- games/peasant/Makefile | 7 +- games/peasant/generate_common.c | 5 +- games/peasant/loadsave_menu.s | 91 ++++-- games/peasant/parse_input.s | 16 +- games/peasant/qkumba_popwr.s | 495 ++++++++++++++++---------------- games/peasant/qload.inc | 4 + games/peasant/save3.s | 2 +- 7 files changed, 347 insertions(+), 273 deletions(-) diff --git a/games/peasant/Makefile b/games/peasant/Makefile index aa9b5154..b44dbf29 100644 --- a/games/peasant/Makefile +++ b/games/peasant/Makefile @@ -69,7 +69,8 @@ qload.o: qload.s qboot.inc \ hgr_text_box.s \ clear_bottom.s \ hgr_hgr2.s \ - gr_offsets.s + gr_offsets.s \ + qkumba_popwr.s ca65 -o qload.o qload.s -l qload.lst ### @@ -92,6 +93,8 @@ generate_common.o: generate_common.c 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 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 hgr2 qload.lst >> qload.inc @@ -116,6 +119,8 @@ qload.inc: generate_common QLOAD ./generate_common -a 0xb00 -s vgi_simple_rectangle qload.lst >> qload.inc echo "hposn_high = \$$BA00" >> qload.inc echo "hposn_low = \$$BB00" >> qload.inc + echo "driveoff = \$$A22" >> qload.inc + echo "driveon = \$$A9D" >> qload.inc #### diff --git a/games/peasant/generate_common.c b/games/peasant/generate_common.c index 712e3b39..aa8e095c 100644 --- a/games/peasant/generate_common.c +++ b/games/peasant/generate_common.c @@ -20,7 +20,10 @@ static void find_address(char *symbol_name, int routine_offset) { while(1) { result=fgets(string,BUFSIZ,fff); - if (result==NULL) break; + if (result==NULL) { + fprintf(stderr,"Error: %s not found!\n",symbol_name); + exit(-1); + } result=strstr(string,temp_name); if (result!=NULL) { diff --git a/games/peasant/loadsave_menu.s b/games/peasant/loadsave_menu.s index 12fc3347..a0e25024 100644 --- a/games/peasant/loadsave_menu.s +++ b/games/peasant/loadsave_menu.s @@ -2,10 +2,33 @@ ; o/~ It's the Loading Screen o/~ + ; FIXME: we can share some of the code here a bit more + ;===================== ; load_menu ;===================== load_menu: + lda #0 + sta loadsave_smc1+1 + sta loadsave_smc2+1 + + jmp common_menu + + ;===================== + ; save_menu + ;===================== +save_menu: + lda #1 + sta loadsave_smc1+1 + sta loadsave_smc2+1 + + jmp common_menu + + + ;===================== + ; common_menu + ;===================== +common_menu: ;============================ ; first read all three saves @@ -148,7 +171,7 @@ save_memset: ;==================== ; draw text box -draw_loadstore_box: +draw_loadsave_box: lda #0 sta BOX_X1H @@ -168,13 +191,26 @@ draw_loadstore_box: ;=================== ; draw main text -draw_loadstore_text: +draw_loadsave_text: - ; TODO: use SAVE message if we're saving instead +loadsave_smc1: + lda #0 + bne do_save_message +do_load_message: + ; load message lda #load_message + jmp loadsave_ready + +do_save_message: + ; save message + lda #save_message + +loadsave_ready: sta OUTH jsr disp_put_string @@ -297,8 +333,16 @@ ls_return: rts do_actual_load: + +loadsave_smc2: + lda #0 + bne go_for_save + +go_for_load: jmp load_game +go_for_save: + jmp save_game ls_done_moving: @@ -457,17 +501,22 @@ done_load: save_game: -.if 0 -; lda #save_message -; sta OUTH + ; print are you sure message -; jsr confirm_action -; bcs done_save + jsr confirm_action - pha + bcs done_save + + ; put which save into A + + lda INVENTORY_Y + + pha ; save slot for later on stack + +; clc +; adc #LOAD_SAVE1 +; sta WHICH_LOAD ; get proper WHICH_LOAD value ;======================== @@ -478,22 +527,24 @@ actually_save: ; first load something from ; disk1/track0 to seek the head there - lda WHICH_LOAD + lda WHICH_LOAD ; save this value as we + ; destroy it for load pha - lda #LOAD_SAVE1 + lda #LOAD_SAVE1 ; use SAVE1 as it's on track 0 sta WHICH_LOAD jsr load_file pla + sta WHICH_LOAD - ; copy save data to $d00 + ; copy save data to $BC00 ldx #0 copy_loop: lda WHICH_LOAD,X - sta $d00,X + sta $BC00,X inx cpx #(END_OF_SAVE-WHICH_LOAD+1) bne copy_loop @@ -512,9 +563,9 @@ copy_loop: jsr driveoff done_save: + lda #$FF ; reload level as we scrawled on $2000 + sta GAME_OVER - jsr change_location ; restore graphics -.endif rts @@ -571,6 +622,9 @@ are_you_sure: ;========================= update_save_info: + lda WHICH_LOAD + pha + ldx #0 update_save_info_loop: clc @@ -595,6 +649,9 @@ update_save_info_loop: cpx #3 bne update_save_info_loop + pla + sta WHICH_LOAD + rts diff --git a/games/peasant/parse_input.s b/games/peasant/parse_input.s index b1933635..14c109e6 100644 --- a/games/peasant/parse_input.s +++ b/games/peasant/parse_input.s @@ -62,15 +62,19 @@ parse_show: cmp #'S' bne parse_version - bit LORES - bit PAGE1 +; bit LORES +; bit PAGE1 - jsr wait_until_keypress +; jsr wait_until_keypress - bit PAGE2 - bit HIRES +; bit PAGE2 +; bit HIRES - jmp done_parse_message +; jmp done_parse_message + + jsr save_menu + + jmp restore_parse_message parse_version: cmp #'V' diff --git a/games/peasant/qkumba_popwr.s b/games/peasant/qkumba_popwr.s index 4c44d22b..c8469e1c 100644 --- a/games/peasant/qkumba_popwr.s +++ b/games/peasant/qkumba_popwr.s @@ -1,247 +1,248 @@ -; popwr -- code provided by qkumba - - -frombuff=$d00 ; sector data to write - -; note these must be contiguous -encbuf=$e00 ; nibble buffer must be page alined -bit2tbl=$f00 - -readnib = $1001 - - -readd5aa: - -try_again: - jsr readnib -try_for_d5: - cmp #$d5 - bne try_again - jsr readnib - cmp #$aa - bne try_for_d5 - - jsr readnib - rts - - ;================================ - ; set up the self-modifying code - ; to point to the proper slot - ;================================ - ; slot number is in high nibble of A -popwr_init: - and #$70 ; the slot number is in the top here - sta slotpatchw1+1 ; self modify the code - sta slotpatchw2+1 - sta slotpatchw3+1 - sta slotpatchw4+1 - - rts - - ;================================ - ; write a sector - ;================================ - -sector_write: - - ; convert the input to nibbles - - ldy #2 ; why start at 2? -aa: - ldx #$aa -b1: - dey -frombuff_smc: - lda frombuff, y - lsr - rol bit2tbl-$aa, x - lsr - rol bit2tbl-$aa, x - sta encbuf, y - lda bit2tbl-$aa, x - and #$3f - sta bit2tbl-$aa, x - inx - bne b1 - tya - bne aa - - jmp cmpsecwr - -.align $100 - - ; look for the proper sector to write - -cmpsecwr: -b2: - jsr readd5aa ; look for dd55aa marker - cmp #$96 - bne b2 - - ldy #3 ; try getting the sector number -b3: - jsr readnib - rol - sta tmpsec - jsr readnib - and tmpsec ; and with prev nibble? - dey - bne b3 - - -requested_sector: - cmp #$d1 - - bne cmpsecwr ; retry if not what we want? - - ;skip tail #$DE #$AA #$EB some #$FFs ... - - ldy #$24 -b4: - dey - bpl b4 - - - ; c0e0 slot 6 ph0 off - ; c0e1 slot 6 ph0 on - ; c0e2 slot 6 ph1 off - ; c0e3 slot 6 ph1 on - ; c0e4 slot 6 ph2 off - ; c0e5 slot 6 ph2 on - ; c0e6 slot 6 ph3 off - ; c0e7 slot 6 ph3 on - ; c0e8 slot 6 motor off - ; c0e9 slot 6 motor on - ; c0ea slot 6 drive 1 - ; c0eb slot 6 drive 2 - ; c0ec slot 6 q6 off \ Q6 Q7 - ; c0ed slot 6 q6 on |-- state machine 0 0 READ - ; c0ee slot 6 q7 off | 0 1 WRITE - ; c0ef slot 6 q7 on / 1 0 SENSE WRITE PROTECT - ; 1 1 WRITE LOAD - - ; write sector data - -slotpatchw1: - ldx #$d1 ; cycle num smc Q6 Q7 - lda $c08d, x ; prime drive 1 X - lda $c08e, x ; required by Unidisk 1 0 ; senese wp? - tya - sta $c08f, x ; 1 1 ; write load - ora $c08c, x ; 0 1 ; write - - ; 40 cycles - - ldy #4 ; 2 cycles - cmp $ea ; nop ; 3 cycles - cmp ($ea,x) ; nop ; 6 cycles -b5: - jsr writenib1 ; (29 cycles) - - ; +6 cycles - dey ; 2 cycles - bne b5 ; 3/2nt - - ; 36 cycles - ; +10 cycles - ldy #(prolog_e-prolog) - ; 2 cycles - cmp $ea ; nop ; 3 cycles -b6: - lda prolog-1, y ; 4 cycles - jsr writenib3 ; (17 cycles) - - ; 32 cycles if branch taken - ; +6 cycles - dey ; 2 cycles - bne b6 ; 3/2nt - - ; 36 cycles on first pass - ; +10 cycles - tya ; 2 cycles - ldy #$56 ; 2 cycles -b7: - eor bit2tbl-1, y ; 5 cycles - tax ; 2 cycles - lda xlattbl, x ; 4 cycles -slotpatchw2: - ldx #$d1 ; slot number smc ; 2 cycles - sta $c08d, x ; wp sense ; 5 cycles - lda $c08c, x ; read ; 4 cycles - - ; 32 cycles if branch taken - - lda bit2tbl-1, y ; 5 cycles - dey ; 2 cycles - bne b7 ; 3/2nt - - ; 32 cycles - ; +9 cycles - clc ; 2 cycles -b88: - eor encbuf, y ; 4 cycles -b8: - tax ; 2 cycles - lda xlattbl, x ; 4 cycles -slotpatchw3: - ldx #$d1 ; slot number smc ; 2 cycles - sta $c08d, x ; wp sense ; 5 cycles - lda $c08c, x ; read ; 4 cycles - bcs f1 ; 3/2nt - - ; 32 cycles if branch taken - - lda encbuf, y ; 4 cycles - iny ; 2 cycles - bne b88 ; 3/2nt - - ; 32 cycles - ; +10 cycles - sec ; 2 cycles - bcs b8 ; 3 cycles - - ; 32 cycles - ; +3 cycles -f1: - ldy #(epilog_e-epilog) - ; 2 cycles - cmp ($ea,x) ; nop ; 6 cycles -b9: - lda epilog-1, y ; 4 cycles - jsr writenib3 ; (17 cycles) - - ; 32 cycles if branch taken - ; +6 cycles - dey ; 2 cycles - bne b9 ;3/2nt - - lda $c08e, x ; read/wp - lda $c08c, x ; read - lda $c088, x ; motor off - rts ; 6 cycles - -writenib1: - cmp ($ea,x) ; nop ; 6 cycles - cmp ($ea,x) ; nop ; 6 cycles -writenib3: -slotpatchw4: - ldx #$d1 ; slot number ; 2 cycles -writenib4: - sta $c08d, x ; wp sense? ; 5 cycles - ora $c08c, x ; read ; 4 cycles - rts ; 6 cycles - -prolog: .byte $ad, $aa, $d5 -prolog_e: -epilog: .byte $ff, $eb, $aa, $de -epilog_e: - -xlattbl: -.byte $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 -.byte $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 -.byte $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC -.byte $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 -.byte $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE -.byte $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC -.byte $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 -.byte $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF +; popwr -- code provided by qkumba + + +frombuff=$bc00 ; sector data to write + +; note these must be contiguous +encbuf=$2000 ; nibble buffer must be page alined +bit2tbl=$2100 + +readnib = $901 + + +readd5aa: + +try_again: + jsr readnib +try_for_d5: + cmp #$d5 + bne try_again + jsr readnib + cmp #$aa + bne try_for_d5 + + jsr readnib + rts + + ;================================ + ; set up the self-modifying code + ; to point to the proper slot + ;================================ + ; slot number is in high nibble of A +popwr_init: + and #$70 ; the slot number is in the top here + sta slotpatchw1+1 ; self modify the code + sta slotpatchw2+1 + sta slotpatchw3+1 + sta slotpatchw4+1 + + rts + + ;================================ + ; write a sector + ;================================ + +sector_write: + + ; convert the input to nibbles + + ldy #2 ; why start at 2? +aa: + ldx #$aa +b1: + dey +frombuff_smc: + lda frombuff, y + lsr + rol bit2tbl-$aa, x + lsr + rol bit2tbl-$aa, x + sta encbuf, y + lda bit2tbl-$aa, x + and #$3f + sta bit2tbl-$aa, x + inx + bne b1 + tya + bne aa + + jmp cmpsecwr + +.align $100 ; why do we align? to ensure timing? + + ; look for the proper sector to write + +cmpsecwr: +b2: + jsr readd5aa ; look for dd55aa marker + cmp #$96 + bne b2 + + ldy #3 ; try getting the sector number +b3: + jsr readnib + rol + sta tmpsec + jsr readnib + and tmpsec ; and with prev nibble? + dey ; sector value is two bytes + bne b3 ; 1 D7 1 D5 1 D3 1 D1 + ; 1 D6 1 D4 1 D2 1 D0 + ; so you shift left and AND to get value + +requested_sector: + cmp #$d1 + + bne cmpsecwr ; retry if not what we want? + + ;skip tail #$DE #$AA #$EB some #$FFs ... + + ldy #$24 +b4: + dey + bpl b4 + + + ; c0e0 slot 6 ph0 off + ; c0e1 slot 6 ph0 on + ; c0e2 slot 6 ph1 off + ; c0e3 slot 6 ph1 on + ; c0e4 slot 6 ph2 off + ; c0e5 slot 6 ph2 on + ; c0e6 slot 6 ph3 off + ; c0e7 slot 6 ph3 on + ; c0e8 slot 6 motor off + ; c0e9 slot 6 motor on + ; c0ea slot 6 drive 1 + ; c0eb slot 6 drive 2 + ; c0ec slot 6 q6 off \ Q6 Q7 + ; c0ed slot 6 q6 on |-- state machine 0 0 READ + ; c0ee slot 6 q7 off | 0 1 WRITE + ; c0ef slot 6 q7 on / 1 0 SENSE WRITE PROTECT + ; 1 1 WRITE LOAD + + ; write sector data + +slotpatchw1: + ldx #$d1 ; cycle num smc Q6 Q7 + lda $c08d, x ; prime drive 1 X + lda $c08e, x ; required by Unidisk 1 0 ; senese wp? + tya + sta $c08f, x ; 1 1 ; write load + ora $c08c, x ; 0 1 ; write + + ; 40 cycles + + ldy #4 ; 2 cycles + cmp $ea ; nop ; 3 cycles + cmp ($ea,x) ; nop ; 6 cycles +b5: + jsr writenib1 ; (29 cycles) + + ; +6 cycles + dey ; 2 cycles + bne b5 ; 3/2nt + + ; 36 cycles + ; +10 cycles + ldy #(prolog_e-prolog) + ; 2 cycles + cmp $ea ; nop ; 3 cycles +b6: + lda prolog-1, y ; 4 cycles + jsr writenib3 ; (17 cycles) + + ; 32 cycles if branch taken + ; +6 cycles + dey ; 2 cycles + bne b6 ; 3/2nt + + ; 36 cycles on first pass + ; +10 cycles + tya ; 2 cycles + ldy #$56 ; 2 cycles +b7: + eor bit2tbl-1, y ; 5 cycles + tax ; 2 cycles + lda xlattbl, x ; 4 cycles +slotpatchw2: + ldx #$d1 ; slot number smc ; 2 cycles + sta $c08d, x ; wp sense ; 5 cycles + lda $c08c, x ; read ; 4 cycles + + ; 32 cycles if branch taken + + lda bit2tbl-1, y ; 5 cycles + dey ; 2 cycles + bne b7 ; 3/2nt + + ; 32 cycles + ; +9 cycles + clc ; 2 cycles +b88: + eor encbuf, y ; 4 cycles +b8: + tax ; 2 cycles + lda xlattbl, x ; 4 cycles +slotpatchw3: + ldx #$d1 ; slot number smc ; 2 cycles + sta $c08d, x ; wp sense ; 5 cycles + lda $c08c, x ; read ; 4 cycles + bcs f1 ; 3/2nt + + ; 32 cycles if branch taken + + lda encbuf, y ; 4 cycles + iny ; 2 cycles + bne b88 ; 3/2nt + + ; 32 cycles + ; +10 cycles + sec ; 2 cycles + bcs b8 ; 3 cycles + + ; 32 cycles + ; +3 cycles +f1: + ldy #(epilog_e-epilog) + ; 2 cycles + cmp ($ea,x) ; nop ; 6 cycles +b9: + lda epilog-1, y ; 4 cycles + jsr writenib3 ; (17 cycles) + + ; 32 cycles if branch taken + ; +6 cycles + dey ; 2 cycles + bne b9 ;3/2nt + + lda $c08e, x ; read/wp + lda $c08c, x ; read + lda $c088, x ; motor off + rts ; 6 cycles + +writenib1: + cmp ($ea,x) ; nop ; 6 cycles + cmp ($ea,x) ; nop ; 6 cycles +writenib3: +slotpatchw4: + ldx #$d1 ; slot number ; 2 cycles +writenib4: + sta $c08d, x ; wp sense? ; 5 cycles + ora $c08c, x ; read ; 4 cycles + rts ; 6 cycles + +prolog: .byte $ad, $aa, $d5 +prolog_e: +epilog: .byte $ff, $eb, $aa, $de +epilog_e: + +xlattbl: +.byte $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 +.byte $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 +.byte $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC +.byte $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 +.byte $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE +.byte $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC +.byte $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 +.byte $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF diff --git a/games/peasant/qload.inc b/games/peasant/qload.inc index 0c912544..41350d32 100644 --- a/games/peasant/qload.inc +++ b/games/peasant/qload.inc @@ -1,4 +1,6 @@ load_file =$0b20 +sector_write =$0c63 +requested_sector =$0d17 decompress_lzsa2_fast =$0de6 getsrc_smc =$0edc hgr2 =$16e3 @@ -23,3 +25,5 @@ hgr_put_char_cursor =$0f15 vgi_simple_rectangle =$12ef hposn_high = $BA00 hposn_low = $BB00 +driveoff = $A22 +driveon = $A9D diff --git a/games/peasant/save3.s b/games/peasant/save3.s index 92d4fb4f..1c2302e9 100644 --- a/games/peasant/save3.s +++ b/games/peasant/save3.s @@ -20,7 +20,7 @@ .byte $00 ; KERREK_STATE = $9C .byte $00 ; ARROW_SCORE = $9D .byte $01 ; SCORE_HUNDREDS= $9E -.byte $09 ; SCORE_TENSONES= $9F +.byte $39 ; SCORE_TENSONES= $9F .byte $FF ; INVENTORY_1 = $A0 .byte $FF ; INVENTORY_2 = $A1 .byte $FF ; INVENTORY_3 = $A2