mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-05 01:28:57 +00:00
Moving memory manager up into Language Card RAM.
This commit is contained in:
parent
cd68312dc6
commit
bd1274448d
@ -4,7 +4,7 @@
|
||||
;
|
||||
; See detailed description in mem.i
|
||||
|
||||
* = $800
|
||||
* = $2000 ; PLASMA loader loads us initially at $2000
|
||||
|
||||
; Use hi-bit ASCII for Apple II
|
||||
!convtab "../include/hiBitAscii.ct"
|
||||
@ -13,13 +13,14 @@
|
||||
!source "../include/global.i"
|
||||
!source "../include/mem.i"
|
||||
!source "../include/plasma.i"
|
||||
!source "../include/debug.i"
|
||||
|
||||
; Constants
|
||||
MAX_SEGS = 96
|
||||
|
||||
DO_COMP_CHECKSUMS = 0 ; during compression debugging
|
||||
DEBUG_DECOMP = 0
|
||||
DEBUG = 0
|
||||
DEBUG = 1
|
||||
SANITY_CHECK = 0 ; also prints out request data
|
||||
|
||||
; Zero page temporary variables
|
||||
@ -46,12 +47,94 @@ headerBuf = $4C00 ; len $1400
|
||||
prodosMemMap = $BF58
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Initial vectors - these have to start at $800
|
||||
codeBegin:
|
||||
clc
|
||||
bcc locationCheck
|
||||
jmp main_dispatch
|
||||
jmp aux_dispatch
|
||||
; Relocate all the pieces to their correct locations
|
||||
relocate:
|
||||
; first our lo memory piece goes to $800 (two pages should be plenty)
|
||||
ldy #0
|
||||
- lda loMemBegin,y
|
||||
sta $800,y
|
||||
lda loMemBegin+$100,y
|
||||
sta $900,y
|
||||
iny
|
||||
bne -
|
||||
; copy the ProDOS code from main memory to aux
|
||||
bit setLcRW+lcBank1 ; only copy bank 1, because bank 2 is PLASMA runtime
|
||||
bit setLcRW+lcBank1 ; write to it
|
||||
ldy #0
|
||||
ldx #$D0
|
||||
.pglup stx .ld+2
|
||||
stx .st+2
|
||||
.bylup sta clrAuxZP ; get byte from main LC
|
||||
.ld lda $D000,y
|
||||
sta setAuxZP ; temporarily turn on aux LC
|
||||
.st sta $D000,y
|
||||
iny
|
||||
bne .bylup
|
||||
inx ; all pages until we hit $00
|
||||
bne .pglup
|
||||
sta clrAuxZP ; ...back to main LC
|
||||
; patch into the main ProDOS MLI entry point
|
||||
lda #$4C ; jmp
|
||||
sta $BFBB
|
||||
lda #<enterProDOS1
|
||||
sta $BFBC
|
||||
lda #>enterProDOS1
|
||||
sta $BFBD
|
||||
; patch into the interrupt handler
|
||||
lda #$4C ; jmp
|
||||
sta $BFEB
|
||||
lda #<enterProDOS2
|
||||
sta $BFEC
|
||||
lda #>enterProDOS2
|
||||
sta $BFED
|
||||
; patch into the shared MLI/IRQ exit routine
|
||||
lda #$4C ; jmp
|
||||
sta $BFA0
|
||||
lda #<exitProDOS
|
||||
sta $BFA1
|
||||
lda #>exitProDOS
|
||||
sta $BFA2
|
||||
; now blow away the main RAM LC area as a check
|
||||
ldx #$D0
|
||||
lda #0
|
||||
tay
|
||||
.clrlup stx .st2+2
|
||||
.st2 sta $D000,Y
|
||||
iny
|
||||
bne .st2
|
||||
inx
|
||||
cpx #$F8
|
||||
bne .clrlup
|
||||
; it's very convenient to have the monitor in the LC for debugging
|
||||
bit setLcWr+lcBank1 ; read from ROM, write to LC RAM
|
||||
.cpmon stx .ld3+2
|
||||
stx .st3+2
|
||||
.ld3 lda $F800,Y
|
||||
.st3 sta $F800,Y
|
||||
iny
|
||||
bne .ld3
|
||||
inx
|
||||
bne .cpmon
|
||||
; Place the bulk of the memory manager code into the newly cleared LC
|
||||
ldx #>hiMemBegin
|
||||
.cpmm stx .ld4+2
|
||||
.ld4 lda hiMemBegin,y
|
||||
.st4 sta $D000,y
|
||||
iny
|
||||
bne .ld4
|
||||
inc .st4+2
|
||||
inx
|
||||
cpx #>(hiMemEnd+$100)
|
||||
bne .cpmm
|
||||
; Ready to actually init the memory manager in its final location.
|
||||
; fall through to j_init...
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vectors and debug support code - these go in low memory at $800
|
||||
loMemBegin: !pseudopc $800 {
|
||||
jmp j_init
|
||||
jmp j_main_dispatch
|
||||
jmp j_aux_dispatch
|
||||
jmp __asmPlasm
|
||||
|
||||
; Vectors for debug macros
|
||||
@ -65,46 +148,131 @@ codeBegin:
|
||||
jmp __crout
|
||||
jmp __waitKey
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Relocation code
|
||||
locationCheck:
|
||||
jsr monrts
|
||||
tsx
|
||||
lda $100,x
|
||||
cmp #>locationCheck
|
||||
bne +
|
||||
jmp init
|
||||
+ sta pSrc+1
|
||||
lda #>*
|
||||
sta pDst+1
|
||||
ldy #0
|
||||
sty pSrc
|
||||
sty pDst
|
||||
ldx #>(tableEnd-codeBegin+$100)
|
||||
- lda (pSrc),y
|
||||
sta (pDst),y
|
||||
iny
|
||||
bne -
|
||||
inc pSrc+1
|
||||
inc pDst+1
|
||||
dex
|
||||
bne -
|
||||
jmp codeBegin
|
||||
j_init:
|
||||
bit setLcRW+lcBank1 ; switch in mem mgr
|
||||
bit setLcRW+lcBank1
|
||||
jsr init
|
||||
bit setLcRW+lcBank2 ; back to PLASMA
|
||||
rts
|
||||
|
||||
j_main_dispatch:
|
||||
bit setLcRW+lcBank1 ; switch in mem mgr
|
||||
bit setLcRW+lcBank1
|
||||
jsr main_dispatch
|
||||
bit setLcRW+lcBank2 ; back to PLASMA
|
||||
rts
|
||||
|
||||
j_aux_dispatch:
|
||||
bit setLcRW+lcBank1 ; switch in mem mgr
|
||||
bit setLcRW+lcBank1
|
||||
jsr aux_dispatch
|
||||
bit setLcRW+lcBank2 ; back to PLASMA
|
||||
rts
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Variables
|
||||
targetAddr: !word 0
|
||||
unusedSeg: !byte 0
|
||||
scanStart: !byte 0, 1 ; main, aux
|
||||
segNum: !byte 0
|
||||
nextLdVec: jmp diskLoader
|
||||
curPartition: !byte 0
|
||||
partFileRef: !byte 0
|
||||
fixupHint: !word 0
|
||||
; Normal entry point for ProDOS MLI calls. This patches the code at $BFBB.
|
||||
enterProDOS1: !zone
|
||||
pla ; saved A reg
|
||||
sta .ld2+1
|
||||
pla ; lo byte of ret addr
|
||||
sta .ld1+1
|
||||
pla ; hi byte of ret addr
|
||||
sta setAuxZP ; switch to aux stack/ZP/LC
|
||||
pha ; hi byte of ret addr
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha ; lo byte of ret addr
|
||||
.ld2 lda #11 ; saved A reg
|
||||
pha
|
||||
lda $E000 ; this is what the original code at $BFBB did
|
||||
jmp $BFBE ; jump back in where ProDOS enter left off
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
!source "../include/debug.i"
|
||||
; Entry point for ProDOS interrupt handler. This patches the code at $BFEB.
|
||||
enterProDOS2: !zone
|
||||
pla ; saved P reg
|
||||
sta .ld2+1
|
||||
pla ; ret addr lo
|
||||
sta .ld1+1
|
||||
pla ; ret addr hi
|
||||
sta setAuxZP ; switch to aux stack/ZP/LC
|
||||
pha
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha
|
||||
.ld2 lda #11 ; ditto
|
||||
pha
|
||||
bit $C08B ; this is what the original code at $BFEB did
|
||||
jmp $BFEE ; back to where ProDOS left off
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Shared exit point for ProDOS MLI and IRQ handlers. This patches the code
|
||||
; at $BFA0.
|
||||
exitProDOS: !zone
|
||||
pla ; saved A reg
|
||||
sta .ld3+1
|
||||
pla ; P-reg for RTI
|
||||
sta .ld2+1
|
||||
pla ; hi byte of ret addr
|
||||
sta .ld1+1
|
||||
pla ; lo byte of ret addr
|
||||
sta clrAuxZP ; back to main stack/ZP/LC
|
||||
pha ; lo byte of ret addr
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha ; hi byte of ret addr
|
||||
.ld2 lda #11 ; ditto
|
||||
pha ; P-reg for RTI
|
||||
.ld3 lda #11 ; self-modified earlier (the saved A reg)
|
||||
; Note! We leave LC bank 1 enabled, since that's where the memory
|
||||
; manager lives, and it's the only code that calls ProDOS.
|
||||
rti ; RTI pops P-reg and *exact* return addr (not adding 1)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Utility routine for convenient assembly routines in PLASMA code.
|
||||
; Params: Y=number of parameters passed from PLASMA routine
|
||||
; 1. Save PLASMA's X register index to evalStk
|
||||
; 2. Verify X register is in the range 0-$10
|
||||
; 3. Load the *last* parameter into A=lo, Y=hi
|
||||
; 4. Run the calling routine (X still points into evalStk for add'l params if needed)
|
||||
; 5. Restore PLASMA's X register, and advance it over the parameter(s)
|
||||
; 6. Store A=lo/Y=hi into PLASMA return value
|
||||
; 7. Return to PLASMA
|
||||
__asmPlasm: !zone
|
||||
pla ; save address of calling routine, so we can call it
|
||||
clc
|
||||
adc #1
|
||||
sta .jsr+1
|
||||
pla
|
||||
adc #0
|
||||
sta .jsr+2
|
||||
; adjust PLASMA stack pointer to skip over params
|
||||
dey
|
||||
sty tmp
|
||||
txa
|
||||
cpx #$11
|
||||
bcs .badx ; X must be in range 0..$10
|
||||
.add adc tmp ; carry cleared by cpx above
|
||||
pha ; and save that
|
||||
cmp #$11 ; again, X must be in range 0..$10
|
||||
bcs .badx
|
||||
lda evalStkL,x ; get last param to A=lo
|
||||
ldy evalStkH,x ; ...Y=hi
|
||||
.jsr jsr $1111 ; call the routine to do work
|
||||
sta tmp ; stash return value lo
|
||||
pla
|
||||
tax ; restore adjusted PLASMA stack pointer
|
||||
lda tmp
|
||||
sta evalStkL,x ; store return value
|
||||
tya
|
||||
sta evalStkH,x
|
||||
rts ; and return to PLASMA interpreter
|
||||
.badx ; X reg ran outside valid range. Print and abort.
|
||||
+prStr : !text $8D,"X=",0
|
||||
+prX
|
||||
ldx #<+
|
||||
ldy #>+
|
||||
jmp fatalError
|
||||
+ !text $8D, "PLASMA x-reg out of range", 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Debug code to support macros
|
||||
|
||||
; Fetch a byte pointed to by the first entry on the stack, and advance that entry.
|
||||
@ -216,6 +384,66 @@ __waitKey: !zone {
|
||||
jmp iorest
|
||||
}
|
||||
|
||||
!macro callMLI cmd, parms {
|
||||
lda #cmd
|
||||
ldx #<parms
|
||||
ldy #>parms
|
||||
jsr _callMLI
|
||||
}
|
||||
|
||||
; Call MLI from main memory rather than LC, since it lives in aux LC.
|
||||
_callMLI: sta .cmd
|
||||
stx .params
|
||||
sty .params+1
|
||||
jsr mli
|
||||
.cmd !byte 0
|
||||
.params !word 0
|
||||
rts
|
||||
|
||||
; Out ProDOS param blocks can't be in LC ram
|
||||
openParams: !byte 3 ; param count
|
||||
!word filename ; pointer to file name
|
||||
!word fileBuf ; pointer to buffer
|
||||
openFileRef: !byte 0 ; returned file number
|
||||
filename: !byte 15 ; length
|
||||
!raw "/LL/GAME.PART." ; TODO: Figure out how to avoid specifying full path. "raw" for ProDOS
|
||||
; If I leave it out, ProDOS complains with error $40.
|
||||
partNumChar: !raw "x" ; "x" replaced by partition number
|
||||
|
||||
readParams: !byte 4 ; param count
|
||||
readFileRef: !byte 0 ; file ref to read
|
||||
readAddr: !word 0
|
||||
readLen: !word 0
|
||||
readGot: !word 0
|
||||
|
||||
setMarkParams: !byte 2 ; param count
|
||||
setMarkFileRef: !byte 0 ; file reference to set mark in
|
||||
setMarkPos: !byte 0 ; mark position (3 byte integer)
|
||||
!byte 0
|
||||
!byte 0
|
||||
|
||||
closeParams: !byte 1 ; param count
|
||||
closeFileRef: !byte 0 ; file ref to close
|
||||
|
||||
paramsEnd = *
|
||||
} ; end of !pseodupc $800
|
||||
loMemEnd = *
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; The remainder of the code gets relocated up into the Language Card, bank 1.
|
||||
hiMemBegin: !pseudopc $D000 {
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Variables
|
||||
targetAddr: !word 0
|
||||
unusedSeg: !byte 0
|
||||
scanStart: !byte 0, 1 ; main, aux
|
||||
segNum: !byte 0
|
||||
nextLdVec: jmp diskLoader
|
||||
curPartition: !byte 0
|
||||
partFileRef: !byte 0
|
||||
fixupHint: !word 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
grabSegment: !zone
|
||||
; Input: None
|
||||
@ -541,8 +769,6 @@ init: !zone
|
||||
; put something interesting on the screen :)
|
||||
jsr home
|
||||
+prStr : !text "Welcome to Mythos.",0
|
||||
; relocate ProDOS to the aux LC bank
|
||||
jsr moveProDOS
|
||||
; close all files
|
||||
lda #0
|
||||
jsr closeFile
|
||||
@ -623,9 +849,9 @@ init: !zone
|
||||
sty tSegAdrHi+3
|
||||
dey
|
||||
sty tSegAdrHi+7
|
||||
lda #<tableEnd
|
||||
lda #<paramsEnd
|
||||
sta tSegAdrLo+4
|
||||
lda #>tableEnd
|
||||
lda #>paramsEnd
|
||||
sta tSegAdrHi+4
|
||||
lda #$40
|
||||
sta tSegAdrHi+5
|
||||
@ -650,6 +876,10 @@ init: !zone
|
||||
lda #$20
|
||||
sta framePtr+1 ; because sanity check verifies it's not $BE or $BF
|
||||
}
|
||||
|
||||
jsr printMem
|
||||
brk
|
||||
|
||||
ldx #0
|
||||
ldy #2 ; 2 pages
|
||||
lda #REQUEST_MEMORY
|
||||
@ -691,132 +921,6 @@ init: !zone
|
||||
ldx #$10 ; initial eval stack index
|
||||
.gomod: jmp $1111 ; jump to module for further bootstrapping
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
moveProDOS: !zone
|
||||
; only do this once
|
||||
lda $BFBB
|
||||
cmp #$4C
|
||||
bne +
|
||||
rts
|
||||
+
|
||||
; copy the ProDOS code from main memory to aux
|
||||
ldy #0
|
||||
ldx #$D0
|
||||
bit setLcRW+lcBank1 ; turn on language card
|
||||
bit setLcRW+lcBank1 ; for writing
|
||||
.pglup stx .ld+2
|
||||
stx .st+2
|
||||
.bylup sta clrAuxZP
|
||||
.ld lda $D000,Y
|
||||
sta setAuxZP
|
||||
.st sta $D000,Y
|
||||
iny
|
||||
bne .bylup
|
||||
inx
|
||||
bne .pglup
|
||||
sta clrAuxZP
|
||||
; patch into the main ProDOS MLI entry point
|
||||
lda #$4C ; jmp
|
||||
sta $BFBB
|
||||
lda #<enterProDOS1
|
||||
sta $BFBC
|
||||
lda #>enterProDOS1
|
||||
sta $BFBD
|
||||
; patch into the interrupt handler
|
||||
lda #$4C ; jmp
|
||||
sta $BFEB
|
||||
lda #<enterProDOS2
|
||||
sta $BFEC
|
||||
lda #>enterProDOS2
|
||||
sta $BFED
|
||||
; patch into the shared MLI/IRQ exit routine
|
||||
lda #$4C ; jmp
|
||||
sta $BFA0
|
||||
lda #<exitProDOS
|
||||
sta $BFA1
|
||||
lda #>exitProDOS
|
||||
sta $BFA2
|
||||
; now blow away the main LC area as a check
|
||||
bit setLcWr+lcBank1 ; only clear bank 1, because bank 2 is PLASMA runtime
|
||||
bit setLcWr+lcBank1 ; write to it
|
||||
ldx #$D0
|
||||
lda #0
|
||||
tay
|
||||
.clrlup stx .st2+2
|
||||
.st2 sta $D000,Y
|
||||
iny
|
||||
bne .st2
|
||||
inx
|
||||
cpx #$F8
|
||||
bne .clrlup
|
||||
; it's very convenient to have the monitor in the LC
|
||||
.cpmon stx .ld3+2
|
||||
stx .st3+2
|
||||
.ld3 lda $F800,Y
|
||||
.st3 sta $F800,Y
|
||||
iny
|
||||
bne .ld3
|
||||
inx
|
||||
bne .cpmon
|
||||
; all done
|
||||
.done rts
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Normal entry point for ProDOS MLI calls. This patches the code at $BFBB.
|
||||
enterProDOS1: !zone
|
||||
pla ; saved A reg
|
||||
sta .ld2+1
|
||||
pla ; lo byte of ret addr
|
||||
sta .ld1+1
|
||||
pla ; hi byte of ret addr
|
||||
sta setAuxZP ; switch to aux stack/ZP/LC
|
||||
pha ; hi byte of ret addr
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha ; lo byte of ret addr
|
||||
.ld2 lda #11 ; saved A reg
|
||||
pha
|
||||
lda $E000 ; this is what the original code at $BFBB did
|
||||
jmp $BFBE ; jump back in where ProDOS enter left off
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Entry point for ProDOS interrupt handler. This patches the code at $BFEB.
|
||||
enterProDOS2: !zone
|
||||
pla ; saved P reg
|
||||
sta .ld2+1
|
||||
pla ; ret addr lo
|
||||
sta .ld1+1
|
||||
pla ; ret addr hi
|
||||
sta setAuxZP ; switch to aux stack/ZP/LC
|
||||
pha
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha
|
||||
.ld2 lda #11 ; ditto
|
||||
pha
|
||||
bit $C08B ; this is what the original code at $BFEB did
|
||||
jmp $BFEE ; back to where ProDOS left off
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Shared exit point for ProDOS MLI and IRQ handlers. This patches the code
|
||||
; at $BFA0.
|
||||
exitProDOS: !zone
|
||||
pla ; saved A reg
|
||||
sta .ld3+1
|
||||
pla ; P-reg for RTI
|
||||
sta .ld2+1
|
||||
pla ; hi byte of ret addr
|
||||
sta .ld1+1
|
||||
pla ; lo byte of ret addr
|
||||
sta clrAuxZP ; back to main stack/ZP/LC
|
||||
bit setLcRW+lcBank2 ; switch in PLASMA
|
||||
bit setLcRW+lcBank2 ; for write as well as read
|
||||
pha ; lo byte of ret addr
|
||||
.ld1 lda #11 ; self-modified earlier
|
||||
pha ; hi byte of ret addr
|
||||
.ld2 lda #11 ; ditto
|
||||
pha ; P-reg for RTI
|
||||
.ld3 lda #11 ; self-modified earlier (the saved A reg)
|
||||
rti ; RTI pops P-reg and *exact* return addr (not adding 1)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
!if DEBUG {
|
||||
printMem: !zone
|
||||
@ -1332,14 +1436,12 @@ openPartition: !zone
|
||||
lda curPartition
|
||||
clc
|
||||
adc #'0' ; assume partition numbers range from 0..9 for now
|
||||
sta .partNumChar
|
||||
sta partNumChar
|
||||
; open the file
|
||||
jsr mli
|
||||
!byte MLI_OPEN
|
||||
!word .openParams
|
||||
+callMLI MLI_OPEN, openParams
|
||||
bcs prodosError
|
||||
; grab the file number, since we're going to keep it open
|
||||
lda .openFileRef
|
||||
lda openFileRef
|
||||
sta partFileRef
|
||||
sta readFileRef
|
||||
; Read the first two bytes, which tells us how long the header is.
|
||||
@ -1361,21 +1463,6 @@ openPartition: !zone
|
||||
sta readAddr
|
||||
jmp readToMain ; finish by reading the rest of the header
|
||||
|
||||
.openParams: !byte 3 ; number of params
|
||||
!word .filename ; pointer to file name
|
||||
!word fileBuf ; pointer to buffer
|
||||
.openFileRef: !byte 0 ; returned file number
|
||||
.filename: !byte 15 ; length
|
||||
!raw "/LL/GAME.PART." ; TODO: Figure out how to avoid specifying full path. "raw" for ProDOS
|
||||
; If I leave it out, ProDOS complains with error $40.
|
||||
.partNumChar: !raw "x" ; "x" replaced by partition number
|
||||
|
||||
readParams: !byte 4 ; number of params
|
||||
readFileRef: !byte 0
|
||||
readAddr: !word 0
|
||||
readLen: !word 0
|
||||
readGot: !word 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
prodosError: !zone
|
||||
pha
|
||||
@ -1500,14 +1587,14 @@ disk_finishLoad: !zone
|
||||
lda partFileRef ; see if we actually queued anything (and opened the file)
|
||||
bne + ; non-zero means we have work to do
|
||||
rts ; nothing to do - return immediately
|
||||
+ sta .setMarkFileRef ; copy the file ref number to our MLI param blocks
|
||||
+ sta setMarkFileRef ; copy the file ref number to our MLI param blocks
|
||||
sta readFileRef
|
||||
lda headerBuf ; grab # header bytes
|
||||
sta .setMarkPos ; set to start reading at first non-header byte in file
|
||||
sta setMarkPos ; set to start reading at first non-header byte in file
|
||||
lda headerBuf+1 ; hi byte too
|
||||
sta .setMarkPos+1
|
||||
sta setMarkPos+1
|
||||
lda #0
|
||||
sta .setMarkPos+2
|
||||
sta setMarkPos+2
|
||||
sta .nFixups
|
||||
jsr setupDecomp ; one-time init for decompression code
|
||||
jsr startHeaderScan ; start scanning the partition header
|
||||
@ -1573,9 +1660,7 @@ disk_finishLoad: !zone
|
||||
lda tSegAdrHi,x ; hi byte too
|
||||
sta pDst+1
|
||||
!if DEBUG { jsr .debug2 }
|
||||
jsr mli ; move the file pointer to the current block
|
||||
!byte MLI_SET_MARK
|
||||
!word .setMarkParams
|
||||
+callMLI MLI_SET_MARK, setMarkParams ; move the file pointer to the current block
|
||||
bcs .prodosErr
|
||||
!if DEBUG >= 2 { +prStr : !text "Deco.",0 }
|
||||
jsr lz4Decompress ; decompress (or copy if uncompressed)
|
||||
@ -1583,18 +1668,18 @@ disk_finishLoad: !zone
|
||||
.resume ldy .ysave
|
||||
.next lda (pTmp),y ; lo byte of length
|
||||
clc
|
||||
adc .setMarkPos ; advance mark position exactly that far
|
||||
sta .setMarkPos
|
||||
adc setMarkPos ; advance mark position exactly that far
|
||||
sta setMarkPos
|
||||
iny
|
||||
lda (pTmp),y ; hi byte of length
|
||||
bpl + ; if hi bit is clear, resource is uncompressed
|
||||
iny ; skip compressed size
|
||||
iny
|
||||
and #$7F ; mask off the flag
|
||||
+ adc .setMarkPos+1 ; bump the high byte of the file mark pos
|
||||
sta .setMarkPos+1
|
||||
+ adc setMarkPos+1 ; bump the high byte of the file mark pos
|
||||
sta setMarkPos+1
|
||||
bcc +
|
||||
inc .setMarkPos+2 ; account for partitions > 64K
|
||||
inc setMarkPos+2 ; account for partitions > 64K
|
||||
+ iny ; increment to next entry
|
||||
bpl + ; if Y index is is small, no need to adjust
|
||||
jsr adjYpTmp ; adjust pTmp and Y to make it small again
|
||||
@ -1604,11 +1689,6 @@ disk_finishLoad: !zone
|
||||
.addrErr:
|
||||
jmp invalAddr
|
||||
|
||||
.setMarkParams: !byte 2 ; param count
|
||||
.setMarkFileRef:!byte 0 ; file reference
|
||||
.setMarkPos: !byte 0 ; mark position (3 byte integer)
|
||||
!byte 0
|
||||
!byte 0
|
||||
.ysave: !byte 0
|
||||
.nFixups: !byte 0
|
||||
|
||||
@ -1652,24 +1732,16 @@ adjYpTmp: !zone
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
closeFile: !zone
|
||||
sta .closeFileRef
|
||||
jsr mli ; now that we're done loading, we can close the partition file
|
||||
!byte MLI_CLOSE
|
||||
!word .closeParams
|
||||
sta closeFileRef
|
||||
+callMLI MLI_CLOSE, closeParams
|
||||
bcs .prodosErr
|
||||
rts
|
||||
.prodosErr:
|
||||
jmp prodosError
|
||||
.closeParams:
|
||||
!byte 1 ; param count
|
||||
.closeFileRef:
|
||||
!byte 0 ; file ref to close
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
readToMain: !zone
|
||||
jsr mli
|
||||
!byte MLI_READ
|
||||
!word readParams
|
||||
+callMLI MLI_READ, readParams
|
||||
bcs .err
|
||||
rts
|
||||
.err: jmp prodosError
|
||||
@ -2187,58 +2259,6 @@ doAllFixups: !zone
|
||||
.mainBase !word 0
|
||||
.auxBase !word 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Utility routine for convenient assembly routines in PLASMA code.
|
||||
; Params: Y=number of parameters passed from PLASMA routine
|
||||
; 1. Save PLASMA's X register index to evalStk
|
||||
; 2. Verify X register is in the range 0-$10
|
||||
; 3. Switch to ROM
|
||||
; 4. Load the *last* parameter into A=lo, Y=hi
|
||||
; 5. Run the calling routine (X still points into evalStk for add'l params if needed)
|
||||
; 6. Switch back to LC RAM
|
||||
; 7. Restore PLASMA's X register, and advance it over the parameter(s)
|
||||
; 8. Store A=lo/Y=hi into PLASMA return value
|
||||
; 9. Return to PLASMA
|
||||
__asmPlasm: !zone
|
||||
pla ; save address of calling routine, so we can call it
|
||||
clc
|
||||
adc #1
|
||||
sta .jsr+1
|
||||
pla
|
||||
adc #0
|
||||
sta .jsr+2
|
||||
; adjust PLASMA stack pointer to skip over params
|
||||
dey
|
||||
sty tmp
|
||||
txa
|
||||
cpx #$11
|
||||
bcs .badx ; X must be in range 0..$10
|
||||
.add adc tmp ; carry cleared by cpx above
|
||||
pha ; and save that
|
||||
cmp #$11 ; again, X must be in range 0..$10
|
||||
bcs .badx
|
||||
lda evalStkL,x ; get last param to A=lo
|
||||
ldy evalStkH,x ; ...Y=hi
|
||||
.jsr jsr $1111 ; call the routine to do work
|
||||
sta tmp ; stash return value lo
|
||||
pla
|
||||
tax ; restore adjusted PLASMA stack pointer
|
||||
lda tmp
|
||||
sta evalStkL,x ; store return value
|
||||
tya
|
||||
sta evalStkH,x
|
||||
rts ; and return to PLASMA interpreter
|
||||
.badx jsr crout ; X reg ran outside valid range. Print and abort.
|
||||
lda #'X'
|
||||
jsr cout
|
||||
txa
|
||||
jsr prbyte
|
||||
jsr crout
|
||||
ldx #<+
|
||||
ldy #>+
|
||||
jmp fatalError
|
||||
+ !text $8D, "PLASMA x-reg out of range", 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Segment tables
|
||||
|
||||
@ -2253,3 +2273,6 @@ tSegAdrHi = * : !fill MAX_SEGS
|
||||
;------------------------------------------------------------------------------
|
||||
; Marker for end of the tables, so we can compute its length
|
||||
tableEnd = *
|
||||
|
||||
} ; end of !pseudopc $D000
|
||||
hiMemEnd = *
|
Loading…
Reference in New Issue
Block a user