diff --git a/include/x16/joystk.a02 b/include/x16/joystk.a02 new file mode 100644 index 0000000..3babf20 --- /dev/null +++ b/include/x16/joystk.a02 @@ -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 diff --git a/include/x16/joystk.h02 b/include/x16/joystk.h02 new file mode 100644 index 0000000..a689489 --- /dev/null +++ b/include/x16/joystk.h02 @@ -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(); diff --git a/include/x16/xmemory.a02 b/include/x16/xmemory.a02 new file mode 100644 index 0000000..a47ce13 --- /dev/null +++ b/include/x16/xmemory.a02 @@ -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 diff --git a/include/x16/xmemory.h02 b/include/x16/xmemory.h02 new file mode 100644 index 0000000..9244168 --- /dev/null +++ b/include/x16/xmemory.h02 @@ -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(); diff --git a/src/c02.c b/src/c02.c index 80e7c4c..2a69a2f 100644 --- a/src/c02.c +++ b/src/c02.c @@ -1,230 +1,228 @@ -/************************************************************** - * C02 Compiler - (C) 2013 Curtis F Kaylor * - * * - * C02 is a simpified C-like language designed for the 6502 * - * * - * This Compiler generates crasm compatible assembly language * - * * - **************************************************************/ - -#include -#include -#include -#include -#include - -#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 +#include +#include +#include +#include + +#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 -#include -#include -#include -#include -#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 +#include +#include +#include +#include +#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; +} diff --git a/src/common.h b/src/common.h index 9dca134..4e7cdaf 100644 --- a/src/common.h +++ b/src/common.h @@ -1,96 +1,96 @@ -/************************************* - * C02 Common Definitions & Routines * - *************************************/ - -#define FNAMLEN 255 //Maximum File Name Length -#define LINELEN 255 //Maximum Input/Output Line Length -#define CONLEN 6 //Maximum Constant Name Length -#define MAXCON 255 //Maximum Number of Constants -#define STCLEN 6 //Maximum Struct Name Length -#define MAXSTC 32 //Maximum Number of Stuctures -#define STMLEN 6 //Maximum Struct Member Name Length -#define MAXSTM 255 //Maximum Number of Stucture Members -#define VARLEN 6 //Maximum Variable Name Length -#define MAXVAR 255 //Maximum Number of Variables -#define MAXTRM 16 //Maximum Terms in Stack -#define DATASPC 4096 //Space to Allocate for Variable Data -#define SUBMAX 4 //Maximum Number of Sub Directories - -#define LABLEN 6 //Maximum Program Label Length -#define MAXLAB 255 //Maximum Number of Program Labels - -#define LBLLEN 6 //Maximum Label Length -#define LBLFMT "L_%04d" //Label Format -#define LABSFX ":" //Label Suffix -#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth) -#define LOCPFX "." //Local Variable Prefix - -#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator -#define CPUARG "6502" //Target CPU Operand -#define ORGOP "ORG" //Origin Pseudo-Op -#define EQUOP "EQU" //Equate Pseudo-Op -#define BYTEOP "BYTE" //Define Byte Pseudo-Op -#define STROP "DS" //Define String Pseudo-Op -#define ALNOP "ALIGN" //Align Pseudo-Op -#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op -#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op - -#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format - -/* Internal defines */ -#define TRUE -1 -#define FALSE 0 - -void prtpos(); //Print current file name and position -#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}} -#define DETAIL(fmt, val) {if (debug) printf(fmt, val);} -#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);} - -int debug; //Print Debug Info (TRUE or FALSE) -int cmos; //Flag: Use 65C02 Instruction Set - -int gencmt; //Generate Assembly Language Comments -char asmcmt[LINELEN]; //Processed Assembly Language Comment - -int curcol, curlin; //Position in Source Code -int savcol, savlin; //Save Position in Source Code - -int bgntim; //Starting Time - -int nxtchr; //Next Character of Source File to Process -int nxtupc; //Next Character Converted to Uppercase -int savchr; //Holds nxtchr when switching input files - -int wrdlen; //Length of Parsed Word -char word[LINELEN]; //Word parsed from source file -char uword[LINELEN]; //Word converted to uppercase -int pstlen; //Length of Parsed String -char pstrng[LINELEN]; //String parsed fron source file -char cmtasm[LINELEN]; //Assembly Language Comment Text -char cputyp[LINELEN]; //CPU Type - -char hdrnam[FNAMLEN]; //Header File Name -char incdir[FNAMLEN]; //Include File Directory -char inpnam[FNAMLEN]; //Input File Name -char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory -int subcnt; //Number of Include Directories -int subidx; //Index into subdir[] - -int alcvar; //Allocate Variables Flag -int inblck; //Multiline Block Flag -int infunc; //Inside Function Definition Flag -int lsrtrn; //Last Statement was a Return Flag -int fcase; //First Case Statement Flag - -int padcnt; //Number of Padding Bytes at End of Program - -void exterr(int errnum); //Print current file name & position and exit -void expctd(char *expected); //Print Expected message and exit - -void addcmt(char *s); //Append string to comment -void chrcmt(char c); //Append character to comment -void setcmt(char *s); //Set comment to string -#define SCMNT(str) if (gencmt) {setcmt(str);} -#define ACMNT(str) if (gencmt) {addcmt(str);} -#define CCMNT(chr) if (gencmt) {chrcmt(chr);} -#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();} +/************************************* + * C02 Common Definitions & Routines * + *************************************/ + +#define FNAMLEN 255 //Maximum File Name Length +#define LINELEN 255 //Maximum Input/Output Line Length +#define CONLEN 6 //Maximum Constant Name Length +#define MAXCON 255 //Maximum Number of Constants +#define STCLEN 6 //Maximum Struct Name Length +#define MAXSTC 32 //Maximum Number of Stuctures +#define STMLEN 6 //Maximum Struct Member Name Length +#define MAXSTM 255 //Maximum Number of Stucture Members +#define VARLEN 6 //Maximum Variable Name Length +#define MAXVAR 255 //Maximum Number of Variables +#define MAXTRM 16 //Maximum Terms in Stack +#define DATASPC 4096 //Space to Allocate for Variable Data +#define SUBMAX 4 //Maximum Number of Sub Directories + +#define LABLEN 6 //Maximum Program Label Length +#define MAXLAB 255 //Maximum Number of Program Labels + +#define LBLLEN 6 //Maximum Label Length +#define LBLFMT "L_%04d" //Label Format +#define LABSFX ":" //Label Suffix +#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth) +#define LOCPFX "." //Local Variable Prefix + +#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator +#define CPUARG "6502" //Target CPU Operand +#define ORGOP "ORG" //Origin Pseudo-Op +#define EQUOP "EQU" //Equate Pseudo-Op +#define BYTEOP "BYTE" //Define Byte Pseudo-Op +#define STROP "DS" //Define String Pseudo-Op +#define ALNOP "ALIGN" //Align Pseudo-Op +#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op +#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op + +#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format + +/* Internal defines */ +#define TRUE -1 +#define FALSE 0 + +void prtpos(); //Print current file name and position +#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}} +#define DETAIL(fmt, val) {if (debug) printf(fmt, val);} +#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);} + +int debug; //Print Debug Info (TRUE or FALSE) +int cmos; //Flag: Use 65C02 Instruction Set + +int gencmt; //Generate Assembly Language Comments +char asmcmt[LINELEN]; //Processed Assembly Language Comment + +int curcol, curlin; //Position in Source Code +int savcol, savlin; //Save Position in Source Code + +int bgntim; //Starting Time + +int nxtchr; //Next Character of Source File to Process +int nxtupc; //Next Character Converted to Uppercase +int savchr; //Holds nxtchr when switching input files + +int wrdlen; //Length of Parsed Word +char word[LINELEN]; //Word parsed from source file +char uword[LINELEN]; //Word converted to uppercase +int pstlen; //Length of Parsed String +char pstrng[LINELEN]; //String parsed fron source file +char cmtasm[LINELEN]; //Assembly Language Comment Text +char cputyp[LINELEN]; //CPU Type + +char hdrnam[FNAMLEN]; //Header File Name +char incdir[FNAMLEN]; //Include File Directory +char inpnam[FNAMLEN]; //Input File Name +char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory +int subcnt; //Number of Include Directories +int subidx; //Index into subdir[] + +int alcvar; //Allocate Variables Flag +int inblck; //Multiline Block Flag +int infunc; //Inside Function Definition Flag +int lsrtrn; //Last Statement was a Return Flag +int fcase; //First Case Statement Flag + +int padcnt; //Number of Padding Bytes at End of Program + +void exterr(int errnum); //Print current file name & position and exit +void expctd(char *expected); //Print Expected message and exit + +void addcmt(char *s); //Append string to comment +void chrcmt(char c); //Append character to comment +void setcmt(char *s); //Set comment to string +#define SCMNT(str) if (gencmt) {setcmt(str);} +#define ACMNT(str) if (gencmt) {addcmt(str);} +#define CCMNT(chr) if (gencmt) {chrcmt(chr);} +#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();} diff --git a/src/expr.c b/src/expr.c index d370803..db8b507 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1,457 +1,457 @@ -/*********************************** - * C02 Expression Parsing Routines * - ***********************************/ - -#include -#include -#include -#include -#include -#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 +#include +#include +#include +#include +#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); +} diff --git a/x16/include/vera-old.a02 b/x16/include/vera-old.a02 new file mode 100644 index 0000000..7d6923a --- /dev/null +++ b/x16/include/vera-old.a02 @@ -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 diff --git a/x16/include/vera-old.h02 b/x16/include/vera-old.h02 new file mode 100644 index 0000000..c0c81c8 --- /dev/null +++ b/x16/include/vera-old.h02 @@ -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(); + diff --git a/x16/include/vera.a02 b/x16/include/vera.a02 new file mode 100644 index 0000000..d99467b --- /dev/null +++ b/x16/include/vera.a02 @@ -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 + diff --git a/x16/include/vera.h02 b/x16/include/vera.h02 new file mode 100644 index 0000000..0580ef8 --- /dev/null +++ b/x16/include/vera.h02 @@ -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(); + diff --git a/x16/include/veraclr.a02 b/x16/include/veraclr.a02 new file mode 100644 index 0000000..6eecbb0 --- /dev/null +++ b/x16/include/veraclr.a02 @@ -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 diff --git a/x16/include/veraclr.h02 b/x16/include/veraclr.h02 new file mode 100644 index 0000000..9484f60 --- /dev/null +++ b/x16/include/veraclr.h02 @@ -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(); diff --git a/x16/include/veradsp.a02 b/x16/include/veradsp.a02 new file mode 100644 index 0000000..057103e --- /dev/null +++ b/x16/include/veradsp.a02 @@ -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 diff --git a/x16/include/veradsp.h02 b/x16/include/veradsp.h02 new file mode 100644 index 0000000..645cfc7 --- /dev/null +++ b/x16/include/veradsp.h02 @@ -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(); diff --git a/x16/include/veralyr.a02 b/x16/include/veralyr.a02 new file mode 100644 index 0000000..d7f6f7b --- /dev/null +++ b/x16/include/veralyr.a02 @@ -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 diff --git a/x16/include/veralyr.h02 b/x16/include/veralyr.h02 new file mode 100644 index 0000000..9e67cf9 --- /dev/null +++ b/x16/include/veralyr.h02 @@ -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(); diff --git a/x16/include/veramem.a02 b/x16/include/veramem.a02 new file mode 100644 index 0000000..9611ffb --- /dev/null +++ b/x16/include/veramem.a02 @@ -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 diff --git a/x16/include/veramem.h02 b/x16/include/veramem.h02 new file mode 100644 index 0000000..02e8b0f --- /dev/null +++ b/x16/include/veramem.h02 @@ -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(); diff --git a/x16/include/veraspi.h02 b/x16/include/veraspi.h02 new file mode 100644 index 0000000..4e5cde4 --- /dev/null +++ b/x16/include/veraspi.h02 @@ -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(); diff --git a/x16/include/veraspr.a02 b/x16/include/veraspr.a02 new file mode 100644 index 0000000..f5fef08 --- /dev/null +++ b/x16/include/veraspr.a02 @@ -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 + diff --git a/x16/include/veraspr.h02 b/x16/include/veraspr.h02 new file mode 100644 index 0000000..a64c821 --- /dev/null +++ b/x16/include/veraspr.h02 @@ -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(); + diff --git a/x16/include/veratil.a02 b/x16/include/veratil.a02 new file mode 100644 index 0000000..62db714 --- /dev/null +++ b/x16/include/veratil.a02 @@ -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 + + diff --git a/x16/include/veratil.h02 b/x16/include/veratil.h02 new file mode 100644 index 0000000..5adf4bc --- /dev/null +++ b/x16/include/veratil.h02 @@ -0,0 +1,9 @@ +/********************************************* + * veratil.h02 - Tile Manipulation Functions * + * for Commander X16 VERA Chip * + * Requires: x16.h02 * + * stddef.h02 * + * veramem.h02 * + * veralyr.h02 * + *********************************************/ + diff --git a/x16/include/veratxt.a02 b/x16/include/veratxt.a02 new file mode 100644 index 0000000..4de5755 --- /dev/null +++ b/x16/include/veratxt.a02 @@ -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 + diff --git a/x16/include/veratxt.h02 b/x16/include/veratxt.h02 new file mode 100644 index 0000000..789a817 --- /dev/null +++ b/x16/include/veratxt.h02 @@ -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 diff --git a/x16/sprattrs.c02 b/x16/sprattrs.c02 new file mode 100644 index 0000000..8dd46fe --- /dev/null +++ b/x16/sprattrs.c02 @@ -0,0 +1,75 @@ +/************************************ + * TESTVERA - Test All Vera Modules * + ************************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#include +#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; + diff --git a/x16/sprdemo.c02 b/x16/sprdemo.c02 new file mode 100644 index 0000000..5001113 --- /dev/null +++ b/x16/sprdemo.c02 @@ -0,0 +1,77 @@ +/********************************* + * SPRDEMO - Vera Sprite Demo * + *********************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#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; + diff --git a/x16/sprsizes.c02 b/x16/sprsizes.c02 new file mode 100644 index 0000000..fc5ab1a --- /dev/null +++ b/x16/sprsizes.c02 @@ -0,0 +1,42 @@ +/********************************* + * SPRSIZES - Print Sprite Sizes * + *********************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#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; + diff --git a/x16/testspr.c02 b/x16/testspr.c02 new file mode 100644 index 0000000..ce25123 --- /dev/null +++ b/x16/testspr.c02 @@ -0,0 +1,117 @@ +/************************************ + * TESTVERA - Test All Vera Modules * + ************************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#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) 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; + diff --git a/x16/testvera.c02 b/x16/testvera.c02 new file mode 100644 index 0000000..917655e --- /dev/null +++ b/x16/testvera.c02 @@ -0,0 +1,680 @@ +/************************************ + * TESTVERA - Test All Vera Modules * + ************************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#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 $4C) xerror(); else passed(); + + puts("TESTING GETHSP() AND SETHSP()"); + sethsp(&$025D); hstop = gethsp(); + //setdst(hstop);printf("HSTOP=%w%n"); + if (>hstop<>$02 or $5D) xerror(); else passed(); + + puts("TESTING GETVSR() AND SETVSR()"); + setvsr(&$016E); vstart = getvsr(); + //setdst(vstart);printf("VSTART=%w%n"); + if (>vstart<>$01 or $6E) xerror(); else passed(); + + puts("TESTING GETVSP() AND SETVSP()"); + setvsp(&$017F); vstop = getvsp(); + //setdst(vstop);printf("VSTOP=%w%n"); + if (>vstop<>$01 or $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 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)<>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 (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 $34) xerror(); + if (>mbase1<>$56 or $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 $AB) xerror(); + if (>tbase1<>$CD or $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 $57) xerror(); + if (>hscrl1<>$24 or $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 $DF) xerror(); + if (>vscrl1<>$0A or $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) 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) 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) 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) 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) 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; + diff --git a/x16/veraregs.c02 b/x16/veraregs.c02 new file mode 100644 index 0000000..c6783cd --- /dev/null +++ b/x16/veraregs.c02 @@ -0,0 +1,153 @@ +/************************************************* + * VERAREGS - Display Contents of Vera Registers * + *************************************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include +#include +#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; + \ No newline at end of file diff --git a/x16/x16.bat b/x16/x16.bat new file mode 100644 index 0000000..f03bb88 --- /dev/null +++ b/x16/x16.bat @@ -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