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

Updated x16/include .a02 files to use 65C02 opcodes

This commit is contained in:
Curtis F Kaylor 2019-11-14 23:56:33 -05:00
parent 7f4e98826c
commit cf56e15c01
31 changed files with 2121 additions and 1923 deletions

Binary file not shown.

Binary file not shown.

19
src/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/c02.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true
}
]
}

View File

@ -1,36 +1,36 @@
/************************************* /*************************************
* C02 Assembly Language Routines * * C02 Assembly Language Routines *
*************************************/ *************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "files.h" #include "files.h"
#include "asm.h" #include "asm.h"
/* Process comment */ /* Process comment */
void prccmt(void) { void prccmt(void) {
if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); } if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); }
else asmcmt[0] = 0; else asmcmt[0] = 0;
setcmt(""); setcmt("");
} }
/* output a single line of assembly code */ /* output a single line of assembly code */
void asmlin(char *opcode, char *oprnd) { void asmlin(char *opcode, char *oprnd) {
if (strlen(lblasm)) strcat(lblasm, LABSFX); if (strlen(lblasm)) strcat(lblasm, LABSFX);
prccmt(); prccmt();
fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt); fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt);
if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt); if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt);
lblasm[0] = 0; lblasm[0] = 0;
} }
/* output a single comment line */ /* output a single comment line */
void cmtlin(void) { void cmtlin(void) {
DEBUG("Writing Comment Line: %s\n", cmtasm) DEBUG("Writing Comment Line: %s\n", cmtasm)
fprintf(outfil, "; %s\n", cmtasm); fprintf(outfil, "; %s\n", cmtasm);
setcmt(""); setcmt("");
} }

View File

@ -1,9 +1,9 @@
/************************************* /*************************************
* C02 Assembly Language Routines * * C02 Assembly Language Routines *
*************************************/ *************************************/
char lblasm[LBLLEN+2]; //Label to emit on next asm line char lblasm[LBLLEN+2]; //Label to emit on next asm line
void asmlin(char *opcode, char *oprnd); //Output a line of assembly code void asmlin(char *opcode, char *oprnd); //Output a line of assembly code
void cmtlin(); //Output a comment lines void cmtlin(); //Output a comment lines
void prccmt(); //Process comment void prccmt(); //Process comment

430
src/c02.c
View File

@ -1,203 +1,227 @@
/************************************************************** /**************************************************************
* C02 Compiler - (C) 2013 Curtis F Kaylor * * C02 Compiler - (C) 2013 Curtis F Kaylor *
* * * *
* C02 is a simpified C-like language designed for the 6502 * * C02 is a simpified C-like language designed for the 6502 *
* * * *
* This Compiler generates crasm compatible assembly language * * This Compiler generates crasm compatible assembly language *
* * * *
**************************************************************/ **************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" //Common Code used by all Modules #include "common.h" //Common Code used by all Modules
#include "files.h" //Open and Close Files #include "files.h" //Open and Close Files
#include "asm.h" //Write out Assembly Language #include "asm.h" //Write out Assembly Language
#include "parse.h" //General Code Parsing #include "parse.h" //General Code Parsing
#include "vars.h" //Variable Parsing, Lookup, and Allocation #include "vars.h" //Variable Parsing, Lookup, and Allocation
#include "expr.h" //Expression Parsing #include "expr.h" //Expression Parsing
#include "label.h" //Label Parsing, Generation, and Lookup #include "label.h" //Label Parsing, Generation, and Lookup
#include "cond.h" //Conditional Parsing #include "cond.h" //Conditional Parsing
#include "stmnt.h" //Statement Compiling Code #include "stmnt.h" //Statement Compiling Code
#include "dclrtn.h" //Statement Compiling Code #include "dclrtn.h" //Statement Compiling Code
#include "include.h" //Include File Parsing #include "include.h" //Include File Parsing
/* Initilize Compiler Variables */ /* Initilize Compiler Variables */
void init(void) { void init(void) {
initim(); //Initialize Elapsed Time initim(); //Initialize Elapsed Time
DEBUG("Initializing Compiler Variables\n",0) DEBUG("Initializing Compiler Variables\n",0)
concnt = 0; //Number of Constants Defined concnt = 0; //Number of Constants Defined
varcnt = 0; //Number of Variables in Table varcnt = 0; //Number of Variables in Table
lblcnt = 0; //Number of Labels in stack lblcnt = 0; //Number of Labels in stack
padcnt = 0; //Number of Padding Bytes at End padcnt = 0; //Number of Padding Bytes at End
curcol = 0; //Current Column in Source Code curcol = 0; //Current Column in Source Code
curlin = 0; //Current Line in Source Code curlin = 0; //Current Line in Source Code
alcvar = TRUE; //Allocate Variables Flag alcvar = TRUE; //Allocate Variables Flag
inblck = FALSE; //Multiline Block Flag inblck = FALSE; //Multiline Block Flag
infunc = FALSE; //Inside Function Definition infunc = FALSE; //Inside Function Definition
xstmnt[0] = 0; //Expected Statement xstmnt[0] = 0; //Expected Statement
nxtwrd[0] = 0; //Next Word (from DEFINE lookup) nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
nxtptr = 0; //Pointer to next character in nxtwrd nxtptr = 0; //Pointer to next character in nxtwrd
vrwrtn = FALSE; //Variables Written Flag vrwrtn = FALSE; //Variables Written Flag
rambas = 0; //RAM Base Address rambas = 0; //RAM Base Address
wrtbas = 0; //Write Base Address wrtbas = 0; //Write Base Address
zpaddr = 0; //Current Zero-Page Address zpaddr = 0; //Current Zero-Page Address
invasc = FALSE; //Invert ASCII Flag invasc = FALSE; //Invert ASCII Flag
mskasc = FALSE; //Set High Bit Flag mskasc = FALSE; //Set High Bit Flag
fcase = FALSE; //First Case Statement Flag fcase = FALSE; //First Case Statement Flag
wrtofs[0] = 0; //Write Offset wrtofs[0] = 0; //Write Offset
xsnvar[0] = 0; //Assigned X Variable Name xsnvar[0] = 0; //Assigned X Variable Name
ysnvar[0] = 0; //Assigned Y Variable Name ysnvar[0] = 0; //Assigned Y Variable Name
subcnt = 0; //Include Subdirectories subcnt = 0; //Include Subdirectories
strcpy(incdir, "../include/"); strcpy(cputyp, CPUARG); //Set CPU Type to Default Value
} strcpy(incdir, "../include/");
}
/* Reads and parses the next Word in Source File */
void pword(void) { /* Parse Pointer Dereference Assignment */
lsrtrn = FALSE; //Clear RETURN flag void ppntr(void) {
getwrd(); lsrtrn = FALSE; //Clear RETURN flag
DEBUG("Parsing Word '%s'\n", word) if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
if (xstmnt[0]) { prcasp(';');
if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt }
else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
} /* Reads and parses the next Word in Source File */
if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement void pword(void) {
} lsrtrn = FALSE; //Clear RETURN flag
getwrd();
/* Process a directive */ DEBUG("Parsing Word '%s'\n", word)
void pdrctv(void) { if (xstmnt[0]) {
skpchr(); //skip '#' if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt
CCMNT('#'); else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
getwrd(); //read directive into word }
DEBUG("Processing directive '%s'\n", word) if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement
if (wordis("DEFINE")) pdefin(); //Parse Define }
else if (wordis("INCLUDE")) pincfl(); //Parse Include File
else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE) /* Process a directive */
else if (wordis("PRAGMA")) pprgma(); void pdrctv(void) {
else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE) skpchr(); //skip '#'
} CCMNT('#');
getwrd(); //read directive into word
void prolog(void) { DEBUG("Processing directive '%s'\n", word)
DEBUG("Writing Assembly Prolog\n", 0) if (wordis("DEFINE")) pdefin(); //Parse Define
asmlin(CPUOP,CPUARG); else if (wordis("INCLUDE")) pincfl(); //Parse Include File
setcmt("Program "); else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE)
addcmt(srcnam); else if (wordis("PRAGMA")) pprgma();
cmtlin(); else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE)
} }
void epilog(void) { void prolog(void) {
if (!vrwrtn) wvrtbl(); //Write Variable Table DEBUG("Writing Assembly Prolog\n", 0)
if (padcnt) { asmlin(CPUOP,cputyp);
SCMNT("PADDING BYTES") setcmt("Program ");
sprintf(word, "$%hhX", padcnt); addcmt(srcnam);
asmlin(STROP, word); cmtlin();
} }
}
void epilog(void) {
/* Compile Source Code*/ if (!vrwrtn) wvrtbl(); //Write Variable Table
void compile(void) { if (padcnt) {
DEBUG("Starting Compilation\n", 0) SCMNT("PADDING BYTES")
prolog(); sprintf(word, "$%hhX", padcnt);
phdrfl(); //Process Header File specified on Command Line asmlin(STROP, word);
skpchr(); }
DEBUG("Parsing Code\n", 0) }
while (TRUE) {
skpspc(); /* Compile Source Code*/
if (match(EOF)) break; //Stop Parsing (End of File) void compile(void) {
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block DEBUG("Starting Compilation\n", 0)
else if (match('#')) pdrctv(); //Parse Directive prolog();
else if (match('/')) skpcmt(TRUE); //Skip Comment phdrfl(); //Process Header File specified on Command Line
else if (isalph()) pword(); //Parse Word skpchr();
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE) DEBUG("Parsing Code\n", 0)
} while (TRUE) {
epilog(); skpspc();
} if (match(EOF)) break; //Stop Parsing (End of File)
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
/* Display "Usage" text and exit*/ else if (match('#')) pdrctv(); //Parse Directive
void usage(void) { else if (match('/')) skpcmt(TRUE); //Skip Comment
printf("Usage: c02 sourcefile.c02\n"); else if (match('*')) ppntr(); //Parse Pointer
exit(EXIT_FAILURE); else if (isalph()) pword(); //Parse Word
} else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
}
/* Parse Command Line Option */ epilog();
int popt(int arg, int argc, char *argv[]) { }
char argstr[32]; //Argument String
char opt; //Option /* Display "Usage" text and exit*/
char optarg[32]; //Option Argument void usage(void) {
strncpy (argstr, argv[arg], 31); printf("Usage: c02 sourcefile.c02\n");
if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE) exit(EXIT_FAILURE);
opt = toupper(argstr[1]); }
if (strchr("HS", opt)) {
if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE) /* Parse Command Line Option */
strncpy(optarg, argv[arg], 31); int popt(int arg, int argc, char *argv[]) {
} char argstr[32]; //Argument String
DEBUG("Processing Command Line Option -%c\n", argstr[1]) char opt; //Option
switch (opt) { char optarg[32]; //Option Argument
case 'H': strncpy (argstr, argv[arg], 31);
strcpy(hdrnam, optarg); if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE)
DEBUG("Header Name set to '%s'\n", hdrnam) opt = toupper(argstr[1]);
break; if (strchr("CHS", opt)) {
case 'S': if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE)
strcpy(subdir[subcnt], optarg); strncpy(optarg, argv[arg], 31);
DEBUG("subdir[%d] ", subcnt) }
DEBUG("set to '%s'\n", subdir[subcnt]) DEBUG("Processing Command Line Option -%c\n", argstr[1])
subcnt++; switch (opt) {
break; case 'C':
default: strcpy(cputyp, optarg);
ERROR("Illegal option -%c\n", opt, EXIT_FAILURE) DEBUG("CPU Type set to '%s'\n", cputyp)
} break;
return arg; case 'H':
} strcpy(hdrnam, optarg);
DEBUG("Header Name set to '%s'\n", hdrnam)
/* Parse Command Line Arguments * break;
* Sets: srcnam - Source File Name (from first arg) * case 'S':
* outnam - Output File Name (from optional second arg) */ strcpy(subdir[subcnt], optarg);
void pargs(int argc, char *argv[]) { DEBUG("subdir[%d] ", subcnt)
int arg; DEBUG("set to '%s'\n", subdir[subcnt])
srcnam[0] = 0; subcnt++;
outnam[0] = 0; break;
DEBUG("Parsing %d arguments\n", argc) default:
if (argc == 0) usage(); //at least one argument is required ERROR("Illegal option -%c\n", opt, EXIT_FAILURE)
for (arg = 1; arg<argc; arg++) { }
DEBUG("Parsing argument %d\n", arg); return arg;
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option }
else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg /* Parse Command Line Arguments *
else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE) * Sets: srcnam - Source File Name (from first arg) *
} * outnam - Output File Name (from optional second arg) */
if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam) void pargs(int argc, char *argv[]) {
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE) int arg;
if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam) srcnam[0] = 0;
} outnam[0] = 0;
DEBUG("Parsing %d arguments\n", argc)
int main(int argc, char *argv[]) { if (argc == 0) usage(); //at least one argument is required
debug = TRUE; //Output Debug Info for (arg = 1; arg<argc; arg++) {
gencmt = TRUE; //Generate Assembly Language Comments DEBUG("Parsing argument %d\n", arg);
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" ); else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg
init(); //Initialize Global Variables else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE)
}
pargs(argc, argv); //Parse Command Line Arguments if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam)
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE)
opnsrc(); //Open Source File if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam)
opnout(); //Open Output File }
opnlog(); //Open Log File
/* Validate CPU Type *
setsrc(); //Set Input to Source File * Uses: cputype *
* Sets: cmos */
compile(); void chkcpu(void) {
if (strcmp(cputyp, "6502") == 0) cmos = FALSE;
logstc(); else if (strcmp(cputyp, "65C02") == 0) cmos = TRUE;
logcon(); else ERROR("Invalid CPU Type %s\n", cputyp, EXIT_FAILURE)
loglab(); }
clssrc(); //Close Source File
clsout(); //Close Output File int main(int argc, char *argv[]) {
clslog(); //Close Log File debug = TRUE; //Output Debug Info
} gencmt = TRUE; //Generate Assembly Language Comments
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" );
init(); //Initialize Global Variables
pargs(argc, argv); //Parse Command Line Arguments
chkcpu(); //Validate CPU Type
opnsrc(); //Open Source File
opnout(); //Open Output File
opnlog(); //Open Log File
setsrc(); //Set Input to Source File
compile();
logstc();
logcon();
loglab();
clssrc(); //Close Source File
clsout(); //Close Output File
clslog(); //Close Log File
}

