mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-25 06:31:25 +00:00
Implemented and debugged more Peeudo-Ops
This commit is contained in:
parent
847ea78c3f
commit
a20695c93c
332
apps/a02.c02
332
apps/a02.c02
@ -3,7 +3,16 @@
|
|||||||
* Uses DASM Syntax but *
|
* Uses DASM Syntax but *
|
||||||
* supports 65C02 Op Codes */
|
* supports 65C02 Op Codes */
|
||||||
|
|
||||||
#define DEBUG %00000100 //Print Debug Information
|
/* DEBUG LEVELS *
|
||||||
|
* $01 - Echo Input Lines *
|
||||||
|
* $02 - Show Labels, Menonics, Operands *
|
||||||
|
* $04 - Symbol Search/Set Details *
|
||||||
|
* $08 - Individual Mnemonic Assembly *
|
||||||
|
* $10 - Term Evaluation Details *
|
||||||
|
^ $20 - IF and SWITCH details *
|
||||||
|
* $40 - Show Binary Output *
|
||||||
|
*/
|
||||||
|
#define DEBUG $07 //Print Debug Information
|
||||||
|
|
||||||
//#include "a02lib.h02" - This will replace all the defs below
|
//#include "a02lib.h02" - This will replace all the defs below
|
||||||
#include <stddef.h02>
|
#include <stddef.h02>
|
||||||
@ -29,10 +38,10 @@ const char amdesc = {"Accumulator", "Immediate", "Zero Page", "Zero Page,X",
|
|||||||
struct pso {char token, name[5];};
|
struct pso {char token, name[5];};
|
||||||
const char psolst = {'B', "BYTE", 'H', "HEX", 'W', "WORD", '=', "EQU", 'F', "FILL",
|
const char psolst = {'B', "BYTE", 'H', "HEX", 'W', "WORD", '=', "EQU", 'F', "FILL",
|
||||||
'I', "INCL", 'S', "SUBR", 'B', "DC", 'F', "DS", 'A', "ALIG",
|
'I', "INCL", 'S', "SUBR", 'B', "DC", 'F', "DS", 'A', "ALIG",
|
||||||
'*', "ORG", 'P', "PROC", 'E', "END", $FF};
|
'*', "ORG", 'P', "PROC", 'M', "ENDS", 'E', "END", $FF};
|
||||||
|
|
||||||
/* Op Code Lookup Table */
|
/* Op Code Lookup Table */
|
||||||
struct opc {int amode; char token, name[5];};
|
struct opc {char opcode, amdidx, name[5];};
|
||||||
const char opcalo = {$00, $00, $FE, $7D, $04, $04, $24, $26, $A6, $6E, $6C, $20, $20, $6E, $2C};
|
const char opcalo = {$00, $00, $FE, $7D, $04, $04, $24, $26, $A6, $6E, $6C, $20, $20, $6E, $2C};
|
||||||
const char opcahi = {$01, $10, $0E, $00, $00, $10, $00, $00, $00, $00, $00, $06, $00, $00, $00};
|
const char opcahi = {$01, $10, $0E, $00, $00, $10, $00, $00, $00, $00, $00, $06, $00, $00, $00};
|
||||||
const char opclst = {
|
const char opclst = {
|
||||||
@ -89,6 +98,10 @@ char inpidx; //Index into Input Buffer
|
|||||||
char eoinp; //End of Input
|
char eoinp; //End of Input
|
||||||
int lineno; //Input File Line Number
|
int lineno; //Input File Line Number
|
||||||
|
|
||||||
|
/* Output Variables */
|
||||||
|
char outlin[128]; //Input Buffer
|
||||||
|
char outidx; //Index into Input Buffer
|
||||||
|
|
||||||
|
|
||||||
/* Assembly Variables */
|
/* Assembly Variables */
|
||||||
char label[8]; //Assembly Line Label
|
char label[8]; //Assembly Line Label
|
||||||
@ -129,6 +142,9 @@ void error() {
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lenerr(w) {setdst(word); strcpy(w); strcat(" TOO LONG"); error(word);}
|
||||||
|
|
||||||
|
|
||||||
/* Read Line of Input from Console *
|
/* Read Line of Input from Console *
|
||||||
* Populates: inplin[] - Line of Input *
|
* Populates: inplin[] - Line of Input *
|
||||||
* Sets: inpidx - Length of Line *
|
* Sets: inpidx - Length of Line *
|
||||||
@ -145,18 +161,16 @@ char readln() {
|
|||||||
}
|
}
|
||||||
inplin[inpidx] = c;
|
inplin[inpidx] = c;
|
||||||
inpidx++;
|
inpidx++;
|
||||||
if (inpidx:-) error("!INPUT OVERFLOW");
|
if (inpidx:-) error("INPUT OVERFLOW");
|
||||||
} while (c);
|
} while (c);
|
||||||
return #FALSE;
|
return #FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prtchr(c) {if (c) putchr(c);} //Print Non-Null Character
|
void prtchr(c) {if (c) putchr(c);} //Print Non-Null Character
|
||||||
void prtlin() {putstr(); newlin();} //Print String plus New Lin
|
|
||||||
void prtbyt() {prbyte(); putchr(' ');} //Print Hexadecimal Word
|
void prtbyt() {prbyte(); putchr(' ');} //Print Hexadecimal Word
|
||||||
void echoln() {putchr('<'); putwrd(lineno); prtlin(inplin);}
|
void echoln() {putchr('<'); putwrd(lineno); putln(inplin);}
|
||||||
|
|
||||||
void init() {
|
void init() { if (#DEBUG&2) putln("#STARTING ASSEMBLY");
|
||||||
if (#DEBUG&2) prtlin("#STARTING ASSEMBLY");
|
|
||||||
lineno = 1; //Initialize Input File Line Number
|
lineno = 1; //Initialize Input File Line Number
|
||||||
orgset = #FALSE; //Origin Not Set
|
orgset = #FALSE; //Origin Not Set
|
||||||
endasm = #FALSE; //End Assembly Fl
|
endasm = #FALSE; //End Assembly Fl
|
||||||
@ -166,11 +180,13 @@ void init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Word from Input Line *
|
/* Parse Word from Input Line *
|
||||||
|
* Args: m = Maximum Length *
|
||||||
|
* w = &Description of Word *
|
||||||
* Populates: word[] *
|
* Populates: word[] *
|
||||||
* Sets: wrdlen *
|
* Sets: wrdlen *
|
||||||
* Updates: inpidx *
|
* Updates: inpidx *
|
||||||
* Returns: Word Found (TRUE/FALSE) */
|
* Returns: Word Found (TRUE/FALSE) */
|
||||||
char pword() {
|
char pword(m, w) {
|
||||||
wrdlen = 0;
|
wrdlen = 0;
|
||||||
while () {
|
while () {
|
||||||
if (#DEBUG:-) putchr(inplin[inpidx]);
|
if (#DEBUG:-) putchr(inplin[inpidx]);
|
||||||
@ -180,6 +196,8 @@ char pword() {
|
|||||||
inpidx++;
|
inpidx++;
|
||||||
}
|
}
|
||||||
word[wrdlen] = 0; //Terminate String
|
word[wrdlen] = 0; //Terminate String
|
||||||
|
if (m and wrdlen > m) lenerr(w);
|
||||||
|
if (#DEBUG&4) {puts("PARSED "); puts(w); printf(setdst(word)," \"%s\"%n");}
|
||||||
if (wrdlen) return #TRUE; else return #FALSE;
|
if (wrdlen) return #TRUE; else return #FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +213,6 @@ int skpchr(c) {
|
|||||||
/* Skip Spaces in Input Line *
|
/* Skip Spaces in Input Line *
|
||||||
* Updates: inpidx */
|
* Updates: inpidx */
|
||||||
void skpspc() {
|
void skpspc() {
|
||||||
i = 0;
|
|
||||||
while (inplin[inpidx]) {
|
while (inplin[inpidx]) {
|
||||||
if (A > ' ') break;
|
if (A > ' ') break;
|
||||||
inpidx++;
|
inpidx++;
|
||||||
@ -229,23 +246,22 @@ void wrtmcd() {
|
|||||||
/* Output Machine Language Character */
|
/* Output Machine Language Character */
|
||||||
void outchr(b) {
|
void outchr(b) {
|
||||||
chkorg();
|
chkorg();
|
||||||
if (mcdidx > 7) {wrtmcd(); newlin();}
|
//if (mcdidx > 7) {wrtmcd(); newlin();}
|
||||||
if (!mcdidx) mcdadr = curadr;
|
//if (!mcdidx) mcdadr = curadr;
|
||||||
if (#DEBUG&64) {putstr("#OUT "); putwrd(curadr); prtbyt(b); newlin();}
|
if (#DEBUG&64) printf(setdst(b,curadr),"#OUT: %w $%x%n");
|
||||||
mcode[mcdidx] = b;
|
if (outidx<127) {outlin[outidx] = b; outidx++;}
|
||||||
mcdidx++;
|
if (mcdidx<7) {mcode[mcdidx] = b; mcdidx++;}
|
||||||
curadr++;
|
curadr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output Machine Language Byte */
|
/* Output Machine Language Byte */
|
||||||
void outbyt() {
|
void outbyt() {
|
||||||
outchr(X);
|
outchr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write Word to Output File */
|
/* Write Word to Output File */
|
||||||
void outwrd(w) {
|
void outwrd(w) {
|
||||||
outbyt(w);
|
outchr(<w); outchr(>w);
|
||||||
c = >w; outchr(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print Symbol Table */
|
/* Print Symbol Table */
|
||||||
@ -291,6 +307,10 @@ void setsym(b, v) {
|
|||||||
symbol.value = v;
|
symbol.value = v;
|
||||||
if (!b) b = (>symbol.value) ? 2 : 1;
|
if (!b) b = (>symbol.value) ? 2 : 1;
|
||||||
symbol.bytes = b;
|
symbol.bytes = b;
|
||||||
|
if (#DEBUG&4) {
|
||||||
|
printf(setdst(symbol.block,symbol.name),"#SYMBOL %s IN BLOCK %d ");
|
||||||
|
printf(setdst(symbol.bytes,symbol.value),"SET TO VALUE %i, SIZE %d%n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Label from Input Line
|
/* Parse Label from Input Line
|
||||||
@ -302,34 +322,35 @@ void setsym(b, v) {
|
|||||||
* Updates: c */
|
* Updates: c */
|
||||||
void plabel() {
|
void plabel() {
|
||||||
local = (skpchr('.')) ? '.' : 0; //Check for Local Label
|
local = (skpchr('.')) ? '.' : 0; //Check for Local Label
|
||||||
if (pword()) {
|
if (#DEBUG&4) {puts("#PARSING "); if (local) puts("LOCAL "); putln("LABEL");}
|
||||||
if (wrdlen>8) error("!SYMBOL TOO LONG");
|
if (pword(8,"SYMBOL")) {
|
||||||
setdst(label); strcpy(word);
|
setdst(label); strcpy(word);
|
||||||
if (#DEBUG&2) {putstr("#FOUND "); if (local) putstr("LOCAL "); putstr("LABEL "); prtlin(label);}
|
//if (#DEBUG&2) {putstr("#FOUND "); if (local) putstr("LOCAL "); putstr("LABEL "); putln(label);}
|
||||||
symbol.block = (local) ? blknum : 0;
|
symbol.block = (local) ? blknum : 0;
|
||||||
setdst(symbol.name);strcpy(label);
|
setdst(symbol.name);strcpy(label);
|
||||||
setsym(0, curadr); symflg = orgset;
|
setsym(0, curadr); symflg = orgset;
|
||||||
} else {
|
} else {
|
||||||
label[0] = 0;
|
label[0] = 0;
|
||||||
if (#DEBUG&2) prtlin("#NO LABEL FOUND");
|
if (#DEBUG&2) putln("#NO LABEL FOUND");
|
||||||
}
|
}
|
||||||
colon = skpchr(':'); //Optional Colon after Label
|
colon = skpchr(':'); //Optional Colon after Label
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Mnemonic from Input Line *
|
/* Parse Mnemonic from Input Line *
|
||||||
* Sets: mnmnc *
|
* Sets: mnmnc = Mnemonic *
|
||||||
|
* word = Mnemonic *
|
||||||
|
* wrdlen = Mnemonic Length *
|
||||||
* Updates: inpidx *
|
* Updates: inpidx *
|
||||||
* Returns: Opcode Found (TRUE/FALSE) */
|
* Returns: Mnemonic Found (TRUE/FALSE) */
|
||||||
char pmnmnc() {
|
char pmnmnc() {
|
||||||
skpspc(); //Skip Leading Spaces
|
skpspc(); //Skip Leading Spaces
|
||||||
dot = skpchr('.'); //Optional Dot before Pseudo-Op
|
dot = skpchr('.'); //Optional Dot before Pseudo-Op
|
||||||
if (pword()) {
|
if (pword(12,"MNEMONIC")) {
|
||||||
if (wrdlen>12) error("!MNEMONIC TOO LONG");
|
|
||||||
for (i=0; i<=wrdlen; i++) mnmnc[i] = word[i];
|
for (i=0; i<=wrdlen; i++) mnmnc[i] = word[i];
|
||||||
if (#DEBUG&2) {putstr("#FOUND MNEMONIC "); prtlin(mnmnc);}
|
if (#DEBUG&2) {putstr("#FOUND MNEMONIC "); putln(mnmnc);}
|
||||||
} else {
|
} else {
|
||||||
mnmnc[0] = 0;
|
mnmnc[0] = 0;
|
||||||
if (#DEBUG&2) prtlin("#NO MNEMONIC FOUND");
|
if (#DEBUG&2) putln("#NO MNEMONIC FOUND");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +364,7 @@ char pmnmnc() {
|
|||||||
* Returns: TRUE if found */
|
* Returns: TRUE if found */
|
||||||
char lookup(amflg, srcptr) {
|
char lookup(amflg, srcptr) {
|
||||||
if (#DEBUG:-) printf(setdst(amflg,srcptr), "LOOKUP(%x,%w)");
|
if (#DEBUG:-) printf(setdst(amflg,srcptr), "LOOKUP(%x,%w)");
|
||||||
while () { //Search Pseudo-Op List
|
while () { //Search Op-Code List
|
||||||
if (#DEBUG:-) printf(setdst(srcptr)," SRCPTR=%w");
|
if (#DEBUG:-) printf(setdst(srcptr)," SRCPTR=%w");
|
||||||
token = *srcptr; srcptr++; if (#DEBUG:-) printf(token, ", TOKEN=%d");
|
token = *srcptr; srcptr++; if (#DEBUG:-) printf(token, ", TOKEN=%d");
|
||||||
if (token == $FF) break;
|
if (token == $FF) break;
|
||||||
@ -367,6 +388,7 @@ char lookup(amflg, srcptr) {
|
|||||||
|
|
||||||
/* Evaluate Binary Number */
|
/* Evaluate Binary Number */
|
||||||
void evlbin() {
|
void evlbin() {
|
||||||
|
if (#DEBUG&16) putln("#EVALUATING BINARY NUMBER");
|
||||||
term = 0;
|
term = 0;
|
||||||
cpychr('%');
|
cpychr('%');
|
||||||
while (isbdgt(inplin[inpidx])) {
|
while (isbdgt(inplin[inpidx])) {
|
||||||
@ -377,6 +399,7 @@ void evlbin() {
|
|||||||
|
|
||||||
/* Evaluate Character Constant */
|
/* Evaluate Character Constant */
|
||||||
void evlchr() {
|
void evlchr() {
|
||||||
|
if (#DEBUG&16) putln("#EVALUATING QUOTED CHARACTER");
|
||||||
cpychr('\'');
|
cpychr('\'');
|
||||||
term = int(inplin[inpidx]);
|
term = int(inplin[inpidx]);
|
||||||
cpychr(0);
|
cpychr(0);
|
||||||
@ -385,6 +408,7 @@ void evlchr() {
|
|||||||
|
|
||||||
/* Evaluate Decimal Number */
|
/* Evaluate Decimal Number */
|
||||||
int evldec() {
|
int evldec() {
|
||||||
|
if (#DEBUG&16) putln("#EVALUATING DECIMAL NUMBER");
|
||||||
term = 0;
|
term = 0;
|
||||||
while (isdigt(inplin[inpidx])) {
|
while (isdigt(inplin[inpidx])) {
|
||||||
term = imultc(10, term);
|
term = imultc(10, term);
|
||||||
@ -395,6 +419,7 @@ int evldec() {
|
|||||||
|
|
||||||
/* Evaluate Hexadecimal Number */
|
/* Evaluate Hexadecimal Number */
|
||||||
int evlhex() {
|
int evlhex() {
|
||||||
|
if (#DEBUG&16) putln("#EVALUATING HEXADECIMAL NUMBER");
|
||||||
term = 0;
|
term = 0;
|
||||||
cpychr('$');
|
cpychr('$');
|
||||||
while (ishdgt(inplin[inpidx])) {
|
while (ishdgt(inplin[inpidx])) {
|
||||||
@ -406,49 +431,68 @@ int evlhex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char evlsym() {
|
||||||
|
local = cpychr('.'); //Check for Local Symbol
|
||||||
|
if (!pword(8,"SYMBOL")) {if (local) error("INVALID SYMBOL"); else return;}
|
||||||
|
if (#DEBUG&16) printf(setdst(word),"#EVALUATING SYMBOL \"%s\"%n");
|
||||||
|
for (i=0; i<wrdlen; i++) {
|
||||||
|
if (opridx:+) {oprnd[opridx] = word[i]; opridx++;}
|
||||||
|
}
|
||||||
|
found = fndsym();
|
||||||
|
if (!found) error("UNDEFINED SYMBOL");
|
||||||
|
return #TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluation Routine Dispatch */
|
||||||
|
void evldsp() {
|
||||||
|
found = #TRUE;
|
||||||
|
if (inplin[inpidx]=='.' or isalph(A)) {
|
||||||
|
if (#DEBUG&32) putln("#ALUMUNDOT");
|
||||||
|
if (evlsym()) term = varble.value; else term = &$0100;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isdigt(inplin[inpidx])) {
|
||||||
|
if (#DEBUG&32) putln("#DIGIT");
|
||||||
|
evldec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (#DEBUG&32) putln("#SOMETHING ELSE");
|
||||||
|
select(inplin[inpidx]) {
|
||||||
|
case '$': evlhex(); break;
|
||||||
|
case '%': evlbin(); break;
|
||||||
|
case '\'': evlchr(); break;
|
||||||
|
default: found = #FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Evaluate Term in Operand *
|
/* Evaluate Term in Operand *
|
||||||
* Updates: inpidx
|
* Updates: inpidx
|
||||||
* Sets: term
|
* Sets: term
|
||||||
* Returns: #TRUE if a term was found */
|
* Returns: #TRUE if a term was found */
|
||||||
char evltrm() {
|
char evltrm() {
|
||||||
skpspc();
|
skpspc();
|
||||||
if (isalud(inplin[inpidx])) {
|
if (#DEBUG&16) printf(inplin[inpidx],"#EVALUATING TERM BEGINNING WITH '%c'%n");
|
||||||
if (evlsym()) term = symbol.value; else term = &$0100;
|
evldsp();
|
||||||
}
|
|
||||||
else if (isdigt(inplin[inpidx]))
|
|
||||||
evldec();
|
|
||||||
else select(inplin[inpidx]) {
|
|
||||||
case '$': evlhex(); break;
|
|
||||||
case '%': evlbin(); break;
|
|
||||||
case '\'': evlchr(); break;
|
|
||||||
default: return #FALSE;
|
|
||||||
}
|
|
||||||
skpspc();
|
skpspc();
|
||||||
if (#DEBUG&2) {putstr("#TERM=$"); putwrd(term); newlin();}
|
if (#DEBUG&16) {if (found) printf(setdst(term),"#TERM=%i%n"); else putln("#NO TERM");}
|
||||||
return #TRUE;
|
return found;
|
||||||
}
|
|
||||||
|
|
||||||
char evlsym() {
|
|
||||||
local = cpychr('.'); //Check for Local Symbol
|
|
||||||
if (!pword()) {if (local) error("INVALID SYMBOL"); else return;}
|
|
||||||
for (i=0; i<wrdlen; i++) {
|
|
||||||
if (opridx:+) {oprnd[opridx] = word[i]; opridx++;}
|
|
||||||
}
|
|
||||||
else found = fndsym();
|
|
||||||
if (found) opdval = symbol.value;
|
|
||||||
else error("UNDEFINED SYMBOL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evaluate Operand *
|
/* Evaluate Operand *
|
||||||
* Args: maxsiz = maximum size *
|
* Args: opdrqd = Operation Required *
|
||||||
* Returns: Operand Value */
|
* reqbyt = Value Must Be Byte *
|
||||||
|
* Sets: opdval = Operand Value
|
||||||
|
* Returns: Operand Found */
|
||||||
char evlopd(opdrqd, reqbyt) {
|
char evlopd(opdrqd, reqbyt) {
|
||||||
hilo = 0; //Return LSB (1) or MSB ($FF)
|
hilo = 0; //Return LSB (1) or MSB ($FF)
|
||||||
prns = 0; //Optional Parenthesis after Hi/Low Operator
|
prns = 0; //Optional Parenthesis after Hi/Low Operator
|
||||||
skpspc();
|
skpspc();
|
||||||
if (cpychr('<')) hilo = 1; else if (cpychr('>')) hilo = $FF;
|
if (#DEBUG&16) printf(inplin[inpidx],"#EVALUATING OPERAND BEGINNING WITH '%c'%n");
|
||||||
|
if (cpychr('<')) hilo = 1; else {if (cpychr('>')) hilo = $FF;}
|
||||||
if (hilo) prns = cpychr('(');
|
if (hilo) prns = cpychr('(');
|
||||||
|
if (#DEBUG&16) printf(hilo,"#HILO SET TO $%x%n");
|
||||||
result = evltrm();
|
result = evltrm();
|
||||||
|
if (#DEBUG&16) printf(setdst(result,term),"#EVLTRM RETURNED $%d, TERM=%i%n");
|
||||||
if (result) {
|
if (result) {
|
||||||
opdval = term;
|
opdval = term;
|
||||||
while (cpychr('+')) {
|
while (cpychr('+')) {
|
||||||
@ -456,25 +500,28 @@ char evlopd(opdrqd, reqbyt) {
|
|||||||
opdval = iadd(setdst(opdval),term);
|
opdval = iadd(setdst(opdval),term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (#DEBUG&16) printf(setdst(opdval),"#CALCULATED OPDVAL %i%n");
|
||||||
if (hilo) {
|
if (hilo) {
|
||||||
if (!result) error("!ILLEGAL OPERAND");
|
if (!result) error("ILLEGAL OPERAND");
|
||||||
if (prns) cpychr(')'); //Skip End Parenthesis
|
if (prns) cpychr(')'); //Skip End Parenthesis
|
||||||
if (hilo:-) opdval = int(>opdval); //Copy MSB to LSB
|
if (hilo:-) opdval = int(>opdval); //Copy MSB to LSB
|
||||||
opdval = int(<opdval); //Return LSB
|
opdval = int(<opdval); //Return LSB
|
||||||
|
if (#DEBUG&16) printf(setdst(hilo,opdval),"#HILO $%x, OPDVAL SET TO %i%n");
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
if (#DEBUG&2) printf(setdst(opdval), "#OPERAND VALUE=%i%n");
|
if (#DEBUG&2) printf(setdst(opdval), "#OPERAND VALUE=%i%n");
|
||||||
if (reqbyt & >opdval) error("!VALUE TOO LARGE");
|
if (reqbyt & >opdval) error("VALUE TOO LARGE");
|
||||||
} else {
|
} else {
|
||||||
if (#DEBUG&2) putln("#NO OPERAND");
|
if (#DEBUG&2) putln("#NO OPERAND");
|
||||||
if (opdrqd) error("!OPERAND REQUIRED");
|
if (opdrqd) error("OPERAND REQUIRED");
|
||||||
}
|
}
|
||||||
return result;
|
return result, opdval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assemble EQU Pseudo-Op */
|
/* Assemble EQU Pseudo-Op */
|
||||||
void asmequ() {
|
void asmequ() {
|
||||||
if (!label[0]) error("!LABEL REQUIRED");
|
if (#DEBUG&8) putln("#ASSEMBLING EQU PSEUDO-OP");
|
||||||
|
if (!label[0]) error("LABEL REQUIRED");
|
||||||
evlopd(#TRUE, #FALSE);
|
evlopd(#TRUE, #FALSE);
|
||||||
setsym(0,opdval); symflg = #TRUE;
|
setsym(0,opdval); symflg = #TRUE;
|
||||||
}
|
}
|
||||||
@ -495,11 +542,13 @@ void asmorg() {
|
|||||||
/* Assemble BYTE Pseudo-Op */
|
/* Assemble BYTE Pseudo-Op */
|
||||||
void asmbyt() {
|
void asmbyt() {
|
||||||
do {
|
do {
|
||||||
|
skpspc();
|
||||||
if (cpychr('"')) { //String Operand
|
if (cpychr('"')) { //String Operand
|
||||||
|
if (#DEBUG&2) putln("#ASSEMBLING .BYTE STRING OPERAND");
|
||||||
while (!cpychr('"')) {outchr(inplin[inpidx]); cpychr(0); }
|
while (!cpychr('"')) {outchr(inplin[inpidx]); cpychr(0); }
|
||||||
skpspc();
|
skpspc();
|
||||||
} else {
|
} else {
|
||||||
if (evlopd(#TRUE, #TRUE)) outbyt(opdval); //Evaluate Operand
|
if (evlopd(#TRUE, #TRUE)) outbyt(<opdval); //Evaluate Operand
|
||||||
}
|
}
|
||||||
} while (cpychr(','));
|
} while (cpychr(','));
|
||||||
}
|
}
|
||||||
@ -507,13 +556,27 @@ void asmbyt() {
|
|||||||
/* Assemble HEX Pseudo-Op */
|
/* Assemble HEX Pseudo-Op */
|
||||||
void asmhex() {
|
void asmhex() {
|
||||||
do {
|
do {
|
||||||
evlhex(); outbyt(term);
|
skpspc();
|
||||||
} while (cpychr(','));
|
evlhex(); outbyt(<term); if (>term) outbyt(>term);
|
||||||
|
skpspc();
|
||||||
|
} while (ishdgt(inplin[inpidx]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assemble SUBROUTINE Pseudo-Op */
|
/* Assemble SUBROUTINE Pseudo-Op */
|
||||||
void asmsub() {
|
void asmsub() {
|
||||||
|
blkcnt++; blknum = blkcnt;
|
||||||
|
if (#DEBUG&2) printf(blknum,"#BLKNUM SET TO %d%n");
|
||||||
|
if (pword(7, "SUBROUTINE NAME")) {
|
||||||
|
opridx=strcpy(setdst(oprnd),word);
|
||||||
|
} else {
|
||||||
|
if (#DEBUG&2) putln("NO SUBROUTINE NAME");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble ENDSUBROUTINE Pseudo-Op */
|
||||||
|
void asmens() {
|
||||||
|
blknum = 1;
|
||||||
|
if (#DEBUG&2) printf(blknum,"#BLKNUM RESET TO %d%n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assemble WORD Pseudo-Op */
|
/* Assemble WORD Pseudo-Op */
|
||||||
@ -525,17 +588,39 @@ void asmwrd() {
|
|||||||
|
|
||||||
/* Assemble ALIGN Pseudo-Op */
|
/* Assemble ALIGN Pseudo-Op */
|
||||||
void asmaln() {
|
void asmaln() {
|
||||||
w = evlopd(#TRUE, #FALSE);
|
//v = size, w = fill
|
||||||
opdval = 0;
|
v = evlopd(#TRUE, #FALSE); if (icmp(iacc(v),&2):-) return;
|
||||||
while(icmp(iacc(opdval),curadr):+) opdval = iadd(setdst(opdval),w);
|
if (#DEBUG&2) printf(setdst(v),"ALIGNING TO %i BYTES%n");
|
||||||
|
w = imod(iacc(curadr),v); w = isub(iacc(v),w); //w = w - (curadr % v)
|
||||||
|
if (#DEBUG&2) printf(setdst(w),"FILLING %i BYTES%n");
|
||||||
|
if (!icmp(w)) return;
|
||||||
|
for (v=0; icmp(iacc(v),w):-; v++) outbyt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assemble FILL Pseudo-Op */
|
||||||
|
void asmfll() {
|
||||||
|
w = evlopd(#TRUE, #FALSE);
|
||||||
|
if (#DEBUG&2) printf(setdst(w),"FILLING %i BYTES%n");
|
||||||
|
for (v=0; icmp(iacc(v),w):-; v++) outbyt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble END Pseudo-Op */
|
||||||
|
void asmend() {
|
||||||
|
endasm = #TRUE;
|
||||||
|
if (#DEBUG&2) printf(endasm,"#ENDASM SET TO $%x%n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Assemble Pseudo-Op */
|
/* Assemble Pseudo-Op */
|
||||||
|
/* Uses: mnmnc = mnemonic *
|
||||||
|
* Sets: token = op code token *
|
||||||
|
* found = pseudo-op found *
|
||||||
|
* Destroys: match *
|
||||||
|
* Returns: TRUE if found */
|
||||||
|
|
||||||
char asmpso() {
|
char asmpso() {
|
||||||
found = lookup(#FALSE, psolst); //Lookup Pseudo-Op
|
found = lookup(#FALSE, psolst); //Lookup Pseudo-Op
|
||||||
if (!found) {if (dot) error("ILLEGAL PSEUDO-OP"); else return #FALSE;}
|
if (!found) {if (dot) error("ILLEGAL PSEUDO-OP"); else return #FALSE;}
|
||||||
if (#DEBUG&2) prtlin("ASSEMBLING PSEUDO-OP");
|
if (#DEBUG&2) printf(token,"#ASSEMBLING PSEUDO-OP TOKEN='%c'%n");
|
||||||
skpspc();
|
skpspc();
|
||||||
select (token) {
|
select (token) {
|
||||||
case '=': asmequ(); break; //EQU
|
case '=': asmequ(); break; //EQU
|
||||||
@ -543,14 +628,14 @@ char asmpso() {
|
|||||||
case 'B': asmbyt(); //BYTE
|
case 'B': asmbyt(); //BYTE
|
||||||
case 'H': asmhex(); //HEX
|
case 'H': asmhex(); //HEX
|
||||||
case 'W': asmwrd(); //WORD
|
case 'W': asmwrd(); //WORD
|
||||||
//case 'F': asmfll(); //FILL
|
case 'F': asmfll(); //FILL
|
||||||
case 'S': asmsub(); //SUBRoutine
|
case 'S': asmsub(); //SUBRoutine
|
||||||
|
case 'M': asmens(); //ENDSubroutine
|
||||||
//case 'I': asminf(); //INCLude
|
//case 'I': asminf(); //INCLude
|
||||||
//case '*': asmorg(); //ORG
|
|
||||||
//case 'P': asmprc(); //PROCessor
|
//case 'P': asmprc(); //PROCessor
|
||||||
case 'A': asmaln(); //ALIGn
|
case 'A': asmaln(); //ALIGn
|
||||||
case 'E': endasm = #TRUE; //END
|
case 'E': asmend(); //END
|
||||||
default: error("!UNIMPLEMENTED");
|
default: error("UNIMPLEMENTED");
|
||||||
}
|
}
|
||||||
return #TRUE;
|
return #TRUE;
|
||||||
}
|
}
|
||||||
@ -588,8 +673,8 @@ char fixopc() {
|
|||||||
void asmopc() {
|
void asmopc() {
|
||||||
opmod = 0;
|
opmod = 0;
|
||||||
found = lookup(#TRUE, opclst); //Lookup OpCode
|
found = lookup(#TRUE, opclst); //Lookup OpCode
|
||||||
if (!found) error("!ILLEGAL MNEMONIC");
|
if (!found) error("ILLEGAL MNEMONIC");
|
||||||
if (#DEBUG&2) {putstr("OPCODE: "); prtbyt(token); prtbyt(amidx);}
|
if (#DEBUG&2) {putstr("#OPCODE: "); prtbyt(token); prtbyt(amidx);}
|
||||||
amdlo = opcalo[amidx]; amdhi = opcahi[amidx];
|
amdlo = opcalo[amidx]; amdhi = opcahi[amidx];
|
||||||
if (#DEBUG&2) {prbyte(amdhi); prbyte(amdlo); newlin();}
|
if (#DEBUG&2) {prbyte(amdhi); prbyte(amdlo); newlin();}
|
||||||
|
|
||||||
@ -610,7 +695,7 @@ void pcmmnt() {
|
|||||||
i++; inpidx++;
|
i++; inpidx++;
|
||||||
}
|
}
|
||||||
cmmnt[i] = 0; //Terminate Comment
|
cmmnt[i] = 0; //Terminate Comment
|
||||||
if (#DEBUG&2) {if (i) {putstr("#COMMENT: "); prtlin(cmmnt);} else prtlin("No Comment Found");}
|
if (#DEBUG&2) {if (i) {putstr("#COMMENT: "); putln(cmmnt);} else putln("#NO COMMENT FOUND");}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append Symbol` to Symbol Table *
|
/* Append Symbol` to Symbol Table *
|
||||||
@ -627,15 +712,16 @@ void addsym() {
|
|||||||
dstptr++;
|
dstptr++;
|
||||||
}
|
}
|
||||||
symptr = dstptr;
|
symptr = dstptr;
|
||||||
|
if (#DEBUG&4) printf(setdst(symbol.name),"#ADDED SYMBOL \"%s\" TO TABLE%n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print Listing Line */
|
/* Print Listing Line */
|
||||||
void prlist() {
|
void prlist() {
|
||||||
prtchr('|');
|
putc('|');
|
||||||
prtchr(local); putstr(label); prtchr(colon); putchr(' ');
|
prtchr(local); putstr(label); prtchr(colon); putspc();
|
||||||
prtchr(dot); putstr(mnmnc); putchr(' ');
|
prtchr(dot); putstr(mnmnc); putspc(' ');
|
||||||
if (opridx) putstr(oprnd);
|
if (opridx) putstr(oprnd);
|
||||||
prtlin(cmmnt);
|
putln(cmmnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void asmlin() {
|
void asmlin() {
|
||||||
@ -647,21 +733,21 @@ void asmlin() {
|
|||||||
pmnmnc(); //Parse Mnemonic
|
pmnmnc(); //Parse Mnemonic
|
||||||
if (mnmnc[0]) {
|
if (mnmnc[0]) {
|
||||||
if (!asmpso()) asmopc(); //Assemble Pseudo-Op or Op-Code
|
if (!asmpso()) asmopc(); //Assemble Pseudo-Op or Op-Code
|
||||||
oprnd[opridx] = 0; //Set oprnd to ""
|
oprnd[opridx] = 0; //Terminste oprnd
|
||||||
}
|
}
|
||||||
pcmmnt(); //Parse Comment
|
pcmmnt(); //Parse Comment
|
||||||
if (label[0]) {
|
if (label[0]) {
|
||||||
if (!symflg) error("INVALID ADDRESS");
|
if (!symflg) error("INVALID ADDRESS");
|
||||||
addsym(); //Add Label to Table
|
addsym(); //Add Label to Table
|
||||||
}
|
}
|
||||||
if (mcdidx) wrtmcd(); //Write Machine Code
|
//if (mcdidx) wrtmcd(); //Write Machine Code
|
||||||
prlist();
|
prlist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main:
|
main:
|
||||||
init(); //Initialize Assembly Variables
|
init(); //Initialize Assembly Variables
|
||||||
goto tests;
|
goto tests;
|
||||||
|
goto tests;
|
||||||
while (!readln()) {
|
while (!readln()) {
|
||||||
if (#DEBUG&1) echoln();
|
if (#DEBUG&1) echoln();
|
||||||
asmlin(); if (endasm) break;
|
asmlin(); if (endasm) break;
|
||||||
@ -678,13 +764,20 @@ void setln(w) {
|
|||||||
inpidx = 0;
|
inpidx = 0;
|
||||||
setdst(inplin);
|
setdst(inplin);
|
||||||
strcpy(w);
|
strcpy(w);
|
||||||
putln(inplin);
|
putstr(">>"); putln(inplin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Print Operand
|
||||||
|
void poprnd() {
|
||||||
|
oprnd[opridx] = 0;
|
||||||
|
printf(setdst(oprnd)," OPRND=\"%s\"%n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void slabel() {setln(); plabel();}
|
||||||
|
|
||||||
//Test function plabel
|
//Test function plabel
|
||||||
void tlabel() {
|
void tlabel() {
|
||||||
setln();
|
slabel();
|
||||||
plabel();
|
|
||||||
if (label[0]) {
|
if (label[0]) {
|
||||||
setdst(label); printf(local," LABEL=\"%s\", LOCAL=%d%n");
|
setdst(label); printf(local," LABEL=\"%s\", LOCAL=%d%n");
|
||||||
setdst(symbol.name); printf(symbol.block, " SYMBOL.BLOCK=%d, NAME=\"%s\", ");
|
setdst(symbol.name); printf(symbol.block, " SYMBOL.BLOCK=%d, NAME=\"%s\", ");
|
||||||
@ -697,9 +790,20 @@ void tlabel() {
|
|||||||
|
|
||||||
//Test function evltrm
|
//Test function evltrm
|
||||||
void tterm() {
|
void tterm() {
|
||||||
|
opridx = 0;
|
||||||
setln();
|
setln();
|
||||||
if (evltrm()) printf(setdst(term)," TERM=%i%n");
|
if (evltrm()) printf(setdst(term)," TERM=%i%n");
|
||||||
else putln("NO TERM FOUND");
|
else putln("NO TERM FOUND");
|
||||||
|
poprnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Test evltopd()
|
||||||
|
void topd() {
|
||||||
|
opridx = 0;
|
||||||
|
setln();
|
||||||
|
if (evlopd(#FALSE,#FALSE)) printf(setdst(opdval)," OPERAND=%i%n");
|
||||||
|
else putln(" NO OPERAND FOUND");
|
||||||
|
poprnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test find symbol
|
//Test find symbol
|
||||||
@ -715,27 +819,69 @@ void tfind(local, tmpptr) {
|
|||||||
void tmnmnc() {
|
void tmnmnc() {
|
||||||
setln();
|
setln();
|
||||||
pmnmnc();
|
pmnmnc();
|
||||||
//print results
|
printf(setdst(mnmnc)," MNEMONIC=\"%s\"%n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void pout() {
|
||||||
|
puts(" OUTLIN: ");
|
||||||
|
for (i=0; i<outidx; i++) printf(outlin[i],"%x ");
|
||||||
|
newlin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tpso() {
|
||||||
|
opridx = 0; outidx = 0;
|
||||||
|
opridx = 0; opridx = 0;
|
||||||
|
setln();
|
||||||
|
pmnmnc();
|
||||||
|
asmpso();
|
||||||
|
if (outidx) pout();
|
||||||
|
printf(setdst(curadr),"#CURADR=$%w%n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void tasm() {
|
||||||
|
setln();
|
||||||
|
asmlin();
|
||||||
|
if (outidx) pout();
|
||||||
|
printf(setdst(curadr),"#CURADR=$%w%n");
|
||||||
}
|
}
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
orgadr = &$0300; orgset = #TRUE;
|
tpso("ORG $0300"); printf(setdst(orgset, orgadr)," ORGSET=$%x, ORGADR=$%w%n");
|
||||||
curadr = orgadr;
|
curadr = orgadr;
|
||||||
tlabel("GLOBAL"); tlabel(".LOCAL"); tlabel("GLOBC:"); tlabel(".LOCC:");
|
//tlabel("GLOBAL"); tlabel(".LOCAL"); tlabel("GLOBC:"); tlabel(".LOCC:");
|
||||||
tterm(" 123"); tterm(" $FF "); tterm("%10101010");
|
//topd(" 123"); topd(" $FF "); topd("%10101010");
|
||||||
tterm(" 4567"); tterm("$1001 "); tterm("%1010101001010101");
|
//topd(" 4567"); topd("$1001 "); topd("%1010101001010101");
|
||||||
tfind(0,"LOCAL"); tfind('.',"GLOBAL"); tfind(0,"LOCC"); tfind('.',"GLOBC");
|
//topd("GLOBAL"); topd(".LOCAL"); topd(" GLOBC"); topd(" .LOCC");
|
||||||
tterm("GLOBAL"); tterm(".LOCAL"); tterm(" GLOBC"); tterm(" .LOCC");
|
slabel("ONE:"); tpso("EQU 1"); addsym();
|
||||||
|
slabel("CEE:"); tpso("EQU 'C'"); addsym();
|
||||||
|
slabel("BIG:"); tpso("EQU $ABCD"); addsym();
|
||||||
|
slabel("TOP:"); tpso("EQU $FFFF"); addsym();
|
||||||
|
tpso("BYTE 0, ONE ,%10 ,$3,'4',CEE");
|
||||||
|
tpso(".DC <BIG, >BIG, \"STRING\" ");
|
||||||
|
tpso("HEX 0 1 2 F 10 F0 FEEF ");
|
||||||
|
tpso("WORD 1, 1001, %11111, $F00F, TOP");
|
||||||
|
tpso("FILL 300");
|
||||||
|
tpso("ALIGN 256");
|
||||||
|
tpso("DS 20");
|
||||||
|
tpso("SUBR MYLIB");
|
||||||
|
tpso("SUBROUTINE");
|
||||||
|
tpso("ENDSUB");
|
||||||
|
tpso("END");
|
||||||
|
|
||||||
|
//tmnmnc("RTS"); tmnmnc("SUBROUTINE"); tmnmnc(" "); tmnmnc("9");tmnmnc(";");
|
||||||
prtsym();
|
prtsym();
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
// 'I', "INCL", 'S', 'F', "DS", 'P', "PROC",
|
||||||
|
|
||||||
|
|
||||||
void dolkup() {
|
void dolkup() {
|
||||||
found = lookup(#FALSE, psolst); if (#DEBUG:-) {prtbyt(found); newlin();}
|
found = lookup(#FALSE, psolst); if (#DEBUG:-) {prtbyt(found); newlin();}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = lookup(#TRUE, opclst); if (#DEBUG:-) {prtbyt(found); newlin();}
|
found = lookup(#TRUE, opclst); if (#DEBUG:-) {prtbyt(found); newlin();}
|
||||||
}
|
}
|
||||||
if (found) {prtbyt(token); prtbyt(amidx);} else putstr("*NOF* ");
|
if (found) {prtbyt(token); prtbyt(amidx);} else putstr("*NOF* ");
|
||||||
prtlin(mnmnc);
|
putln(mnmnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
tstlkp:
|
tstlkp:
|
||||||
|
Loading…
Reference in New Issue
Block a user