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:
parent
d02c8b6a3a
commit
77b0f1017f
65
a02.c
65
a02.c
@ -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
4
a02.h
@ -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[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user