View File

@ -1,60 +1,60 @@
/************************************* /*************************************
* C02 Common Definitions & Routines * * C02 Common Definitions & Routines *
*************************************/ *************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include "common.h" #include "common.h"
struct timespec curtim; //Current Time struct timespec curtim; //Current Time
/* Error - Print Input File name & position and exit */ /* Error - Print Input File name & position and exit */
void exterr(int errnum) { void exterr(int errnum) {
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam); fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
exit(errnum); exit(errnum);
} }
/* Error - print "Expected" error message * /* Error - print "Expected" error message *
and exit with general failure code * and exit with general failure code *
Args: expected - Description of what was expected */ Args: expected - Description of what was expected */
void expctd(char *expstr) { void expctd(char *expstr) {
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr); fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
exterr(EXIT_FAILURE); exterr(EXIT_FAILURE);
} }
/* Print current position in file */ /* Print current position in file */
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); } void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
/* Initialize elapsed time counter */ /* Initialize elapsed time counter */
void initim(void) { void initim(void) {
timespec_get (&curtim, TIME_UTC); timespec_get (&curtim, TIME_UTC);
bgntim = curtim.tv_sec; bgntim = curtim.tv_sec;
} }
/* Print elapsed time */ /* Print elapsed time */
void prttim(void) { void prttim(void) {
timespec_get (&curtim, TIME_UTC); timespec_get (&curtim, TIME_UTC);
printf("[%d", curtim.tv_sec - bgntim); printf("[%d", curtim.tv_sec - bgntim);
printf(".%06d]",curtim.tv_nsec/1000); printf(".%06d]",curtim.tv_nsec/1000);
} }
/* Set comment to string */ /* Set comment to string */
void setcmt(char *s) { strcpy(cmtasm, s); } void setcmt(char *s) { strcpy(cmtasm, s); }
/* Append string to comment */ /* Append string to comment */
void addcmt(char *s) { void addcmt(char *s) {
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s); if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
} }
/* Append character to comment */ /* Append character to comment */
void chrcmt(char c) { void chrcmt(char c) {
if (strlen(cmtasm)>72) return; if (strlen(cmtasm)>72) return;
if (cmtasm[0] == 0 && c == ' ') return; if (cmtasm[0] == 0 && c == ' ') return;
int i = strlen(cmtasm); int i = strlen(cmtasm);
cmtasm[i++] = c; cmtasm[i++] = c;
cmtasm[i] = 0; cmtasm[i] = 0;
} }

View File

@ -1,94 +1,98 @@
/************************************* /*************************************
* C02 Common Definitions & Routines * * C02 Common Definitions & Routines *
*************************************/ *************************************/
#define FNAMLEN 255 //Maximum File Name Length #define FNAMLEN 255 //Maximum File Name Length
#define LINELEN 255 //Maximum Input/Output Line Length #define LINELEN 255 //Maximum Input/Output Line Length
#define CONLEN 6 //Maximum Constant Name Length #define CONLEN 6 //Maximum Constant Name Length
#define MAXCON 255 //Maximum Number of Constants #define MAXCON 255 //Maximum Number of Constants
#define STCLEN 6 //Maximum Struct Name Length #define STCLEN 6 //Maximum Struct Name Length
#define MAXSTC 32 //Maximum Number of Stuctures #define MAXSTC 32 //Maximum Number of Stuctures
#define STMLEN 6 //Maximum Struct Member Name Length #define STMLEN 6 //Maximum Struct Member Name Length
#define MAXSTM 255 //Maximum Number of Stucture Members #define MAXSTM 255 //Maximum Number of Stucture Members
#define VARLEN 6 //Maximum Variable Name Length #define VARLEN 6 //Maximum Variable Name Length
#define MAXVAR 255 //Maximum Number of Variables #define MAXVAR 255 //Maximum Number of Variables
#define MAXTRM 16 //Maximum Terms in Stack #define MAXTRM 16 //Maximum Terms in Stack
#define DATASPC 4096 //Space to Allocate for Variable Data #define DATASPC 4096 //Space to Allocate for Variable Data
#define SUBMAX 4 //Maximum Number of Sub Directories #define SUBMAX 4 //Maximum Number of Sub Directories
#define LABLEN 6 //Maximum Program Label Length #define LABLEN 6 //Maximum Program Label Length
#define MAXLAB 255 //Maximum Number of Program Labels #define MAXLAB 255 //Maximum Number of Program Labels
#define LBLLEN 6 //Maximum Label Length #define LBLLEN 6 //Maximum Label Length
#define LBLFMT "L_%04d" //Label Format #define LBLFMT "L_%04d" //Label Format
#define LABSFX ":" //Label Suffix #define LABSFX ":" //Label Suffix
#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth) #define MAXLBL 15 //Maximum Number of Labels (Nesting Depth)
#define LOCPFX "." //Local Variable Prefix #define LOCPFX "." //Local Variable Prefix
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator #define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
#define CPUARG "6502" //Target CPU Operand #define CPUARG "6502" //Target CPU Operand
#define ORGOP "ORG" //Origin Pseudo-Op #define ORGOP "ORG" //Origin Pseudo-Op
#define EQUOP "EQU" //Equate Pseudo-Op #define EQUOP "EQU" //Equate Pseudo-Op
#define BYTEOP "DC" //Define Byte Pseudo-Op #define BYTEOP "BYTE" //Define Byte Pseudo-Op
#define STROP "DS" //Define String Pseudo-Op #define STROP "DS" //Define String Pseudo-Op
#define ALNOP "ALIGN" //Align Pseudo-Op #define ALNOP "ALIGN" //Align Pseudo-Op
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op #define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op #define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format #define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
/* Internal defines */ /* Internal defines */
#define TRUE -1 #define TRUE -1
#define FALSE 0 #define FALSE 0
void initim(); //Initialize elapsed time counter void initim(); //Initialize elapsed time counter
void prtpos(); //Print current file name and position void prtpos(); //Print current file name and position
void prttim(); //Print elapsed time void prttim(); //Print elapsed time
#define DEBUG(fmt, val) {if (debug) {prtpos(); prttim(); printf(fmt, val);}} #define DEBUG(fmt, val) {if (debug) {prtpos(); prttim(); printf(fmt, val);}}
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);} #define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);} #define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
int debug; //Print Debug Info (TRUE or FALSE) 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 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 curcol, curlin; //Position in Source Code
int savcol, savlin; //Save Position in Source Code
int bgntim; //Starting Time
int bgntim; //Starting Time
int nxtchr; //Next Character of Source File to Process
int nxtupc; //Next Character Converted to Uppercase int nxtchr; //Next Character of Source File to Process
int savchr; //Holds nxtchr when switching input files 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 int wrdlen; //Length of Parsed Word
char uword[LINELEN]; //Word converted to uppercase char word[LINELEN]; //Word parsed from source file
char cmtasm[LINELEN]; //Assembly Language Comment Text char uword[LINELEN]; //Word converted to uppercase
int pstlen; //Length of Parsed String
char hdrnam[FNAMLEN]; //Header File Name char pstrng[LINELEN]; //String parsed fron source file
char incdir[FNAMLEN]; //Include File Directory char cmtasm[LINELEN]; //Assembly Language Comment Text
char inpnam[FNAMLEN]; //Input File Name char cputyp[LINELEN]; //CPU Type
char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
int subcnt; //Number of Include Directories char hdrnam[FNAMLEN]; //Header File Name
int subidx; //Index into subdir[] char incdir[FNAMLEN]; //Include File Directory
char inpnam[FNAMLEN]; //Input File Name
int alcvar; //Allocate Variables Flag char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
int inblck; //Multiline Block Flag int subcnt; //Number of Include Directories
int infunc; //Inside Function Definition Flag int subidx; //Index into subdir[]
int lsrtrn; //Last Statement was a Return Flag
int fcase; //First Case Statement Flag int alcvar; //Allocate Variables Flag
int inblck; //Multiline Block Flag
int padcnt; //Number of Padding Bytes at End of Program int infunc; //Inside Function Definition Flag
int lsrtrn; //Last Statement was a Return Flag
void exterr(int errnum); //Print current file name & position and exit int fcase; //First Case Statement Flag
void expctd(char *expected); //Print Expected message and exit
int padcnt; //Number of Padding Bytes at End of Program
void addcmt(char *s); //Append string to comment
void chrcmt(char c); //Append character to comment void exterr(int errnum); //Print current file name & position and exit
void setcmt(char *s); //Set comment to string void expctd(char *expected); //Print Expected message and exit
#define SCMNT(str) if (gencmt) {setcmt(str);}
#define ACMNT(str) if (gencmt) {addcmt(str);} void addcmt(char *s); //Append string to comment
#define CCMNT(chr) if (gencmt) {chrcmt(chr);} void chrcmt(char c); //Append character to comment
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();} void setcmt(char *s); //Set comment to string
#define SCMNT(str) if (gencmt) {setcmt(str);}
#define ACMNT(str) if (gencmt) {addcmt(str);}
#define CCMNT(chr) if (gencmt) {chrcmt(chr);}
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();}

View File

@ -1,138 +1,138 @@
/************************************ /************************************
* C02 Conditional Parsing Routines * * C02 Conditional Parsing Routines *
************************************/ ************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "asm.h" #include "asm.h"
#include "parse.h" #include "parse.h"
#include "vars.h" #include "vars.h"
#include "expr.h" #include "expr.h"
#include "label.h" #include "label.h"
#include "cond.h" #include "cond.h"
int cmprtr; //Encoded Comparison Operator int cmprtr; //Encoded Comparison Operator
int cmpenc; //Encoded Comparator Character int cmpenc; //Encoded Comparator Character
/* Encode Comparison Operator Character * /* Encode Comparison Operator Character *
* Args: Comparison Operator Character * * Args: Comparison Operator Character *
* Returns: Comparison Operator Bit Mask */ * Returns: Comparison Operator Bit Mask */
int enccmp(char c) { int enccmp(char c) {
int e; int e;
DEBUG("Encoding Comparison Character '%c'", c) DEBUG("Encoding Comparison Character '%c'", c)
switch(c) { switch(c) {
case '=': e = 1; break; case '=': e = 1; break;
case '<': e = 2; break; case '<': e = 2; break;
case '>': e = 4; break; case '>': e = 4; break;
default: e = 0; default: e = 0;
} }
if (e) { CCMNT(c); skpchr(); } if (e) { CCMNT(c); skpchr(); }
DETAIL(", encoded as %d\n", e); DETAIL(", encoded as %d\n", e);
return e; return e;
} }
/* Process and Compile Comparison Operator and * /* Process and Compile Comparison Operator and *
* Args: comparator - Encoded Comparison Operator * * Args: comparator - Encoded Comparison Operator *
* Uses: term - Term Being Compared Against * * Uses: term - Term Being Compared Against *
* label - Branch Target if Comparison is FALSE */ * label - Branch Target if Comparison is FALSE */
void prccmp(void) { void prccmp(void) {
DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp) DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp)
if (cmprtr > 7) { //Process Flag if (cmprtr > 7) { //Process Flag
cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal
if (cmprtr) asmlin("BPL", cmplbl); if (cmprtr) asmlin("BPL", cmplbl);
else asmlin("BMI", cmplbl); else asmlin("BMI", cmplbl);
return; return;
} }
cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal
switch(cmprtr) { switch(cmprtr) {
case 0: // Raw Expression (Skip) case 0: // Raw Expression (Skip)
asmlin("BEQ", cmplbl); break; asmlin("BEQ", cmplbl); break;
case 1: // = or == case 1: // = or ==
asmlin("CMP", term); asmlin("BNE", cmplbl); break; asmlin("CMP", term); asmlin("BNE", cmplbl); break;
case 2: // < case 2: // <
asmlin("CMP", term); asmlin("BCS", cmplbl); break; asmlin("CMP", term); asmlin("BCS", cmplbl); break;
case 3: // <= or =< case 3: // <= or =<
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break; asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break;
case 4: // > case 4: // >
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break; asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break;
case 5: // >= or => case 5: // >= or =>
asmlin("CMP", term); asmlin("BCC", cmplbl); break; asmlin("CMP", term); asmlin("BCC", cmplbl); break;
case 6: // <> or >< case 6: // <> or ><
asmlin("CMP", term); asmlin("BEQ", cmplbl); break; asmlin("CMP", term); asmlin("BEQ", cmplbl); break;
case 7: // Raw Expression (Normal) case 7: // Raw Expression (Normal)
asmlin("BNE", cmplbl); break; asmlin("BNE", cmplbl); break;
default: default:
ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE) ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE)
} }
} }
/* Parse Comparison */ /* Parse Comparison */
void prscmp(int revrse) { void prscmp(int revrse) {
skpspc(); skpspc();
cmpenc = enccmp(nxtchr); //Encode Comparison Character cmpenc = enccmp(nxtchr); //Encode Comparison Character
cmprtr = cmpenc; //Set Encoded Comparator cmprtr = cmpenc; //Set Encoded Comparator
if (cmprtr) { if (cmprtr) {
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
} }
skpspc(); skpspc();
if (cmprtr) prstrm(FALSE); if (cmprtr) prstrm(FALSE);
//prccmp(); - Do after check for logical operator //prccmp(); - Do after check for logical operator
DEBUG("Parsed comparator %d\n", cmprtr) DEBUG("Parsed comparator %d\n", cmprtr)
} }
/* Parse Flag Operator */ /* Parse Flag Operator */
void prsflg(int revrse) { void prsflg(int revrse) {
DEBUG("Parsing Flag Operator '%c'\n", nxtchr) DEBUG("Parsing Flag Operator '%c'\n", nxtchr)
if (match('+')) cmprtr = 8; //Bit 0 = 0 if (match('+')) cmprtr = 8; //Bit 0 = 0
else if (match('-')) cmprtr = 9; //Bit 1 = 1 else if (match('-')) cmprtr = 9; //Bit 1 = 1
else expctd("Flag operator"); else expctd("Flag operator");
skpchr(); skpchr();
} }
/* Parse Logical Operator * /* Parse Logical Operator *
* Sets: logops */ * Sets: logops */
void prslop(void) { void prslop(void) {
DEBUG("Checking for Logical Operator\n", 0) DEBUG("Checking for Logical Operator\n", 0)
logopr = LOPNONE; logopr = LOPNONE;
skpspc(); skpspc();
if (isalph()) { if (isalph()) {
getwrd(); //Get Logical Operator getwrd(); //Get Logical Operator
DEBUG("Parsing Logical Operator %s\n", word) DEBUG("Parsing Logical Operator %s\n", word)
if (wordis("AND")) logopr = LOPAND; if (wordis("AND")) logopr = LOPAND;
else if (wordis("OR")) logopr = LOPOR; else if (wordis("OR")) logopr = LOPOR;
else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE) else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE)
} }
DEBUG("Set LOGOPR to %d\n", logopr) DEBUG("Set LOGOPR to %d\n", logopr)
} }
/* Parse and Compile Conditional Expression * /* Parse and Compile Conditional Expression *
* Condition = <expression> <comparator> <term> */ * Condition = <expression> <comparator> <term> */
void prscnd(char trmntr, int revrse) { void prscnd(char trmntr, int revrse) {
DEBUG("Parsing condition with REVRSE=%d\n", revrse) DEBUG("Parsing condition with REVRSE=%d\n", revrse)
tmplbl[0] = 0; tmplbl[0] = 0;
do { do {
strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
revcmp = revrse; revcmp = revrse;
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE; if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
DEBUG("Set REVCMP to %d\n", revcmp) DEBUG("Set REVCMP to %d\n", revcmp)
if (!look('.')) prsxpr(0); if (!look('.')) prsxpr(0);
if (look(':')) prsflg(revcmp); //Parse Flag Operator if (look(':')) prsflg(revcmp); //Parse Flag Operator
else prscmp(revcmp); //Parse Comparison Operator else prscmp(revcmp); //Parse Comparison Operator
prslop(); //Parse Logical Operator prslop(); //Parse Logical Operator
if (logopr == LOPOR) { if (logopr == LOPOR) {
revcmp = (revcmp) ? FALSE: TRUE; revcmp = (revcmp) ? FALSE: TRUE;
DEBUG("Set REVCMP to %d\n", revcmp) DEBUG("Set REVCMP to %d\n", revcmp)
} }
if (logopr && revcmp) { if (logopr && revcmp) {
if (!tmplbl[0]) newlbl(tmplbl); if (!tmplbl[0]) newlbl(tmplbl);
strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
} }
prccmp(); //Process Comparison/Flag Operator prccmp(); //Process Comparison/Flag Operator
} while (logopr); } while (logopr);
if (tmplbl[0]) setlbl(tmplbl); if (tmplbl[0]) setlbl(tmplbl);
expect(trmntr); expect(trmntr);
} }

