mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-21 10:32:08 +00:00
Added ALIGN and END Pseudo-Ops to A02 Assembler
This commit is contained in:
parent
d02c8b6a3a
commit
77b0f1017f
67
a02.c
67
a02.c
@ -18,7 +18,7 @@ int orgadr; //Origin Address
|
||||
int curadr; //Current 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 symtbl[MAXSYM]; //Global Symbol Table
|
||||
int symcnt; //Number of Global Labels
|
||||
@ -31,6 +31,8 @@ char cmmnt[MAXSTR]; //Assembly Line Comment
|
||||
char mcode[MAXSTR]; //Generated Bytes
|
||||
char strng[MAXSTR]; //Parsed String
|
||||
|
||||
int opridx; //Index into Operand
|
||||
|
||||
unsigned char token, opmod; //OpCode Token, Modifier
|
||||
unsigned int amode; //Addressing Modes
|
||||
int zpage, opval; //ZeroPage Flag, Operand Value
|
||||
@ -41,10 +43,11 @@ char bytstr[5]; //String Representation of Byte
|
||||
char inplin[MAXSTR]; //Input Buffer
|
||||
char *linptr; //Pointer into Input Buffer
|
||||
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 passno; //Assembler Pass Number (1 or 2)
|
||||
int endasm; //End Assembly Flag
|
||||
|
||||
char prgnam[256]; //Assembler Path and Name (from Command Line)
|
||||
char inpnam[256]; //Input File Name
|
||||
char outnam[256]; //Output File Name
|
||||
@ -114,6 +117,14 @@ void setsym(int value, int bytes) {
|
||||
symbol.value = value;
|
||||
if (bytes) symbol.bytes = bytes;
|
||||
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
|
||||
@ -137,10 +148,8 @@ int plabel(void) {
|
||||
strcpy(symbol.name, label);
|
||||
setsym(curadr, 0);
|
||||
}
|
||||
if (block) {
|
||||
for (int i=strlen(label)+1; i; i--) label[i] = label[i-1];
|
||||
label[0] = '.';
|
||||
}
|
||||
if (block) pfxstr('.', label);
|
||||
skpspc(); //Skip to Mnemonic, Comment, or EOL
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -205,6 +214,7 @@ struct sym *evlsym() {
|
||||
for (int i=0; name[i]; i++) if (opridx<MAXSTR) oprnd[opridx++] = name[i];
|
||||
struct sym *result = fndsym(block, name);
|
||||
if (passno == 2 && result == NULL) xerror("Undefined Symbol %s\n", name);
|
||||
if (result) result->refrd = TRUE; //Symbol was Referenced
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -299,6 +309,16 @@ void asmwrd(void) {
|
||||
} 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 */
|
||||
void asmfll(void) {
|
||||
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);
|
||||
}
|
||||
|
||||
/* Assemble END Pseudo-Op */
|
||||
void asmend(void) {
|
||||
endasm = TRUE;
|
||||
}
|
||||
|
||||
/* Assemble Pseudo-Op */
|
||||
int asmpso(void) {
|
||||
if (lkpopc(psolst) == FALSE) return FALSE;
|
||||
int asmpso(int dot) {
|
||||
if (lkpopc(psolst) == FALSE && dot == FALSE) return FALSE;
|
||||
skpspc();
|
||||
if (DEBUG) printf("Assembling Pseudo-Op %s, Token '%c'\n", mnmnc, token);
|
||||
switch (token) {
|
||||
@ -372,14 +397,18 @@ int asmpso(void) {
|
||||
case 'I': asminf(); break; //INCLude
|
||||
case '*': asmorg(); break; //ORG
|
||||
case 'P': asmprc(); break; //PROCessor
|
||||
case 'E': asmend(); break; //END
|
||||
case 'A': asmaln(); break; //ALIGn
|
||||
default: xerror("Undefined Pseudo-Op %s\n", mnmnc);
|
||||
}
|
||||
if (dot) pfxstr('.', mnmnc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Lookup Opcode */
|
||||
int lkpopc(struct opc opl[]) {
|
||||
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
|
||||
for (int i=0; opl[i].name[0]; i++) {
|
||||
if (strcmp(opl[i].name, mne)) continue;
|
||||
@ -498,9 +527,9 @@ void dbgopc(void) {
|
||||
}
|
||||
|
||||
/* Assemble Opcode */
|
||||
int asmopc(void) {
|
||||
int asmopc(int dot) {
|
||||
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 (DEBUG) printf("Assembling Opcode Token 0x%02X, ", token);
|
||||
if (DEBUG) printf("Addressing Mode Mask 0x%04X\n", amode);
|
||||
@ -526,9 +555,10 @@ int asmopc(void) {
|
||||
* Returns: Label Found (TRUE/FALSE) */
|
||||
int pmnmnc(void) {
|
||||
if (DEBUG) puts("Parsing Mnemonic");
|
||||
int dot = cpychr('.'); //Optional Dot before Pseudo-Op
|
||||
int found = pword(TRUE, mnmnc);
|
||||
opridx = 0; //Initialize Operand Index
|
||||
if (found) asmopc();
|
||||
if (found) asmopc(dot);
|
||||
oprnd[opridx] = 0; //Terminate Operand String
|
||||
return found;
|
||||
}
|
||||
@ -568,6 +598,7 @@ void clsinc(void) {
|
||||
incfil = NULL;
|
||||
incnam[0] = 0;
|
||||
lineno = savlno;
|
||||
endasm = FALSE; //Clear End Flag for Return to Maun File
|
||||
}
|
||||
|
||||
/* Assemble Input File (Two Pass) *
|
||||
@ -576,7 +607,8 @@ void clsinc(void) {
|
||||
* Uses: inplin - Input Line Buffer *
|
||||
* lineno - Input File Line Number */
|
||||
void asmfil(int pass) {
|
||||
passno = pass; //Assembly Pass Number
|
||||
endasm = FALSE; //Reset End Assembly Flag
|
||||
passno = pass; //Assembly Pass Number
|
||||
if (DEBUG) printf("Assembling Pass %d\n", pass);
|
||||
lineno = 1; //Initialize Input File Line Number
|
||||
blknum = 1; //Initialize Local Block Number
|
||||
@ -586,7 +618,7 @@ void asmfil(int pass) {
|
||||
while (TRUE) {
|
||||
if (incfil) linptr = fgets(inplin, MAXSTR, incfil);
|
||||
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);
|
||||
lstadr = curadr; //Set List Address
|
||||
mcode[0] = 0; //Clear Generated Macbine Code
|
||||
@ -606,9 +638,10 @@ void asmfil(int pass) {
|
||||
|
||||
/* Print Symbol Table */
|
||||
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++) {
|
||||
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
|
||||
asmfil(1); //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
|
||||
}
|
||||
|
||||
|
4
a02.h
4
a02.h
@ -42,8 +42,8 @@ struct amd amdesc[] = {
|
||||
struct opc {char name[5], token; int amode;};
|
||||
struct opc psolst[] = {
|
||||
{"BYTE", 'B', 0}, {"HEX", 'H'}, {"WORD", 'W', 0}, {"EQU", '=', 0}, {"FILL", 'F', 0},
|
||||
{"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"ORG", '*', 0}, {"PROC", 'P', 0},
|
||||
{"DC", 'B', 0}, {"DS", 'F', 0}, {"", 0, 0}
|
||||
{"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"DC", 'B', 0}, {"DS", 'F', 0}, {"ALIG", 'A', 0},
|
||||
{"ORG", '*', 0}, {"PROC", 'P', 0}, {"END", 'E', 0}, {"", 0, 0}
|
||||
};
|
||||
|
||||
struct opc opclst[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user