diff --git a/src/.vscode/ipch/771b4d3d25e434c7/C02.ipch b/src/.vscode/ipch/771b4d3d25e434c7/C02.ipch new file mode 100644 index 0000000..f6d23ac Binary files /dev/null and b/src/.vscode/ipch/771b4d3d25e434c7/C02.ipch differ diff --git a/src/.vscode/ipch/771b4d3d25e434c7/mmap_address.bin b/src/.vscode/ipch/771b4d3d25e434c7/mmap_address.bin new file mode 100644 index 0000000..862b842 Binary files /dev/null and b/src/.vscode/ipch/771b4d3d25e434c7/mmap_address.bin differ diff --git a/src/.vscode/launch.json b/src/.vscode/launch.json new file mode 100644 index 0000000..8870f0a --- /dev/null +++ b/src/.vscode/launch.json @@ -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 + } + ] +} \ No newline at end of file diff --git a/src/asm.c b/src/asm.c index 41dc1bb..9c82ae6 100644 --- a/src/asm.c +++ b/src/asm.c @@ -1,36 +1,36 @@ -/************************************* - * C02 Assembly Language Routines * - *************************************/ - -#include -#include -#include -#include -#include - -#include "common.h" -#include "files.h" -#include "asm.h" - -/* Process comment */ -void prccmt(void) { - if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); } - else asmcmt[0] = 0; - setcmt(""); -} - -/* output a single line of assembly code */ -void asmlin(char *opcode, char *oprnd) { - if (strlen(lblasm)) strcat(lblasm, LABSFX); - prccmt(); - fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt); - if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt); - lblasm[0] = 0; -} - -/* output a single comment line */ -void cmtlin(void) { - DEBUG("Writing Comment Line: %s\n", cmtasm) - fprintf(outfil, "; %s\n", cmtasm); - setcmt(""); -} +/************************************* + * C02 Assembly Language Routines * + *************************************/ + +#include +#include +#include +#include +#include + +#include "common.h" +#include "files.h" +#include "asm.h" + +/* Process comment */ +void prccmt(void) { + if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); } + else asmcmt[0] = 0; + setcmt(""); +} + +/* output a single line of assembly code */ +void asmlin(char *opcode, char *oprnd) { + if (strlen(lblasm)) strcat(lblasm, LABSFX); + prccmt(); + fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt); + if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt); + lblasm[0] = 0; +} + +/* output a single comment line */ +void cmtlin(void) { + DEBUG("Writing Comment Line: %s\n", cmtasm) + fprintf(outfil, "; %s\n", cmtasm); + setcmt(""); +} diff --git a/src/asm.h b/src/asm.h index eb5c10b..b482ad5 100644 --- a/src/asm.h +++ b/src/asm.h @@ -1,9 +1,9 @@ -/************************************* - * C02 Assembly Language Routines * - *************************************/ - -char lblasm[LBLLEN+2]; //Label to emit on next asm line - -void asmlin(char *opcode, char *oprnd); //Output a line of assembly code -void cmtlin(); //Output a comment lines -void prccmt(); //Process comment +/************************************* + * C02 Assembly Language Routines * + *************************************/ + +char lblasm[LBLLEN+2]; //Label to emit on next asm line + +void asmlin(char *opcode, char *oprnd); //Output a line of assembly code +void cmtlin(); //Output a comment lines +void prccmt(); //Process comment diff --git a/src/common.c b/src/common.c index 1c3871c..c2d1cfc 100644 --- a/src/common.c +++ b/src/common.c @@ -1,60 +1,60 @@ -/************************************* - * C02 Common Definitions & Routines * - *************************************/ - -#include -#include -#include -#include -#include -#include -#include "common.h" - -struct timespec curtim; //Current Time - -/* Error - Print Input File name & position and exit */ -void exterr(int errnum) { - fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam); - exit(errnum); -} - -/* Error - print "Expected" error message * - and exit with general failure code * - Args: expected - Description of what was expected */ -void expctd(char *expstr) { - fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr); - exterr(EXIT_FAILURE); -} - -/* Print current position in file */ -void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); } - -/* Initialize elapsed time counter */ -void initim(void) { - timespec_get (&curtim, TIME_UTC); - bgntim = curtim.tv_sec; -} - -/* Print elapsed time */ -void prttim(void) { - timespec_get (&curtim, TIME_UTC); - printf("[%d", curtim.tv_sec - bgntim); - printf(".%06d]",curtim.tv_nsec/1000); -} - -/* Set comment to string */ -void setcmt(char *s) { strcpy(cmtasm, s); } - -/* Append string to comment */ -void addcmt(char *s) { - if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s); -} - -/* Append character to comment */ -void chrcmt(char c) { - if (strlen(cmtasm)>72) return; - if (cmtasm[0] == 0 && c == ' ') return; - int i = strlen(cmtasm); - cmtasm[i++] = c; - cmtasm[i] = 0; -} +/************************************* + * C02 Common Definitions & Routines * + *************************************/ + +#include +#include +#include +#include +#include +#include +#include "common.h" + +struct timespec curtim; //Current Time + +/* Error - Print Input File name & position and exit */ +void exterr(int errnum) { + fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam); + exit(errnum); +} + +/* Error - print "Expected" error message * + and exit with general failure code * + Args: expected - Description of what was expected */ +void expctd(char *expstr) { + fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr); + exterr(EXIT_FAILURE); +} + +/* Print current position in file */ +void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); } + +/* Initialize elapsed time counter */ +void initim(void) { + timespec_get (&curtim, TIME_UTC); + bgntim = curtim.tv_sec; +} + +/* Print elapsed time */ +void prttim(void) { + timespec_get (&curtim, TIME_UTC); + printf("[%d", curtim.tv_sec - bgntim); + printf(".%06d]",curtim.tv_nsec/1000); +} + +/* Set comment to string */ +void setcmt(char *s) { strcpy(cmtasm, s); } + +/* Append string to comment */ +void addcmt(char *s) { + if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s); +} + +/* Append character to comment */ +void chrcmt(char c) { + if (strlen(cmtasm)>72) return; + if (cmtasm[0] == 0 && c == ' ') return; + int i = strlen(cmtasm); + cmtasm[i++] = c; + cmtasm[i] = 0; +} diff --git a/src/cond.c b/src/cond.c index 54fd01e..a74a72d 100644 --- a/src/cond.c +++ b/src/cond.c @@ -1,138 +1,138 @@ -/************************************ - * C02 Conditional Parsing Routines * - ************************************/ -#include -#include -#include -#include -#include -#include "common.h" -#include "asm.h" -#include "parse.h" -#include "vars.h" -#include "expr.h" -#include "label.h" -#include "cond.h" - -int cmprtr; //Encoded Comparison Operator -int cmpenc; //Encoded Comparator Character - -/* Encode Comparison Operator Character * - * Args: Comparison Operator Character * - * Returns: Comparison Operator Bit Mask */ -int enccmp(char c) { - int e; - DEBUG("Encoding Comparison Character '%c'", c) - switch(c) { - case '=': e = 1; break; - case '<': e = 2; break; - case '>': e = 4; break; - default: e = 0; - } - if (e) { CCMNT(c); skpchr(); } - DETAIL(", encoded as %d\n", e); - return e; -} - -/* Process and Compile Comparison Operator and * - * Args: comparator - Encoded Comparison Operator * - * Uses: term - Term Being Compared Against * - * label - Branch Target if Comparison is FALSE */ -void prccmp(void) { - DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp) - if (cmprtr > 7) { //Process Flag - cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal - if (cmprtr) asmlin("BPL", cmplbl); - else asmlin("BMI", cmplbl); - return; - } - cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal - switch(cmprtr) { - case 0: // Raw Expression (Skip) - asmlin("BEQ", cmplbl); break; - case 1: // = or == - asmlin("CMP", term); asmlin("BNE", cmplbl); break; - case 2: // < - asmlin("CMP", term); asmlin("BCS", cmplbl); break; - case 3: // <= or =< - asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break; - case 4: // > - asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break; - case 5: // >= or => - asmlin("CMP", term); asmlin("BCC", cmplbl); break; - case 6: // <> or >< - asmlin("CMP", term); asmlin("BEQ", cmplbl); break; - case 7: // Raw Expression (Normal) - asmlin("BNE", cmplbl); break; - default: - ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE) - } -} - -/* Parse Comparison */ -void prscmp(int revrse) { - skpspc(); - cmpenc = enccmp(nxtchr); //Encode Comparison Character - cmprtr = cmpenc; //Set Encoded Comparator - if (cmprtr) { - cmpenc = enccmp(nxtchr); //Encode Next Comparison Character - if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator - } - skpspc(); - if (cmprtr) prstrm(FALSE); - //prccmp(); - Do after check for logical operator - DEBUG("Parsed comparator %d\n", cmprtr) -} - -/* Parse Flag Operator */ -void prsflg(int revrse) { - DEBUG("Parsing Flag Operator '%c'\n", nxtchr) - if (match('+')) cmprtr = 8; //Bit 0 = 0 - else if (match('-')) cmprtr = 9; //Bit 1 = 1 - else expctd("Flag operator"); - skpchr(); -} - -/* Parse Logical Operator * - * Sets: logops */ -void prslop(void) { - DEBUG("Checking for Logical Operator\n", 0) - logopr = LOPNONE; - skpspc(); - if (isalph()) { - getwrd(); //Get Logical Operator - DEBUG("Parsing Logical Operator %s\n", word) - if (wordis("AND")) logopr = LOPAND; - else if (wordis("OR")) logopr = LOPOR; - else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE) - } - DEBUG("Set LOGOPR to %d\n", logopr) -} - -/* Parse and Compile Conditional Expression * - * Condition = */ -void prscnd(char trmntr, int revrse) { - DEBUG("Parsing condition with REVRSE=%d\n", revrse) - tmplbl[0] = 0; - do { - strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); - revcmp = revrse; - if (look('!')) revcmp = (revcmp) ? FALSE: TRUE; - DEBUG("Set REVCMP to %d\n", revcmp) - if (!look('.')) prsxpr(0); - if (look(':')) prsflg(revcmp); //Parse Flag Operator - else prscmp(revcmp); //Parse Comparison Operator - prslop(); //Parse Logical Operator - if (logopr == LOPOR) { - revcmp = (revcmp) ? FALSE: TRUE; - DEBUG("Set REVCMP to %d\n", revcmp) - } - if (logopr && revcmp) { - if (!tmplbl[0]) newlbl(tmplbl); - strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); - } - prccmp(); //Process Comparison/Flag Operator - } while (logopr); - if (tmplbl[0]) setlbl(tmplbl); - expect(trmntr); -} +/************************************ + * C02 Conditional Parsing Routines * + ************************************/ +#include +#include +#include +#include +#include +#include "common.h" +#include "asm.h" +#include "parse.h" +#include "vars.h" +#include "expr.h" +#include "label.h" +#include "cond.h" + +int cmprtr; //Encoded Comparison Operator +int cmpenc; //Encoded Comparator Character + +/* Encode Comparison Operator Character * + * Args: Comparison Operator Character * + * Returns: Comparison Operator Bit Mask */ +int enccmp(char c) { + int e; + DEBUG("Encoding Comparison Character '%c'", c) + switch(c) { + case '=': e = 1; break; + case '<': e = 2; break; + case '>': e = 4; break; + default: e = 0; + } + if (e) { CCMNT(c); skpchr(); } + DETAIL(", encoded as %d\n", e); + return e; +} + +/* Process and Compile Comparison Operator and * + * Args: comparator - Encoded Comparison Operator * + * Uses: term - Term Being Compared Against * + * label - Branch Target if Comparison is FALSE */ +void prccmp(void) { + DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp) + if (cmprtr > 7) { //Process Flag + cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal + if (cmprtr) asmlin("BPL", cmplbl); + else asmlin("BMI", cmplbl); + return; + } + cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal + switch(cmprtr) { + case 0: // Raw Expression (Skip) + asmlin("BEQ", cmplbl); break; + case 1: // = or == + asmlin("CMP", term); asmlin("BNE", cmplbl); break; + case 2: // < + asmlin("CMP", term); asmlin("BCS", cmplbl); break; + case 3: // <= or =< + asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break; + case 4: // > + asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break; + case 5: // >= or => + asmlin("CMP", term); asmlin("BCC", cmplbl); break; + case 6: // <> or >< + asmlin("CMP", term); asmlin("BEQ", cmplbl); break; + case 7: // Raw Expression (Normal) + asmlin("BNE", cmplbl); break; + default: + ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE) + } +} + +/* Parse Comparison */ +void prscmp(int revrse) { + skpspc(); + cmpenc = enccmp(nxtchr); //Encode Comparison Character + cmprtr = cmpenc; //Set Encoded Comparator + if (cmprtr) { + cmpenc = enccmp(nxtchr); //Encode Next Comparison Character + if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator + } + skpspc(); + if (cmprtr) prstrm(FALSE); + //prccmp(); - Do after check for logical operator + DEBUG("Parsed comparator %d\n", cmprtr) +} + +/* Parse Flag Operator */ +void prsflg(int revrse) { + DEBUG("Parsing Flag Operator '%c'\n", nxtchr) + if (match('+')) cmprtr = 8; //Bit 0 = 0 + else if (match('-')) cmprtr = 9; //Bit 1 = 1 + else expctd("Flag operator"); + skpchr(); +} + +/* Parse Logical Operator * + * Sets: logops */ +void prslop(void) { + DEBUG("Checking for Logical Operator\n", 0) + logopr = LOPNONE; + skpspc(); + if (isalph()) { + getwrd(); //Get Logical Operator + DEBUG("Parsing Logical Operator %s\n", word) + if (wordis("AND")) logopr = LOPAND; + else if (wordis("OR")) logopr = LOPOR; + else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE) + } + DEBUG("Set LOGOPR to %d\n", logopr) +} + +/* Parse and Compile Conditional Expression * + * Condition = */ +void prscnd(char trmntr, int revrse) { + DEBUG("Parsing condition with REVRSE=%d\n", revrse) + tmplbl[0] = 0; + do { + strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); + revcmp = revrse; + if (look('!')) revcmp = (revcmp) ? FALSE: TRUE; + DEBUG("Set REVCMP to %d\n", revcmp) + if (!look('.')) prsxpr(0); + if (look(':')) prsflg(revcmp); //Parse Flag Operator + else prscmp(revcmp); //Parse Comparison Operator + prslop(); //Parse Logical Operator + if (logopr == LOPOR) { + revcmp = (revcmp) ? FALSE: TRUE; + DEBUG("Set REVCMP to %d\n", revcmp) + } + if (logopr && revcmp) { + if (!tmplbl[0]) newlbl(tmplbl); + strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl); + } + prccmp(); //Process Comparison/Flag Operator + } while (logopr); + if (tmplbl[0]) setlbl(tmplbl); + expect(trmntr); +} diff --git a/src/cond.h b/src/cond.h index d57196a..1501fe1 100644 --- a/src/cond.h +++ b/src/cond.h @@ -1,10 +1,10 @@ -/************************************ - * C02 Conditional Parsing Routines * - ************************************/ - -enum LOGOPS {LOPNONE, LOPAND, LOPOR}; - -int revcmp; //Reverse Comparison -int logopr; //Logical Operator (set to LOGOPS) - -void prscnd(char trmntr, int revrse); //Parse Conditional Expression +/************************************ + * C02 Conditional Parsing Routines * + ************************************/ + +enum LOGOPS {LOPNONE, LOPAND, LOPOR}; + +int revcmp; //Reverse Comparison +int logopr; //Logical Operator (set to LOGOPS) + +void prscnd(char trmntr, int revrse); //Parse Conditional Expression diff --git a/src/dclrtn.h b/src/dclrtn.h index 98486f3..fcf7516 100644 --- a/src/dclrtn.h +++ b/src/dclrtn.h @@ -1,17 +1,17 @@ -/************************************ - * C02 Declaration Compiling Routines * - ************************************/ - -char fncnam[VARLEN+1]; //Function Name -char prmtra[VARLEN+1]; //Function Parameter A -char prmtrx[VARLEN+1]; //Function Parameter X -char prmtry[VARLEN+3]; //Function Parameter Y -int prmcnt; //Number of Parameters -//int lpemtd; //Location Prefix Emitted - -void addcon(int numval); //Add Constant -int pmodfr(); //Check for and Parse Modifier -int ctype(int reqtyp); //Check for Type Keyword -int ptype(int m); //Check for and Parse Type Keyword - -enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT}; +/************************************ + * C02 Declaration Compiling Routines * + ************************************/ + +char fncnam[VARLEN+1]; //Function Name +char prmtra[VARLEN+1]; //Function Parameter A +char prmtrx[VARLEN+1]; //Function Parameter X +char prmtry[VARLEN+3]; //Function Parameter Y +int prmcnt; //Number of Parameters +//int lpemtd; //Location Prefix Emitted + +void addcon(int numval); //Add Constant +int pmodfr(); //Check for and Parse Modifier +int ctype(int reqtyp); //Check for Type Keyword +int ptype(int m); //Check for and Parse Type Keyword + +enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT}; diff --git a/src/files.c b/src/files.c index 147c2d3..76c57d9 100644 --- a/src/files.c +++ b/src/files.c @@ -1,102 +1,102 @@ -/****************************** - * C02 File Handling Routines * - ******************************/ - -#include -#include -#include -#include -#include - -#include "common.h" -#include "files.h" - -/* Error - Print textual description of system error * - * and exit with system error code */ -void extsys(char *s) { - perror(s); - exterr(errno); -} - -/* Open Source File * - * Uses: srcnam - Source File Name * - * Sets: srcfil - Source File Handle */ -void opnsrc(void) { - DEBUG("Processing Source File Name '%s'\n", srcnam) - if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02" - DEBUG("opening Source File '%s'\n", srcnam) - srcfil = fopen(srcnam, "r"); //open file - if (srcfil == NULL) extsys(srcnam); -} - -/* Close Source File */ -void clssrc(void) { fclose(srcfil); } - -/* Open Output File * - * Uses: outnam - Output File Name * - * Sets: outfil - Output File Handle */ -void opnout(void) { - DEBUG("Processing Output File Name '%s'\n", outnam) - if (strlen(outnam) == 0) //if Output File not specified - { - strcpy(outnam, srcnam); //copy Source Name to Ouput Name - char *dot = strrchr(outnam, '.'); //find extension - if (dot != NULL) *dot = 0; //and remove it - DEBUG("Set Output File Name to '%s'\n", outnam) - } - if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm" - DEBUG("Opening Output File '%s'\n", outnam) - outfil = fopen(outnam, "w"); //open file - if (outfil == NULL) extsys(outnam); -} - -/* Close Output File */ -void clsout(void) { - fprintf(outfil, "\n"); - fclose(outfil); -} - -/* Open Log File * - * Uses: srcnam - Source File Name * - * Sets: logfil - Log File Handle */ -void opnlog(void) { - strcpy(lognam, srcnam); //set Log File Name to Source File Name - char *dot = strrchr(lognam, '.'); //find file extension - if (dot != NULL) *dot = 0; //and remove it - strcat(lognam, ".log"); //add extension ".log" - DEBUG("Opening Log File '%s'\n", lognam) - logfil = fopen(lognam, "w"); - if (logfil == NULL) extsys(lognam); -} - -/* Close Log File * - * Uses: logfil - Log File Handle */ -void clslog(void) { fclose(logfil); } - -/* Open Include file * - * Uses: incnam - Include File Name * - * subnam - Include File Name (Subdirectory) * - * Sets: incfil - Include File Handle */ -void opninc(int chksub) -{ - if (chksub) { - for (subidx=0; subidx +#include +#include +#include +#include + +#include "common.h" +#include "files.h" + +/* Error - Print textual description of system error * + * and exit with system error code */ +void extsys(char *s) { + perror(s); + exterr(errno); +} + +/* Open Source File * + * Uses: srcnam - Source File Name * + * Sets: srcfil - Source File Handle */ +void opnsrc(void) { + DEBUG("Processing Source File Name '%s'\n", srcnam) + if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02" + DEBUG("opening Source File '%s'\n", srcnam) + srcfil = fopen(srcnam, "r"); //open file + if (srcfil == NULL) extsys(srcnam); +} + +/* Close Source File */ +void clssrc(void) { fclose(srcfil); } + +/* Open Output File * + * Uses: outnam - Output File Name * + * Sets: outfil - Output File Handle */ +void opnout(void) { + DEBUG("Processing Output File Name '%s'\n", outnam) + if (strlen(outnam) == 0) //if Output File not specified + { + strcpy(outnam, srcnam); //copy Source Name to Ouput Name + char *dot = strrchr(outnam, '.'); //find extension + if (dot != NULL) *dot = 0; //and remove it + DEBUG("Set Output File Name to '%s'\n", outnam) + } + if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm" + DEBUG("Opening Output File '%s'\n", outnam) + outfil = fopen(outnam, "w"); //open file + if (outfil == NULL) extsys(outnam); +} + +/* Close Output File */ +void clsout(void) { + fprintf(outfil, "\n"); + fclose(outfil); +} + +/* Open Log File * + * Uses: srcnam - Source File Name * + * Sets: logfil - Log File Handle */ +void opnlog(void) { + strcpy(lognam, srcnam); //set Log File Name to Source File Name + char *dot = strrchr(lognam, '.'); //find file extension + if (dot != NULL) *dot = 0; //and remove it + strcat(lognam, ".log"); //add extension ".log" + DEBUG("Opening Log File '%s'\n", lognam) + logfil = fopen(lognam, "w"); + if (logfil == NULL) extsys(lognam); +} + +/* Close Log File * + * Uses: logfil - Log File Handle */ +void clslog(void) { fclose(logfil); } + +/* Open Include file * + * Uses: incnam - Include File Name * + * subnam - Include File Name (Subdirectory) * + * Sets: incfil - Include File Handle */ +void opninc(int chksub) +{ + if (chksub) { + for (subidx=0; subidx -#include -#include -#include -#include - -#include "common.h" -#include "files.h" -#include "asm.h" -#include "parse.h" -#include "label.h" -#include "vars.h" - -/* Add New Program Label */ -void addlab(char *name) { - 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) - DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt) - strcpy(labnam[labcnt++], name); -} - -int fndlab(char *name) { - DEBUG("Looking for Program Label %s\n", name) - for (labidx=0; labidx-1; i--) - if (lblflg[lbltyp[i]] == lbflag) break; - DEBUG("Search produced label index %d\n", i) - if (i>=0) strcpy(tmplbl, lblnam[i]); - return i; -} - -/* Set Block Flag for Last Label */ -void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; } - -/* Set label for next line of * - * Assembly Language Code * - * to word */ -void setlbl(char *lblset) { - DEBUG("Setting Label '%s'\n", lblset) - if (strlen(lblasm) > 0) { - DEBUG("Emitting Label '%s'\n'", lblasm); - asmlin("",""); //Emit Block End Label on it's own line - } - if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE) - strcpy(lblasm, lblset); -} - -/* Parse Program Label */ -void prslab(void) { - DEBUG("Parsing Label '%s''\n", word) - addlab(word); - CCMNT(nxtchr); - skpchr(); //skip ':' -} - -/* generate new label */ -void newlbl(char* lbname) { - sprintf(lbname, LBLFMT, lblnxt++); - DEBUG("Generated new label '%s'\n", lbname) -} - -/* Check Label Contents * - * If lbname is blank, generate new * - * label and copy into lbname */ -void chklbl(char* lbname) { - if (lbname[0]) return; - newlbl(lbname); -} - -/* Request Label * - * if label is already set, returns that label * - * else generates new label and sets it */ -void reqlbl(char* lbname) { - DEBUG("Requesting Label\n",0) - if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);} - else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)} -} - -/* End Function Block */ -void endfnc(void) { - DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn) - if (!lsrtrn) asmlin("RTS", ""); - infunc = FALSE; - DEBUG("Set infunc to %d\n", infunc) -} - -/* Pop Label from Stack and Emit on Next Line */ -int poplbl(void) { - int lbtype = lbltyp[--lblcnt]; - DEBUG("Popped label type %d\n", lbtype) - switch (lbtype) { - case LTFUNC: endfnc(); break; //Return From Subroutine - case LTDO: strcpy(loplbl, lblnam[lblcnt]); break; - case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break; - case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break; - case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop - default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label - } - if (lbtype != LTCASE) inblck = lblblk[lblcnt-1]; - return lbtype; -} - -/* Get Top Label and Return Type */ -int toplbl(char *rtlbl) { - if (lblcnt) { - strcpy(rtlbl, lblnam[lblcnt-1]); - DEBUG("Found top label %s\n", rtlbl) - return lbltyp[lblcnt-1]; - } - rtlbl[0] = 0; //Clear Label - return LTNONE; -} - -/* Push Label onto Stack * - * Args: lbltyp - Label type * - * Uses: curlbl - Label to push */ -void pshlbl(int lbtype, char* lbname) { - DEBUG("Pushing label type %d\n", lbtype) - strcpy(lblnam[lblcnt], lbname); - lbltyp[lblcnt] = lbtype; - lblblk[lblcnt++] = FALSE; - DEBUG("Pushed label '%s' onto stack\n", lbname) -} +/****************************************************** + * C02 Label Parsing, Generation, and Lookup Routines * + ******************************************************/ + +#include +#include +#include +#include +#include + +#include "common.h" +#include "files.h" +#include "asm.h" +#include "parse.h" +#include "label.h" +#include "vars.h" + +/* Add New Program Label */ +void addlab(char *name) { + 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) + DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt) + strcpy(labnam[labcnt++], name); +} + +int fndlab(char *name) { + DEBUG("Looking for Program Label %s\n", name) + for (labidx=0; labidx-1; i--) + if (lblflg[lbltyp[i]] == lbflag) break; + DEBUG("Search produced label index %d\n", i) + if (i>=0) strcpy(tmplbl, lblnam[i]); + return i; +} + +/* Set Block Flag for Last Label */ +void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; } + +/* Set label for next line of * + * Assembly Language Code * + * to word */ +void setlbl(char *lblset) { + DEBUG("Setting Label '%s'\n", lblset) + if (strlen(lblasm) > 0) { + DEBUG("Emitting Label '%s'\n'", lblasm); + asmlin("",""); //Emit Block End Label on it's own line + } + if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE) + strcpy(lblasm, lblset); +} + +/* Parse Program Label */ +void prslab(void) { + DEBUG("Parsing Label '%s''\n", word) + addlab(word); + CCMNT(nxtchr); + skpchr(); //skip ':' +} + +/* generate new label */ +void newlbl(char* lbname) { + sprintf(lbname, LBLFMT, lblnxt++); + DEBUG("Generated new label '%s'\n", lbname) +} + +/* Check Label Contents * + * If lbname is blank, generate new * + * label and copy into lbname */ +void chklbl(char* lbname) { + if (lbname[0]) return; + newlbl(lbname); +} + +/* Request Label * + * if label is already set, returns that label * + * else generates new label and sets it */ +void reqlbl(char* lbname) { + DEBUG("Requesting Label\n",0) + if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);} + else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)} +} + +/* End Function Block */ +void endfnc(void) { + DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn) + if (!lsrtrn) asmlin("RTS", ""); + infunc = FALSE; + DEBUG("Set infunc to %d\n", infunc) +} + +/* Pop Label from Stack and Emit on Next Line */ +int poplbl(void) { + int lbtype = lbltyp[--lblcnt]; + DEBUG("Popped label type %d\n", lbtype) + switch (lbtype) { + case LTFUNC: endfnc(); break; //Return From Subroutine + case LTDO: strcpy(loplbl, lblnam[lblcnt]); break; + case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break; + case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break; + case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop + default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label + } + if (lbtype != LTCASE) inblck = lblblk[lblcnt-1]; + return lbtype; +} + +/* Get Top Label and Return Type */ +int toplbl(char *rtlbl) { + if (lblcnt) { + strcpy(rtlbl, lblnam[lblcnt-1]); + DEBUG("Found top label %s\n", rtlbl) + return lbltyp[lblcnt-1]; + } + rtlbl[0] = 0; //Clear Label + return LTNONE; +} + +/* Push Label onto Stack * + * Args: lbltyp - Label type * + * Uses: curlbl - Label to push */ +void pshlbl(int lbtype, char* lbname) { + DEBUG("Pushing label type %d\n", lbtype) + strcpy(lblnam[lblcnt], lbname); + lbltyp[lblcnt] = lbtype; + lblblk[lblcnt++] = FALSE; + DEBUG("Pushed label '%s' onto stack\n", lbname) +} diff --git a/src/label.h b/src/label.h index 0b2068a..f83c242 100644 --- a/src/label.h +++ b/src/label.h @@ -1,41 +1,41 @@ -/****************************************************** - * C02 Label Parsing, Generation, and Lookup Routines * - ******************************************************/ - -char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names -int labcnt; //Number of Program Labels -int labidx; //Index into labnam[] - -char curlbl[LBLLEN+1]; //Most recently generated label -char cmplbl[LBLLEN+1]; //Label for Comparison -char cndlbl[LBLLEN+1]; //Label for Conditional Code -char endlbl[LBLLEN+1]; //End Label -char forlbl[LBLLEN+1]; //For Loop Label -char loplbl[LBLLEN+1]; //Skip Increment Label -char skplbl[LBLLEN+1]; //Skip Increment Label -char tmplbl[LBLLEN+1]; //Temporary Label -char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table -int lbltyp[MAXLBL+1]; //Label Type -int lblblk[MAXLBL+1]; //Label Ends Program Block -int lblcnt; //Number of Labels in stack -int lblnxt; //Sequence of next label to be generated -char lbltmp[LBLLEN+1]; //Label Temporary Storage - -enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types -enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types - -void addlab(char *name); //Add Program Label -int fndlab(char *name); //Find Program Label -void prslab(); //Parse Program Label -void loglab(void); //Print Program Label Table - -void chklbl(char* lbname); //Check Label Contents -int lstlbl(int lbflag); //Find Last Label of Specified Types * -void newlbl(char* lbname); //Generate New Block Label -int poplbl(); //Pop Last Label and Emit on Next Line -void pshlbl(int lbtype, char* lbname); //Push Label onto Stack -void reqlbl(char* lbname); //Require Label -void setblk(int blkflg); //Set Block Flag for Last Label -void setlbl(char *lblset); //Emit word as Label on Next Line -int toplbl(char *rtlbl); //Get Top Label and Return Type - +/****************************************************** + * C02 Label Parsing, Generation, and Lookup Routines * + ******************************************************/ + +char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names +int labcnt; //Number of Program Labels +int labidx; //Index into labnam[] + +char curlbl[LBLLEN+1]; //Most recently generated label +char cmplbl[LBLLEN+1]; //Label for Comparison +char cndlbl[LBLLEN+1]; //Label for Conditional Code +char endlbl[LBLLEN+1]; //End Label +char forlbl[LBLLEN+1]; //For Loop Label +char loplbl[LBLLEN+1]; //Skip Increment Label +char skplbl[LBLLEN+1]; //Skip Increment Label +char tmplbl[LBLLEN+1]; //Temporary Label +char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table +int lbltyp[MAXLBL+1]; //Label Type +int lblblk[MAXLBL+1]; //Label Ends Program Block +int lblcnt; //Number of Labels in stack +int lblnxt; //Sequence of next label to be generated +char lbltmp[LBLLEN+1]; //Label Temporary Storage + +enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types +enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types + +void addlab(char *name); //Add Program Label +int fndlab(char *name); //Find Program Label +void prslab(); //Parse Program Label +void loglab(void); //Print Program Label Table + +void chklbl(char* lbname); //Check Label Contents +int lstlbl(int lbflag); //Find Last Label of Specified Types * +void newlbl(char* lbname); //Generate New Block Label +int poplbl(); //Pop Last Label and Emit on Next Line +void pshlbl(int lbtype, char* lbname); //Push Label onto Stack +void reqlbl(char* lbname); //Require Label +void setblk(int blkflg); //Set Block Flag for Last Label +void setlbl(char *lblset); //Emit word as Label on Next Line +int toplbl(char *rtlbl); //Get Top Label and Return Type + diff --git a/src/stmnt.h b/src/stmnt.h index 610066a..4a95bc2 100644 --- a/src/stmnt.h +++ b/src/stmnt.h @@ -1,21 +1,21 @@ -/************************************ - * C02 Statement Compiling Routines * - ************************************/ - -char asnvar[VARLEN+1]; //Assigned Variable Name -int asntyp; //Assigned Variable Type -char asnidx[VARLEN+1] ; //Assigned Variable Index -int asnivt; //Assigned Index Variable Type -char ysnvar[VARLEN+1]; //Assigned Y Variable Name -char ysnidx[VARLEN+1] ; //Assigned Y Variable Index -int ysnivt; //Assigned Y Index Variable Type -char xsnvar[VARLEN+1]; //Assigned X Variable Name -char xsnidx[VARLEN+1] ; //Assigned X Variable Index -int xsnivt; //Assigned X Index Variable Type - -char xstmnt[LINELEN]; //Expected Statement - -void bgnblk(char blkchr); //End Program Block -void endblk(int blkflg); //End Program Block -void pdowhl(); //Parse and Compile WHILE after DO -void pstmnt(); //Parse and Compile Program Statement +/************************************ + * C02 Statement Compiling Routines * + ************************************/ + +char asnvar[VARLEN+1]; //Assigned Variable Name +int asntyp; //Assigned Variable Type +char asnidx[VARLEN+1] ; //Assigned Variable Index +int asnivt; //Assigned Index Variable Type +char ysnvar[VARLEN+1]; //Assigned Y Variable Name +char ysnidx[VARLEN+1] ; //Assigned Y Variable Index +int ysnivt; //Assigned Y Index Variable Type +char xsnvar[VARLEN+1]; //Assigned X Variable Name +char xsnidx[VARLEN+1] ; //Assigned X Variable Index +int xsnivt; //Assigned X Index Variable Type + +char xstmnt[LINELEN]; //Expected Statement + +void bgnblk(char blkchr); //End Program Block +void endblk(int blkflg); //End Program Block +void pdowhl(); //Parse and Compile WHILE after DO +void pstmnt(); //Parse and Compile Program Statement