View File

@ -1,10 +1,10 @@
/************************************ /************************************
* C02 Conditional Parsing Routines * * C02 Conditional Parsing Routines *
************************************/ ************************************/
enum LOGOPS {LOPNONE, LOPAND, LOPOR}; enum LOGOPS {LOPNONE, LOPAND, LOPOR};
int revcmp; //Reverse Comparison int revcmp; //Reverse Comparison
int logopr; //Logical Operator (set to LOGOPS) int logopr; //Logical Operator (set to LOGOPS)
void prscnd(char trmntr, int revrse); //Parse Conditional Expression void prscnd(char trmntr, int revrse); //Parse Conditional Expression

View File

@ -53,6 +53,7 @@ void addfnc(void) {
infunc = TRUE; //Set Inside Function Definition Flag infunc = TRUE; //Set Inside Function Definition Flag
DEBUG("Set infunc to %d\n", infunc) DEBUG("Set infunc to %d\n", infunc)
setlbl(fncnam); //Set Function Entry Point setlbl(fncnam); //Set Function Entry Point
asmlin(LOCOP, ""); //Set Local Variables Boundary
if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter
if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter
if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter

View File

@ -1,17 +1,17 @@
/************************************ /************************************
* C02 Declaration Compiling Routines * * C02 Declaration Compiling Routines *
************************************/ ************************************/
char fncnam[VARLEN+1]; //Function Name char fncnam[VARLEN+1]; //Function Name
char prmtra[VARLEN+1]; //Function Parameter A char prmtra[VARLEN+1]; //Function Parameter A
char prmtrx[VARLEN+1]; //Function Parameter X char prmtrx[VARLEN+1]; //Function Parameter X
char prmtry[VARLEN+3]; //Function Parameter Y char prmtry[VARLEN+3]; //Function Parameter Y
int prmcnt; //Number of Parameters int prmcnt; //Number of Parameters
//int lpemtd; //Location Prefix Emitted //int lpemtd; //Location Prefix Emitted
void addcon(int numval); //Add Constant void addcon(int numval); //Add Constant
int pmodfr(); //Check for and Parse Modifier int pmodfr(); //Check for and Parse Modifier
int ctype(int reqtyp); //Check for Type Keyword int ctype(int reqtyp); //Check for Type Keyword
int ptype(int m); //Check for and Parse Type Keyword int ptype(int m); //Check for and Parse Type Keyword
enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT}; enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT};

View File

