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 NPC2: LDA GPC0 ; PUT BIT 0 INTO 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 GTBT2: LDA VPC0 ; PUT BIT 0 INTO 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