1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-06-27 12:29:37 +00:00

Merge pull request #11 from RevCurtisP/x16vera

Commander X16 Vera chip modules
This commit is contained in:
RevCurtisP 2019-11-20 11:13:36 -05:00 committed by GitHub
commit fdaa5e39fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 5528 additions and 827 deletions

33
include/x16/joystk.a02 Normal file
View 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
View 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
View 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
View 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
View File

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

View File

@ -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;
}

View File

@ -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();}

View File

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