summaryrefslogtreecommitdiff
path: root/asmmon.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
commitc5150ee31f07208422f1435de9b35a0d0168cbb5 (patch)
tree78150bf0339cf81401c00973f96c94a3c231015e /asmmon.c
parent59dc46ca8fe1eb6f98abb98fe8579aeaedd2ff15 (diff)
Completely changed the assembler.
It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller.
Diffstat (limited to 'asmmon.c')
-rw-r--r--asmmon.c1883
1 files changed, 600 insertions, 1283 deletions
diff --git a/asmmon.c b/asmmon.c
index 3f715ac..de4b9a3 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -1,97 +1,15 @@
-#include "opcode.h"
-#include <ctype.h>
-#include <string.h>
-
-#define debug 1
-
-#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _IND, _INX, _INY, _ABS, _IMPL) \
-{opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \
-opcodes[num].imm = _IMM; \
-opcodes[num].zm = _ZM; opcodes[num].zmx = _ZMX; opcodes[num].zmy = _ZMY; \
-opcodes[num].ind = _IND; opcodes[num].inx = _INX; opcodes[num].iny = _INY; \
-opcodes[num].abs = _ABS; opcodes[num].impl = _IMPL;}
+#include "asmmon.h"
+uint16_t linenum = 10;
+uint16_t lineidx = 0;
+uint16_t stridx = 0;
+uint16_t comidx = 0;
+uint8_t defined = 0;
-struct fixup {
- struct fixup *nxt;
- struct label *l;
- uint64_t adr;
-};
+uint8_t isfixup = 0;
-struct label {
- struct label* nxt;
- uint64_t adr;
- uint8_t def;
- char name[1];
-};
static char tstr[2048];
-struct label *labels = 0;
-struct fixup *fixups = 0;
-uint8_t defined = 0;
-struct label *mklabel(const char *name, uint64_t adr, uint8_t def) {
- struct label *l;
- for (l = labels; l; l = l->nxt) {
- if (!strcasecmp(name, l->name)) {
- if (def) {
- if (l->def) {
- printf("oof, you cannot redefine the label: %s\n", name);
- defined = 1;
- } else {
- defined = 0;
- }
- l->def = def;
- l->adr = adr;
- }
- return l;
- }
- }
- l = malloc(sizeof(*l) + strlen(name));
- l->def = def;
- l->adr = adr;
- strcpy(l->name, name);
- l->nxt = labels;
- labels = l;
- defined = 0;
- return l;
-}
-uint64_t use_label(const char *name, uint64_t adr) {
- struct label *l = mklabel(name, 0, 0);
- adr++;
- if (l->def) {
- return l->adr;
- } else {
- printf("oof, label %s, does not exist, yet.\n", name);
- struct fixup *f = malloc(sizeof(*f));
- f->nxt = fixups;
- f->adr = adr;
- f->l = l;
- fixups = f;
- return adr-1;
- }
-}
-void reslv_fixups(void) {
- struct fixup *f;
- for (f = fixups; f; f = f->nxt) {
- if (f->l->def) {
- addr[f->adr] = f->l->adr & 0xFF;
- if (f->l->adr & 0xFF00)
- addr[f->adr+1] = f->l->adr >> 8;
- if (f->l->adr & 0xFF000000) {
- addr[f->adr+2] = f->l->adr >> 16;
- addr[f->adr+3] = f->l->adr >> 24;
- }
- if (f->l->adr & 0xFF00000000000000) {
- addr[f->adr+4] = f->l->adr >> 32;
- addr[f->adr+5] = f->l->adr >> 40;
- addr[f->adr+6] = f->l->adr >> 48;
- addr[f->adr+7] = f->l->adr >> 56;
- }
- } else {
- printf("oof, undefined reference to '%s', at $%016llX.\n", f->l->name, f->adr);
- }
- }
-}
void viewmem(uint64_t address) {
printf("\t\t\t");
for (int ind = 0; ind < 0x10; ind++) {
@@ -114,19 +32,17 @@ void viewmem(uint64_t address) {
void usage() {
puts("SuBAsm for CISC-0.2");
puts("Commands:");
- puts("\tviewmem, vm, v\t\tGet the contents of memory\n"
- "\t\t\t\t(Displays 256 bytes of memory\n"
- "\t\t\t\t starting from where the program counter\n"
- "\t\t\t\t currently is).");
- puts("\trelsv, rf, r\t\tResolve any currently unknown labels.");
- puts("\tdisasm, dis,\n"
- "\td [start-][end]\t\tDisassemble from starting address, to\n"
- "\t\t\t\tending address.");
- puts("\tinst, i [inst]\t\tGet a descriptions of that instruction.\n"
- "\t\t\t\tIf no argument is specified, or the\n"
- "\t\t\t\targument specified is \"all\", list all\n"
- "\t\t\t\tinstructions, along with a description\n"
- "\t\t\t\tfor each of them.");
+ puts("\tasm, a\t\t\tAssembles the currently written program.");
+ puts("\tinst, i [inst]\t\tGet a descriptions of that instruction.");
+ puts("\t\t\t\tIf no argument is specified, or the");
+ puts("\t\t\t\targument specified is \"all\", list all");
+ puts("\t\t\t\tinstructions, along with a description");
+ puts("\t\t\t\tfor each of them.");
+ puts("\tlist, l\t\t\tLists the currently written program.");
+ puts("\tviewmem, vm, v\t\tGet the contents of memory");
+ puts("\t\t\t\t(Displays 256 bytes of memory");
+ puts("\t\t\t\t starting from where the program counter");
+ puts("\t\t\t\t currently is).");
puts("\tquit, q\t\t\tQuit the emulator.");
puts("\thelp, h\t\t\tDisplays this mesage.");
}
@@ -142,1237 +58,638 @@ void instinfo(const char *inst) {
}
}
-void disasm(uint8_t prefix, uint8_t opcode, uint64_t value) {
- char postfix[3];
- char op[4];
- uint8_t addrsize = (prefix & 8) >> 3;
- uint8_t rs = (prefix & 0x30) >> 4;
- uint8_t regsize = (1 << rs);
- op[0] = opname[opcode][0];
- op[1] = opname[opcode][1];
- op[2] = opname[opcode][2];
- op[3] = '\0';
- if (regsize == 1) {
- postfix[0] = '\0';
- postfix[1] = '\0';
- postfix[2] = '\0';
+char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg) {
+ if (dbg) {
+ printf("showbits(): ");
+ }
+ char *bits = malloc((sizeof(uint64_t) << 3)+1);
+ char bit = 0;
+ uint8_t i;
+ uint8_t j = 0;
+ if (bitnum > 63) {
+ bitnum = (sizeof(uint64_t) << 3) - 1;
+ }
+ if (!bitnum) {
+ i = (sizeof(uint64_t) << 3) - 1;
} else {
- postfix[0] = '.';
- if (regsize == 2)
- postfix[1] = 'W';
- else if (regsize == 4)
- postfix[1] = 'D';
- else if (regsize == 8)
- postfix[1] = 'Q';
- else {
- postfix[0] = '\0';
- postfix[1] = '\0';
+ i = bitnum;
+ }
+ for (; (value > 0 && !bitnum) || (j <= bitnum && bitnum); j++) {
+ if (value > 0 && !bitnum) {
+ bits[j] = (value & 1) ? '1' : '0';
+ value>>=1;
+ } else {
+ bits[j] = (value & ((uint64_t)1 << i)) ? '1' : '0';
+ i--;
}
- postfix[2] = '\0';
}
- switch (optype[opcode]) {
- case IMPL:
- printf("%s\n" , opname[opcode]);
- break;
- case IMM:
- if (regsize == 1)
- printf("%s #$%02x\n" , op, value);
- if (regsize == 2)
- printf("%s%s #$%04x\n" , op, postfix, value);
- if (regsize == 4)
- printf("%s%s #$%08x\n" , op, postfix, value);
- if (regsize == 8)
- printf("%s%s #$%016llx\n" , op, postfix, value);
- break;
- case ZM:
- case ZMX:
- case ZMY:
- if (addrsize)
- printf("%s%s $%08x%s\n" , op, postfix, value, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
- else
- printf("%s%s $%02x%s\n" , op, postfix, value, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
- break;
- case IND:
- case INDX:
- case INDY:
- if (addrsize)
- printf("%s%s ($%08x%s\n" , op, postfix, value, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
- else
- printf("%s%s ($%02x%s\n" , op, postfix, value, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
- break;
- case ABS:
- if (addrsize)
- printf("%s%s $%016llx\n" , op, postfix, value);
- else
- printf("%s%s $%04x\n" , op, postfix, value);
- break;
+ bits[j] = '\0';
+ if (dbg) {
+ printf("bits: %s\n", bits);
+ }
+ return bits;
+}
+
+uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) {
+ uint16_t i = start;
+ uint8_t j = 0;
+ uint8_t flags = 0;
+ uint8_t isstr;
+ uint8_t iscom;
+ uint8_t iscm = 0;
+ uint8_t fall = 0;
+ uint8_t bitnum;
+ uint8_t opsize = 0;
+ uint8_t spaces;
+ uint8_t tabs;
+ char mne_lower[4];
+ if (all) {
+ end = lineidx;
+ }
+ for (; i < end; i++) {
+ flags = 0;
+ flags |= (tokline[i].dir != 0x00FF) << 0;
+ flags |= (tokline[i].mne != 0x00FF) << 1;
+ flags |= (tokline[i].rs != 0x00FF) << 2;
+ flags |= (tokline[i].am != 0x00FF) << 3;
+ flags |= (tokline[i].opbase != 0x00FF) << 4;
+ flags |= (tokline[i].sym != 0xFFFF) << 5;
+ flags |= (tokline[i].rs != 0x00FF) << 6;
+ flags |= (tokline[i].am != 0x00FF) << 7;
+ iscm = tokline[i].cm != 0xFF;
+ isstr = tokline[i].str != 0xFFFF;
+ iscom = tokline[i].com != 0xFFFF;
+ if (dbg) {
+ printf("list(): ");
+ }
+ if (ln) {
+ printf("%u\t", tokline[i].linenum);
+ } else if (addr) {
+ printf("$%llX:\t", tokline[i].addr);
+ }
+ spaces = tokline[i].sspace;
+ tabs = tokline[i].stab;
+ while (spaces || tabs) {
+ if (spaces) {
+ putchar(' ');
+ spaces--;
+ }
+ if (tabs) {
+ putchar('\t');
+ tabs--;
+ }
+ }
+ if (flags & 0x01) {
+ printf(".%s ", dir_t[tokline[i].dir]);
+ if (isstr) {
+ printf("\"%s\"", string[tokline[i].str]);
+ }
+ }
+ if (flags & 0x02) {
+ for (; j < 3; j++) {
+ mne_lower[j] = tolower(mne[tokline[i].mne][j]);
+ }
+ mne_lower[j] = '\0';
+ j = 0;
+ printf("%s", mne_lower);
+ }
+ if (flags & 0x04) {
+ printf("%s ", rs_t[tokline[i].rs]);
+ } else if (flags & 0x02) {
+ printf(" ");
+ }
+ if (flags & 0x7F) {
+ switch (tokline[i].am) {
+ case IMM:
+ putchar('#');
+ break;
+ case INDX:
+ case INDY:
+ case IND:
+ putchar('(');
+ break;
+ }
+ }
+ if (flags & 0x20) {
+ printf("%s", get_symname(tokline[i].sym, 0));
+ if (tokline[i].islabel) {
+ printf(": ");
+ } else if (tokline[i].issym) {
+ printf(" = ");
+ }
+ }
+ if (flags & 0x10) {
+ if (flags & 0x04) {
+ bitnum = (tokline[i].rs << 3);
+ } else {
+ opsize += (tokline[i].op <= 0x000000FF) + 0;
+ opsize += (tokline[i].op > 0x000000FF) + 1;
+ opsize += (tokline[i].op > 0x0000FFFF) + 2;
+ opsize += (tokline[i].op > 0xFFFFFFFF) + 3;
+ if (opsize) {
+ bitnum = bitsize[opsize-1];
+ }
+ }
+
+ switch (tokline[i].opbase) {
+ case BASE_HEX: printf("$%llX", tokline[i].op); break;
+ case BASE_DEC: printf("%llu", tokline[i].op); break;
+ case BASE_BIN: printf("%%%s", showbits(tokline[i].op, bitnum, dbg)); break;
+ }
+ bitnum = 0;
+ opsize = 0;
+ }
+ if (iscm) {
+ switch (tokline[i].cm) {
+ case 0:
+ putchar('+');
+ break;
+ case 1:
+ putchar ('-');
+ break;
+ }
+ opsize += (tokline[i].aop <= 0x000000FF) + 0;
+ opsize += (tokline[i].aop > 0x000000FF) + 1;
+ opsize += (tokline[i].aop > 0x0000FFFF) + 2;
+ opsize += (tokline[i].aop > 0xFFFFFFFF) + 3;
+ if (opsize) {
+ bitnum = bitsize[opsize-1];
+ }
+ switch (tokline[i].aopbase) {
+ case BASE_HEX: printf("$%llX", tokline[i].aop); break;
+ case BASE_DEC: printf("%llu", tokline[i].aop); break;
+ case BASE_BIN: printf("%%%s", showbits(tokline[i].aop, bitnum, dbg)); break;
+ }
+ bitnum = 0;
+ opsize = 0;
+ }
+ if (flags & 0x7F) {
+ if (fall) {
+ fall = 0;
+ }
+ switch (tokline[i].am) {
+ case INDX:
+ case ZMX:
+ printf(", x");
+ if (tokline[i].am == ZMX) {
+ break;
+ }
+ fall = 1;
+ /* Falls Through. */
+ case INDY:
+ fall = !fall;
+ /* Falls Through. */
+ case IND:
+ putchar(')');
+ if (!fall) {
+ break;
+ }
+ /* Falls Through. */
+ case ZMY:
+ printf(", y");
+ break;
+ }
+ }
+ spaces = tokline[i].espace;
+ tabs = tokline[i].etab;
+ while (spaces || tabs) {
+ if (spaces) {
+ putchar(' ');
+ spaces--;
+ }
+ if (tabs) {
+ putchar('\t');
+ tabs--;
+ }
+ }
+ if (iscom) {
+ printf(";%s", comment[tokline[i].com]);
+ }
+ puts("");
}
}
+uint64_t assemble(uint8_t dbg) {
+ uint64_t bytecount = 0;
+ uint64_t tmpaddr;
+ uint64_t value;
+ uint16_t flags = 0;
+ uint16_t i = 0;
+ uint16_t k = 0;
+ uint16_t tmp;
+ uint8_t c = 0;
+ uint8_t prefix = 0;
+ uint8_t opsize = 0;
+ uint8_t skip = 0;
+
+ uint64_t address;
+ uint16_t symid;
+ uint16_t str;
+ uint16_t com;
+ uint8_t islabel;
+ uint8_t opbase;
+ uint8_t aopbase;
+ uint8_t dir;
+ uint8_t am;
+ uint8_t cm;
+ uint8_t rs;
+ uint8_t ins;
+
+ for (; i < lineidx; i++) {
+ if (dbg) {
+ printf("assemble(): i: $%llX\n", i);
+ }
+ address = tokline[i].addr;
+ tmpaddr = address;
+ symid = tokline[i].sym;
+ str = tokline[i].str;
+ com = tokline[i].com;
+ islabel = tokline[i].islabel;
+ opbase = tokline[i].opbase;
+ aopbase = tokline[i].aopbase;
+ dir = tokline[i].dir;
+ am = tokline[i].am;
+ cm = tokline[i].cm;
+ rs = tokline[i].rs;
+ ins = tokline[i].mne;
+ flags = 0;
+ flags |= (dir != 0x00FF) << 0x00;
+ flags |= (ins != 0x00FF) << 0x01;
+ flags |= (rs != 0x00FF) << 0x02;
+ flags |= (am != 0x00FF) << 0x03;
+ flags |= (opbase != 0x00FF) << 0x04;
+ flags |= (aopbase != 0x00FF) << 0x05;
+ flags |= (symid != 0xFFFF) << 0x06;
+ flags |= (islabel ) << 0x07;
+ flags |= (am != 0x00FF) << 0x08;
+ flags |= (cm != 0x00FF) << 0x09;
+ flags |= (str != 0xFFFF) << 0x0A;
+ if (dbg) {
+ printf("assemble(): ");
+ putchar('%');
+ printf("%u", str != 0xFFFF);
+ printf("%u", cm != 0x00FF);
+ printf("%u", am != 0x00FF);
+ printf("%u", islabel );
+ printf("%u", symid != 0xFFFF);
+ printf("%u", aopbase != 0x00FF);
+ printf("%u", opbase != 0x00FF);
+ printf("%u", am != 0x00FF);
+ printf("%u", rs != 0x00FF);
+ printf("%u", ins != 0x00FF);
+ printf("%u", dir != 0x00FF);
+ puts("");
+
+ printf("assemble(): ");
+ printf("flags: $%04X\n", flags);
+ }
+ if (!flags) {
+ if (dbg) {
+ printf("assemble(): ");
+ puts("This line only contains a comment, so skip it.");
+ }
+ continue;
+ }
+ opsize = 0;
+ skip = 0;
+ if ((flags & 0x53) == 0x42) {
+ value = use_symbol("", symid, tmpaddr, 1, 0);
+ } else {
+ value = tokline[i].op;
+ }
+ if ((flags & 0x51) == 0x41) {
+ value = use_symbol("", symid, tmpaddr, 1, 0);
+ }
+ if (flags & 0x220) {
+ switch (cm) {
+ case 0: value += tokline[i].aop; break;
+ case 1: value -= tokline[i].aop; break;
+ }
+ }
+ if (dbg) {
+ printf("assemble(): value: $%llX\n", value);
+ }
+ switch (dir) {
+ case DIR_ORG:
+ tmpaddr = value;
+ if (dbg) {
+ printf("assemble(): ");
+ printf("The Program Counter's origin is now at, $%llX.\n", value);
+ }
+ skip = 1;
+ break;
+ case DIR_BYTE:
+ if (flags & 0x400) {
+ for (k = 0; string[str][k] != '\0'; k++) {
+ switch (string[str][k]) {
+ case '\\':
+ switch (string[str][k+1]) {
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case '0': c = '\0'; break;
+ }
+ k++;
+ break;
+ default:
+ c = string[str][k];
+ break;
+ }
+ addr[tmpaddr++] = c;
+ }
+ addr[tmpaddr] = '\0';
+ if (dbg) {
+ printf("assemble(): ");
+ printf("Placed string \"%s\"", string[str]);
+ printf(", at address(es) $%llX-$%llX.\n", address, tmpaddr);
+ }
+ } else {
+ addr[tmpaddr++] = value & 0xFF;
+ }
+ break;
+ case DIR_QWORD:
+ addr[tmpaddr+7] = value >> 0x38;
+ addr[tmpaddr+6] = value >> 0x30;
+ addr[tmpaddr+5] = value >> 0x28;
+ addr[tmpaddr+4] = value >> 0x20;
+ tmp+=4;
+ case DIR_DWORD:
+ addr[tmpaddr+3] = value >> 0x18;
+ addr[tmpaddr+2] = value >> 0x10;
+ tmp+=2;
+ case DIR_WORD:
+ addr[tmpaddr+1] = value >> 0x08;
+ addr[tmpaddr ] = value & 0xFF;
+ tmp+=2;
+
+ }
+ tmpaddr += tmp;
+ tmp = 0;
+ if (skip || flags & 0x80) {
+ if (dbg) {
+ printf("assemble(): The address that this line starts at is, $%llX.\n", address);
+ printf("assemble(): The address that this line ends on is, $%llX.\n", tmpaddr);
+ }
+ continue;
+ }
+ if (flags == 0x108) {
+ if (dbg) {
+ printf("assemble(): The address that this line starts at is, $%llX.\n", address);
+ printf("assemble(): The address that this line ends on is, $%llX.\n", tmpaddr);
+ }
+ continue;
+ }
+ if (flags & 0x04) {
+ prefix = (rs << 4) | 3;
+ } else {
+ rs = 0;
+ }
+ if (flags & 0x102) {
+ if (ins == 80) {
+ if (flags & 0x10) {
+ am = IMM;
+ prefix |= 0x13;
+ } else {
+ am = IMPL;
+ addr[tmpaddr++] = opcodes[ins][IMM];
+ bytecount++;
+ if (dbg) {
+ printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
+ printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[IMM]);
+ printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][IMM]);
+ }
+ }
+ }
+ opsize = 0;
+ if (am != IMM && am != IMPL) {
+ opsize = (value <= 0x00000000000000FF) ? 1 : opsize;
+ opsize = (value > 0x00000000000000FF) ? 2 : opsize;
+ opsize = (value > 0x000000000000FFFF) ? 3 : opsize;
+ opsize = (value > 0x0000000000FFFFFF) ? 4 : opsize;
+ opsize = (value > 0x00000000FFFFFFFF) ? 5 : opsize;
+ opsize = (value > 0x000000FFFFFFFFFF) ? 6 : opsize;
+ opsize = (value > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
+ opsize = (value > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
+ if (opsize) {
+ opsize--;
+ prefix |= amp[opsize];
+ }
+ }
+ if (prefix) {
+ if (dbg) {
+ printf("assemble(): ");
+ puts("Prefix byte detected.");
+ }
+ addr[tmpaddr++] = prefix;
+ bytecount++;
+ if (dbg) {
+ uint8_t addrsize = (prefix & 0x0C) >> 2;
+ uint8_t regsize = (prefix & 0x30) >> 4;
+
+ printf("assemble(): ");
+ printf("The values of the prefix bits are");
+ printf(", AM: %u, RS: %u\n", addrsize, regsize);
+ }
+ prefix = 0;
+ }
+ if (opcodes[ins][am] != 0xFF) {
+ addr[tmpaddr++] = opcodes[ins][am];
+ bytecount++;
+ if (dbg) {
+ printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
+ printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[am]);
+ printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][am]);
+ }
+ switch (am) {
+ case IMM:
+ switch (rs) {
+ case 3:
+ addr[tmpaddr+7] = value >> 0x38;
+ addr[tmpaddr+6] = value >> 0x30;
+ addr[tmpaddr+5] = value >> 0x28;
+ addr[tmpaddr+4] = value >> 0x20;
+ tmp+=4;
+ case 2:
+ addr[tmpaddr+3] = value >> 0x18;
+ addr[tmpaddr+2] = value >> 0x10;
+ tmp+=2;
+ case 1:
+ addr[tmpaddr+1] = value >> 0x08;
+ tmp+=1;
+ case 0:
+ addr[tmpaddr ] = value & 0xFF;
+ tmp+=1;
+ }
+ break;
+ case ABS:
+ case ZM:
+ case ZMX:
+ case ZMY:
+ case IND:
+ case INDX:
+ case INDY:
+ switch (opsize) {
+ case 7: addr[tmpaddr+7] = value >> 0x38; tmp++;
+ case 6: addr[tmpaddr+6] = value >> 0x30; tmp++;
+ case 5: addr[tmpaddr+5] = value >> 0x28; tmp++;
+ case 4: addr[tmpaddr+4] = value >> 0x20; tmp++;
+ case 3: addr[tmpaddr+3] = value >> 0x18; tmp++;
+ case 2: addr[tmpaddr+2] = value >> 0x10; tmp++;
+ case 1: addr[tmpaddr+1] = value >> 0x08; tmp++;
+ case 0: addr[tmpaddr ] = value & 0xFF; tmp++;
+ }
+ break;
+ }
+ tmpaddr += tmp;
+ bytecount += tmp;
+ tmp = 0;
+ }
+ }
+ if (dbg) {
+ printf("assemble(): The address that this line starts at is, $%llX.\n", address);
+ printf("assemble(): The address that this line ends on is, $%llX.\n", tmpaddr);
+ printf("assemble(): The program size is now at");
+ printf(", %llu bytes in decimal", bytecount);
+ printf(", and $%llX bytes in hex.\n", bytecount);
+ }
+ }
+ return bytecount;
+}
+
int asmmon(const char *fn) {
- /* mne IMM ZM ZMX ZMY IND INX INY ABS IMPL*/
- SETOP( 0, "CPS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 1, "ADC", 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00);
- SETOP( 2, "AAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02);
- SETOP( 3, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 4, "CPB", 0x09, 0x2D, 0x00, 0x00, 0x55, 0xAD, 0xAC, 0x2C, 0x00);
- SETOP( 5, "PHB", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 6, "DEC", 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xE5);
- SETOP( 7, "JMP", 0x00, 0x0E, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x10, 0x00);
- SETOP( 8, "SBC", 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00);
- SETOP( 9, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12);
- SETOP(10, "ENT", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(11, "CPY", 0x19, 0x3D, 0x00, 0x00, 0x85, 0x00, 0x00, 0x4C, 0x00);
- SETOP(12, "PLB", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(13, "INC", 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xF5);
- SETOP(14, "JSR", 0x00, 0x1E, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x00);
- SETOP(15, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00);
- SETOP(16, "AND", 0x21, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00);
- SETOP(17, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22);
- SETOP(18, "PLP", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(19, "CPX", 0x29, 0x4D, 0x00, 0x00, 0xB5, 0x00, 0x00, 0x3C, 0x00);
- SETOP(20, "PHY", 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(21, "BPO", 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00);
- SETOP(22, "ORA", 0x31, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00);
- SETOP(23, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32);
- SETOP(24, "STT", 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(25, "PLY", 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(26, "BNG", 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00);
- SETOP(27, "XOR", 0x41, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00);
- SETOP(28, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42);
- SETOP(29, "PHA", 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(30, "PHX", 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(31, "BCS", 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00);
- SETOP(32, "LSL", 0x51, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00);
- SETOP(33, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52);
- SETOP(34, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58);
- SETOP(35, "PLX", 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(36, "BCC", 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00);
- SETOP(37, "LSR", 0x61, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00);
- SETOP(38, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62);
- SETOP(39, "PLA", 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(40, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A);
- SETOP(41, "BEQ", 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00);
- SETOP(42, "ROL", 0x71, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00);
- SETOP(43, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72);
- SETOP(44, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78);
- SETOP(45, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A);
- SETOP(46, "BNE", 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00);
- SETOP(47, "ROR", 0x81, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00);
- SETOP(48, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82);
- SETOP(49, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88);
- SETOP(50, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A);
- SETOP(51, "BVS", 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00);
- SETOP(52, "MUL", 0x91, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00);
- SETOP(53, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92);
- SETOP(54, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98);
- SETOP(55, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A);
- SETOP(56, "BVC", 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00);
- SETOP(57, "DIV", 0xA1, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x00);
- SETOP(58, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2);
- SETOP(59, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8);
- SETOP(60, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA);
- SETOP(61, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE);
- SETOP(62, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
- SETOP(63, "CMP", 0xB1, 0xB6, 0x00, 0x00, 0x25, 0x7D, 0x7C, 0xB4, 0x00);
- SETOP(64, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2);
- SETOP(65, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8);
- SETOP(66, "LDX", 0xB9, 0xBD, 0x00, 0xC9, 0x95, 0x00, 0x00, 0xBC, 0x00);
- SETOP(67, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA);
- SETOP(68, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0);
- SETOP(69, "LDA", 0xC1, 0xC6, 0x79, 0x39, 0x05, 0x5D, 0x5C, 0xC4, 0x00);
- SETOP(70, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5);
- SETOP(71, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8);
- SETOP(72, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCA);
- SETOP(73, "STA", 0x00, 0xCD, 0x89, 0x49, 0x15, 0x6D, 0x6C, 0xCC, 0x00);
- SETOP(74, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0);
- SETOP(75, "LDB", 0xD1, 0xD6, 0x99, 0x59, 0x35, 0x8D, 0x8C, 0xD4, 0x00);
- SETOP(76, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5);
- SETOP(77, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8);
- SETOP(78, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA);
- SETOP(79, "STB", 0x00, 0xDD, 0xA9, 0x69, 0x45, 0x9D, 0x9C, 0xDC, 0x00);
- SETOP(80, "TXS", 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(81, "LDY", 0xE1, 0xE6, 0xE9, 0x00, 0x65, 0x00, 0x00, 0xE4, 0x00);
- SETOP(82, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
- SETOP(83, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA);
- SETOP(84, "STY", 0x00, 0xED, 0xF9, 0x00, 0x75, 0x00, 0x00, 0xEC, 0x00);
- SETOP(85, "DEB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE);
- SETOP(86, "ASR", 0xF1, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x00);
- SETOP(87, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2);
- SETOP(88, "STX", 0x00, 0xFD, 0x00, 0xD9, 0xA5, 0x00, 0x00, 0xFC, 0x00);
- SETOP(89, "INB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE);
FILE *fp;
- if (strcasecmp(fn, "stdin") != 0) {
+ if (strcasecmp(fn, "stdin")) {
fp = fopen(fn, "r");
- if (fp == NULL)
+ if (fp == NULL) {
return 2;
+ }
}
uint8_t done = 0;
+ uint8_t use_lexer = 1;
uint64_t address = 0x0000;
uint64_t bytecount = 0;
- uint64_t start, end;
- uint8_t prefix, opcode;
while (!(done & 1)) {
- char *buf = NULL;
- char *ins;
- char *postfix;
- char mode[3];
- opent op;
- uint8_t addrmode = IMPL;
- uint8_t addrtok = 0;
- uint64_t value = 0;
- uint64_t val2 = 0;
- char *oprand;
- char *oprand2;
+ /*char *buf = NULL;*/
char *cmd;
- char ir[2] = ""; /* Index register. */
- int a = 0;
- int b = 0;
+ char *arg = malloc(sizeof(char *)*128);
char *tmp = malloc(sizeof(char *)*128);
- char *tmp2;
+ char *lex_line = NULL;
size_t size;
- prefix = 0;
+ ssize_t line_len;
done = 0;
if (!strcasecmp(fn, "stdin")) {
- getline(&buf, &size, stdin);
+ line_len = getline(&lex_line, &size, stdin);
} else {
- getline(&buf, &size, fp);
+ line_len = getline(&lex_line, &size, fp);
}
- cmd = strtok_r(buf, "\n", &tmp);
+ cmd = malloc(sizeof(char *)*(line_len+1));
+ memcpy(cmd, lex_line, line_len+1);
+ cmd = strtok_r(cmd, " \t\n", &tmp);
if (cmd != NULL) {
if (strcasecmp(cmd, "done") == 0) {
done |= 1;
} else {
- ins = strtok(buf, "\t\n ");
- if (ins != NULL) {
- oprand = strtok(NULL, "\t\n");
- strtok_r(ins, ".", &postfix);
- if (oprand != NULL) {
- for (int i = 0; i < strlen(oprand); i++) {
- switch (oprand[i]) {
- case '(':
- addrmode = IND;
- break;
- case '+':
- addrtok = 1;
- break;
- case '-':
- addrtok = 2;
-
- }
-
- if (oprand[i] == '"')
- break;
- if (a && oprand[a] == ',') {
- if (oprand[i] == 'x' || oprand[i] == 'X') {
- ir[0] = 'x';
- ir[1] = '\0';
- }
- if (oprand[i] == 'y' || oprand[i+1] == 'Y') {
- ir[0] = 'y';
- ir[1] = '\0';
- }
- if (b && ir[0] == 'y')
- oprand[b] = '\0';
- }
- if (oprand[i] == ')' && oprand[i+1] == ',')
- b = i;
- else if (oprand[i] == ')')
- oprand[i] = '\0';
- if (oprand[i] == ',' || oprand[i] == ';')
- a = i;
- }
- if (a)
- oprand[a] = '\0';
- }
- }
- if (!strcasecmp(cmd, "quit") || !strcasecmp(cmd, "q")) {
- printf("The total size of the program code is, %llu bytes in decimal, and $%llX bytes in hex.\n", bytecount, bytecount);
+ if (cmd[0] == 'q' || !strcasecmp(cmd, "quit")) {
return 2;
- }
- if (!strcasecmp(cmd, "viewmem") || !strcasecmp(cmd, "vm") || !strcasecmp(cmd, "v")) {
+ } else if (cmd[0] == 'v' || !strcasecmp(cmd, "viewmem") || !strcasecmp(cmd, "vm")) {
done |= 4;
viewmem(address);
- }
- if (!strcasecmp(cmd, "reslv") || !strcasecmp(cmd, "rf") || !strcasecmp(cmd, "r")) {
- done |= 4;
- puts("Resolving unknown labels.");
- reslv_fixups();
- puts("Finished resolving unknown labels.");
- }
- if (!strcasecmp(cmd, "help") || !strcasecmp(cmd, "h")) {
+ } else if (!strcasecmp(cmd, "l") || !strcasecmp(cmd, "list")) {
done |= 4;
- usage();
- }
- if (oprand == NULL && ins == NULL && postfix == NULL) {
- done |= 2;
- }
- cmd = strtok(cmd, " \n");
- if (!strcasecmp(cmd, "inst") || !strcasecmp(cmd, "i")) {
- done |= 64;
- done |= 6;
- if (oprand != NULL) {
- instinfo(oprand);
- } else {
- instinfo("all");
- }
+ /*tmp = strtok_r(lex_line, "\n", &tmp);*/
+ if (tmp != NULL) {
+ uint16_t i = 0;
+ uint16_t j = 0;
- }
- if (!strcasecmp(cmd, "disasm") || !strcasecmp(cmd, "dis") || !strcasecmp(cmd, "d")) {
- done |= 64;
- done |= 6;
- if (oprand != NULL) {
- cmd = strtok_r(oprand, " -", &tmp);
- if (cmd != NULL) {
- for (int i = 0; i < strlen(cmd); i++) {
- if ((isalnum(cmd[i]) || cmd[i] == '_') && cmd[i] != '"') {
- value = use_label(tmp, address);
- sprintf(tmp, "%llx", value);
- break;
- }
- if (cmd[i] == '$') {
- cmd = strtok(cmd, "$");
- value = strtoull(cmd, NULL, 16);
- break;
- }
- if (cmd[i] == ';') {
- done |= 16;
- break;
- }
+ uint16_t start = 0;
+ uint16_t end = 0;
+ uint16_t value = 0;
+
+ uint8_t base = 0xFF;
+
+ uint8_t isflag = 0;
+ uint8_t isstart = 1;
+
+ uint8_t isdebug = 0;
+ uint8_t islinenum = 0;
+ uint8_t isaddr = 0;
+
+ while (tmp[i] != '\0') {
+ if (isspace(tmp[i])) {
+ for (; isspace(tmp[i]); i++);
}
- start = value;
- for (int i = 0; i < strlen(tmp); i++) {
- if ((isalnum(tmp[i]) || tmp[i] == '_') && tmp[i] != '"') {
- value = use_label(tmp, address);
- sprintf(tmp, "%llx", value);
- break;
- }
- if (tmp[i] == '$') {
- tmp = strtok(tmp, "$");
- value = strtoull(tmp, NULL, 16);
+ switch (tmp[i]) {
+ case '$': base = BASE_HEX; i++; break;
+ case '%': base = BASE_BIN; i++; break;
+ default:
+ j = i;
+ for (; isdigit(tmp[j]); j++, isflag++);
+ base = (isflag) ? BASE_DEC : 0xFF;
+ isflag = 0;
+ j = 0;
break;
- }
- if (tmp[i] == ';') {
- done |= 16;
- break;
- }
}
- (!strlen(tmp)) ? (end = address) : (end = value);
- } else {
- start = value;
- end = address;
- }
- } else {
- start = 0;
- end = address;
- }
- while (start < end) {
- uint8_t rs;
- uint8_t regsize;
- uint8_t addrsize;
- if (start < 0xFF)
- printf("$%02llx: ", start);
- else if (start < 0xFFFF)
- printf("$%04llx: ", start);
- else if (start < 0xFFFFFFFF)
- printf("$%08llx: ", start);
- else if (start < 0xFFFFFFFFFFFFFFFF)
- printf("$%016llx: ", start);
- prefix = addr[start];
- if ((prefix & 0x03) == 0x03) {
- start+=1;
- addrsize = (prefix & 0x0C) >> 2;
- rs = (prefix & 0x30) >> 4;
- regsize = (1 << rs);
- } else {
- prefix = 0;
- regsize = 1;
- addrsize = 0;
- }
- opcode = addr[start];
- start+=1;
- switch (optype[opcode]) {
- case IMPL:
- break;
- case IMM:
- value = addr[start];
- switch (regsize) {
- case 8:
- value |= (uint64_t)addr[start+7] << 56;
- value |= (uint64_t)addr[start+6] << 48;
- value |= (uint64_t)addr[start+5] << 40;
- value |= (uint64_t)addr[start+4] << 32;
- case 4:
- value |= addr[start+3] << 24;
- value |= addr[start+2] << 16;
- case 2:
- value |= addr[start+1] << 8;
- }
- start += regsize;
- break;
- case ZM:
- case ZMX:
- case ZMY:
- case IND:
- case INDX:
- case INDY:
- value = addr[start];
- switch (addrsize) {
- case 0:
- start+=1;
- break;
- case 1:
- value |= addr[start+1] << 8;
- value |= addr[start+2] << 16;
- start+=3;
- break;
- case 2:
- value |= addr[start+1] << 8;
- value |= addr[start+2] << 16;
- value |= addr[start+3] << 24;
- value |= (uint64_t)addr[start+4] << 32;
- value |= (uint64_t)addr[start+5] << 40;
- start+=6;
- break;
- case 3:
- value |= addr[start+1] << 8;
- value |= addr[start+2] << 16;
- value |= addr[start+3] << 24;
- start+=4;
- break;
+ for (; !isspace(tmp[i]) && tmp[i] != '-'; arg[j++] = tmp[i++]);
+ arg[j] = '\0';
+ j = 0;
+ if (base != 0xFF) {
+ switch (base) {
+ case BASE_HEX: value = strtol(arg, NULL, 16); break;
+ case BASE_BIN: value = strtol(arg, NULL, 2); break;
+ case BASE_DEC: value = strtol(arg, NULL, 10); break;
}
- break;
- case ABS:
- value = addr[start];
- value |= addr[start+1] << 8;
- switch (addrsize) {
- case 0:
- start+=2;
- break;
- case 1:
- value |= addr[start+2] << 16;
- value |= addr[start+3] << 24;
- value |= (uint64_t)addr[start+4] << 32;
- start+=5;
- break;
- case 2:
- value |= addr[start+2] << 16;
- value |= addr[start+3] << 24;
- value |= (uint64_t)addr[start+4] << 32;
- value |= (uint64_t)addr[start+5] << 40;
- value |= (uint64_t)addr[start+6] << 48;
- start+=7;
- break;
- case 3:
- value |= addr[start+2] << 16;
- value |= addr[start+3] << 24;
- value |= (uint64_t)addr[start+4] << 32;
- value |= (uint64_t)addr[start+5] << 40;
- value |= (uint64_t)addr[start+6] << 48;
- value |= (uint64_t)addr[start+7] << 56;
- start+=8;
- break;
+ base = 0xFF;
+ (isstart) ? (start = value) : (end = value);
+ if (isstart) {
+ isstart = (tmp[i] != '-');
}
- break;
- }
- disasm(prefix, opcode, value);
- }
- }
- if (!(done & 64)) {
- if (ins != NULL) {
- for (int i = 0; i < strlen(ins); i++) {
- if (i && ins[i] == ':') {
- ins[i] = '\0';
- mklabel(ins, address, 1);
- #if debug
- printf("Created label with the name %s, at address: $%llx\n", ins, address);
- #endif
- done |= 6;
- break;
- }
- if (i && ins[i] == '=') {
- /*ins = strtok_r(oprand2)*/
- }
- if (ins[i] == ';') {
- if (i && (ins[i-1] == ' ' || ins[i-1] == '\t'))
- ins[i] = '\0';
- else
- done |=6;
- break;
- }
- }
- if (!(done & 6)) {
- if (oprand != NULL) {
- if (!strcasecmp(ins, ".org")) {
- done |= 6;
- oprand = strtok(oprand, "$");
- address = strtoull(oprand, NULL, 16);
- #if debug
- printf("Origin for program code is now at address $%llx.\n", address);
- #endif
- }
- if (!strcasecmp(ins, ".byte") || !strcasecmp(ins, ".word") || !strcasecmp(ins, ".dword") || !strcasecmp(ins, ".qword")) {
- done |= 6;
- uint8_t qstr = 0;
- uint64_t staddr = address;
- uint16_t slen = 0;
- char *tmpstr = tstr;
- char c;
- for (int i = 0; i < strlen(oprand); i++) {
- if (!qstr) {
- if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
- qstr = 0;
- value = use_label(oprand, address);
- sprintf(oprand, "%llx", value);
- break;
- }
- if (!strcasecmp(ins, ".byte")) {
- if (oprand[i] == '"') {
- qstr = 1;
- continue;
- } else if (oprand[i] == '\'') {
- qstr = 2;
- continue;
- }
- }
- if (oprand[i] == '$') {
- qstr = 0;
- oprand = strtok(oprand, "$");
- value = strtoull(oprand, NULL, 16);
- break;
- }
- if (oprand[i] == ';') {
- qstr = 0;
- done |= 16;
- break;
- }
- } else if (qstr == 1) {
- switch (oprand[i]) {
- case 0:
- puts("oof, unterminated string.");
- qstr = 4;
- break;
- case '"':
- value = '\0';
- c = '\0';
- tmpstr[slen++] = '\0';
- qstr = 3;
- break;
- case '\\':
- switch (oprand[i+1]) {
- case 'n':
- value = '\n';
- c = '\n';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'n';
- break;
- case 't':
- value = '\t';
- c = '\t';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 't';
- break;
- case 'r':
- value = '\r';
- c = '\r';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'r';
- break;
- case '0':
- break;
- default:
- value = oprand[i];
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = oprand[i];
- break;
- }
- i++;
- break;
- default:
- value = oprand[i];
- c = oprand[i];
- tmpstr[slen++] = c;
- break;
- }
- addr[address++] = (uint8_t)value & 0xFF;
- } else if (qstr == 2) {
- switch (oprand[i]) {
- case 0:
- puts("oof, unterminated string.");
- qstr = 4;
- break;
- case '\'':
- c = '\0';
- tmpstr[slen++] = '\0';
- qstr = 3;
- break;
- case '\\':
- switch (oprand[i+1]) {
- case 'n':
- value = '\n';
- c = '\n';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'n';
- break;
- case 't':
- value = '\t';
- c = '\t';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 't';
- break;
- case 'r':
- value = '\r';
- c = '\r';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'r';
- break;
- case '0':
- break;
- default:
- value = oprand[i];
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = oprand[i];
- break;
- }
- i++;
- break;
- default:
- value = oprand[i];
- c = oprand[i];
- tmpstr[slen++] = c;
- break;
- }
- if (qstr != 3)
- addr[address++] = (uint8_t)value & 0xFF;
- }
- }
- if (!strcasecmp(ins, ".byte") && !qstr)
- addr[address++] = value & 0xFF;
- if (!strcasecmp(ins, ".word")) {
- addr[address] = (uint8_t)value & 0xFF;
- addr[address+1] = value >> 8;
- address+=2;
- }
- if (!strcasecmp(ins, ".dword")) {
- addr[address] = (uint8_t)value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
- }
- if (!strcasecmp(ins, ".qword")) {
- addr[address] = (uint8_t)value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- addr[address+4] = value >> 32;
- addr[address+5] = value >> 40;
- addr[address+6] = value >> 48;
- addr[address+7] = value >> 56;
- address+=8;
- }
- #if debug
- if (!qstr) {
- printf("The value $%llx was placed at address%s ", value, (staddr != address-1) ? "es" : "");
- if (staddr == address-1)
- printf("$%llx.\n", staddr);
- else
- printf("$%llx-$%llx.\n", staddr, address-1);
- } else {
- printf("The string \"%s\", was placed at address%s ", tmpstr, (staddr != address-1) ? "es" : "");
- if (staddr == address-1)
- printf("$%llx.\n", staddr);
- else
- printf("$%llx-$%llx.\n", staddr, address-1);
- }
- #endif
- }
- }
- }
- }
- }
-
- if (oprand == NULL && !strcasecmp(ins, "TXS")) {
- addrmode = IMM;
- done |= 32;
- }
- else if (oprand != NULL && !strcasecmp(ins, "TXS"))
- prefix = 0x13;
- if (!(done & 2) && oprand != NULL) {
- mode[0] = oprand[0];
- mode[1] = oprand[1];
- strtok_r(oprand, "+-", &oprand2);
- if (ir[0] == 'x' || ir[0] == 'y') {
- oprand2 = strtok_r(oprand2, ",)", &tmp2);
- }
- if (oprand2 != NULL) {
- int i = 0;
- for (; (oprand2[i] == '$' || oprand2[i] == '%') || isxdigit(oprand2[i]); i++);
- if (i) {
- oprand2[i] = '\0';
- }
- }
- uint8_t isimm = oprand[0] == '#';
- /* This flag is used for checking if there is a secondary token. */
- uint8_t issectok = (oprand[1] == '$' || oprand[1] == '%' || isdigit(oprand[1]));
- if (oprand[0] == '$' || (isimm && issectok) || (oprand[0] == '(' && issectok)) {
- oprand = strtok(oprand, "#($%");
- if (isimm) {
- addrmode = IMM;
- done |= 32;
- if (mode[1] == '$')
- value = strtoull(oprand, NULL, 16);
- else if (mode[1] == '%')
- value = strtoull(oprand, NULL, 2);
- else
- value = strtoull(oprand, NULL, 10);
- } else {
- if (mode[0] == '$' || mode[1] == '$')
- value = strtoull(oprand, NULL, 16);
- else if (mode[0] == '%' || mode[1] == '%')
- value = strtoull(oprand, NULL, 2);
- else
- value = strtoull(oprand, NULL, 10);
- if (mode[0] != '(') {
- if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) {
- addrmode = ZM;
- } else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) {
- if (ir[0] == 'x' || ir[0] == 'y') {
- addrmode = ZM;
- } else {
- addrmode = ABS;
+ } else {
+ for (; isalpha(arg[j]); j++, isflag++);
+ j = 0;
+ if (isflag) {
+ isdebug = (arg[j] == 'd' || !strcasecmp(arg, "debug" ));
+ islinenum = (arg[j] == 'l' || !strcasecmp(arg, "linenum"));
+ if (!islinenum) {
+ isaddr = (arg[j] == 'a' || !strcasecmp(arg, "address"));
}
}
+ isflag = 0;
}
- if (addrmode == ZM || addrmode == IND) {
- if (value & 0xFFFF00)
- prefix |= 0x7;
- else if (value & 0xFFFF00000000)
- prefix |= 0xB;
- else if (value & 0xFFFF000000)
- prefix |= 0xF;
- }
- if (addrmode == ABS) {
- if (value & 0xFF00000000)
- prefix |= 0x7;
- else if (value & 0xFF000000000000)
- prefix |= 0xB;
- else if (value & 0xFF00000000000000)
- prefix |= 0xF;
- }
- if ((addrmode == 2 || addrmode == 6) && ir != NULL) {
- switch (ir[0]) {
- case 'x':
- if (addrmode == ZM)
- addrmode = ZMX;
- else if (addrmode == IND)
- addrmode = INDX;
- break;
- case 'y':
- if (addrmode == ZM)
- addrmode = ZMY;
- else if (addrmode == IND)
- addrmode = INDY;
- break;
- default:
- done |= 32;
- break;
- }
- }
+ i++;
}
+ list(start, end, isstart, islinenum, isaddr, isdebug);
} else {
- if (mode[0] == '(') {
- oprand = strtok(oprand, "#($%");
- } else if (isimm) {
- oprand = strtok(oprand, "#");
- addrmode = IMM;
- done |= 32;
- }
- for (int i = 0; i < strlen(oprand); i++) {
- if (oprand[i] == ';') {
- done |= 16;
- break;
- }
- if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
- value = use_label(oprand, address);
- if (!isimm) {
- if (mode[0] != '(') {
- if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) {
- addrmode = ZM;
- } else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) {
- if (ir[0] == 'x' || ir[0] == 'y') {
- addrmode = ZM;
- } else {
- addrmode = ABS;
- }
- }
- }
- if (addrmode == ZM || addrmode == IND) {
- if (value & 0xFFFF00)
- prefix |= 0x7;
- else if (value & 0xFFFF00000000)
- prefix |= 0xB;
- else if (value & 0xFFFF000000)
- prefix |= 0xF;
- }
- if (addrmode == ABS) {
- if (value & 0xFF00000000)
- prefix |= 0x7;
- else if (value & 0xFF000000000000)
- prefix |= 0xB;
- else if (value & 0xFF00000000000000)
- prefix |= 0xF;
- }
- if ((addrmode == ZM || addrmode == IND) && ir != NULL && a) {
- switch (ir[0]) {
- case 'x':
- if (addrmode == ZM)
- addrmode = ZMX;
- else if (addrmode == IND)
- addrmode = INDX;
- break;
- case 'y':
- if (addrmode == ZM)
- addrmode = ZMY;
- else if (addrmode == IND)
- addrmode = INDY;
- break;
- default:
- done |= 32;
- break;
- }
- }
- }
- sprintf(oprand, "%llx", value);
- break;
- }
- }
+ list(0, 0, 1, 0, 0, 0);
}
- if (oprand2 != NULL && (addrtok == 1 || addrtok == 2)) {
- mode[0] = oprand2[0];
- if (mode[0] == '$' || mode[0] == '%') {
- oprand2++;
- printf("mode[0]: %i, oprand2: %s\n", mode[0], oprand2);
- switch (mode[0]) {
- case '$':
- val2 = strtoull(oprand2, NULL, 16);
- break;
- case '%':
- val2 = strtoull(oprand2, NULL, 2);
- break;
- }
- } else {
- val2 = strtoull(oprand2, NULL, 10);
- }
- switch (addrtok) {
- case 1:
- value += val2;
- break;
- case 2:
- value -= val2;
- break;
- }
- }
- }
- if (ins != NULL && !(done & 6)) {
- uint8_t i;
- for (i = 0; i < OPNUM; i++) {
- if (strcasecmp(opcodes[i].mnemonic, ins) == 0) {
- if (addrmode == IMPL && (opcodes[i].impl || opcodes[i].impl == CPS)) {
- done |= 8;
- } else if (addrmode == IMM) {
- switch (opcodes[i].imm) {
- case PHB:
- case PHP:
- case PHA:
- case PHY:
- case PHX:
- case PLB:
- case PLP:
- case PLA:
- case PLY:
- case PLX:
- case STT:
- case TXS:
- case LSL:
- case LSR:
- case ROL:
- case ROR:
- case ASR:
- case ENT:
- done |= 8;
- break;
- }
- } else {
- if (strcasecmp(ins, "JMP") == 0)
- done |=8;
- if (strcasecmp(ins, "JSR") == 0)
- done |=8;
- if (strcasecmp(ins, "JSL") == 0)
- done |=8;
- if (strcasecmp(ins, "INC") == 0)
- done |=8;
- if (strcasecmp(ins, "BPO") == 0)
- done |=8;
- if (strcasecmp(ins, "BNG") == 0)
- done |=8;
- if (strcasecmp(ins, "BCS") == 0)
- done |=8;
- if (strcasecmp(ins, "BCC") == 0)
- done |=8;
- if (strcasecmp(ins, "BEQ") == 0)
- done |=8;
- if (strcasecmp(ins, "BNE") == 0)
- done |=8;
- if (strcasecmp(ins, "BVS") == 0)
- done |=8;
- if (strcasecmp(ins, "BVC") == 0)
- done |=8;
- }
- op = opcodes[i];
- break;
- }
- }
- if (postfix != NULL && !(done & 8)) {
- if (!strcasecmp(postfix, "w") || !strcasecmp(postfix, "2")) {
- prefix |= 0x13;
- } else if (!strcasecmp(postfix, "d") || !strcasecmp(postfix, "4")) {
- prefix |= 0x23;
- } else if (!strcasecmp(postfix, "q") || !strcasecmp(postfix, "8")) {
- prefix |= 0x33;
- } else if (!prefix) {
- done |=8;
- }
- } else if (postfix == NULL && (!(done & 8) && !prefix)) {
- done |=8;
- }
- uint8_t r;
- uint8_t r2;
- if (!(done & 8)) {
- r = prefix;
- addr[address] = prefix;
- address += 1;
- bytecount+=1;
+ } else if (!strcasecmp(cmd, "asm") || !strcasecmp(cmd, "a")) {
+ done |= 4;
+ puts("Assembling program.");
+ bytecount = assemble(0);
+ puts("Finished assembling program.");
+ printf("Total Assembled Program Size: %llu/$%llX bytes.\n", bytecount, bytecount);
+ } else if (!strcasecmp(cmd, "help") || !strcasecmp(cmd, "h")) {
+ done |= 4;
+ usage();
+ } else if (!strcasecmp(cmd, "inst") || !strcasecmp(cmd, "i")) {
+ done |= 64;
+ done |= 6;
+ strtok_r(cmd, " \t", &tmp);
+ if (tmp != NULL) {
+ instinfo(tmp);
} else {
- r = 0;
+ instinfo("all");
}
- r2 = 1 << ((prefix & 0x30) >> 4);
- switch (addrmode) {
- case IMPL:
- if (op.impl || op.impl == CPS) {
- addr[address++] = op.impl;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s requires an operand.\n", op.mnemonic);
- }
- break;
- case IMM:
- if (op.imm) {
- if ((prefix & 0x30) == 0x10 && op.imm == TXS)
- r = prefix;
- addr[address++] = op.imm;
- bytecount+=1;
- switch (op.imm) {
- case PHP:
- case PHA:
- case PHY:
- case PHX:
- case PLP:
- case PLA:
- case PLY:
- case PLX:
- case STT:
- case LSL:
- case LSR:
- case ROL:
- case ROR:
- case ASR:
- case ENT:
- addr[address++] = value & 0xFF;
- bytecount+=1;
- break;
- case TXS:
- if ((r & 0x30) == 0x10) {
- addr[address] = value & 0xFF;
- addr[address+2] = value >> 8;
- address+=2;
- bytecount+=2;
- }
- break;
- default:
- addr[address] = value & 0xFF;
- if (r & 0x10) {
- addr[address+1] = value >> 8;
- }
- if (r & 0x20) {
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- }
- if (r & 0x30) {
- addr[address+4] = value >> 32;
- addr[address+5] = value >> 40;
- addr[address+6] = value >> 48;
- addr[address+7] = value >> 56;
- }
- address+=r2;
- bytecount+=r2;
- break;
- }
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Immediate data.\n", op.mnemonic);
- }
- break;
- case ZM:
- if (op.zm) {
- addr[address++] = op.zm;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Zero Matrix.\n", op.mnemonic);
- }
- break;
- case ZMX:
- if (op.zmx) {
- addr[address++] = op.zmx;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with x.\n", op.mnemonic);
- }
- break;
- case ZMY:
- if (op.zmy) {
- addr[address++] = op.zmy;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with y.\n", op.mnemonic);
- }
- break;
- case ABS:
- if (op.abs) {
- addr[address++] = op.abs;
- bytecount+=1;
- addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- switch ((r & 0x0C) >> 2) {
- case 3:
- addr[address+7] = value >> 56;
- address += 1;
- bytecount+=1;
- case 2:
- addr[address+6] = (uint64_t)value >> 48;
- addr[address+5] = (uint64_t)value >> 40;
- address += 2;
- bytecount+=2;
- case 1:
- addr[address+4] = (uint64_t)value >> 32;
- addr[address+3] = value >> 24;
- addr[address+2] = value >> 16;
- address += 3;
- bytecount+=3;
- }
- address += 2;
- bytecount+=2;
- break;
- } else {
- fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic);
- }
- break;
- case IND:
- if (op.ind) {
- addr[address++] = op.ind;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s cannot use pointers.\n", op.mnemonic);
- }
- break;
- case INDX:
- if (op.inx) {
- addr[address++] = op.inx;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Indexed Indirect.\n", op.mnemonic);
- }
- break;
- case INDY:
- if (op.iny) {
- addr[address++] = op.iny;
- bytecount+=1;
- addr[address] = value & 0xFF;
- switch ((r & 0x0C) >> 2) {
- case 2:
- addr[address+5] = (uint64_t)value >> 40;
- addr[address+4] = (uint64_t)value >> 32;
- address += 2;
- bytecount+=2;
- case 3:
- addr[address+3] = value >> 24;
- address += 1;
- bytecount+=1;
- case 1:
- addr[address+2] = value >> 16;
- addr[address+1] = value >> 8;
- address += 2;
- bytecount+=2;
- }
- address += 1;
- bytecount+=1;
- break;
- } else {
- fprintf(stderr, "oof, %s does not use Indirect Indexed.\n", op.mnemonic);
- }
- break;
- }
- #if debug
- if (!(done & 6)) {
- printf("Instruction: %s, ", ins);
- printf("Addressing Mode: %s,", adrmode[addrmode]);
- switch (addrmode) {
- case ZM:
- printf(" ");
- break;
- case IMM:
- case ABS:
- case ZMX:
- case ZMY:
- case IND:
- printf(" ");
- break;
- case IMPL:
- case INDX:
- case INDY:
- printf(" ");
- break;
- }
- printf("Address: $%llX", address);
- #if (!__GLIBC__) || (__TINYC__)
- if (postfix != NULL) {
- #else
- if (postfix[0] != '\0') {
- #endif
- printf(", Suffix: %s", postfix);
- }
- if (prefix) {
- printf(", Prefix: $%02X", prefix);
- }
- if (oprand != NULL && !(done & 16)) {
- printf(", Operand: %s", oprand);
- }
- if (addrtok) {
- printf(",\tArithmetic mode, and operand: %s, $%llX", (addrtok == 1) ? "+" : "-", val2);
- }
- if (ir[0] != '\0' && !(done & 32)) {
- printf(",\tIndex Register: %s", ir);
- }
- puts("");
+ }
+ if (use_lexer) {
+ if (!(done & 4)) {
+ address = lex(lex_line, address, 0);
}
- #endif
}
}
}
}
- reslv_fixups();
+ reslv_fixups(0);
return 0;
}