2023-11-16 18:19:54 -05:00

314 lines
6.9 KiB
Plaintext

PAGE
SBTTL "--- PAGING ROUTINES ---"
; -----------------------
; GET NEXT BYTE OF G-CODE
; -----------------------
; EXIT: BYTE IN [A] & [Y], FLAGS SET
NEXTPC: LDA GPCFLG ; IS [GPOINT] VALID?
BNE NPC2 ; YES, CONTINUE
LDX GPCH ; GET TARGET V-PAGE
LDA MEMMAP,X ; IS IT ALREADY RESIDENT?
BEQ NPC0 ; NO, PAGE IT IN
CMP PAGE0 ; IS IT IN PRELOAD?
BCC NPC1 ; YES, CONTINUE
; HANDLE A RESIDENT "PURE" PAGE
JSR UPTIME ; UPDATE STAMP
JMP NPC1 ; CONTINUE W/PAGE ADDR IN [A]
; FETCH A NON-RESIDENT "PURE" PAGE
NPC0: STA VPCFLG ; ([A]=0) INVALIDATE [VPC]
JSR PAGE ; GET ABS PAGE OF V-BLOCK [X] IN [A]
JMP NEXTPC
;THIS JUMP SHOULD NOT BE NEEDED BUT SEEMS TO HELP
; [A] HAS ABS ADDR OF TARGET PAGE (FIRST RAM PAGE OF TWO PAGES)
NPC1: STA GPOINT+HI ; FORM MSB OF G-POINTER
LDA GPCL ; IF BIT 7 SET
BPL NPC1A
INC GPOINT+HI ; POINT [GPOINT] AT NEXT RAM PAGE
NPC1A: LDA #$FF
STA GPCFLG ; VALIDATE [GPC]
; [GPOINT] HAS POINTER TO ABS PAGE ADDR
; PUT BITS 0 THRU 7 OF GPC INTO <Y>
NPC2: LDA GPC0 ; PUT BIT 0 INTO <C>
LSR A
LDA GPCL ; GET BITS 1-8
ROL A ; DON'T WORRY ABOUT BIT 8
TAY
LDA (GPOINT),Y ; GET A G-BYTE
; INCREMENT [GPC]
; IF CROSSING A !RAM! PAGE ADJUST [GPOINT]
; IF CROSSING A V-PAGE INVALIDATE FLAG
PHA ; SAVE THE BYTE
LDA GPC0 ; EFFECTIVLY ADD 1
EOR #$01
STA GPC0
BNE NPC3 ; BRANCH NO CARRY
INC GPCL
BEQ NPC4 ; BRANCH CROSSED V-PAGE
LDA GPCL ; TEST FOR CROSS !RAM! PAGE
AND #$7F
BNE NPC3 ; BRANCH NO CROSS
INC GPOINT+HI ; ADJUST RAM POINTER
JMP NPC3
NPC4: INC GPCH ; CROSS V-PAGE
LDA #00
STA GPCFLG ; INVALIDATE FLAG
NPC3: PLA ; RESTORE BYTE
TAY ; SET FLAGS
RTS
; ----------------------------
; GET A BYTE OF VIRTUAL MEMORY
; ----------------------------
; EXIT: SAME AS "NEXTPC"
GETBYT: LDA VPCFLG ; [VPC] VALID?
BNE GTBT2 ; YES, CONTINUE
LDX VPCH ; GET TARGET V-PAGE
LDA MEMMAP,X ; ALREADY IN RAM?
BEQ GTBT0 ; NO, PAGE IT IN
CMP PAGE0 ; IS IT PRELOADED?
BCC GTBT1 ; YES, CONTINUE
; HANDLE A RESIDENT PAGE
JSR UPTIME ; STAMP PAGE & UPDATE STAMP
JMP GTBT1 ; CONTINUE W/BUFFER ADDR IN [A]
; HANDLE A NON-RESIDENT PAGE
GTBT0: STA GPCFLG ; ([A]=0) INVALIDATE [GPC]
JSR PAGE ; GET ABS PAGE OF V-BLOCK [X] INTO [A]
JMP GETBYT
;THIS JMP SHOULD NOT BE NEEDED BUT SEEMS TO HELP
; [A] HAS ABS PAGE # OF TARGET PAGE
GTBT1: STA VPOINT+HI ; SET MSB OF POINTER
LDA VPCL ; IF BIT 7 SET
BPL GTBT1A
INC VPOINT+HI ; POINT AT NEXT RAM PAGE
GTBT1A: LDA #$FF
STA VPCFLG ; VALIDATE [VPC]
; [VPOINT] POINTS TO ABS ADDR OF TARGET V-PAGE
; PUT BITS 0 THRU 7 OF GPC INTO <Y>
GTBT2: LDA VPC0 ; PUT BIT 0 INTO <C>
LSR A
LDA VPCL ; GET BITS 1-8
ROL A ; DON'T WORRY ABOUT BIT 8
TAY
LDA (VPOINT),Y ; GET A V-BYTE
; INCREMENT [VPC]
; IF CROSSING A !RAM! PAGE ADJUST [GPOINT]
; IF CROSSING A V-PAGE INVALIDATE FLAG
PHA ; SAVE THE BYTE
LDA VPC0 ; EFFECTIVLY ADD 1
EOR #$01
STA VPC0
BNE GTBT3 ; BRANCH NO CARRY
INC VPCL
BEQ GTBT4 ; BRANCH CROSSED V-PAGE
LDA VPCL ; TEST FOR CROSS !RAM! PAGE
AND #$7F
BNE GTBT3 ; BRANCH NO CROSS
INC VPOINT+HI ; ADJUST RAM POINTER
JMP GTBT3
GTBT4: INC VPCH ; CROSS V-PAGE
LDA #00
STA VPCFLG ; INVALIDATE FLAG
GTBT3: PLA ; RESTORE BYTE
TAY ; SET FLAGS
RTS
; -------------------------------
; LOCATE A PAGE OF VIRTUAL MEMORY
; -------------------------------
;-----------------------------------------------------------------
; A VIRTUAL PAGE IS 512 BYTES OF VIRTUAL MEMORY.
; WHEN PAGED INTO MACHINE RAM IT MUST OCCUPY TWO CONSECUTIVE
; 256 BYTE !RAM! PAGES.
;
; [PAGMAP],BUFFER RETURN THE V-PAGE IN THAT BUFFFER
; (A BUFFER IS TWO CONSECUTIVE RAM PAGES)
; [MEMMAP],VPAGE RETURNS RAM PAGE LOWER HALF OF VPAGE IS IN
;
; [PAGE0] - RAM PAGE WHERE BUFFER(0) STARTS
;-----------------------------------------------------------------
; ENTRY: V-BLOCK TO SEARCH FOR IN [X]
; EXIT: ABSOLUTE PAGE ADDRESS IN [A]
PAGE: STX DBLOCK ; GIVE TARGET V-PAGE TO GROS
; DE-ALLOCATE THE EARLIEST V-PAGE
PGE1: JSR EARLY ; GET INDEX OF EARLIEST BUFFER INTO [SWAP]
LDY SWAP
LDX PAGMAP,Y ; GET V-PAGE OF EARLIEST BUFFER
BEQ PGE2 ; 0 = NO PAGE IN BUFFER
LDA #0
STA MEMMAP,X ; ZERO THE [MEMMAP] ENTRY
; SPLICE THE TARGET PAGE INTO THE BUFFER MAP
PGE2: LDA DBLOCK ; TARGET V-PAGE
STA PAGMAP,Y ; ADD IT TO BUFFER MAP
TAX ; USE LATER FOR INDEX INTO [MEMMAP]
TYA ; CALC THE ABSOLUTE ADDRESS
ASL A ; * 2 FOR 512 BYTE VPAGES
CLC ; OF THE
ADC PAGE0 ; CORRESPONDING BUFFER
STA MEMMAP,X ; TELL [MEMMAP] WHERE TO FIND THE PAGE
STA DBUFF+HI ; TELL GROS WHERE THE BUFFER IS
STA TARGET ; SAVE HERE
JSR GETDSK ; GET PAGE [DBLOCK] INTO [DBUFF]
LDA TARGET ; RESTORE BUFFER PAGE
; FALL THROUGH ...
; ----------------
; UPDATE TIMESTAMP
; ----------------
; ENTRY: ABS BUFFER PAGE OF V-BLOCK
UPTIME: STA TARGET ; SAVE FOR LATER
SEC ; FORM A ZERO-ALIGNED
SBC PAGE0 ; INDEX
;***
LSR A ; / 2 FOR 512 BYTE PAGES
;***
TAY ; INTO [LRUMAP]
LDA LRUMAP,Y ; CHECK THIS PAGE'S STAMP
CMP STAMP ; SAME AS CURRENT STAMP?
BEQ UT3 ; EXIT NOW IF SO
INC STAMP ; ELSE UPDATE STAMP
BNE UT2 ; CONTINUE IF NO OVERFLOW
; HANDLE STAMP OVERFLOW
JSR EARLY2 ; GET EARLIEST STAMP INTO [LRU]
LDX #0 ; INIT INDEX
UT0: LDA LRUMAP,X ; ELSE GET A STAMP READING
BEQ UT1 ; EXIT IF ZERO
SEC ; SUBTRACT OFF
SBC LRU ; EARLIEST STAMP READING
STA LRUMAP,X ; REPLACE IN MAP
UT1: INX
CPX PMAX ; LOOP TILL
BCC UT0 ; ALL STAMPS FIXED
LDA #0 ; TURN BACK
SEC ; THE CLOCK
SBC LRU ; TO REFLECT STAMP FUDGING
STA STAMP
UT2: LDA STAMP ; STAMP BUFFER [Y]
STA LRUMAP,Y ; WITH THE NEW STAMP
UT3: LDA TARGET ; RESTORE BUFFER ADDR
RTS
; --------------------------------
; LOCATE EARLIEST ACTIVE TIMESTAMP
; --------------------------------
; EXIT: [LRU] = EARLIEST TIMESTAMP
; [SWAP] = INDEX TO EARLIEST BUFFER
EARLY: LDX #0 ; INIT INDEX
STX SWAP
LDA LRUMAP ; GET TIMESTAMP OF BUFFER #0
INX ; START COMPARE WITH BUFFER #1
EAR0: CMP LRUMAP,X ; IS THIS STAMP EARLIER THAN [A]?
BCC EAR1 ; IF STILL SMALLER, TRY NEXT STAMP
LDA LRUMAP,X ; ELSE CHANGE EARLIEST ENTRY
STX SWAP ; AND UPDATE BUFFER INDEX
EAR1: INX
CPX PMAX ; OUT OF BUFFERS?
BCC EAR0 ; LOOP TILL EMPTY
RTS ; [SWAP] HAS INDEX TO EARLIEST BUFFER
; THIS IS FOR OVERFLOW, IGNORES 0 ENTRIES
SAVEY: DB 0
EARLY2: LDX #0 ; INIT INDEX
STX SWAP
STY SAVEY
EAR23: LDA LRUMAP,X ; GET TIMESTAMP OF BUFFER #0
CMP #0 ; DON'T USE A ZERO VALUE
BNE EAR22 ; OK, NOT 0
INX
CPX PMAX ; OUT OF BUFFERS?
BCC EAR23 ; NO, KEEP LOOKING
BCS EAR24 ; YUP, SO WILL HAVE TO USE 0
EAR22: INX ; START COMPARE WITH NEXT BUFFER
EAR20: CMP LRUMAP,X ; IS THIS STAMP EARLIER THAN [A]?
BCC EAR21 ; IF STILL SMALLER, TRY NEXT STAMP
LDY LRUMAP,X
BEQ EAR21
TYA
STX SWAP
EAR21: INX
CPX PMAX ; OUT OF BUFFERS?
BCC EAR20 ; LOOP TILL EMPTY
EAR24: STA LRU ; [A] HAS EARLIEST STAMP
; CMP #2 ; DON'T MAKE IT 0
; BCC EAR25
DEC LRU ; MAKE SO END RESULT NOT 0
EAR25: LDY SAVEY
RTS ; [SWAP] HAS INDEX TO EARLIEST BUFFER
END