mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-03-02 01:40:25 +00:00
598 lines
10 KiB
NASM
598 lines
10 KiB
NASM
PAGE
|
||
STTL "--- TIME-STAMP PAGING ROUTINE ---"
|
||
|
||
|
||
; -------------------------
|
||
; 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)
|
||
; PAGING BUFFERS ARE IN HIGH AUX
|
||
;
|
||
DSKBNK: DB 00
|
||
;
|
||
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
|
||
;
|
||
;
|
||
; 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 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
|
||
|
||
; [J] HAS # PAGES IN GAME ROUNDED
|
||
; DOWN, BUT PAGE 0 IS IN ALREADY
|
||
; SO WE NEED ONLY LOAD [J] MORE
|
||
; PAGES OR FILL MEM WITH SIDE 1
|
||
; IF THE GAME IS LARGER THAN SIDE 1
|
||
|
||
; FILL MAIN AND AUX
|
||
; # GETRES ASSUMED TO BE POINTING
|
||
; # AT V-PAGE 1 AND RAM PAGE ZBEGIN+1
|
||
; # ALSO, GETRES SHOULD ROLL INTO
|
||
; # AUX RAM WHEN INCREMENTING DBUFF
|
||
|
||
FLP: JSR DECJ ; C=0 IF [J] GOES TO 0
|
||
BCC FIN
|
||
JSR GETDSK ; (CBD)
|
||
BCC FLP0
|
||
JMP DSKERR ; OH SHIT
|
||
|
||
FLP0: LDA DSKBNK ; IS IT FILLING AUX ?
|
||
CMP #AUX
|
||
BNE FLP ; JMP
|
||
|
||
FLP1: LDA DBUFF+HI
|
||
CMP #PBEGIN ;FILLED TO PAGING BUFFERS YET?
|
||
BNE FLP ;NO, NOT YET
|
||
|
||
LDA #CLS ; clear the screen
|
||
JSR CHROUT
|
||
|
||
LDA SIDEFLG ; IF NOT ON SIDE 2 YET
|
||
CMP #2
|
||
BEQ FLPj
|
||
LDX #2
|
||
LDY #0
|
||
JSR PLOT
|
||
JSR SIDE2 ; GO ASK FOR IT NOW
|
||
FLPj:
|
||
LDA RESFLG ; IF A RESTART (NOT COLD), DON'T NEED XRAM LOAD
|
||
BNE FIN ; (1=RESTART)
|
||
LDA XEXIST ; is there expansion ram?
|
||
BNE LDXRAM
|
||
FIN: RTS
|
||
|
||
; COPY ALL OF SIDE 2 TO XRAM TO USE AS RAM DISK FOR FASTER DISK ACCESS
|
||
|
||
LDXRAM:
|
||
; [J] HAS # PAGES IN GAME ROUNDED
|
||
; DOWN, AND LESS WHAT IS ALREADY IN
|
||
; SO WE NEED ONLY LOAD [J] MORE
|
||
; PAGES
|
||
LDA #0
|
||
STA I+HI ; XRAM PAGE COUNTER
|
||
STA I+LO
|
||
STA L+LO ; BANK TO START ON
|
||
|
||
LDX #<LMSG ; TELL LOADING SIDE2 INTO XRAM
|
||
LDA #>LMSG
|
||
LDY #LMSGL
|
||
JSR DLINE
|
||
|
||
FILL: JSR DECJ ; C=0 IF [J] GOES LT 0
|
||
BCC FILLED
|
||
|
||
LDA #'*' ; show slow progress
|
||
JSR CHROUT
|
||
|
||
LDA #>IOBUFF
|
||
STA DBUFF+HI ; FAKE GETDSK OUT
|
||
JSR GETDSK
|
||
BCC FILL0
|
||
JMP DSKERR ; OH SHIT
|
||
FILLED:
|
||
LDA L+LO ; see if we can fit i-save
|
||
CMP XEXIST ; if another bank is there, use it
|
||
BCS NOISAVE ; nope, no room
|
||
LDA XEXIST ; get save bank
|
||
STA ISRBANK ; save it
|
||
DEC XEXIST ; mark this one as unavailable
|
||
NOISAVE:
|
||
LDA #1
|
||
STA RESFLG ; SET RESTART FLAG ON FOR XRAM LOAD
|
||
RTS
|
||
|
||
FILL0: LDY I+HI ; PAGE
|
||
LDX L+LO ; BANK
|
||
LDA #XWRITE ; show we want to write
|
||
JSR EXIO ; and go get it
|
||
|
||
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 5 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
|
||
|
||
|
||
; 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 #VAUX ;IS IT A PAGE IN MAIN
|
||
BCS VLD2 ;NO, IT IS IN AUX
|
||
|
||
ADC #>ZBEGIN ;ADD OFFSET TO GET RAM PAGE
|
||
LDY #MAIN
|
||
JMP VLDEXI ;JMP
|
||
VLD1:
|
||
CMP #1 ;BETWEEN 64K AND 128K ?
|
||
BNE VLD3 ;NO, ABOVE 128K
|
||
|
||
LDA MPCM
|
||
CMP #<PRELOAD
|
||
BCS VLD3 ;PAGED
|
||
|
||
VLD2: SEC
|
||
SBC #VAUX-AUXSTART ;FIX TO OFFST INTO AUX RAM
|
||
LDY #AUX
|
||
|
||
VLDEXI: STY MPCBNK
|
||
STA MPCPNT+HI
|
||
|
||
NOMUCK: RTS
|
||
|
||
VLD3: ;MUST BE PAGED
|
||
LDA MPCH
|
||
LDY MPCM
|
||
JSR PAGE ;RETURN BUFFER IN A THAT HAS VPAGE A,Y
|
||
CLC
|
||
ADC #PBEGIN
|
||
STA MPCPNT+HI
|
||
LDY #AUX
|
||
STY MPCBNK
|
||
|
||
;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 #VAUX ;IS IT A PAGE IN MAIN
|
||
BCS VLDZ2 ;NO, IT IS IN AUX
|
||
ADC #>ZBEGIN ;ADD OFFSET TO GET RAM PAGE
|
||
VLDZ0: LDY #MAIN
|
||
JMP VLDZEXI ;JMP
|
||
|
||
VLDZ1: CMP #1 ;BETWEEN 64K AND 128K ?
|
||
BNE VLDZ3 ;NO, ABOVE 128K
|
||
LDA ZPCM
|
||
CMP #<PRELOAD
|
||
BCS VLDZ3 ;PAGED
|
||
VLDZ2: SEC
|
||
SBC #VAUX-AUXSTART
|
||
LDY #AUX
|
||
VLDZEXI:
|
||
STY ZPCBNK
|
||
STA ZPCPNT+HI
|
||
NOZMUCK:
|
||
RTS
|
||
|
||
VLDZ3: ;MUST BE PAGED
|
||
LDA ZPCH
|
||
LDY ZPCM
|
||
JSR PAGE ;RETURN BUFFER IN A THAT HAS VPAGE A,Y
|
||
CLC
|
||
ADC #PBEGIN
|
||
STA ZPCPNT+HI
|
||
LDY #AUX
|
||
STY ZPCBNK
|
||
|
||
;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 PAGING 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 REALLY 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
|
||
|
||
; 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
|
||
LDX #AUX ; SET FLAG
|
||
STX DSKBNK
|
||
|
||
LDA XEXIST ; IF XRAM EXISTS, IT'S ALL IN THERE
|
||
BNE GETXPAGE ; SO GET IT FROM THERE
|
||
|
||
JSR GETDSK
|
||
BCC T2
|
||
JMP DSKERR ; COULDN'T READ DISK
|
||
GETXPAGE:
|
||
LDA DBLOCK+LO
|
||
SEC ; SIDE 2, SO SUBTRACT OFF PRELOAD
|
||
SBC #<PRELOAD ; AMOUNT SO GET ACCURATE
|
||
PHA ; CALCULATION WHERE SECTOR IS
|
||
LDA DBLOCK+HI
|
||
SBC #>PRELOAD ; PICK UP CARRY
|
||
TAX
|
||
PLA ; [Y] = LOW, [X] = HIGH
|
||
TAY
|
||
|
||
LDA #XREAD ; to read the info
|
||
JSR EXIO ; and go get, boys
|
||
|
||
JMP GOT
|
||
|
||
; 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 [A]
|
||
; 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 (?, COLD ?)
|
||
|
||
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
|
||
|
||
JMP GETSIDE1
|
||
|
||
; 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
|
||
|
||
;;
|
||
;; THIS IS RAM EXPANSION STUFF
|
||
;;
|
||
; CHECK IF THERE IS EXPANSION RAM ON THIS MACHINE
|
||
; while your at it, count how many banks there are!
|
||
MEMCHK:
|
||
LDA #0
|
||
STA XEXIST ; SET TO NO
|
||
|
||
MEMLOOP:
|
||
LDX XEXIST ; BANK #
|
||
LDA #$55 ; FIRST CHECK IF MACHINE HAS XRAM
|
||
JSR CHKX
|
||
BCS MEMXNO
|
||
INC XEXIST ; point to next one
|
||
LDA XEXIST ; get it
|
||
AND #$08 ; only bits 0-2 are significant
|
||
BEQ MEMLOOP
|
||
MEMXNO:
|
||
LDA XEXIST ; see if any there
|
||
CMP #3 ; is it at least 3 banks worth?
|
||
BCC NOEX ; nope, no (or not enough) expansion ram
|
||
DEC XEXIST ; point to last one
|
||
RTS ; and end it
|
||
NOEX:
|
||
LDA #0 ; so make sure it is zero
|
||
STA XEXIST ; so we don't use it
|
||
RTS ; so long, and thanks for the fish
|
||
|
||
; CHECK FOR THE PRESENCE OF 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 #$E0 ; only check 32 chars
|
||
CLOOP1: STA IOBUFF,Y
|
||
INY
|
||
BNE CLOOP1
|
||
|
||
LDA #XWRITE ; write to expansion
|
||
LDX L+LO ; this bank
|
||
LDY #0 ; and always just do page 0
|
||
JSR EXIO ; and go to it
|
||
|
||
LDA #0 ; CLEAR IOBUFF BEFORE READ
|
||
LDY #$E0 ; SO SURE IT GETS DONE
|
||
CLOOP2: STA IOBUFF,Y
|
||
INY
|
||
BNE CLOOP2
|
||
|
||
LDA #XREAD ; now see if it is there
|
||
LDX L+LO
|
||
LDY #0
|
||
JSR EXIO
|
||
|
||
LDA IOCHAR ; SEE IF READ BACK RIGHT THING
|
||
LDY #$E0
|
||
CLOOP3: CMP IOBUFF,Y
|
||
BNE CNOX
|
||
INY
|
||
BNE CLOOP3
|
||
CLC
|
||
RTS
|
||
CNOX: SEC ; NOT THERE
|
||
RTS
|
||
|
||
;
|
||
; DOISAVE - write stuff to ex-mem save bank
|
||
;
|
||
DOISAVE:
|
||
LDY #0 ; MOVE PAGE AT [DBUFF]
|
||
DOIC: LDA (DBUFF),Y ; INTO
|
||
STA IOBUFF,Y ; [IOBUFF] FOR I/O
|
||
INY
|
||
BNE DOIC
|
||
|
||
LDX ISRBANK ; get bank and
|
||
LDY ISRPAGE ; page
|
||
LDA #XWRITE ; show writing it
|
||
JSR EXIO ; and do it
|
||
|
||
INC ISRPAGE ; show next page
|
||
INC DBUFF+HI ; point to next page
|
||
RTS ; goodbye, sweet maiden
|
||
|
||
;
|
||
; DOIRES - get save stuff from ex-mem save bank
|
||
;
|
||
DOIRES:
|
||
LDX ISRBANK ; get bank and
|
||
LDY ISRPAGE ; page
|
||
LDA #XREAD ; show we want to read
|
||
JSR EXIO ; and do it
|
||
|
||
LDY #0 ; MOVE PAGE AT [IOBUFF]
|
||
DOIRC:
|
||
LDA IOBUFF,Y ; TO
|
||
STA (DBUFF),Y ; DBUFF
|
||
INY
|
||
BNE DOIRC
|
||
|
||
INC ISRPAGE ; show next page
|
||
INC DBUFF+HI ; and next mem loc
|
||
RTS ; goodbye, sweet maiden
|
||
|
||
PAGE
|
||
|
||
END
|
||
|