mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-08 09:11:27 +00:00
503 lines
9.4 KiB
Plaintext
503 lines
9.4 KiB
Plaintext
PAGE
|
|
SBTTL "--- I/O SUPPORT ROUTINES ---"
|
|
|
|
;-----------------------------------------
|
|
; INCRIMENT [VPC]+HI,[VPC]+LO,[VPC0]
|
|
;-----------------------------------------
|
|
|
|
INCVPC: LDA VPC0 ; EFFECTIVLY ADD 1
|
|
EOR #$01 ; WITH EOR
|
|
STA VPC0
|
|
BNE VPEX1
|
|
|
|
STA VPCFLG ; INVALIDATE FLAG
|
|
|
|
INC VPC+LO
|
|
BNE VPEX1
|
|
INC VPC+HI
|
|
VPEX1: RTS
|
|
|
|
;----------------------------
|
|
; ADD A,X TO [VPC]+HI,+LO,0
|
|
;----------------------------
|
|
|
|
ADDVPC: STX J+LO ; SAVE <X>
|
|
LSR A ; SHIFT SO AS TO ALIGN WITH 8,8,1 BIT PATTERN
|
|
; IN [VPC]
|
|
STA J+HI
|
|
ROR J+LO ; SHIFT LOW PART
|
|
BCC AVISK
|
|
JSR INCVPC ; IF CARRY SET ADD 1 TO [VPC]
|
|
CLC
|
|
AVISK: LDA VPC+LO
|
|
ADC J+LO
|
|
STA VPC+LO
|
|
LDA VPC+HI
|
|
ADC J+HI
|
|
STA VPC+HI
|
|
|
|
LDA #00 ; INVALIDATE FLAG
|
|
STA VPCFLG
|
|
|
|
RTS
|
|
|
|
|
|
;-----------------------------------------
|
|
; INCRIMENT [GPC]+HI,[GPC]+LO,[GPC0]
|
|
;-----------------------------------------
|
|
|
|
INCGPC: LDA GPC0 ; EFFECTIVLY ADD 1
|
|
EOR #$01 ; WITH EOR
|
|
STA GPC0
|
|
BNE GPEX1
|
|
|
|
STA GPCFLG ; INVALIDATE FLAG
|
|
|
|
INC GPC+LO
|
|
BNE GPEX1
|
|
INC GPC+HI
|
|
GPEX1: RTS
|
|
|
|
;----------------------------
|
|
; ADD A,X TO [GPC]+HI,+LO,0
|
|
;----------------------------
|
|
|
|
ADDGPC: STX J+LO ; SAVE <X>
|
|
LSR A ; SHIFT SO AS TO ALIGN WITH 8,8,1 BIT PATTERN
|
|
; IN [GPC]
|
|
STA J+HI
|
|
ROR J+LO ; SHIFT LOW PART
|
|
BCC AGISK
|
|
JSR INCGPC ; IF CARRY SET ADD 1 TO [GPC]
|
|
CLC
|
|
AGISK: LDA GPC+LO
|
|
ADC J+LO
|
|
STA GPC+LO
|
|
LDA GPC+HI
|
|
ADC J+HI
|
|
STA GPC+HI
|
|
|
|
LDA #00 ; INVALIDATE FLAG
|
|
STA GPCFLG
|
|
|
|
RTS
|
|
|
|
;-----------------------------------------
|
|
; INCRIMENT [IADR2]+HI,[IADR2]+LO,[IADR20]
|
|
;-----------------------------------------
|
|
|
|
INCIA2: LDA IADR20 ; EFFECTIVLY ADD 1
|
|
EOR #$01 ; WITH EOR
|
|
STA IADR20
|
|
BNE INEX2
|
|
INC IADR2+LO
|
|
BNE INEX2
|
|
INC IADR2+HI
|
|
INEX2: RTS
|
|
|
|
;----------------------------
|
|
; ADD A,X TO [IADR2]+HI,+LO,0
|
|
;----------------------------
|
|
|
|
ADDIA2: STX J+LO ; SAVE <X>
|
|
LSR A ; SHIFT SO AS TO ALIGN WITH 8,8,1 BIT PATTERN
|
|
; IN [IADR2]
|
|
STA J+HI
|
|
ROR J+LO ; SHIFT LOW PART
|
|
BCC ADIS2
|
|
JSR INCIA2 ; IF CARRY SET ADD 1 TO [IADR1]
|
|
CLC
|
|
ADIS2: LDA IADR2+LO
|
|
ADC J+LO
|
|
STA IADR2+LO
|
|
LDA IADR2+HI
|
|
ADC J+HI
|
|
STA IADR2+HI
|
|
RTS
|
|
|
|
;-----------------------------------------
|
|
; INCRIMENT [IADR1]+HI,[IADR1]+LO,[IADR10]
|
|
;-----------------------------------------
|
|
|
|
INCIA1: LDA IADR10 ; EFFECTIVLY ADD 1
|
|
EOR #$01 ; WITH EOR
|
|
STA IADR10
|
|
BNE INEX1
|
|
INC IADR1+LO
|
|
BNE INEX1
|
|
INC IADR1+HI
|
|
INEX1: RTS
|
|
|
|
;----------------------------
|
|
; ADD A,X TO [IADR1]+HI,+LO,0
|
|
;----------------------------
|
|
|
|
ADDIA1: STX J+LO ; SAVE <X>
|
|
LSR A ; SHIFT SO AS TO ALIGN WITH 8,8,1 BIT PATTERN
|
|
; IN [IADR1]
|
|
STA J+HI
|
|
ROR J+LO ; SHIFT LOW PART
|
|
BCC ADISK
|
|
JSR INCIA1 ; IF CARRY SET ADD 1 TO [IADR1]
|
|
CLC
|
|
ADISK: LDA IADR1+LO
|
|
ADC J+LO
|
|
STA IADR1+LO
|
|
LDA IADR1+HI
|
|
ADC J+HI
|
|
STA IADR1+HI
|
|
RTS
|
|
; ----------------
|
|
; GET BLOCKSET [A]
|
|
; ----------------
|
|
|
|
; ENTRY: BLOCKSET ID # (1-255) IN [A]
|
|
; EXIT: VIRTUAL BASE ADDR OF BLOCKSET DATA IN [BSADR]
|
|
; # BLOCKS IN [BSIZE]
|
|
; BLOCKSET DATA PAGED INTO RAM
|
|
|
|
GETBS: LDY #0
|
|
STY VPCFLG ; INVALIDATE [VPC]
|
|
STY I+HI ; CLEAR MSB OF INDEX
|
|
STY MUL ; AND MULTIPLICATION
|
|
STY MUH ; REGISTERS
|
|
|
|
SEC
|
|
SBC #1 ; ZERO-ALIGN AND
|
|
ASL A ; WORD-ALIGN THE
|
|
ROL I+HI ; BLOCKSET INDEX (ALSO CLEARS CARRY)
|
|
|
|
ADC BTAB+LO ; ADD BASE ADDRESS OF
|
|
STA I+LO ; BLOCKSET TABLE
|
|
LDA I+HI ; TO GET ABS ADDR OF POINTER
|
|
ADC BTAB+HI ; INTO [I]
|
|
STA I+HI
|
|
|
|
LDA (I),Y ; GET MSB OF POINTER ([Y] = 0)
|
|
STA VPCH
|
|
INY ; ALSO GET LSB
|
|
LDA (I),Y ; SO THAT [VPC] POINTS TO
|
|
STA VPCL ; V-ADDR OF BLOCKSET FILE
|
|
|
|
;***
|
|
LDA #00
|
|
STA VPC0
|
|
;***
|
|
JSR GETBYT
|
|
STA BLKLEN ; SAVE # BYTES PER BLOCK
|
|
|
|
JSR GETBYT ; 2ND BYTE HAS # BLOCKS
|
|
STA BSIZE ; SAVE HERE FOR REFERENCE
|
|
STA MUSHFT ; AND HERE FOR MULTIPLY
|
|
|
|
LDA VPCL ; MOVE V-ADDR OF BLOCKSET DATA
|
|
STA BSADR+LO ; INTO [BSADR]
|
|
LDA VPCH
|
|
STA BSADR+HI
|
|
|
|
CMP IPURE ; IS THIS SET IN I-PRELOAD?
|
|
BCC GBLX ; EXIT NOW IF SO
|
|
|
|
; LOAD THE ENTIRE BLOCKSET AT [VPC] INTO PAGING RAM
|
|
|
|
LDY #7 ; INIT BIT-LOOP INDEX
|
|
LDX BLKLEN ; GET BLOCK LENGTH
|
|
DEX ; ZERO-ALIGN
|
|
GBL1: TXA ; MULTIPLY BY
|
|
LSR MUSHFT ; # BLOCKS IN BLOCKSET
|
|
BCC GBL2 ; TO GET SIZE
|
|
ADC MUH ; OF BLOCKSET
|
|
STA MUH ; IN [MUL/H]
|
|
GBL2: ROR MUH
|
|
ROR MUL
|
|
DEY
|
|
BPL GBL1
|
|
|
|
;***
|
|
LSR MUH
|
|
ROR MUL
|
|
;***
|
|
|
|
LDA VPCL ; ADD LSB OF BLOCKSET START ADDRESS
|
|
CLC ; TO LSB OF
|
|
ADC MUL ; BLOCKSET SIZE IN [MUL/H]
|
|
BCC GBL3 ; CONTINUE IF NO PAGE OVERFLOW
|
|
INC MUH ; ELSE FORCE EXTRA PAGE LOAD
|
|
|
|
GBL3: LDA MUH ; IF [MUH] = 0,
|
|
BEQ GBLX ; NO MORE PAGES ARE NEEDED
|
|
|
|
GBL4: INC VPCH ; ELSE POINT TO NEXT PAGE
|
|
LDA #0
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
JSR GETBYT ; GET A BYTE (FORCE PAGE LOAD)
|
|
DEC MUH ; LOADED ALL BLOCKSET PAGES YET?
|
|
BNE GBL4 ; LOOP TILL EMPTY
|
|
|
|
LDA #0
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
|
|
GBLX: RTS
|
|
|
|
; ---------------------------------
|
|
; GET BLOCK [A] IN CURRENT BLOCKSET
|
|
; ---------------------------------
|
|
|
|
; ENTRY: BLOCK ID # (0-255) IN [A]
|
|
; EXIT: BLOCK DATA IN [BLOCK]
|
|
|
|
GETBLK: STA MUSHFT ; SAVE BLOCK ID
|
|
|
|
LDA #0
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
STA MUL ; CLEAR LSB AND
|
|
STA MUH ; MSB OF OFFSET
|
|
|
|
LDY #7 ; INIT BIT-SHIFT INDEX
|
|
|
|
LDX BLKLEN ; GET LENGTH OF BLOCKS
|
|
DEX ; ZERO-ALIGN
|
|
STX I+LO ; SAVE FOR LATER LOOPING
|
|
MULP: TXA
|
|
LSR MUSHFT
|
|
BCC MUSK
|
|
ADC MUH
|
|
STA MUH
|
|
MUSK: ROR MUH
|
|
ROR MUL
|
|
DEY
|
|
BPL MULP
|
|
|
|
;MUEND: LDA MUL ; [MUL/H] HAS BLOCK OFFSET
|
|
; CLC
|
|
; ADC BSADR+LO ; ADD THE VIRTUAL BASE ADDR
|
|
; STA VPCL ; OF THE CURRENT BLOCKSET
|
|
; LDA MUH ; TO GET THE VIRTUAL BASE ADDRESS
|
|
; ADC BSADR+HI ; OF THE DESIRED BLOCK
|
|
; STA VPCH
|
|
|
|
;***
|
|
MUEND: LDA BSADR+LO ; PUT WORD POINTER TO START OF BLOCKSET
|
|
STA VPCL ; IN VPCH,L
|
|
LDA BSADR+HI
|
|
STA VPCH
|
|
LDA #00 ; ZERO BOTTEM BIT
|
|
STA VPC0
|
|
|
|
LDA MUH ; ADD OFFSET TO BLOCK TO VPC
|
|
LDX MUL
|
|
JSR ADDVPC
|
|
;***
|
|
|
|
GBLL: JSR GETBYT ; GET A BYTE
|
|
LDX I+LO
|
|
STA BLOCK,X ; STORE BYTE IN [BLOCK]
|
|
DEC I+LO
|
|
DEX ; LOOP TILL
|
|
BPL GBLL ; ALL BYTES DONE
|
|
|
|
; NEGATE [BLOCK] IF [NEGATE] IS TRUE
|
|
|
|
LDA NEGATE
|
|
BEQ BLOCKX
|
|
|
|
LDX #7 ; NEGATE [BLOCK]
|
|
GBLLL: LDA BLOCK,X
|
|
EOR #$FF
|
|
STA BLOCK,X
|
|
DEX
|
|
BPL GBLLL
|
|
|
|
BLOCKX: RTS
|
|
|
|
; ------------------------
|
|
; SETUP FOR SETI AND SWAPI
|
|
; ------------------------
|
|
|
|
ISETUP: LDX ARG4+LO ; GET ADDR OF DESTINATION ICON
|
|
LDA ARG4+HI
|
|
CMP IPURE ; IS DEST IN I-PRELOAD?
|
|
BCC ISU ; CONTINUE IF SO
|
|
|
|
JMP PRERR2 ; ELSE PURITY VIOLATION!
|
|
|
|
;----------------------
|
|
; ENTRY FOR MASK SET UP
|
|
;----------------------
|
|
|
|
ISU: JSR GETI ; FETCH STATS OF DEST ICON
|
|
|
|
LDA IX1 ; COPY DEST ICON STATS
|
|
STA IX2 ; INTO AUXILIARY REGISTERS
|
|
LDA IY1
|
|
STA IY2
|
|
|
|
LDA IADR10
|
|
STA IADR20
|
|
LDA IADR1+LO
|
|
STA IADR2+LO
|
|
LDA IADR1+HI
|
|
STA IADR2+HI
|
|
|
|
LDX ARG3+LO ; NOW GET SOURCE ICON STATS
|
|
LDA ARG3+HI
|
|
|
|
; FALL THROUGH TO ...
|
|
|
|
; --------
|
|
; GET ICON
|
|
; --------
|
|
|
|
; ENTRY: V-ADDR OF ICON FILE IN [X/A]
|
|
; EXIT: ICON DATA V-ADDR IN [IADR1]
|
|
; X-SIZE IN [IX1] & [XDEX1]
|
|
; Y-SIZE IN [IY1] & [YDEX1]
|
|
; ASSIGNED BLOCKSET IN [BSET]
|
|
|
|
GETI: STX VPCL
|
|
STA VPCH
|
|
LDA #0
|
|
;***
|
|
STA VPC0
|
|
;***
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
|
|
JSR GETBYT ; 1ST BYTE HAS
|
|
STA BSET ; ASSIGNED BLOCKSET
|
|
|
|
JSR GETBYT ; 2ND BYTE HAS
|
|
STA ITERS ; # ITERATIONS
|
|
|
|
JSR GETBYT ; 3RD BYTE HAS
|
|
STA IX1 ; X-SIZE
|
|
|
|
JSR GETBYT ; 4TH BYTE HAS
|
|
STA IY1 ; Y-SIZE
|
|
STA J+LO ; SAVE HERE FOR LATER
|
|
|
|
LDA VPCL ; SAVE BASE V-ADDR
|
|
STA IADR1+LO ; IN [IADR]
|
|
LDA VPCH
|
|
STA IADR1+HI
|
|
LDA VPC0
|
|
STA IADR10
|
|
|
|
|
|
CMP IPURE ; IS THIS ICON PRELOADED?
|
|
|
|
BCC NEWXY ; YES, SCRAM NOW
|
|
|
|
|
|
; MAKE SURE ICON DATA IS PAGED INTO RAM
|
|
|
|
LDA VPCL ; GET CURRENT PAGE POINTER
|
|
CLC
|
|
ADC IX1 ; ADD X-OFFSET
|
|
BCS ILD1 ; GET NEW PAGE IF BOUNDARY CROSSED
|
|
|
|
ILD0: DEC J+LO ; OUT OF X-LINES YET?
|
|
BEQ ILD2 ; YES, ICON IS ALL LOADED
|
|
ADC IX1 ; ELSE ADD ANOTHER X-LINE
|
|
BCC ILD0 ; LOOP BACK IF SAME PAGE
|
|
|
|
ILD1: STA J+HI ; SAVE NEW PAGE POINTER
|
|
INC VPCH ; POINT TO NEXT PAGE
|
|
LDA #0
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
JSR GETBYT ; TO FORCE PAGE LOAD
|
|
LDA J+HI ; RESTORE POINTER
|
|
CLC ; CLEAR CARRY FOR NEW LOOP
|
|
BCC ILD0 ; BRANCH ALWAYS
|
|
|
|
ILD2: LDA #0
|
|
STA VPCFLG ; INVALIDATE [VPC]
|
|
|
|
; FALL THROUGH ...
|
|
|
|
|
|
; -------------------------
|
|
; REFRESH [XDEX1] & [YDEX1]
|
|
; -------------------------
|
|
|
|
NEWXY: LDA IX1
|
|
STA XDEX1
|
|
LDA IY1
|
|
STA YDEX1
|
|
RTS
|
|
|
|
; -----------------------------
|
|
; WILL SOURCE ICON FIT IN DEST?
|
|
; -----------------------------
|
|
|
|
; ENTRY: SOURCE STATS IN [1] REGISTERS, DEST IN [2]
|
|
; EXIT: CARRY CLEAR IF FIT OKAY, ELSE CARRY SET
|
|
; [IADR2] HAS ABSOLUTE ADDRESS OF SUB-ICON
|
|
|
|
DOFIT: LDA ARG1+LO ; GET X-POSITION
|
|
CLC
|
|
ADC IX1 ; ADD X-SIZE OF SOURCE
|
|
CMP IX2 ; COMPARE TO SIZE OF DEST
|
|
BCC FIT ; OKAY IF LESS
|
|
BNE FITEX ; OR EQUAL; ELSE EXIT W/CARRY SET
|
|
|
|
FIT: LDA ARG2+LO ; GET Y-POSITION
|
|
TAY ; SAVE HERE FOR INDEXING BELOW
|
|
CLC
|
|
ADC IY1 ; ADD SIZE OF SOURCE
|
|
CMP IY2 ; COMPARE TO SIZE OF DEST
|
|
BCC FIT0 ; OKAY IS LESS
|
|
BNE FITEX ; SO IS EQUAL; ELSE EXIT W/CARRY SET
|
|
|
|
; MAKE [IADR2] POINT TO ADDR OF SUB-ICON
|
|
|
|
FIT0: LDA ARG1+LO ; IF X-POS OF SUB-ICON IS 0,
|
|
BEQ FIT3 ; DON'T ADD X-OFFSET
|
|
|
|
; LDA IADR2+LO
|
|
; CLC
|
|
; ADC ARG1+LO ; ADD X-COORD OF SUB-ICON
|
|
; STA IADR2+LO ; TO BASE ADDR OF DEST ICON
|
|
; BCC FIT3 ; TO GET BASE ADDR OF SUB-ICON
|
|
; INC IADR2+HI
|
|
; BNE FIT3 ; ALWAYS SKIP 1ST Y-ITERATION
|
|
;***
|
|
LDA #0
|
|
LDX ARG1+LO
|
|
JSR ADDIA2
|
|
JMP FIT3
|
|
;***
|
|
|
|
;FIT2: LDA IADR2+LO ; ADD X-SIZE OF DEST ICON
|
|
; CLC ; TO BASE ADDR OF SUB-ICON
|
|
; ADC IX2 ; ONCE FOR EACH Y-COORD
|
|
; STA IADR2+LO
|
|
; BCC FIT3
|
|
; INC IADR2+HI
|
|
;***
|
|
FIT2: LDA #0
|
|
LDX IX2
|
|
JSR ADDIA2
|
|
;***
|
|
|
|
FIT3: DEY ; OUT OF Y-COORDS YET?
|
|
BPL FIT2 ; NO, KEEP ADDING
|
|
|
|
LDA IADR2+HI ; MAKE SUB-ICON ADDR ABSOLUTE
|
|
SEC ; BY STRIPPING OFF THE
|
|
SBC ISTART ; V-OFFSET
|
|
|
|
;***
|
|
LSR IADR20
|
|
ROL IADR2+LO
|
|
ROL A
|
|
;***
|
|
CLC ; AND ADDING THE ABS ADDR
|
|
ADC ICODE+HI ; OF THE
|
|
STA IADR2+HI ; I-PRELOAD (LSB NEEDN'T CHANGE)
|
|
CLC ; CLEAR CARRY FOR SUCCESS
|
|
|
|
FITEX: RTS
|
|
|
|
END
|
|
|