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

616 lines
9.9 KiB
NASM

PAGE
SBTTL "--- TIME-STAMP PAGING ROUTINE ---"
; ------
; GETBYT
; ------
GETBYT: LDA MPCPNT+HI
CMP #SWAPMEM ; SPEEDUP
BCC GETB1
SEI
LDA RAMFLG ; SWAP IN RAM
AND #RAM
STA RAMFLG
GETB1: LDY MPCL
LDA (MPCPNT),Y ;GET THE BYTE
TAX
SEI
LDA RAMFLG ; RESET TO KERNAL ROM
ORA #KERNAL
STA RAMFLG
CLI
TXA
INC MPCL ;POINT TO NEXT BYTE
BNE GETGOT ;IF NO CROSS WE ARE STILL VALID
JSR CRSMPC
GETGOT: TAY ;SET FLAGS
RTS ;RED SLIPPER TIME
; ------
; NEXTPC
; ------
; LIKE GETBYT
NEXTPC: LDA ZPCPNT+HI
CMP #SWAPMEM ; SPEEDUP
BCC NEXT1
SEI
LDA RAMFLG ; SWAP IN RAM
AND #RAM
STA RAMFLG
NEXT1: LDY ZPCL
LDA (ZPCPNT),Y
TAX
SEI
LDA RAMFLG ; RESET TO KERNAL ROM
ORA #KERNAL
STA RAMFLG
CLI
TXA
INC ZPCL
BNE NXTGOT
JSR CRSZPC
NXTGOT: TAY
RTS
; -------------------------
; POINT [MPC] TO V-ADDR [I]
; -------------------------
SETWRD: LDA I+LO
STA MPCL
LDA I+HI
STA MPCM
LDA #0
STA MPCH ; ZERO TOP BIT
JMP VLDMPC
; THE FIRST 86K (SIDE1) MUST
; BE RAM RESIDENT (344=$158 PAGES)
;
; PAGES V$0 TO ($FE-VBEGIN) ARE IN MAIN (BANK1)
; PAGES ($FE-VBEGIN) TO V$158 ARE IN AUX (BANK0)
; PAGENG BUFFERS ARE IN HIGH AUX
;
WANTED: DB 00,00
;
CURRENT: DB 00
NEXT: DB 00
NSUBA: DB 00
PSUBA: DB 00
NSUBCUR: DB 00
;
YTEMP: DB 00
ATEMP: DB 00
NSUBY: DB 00
;
; MAKE [MPCPNT],[MPCBNK] POINT TO
; THE RAM PAGE AND BANK THAT HOLDS
; THE V-PAGE MPCH,M
;
VLDMPC: LDA MPCH
BNE VLD1 ;NOT IN FIRST V-64K
LDA MPCM
CMP ZPURE ;IS IT PRELOAD
BCS VLD1 ;NO
ADC #HIGH ZBEGIN ;ADD OFFSET TO GET RAM PAGE
STA MPCPNT+HI
CMP #$D0 ; SKIP $D0-$DF ; SPEEDUP
BCC NOMUCK
ADC #$0F ; 1 LESS AS CARRY SET
STA MPCPNT+HI
NOMUCK: RTS
VLD1: ;MUST BE PAGED
LDA MPCH
LDY MPCM
JSR PAGE ;RETURN BUFFER IN A THAT HAS VPAGE A,Y
CLC
ADC #PBEGIN
STA MPCPNT+HI
;TEST FOR MUCK
LDA MUCKFLG
BEQ NOMUCK
JMP VLDZPC ;MAY HAVE MUCKED ZPC SO GO FIX
;SAME IDEA AS VLDMPC
VLDZPC: LDA ZPCH
BNE VLDZ1 ;NOT IN FIRST V-64K
LDA ZPCM
CMP ZPURE ;IS IT PRELOAD
BCS VLDZ1 ;NO
ADC #HIGH ZBEGIN ;ADD OFFSET TO GET RAM PAGE
STA ZPCPNT+HI
CMP #$D0 ; SKIP $D0-$DF ; SPEEDUP
BCC NOZMUCK
ADC #$0F ; 1 LESS AS CARRY SET
STA ZPCPNT+HI
NOZMUCK: RTS
VLDZ1: ;MUST BE PAGED
LDA ZPCH
LDY ZPCM
JSR PAGE ;RETURN BUFFER IN A THAT HAS VPAGE A,Y
CLC
ADC #PBEGIN
STA ZPCPNT+HI
;TEST MUCKING
LDA MUCKFLG
BEQ NOZMUCK
JMP VLDMPC ;MAY HAVE MUCKED MPC SO GO FIX
; FIND V-PAGE A,Y IF IT IS IN MEM
; AND RETURN WITH LINKED LIST
; PROPERLY MAINTAINED
; IF V-PAGE A,Y NOT IN MEM
; GET FROM DISK AND PUT IN RIGHT
; PLACE
MUCKFLG: DB 00 ; 00 IF PAGING BUFFERS NOT MUCKED
PAGE: STA WANTED+HI
STY WANTED+LO
; CLEAR MUCK FLAG
LDX #0
STX MUCKFLG
JSR WHERE
BCC TOUGH ;PAGE IS RESIDENT IN PAGENG SPACE
; PAGE MUST BE BROUGHT IN FROM DISK
LDX CURRENT ;GET BUFFER TO PUT PAGE INTO
LDA NEXTPNT,X ;BY LOOKING AT NEXT POINTER
STA CURRENT ;MAKE IT THE CURRENT BUFFER
TAX
LDA WANTED+HI ;LET BUFFER MAP KNOW
STA VPAGEH,X ;WHICH PAGE
LDA WANTED+LO ;IS GOING TO
STA VPAGEL,X ;BE THERE
TAY
TXA
PHA ;SAVE BUFFER
LDA WANTED+HI
; Y = WANTED+LO
; X = BUFFER
JSR GETVPAGE ;PUT V-PAGE A,Y INTO PAGENG BUFFER X
;INDICATE A MUCKING
DEC MUCKFLG
PLA ;RESTOR BUFFER NUMBER
RTS
; THIS IS WHERE THINGS GET WEIRD
TOUGH: STA NEXT
CMP CURRENT ;GETS REALY FUCKED IF CURRENT=NEXT
BNE T1
RTS ;DO NOT CHANGE POINTERS IF IT DOES, ALL IS WELL
; Y=NEXT(CURRENT)
; DO THE RIGHT THING TO THE POINTERS
; ASK LIM TO EXPLAIN ,HA HA.
T1: LDY CURRENT
LDA NEXTPNT,Y
STA NSUBCUR
LDA NEXT
JSR DETATCH
LDY CURRENT
LDA NEXT
JSR INSERT
LDA NEXT
STA CURRENT
T2: RTS
; GET A PAGE IN BANK 1, PREPAGED
; TEMPORARY NOTE: GET A PAGED PAGE [A,Y] >(DBLOCK)
; FROM DISK & PUT IN PAGING BUFFER [X] (MUST BE MADE ABSOLUTE)
GETVPAGE: STA DBLOCK+HI
STY DBLOCK+LO
TXA ; OFFSET INTO CORRECT RAM PAGE
CLC
ADC #PBEGIN ; MAKE ABSOLUTE
STA DBUFF+HI
LDA XEXIST ; IF XRAM EXISTS, IT'S ALL IN THERE
BNE GETXPAGE ; SO GET IT FROM THERE
JSR GETDSK
BCC T2 ; RTS
JMP DSKERR ; COULDN'T READ DISK
GETXPAGE: LDA DBLOCK+LO
SEC ; SIDE 2, SO SUBTRACT SIDE 1
SBC ZPURE ; AMOUNT SO GET ACCURATE
PHA ; CALCULATION WHERE SECTOR IS
LDA DBLOCK+HI
SBC #0 ; PICK UP CARRY
TAX
PLA ; [A] = LOW, [X] = HIGH
STX XFLAGS+XBANK ; BANK CURRENTLY WRITING TO
STA XFLAGS+XRAM+HI ; BLOCK IN XRAM
LDA #0
STA XFLAGS+XRAM+LO
STA XFLAGS+XINT ; NO INTERRUPTS
STA XFLAGS+XINCR ; INCREMENT ADDR POINTERS
STA XFLAGS+XSIZ+LO ; AMOUNT TO WRITE IS 1 PG
LDA #1
STA XFLAGS+XSIZE+HI
LDA #HIGH IOBUFF
STA XFLAGS+XBUFF+HI
LDA #LOW IOBUFF
STA XFLAGS+XBUFF+LO
LDA #XREAD ; READ FROM XRAM
STA XFLAGS+XFER ; THIS WRITE DOES ACTUAL TRANSFER
JMP GOT ; AND TRANSFER IT PROPERLY TO PAGING
; PREV(A)=Y
; PREV(NEXT(Y))=A
; NEXT(A)=NEXT(Y)
; NEXT(Y)=A
; INSERT A BEFORE Y
INSERT: STA ATEMP
STY YTEMP
TAX
TYA
STA PREVPNT,X
LDA NEXTPNT,Y
STA NSUBY
TXA
LDX NSUBY
STA PREVPNT,X
TXA
LDX ATEMP
STA NEXTPNT,X
LDA ATEMP
STA NEXTPNT,Y
RTS
; DETATCH BUFFER HIGH ALOW
; NEXT(PREV(A))=NEXT(A)
; PREV(NEXT(A))=PREV(A)
DETATCH: TAX
LDA NEXTPNT,X
STA NSUBA
LDA PREVPNT,X
STA PSUBA
TAX
LDA NSUBA
STA NEXTPNT,X
LDA PSUBA
LDX NSUBA
STA PREVPNT,X
RTS
; RETURN BUFFER OF PAGE [WANTED]
; IN [A] ELSE SEC (Y=WANTED+LO)
; (CHECKING FOR PAGED BUFFER ALREADY RESIDENT)
WHERE: LDX #NUMBUFS-1
WHLOOP:
LDA WANTED+HI
CMP VPAGEH,X ;HIGH SAME
BEQ WHGOT
WHNOGOT:
DEX
BPL WHLOOP
SEC
RTS
WHGOT:
TYA
CMP VPAGEL,X
BNE WHNOGOT
TXA
CLC
RTS
; SETS UP PAGING SYSTEM - CALLED FROM WARM
INITPAG: LDX #NUMBUFS-1
STX CURRENT
LDA #$FF
INILP:
STA VPAGEH,X
DEX
BPL INILP
LDX #0
LDY #1
INILP2:
TYA
STA PREVPNT,X
INX
INY
CPX #NUMBUFS
BCC INILP2
LDA #00
DEX
STA PREVPNT,X
LDX #0
LDY #$FF
LDA #NUMBUFS-1
INILP3:
STA NEXTPNT,X
INX
INY
TYA
CPX #NUMBUFS
BCC INILP3
; FALL THRU TO GETSIDE1
;
; GET SIDE 1 LOADS ALL CODE FROM
; DISK SIDE 1 INTO ITS CORRECT
; PLACE
; THE FIRST VPAGE MUST ALREADY BE
; RESIDENT AT [ZBEGIN]
GETSIDE1: LDA DBLOCK+LO ; INCREMENT NOT CORRECT, SO
CMP ZPURE ; (LAST PRELOAD PG YET?
BCS FIN ; YES)
LDX DBLOCK+HI ; REFIGURE EACH TIME FOR NOW
LDY #3 ; SIDE 1 STARTS ON TRACK 3
JSR SETTS ; GO GET TRACK & SECTOR
JSR GETRES ; AND GO READ THE DISK
BCC GETSIDE1
JMP DSKERR ; OH SHIT
FIN: ; ALL DONE WITH LOADING SIDE1 NOW
JSR CLS ; CLEAR THE SCREEN FOR NEATNESS
LDX #2
LDY #0
CLC
JSR PLOT
JSR SIDE2 ;CODE EXISTS ON SIDE2 AND WE HAVE SIDE 1
LDA RESFLG ; IF A RESTART (NOT COLD), DON'T NEED XRAM LOAD
BNE FIN2 ; (1=RESTART)
LDA XEXIST ; IS THERE EXPANSION RAM?
BNE LDXRAM ; YES, GO FILL IT
FIN2: RTS
; COPY ALL OF SIDE 2 TO XRAM TO USE AS RAM DISK FOR FASTER DISK ACCESS
LDXRAM: LDA ZBEGIN+ZLENTH+1 ; GET LENGTH OF GAME (QUADS)
STA J+LO
LDA ZBEGIN+ZLENTH+0
LDY #5
SLP: LSR A ; CONVERT QUADS TO PAGES WITH /64
ROR J+LO
DEY
BPL SLP
STA J+HI
SEC ; NOW SUBTRACT WHAT HAS ALREADY BEEN LOADED
LDA J+LO
SBC #LOW PSIDE1
STA J+LO
LDA J+HI
SBC #HIGH PSIDE1
STA J+HI
; [J] HAS # PAGES IN GAME ROUNDED
; DOWN, AND LESS WHAT IS ALREADY IN
; SO WE NEED ONLY LOAD [J] MORE
; PAGES
INC J+LO ; SEEMS TO HELP
INC J+LO
LDA #0
STA I+HI ; XRAM PAGE COUNTER
STA I+LO
STA L+LO ; BANK TO START ON
LDX #LOW LMSG ; TELL LOADING SIDE2 INTO XRAM
LDA #HIGH LMSG
LDY #LMSGL
JSR DLINE
FILL: JSR DECJ ; C=0 IF [J] GOES LT 0
BCC FILLED
LDA #HIGH IOBUFF
STA DBUFF+HI ; FAKE GETDSK OUT
JSR GETDSK
BCC FILL0
JMP DSKERR ; OH SHIT
FILLED: LDA #1
STA RESFLG ; SET RESTART FLAG ON FOR XRAM LOAD
RTS
FILL0: LDA I+HI
STA XFLAGS+XRAM+HI ; WHERE TO WRITE IN XRAM
LDA I+LO
STA XFLAGS+XRAM+LO
LDA #0
STA XFLAGS+XINT ; NO INTERRUPTS
STA XFLAGS+XINCR ; INCREMENT ADDR POINTERS
STA XFLAGS+XSIZ+LO ; AMOUNT TO WRITE IS 1 PG
LDA #1
STA XFLAGS+XSIZE+HI
LDA L+LO
STA XFLAGS+XBANK ; BANK CURRENTLY WRITING TO
LDA #HIGH IOBUFF ; ALWAYS WRITE FROM IOBUFF
STA XFLAGS+XBUFF+HI
LDA #LOW IOBUFF
STA XFLAGS+XBUFF+LO
LDA #XWRITE ; WRITE TEST TO XRAM
STA XFLAGS+XFER ; THIS WRITE DOES ACTUAL TRANSFER
INC I+HI ; NEXT PAGE
BNE FILL
INC L+LO ; NEXT BANK
JMP FILL
LMSG: DB EOL,EOL,"Side 2 being loaded into expansion ram"
DB EOL,EOL,"This will take about 10 minutes"
DB EOL
LMSGL EQU $-LMSG
;DECJ RETURNS C=0 WHEN J=$FFFF
DECJ: LDA J+LO
SEC
SBC #1
STA J+LO
LDA J+HI
SBC #0
STA J+HI
RTS
; CHECK IF THERE IS EXPANSION RAM ON THIS MACHINE
MEMCHK: LDA #$55 ; FIRST CHECK IF MACHINE HAS XRAM
LDX #0 ; BANK 0
STX XEXIST ; SET TO NO
JSR CHKX
BCS MEMXNO
LDA #$AA
LDX #1
JSR CHKX
BCS MEMXNO
LDA #$FE ; CHECK FOR 3 BANKS WORTH (NEED 170K)
LDX #2
JSR CHKX
BCS MEMXNO
LDA #1
STA XEXIST ; YES, THERE IS EXPANSION RAM PRESENT
MEMXNO: RTS ; OF AUX MEMORY
; CHECK FOR THE PRECENCE OF A 256K EXPANSION RAM
; SET ALL THE FLAGS WRITE & SEE IF READ BACK WHAT WROTE
CHKX: STX L+LO ; SAVE BANK TO TEST FOR THIS TIME
STA IOCHAR ; HOLD FOR CMP
LDY #0
CLOOP1: STA IOBUFF,Y
INY
BNE CLOOP1
LDA #0
STA XFLAGS+XRAM+HI
STA XFLAGS+XRAM+LO
STA XFLAGS+XINT
STA XFLAGS+XINCR
STA XFLAGS+XSIZ+LO
LDA #1
STA XFLAGS+XSIZE+HI
LDA L+LO
STA XFLAGS+XBANK
LDA #HIGH IOBUFF
STA XFLAGS+XBUFF+HI
LDA #LOW IOBUFF
STA XFLAGS+XBUFF+LO
LDA #XWRITE ; WRITE TEST TO XRAM
STA XFLAGS+XFER ; THIS WRITE DOES ACTUAL TRANSFER
LDA #0 ; CLEAR IOBUFF BEFORE READ
LDY #0 ; SO SURE IT GETS DONE
CLOOP2: STA IOBUFF,Y
INY
BNE CLOOP2
LDA #0
STA XFLAGS+XRAM+HI
STA XFLAGS+XRAM+LO
STA XFLAGS+XINT
STA XFLAGS+XINCR
STA XFLAGS+XSIZ+LO
LDA #1
STA XFLAGS+XSIZE+HI
LDA L+LO
STA XFLAGS+XBANK
LDA #HIGH IOBUFF
STA XFLAGS+XBUFF+HI
LDA #LOW IOBUFF
STA XFLAGS+XBUFF+LO
LDA #XREAD ; READ WHAT JUST WROTE
STA XFLAGS+XFER ; THIS WRITE DOES ACTUAL TRANSFER
LDA IOCHAR ; SEE IF READ BACK RIGHT THING
LDY #0
CLOOP3: CMP IOBUFF,Y
BNE CNOX
INY
BNE CLOOP3
CLC
RTS
CNOX: SEC ; NOT THERE
RTS
; TAKE CARE OF CROSSING A PAGE
CRSMPC:
PHA
INC MPCM
BNE CRS1
INC MPCH
CRS1: JSR VLDMPC
PLA
RTS
;SAME AS CRSMPC
CRSZPC:
PHA
INC ZPCM
BNE CRSZ1
INC ZPCH
CRSZ1: JSR VLDZPC
PLA
RTS
PAGE
END