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 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 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 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 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