Files
erkyrath.infocom-zcode-terps/acorn/paging.asm
Andrew Plotkin b642da811e Initial commit.
2023-11-16 18:19:54 -05:00

205 lines
3.8 KiB
NASM

PAGE
SBTTL "--- PAGING ROUTINES ---"
; -------------------------
; FETCH NEXT BYTE OF Z-CODE
; -------------------------
; EXIT: BYTE AT [ZPC] IN [A] & [Y], FLAGS SET
NEXTPC: LDA ZPCFLG ; HAS PAGE CHANGED?
BEQ NEWZ ; APPARENTLY SO
NPC: LDY ZPCL
LDA (ZPCPNT),Y ; GRAB A Z-BYTE
IF DEBUG
STA MBYTE
LDA #1 ; BREAKPOINT #1
JSR DOBUG
LDA MBYTE
ENDIF
INC ZPCL
BNE NXTX
LDY #0
STY ZPCFLG
INC ZPCM ; POINT [ZPC] TO NEXT PAGE
BNE NXTX
INC ZPCH
NXTX: TAY ; SET FLAGS
RTS
; --------------
; SWITCH Z-PAGES
; --------------
NEWZ: LDA ZPCM ; GET LSB OF TARGET INTO [A]
LDY ZPCH ; AND MSB INTO [Y]
BNE NZ0 ; SWAP IF MSB <> 0
CMP ZPURE ; IS PAGE IN PRELOAD?
BCS NZ0 ; NO, SWAP IT IN
ADC ZCODE ; ELSE CALC ABSOLUTE PAGE
BNE NZ1 ; AND GIVE IT TO [ZPCPNT]
NZ0: LDX #0
STX MPCFLG ; INVALIDATE [MPC]
JSR PAGE ; LOCATE PAGE [A/Y] IN SWAPPING SPACE
NZ1: STA ZPCPNT+HI ; AND UPDATE MSB OF POINTER
LDX #$FF
STX ZPCFLG ; VALIDATE [ZPC]
INX ; (= 0) CLEAR LSB
STX ZPCPNT+LO ; OF [ZPCPNT]
BEQ NPC ; GET THE BYTE
; -------------------------------
; GET NEXT BYTE OF VIRTUAL MEMORY
; -------------------------------
; EXIT: BYTE AT [MPC] IN [A] & [Y], FLAGS SET
GETBYT: LDA MPCFLG ; [MPC] VALID?
BEQ NEWM ; NO, SWITCH PAGES
GTB: LDY MPCL ; GRAB NEXT BYTE
LDA (MPCPNT),Y
IF DEBUG
STA MBYTE
LDA #2 ; BREAKPOINT #2
JSR DOBUG
LDA MBYTE
ENDIF
INC MPCL ; END OF THIS PAGE?
BNE NXMX ; NO, CONTINUE
LDY #0 ; ELSE INVALIDATE
STY MPCFLG ; [MPC]
INC MPCM ; POINT [MPC] TO
BNE NXMX ; NEXT PAGE
INC MPCH
NXMX: TAY ; SET FLAGS
RTS
; --------------
; SWITCH M-PAGES
; --------------
NEWM: LDA MPCM ; GET LSB AND
LDY MPCH ; MSB OF TARGET PAGE
BNE NM0 ; SWAP IF MSB <> 0
PATCH EQU $+1 ; PATCH POINT FOR "VERIFY"
CMP ZPURE ; TARGET IN PRELOAD?
BCS NM0 ; NO, SWAP IT IN
ADC ZCODE ; ELSE MAKE IT ABSOLUTE
BNE NM1 ; AND GIVE TO [MPCPNT]
NM0: LDX #0
STX ZPCFLG ; INVALIDATE [ZPC]
JSR PAGE ; GET PAGE OF TARGET BLOCK IN [A/Y]
NM1: STA MPCPNT+HI ; SET MSB OF POINTER
LDX #$FF
STX MPCFLG ; [MPC] IS NOW VALID
INX ; CLEAR LSB
STX MPCPNT+LO ; OF [MPCPNT]
BEQ GTB
; -------------------------------
; LOCATE A PAGE OF VIRTUAL MEMORY
; -------------------------------
; ENTRY: TARGET PAGE IN [A/Y] (LSB/MSB)
; EXIT: ABSOLUTE PAGE ADDRESS IN [A]
PAGE: STA TARGET+LO ; SAVE THE
STY TARGET+HI ; TARGET PAGE FOR REFERENCE
LDX #0 ; INIT INDEX
STX ZPAGE ; KEEP A RUNNING TALLY
PG1: CMP PTABL,X ; SEARCH FOR LSB IN [A]
BEQ PG3 ; IF FOUND, CHECK MSB
PG2: INC ZPAGE ; UPDATE TALLY
INX
CPX PMAX ; OUT OF PAGING SPACE?
BCC PG1 ; NO, KEEP LOOKING
BCS SWAP ; ELSE PAGE MUST BE SWAPPED IN
PG3: TYA ; GET MSB OF TARGET
CMP PTABH,X ; MATCHED?
BEQ PFOUND ; YES, PAGE IS IN [ZPAGE]
LDA TARGET+LO ; ELSE RESTORE LSB OF TARGET
JMP PG2 ; AND RESUME SEARCH
; SWAP IN TARGET PAGE IN [TARGET]
SWAP: LDX LRU ; SPLICE THE
LDA TARGET+LO ; TARGET PAGE
STA PTABL,X ; INTO THE PAGING TABLES
STA DBLOCK+LO ; AND GIVE IT TO ZDOS
LDA TARGET+HI ; SAME FOR MSB
STA PTABH,X
STA DBLOCK+HI
TXA
STA ZPAGE ; SAVE FOR "PFOUND"
CLC
ADC PAGE0 ; MAKE IT ABSOLUTE
STA DBUFF+HI ; GIVE PAGE ADDRESS TO ZDOS
JSR GETDSK ; GET BLOCK INTO SWAPPING SPACE
INC LRU ; UPDATE PAGE POINTER
LDA LRU
CMP PMAX ; TOP OF PAGING SPACE?
BCC PFOUND ; NO, EXIT
LDA #0
STA LRU ; ELSE RESET POINTER
PFOUND: LDA ZPAGE ; GET SWAPPING PAGE INDEX
CLC
ADC PAGE0 ; MAKE IT ABSOLUTE
RTS ; AND RETURN IT IN [A]
; -------------------------
; POINT [MPC] TO V-ADDR [I]
; -------------------------
SETWRD: LDA I+LO
STA MPCL
LDA I+HI
STA MPCM
LDA #0
STA MPCH ; ZERO TOP BIT
STA MPCFLG ; INVALIDATE [MPC]
RTS
; ----------------------------
; GET Z-WORD AT [MPC] INTO [I]
; ----------------------------
GETWRD: JSR GETBYT
STA I+HI
JSR GETBYT
STA I+LO
RTS
END