mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-10 02:00:22 +00:00
616 lines
9.9 KiB
NASM
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
|