Files
erkyrath.infocom-zcode-terps/atari/iosubs.dip
Andrew Plotkin b642da811e Initial commit.
2023-11-16 18:19:54 -05:00

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