@ -1,372 +1,454 @@
/*********************************** /***********************************
* C02 Expression Parsing Routines * * C02 Expression Parsing Routines *
***********************************/ ***********************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "asm.h" #include "asm.h"
#include "parse.h" #include "parse.h"
#include "vars.h" #include "vars.h"
#include "label.h" #include "label.h"
#include "expr.h" #include "expr.h"
/* Push Term and Operator onto Stack */ /* Push Term and Operator onto Stack */
void pshtrm(void) { void pshtrm(void) {
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE) if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
oprstk[trmidx] = oper; //Put Current Operator on Stack oprstk[trmidx] = oper; //Put Current Operator on Stack
strcpy(trmstk[trmidx], term); //Put Current Term on Stack strcpy(trmstk[trmidx], term); //Put Current Term on Stack
trmidx++; //Increment Stack Pointer 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 /* Pop Term and Operator off Stack */
strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack void poptrm(void) {
oper = oprstk[trmidx]; //Restore Current Operator from Stack trmidx--; //Decrement Stack Pointer
} strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack
oper = oprstk[trmidx]; //Restore Current Operator from Stack
/* Parse value (literal or identifier) * DEBUG("expr.pshtrm: Popped term %s ", term)
* Args: alwreg - allow registers * DETAIL("and operator '%c' off stack\n", oper)
8 alwcon - allow constants * }
* Sets: value - the value (as a string) *
* valtyp - value type */ /* Parse value (literal or identifier) *
void prsval(int alwreg, int alwcon) { * Args: alwreg - allow registers *
DEBUG("Parsing value\n", 0) 8 alwcon - allow constants *
skpspc(); * Sets: value - the value (as a string) *
if (islpre()) prslit(); //Parse Literal * valtyp - value type */
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable void prsval(int alwreg, int alwcon) {
else if (isbtop()) prsbop(); //Parse Byte Operator DEBUG("expr.prsval: Parsing value\n", 0)
else expctd("literal or variable"); skpspc();
DEBUG("Parsed value of type %d\n", valtyp) if (islpre()) prslit(); //Parse Literal
skpspc(); else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
} else if (isbtop()) prsbop(); //Parse Byte Operator
else expctd("literal or variable");
/* Process Unary Minus */ DEBUG("expr.prsval: Parsed value %s ", value)
void prcmns(void) { DETAIL("of type %d\n", valtyp)
DEBUG("Processing unary minus", 0) skpspc();
asmlin("LDA", "#$00"); //Handle Unary Minus }
}
/* Process Unary Minus */
/* Parse array index * void prcmns(void) {
* Args: clbrkt - require closing bracket * DEBUG("Processing unary minus", 0)
* Sets: value - array index or * asmlin("LDA", "#$00"); //Handle Unary Minus
* "" if no index defined */ }
void prsidx(int clbrkt) {
expect('['); /* Parse array index *
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants * Args: clbrkt - require closing bracket *
DEBUG("Parsed array index '%s'\n", value) * Sets: value - array index or *
if (clbrkt) expect(']'); * "" if no index defined */
} void prsidx(int clbrkt) {
expect('[');
/* Process Simple Array Index * prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
* Uses: term - array variable name * DEBUG("expr.prsidx: Parsed array index '%s'\n", value)
* valtyp - array index value type * if (clbrkt) expect(']');
* value - array index as string * }
* word - array index raw string *
* Sets: term - modified variable name */ /* Process Simple Array Index *
void prcsix(void) { * Uses: term - array variable name *
if (valtyp == LITERAL) { * valtyp - array index value type *
strcat(term, "+"); * value - array index as string *
strcat(term, word); * word - array index raw string *
} * Sets: term - modified variable name */
else if (strcmp(value, "Y")==0) void prcsix(void) {
strcat(term, ",Y"); DEBUG("expr.prcsix: Processing simple array index %s\n", word);
else { if (valtyp == LITERAL) {
if (strcmp(value, "A")==0) asmlin("TAX", ""); strcat(term, "+");
else if (strcmp(value, "X")!=0) asmlin("LDX", value); strcat(term, word);
strcat(term, ",X"); }
} else if (strcmp(value, "Y")==0)
} strcat(term, ",Y");
else {
/* Process Expression Array Index */ if (strcmp(value, "A")==0) asmlin("TAX", "");
void prcxix(void) { else if (strcmp(value, "X")!=0) asmlin("LDX", value);
pshtrm(); //Push Array Variable onto Term Stack strcat(term, ",X");
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term }
prcftm(FALSE); //Process First Term of Expression DEBUG("expr.prcsix: Set term to %s\n", term);
prsrxp(']'); //Parse Rest of Expression }
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term /* Process Expression Array Index */
poptrm(); //Pop Array Variable off Term Stack void prcxix(void) {
strcat(term, ",X"); 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
/* Check for, Parse, and Process Index */ prcftm(FALSE); //Process First Term of Expression
void chkidx(void) { prsrxp(']'); //Parse Rest of Expression
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp) asmlin("TAX", ""); //Transfer Result of Expression to Index Register
if (valtyp == ARRAY) { if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
if (look('-')) { poptrm(); //Pop Array Variable off Term Stack
prcmns(); strcat(term, ",X");
prcxix(); DEBUG("expr.prcxix: Set term to %s\n", term);
} }
else {
prsidx(FALSE); /* Check for, Parse, and Process Index */
if (valtyp > REGISTER) prcxix(); void chkidx(void) {
else if (look(']')) prcsix(); //DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
else prcxix(); if (valtyp == ARRAY) {
} if (look('-')) {
} prcmns();
} prcxix();
}
/* Parse Term in Expression * else {
* Sets: term - the term (as a string) */ prsidx(FALSE);
int prstrm(int alwint) { if (valtyp > REGISTER) prcxix();
DEBUG("Parsing term\n", 0) else if (look(']')) prcsix();
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants else prcxix();
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE) }
strcpy(term, value); }
if (valtyp == VARIABLE && prcvar(alwint)) return TRUE; }
DEBUG("Parsed term %s\n", term)
chkidx(); //Check for Array Index /* Parse Pointer *
skpspc(); * Sets: term - Compiled Pointer */
return FALSE; void prsptr(void) {
} DEBUG("Parsing pointer\n", 0)
expect('*'); //Pointer Dereference Operator
/* Process Address Reference prsvar(FALSE,FALSE); //Parse Variable to Dereference
* Args: adract = Address Action (adacts) * strcpy(term, value);
* symbol = Symbol to Process */ if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
void prcadr(int adract, char* symbol) { DEBUG("expr.prsptr: Set term to %s\n", term);
DEBUG("Processing address '%s'\n", word) }
strcpy(word,"#>(");
strcat(word,symbol); /* Process Pointer Index *
strcat(word,")"); * Sets: term - Compiled Pointer */
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); } void prcptx(char *index) {
else asmlin("LDY", word); DEBUG("expr.prcptx: Processing Dereferenced Pointer %s ", term)
strcpy(word,"#<("); DETAIL("index [%s]\n", index)
strcat(word,symbol); if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
strcat(word,")"); if (strcmp(index,"A")==0) asmlin("TAY", "");
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); } else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
else asmlin("LDX", word); }
}
/* Process Pointer *
/* Parse and Compile Address of Operator * * Sets: term - Compiled Pointer */
* Args: adract = Address Action */ int prcptr(void) {
void prsadr(int adract) { prsptr();
DEBUG("Parsing address\n", 0) DEBUG("expr.prcptr: Dereferencing Pointer %s\n", value);
if (isnpre()) prsnum(0xFFFF); if (valtyp == ARRAY) {
else { prsidx(TRUE);
getwrd(); prcptx(value);
if (fndlab(word)) strcpy(value, word); sprintf(word, "(%s),Y", term);
else prsvrw(FALSE, TRUE); } else if (cmos) {
} sprintf(word, "(%s)", term);
if (adract) prcadr(adract, value); //Compile Address Reference } else {
else strcpy(word, value); //Save for Calling Routine asmlin("LDY","0");
} sprintf(word, "(%s),Y", term);
}
/* Parse and Create Anonymous String * strcpy(term, word);
* Args: adract = Address Action * DEBUG("expr.prcptr: Set term to %s\n", term);
* alwstr = Allow String */ return FALSE; //Return Value Not an Integer
void prsstr(int adract, int alwstr) { }
if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
DEBUG("Parsing anonymous string\n", 0) /* Parse Term in Expression *
newlbl(vrname); //Generate Variable Name * Sets: term - the term (as a string) *
value[0] = 0; //Use Variable Size 0 * Returns: TRUE if term is an integer */
setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size int prstrm(int alwint) {
prsdts(); //Parse Data String DEBUG("Parsing term\n", 0)
setdat(); //Set Variable Data if (match('*')) return prcptr(); //Parse and Deference Pointer
varcnt++; //Increment Variable Counter prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
if (adract) prcadr(adract, vrname); //Compile Address Reference if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
else strcpy(word, vrname); //Save for Calling Routine strcpy(term, value);
} if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
DEBUG("expr.prstrm: Parsed term %s\n", term)
/* Check for and Process Address or String * chkidx(); //Check for Array Index
* Args: adract = Address Action * skpspc();
* alwstr = Allow String */ return FALSE;
int chkadr(int adract, int alwstr) { }
DEBUG("Checking for Address or String\n", 0)
int result = TRUE; /* Process Address Reference
if (look('&')) prsadr(adract); * Args: adract = Address Action (adacts) *
else if (match('"')) prsstr(adract, alwstr); * symbol = Symbol to Process */
else result = FALSE; void prcadr(int adract, char* symbol) {
skpspc(); DEBUG("Processing address '%s'\n", word)
return result; strcpy(word,"#>(");
} strcat(word,symbol);
strcat(word,")");
/* Parse Byte Operator */ if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
void prsbop(void) { else asmlin("LDY", word);
char byteop = getnxt(); strcpy(word,"#<(");
CCMNT(byteop); strcat(word,symbol);
DEBUG("Parsing byte operator '%c'\n", byteop) strcat(word,")");
if (chkadr(FALSE, FALSE)) { if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
sprintf(value, "%c(%s)", byteop, word); else asmlin("LDX", word);
valtyp = LITERAL; }
} else {
reqvar(FALSE); /* Parse and Compile Address of Operator *
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE) * Args: adract = Address Action */
if (byteop == '>') strcat(value, "+1"); void prsadr(int adract) {
vartyp = VTCHAR; DEBUG("Parsing address\n", 0)
} if (isnpre()) prsnum(0xFFFF);
DEBUG("Set value to \"%s\"\n", value) else {
} getwrd();
if (fndlab(word)) strcpy(value, word);
/* Parse Function Argument or Return Values */ else prsvrw(FALSE, TRUE);
void prsfpr(char trmntr) { }
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) { if (adract) prcadr(adract, value); //Compile Address Reference
if (!look('.')) {if (prsxpf(0)) goto prsfne;} else strcpy(word, value); //Save for Calling Routine
if (look(',') && !chkadr(ADLDYX, TRUE)) { }
if (!look('.')) {
if (prstrm(TRUE)) goto prsfne; /* Parse and Create Anonymous String *
asmlin("LDY", term); * Args: adract = Address Action *
} * alwstr = Allow String */
if (look(',')) { void prsstr(int adract, int alwstr) {
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE); DEBUG("Parsing anonymous string\n", 0)
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE); newlbl(vrname); //Generate Variable Name
asmlin("LDX", value); } value[0] = 0; //Use Variable Size 0
} setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size
} prsdts(); //Parse Data String
prsfne: setdat(); //Set Variable Data
expect(trmntr); varcnt++; //Increment Variable Counter
} if (adract) prcadr(adract, vrname); //Compile Address Reference
else strcpy(word, vrname); //Save for Calling Routine
/* Parse function call */ }
void prsfnc(char trmntr) {
DEBUG("Processing Function Call '%s'\n", term) /* Check for and Process Address or String *
//int argexp = FALSE; //Expression(s) in second and third argument * Args: adract = Address Action *
pshtrm(); //Push Function Name onto Term Stack * alwstr = Allow String */
skpchr(); //skip open paren int chkadr(int adract, int alwstr) {
CCMNT('('); DEBUG("Checking for Address or String\n", 0)
prsfpr(')'); //Parse Function Parameters int result = TRUE;
expect(trmntr); if (look('&')) prsadr(adract);
poptrm(); //Pop Function Name off Term Stack else if (match('"')) prsstr(adract, alwstr);
asmlin("JSR", term); else result = FALSE;
skpspc(); skpspc();
} return result;
}
/* Process Integer Variable */
void prcvri(void) { /* Parse Byte Operator */
DEBUG("Processing Integer Variable '%s'\n", value) void prsbop(void) {
asmlin("LDX", value); char byteop = getnxt();
strcat(value, "+1"); CCMNT(byteop);
asmlin("LDY", value); DEBUG("Parsing byte operator '%c'\n", byteop)
} if (chkadr(FALSE, FALSE)) {
sprintf(value, "%c(%s)", byteop, word);
/* Process Variable in Term */ valtyp = LITERAL;
int prcvar(int alwint) { } else {
switch (vartyp) { reqvar(FALSE);
case VTINT: if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE) if (byteop == '>') strcat(value, "+1");
prcvri(); vartyp = VTCHAR;
return TRUE; }
case VTARRAY: DEBUG("Set value to \"%s\"\n", value)
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE) }
prcadr(ADNONE, term);
return TRUE; /* Parse Function Argument or Return Values */
case VTSTRUCT: void prsfpr(char trmntr) {
if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE) int pusha = 0; int pushy = 0; //A and Y Arguments Pushed
prcadr(ADNONE, term); if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
return TRUE; if (look('.')) pusha = 255;
default: else {if (prsxpf(0)) goto prsfne;}
return FALSE; if (look(',') && !chkadr(ADLDYX, TRUE)) {
} if (look('.')) {
} pushy = -1;
}
/* Process first term of expression */ else {
int prcftm(int alwint) { if (look('(')) {
DEBUG("Processing first term '%s'\n", value) if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
strcpy(term, value); prsxpr(')'); asmlin("TAY", ""); //Evaluate Expression, and Copy to Y
if (valtyp == VARIABLE && prcvar(alwint)) return TRUE; }
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function else {
else if (wordis("A")) return FALSE; if (prstrm(TRUE)) goto prsfne;
else if (wordis("X")) asmlin("TXA", ""); asmlin("LDY", term);
else if (wordis("Y")) asmlin("TYA", ""); }
else { chkidx(); asmlin("LDA", term); } }
return FALSE; if (look(',')) {
} if (look('(')) {
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
/* Parse first term of expession * if (pushy==0) {pushy = 1; asmlin("PHA",""); asmlin("PHY","");} //Save Y on Stack
* First term can include function calls */ prsxpr(')'); asmlin("TAX", ""); //Evaluate Expression, and Copy to X
int prsftm(int alwint) { }
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants else {
return prcftm(alwint); 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);
/* Process Arithmetic or Bitwise Operator * asmlin("LDX", value);
* 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 prsfne:
case '-': asmlin("SEC", ""); asmlin("SBC", term); break; //Subtraction if (pushy==1) {asmlin("PLA",""); asmlin("TAY","");} //Pull Y Off Stack
case '&': asmlin("AND", term); break; //Bitwise AND if (pusha==1) asmlin("PLA",""); //Pull A Off Stack
case '!': //For systems that don't have pipe in character set expect(trmntr);
case '|': asmlin("ORA", term); break; //Bitwise OR }
case '^': asmlin("EOR", term); break; //Bitwise XOR
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE) /* Parse function call */
} void prsfnc(char trmntr) {
oper = 0; DEBUG("Processing Function Call '%s'\n", term)
} //int argexp = FALSE; //Expression(s) in second and third argument
pshtrm(); //Push Function Name onto Term Stack
/* Parse Remainder of Expression */ skpchr(); //skip open paren
void prsrxp(char trmntr) { CCMNT('(');
skpspc(); prsfpr(')'); //Parse Function Parameters
while (isoper()) { expect(trmntr);
trmcnt++; //Increment Expression Depth poptrm(); //Pop Function Name off Term Stack
prsopr(); //Parse Operator asmlin("JSR", term);
prstrm(FALSE); //Parse Term skpspc();
prcopr(); //Process Operator }
trmcnt--; //Decrement Expression Depth
} /* Process Integer Variable */
expect(trmntr); void prcvri(void) {
} DEBUG("Processing Integer Variable '%s'\n", value)
asmlin("LDX", value);
int prsxpp(char trmntr, int alwint) { strcat(value, "+1");
DEBUG("Parsing expression\n", 0) asmlin("LDY", value);
skpspc(); }
trmcnt = 0; //Initialize Expression Depth
if (match('-')) prcmns(); //Process Unary Minus /* Process Integer Variable in Term *
else if (prsftm(alwint)) return TRUE; //Parse First Term * Args: alwint = Allow Integer-Like Variable *
prsrxp(trmntr); //Parse Remainder of Express * Returns: Integer-Like Variable Processed - TRUE/FALSE */
return FALSE; int prcivr(int alwint) {
} switch (vartyp) {
case VTINT:
/* Parse and compile expression */ if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
void prsxpr(char trmntr) { prcvri();
prsxpp(trmntr, FALSE); return TRUE;
} case VTARRAY:
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE)
/* Parse and compile function parameter expression * prcadr(ADNONE, term);
* Returns: TRUE if Integer Expression */ return TRUE;
int prsxpf(char trmntr) { case VTSTRUCT:
return prsxpp(trmntr, TRUE); if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE)
} prcadr(ADNONE, term);
return TRUE;
/* Parse and Compile Integer Expression * default:
* (Address, Integer Literal, Variable, * return FALSE;
* Struct Member, or Function) * }
* Args: trmntr - expression terminator * }
* asmxpr - assemble expression *
* Sets: value - Parsed Value or Symbol */ /* Process first term of expression */
void prsxpi(char trmntr, int asmxpr) { int prcftm(int alwint) {
skpspc(); DEBUG("Processing first term '%s'\n", value)
DEBUG("Parsing integer expression\n", 0) strcpy(term, value);
if (!chkadr(TRUE, FALSE)) { if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
if (isnpre()) { if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
DEBUG("Parsing Integer Literal\n", 0) else if (wordis("A")) return FALSE;
int number = prsnum(0xFFFF); //Parse Number into value else if (wordis("X")) asmlin("TXA", "");
if (asmxpr) { else if (wordis("Y")) asmlin("TYA", "");
sprintf(value, "#%d", number & 0xFF); asmlin("LDX", value); else { chkidx(); asmlin("LDA", term); }
sprintf(value, "#%d", number >> 8); asmlin("LDY", value); return FALSE;
} }
} else if (isalph()) {
prsvar(FALSE, TRUE); /* Parse first term of expession *
if (valtyp == FUNCTION) { * First term can include function calls */
strcpy(term, value); int prsftm(int alwint) {
prsfnc(0); //Parse Expression Function DEBUG("Parsing first term\n", 0)
} else if (valtyp == STRUCTURE) { if (match('*')) {
prsmbr(value); prcptr(); //Parse and Deference Pointer
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE) asmlin("LDA", term);
} else if (valtyp == VARIABLE && vartyp == VTINT) { return FALSE;
if (asmxpr) prcvri(); //Process Integer Variable }
} else { prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE) return prcftm(alwint);
} }
} else {
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE); /* Process Arithmetic or Bitwise Operator *
} * and the term that follows it */
} void prcopr(void) {
expect(trmntr); 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) {
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);
}

View File

@ -1,30 +1,32 @@
/********************************** /**********************************
* C02 Expession Parsing Routines * * C02 Expession Parsing Routines *
**********************************/ **********************************/
enum adacts {ADNONE, ADLDYX, ADPUSH}; enum adacts {ADNONE, ADLDYX, ADPUSH};
char term[255]; //Term parsed from equation char term[255]; //Term parsed from equation
char oprstk[MAXTRM]; //Operator Stack char oprstk[MAXTRM]; //Operator Stack
char trmstk[MAXTRM][VARLEN+1]; //Function/Index Terms Stack char trmstk[MAXTRM][VARLEN+1]; //Function/Index Terms Stack
int trmidx; //Next Index in Stack int trmidx; //Next Index in Stack
int trmcnt; //Number of total terms in current expression int trmcnt; //Number of total terms in current expression
int chkadr(int adract, int alwstr); //Check for and Process Address or String int chkadr(int adract, int alwstr); //Check for and Process Address or String
void chkidx(); //Check for, Parse, and Process Index void chkidx(); //Check for, Parse, and Process Index
int prcftm(int alwint); //Process First Term int prcftm(int alwint); //Process First Term
void prcvri(void); //Process Integer Variable void prcptx(char *index); //Process Pointer Index
int prcvar(int alwint); //Process Variable in Term void prcvri(void); //Process Integer Variable
void prsadr(int adract); //Parse and Compile Address of Operator int prcivr(int alwint); //Process Integer Variable in Term
void prsbop(void); //Parse Byte Operator void prsadr(int adract); //Parse and Compile Address of Operator
void prsval(int alwreg, int alwcon); //Parse Value void prsbop(void); //Parse Byte Operator
void prsfnc(char trmntr); //Parse function call void prsval(int alwreg, int alwcon); //Parse Value
void prsfpr(char trmntr); //Parse Function Paraeters or Return void prsfnc(char trmntr); //Parse function call
void prsidx(); //Parse Array Index void prsfpr(char trmntr); //Parse Function Paraeters or Return
int prstrm(int alwint); //Parse Term in Expression void prsidx(); //Parse Array Index
void prsrxp(char trmntr); //Parse Rest of Expression void prsptr(void); //Parse Pointer
int prsxpf(char trmntr); //Parse Expression in Function Call int prstrm(int alwint); //Parse Term in Expression
void prsxpr(char trmntr); //Parse Expression void prsrxp(char trmntr); //Parse Rest of Expression
void prsxpi(char trmntr, int asmxpr); //Parse Integer Expression int prsxpf(char trmntr); //Parse Expression in Function Call
void prsxpr(char trmntr); //Parse Expression
void prsxpi(char trmntr, int asmxpr); //Parse Integer Expression

