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

467 lines
7.2 KiB
NASM

PAGE
SBTTL "--- TIME-STAMP PAGENG 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 98.5K (SIDE1) MUST
; BE RAM RESIDENT (394=$18A PAGES)
; 98.5K = $18A PAGES (V$0 TO V$189)
;
; PAGES V$13A TO V$189 ARE IN RAMDISK
; PAGES V$0 TO ($BF-VBEGIN) ARE IN MAIN
; PAGES ($C0-VBEGIN) TO V$139 ARE IN AUX
; PAGENG BUFFERS ARE IN AUX FROM
; V$13A-($C0-VBEGIN)+$08 TO $BF
;
DSKBNK: DB 00
RAMSEC: 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 (NOT RAMDSK)
; # GETDSK ASSUMED TO BE POINTING
; # AT V-PAGE 1 AND RAM PAGE ZBEGIN+1
; # ALSO, GETDSK SHOULD ROLL INTO
; # AUX RAM WHEN INCMNTING DBUFF
FLP: JSR DECJ ;C=0 IF [J] GOES HIGH 0
BCC FIN
JSR GETDSK
LDA DSKBNK ;IS IT FILLING AUX ?
CMP #AUX
BNE FLP ;NO
LDA DBUFF+HI
CMP #PBEGIN ;FILLED TO PAGING BUFFERS YET?
BNE FLP ;NO, NOT YET
; NOW PUT STUFF IN RAMDSK
LDA #MAIN
STA DSKBNK ;POINT BACK TO MAIN MEM
LDA #0
STA RAMSEC ;POINT TO FIRST SECTOR
LP2:
LDA #>IOBUFF
STA DBUFF+HI ;MAKE GETDSK LEAVE CODE AT [IOBUFF]
JSR DECJ
BCC FIN
JSR GETDSK
LDY #>IOBUFF ;SET UP RAMDSK PARMS
LDA RAMSEC
LDX #WRITE
STA RDBNK+MAIN ;SO WE REALLY JSR RAMDSK
JSR RAMDSK ;CALL RAMDSK
INC RAMSEC
LDA RAMSEC
CMP #RMDSIZE
BCC LP2
JSR CLS ; CLEAR THE SCREEN FOR NEATNESS
LDA #2
STA CV
JMP SIDE2 ;CODE EXISTS ON SIDE2 AND WE HAVE SIDE 1
FIN:
RTS
;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
BEQ VLDEXI ;BRA
VLD2: SBC #VAUX-AUXSTART ;FIX TO OFFST INTO AUX RAM
LDY #AUX
BNE VLDEXI
VLD1: CMP #1 ;BETWEEN 64K AND 128K ?
BNE VLD3 ;NO, ABOVE 128K
LDA MPCM
CMP #<VRAMDSK
BCS VLD3 ;ABOVE AUX
ADC #V64PG
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
LDY #MAIN
BEQ VLDZEXI ;BRA
VLDZ2: SBC #VAUX-AUXSTART ;FIX TO OFFST INTO AUX RAM
LDY #AUX
BNE VLDZEXI
VLDZ1: CMP #1 ;BETWEEN 64K AND 128K ?
BNE VLDZ3 ;NO, ABOVE 128K
LDA ZPCM
CMP #<VRAMDSK
BCS VLDZ3 ;ABOVE AUX
ADC #V64PG
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 PAGENG 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
RTS
GETVPAGE:
CMP #>PSIDE1 ;CHECK IF IN RAMDSK
BCC GETYES
BNE GETNO
CPY #<PSIDE1 ;NOT SHURE
BCC GETYES
GETNO: STA DBLOCK+HI
STY DBLOCK+LO
TXA ;OFFSET INTO CORRECT RAM PAGE
CLC
ADC #PBEGIN
STA DBUFF+HI
LDX #AUX
STX DSKBNK
JMP GETDSK
GETYES: TYA
SEC
SBC #<VRAMDSK ; ZERO LIGN INTO RAMDSK
PHA ; SAVE RAMDSK SECTOR
TXA
CLC ; OFFSET TO CORRECT RAM PAGE
ADC #PBEGIN
TAY ; DESTINATION
STA RDBNK+MAIN ;FOR SAFTY
LDX #AUX ; SELECT AUX TO WRITE TO
STX RMDBNK
LDX #READ ; COMMAND
PLA ; SECTOR
JMP RAMDSK
; 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 HIGH ALOW ELSE SEC (Y=WANTED+LO)
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
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
GETBYT:
LDY MPCBNK ;SELECT CURRENT BANK
STA RDBNK,Y ;ENABLE READ
LDY MPCL
LDA (MPCPNT),Y ;GET THE BYTE
STA RDBNK+MAIN ;KILL (FOR SAFTY)
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
; LIKE GETBYT
NEXTPC: LDY ZPCBNK
STA RDBNK,Y
LDY ZPCL
LDA (ZPCPNT),Y
STA RDBNK+MAIN ;KILL
INC ZPCL
BNE NXTGOT
JSR CRSZPC
NXTGOT: TAY
RTS
PAGE
END