From 0d5a07b9b061677f201722e0c54827a29a487d42 Mon Sep 17 00:00:00 2001 From: 4am Date: Tue, 24 Mar 2020 16:30:14 -0400 Subject: [PATCH] Handle more than 256 games (#140) --- src/4cade.init.a | 24 ++-- src/constants.a | 4 +- src/fx/fx.hgr.common.a | 2 +- src/fx/fx.hgr.precomputed.1bit.a | 2 +- src/fx/fx.hgr.precomputed.2bit.a | 2 +- src/fx/fx.hgr.precomputed.3bit.a | 2 +- src/fx/fx.hgr.radial.a | 8 +- src/fx/fx.hgr.radial.common.a | 4 +- src/fx/fx.hgr.radial3.a | 4 +- src/glue.launch.a | 71 ++++++---- src/glue.prorwts2.lc2.a | 10 +- src/hw.mockingboard.a | 2 +- src/macros.a | 46 ++++++- src/okvs.a | 228 ++++++++++++++++++++----------- src/parse.common.a | 2 +- src/parse.games.a | 2 +- src/parse.prefs.a | 22 +-- src/prodos.impl.lc2.a | 2 +- src/prodos.path.a | 2 +- src/textrank.a | 20 +-- src/ui.animation.a | 2 +- src/ui.attract.dhgr.a | 30 ++-- src/ui.attract.gr.a | 10 +- src/ui.attract.hgr.a | 26 ++-- src/ui.attract.mode.a | 54 +++++--- src/ui.attract.shr.a | 10 +- src/ui.browse.mode.a | 45 +++--- src/ui.credits.a | 25 +--- src/ui.font.lc2.a | 12 +- src/ui.offscreen.a | 8 +- src/ui.overlay.a | 26 ++-- src/ui.search.mode.a | 23 ++-- src/ui.wait.a | 2 +- 33 files changed, 441 insertions(+), 291 deletions(-) diff --git a/src/4cade.init.a b/src/4cade.init.a index 76f319237..ad8d70dc0 100644 --- a/src/4cade.init.a +++ b/src/4cade.init.a @@ -179,7 +179,7 @@ +READ_ROM_NO_WRITE jsr BuildAcceleratorFunction +READ_RAM2_WRITE_RAM2 - +STAY @accelSrc + +ST16 @accelSrc dex - @accelSrc=*+1 @@ -227,7 +227,7 @@ SetCursorPosition jmp $FC22 LoadingPrint - +STAY PTR + +ST16 PTR ldy #0 lda (PTR),y sta @max @@ -347,7 +347,7 @@ CopyDevs lda hddopendir+1 ; save current directory as 'root' ldy hddopendir+3 jsr SwitchToBank1 - +STAY gRootDirectory + +ST16 gRootDirectory jsr LoadFile ; load preferences file into $8000 !word kRootDirectory @@ -357,8 +357,8 @@ CopyDevs !word gGlobalPrefsStore !word - !byte 16 - +LDAY SRC ; (SRC) points to free space after the OKVS data structure we just created - +STAY gGamesListStore ; save pointer to free space for next store + +LD16 SRC ; (SRC) points to free space after the OKVS data structure we just created + +ST16 gGamesListStore ; save pointer to free space for next store jsr LoadFile ; load games list file into $8200 !word kRootDirectory @@ -385,13 +385,14 @@ CopyDevs +LDADDR gGamesListStore jsr okvs_len - sta GameCount - sta SAVE + +LD16 WCOUNT + +ST16 GameCount + +ST16 SAVE jsr pref_get ; see if cheats are enabled by default !word kCheat !word 0 - +STAY PTR ; (PTR) -> cheat pref value as length-prefixed string '1' or '0' + +ST16 PTR ; (PTR) -> cheat pref value as length-prefixed string '1' or '0' ldy #1 lda (PTR),y ; A = #$B1 or #$B0 and #1 ; A = #$01 or #$00 @@ -408,18 +409,21 @@ CopyDevs pha @inner lda SAVE - cmp @kPowersOfTen,y - bcc @digitDone + sec sbc @kPowersOfTen,y sta SAVE lda SAVE+1 sbc #0 + bcc @digitDone sta SAVE+1 pla adc #0 pha jmp @inner @digitDone + lda SAVE + adc @kPowersOfTen,y + sta SAVE pla ora #$30 sta VisibleGameCount,y diff --git a/src/constants.a b/src/constants.a index 3c48a8e1d..8bf1ff1b3 100644 --- a/src/constants.a +++ b/src/constants.a @@ -72,10 +72,13 @@ PTR = $02 ; word SRC = $04 ; word DEST = $06 ; word SAVE = $08 ; word +WINDEX = $0A ; word +WCOUNT = $0C ; word HTAB = $24 ; byte VTAB = $25 ; byte RNDSEED = $4E ; word ; textrank +BestMatchIndex = $E5 ; word tmpx = $E7 ; byte remainder = $E8 ; word num1 = $EA ; word @@ -91,7 +94,6 @@ gamelength= $F9 ; byte firstletter= $FA ; byte MatchCount = $FB ; byte BestMatchScore = $FC ; byte -BestMatchIndex = $FD ; byte ; $FE ; used by ParseGamesList ; $FF ; used by ParseGamesList diff --git a/src/fx/fx.hgr.common.a b/src/fx/fx.hgr.common.a index 9b6dc11cc..c2c78a06b 100644 --- a/src/fx/fx.hgr.common.a +++ b/src/fx/fx.hgr.common.a @@ -100,7 +100,7 @@ HGRStaggerToWhite SetCopyMask ; in: A/Y points to 8-byte array of bit masks used by HGRBlockCopyWithMask - +STAY CopyMaskAddr + +ST16 CopyMaskAddr rts HGRBlockCopyWithMask diff --git a/src/fx/fx.hgr.precomputed.1bit.a b/src/fx/fx.hgr.precomputed.1bit.a index 7c824a396..ab2f39734 100644 --- a/src/fx/fx.hgr.precomputed.1bit.a +++ b/src/fx/fx.hgr.precomputed.1bit.a @@ -137,7 +137,7 @@ hgr1himirror = $BF40 ; $C0 bytes +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS copymasks, mirror_copymasks +LDADDR .coords - +STAY input + +ST16 input jmp InputLoop Exit1Bit rts InputLoop diff --git a/src/fx/fx.hgr.precomputed.2bit.a b/src/fx/fx.hgr.precomputed.2bit.a index b1a057316..1fd852b7c 100644 --- a/src/fx/fx.hgr.precomputed.2bit.a +++ b/src/fx/fx.hgr.precomputed.2bit.a @@ -124,7 +124,7 @@ hgr1himirror = $BF40 ; $C0 bytes +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS_2BIT copymasks, mirror_copymasks +LDADDR .coords - +STAY input + +ST16 input jmp InputLoop Exit2Bit rts InputLoop diff --git a/src/fx/fx.hgr.precomputed.3bit.a b/src/fx/fx.hgr.precomputed.3bit.a index cb140b3ec..47528d835 100644 --- a/src/fx/fx.hgr.precomputed.3bit.a +++ b/src/fx/fx.hgr.precomputed.3bit.a @@ -130,7 +130,7 @@ hgrhi3c = $BE80 ; $80 bytes +BUILD_EXTRA_COLS +BUILD_SPARSE_BITMASKS_3BIT +LDADDR .coords - +STAY input + +ST16 input jmp InputLoop Exit3Bit rts InputLoop diff --git a/src/fx/fx.hgr.radial.a b/src/fx/fx.hgr.radial.a index 590ba80d1..929903b16 100644 --- a/src/fx/fx.hgr.radial.a +++ b/src/fx/fx.hgr.radial.a @@ -13,7 +13,7 @@ +BUILD_SPARSE_BITMASKS copymasks, mirror_copymasks +LDADDR EndCoordinates-2 - +STAY input + +ST16 input LoopBL ; bottom-left quadrant (opposite row, original column, reverse input order) ldy #0 lda (input),y @@ -29,7 +29,7 @@ LoopBL ; bottom-left quadrant (opposite row, origi DoneBL +LDADDR Coordinates - +STAY input + +ST16 input LoopTL ; top-left quadrant ldy #0 lda (input),y @@ -45,7 +45,7 @@ LoopTL ; top-left quadrant DoneTL +LDADDR EndCoordinates-2 - +STAY input + +ST16 input LoopTR ; top-right quadrant (same row, opposite column, reverse input order) ldy #0 lda (input),y @@ -63,7 +63,7 @@ LoopTR ; top-right quadrant (same row, opposite co DoneTR +LDADDR Coordinates - +STAY input + +ST16 input LoopBR ; bottom-right quadrant (opposite row, opposite column, original input order) ldy #0 lda (input),y diff --git a/src/fx/fx.hgr.radial.common.a b/src/fx/fx.hgr.radial.common.a index 3e8087032..2ce1c0161 100644 --- a/src/fx/fx.hgr.radial.common.a +++ b/src/fx/fx.hgr.radial.common.a @@ -3,9 +3,9 @@ +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS copymasks, mirror_copymasks +LDADDR Coordinates - +STAY input + +ST16 input +LDADDR EndCoordinates-2 - +STAY reverse_input + +ST16 reverse_input jmp Loop Exit rts Loop ldy #0 diff --git a/src/fx/fx.hgr.radial3.a b/src/fx/fx.hgr.radial3.a index 8bda0f3ef..dabaa57e9 100644 --- a/src/fx/fx.hgr.radial3.a +++ b/src/fx/fx.hgr.radial3.a @@ -12,9 +12,9 @@ +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS copymasks, mirror_copymasks +LDADDR Coordinates - +STAY input + +ST16 input +LDADDR EndCoordinates-2 - +STAY reverse_input + +ST16 reverse_input jmp Loop Exit rts Loop ldy #0 diff --git a/src/glue.launch.a b/src/glue.launch.a index 25604e7c5..e0347f29e 100644 --- a/src/glue.launch.a +++ b/src/glue.launch.a @@ -12,28 +12,49 @@ ; - Launch ; ; Public variables: -; - gGameToLaunch - 0-based index into gGamesListStore +; - gGameToLaunch - 0-based index into gGamesListStore (word) ; +gGameToLaunch + !word $FF,$FF + +AnyGameSelected +; in: none +; out: A/Y = gGameToLaunch (word) +; C clear if gGameToLaunch is not #$FFFF +; C set if gGameToLaunch is #$FFFF +; X preserved + +LD16 gGameToLaunch + +CMP16 $FFFF + beq + + clc + rts ++ sec + rts + GetGameToLaunch -; in: gGameToLaunch = index into gGamesListStore -; out: A/Y points to game filename -gGameToLaunch=*+1 - ldx #$FF ; SMC +; in: gGameToLaunch = index into gGamesListStore (word) or #$FFFF if no game selected +; out: C clear if a game is selected, and +; A/Y points to game filename +; C set if no game is selected + jsr AnyGameSelected + bcs @exit + +ST16 WINDEX +LDADDR gGamesListStore - jmp okvs_nth + jsr okvs_nth + clc +@exit rts FindGame ; in: A/Y points to game filename ; out: C clear if game exists in gGamesListStore, and -; X = game index, or #$FF if the game doesn't really exist but -; we want to return a successful result anyway -; C set if game does not exist, and -; X clobbered (this can happen because slideshows list games -; that require a joystick, but the games list parser filters out -; joystick-only games if the machine doesn't have a joystick) -; A,Y always clobbered - +STAY @key +; $WINDEX = game index, or #$FFFF if the game doesn't really +; exist but we want to return a successful result anyway +; C set if game does not exist (this can happen because slideshows +; list games that require a joystick, but the games list parser +; filters them out if the machine doesn't have a joystick) +; all registers clobbered + +ST16 @key jsr okvs_find !word gGamesListStore @key !word $FDFD ; SMC @@ -41,8 +62,10 @@ FindGame ; Hack to allow self-running demos that don't correspond to a game ; filename. If the name ends in a '.', accept it unconditionally. ldx #$FF - +LDAY @key - +STAY PARAM + stx WINDEX + stx WINDEX+1 + +LD16 @key + +ST16 PARAM ldy #0 lda (PARAM),y tay @@ -58,10 +81,10 @@ FindGame FindGameInActionSlideshow ; in: A/Y points to game filename ; out: C clear if game exists, and -; X = game index, and +; $WINDEX = game index, and ; A/Y points to game display name + game info bitfield ; C set if game can't be found by any means - +STAY @sskey + +ST16 @sskey jsr FindGame bcc + ; if the game was not found, try getting the value of the current record from @@ -86,14 +109,14 @@ GetGameDisplayName ; out of thin air) ; gValLen possibly clobbered (up to gValLen+MaxInputLength) ; X preserved - +STAY SAVE + +ST16 SAVE jsr okvs_get_current ; get value for this key ; (PTR) -> truncated game display name + info bitfield ldy #0 lda (PTR), y ; A = length of truncated game display name + info bitfield cmp #1 ; 1 means there's no title, just info bitfield (1 byte) beq + - +LDAY PTR + +LD16 PTR rts + ; game display name is truncated, we must expand it iny ; Y = 1 @@ -132,8 +155,8 @@ GetGameDisplayName PlayGame jsr GetGameToLaunch ; A/Y = address of game filename - +STAY SAVE - +STAY @pfile + +ST16 SAVE + +ST16 @pfile jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) @@ -148,7 +171,7 @@ PlayGame lda #kGameDirectoryLen sta gPathname - +LDAY SAVE + +LD16 SAVE jsr AddToPath ; attach the separator @@ -165,7 +188,7 @@ PlayGame ; then attach the game name - +LDAY SAVE + +LD16 SAVE jsr AddToPath ; don't look while I do this diff --git a/src/glue.prorwts2.lc2.a b/src/glue.prorwts2.lc2.a index 3f77737dc..feec9c135 100644 --- a/src/glue.prorwts2.lc2.a +++ b/src/glue.prorwts2.lc2.a @@ -12,7 +12,7 @@ LoadFileInternal LoadFileAuxInternal sta @auxreq+1 ; call with A=1 to load directly into aux memory +LDADDR gPathname - +STAY namlo ; set filename + +ST16 namlo ; set filename jsr traverse ; go to subdirectory, set up filename for read lda #cmdread ; read (instead of write) sta reqcmd @@ -23,8 +23,8 @@ LoadFileAuxInternal sta sizelo ; otherwise query the load address from file metadata sta sizehi ; 0 = query load address jsr hddopendir ; call ProRWTS2 - +LDAY ldrlo2 - +STAY ldrlo + +LD16 ldrlo2 + +ST16 ldrlo + lda #$FF ; read entire file (ProRWTS2 will figure out exact size) sta sizehi @auxreq @@ -35,7 +35,7 @@ JumpOpen LoadDHRFileInternal +LDADDR gPathname - +STAY namlo ; set filename + +ST16 namlo ; set filename jsr traverse ; go to subdirectory, set up filename for read lda #$20 sta sizehi @@ -57,7 +57,7 @@ LoadDHRFileInternal SaveSmallFileInternal +LDADDR gPathname - +STAY namlo ; set filename for ProRWTS2 + +ST16 namlo ; set filename for ProRWTS2 jsr traverse ; go to subdirectory, set up filename for read ;lda #cmdread ; read (instead of write) ;sta reqcmd diff --git a/src/hw.mockingboard.a b/src/hw.mockingboard.a index 1281c575a..9df7f6396 100644 --- a/src/hw.mockingboard.a +++ b/src/hw.mockingboard.a @@ -26,7 +26,7 @@ ; A/Y clobbered ;------------------------------------------------------------------------------ GetMockingboardStuff - +STAY @callback+1 + +ST16 @callback+1 lda #$00 sta $80 sta $82 ; type diff --git a/src/macros.a b/src/macros.a index 86c0c3e61..c4356ad87 100755 --- a/src/macros.a +++ b/src/macros.a @@ -55,17 +55,51 @@ } ; load a 16-bit value into A (low) and Y (high) -!macro LDAY .ptr { +!macro LD16 .ptr { lda .ptr ldy .ptr+1 } ; store a 16-bit value from A (low) and Y (high) -!macro STAY .ptr { +!macro ST16 .ptr { sta .ptr sty .ptr+1 } +; decrement a 16-bit value in A (low) and Y (high) +!macro DEC16 { + sec + sbc #1 + bcs + + dey ++ +} + +; increment a 16-bit value in A (low) and Y (high) +!macro INC16 { + clc + adc #1 + bne + + iny ++ +} + +; compare a 16-bit value in A (low) and Y (high) to an absolute address +!macro CMP16ADDR .addr { + cmp .addr + bne + + cpy .addr+1 ++ +} + +; compare a 16-bit value in A (low) and Y (high) to an immediate value +!macro CMP16 .val { + cmp #<.val + bne + + cpy #>.val ++ +} + !macro LBPL .target { bmi + jmp .target @@ -94,6 +128,14 @@ !byte $2C } +; debugging +!macro DEBUGWAIT { + bit $c010 +- bit $c000 + bpl - + bit $c010 +} + ; various language card configurations !macro READ_RAM1_NO_WRITE { bit $C088 diff --git a/src/okvs.a b/src/okvs.a index 9ee1239b9..923b2aba1 100644 --- a/src/okvs.a +++ b/src/okvs.a @@ -1,7 +1,7 @@ ;license:MIT ;(c) 2018-2020 by 4am ; -; Ordered key/value store (6502 compatible) +; Ordered key/value store (6502 compatible)(256+ records compatible) ; ; Public functions ; - okvs_init(address) reset (required) @@ -15,12 +15,12 @@ ; - okvs_iter(address, callback) iterate through keys ; - okvs_iter_values(address, callback) iterate through values ; -; Call init() once. Call it again to reset the store to 0 keys. +; Call init() once. Call it again to reset the store to 0 records. ; -; Keys are maintained in a singly linked list, so most functions are O(n). +; Records are maintained in a singly linked list, so most functions are O(n). ; len() and append() are O(1) though. ; -; Key count is stored as a byte, so a store can hold a maximum of 255 keys. +; Record count is stored as a word, so a store can hold 65535 records. ; ; Keys and values are length-prefixed strings (Pascal style), so max length ; of any single key or value is 255 bytes. @@ -34,23 +34,24 @@ ; There is no range checking because this is assembly. ; All functions take the starting address of the store's data buffer in -; memory, so there can be multiple independent stores at one time. append() -; will happily extend the store's data buffer without limit. There is no -; overflow protection because this is assembly. +; memory, so there can be multiple independent stores at one time. The next- +; record pointers are actual memory addresses, so stores are not easily +; relocatable. append() will happily extend the store's data buffer without +; limit. There is no overflow protection because this is assembly. ; ; There is no sort() function. ; ; There is no delete() function. ; -; Keys can be duplicated, but get() will always return the one that was -; append()ed first. +; Keys can be duplicated, but get() and find() will always return the one that +; was append()ed first. ; ; Structures: ; ; Store -; +0 length (byte) -; +1 free space pointer after last record (word) -; +3 Record +; +0 number of records (word) +; +2 free space pointer after last record (word) +; +4 Record ; ...Record... ; ...Record... ; @@ -75,13 +76,15 @@ okvs_init ; PTR -> store ; Y = 0 tya - sta (PTR),y ; set number of keys in store to 0 + sta (PTR),y ; set number of keys in store to 0 (word) + iny + sta (PTR),y - iny ; set next-free-space pointer to store + 3 + iny ; set next-free-space pointer to store + 4 ldx PTR+1 lda PTR clc - adc #$03 + adc #$04 bcc + inx + sta (PTR),y @@ -94,9 +97,9 @@ okvs_init ; okvs_len ; ; in: A/Y = handle to storage space -; out: A contains number of keys in this store +; out: $WCOUNT contains number of keys in this store ; X preserved -; Y clobbered +; A, Y clobbered ; $00/$01 clobbered ; $02/$03 clobbered ;------------------------------------------------------------------------------ @@ -104,7 +107,11 @@ okvs_len jsr GetStoreAddressFromAY ; PTR -> store ; Y = 0 - lda (PTR),y ; A = number of keys in store + lda (PTR), y ; get number of keys in store (word) + sta WCOUNT + iny + lda (PTR), y + sta WCOUNT+1 rts ;------------------------------------------------------------------------------ @@ -115,8 +122,8 @@ okvs_len ; +3 [word] address of key ; +5 [word] address of value ; +7 [byte] maximum length of value (or 0 to fit) -; out: X = new number of records (same as calling okvs_len after okvs_append) -; A/Y clobbered +; out: (new record count is not returned because no one cares) +; all registers clobbered ; $00/$01 clobbered ; $02/$03 clobbered ; $04/$05 has the address of the next available byte after the new record @@ -128,10 +135,20 @@ okvs_append ; PTR -> store ; Y = 0 lda (PTR),y ; A = number of keys in store - ;;clc - adc #1 - pha ; will return this later + sta WINDEX + iny + lda (PTR), y + sta WINDEX+1 + inc WINDEX + bne + + inc WINDEX+1 ++ + dey + lda WINDEX sta (PTR),y ; increment number of keys + lda WINDEX+1 + iny + sta (PTR),y iny lda (PTR),y ; get address of next free space tax @@ -187,23 +204,22 @@ okvs_append inc PTR+1 + lda PTR+1 sta SRC+1 ; SRC -> byte after this record - +LDAY SAVE - +STAY PTR ; PTR -> this record again + +LD16 SAVE + +ST16 PTR ; PTR -> this record again ldy #0 lda SRC ; update next-record pointer sta (PTR),y iny lda SRC+1 sta (PTR),y - pla - tax ; X = new OKVS length jsr GetStoreAddress ; PTR -> store ldy #2 -- lda SRC-1,y + lda SRC-2,y sta (PTR),y ; update next-free-space pointer in head - dey - bne - + iny + lda SRC-2,y + sta (PTR),y rts ;------------------------------------------------------------------------------ @@ -214,7 +230,7 @@ okvs_append ; +3 [word] address of key ; out: if C clear, record was found ; A/Y = lo/hi address of key (okvs_find) or value (okvs_get) -; X = numeric index of found record +; $WINDEX = index of found record (word) ; if C set, keyrecord was not found and all registers are clobbered ; all other flags clobbered ; $00/$01 clobbered @@ -232,13 +248,21 @@ okvs_get ; PTR -> store ; Y = 0 lda (PTR),y ; A = number of keys in store + sta WCOUNT + iny + lda (PTR),y + sta WCOUNT+1 + bne + + dey + lda (PTR),y beq @fail ; no keys, fail immediately - sta @max - jsr incptr3 ++ + jsr incptr4 ; PTR -> first record - ldx #0 +LDPARAMPTR 3, SRC ; SRC -> key we want to find ldy #0 + sty WINDEX + sty WINDEX+1 lda (SRC),y tay iny @@ -261,24 +285,30 @@ okvs_get KEYLEN = *+1 cpy #$D1 ; SMC bne @matchKeyLoop - +LDAY DEST + +LD16 DEST clc @maybeGetValue brk ; SMC jsr okvs_get_current - +LDAY PTR + +LD16 PTR clc rts @next jsr derefptr ; PTR -> next record - inx -@max = *+1 - cpx #$D1 ; SMC + inc WINDEX + bne + + inc WINDEX+1 ++ + lda WINDEX + cmp WCOUNT + bne @matchRecordLoop + lda WINDEX+1 + cmp WCOUNT+1 bne @matchRecordLoop @fail sec rts okvs_get_current - +STAY PTR + +ST16 PTR ldy #0 lda (PTR),y clc @@ -293,50 +323,61 @@ okvs_get_current ; get (N+1)th key, with wraparound ; ; in: A/Y = handle to storage space -; X = record index -; out: A/Y = lo/hi address of (X+1)th key, or first key if X was the last record -; X = next record index -; SAVE clobbered +; $WINDEX = record index (word) +; out: A/Y = lo/hi address of ($WINDEX+1)th key, or first key if $WINDEX was the last record +; $WINDEX = record index of next record ; see okvs_nth for other exit conditions ;------------------------------------------------------------------------------ okvs_next - +STAY PARAM - inx - stx SAVE - jsr okvs_len - eor SAVE + +ST16 PARAM + inc WINDEX bne + - tax + inc WINDEX+1 + - +LDAY PARAM + jsr okvs_len + +LD16 WINDEX + +CMP16ADDR WCOUNT + bne + + lda #0 + sta WINDEX + sta WINDEX+1 ++ + +LD16 PARAM ; /!\ execution falls through here to okvs_nth ;------------------------------------------------------------------------------ ; okvs_nth ; get (N)th key ; ; in: A/Y = handle to storage space -; X = record index +; $WINDEX = record index ; out: A/Y = lo/hi address of nth key -; X preserved +; $WINDEX preserved +; X = 0 ; Z = 0 ; all other flags clobbered -; PTR clobbered +; $PTR clobbered ;------------------------------------------------------------------------------ okvs_nth jsr GetStoreAddressFromAY ; PTR -> store - jsr incptr3 + jsr incptr4 ; PTR -> first record - txa - beq @found - pha + +LD16 WINDEX + +ST16 SAVE + jmp @next - jsr derefptr - dex +@next + dec SAVE + lda SAVE + cmp #$FF bne - - pla - tax -@found jsr incptr2 - +LDAY PTR + dec SAVE+1 + lda SAVE+1 + cmp #$FF + bne - + jsr incptr2 + +LD16 PTR + ldx #0 rts ;------------------------------------------------------------------------------ @@ -372,7 +413,7 @@ okvs_update !word $FDFD ; SMC !word $FDFD ; SMC bcs @exit - +STAY DEST + +ST16 DEST ldy #0 lda (SAVE),y tay @@ -391,13 +432,15 @@ okvs_update ; +1 [word] handle to storage space ; +3 [word] address of callback ; out: will be called for each record in the store, in order, with -; X = numeric index of record +; $WINDEX = numeric index of record (word) ; A/Y = address of key or value (depends on which entry point you call) ; all registers are clobbered ; Z=1 ; all other flags clobbered ; PARAM clobbered ; PTR clobbered +; WINDEX clobbered +; WCOUNT clobbered ;------------------------------------------------------------------------------ okvs_iter lda #$D0 ; 'BNE' opcode @@ -409,14 +452,23 @@ okvs_iter_values jsr GetStoreAddress ; PTR -> store ; Y = 0 - lda (PTR),y ; A = number of keys in store + lda (PTR),y ; get number of keys in store (word) + sta WCOUNT + iny + lda (PTR),y + sta WCOUNT+1 + bne + + dey + lda (PTR),y beq @exit ; no keys, exit immediately - sta @max ++ +LDPARAM 3 - +STAY @callback - jsr incptr3 + +ST16 @callback + jsr incptr4 ; PTR -> first record - ldx #0 + lda #0 + sta WINDEX + sta WINDEX+1 @loop lda #2 ; for iter, skip length = 2 @branch bne + ; SMC (iter_values puts a BIT here, so no branch) @@ -426,13 +478,19 @@ okvs_iter_values clc adc #3 ; skip over pointer to next record (2 bytes) + key length (1 byte) + sta @skiplen - txa - pha ; save X on stack + lda WCOUNT+1 ; save WCOUNT on stack + pha + lda WCOUNT + pha + lda WINDEX+1 ; save WINDEX on stack + pha + lda WINDEX + pha lda PTR+1 tay pha lda PTR - pha ; save PTR on stack (in case callback clobbers it) + pha ; save PTR on stack clc @skiplen=*+1 adc #$FD ; SMC skip over pointer (and possibly key) @@ -446,18 +504,30 @@ okvs_iter_values pla sta PTR+1 ; restore PTR from stack pla - tax ; restore X from stack + sta WINDEX + pla + sta WINDEX+1 + pla + sta WCOUNT + pla + sta WCOUNT+1 jsr derefptr ; PTR -> next record - inx -@max=*+1 - cpx #$FD ; SMC + inc WINDEX + bne + + inc WINDEX+1 ++ + lda WINDEX + cmp WCOUNT + bne @loop + lda WINDEX+1 + cmp WCOUNT+1 bne @loop @exit rts ;------------------------------------------------------------------------------ ; internal functions -incptr3 jsr incptr +incptr4 jsr incptr2 incptr2 jsr incptr incptr ; preserves A, X, and Y @@ -467,7 +537,7 @@ incptr + rts GetStoreAddressFromAY - +STAY PTR + +ST16 PTR jmp derefptr GetStoreAddress diff --git a/src/parse.common.a b/src/parse.common.a index a60b5af6f..353bdcb50 100644 --- a/src/parse.common.a +++ b/src/parse.common.a @@ -32,7 +32,7 @@ ParseKeyValueList +PARAMS_ON_STACK 5 +LDPARAM 1 - +STAY @store2 + +ST16 @store2 jsr SetKeyPtr ldy #5 lda (PARAM),y diff --git a/src/parse.games.a b/src/parse.games.a index 9810c0514..16becb1ff 100644 --- a/src/parse.games.a +++ b/src/parse.games.a @@ -28,7 +28,7 @@ ParseGamesList +PARAMS_ON_STACK 4 +LDPARAM 1 - +STAY @store2 + +ST16 @store2 jsr SetKeyPtr ldy #$00 ; index into ($FE) pointing to current character diff --git a/src/parse.prefs.a b/src/parse.prefs.a index 065014689..da5d27cb2 100644 --- a/src/parse.prefs.a +++ b/src/parse.prefs.a @@ -55,7 +55,7 @@ kCheat ._ .addStringFromStore - +STAY .key + +ST16 .key jsr .addString +LDADDR .kEquals jsr .addString @@ -66,7 +66,7 @@ kCheat +LDADDR .kLF ; execution falls through here .addString - +STAY $00 + +ST16 $00 ldy #0 lda ($00),y beq PREFRTS @@ -103,7 +103,7 @@ PREFRTS rts ; +3 [word] address of OKVS, or 0 ; gGlobalPrefsStore must be initialized (this is done in 4cade.init) ; out: A/Y = address of pref value -; X = index of pref value in passed store +; $WINDEX = index of pref value in passed store ; (if OKVS parameter is 0, no validation occurs and X=0 and Z=1 on exit, ; some callers rely on this behavior, so don't change it!) ; PARAM clobbered @@ -122,8 +122,8 @@ pref_get bcs .useDefaultValue ; if pref key is not found, use default value ldx .store1+1 beq PREFRTS ; if no OKVS to validate against, we're done - +STAY + - +STAY PTR + +ST16 + + +ST16 PTR ldy #0 lda (PTR),y beq .useDefaultValue ; if pref value is empty, use default value @@ -132,9 +132,11 @@ pref_get + !word $FDFD ; SMC bcc + ; found key, continue .useDefaultValue ; did not find key, use first key in passed store as a default value - ldx #0 + lda #0 + sta WINDEX + sta WINDEX+1 + - +LDAY .store1 + +LD16 .store1 jmp okvs_nth ;------------------------------------------------------------------------------ @@ -161,7 +163,7 @@ pref_set ++ !word $FDFD ; SMC +LDADDR kGlobalPrefsBuffer ; clear prefs buffer - +STAY $FE + +ST16 $FE ldx #$02 ldy #$00 tya @@ -199,7 +201,7 @@ pref_set +LDADDR kGlobalPrefsFilename ; write prefs buffer to file on disk jsr SetPath - +LDAY kGlobalPrefsBuffer + +LD16 kGlobalPrefsBuffer ; /!\ execution falls through here to glue.prorwts/SaveSmallFile ;------------------------------------------------------------------------------ ; SaveSmallFile @@ -215,7 +217,7 @@ pref_set ; all registers clobbered ;------------------------------------------------------------------------------ SaveSmallFile - +STAY ldrlo ; set data buffer address for ProRWTS2 + +ST16 ldrlo ; set data buffer address for ProRWTS2 jsr SwitchToBank2 jsr SaveSmallFileInternal jmp SwitchToBank1 diff --git a/src/prodos.impl.lc2.a b/src/prodos.impl.lc2.a index 6b4628641..e66a0890a 100644 --- a/src/prodos.impl.lc2.a +++ b/src/prodos.impl.lc2.a @@ -384,7 +384,7 @@ ProDOS_enter ; all registers clobbered ;------------------------------------------------------------------------------ traverse - +LDAY gRootDirectory + +LD16 gRootDirectory sta (reloc + unrhddblocklo - unrelochdd) + 1 sty (reloc + unrhddblockhi - unrelochdd) + 1 sta @myreadblock+1 diff --git a/src/prodos.path.a b/src/prodos.path.a index 9f65608ca..5829c7521 100644 --- a/src/prodos.path.a +++ b/src/prodos.path.a @@ -25,7 +25,7 @@ kRootDirectory=*+1 stx gPathname ; execution falls through here AddToPath - +STAY PTR + +ST16 PTR ldy #0 lda (PTR),y ; length of this segment beq @done diff --git a/src/textrank.a b/src/textrank.a index 8073f7774..022f2f3dc 100644 --- a/src/textrank.a +++ b/src/textrank.a @@ -38,11 +38,11 @@ BuildSearchStore ; callback called by okvs_iter on gGamesListStore ; in: A/Y contains address of filename -; X contains 0-based index of the current record in gGamesListStore +; $WINDEX contains 0-based index of the current record in gGamesListStore (word) ; out: all registers and flags clobbered - +STAY @key + +ST16 @key jsr GetGameDisplayName - +STAY @value + +ST16 @value @append jsr okvs_append !word gSearchStore @@ -64,6 +64,7 @@ ResetTextRank stx BestMatchScore dex stx BestMatchIndex + stx BestMatchIndex+1 rts ;------------------------------------------------------------------------------ @@ -73,17 +74,16 @@ ResetTextRank ; against the current InputBuffer ; in: A/Y contains address of game display name -; X contains 0-based index of the current record in gSearchStore +; $WINDEX contains 0-based index of the current record in gSearchStore (word) ; out: all registers and flags clobbered ; MatchCount possibly incremented (if this game was a match at all) ; BestMatchScore and BestMatchIndex possibly updated (if this game ; was the best match so far) ;------------------------------------------------------------------------------ TextRankCallback - stx tmpx ; X = OKVS index of this game - +STAY zpstring ; A/Y = address of this game display name + +ST16 zpstring ; A/Y = address of this game display name +LDADDR InputLength - +STAY zpword + +ST16 zpword ldy #0 lda (zpstring),y cmp InputLength @@ -162,8 +162,10 @@ TextRankCallback bcc + beq + sta BestMatchScore - ldx tmpx - stx BestMatchIndex + lda WINDEX + sta BestMatchIndex + lda WINDEX+1 + sta BestMatchIndex+1 inc MatchCount + rts diff --git a/src/ui.animation.a b/src/ui.animation.a index 954aee414..e090e0746 100644 --- a/src/ui.animation.a +++ b/src/ui.animation.a @@ -46,7 +46,7 @@ MaybeAnimateTitle ; load the animation routine, which is stored in a subdirectory by filename jsr GetGameToLaunch - +STAY + + +ST16 + jsr LoadFile !word kAnimatedTitleDirectory + !word $FDFD diff --git a/src/ui.attract.dhgr.a b/src/ui.attract.dhgr.a index ac836f8a1..967d6e622 100644 --- a/src/ui.attract.dhgr.a +++ b/src/ui.attract.dhgr.a @@ -69,7 +69,7 @@ DHGRActionSlideshow DHGRSingle bit MachineStatus ; only show DHGR screenshots if we have 128K bvc DHGRRTS - +STAY @fname + +ST16 @fname jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 !word kRootDirectory @@ -147,11 +147,11 @@ LoadDHGRTransition jsr pref_get ; get DHGR transition effect from prefs !word kNextDFX !word gDFXStore - +STAY ++ ; A/Y = filename (don't load file yet) - ; X = index of the transition in DFX store + +ST16 ++ ; A/Y = filename (don't load file yet) + ; $WINDEX = index of the transition in DFX store +LDADDR gDFXStore jsr okvs_next ; get transition after this one - +STAY + + +ST16 + jsr pref_set ; update prefs store and save to disk !word kNextDFX @@ -169,7 +169,7 @@ LoadDHGRTransition ; to load and display a single DHGR title screenshot ; in: A/Y contains address of filename (name only, path is always /TITLE.DHGR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -179,14 +179,16 @@ DHGRTitleCallback bit KBD bmi DHGRRTS - +STAY + + +ST16 + jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows bcs DHGRRTS - stx gGameToLaunch + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) ; load DHGR screenshot at $4000/main and $4000/aux jsr LoadDHRFile @@ -201,7 +203,7 @@ DHGRTitleCallback ; to load and display a single DHGR action screenshot ; in: A/Y contains address of filename (name only, path is always /ACTION.DHGR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -211,15 +213,17 @@ DHGRActionCallback bit KBD bmi DHGRRTS - +STAY + + +ST16 + jsr FindGameInActionSlideshow ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs DHGRRTS - +STAY SAVE ; (SAVE) -> game display name + game info bitfield - stx gGameToLaunch + +ST16 SAVE ; (SAVE) -> game display name + game info bitfield + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 !word kDHGRActionDirectory @@ -292,8 +296,8 @@ DrawGameTitleInActionSlideshowHGR ;------------------------------------------------------------------------------ RedrawForDHGR jsr SwitchToBank2 - +LDAY DBIRow0+1 - +STAY $26 + +LD16 DBIRow0+1 + +ST16 $26 lda #8 sta i -- ldy gPathname diff --git a/src/ui.attract.gr.a b/src/ui.attract.gr.a index 3c38efdf1..80395a0de 100644 --- a/src/ui.attract.gr.a +++ b/src/ui.attract.gr.a @@ -33,7 +33,7 @@ GRActionSlideshow ; graphics mode set to display hi-res screen ;------------------------------------------------------------------------------ GRSingle - +STAY @fname + +ST16 @fname jsr BlankGR ; switch to GR mode with initial blank screen jsr LoadFile ; load GR screenshot into $6000 !word kRootDirectory @@ -83,7 +83,7 @@ GRRTS rts ; to load and display a single GR action screenshot ; in: A/Y contains address of filename (name only, path is always /ACTION.GR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) @@ -93,14 +93,16 @@ GRActionCallback bit KBD bmi GRRTS - +STAY + + +ST16 + jsr FindGameInActionSlideshow ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs GRRTS - stx gGameToLaunch + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr LoadFile ; load GR screenshot into $6000 !word kGRActionDirectory diff --git a/src/ui.attract.hgr.a b/src/ui.attract.hgr.a index c010733c6..e4814e409 100644 --- a/src/ui.attract.hgr.a +++ b/src/ui.attract.hgr.a @@ -48,7 +48,7 @@ HGRActionSlideshow ; graphics mode still displaying hi-res screen with last picture visible ;------------------------------------------------------------------------------ HGRSingle - +STAY @fname + +ST16 @fname jsr LoadFile ; load compressed HGR screenshot at $3FF8 !word kRootDirectory @fname !word $FDFD ; SMC @@ -79,11 +79,11 @@ LoadHGRTransition jsr pref_get ; get HGR transition effect from prefs !word kNextFX !word gFXStore - +STAY ++ ; A/Y = filename (don't load file yet) - ; X = index of the transition in FX store + +ST16 ++ ; A/Y = filename (don't load file yet) + ; $WINDEX = index of the transition in FX store +LDADDR gFXStore jsr okvs_next ; get transition after this one - +STAY + + +ST16 + jsr pref_set ; update prefs store and save to disk !word kNextFX @@ -101,7 +101,7 @@ HGRRTS rts ; to load and display a single HGR title screenshot ; in: A/Y contains address of filename (name only, path is always /TITLE.HGR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -110,14 +110,16 @@ HGRTitleCallback bit KBD bmi HGRRTS - +STAY + + +ST16 + jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows bcs HGRRTS - stx gGameToLaunch + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr LoadFile ; load HGR screenshot at $4000 !word kHGRTitleDirectory @@ -132,7 +134,7 @@ HGRTitleCallback ; to load and display a single HGR action screenshot ; in: A/Y contains address of filename (name only, path is always /ACTION.HGR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) @@ -142,7 +144,7 @@ HGRActionCallback bit KBD bmi HGRRTS - +STAY + + +ST16 + jsr FindGameInActionSlideshow ; if game name is not found (C will be set here), it means the game @@ -151,8 +153,10 @@ HGRActionCallback bcs HGRRTS ; found the game - +STAY SAVE ; (SAVE) -> game display name + game info bitfield - stx gGameToLaunch + +ST16 SAVE ; (SAVE) -> game display name + game info bitfield + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr LoadFile ; load compressed HGR screenshot at $3FF8 !word kHGRActionDirectory diff --git a/src/ui.attract.mode.a b/src/ui.attract.mode.a index 62ad513c9..923bb0b4f 100644 --- a/src/ui.attract.mode.a +++ b/src/ui.attract.mode.a @@ -36,11 +36,11 @@ MegaAttractMode jsr pref_get ; get attract mode module from prefs !word kNextAttract !word gAttractModeStore - +STAY @mname ; A/Y = module name - ; X = index of module in attract store + +ST16 @mname ; A/Y = module name + ; $WINDEX = index of module in attract store +LDADDR gAttractModeStore jsr okvs_next ; get module after this one - +STAY + + +ST16 + jsr pref_set ; update prefs store and save to disk !word kNextAttract @@ -49,11 +49,11 @@ MegaAttractMode jsr okvs_get !word gAttractModeStore @mname !word $FDFD ; SMC - +STAY PTR + +ST16 PTR ldy #1 lda (PTR),y tax ; X = module type - +LDAY @mname ; A/Y = address of module name + +LD16 @mname ; A/Y = address of module name jsr RunAttractModule lda KBD bpl MegaAttractMode @@ -66,17 +66,18 @@ MegaAttractMode ; MiniAttractMode ; run attract modules related to one game ; -; in: gGameToLaunch = index in gGamesListStore +; in: gGameToLaunch = index in gGamesListStore (word) ; out: all flags and registers clobbered ; assume all of main memory has been clobbered ;------------------------------------------------------------------------------ MiniAttractMode jsr GetGameToLaunch - +STAY + + +ST16 + jsr BlankHGR ; X = 0 - stx @MiniAttractIndex + stx MiniAttractIndex + stx MiniAttractIndex+1 @loop jsr LoadFile ; load mini attract mode configuration file into $8000 !word kMiniAttractDirectory @@ -90,25 +91,34 @@ MiniAttractMode +LDADDR gAttractModeStore jsr okvs_len - cmp @MiniAttractIndex + lda WCOUNT + cmp MiniAttractIndex + bne + + lda WCOUNT+1 + cmp MiniAttractIndex+1 beq ATTRTS ; we've run through all modules, so exit to caller - -@MiniAttractIndex=*+1 - ldx #$FD ; SMC ++ + +LD16 MiniAttractIndex + +ST16 WINDEX +LDADDR gAttractModeStore jsr okvs_nth ; get the next module on the list - +STAY SAVE + +ST16 SAVE jsr okvs_get_current ; get module type ldy #1 lda (PTR),y tax ; X = module type - +LDAY SAVE ; A/Y = address of module name + +LD16 SAVE ; A/Y = address of module name jsr RunAttractModule ; execute the module - inc @MiniAttractIndex + inc MiniAttractIndex + bne + + inc MiniAttractIndex+1 ++ lda KBD bpl @loop ATTRTS rts +MiniAttractIndex + !word 0 ; SMC ;------------------------------------------------------------------------------ ; RunAttractModule @@ -125,8 +135,8 @@ ATTRTS rts ; assume all of main memory has been clobbered ;------------------------------------------------------------------------------ RunAttractModule - +STAY @key - +STAY @key2 + +ST16 @key + +ST16 @key2 cpx #$30 bne @NotDemo @@ -136,12 +146,14 @@ RunAttractModule ; All demos are strictly 48K / main memory. No demo uses the ; language card or auxiliary memory. - +LDAY @key + +LD16 @key jsr FindGame bcs ATTRTS ; if game doesn't exist, skip the demo - cpx #$FF + +LD16 WINDEX + +CMP16 $FFFF beq + - stx gGameToLaunch + +ST16 gGameToLaunch ; if this demo corresponds to a game, save its index + ; in case user presses RETURN during the demo (we will launch the game) + jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) @@ -182,7 +194,7 @@ RunAttractModule sta @jmp+1 lda @slideshowshi-1,x sta @jmp+2 - +LDAY @key ; pass in module name + +LD16 @key ; pass in module name @jmp jmp $FDFD ; SMC @dispatchSingle diff --git a/src/ui.attract.shr.a b/src/ui.attract.shr.a index 47f9f409a..37e603616 100644 --- a/src/ui.attract.shr.a +++ b/src/ui.attract.shr.a @@ -42,7 +42,7 @@ SHRRTS rts ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ SHRSingle - +STAY + + +ST16 + lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card and #SUPPORTS_SHR beq SHRRTS @@ -76,7 +76,7 @@ LoadSHRTransition ; to load and display a single SHR graphic ; in: A/Y contains address of filename (name only, path is always /ARTWORK.SHR/) -; X contains 0-based index of the current record in gSlideshowStore +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -86,14 +86,16 @@ SHRArtworkCallback bit KBD bmi SHRRTS - +STAY @sfname + +ST16 @sfname jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows bcs SHRRTS - stx gGameToLaunch + + +LD16 WINDEX ; save game index in case user hits RETURN + +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr BlankSHR diff --git a/src/ui.browse.mode.a b/src/ui.browse.mode.a index 9c6d513f4..ba1538078 100644 --- a/src/ui.browse.mode.a +++ b/src/ui.browse.mode.a @@ -64,33 +64,25 @@ OnBrowseSearch jmp SearchMode OnBrowsePrevious - ldx gGameToLaunch - inx ; Slightly pathological case: there may be no - ; current game by the time we get here, e.g. - ; if we entered browse mode by pressing left - ; or up arrow from the global help screen. - ; In this case, pretend we were at game 0 and - ; continue with the key handler logic. - beq + - dex - bne .decindex -+ ldx GameCount - -.decindex - dex - -.setindex - stx gGameToLaunch + +LD16 gGameToLaunch + +CMP16 0 + bne @notFirstGame + +LD16 GameCount +@notFirstGame + +DEC16 + +ST16 gGameToLaunch jmp OnBrowseChanged OnBrowseNext - ldx gGameToLaunch - inx -GameCount = *+1 - cpx #$D1 ; SMC - bne .setindex - ldx #0 - beq .setindex ; branch always + +LD16 gGameToLaunch + +INC16 + +CMP16ADDR GameCount + bne @notLastGame + lda #0 + tay +@notLastGame + +ST16 gGameToLaunch + jmp OnBrowseChanged OnBrowseLaunch jsr PlayGame @@ -110,7 +102,7 @@ ForceBrowseChanged bit CLEARKBD ; execution falls through here OnBrowseChanged -; in: gGameToLaunch = game index +; in: gGameToLaunch = game index (word) jsr SwitchToBank2 jsr EnableAcceleratorAndSwitchToBank1 jsr LoadGameTitleOffscreen @@ -175,3 +167,6 @@ BrowseKeyDispatch !byte kBrowseNext !byte kBrowsePrevious !byte kBrowsePrevious + +GameCount + !word 0 diff --git a/src/ui.credits.a b/src/ui.credits.a index 33f20ee85..9459c6295 100644 --- a/src/ui.credits.a +++ b/src/ui.credits.a @@ -27,11 +27,11 @@ Credits ror ; draw on offscreen page +LDADDR $8000 tax - jsr DrawPage ; draw credits +- jsr DrawPage ; draw credits jsr ShowOtherPage ; show credits jsr WaitForKeyFor30Seconds; wait --- bit CLEARKBD ; don't care about key -- sec ; if called from search mode, tell caller to refresh + bit CLEARKBD ; don't care about key + sec ; if called from search mode, tell caller to refresh rts ;------------------------------------------------------------------------------ @@ -39,9 +39,7 @@ Credits ; display global help page and wait ; ; in: none -; out: if user presses an arrow key within 30 seconds, this exits via BrowseMode -; otherwise this returns to caller with -; C clear, all other flags and registers clobbered +; out: see above ;------------------------------------------------------------------------------ Help jsr LoadFile ; load help text into $8000 @@ -53,17 +51,4 @@ Help ror ; draw on offscreen page +LDADDR $8000 ldx #8 - jsr DrawPage ; draw help text - jsr ShowOtherPage - jsr WaitForKeyFor30Seconds - cmp #$88 - beq BrowseMode - cmp #$83 - beq - - cmp #$81 - beq - - jsr IsUpDownOrRightArrow - beq - - jsr IsSearchKey - bne -- - rts + bne - ; always branches diff --git a/src/ui.font.lc2.a b/src/ui.font.lc2.a index 043afa4b8..c30029b4d 100644 --- a/src/ui.font.lc2.a +++ b/src/ui.font.lc2.a @@ -22,7 +22,7 @@ DrawPageInternal stx @leftMargin ldx #0 stx VTAB - +STAY PTR + +ST16 PTR @drawLine @leftMargin=*+1 lda #$FD ; SMC @@ -51,7 +51,7 @@ DrawPageInternal tya beq @skip ldx SAVE - +LDAY PTR + +LD16 PTR plp php jsr DrawBufferInternal @@ -96,7 +96,7 @@ DrawCenteredStringInternal ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; clobbers A/X/Y ; clobbers PTR/PTR+1 - +STAY PTR + +ST16 PTR ldy #0 php @@ -116,7 +116,7 @@ DrawStringInternal ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; clobbers A/X/Y ; clobbers PTR/PTR+1 - +STAY PTR + +ST16 PTR ldy #0 + lda (PTR),y @@ -125,7 +125,7 @@ DrawStringInternal bne + inc PTR+1 + - +LDAY PTR + +LD16 PTR ; /!\ execution falls through here to DrawBufferInternal DrawBufferInternal @@ -141,7 +141,7 @@ DrawBufferInternal ; HTAB is incremented for each character ; VTAB is NOT incremented ; clobbers A/X/Y - +STAY DBISrc+1 + +ST16 DBISrc+1 php dex lda VTAB diff --git a/src/ui.offscreen.a b/src/ui.offscreen.a index ca2340810..b1172607d 100644 --- a/src/ui.offscreen.a +++ b/src/ui.offscreen.a @@ -83,9 +83,9 @@ LoadOffscreenFromAY rts LoadGameTitleOffscreen -; in: gGameToLaunch = index into gGamesListStore +; in: gGameToLaunch = index into gGamesListStore (word) jsr GetGameToLaunch - +STAY @fname + +ST16 @fname bit MachineStatus ; if < 128K, don't bother checking for DHGR title bvc @hgr jsr okvs_get_current @@ -109,8 +109,8 @@ LoadGameTitleOffscreen rts @dhgr jsr BlankDHGR - +LDAY @fname - +STAY + + +LD16 @fname + +ST16 + jsr LoadDHRFile !word kDHGRTitleDirectory + !word $FDFD diff --git a/src/ui.overlay.a b/src/ui.overlay.a index 0a4f9cce0..e8d3f1ea1 100644 --- a/src/ui.overlay.a +++ b/src/ui.overlay.a @@ -78,7 +78,7 @@ sCheatDescriptionSuffix ; draw 2- or 4-line UI on the HGR page that is not currently showing, then ; show that HGR page ; -; in: gGameToLaunch = game index, or #$FF if no game is selected +; in: gGameToLaunch = game index (word), or #$FFFF if no game is selected ; out: all flags and registers clobbered ;------------------------------------------------------------------------------ DrawUIWithoutDots @@ -104,14 +104,11 @@ DrawUI sta gPathname ; hack, used by first RedrawForDHGR which follows ; Draw40Chars which doesn't set gPathname - ldx gGameToLaunch - inx ; if no game, nothing more to do on UI line 2 - beq @doneWithLine2 - - jsr GetGameToLaunch + jsr GetGameToLaunch ; get current game, if any + bcs @doneWithLine2 ; if no game, nothing more to do on UI line 2 jsr GetGameDisplayName ; A/Y -> game display name + bitfield of game info - +STAY PTR + +ST16 PTR ldy #0 lda (PTR),y ; A = game display name length + 1 sta SAVE @@ -234,7 +231,7 @@ gDrawingOnscreen=*+1 ; (SAVE) -> length-prefixed cheat description +LDADDR sCheatDescriptionPrefix jsr SetPath - +LDAY SAVE + +LD16 SAVE jsr AddToPath +LDADDR sCheatDescriptionSuffix jsr AddToPath @@ -249,18 +246,17 @@ gDrawingOnscreen=*+1 jmp ShowOtherPage CheckCheats - ldy #kCheatsEnabled - ldx gGameToLaunch - inx - beq + + ldx #kCheatsEnabled + jsr AnyGameSelected + bcs + gGameToLaunchInfo=*+1 lda #$FD ; SMC and #CHEAT_CATEGORY - tay + tax + - lda kCheatDescriptionLo,y + lda kCheatDescriptionLo,x sta SAVE - lda kCheatDescriptionHi,y + lda kCheatDescriptionHi,x sta SAVE+1 - rts diff --git a/src/ui.search.mode.a b/src/ui.search.mode.a index 1b2f3337c..cd675f1b0 100644 --- a/src/ui.search.mode.a +++ b/src/ui.search.mode.a @@ -99,7 +99,8 @@ InputKeyDispatch SearchMode ldx #$FF txs - stx gGameToLaunch ; $FF = no game selected + stx gGameToLaunch ; $FFFF = no game selected + stx gGameToLaunch+1 jsr BuildSearchStore jsr Home ; clear screen (switches to text mode) stx OffscreenPage ; don't show text page 2 by accident @@ -145,15 +146,14 @@ OnBack bpl OnInputChanged ; always branches OnTab - ldx gGameToLaunch - inx - beq OnError + jsr AnyGameSelected + bcs OnError jsr MiniAttractMode cmp #$8D ; if we exited mini attract mode bne .req_redraw ; by pressing Enter, launch the game OnLaunch - ldx gGameToLaunch + ldx gGameToLaunch+1 inx beq OnError jsr PlayGame @@ -179,7 +179,8 @@ OnInputChanged bne FindMatchingTitle ; no input, reset params and UI dex - stx gGameToLaunch ; no game selected + stx gGameToLaunch ; $FFFF = no game selected + stx gGameToLaunch+1 jsr LoadTitleOffscreen jmp DrawUIWithoutDots @@ -227,8 +228,11 @@ SoftBell rts + - ldx BestMatchIndex ; check if the new best match is the same - cpx gGameToLaunch ; as the current best match + lda BestMatchIndex ; check if the new best match is the same + cmp gGameToLaunch ; as the current best match + bne @load + lda BestMatchIndex+1 + cmp gGameToLaunch+1 bne @load jsr ToggleOffscreenPage ; Since we're not loading a new screenshot @@ -237,7 +241,8 @@ SoftBell lda #1 bne @noload ; always branches @load - stx gGameToLaunch + +LD16 BestMatchIndex + +ST16 gGameToLaunch jsr LoadGameTitleOffscreen lda #0 @noload diff --git a/src/ui.wait.a b/src/ui.wait.a index 14ee5e87d..75193bf2d 100644 --- a/src/ui.wait.a +++ b/src/ui.wait.a @@ -30,7 +30,7 @@ ExecuteTransitionAtA000AndWait ;------------------------------------------------------------------------------ ExecuteTransitionAndWait lda #0 - +STAY @j+1 + +ST16 @j+1 @j jsr $FDFD ; SMC call transition effect code ldx #$20 ; picture is showing so now we wait - lda #0