View File

@ -1,102 +1,102 @@
/****************************** /******************************
* C02 File Handling Routines * * C02 File Handling Routines *
******************************/ ******************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "files.h" #include "files.h"
/* Error - Print textual description of system error * /* Error - Print textual description of system error *
* and exit with system error code */ * and exit with system error code */
void extsys(char *s) { void extsys(char *s) {
perror(s); perror(s);
exterr(errno); exterr(errno);
} }
/* Open Source File * /* Open Source File *
* Uses: srcnam - Source File Name * * Uses: srcnam - Source File Name *
* Sets: srcfil - Source File Handle */ * Sets: srcfil - Source File Handle */
void opnsrc(void) { void opnsrc(void) {
DEBUG("Processing Source File Name '%s'\n", srcnam) DEBUG("Processing Source File Name '%s'\n", srcnam)
if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02" if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02"
DEBUG("opening Source File '%s'\n", srcnam) DEBUG("opening Source File '%s'\n", srcnam)
srcfil = fopen(srcnam, "r"); //open file srcfil = fopen(srcnam, "r"); //open file
if (srcfil == NULL) extsys(srcnam); if (srcfil == NULL) extsys(srcnam);
} }
/* Close Source File */ /* Close Source File */
void clssrc(void) { fclose(srcfil); } void clssrc(void) { fclose(srcfil); }
/* Open Output File * /* Open Output File *
* Uses: outnam - Output File Name * * Uses: outnam - Output File Name *
* Sets: outfil - Output File Handle */ * Sets: outfil - Output File Handle */
void opnout(void) { void opnout(void) {
DEBUG("Processing Output File Name '%s'\n", outnam) DEBUG("Processing Output File Name '%s'\n", outnam)
if (strlen(outnam) == 0) //if Output File not specified if (strlen(outnam) == 0) //if Output File not specified
{ {
strcpy(outnam, srcnam); //copy Source Name to Ouput Name strcpy(outnam, srcnam); //copy Source Name to Ouput Name
char *dot = strrchr(outnam, '.'); //find extension char *dot = strrchr(outnam, '.'); //find extension
if (dot != NULL) *dot = 0; //and remove it if (dot != NULL) *dot = 0; //and remove it
DEBUG("Set Output File Name to '%s'\n", outnam) DEBUG("Set Output File Name to '%s'\n", outnam)
} }
if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm" if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm"
DEBUG("Opening Output File '%s'\n", outnam) DEBUG("Opening Output File '%s'\n", outnam)
outfil = fopen(outnam, "w"); //open file outfil = fopen(outnam, "w"); //open file
if (outfil == NULL) extsys(outnam); if (outfil == NULL) extsys(outnam);
} }
/* Close Output File */ /* Close Output File */
void clsout(void) { void clsout(void) {
fprintf(outfil, "\n"); fprintf(outfil, "\n");
fclose(outfil); fclose(outfil);
} }
/* Open Log File * /* Open Log File *
* Uses: srcnam - Source File Name * * Uses: srcnam - Source File Name *
* Sets: logfil - Log File Handle */ * Sets: logfil - Log File Handle */
void opnlog(void) { void opnlog(void) {
strcpy(lognam, srcnam); //set Log File Name to Source File Name strcpy(lognam, srcnam); //set Log File Name to Source File Name
char *dot = strrchr(lognam, '.'); //find file extension char *dot = strrchr(lognam, '.'); //find file extension
if (dot != NULL) *dot = 0; //and remove it if (dot != NULL) *dot = 0; //and remove it
strcat(lognam, ".log"); //add extension ".log" strcat(lognam, ".log"); //add extension ".log"
DEBUG("Opening Log File '%s'\n", lognam) DEBUG("Opening Log File '%s'\n", lognam)
logfil = fopen(lognam, "w"); logfil = fopen(lognam, "w");
if (logfil == NULL) extsys(lognam); if (logfil == NULL) extsys(lognam);
} }
/* Close Log File * /* Close Log File *
* Uses: logfil - Log File Handle */ * Uses: logfil - Log File Handle */
void clslog(void) { fclose(logfil); } void clslog(void) { fclose(logfil); }
/* Open Include file * /* Open Include file *
* Uses: incnam - Include File Name * * Uses: incnam - Include File Name *
* subnam - Include File Name (Subdirectory) * * subnam - Include File Name (Subdirectory) *
* Sets: incfil - Include File Handle */ * Sets: incfil - Include File Handle */
void opninc(int chksub) void opninc(int chksub)
{ {
if (chksub) { if (chksub) {
for (subidx=0; subidx<subcnt; subidx++) { for (subidx=0; subidx<subcnt; subidx++) {
DEBUG("Attempting to open include file '%s'\n", subnam[subidx]) DEBUG("Attempting to open include file '%s'\n", subnam[subidx])
incfil = fopen(subnam[subidx], "r"); incfil = fopen(subnam[subidx], "r");
if (incfil == NULL) DEBUG("Open failed\n", 0) if (incfil == NULL) DEBUG("Open failed\n", 0)
else { else {
strcpy(incnam, subnam[subidx]); strcpy(incnam, subnam[subidx]);
DEBUG("INCNAM set to '%s'\n", incnam); DEBUG("INCNAM set to '%s'\n", incnam);
return; return;
} }
} }
} }
DEBUG("Opening include file '%s'\n", incnam) DEBUG("Opening include file '%s'\n", incnam)
incfil = fopen(incnam, "r"); incfil = fopen(incnam, "r");
if (incfil == NULL) extsys(incnam); if (incfil == NULL) extsys(incnam);
} }
/* Close Include File * /* Close Include File *
* Uses: incfil - Include File Handle */ * Uses: incfil - Include File Handle */
void clsinc(void) { fclose(incfil); } void clsinc(void) { fclose(incfil); }

View File

@ -1,27 +1,27 @@
/****************************** /******************************
* C02 File Handling Routines * * C02 File Handling Routines *
******************************/ ******************************/
FILE *srcfil; //Source File (Input) FILE *srcfil; //Source File (Input)
FILE *outfil; //Assembler File (Output) FILE *outfil; //Assembler File (Output)
FILE *logfil; //Log File (Output) FILE *logfil; //Log File (Output)
FILE *incfil; //Include File Handle FILE *incfil; //Include File Handle
FILE *inpfil; //Current Input File FILE *inpfil; //Current Input File
char srcnam[FNAMLEN]; //Source File Name char srcnam[FNAMLEN]; //Source File Name
char outnam[FNAMLEN]; //Assembler File Name char outnam[FNAMLEN]; //Assembler File Name
char lognam[FNAMLEN]; //Log File Name char lognam[FNAMLEN]; //Log File Name
char incnam[FNAMLEN]; //Include File Name char incnam[FNAMLEN]; //Include File Name
char subnam[SUBMAX][FNAMLEN]; //Include File Name (Subdirectory) char subnam[SUBMAX][FNAMLEN]; //Include File Name (Subdirectory)
void opnsrc(); //Open Source File void opnsrc(); //Open Source File
void clssrc(); //Close Source File void clssrc(); //Close Source File
void opnout(); //Open Output File void opnout(); //Open Output File
void clsout(); //Close Output File void clsout(); //Close Output File
void opnlog(); //Open Log File void opnlog(); //Open Log File
void clslog(); //Close Log File void clslog(); //Close Log File
void opninc(int chksub); //Open Include File void opninc(int chksub); //Open Include File
void clsinc(); //Close Include File void clsinc(); //Close Include File

View File

@ -37,8 +37,8 @@ void pincnm(void) {
sublen[subidx] = strlen(subnam[subidx]); sublen[subidx] = strlen(subnam[subidx]);
subnam[subidx][sublen[subidx]++] = '/'; subnam[subidx][sublen[subidx]++] = '/';
} }
dlmtr = '>';
} }
dlmtr = '>';
} }
else if (dlmtr != '"') else if (dlmtr != '"')
ERROR("Unexpected character '%c' after include\n", dlmtr, EXIT_FAILURE) ERROR("Unexpected character '%c' after include\n", dlmtr, EXIT_FAILURE)
@ -86,7 +86,7 @@ void pdefin(void) {
/* Parse ASCII Subdirective */ /* Parse ASCII Subdirective */
void pascii(void) { void pascii(void) {
getwrd(); //Get Pragma Subdirective getwrd(); //Get Subdirective Argument
DEBUG("Parsing subdirective '%s'\n", word) DEBUG("Parsing subdirective '%s'\n", word)
if (wordis("INVERT")) if (wordis("INVERT"))
invasc = TRUE; invasc = TRUE;
@ -146,7 +146,7 @@ void pprgma(void) {
else if (wordis("ORIGIN")) else if (wordis("ORIGIN"))
porign(); //Parse Origin porign(); //Parse Origin
else if (wordis("PADDING")) else if (wordis("PADDING"))
ppddng(); //Parse Origin ppddng(); //Parse Padding
else if (wordis("RAMBASE")) else if (wordis("RAMBASE"))
prambs(); //Parse RamBase prambs(); //Parse RamBase
else if (wordis("VARTABLE")) else if (wordis("VARTABLE"))

View File

@ -1,14 +1,14 @@
/************************************* /*************************************
* C02 Include File Parsing Routines * * C02 Include File Parsing Routines *
*************************************/ *************************************/
char line[255]; /*Entire line parsed from include file*/ char line[255]; /*Entire line parsed from include file*/
void logcon(); //Print Constant Table to Log File void logcon(); //Print Constant Table to Log File
void pdefin(); //Process define directive void pdefin(); //Process define directive
void pdefin(); //Process define directive void pdefin(); //Process define directive
void penumd(); //Process enum directive void penumd(); //Process enum directive
void phdrfl(); //Process command line header file void phdrfl(); //Process command line header file
void pincfl(); //Process include file void pincfl(); //Process include file
void pprgma(); //Parse Pragma Directive void pprgma(); //Parse Pragma Directive
void setsrc(); ///Set Input to Source File void setsrc(); ///Set Input to Source File

View File

@ -1,153 +1,153 @@
/****************************************************** /******************************************************
* C02 Label Parsing, Generation, and Lookup Routines * * C02 Label Parsing, Generation, and Lookup Routines *
******************************************************/ ******************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "files.h" #include "files.h"
#include "asm.h" #include "asm.h"
#include "parse.h" #include "parse.h"
#include "label.h" #include "label.h"
#include "vars.h" #include "vars.h"
/* Add New Program Label */ /* Add New Program Label */
void addlab(char *name) { void addlab(char *name) {
if (fndvar(name)) ERROR("Label %s conflicts with variable with same name", name, EXIT_FAILURE) if (fndvar(name)) ERROR("Label %s conflicts with variable with same name", name, EXIT_FAILURE)
if (fndlab(name)) ERROR("Duplicate program label %s\n", name, EXIT_FAILURE) if (fndlab(name)) ERROR("Duplicate program label %s\n", name, EXIT_FAILURE)
DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt) DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt)
strcpy(labnam[labcnt++], name); strcpy(labnam[labcnt++], name);
} }
int fndlab(char *name) { int fndlab(char *name) {
DEBUG("Looking for Program Label %s\n", name) DEBUG("Looking for Program Label %s\n", name)
for (labidx=0; labidx<labcnt; labidx++) for (labidx=0; labidx<labcnt; labidx++)
if (strcmp(labnam[labidx], name) == 0) return TRUE; if (strcmp(labnam[labidx], name) == 0) return TRUE;
DEBUG("Label %s Not Found\n", name) DEBUG("Label %s Not Found\n", name)
return FALSE; return FALSE;
} }
/* Print Program Label Table to Log File */ /* Print Program Label Table to Log File */
void loglab(void) { void loglab(void) {
int i; int i;
fprintf(logfil, "\n%-10s\n", "Label"); fprintf(logfil, "\n%-10s\n", "Label");
for (i=0; i<labcnt; i++) { for (i=0; i<labcnt; i++) {
fprintf(logfil, "%-10s\n", labnam[i]); fprintf(logfil, "%-10s\n", labnam[i]);
} }
} }
const char lblflg[] = {LFNONE, LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE, LFNONE}; //Label Type Flags const char lblflg[] = {LFNONE, LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE, LFNONE}; //Label Type Flags
// enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types // enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
/* Find Last Label of Specified Types * /* Find Last Label of Specified Types *
* Args: lbtyp1: First label type * * Args: lbtyp1: First label type *
* lbtyp2: Second label type * * lbtyp2: Second label type *
* Sets: tmplbl - Label name * * Sets: tmplbl - Label name *
* Returns: Index into label table * * Returns: Index into label table *
* (-1 if not found) */ * (-1 if not found) */
int lstlbl(int lbflag) { int lstlbl(int lbflag) {
int i; int i;
DEBUG("Searching for label flag %d\n", lbflag) DEBUG("Searching for label flag %d\n", lbflag)
for (i = lblcnt - 1; i>-1; i--) for (i = lblcnt - 1; i>-1; i--)
if (lblflg[lbltyp[i]] == lbflag) break; if (lblflg[lbltyp[i]] == lbflag) break;
DEBUG("Search produced label index %d\n", i) DEBUG("Search produced label index %d\n", i)
if (i>=0) strcpy(tmplbl, lblnam[i]); if (i>=0) strcpy(tmplbl, lblnam[i]);
return i; return i;
} }
/* Set Block Flag for Last Label */ /* Set Block Flag for Last Label */
void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; } void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; }
/* Set label for next line of * /* Set label for next line of *
* Assembly Language Code * * Assembly Language Code *
* to word */ * to word */
void setlbl(char *lblset) { void setlbl(char *lblset) {
DEBUG("Setting Label '%s'\n", lblset) DEBUG("Setting Label '%s'\n", lblset)
if (strlen(lblasm) > 0) { if (strlen(lblasm) > 0) {
DEBUG("Emitting Label '%s'\n'", lblasm); DEBUG("Emitting Label '%s'\n'", lblasm);
asmlin("",""); //Emit Block End Label on it's own line asmlin("",""); //Emit Block End Label on it's own line
} }
if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE) if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
strcpy(lblasm, lblset); strcpy(lblasm, lblset);
} }
/* Parse Program Label */ /* Parse Program Label */
void prslab(void) { void prslab(void) {
DEBUG("Parsing Label '%s''\n", word) DEBUG("Parsing Label '%s''\n", word)
addlab(word); addlab(word);
CCMNT(nxtchr); CCMNT(nxtchr);
skpchr(); //skip ':' skpchr(); //skip ':'
} }
/* generate new label */ /* generate new label */
void newlbl(char* lbname) { void newlbl(char* lbname) {
sprintf(lbname, LBLFMT, lblnxt++); sprintf(lbname, LBLFMT, lblnxt++);
DEBUG("Generated new label '%s'\n", lbname) DEBUG("Generated new label '%s'\n", lbname)
} }
/* Check Label Contents * /* Check Label Contents *
* If lbname is blank, generate new * * If lbname is blank, generate new *
* label and copy into lbname */ * label and copy into lbname */
void chklbl(char* lbname) { void chklbl(char* lbname) {
if (lbname[0]) return; if (lbname[0]) return;
newlbl(lbname); newlbl(lbname);
} }
/* Request Label * /* Request Label *
* if label is already set, returns that label * * if label is already set, returns that label *
* else generates new label and sets it */ * else generates new label and sets it */
void reqlbl(char* lbname) { void reqlbl(char* lbname) {
DEBUG("Requesting Label\n",0) DEBUG("Requesting Label\n",0)
if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);} if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);}
else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)} else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)}
} }
/* End Function Block */ /* End Function Block */
void endfnc(void) { void endfnc(void) {
DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn) DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn)
if (!lsrtrn) asmlin("RTS", ""); if (!lsrtrn) asmlin("RTS", "");
infunc = FALSE; infunc = FALSE;
DEBUG("Set infunc to %d\n", infunc) DEBUG("Set infunc to %d\n", infunc)
} }
/* Pop Label from Stack and Emit on Next Line */ /* Pop Label from Stack and Emit on Next Line */
int poplbl(void) { int poplbl(void) {
int lbtype = lbltyp[--lblcnt]; int lbtype = lbltyp[--lblcnt];
DEBUG("Popped label type %d\n", lbtype) DEBUG("Popped label type %d\n", lbtype)
switch (lbtype) { switch (lbtype) {
case LTFUNC: endfnc(); break; //Return From Subroutine case LTFUNC: endfnc(); break; //Return From Subroutine
case LTDO: strcpy(loplbl, lblnam[lblcnt]); break; case LTDO: strcpy(loplbl, lblnam[lblcnt]); break;
case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break; case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break;
case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break; case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break;
case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label
} }
if (lbtype != LTCASE) inblck = lblblk[lblcnt-1]; if (lbtype != LTCASE) inblck = lblblk[lblcnt-1];
return lbtype; return lbtype;
} }
/* Get Top Label and Return Type */ /* Get Top Label and Return Type */
int toplbl(char *rtlbl) { int toplbl(char *rtlbl) {
if (lblcnt) { if (lblcnt) {
strcpy(rtlbl, lblnam[lblcnt-1]); strcpy(rtlbl, lblnam[lblcnt-1]);
DEBUG("Found top label %s\n", rtlbl) DEBUG("Found top label %s\n", rtlbl)
return lbltyp[lblcnt-1]; return lbltyp[lblcnt-1];
} }
rtlbl[0] = 0; //Clear Label rtlbl[0] = 0; //Clear Label
return LTNONE; return LTNONE;
} }
/* Push Label onto Stack * /* Push Label onto Stack *
* Args: lbltyp - Label type * * Args: lbltyp - Label type *
* Uses: curlbl - Label to push */ * Uses: curlbl - Label to push */
void pshlbl(int lbtype, char* lbname) { void pshlbl(int lbtype, char* lbname) {
DEBUG("Pushing label type %d\n", lbtype) DEBUG("Pushing label type %d\n", lbtype)
strcpy(lblnam[lblcnt], lbname); strcpy(lblnam[lblcnt], lbname);
lbltyp[lblcnt] = lbtype; lbltyp[lblcnt] = lbtype;
lblblk[lblcnt++] = FALSE; lblblk[lblcnt++] = FALSE;
DEBUG("Pushed label '%s' onto stack\n", lbname) DEBUG("Pushed label '%s' onto stack\n", lbname)
} }

