1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-25 06:31:25 +00:00

Added ALIGN and END Pseudo-Ops to A02 Assembler

This commit is contained in:
Curtis F Kaylor 2019-11-14 17:56:34 -05:00
parent d02c8b6a3a
commit 77b0f1017f
2 changed files with 52 additions and 19 deletions

65
a02.c
View File

@ -18,7 +18,7 @@ int orgadr; //Origin Address
int curadr; //Current Address int curadr; //Current Address
int lstadr; //List Address int lstadr; //List Address
struct sym {int block; char name[MAXLBL+1]; int bytes, value;}; struct sym {int block; char name[MAXLBL+1]; int bytes, value, refrd;};
struct sym symbol; //Current Symbol struct sym symbol; //Current Symbol
struct sym symtbl[MAXSYM]; //Global Symbol Table struct sym symtbl[MAXSYM]; //Global Symbol Table
int symcnt; //Number of Global Labels int symcnt; //Number of Global Labels
@ -31,6 +31,8 @@ char cmmnt[MAXSTR]; //Assembly Line Comment
char mcode[MAXSTR]; //Generated Bytes char mcode[MAXSTR]; //Generated Bytes
char strng[MAXSTR]; //Parsed String char strng[MAXSTR]; //Parsed String
int opridx; //Index into Operand
unsigned char token, opmod; //OpCode Token, Modifier unsigned char token, opmod; //OpCode Token, Modifier
unsigned int amode; //Addressing Modes unsigned int amode; //Addressing Modes
int zpage, opval; //ZeroPage Flag, Operand Value int zpage, opval; //ZeroPage Flag, Operand Value
@ -41,10 +43,11 @@ char bytstr[5]; //String Representation of Byte
char inplin[MAXSTR]; //Input Buffer char inplin[MAXSTR]; //Input Buffer
char *linptr; //Pointer into Input Buffer char *linptr; //Pointer into Input Buffer
int lineno; //Input File Line Number int lineno; //Input File Line Number
int opridx; //Index into Operand
int passno; //Assembler Pass Number (1 or 2)
int savlno; //Line Number (Saved) int savlno; //Line Number (Saved)
int passno; //Assembler Pass Number (1 or 2)
int endasm; //End Assembly Flag
char prgnam[256]; //Assembler Path and Name (from Command Line) char prgnam[256]; //Assembler Path and Name (from Command Line)
char inpnam[256]; //Input File Name char inpnam[256]; //Input File Name
char outnam[256]; //Output File Name char outnam[256]; //Output File Name
@ -114,6 +117,14 @@ void setsym(int value, int bytes) {
symbol.value = value; symbol.value = value;
if (bytes) symbol.bytes = bytes; if (bytes) symbol.bytes = bytes;
else symbol.bytes = (value > 0xFF) ? 2 : 1; else symbol.bytes = (value > 0xFF) ? 2 : 1;
symbol.refrd = FALSE;
}
/* Add Character to Beginning of String */
void pfxstr(char c, char* s) {
for (int i=strlen(s)+1; i; i--)
s[i] = s[i-1]; //Copy All Characters to the Right
s[0] = c; //Insert Character at Beginning
} }
/* Parse Label from Input Line /* Parse Label from Input Line
@ -137,10 +148,8 @@ int plabel(void) {
strcpy(symbol.name, label); strcpy(symbol.name, label);
setsym(curadr, 0); setsym(curadr, 0);
} }
if (block) { if (block) pfxstr('.', label);
for (int i=strlen(label)+1; i; i--) label[i] = label[i-1]; skpspc(); //Skip to Mnemonic, Comment, or EOL
label[0] = '.';
}
return found; return found;
} }
@ -205,6 +214,7 @@ struct sym *evlsym() {
for (int i=0; name[i]; i++) if (opridx<MAXSTR) oprnd[opridx++] = name[i]; for (int i=0; name[i]; i++) if (opridx<MAXSTR) oprnd[opridx++] = name[i];
struct sym *result = fndsym(block, name); struct sym *result = fndsym(block, name);
if (passno == 2 && result == NULL) xerror("Undefined Symbol %s\n", name); if (passno == 2 && result == NULL) xerror("Undefined Symbol %s\n", name);
if (result) result->refrd = TRUE; //Symbol was Referenced
return result; return result;
} }
@ -299,6 +309,16 @@ void asmwrd(void) {
} while (cpychr(',')); } while (cpychr(','));
} }
/* Assemble FILL Pseudo-Op */
void asmaln(void) {
if (DEBUG) puts("Assembling ALIGN Pseudo-Op");
int size = evlopd(0xFFFF); if (size < 2) return;
if (DEBUG) printf("Aligning to %d Bytes\n", size);
int fill = size - (curadr % size); if (fill == size) return;
if (DEBUG) printf("Filling %d Bytes\n", fill);
for (int i=0; i<fill; i++) outbyt(0);
}
/* Assemble FILL Pseudo-Op */ /* Assemble FILL Pseudo-Op */
void asmfll(void) { void asmfll(void) {
if (DEBUG) puts("Assembling FILL Pseudo-Op"); if (DEBUG) puts("Assembling FILL Pseudo-Op");
@ -357,9 +377,14 @@ void asminf(void) {
if (DEBUG) printf("Include File Set to Name to ''\n", incnam); if (DEBUG) printf("Include File Set to Name to ''\n", incnam);
} }
/* Assemble END Pseudo-Op */
void asmend(void) {
endasm = TRUE;
}
/* Assemble Pseudo-Op */ /* Assemble Pseudo-Op */
int asmpso(void) { int asmpso(int dot) {
if (lkpopc(psolst) == FALSE) return FALSE; if (lkpopc(psolst) == FALSE && dot == FALSE) return FALSE;
skpspc(); skpspc();
if (DEBUG) printf("Assembling Pseudo-Op %s, Token '%c'\n", mnmnc, token); if (DEBUG) printf("Assembling Pseudo-Op %s, Token '%c'\n", mnmnc, token);
switch (token) { switch (token) {
@ -372,14 +397,18 @@ int asmpso(void) {
case 'I': asminf(); break; //INCLude case 'I': asminf(); break; //INCLude
case '*': asmorg(); break; //ORG case '*': asmorg(); break; //ORG
case 'P': asmprc(); break; //PROCessor case 'P': asmprc(); break; //PROCessor
case 'E': asmend(); break; //END
case 'A': asmaln(); break; //ALIGn
default: xerror("Undefined Pseudo-Op %s\n", mnmnc); default: xerror("Undefined Pseudo-Op %s\n", mnmnc);
} }
if (dot) pfxstr('.', mnmnc);
return TRUE; return TRUE;
} }
/* Lookup Opcode */ /* Lookup Opcode */
int lkpopc(struct opc opl[]) { int lkpopc(struct opc opl[]) {
if (DEBUG) printf("Looking up Mnemonic %s\n", mnmnc); if (DEBUG) printf("Looking up Mnemonic %s\n", mnmnc);
token = 0xFF; //Set Token to Invalid
char mne[5]; strncpy(mne, mnmnc, 4); mne[4] = 0; //Truncate Mnemonic to Four Characters char mne[5]; strncpy(mne, mnmnc, 4); mne[4] = 0; //Truncate Mnemonic to Four Characters
for (int i=0; opl[i].name[0]; i++) { for (int i=0; opl[i].name[0]; i++) {
if (strcmp(opl[i].name, mne)) continue; if (strcmp(opl[i].name, mne)) continue;
@ -498,9 +527,9 @@ void dbgopc(void) {
} }
/* Assemble Opcode */ /* Assemble Opcode */
int asmopc(void) { int asmopc(int dot) {
opmod = 0; opmod = 0;
if (asmpso()) return TRUE; //Check For/Assemble Pseudo-Op if (asmpso(dot)) return TRUE; //Check For/Assemble Pseudo-Op
if (lkpopc(opclst) == FALSE) xerror("Invalid Mnemonic %s\n", mnmnc); if (lkpopc(opclst) == FALSE) xerror("Invalid Mnemonic %s\n", mnmnc);
if (DEBUG) printf("Assembling Opcode Token 0x%02X, ", token); if (DEBUG) printf("Assembling Opcode Token 0x%02X, ", token);
if (DEBUG) printf("Addressing Mode Mask 0x%04X\n", amode); if (DEBUG) printf("Addressing Mode Mask 0x%04X\n", amode);
@ -526,9 +555,10 @@ int asmopc(void) {
* Returns: Label Found (TRUE/FALSE) */ * Returns: Label Found (TRUE/FALSE) */
int pmnmnc(void) { int pmnmnc(void) {
if (DEBUG) puts("Parsing Mnemonic"); if (DEBUG) puts("Parsing Mnemonic");
int dot = cpychr('.'); //Optional Dot before Pseudo-Op
int found = pword(TRUE, mnmnc); int found = pword(TRUE, mnmnc);
opridx = 0; //Initialize Operand Index opridx = 0; //Initialize Operand Index
if (found) asmopc(); if (found) asmopc(dot);
oprnd[opridx] = 0; //Terminate Operand String oprnd[opridx] = 0; //Terminate Operand String
return found; return found;
} }
@ -568,6 +598,7 @@ void clsinc(void) {
incfil = NULL; incfil = NULL;
incnam[0] = 0; incnam[0] = 0;
lineno = savlno; lineno = savlno;
endasm = FALSE; //Clear End Flag for Return to Maun File
} }
/* Assemble Input File (Two Pass) * /* Assemble Input File (Two Pass) *
@ -576,6 +607,7 @@ void clsinc(void) {
* Uses: inplin - Input Line Buffer * * Uses: inplin - Input Line Buffer *
* lineno - Input File Line Number */ * lineno - Input File Line Number */
void asmfil(int pass) { void asmfil(int pass) {
endasm = FALSE; //Reset End Assembly Flag
passno = pass; //Assembly Pass Number passno = pass; //Assembly Pass Number
if (DEBUG) printf("Assembling Pass %d\n", pass); if (DEBUG) printf("Assembling Pass %d\n", pass);
lineno = 1; //Initialize Input File Line Number lineno = 1; //Initialize Input File Line Number
@ -586,7 +618,7 @@ void asmfil(int pass) {
while (TRUE) { while (TRUE) {
if (incfil) linptr = fgets(inplin, MAXSTR, incfil); if (incfil) linptr = fgets(inplin, MAXSTR, incfil);
else linptr = fgets(inplin, MAXSTR, inpfil); else linptr = fgets(inplin, MAXSTR, inpfil);
if (linptr == NULL) {if (incfil) {clsinc(); continue;} else break;} if (endasm || linptr == NULL) {if (incfil) {clsinc(); continue;} else break;}
if (DEBUG) printf("%05d %04X: %s", lineno, curadr, inplin); if (DEBUG) printf("%05d %04X: %s", lineno, curadr, inplin);
lstadr = curadr; //Set List Address lstadr = curadr; //Set List Address
mcode[0] = 0; //Clear Generated Macbine Code mcode[0] = 0; //Clear Generated Macbine Code
@ -606,9 +638,10 @@ void asmfil(int pass) {
/* Print Symbol Table */ /* Print Symbol Table */
void prtsym(void) { void prtsym(void) {
fprintf(lstfil, "\n%s Symbol Table\nBlock Name Size Value\n", "Global"); fprintf(lstfil, "\n%s Symbol Table\nBlock Name Size Value Rfd\n", "Global");
for (int i=0; i<symcnt; i++) { for (int i=0; i<symcnt; i++) {
fprintf(lstfil, "%5d %-8s %4d %5d\n", symtbl[i].block, symtbl[i].name, symtbl[i].bytes, symtbl[i].value); int refrd = (symtbl[i].refrd) ? '*' : ' ';
fprintf(lstfil, "%5d %-8s %4d %5d %c \n", symtbl[i].block, symtbl[i].name, symtbl[i].bytes, symtbl[i].value, refrd);
} }
} }
@ -653,7 +686,7 @@ int main(int argc, char *argv[]) {
lstfil = opnfil(lstnam, "w"); // Open List File lstfil = opnfil(lstnam, "w"); // Open List File
asmfil(1); //Assemble Input File (First Pass) asmfil(1); //Assemble Input File (First Pass)
asmfil(2); //Assemble Input File (First Pass) asmfil(2); //Assemble Input File (First Pass)
if (lstfil) prtsym(); //Print Symbol Table if (lstfil && symcnt) prtsym(); //Print Symbol Table
exit(0); //Exit with No Errors exit(0); //Exit with No Errors
} }

4
a02.h
View File

@ -42,8 +42,8 @@ struct amd amdesc[] = {
struct opc {char name[5], token; int amode;}; struct opc {char name[5], token; int amode;};
struct opc psolst[] = { struct opc psolst[] = {
{"BYTE", 'B', 0}, {"HEX", 'H'}, {"WORD", 'W', 0}, {"EQU", '=', 0}, {"FILL", 'F', 0}, {"BYTE", 'B', 0}, {"HEX", 'H'}, {"WORD", 'W', 0}, {"EQU", '=', 0}, {"FILL", 'F', 0},
{"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"ORG", '*', 0}, {"PROC", 'P', 0}, {"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"DC", 'B', 0}, {"DS", 'F', 0}, {"ALIG", 'A', 0},
{"DC", 'B', 0}, {"DS", 'F', 0}, {"", 0, 0} {"ORG", '*', 0}, {"PROC", 'P', 0}, {"END", 'E', 0}, {"", 0, 0}
}; };
struct opc opclst[] = { struct opc opclst[] = {