mirror of
https://github.com/a2-4am/4cade.git
synced 2025-01-14 12:34:07 +00:00
Handle more than 256 games (#140)
This commit is contained in:
parent
57b5cd0cb5
commit
0d5a07b9b0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -26,7 +26,7 @@
|
||||
; A/Y clobbered
|
||||
;------------------------------------------------------------------------------
|
||||
GetMockingboardStuff
|
||||
+STAY @callback+1
|
||||
+ST16 @callback+1
|
||||
lda #$00
|
||||
sta $80
|
||||
sta $82 ; type
|
||||
|
46
src/macros.a
46
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
|
||||
|
228
src/okvs.a
228
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: <callback> 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
|
||||
|
@ -32,7 +32,7 @@ ParseKeyValueList
|
||||
+PARAMS_ON_STACK 5
|
||||
|
||||
+LDPARAM 1
|
||||
+STAY @store2
|
||||
+ST16 @store2
|
||||
jsr SetKeyPtr
|
||||
ldy #5
|
||||
lda (PARAM),y
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user