View File

@ -1,41 +1,41 @@
/****************************************************** /******************************************************
* C02 Label Parsing, Generation, and Lookup Routines * * C02 Label Parsing, Generation, and Lookup Routines *
******************************************************/ ******************************************************/
char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names
int labcnt; //Number of Program Labels int labcnt; //Number of Program Labels
int labidx; //Index into labnam[] int labidx; //Index into labnam[]
char curlbl[LBLLEN+1]; //Most recently generated label char curlbl[LBLLEN+1]; //Most recently generated label
char cmplbl[LBLLEN+1]; //Label for Comparison char cmplbl[LBLLEN+1]; //Label for Comparison
char cndlbl[LBLLEN+1]; //Label for Conditional Code char cndlbl[LBLLEN+1]; //Label for Conditional Code
char endlbl[LBLLEN+1]; //End Label char endlbl[LBLLEN+1]; //End Label
char forlbl[LBLLEN+1]; //For Loop Label char forlbl[LBLLEN+1]; //For Loop Label
char loplbl[LBLLEN+1]; //Skip Increment Label char loplbl[LBLLEN+1]; //Skip Increment Label
char skplbl[LBLLEN+1]; //Skip Increment Label char skplbl[LBLLEN+1]; //Skip Increment Label
char tmplbl[LBLLEN+1]; //Temporary Label char tmplbl[LBLLEN+1]; //Temporary Label
char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table
int lbltyp[MAXLBL+1]; //Label Type int lbltyp[MAXLBL+1]; //Label Type
int lblblk[MAXLBL+1]; //Label Ends Program Block int lblblk[MAXLBL+1]; //Label Ends Program Block
int lblcnt; //Number of Labels in stack int lblcnt; //Number of Labels in stack
int lblnxt; //Sequence of next label to be generated int lblnxt; //Sequence of next label to be generated
char lbltmp[LBLLEN+1]; //Label Temporary Storage char lbltmp[LBLLEN+1]; //Label Temporary Storage
enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types
void addlab(char *name); //Add Program Label void addlab(char *name); //Add Program Label
int fndlab(char *name); //Find Program Label int fndlab(char *name); //Find Program Label
void prslab(); //Parse Program Label void prslab(); //Parse Program Label
void loglab(void); //Print Program Label Table void loglab(void); //Print Program Label Table
void chklbl(char* lbname); //Check Label Contents void chklbl(char* lbname); //Check Label Contents
int lstlbl(int lbflag); //Find Last Label of Specified Types * int lstlbl(int lbflag); //Find Last Label of Specified Types *
void newlbl(char* lbname); //Generate New Block Label void newlbl(char* lbname); //Generate New Block Label
int poplbl(); //Pop Last Label and Emit on Next Line int poplbl(); //Pop Last Label and Emit on Next Line
void pshlbl(int lbtype, char* lbname); //Push Label onto Stack void pshlbl(int lbtype, char* lbname); //Push Label onto Stack
void reqlbl(char* lbname); //Require Label void reqlbl(char* lbname); //Require Label
void setblk(int blkflg); //Set Block Flag for Last Label void setblk(int blkflg); //Set Block Flag for Last Label
void setlbl(char *lblset); //Emit word as Label on Next Line void setlbl(char *lblset); //Emit word as Label on Next Line
int toplbl(char *rtlbl); //Get Top Label and Return Type int toplbl(char *rtlbl); //Get Top Label and Return Type

View File

