; Commander X16 Extended Memory Assembly Langyage Routines for C02 ;Extended Memory Constants XLBANK EQU $0F ;Maximum Logical Bank ;Extended Memory Address - Defined in x16.a02 ; Physical Address Logical Address ;XMBANK Bank ($00-$FF) Bits 20-13 ;XADRLO Address LSB ($00-$FF) Bits 7- 0 ;XADRHI Address MSB ($A0-$BF) Bits 12- 8 ;VIA Registers XSBANK EQU $9F61 ;RAM Bank Select ;xgetla() - Get Logical Extended Memory Address ;Destroys: TEMP0 ;Returns: A = Logical Bank ($0-$F$) ; $FF if Physical Address Invalid ; Y,X = Logical Address ($0000-$FFFF) ; Carry Set if Physical Address is Invalid XGETLA: JSR XGETPN ;xclcla(bank,page,byte) - Convert Physical to Logical Address ;Args: A = Physical Bank ($00,$FF) ; Y,X = Physical Address ($A000-$BFFF) ;Destroys: TEMP0 ;Returns: A = Logical Bank ($00-$0F) ; Y,X = Logical Address ($0000-$000F) ; Carry Set if Physical Address is Invalid XCLCLA: STA TEMP0 ;Save Physical Bank TYA ;Get Physical MSB AND #$E0 ;Isolate Bits 5-7 CMP #$A0 ;If Not in Banked RAM Area BNE XRCSET ; Return Carry Set TYA ;Get Physical MSB ASL ;Rotate Bits 8-12 to 11-15 ASL ASL LSR TEMP0 ;Rotate Physical Bank ROR ;into Logical Bits 13-20 LSR TEMP0 ROR LSR TEMP0 ROR TAY ;Copy MSB into Y LDA TEMP0 ;Load Bank into A CLC ;Return Carry Clear RTS XRCSET: SEC ;Return Carry Set RTS ;xclcpa(bank,page,byte) - Convert Logical to Physical Address ;Args: A = Logical Bank ($00-$0F) ; Y,X = Logical Address ($0000-$000F) ;Destroys: TEMP0 ;Returns: A = Physical Bank ($00,$FF) ; Y,X = Physical Address ($A000-$BFFF) ; Carry Set if Logical Address is Invalid XCLCPA: CMP #$10 ;If Bank >= 16 BCS XLPADX ; Return Carry Set STA TEMP0 ;Store Logical Bank,LSB,MSB in TEMP0,TEMP1,TEMP2 TYA ;Get Logical Address MSB ASL ;Rotate Logical Bits 13-20 into Physical Bank ROL TEMP0 ASL ROL TEMP0 ASL ROL TEMP0 LSR ;Shift Bits 8-12 back into Position LSR LSR ORA #$A0 ;Convert to Physical MSB TAY ;and Copy Back to Y LDA TEMP0 ;Load Physical Bank into Accumulator XLPADX: RTS ;xsetla(bank,page,byte) - Set Logical Extended Memory Address ;Args: A = Logical Bank ($0-$F$) ; Y,X = Logical Address ($0000-$FFFF) ;Destroys: TEMP0 ;Returns: A = Physical Bank ($00-$FF) ; Y,X = Physical Address ($A000-$BFFF) XSETLA: JSR XCLCPA ;Convert Logical Address to Physical Address BCC XSETPN ;If Valid, Store and Return RTS ;Else Return Carry Set ;xsetpa(bank,page,byte) - Set Physical Extended Memory Address ;Args: A = Physical Bank ($00-$FF) ; Y,X = Physical Address ($A000-$BFFF) ;Destroys: TEMP0 ;Returns: A = Physical Bank ($FF if Address Invalid) ; Y,X = Physical Address ; Carry Set if Logical Address is Invalid XSETPA: JSR XVALPA ;Validate Physical Address BCS XSETPX ;If Invalid, Return Carry Set ;XSETPn(bank,page,byte) - Set Physical Address without Error Checking ;Args: A,Y,X = Physical Extended Address XSETPN: STA XMBANK ;Store Physical Bank STY XADRHI ;Store Physical MSB STX XADRLO ;Store Physical LSB XSETPX: RTS ;XGETPA() - Get Physical Extended Memory Address ;Returns: A = Physical Bank ($FF if Address Invalid) ; Y,X = Physical Address XGETPA: LDA XADRHI ;Load Physical MSB AND #$E0 ;Isolate Bits 5-7 CMP #$A0 ;If Not in Banked RAM Area BNE XRCSET ; Return Carry Set ;xgetpn() - Get Physical Address without Error Checking ;Returns: A,Y,X = Physical Extended Address XGETPN: LDA XMBANK ;Load Physical Bank LDY XADRHI ;Load Physical MSB LDX XADRLO ;Load Physical LSB RTS ;xvalpa(bank,page,byte) - Validate Physical Extended Address ;Args: A = Physical Bank ($00-$FF) ; Y,X = Physical Address ($A000-$BFFF) ;Returns: Carry Set if Logical Address is Invalid XVALPA: CPY #$A0 ;If MSB<$A0 BCC XRCSET ; Return Carry Set CPY #$C0 ;Return Carry Set if MSB>=$C0 RTS ;xselrb() - Select Extended RAM Bank ;Sets: XSBANK to XMBANK ;Returns: Y = 0 XSELRB: LDY XMBANK ;Get Physical Bank STY XSBANK ;and Select RAM Bank LDY #0 RTS ;xgetl() - Read Long from Extended Memory ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Returns: A,Y,X = Bytes Read ; Carry Set if Address Rolled Over XGETL: JSR XGETI ;Read X,Y from Extended Memory BRA XGETC ;Read A from Extended Memory ;xgeti() - Read Word from Extended Memory ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A ;Returns: Y,X = Word Read ; Carry Set if Address Rolled Over XGETI: JSR XGETC ;Read LSB from Extended Memory TAX ;and Return in X JSR XGETC ;Read MSB from Extended Memory TAY ;and Return in Y RTS ;xgetc() - Read Byte from Extended Memory ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: Y ;Returns: A = Byte Read ; Carry Set if Address Rolled Over XGETC: JSR XSELRB ;Select Extended RAM Bank LDA (XADRLO),Y ;Load Character at Extended Address TAY ;Save Character JSR XINCPA ;Increment Physical Address TYA ;Restore Character RTS ;xload(size) - Load from Extended Memory ;Args: Y,X = Number of Bytes to Load ;Requires: DSTLO,DSTHI = Local Memory Start Address ; XMBANK,XADRHI,XADRLO = Extended Memory Address ;Destroys: TEMP0 ;Affects: A,X,Y XLOAD: STY TEMP0 ;and Store in TEMP0 JSR XSELRB ;Select Extended RAM Bank XLOADL: JSR XREADL ;Read Count LSB Bytes LDA TEMP0 ;Load MSB BEQ XLOADX ;If Not Zero DEC TEMP0 ; Decrement MSB BRA XLOADL ; and Read Another 256 Bytes XLOADX: RTS ;xread(n,&dest) - Read Bytes from Extended Memory ;Args: A = Number of Bytes to Read ; Y,X = Address of Array to Read Into ;Sets: DSTLO,DSTHI ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A,X,Y XREAD: JSR SETDST ;Set Destination to String TAX ;Copy Byte Count to X JSR XSELRB ;Select Extended RAM Bank XREADL: LDA (XADRLO) ;Get Character at Extended Address STA (DSTLO) ;Write to Array INC DSTLO ;Increment Destination Address BNE XREADS INC DSTHI XREADS: JSR XINCPA ;Increment Physical Address DEX ;Increment Counter BNE XREADL ;and Loop if Not Zero RTS ;xsave(size) - Save from Extended Memory ;Args: Y,X = Number of Bytes to Save ;Requires: SRCLO,SRCHI = Local Memory Start Address ; XMBANK,XADRHI,XADRLO = Extended Memory Address ;Destroys: TEMP0 ;Affects: A,X,Y XSAVE: STY TEMP0 ;and Store in TEMP0 JSR XSELRB ;Select Extended RAM Bank XSAVEL: JSR XWRITL ;Write Count LSB Bytes LDA TEMP0 ;Load MSB BEQ XSAVEX ;If Not Zero DEC TEMP0 ; Decrement MSB BRA XSAVEL ; and Write Another 256 Bytes XSAVEX: RTS ;xwrite(n,&source) - Write Bytes to Extended Memory ;Args: A = Number of Bytes to Write ; Y,X = Address of Array to Write From ;Sets: SRCLO,SRCHI ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A,X,Y XWRITE: JSR SETSRC ;Set Destination to String TAX ;Copy Byte Count to X JSR XSELRB ;Select Extended RAM Bank XWRITL: LDA (SRCLO) STA (XADRLO) ;Get Character at Extended Address INC SRCLO ;Increment Destination Address BNE XWRITS INC SRCHI XWRITS: JSR XINCPA ;Increment Physical Address DEX ;Increment Counter BNE XWRITL ;and Loop if Not Zero RTS ;xswap(size) - Swap with Extended Memory ;Args: Y,X = Number of Bytes to Swap ;Requires: DSTLO,DSTHI = Local Memory Start Address ; XMBANK,XADRHI,XADRLO = Extended Memory Address ;Destroys: TEMP0 ;Affects: A,X,Y XSWAP: STY TEMP0 ;and Store in TEMP0 JSR XSELRB ;Select Extended RAM Bank XSWAPL: JSR XCHNGL ;Write Count LSB Bytes LDA TEMP0 ;Load MSB BEQ XSWAPX ;If Not Zero DEC TEMP0 ; Decrement MSB BRA XSWAPL ; and Write Another 256 Bytes XSWAPX: RTS ;xchng(n,&dest) - Exhange with Bytes in Extended Memory ;Args: A = Number of Bytes to Read ; Y,X = Address of Array to Read Into ;Sets: DSTLO,DSTHI ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A,X,Y XCHNG: JSR SETDST ;Set Destination to String TAX ;Copy Byte Count to X JSR XSELRB ;Select Extended RAM Bank XCHNGL: LDA (XADRLO) ;Get Character at Extended Address TAY ;and Save It LDA (DSTLO) ;Get Character from Array STA (XADRLO) ;and Store at Extended Address TYA ;Retrieve Original Character STA (DSTLO) ;and Store in Array INC DSTLO ;Increment Destination Address BNE XCHNGS INC DSTHI XCHNGS: JSR XINCPA ;Increment Physical Address DEX ;Increment Counter BNE XCHNGL ;and Loop if Not Zero RTS ;xputl(nsb,msb,lsb) - Write Long to Extended Memory ;Args: A,Y,X = Long to Write ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: Y ;Returns: Carry Set if Address Rolled Over XPUTL: PHA ;Save NSB JSR XPUTI ;Write LSB, MSB to Extended Memory PLA ;Retrieve NSB BRA XPUTCN ;and Write to Extended Memory ;xputi(i) - Write Word to Extended Memory ;Args: Y,X = Word to Write ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A,Y ;Returns: Carry Set if Address Rolled Over XPUTI: PHY ;Save MSB TXA ;Get LSB JSR XPUTC ;and Write to Extended Memory PLA ;Retrieve MSB BRA XPUTCN ;and Write to Extended Memory ;xputc(c) - Write Byte to Extended Memory ;Args: A = Integer to Write ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A,Y ;Returns: Carry Set if Address Rolled Over XPUTC: JSR XSELRB ;Select Extended RAM Bank XPUTCN: STA (XADRLO) ;Store Character at Extended Address ;xincpa() - Increment Physical Extended Address ;Updates: XMBANK, XADRHI, XADRLO - Physical Address ;Affects: A ;Returns: Carry Set if Address Rolled Over XINCPA: CLC ;Preset Carry to Clear INC XADRLO ;Increment Physical LSB BNE XINCPX ;If Zero INC XADRHI ; Increment Physical MSB LDA XADRHI ; Load Physical MSB CMP #$C0 ; If More than Maximum BCC XINCPX LDA #$A0 ; Set MSB to Minimum STA XADRHI INC XMBANK ; Increment Bank LDA XMBANK ; and Write to Bank Select STA XSBANK BNE XINCPX ; If Not Zero CLC ; Return Carry Clear XINCPX: RTS ;xrdpg(xbank, xpage, mpage) - Read Extended Memory Page XRDPG: STX DSTHI ;Set Destination MSB to Memory Page LDX #0 ;Set Extended Memory LSB to 0 STX DSTLO ;Set Destination LSB to 0 JSR XCLCPA ;Convert Logical to Physical Address BCS XRDPGX ;If Invalid, Return Carry Set JSR SETSRC ;Set Source Address, Y to 0 XRDPGM: STA XSBANK ;Select Extended RAM Bank XRDPGL: LDA (SRCLO),Y ;Read Byte from Extended Memory STA (DSTLO),Y ;and Write to Local Memory INY ;Increment Counter BNE XRDPGL ;and Loop if Not 0 XRDPGX: RTS ;xwrtpg(xbank, xpage, mpage) - Write Extended Memory Page XWRTPG: JSR XSRCPA ;Set Source Address and Physical Address BEQ XRDPGM ;and Copy Bytes XSRCPA: STX SRCHI ;Set Destination MSB to Memory Page LDX #0 ;Set Extended Memory LSB to 0 STX SRCLO ;Set Destination LSB to 0 JSR XCLCPA ;Convert Logical to Physical Address BCS XRDPGX ;If Invalid, Return Carry Set JSR SETDST ;Set Destination to Extended Address LDY #0 ;Set Counter to 0 BEQ XRDPGM ;and Copy Bytes ;xswppg(xbank, xpage, mpage) - Swap with Extended Memory Page XSWPPG: JSR XSRCPA ;Set Source Address and Physical Address STA XSBANK ;Select Extended RAM Bank XSWPPL: LDA (DSTLO),Y ;Read From Local Memory TAX ;and Save Contents LDA (SRCLO),Y ;Read Byte from Extended Memory STA (DSTLO),Y ;and Write to Local Memory TXA ;Retrieve Byte Read from Local Memory LDA (SRCLO),Y ;and Write to Extended Memory INY ;Increment Counter BNE XSWPPL ;and Loop if Not 0 RTS