; C02 module vera.h02 assembly language subroutines ; Requires External Functions NYBCAT, NYBCUT ; and Variables TEMP0 ;getadr() - Get Vera Address ;Args: A = Bank + Auto-Increment ; Y,X = Address GETADR: LDX $9F20 ;Store Address LSB LDY $9F21 ;Store Address MSB LDA $9F22 ;Store Bank & Auto-Increment RTS ;getvid() - Get Video Output Mode ;Returns: A = Video Mode ; Y = Chroma Disabled ; X = Current Field GETVID: LDA #$00 ;Set Register Offset to Video Output JSR GETDCR ;Read from Display Composer LDY #$00 ;Set Chroma Disabled to FALSE LDX #$00 ;Set Video Field to EVEN BIT GETVIM ;Test Chroma Disabled Bit BEQ GETVIE ;If Bit 3 is Set DEY ; Set Chroma Disabled to TRUE BIT GETVIM ;Test Chroma Disabled Bit GETVIE: BCC GETVIF ;If Bit 7 is Set DEX ; Set Video Field to ODD GETVIF: AND #$03 ;Isolate Bits 0-2 (Video Output Mode) RTS GETVIM: .DC $04 ;Chroma Disable Bit Mask ;getbdr() - Get Get Border Color ;Returns: A = Border Color Palette Index GETBDR: LDA #$03 ;Set Register Offset to Border Color ;getdcr() - Get Display Composer Register ;Args: A = Register Offset ;Affects: Y ;Returns: A = Contents of Register ; X = Current Data Port GETDCR: LDY #$00 ;Set MSB to Display Composer Page TAX ;Set LSB to Register Offset ;and Execute GETREG ;getreg(&addr); ;Args: Y,X = Address ;Returns: A = Mode ; X = Current Data Port GETREG: LDA #$0F ;Set Bank to Registers GETBYT: JSR SETADR ;Set Vera Address LDX $9F25 ;Get Current Data Port LDA $9F23,X ;Read LSB from Data Port RTS ;getmem(count, &addr) - Read Array From Vera Memory ;Args: A = Number of Bytes to Read ; Y,X = Address of Array to Read Into ;Requires: setadr() ;Sets: DSTLO,DSTHI = Address of Array ; TEMP0 = Number of Bytes to Read ;Affects: A ;Returns: Y = Number of Bytes Read ; X = Current Data Port GETMEM: JSR SETDST ;Save Destination Address GETMEA: STA TEMP0 ;Save Number of Bytes LDY #0 ;Initialize Counter LDX $9F25 ;Get Current Data Port GETMEL: LDA $9F23,X ;Read Byte from Data Port STA (DSTLO),Y ;Store in Memory INY ;Increment Counter CPY TEMP0 ;If Limit Not Reached BNE GETMEL ; Loop ;getmod() - Get Layer 0/1 Mode ;Args: A = Layer (0/1) ;Affects: Y ;Returns: A = Layer Mode ; X = Current Data Port GETMOD: JSR GETLRC ;Read Register LSR ;Shift Left Five Bits LSR LSR LSR RTS ;getenb() - Get Layer 0/1 Enabled ;Args: A = Layer (0/1) ;Affects: Y ;Returns: A = $FF - Layer Enabled ; $00 - Layer Disabled ; X = Current Data Port GETENB: JSR GETLRC ;Read Register AND #$01 ;Isolate Bit 1 BEQ GETENX ;If Set LDA #$FF ; Return TRUE GETENX: RTS ;Else Return FALSE ;getlrc() - Get Layer 0/1 Control Register ;Args: A = Layer (0/1) ;Affects: Y ;Returns: A = Control Register Contents ; X = Current Data Port GETLRC: LDX #0 ;Set Offset to Control Register ;getlrr() - Get Layer 0/1 Register ;Args: A = Layer (0/1) ; X = Register Offset ;Affects: Y ;Returns: A = Contents of Register ; X = Current Data Port GETLRR: JSR GETLRP ;Get Layer Page in Y BNE GETREG ;and Read Register Contents ;getlrp() - Get Layer 0/1 Register Page ;Args: A = Layer (0/1) ;Returns: A,Y = Layer Register Page GETLRP: AND #$01 ;Isolate Bit 1 ASL ;Move to Left Nybble ASL ASL ASL ORA #$20 ;And Add to 2 TAY ;Return Page in Y RTS ;getchd(index, &array) - Read Character Data into Array ;Args: A = Character Index ; Y,X = Address of Array to Read into ;Destroys: TEMP0,TEMP1,TEMP2 ;Returns: A = Number of Bytes Read GETCHD: JSR SETDST ;Store Address in Destination Pointer STA TEMP1 ;Set Offset LSB to Index LDA #0 ;Set Offset MSB to Zero ASL TEMP1 ;Multiple Offset by 2 ROL STA TEMP2 ;and Store MSB JSR GETLRI ;Get Tile Base TXA ;Add Offset To Tile Base CLC ADC TEMP0 STA TEMP0 TYA ADC TEMP1 STA TEMP1 LDA #0 ADC #0 JSR GETMBX ;Multiply by 4 ORA #$10 ;Set Auto-Increment to 1 JSR SETADR ;and Set Vera Address LDA #8 ;Set Byte Count to 8 BNE GETMEA ;and Read Bytes into Array ;gettba() - Get Layer 0/1 Tile Base Address ;Args: A = Layer (0/1) ;Destroys: TEMP1,TEMP2 ;Returns: A = Tile Base Bank ; Y,X = Tile Base Address GETTBA: LDX #4 ;Set Register Offset .DC $2C ;Read Register Pair and Rotate ;getmba() - Get Layer 0/1 Map Base Address ;Args: A = Layer (0/1) ;Destroys: TEMP1,TEMP2 ;Returns: A = Map Base Bank ; Y,X = Map Base Address GETMBA: LDX #2 ;Set Register Offset JSR GETLRI ;Read Register Pair as Integer LDA #0 ;Initialize Page to 0 JSR SAVRXY ;Save Integer in TEMP1,TEMP2 GETMBX: LDX #2 ;Do Twice GETMBL: ASL TEMP1 ; Rotate LSB ROL TEMP2 ; MSB and ROL ; Bank Left DEX BNE GETMBL JMP RESRXY ;Load LSB, MSB and Return ;getvsc() - Get Layer 0/1 Vertical Scroll ;Args: A = Layer (0/1) ;Returns: A,X = Vertical Scroll LSB ; Y = Vertical Scroll MSB GETVSC: LDX #8 ;Set Register Offset .DC $2C ;Skip to GETLRI (BIT Absolute) ;gethsc() - Get Layer 0/1 Horizontal Scroll ;Args: A = Layer (0/1) ;Returns: A,X = Horizontal Scroll LSB ; Y = Horizontal Scroll MSB GETHSC: LDX #6 ;Set Register Offset .DC $2C ;Skip to GETLRI (BIT Absolute) ;gettbs() - Get Layer 0/1 Tile Base ;Args: A = Layer (0/1) ;Returns: A,X = Tile Base LSB ; Y = Tile Base MSB GETTBS: LDX #4 ;Set Register Offset .DC $2C ;Skip to GETLRI (BIT Absolute) ;getmbs() - Get Layer 0/1 Map Base ;Args: A = Layer (0/1) ;Returns: A,X = Map Base LSB ; Y = Map Base MSB GETMBS: LDX #2 ;Set Register Offset ;getlri() - Get Layer 0/1 Register Pair as Integer ;Args: A = Layer (0/1) ; X = Register Offset ;Returns: A,X = Integer LSB ; Y = Integer LSB GETLRI: JSR GETLRP ;Get Layer Page in Y BNE GETREI ;and Read Register Contents ;mapsiz() - Convert Map Size Specifier to Pixels ;Args: A = Map Size Specifier ;Affects: A ;Returns: Y,X Map Size in Pixels MAPSIZ: TAX ;Copy Map Size Specifier to X LDA MAPSIH,X ;Load Pixels MSB from Table TAY ;and Return in Y LDA MAPSIL,X ;Load Pixels LSB from Table TAX ;and Return in X MAPSIL: .DC $20,$40,$80,$00 MAPSIH: .DC $00,$00,$00,$01 ;tilsiz() - Convert Tile Size Specifier to Pixels ;Args: A = Tile Size Specifier ;Affects: A ;Returns: A Tile Size in Pixels TILSIZ: TAX ;Copy Map Size Specifier to X LDA TILSIT,X ;Load Pixels MSB from Table RTS TILSIT: .DC $08,$10 ;gettsz() - Get Layer 0/1 Tile Size ;getmsz() - Get Layer 0/1 Map Size ;Args: A = Layer (0/1) ;Affects: X ;Returns: A = Map Width Specifier ; Y = Map Height Specifier ;getvsp() - Get Vertical Stop ;Affects: A ;Returns: Y,X = Vertical Stop GETVSP: LDA #7 ;Set Reg Offset to Vertical Stop JSR GETHVS ;Read Registers LSR ;Shift Left One Bit JMP GETVSS ;Then Four More Bits and Mask ;getvsr() - Get Vertical Start ;Affects: A ;Returns: Y,X = Vertical Start GETVSR: LDA #6 ;Set Reg Offset to Vertical Start JSR GETHVS ;Read Registers GETVSS: LSR ;Shift Left Four Bit LSR LSR LSR AND #$01 ;Isolate Bit 0 TAY ;and Copy MSB to Y RTS ;gethsp() - Get Horizontal Stop ;Affects: A ;Returns: Y,X = Horizontal Stop GETHSP: LDA #5 ;Set Lookup Index to Horizontal Start JSR GETHVS ;Read Registers LSR ;Shift Left Two Bits LSR JMP GETHSS ;then Mask and Return ;gethsr() - Get Horizontal Start ;Affects: A ;Returns: Y,X = Horizontal Start GETHSR: LDA #4 ;Set Lookup Index to Horizontal Start JSR GETHVS ;Read Registers ;.dc $ff ;debug GETHSS: AND #$03 ;Isolate Bit 0 TAY ;and Copy MSB to Y RTS ;gethvs() - Get Start/Stop Low Byte and High Bits ;Args: X = Low Register ;Affects: Y ;Returns: A = High Bits ; X = Low Byte GETHVS: JSR GETDCR ;Read LSB from Register ;.dc $ff ;debug PHA ;and Save It LDA #8 ;Load Register Offset for High Bits STA $9F20 ;Set As Address LSB LDA $9F23,X ;and Read High Bits into A .DC $FA ;PLX ;Restore LSB into X RTS ;getiql() - Get Interrupt Line ;Affects: A ;Returns: Y,X = Interrupt Line# GETIQL: LDA #9 ;Set Register Offset to Interrupt Line .DC $2C ;Skip to SETDCX (BIT Absolute) ;getscl() - Get Horizontal and Vertical Scale ;Returns: A,X = Horizontal Scale ; Y = Vertical Scale GETSCL: LDA #1 ;Set Register Offset to HSCALE,VSCALE .DC $2C ;Skip SETDCI (BIT Absolute) ;getdci() - Get Display Composer Register Pair ;Args: A = Register Offset ;Affects: Y ;Returns: A,X = Integer LSB ; Y = Integer LSB GETDCI: LDY #$00 ;Set MSB to Display Composer Page TAX ;Set LSB to Register Offset ;and Execute GETREI ;getrei(addr); Read Vera Register Pair ;Args: Y,X = Address ;Returns: A,X = Integer LSB ; Y = Integer LSB GETREI: LDA #$0F ;Set Bank to Registers ;getint(addr); Read Integer from Vera Memory ;Args: A = Bank ; Y,X = Address ;Returns: A,X = Integer LSB ; Y = Integer LSB GETINT: ORA #$10 ;Set Auto-Increment to 1 JSR SETADR ;Set Vera Address LDX $9F25 ;Get Current Data Port LDA $9F23,X ;Read LSB from Data Port LDY $9F23,X ;Read MSB Data Port TAX ;Copy LSB to X RTS ;setvsp() - Set Horizontal Stop ;Args: Y,X = Horizontal Stop ;Affects: A,X,Y SETVSP: TYA ;Convert MSB to High Bit AND #$01 ASL ASL ASL ASL ASL STA TEMP1 ;and Save TXA ;Copy LSB to Accumlator LDX #7 ;Set Register Offset to Horizontal Start LDY #$DF ;Set High Bits Mask JMP SETHST ;OR in High Bits and Write Back ;setvsr() - Set Horizontal Start ;Args: Y,X = Horizontal Start ;Affects: A,X,Y SETVSR: TYA ;Convert MSB to High Bit AND #$01 ASL ASL ASL ASL STA TEMP1 ;and Save TXA ;Copy LSB to Accumlator LDX #6 ;Set Register Offset to Horizontal Start LDY #$EF ;Set High Bits Mask JMP SETHST ;OR in High Bits and Write Back ;sethsp() - Set Horizontal Stop ;Args: Y,X = Horizontal Stop ;Affects: A,X,Y SETHSP: TYA ;Convert MSB to High Bits AND #$03 ASL ASL STA TEMP1 ;and Save TXA ;Copy LSB to Accumlator LDX #5 ;Set Register Offset to Horizontal Start LDY #$F3 ;Set High Bits Mask JMP SETHST ;OR in High Bits and Write Back ;sethsr() - Set Horizontal St7art ;Args: Y,X = Horizontal Start ;Destroys TEMP0,TEMP1,TEMP2 ;Affects: A,X,Y SETHSR: TYA ;Convert MSB to High Bits AND #$03 STA TEMP1 ;and Save TXA ;Copy LSB to Accumlator LDX #4 ;Set Register Offset to Horizontal Start LDY #$FC ;Set High Bits Mask SETHST: STY TEMP2 ;Save JSR SETHVS ;Write LSB and Get High Bits AND TEMP2 ;Mask Start Stop High ORA TEMP1 ;OR in High Bits STA $9F23,X ;and Write back to Register RTS SETHVS: JSR SETDCX ;Write LSB LDA #8 ;Load Register Offset for High Bits STA $9F20 ;Set As Address LSB LDA $9F23,X ;and Read High Bits into A RTS ;setvid() - Set Video Output Mode ;Args: A = Video Mode ; Y = Chroma Disabled ;Destroys: TEMP0 SETVID: AND #3 ;Isolate Video Mode Bits CPY #0 ;Set Chroma Mask to BEQ SETVIF ; 0 if Y is Zero or LDY #4 ; 4 if it is not SETVIF: STY TEMP0 ;Save Chroma Bit ORA TEMP0 ;Combine with Video Mode Bits LDX #0 ;Set Register Offset to Video Mode BEQ SETDCX ;Write to Register ;setbdr() - Set Border Color ;Args: A = Border Color Palette Index SETBDR: LDX #3 ;Set Register Offset to Border Color .DC $2C ;Skip to SETDCX (BIT Absolute) ;setdcr() - Set Display Composer Register ;Args: A = Register Offset ; Y = Value to Write ;Affects: Y ;Returns: A = Value Written ; X = Current Data Port SETDCR: TAX ;Set LSB to Register Offset TYA ;Move Write Value to Accumulator SETDCX: LDY #$00 ;Set MSB to Display Composer Page ;setreg(addr) - Set Register ;Args: A = Value to Write ; Y,X = Address ;Sets: TEMP0 = Value to Write ;Affects: Y ;Returns: A = Value Written ; X = Current Data Port SETREG: STA TEMP0 ;Save Value to Write SETREH: LDA #$0F ;Set Bank, Auto-Increment ;setbyt(addr) - Write Byte to Vera Memory ;Args: A = Bank ; Y,X = Address ;Uses: TEMP0 = Value to Write ;Affects: Y ;Returns: A = Value Written ; X = Current Data Port SETBYT: JSR SETADR ;Set Vera Address LDA TEMP0 ;Retrieve Value to Write LDX $9F25 ;Get Current Data Port STA $9F23,X ;Write Value to Data Port RTS ;settbs() - Set Layer 0/1 Map Base ;Args: A = Layer (0/1) ; Y,X = Map Base ;Sets: TEMP1,TEMP2 = Map Base ;Affecta: A,Y,X SETTBS: JSR SAVRXY ;Store Map Base in TEMP1,TEMP2 LDX #4 ;Set Register Offset BNE SETLRI ;Write to Layer Register ;setmbs() - Set Layer 0/1 Map Base ;Args: A = Layer (0/1) ; Y,X = Map Base ;Sets: TEMP1,TEMP2 = Map Base ;Affecta: A,Y,X SETMBS: JSR SAVRXY ;Store Map Base in TEMP1,TEMP2 LDX #2 ;Set Register Offset BNE SETLRI ;Write to Layer Register ;setvsc() - Set Layer 0/1 Vertical Scroll ;Args: A = Layer (0/1) ; Y,X = Map Base ;Sets: TEMP1,TEMP2 = Vertical Scroll ;Affecta: A,Y,X SETVSC: JSR SAVRXY ;Store Vertical Scroll in TEMP1,TEMP2 LDX #8 ;Set Register Offset BNE SETLRI ;Write to Layer Register ;sethsc() - Set Layer 0/1 Horizontal Scroll ;Args: A = Layer (0/1) ; Y,X = Map Base ;Sets: TEMP1,TEMP2 = Horizontal Scroll ;Affecta: A,Y,X SETHSC: JSR SAVRXY ;Store Horizontal Scroll in TEMP1,TEMP2 LDX #6 ;Set Register Offset ;setlri() - Write Integer to Get Layer 0/1 Register ;Args: A = Layer (0/1) ; X = Register Offset ;Uses: TEMP1,TEMP2 = Integer Value ;Affecta: A,Y,X SETLRI: JSR GETLRP ;Get Layer Page in Y BNE SETREI ;and Write Integer to Register ;setiql() - Set IRQ Line ;Args: Y,X = IRQ Line Number` ;Sets: TEMP1,TEMP2 = IRQ Line Number ;Affecta: A,Y,X SETIQL: TXA ;Copy LSB to Accumulator LDX #9 ;Set Register Offset to HSCALE,VSCALE .DC $2C ;Skip to SETDCP (BIT Absolute) ;setscl() - Set Horizontal and Vertical Scale ;Args: A = Horizontal Scale ; Y = Vertical Scale SETSCL: LDX #1 ;Set Register Offset to HSCALE,VSCALE ;setdcp() - Set Display Composer Register Pair ;Args: A = First Register Value ; Y = Second Register Value ; X = Register Offset ;Affects: A,Y ;Returns: X = Current Data Port SETDCP: STA TEMP1 ;Store First Value as LSB STY TEMP2 ;Store Second Value as MSB LDY #$00 ;Set MSB to Display Composer Page ;setrei(addr); Set Vera Register to Integer ;Args: Y,X = Address ;Uses: TEMP1,TEMP2 = Integer Value ;Affects: A,Y ;Returns: X = Current Data Port SETREI: LDA #$0F ;Set Bank to Registers ;setint(addr); Write Integer to Vera Memory ;Args: A = Bank ; Y,X = Address ;Uses: TEMP1,TEMP2 = Integer Value ;Affects: A,Y ;Returns: X = Current Data Port SETINT: ORA #$10 ;Set Auto-Increment to 1 JSR SETADR ;Set Vera Address LDX $9F25 ;Get Current Data Port LDA TEMP1 ;Get LSB STA $9F23,X ;Write to Data Port LDA TEMP2 ;Get MSB STA $9F23,X ;Write to Data Port RTS ;setmem(count, &addr) - Write Array to Vera Memory ;Args: A = Number of Bytes to Write ; Y,X = Address of Array to Write From ;Requires: setadr() ;Sets: SRCLO,SRCHI = Address of Array ; TEMP0 = Number of Bytes to Write ;Affects: A ;Returns: Y = Number of Bytes Written ; X = Current Data Port SETMEM: STA TEMP0 ;Save Number of Bytes JSR SETSRC ;Save Destination Address LDX $9F25 ;Get Current Data Port LDY #0 ;Initialize Counter SETMEL: LDA (SRCLO),Y ;Read Byte from Array STA $9F23,X ;Write Byte to Data Port INY ;Increment Counter CPY TEMP0 ;If Limit Not Reached BNE SETMEL ; Loop RTS ;rgbclr(r,g,b) - Convert RGB Values to Palette Color ;Args: A = Red Value (0-15) ; Y = Green Value (0-15) ; X = Blue Value (0-15) ;Affects: A ;Returns: Y = Color MSB (0000RRRR) ; X = Color LSB (GGGGBBBB) RGBCLR: PHA ;Save Red Value TYA ;Copy Green Value to Left Nybble .DC $DA ;PHX Copy Blue Value .DC $7A ;PLY to Right Nybble JSR NYBCAT ;Concatanate Green and Blue TAX ;and Return as LSB .DC $7A ;PLY Return Red as MSB RTS ;clrrgb(c) - Convert Palette Color to RGB Values ;Args: Y = Color MSB (0000RRRR) ; X = Color LSB (GGGGBBBB) ;Returns: A = Red Value (0-15) ; Y = Green Value (0-15) ; X = Blue Value (0-15) CLRRGB: .DC $5A ;PHY Save MSB TXA ;Copy LSB into Accumulator JSR NYBCUT ;and Split into Nybbles .DC $5A ;PHY Return Blue Value .DC $FA ;PLX in X Register TAY ;Green Value in Y Register PLA ;and Red Value in Accumulator RTS ;getclr(idx) - Get Color Entry idx from Palette ;Args: A = Color Entry Index ;Affects: A ;Returns: Y = Color MSB (0000RRRR) ; X = Color LSB (GGGGBBBB) GETCLR: JSR SETIDX ;Set Vera Address to Palette Index LDX $9F25 ;Get Current Data Port LDA $9F23,X ;Read LSB from Data Port LDY $9F23,X ;Read MSB from Data Port TAX ;Copy LSB to X Register RTS ;setclr(idx) - Set Color Entry idx in Palette ;Args: A = Color Entry Index ; Y = Color MSB (0000RRRR) ; X = Color LSB (GGGGBBBB) ;Affects: A ;Returns: Y,X = Color Entry Address SETCLR: JSR SAVRXY ;Save Color Value JSR SETIDX ;Set Vera Address to Palette Index LDX $9F25 ;Get Current Data Port LDA TEMP1 ;Retrieve Color Value LSB STA $9F23,X ;and Write to Data Port LDA TEMP2 ;Retrieve Color Value MSB STA $9F23,X ;Read MSB from Data Port RTS ;setidx(idx) - Set Vera Address to Palette Index ;Args: A = Index ;Returns: A = Bank + Auto-Increment ; Y,X = Address SETIDX: ASL ;Multiply Index by 2 TAX ;and Set as LSB LDA #$10 ;Get Palette Page ADC #$00 ;Add Carry from Multiply TAY ;and Set as MSB ;regadr(opts,addr) - Set Vera Address to Internal Register ;Args: Y,X = Register Address ;Returns: A= Bank + Auto-Increment REGADR: LDA #$1F ;Set Bank and Auto-Increment ;setadr(opts,addr) - Set Vera Address ;Args: A = Bank + Auto-Increment ; Y,X = Address SETADR: STX $9F20 ;Store Address LSB STY $9F21 ;Store Address MSB STA $9F22 ;Store Bank & Auto-Increment RTS