@ -13,6 +13,8 @@
#include "asm.h" #include "asm.h"
#include "parse.h" #include "parse.h"
#include "label.h" #include "label.h"
#include "expr.h"
#include "stmnt.h"
/* Various tests against nxtchr */ /* Various tests against nxtchr */
int match(char c) {return TF(nxtchr == c);} int match(char c) {return TF(nxtchr == c);}
@ -81,12 +83,15 @@ void skpspc(void) {
* otherwise FALSE */ * otherwise FALSE */
int look(char c) { int look(char c) {
int found; int found;
DEBUG("parse.look: Looking for '%c', ", c);
skpspc(); skpspc();
found = match(c); found = match(c);
if (found) { if (found) {
skpchr(); skpchr();
CCMNT(c); CCMNT(c);
DETAIL("Found\n", 0);
} }
else DETAIL("Not found\n", 0);
return found; return found;
} }
@ -136,6 +141,8 @@ void getwrd(void) {
while (isanum()) word[wrdlen++] = toupper(getnxt()); while (isanum()) word[wrdlen++] = toupper(getnxt());
word[wrdlen] = 0; word[wrdlen] = 0;
ACMNT(word); ACMNT(word);
DEBUG("parse.getwrd: Read word '%s' ", word)
DETAIL("delimited by '%c'\n", nxtchr)
} }
/* Escape Character */ /* Escape Character */
@ -154,31 +161,41 @@ char escape(char c) {
} }
} }
/* Escape Numeric Literal */
char escnum(void) {
DEBUG("Escaping numeric literal\n", 0);
char c = prsnum(0xff);
return c;
}
/* Get String * /* Get String *
* Sets: word = parsed string * Sets: word = parsed string
* wrdlen = length of string (including terminator) */ * wrdlen = length of string (including terminator) */
void getstr(void) { void getstr(void) {
char strdel; char strdel;
int escnxt = FALSE; int escnxt = FALSE;
wrdlen = 0; pstlen = 0;
DEBUG("Parsing string\n", 0) DEBUG("Parsing string\n", 0)
strdel = getnxt(); //Get String Delimiter strdel = getnxt(); //Get String Delimiter
CCMNT(strdel); CCMNT(strdel);
while(!match(strdel) || escnxt) { while(!match(strdel) || escnxt) {
if (isnl()) ERROR("String Not Terminated", 0, EXIT_FAILURE)
CCMNT(nxtchr); CCMNT(nxtchr);
if (escnxt) { if (escnxt) {
word[wrdlen++] = escape(getnxt()); if (isnpre()) pstrng[pstlen++] = escnum();
else pstrng[pstlen++] = escape(getnxt());
escnxt = FALSE; escnxt = FALSE;
} }
else { else {
if (match('\\')) escnxt = TRUE; if (match('\\')) escnxt = TRUE;
else word[wrdlen++] = prcchr(nxtchr); else pstrng[pstlen++] = prcchr(nxtchr);
skpchr(); skpchr();
} }
} }
skpchr(); //Skip End Delimiter skpchr(); //Skip End Delimiter
CCMNT(strdel); CCMNT(strdel);
word[wrdlen] = 0; pstrng[pstlen] = 0;
strcpy(word,pstrng); wrdlen=pstlen;
} }
/* Read Binary number from input file * /* Read Binary number from input file *
@ -357,21 +374,24 @@ void poperr(char* name) {
} }
/* Process Post Operator */ /* Process Post Operator */
void prcpst(int isint, char* name, char *index) { void prcpst(int isint, char* name, char *index, char indtyp, char ispntr) {
DEBUG("Processing post operation '%c'\n", oper) DEBUG("parse.prcpst: Processing post operation '%c'\n", oper)
if (ispntr) ERROR("Post Operation on dereferenced pointer %s not supported\n", name, EXIT_FAILURE)
//sprintf(word,"(%s),Y", name); strcpy(name, word); }
char name1[VARLEN+3]; char name1[VARLEN+3];
strcpy(name1, name); strcat(name1, "+1"); strcpy(name1, name); strcat(name1, "+1");
if (strlen(index)) { if (strlen(index)) {
asmlin("LDX", index); if (ispntr) prcptx(index); //Process Pointer Index
strcat(name,",X"); else prcidx(indtyp, name, index); //Process Index
} }
else if (ispntr) asmlin("LDY","0");
switch(oper) { switch(oper) {
case '+': case '+':
if (strcmp(name, "X")==0) asmlin("INX", ""); if (strcmp(name, "X")==0) asmlin("INX", "");
else if (strcmp(name, "Y")==0) asmlin("INY", ""); else if (strcmp(name, "Y")==0) asmlin("INY", "");
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit INC, 6502 does not else if (strcmp(name, "A")==0 && !cmos) poperr(name); //65C02 supports implicit INC, 6502 does not
else { else {
asmlin("INC", name); asmlin("INC", word);
if (isint) { if (isint) {
newlbl(skplbl); newlbl(skplbl);
asmlin("BNE", skplbl); asmlin("BNE", skplbl);
@ -383,7 +403,7 @@ void prcpst(int isint, char* name, char *index) {
case '-': case '-':
if (strcmp(name, "X")==0) asmlin("DEX", ""); if (strcmp(name, "X")==0) asmlin("DEX", "");
else if (strcmp(name, "Y")==0) asmlin("DEY", ""); else if (strcmp(name, "Y")==0) asmlin("DEY", "");
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit DEC, 6502 does not else if (strcmp(name, "A")==0 && !cmos) poperr(name); //65C02 supports implicit DEC, 6502 does not
else { else {
if (isint) { if (isint) {
newlbl(skplbl); newlbl(skplbl);
@ -392,7 +412,7 @@ void prcpst(int isint, char* name, char *index) {
asmlin("DEC", name1); asmlin("DEC", name1);
setlbl(skplbl); setlbl(skplbl);
} }
asmlin("DEC", name); asmlin("DEC", name);
} }
break; break;
case '<': case '<':
@ -419,7 +439,7 @@ void prcpst(int isint, char* name, char *index) {
} }
/* Parse Post Operator */ /* Parse Post Operator */
int prspst(char trmntr, int isint, char* name, char* index) { int prspst(char trmntr, int isint, char* name, char* index, char indtyp, char ispntr) {
oper = getnxt(); oper = getnxt();
CCMNT(oper); CCMNT(oper);
DEBUG("Checking for post operation '%c'\n", oper) DEBUG("Checking for post operation '%c'\n", oper)
@ -427,7 +447,7 @@ int prspst(char trmntr, int isint, char* name, char* index) {
skpchr(); skpchr();
CCMNT(oper); CCMNT(oper);
expect(trmntr); expect(trmntr);
prcpst(isint, name, index); //Process Post-Op prcpst(isint, name, index, indtyp, ispntr); //Process Post-Op
return 0; return 0;
} }
DEBUG("Not a post operation\n", 0) DEBUG("Not a post operation\n", 0)

View File

@ -55,7 +55,7 @@ int prsbyt(); //Parse Numeric Byte
void prslit(); //Parse Literal void prslit(); //Parse Literal
int prsnum(int maxval); //Parse Numeric int prsnum(int maxval); //Parse Numeric
void prsopr(); //Parse Arithmetic Operator void prsopr(); //Parse Arithmetic Operator
int prspst(char trmntr, int isint, char* name, char* index); //Parse Post Operator int prspst(char trmntr, int isint, char* name, char* index, char indtyp, char ispntr); //Parse Post Operator
int psizof(void); //Parse SizeOf Operator int psizof(void); //Parse SizeOf Operator
int pidxof(void); //Parse SizeOf Operator int pidxof(void); //Parse SizeOf Operator
void skpchr(); //Skip Next Character void skpchr(); //Skip Next Character

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,23 @@
/************************************ /************************************
* C02 Statement Compiling Routines * * C02 Statement Compiling Routines *
************************************/ ************************************/
char asnvar[VARLEN+1]; //Assigned Variable Name char asnvar[VARLEN+1]; //Assigned Variable Name
int asntyp; //Assigned Variable Type int asntyp; //Assigned Variable Type
char asnidx[VARLEN+1] ; //Assigned Variable Index char asnidx[VARLEN+1] ; //Assigned Variable Index
int asnivt; //Assigned Index Variable Type int asnivt; //Assigned Index Variable Type
char ysnvar[VARLEN+1]; //Assigned Y Variable Name char ysnvar[VARLEN+1]; //Assigned Y Variable Name
char ysnidx[VARLEN+1] ; //Assigned Y Variable Index char ysnidx[VARLEN+1] ; //Assigned Y Variable Index
int ysnivt; //Assigned Y Index Variable Type int ysnivt; //Assigned Y Index Variable Type
char xsnvar[VARLEN+1]; //Assigned X Variable Name char xsnvar[VARLEN+1]; //Assigned X Variable Name
char xsnidx[VARLEN+1] ; //Assigned X Variable Index char xsnidx[VARLEN+1] ; //Assigned X Variable Index
int xsnivt; //Assigned X Index Variable Type int xsnivt; //Assigned X Index Variable Type
char xstmnt[LINELEN]; //Expected Statement char xstmnt[LINELEN]; //Expected Statement
void bgnblk(char blkchr); //End Program Block void bgnblk(char blkchr); //End Program Block
void endblk(int blkflg); //End Program Block void endblk(int blkflg); //End Program Block
void pdowhl(); //Parse and Compile WHILE after DO void prcasp(char trmntr); //Process Pointer Assignment
void pstmnt(); //Parse and Compile Program Statement void prcidx(int idxtyp, char *name, char *index);
void pdowhl(); //Parse and Compile WHILE after DO
void pstmnt(); //Parse and Compile Program Statement

View File

@ -21,7 +21,7 @@
* varcnt if not found * * varcnt if not found *
* Returns: TRUE if found, otherwise FALSE */ * Returns: TRUE if found, otherwise FALSE */
int fndvar(char *name) { int fndvar(char *name) {
DEBUG("Looking up variable '%s'\n", name) DEBUG("vars,fndvar: Looking up variable '%s'\n", name)
for (varidx=0; varidx<varcnt; varidx++) { for (varidx=0; varidx<varcnt; varidx++) {
if (strcmp(vartbl[varidx].name, name) == 0) { if (strcmp(vartbl[varidx].name, name) == 0) {
memcpy(&varble, &vartbl[varidx], sizeof(varble)); memcpy(&varble, &vartbl[varidx], sizeof(varble));
@ -37,7 +37,7 @@ int fndvar(char *name) {
* sctcnt if not found * * sctcnt if not found *
* Returns: TRUE if found, otherwise FALSE */ * Returns: TRUE if found, otherwise FALSE */
int fndstc(char *name) { int fndstc(char *name) {
DEBUG("Looking up struct '%s'\n", name) DEBUG("vars.fndstc: Looking up struct '%s'\n", name)
for (stcidx=0; stcidx<stccnt; stcidx++) for (stcidx=0; stcidx<stccnt; stcidx++)
if (strcmp(strcts[stcidx].name, name) == 0) return TRUE; if (strcmp(strcts[stcidx].name, name) == 0) return TRUE;
return FALSE; return FALSE;
@ -48,7 +48,7 @@ int fndstc(char *name) {
* stmcnt if not found * * stmcnt if not found *
* Returns: TRUE if found, otherwise FALSE */ * Returns: TRUE if found, otherwise FALSE */
int fndmbr(int idx, char *name) { int fndmbr(int idx, char *name) {
DEBUG("Looking up member '%s'\n", word) DEBUG("vars.fndmbr: Looking up member '%s'\n", word)
for (mbridx=0; mbridx<mbrcnt; mbridx++) { for (mbridx=0; mbridx<mbrcnt; mbridx++) {
if (membrs[mbridx].strcti != idx) continue; if (membrs[mbridx].strcti != idx) continue;
if (strcmp(membrs[mbridx].name, name) == 0) { if (strcmp(membrs[mbridx].name, name) == 0) {
@ -88,7 +88,7 @@ void prcmbr(char* name) {
getwrd(); //Get Member Name getwrd(); //Get Member Name
valtyp = gettyp(); //Determine Variable Type valtyp = gettyp(); //Determine Variable Type
if (valtyp == FUNCTION) ERROR("Illegal Function Reference\n", 0, EXIT_FAILURE) if (valtyp == FUNCTION) ERROR("Illegal Function Reference\n", 0, EXIT_FAILURE)
DEBUG("Checking for member %s", word) DETAIL(" with struct index %d\n", stcidx) DEBUG("vars.prcmbr: Checking for member %s", word) DETAIL(" with struct index %d\n", stcidx)
if (!fndmbr(stcidx, word)) ERROR("Struct does Not Contain Member %s\n", word, EXIT_FAILURE) if (!fndmbr(stcidx, word)) ERROR("Struct does Not Contain Member %s\n", word, EXIT_FAILURE)
mbrofs += membr.offset; //Get Member Offet in Struct mbrofs += membr.offset; //Get Member Offet in Struct
} }
@ -117,7 +117,7 @@ void prsvrw(int alwreg, int alwcon) {
valtyp = gettyp(); //Determine Variable Type valtyp = gettyp(); //Determine Variable Type
if (valtyp != FUNCTION) chksym(alwreg, alwcon, word); if (valtyp != FUNCTION) chksym(alwreg, alwcon, word);
strcpy(value, word); strcpy(value, word);
DEBUG("Parsed variable '%s'\n", value) DEBUG("vars.prsvrw: Parsed variable '%s'\n", value)
if (valtyp == STRUCTURE) prsmbr(value); if (valtyp == STRUCTURE) prsmbr(value);
} }
@ -143,7 +143,7 @@ void reqvar(int alwary) {
* Returns: variable size (as integer */ * Returns: variable size (as integer */
int pidxof(void) { int pidxof(void) {
expect('?'); //Check for and Skip SizeOf Operator expect('?'); //Check for and Skip SizeOf Operator
DEBUG("Parsing IndexOf operator", 0); DEBUG("vars.pidxof: Parsing IndexOf operator", 0);
mbridx = -1; //Set Member Index to None mbridx = -1; //Set Member Index to None
reqvar(FALSE); //Parse Variable Name to get Size Of reqvar(FALSE); //Parse Variable Name to get Size Of
if (mbridx > -1) { if (mbridx > -1) {
@ -159,7 +159,7 @@ int pidxof(void) {
* Returns: variable size (as integer */ * Returns: variable size (as integer */
int psizof(void) { int psizof(void) {
expect('@'); //Check for and Skip SizeOf Operator expect('@'); //Check for and Skip SizeOf Operator
DEBUG("Parsing SizeOf operator", 0); DEBUG("vars.pdizof: Parsing SizeOf operator", 0);
mbridx = -1; //Set Member Index to None mbridx = -1; //Set Member Index to None
reqvar(FALSE); //Parse Variable Name to get Size Of reqvar(FALSE); //Parse Variable Name to get Size Of
if (mbridx > -1) { if (mbridx > -1) {
@ -181,7 +181,7 @@ int psizof(void) {
/* Parse Data Array */ /* Parse Data Array */
void prsdta(void) { void prsdta(void) {
DEBUG("Parsing Array Data\n", 0) DEBUG("vars.prsdta: Parsing Array Data\n", 0)
int i; int i;
dtype = DTARRY; dtype = DTARRY;
expect('{'); expect('{');
@ -202,7 +202,7 @@ void prsdts(void) {
dtype = DTSTR; dtype = DTSTR;
getstr(); getstr();
strcpy(value, word); strcpy(value, word);
DEBUG("Parsed Data String '%s'\n", value) DEBUG("vars.prsdts: Parsed Data String '%s'\n", value)
} }
/* Store variable data * /* Store variable data *
@ -212,34 +212,34 @@ void prsdts(void) {
void setdat(void) { void setdat(void) {
int i; int i;
if (dtype == DTBYTE) { if (dtype == DTBYTE) {
DEBUG("Setting variable data to '%d'\n", litval) DEBUG("vars.setdat: Setting variable data to '%d'\n", litval)
dlen = 1; dlen = 1;
datvar[dsize++] = litval; datvar[dsize++] = litval;
} }
else if (dtype == DTINT) { else if (dtype == DTINT) {
DEBUG("Setting variable data to '%d'\n", litval) DEBUG("vars.setdat: Setting variable data to '%d'\n", litval)
dlen = 2; dlen = 2;
datvar[dsize++] = litval & 0xFF; datvar[dsize++] = litval & 0xFF;
datvar[dsize++] = litval >> 8; datvar[dsize++] = litval >> 8;
} }
else if (dtype == DTARRY) { else if (dtype == DTARRY) {
DEBUG("Setting variable data to array of length %d\n", dlen) DEBUG("vars.setdat: Setting variable data to array of length %d\n", dlen)
for (i=0; i<dlen; i++) datvar[dsize++] = dattmp[i]; for (i=0; i<dlen; i++) datvar[dsize++] = dattmp[i];
} }
else { else {
DEBUG("Setting variable data to '%s'\n", value) DEBUG("vars.setdat: Setting variable data to '%s'\n", value)
dlen = strlen(value); dlen = strlen(value);
for (i=0; i<dlen; i++) datvar[dsize++] = value[i]; for (i=0; i<dlen; i++) datvar[dsize++] = value[i];
} }
datlen[varcnt] = dlen; datlen[varcnt] = dlen;
dattyp[varcnt] = dtype; dattyp[varcnt] = dtype;
DEBUG("Total data allocated: %d bytes\n", dsize) DEBUG("vars.setdat: Total data allocated: %d bytes\n", dsize)
} }
/* Parse and store variable data */ /* Parse and store variable data */
void prsdat(int m, int t) { void prsdat(int m, int t) {
if ((m & MTCONST) == 0) ERROR("Initialization allowed only on variables declared CONST\n", 0, EXIT_FAILURE); if ((m & MTCONST) == 0) ERROR("Initialization allowed only on variables declared CONST\n", 0, EXIT_FAILURE);
DEBUG("Parsing variable data\n", 0) DEBUG("vars.prsdat: Parsing variable data\n", 0)
skpspc(); skpspc();
if (t == VTINT) {dtype = DTINT; litval = prsnum(0xFFFF); } //Parse Integer if (t == VTINT) {dtype = DTINT; litval = prsnum(0xFFFF); } //Parse Integer
else if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal else if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal
@ -253,7 +253,7 @@ void prsdat(int m, int t) {
* Uses: vrname - variable name * * Uses: vrname - variable name *
* value - variable size */ * value - variable size */
void setvar(int m, int t) { void setvar(int m, int t) {
DEBUG("Added variable '%s' ", vrname); DEBUG("vars.setvar: Added variable '%s' ", vrname);
strncpy(vartbl[varcnt].name, vrname, VARLEN); strncpy(vartbl[varcnt].name, vrname, VARLEN);
vartbl[varcnt].modifr = m; vartbl[varcnt].modifr = m;
vartbl[varcnt].type = t; vartbl[varcnt].type = t;
@ -294,17 +294,17 @@ void addvar(int m, int t) {
} }
else { else {
if (t == VTSTRUCT) { if (t == VTSTRUCT) {
DEBUG("Setting variable size to %d\n", strct.size) DEBUG("vars.addvar: Setting variable size to %d\n", strct.size)
sprintf(value, "%d", strct.size); sprintf(value, "%d", strct.size);
} else if (t == VTINT) { } else if (t == VTINT) {
DEBUG("Setting variable size to %d\n", 2) DEBUG("vars.addvar: Setting variable size to %d\n", 2)
sprintf(value, "%d", 2); sprintf(value, "%d", 2);
} else if (match('[')) { } else if (match('[')) {
t = VTARRAY; //Set Type to Array t = VTARRAY; //Set Type to Array
CCMNT('[') CCMNT('[')
skpchr(); skpchr();
if (alcvar) { if (alcvar) {
DEBUG("Parsing array size\n", 0) DEBUG("vars.addvar: Parsing array size\n", 0)
sprintf(value, "%d", prsnum(0xFF) + 1); sprintf(value, "%d", prsnum(0xFF) + 1);
} }
expect(']'); expect(']');

View File

@ -25,7 +25,7 @@ RGBCLR: LSR ;Divide Red Value by 16
LSR LSR
ORA TEMP0 ;Combine with Green ORA TEMP0 ;Combine with Green
TAX ;and Return as LSB TAX ;and Return as LSB
.DC $7A ;PLY Return Red as MSB PLY ;Return Red as MSB
RTS RTS
;clrrgb(c) - Convert Palette Color to RGB Values ;clrrgb(c) - Convert Palette Color to RGB Values
@ -34,7 +34,7 @@ RGBCLR: LSR ;Divide Red Value by 16
;Returns: A = Red Value (0-255) ;Returns: A = Red Value (0-255)
; Y = Green Value (0-255) ; Y = Green Value (0-255)
; X = Blue Value (0-255) ; X = Blue Value (0-255)
CLRRGB: .DC $5A ;PHY Save MSB CLRRGB: PHY ;Save MSB
TXA ;Copy LSB into Accumulator TXA ;Copy LSB into Accumulator
AND #$F0 ;Isolate Green Value AND #$F0 ;Isolate Green Value
TAY ;and Return in Y TAY ;and Return in Y
@ -73,7 +73,7 @@ GETCLN: LDX $9F25 ;Get Current Data Port
; Y = Green Value (0-255) ; Y = Green Value (0-255)
; X = Blue Value (0-255) ; X = Blue Value (0-255)
GETRGB: JSR GETCLN ;Get Next Color Entry GETRGB: JSR GETCLN ;Get Next Color Entry
JMP CLRRGB ;Convert to RGB and Return BRA CLRRGB ;Convert to RGB and Return
;setclr(idx) - Set Color Entry idx in Palette ;setclr(idx) - Set Color Entry idx in Palette
;Args: A = Color Entry Index ;Args: A = Color Entry Index
@ -106,7 +106,7 @@ SETCLN: TXA ;Copy LSB to Accumulator
;Destroys: TEMP0 ;Destroys: TEMP0
;Affects: A,Y,X ;Affects: A,Y,X
SETRGB: JSR RGBCLR ;Convert RGB to Vera Color Value SETRGB: JSR RGBCLR ;Convert RGB to Vera Color Value
JMP SETCLN ;and Write to Next Palette Entry BRA SETCLN ;and Write to Next Palette Entry
;setidy(idx) - Set Palette Index and Entry Count ;setidy(idx) - Set Palette Index and Entry Count
;Args: A = Palette Index ;Args: A = Palette Index

View File

@ -86,7 +86,7 @@ GETVIM: .DC $04 ;Chroma Disable Bit Mask
GETVSP: LDA #7 ;Set Reg Offset to Vertical Stop GETVSP: LDA #7 ;Set Reg Offset to Vertical Stop
JSR GETHVS ;Read Registers JSR GETHVS ;Read Registers
LSR ;Shift Left One Bit LSR ;Shift Left One Bit
JMP GETVSS ;Then Four More Bits and Mask BRA GETVSS ;Then Four More Bits and Mask
;getvsr() - Get Vertical Start ;getvsr() - Get Vertical Start
;Affects: A ;Affects: A
@ -108,7 +108,7 @@ GETHSP: LDA #5 ;Set Lookup Index to Horizontal Start
JSR GETHVS ;Read Registers JSR GETHVS ;Read Registers
LSR ;Shift Left Two Bits LSR ;Shift Left Two Bits
LSR LSR
JMP GETHSS ;then Mask and Return BRA GETHSS ;then Mask and Return
;gethsr() - Get Horizontal Start ;gethsr() - Get Horizontal Start
;Affects: A ;Affects: A
@ -127,9 +127,9 @@ GETHSS: AND #$03 ;Isolate Bit 0
GETHVS: JSR GETDCB ;Read LSB from Register GETHVS: JSR GETDCB ;Read LSB from Register
PHA ;and Save It PHA ;and Save It
LDA #8 ;Load Register Offset for High Bits LDA #8 ;Load Register Offset for High Bits
STA $9F20 ;Set As Address LSB STA $9F20 ;Set As Address LSB
LDA $9F23,X ;and Read High Bits into A LDA $9F23,X ;and Read High Bits into A
.DC $FA ;PLX ;Restore LSB into X PLX ;Restore LSB into X
RTS RTS
;setbdr() - Set Border Color ;setbdr() - Set Border Color

View File

@ -263,7 +263,7 @@ SETLRM: AND TEMP1 ;Apply Mask
;Returns: A = Contents of Register ;Returns: A = Contents of Register
; X = Current Data Port ; X = Current Data Port
SETLRR: ;.dc $ff SETLRR: ;.dc $ff
.DC $5A ;PHY Save Value to Write PHY ;Save Value to Write
JSR GETLRP ;Get Layer Page in Y JSR GETLRP ;Get Layer Page in Y
PLA ;Restore Value to Write PLA ;Restore Value to Write
JMP SETREG ;and Write to Register JMP SETREG ;and Write to Register
@ -278,7 +278,7 @@ SETLRR: ;.dc $ff
SETLRS: ;.dc $ff SETLRS: ;.dc $ff
JSR SAVREG ;Save Layer, Value, and Mask JSR SAVREG ;Save Layer, Value, and Mask
JSR GETLRS ;Get Layer Size Register JSR GETLRS ;Get Layer Size Register
JMP SETLRM ;Mask in Value and Write Back BRA SETLRM ;Mask in Value and Write Back
;setmod() - Set Layer 0/1 Mode ;setmod() - Set Layer 0/1 Mode
;Args: A = Layer (0/1) ;Args: A = Layer (0/1)

View File

@ -24,7 +24,7 @@ ASLADR: ASL TEMP1 ;Shift LSB Left
ROL TEMP0 ;Rotate Carry Left into LSB ROL TEMP0 ;Rotate Carry Left into LSB
DEX ;Decrement Shift Count DEX ;Decrement Shift Count
BNE ASLADR ;and Loop if Not Zero BNE ASLADR ;and Loop if Not Zero
JMP RESREG ;Return Bank, MSB, LSB BRA RESREG ;Return Bank, MSB, LSB
;chkadr(opts,addr) - Check Vera Address ;chkadr(opts,addr) - Check Vera Address
;Args: A = Bank + Auto-Increment ;Args: A = Bank + Auto-Increment
@ -163,7 +163,7 @@ SETVRB: STA TEMP1 ;Save Bit Pattern
JSR GETVRG ;Read Register JSR GETVRG ;Read Register
AND TEMP0 ;Mask Result AND TEMP0 ;Mask Result
ORA TEMP1 ;Set Bits ORA TEMP1 ;Set Bits
JMP SETBYN ;Write Back to Register BRA SETBYN ;Write Back to Register
;setreg(addr) - Set Register ;setreg(addr) - Set Register
;Args: A = Value to Write ;Args: A = Value to Write

View File

@ -28,7 +28,7 @@ MAXSPR EQU 128 ;Maximum Sprite Index
ADDSPD: JSR SAVREG ;Save Sprite Index, Addend ADDSPD: JSR SAVREG ;Save Sprite Index, Addend
JSR GETSPD ;Read Sprite Address Register JSR GETSPD ;Read Sprite Address Register
JSR ADDTXY ;Add Number to Address JSR ADDTXY ;Add Number to Address
JMP SETSTD ;Write Sprite (TEMP0) Address Register BRA SETSTD ;Write Sprite (TEMP0) Address Register
;subspd(index,number) - Decrement Sprite Address Register ;subspd(index,number) - Decrement Sprite Address Register
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -37,7 +37,7 @@ ADDSPD: JSR SAVREG ;Save Sprite Index, Addend
SUBSPD: JSR SAVREG ;Save Sprite Index, Addend SUBSPD: JSR SAVREG ;Save Sprite Index, Addend
JSR GETSPD ;Read Sprite Address Register JSR GETSPD ;Read Sprite Address Register
JSR ADDTXY ;Add Number to Address JSR ADDTXY ;Add Number to Address
JMP SETSTD ;Write Sprite (TEMP0) Address Register BRA SETSTD ;Write Sprite (TEMP0) Address Register
;clrspr(index) - Set Sprite Attributes ;clrspr(index) - Set Sprite Attributes
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -133,7 +133,7 @@ GETSXF: RTS
GETSPW: JSR GETSPS ;Get Sprite Size Register GETSPW: JSR GETSPS ;Get Sprite Size Register
ASL ;Shift Left 2 Bits ASL ;Shift Left 2 Bits
ASL ASL
JMP GETSP6 ;Then Right 6 Bits BRA GETSP6 ;Then Right 6 Bits
;getsph(index) - Get Sprite Height Specifier ;getsph(index) - Get Sprite Height Specifier
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -327,7 +327,7 @@ SETSPZ: PHA ;Save Sprite Depth
SETSP2: ASL ;Move to Bits 2 and 3 SETSP2: ASL ;Move to Bits 2 and 3
ASL ASL
STX TEMP1 ;Save Bit Mask STX TEMP1 ;Save Bit Mask
JMP SETSP6 ;Set Bits in Control Register BRA SETSP6 ;Set Bits in Control Register
;getspu(index) - Get Sprite Width, Height, and Mode ;getspu(index) - Get Sprite Width, Height, and Mode
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -344,7 +344,7 @@ GETSPU: STA TEMP0 ;Save Sprite Index
LDA TEMP0 ;Retrieve Sprite Index LDA TEMP0 ;Retrieve Sprite Index
JSR GETSPP ;Get Mode JSR GETSPP ;Get Mode
TAX ;Return Mode in X TAX ;Return Mode in X
.DC $7A ;PLY Height in Y PLY ;Height in Y
PLA ;and Width in A PLA ;and Width in A
RTS RTS
@ -364,7 +364,7 @@ GETSPL: JSR GETSPU ;Get Width, Height, Mode and Execute GETSCL
;Affects: A ;Affects: A
;Returns: Y,X = Data Size in Bytes ;Returns: Y,X = Data Size in Bytes
GETSCL: ;.DC $FF ;Debug GETSCL: ;.DC $FF ;Debug
.DC $DA ;PHX Save Mode PHX ;Save Mode
PHA ;Save Width PHA ;Save Width
TYA ;Copy Height to Accumulator TYA ;Copy Height to Accumulator
JSR GETSCS ;Calculate Height in Pixles JSR GETSCS ;Calculate Height in Pixles
@ -376,7 +376,7 @@ GETSLK: ASL TEMP1 ;Multiply LSB
ROL ;and MSB by 2 ROL ;and MSB by 2
DEY ;Decrement Counter DEY ;Decrement Counter
BNE GETSLK ;and Loop if Not Zero BNE GETSLK ;and Loop if Not Zero
.DC $FA ;PLX Retrieve Mode PLX ;Retrieve Mode
BNE GETSSK ;If 0 (4 Bits Per Pixel) BNE GETSSK ;If 0 (4 Bits Per Pixel)
LSR ; Divide MSB LSR ; Divide MSB
ROR TEMP1 ; snd LSB by 2 ROR TEMP1 ; snd LSB by 2
@ -444,7 +444,7 @@ SETSPW: PHA ;Save Sprite Index
LDX #$CF ;Set Bit Mask LDX #$CF ;Set Bit Mask
TYA ;Copy Specifier to Accumulator TYA ;Copy Specifier to Accumulator
AND #$03 ;Isolate Bits 0 and 1 AND #$03 ;Isolate Bits 0 and 1
JMP SETSP4 ;Shift Left Four Bits and Write Masked BRA SETSP4 ;Shift Left Four Bits and Write Masked
;setsph(index) - Set Sprite Height Specifier ;setsph(index) - Set Sprite Height Specifier
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -458,7 +458,7 @@ SETSP4: ASL
ASL ASL
ASL ASL
ASL ASL
JMP SETSP7 ;Write Masked to Size Register BRA SETSP7 ;Write Masked to Size Register
;setspp(index) - Set Sprite Palette Offset ;setspp(index) - Set Sprite Palette Offset
;Args: A = Sprite Index ;Args: A = Sprite Index
@ -471,7 +471,7 @@ SETSP7: STA TEMP0 ;Save Value
STX TEMP1 ;Save Bit Mask STX TEMP1 ;Save Bit Mask
PLA ;Retrieve Sprite Index PLA ;Retrieve Sprite Index
JSR GETSPS ;Get Sprite Size Register JSR GETSPS ;Get Sprite Size Register
JMP SETSP8 ;Apply Mask, Set Bits, and Write BRA SETSP8 ;Apply Mask, Set Bits, and Write
;setsps(index,value) - Set Sprite Attribute Size Register ;setsps(index,value) - Set Sprite Attribute Size Register
;Args: A = Sprite Index ;Args: A = Sprite Index

View File

@ -9,7 +9,8 @@ ECHO Compiling File %1.c02 for Commander X16
..\c02.exe -h x16 -s x16 -s cbm %1 >%1.dbg ..\c02.exe -h x16 -s x16 -s cbm %1 >%1.dbg
IF %ERRORLEVEL% NEQ 0 GOTO EOF IF %ERRORLEVEL% NEQ 0 GOTO EOF
ECHO Assembling File %1.asm ECHO Assembling File %1.asm
C:\Programs\dasm %1.asm -f1 -o%1.prg -l%1.lst -s%1.sym ..\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 IF %ERRORLEVEL% NEQ 0 GOTO EOF