4cade/src/4cade.a

220 lines
8.0 KiB
Plaintext

;license:MIT
;(c) 2018-2020 by 4am
;
!cpu 6502
!to "build/LAUNCHER.SYSTEM",plain
*=$2000
!ifndef RELBASE {
RELBASE=$2000
}
!source "src/constants.a" ; no code in these
!source "src/macros.a"
; first-run initialization, relocates code to language card and jumps
; to |Reenter|
!source "src/4cade.init.a"
!source "src/4cade.init.cffa.a"
!source "src/4cade.init.gs.a"
FirstMover
!pseudopc RELBASE {
;------------------------------------------------------------------------------
; Reenter
; This is the primary entry point for returning to the launcher from anywhere.
; - Self-running demos call this when the user presses a key or when the demo
; cycles ends naturally.
; - It is set as the reset vector, so the user can play a game then press
; Ctrl-Reset to return to the launcher and choose another.
; - It also functions as a reset vector while the launcher is running.
; - It is also called on program startup, after the first-run initialization.
;
; When execution reaches this point, we may have previously backed up the stack
; and stack pointer, in which case it is now our job to restore it and return
; to the caller. This allows magic like 'JSR PlayGame' then continuing once the
; JSR returns.
;
; If there is no stack to restore, this exits via SearchMode.
;
; in: none
; out: see above
;------------------------------------------------------------------------------
Reenter
cld
sta $C000 ; Turn 80STORE switch off
ldx #$ff
txs ; so that we never trash the reset vector
jsr SwitchToBank2
jsr DisableAccelerator ; back to 1 MHz (especially important on IIgs
; which restores default speed on Ctrl-Reset)
jsr CloseHandles ; close any open handles to restore ProRWTS
ldx #(end_promote-promote-1)
- lda promote,x ; copy ProDOS shim to main memory for GS/OS exit
sta $bf00,x
dex
bpl -
ldx #5
- lda ResetVector,x ; copy reentry wrapper to bottom of stack
sta $100,x ; (used as reset vector because //e always
dex ; switches to ROM on Ctrl-Reset)
bpl -
inx
stx $3F2 ; page 3 reset vector to ($100)
sei
stx $3FE ; page 3 IRQ vector to ($100)
inx
stx $3FF
cli
stx $3F3
ldx #$A4
stx $3F4
RestoreStackNextTime
bne SearchMode ; (SMC) not an unconditional branch because code
; might change the branch target to the next opcode
; If we fall through to here, it's because we backed up the stack and
; stack pointer and wanted this routine to restore it and return to
; caller.
lda #(SearchMode - RestoreStackNextTime) - 2
; reset to branch so we don't try to
sta RestoreStackNextTime + 1
; restore the same stack twice
STACKPTR
ldx #$D1 ; SMC, restore stack pointer
txs
inx
- lda STACKBASE - $100 + gStackSize,x
; restore stack
sta $100,x
inx
bne -
SwitchToBank1
+READ_RAM1_WRITE_RAM1
rts
ResetVector ; 6 bytes, copied to $100
+READ_RAM1_NO_WRITE
jmp Reenter
; these routines will only be called after relocating to language card
!source "src/ui.search.mode.a" ; \__ execution falls through
!source "src/ui.animation.a" ; /
!source "src/ui.browse.mode.a"
!source "src/ui.attract.mode.a"
!source "src/ui.attract.hgr.a"
!source "src/ui.attract.dhgr.a"
!source "src/ui.attract.shr.a"
!source "src/ui.attract.gr.a"
!source "src/ui.attract.dgr.a"
!source "src/ui.offscreen.a"
!source "src/ui.cheats.a"
!source "src/ui.credits.a"
!source "src/ui.reboot.a"
!source "src/ui.common.a"
!source "src/ui.font.a"
!source "src/ui.overlay.a"
!source "src/parse.prefs.a"
!source "src/glue.launch.a"
!source "src/glue.prorwts2.a"
!source "src/glue.decompress.a"
!source "src/textrank.a"
!source "src/okvs.a"
!source "src/wait.a"
; add new files above here
!source "src/hw.vbl.a"
!source "src/ui.wait.a"
gMegaAttractModeFilter ; module types to include in mega-attract mode
!byte %11111111
; |||||||+- bit 0 include self-running demos
; ||||||+-- bit 1 include HGR title slideshows
; |||||+--- bit 2 include HGR action slideshows
; ||||+---- bit 3 include DHGR title slideshows
; |||+----- bit 4 include DHGR action slideshows
; ||+------ bit 5 include SHR box art slideshows
; |+------- bit 6 include GR action slideshows
; +-------- bit 7 include DGR action slideshows
gSearchStore
!word $6000
gSlideshowStore
!word $0800
gGlobalPrefsStore
!word $D001 ; leave $D000 alone because FastChip accelerator
; flips out if it has certain values (it will
; be set to $55 as part of the 64K memory test,
; which is apparently one of the acceptable values)
SwitchToBank2
+READ_RAM2_WRITE_RAM2
rts
!source "src/prodos.path.a" ; paths end up on the same page
; iLoadXSingle (label is in constants.a)
jmp LoadXSingle ; no direct calling - target can move
; iAddToPath (label is in constants.a)
jmp AddToPath ; no direct calling - target can move
; iLoadFileDirect (label is in constants.a)
jmp LoadFileDirect ; no direct calling - target can move
; WaitForVBL (label is in constants.a)
jmp WaitForVBL_iie ; SMC to RTS on a II+
; UnwaitForVBL (label is in constants.a)
rts ; SMC to JMP on a IIc
!word iUnwaitForVBL
; MockingboardStuff (label is in constants.a)
; slot number where Mockingboard was detected and type of board
; #$00 if no Mockingboard detected
!byte $FD ; MockingboardStuff ($FFF8)
; MachineStatus (label is in constants.a so prelaunchers can use it)
; 7 6 5 4 3 2 1 0
; | | | | | | | +- bit 0 reserved
; | | | | | | +--- bit 1 reserved
; | | | | | +----- bit 2 reserved
; | | | | +------- bit 3 = 1 if cheats are enabled
; | | | +--------- bit 4 = 1 if VidHD
; | | +----------- bit 5 = 1 if IIgs
; | +------------- bit 6 = 1 if 128K
; +--------------- bit 7 = 1 if joystick
; Use the bit masks defined in constants.a
!byte $FD ; MachineStatus ($FFF9)
!word Reenter ; NMI vector ($FFFA-B)
!word Reenter ; reset vector ($FFFC-D)
!word Ignore ; IRQ vector ($FFFE-F)
}
LastMover
COPYSRC = *
!pseudopc hdddataend {
COPYDST = *
!source "src/prodos.impl.lc2.a"
!source "src/glue.prorwts2.lc2.a"
!source "src/glue.launch.lc2.a"
!source "src/hw.accel.lc2.a"
STACKBASE = *
OKVS_CACHE = STACKBASE + gStackSize
LCRAM2_END = OKVS_CACHE + 5
!if LCRAM2_END >= DisableAccelerator {
!error "code is too large: ends at ", LCRAM2_END
}
FONTDST = $E000
}
EvenLasterMover
FONTSRC = *
!pseudopc FONTDST {
!source "src/ui.font.data.a"
}
!if RELBASE = $2000 {
!ifdef PASS2 {
} else { ;PASS2
!set PASS2=1
!warn "ProRWTS ends at ", hdddataend - 1
!warn "STACK at ", STACKBASE
!warn "OKVS CACHE at ", OKVS_CACHE
!warn "LCRAM2 ends at ", LCRAM2_END
!warn "RELBASE = ", $10000 - (LastMover - FirstMover)
}
}