Files
Andrew Plotkin b642da811e Initial commit.
2023-11-16 18:19:54 -05:00

598 lines
10 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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