mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-02-23 18:29:02 +00:00
Merge pull request #11 from RevCurtisP/x16vera
Commander X16 Vera chip modules
This commit is contained in:
commit
fdaa5e39fa
33
include/x16/joystk.a02
Normal file
33
include/x16/joystk.a02
Normal file
@ -0,0 +1,33 @@
|
||||
;Joystick Constants and Functions
|
||||
;for Commander X16 Computer
|
||||
|
||||
JYSTKS EQU 2 ;Number of Joysticks
|
||||
|
||||
.JYDATA EQU $02BC ;Joystick 0 Data
|
||||
|
||||
.GETJOY EQU $FF06 ;Kernal GETJOY Routine
|
||||
|
||||
;Joystick Bit Masks
|
||||
JOYUP EQU $08 ;Up
|
||||
JOYDN EQU $04 ;Down
|
||||
JOYLF EQU $02 ;Left
|
||||
JOYRT EQU $01 ;Right
|
||||
JOYB0 EQU $80 ;Button
|
||||
|
||||
;Read Joystick
|
||||
JOYSTK: CMP #JYSTKS ;If Invalid Joystick Number
|
||||
BCS JOYSTE ; Return ERROR
|
||||
STA TEMP0 ;Save Joystick Number
|
||||
JSR $FF06 ;Call Kernal GETJOY Routine
|
||||
LDA TEMP0 ;Retrieve Joystick Number
|
||||
ASL ;Multiply it by 3
|
||||
ADC TEMP0 ;(Assumes Number<128)
|
||||
TAX ;and Copy to X-Register
|
||||
LDA $02BE,X ;If Controller Not Present
|
||||
BNE JOYSTE ; Return ERROR
|
||||
LDA $02BC,X ;Read Controller Status
|
||||
;EOR #$FF ;Invert Bits
|
||||
AND #$CF ;and Mask off Select/Start
|
||||
RTS
|
||||
JOYSTE: LDA #255 ;Return Error Code
|
||||
RTS
|
24
include/x16/joystk.h02
Normal file
24
include/x16/joystk.h02
Normal file
@ -0,0 +1,24 @@
|
||||
/* Joystick Functions for *
|
||||
* Commander X-16 Computer */
|
||||
|
||||
#define JYSTKS 2 //Number of Joysticks
|
||||
|
||||
#define JOYUP $08 //Up
|
||||
#define JOYDN $04 //Down
|
||||
#define JOYLF $02 //Left
|
||||
#define JOYRT $01 //Right
|
||||
#define JOYB0 $80 //Button
|
||||
|
||||
char jydata[]; //Joystick Data
|
||||
|
||||
/* Poll Joysticks` *
|
||||
* Sets: j = Joystick Number *
|
||||
* Returns: $FF = Error *
|
||||
* No Joysticks */
|
||||
void getjoy();
|
||||
|
||||
/* Read Joystick State *
|
||||
* Args: j = Joystick Number *
|
||||
* Returns: $FF = Error *
|
||||
* No Joysticks */
|
||||
char joystk();
|
360
include/x16/xmemory.a02
Normal file
360
include/x16/xmemory.a02
Normal file
@ -0,0 +1,360 @@
|
||||
; 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
|
115
include/x16/xmemory.h02
Normal file
115
include/x16/xmemory.h02
Normal file
@ -0,0 +1,115 @@
|
||||
/****************************************
|
||||
* xmemory.h02 - Extended Memory Access *
|
||||
* for Commander X16 *
|
||||
****************************************/
|
||||
|
||||
#define XLBANK $0F //Maximum Logical Bank
|
||||
|
||||
/* Read Byte to Extended Memory *
|
||||
* Returns: char b: Byte Read *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
char xgetc();
|
||||
|
||||
/* Read Word to Extended Memory *
|
||||
* Returns: int i: Word Read *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
int xgeti();
|
||||
|
||||
/* Read Word, Byte to Extended Memory *
|
||||
* Args: char b: Byte Read *
|
||||
* int i: Word Read *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
char xgetl();
|
||||
|
||||
/* Get Logical Extended Address *
|
||||
* Returns: char lbank - Logical Bank *
|
||||
* int laddr - Logical Address *
|
||||
* Sets Carry if Physical Address Invalid */
|
||||
char xgetla();
|
||||
|
||||
/* Get Physical Extended Address *
|
||||
* Returns: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte *
|
||||
* Sets Carry if Physical Address Invalid */
|
||||
char xgetpa();
|
||||
|
||||
/* Convert Physical to Logical Address *
|
||||
* Args: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte *
|
||||
* Returns: char lbank - Logical Bank *
|
||||
* int laddr - Logical Address *
|
||||
* Sets Carry if Physical Address Invalid */
|
||||
char xclcla();
|
||||
|
||||
/* Increment Physical Address *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
void xincpa();
|
||||
|
||||
/* Convert Logical to Physical Address *
|
||||
* Args: char lbank - Logical Bank *
|
||||
* int laddr - Logical Address *
|
||||
* Returns: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte *
|
||||
* Sets Carry if Logical Address Invalid */
|
||||
char xclcpa();
|
||||
|
||||
/* Write Byte to Extended Memory *
|
||||
* Args: char b: Byte to Write *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
void xputc();
|
||||
|
||||
/* Write Word to Extended Memory *
|
||||
* Args: int i: Word to Write *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
void xputi();
|
||||
|
||||
/* Write Word, Byte to Extended Memory *
|
||||
* Args: char b: Byte to Write *
|
||||
* int i: Word to Write *
|
||||
* Sets Carry if Address Rolled Over */
|
||||
void xputl();
|
||||
|
||||
/* Read Extended Memory Page *
|
||||
* Args: char lbank - Logical Bank *
|
||||
* char lpage - Logical Page *
|
||||
* char mpage - Memory Page *
|
||||
* Sets Carry if Logical Bank Invalid */
|
||||
void xrdpg();
|
||||
|
||||
/* Set Logical Extended Address *
|
||||
* Args: char lbank - Logical Bank *
|
||||
* int laddr - Logical Address *
|
||||
* Sets Carry if Logical Address Invalid */
|
||||
void xsetla();
|
||||
|
||||
/* Set Physical Extended Address *
|
||||
* without Error Checking *
|
||||
* Args: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte */
|
||||
void xsetpn();
|
||||
|
||||
/* Set Physical Extended Address *
|
||||
* with Error Checking *
|
||||
* Args: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte *
|
||||
* Sets Carry if Physical Address Invalid */
|
||||
void xsetpa();
|
||||
|
||||
/* Validate Physical Extended Address *
|
||||
* Args: char pbank - Physical Bank *
|
||||
* char ppage - Physical Page *
|
||||
* char pbyte - Physical Byte *
|
||||
* Sets Carry if Physical Address Invalid */
|
||||
void xvalpa();
|
||||
|
||||
/* Write Extended Memory Page *
|
||||
* Args: char lbank - Logical Bank *
|
||||
* char lpage - Logical Page *
|
||||
* char mpage - Memory Page *
|
||||
* Sets Carry if Logical Bank Invalid */
|
||||
void xwrtpg();
|
458
src/c02.c
458
src/c02.c
@ -1,230 +1,228 @@
|
||||
/**************************************************************
|
||||
* C02 Compiler - (C) 2013 Curtis F Kaylor *
|
||||
* *
|
||||
* C02 is a simpified C-like language designed for the 6502 *
|
||||
* *
|
||||
* This Compiler generates crasm compatible assembly language *
|
||||
* *
|
||||
**************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h" //Common Code used by all Modules
|
||||
#include "files.h" //Open and Close Files
|
||||
#include "asm.h" //Write out Assembly Language
|
||||
#include "parse.h" //General Code Parsing
|
||||
#include "vars.h" //Variable Parsing, Lookup, and Allocation
|
||||
#include "expr.h" //Expression Parsing
|
||||
#include "label.h" //Label Parsing, Generation, and Lookup
|
||||
#include "cond.h" //Conditional Parsing
|
||||
#include "stmnt.h" //Statement Compiling Code
|
||||
#include "dclrtn.h" //Statement Compiling Code
|
||||
#include "include.h" //Include File Parsing
|
||||
|
||||
/* Initilize Compiler Variables */
|
||||
void init(void) {
|
||||
DEBUG("Initializing Compiler Variables\n",0)
|
||||
concnt = 0; //Number of Constants Defined
|
||||
varcnt = 0; //Number of Variables in Table
|
||||
lblcnt = 0; //Number of Labels in stack
|
||||
padcnt = 0; //Number of Padding Bytes at End
|
||||
curcol = 0; //Current Column in Source Code
|
||||
curlin = 0; //Current Line in Source Code
|
||||
alcvar = TRUE; //Allocate Variables Flag
|
||||
inblck = FALSE; //Multiline Block Flag
|
||||
infunc = FALSE; //Inside Function Definition
|
||||
xstmnt[0] = 0; //Expected Statement
|
||||
nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
|
||||
nxtptr = 0; //Pointer to next character in nxtwrd
|
||||
vrwrtn = FALSE; //Variables Written Flag
|
||||
rambas = 0; //RAM Base Address
|
||||
wrtbas = 0; //Write Base Address
|
||||
zpaddr = 0; //Current Zero-Page Address
|
||||
invasc = FALSE; //Invert ASCII Flag
|
||||
mskasc = FALSE; //Set High Bit Flag
|
||||
fcase = FALSE; //First Case Statement Flag
|
||||
wrtofs[0] = 0; //Write Offset
|
||||
xsnvar[0] = 0; //Assigned X Variable Name
|
||||
ysnvar[0] = 0; //Assigned Y Variable Name
|
||||
subcnt = 0; //Include Subdirectories
|
||||
strcpy(cputyp, CPUARG); //Set CPU Type to Default Value
|
||||
strcpy(incdir, "../include/");
|
||||
}
|
||||
|
||||
/* Parse Pointer Dereference Assignment */
|
||||
void ppntr(void) {
|
||||
lsrtrn = FALSE; //Clear RETURN flag
|
||||
if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||
prcasp(';');
|
||||
}
|
||||
|
||||
/* Reads and parses the next Word in Source File */
|
||||
void pword(void) {
|
||||
lsrtrn = FALSE; //Clear RETURN flag
|
||||
getwrd();
|
||||
DEBUG("Parsing Word '%s'\n", word)
|
||||
if (xstmnt[0]) {
|
||||
if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt
|
||||
else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||
}
|
||||
if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement
|
||||
}
|
||||
|
||||
/* Process a directive */
|
||||
void pdrctv(void) {
|
||||
skpchr(); //skip '#'
|
||||
CCMNT('#');
|
||||
getwrd(); //read directive into word
|
||||
DEBUG("Processing directive '%s'\n", word)
|
||||
if (wordis("DEFINE")) pdefin(); //Parse Define
|
||||
else if (wordis("INCLUDE")) pincfl(); //Parse Include File
|
||||
else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE)
|
||||
else if (wordis("PRAGMA")) pprgma();
|
||||
else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE)
|
||||
}
|
||||
|
||||
void prolog(void) {
|
||||
DEBUG("Writing Assembly Prolog\n", 0)
|
||||
asmlin(CPUOP,cputyp);
|
||||
setcmt("Program ");
|
||||
addcmt(srcnam);
|
||||
cmtlin();
|
||||
}
|
||||
|
||||
void epilog(void) {
|
||||
if (!vrwrtn) wvrtbl(); //Write Variable Table
|
||||
if (padcnt) {
|
||||
SCMNT("PADDING BYTES")
|
||||
sprintf(word, "$%hhX", padcnt);
|
||||
asmlin(STROP, word);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compile Source Code*/
|
||||
void compile(void) {
|
||||
DEBUG("Starting Compilation\n", 0)
|
||||
prolog();
|
||||
phdrfl(); //Process Header File specified on Command Line
|
||||
skpchr();
|
||||
DEBUG("Parsing Code\n", 0)
|
||||
while (TRUE) {
|
||||
skpspc();
|
||||
if (match(EOF)) break; //Stop Parsing (End of File)
|
||||
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
|
||||
else if (match('#')) pdrctv(); //Parse Directive
|
||||
else if (match('/')) skpcmt(TRUE); //Skip Comment
|
||||
else if (match('*')) ppntr(); //Parse Pointer
|
||||
else if (isalph()) pword(); //Parse Word
|
||||
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
|
||||
}
|
||||
epilog();
|
||||
}
|
||||
|
||||
/* Display "Usage" text and exit*/
|
||||
void usage(void) {
|
||||
printf("Usage: c02 sourcefile.c02\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Parse Command Line Option */
|
||||
int popt(int arg, int argc, char *argv[]) {
|
||||
char argstr[32]; //Argument String
|
||||
char opt; //Option
|
||||
char optarg[32]; //Option Argument
|
||||
strncpy (argstr, argv[arg], 31);
|
||||
if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE)
|
||||
opt = toupper(argstr[1]);
|
||||
if (strchr("CHS", opt)) {
|
||||
if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE)
|
||||
strncpy(optarg, argv[arg], 31);
|
||||
}
|
||||
DEBUG("Processing Command Line Option -%c\n", argstr[1])
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
debug = TRUE;
|
||||
DEBUG("Debug output enable\n", 0)
|
||||
break;
|
||||
case 'C':
|
||||
strcpy(cputyp, optarg);
|
||||
DEBUG("CPU Type set to '%s'\n", cputyp)
|
||||
break;
|
||||
case 'H':
|
||||
strcpy(hdrnam, optarg);
|
||||
DEBUG("Header Name set to '%s'\n", hdrnam)
|
||||
break;
|
||||
case 'S':
|
||||
strcpy(subdir[subcnt], optarg);
|
||||
DEBUG("subdir[%d] ", subcnt)
|
||||
DEBUG("set to '%s'\n", subdir[subcnt])
|
||||
subcnt++;
|
||||
break;
|
||||
default:
|
||||
ERROR("Illegal option -%c\n", opt, EXIT_FAILURE)
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* Parse Command Line Arguments *
|
||||
* Sets: srcnam - Source File Name (from first arg) *
|
||||
* outnam - Output File Name (from optional second arg) */
|
||||
void pargs(int argc, char *argv[]) {
|
||||
int arg;
|
||||
srcnam[0] = 0;
|
||||
outnam[0] = 0;
|
||||
DEBUG("Parsing %d arguments\n", argc)
|
||||
if (argc == 0) usage(); //at least one argument is required
|
||||
for (arg = 1; arg<argc; arg++) {
|
||||
DEBUG("Parsing argument %d\n", arg);
|
||||
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option
|
||||
else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
|
||||
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg
|
||||
else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE)
|
||||
}
|
||||
if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam)
|
||||
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE)
|
||||
if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam)
|
||||
}
|
||||
|
||||
/* Validate CPU Type *
|
||||
* Uses: cputype *
|
||||
* Sets: cmos */
|
||||
void chkcpu(void) {
|
||||
if (strcmp(cputyp, "6502") == 0) cmos = FALSE;
|
||||
else if (strcmp(cputyp, "65C02") == 0) cmos = TRUE;
|
||||
else ERROR("Invalid CPU Type %s\n", cputyp, EXIT_FAILURE)
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
debug = FALSE; //Do Not Output Debug Info by Default
|
||||
gencmt = TRUE; //Generate Assembly Language Comments
|
||||
|
||||
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" );
|
||||
|
||||
init(); //Initialize Global Variables
|
||||
|
||||
pargs(argc, argv); //Parse Command Line Arguments
|
||||
chkcpu(); //Validate CPU Type
|
||||
|
||||
opnsrc(); //Open Source File
|
||||
opnout(); //Open Output File
|
||||
opnlog(); //Open Log File
|
||||
|
||||
setsrc(); //Set Input to Source File
|
||||
|
||||
compile();
|
||||
|
||||
logstc();
|
||||
logcon();
|
||||
loglab();
|
||||
|
||||
clssrc(); //Close Source File
|
||||
clsout(); //Close Output File
|
||||
clslog(); //Close Log File
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
* C02 Compiler - (C) 2013 Curtis F Kaylor *
|
||||
* *
|
||||
* C02 is a simpified C-like language designed for the 6502 *
|
||||
* *
|
||||
* This Compiler generates crasm compatible assembly language *
|
||||
* *
|
||||
**************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h" //Common Code used by all Modules
|
||||
#include "files.h" //Open and Close Files
|
||||
#include "asm.h" //Write out Assembly Language
|
||||
#include "parse.h" //General Code Parsing
|
||||
#include "vars.h" //Variable Parsing, Lookup, and Allocation
|
||||
#include "expr.h" //Expression Parsing
|
||||
#include "label.h" //Label Parsing, Generation, and Lookup
|
||||
#include "cond.h" //Conditional Parsing
|
||||
#include "stmnt.h" //Statement Compiling Code
|
||||
#include "dclrtn.h" //Statement Compiling Code
|
||||
#include "include.h" //Include File Parsing
|
||||
|
||||
/* Initilize Compiler Variables */
|
||||
void init(void) {
|
||||
DEBUG("Initializing Compiler Variables\n",0)
|
||||
concnt = 0; //Number of Constants Defined
|
||||
varcnt = 0; //Number of Variables in Table
|
||||
lblcnt = 0; //Number of Labels in stack
|
||||
padcnt = 0; //Number of Padding Bytes at End
|
||||
curcol = 0; //Current Column in Source Code
|
||||
curlin = 0; //Current Line in Source Code
|
||||
alcvar = TRUE; //Allocate Variables Flag
|
||||
inblck = FALSE; //Multiline Block Flag
|
||||
infunc = FALSE; //Inside Function Definition
|
||||
xstmnt[0] = 0; //Expected Statement
|
||||
nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
|
||||
nxtptr = 0; //Pointer to next character in nxtwrd
|
||||
vrwrtn = FALSE; //Variables Written Flag
|
||||
rambas = 0; //RAM Base Address
|
||||
wrtbas = 0; //Write Base Address
|
||||
zpaddr = 0; //Current Zero-Page Address
|
||||
invasc = FALSE; //Invert ASCII Flag
|
||||
mskasc = FALSE; //Set High Bit Flag
|
||||
fcase = FALSE; //First Case Statement Flag
|
||||
wrtofs[0] = 0; //Write Offset
|
||||
xsnvar[0] = 0; //Assigned X Variable Name
|
||||
ysnvar[0] = 0; //Assigned Y Variable Name
|
||||
subcnt = 0; //Include Subdirectories
|
||||
strcpy(cputyp, CPUARG); //Set CPU Type to Default Value
|
||||
strcpy(incdir, "../include/");
|
||||
}
|
||||
|
||||
/* Parse Pointer Dereference Assignment */
|
||||
void ppntr(void) {
|
||||
lsrtrn = FALSE; //Clear RETURN flag
|
||||
if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||
prcasp(';');
|
||||
}
|
||||
|
||||
/* Reads and parses the next Word in Source File */
|
||||
void pword(void) {
|
||||
lsrtrn = FALSE; //Clear RETURN flag
|
||||
getwrd();
|
||||
DEBUG("Parsing Word '%s'\n", word)
|
||||
if (xstmnt[0]) {
|
||||
if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt
|
||||
else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||
}
|
||||
if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement
|
||||
}
|
||||
|
||||
/* Process a directive */
|
||||
void pdrctv(void) {
|
||||
skpchr(); //skip '#'
|
||||
CCMNT('#');
|
||||
getwrd(); //read directive into word
|
||||
DEBUG("Processing directive '%s'\n", word)
|
||||
if (wordis("DEFINE")) pdefin(); //Parse Define
|
||||
else if (wordis("INCLUDE")) pincfl(); //Parse Include File
|
||||
else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE)
|
||||
else if (wordis("PRAGMA")) pprgma();
|
||||
else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE)
|
||||
}
|
||||
|
||||
void prolog(void) {
|
||||
DEBUG("Writing Assembly Prolog\n", 0)
|
||||
asmlin(CPUOP,cputyp);
|
||||
setcmt("Program ");
|
||||
addcmt(srcnam);
|
||||
cmtlin();
|
||||
}
|
||||
|
||||
void epilog(void) {
|
||||
if (!vrwrtn) wvrtbl(); //Write Variable Table
|
||||
if (padcnt) {
|
||||
SCMNT("PADDING BYTES")
|
||||
sprintf(word, "$%hhX", padcnt);
|
||||
asmlin(STROP, word);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compile Source Code*/
|
||||
void compile(void) {
|
||||
DEBUG("Starting Compilation\n", 0)
|
||||
prolog();
|
||||
phdrfl(); //Process Header File specified on Command Line
|
||||
skpchr();
|
||||
DEBUG("Parsing Code\n", 0)
|
||||
while (TRUE) {
|
||||
skpspc();
|
||||
if (match(EOF)) break; //Stop Parsing (End of File)
|
||||
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
|
||||
else if (match('#')) pdrctv(); //Parse Directive
|
||||
else if (match('/')) skpcmt(TRUE); //Skip Comment
|
||||
else if (match('*')) ppntr(); //Parse Pointer
|
||||
else if (isalph()) pword(); //Parse Word
|
||||
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
|
||||
}
|
||||
epilog();
|
||||
}
|
||||
|
||||
/* Display "Usage" text and exit*/
|
||||
void usage(void) {
|
||||
printf("Usage: c02 sourcefile.c02\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Parse Command Line Option */
|
||||
int popt(int arg, int argc, char *argv[]) {
|
||||
char argstr[32]; //Argument String
|
||||
char opt; //Option
|
||||
char optarg[32]; //Option Argument
|
||||
strncpy (argstr, argv[arg], 31);
|
||||
if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE)
|
||||
opt = toupper(argstr[1]);
|
||||
if (strchr("CHS", opt)) {
|
||||
if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE)
|
||||
strncpy(optarg, argv[arg], 31);
|
||||
}
|
||||
DEBUG("Processing Command Line Option -%c\n", argstr[1])
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
debug = TRUE;
|
||||
DEBUG("Debug output enable\n", 0)
|
||||
break;
|
||||
case 'C':
|
||||
strcpy(cputyp, optarg);
|
||||
DEBUG("CPU Type set to '%s'\n", cputyp)
|
||||
break;
|
||||
case 'H':
|
||||
strcpy(hdrnam, optarg);
|
||||
DEBUG("Header Name set to '%s'\n", hdrnam)
|
||||
break;
|
||||
case 'S':
|
||||
strcpy(subdir[subcnt], optarg);
|
||||
DEBUG("subdir[%d] ", subcnt)
|
||||
DEBUG("set to '%s'\n", subdir[subcnt])
|
||||
subcnt++;
|
||||
break;
|
||||
default:
|
||||
ERROR("Illegal option -%c\n", opt, EXIT_FAILURE)
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* Parse Command Line Arguments *
|
||||
* Sets: srcnam - Source File Name (from first arg) *
|
||||
* outnam - Output File Name (from optional second arg) */
|
||||
void pargs(int argc, char *argv[]) {
|
||||
int arg;
|
||||
srcnam[0] = 0;
|
||||
outnam[0] = 0;
|
||||
DEBUG("Parsing %d arguments\n", argc)
|
||||
if (argc == 0) usage(); //at least one argument is required
|
||||
for (arg = 1; arg<argc; arg++) {
|
||||
DEBUG("Parsing argument %d\n", arg);
|
||||
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option
|
||||
else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
|
||||
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg
|
||||
else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE)
|
||||
}
|
||||
if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam)
|
||||
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE)
|
||||
if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam)
|
||||
}
|
||||
|
||||
/* Validate CPU Type *
|
||||
* Uses: cputype *
|
||||
* Sets: cmos */
|
||||
void chkcpu(void) {
|
||||
if (strcmp(cputyp, "6502") == 0) cmos = FALSE;
|
||||
else if (strcmp(cputyp, "65C02") == 0) cmos = TRUE;
|
||||
else ERROR("Invalid CPU Type %s\n", cputyp, EXIT_FAILURE)
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
debug = FALSE; //Do Not Output Debug Info by Default
|
||||
gencmt = TRUE; //Generate Assembly Language Comments
|
||||
|
||||
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" );
|
||||
|
||||
init(); //Initialize Global Variables
|
||||
|
||||
pargs(argc, argv); //Parse Command Line Arguments
|
||||
chkcpu(); //Validate CPU Type
|
||||
|
||||
opnsrc(); //Open Source File
|
||||
opnout(); //Open Output File
|
||||
opnlog(); //Open Log File
|
||||
|
||||
setsrc(); //Set Input to Source File
|
||||
|
||||
compile();
|
||||
|
||||
logstc();
|
||||
logcon();
|
||||
loglab();
|
||||
|
||||
clssrc(); //Close Source File
|
||||
clsout(); //Close Output File
|
||||
clslog(); //Close Log File
|
||||
}
|
||||
|
88
src/common.c
88
src/common.c
@ -1,44 +1,44 @@
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
/* Error - Print Input File name & position and exit */
|
||||
void exterr(int errnum) {
|
||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||
exit(errnum);
|
||||
}
|
||||
|
||||
/* Error - print "Expected" error message *
|
||||
and exit with general failure code *
|
||||
Args: expected - Description of what was expected */
|
||||
void expctd(char *expstr) {
|
||||
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
||||
exterr(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Print current position in file */
|
||||
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||
|
||||
/* Set comment to string */
|
||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||
|
||||
/* Append string to comment */
|
||||
void addcmt(char *s) {
|
||||
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
||||
}
|
||||
|
||||
/* Append character to comment */
|
||||
void chrcmt(char c) {
|
||||
if (strlen(cmtasm)>72) return;
|
||||
if (cmtasm[0] == 0 && c == ' ') return;
|
||||
int i = strlen(cmtasm);
|
||||
cmtasm[i++] = c;
|
||||
cmtasm[i] = 0;
|
||||
}
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
/* Error - Print Input File name & position and exit */
|
||||
void exterr(int errnum) {
|
||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||
exit(errnum);
|
||||
}
|
||||
|
||||
/* Error - print "Expected" error message *
|
||||
and exit with general failure code *
|
||||
Args: expected - Description of what was expected */
|
||||
void expctd(char *expstr) {
|
||||
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
||||
exterr(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Print current position in file */
|
||||
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||
|
||||
/* Set comment to string */
|
||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||
|
||||
/* Append string to comment */
|
||||
void addcmt(char *s) {
|
||||
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
||||
}
|
||||
|
||||
/* Append character to comment */
|
||||
void chrcmt(char c) {
|
||||
if (strlen(cmtasm)>72) return;
|
||||
if (cmtasm[0] == 0 && c == ' ') return;
|
||||
int i = strlen(cmtasm);
|
||||
cmtasm[i++] = c;
|
||||
cmtasm[i] = 0;
|
||||
}
|
||||
|
192
src/common.h
192
src/common.h
@ -1,96 +1,96 @@
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#define FNAMLEN 255 //Maximum File Name Length
|
||||
#define LINELEN 255 //Maximum Input/Output Line Length
|
||||
#define CONLEN 6 //Maximum Constant Name Length
|
||||
#define MAXCON 255 //Maximum Number of Constants
|
||||
#define STCLEN 6 //Maximum Struct Name Length
|
||||
#define MAXSTC 32 //Maximum Number of Stuctures
|
||||
#define STMLEN 6 //Maximum Struct Member Name Length
|
||||
#define MAXSTM 255 //Maximum Number of Stucture Members
|
||||
#define VARLEN 6 //Maximum Variable Name Length
|
||||
#define MAXVAR 255 //Maximum Number of Variables
|
||||
#define MAXTRM 16 //Maximum Terms in Stack
|
||||
#define DATASPC 4096 //Space to Allocate for Variable Data
|
||||
#define SUBMAX 4 //Maximum Number of Sub Directories
|
||||
|
||||
#define LABLEN 6 //Maximum Program Label Length
|
||||
#define MAXLAB 255 //Maximum Number of Program Labels
|
||||
|
||||
#define LBLLEN 6 //Maximum Label Length
|
||||
#define LBLFMT "L_%04d" //Label Format
|
||||
#define LABSFX ":" //Label Suffix
|
||||
#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth)
|
||||
#define LOCPFX "." //Local Variable Prefix
|
||||
|
||||
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
|
||||
#define CPUARG "6502" //Target CPU Operand
|
||||
#define ORGOP "ORG" //Origin Pseudo-Op
|
||||
#define EQUOP "EQU" //Equate Pseudo-Op
|
||||
#define BYTEOP "BYTE" //Define Byte Pseudo-Op
|
||||
#define STROP "DS" //Define String Pseudo-Op
|
||||
#define ALNOP "ALIGN" //Align Pseudo-Op
|
||||
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op
|
||||
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
|
||||
|
||||
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
|
||||
|
||||
/* Internal defines */
|
||||
#define TRUE -1
|
||||
#define FALSE 0
|
||||
|
||||
void prtpos(); //Print current file name and position
|
||||
#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}}
|
||||
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
|
||||
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
|
||||
|
||||
int debug; //Print Debug Info (TRUE or FALSE)
|
||||
int cmos; //Flag: Use 65C02 Instruction Set
|
||||
|
||||
int gencmt; //Generate Assembly Language Comments
|
||||
char asmcmt[LINELEN]; //Processed Assembly Language Comment
|
||||
|
||||
int curcol, curlin; //Position in Source Code
|
||||
int savcol, savlin; //Save Position in Source Code
|
||||
|
||||
int bgntim; //Starting Time
|
||||
|
||||
int nxtchr; //Next Character of Source File to Process
|
||||
int nxtupc; //Next Character Converted to Uppercase
|
||||
int savchr; //Holds nxtchr when switching input files
|
||||
|
||||
int wrdlen; //Length of Parsed Word
|
||||
char word[LINELEN]; //Word parsed from source file
|
||||
char uword[LINELEN]; //Word converted to uppercase
|
||||
int pstlen; //Length of Parsed String
|
||||
char pstrng[LINELEN]; //String parsed fron source file
|
||||
char cmtasm[LINELEN]; //Assembly Language Comment Text
|
||||
char cputyp[LINELEN]; //CPU Type
|
||||
|
||||
char hdrnam[FNAMLEN]; //Header File Name
|
||||
char incdir[FNAMLEN]; //Include File Directory
|
||||
char inpnam[FNAMLEN]; //Input File Name
|
||||
char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
|
||||
int subcnt; //Number of Include Directories
|
||||
int subidx; //Index into subdir[]
|
||||
|
||||
int alcvar; //Allocate Variables Flag
|
||||
int inblck; //Multiline Block Flag
|
||||
int infunc; //Inside Function Definition Flag
|
||||
int lsrtrn; //Last Statement was a Return Flag
|
||||
int fcase; //First Case Statement Flag
|
||||
|
||||
int padcnt; //Number of Padding Bytes at End of Program
|
||||
|
||||
void exterr(int errnum); //Print current file name & position and exit
|
||||
void expctd(char *expected); //Print Expected message and exit
|
||||
|
||||
void addcmt(char *s); //Append string to comment
|
||||
void chrcmt(char c); //Append character to comment
|
||||
void setcmt(char *s); //Set comment to string
|
||||
#define SCMNT(str) if (gencmt) {setcmt(str);}
|
||||
#define ACMNT(str) if (gencmt) {addcmt(str);}
|
||||
#define CCMNT(chr) if (gencmt) {chrcmt(chr);}
|
||||
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();}
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#define FNAMLEN 255 //Maximum File Name Length
|
||||
#define LINELEN 255 //Maximum Input/Output Line Length
|
||||
#define CONLEN 6 //Maximum Constant Name Length
|
||||
#define MAXCON 255 //Maximum Number of Constants
|
||||
#define STCLEN 6 //Maximum Struct Name Length
|
||||
#define MAXSTC 32 //Maximum Number of Stuctures
|
||||
#define STMLEN 6 //Maximum Struct Member Name Length
|
||||
#define MAXSTM 255 //Maximum Number of Stucture Members
|
||||
#define VARLEN 6 //Maximum Variable Name Length
|
||||
#define MAXVAR 255 //Maximum Number of Variables
|
||||
#define MAXTRM 16 //Maximum Terms in Stack
|
||||
#define DATASPC 4096 //Space to Allocate for Variable Data
|
||||
#define SUBMAX 4 //Maximum Number of Sub Directories
|
||||
|
||||
#define LABLEN 6 //Maximum Program Label Length
|
||||
#define MAXLAB 255 //Maximum Number of Program Labels
|
||||
|
||||
#define LBLLEN 6 //Maximum Label Length
|
||||
#define LBLFMT "L_%04d" //Label Format
|
||||
#define LABSFX ":" //Label Suffix
|
||||
#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth)
|
||||
#define LOCPFX "." //Local Variable Prefix
|
||||
|
||||
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
|
||||
#define CPUARG "6502" //Target CPU Operand
|
||||
#define ORGOP "ORG" //Origin Pseudo-Op
|
||||
#define EQUOP "EQU" //Equate Pseudo-Op
|
||||
#define BYTEOP "BYTE" //Define Byte Pseudo-Op
|
||||
#define STROP "DS" //Define String Pseudo-Op
|
||||
#define ALNOP "ALIGN" //Align Pseudo-Op
|
||||
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op
|
||||
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
|
||||
|
||||
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
|
||||
|
||||
/* Internal defines */
|
||||
#define TRUE -1
|
||||
#define FALSE 0
|
||||
|
||||
void prtpos(); //Print current file name and position
|
||||
#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}}
|
||||
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
|
||||
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
|
||||
|
||||
int debug; //Print Debug Info (TRUE or FALSE)
|
||||
int cmos; //Flag: Use 65C02 Instruction Set
|
||||
|
||||
int gencmt; //Generate Assembly Language Comments
|
||||
char asmcmt[LINELEN]; //Processed Assembly Language Comment
|
||||
|
||||
int curcol, curlin; //Position in Source Code
|
||||
int savcol, savlin; //Save Position in Source Code
|
||||
|
||||
int bgntim; //Starting Time
|
||||
|
||||
int nxtchr; //Next Character of Source File to Process
|
||||
int nxtupc; //Next Character Converted to Uppercase
|
||||
int savchr; //Holds nxtchr when switching input files
|
||||
|
||||
int wrdlen; //Length of Parsed Word
|
||||
char word[LINELEN]; //Word parsed from source file
|
||||
char uword[LINELEN]; //Word converted to uppercase
|
||||
int pstlen; //Length of Parsed String
|
||||
char pstrng[LINELEN]; //String parsed fron source file
|
||||
char cmtasm[LINELEN]; //Assembly Language Comment Text
|
||||
char cputyp[LINELEN]; //CPU Type
|
||||
|
||||
char hdrnam[FNAMLEN]; //Header File Name
|
||||
char incdir[FNAMLEN]; //Include File Directory
|
||||
char inpnam[FNAMLEN]; //Input File Name
|
||||
char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
|
||||
int subcnt; //Number of Include Directories
|
||||
int subidx; //Index into subdir[]
|
||||
|
||||
int alcvar; //Allocate Variables Flag
|
||||
int inblck; //Multiline Block Flag
|
||||
int infunc; //Inside Function Definition Flag
|
||||
int lsrtrn; //Last Statement was a Return Flag
|
||||
int fcase; //First Case Statement Flag
|
||||
|
||||
int padcnt; //Number of Padding Bytes at End of Program
|
||||
|
||||
void exterr(int errnum); //Print current file name & position and exit
|
||||
void expctd(char *expected); //Print Expected message and exit
|
||||
|
||||
void addcmt(char *s); //Append string to comment
|
||||
void chrcmt(char c); //Append character to comment
|
||||
void setcmt(char *s); //Set comment to string
|
||||
#define SCMNT(str) if (gencmt) {setcmt(str);}
|
||||
#define ACMNT(str) if (gencmt) {addcmt(str);}
|
||||
#define CCMNT(chr) if (gencmt) {chrcmt(chr);}
|
||||
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();}
|
||||
|
914
src/expr.c
914
src/expr.c
@ -1,457 +1,457 @@
|
||||
/***********************************
|
||||
* C02 Expression Parsing Routines *
|
||||
***********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Push Term and Operator onto Stack */
|
||||
void pshtrm(void) {
|
||||
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
|
||||
oprstk[trmidx] = oper; //Put Current Operator on Stack
|
||||
strcpy(trmstk[trmidx], term); //Put Current Term on Stack
|
||||
trmidx++; //Increment Stack Pointer
|
||||
DEBUG("expr.pshtrm: Pushed term %s ", term)
|
||||
DETAIL("and operator '%onto stack'\n", oper)
|
||||
}
|
||||
|
||||
/* Pop Term and Operator off Stack */
|
||||
void poptrm(void) {
|
||||
trmidx--; //Decrement Stack Pointer
|
||||
strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack
|
||||
oper = oprstk[trmidx]; //Restore Current Operator from Stack
|
||||
DEBUG("expr.pshtrm: Popped term %s ", term)
|
||||
DETAIL("and operator '%c' off stack\n", oper)
|
||||
}
|
||||
|
||||
/* Parse value (literal or identifier) *
|
||||
* Args: alwreg - allow registers *
|
||||
8 alwcon - allow constants *
|
||||
* Sets: value - the value (as a string) *
|
||||
* valtyp - value type */
|
||||
void prsval(int alwreg, int alwcon) {
|
||||
DEBUG("expr.prsval: Parsing value\n", 0)
|
||||
skpspc();
|
||||
if (islpre()) prslit(); //Parse Literal
|
||||
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
|
||||
else if (isbtop()) prsbop(); //Parse Byte Operator
|
||||
else expctd("literal or variable");
|
||||
DEBUG("expr.prsval: Parsed value %s ", value)
|
||||
DETAIL("of type %d\n", valtyp)
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Process Unary Minus */
|
||||
void prcmns(void) {
|
||||
DEBUG("Processing unary minus", 0)
|
||||
asmlin("LDA", "#$00"); //Handle Unary Minus
|
||||
}
|
||||
|
||||
/* Parse array index *
|
||||
* Args: clbrkt - require closing bracket *
|
||||
* Sets: value - array index or *
|
||||
* "" if no index defined */
|
||||
void prsidx(int clbrkt) {
|
||||
expect('[');
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
DEBUG("expr.prsidx: Parsed array index '%s'\n", value)
|
||||
if (clbrkt) expect(']');
|
||||
}
|
||||
|
||||
/* Process Simple Array Index *
|
||||
* Uses: term - array variable name *
|
||||
* valtyp - array index value type *
|
||||
* value - array index as string *
|
||||
* word - array index raw string *
|
||||
* Sets: term - modified variable name */
|
||||
void prcsix(void) {
|
||||
DEBUG("expr.prcsix: Processing simple array index %s\n", word);
|
||||
if (valtyp == LITERAL) {
|
||||
strcat(term, "+");
|
||||
strcat(term, word);
|
||||
}
|
||||
else if (strcmp(value, "Y")==0)
|
||||
strcat(term, ",Y");
|
||||
else {
|
||||
if (strcmp(value, "A")==0) asmlin("TAX", "");
|
||||
else if (strcmp(value, "X")!=0) asmlin("LDX", value);
|
||||
strcat(term, ",X");
|
||||
}
|
||||
DEBUG("expr.prcsix: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Process Expression Array Index */
|
||||
void prcxix(void) {
|
||||
DEBUG("expr.prcxix: Processing Expression Array Index", 0)
|
||||
pshtrm(); //Push Array Variable onto Term Stack
|
||||
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
||||
prcftm(FALSE); //Process First Term of Expression
|
||||
prsrxp(']'); //Parse Rest of Expression
|
||||
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
||||
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
||||
poptrm(); //Pop Array Variable off Term Stack
|
||||
strcat(term, ",X");
|
||||
DEBUG("expr.prcxix: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Check for, Parse, and Process Index */
|
||||
void chkidx(void) {
|
||||
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
|
||||
if (valtyp == ARRAY) {
|
||||
if (look('-')) {
|
||||
prcmns();
|
||||
prcxix();
|
||||
}
|
||||
else {
|
||||
prsidx(FALSE);
|
||||
if (valtyp > REGISTER) prcxix();
|
||||
else if (look(']')) prcsix();
|
||||
else prcxix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse Pointer *
|
||||
* Sets: term - Compiled Pointer */
|
||||
void prsptr(void) {
|
||||
DEBUG("Parsing pointer\n", 0)
|
||||
expect('*'); //Pointer Dereference Operator
|
||||
prsvar(FALSE,FALSE); //Parse Variable to Dereference
|
||||
strcpy(term, value);
|
||||
if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
|
||||
DEBUG("expr.prsptr: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Process Pointer Index *
|
||||
* Sets: term - Compiled Pointer */
|
||||
void prcptx(char *index) {
|
||||
DEBUG("expr.prcptx: Processing Dereferenced Pointer %s ", term)
|
||||
DETAIL("index [%s]\n", index)
|
||||
if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
|
||||
if (strcmp(index,"A")==0) asmlin("TAY", "");
|
||||
else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
|
||||
}
|
||||
|
||||
/* Process Pointer *
|
||||
* Sets: term - Compiled Pointer */
|
||||
int prcptr(void) {
|
||||
prsptr();
|
||||
DEBUG("expr.prcptr: Dereferencing Pointer %s\n", value);
|
||||
if (valtyp == ARRAY) {
|
||||
prsidx(TRUE);
|
||||
prcptx(value);
|
||||
sprintf(word, "(%s),Y", term);
|
||||
} else if (cmos) {
|
||||
sprintf(word, "(%s)", term);
|
||||
} else {
|
||||
asmlin("LDY","0");
|
||||
sprintf(word, "(%s),Y", term);
|
||||
}
|
||||
strcpy(term, word);
|
||||
DEBUG("expr.prcptr: Set term to %s\n", term);
|
||||
return FALSE; //Return Value Not an Integer
|
||||
}
|
||||
|
||||
/* Parse Term in Expression *
|
||||
* Sets: term - the term (as a string) *
|
||||
* Returns: TRUE if term is an integer */
|
||||
int prstrm(int alwint) {
|
||||
DEBUG("Parsing term\n", 0)
|
||||
if (match('*')) return prcptr(); //Parse and Deference Pointer
|
||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
||||
strcpy(term, value);
|
||||
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||
DEBUG("expr.prstrm: Parsed term %s\n", term)
|
||||
chkidx(); //Check for Array Index
|
||||
skpspc();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Process Address Reference
|
||||
* Args: adract = Address Action (adacts) *
|
||||
* symbol = Symbol to Process */
|
||||
void prcadr(int adract, char* symbol) {
|
||||
DEBUG("Processing address '%s'\n", word)
|
||||
strcpy(word,"#>(");
|
||||
strcat(word,symbol);
|
||||
strcat(word,")");
|
||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||
else asmlin("LDY", word);
|
||||
strcpy(word,"#<(");
|
||||
strcat(word,symbol);
|
||||
strcat(word,")");
|
||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||
else asmlin("LDX", word);
|
||||
}
|
||||
|
||||
/* Parse and Compile Address of Operator *
|
||||
* Args: adract = Address Action */
|
||||
void prsadr(int adract) {
|
||||
DEBUG("expr.prsadr: Parsing address\n", 0)
|
||||
if (isnpre()) prsnum(0xFFFF);
|
||||
else {
|
||||
getwrd();
|
||||
if (fndlab(word)) strcpy(value, word);
|
||||
else prsvrw(FALSE, TRUE);
|
||||
}
|
||||
if (adract) prcadr(adract, value); //Compile Address Reference
|
||||
else strcpy(word, value); //Save for Calling Routine
|
||||
}
|
||||
|
||||
/* Parse and Create Anonymous String *
|
||||
* Args: adract = Address Action *
|
||||
* alwstr = Allow String */
|
||||
void prsstr(int adract, int alwstr) {
|
||||
if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
|
||||
DEBUG("Parsing anonymous string\n", 0)
|
||||
newlbl(vrname); //Generate Variable Name
|
||||
value[0] = 0; //Use Variable Size 0
|
||||
setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size
|
||||
prsdts(); //Parse Data String
|
||||
setdat(); //Set Variable Data
|
||||
varcnt++; //Increment Variable Counter
|
||||
if (adract) prcadr(adract, vrname); //Compile Address Reference
|
||||
else strcpy(word, vrname); //Save for Calling Routine
|
||||
}
|
||||
|
||||
/* Check for and Process Address or String *
|
||||
* Args: adract = Address Action *
|
||||
* alwstr = Allow String */
|
||||
int chkadr(int adract, int alwstr) {
|
||||
DEBUG("expr.chkadr: Checking for Address or String\n", 0)
|
||||
int result = TRUE;
|
||||
if (look('&')) prsadr(adract);
|
||||
else if (match('"')) prsstr(adract, alwstr);
|
||||
else result = FALSE;
|
||||
skpspc();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse Byte Operator */
|
||||
void prsbop(void) {
|
||||
char byteop = getnxt();
|
||||
CCMNT(byteop);
|
||||
DEBUG("Parsing byte operator '%c'\n", byteop)
|
||||
if (chkadr(FALSE, FALSE)) {
|
||||
sprintf(value, "%c(%s)", byteop, word);
|
||||
valtyp = LITERAL;
|
||||
} else {
|
||||
reqvar(FALSE);
|
||||
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
||||
if (byteop == '>') strcat(value, "+1");
|
||||
vartyp = VTCHAR;
|
||||
}
|
||||
DEBUG("Set value to \"%s\"\n", value)
|
||||
}
|
||||
|
||||
/* Parse Function Argument or Return Values */
|
||||
void prsfpr(char trmntr) {
|
||||
int pusha = 0; int pushy = 0; //A and Y Arguments Pushed
|
||||
DEBUG("expr.prsfpr: Parsing Function Argument or Return Values\n", 0)
|
||||
if (!chkadr(ADLDYX, TRUE) && !match(')')) {
|
||||
DEBUG("expr.prsfpr: Parsing Accumulator Expression\n", 0);
|
||||
if (look('.')) pusha = 255;
|
||||
else {if (prsxpf(0)) goto prsfne;}
|
||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||
if (look('.')) {
|
||||
pushy = -1;
|
||||
}
|
||||
else {
|
||||
if (look('(')) {
|
||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||
prsxpr(')'); asmlin("TAY", ""); //Evaluate Expression, and Copy to Y
|
||||
}
|
||||
else {
|
||||
if (prstrm(TRUE)) goto prsfne;
|
||||
asmlin("LDY", term);
|
||||
}
|
||||
}
|
||||
if (look(',')) {
|
||||
if (look('(')) {
|
||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||
if (pushy==0) {pushy = 1; asmlin("PHA",""); asmlin("PHY","");} //Save Y on Stack
|
||||
prsxpr(')'); asmlin("TAX", ""); //Evaluate Expression, and Copy to X
|
||||
}
|
||||
else {
|
||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
||||
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
asmlin("LDX", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prsfne:
|
||||
if (pushy==1) {asmlin("PLA",""); asmlin("TAY","");} //Pull Y Off Stack
|
||||
if (pusha==1) asmlin("PLA",""); //Pull A Off Stack
|
||||
expect(trmntr);
|
||||
}
|
||||
|
||||
/* Parse function call */
|
||||
void prsfnc(char trmntr) {
|
||||
DEBUG("Processing Function Call '%s'\n", term)
|
||||
//int argexp = FALSE; //Expression(s) in second and third argument
|
||||
pshtrm(); //Push Function Name onto Term Stack
|
||||
skpchr(); //skip open paren
|
||||
CCMNT('(');
|
||||
prsfpr(')'); //Parse Function Parameters
|
||||
expect(trmntr);
|
||||
poptrm(); //Pop Function Name off Term Stack
|
||||
asmlin("JSR", term);
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Process Integer Variable */
|
||||
void prcvri(void) {
|
||||
DEBUG("Processing Integer Variable '%s'\n", value)
|
||||
asmlin("LDX", value);
|
||||
strcat(value, "+1");
|
||||
asmlin("LDY", value);
|
||||
}
|
||||
|
||||
/* Process Integer Variable in Term *
|
||||
* Args: alwint = Allow Integer-Like Variable *
|
||||
* Returns: Integer-Like Variable Processed - TRUE/FALSE */
|
||||
int prcivr(int alwint) {
|
||||
switch (vartyp) {
|
||||
case VTINT:
|
||||
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||
prcvri();
|
||||
return TRUE;
|
||||
case VTARRAY:
|
||||
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE)
|
||||
prcadr(ADNONE, term);
|
||||
return TRUE;
|
||||
case VTSTRUCT:
|
||||
if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE)
|
||||
prcadr(ADNONE, term);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process first term of expression */
|
||||
int prcftm(int alwint) {
|
||||
DEBUG("Processing first term '%s'\n", value)
|
||||
strcpy(term, value);
|
||||
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
||||
else if (wordis("A")) return FALSE;
|
||||
else if (wordis("X")) asmlin("TXA", "");
|
||||
else if (wordis("Y")) asmlin("TYA", "");
|
||||
else { chkidx(); asmlin("LDA", term); }
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Parse first term of expession *
|
||||
* First term can include function calls */
|
||||
int prsftm(int alwint) {
|
||||
DEBUG("Parsing first term\n", 0)
|
||||
if (match('*')) {
|
||||
prcptr(); //Parse and Deference Pointer
|
||||
asmlin("LDA", term);
|
||||
return FALSE;
|
||||
}
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
return prcftm(alwint);
|
||||
}
|
||||
|
||||
/* Process Arithmetic or Bitwise Operator *
|
||||
* and the term that follows it */
|
||||
void prcopr(void) {
|
||||
DEBUG("Processing operator '%c'\n", oper)
|
||||
switch(oper) {
|
||||
case '+': asmlin("CLC", ""); asmlin("ADC", term); break; //Addition
|
||||
case '-': asmlin("SEC", ""); asmlin("SBC", term); break; //Subtraction
|
||||
case '&': asmlin("AND", term); break; //Bitwise AND
|
||||
case '!': //For systems that don't have pipe in character set
|
||||
case '|': asmlin("ORA", term); break; //Bitwise OR
|
||||
case '^': asmlin("EOR", term); break; //Bitwise XOR
|
||||
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
|
||||
}
|
||||
oper = 0;
|
||||
}
|
||||
|
||||
/* Parse Remainder of Expression */
|
||||
void prsrxp(char trmntr) {
|
||||
skpspc();
|
||||
while (isoper()) {
|
||||
trmcnt++; //Increment Expression Depth
|
||||
prsopr(); //Parse Operator
|
||||
prstrm(FALSE); //Parse Term
|
||||
prcopr(); //Process Operator
|
||||
trmcnt--; //Decrement Expression Depth
|
||||
}
|
||||
expect(trmntr);
|
||||
}
|
||||
|
||||
int prsxpp(char trmntr, int alwint) {
|
||||
DEBUG("Parsing expression\n", 0)
|
||||
skpspc();
|
||||
trmcnt = 0; //Initialize Expression Depth
|
||||
if (match('-')) prcmns(); //Process Unary Minus
|
||||
else if (prsftm(alwint)) return TRUE; //Parse First Term
|
||||
prsrxp(trmntr); //Parse Remainder of Express
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Parse and compile expression */
|
||||
void prsxpr(char trmntr) {
|
||||
prsxpp(trmntr, FALSE);
|
||||
}
|
||||
|
||||
/* Parse and compile function parameter expression *
|
||||
* Returns: TRUE if Integer Expression */
|
||||
int prsxpf(char trmntr) {
|
||||
DEBUG("expr.prsxpf: Parsing Function Expression\n", 0)
|
||||
return prsxpp(trmntr, TRUE);
|
||||
}
|
||||
|
||||
/* Parse and Compile Integer Expression *
|
||||
* (Address, Integer Literal, Variable, *
|
||||
* Struct Member, or Function) *
|
||||
* Args: trmntr - expression terminator *
|
||||
* asmxpr - assemble expression *
|
||||
* Sets: value - Parsed Value or Symbol */
|
||||
void prsxpi(char trmntr, int asmxpr) {
|
||||
skpspc();
|
||||
DEBUG("Parsing integer expression\n", 0)
|
||||
if (!chkadr(TRUE, FALSE)) {
|
||||
if (isnpre()) {
|
||||
DEBUG("Parsing Integer Literal\n", 0)
|
||||
int number = prsnum(0xFFFF); //Parse Number into value
|
||||
if (asmxpr) {
|
||||
sprintf(value, "#%d", number & 0xFF); asmlin("LDX", value);
|
||||
sprintf(value, "#%d", number >> 8); asmlin("LDY", value);
|
||||
}
|
||||
} else if (isalph()) {
|
||||
prsvar(FALSE, TRUE);
|
||||
if (valtyp == FUNCTION) {
|
||||
strcpy(term, value);
|
||||
DEBUG("expr.prsxpi: Set term to %s\n", term)
|
||||
prsfnc(0); //Parse Expression Function
|
||||
} else if (valtyp == STRUCTURE) {
|
||||
prsmbr(value);
|
||||
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
||||
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
||||
if (asmxpr) prcvri(); //Process Integer Variable
|
||||
} else {
|
||||
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||
}
|
||||
} else {
|
||||
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
expect(trmntr);
|
||||
}
|
||||
/***********************************
|
||||
* C02 Expression Parsing Routines *
|
||||
***********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Push Term and Operator onto Stack */
|
||||
void pshtrm(void) {
|
||||
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
|
||||
oprstk[trmidx] = oper; //Put Current Operator on Stack
|
||||
strcpy(trmstk[trmidx], term); //Put Current Term on Stack
|
||||
trmidx++; //Increment Stack Pointer
|
||||
DEBUG("expr.pshtrm: Pushed term %s ", term)
|
||||
DETAIL("and operator '%onto stack'\n", oper)
|
||||
}
|
||||
|
||||
/* Pop Term and Operator off Stack */
|
||||
void poptrm(void) {
|
||||
trmidx--; //Decrement Stack Pointer
|
||||
strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack
|
||||
oper = oprstk[trmidx]; //Restore Current Operator from Stack
|
||||
DEBUG("expr.pshtrm: Popped term %s ", term)
|
||||
DETAIL("and operator '%c' off stack\n", oper)
|
||||
}
|
||||
|
||||
/* Parse value (literal or identifier) *
|
||||
* Args: alwreg - allow registers *
|
||||
8 alwcon - allow constants *
|
||||
* Sets: value - the value (as a string) *
|
||||
* valtyp - value type */
|
||||
void prsval(int alwreg, int alwcon) {
|
||||
DEBUG("expr.prsval: Parsing value\n", 0)
|
||||
skpspc();
|
||||
if (islpre()) prslit(); //Parse Literal
|
||||
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
|
||||
else if (isbtop()) prsbop(); //Parse Byte Operator
|
||||
else expctd("literal or variable");
|
||||
DEBUG("expr.prsval: Parsed value %s ", value)
|
||||
DETAIL("of type %d\n", valtyp)
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Process Unary Minus */
|
||||
void prcmns(void) {
|
||||
DEBUG("Processing unary minus", 0)
|
||||
asmlin("LDA", "#$00"); //Handle Unary Minus
|
||||
}
|
||||
|
||||
/* Parse array index *
|
||||
* Args: clbrkt - require closing bracket *
|
||||
* Sets: value - array index or *
|
||||
* "" if no index defined */
|
||||
void prsidx(int clbrkt) {
|
||||
expect('[');
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
DEBUG("expr.prsidx: Parsed array index '%s'\n", value)
|
||||
if (clbrkt) expect(']');
|
||||
}
|
||||
|
||||
/* Process Simple Array Index *
|
||||
* Uses: term - array variable name *
|
||||
* valtyp - array index value type *
|
||||
* value - array index as string *
|
||||
* word - array index raw string *
|
||||
* Sets: term - modified variable name */
|
||||
void prcsix(void) {
|
||||
DEBUG("expr.prcsix: Processing simple array index %s\n", word);
|
||||
if (valtyp == LITERAL) {
|
||||
strcat(term, "+");
|
||||
strcat(term, word);
|
||||
}
|
||||
else if (strcmp(value, "Y")==0)
|
||||
strcat(term, ",Y");
|
||||
else {
|
||||
if (strcmp(value, "A")==0) asmlin("TAX", "");
|
||||
else if (strcmp(value, "X")!=0) asmlin("LDX", value);
|
||||
strcat(term, ",X");
|
||||
}
|
||||
DEBUG("expr.prcsix: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Process Expression Array Index */
|
||||
void prcxix(void) {
|
||||
DEBUG("expr.prcxix: Processing Expression Array Index", 0)
|
||||
pshtrm(); //Push Array Variable onto Term Stack
|
||||
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
||||
prcftm(FALSE); //Process First Term of Expression
|
||||
prsrxp(']'); //Parse Rest of Expression
|
||||
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
||||
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
||||
poptrm(); //Pop Array Variable off Term Stack
|
||||
strcat(term, ",X");
|
||||
DEBUG("expr.prcxix: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Check for, Parse, and Process Index */
|
||||
void chkidx(void) {
|
||||
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
|
||||
if (valtyp == ARRAY) {
|
||||
if (look('-')) {
|
||||
prcmns();
|
||||
prcxix();
|
||||
}
|
||||
else {
|
||||
prsidx(FALSE);
|
||||
if (valtyp > REGISTER) prcxix();
|
||||
else if (look(']')) prcsix();
|
||||
else prcxix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse Pointer *
|
||||
* Sets: term - Compiled Pointer */
|
||||
void prsptr(void) {
|
||||
DEBUG("Parsing pointer\n", 0)
|
||||
expect('*'); //Pointer Dereference Operator
|
||||
prsvar(FALSE,FALSE); //Parse Variable to Dereference
|
||||
strcpy(term, value);
|
||||
if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
|
||||
DEBUG("expr.prsptr: Set term to %s\n", term);
|
||||
}
|
||||
|
||||
/* Process Pointer Index *
|
||||
* Sets: term - Compiled Pointer */
|
||||
void prcptx(char *index) {
|
||||
DEBUG("expr.prcptx: Processing Dereferenced Pointer %s ", term)
|
||||
DETAIL("index [%s]\n", index)
|
||||
if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
|
||||
if (strcmp(index,"A")==0) asmlin("TAY", "");
|
||||
else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
|
||||
}
|
||||
|
||||
/* Process Pointer *
|
||||
* Sets: term - Compiled Pointer */
|
||||
int prcptr(void) {
|
||||
prsptr();
|
||||
DEBUG("expr.prcptr: Dereferencing Pointer %s\n", value);
|
||||
if (valtyp == ARRAY) {
|
||||
prsidx(TRUE);
|
||||
prcptx(value);
|
||||
sprintf(word, "(%s),Y", term);
|
||||
} else if (cmos) {
|
||||
sprintf(word, "(%s)", term);
|
||||
} else {
|
||||
asmlin("LDY","0");
|
||||
sprintf(word, "(%s),Y", term);
|
||||
}
|
||||
strcpy(term, word);
|
||||
DEBUG("expr.prcptr: Set term to %s\n", term);
|
||||
return FALSE; //Return Value Not an Integer
|
||||
}
|
||||
|
||||
/* Parse Term in Expression *
|
||||
* Sets: term - the term (as a string) *
|
||||
* Returns: TRUE if term is an integer */
|
||||
int prstrm(int alwint) {
|
||||
DEBUG("Parsing term\n", 0)
|
||||
if (match('*')) return prcptr(); //Parse and Deference Pointer
|
||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
||||
strcpy(term, value);
|
||||
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||
DEBUG("expr.prstrm: Parsed term %s\n", term)
|
||||
chkidx(); //Check for Array Index
|
||||
skpspc();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Process Address Reference
|
||||
* Args: adract = Address Action (adacts) *
|
||||
* symbol = Symbol to Process */
|
||||
void prcadr(int adract, char* symbol) {
|
||||
DEBUG("Processing address '%s'\n", word)
|
||||
strcpy(word,"#>(");
|
||||
strcat(word,symbol);
|
||||
strcat(word,")");
|
||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||
else asmlin("LDY", word);
|
||||
strcpy(word,"#<(");
|
||||
strcat(word,symbol);
|
||||
strcat(word,")");
|
||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||
else asmlin("LDX", word);
|
||||
}
|
||||
|
||||
/* Parse and Compile Address of Operator *
|
||||
* Args: adract = Address Action */
|
||||
void prsadr(int adract) {
|
||||
DEBUG("expr.prsadr: Parsing address\n", 0)
|
||||
if (isnpre()) prsnum(0xFFFF);
|
||||
else {
|
||||
getwrd();
|
||||
if (fndlab(word)) strcpy(value, word);
|
||||
else prsvrw(FALSE, TRUE);
|
||||
}
|
||||
if (adract) prcadr(adract, value); //Compile Address Reference
|
||||
else strcpy(word, value); //Save for Calling Routine
|
||||
}
|
||||
|
||||
/* Parse and Create Anonymous String *
|
||||
* Args: adract = Address Action *
|
||||
* alwstr = Allow String */
|
||||
void prsstr(int adract, int alwstr) {
|
||||
if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
|
||||
DEBUG("Parsing anonymous string\n", 0)
|
||||
newlbl(vrname); //Generate Variable Name
|
||||
value[0] = 0; //Use Variable Size 0
|
||||
setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size
|
||||
prsdts(); //Parse Data String
|
||||
setdat(); //Set Variable Data
|
||||
varcnt++; //Increment Variable Counter
|
||||
if (adract) prcadr(adract, vrname); //Compile Address Reference
|
||||
else strcpy(word, vrname); //Save for Calling Routine
|
||||
}
|
||||
|
||||
/* Check for and Process Address or String *
|
||||
* Args: adract = Address Action *
|
||||
* alwstr = Allow String */
|
||||
int chkadr(int adract, int alwstr) {
|
||||
DEBUG("expr.chkadr: Checking for Address or String\n", 0)
|
||||
int result = TRUE;
|
||||
if (look('&')) prsadr(adract);
|
||||
else if (match('"')) prsstr(adract, alwstr);
|
||||
else result = FALSE;
|
||||
skpspc();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse Byte Operator */
|
||||
void prsbop(void) {
|
||||
char byteop = getnxt();
|
||||
CCMNT(byteop);
|
||||
DEBUG("Parsing byte operator '%c'\n", byteop)
|
||||
if (chkadr(FALSE, FALSE)) {
|
||||
sprintf(value, "%c(%s)", byteop, word);
|
||||
valtyp = LITERAL;
|
||||
} else {
|
||||
reqvar(FALSE);
|
||||
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
||||
if (byteop == '>') strcat(value, "+1");
|
||||
vartyp = VTCHAR;
|
||||
}
|
||||
DEBUG("Set value to \"%s\"\n", value)
|
||||
}
|
||||
|
||||
/* Parse Function Argument or Return Values */
|
||||
void prsfpr(char trmntr) {
|
||||
int pusha = 0; int pushy = 0; //A and Y Arguments Pushed
|
||||
DEBUG("expr.prsfpr: Parsing Function Argument or Return Values\n", 0)
|
||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
|
||||
DEBUG("expr.prsfpr: Parsing Accumulator Expression\n", 0);
|
||||
if (look('.')) pusha = 255;
|
||||
else {if (prsxpf(0)) goto prsfne;}
|
||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||
if (look('.')) {
|
||||
pushy = -1;
|
||||
}
|
||||
else {
|
||||
if (look('(')) {
|
||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||
prsxpr(')'); asmlin("TAY", ""); //Evaluate Expression, and Copy to Y
|
||||
}
|
||||
else {
|
||||
if (prstrm(TRUE)) goto prsfne;
|
||||
asmlin("LDY", term);
|
||||
}
|
||||
}
|
||||
if (look(',')) {
|
||||
if (look('(')) {
|
||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||
if (pushy==0) {pushy = 1; asmlin("PHA",""); asmlin("PHY","");} //Save Y on Stack
|
||||
prsxpr(')'); asmlin("TAX", ""); //Evaluate Expression, and Copy to X
|
||||
}
|
||||
else {
|
||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
||||
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
asmlin("LDX", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prsfne:
|
||||
if (pushy==1) {asmlin("PLA",""); asmlin("TAY","");} //Pull Y Off Stack
|
||||
if (pusha==1) asmlin("PLA",""); //Pull A Off Stack
|
||||
expect(trmntr);
|
||||
}
|
||||
|
||||
/* Parse function call */
|
||||
void prsfnc(char trmntr) {
|
||||
DEBUG("Processing Function Call '%s'\n", term)
|
||||
//int argexp = FALSE; //Expression(s) in second and third argument
|
||||
pshtrm(); //Push Function Name onto Term Stack
|
||||
skpchr(); //skip open paren
|
||||
CCMNT('(');
|
||||
prsfpr(')'); //Parse Function Parameters
|
||||
expect(trmntr);
|
||||
poptrm(); //Pop Function Name off Term Stack
|
||||
asmlin("JSR", term);
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Process Integer Variable */
|
||||
void prcvri(void) {
|
||||
DEBUG("Processing Integer Variable '%s'\n", value)
|
||||
asmlin("LDX", value);
|
||||
strcat(value, "+1");
|
||||
asmlin("LDY", value);
|
||||
}
|
||||
|
||||
/* Process Integer Variable in Term *
|
||||
* Args: alwint = Allow Integer-Like Variable *
|
||||
* Returns: Integer-Like Variable Processed - TRUE/FALSE */
|
||||
int prcivr(int alwint) {
|
||||
switch (vartyp) {
|
||||
case VTINT:
|
||||
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||
prcvri();
|
||||
return TRUE;
|
||||
case VTARRAY:
|
||||
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE)
|
||||
prcadr(ADNONE, term);
|
||||
return TRUE;
|
||||
case VTSTRUCT:
|
||||
if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE)
|
||||
prcadr(ADNONE, term);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process first term of expression */
|
||||
int prcftm(int alwint) {
|
||||
DEBUG("Processing first term '%s'\n", value)
|
||||
strcpy(term, value);
|
||||
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
||||
else if (wordis("A")) return FALSE;
|
||||
else if (wordis("X")) asmlin("TXA", "");
|
||||
else if (wordis("Y")) asmlin("TYA", "");
|
||||
else { chkidx(); asmlin("LDA", term); }
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Parse first term of expession *
|
||||
* First term can include function calls */
|
||||
int prsftm(int alwint) {
|
||||
DEBUG("Parsing first term\n", 0)
|
||||
if (match('*')) {
|
||||
prcptr(); //Parse and Deference Pointer
|
||||
asmlin("LDA", term);
|
||||
return FALSE;
|
||||
}
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
return prcftm(alwint);
|
||||
}
|
||||
|
||||
/* Process Arithmetic or Bitwise Operator *
|
||||
* and the term that follows it */
|
||||
void prcopr(void) {
|
||||
DEBUG("Processing operator '%c'\n", oper)
|
||||
switch(oper) {
|
||||
case '+': asmlin("CLC", ""); asmlin("ADC", term); break; //Addition
|
||||
case '-': asmlin("SEC", ""); asmlin("SBC", term); break; //Subtraction
|
||||
case '&': asmlin("AND", term); break; //Bitwise AND
|
||||
case '!': //For systems that don't have pipe in character set
|
||||
case '|': asmlin("ORA", term); break; //Bitwise OR
|
||||
case '^': asmlin("EOR", term); break; //Bitwise XOR
|
||||
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
|
||||
}
|
||||
oper = 0;
|
||||
}
|
||||
|
||||
/* Parse Remainder of Expression */
|
||||
void prsrxp(char trmntr) {
|
||||
skpspc();
|
||||
while (isoper()) {
|
||||
trmcnt++; //Increment Expression Depth
|
||||
prsopr(); //Parse Operator
|
||||
prstrm(FALSE); //Parse Term
|
||||
prcopr(); //Process Operator
|
||||
trmcnt--; //Decrement Expression Depth
|
||||
}
|
||||
expect(trmntr);
|
||||
}
|
||||
|
||||
int prsxpp(char trmntr, int alwint) {
|
||||
DEBUG("Parsing expression\n", 0)
|
||||
skpspc();
|
||||
trmcnt = 0; //Initialize Expression Depth
|
||||
if (match('-')) prcmns(); //Process Unary Minus
|
||||
else if (prsftm(alwint)) return TRUE; //Parse First Term
|
||||
prsrxp(trmntr); //Parse Remainder of Express
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Parse and compile expression */
|
||||
void prsxpr(char trmntr) {
|
||||
prsxpp(trmntr, FALSE);
|
||||
}
|
||||
|
||||
/* Parse and compile function parameter expression *
|
||||
* Returns: TRUE if Integer Expression */
|
||||
int prsxpf(char trmntr) {
|
||||
DEBUG("expr.prsxpf: Parsing Function Expression\n", 0)
|
||||
return prsxpp(trmntr, TRUE);
|
||||
}
|
||||
|
||||
/* Parse and Compile Integer Expression *
|
||||
* (Address, Integer Literal, Variable, *
|
||||
* Struct Member, or Function) *
|
||||
* Args: trmntr - expression terminator *
|
||||
* asmxpr - assemble expression *
|
||||
* Sets: value - Parsed Value or Symbol */
|
||||
void prsxpi(char trmntr, int asmxpr) {
|
||||
skpspc();
|
||||
DEBUG("Parsing integer expression\n", 0)
|
||||
if (!chkadr(TRUE, FALSE)) {
|
||||
if (isnpre()) {
|
||||
DEBUG("Parsing Integer Literal\n", 0)
|
||||
int number = prsnum(0xFFFF); //Parse Number into value
|
||||
if (asmxpr) {
|
||||
sprintf(value, "#%d", number & 0xFF); asmlin("LDX", value);
|
||||
sprintf(value, "#%d", number >> 8); asmlin("LDY", value);
|
||||
}
|
||||
} else if (isalph()) {
|
||||
prsvar(FALSE, TRUE);
|
||||
if (valtyp == FUNCTION) {
|
||||
strcpy(term, value);
|
||||
DEBUG("expr.prsxpi: Set term to %s\n", term)
|
||||
prsfnc(0); //Parse Expression Function
|
||||
} else if (valtyp == STRUCTURE) {
|
||||
prsmbr(value);
|
||||
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
||||
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
||||
if (asmxpr) prcvri(); //Process Integer Variable
|
||||
} else {
|
||||
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||
}
|
||||
} else {
|
||||
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
expect(trmntr);
|
||||
}
|
||||
|
642
x16/include/vera-old.a02
Normal file
642
x16/include/vera-old.a02
Normal file
@ -0,0 +1,642 @@
|
||||
; 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
|
20
x16/include/vera-old.h02
Normal file
20
x16/include/vera-old.h02
Normal file
@ -0,0 +1,20 @@
|
||||
/***************************************************
|
||||
* vera.h02 - Commander X16 Routines for Vera chip *
|
||||
***************************************************/
|
||||
|
||||
/* Convert R, G, and B Values *
|
||||
* to Palette Color Value *
|
||||
* Args: r - Red Value (0-15) *
|
||||
* g - Green Value (0-15) *
|
||||
* b - Blue Value (0-15) *
|
||||
* Returns: int c - Color Value */
|
||||
char rgbclr();
|
||||
|
||||
/* Convert Palette Color Value *
|
||||
* to R, G, and B Values *
|
||||
* Args: int c - Color Value *
|
||||
* Returns: Red Value (0-15) *
|
||||
* Green Value (0-15) *
|
||||
* Blue Value (0-15) */
|
||||
char clrrgb();
|
||||
|
14
x16/include/vera.a02
Normal file
14
x16/include/vera.a02
Normal file
@ -0,0 +1,14 @@
|
||||
; C02 module vera.h02 assembly language subroutines
|
||||
|
||||
;Vera Internal Address Space
|
||||
;$00000-$1FFFF Video RAM
|
||||
;$F0000-$F001F Display composer Registers
|
||||
;$F1000-$F11FF Palette
|
||||
;$F2000-$F200F Layer 0 Registers
|
||||
;$F3000-$F300F Layer 1 Registers
|
||||
;$F4000-$F400F Sprite Registers
|
||||
;$F5000-$F53FF Sprite Attributes
|
||||
;$F6000- Audio
|
||||
;$F7000-$F7001 SPI
|
||||
;$F8000-$F8003 UART
|
||||
|
31
x16/include/vera.h02
Normal file
31
x16/include/vera.h02
Normal file
@ -0,0 +1,31 @@
|
||||
/***************************************************
|
||||
* vera.h02 - Commander X16 Routines for Vera chip *
|
||||
***************************************************/
|
||||
|
||||
/* Convert Palette Color Value *
|
||||
* to R, G, and B Values *
|
||||
* Args: int c - Color Value *
|
||||
* Returns: Red Value (0-15) *
|
||||
* Green Value (0-15) *
|
||||
* Blue Value (0-15) */
|
||||
char clrrgb();
|
||||
|
||||
/* Read Color Value from Palette *
|
||||
* Args: char i - Palette Index *
|
||||
* Returns: int c - Color Value */
|
||||
char getclr();
|
||||
|
||||
/* Convert R, G, and B Values *
|
||||
* to Palette Color Value *
|
||||
* Args: r - Red Value (0-15) *
|
||||
* g - Green Value (0-15) *
|
||||
* b - Blue Value (0-15) *
|
||||
* Returns: int c - Color Value */
|
||||
char rgbclr();
|
||||
|
||||
/* Write Color Value to Palette *
|
||||
* Args: i - Index into Palette *
|
||||
* int c - Color Value *
|
||||
* Returns: int d = Entry Address */
|
||||
char setclr();
|
||||
|
144
x16/include/veraclr.a02
Normal file
144
x16/include/veraclr.a02
Normal file
@ -0,0 +1,144 @@
|
||||
; Vera Display Composer Assembly Language Routines for C02
|
||||
; Requires External Routines NYBCAT, NYBCUT, REGADR, and SAVRXY
|
||||
; and External Variables TEMP1 and TEMP2
|
||||
|
||||
;rgbclr(r,g,b) - Convert RGB Values to Palette Color
|
||||
;Args: A = Red Value (0-255)
|
||||
; Y = Green Value (0-255)
|
||||
; X = Blue Value (0-255)
|
||||
;Destroys: TEMP0
|
||||
;Affects: A
|
||||
;Returns: Y = Color MSB (0000RRRR)
|
||||
; X = Color LSB (GGGGBBBB)
|
||||
RGBCLR: LSR ;Divide Red Value by 16
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
PHA ;and Save It
|
||||
TYA ;Copy Green Value to Accumulator
|
||||
AND #$F0 ;Strip Low Nybble
|
||||
STA TEMP0 ;and Store It
|
||||
TXA ;Copy Blue Value to Accumulator
|
||||
LSR ;Divide by 16
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
ORA TEMP0 ;Combine with Green
|
||||
TAX ;and Return as LSB
|
||||
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-255)
|
||||
; Y = Green Value (0-255)
|
||||
; X = Blue Value (0-255)
|
||||
CLRRGB: PHY ;Save MSB
|
||||
TXA ;Copy LSB into Accumulator
|
||||
AND #$F0 ;Isolate Green Value
|
||||
TAY ;and Return in Y
|
||||
TXA ;Copy LSB into Accumulator
|
||||
ASL ;Shift Low Nybble Left
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
TAX ;and Return in X
|
||||
PLA ;Retrieve MSB (Red)
|
||||
ASL ;Shift Low Nybble Left
|
||||
ASL
|
||||
ASL
|
||||
ASL ;and Return in A
|
||||
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
|
||||
|
||||
;getcln() - Get Next Color Entry from Palette
|
||||
;Affects: A
|
||||
;Returns: Y = Color MSB (0000RRRR)
|
||||
; X = Color LSB (GGGGBBBB)
|
||||
GETCLN: 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
|
||||
|
||||
;getrgb() - Get Next Palette Entry as RGB
|
||||
;Returns: A = Red Value (0-255)
|
||||
; Y = Green Value (0-255)
|
||||
; X = Blue Value (0-255)
|
||||
GETRGB: JSR GETCLN ;Get Next Color Entry
|
||||
BRA CLRRGB ;Convert to RGB and Return
|
||||
|
||||
;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
|
||||
JSR RESRXY ;Restore Color Value
|
||||
|
||||
|
||||
;setcln() - Set Next Color Entry in Palette
|
||||
;Args: Y = Color MSB (0000RRRR)
|
||||
; X = Color LSB (GGGGBBBB)
|
||||
;Affects: A,X
|
||||
SETCLN: TXA ;Copy LSB to Accumulator
|
||||
LDX $9F25 ;Get Current Data Port
|
||||
STA $9F23,X ;and Write to Data Port
|
||||
TYA ;Copy MSB to Accumulator
|
||||
STA $9F23,X ;and Write to Data Port
|
||||
RTS
|
||||
|
||||
|
||||
;setrgb() - Set Next Palette Entry to RGB Color
|
||||
;Args: A = Red Value (0-255)
|
||||
; Y = Green Value (0-255)
|
||||
; X = Blue Value (0-255)
|
||||
;Destroys: TEMP0
|
||||
;Destroys: TEMP0
|
||||
;Affects: A,Y,X
|
||||
SETRGB: JSR RGBCLR ;Convert RGB to Vera Color Value
|
||||
BRA SETCLN ;and Write to Next Palette Entry
|
||||
|
||||
;setidy(idx) - Set Palette Index and Entry Count
|
||||
;Args: A = Palette Index
|
||||
; Y = Number of Entries
|
||||
;Returns: A = Bank + Auto-Increment
|
||||
; Y,X = Address
|
||||
SETIDY: STY TEMP0 ;Store Number of Colors
|
||||
ASL TEMP0 ;and Multiply by 2
|
||||
|
||||
;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
|
||||
JMP REGADR ;and Set Address to Register
|
||||
|
||||
;getplt(idx,num) - Set Palette Colors
|
||||
;Args: A = Starting Index
|
||||
; Y = Number of Entries (1-128)
|
||||
;Uses: DSTLO,DSTHI = Address of Destination Array
|
||||
;Affects: A,X,Y
|
||||
GETPLT: JSR SETIDY ;Set Vera Address and Entry Count
|
||||
JMP GETMEA ;Read Color Entries from Vera Memory
|
||||
|
||||
;setplt(idx,num) - Set Palette Colors
|
||||
;Args: A = Starting Index
|
||||
; Y = Number of Entries (1-128)
|
||||
;Uses: SRCLO,SRCHI = Address of Color Entries
|
||||
;Affects: A,X,Y
|
||||
SETPLT: JSR SETIDY ;Set Vera Address and Entry Count
|
||||
JMP SETMEA ;Write Color Entries to Vera Memory
|
72
x16/include/veraclr.h02
Normal file
72
x16/include/veraclr.h02
Normal file
@ -0,0 +1,72 @@
|
||||
/*********************************************
|
||||
* veraclr.h02 - Color Palette functions for *
|
||||
* Commander X16 VERA Chip *
|
||||
*********************************************/
|
||||
|
||||
/* Convert Palette Color Value *
|
||||
* to R, G, and B Values *
|
||||
* Args: int c - Color Value *
|
||||
* Returns: Red Value (0-255) *
|
||||
* Green Value (0-255) *
|
||||
* Blue Value (0-255) */
|
||||
char clrrgb();
|
||||
|
||||
/* Read Next Entry from Palette *
|
||||
* Returns: int c - Color Value */
|
||||
char getcln();
|
||||
|
||||
/* Read Color Value from Palette *
|
||||
* Args: char i - Palette Index *
|
||||
* Returns: int c - Color Value */
|
||||
char getclr();
|
||||
|
||||
/* Read Color Entries from Palette *
|
||||
* Args: i - Index into Palette *
|
||||
* n - Number of Entries *
|
||||
* Requires: setdst(&array) */
|
||||
char getplt();
|
||||
|
||||
/* Read RGB Color from Palette *
|
||||
* Requires: setidx() *
|
||||
* Returns: Red Value (0-255) *
|
||||
* Green Value (0-255) *
|
||||
* Blue Value (0-255) */
|
||||
char getrgb();
|
||||
|
||||
/* Convert R, G, and B Values *
|
||||
* to Palette Color Value *
|
||||
* Args: r - Red Value (0-255) *
|
||||
* g - Green Value (0-255) *
|
||||
* b - Blue Value (0-255) *
|
||||
* Returns: int c - Color Value */
|
||||
char rgbclr();
|
||||
|
||||
/* Set Next Palette Entry to Color *
|
||||
* Requires: setidx() *
|
||||
* Args: int c - Color Value */
|
||||
char setcln();
|
||||
|
||||
/* Write Color Value to Palette *
|
||||
* Args: i - Index into Palette *
|
||||
* int c - Color Value */
|
||||
char setclr();
|
||||
|
||||
/* Set Vera Address to Palette Index *
|
||||
* Args: i - Index into Palette *
|
||||
* int c - Color Value *
|
||||
* Returns: char b = Bank |Auto-Incr *
|
||||
* int d = Entry Address */
|
||||
char setidx();
|
||||
|
||||
/* Write Color Entries to Palette *
|
||||
* Args: i - Index into Palette *
|
||||
* n - Number of Entries *
|
||||
* Requires: setsrc(&entries) */
|
||||
char setplt();
|
||||
|
||||
/* Set Next Palette Entry to RGB *
|
||||
* Requires: setidx() *
|
||||
* Args: r - Red Value (0-255) *
|
||||
* g - Green Value (0-255) *
|
||||
* b - Blue Value (0-255) */
|
||||
char setrgb();
|
261
x16/include/veradsp.a02
Normal file
261
x16/include/veradsp.a02
Normal file
@ -0,0 +1,261 @@
|
||||
; Vera Display Composer Assembly Language Routines for C02
|
||||
; Requires External Routines GETVRG and SETDCX, SETDST
|
||||
; and External Variables TEMP0, TEMP1, and TEMP2
|
||||
|
||||
;Display Composer Registers
|
||||
;$F0000 Video Control
|
||||
;$F0001 Horizontal Scale
|
||||
;$F0002 Vertical Scale
|
||||
;$F0003 Border Color
|
||||
;$F0004 Horizontal Start LSB
|
||||
;$F0005 Horizontal Stop LSB
|
||||
;$F0006 Vertical Start LSB
|
||||
;$F0007 Vertical Stop LSB
|
||||
;$F0008 Start/Stop High Bits
|
||||
;$F0009 IRQ Line LSB
|
||||
;$F000A IRQ Line MSB
|
||||
|
||||
;getbdr() - Get Border Color
|
||||
;Returns: A = Border Color Palette Index
|
||||
GETBDR: LDA #$03 ;Set Register Offset to Border Color
|
||||
|
||||
;getdcb(reg) - Read Single Display Composer Register
|
||||
;Args: A = Register Offset
|
||||
;Affects: Y
|
||||
;Returns: A = Contents of Register
|
||||
; X = Current Data Port
|
||||
GETDCB: LDY #$00 ;Set MSB to Display Composer Page
|
||||
TAX ;Set LSB to Register Offset
|
||||
JMP GETVRG ;and Execute Vera Register
|
||||
|
||||
;getdcr(&array) - Read All Display Composer Registers
|
||||
;Args: Y,X = Address of Array
|
||||
;Affects: Y
|
||||
;Returns: A = Contents of Register
|
||||
; X = Current Data Port
|
||||
GETDCR: JSR SETDST ;Set Destination Pointer to Array
|
||||
JSR SETDCA ;Set Address to Display Composer
|
||||
LDA #11 ;Set Number of Registers to 11
|
||||
JMP GETMEA ;and Read Registers
|
||||
|
||||
SETDCA: LDY #00 ;Set Page to Display Composer
|
||||
LDX #0 ;Set Register to 0
|
||||
JMP REGADR ;Set Vera Address to Register
|
||||
|
||||
;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
|
||||
|
||||
;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
|
||||
JMP GETVRI ;Get Vera Register Pair
|
||||
|
||||
;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 GETDCB ;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
|
||||
|
||||
;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
|
||||
BRA 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
|
||||
BRA 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
|
||||
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 GETDCB ;Read LSB from Register
|
||||
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
|
||||
PLX ;Restore LSB into X
|
||||
RTS
|
||||
|
||||
;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
|
||||
JMP SETREG ;Write to Register
|
||||
|
||||
;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
|
||||
|
||||
;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
|
||||
JMP SETREI ;Set Register to Integer
|
||||
|
||||
;sethsp() - Set Horizontal Stop
|
||||
;Args: Y,X = Horizontal Stop
|
||||
;Destroys TEMP1,TEMP2
|
||||
;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
|
||||
BNE SETHVS ;OR in High Bits and Write Back
|
||||
|
||||
;sethsr() - Set Horizontal Start
|
||||
;Args: Y,X = Horizontal Start
|
||||
;Destroys 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
|
||||
|
||||
;sethvs() - Set Horizontal/Vertical Start/Stop
|
||||
;Args: A = Start/Stop LSB
|
||||
; Y = High Bits and Mask
|
||||
; X = LSB Register Offset
|
||||
;Uses: TEMP1 = Start Stop High Bits
|
||||
;Destroys: TEMP2
|
||||
;Affects: A,X,Y
|
||||
SETHVS: STY TEMP2 ;Save
|
||||
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
|
||||
AND TEMP2 ;Mask Start Stop High
|
||||
ORA TEMP1 ;OR in High Bits
|
||||
STA $9F23,X ;and Write back to Register
|
||||
RTS
|
||||
|
||||
;setvsp() - Set Horizontal Stop
|
||||
;Args: Y,X = Horizontal Stop
|
||||
;Destroys TEMP1,TEMP2
|
||||
;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
|
||||
BNE SETHVS ;OR in High Bits and Write Back
|
||||
|
||||
;setvsr() - Set Horizontal Start
|
||||
;Args: Y,X = Horizontal Start
|
||||
;Destroys TEMP1,TEMP2
|
||||
;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
|
||||
BNE SETHVS ;OR in High Bits and Write Back
|
76
x16/include/veradsp.h02
Normal file
76
x16/include/veradsp.h02
Normal file
@ -0,0 +1,76 @@
|
||||
/*********************************************
|
||||
* veradsp.h02 - Display Composer Functions *
|
||||
* Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
*********************************************/
|
||||
|
||||
/* Get Border Color *
|
||||
* Returns: char i - Color Index */
|
||||
char getbdr();
|
||||
|
||||
/* Get Horizontal Stop *
|
||||
* Returns: int i - Horizontal Stop */
|
||||
char gethsp();
|
||||
|
||||
/* Get Horizontal Start *
|
||||
* Returns: int i - Horizontal Start */
|
||||
char gethsr();
|
||||
|
||||
/* Get IRQ Line *
|
||||
* Returns: int i - IRQ Line */
|
||||
char getiql();
|
||||
|
||||
/* Get Horizontal and Vertical Scale *
|
||||
* Returns: char h - Horizontal Scale *
|
||||
* char v - Vertical Scale */
|
||||
char getscl();
|
||||
|
||||
/* Get Video Output Mode *
|
||||
* Returns: char m - Output Mode *
|
||||
* char c - Chroma Disabled *
|
||||
* char f - Current Field */
|
||||
char getvid();
|
||||
|
||||
/* Get Vertical Stop *
|
||||
* Returns: int i - Vertical Stop */
|
||||
char getvsp();
|
||||
|
||||
/* Get Vertical Start *
|
||||
* Returns: int i - Vertical Start */
|
||||
char getvsr();
|
||||
|
||||
/* Set Border Color *
|
||||
* Args: char i - Color Index */
|
||||
char setbdr();
|
||||
|
||||
/* Set Horizontal Stop *
|
||||
* Args: int i - Horizontal Stop */
|
||||
char sethsp();
|
||||
|
||||
/* Set Horizontal Start *
|
||||
* Args: int i - Horizontal Start */
|
||||
char sethsr();
|
||||
|
||||
/* set IRQ Line *
|
||||
* Args: int i - IRQ Line */
|
||||
char setiql();
|
||||
|
||||
/* Set Horizontal and Vertical Scale *
|
||||
* Args: char h - Horizontal Scale *
|
||||
* char v - Vertical Scale */
|
||||
char setscl();
|
||||
|
||||
/* Set Video Output Mode *
|
||||
* Args: char m - Output Mode *
|
||||
* char c - Chroma Disabled */
|
||||
char setvid();
|
||||
|
||||
/* Set Vertical Stop *
|
||||
* Args: int i - Vertical Stop */
|
||||
char setvsp();
|
||||
|
||||
/* Set Vertical Start *
|
||||
* Args: int i - Vertical Start */
|
||||
char setvsr();
|
384
x16/include/veralyr.a02
Normal file
384
x16/include/veralyr.a02
Normal file
@ -0,0 +1,384 @@
|
||||
; Vera Layer Control Assembly Language Routines for C02
|
||||
; Requires External Routines GETVRG, GETVRI, RESRXY, SAVREG, SAVRXY
|
||||
; and External Variables TEMP0, TEMP1, TEMP2, TEMP3
|
||||
|
||||
;Layer 0/1 Registers
|
||||
;$F2000/$F3000 Layer Control (Mode and Enabled)
|
||||
;$F2001/$F3001 Tile and Map Height and Width
|
||||
;$F2002/$F3002 Map Base Bits 9-2
|
||||
;$F2003/$F3003 Map Base Bits 17-10
|
||||
;$F2004/$F3004 Tile Base Bits 9-2
|
||||
;$F2005/$F3005 Tile Base Bits 17-10
|
||||
;$F2006/$F3006 Horizontal Scroll LSB
|
||||
;$F2007/$F3007 Horizontal Scroll MSB or Bitmap Palette Offset
|
||||
;$F2008/$F3008 Vertical Scroll LSB
|
||||
;$F2009/$F3009 Vertical Scroll MSB
|
||||
|
||||
;getbpo(lyr) - Get Bitmap Palette Offset
|
||||
;Args: A = Layer (0/1)
|
||||
;Affects: Y
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;Returns: A = Control Register Contents
|
||||
; X = Current Data Port
|
||||
GETBPO: LDX #7 ;Set Offset to Bitmap Palette Offset
|
||||
JSR GETLRR ;Read Register
|
||||
ASL ;and Multiply by 16
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
RTS
|
||||
|
||||
;getlrs(lyr) - Get Layer 0/1 Size Register
|
||||
;Args: A = Layer (0/1)
|
||||
;Affects: Y
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;Returns: A = Size Register Contents
|
||||
; X = Current Data Port
|
||||
GETLRS: LDX #1 ;Set Offset to Size Register
|
||||
.DC $2C ;Skip to GETLRR (BIT Absolute)
|
||||
|
||||
;getlrc(lyr) - Get Layer 0/1 Control Register
|
||||
;Args: A = Layer (0/1)
|
||||
;Affects: Y
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;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
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;Affects: Y
|
||||
;Returns: A = Contents of Register
|
||||
; X = Current Data Port
|
||||
GETLRR: STX TEMP3 ;Save Register Offset - Obselete?
|
||||
JSR GETLRP ;Get Layer Page in Y
|
||||
JMP GETVRG ;and Read Vera Register
|
||||
|
||||
;getlrp(lyr) - 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
|
||||
|
||||
;getenb(lyr) - 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
|
||||
|
||||
;getmod(lyr) - 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
|
||||
LSR
|
||||
RTS
|
||||
|
||||
;getmsz(lyr) - Get Layer 0/1 Map Size
|
||||
;Args: A = Layer (0/1)
|
||||
;Affects: X
|
||||
;Returns: A = Width Specifier
|
||||
; Y = Height Specifier
|
||||
GETMSZ: JSR GETLRS ;Read Size Register
|
||||
TAX ;Save Contents
|
||||
LSR ;Shift Right 2 Bits
|
||||
LSR
|
||||
AND #$03 ;Isolate Bits 0 and 1
|
||||
TAY ;and Return in Y
|
||||
TXA ;Restore Register Contents
|
||||
AND #$03 ;Return Bits 0 and 1 in A
|
||||
RTS
|
||||
|
||||
;gettsz(lyr) - Get Layer 0/1 Map Size
|
||||
;Args: A = Layer (0/1)
|
||||
;Affects: X
|
||||
;Returns: A = Width Specifier
|
||||
; Y = Height Specifier
|
||||
GETTSZ: JSR GETLRS ;Read Size Register
|
||||
LSR ;Shift Right 4 Bits
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
TAX ;Save Intermediate Value
|
||||
LSR ;Shift Right 1 More Bit
|
||||
AND #$01 ;Isolate Bit 0
|
||||
TAY ;and Return in Y
|
||||
TXA ;Restore Intermediate Value
|
||||
AND #$01 ;and Return Bit 0 in A
|
||||
RTS
|
||||
|
||||
;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
|
||||
JMP GETVRI ;and Read Register Contents
|
||||
|
||||
;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)
|
||||
;Sets: TEMP0 = Bank
|
||||
; TEMP1 = Address LSB
|
||||
; TEMP2 = Address MSB
|
||||
;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 SAVREG ;Save Integer in TEMP1,TEMP2
|
||||
LDX #2 ;Set Count to 2
|
||||
JMP ASLADR ;and Shift Address Left
|
||||
|
||||
;mapsiz() - Convert Map Size Specifier to Pixels
|
||||
;Args: A = Map Size Specifier
|
||||
;Affects: A
|
||||
;Returns: A = Shift Count
|
||||
; Y,X Map Size in Pixels
|
||||
MAPSIZ: TAX ;Copy Size Specifier to X
|
||||
LDA MAPSIC,X ;Load Shift Count from Table
|
||||
PHA ;and Save it
|
||||
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
|
||||
PLA ;Return Shift Count in A
|
||||
RTS
|
||||
MAPSIC: .DC $05,$06,$07,$08
|
||||
MAPSIL: .DC $20,$40,$80,$00
|
||||
MAPSIH: .DC $00,$00,$00,$01
|
||||
|
||||
;tilsiz() - Convert Tile Size Specifier to Pixels
|
||||
;Args: A = Tile Size Specifier
|
||||
;Returns: A = Tile Size in Pixels
|
||||
; Y = Shift Count
|
||||
TILSIZ: TAX ;Copy Map Size Specifier to X
|
||||
LDA TILSIT,X ;Return Pixels in A
|
||||
LDY TILSIC,X ;and Shift Count in Y
|
||||
RTS
|
||||
TILSIC: .DC $03,$04
|
||||
TILSIT: .DC $08,$10
|
||||
|
||||
;setbpo(lyr) - Set Bitmap Palette Offset
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Bitmap Palette Offset
|
||||
;Affects: Y
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;Returns: A = Control Register Contents
|
||||
; X = Current Data Port
|
||||
SETBPO: PHA ;Save Layer Number
|
||||
TYA ;Copy Offset to Accumulator
|
||||
LSR ;Divide by 16
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
TAY ;Copy Back to Y
|
||||
PLA ;Restore Layer Number
|
||||
LDX #7 ;Set Register Offset
|
||||
BNE SETLRR ;and Write to Register
|
||||
|
||||
;setenb(lyr,flg) - Get Layer 0/1 Enabled
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Layer Enabled Flags
|
||||
;Destroys: TEMP0
|
||||
;Affects: A,X,Y
|
||||
SETENB: CPY #0 ;Test Enabled Argument`
|
||||
BEQ SETENZ ;If Not Zero
|
||||
LDY #$01 ; Set to 1
|
||||
SETENZ: LDX #$FE ;Set Control Register Mask
|
||||
|
||||
;setlrc(lyr,val,msk) - Set Layer 0/1 Control Register
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Value to Write
|
||||
; X = Register Mask
|
||||
;Affects: Y
|
||||
;Returns: A = Value Written
|
||||
; X = Current Data Port
|
||||
SETLRC: JSR SAVREG ;Save Layer, Value, and Mask
|
||||
JSR GETLRC ;Get Layer Control Register
|
||||
SETLRM: AND TEMP1 ;Apply Mask
|
||||
ORA TEMP2 ;OR in Value
|
||||
TAY ;and Move to Y Register
|
||||
LDA TEMP0 ;Restore Layer Number
|
||||
LDX TEMP3 ;Get Register Offset
|
||||
|
||||
;setlrr() - Set Layer 0/1 Register
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Value to Write
|
||||
; X = Register Offset
|
||||
;Affects: Y
|
||||
;Returns: A = Contents of Register
|
||||
; X = Current Data Port
|
||||
SETLRR: ;.dc $ff
|
||||
PHY ;Save Value to Write
|
||||
JSR GETLRP ;Get Layer Page in Y
|
||||
PLA ;Restore Value to Write
|
||||
JMP SETREG ;and Write to Register
|
||||
|
||||
;setlrs(lyr,val,msk) - Set Layer 0/1 Size Register
|
||||
;Args: A = Layer (0/1)
|
||||
/; Y = Value to Write
|
||||
; X = Register Mask
|
||||
;Affects: Y
|
||||
;Returns: A = Value Written
|
||||
; X = Current Data Port
|
||||
SETLRS: ;.dc $ff
|
||||
JSR SAVREG ;Save Layer, Value, and Mask
|
||||
JSR GETLRS ;Get Layer Size Register
|
||||
BRA SETLRM ;Mask in Value and Write Back
|
||||
|
||||
;setmod() - Set Layer 0/1 Mode
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Layer Mode
|
||||
;Destroys: TEMP0
|
||||
;Affects: A,X,Y
|
||||
SETMOD: TAX ;Save Layer Number
|
||||
TYA ;Copy Mode to Accumulator
|
||||
ASL ;Shift to Bits 5-7
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
TAY ;Copy Write Value to Y
|
||||
TXA ;Restore Layer Number
|
||||
LDX #$1F ;Set Control Register Mask
|
||||
BNE SETLRC ;and Update Control Register
|
||||
|
||||
;setmsz(lyr) - Set Layer 0/1 Map Size
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Width Specifier
|
||||
; X = Height Specifier
|
||||
;Destroys: TEMP0
|
||||
;Affects: A,X,Y
|
||||
SETMSZ: PHA ;Save Layer Number
|
||||
TXA ;Get Height Specifier
|
||||
AND #$03 ;Strip High Bits
|
||||
ASL ;Rotate Left 2 Bits
|
||||
ASL
|
||||
STA TEMP0 ;and Save It
|
||||
TYA ;Get Width Specifier
|
||||
AND #$03 ;Strip High Bits
|
||||
ORA TEMP0 ;OR in Height Specifier
|
||||
TAY ;Copy Write Value to Y
|
||||
PLA ;Restore Layer Number
|
||||
LDX #$F0 ;Set Size Register Mask
|
||||
BNE SETLRS ;and Update Size Register
|
||||
|
||||
;settsz(lyr) - Set Layer 0/1 Tile Size
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Width Specifier
|
||||
; X = Height Specifier
|
||||
;Destroys: TEMP0
|
||||
;Affects: A,X,Y
|
||||
SETTSZ: PHA ;Save Layer Number
|
||||
TXA ;Get Height Specifier
|
||||
AND #$01 ;Strip High Bits
|
||||
ASL ;Rotate Left 1 Bits
|
||||
STA TEMP0 ;and Save It
|
||||
TYA ;Get Width Specifier
|
||||
AND #$01 ;Strip High Bits
|
||||
ORA TEMP0 ;OR in Height Specifier
|
||||
ASL ;Shift Left 4 More Bits
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
TAY ;Copy Write Value to Y
|
||||
PLA ;Restore Layer Number
|
||||
LDX #$CF ;Set Size Register Mask
|
||||
BNE SETLRS ;and Update Size Register
|
||||
|
||||
;sethsc() - Set Layer 0/1 Horizontal Scroll
|
||||
;Args: A = Layer (0/1)
|
||||
; Y,X = Map Base
|
||||
;Sets: TEMP1,TEMP2 = Horizontal Scroll
|
||||
;Affects: 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
|
||||
;Affects: A,Y,X
|
||||
SETLRI: JSR GETLRP ;Get Layer Page in Y
|
||||
JMP SETREI ;and Write Integer to Register
|
||||
|
||||
;setmbs() - Set Layer 0/1 Map Base
|
||||
;Args: A = Layer (0/1)
|
||||
; Y,X = Map Base
|
||||
;Sets: TEMP1,TEMP2 = Map Base
|
||||
;Affects: A,Y,X
|
||||
SETMBS: JSR SAVRXY ;Store Map Base in TEMP1,TEMP2
|
||||
LDX #2 ;Set Register Offset
|
||||
BNE SETLRI ;Write to Layer Register
|
||||
|
||||
;settbs() - Set Layer 0/1 Map Base
|
||||
;Args: A = Layer (0/1)
|
||||
; Y,X = Map Base
|
||||
;Sets: TEMP1,TEMP2 = Map Base
|
||||
;Affects: A,Y,X
|
||||
SETTBS: JSR SAVRXY ;Store Map Base in TEMP1,TEMP2
|
||||
LDX #4 ;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
|
||||
;Affects: A,Y,X
|
||||
SETVSC: JSR SAVRXY ;Store Vertical Scroll in TEMP1,TEMP2
|
||||
LDX #8 ;Set Register Offset
|
||||
BNE SETLRI ;Write to Layer Register
|
108
x16/include/veralyr.h02
Normal file
108
x16/include/veralyr.h02
Normal file
@ -0,0 +1,108 @@
|
||||
/*********************************************
|
||||
* veralyr.h02 - Layer control functions for *
|
||||
* Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
*********************************************/
|
||||
|
||||
/* Get Layer Enabled *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: $FF = Layer Enabled *
|
||||
* $00 = Disabled */
|
||||
char getenb();
|
||||
|
||||
/* Get Horizontal Scroll Offset *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: int d - Horizontal Scroll */
|
||||
char gethsc();
|
||||
|
||||
/* Get Layer Mode *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char m - Layer Mode */
|
||||
char getmod();
|
||||
|
||||
/* Get Map Base Address *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char b - Bank *
|
||||
* int d - Address */
|
||||
char getmba();
|
||||
|
||||
/* Get Map Base Register *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: int d - Map Base */
|
||||
char getmbs();
|
||||
|
||||
//Not Implemented
|
||||
/* Get Map Size Specifier *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char w - Map Width *
|
||||
* char h - Map Height */
|
||||
char getmsz();
|
||||
|
||||
/* Get Tile Base Address *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char b - Bank *
|
||||
* int d - Address */
|
||||
char gettba();
|
||||
|
||||
/* Get Tile Base Register *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: int d - Tile Base */
|
||||
char gettbs();
|
||||
|
||||
//Not Implemented
|
||||
/* Get Tile Size Specifier *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char s - Tile Size */
|
||||
char gettsz();
|
||||
|
||||
/* Get Vertical Scroll Offset *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: int d - Vertical Scroll */
|
||||
char getvsc();
|
||||
|
||||
/* Convert Map Size to Pixels *
|
||||
* Args: char s - Map Size Specifier *
|
||||
* Returns: int p - Size in Pixels */
|
||||
char mapsiz();
|
||||
|
||||
/* Set Layer Enabled *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* char e - Enabled */
|
||||
char setenb();
|
||||
|
||||
/* Set Horizontal Scroll Offset *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* int d - Horizontal Scroll */
|
||||
char sethsc();
|
||||
|
||||
/* Set Layer Mode *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* Returns: char m - Layer Mode */
|
||||
char setmod();
|
||||
|
||||
/* Set Map Base Register *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* int d - Map Base */
|
||||
char setmbs();
|
||||
|
||||
/* Set Map Size Specifier *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* char s - Map Size */
|
||||
char setmsz();
|
||||
|
||||
/* Set Tile Base Register *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* int d - Tile Base */
|
||||
char settbs();
|
||||
|
||||
/* Set Tile Size Specifier *
|
||||
* Args: char l - Layer (0/1) *
|
||||
* char s - Tile Size */
|
||||
char settsz();
|
||||
|
||||
/* Convert Tile Size to Pixels *
|
||||
* Args: char s - Tile Size Specifier *
|
||||
* Returns: int p - Size in Pixels */
|
||||
char tilsiz();
|
236
x16/include/veramem.a02
Normal file
236
x16/include/veramem.a02
Normal file
@ -0,0 +1,236 @@
|
||||
; Vera Memory Access Assembly Language Routines for C02
|
||||
; Requires External Routines RESRXY, SETDST, and SETSRC
|
||||
; and External Variables TEMP0 and TEMP1
|
||||
|
||||
;Vera External Registers
|
||||
;$9F20 Address LSB
|
||||
;$9F21 Address MSB
|
||||
;$9F22 Auto-Increment and Address Bank
|
||||
;$9F23 Data Port 0
|
||||
;$9F24 Data Port 1
|
||||
;$9F25 Control Register
|
||||
;$9F26 Interrupt Enable
|
||||
;$9F27 Interrupt Status
|
||||
|
||||
;asladr() - Shift Vera Address Left`
|
||||
;Args: X = Number of Bits to Shift
|
||||
;Updates: TEMP0 = Bank
|
||||
; TEMP1 = Address LSB
|
||||
; TEMP3 = Address MSB
|
||||
;Returns: A = Bank
|
||||
; Y,X = Address
|
||||
ASLADR: ASL TEMP1 ;Shift LSB Left
|
||||
ROL TEMP2 ;Rotate Carry Left into MSB
|
||||
ROL TEMP0 ;Rotate Carry Left into LSB
|
||||
DEX ;Decrement Shift Count
|
||||
BNE ASLADR ;and Loop if Not Zero
|
||||
BRA RESREG ;Return Bank, MSB, LSB
|
||||
|
||||
;chkadr(opts,addr) - Check Vera Address
|
||||
;Args: A = Bank + Auto-Increment
|
||||
; Y,X = Address
|
||||
;Returns: A = $00 - Address is Invalid
|
||||
; $FF - Address is Valid
|
||||
CHKADR: AND #$0F ;Isolate Bank
|
||||
CMP #$0F ;If Registers
|
||||
BEQ GETVRT ; Return True
|
||||
CMP #$02 ;Else If <2
|
||||
BCS GETVRT ; Return True
|
||||
LDA #$0 ;Else Return False
|
||||
RTS
|
||||
|
||||
;clrmem(count) - Write Array to Vera Memory
|
||||
;Args: A = Number of Bytes to Clear
|
||||
;Returns: A,Y = 0
|
||||
; X = Current Data Port
|
||||
CLRMEM: TAY ;Copy Number of Bytes to Y
|
||||
LDA #0 ;Set Write Value to Zero
|
||||
|
||||
;filmem(byte, count) - Fill Vera Memory with Byte
|
||||
;Args: A = Byte to Fill Memory With
|
||||
; Y = Number of Bytes to Fill
|
||||
;Returns: Y = 0
|
||||
; X = Current Data Port
|
||||
FILMEM LDX $9F25 ;Get Current Data Port
|
||||
FILMEL: STA $9F23,X ;Write Byte to Data Port
|
||||
DEY ;Decrement Counter
|
||||
BNE FILMEL ;If Not Zero Loop
|
||||
RTS
|
||||
|
||||
;getadr() - Get Vera Address
|
||||
;Args: A = Bank + Auto-Increment
|
||||
; Y,X = Address
|
||||
GETADR: LDX $9F20 ;Read Address LSB
|
||||
LDY $9F21 ;Read Address MSB
|
||||
LDA $9F22 ;Read Bank & Auto-Increment
|
||||
RTS
|
||||
|
||||
;getvrb(&addr) - Get Vera Register Bit Status
|
||||
;Args: A = Bit Mask
|
||||
; Y,X = Address
|
||||
;Returns: A = Mode
|
||||
; X = Current Data Port
|
||||
GETVRB: STA TEMP0 ;Save Bit Mask
|
||||
JSR GETVRG ;Read Register
|
||||
AND TEMP0 ;Mask Register Bit
|
||||
BEQ GETVRX ;If Set
|
||||
GETVRT: LDA #$FF ; Return TRUE
|
||||
GETVRX: RTS ;Else Return FALSE
|
||||
|
||||
;getvrg(&addr) - Read Vera Internal Register
|
||||
;Args: Y,X = Address
|
||||
;Returns: A = Mode
|
||||
; X = Current Data Port
|
||||
GETVRG: LDA #$0F ;Set Bank to Registers
|
||||
;and Execute GETBYT
|
||||
;getbyt(&addr);
|
||||
;Args: A = Bank
|
||||
; Y,X = Address
|
||||
;Affects: Y
|
||||
;Returns: A = Contents of Memory
|
||||
; X = Current Data Port
|
||||
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
|
||||
TYA ;Return Count
|
||||
RTS
|
||||
|
||||
;getvri(addr); Read Vera Register Pair
|
||||
;Args: Y,X = Address
|
||||
;Returns: A,X = Integer LSB
|
||||
; Y = Integer LSB
|
||||
GETVRI: 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: AND #$0F ;Set Auto-Increment to 1
|
||||
ORA #$10
|
||||
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
|
||||
|
||||
;regadr(addr) - Set Vera Address to Internal Register
|
||||
;Args: Y,X = Register Address
|
||||
;Returns: A = Bank | Auto-Increment
|
||||
REGADR: LDA #$0F ;Set Bank and Auto-Increment
|
||||
|
||||
;setadi(bank,addr) - Set Vera Address with Auto-Increment
|
||||
;Args: A = Bank
|
||||
; Y,X = Address
|
||||
SETADI: ORA #$10 ;Set Auto-Increment to 1
|
||||
|
||||
;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
|
||||
|
||||
;setvrb(bits, &addr) - Set Vera Register Bits
|
||||
;Args: A = Bit Pattern
|
||||
; Y,X = Address
|
||||
;Uses: TEMP0 = Bit Mask
|
||||
;Sets: TEMP1 = Bit Pattern
|
||||
;Affects: A,Y,X
|
||||
SETVRB: STA TEMP1 ;Save Bit Pattern
|
||||
JSR GETVRG ;Read Register
|
||||
AND TEMP0 ;Mask Result
|
||||
ORA TEMP1 ;Set Bits
|
||||
BRA SETBYN ;Write Back to Register
|
||||
|
||||
;setreg(addr) - Set Register
|
||||
;Args: A = Value to Write
|
||||
; Y,X = Address
|
||||
;Sets: TEMP0 = Value to Write
|
||||
;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
|
||||
;Returns: A = Value Written
|
||||
; X = Current Data Port
|
||||
SETBYT: JSR SETADR ;Set Vera Address
|
||||
LDA TEMP0 ;Retrieve Value to Write
|
||||
SETBYN: LDX $9F25 ;Get Current Data Port
|
||||
STA $9F23,X ;Write Value to Data Port
|
||||
RTS
|
||||
|
||||
;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
|
||||
|
||||
;setina(addr) - Write Integer to Vera Address
|
||||
;Args: A = Bank
|
||||
; Y,X = Address
|
||||
;Uses: TEMP1,TEMP2 = Integer Value
|
||||
;Affects: A,Y
|
||||
;Returns: X = Current Data Port
|
||||
SETINA: ORA #$10 ;Set Auto-Increment to 1
|
||||
JSR SETADR ;Set Vera Address
|
||||
JSR RESRXY ;Restore Integer into Y,X
|
||||
|
||||
;setint(addr) - Write Integer to Vera Memory
|
||||
;Args: Y,X = Integer to Write
|
||||
;Requires: setadr();
|
||||
;Affects: A,Y
|
||||
;Returns: X = Current Data Port
|
||||
SETINT: TXA ;Copy LSB to Accumlator
|
||||
LDX $9F25 ;Get Current Data Port
|
||||
STA $9F23,X ;Write to Data Port
|
||||
TYA ;Copy MSB to Accumlator
|
||||
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
|
||||
;Returns: A,Y = Number of Bytes Written
|
||||
; X = Current Data Port
|
||||
SETMEM: JSR SETSRC ;Save Source Address
|
||||
SETMET: STA TEMP0 ;Save Number of Bytes
|
||||
SETMEA: 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
|
||||
TYA ;Return Count
|
||||
RTS
|
80
x16/include/veramem.h02
Normal file
80
x16/include/veramem.h02
Normal file
@ -0,0 +1,80 @@
|
||||
/*********************************************
|
||||
* veramem.h02 - Memory Access Functions for *
|
||||
* Commander X16 VERA Chip *
|
||||
* *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
*********************************************/
|
||||
|
||||
|
||||
/* Check Vera Memory Address *
|
||||
* Args: char opts - Bank | Auto-Increment *
|
||||
* int addr - Address *
|
||||
* Returns: char valid - #TRUE or #FALSE */
|
||||
char chkadr();
|
||||
|
||||
/* Clear Vera Memory *
|
||||
* Args: char n - Number of Bytes *
|
||||
* Requires: setadr(bank,addr) */
|
||||
char clrmem();
|
||||
|
||||
/* Fill Vera Memory *
|
||||
* Args: char b - Byte to Write *
|
||||
* char n - Number of Bytes *
|
||||
* Requires: setadr(bank,addr) */
|
||||
char filmem();
|
||||
|
||||
/* Get Vera Memory Address *
|
||||
* Returns: char bank - Address Bits 16-19 *
|
||||
* int addr - Address Bits 0-15 */
|
||||
char getadr();
|
||||
|
||||
/* Read Byte from Vera Memory *
|
||||
* Args: char bank - Address Bits 16-19 *
|
||||
* int addr - Address Bits 0-15 *
|
||||
* Returns: char byte - Contents of Memory */
|
||||
char getbyt();
|
||||
|
||||
/* Read Integer from Vera Memory *
|
||||
* Args: char bank - Address Bits 16-19 *
|
||||
* int addr - Address Bits 0-15 *
|
||||
* Returns: int byte - Contents of Memory */
|
||||
char getint();
|
||||
|
||||
/* Read from Vera Memory into Array *
|
||||
* Args: char n - Number of Bytes *
|
||||
* int d - Address of Array *
|
||||
* Requires: setadr(bank,addr) *
|
||||
* Returns: char count - Bytes Written */
|
||||
char getmem();
|
||||
|
||||
/* Set Address to Internal Register *
|
||||
* Args: int addr - Register Address *
|
||||
char regadr();
|
||||
|
||||
/* Set Vera Address with Auto-Increment *
|
||||
* Args: char opts - Bank *
|
||||
* int addr - Address *
|
||||
char setadi();
|
||||
|
||||
/* Set Vera Memory Address *
|
||||
* Args: char opts - Bank | Auto-Increment *
|
||||
* int addr - Address *
|
||||
char setadr();
|
||||
|
||||
/* Write Byte to Vera Memory *
|
||||
* Args: char byte - Byte to Write *
|
||||
* Requires: setadr(bank,addr) */
|
||||
char setbyt();
|
||||
|
||||
/* Write Integer to Vera Memory *
|
||||
* Args: int word - Integer to Write *
|
||||
* Requires: setadr(bank,addr) */
|
||||
char setint();
|
||||
|
||||
/* Write from Array to Vera Memory *
|
||||
* Args: char n - Number of Bytes *
|
||||
* int d - Address of Array *
|
||||
* Requires: setadr(bank,addr) *
|
||||
* Returns: char count - Bytes Written */
|
||||
char setmem();
|
17
x16/include/veraspi.h02
Normal file
17
x16/include/veraspi.h02
Normal file
@ -0,0 +1,17 @@
|
||||
/**********************************************
|
||||
* veraspi.h02 - SPI Controller Routines *
|
||||
* for Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
**********************************************/
|
||||
|
||||
/* Read Bytes From SD Card *
|
||||
* Args: char n = Number of Bytes *
|
||||
* int d = Destination Address */
|
||||
sread();
|
||||
|
||||
/* Write Bytes to SD Card *
|
||||
* Args: char n = Number of Bytes *
|
||||
* int d = Source Address */
|
||||
swrite();
|
535
x16/include/veraspr.a02
Normal file
535
x16/include/veraspr.a02
Normal file
@ -0,0 +1,535 @@
|
||||
;Vera Sprite Manipulation Assembly Language Routines for C02
|
||||
;Requires External Routines GETMEA, GETVRB, GETVRG, SETMET, SETSRD, SETVRB
|
||||
;and External Variables DSTHI, DSTLO, SRCHI, SRCLO, TEMP0, TEMP0, TEMP2
|
||||
|
||||
;Sprite Control Registers
|
||||
;$F4000 SPR_CTRL Bit 0 - Enabled
|
||||
;$F4001 SPR_COLLISION Bits 0-3 Collision Mask
|
||||
|
||||
;Sprite attributes
|
||||
;$F5000 - 128 Entries of the Following Format:
|
||||
|
||||
; Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
|
||||
;+0 ---------------------Address (12:5)---------------------------
|
||||
;+1 Mode -------Address (16:13)-------
|
||||
;+2 ------------------------X (7:0)-------------------------------
|
||||
;+3 ---X (9:8)---
|
||||
;+4 ------------------------Y (7:0)-------------------------------
|
||||
;+5 ---Y (9:8)---
|
||||
;+6 --------Collision mask-------- ---Z-depth--- V-flip H-flip
|
||||
;+7 Sprite height Sprite width --------Palette offset--------
|
||||
|
||||
MAXSPR EQU 128 ;Maximum Sprite Index
|
||||
|
||||
;addspd(index,number) - Add to Sprite Address Register
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Number to Add
|
||||
;Affects: A,X,Y
|
||||
ADDSPD: JSR SAVREG ;Save Sprite Index, Addend
|
||||
JSR GETSPD ;Read Sprite Address Register
|
||||
JSR ADDTXY ;Add Number to Address
|
||||
BRA SETSTD ;Write Sprite (TEMP0) Address Register
|
||||
|
||||
;subspd(index,number) - Decrement Sprite Address Register
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Number to Add
|
||||
;Affects: A,X,Y
|
||||
SUBSPD: JSR SAVREG ;Save Sprite Index, Addend
|
||||
JSR GETSPD ;Read Sprite Address Register
|
||||
JSR ADDTXY ;Add Number to Address
|
||||
BRA SETSTD ;Write Sprite (TEMP0) Address Register
|
||||
|
||||
;clrspr(index) - Set Sprite Attributes
|
||||
;Args: A = Sprite Index
|
||||
;Destroys: TEMP0
|
||||
;Returns: A,Y = 0
|
||||
; X = Current Data Port
|
||||
CLRSPR: JSR SETSP0 ;Set Sprite Attributes Address
|
||||
JMP CLRMEM ;and Read from Vera
|
||||
|
||||
;getspc() - Read Sprites Collision Status
|
||||
;Affects: Y
|
||||
;Returns: A = Sprite Collision Status
|
||||
; X = Current Data Port
|
||||
GETSPC: LDX #$02 ;Set Offset to Sprite Control
|
||||
LDY #$40 ;Set Page to Sprite Registers
|
||||
JSR GETVRG ;Read Vera Register
|
||||
AND #$0F ;Return Bits 0-3
|
||||
RTS
|
||||
|
||||
;getspd(index) - Get Sprite Address Register
|
||||
;Args: A = Index
|
||||
;Affects: A
|
||||
;Returns: Y,X = Address Register Contents
|
||||
GETSPD: JSR GETSP0 ;Get Sprite Attribute Address
|
||||
JSR GETVRI ;Read Vera Register Pair
|
||||
TYA
|
||||
AND #$0F
|
||||
TAY
|
||||
RTS
|
||||
|
||||
;getspe() - Read Sprites Enabled Flag
|
||||
;Affects: Y
|
||||
;Returns: A = $FF - Sprites Enabled
|
||||
; $00 - Sprites Disabled
|
||||
; X = Current Data Port
|
||||
GETSPE: LDA #$01 ;Set Mask to %0000001
|
||||
LDX #$00 ;Set Offset to Sprite Control
|
||||
GETSP4: LDY #$40 ;Set Page to Sprite Registers
|
||||
JMP GETVRB ;Get Register Bit Sratus
|
||||
|
||||
;getspt(mask) - Test Sprite Collision Status
|
||||
;Args: A = Collision Bit Mask
|
||||
;Affects: Y
|
||||
;Returns: A = Sprite Collision Bits
|
||||
; X = Current Data Port
|
||||
GETSPT: LDX #$01 ;Set Offset to Sprite Collisions
|
||||
BNE GETSP4 ;Get Register Bit Status
|
||||
|
||||
;getspa(index) - Get Sprite Data Address
|
||||
;Args: A = Index
|
||||
;Returns: A = Bank
|
||||
; Y,X = Address
|
||||
GETSPA: JSR GETSPD ;Get Address Register Contents
|
||||
|
||||
;getsca(index) - Get Vera Address from Sprite Address
|
||||
;Args: Y,X = Sprite Address
|
||||
;Returns: A = Bank
|
||||
; Y,X = Address
|
||||
GETSCA: LDA #0 ;Set Bank to 0
|
||||
JSR SAVREG ;Save Address
|
||||
LDX #5 ;Set Shift Count
|
||||
JMP ASLADR ;and Shift Address Left
|
||||
|
||||
;getspb(index) - Get Sprite Bits Per Pixel
|
||||
;Args: A = Index
|
||||
;Returns: A = Mode (0=4bpp, 1=8bpp)
|
||||
GETSPB: JSR GETSP1 ;Read Sprite Register #1
|
||||
ASL ;Move High Bit to Carry
|
||||
LDA #0 ;Clear Accumulator
|
||||
ROL ;Move Carry into Low Bit
|
||||
RTS
|
||||
|
||||
;getspv(index) - Get Sprite Vertical Flip
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Vertical Flip Flag
|
||||
GETSPV: LDY #$02 ;Set Bit Mask to Bit 1
|
||||
.DC $2C ;Skip Next Instruction (Bit Absolute)
|
||||
|
||||
;getspf(index) - Get Sprite Horizontal Flip
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Horizontal Flip Flag
|
||||
GETSPF: LDY #$01 ;Set Bit Mask to Bit 0
|
||||
STY TEMP0 ;and Store It
|
||||
JSR GETSPN ;Get Sprite Control Register
|
||||
AND TEMP0 ;Mask Bit(s)
|
||||
BEQ GETSXF ;If Clear, Return FALSE
|
||||
LDA #$FF ;Else Return TRUE
|
||||
GETSXF: RTS
|
||||
|
||||
;getspw(index) - Get Sprite Width Specifier
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Palette Offset
|
||||
GETSPW: JSR GETSPS ;Get Sprite Size Register
|
||||
ASL ;Shift Left 2 Bits
|
||||
ASL
|
||||
BRA GETSP6 ;Then Right 6 Bits
|
||||
|
||||
;getsph(index) - Get Sprite Height Specifier
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Sprite Height Specifier
|
||||
GETSPH: JSR GETSPS ;Get Sprite Size Register
|
||||
GETSP6: LSR ;Shift Right 6 Bits
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
RTS
|
||||
|
||||
;getspm(index) - Get Sprite Collision Mask
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Collision Mask
|
||||
GETSPM: JSR GETSPN ;Get Sprite Control Register
|
||||
LSR ;Shift High Nybble to Low Nybble
|
||||
LSR
|
||||
LSR
|
||||
LSR
|
||||
RTS
|
||||
|
||||
;getspp(index) - Get Sprite Palette Offset
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Palette Offset
|
||||
GETSPP: JSR GETSPS ;Get Sprite Size Register
|
||||
AND #$0F ;Return Low Nybble
|
||||
RTS
|
||||
|
||||
;getspq(mode) - Calculate Bits Per Pixel
|
||||
;Args: A = Mode
|
||||
;Returns: A = Bits per Pixel
|
||||
; Y = Divisor Shift Count
|
||||
GETSPQ: AND #$01 ;Strip High Bits
|
||||
TAX ;Copy Mode to X
|
||||
LDA GETSTQ,X ;Read BPP from Table
|
||||
LDY GETSYQ,X ;Read Shift Count from Table
|
||||
RTS
|
||||
GETSTQ: .DC 4,8 ;Table: Bits Per Pixel
|
||||
GETSYQ: .DC 1,0 ;Table: Divisor SHift Count
|
||||
|
||||
;getsp1(index) - Get Sprite Register 1 (Mode, Addr MSB)
|
||||
;Args: A = Sprite Index
|
||||
GETSP1: LDY #1 ;Set Offset to Sprite Address MSB
|
||||
.DC $2C ;Skip to GETSPG (Bit Absolute)
|
||||
|
||||
;getsps(index) - Get Sprite Size Register
|
||||
;Args: A = Sprite Index
|
||||
GETSPS: LDY #7 ;Set Offset to Sprite Size Register
|
||||
.DC $2C ;Skip to GETSPG (Bit Absolute)
|
||||
|
||||
;getspn(index) - Get Sprite Control Register
|
||||
;Args: A = Sprite Index
|
||||
;Returns: Sprite Control Register Contents
|
||||
GETSPN: LDY #6 ;Set Offset to Sprite Address MSB
|
||||
|
||||
;getspg(index) - Get Sprite Register
|
||||
;Args: A = Sprite Index
|
||||
; Y = Register Offset
|
||||
;Returns: A = Mode (0=4bpp, 1=8bpp)
|
||||
GETSPG: JSR GETSPO ;Get Sprite Attribute Address
|
||||
JMP GETVRG ;Read Vera Register
|
||||
|
||||
;getspx(index) - Get Sprite X-Coordinate
|
||||
;Args: A = Index
|
||||
;Returns: Y,X = X-Coordinate
|
||||
GETSPX: LDY #2 ;Set Offset to X-Coordinate
|
||||
.DC $2C ;Skip to GETSPI (Bit Absolute)
|
||||
|
||||
;getspy(index) - Get Sprite Y-Coordinate
|
||||
;Args: A = Index
|
||||
;Returns: Y,X = X-Coordinate
|
||||
GETSPY: LDY #4 ;Set Offset to Y-Coordinate
|
||||
GETSPI: JSR GETSPO ;Get Sprite Attribute Address
|
||||
JMP GETVRI ;Read Vera Register Pair
|
||||
|
||||
;getspz(index) - Get Sprite Z-Depth
|
||||
;Args: A = Sprite Index
|
||||
;Returns: A = Z-Depth (0-3)
|
||||
GETSPZ: JSR GETSPN ;Get Sprite Control Register
|
||||
AND #$0F ;Clear High Nybble
|
||||
LSR ;Shift Right Two Bits
|
||||
LSR
|
||||
RTS
|
||||
|
||||
;getspk(&spregs) - Get Sprite Control Registers`
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Address of Destination Array
|
||||
GETSPK: JSR SETDST ;Set Destination Address
|
||||
JSR SETSCR ;Set Vera
|
||||
JMP GETMEA ;and Read from Vera
|
||||
|
||||
;setscr() - Set Vera Address to Sprite Control Registers
|
||||
SETSCR: LDY #$40 ;Set Page to Sprite Control Registers
|
||||
LDX #$00 ;Set Offset to 0
|
||||
JSR REGADR ;Set Vera Address to Register
|
||||
LDA #2 ;Set Size to 2 Bytes
|
||||
RTS
|
||||
|
||||
;setspk(&spregs) - Get Sprite Control Registers`
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Address of Destination Array
|
||||
SETSPK: JSR SETSRC ;Set Destination Address
|
||||
JSR SETSCR ;Set Vera
|
||||
JMP SETMET ;and Write to Vera
|
||||
|
||||
;getspr(index,&sprite) - Get Sprite Attributes
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Address of Destination Array
|
||||
GETSPR: JSR SETDST ;Set Destination Address
|
||||
JSR SETSP0 ;Set Sprite Attributes Address
|
||||
JMP GETMEA ;and Read from Vera
|
||||
|
||||
;getspo(index,offset) - Get Sprite Attribute Address
|
||||
;Args: A = Sprite Index
|
||||
; Y = Attribute Offset
|
||||
;Destroys: TEMP3
|
||||
;Returns: A,X = Address LSB
|
||||
; Y = Address MSB
|
||||
GETSP0: LDY #0 ;Set Attribute Offset to 0
|
||||
GETSPO: STA TEMP3 ;Set LSB to Index
|
||||
TYA ;Copy Offset to Accumulator
|
||||
AND #$07 ;Modulo 8
|
||||
PHA ;and Save It
|
||||
LDA #0 ;Set MSB to 0
|
||||
ASL TEMP3 ;Multiply by 8
|
||||
ROL
|
||||
ASL TEMP3
|
||||
ROL
|
||||
ASL TEMP3
|
||||
ROL
|
||||
ORA #$50 ;Add to Register Page
|
||||
TAY ;Return MSB in Y
|
||||
PLA ;Restore Offset
|
||||
ORA TEMP3 ;Add to LSB
|
||||
TAX ;and Return in X
|
||||
RTS
|
||||
|
||||
;setspa(index) - Set Vera Address to Sprite Address
|
||||
;Args: Y,X = Sprite Address
|
||||
;Affects: A,X,Y
|
||||
SETSPA: JSR GETSCA ;Convert Sprite Address to Vera Address
|
||||
JMP SETADI ;Set Vera Address with Auto-Increment
|
||||
|
||||
;setspb() - Set Sprite Bits Per Pixel
|
||||
;Args: A = Sprite Index
|
||||
; Y = Bits Per Pixel
|
||||
;Affects: A,X,Y
|
||||
SETSPB: STY TEMP0 ;Save Bits Per Pixel
|
||||
JSR GETSP1 ;Read Sprite Register #1
|
||||
ASL ;Shift Out Bit 7
|
||||
LSR TEMP0 ;Shift BPP to Carry
|
||||
ROR ;then into Bit 7
|
||||
JMP SETBYN ;and Write to Register
|
||||
|
||||
;setspd(index,addr) - Set Sprite Address Register
|
||||
;Args: A = Index
|
||||
; Y,X = Address Register Value
|
||||
SETSPD: STA TEMP0 ;Save Sprite Index
|
||||
SETSTD: TYA ;Copy MSB to Accumulator
|
||||
AND #$0F ;Strip High Nybble
|
||||
TAY ;and Copy Back to Y
|
||||
JSR SAVRXY ;Copy Value to TEMP1,TEMP2
|
||||
LDA TEMP0 ;Restore Sprite Index
|
||||
JSR GETSP1 ;Read MSB Register
|
||||
AND #$F0 ;Strip Low Nybble
|
||||
ORA TEMP2 ;Combine with MSB
|
||||
STA TEMP2 ;and Save for Write
|
||||
LDA TEMP0 ;Restore Sprite Index
|
||||
JSR GETSP0 ;Get Sprite Attribute Address
|
||||
JMP SETREI ;Write TEMP1,TEMP2 to Attribute
|
||||
|
||||
;setspm(index) - Set Sprite Collision Mask
|
||||
;Args: A = Sprite Index
|
||||
; Y = Collision Mask
|
||||
SETSPM: PHA ;Save Sprite Depth
|
||||
LDX #$0F ;Set Bit Mask
|
||||
TYA ;Copy Mask to Accumulator
|
||||
ASL ;Shift Left Two Byte
|
||||
ASL
|
||||
JMP SETSP2 ;Then Two More and Write
|
||||
|
||||
;setspz(index,depth) - Set Sprite Z-Depth
|
||||
;Args: A = Sprite Index
|
||||
; Y = Z-Depth (0-3)
|
||||
SETSPZ: PHA ;Save Sprite Depth
|
||||
LDX #$F3 ;Set Bit Mask
|
||||
TYA ;Copy Z-Depth to Accumulator
|
||||
AND #$03 ;Isolate Bits 0 and 1
|
||||
SETSP2: ASL ;Move to Bits 2 and 3
|
||||
ASL
|
||||
STX TEMP1 ;Save Bit Mask
|
||||
BRA SETSP6 ;Set Bits in Control Register
|
||||
|
||||
;getspu(index) - Get Sprite Width, Height, and Mode
|
||||
;Args: A = Sprite Index
|
||||
;Sets: TEMP0 = Sprite Index
|
||||
;Returns: A = Width Specifier
|
||||
; Y = Height Specifier
|
||||
; X = Mode
|
||||
GETSPU: STA TEMP0 ;Save Sprite Index
|
||||
JSR GETSPW ;Get Sprite Width Specifier
|
||||
PHA ;and Save It
|
||||
LDA TEMP0 ;Retrieve Sprite Indes
|
||||
JSR GETSPH ;Get Sprite Height Specifier
|
||||
PHA ;and Save It
|
||||
LDA TEMP0 ;Retrieve Sprite Index
|
||||
JSR GETSPP ;Get Mode
|
||||
TAX ;Return Mode in X
|
||||
PLY ;Height in Y
|
||||
PLA ;and Width in A
|
||||
RTS
|
||||
|
||||
;getspl(index) - Get Sprite Data Size
|
||||
;Args: A = Sprite Index
|
||||
;Sets: TEMP0 = Sprite Index
|
||||
; TEMP1,TEMP2 = Data Size LSB,MSB
|
||||
;Affects: A
|
||||
;Returns: Y,X = Data Size in Bytes
|
||||
GETSPL: JSR GETSPU ;Get Width, Height, Mode and Execute GETSCL
|
||||
|
||||
;getscl(width,height,mode) - Calculate Sprite Data Size
|
||||
;Args: A = Width Specifier
|
||||
; Y = Height Specifier
|
||||
; X = Mode (Bits Per Pixel)
|
||||
;Sets: TEMP1,TEMP2 = Data Size LSB,MSB
|
||||
;Affects: A
|
||||
;Returns: Y,X = Data Size in Bytes
|
||||
GETSCL: ;.DC $FF ;Debug
|
||||
PHX ;Save Mode
|
||||
PHA ;Save Width
|
||||
TYA ;Copy Height to Accumulator
|
||||
JSR GETSCS ;Calculate Height in Pixles
|
||||
STA TEMP1 ;Save as LSB
|
||||
PLA ;Retrieve Width
|
||||
JSR GETSCS ;Get Width Shift Counter in Y
|
||||
LDA #0 ;Set MSB to 0
|
||||
GETSLK: ASL TEMP1 ;Multiply LSB
|
||||
ROL ;and MSB by 2
|
||||
DEY ;Decrement Counter
|
||||
BNE GETSLK ;and Loop if Not Zero
|
||||
PLX ;Retrieve Mode
|
||||
BNE GETSSK ;If 0 (4 Bits Per Pixel)
|
||||
LSR ; Divide MSB
|
||||
ROR TEMP1 ; snd LSB by 2
|
||||
GETSSK: STA TEMP2 ;Save MSB in TEMP2
|
||||
JMP RESRXY ;Return LSB snd MSB in X and Y
|
||||
|
||||
;getscs(size) - Calculate Sprite Size in Pixels
|
||||
;Args: A = Height/Width Specifier
|
||||
;Returns: A = Size in Pixels
|
||||
; Y = Width Multiplier Shift Count
|
||||
; X = Height/Width Specifier
|
||||
GETSCS: AND #$03 ;Strip High Bits
|
||||
TAX ;Copy Specifier to X
|
||||
LDA GETSCT,X ;Load Size in Pixels from Table
|
||||
LDY GETSCY,X ;Load Shift Count from Table
|
||||
RTS
|
||||
GETSCT: .DC 8,16,32,64 ;Table: Size in Pixels
|
||||
GETSCY: .DC 3, 4, 5, 6 ;Table: Shift Multiplier
|
||||
|
||||
;setspv(index) - Set Sprite Vertical Flip
|
||||
;Args: A = Sprite Index
|
||||
; Y = Vertical Flip Flag
|
||||
SETSPV: LDX #$02 ;Set Bit Pattern for Register
|
||||
.DC $2C ;Skip Next Instruction (Bit Absolute)
|
||||
|
||||
;setspf(index) - Set Sprite Horizontal Flip
|
||||
;Args: A = Sprite Index
|
||||
; Y = Horizontal Flip Flag
|
||||
SETSPF: LDX #$01 ;Set Bit Pattern for Register
|
||||
PHA ;Save Sprite Index
|
||||
TXA ;Copy Bit Pattern to Accumulator
|
||||
EOR #$FF ;Convert to Bit Mask
|
||||
STA TEMP1 ;and Save It
|
||||
TYA ;Copy Flag to Accumulator
|
||||
BEQ SETSP6 ;If Not Zero
|
||||
TXA ;Change to %00000001
|
||||
SETSP6: STA TEMP0 ;and Store It
|
||||
PLA ;Retrieve Sprite Index
|
||||
JSR GETSPN ;Get Sprite Control Register
|
||||
SETSP8: AND TEMP1 ;Apply Mask
|
||||
ORA TEMP0 ;Set Bit(s)
|
||||
JMP SETBYN ;and Write Back to Register
|
||||
|
||||
;setspn(index,value) - Set Sprite Attribute Control Register
|
||||
;Args: A = Sprite Index
|
||||
; Y = Value to Write
|
||||
;Returns: A = Mode (0=4bpp, 1=8bpp)
|
||||
SETSPN: STY TEMP0 ;Save Value to Write
|
||||
LDY #6 ;Set Offset to Control Register
|
||||
BNE SETSTG ;and Write Value to Register
|
||||
|
||||
;setspg(index,offset,value) - Set Sprite Attribute Register
|
||||
;Args: A = Sprite Index
|
||||
; Y = Register Offset
|
||||
; X = Value to Write
|
||||
;Returns: A = Mode (0=4bpp, 1=8bpp)
|
||||
SETSPG: STX TEMP0 ;Save Value to Write
|
||||
SETSTG: JSR GETSPO ;Get Attribute Address for Sprite A Register Y
|
||||
JMP SETREH ;Write TEMP0 to Register
|
||||
|
||||
;setspw(index) - Set Sprite Width Specifier
|
||||
;Args: A = Sprite Index
|
||||
; Y = Sprite Width Specifier
|
||||
SETSPW: PHA ;Save Sprite Index
|
||||
LDX #$CF ;Set Bit Mask
|
||||
TYA ;Copy Specifier to Accumulator
|
||||
AND #$03 ;Isolate Bits 0 and 1
|
||||
BRA SETSP4 ;Shift Left Four Bits and Write Masked
|
||||
|
||||
;setsph(index) - Set Sprite Height Specifier
|
||||
;Args: A = Sprite Index
|
||||
; Y = Sprite Height Specifier
|
||||
SETSPH: PHA ;Save Sprite Index
|
||||
LDX #$3F ;Set Bit Mask
|
||||
TYA ;Copy Specifier to Accumulator
|
||||
ASL ;Shift Left Six Bits
|
||||
ASL
|
||||
SETSP4: ASL
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
BRA SETSP7 ;Write Masked to Size Register
|
||||
|
||||
;setspp(index) - Set Sprite Palette Offset
|
||||
;Args: A = Sprite Index
|
||||
; Y = Palette Offset
|
||||
SETSPP: PHA ;Save Sprite Index
|
||||
LDX #$F0 ;Set Bit Mask
|
||||
TYA ;Copy Offset to Accumulator
|
||||
AND #$0F ;Isolate Low Nybble
|
||||
SETSP7: STA TEMP0 ;Save Value
|
||||
STX TEMP1 ;Save Bit Mask
|
||||
PLA ;Retrieve Sprite Index
|
||||
JSR GETSPS ;Get Sprite Size Register
|
||||
BRA SETSP8 ;Apply Mask, Set Bits, and Write
|
||||
|
||||
;setsps(index,value) - Set Sprite Attribute Size Register
|
||||
;Args: A = Sprite Index
|
||||
; Y = Value to Write
|
||||
;Returns: A = Mode (0=4bpp, 1=8bpp)
|
||||
SETSPS: STY TEMP0 ;Save Value to Write
|
||||
LDY #7 ;Set Offset to Size Register
|
||||
BNE SETSTG ;and Write Value to Register
|
||||
|
||||
;setspe() - Enable/Disable Sprites
|
||||
;Args: A = Sprites Enabled Flag
|
||||
; 0 for Disabled, Any Other Value for Enabled
|
||||
;Affects: A,X,Y
|
||||
SETSPE: ORA #0 ;If Accumulator
|
||||
BEQ SETSKE ;is Not Zero
|
||||
LDA ##01 ;Set to %00000001
|
||||
SETSKE: LDY #$FE ;Set Mask to %11111110
|
||||
STY TEMP0
|
||||
LDX #$00 ;Set Offset to Sprite Control
|
||||
LDY #$40 ;Set Page to Sprite Registers
|
||||
JMP SETVRB ;Get Register Bit
|
||||
|
||||
;setspo(index,offset) - Set Sprite Attributes Address
|
||||
;Args: A = Sprite Index
|
||||
; Y = Attribute Offset
|
||||
SETSP0: LDY #0 ;Set Offset to 0
|
||||
SETSPO: JSR GETSPO ;Get Sprite Attributes Address
|
||||
JSR REGADR ;Set as Vera Register Address
|
||||
LDA #8 ;Set Size to 8 Bytes
|
||||
RTS
|
||||
|
||||
;setspr(index,&sprite) - Set Sprite Attributes
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Address of Source Structure
|
||||
;Destroys: TEMP0
|
||||
;Returns: A,Y = Number of Bytes Written
|
||||
; X = Current Data Port
|
||||
SETSPR: JSR SETSRC ;Set Destination Address
|
||||
JSR SETSP0 ;Set Sprite Attributes Address
|
||||
JMP SETMET ;and Write from Vera
|
||||
|
||||
;setspy(index,coord) - Set Sprite Y-Coordinate
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = Y-Coordinate
|
||||
SETSPY: JSR SAVRXY ;Store Value in TEMP1,TEMP2
|
||||
LDY #4 ;Set Register Offset to Y-Coordinate
|
||||
BNE SETSPI ;Write TEMP1,TEMP2 to Registers
|
||||
|
||||
;setspx(index,coord) - Set Sprite X-Coordinate
|
||||
;Args: A = Sprite Index
|
||||
; Y,X = X-Coordinate
|
||||
SETSPX: JSR SAVRXY ;Store Value in TEMP1,TEMP2
|
||||
LDY #2 ;Set Register Offset to X-Coordinate
|
||||
|
||||
;setspi(index) - Write to Sprite Attribute Register Pair
|
||||
;Args: A = Sprite Index
|
||||
; Y = Attribute Offset
|
||||
;Uses: TEMP1.TEMP2 = Integer to Write
|
||||
SETSPI: JSR GETSPO ;Get Sprite Attribute Address
|
||||
JMP SETREI ;Write TEMP1,TEMP2 to Attribute
|
||||
|
272
x16/include/veraspr.h02
Normal file
272
x16/include/veraspr.h02
Normal file
@ -0,0 +1,272 @@
|
||||
/**********************************************
|
||||
* veraspr.h02 - Sprite Manipulation Routines *
|
||||
* for Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
**********************************************/
|
||||
|
||||
#define MAXSPR 128 //Maximum Sprite Index;
|
||||
|
||||
/* Sprite Attributes */
|
||||
struct sprite {
|
||||
int addr; //Data Address
|
||||
int horz; //Horizontal Coordinate
|
||||
int vert; //Vertical Coordinate
|
||||
char ctrl; //Control Register
|
||||
char size; //Size Register
|
||||
};
|
||||
|
||||
/* Sprite Control Registers */
|
||||
struct spregs {
|
||||
char ctrl; //Control Register
|
||||
char clsn; //Collision Mask
|
||||
};
|
||||
|
||||
/* Add to Sprite Address Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* int w - Integer to Add */
|
||||
char addspd();
|
||||
|
||||
/* Clear Sprite Attributes *
|
||||
* Args: char n - Sprite Index */
|
||||
char clrspr();
|
||||
|
||||
/* Get Vera Address from Sprite Address *
|
||||
* Args: int d - Sprite Address *
|
||||
* Returns: char bank - Address Bits 16-19 *
|
||||
* int addr - Address Bits 0-15 */
|
||||
char getsca();
|
||||
|
||||
/* Calculate Sprite Data Size *
|
||||
* Args: char w - Width Specifier *
|
||||
* char h - Height Specifier *
|
||||
* char m - Mode (Bits per Pixel) *
|
||||
* Returns: int s - Data Size in Bytes */
|
||||
char getscl();
|
||||
|
||||
/* Calculate Sprite Size in Pixels *
|
||||
* Args: char s - Height/Width Specifier *
|
||||
* Returns: char p - Height/Width in Pixels *
|
||||
* char m - Multiplier Shift Count */
|
||||
char getscs();
|
||||
|
||||
/* Get Sprite Data Address *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char bank - Address Bits 16-19 *
|
||||
* int addr - Address Bits 0-15 */
|
||||
char getspa();
|
||||
|
||||
/* Get Sprite Bits per Pixel *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char m - Sprite Mode *
|
||||
* 0=4bpp, 1=8bpp */
|
||||
char getspb();
|
||||
|
||||
/* Read Sprite Collision Status *
|
||||
* Returns: char c - Collision Status */
|
||||
char getspc();
|
||||
|
||||
/* Get Sprite Address Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: int w - Address Register Contents */
|
||||
char getspd();
|
||||
|
||||
/* Read Sprite Enabled Status *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char e - Enabled (TRUE/FALSE) */
|
||||
char getspe();
|
||||
|
||||
/* Get Sprite Horizontal Flip Flag *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char f - Flipped (TRUE/FALSE) */
|
||||
char getspf();
|
||||
|
||||
/* Get Sprite Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* char o - Register Offset *
|
||||
* Returns: char r - Register Contents */
|
||||
char getspg();
|
||||
|
||||
/* Get Sprite Height Specifier *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char h - Height Specifier */
|
||||
char getsph();
|
||||
|
||||
/* Read Sprite Attribute Pair *
|
||||
* Args: char n - Sprite Index *
|
||||
* char 0 - Attribute Offset *
|
||||
* Returns: int i - Attribute LSB,MSB */
|
||||
char getspi();
|
||||
|
||||
/* Get Sprite Data Size *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: int s - Data Size in Bytes */
|
||||
char getspl();
|
||||
|
||||
/* Get Sprite Collision Mask *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char m - Collision Mask */
|
||||
char getspm();
|
||||
|
||||
/* Get Sprite Control Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char r - Register Contents */
|
||||
char getspn();
|
||||
|
||||
/* Get Sprite Attribute Address *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: int d - Address */
|
||||
char getspo();
|
||||
|
||||
/* Get Sprite Palette Offset *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char p - Palette Offset */
|
||||
char getspp();
|
||||
|
||||
/* Get Sprite Attributes *
|
||||
* Args: char n - Sprite Index *
|
||||
* int d - Struct Address *
|
||||
* Returns: char b - Number of Bytes */
|
||||
char getspr();
|
||||
|
||||
/* Get Sprite Size Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char r - Register Contents */
|
||||
char getsps();
|
||||
|
||||
/* Test Sprite Collision Status *
|
||||
* Args: char b - Collision Bitmask *
|
||||
* Returns: char c - Collision Status */
|
||||
char getspt();
|
||||
|
||||
/* Get Sprite Width, Height, and Mode *
|
||||
* Args: char n = Sprite Index *
|
||||
* Returns: char w - Width Specifier *
|
||||
* char h - Height Specifier *
|
||||
* char m - Mode (Bits per Pixel) */
|
||||
char getspu();
|
||||
|
||||
/* Get Sprite Vertical Flip Flag *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char f - Flipped (TRUE/FALSE) */
|
||||
char getspv();
|
||||
|
||||
/* Get Sprite Width Specifier *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char w - Width Specifier */
|
||||
char getspw();
|
||||
|
||||
/* Get Sprite X-Coordinate *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: int i - X-Coordinate */
|
||||
char getspx();
|
||||
|
||||
/* Get Sprite Y-Coordinate *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: int i - Y-Coordinate */
|
||||
char getspy();
|
||||
|
||||
/* Get Sprite Z-Depth *
|
||||
* Args: char n - Sprite Index *
|
||||
* Returns: char z - Z-Depth */
|
||||
char getspz();
|
||||
|
||||
/* Set Sprite Bits per Pixel *
|
||||
* Args: char n - Sprite Index *
|
||||
* char m - Sprite Mode *
|
||||
* 0=4bpp, 1=8bpp */
|
||||
char setspb();
|
||||
|
||||
/* Set Sprite Address Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* int w - Address Value */
|
||||
char setspd();
|
||||
|
||||
/* Set Sprite Enabled Status *
|
||||
* Args: char e - Enabled (TRUE/FALSE) */
|
||||
char setspe();
|
||||
|
||||
/* Set Sprite Horizontal Flip Flag *
|
||||
* Args: char n - Sprite Index *
|
||||
* char f - Flipped (TRUE/FALSE) */
|
||||
char setspf();
|
||||
|
||||
/* Set Sprite Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* char o - Register Offset *
|
||||
* char b - Value to Write */
|
||||
char setspg();
|
||||
|
||||
/* Set Sprite Height Specifier *
|
||||
* Args: char n - Sprite Index *
|
||||
* char w - Height Specifier */
|
||||
char setsph();
|
||||
|
||||
/* Write Sprite Attribute Pair *
|
||||
* Args: char n - Sprite Index *
|
||||
* char 0 - Attribute Offset *
|
||||
* Requires: setrxy(integer) */
|
||||
char setspi();
|
||||
|
||||
/* Set Sprite Collision Mask *
|
||||
* Args: char n - Sprite Index *
|
||||
* char m - Collision Mask */
|
||||
char setspm();
|
||||
|
||||
/* Set Sprite Control Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* char r - Register Contents */
|
||||
char setspn();
|
||||
|
||||
/* Set Sprite Attribute Address *
|
||||
* Args: char n - Sprite Index *
|
||||
* char o - Register Offset */
|
||||
char setspo();
|
||||
|
||||
/* Set Sprite Palette Offset *
|
||||
* Args: char n - Sprite Index *
|
||||
* char p - Palette Offset */
|
||||
char setspp();
|
||||
|
||||
/* Set Sprite Attributes *
|
||||
* Args: char n - Sprite Index *
|
||||
* int d - Struct Address *
|
||||
* Returns: char b - Number of Bytes */
|
||||
char setspr();
|
||||
|
||||
/* Aet Sprite Size Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* char r - Register Contents */
|
||||
char setsps();
|
||||
|
||||
/* Set Sprite Vertical Flip Flag *
|
||||
* Args: char n - Sprite Index *
|
||||
* char f - Flipped (TRUE/FALSE) */
|
||||
char setspv();
|
||||
|
||||
/* Set Sprite Width Specifier *
|
||||
* Args: char n - Sprite Index *
|
||||
* char w - Width Specifier */
|
||||
char setspw();
|
||||
|
||||
/* Set Sprite X-Coordinate *
|
||||
* Args: char n - Sprite Index *
|
||||
* int i - X-Coordinate */
|
||||
char setspx();
|
||||
|
||||
/* Set Sprite Y-Coordinate *
|
||||
* Args: char n - Sprite Index *
|
||||
* int i - Y-Coordinate */
|
||||
char setspy();
|
||||
|
||||
/* Set Sprite Z-Depth *
|
||||
* Args: char n - Sprite Index *
|
||||
* char z - Z-Depth */
|
||||
char setspz();
|
||||
|
||||
/* Subtract from Sprite Address Register *
|
||||
* Args: char n - Sprite Index *
|
||||
* int w - Integer to Subtract */
|
||||
char subspd();
|
||||
|
23
x16/include/veratil.a02
Normal file
23
x16/include/veratil.a02
Normal file
@ -0,0 +1,23 @@
|
||||
; Vera Tile Manipulation Assembly Language Routines for C02
|
||||
; Requires External Routines
|
||||
; and External Variables TEMP1
|
||||
|
||||
;gettda() - Get Tile Data Address
|
||||
;Args: A = Layer (0/1)
|
||||
;
|
||||
;Destroys: TEMP1,TEMP2
|
||||
;Returns: A = Tile Base Bank
|
||||
; Y,X = Tile Base Address
|
||||
GETTBA: JSR SET
|
||||
|
||||
;gettdo() - Get Tile Data Offset
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Tile Offset
|
||||
;Destroys: TEMP1,TEMP2
|
||||
;Returns: A = Tile Base Bank
|
||||
; Y,X = Tile Base Address
|
||||
GETTBA: STA TEMP0 ;Save Layer Number
|
||||
STY TEMP1 ;Set LSB to Offset
|
||||
JSR GETTSZ ;Get Tile Size
|
||||
|
||||
|
9
x16/include/veratil.h02
Normal file
9
x16/include/veratil.h02
Normal file
@ -0,0 +1,9 @@
|
||||
/*********************************************
|
||||
* veratil.h02 - Tile Manipulation Functions *
|
||||
* for Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
* veralyr.h02 *
|
||||
*********************************************/
|
||||
|
67
x16/include/veratxt.a02
Normal file
67
x16/include/veratxt.a02
Normal file
@ -0,0 +1,67 @@
|
||||
; Vera Layer Control Assembly Language Routines for C02
|
||||
; Requires External Routines GETMEA, GETMBX, GETTBS,
|
||||
; and External Variables TEMP0,TEMP1,TEMP2
|
||||
|
||||
;getvca(layer, index) - Get Vera Character Address
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Character Index
|
||||
;Sets: TEMP0 = Bank
|
||||
; TEMP1 = Address LSB
|
||||
; TEMP2 = Address MSB
|
||||
;Returns: A = Bank
|
||||
; Y = Address LSB
|
||||
; X = Address MSB
|
||||
GETVCA: PHA ;Save Layer Number
|
||||
STY 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
|
||||
PLA ;Restore Layer Number
|
||||
JSR GETTBS ;Get Tile Base
|
||||
TXA ;Add Tile Base LSB
|
||||
CLC
|
||||
ADC TEMP1 ;to Offset LSB
|
||||
STA TEMP1
|
||||
TYA ;Add Tile Base MSB
|
||||
ADC TEMP2 ;to Offset MSB
|
||||
STA TEMP2
|
||||
LDA #0 ;Set Bank
|
||||
ADC #0 ;to Carry
|
||||
STA TEMP0
|
||||
LDX #2 ;Set Count to 2
|
||||
JMP ASLADR ;and Shift Address Left
|
||||
|
||||
;getvcd(layer, index) - Read Vera Character Data to Array
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Character Index
|
||||
;Uses: DSTLO,DSTHI = Address of Array
|
||||
;Destroys: TEMP0,TEMP1,TEMP2
|
||||
;Returns: A = Number of Bytes Read
|
||||
GETVCD: JSR SETVAC ;Set Vera Address to Character Address
|
||||
LDA #8 ;Set Byte Count to 8
|
||||
JMP GETMEA ;and Read Bytes into Array
|
||||
|
||||
;setvac(layer, index) - Set Vera Address to Character Address
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Character Index
|
||||
;Sets: TEMP0 = Bank
|
||||
; TEMP1 = Address LSB
|
||||
; TEMP2 = Address MSB
|
||||
;Returns: A = Bank + Auto-Increment
|
||||
; Y = Address LSB
|
||||
; X = Address MSB
|
||||
SETVAC: JSR GETVCA
|
||||
ORA #$10 ;Set Auto-Increment to 1
|
||||
JMP SETADR ;and Set Vera Address
|
||||
|
||||
;setvcd(layer, index) - Write Vera Character Data from Array
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Character Index
|
||||
;Uses: SRCLO,SRCHI = Address of Array
|
||||
;Destroys: TEMP0,TEMP1,TEMP2
|
||||
;Returns: A = Number of Bytes Read
|
||||
GETVCD: JSR SETVAC ;Set Vera Address to Character Address
|
||||
LDA #8 ;Set Byte Count to 8
|
||||
JMP SETMEA ;and Read Bytes into Array
|
||||
|
16
x16/include/veratxt.h02
Normal file
16
x16/include/veratxt.h02
Normal file
@ -0,0 +1,16 @@
|
||||
/*****************************************
|
||||
* veratxt.h02 - Text Mode Functions for *
|
||||
* Commander X16 VERA Chip *
|
||||
* Requires: x16.h02 *
|
||||
* stddef.h02 *
|
||||
* veramem.h02 *
|
||||
* veralyr.h02 *
|
||||
*****************************************/
|
||||
|
||||
;getvcd(lyr) - Get Vera Character Data
|
||||
;Args: A = Layer (0/1)
|
||||
; Y = Bitmap Palette Offset
|
||||
;Affects: Y
|
||||
;Sets: TEMP3 = Register Offset
|
||||
;Returns: A = Control Register Contents
|
||||
; X = Current Data Port
|
75
x16/sprattrs.c02
Normal file
75
x16/sprattrs.c02
Normal file
@ -0,0 +1,75 @@
|
||||
/************************************
|
||||
* TESTVERA - Test All Vera Modules *
|
||||
************************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <string.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veraspr.h02" //Vera Sprites
|
||||
|
||||
char i; //Index Variable
|
||||
|
||||
char aa,xx,yy; //Functions Parameters/Variables
|
||||
char ii,oo,ss[128];
|
||||
int yx;
|
||||
|
||||
void prthdr() {
|
||||
putln("SPR ADDRESS MODE XPOS YPOS MASK Z VFLIP HFLIP HGHT WDTH POF");
|
||||
}
|
||||
|
||||
void prtpos(yx) {
|
||||
setdst(&ss); aa = itoa(yx);
|
||||
for (ii=strlen(&ss); ii<4; ii++) putspc();
|
||||
puts(&ss); putspc();
|
||||
}
|
||||
|
||||
void prtflg(aa) {
|
||||
if (aa) puts("TRUE ");
|
||||
else puts("FALSE ");
|
||||
}
|
||||
|
||||
void prtsiz() {
|
||||
select(A) {
|
||||
case 0: puts(" 8");
|
||||
case 1: puts("16");
|
||||
case 2: puts("32");
|
||||
case 3: puts("64");
|
||||
default: puts("??");
|
||||
}
|
||||
puts("PX ");
|
||||
}
|
||||
|
||||
void prtofs(aa) {
|
||||
if (aa) {aa<<;aa<<;aa<<;aa<<;}
|
||||
printf(aa,"%r ");
|
||||
}
|
||||
|
||||
main:
|
||||
newlin();
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
if (!i&31) prthdr();
|
||||
printf(i,"%r ");
|
||||
printf(setdst(getspa(i))," $%g%w ");
|
||||
if (getspb(i)) puts("8BPP "); else puts("4BPP ");
|
||||
prtpos(getspx(i));
|
||||
prtpos(getspy(i));
|
||||
putmsk(getspm(i),$0F); putspc();
|
||||
putdec(getspz(i)); putspc();
|
||||
prtflg(getspf(i));
|
||||
prtflg(getspv(i));
|
||||
prtsiz(getsph(i));
|
||||
prtsiz(getspw(i));
|
||||
prtofs(getspp(i));
|
||||
newlin();
|
||||
if (i&31==31 and anykey() == #ESCKEY) goto exit;
|
||||
}
|
||||
newlin();
|
||||
goto exit;
|
||||
|
77
x16/sprdemo.c02
Normal file
77
x16/sprdemo.c02
Normal file
@ -0,0 +1,77 @@
|
||||
/*********************************
|
||||
* SPRDEMO - Vera Sprite Demo *
|
||||
*********************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veraspr.h02" //Vera Sprites
|
||||
|
||||
char spindx; //Sprite Index
|
||||
int spaddr; //Sprite Address
|
||||
char spxlo,spxhi; //Sprite X-Coordinate
|
||||
char spylo,spyhi; //Sprite Y-Coordinate
|
||||
|
||||
struct spregs spctrl; //Sprite Control Registers
|
||||
struct sprite spattr; //Sprite Attributes
|
||||
|
||||
const char happy =
|
||||
{0,0,7,7,7,7,0,0,
|
||||
0,7,7,7,7,7,7,0,
|
||||
7,7,0,7,7,0,7,7,
|
||||
7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,
|
||||
7,0,7,7,7,7,0,7,
|
||||
0,7,0,0,0,0,7,7,
|
||||
0,0,7,7,7,7,0,0};
|
||||
|
||||
|
||||
/*Print Sprite Control Registers*/
|
||||
void prtspk() {
|
||||
printf(spctrl.ctrl, "CTRL=%b, ");
|
||||
printf(spctrl.clsn, "CLSN=%b%n");
|
||||
}
|
||||
|
||||
/*Print Sprite Attributes */
|
||||
void prtspr() {
|
||||
printf(setdst(spattr.addr),"ADR=$%w, ");
|
||||
printf(setdst(spattr.horz),"HRZ=%i, ");
|
||||
printf(setdst(spattr.vert),"VRT=%i, ");
|
||||
printf(spattr.ctrl,"CTL=$%h, ");
|
||||
printf(spattr.size,"SIZ=$%h%n");
|
||||
}
|
||||
|
||||
main:
|
||||
|
||||
spxlo=0; spxhi=0; spylo=0; spyhi=0;
|
||||
for (spindx=0; spindx<#MAXSPR; spindx++) {
|
||||
spaddr=&$800;
|
||||
setspa(spaddr); //Set Vera Address to Sprite Address
|
||||
setmem(@happy,&happy); //Write Sprite Data to Vera
|
||||
setspd(spindx,spaddr); //Set Sprite Address
|
||||
setspb(spindx,1); //Set Mode to 8 Bits per Pixel
|
||||
setspx(spindx,spxhi,spxlo); //Set Sprite X-Coordinate
|
||||
setspy(spindx,spyhi,spylo); //Set Sprite Y-Coordinate
|
||||
setspz(spindx,3); //Display in Front of Layer 1
|
||||
setspe(#TRUE); //Enable Sprites
|
||||
|
||||
spxlo=spxlo+16; if (!spxlo) spylo=spylo+16;
|
||||
|
||||
}
|
||||
|
||||
getspk(&spctrl); //Read Sprite Control Registers
|
||||
puts("SPRITES: ");
|
||||
prtspk(); //Print Sprite Control Registers
|
||||
|
||||
getspr(spindx,&spattr); //Read Sprite Attributes
|
||||
printf(spindx,"SPRITE %d ");
|
||||
prtspr(); //Print Sprite Attributes
|
||||
|
||||
goto exit;
|
||||
|
42
x16/sprsizes.c02
Normal file
42
x16/sprsizes.c02
Normal file
@ -0,0 +1,42 @@
|
||||
/*********************************
|
||||
* SPRSIZES - Print Sprite Sizes *
|
||||
*********************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veraspr.h02" //Vera Sprites
|
||||
|
||||
char aa,yy,xx;
|
||||
char height, width, mode;
|
||||
int size;
|
||||
|
||||
void padint(aa,yy,xx) {
|
||||
if (xx&96) putc(aa);
|
||||
if (yy < 4) putc(aa);
|
||||
}
|
||||
|
||||
main:
|
||||
newlin();
|
||||
|
||||
for (mode=0; mode<2; mode++) {
|
||||
printf(getspq(mode),"%n\18%dBPP");
|
||||
for (width=0;width<4; width++) printf(getspj(width)," %r");
|
||||
for (height=0; height<4; height++) {
|
||||
printf(getspj(height),"%n\$12 %r\$92"); putchr(146); putspc();
|
||||
for (width=0; width<4; width++) {
|
||||
size = getspk(width, height, mode);
|
||||
padint(' ',size); putint(size); putspc();
|
||||
}
|
||||
}
|
||||
newlin();
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
117
x16/testspr.c02
Normal file
117
x16/testspr.c02
Normal file
@ -0,0 +1,117 @@
|
||||
/************************************
|
||||
* TESTVERA - Test All Vera Modules *
|
||||
************************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veraspr.h02" //Vera Sprites
|
||||
|
||||
const char abcdef = {1,2,3,4,5,6};
|
||||
char buffer[255]; //Buffer for getmem
|
||||
|
||||
char d,e,f,i,j,k; //Index Variables
|
||||
char b,h,l,m,n,p,w; //Temporary Variables
|
||||
char bank,msb,lsb; //Vera Memory Address
|
||||
int addr; //16-bit Address
|
||||
int bytes,size; //Integer Size Values
|
||||
int height,width; //Integer Height and Width Value
|
||||
|
||||
char spenbl; //Sprite Enabled
|
||||
char spmode; //Sprite Mode (Bits Per Pixel)
|
||||
int spaddr; //Sprite Attributes/Data Address
|
||||
int spsize; //Sprite Data Size
|
||||
struct sprite spattr; //Sprite Attributes (Read)
|
||||
struct sprite spattw; //Sprite Attributes (Write)
|
||||
|
||||
char aa,xx,yy; //Functions Parameters/Variables
|
||||
|
||||
void failed() {
|
||||
putln(" FAILED");
|
||||
}
|
||||
|
||||
void passed() {
|
||||
putln(" PASSED");
|
||||
//newlin();
|
||||
}
|
||||
|
||||
void padint(aa,yy,xx) {
|
||||
if (xx&96) putc(aa);
|
||||
if (yy < 4) putc(aa);
|
||||
}
|
||||
|
||||
void prtadr(aa,yy,xx) {
|
||||
putc('$'); prhex(aa); prbyte(yy); prbyte(xx);
|
||||
}
|
||||
|
||||
void prtflg(aa,yy,xx) {
|
||||
if (aa) setdst("TRUE"); else setdst("FALSE");
|
||||
printf(aa,yy,xx);
|
||||
}
|
||||
|
||||
void prtreg(aa,yy,xx) {
|
||||
printf(aa,"(%d,"); printf(yy,"%d,"); printf(xx,"%d) ");
|
||||
}
|
||||
|
||||
/*Print Sprite Attributes */
|
||||
void prtspr() {
|
||||
printf(setdst(spattr.addr),"ADR=$%w, ");
|
||||
printf(setdst(spattr.horz),"HRZ=%i, ");
|
||||
printf(setdst(spattr.vert),"VRT=%i, ");
|
||||
printf(spattr.ctrl,"CTL=$%h, ");
|
||||
printf(spattr.size,"SIZ=$%h%n");
|
||||
}
|
||||
|
||||
void xerror() {
|
||||
putln(" ERROR ENCOUNTERED");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
main:
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
printf("TESTING GETSPL() AND GETSPU()");
|
||||
n = 0; //Sprite Index
|
||||
h = 8; height = &8; //Sprite Height in Pixels
|
||||
for (i=0; i<4; i++) {
|
||||
setsph(n,i); //Set Sprite Height Specifier
|
||||
w = 8; //Sprite Width in Pixels
|
||||
size = height; size<<; size<<; //Set Size to Height*4
|
||||
for (j=0; j<4; j++) {
|
||||
setspw(n,j); //Set Sprite Width Specifier
|
||||
p = 4; //Bits Per Pixeg
|
||||
bytes = size;
|
||||
printf(h,"%nHEIGHT=%d "); if (!i) putspc();
|
||||
printf(w,"WIDTH=%d "); if (!j) putspc();
|
||||
for (k=0; k<2; k++) {
|
||||
setspp(n,k);
|
||||
printf(p,"%dBPP ");
|
||||
d,e,f = getspu(n); prtreg();
|
||||
if (d<>j or e<>i or f<>k) xerror();
|
||||
spsize = getspl(n); //Get Sprite Data Size
|
||||
setdst(spsize); printf("SIZE=%i "); padint(' ',spsize);
|
||||
setdst(bytes); printf("[%i] "); padint(' ',bytes);
|
||||
if (<spsize <> <bytes or >spsize <> >bytes) xerror();
|
||||
p<<; bytes<<; //Multiply BPP, Size by 2
|
||||
}
|
||||
w<<; size<<; //Multiply Width, Size by 2
|
||||
}
|
||||
h<<; height<<; //Multiply Height by 2
|
||||
n++; //Increment Sprite Index
|
||||
newlin();
|
||||
}
|
||||
passed();
|
||||
|
||||
|
||||
newlin();
|
||||
|
||||
goto exit;
|
||||
|
680
x16/testvera.c02
Normal file
680
x16/testvera.c02
Normal file
@ -0,0 +1,680 @@
|
||||
/************************************
|
||||
* TESTVERA - Test All Vera Modules *
|
||||
************************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veradsp.h02" //Vera Display Controller
|
||||
#include "include/veraclr.h02" //Vera Color Palette
|
||||
#include "include/veralyr.h02" //Vera Layer Control
|
||||
#include "include/veraspr.h02" //Vera Sprites
|
||||
#include "include/vera.h02"
|
||||
|
||||
const char abcdef = {1,2,3,4,5,6};
|
||||
char buffer[255]; //Buffer for getmem
|
||||
|
||||
char d,e,f,i,j,k; //Index Variables
|
||||
char b,h,l,m,n,p,w; //Temporary Variables
|
||||
char bank,msb,lsb; //Vera Memory Address
|
||||
int addr,bytes,size; //16-bit Address and Sizes
|
||||
int height,width; //16-bit Height and Width Value
|
||||
|
||||
char hscale,vscale; //Video Scaling
|
||||
char hrzvrt[5]; //Horizontal and Vertical Register Contents
|
||||
char index; //Color Palette Index
|
||||
char mode,mono,field; //Video Output Mode, Monochrome Flag, Current Field
|
||||
char red,green,blue; //Color Components
|
||||
char enabld; //Layer Enabled
|
||||
|
||||
int color,colour;
|
||||
int hstart,hstop; //Horizontal Start and Stop
|
||||
int vstart,vstop; //Vertical Start and Stop
|
||||
int irqlin; //IRQ Line#
|
||||
|
||||
char spenbl; //Sprite Enabled
|
||||
char spmode; //Sprite Mode (Bits Per Pixel)
|
||||
int spaddr; //Sprite Attributes Address
|
||||
int spsize; //Sprite Data Size
|
||||
struct sprite spattr; //Sprite Attributes (Read)
|
||||
struct sprite spattw; //Sprite Attributes (Write)
|
||||
|
||||
/* Layer 0/1 */
|
||||
|
||||
const char msizel = {32,64,128,0};
|
||||
const char msizeh = { 0, 0, 0,1};
|
||||
const char tsizel = {8,16};
|
||||
|
||||
char layer; //Layer Number
|
||||
char layer0[9]; //Layer 0 Register Contents
|
||||
char layer1[9]; //Layer 1 Register Contents
|
||||
char tsize; //Tile Size in Pixels
|
||||
int msize; //Map Size in Pixeks
|
||||
int mbase0,mbase1; //Map Base, Layer 0 and 1
|
||||
int tbase0,tbase1; //Tile Base, Layer 0 and 1
|
||||
int mbaddr,tbaddr; //Map and Tile Base Address
|
||||
int hscrl0,hscrl1; //Horizontal Scroll, Layer 0 and 1
|
||||
int vscrl0,vscrl1; //Vertical Scroll, Layer 0 and 1
|
||||
|
||||
|
||||
char aa,xx,yy; //Functions Parameters/Variables
|
||||
|
||||
void failed() {
|
||||
putln(" FAILED");
|
||||
}
|
||||
|
||||
void passed() {
|
||||
putln(" PASSED");
|
||||
//newlin();
|
||||
}
|
||||
|
||||
void padint(aa,yy,xx) {
|
||||
if (xx&96) putc(aa);
|
||||
if (yy < 4) putc(aa);
|
||||
}
|
||||
|
||||
void prtadr(aa,yy,xx) {
|
||||
putc('$'); prhex(aa); prbyte(yy); prbyte(xx);
|
||||
}
|
||||
|
||||
void prtflg(aa,yy,xx) {
|
||||
if (aa) setdst("TRUE"); else setdst("FALSE");
|
||||
printf(aa,yy,xx);
|
||||
}
|
||||
|
||||
void prtreg(aa,yy,xx) {
|
||||
printf(aa,"(%d,"); printf(yy,"%d,"); printf(xx,"%d) ");
|
||||
}
|
||||
|
||||
void prtrgb(aa,yy,xx) {
|
||||
prbyte(aa); putchr(',');
|
||||
prbyte(yy); putchr(',');
|
||||
prbyte(xx); putspc();
|
||||
}
|
||||
|
||||
void prtscl() {
|
||||
printf(hscale, "HSCALE=%h, ");
|
||||
printf(vscale, "VSCALE=%h%n");
|
||||
}
|
||||
|
||||
/*Print Sprite Attributes */
|
||||
void prtspr() {
|
||||
printf(setdst(spattr.addr),"ADR=$%w, ");
|
||||
printf(setdst(spattr.horz),"HRZ=%i, ");
|
||||
printf(setdst(spattr.vert),"VRT=%i, ");
|
||||
printf(spattr.ctrl,"CTL=$%h, ");
|
||||
printf(spattr.size,"SIZ=$%h%n");
|
||||
}
|
||||
|
||||
void prttmp() {
|
||||
printf(temp0, "TEMP0=$%h%n");
|
||||
printf(temp1, "TEMP1=$%h%n");
|
||||
printf(temp2, "TEMP2=$%h%n");
|
||||
printf(temp3, "TEMP3=$%h%n");
|
||||
}
|
||||
|
||||
void prtvid() {
|
||||
select (mode) {
|
||||
case 0: puts("DISABLED");
|
||||
case 1: puts("VGA");
|
||||
case 2: puts("NTSC");
|
||||
case 3: puts("RGB");
|
||||
default: puts("UNDEFINED");
|
||||
}
|
||||
if (mono) puts(" MONOCHROME"); else puts(" COLOR");
|
||||
puts(", ");
|
||||
if (field) puts("ODD"); else puts("EVEN");
|
||||
putln(" FIELD");
|
||||
}
|
||||
|
||||
int toint(.,yy,xx) {}
|
||||
|
||||
void xerror() {
|
||||
putln(" ERROR ENCOUNTERED");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
main:
|
||||
newlin();
|
||||
|
||||
|
||||
|
||||
puts("TESTING GETMEM() AND SETMEM()");
|
||||
setadr($20,&0); setmem(@abcdef,&abcdef);
|
||||
setadr($20,&0); getmem(@abcdef,&buffer);
|
||||
setdst(&abcdef); if (memcmp(@abcdef,&buffer)) xerror();
|
||||
passed();
|
||||
|
||||
puts("TESTING GETVID() AND SETVID()");
|
||||
for (i=0;i<4;i++) {
|
||||
for (j=1;j:+;j--) {
|
||||
//inline $ff;
|
||||
setvid(i,j);
|
||||
mode,mono,field = getvid();
|
||||
//prtvid();
|
||||
if (mode<>i or mono&j<>j) xerror();
|
||||
}
|
||||
}
|
||||
passed();
|
||||
|
||||
puts("TESTING GETBDR() AND SETBDR()");
|
||||
i=0; do {
|
||||
setbdr(i);
|
||||
index = getbdr();
|
||||
if (index<>i) xerror();
|
||||
//printf(index, "BORDER=%h%n");
|
||||
i++;
|
||||
} while(i);
|
||||
passed();
|
||||
|
||||
puts("TESTING GETSCL() AND SETSCL()");
|
||||
i=1; do {
|
||||
j=1;
|
||||
do {
|
||||
setscl(i,j); hscale,vscale = getscl();
|
||||
if (hscale<>i or vscale<>j) xerror("ERROR IN GETSCL()/SETSCL()");
|
||||
j<<;
|
||||
} while (j);
|
||||
i<<;
|
||||
} while (i);
|
||||
passed();
|
||||
|
||||
//putln("SAVING START AND STOP REGISTERS");
|
||||
setadr($1F, &$0004); getmem(5, &hrzvrt);
|
||||
//for (i=0;i<5;i++) printf(hrzvrt[i], "%h "); newlin();
|
||||
|
||||
puts("TESTING GETHSR() AND SETHSR()");
|
||||
sethsr(&$024C);
|
||||
hstart = gethsr();
|
||||
//setdst(hstart);printf("HSTART=%w%n");
|
||||
if (>hstart<>$02 or <hstart<>$4C) xerror(); else passed();
|
||||
|
||||
puts("TESTING GETHSP() AND SETHSP()");
|
||||
sethsp(&$025D); hstop = gethsp();
|
||||
//setdst(hstop);printf("HSTOP=%w%n");
|
||||
if (>hstop<>$02 or <hstop<>$5D) xerror(); else passed();
|
||||
|
||||
puts("TESTING GETVSR() AND SETVSR()");
|
||||
setvsr(&$016E); vstart = getvsr();
|
||||
//setdst(vstart);printf("VSTART=%w%n");
|
||||
if (>vstart<>$01 or <vstart<>$6E) xerror(); else passed();
|
||||
|
||||
puts("TESTING GETVSP() AND SETVSP()");
|
||||
setvsp(&$017F); vstop = getvsp();
|
||||
//setdst(vstop);printf("VSTOP=%w%n");
|
||||
if (>vstop<>$01 or <vstop<>$7F) xerror(); else passed();
|
||||
|
||||
//putln("RESTORING START AND STOP REGISTERS");
|
||||
setadr($1F, &$0004); setmem(5, &hrzvrt);
|
||||
|
||||
puts("TESTING GETIRL() AND SETIRL()");
|
||||
for (i=0;i<2;i++) {
|
||||
j=0;
|
||||
do {
|
||||
setiql(0,i,j);
|
||||
irqlin = getiql();
|
||||
//setdst(); printf("IRQ LINE=%w%n");
|
||||
if (>irqlin<>i or <irqlin<>j) xerror();
|
||||
j++;
|
||||
} while (j);
|
||||
}
|
||||
passed();
|
||||
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
puts("TESTING RGBCLR() AND CLRRGB()");
|
||||
for (red=7;red<255;red=red+8) {
|
||||
for (green=7;green<255;green=green+8) {
|
||||
for (blue=7;blue<255;blue=blue+8) {
|
||||
color = rgbclr(red,green,blue);
|
||||
i,j,k = clrrgb(color);
|
||||
if (red&$f0<>i or green&$f0<>j or blue&$f0<>k) {
|
||||
prtrgb(red,green,blue);
|
||||
putwrd(color); putspc();
|
||||
prtrgb(i,j,k); newlin();
|
||||
xerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
passed();
|
||||
|
||||
puts("TESTING GETCLR() AND SETCLR()");
|
||||
for (i=16; i<32; i++) {
|
||||
//puthex(i); putspc();
|
||||
color = getclr(i);
|
||||
//putwrd(color); putspc();
|
||||
if (i&15<>>color or nybdup(i)<><color) xerror();
|
||||
//if (i&7==7) newlin();
|
||||
}
|
||||
//passed();
|
||||
|
||||
//puts("TESTING SETCLR()");
|
||||
for (i=128; i<160; i++) {
|
||||
//puthex(i); putspc();
|
||||
red = i; green = i + 32; blue = i + 64;
|
||||
//prhex(red); prhex(green); prhex(blue); putspc(); putspc();
|
||||
color = rgbclr(red,green,blue);
|
||||
setclr(i,color);
|
||||
colour = getclr(i);
|
||||
//putwrd(colour); putspc();
|
||||
if (<colour<><color or >colour<>>color) xerror();
|
||||
//if (i&7==7) newlin();
|
||||
}
|
||||
passed();
|
||||
|
||||
puts("TESTING GETRGB() AND SETRGB()");
|
||||
for (l=128; l<160; l++) {
|
||||
red = l; green = l + 32; blue = l + 64;
|
||||
setidx(i); setrgb(red,green,blue);
|
||||
setidx(l); i,j,k = getrgb();
|
||||
if (red&$f0<>i or green&$f0<>j or blue&$f0<>k) {
|
||||
puthex(l); putspc();
|
||||
prtrgb(red,green,blue);
|
||||
putwrd(color); putspc();
|
||||
prtrgb(i,j,k); newlin();
|
||||
xerror();
|
||||
}
|
||||
}
|
||||
passed();
|
||||
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
//putln("SAVING LAYER REGISTERS");
|
||||
setadr($1F,&$2000); getmem(@layer0,&layer0);
|
||||
setadr($1F,&$3000); getmem(@layer1,&layer1);
|
||||
|
||||
printf("TESTING GETENB() AND SETENB()");
|
||||
setenb(0,$00); if (getenb(0)<>$00) xerror();
|
||||
setenb(0,$FF); if (getenb(0)<>$FF) xerror();
|
||||
setenb(1,$00); if (getenb(1)<>$00) xerror();
|
||||
setenb(1,$FF); if (getenb(1)<>$FF) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETMOD() AND SETMOD()");
|
||||
for (i=0;i<2;i++) {for (j=0;j<8;j++) {
|
||||
setmod(i,j); if (getmod(i)<>j) goto reslyr; //xerror();
|
||||
} }
|
||||
passed();
|
||||
|
||||
printf("TESTING GETMSZ() AND SETMSZ()");
|
||||
for (i=0;i<2;i++) {for (j=0;j<4;j++) {for (k=0;k<4;k++) {
|
||||
//printf(j,"%nJ=%h, "); printf(k,"K=%h");
|
||||
setmsz(i,j,k); w, h = getmsz(i);
|
||||
//printf(w," WIDTH=%h, "); printf(h,"HEIGHT=%h");
|
||||
if (w<>j or h<>k) xerror();
|
||||
}}}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETTSZ() AND SETTSZ()");
|
||||
for (i=0;i<2;i++) {for (j=0;j<2;j++) {for (k=0;k<2;k++) {
|
||||
//printf(j,"%nJ=%h, "); printf(k,"K=%h");
|
||||
settsz(i,j,k); w, h = gettsz(i);
|
||||
//printf(w," WIDTH=%h, "); printf(h,"HEIGHT=%h");
|
||||
if (w<>j or h<>k) xerror();
|
||||
}}}
|
||||
passed();
|
||||
|
||||
printf("TESTING MAPSIZ() AND TILSIZ()");
|
||||
for (i=0; i<@msizel; i++) {
|
||||
msize = mapsiz(i);
|
||||
//printf(i,"%nMAP SIZE %h = "); setdst(msize); printf("$%w PIXELS");
|
||||
if (<msize<>msizel[i] or >msize<>msizeh[i]) xerror();
|
||||
}
|
||||
for (i=0; i<@tsizel; i++) {
|
||||
tsize = tilsiz(i);
|
||||
//printf(i,"%nTILE SIZE %h = "); printf(tsize, "$%h PIXELS");
|
||||
if (tsize<>tsizel[i]) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETMBS() AND SETMBS()");
|
||||
setmbs(0,&$1234); mbase0 = getmbs(0);
|
||||
setmbs(1,&$5678); mbase1 = getmbs(1);
|
||||
//setdst(mbase0); printf("%nMBASE0=$%w, "); setdst(mbase1); printf("MBASE1=$%w%n");
|
||||
if (>mbase0<>$12 or <mbase0<>$34) xerror();
|
||||
if (>mbase1<>$56 or <mbase1<>$78) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETTBS() AND SETTBS()");
|
||||
settbs(0,&$90AB); tbase0 = gettbs(0);
|
||||
settbs(1,&$CDEF); tbase1 = gettbs(1);
|
||||
//setdst(tbase0); printf("%nTBASE0=$%w, "); setdst(tbase1); printf("TBASE1=$%w%n");
|
||||
if (>tbase0<>$90 or <tbase0<>$AB) xerror();
|
||||
if (>tbase1<>$CD or <tbase1<>$EF) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETMBA() AND GETTBA()");
|
||||
i,j,k = getmba(0); if (i<>$00 or j<>$48 or k<>$D0) xerror();
|
||||
i,j,k = getmba(1); if (i<>$01 or j<>$59 or k<>$E0) xerror();
|
||||
i,j,k = gettba(0); if (i<>$02 or j<>$42 or k<>$AC) xerror();
|
||||
i,j,k = gettba(1); if (i<>$03 or j<>$37 or k<>$BC) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETHSC() AND SETHSC()");
|
||||
sethsc(0,&$1357); hscrl0 = gethsc(0);
|
||||
sethsc(1,&$2468); hscrl1 = gethsc(1);
|
||||
//setdst(hscrl0); printf("%nHSCRL0=$%w, "); setdst(hscrl1); printf("HSCRL1=$%w%n");
|
||||
if (>hscrl0<>$13 or <hscrl0<>$57) xerror();
|
||||
if (>hscrl1<>$24 or <hscrl1<>$68) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETVSC() AND SETVSC()");
|
||||
setvsc(0,&$9BDF); vscrl0 = getvsc(0);
|
||||
setvsc(1,&$0ACE); vscrl1 = getvsc(1);
|
||||
//setdst(vscrl0); printf("%nVSCRL0=$%w, "); setdst(hscrl1); printf("VSCRL1=$%w%n");
|
||||
if (>vscrl0<>$9B or <vscrl0<>$DF) xerror();
|
||||
if (>vscrl1<>$0A or <vscrl1<>$CE) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETBPO() AND SETBPO()");
|
||||
i = 0; do {
|
||||
setbpo(0,i); if (getbpo(0)<>i) xerror();
|
||||
setbpo(1,i); if (getbpo(1)<>i) xerror();
|
||||
i = i + 16;
|
||||
} while (i);
|
||||
passed();
|
||||
|
||||
reslyr:
|
||||
setadr($1F, &$2000); setmem(@layer0, &layer0);
|
||||
setadr($1F, &$3000); setmem(@layer1, &layer1);
|
||||
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
printf("TESTING GETSPE() AND SETSPE()");
|
||||
setspe(#FALSE); if (getspe()) xerror();
|
||||
setspe(#TRUE); if (!getspe()) xerror();
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPO() AND SETSPO()");
|
||||
addr = &$5000;
|
||||
for (i=0; i<#MAXSPR;i++) {
|
||||
for (j=0;j<8;j++) {
|
||||
spaddr = getspo(i,j);
|
||||
//printf(i,"%nSPRITE %r "); printf(j,"OFFSET %d ADDRESS=$"); putwrd(spaddr);
|
||||
if (<spaddr <> <addr or >spaddr <> >addr) xerror();
|
||||
if (setspo(i,j)<>8) xerror(); //Returns number of attribute bytes per sprite
|
||||
b,m,l = getadr();
|
||||
//puts(", $"); putexh(b,m,l);
|
||||
if (b <> $1F or l <> <addr or m <> >addr) xerror();
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPR() AND SETSPR()");
|
||||
bank=$1f;msb=$50; lsb=$00;
|
||||
for (i=0; i<#MAXSPR;i++) {
|
||||
lsb=lsb+8; if (!lsb) msb++;
|
||||
/* Set Sprite Attributes */
|
||||
spattw[0]=i^$FF; spattw[1]=i|$80; //Sprite Address & Mode
|
||||
spattw[2]=i|$80; spattw[3]=0; spattw.horz<<; spattw.horz<<;
|
||||
spattw[4]=i^$FF; spattw[5]=0; spattw.vert<<; spattw.vert<<;
|
||||
spattw[6]=(i&1) ? $80|i : i;//Sprite Control
|
||||
spattw[7]=(i&1) ? i : $80|i; //Sprite Size
|
||||
l = setspr(i,&spattw); if (l<>8) xerror();
|
||||
b,m,l = getadr(); if (b<>bank or m<>msb or l<>lsb) xerror();
|
||||
/* Get Sprite Attributes */
|
||||
l = getspr(i,&spattr); if (l<>8) xerror();
|
||||
b,m,l = getadr(); if (b<>bank or m<>msb or l<>lsb) xerror();
|
||||
//printf(i, "SPRITE %r ATTRS: "); prtspr();
|
||||
for (j=0; j<@spattr; j++) {if (spattr[j]<>spattw[j]) xerror();}
|
||||
/* Clear Sprite Attributes */
|
||||
clrspr(i); b,m,l = getadr(); if (b<>bank or m<>msb or l<>lsb) xerror();
|
||||
getspr(i, &spattr); b,m,l = getadr(); if (b<>bank or m<>msb or l<>lsb) xerror();
|
||||
for (j=0; j<@spattr; j++) {if (spattr[j]) xerror();}
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPD() AND SETSPD()");
|
||||
spaddr=&$800; //Sprite Address Register Value
|
||||
bank=1; msb=0; lsb=0; //Sprite Data Address (spaddr<<5)
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i,"%nSPRITE %r ");
|
||||
setspg(i,1,$80); //Set Bit 7 of Register 1 (Mode)
|
||||
setspd(i,spaddr);
|
||||
//printf(getspg(i,1),"REG=$%h"); printf(getspg(i,0),"%h ");
|
||||
if (!getspg(i,1)&$80) xerror(); //Check Bit 7 of Register 1
|
||||
addr = getspd(i);
|
||||
//printf(setdst(addr),"ADDRESS=$%w");
|
||||
if (<addr <> <spaddr or >addr <> >spaddr) xerror();
|
||||
b,m,l = getspa(i);
|
||||
//printf(setdst(b,m,l)," ($%g%w)");
|
||||
if (b<>bank or m<>msb or l<>lsb) xerror();
|
||||
spaddr++;
|
||||
lsb = lsb + $20; if (!lsb) msb++;
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING SETSPB() AND GETSPB()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
k=127-i; setspg(i,1,k); //Set Bits 0-6 of Register
|
||||
for (j=1; j:+; j--) {
|
||||
setspb(i,j);
|
||||
spmode = getspb(i);
|
||||
//printf(spmode,"MODE=%d ");
|
||||
//printf(getspg(i,1),"REG=$%h ");
|
||||
if (spmode<>j) xerror();
|
||||
}
|
||||
if (getspg(i,1)<>k) xerror(); //Check Bits 0-6 of Register
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPX() AND SETSPX()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
lsb = i&3; msb = i+64;
|
||||
setspx(i, msb, lsb); l = getspg(i,2); m = getspg(i,3);
|
||||
//printf(setdst(.,m,l),"REG=$%w ");
|
||||
if (l<>lsb or m<>msb) xerror();
|
||||
n,m,l = getspx(i);
|
||||
//printf(setdst(.,m,l),"X=%i ");
|
||||
if (m<>msb or l<>lsb) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPY() AND SETSPY()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
lsb = i&3^3; msb = 192-i;
|
||||
setspy(i, msb, lsb); l = getspg(i,4); m = getspg(i,5);
|
||||
//printf(setdst(.,m,l),"REG=$%w ");
|
||||
if (l<>lsb or m<>msb) xerror();
|
||||
n,m,l = getspy(i);
|
||||
//printf(setdst(.,m,l),"Y=%i ");
|
||||
if (m<>msb or l<>lsb) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPF() AND SETSPF()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
setspn(i,$ff); //Set All Bits in Control Register
|
||||
for (j=1; j:+; j--) { //1 to 0
|
||||
k = j-1; //#FALSE then #TRUE
|
||||
setspf(i,k);
|
||||
//printf(getspn(i),"REG=$%h ");
|
||||
n = getspf(i);
|
||||
//prtflg(n,"HFLIP=$%h (%s) ");
|
||||
if (n<>k) xerror();
|
||||
}
|
||||
if (getspn(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPV() AND SETSPV()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
setspn(i,$ff); //Set All Bits in Control Register
|
||||
for (j=1; j:+; j--) { //1 to 0
|
||||
k = j-1; //#FALSE then #TRUE
|
||||
setspv(i,k);
|
||||
//printf(getspn(i),"REG=$%h ");
|
||||
n = getspv(i);
|
||||
//prtflg(n,"HFLIP=$%h (%s) ");
|
||||
if (n<>k) xerror();
|
||||
}
|
||||
if (getspn(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPZ() AND SETSPZ()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r ");
|
||||
setspn(i,$ff); //Set All Bits in Control Register
|
||||
for (j=0; j<4; j++) {
|
||||
setspz(i,j);
|
||||
//printf(getspn(i),"REG=$%h ");
|
||||
n = getspz(i);
|
||||
//printf(n,"ZDEPTH=%d ");
|
||||
if (n<>j) xerror();
|
||||
}
|
||||
if (getspn(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPM() AND SETSPM()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%n%r ");
|
||||
setspn(i,$ff); //Set All Bits in Control Register
|
||||
for (j=0; j<16; j++) {
|
||||
setspm(i,j);
|
||||
//printf(getspn(i),"%h:");
|
||||
n = getspm(i);
|
||||
//printf(n,"%g ");
|
||||
if (n<>j) xerror();
|
||||
}
|
||||
if (getspn(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPP() AND SETSPP()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%n%r ");
|
||||
setsps(i,$ff); //Set All Bits in Control Register
|
||||
for (j=0; j<16; j++) {
|
||||
setspp(i,j);
|
||||
//printf(getsps(i),"%h:");
|
||||
n = getspp(i);
|
||||
//printf(n,"%g ");
|
||||
if (n<>j) xerror();
|
||||
}
|
||||
if (getsps(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPH() AND SETSPH()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r HEIGHT ");
|
||||
setsps(i,$ff); //Set All Bits in Control Register
|
||||
for (j=0; j<4; j++) {
|
||||
setsph(i,j);
|
||||
//printf(getsps(i),"[$%h] ");
|
||||
n = getsph(i);
|
||||
//printf(n,"%d ");
|
||||
if (n<>j) xerror();
|
||||
}
|
||||
if (getsps(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPW() AND SETSPW()");
|
||||
for (i=0; i<#MAXSPR; i++) {
|
||||
//printf(i, "%nSPRITE %r WIDTH ");
|
||||
setsps(i,$ff); //Set All Bits in Control Register
|
||||
for (j=0; j<4; j++) {
|
||||
setspw(i,j);
|
||||
//printf(getsps(i),"[$%h] ");
|
||||
n = getspw(i);
|
||||
//printf(n,"%d ");
|
||||
if (n<>j) xerror();
|
||||
}
|
||||
if (getsps(i)<>$ff) xerror();
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPJ() AND GETSPK()");
|
||||
l = 8; m = 3; //Size in Pixels, Shift Counter
|
||||
for (i=0; i<4; i++) {
|
||||
//printf(i,"%nSIZE %r =");
|
||||
j,k = getspj(i);
|
||||
//printf(j,"%r PIXELS, ");
|
||||
//printf(k,"SHIFT COUNT %d");
|
||||
if (j<>l or k<>m) xerror();
|
||||
l<<; m++; //Multiply Size by Two, Increment Shift Counter
|
||||
}
|
||||
h = 8; height = &8; //Sprite Height in Pixels
|
||||
for (i=0; i<4; i++) {
|
||||
w = 8; //Sprite Width in Pixels
|
||||
size = height; size<<; size<<; //Set Size to Height*4
|
||||
for (j=0; j<4; j++) {
|
||||
p = 4; //Bits Per Pixeg
|
||||
bytes = size;
|
||||
//printf(h,"%nSPRITE HEIGHT=%l"); printf(w,"WIDTH=%l");
|
||||
for (k=0; k<2; k++) {
|
||||
//printf(p,"%d BPP ");
|
||||
spsize = getspk(j,i,k); //Calculate Sprite Data Size
|
||||
//printf(setdst(spsize),"SIZE=%i "); padint(' ',spsize);
|
||||
//printf(setdst(bytes),"[%i] "); padint(' ',bytes);
|
||||
if (<spsize <> <bytes or >spsize <> >bytes) xerror();
|
||||
p<<; bytes<<; //Multiply BPP, Size by 2
|
||||
}
|
||||
w<<; size<<; //Multiply Width, Size by 2
|
||||
}
|
||||
h<<; height<<; //Multiply Height by 2
|
||||
}
|
||||
passed();
|
||||
|
||||
printf("TESTING GETSPL() AND GETSPU()");
|
||||
n = 0; //Sprite Index
|
||||
h = 8; height = &8; //Sprite Height in Pixels
|
||||
for (i=0; i<4; i++) {
|
||||
setsph(n,i); //Set Sprite Height Specifier
|
||||
w = 8; //Sprite Width in Pixels
|
||||
size = height; size<<; size<<; //Set Size to Height*4
|
||||
for (j=0; j<4; j++) {
|
||||
setspw(n,j); //Set Sprite Width Specifier
|
||||
p = 4; //Bits Per Pixeg
|
||||
bytes = size;
|
||||
//printf(h,"%nHEIGHT=%d "); if (!i) putspc();
|
||||
//printf(w,"WIDTH=%d "); if (!j) putspc();
|
||||
for (k=0; k<2; k++) {
|
||||
setspp(n,k);
|
||||
d,e,f = getspu(n);
|
||||
//printf(p,"%dBPP "); prtreg();
|
||||
if (d<>j or e<>i or f<>k) xerror();
|
||||
spsize = getspl(n); //Get Sprite Data Size
|
||||
//printf(setdst(spsize),"SIZE=%i "); padint(' ',spsize);
|
||||
//printf(setdst(bytes),"[%i] "); padint(' ',bytes);
|
||||
if (<spsize <> <bytes or >spsize <> >bytes) xerror();
|
||||
p<<; bytes<<; //Multiply BPP, Size by 2
|
||||
}
|
||||
w<<; size<<; //Multiply Width, Size by 2
|
||||
}
|
||||
h<<; height<<; //Multiply Height by 2
|
||||
n++; //Increment Sprite Index
|
||||
}
|
||||
passed();
|
||||
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
newlin();
|
||||
|
||||
goto exit;
|
||||
|
153
x16/veraregs.c02
Normal file
153
x16/veraregs.c02
Normal file
@ -0,0 +1,153 @@
|
||||
/*************************************************
|
||||
* VERAREGS - Display Contents of Vera Registers *
|
||||
*************************************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <intlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <memory.h02>
|
||||
#include <nybble.h02>
|
||||
#include <screen.h02>
|
||||
#include "include/veramem.h02" //Vera Memory Access
|
||||
#include "include/veradsp.h02" //Vera Display Controller
|
||||
#include "include/veraclr.h02" //Vera Color Palette
|
||||
#include "include/veralyr.h02" //Vera Layer Control
|
||||
//#include "include/veraspr.h02" //Vera Sprites
|
||||
/* Globals */
|
||||
char i,j,k; //Loop Indexes
|
||||
char aa,yy,xx; //Function Paramaters
|
||||
char zz; //Function Variable
|
||||
int yx; //Function Paramater
|
||||
|
||||
/* Display Composer */
|
||||
char vmode,mono,field; //Video Output Mode, Monochrome Flag, Current Field
|
||||
char hscale,vscale; //Video Scaling
|
||||
char bcpidx; //Border Color Palette Index
|
||||
int bcolor; //Border Color Value
|
||||
int hstart,hstop; //Horizontal Start and Stop
|
||||
int vstart,vstop; //Vertical Start and Stop
|
||||
|
||||
/* Layer 0/1 */
|
||||
char layer; //Layer Number
|
||||
char lmode; //Layer Mode
|
||||
char height,width; //Map/Tile Height and Width
|
||||
|
||||
|
||||
//Print Vera Address
|
||||
void prtadr(aa,yx) {
|
||||
puts("ADDRESS: $"); putnyb(aa); putwrd(yx);
|
||||
}
|
||||
|
||||
//Print Masked Bits (byte, mask)
|
||||
void prtmsk(aa,yy) {
|
||||
xx = $80;
|
||||
do {
|
||||
zz = (aa&xx) ? '1' : '0';
|
||||
if (yy&xx) putchr(zz);
|
||||
xx>>;
|
||||
} while(xx);
|
||||
}
|
||||
|
||||
//Print Three Values Enclosed in Parentheses
|
||||
void prtprn(aa,yy,xx) {
|
||||
printf(aa,"($%h"); printf(yy,",$%h"); printf(xx,",$%h)");
|
||||
}
|
||||
|
||||
main:
|
||||
|
||||
clrscr(); //Clear Screen
|
||||
|
||||
putln("DISPLAY COMPOSER");
|
||||
|
||||
puts(" VIDEO MODE: ");
|
||||
vmode,mono,field = getvid();
|
||||
select (vmode) {
|
||||
case 0: puts("DISABLED");
|
||||
case 1: puts("VGA");
|
||||
case 2: puts("NTSC");
|
||||
case 3: puts("RGB");
|
||||
default: puts("UNDEFINED");
|
||||
}
|
||||
if (mono) puts(" MONOCHROME"); else puts(" COLOR");
|
||||
if (field) puts(", ODD"); else puts(", EVEN"); putln(" FIELD");
|
||||
|
||||
bcpidx = getbdr(); printf(bcpidx, " BORDER PALETTE INDEX: $%h");
|
||||
bcolor = getclr(bcpidx); puts(setdst(bcolor)); printf(", COLOR=$%w ");
|
||||
prtprn(clrrgb(bcolor)); newlin();
|
||||
|
||||
hscale,vscale = getscl(); hstart = gethsr(); hstop = gethsp(); vstart = getvsr(); vstop = getvsp();
|
||||
printf(hscale, " HORIZONTAL SCALE: %d, "); setdst(hstart); printf("START: %i, "); setdst(hstop); printf("STOP: %i%n");
|
||||
printf(vscale, " VERTICAL SCALE: %d, "); setdst(vstart); printf("START: %i, "); setdst(vstop); printf("STOP: %i%n");
|
||||
|
||||
setdst(getiql()); printf(" IRQ LINE: $%i%n");
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
putln("PALETTE COLORS");
|
||||
|
||||
putrps(5); i=0 ;do {printf(i," %h "); i=i+16; } while(i) ; newlin();
|
||||
for (i=0;i<16;i++) {
|
||||
printf(i," %h ");
|
||||
j=0; do {
|
||||
k = i + j; setdst(getclr(k)); printf(k,"%q ");
|
||||
j = j + 16;
|
||||
} while (j);
|
||||
newlin();
|
||||
}
|
||||
newlin();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
for (layer=0; layer<2; layer++) {
|
||||
|
||||
printf(layer, "LAYER %d%n");
|
||||
|
||||
puts(" MODE: "); lmode = getmod(layer);
|
||||
select(getmod(layer)) {
|
||||
case 0: puts("16 COLOR TEXT");
|
||||
case 1: puts("256 COLOR TEXT");
|
||||
case 2: puts("TILE 2BPP");
|
||||
case 3: puts("TILE 4BPP");
|
||||
case 4: puts("TILE 8BPP");
|
||||
case 5: puts("BITMAP 2BPP");
|
||||
case 6: puts("BITMAP 4BPP");
|
||||
case 7: puts("BITMAP 8BPP");
|
||||
default: puts("UNDEFINED");
|
||||
}
|
||||
if (getenb(layer)) putln(", ENABLED"); else putln(", DISABLED");
|
||||
|
||||
width, height = getmsz(layer);
|
||||
setdst(mapsiz(width)); printf(width," MAP WIDTH: %d (%i PIXELS)");
|
||||
setdst(mapsiz(height)); printf(height,", HEIGHT: %d (%i PIXELS)%n");
|
||||
|
||||
width, height = gettsz(layer);
|
||||
printf(width," TILE WIDTH: %d"); printf(tilsiz(width)," (%d PIXELS)");
|
||||
printf(height,", HEIGHT: %d"); printf(tilsiz(height)," (%d PIXELS)%n");
|
||||
|
||||
setdst(getmbs(layer)); printf(" MAP BASE: $%w, ");
|
||||
prtadr(getmba(layer)); newlin();
|
||||
|
||||
setdst(gettbs(layer)); printf(" TILE BASE: $%w, ");
|
||||
prtadr(gettba(layer)); newlin();
|
||||
|
||||
setdst(gethsc(layer)); printf(" HORIZONTAL SCROLL: $%i");
|
||||
setdst(getvsc(layer)); printf(", VERTICAL SCROLL: $%i%n");
|
||||
|
||||
printf(getbpo(layer)); printf(" BITMAP PALETTE OFFSET: $%h%n");
|
||||
|
||||
newlin();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
//puts("SPRITES "); if (getspe()) puts("ENABLED"); else puts("DISABLED");
|
||||
//puts(", COLLISION STATUS: %"); putmsk(getsps(),$0f); newlin();
|
||||
|
||||
|
||||
|
||||
goto exit;
|
||||
|
20
x16/x16.bat
Normal file
20
x16/x16.bat
Normal file
@ -0,0 +1,20 @@
|
||||
@REM Compile and Run C02 Program for Commander X16 Emulator
|
||||
@ECHO OFF
|
||||
IF EXIST %1.c02 GOTO COMPILE
|
||||
ECHO File %1.c02 not found
|
||||
GOTO EOF
|
||||
|
||||
:COMPILE
|
||||
ECHO Compiling File %1.c02 for Commander X16
|
||||
..\c02.exe -h x16 -s x16 -s cbm %1 >%1.dbg
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
ECHO Assembling File %1.asm
|
||||
..\a02.exe -p %1.asm %1.asm %1.lst >%1.out
|
||||
REM C:\Programs\dasm %1.asm -f1 -o%1.prg -l%1.lst -s%1.sym
|
||||
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
|
||||
ECHO Starting Emulator in Debug Mode
|
||||
REM C:\Programs\x16emu\x16emu -prg %1.prg -run -debug -log v >%1.out
|
||||
C:\Programs\x16emu\x16emu -prg %1.prg -run -debug
|
||||
:EOF
|
Loading…
x
Reference in New Issue
Block a user