refactor 4cade.a into 4cade.init.a and ui.attract.mode.a, add DFX.CONF, add PREFS.CONF (not yet used)

This commit is contained in:
4am 2018-11-07 18:56:39 -05:00
parent 6145de0581
commit c406b2e2ec
10 changed files with 411 additions and 362 deletions

View File

@ -1,6 +1,7 @@
#
# 4cade Makefile
# assembles source code, optionally builds a disk image and mounts it
# note: Windows users should probably use winmake.bat instead
#
# original by Quinn Dunki on 2014-08-15
# One Girl, One Laptop Productions
@ -69,9 +70,11 @@ dsk: md asm
cp res/_FileInformation.txt build/ >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "build/LAUNCHER.SYSTEM" >>build/log
$(CADIUS) CREATEFOLDER build/"$(DISK)" "/${VOLUME}/X/" >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/PREFS.CONF" >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/GAMES.CONF" >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/ATTRACT.CONF" >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/FX.CONF" >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/DFX.CONF" >>build/log
rsync -aP res/hgr/* build/HGR >>build/log
bin/buildfileinfo.py build/HGR >>build/log
$(CADIUS) ADDFOLDER build/"$(DISK)" "/${VOLUME}/HGR" "build/HGR" >>build/log

View File

@ -1,7 +1,7 @@
PRODOS=Type(FF),AuxType(0000),Access(C3)
LAUNCHER.SYSTEM=Type(FF),AuxType(2000),Access(C3)
COVER=Type(06),AuxType(2000),Access(C3)
COVER.A2FC=Type(06),AuxType(2000),Access(C3)
PREFS.CONF=Type(04),AuxType(4000),Access(C3)
GAMES.CONF=Type(04),AuxType(4000),Access(C3)
ATTRACT.CONF=Type(04),AuxType(4000),Access(C3)
FX.CONF=Type(04),AuxType(4000),Access(C3)
DFX.CONF=Type(04),AuxType(4000),Access(C3)

1
res/dfx.conf Normal file
View File

@ -0,0 +1 @@
# # transition effects for DHGR slideshows # DHGR.RIPPLE DHGR.RADIAL DHGR.STAR DHGR.RADIAL3 DHGR.IRIS DHGR.RADIAL2 DHGR.RADIAL4 DHGR.RADIAL5 #TODO port this to a separate file like the others #DHGR.FIZZLE [eof]

1
res/prefs-sample.conf Normal file
View File

@ -0,0 +1 @@
# 4cade preferences file # Do not edit by hand. # Or do. I'm a comment, not a cop. # value=game directory listed in GAMES.CONF, or empty LASTPLAYED=SAMMY.LIGHTFOOT # value=attract mode module listed in ATTRACT.CONF, or empty NEXTATTRACT=FAVORITES.CONF # value=transition effect listed in FX.CONF, or empty NEXTFX=RIPPLE # value=transition effect listed in DFX.CONF, or empty NEXTDFX=DHGR.STAR [eof]

1
res/prefs.conf Normal file
View File

@ -0,0 +1 @@
# 4cade preferences file # Do not edit by hand. # Or do. I'm a comment, not a cop. # value=game directory listed in GAMES.CONF, or empty LASTPLAYED= # value=attract mode module listed in ATTRACT.CONF, or empty LASTATTRACT= # value=transition effect listed in FX.CONF, or empty LASTFX= # value=transition effect listed in DFX.CONF, or empty LASTDFX= [eof]

View File

@ -4,100 +4,7 @@
!source "src/constants.a"
!source "src/macros.a"
sta $C00E
sta $C00C
sta $C004
sta $C002
sta $C000
jsr $FB2F
jsr $FC58
jsr Has64K ; check for 64K (required)
bcs @no64K
jsr DisableAccelerator ; set to 1 MHz
jsr Has128K ; check for 128K (absence is OK, we just filter out some games)
ror MachineStatus
jsr HasJoystick ; check for joystick (absence is OK, we just filter out some games)
ror MachineStatus ; now bit 6 = 1 if 128K
; bit 7 = 1 if joystick
jsr init ; initialize ProRWTS2 (bye bye ProDOS)
+READ_RAM1_WRITE_RAM1
ldx #$00 ; relocate rest of program to RAM bank 1 in language card
@FM lda FirstMover,x
sta $D000,x
inx
bne @FM
lda @FM+2
cmp #>LastMover
bcs +
inc @FM+2
inc @FM+5
bne @FM
+
jmp OneTimeSetup
@no64K
ldy #@no64Klen
- lda @s_no64K,y
sta $6B6,y
dey
bpl -
@hang bmi @hang
@s_no64K !raw "REQUIRES 64K"
@no64Klen=*-@s_no64K
; ProRWTS2 has its own function to relocate itself
!source "src/prorwts2.a"
; these routines will only be called once, from main memory, before relocating to language card
ProRWTSBuffer
!source "src/hw.memcheck.a"
!source "src/hw.joystick.a"
!source "src/hw.normfast.a"
*=ProRWTSBuffer+512 ; ProRWTS needs a 512-byte buffer for its init function
; so we reuse as much of the 1-time code as possible
; and fill the rest with zeros
OneTimeSetup
lda hddopendir+1 ; save current directory as 'root'
ldy hddopendir+3
+STAY gRootDirectory
jsr LoadFile ; load games list
!word kGameListConfFile
jsr ParseGamesList ; parse games list
!word gGamesListStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gFXStore ; save pointer to free space for next store
jsr LoadFile ; load transition effects list
!word kFXConfFile
jsr ParseKeyValueList ; parse transition effects list
!word gFXStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gAttractModeStore ; save pointer to free space for next store
jsr LoadFile ; load attract-mode configuration
!word kAttractModeConfFile
jsr ParseKeyValueList ; parse attract-mode configuration
!word gAttractModeStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gSlideshowStore ; save pointer to free space for next store
jmp Main
kGameListConfFile
!byte @kGameListConfFile_e-@kGameListConfFile_b
@kGameListConfFile_b
!text "GAMES.CONF"
@kGameListConfFile_e
kFXConfFile
!byte @kFXConfFile_e-@kFXConfFile_b
@kFXConfFile_b
!text "FX.CONF"
@kFXConfFile_e
kAttractModeConfFile
!byte @kAttractModeConfFile_e-@kAttractModeConfFile_b
@kAttractModeConfFile_b
!text "ATTRACT.CONF"
@kAttractModeConfFile_e
!source "src/4cade.init.a"
FirstMover
!pseudopc $D000 {
@ -112,218 +19,6 @@ Main
jsr AttractMode
jmp -
AttractMode
jsr okvs_nth ; get filename of next attract-mode module
!word gAttractModeStore
@index !byte 0
+STAY @key
inc @index ; increment module index for next time
jsr okvs_len
!word gAttractModeStore
cmp @index
bne +
lda #0
sta @index
+
jsr okvs_get
!word gAttractModeStore
@key !word $FDFD
+STAY PTR
jsr +
lda $C000
bpl AttractMode
rts
+
ldy #1
lda (PTR),y
and #$0F
cmp #$03
bne @Slideshow
+LOAD_PATH kDemoDirectory
ldy gPathname
iny
iny
sty ProDOS_prefix
- lda gPathname-2, y
sta ProDOS_prefix, y
dey
bne -
lda #'/'
sta ProDOS_prefix+1
lda #'X'
sta ProDOS_prefix+2
+LOAD_FILE_IMM @key
ldx #(@end_prelaunch-@prelaunch-1)
- lda @prelaunch,x ; copy pre-launch code to main memory
sta $100,x
dex
bpl -
ldx #(end_promote-promote-1)
- lda promote,x ; copy tiny ProDOS to main memory
sta $bf00,x
dex
bpl -
jmp $106 ; jump to pre-launch code
@prelaunch ; this runs from main memory
lda $C088 ; entry point used by some self-running demos
jmp Reenter
+READ_ROM_NO_WRITE ; entry point to launch game (called above)
jsr $FE89 ; initialize machine like a cold boot
jsr $FE93 ; (many games assume a 'clean slate')
sta $C000
sta $C002
sta $C004
sta $C00C
sta $C00E
jsr $FB2F
jsr $FC58
ldx #$FF
txs
jmp (ldrlo2) ; jump to game
@end_prelaunch
@Slideshow
pha ; save module type
+LOAD_FILE kAttractModeSlideshowDirectory, @key
jsr ParseKeyValueList ; parse slideshow configuration
!word gSlideshowStore
!word ldrlo2 ; (ldrlo2) points to load address
pla ; restore module type
cmp #$01
beq @HGRSlideshow
;@DHGRSlideshow
; load transition effect code at $6000
jsr ResetPath
+LDADDR kFXDirectory
jsr AddToPath
+LDADDR kPathSeparator
jsr AddToPath
+LDADDR @dfx
jsr AddToPath
jsr LoadFile
!word gPathname
jsr BlankDHGR
jsr okvs_iter
!word gSlideshowStore
!word DHGRLoad
jmp BlankHGR
@dfx
!byte @dfx_e-@dfx_b
@dfx_b
!text "DHGR.RADIAL3"
@dfx_e
@HGRSlideshow
jsr LoadTransition
jsr okvs_iter
!word gSlideshowStore
!word HGRLoad
rts
HGRLoad
ldx $C000
bpl +
rts
+
+STAY PTR
; load HGR screenshot at $4000
+LOAD_FILE kHGRScreenshotDirectory, PTR
; jsr LoadTransition
jsr $6000 ; transition effect code was loaded here earlier
jmp WaitOnScreenshot
DHGRLoad
ldx $C000
bpl +
rts
+
+STAY PTR
jsr ResetPath
+LDADDR kDHGRScreenshotDirectory
jsr AddToPath
+LDADDR kPathSeparator
jsr AddToPath
+LDAY PTR
jsr AddToPath
jsr LoadDHRFile
!word gPathname
; jsr FizzleDHGR
jsr $6000
; note: execution falls through here
WaitOnScreenshot
ldx #$20
- lda #0
jsr WaitForKeyWithTimeout
bmi +
dex
bpl -
+ rts
LoadTransition
jsr okvs_nth ; get filename of transition effect code
!word gFXStore
@fxindex !byte 0
+STAY @fxkey
inc @fxindex ; increment transition effect index for next time
jsr okvs_len
!word gFXStore
cmp @fxindex
bne +
lda #0
sta @fxindex
+
; load transition effect code at $6000
+LOAD_FILE kFXDirectory, @fxkey
rts
@fxkey !word $FDFD
promote
!pseudopc $bf00 {
lda $c08b
clc
bcc @do_enter
;$bf06
rts ;clock interface, must be RTS on real ProDOS if program uses $20x
@do_enter
lda $c08b
jmp ProDOS_enter
!text "q4!"
;$bf10
!word $c1d1, $c2d1, $c3d1, $c4d1, $c5d1, $c6d1, $c7d1
ProDOS_exit
lda $c081
pla ;saved inside ProDOS_enter
tay
pla
tax
lda #0
rts
ProDOS_fatal ;only for debugging, will be removed
lda $c081
jsr $fe89
jsr $fe93
jmp $ff3a
ProDOS_prefix=$bfd0
; !fill $2e
}
end_promote
Reboot
ldx #(@end-@start-1)
- lda @start,x
@ -333,69 +28,17 @@ Reboot
jmp $300
@start
+READ_ROM_NO_WRITE
jmp $FF59
jmp $FAA6
@end
Home
ldx #(@end-@start-1)
- lda @start,x
sta $300,x
dex
bpl -
jmp $300
@start
; this will be run from main memory
+READ_ROM_NO_WRITE
sta $C00C ; get out of DHGR mode
sta $C05F ; get out of DHGR mode
jsr $FB2F ; TEXT
jsr $FC58 ; HOME
+READ_RAM1_WRITE_RAM1
rts
@end
BlankHGR
jsr Home
jsr ClearHGR1 ; clear hi-res screen 1
lda $c057 ; show hi-res screen 1 (now blank)
lda $c054
lda $c052
lda $c050
rts
BlankDHGR
jsr Home
jsr ClearHGR1 ; clear hi-res screen 1
sta $C005
jsr ClearHGR1 ; clear hi-res screen 1 in auxmem
sta $C004
sta $c00d
sta $c057
sta $c054
sta $c052
sta $c050
sta $c05e
rts
ClearHGR1
ldx #$20 ; clear hi-res screen 1
stx @a+2
lda #0
tay
@a sta $2000,y
iny
bne @a
inc @a+2
dex
bne @a
rts
; these routines will only be called after relocating to language card
!source "src/ui.attract.mode.a"
!source "src/prodos.path.a"
!source "src/glue.prorwts2.a"
!source "src/okvs.a"
!source "src/wait.a"
!source "src/parse.common.a"
!source "src/parse.games.a"
!source "src/fx/fx.dhgr.fizzle.a"
gGamesListStore
!word *+2 ; address of first okvs store
}

110
src/4cade.init.a Normal file
View File

@ -0,0 +1,110 @@
sta $C00E
sta $C00C
sta $C004
sta $C002
sta $C000
jsr $FB2F
jsr $FC58
jsr Has64K ; check for 64K (required)
bcs @no64K
jsr DisableAccelerator ; set to 1 MHz
jsr Has128K ; check for 128K (absence is OK, we just filter out some games)
ror MachineStatus
jsr HasJoystick ; check for joystick (absence is OK, we just filter out some games)
ror MachineStatus ; now bit 6 = 1 if 128K
; bit 7 = 1 if joystick
jsr init ; initialize ProRWTS2 (bye bye ProDOS)
+READ_RAM1_WRITE_RAM1
ldx #$00 ; relocate rest of program to RAM bank 1 in language card
@FM lda FirstMover,x
sta $D000,x
inx
bne @FM
lda @FM+2
cmp #>LastMover
bcs +
inc @FM+2
inc @FM+5
bne @FM
+
jmp OneTimeSetup
@no64K
ldy #@no64Klen
- lda @s_no64K,y
sta $6B6,y
dey
bpl -
@hang bmi @hang
@s_no64K !raw "REQUIRES 64K"
@no64Klen=*-@s_no64K
; ProRWTS2 has its own function to relocate itself
!source "src/prorwts2.a"
; these routines will only be called once, from main memory, before relocating to language card
ProRWTSBuffer
!source "src/hw.memcheck.a"
!source "src/hw.joystick.a"
!source "src/hw.normfast.a"
*=ProRWTSBuffer+512 ; ProRWTS needs a 512-byte buffer for its init function
; so we reuse as much of the 1-time code as possible
; and fill the rest with zeros
OneTimeSetup
lda hddopendir+1 ; save current directory as 'root'
ldy hddopendir+3
+STAY gRootDirectory
jsr LoadFile ; load games list
!word kGameListConfFile
jsr ParseGamesList ; parse games list
!word gGamesListStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gFXStore ; save pointer to free space for next store
jsr LoadFile ; load HGR transition effects list
!word kFXConfFile
jsr ParseKeyValueList ; parse HGR transition effects list
!word gFXStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gDFXStore ; save pointer to free space for next store
jsr LoadFile ; load DHGR transition effects list
!word kDFXConfFile
jsr ParseKeyValueList ; parse DHGR transition effects list
!word gDFXStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gAttractModeStore ; save pointer to free space for next store
jsr LoadFile ; load attract-mode configuration
!word kAttractModeConfFile
jsr ParseKeyValueList ; parse attract-mode configuration
!word gAttractModeStore
!word ldrlo2 ; (ldrlo2) points to load address
+LDAY SRC
+STAY gSlideshowStore ; save pointer to free space for next store
jmp Main
kGameListConfFile
!byte @kGameListConfFile_e-@kGameListConfFile_b
@kGameListConfFile_b
!text "GAMES.CONF"
@kGameListConfFile_e
kFXConfFile
!byte @kFXConfFile_e-@kFXConfFile_b
@kFXConfFile_b
!text "FX.CONF"
@kFXConfFile_e
kDFXConfFile
!byte @kDFXConfFile_e-@kDFXConfFile_b
@kDFXConfFile_b
!text "DFX.CONF"
@kDFXConfFile_e
kAttractModeConfFile
!byte @kAttractModeConfFile_e-@kAttractModeConfFile_b
@kAttractModeConfFile_b
!text "ATTRACT.CONF"
@kAttractModeConfFile_e

View File

@ -7,6 +7,8 @@
; - LoadFile
; - LoadDHRFile
;
; - promote
;
gRootDirectory
!word $FDFD
@ -184,6 +186,37 @@ traverse
@go
rts
promote
!pseudopc $bf00 {
lda $c08b
clc
bcc @do_enter
;$bf06
rts ;clock interface, must be RTS on real ProDOS if program uses $20x
@do_enter
lda $c08b
jmp ProDOS_enter
!text "q4!"
;$bf10
!word $c1d1, $c2d1, $c3d1, $c4d1, $c5d1, $c6d1, $c7d1
ProDOS_exit
lda $c081
pla ;saved inside ProDOS_enter
tay
pla
tax
lda #0
rts
ProDOS_fatal ;only for debugging, will be removed
lda $c081
jsr $fe89
jsr $fe93
jmp $ff3a
ProDOS_prefix=$bfd0
; !fill $2e
}
end_promote
;------------------------------------------------------------------------------
; ProDOS_enter
; intercept certain ProDOS requests

View File

@ -11,6 +11,8 @@ gAttractModeStore
!word $FDFD
gFXStore
!word $FDFD
gDFXStore
!word $FDFD
gSlideshowStore
!word $FDFD

255
src/ui.attract.mode.a Normal file
View File

@ -0,0 +1,255 @@
;license:MIT
;(c) 2018 by 4am
;
; Mega Attract Mode - cycle through slideshows and self-running demos
;
; Public functions
; - AttractMode
;
AttractMode
jsr okvs_nth ; get filename of next attract-mode module
!word gAttractModeStore
@index !byte 0
+STAY @key
inc @index ; increment module index for next time
jsr okvs_len
!word gAttractModeStore
cmp @index
bne +
lda #0
sta @index
+
jsr okvs_get
!word gAttractModeStore
@key !word $FDFD
+STAY PTR
jsr @RunNextAttractModule
lda $C000
bpl AttractMode
rts
@RunNextAttractModule
ldy #1
lda (PTR),y
and #$0F
cmp #$03
bne @Slideshow
; Self-running demos are loaded into main memory and executed.
; Each binary has been patched to quit on any key and jump back
; to the |Reenter| entry point.
; All demos are strictly 48K / main memory. No demo uses the
; language card or auxiliary memory.
+LOAD_PATH kDemoDirectory
ldy gPathname
iny
iny
sty ProDOS_prefix
- lda gPathname-2, y
sta ProDOS_prefix, y
dey
bne -
lda #'/'
sta ProDOS_prefix+1
lda #'X'
sta ProDOS_prefix+2
+LOAD_FILE_IMM @key
ldx #(@end_prelaunch-@prelaunch-1)
- lda @prelaunch,x ; copy pre-launch code to main memory
sta $100,x
dex
bpl -
ldx #(end_promote-promote-1)
- lda promote,x ; copy tiny ProDOS to main memory
sta $bf00,x
dex
bpl -
jmp $106 ; jump to pre-launch code
!pseudopc $100 {
@prelaunch ; this runs from main memory
lda $C088 ; entry point used by some self-running demos
jmp Reenter
+READ_ROM_NO_WRITE ; entry point to launch game (called above)
jsr $FE89 ; initialize machine like a cold boot
jsr $FE93 ; (many games assume a 'clean slate')
sta $C000
sta $C002
sta $C004
sta $C00C
sta $C00E
jsr $FB2F
jsr $FC58
ldx #$FF
txs
jmp (ldrlo2) ; jump to game
@end_prelaunch
}
@Slideshow ; HGR or DHGR slideshow
pha ; save module type (1=HGR, 2=DHGR)
+LOAD_FILE kAttractModeSlideshowDirectory, @key
jsr ParseKeyValueList ; parse slideshow configuration
!word gSlideshowStore
!word ldrlo2 ; (ldrlo2) points to load address
pla ; restore module type
cmp #$01
beq @HGRSlideshow
@DHGRSlideshow
jsr LoadDHGRTransition ; load transition effect code at $6000
jsr BlankDHGR ; switch to DHGR mode with initial blank screen
jsr okvs_iter ; cycle through all listed DHGR files
!word gSlideshowStore
!word DHGRLoad
jmp BlankHGR ; switch back to HGR mode with initial blank screen
@HGRSlideshow
jsr LoadTransition ; load transition effect code at $6000
jsr okvs_iter ; cycle through all listed HGR files
!word gSlideshowStore
!word HGRLoad
rts
;------------------------------------------------------------------------------
; internal functions
HGRLoad
ldx $C000
bpl +
rts
+
+STAY PTR
; load HGR screenshot at $4000
+LOAD_FILE kHGRScreenshotDirectory, PTR
; jsr LoadTransition
jsr $6000 ; transition effect code was loaded here earlier
jmp WaitOnScreenshot
DHGRLoad
ldx $C000
bpl +
rts
+
; load DHGR screenshot at $4000/main and $4000/aux
+STAY PTR
jsr ResetPath
+LDADDR kDHGRScreenshotDirectory
jsr AddToPath
+LDADDR kPathSeparator
jsr AddToPath
+LDAY PTR
jsr AddToPath
jsr LoadDHRFile
!word gPathname
jsr $6000 ; transition effect code was loaded here earlier
; note: execution falls through here
WaitOnScreenshot
ldx #$20
- lda #0
jsr WaitForKeyWithTimeout
bmi +
dex
bpl -
+ rts
LoadTransition
jsr okvs_nth ; get filename of transition effect code
!word gFXStore
@fxindex !byte 0
+STAY @fxkey
inc @fxindex ; increment transition effect index for next time
jsr okvs_len
!word gFXStore
cmp @fxindex
bne +
lda #0
sta @fxindex
+
; load transition effect code at $6000
+LOAD_FILE kFXDirectory, @fxkey
rts
@fxkey !word $FDFD
LoadDHGRTransition
jsr okvs_nth ; get filename of transition effect code
!word gDFXStore
@dfxindex
!byte 0
+STAY @dfxkey
inc @dfxindex ; increment transition effect index for next time
jsr okvs_len
!word gDFXStore
cmp @dfxindex
bne +
lda #0
sta @dfxindex
+
; load transition effect code at $6000
+LOAD_FILE kFXDirectory, @dfxkey
rts
@dfxkey !word $FDFD
BlankHGR
jsr Home
jsr ClearHGR1 ; clear hi-res screen 1
lda $c057 ; show hi-res screen 1 (now blank)
lda $c054
lda $c052
lda $c050
rts
BlankDHGR
jsr Home
jsr ClearHGR1 ; clear hi-res screen 1
sta $C005
jsr ClearHGR1 ; clear hi-res screen 1 in auxmem
sta $C004
sta $c00d
sta $c057
sta $c054
sta $c052
sta $c050
sta $c05e
rts
ClearHGR1
ldx #$20 ; clear hi-res screen 1
stx @a+2
lda #0
tay
@a sta $2000,y
iny
bne @a
inc @a+2
dex
bne @a
rts
Home
ldx #(@end-@start-1)
- lda @start,x
sta $300,x
dex
bpl -
jmp $300
@start
; this will be run from main memory
+READ_ROM_NO_WRITE
sta $C00C ; get out of DHGR mode
sta $C05F ; get out of DHGR mode
jsr $FB2F ; TEXT
jsr $FC58 ; HOME
+READ_RAM1_WRITE_RAM1
rts
@end