summaryrefslogtreecommitdiff
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
parent59dc46ca8fe1eb6f98abb98fe8579aeaedd2ff15 (diff)
Completely changed the assembler.
It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller.
-rw-r--r--Makefile5
-rw-r--r--asmmon.c1883
-rw-r--r--asmmon.h214
-rw-r--r--lexer.c885
-rw-r--r--opcode.h50
-rw-r--r--programs/subeditor.s39
-rw-r--r--sux.c568
-rw-r--r--test/fib-new.s46
-rw-r--r--test/lex.s40
-rw-r--r--test/reg-transfer.s23
10 files changed, 2025 insertions, 1728 deletions
diff --git a/Makefile b/Makefile
index 9b7ebb0..4aee289 100644
--- a/Makefile
+++ b/Makefile
@@ -7,8 +7,9 @@ else
PCC_CFLAGS=
endif
+
CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
-OBJS = asmmon.o sux.o
+OBJS = sux.o asmmon.o lexer.o
OBJS2 = subasm.o subeditor.o
OBJ_NAME = cisc-0.2
OBJ_NAME2 = subeditor-c
@@ -21,6 +22,8 @@ sux.o :
$(CC) sux.c -c $(CFLAGS) -o sux.o
asmmon.o :
$(CC) asmmon.c -c $(CFLAGS) -o asmmon.o
+lexer.o :
+ $(CC) lexer.c -c $(CFLAGS) -o lexer.o
subasm.o :
$(CC) programs/c-ports/subasm.c -c $(CFLAGS) -o subasm.o
subeditor.o :
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;
}
diff --git a/asmmon.h b/asmmon.h
new file mode 100644
index 0000000..cc21c14
--- /dev/null
+++ b/asmmon.h
@@ -0,0 +1,214 @@
+#include "opcode.h"
+#include <ctype.h>
+#include <string.h>
+
+#define debug 1
+
+char lexeme[0x1000];
+uint8_t lex_type;
+
+static const uint8_t opcodes[OPNUM][9] = {
+ /* IMM ZM ZMX ZMY IND INDX INDY ABS IMPL*/
+ [ 0] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
+ [ 1] = {0x01, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0xFF},
+ [ 2] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02},
+ [ 3] = {0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [ 4] = {0x09, 0x2D, 0xFF, 0xFF, 0x55, 0xAD, 0xAC, 0x2C, 0xFF},
+ [ 5] = {0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [ 6] = {0xFF, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xE5},
+ [ 7] = {0xFF, 0x0E, 0xFF, 0xFF, 0xCE, 0xFF, 0xFF, 0x10, 0xFF},
+ [ 8] = {0x11, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xFF},
+ [ 9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12},
+ [10] = {0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [11] = {0x19, 0x3D, 0xFF, 0xFF, 0x85, 0xFF, 0xFF, 0x4C, 0xFF},
+ [12] = {0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [13] = {0xFF, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xF5},
+ [14] = {0xFF, 0x1E, 0xFF, 0xFF, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF},
+ [15] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0xFF},
+ [16] = {0x21, 0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0xFF},
+ [17] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22},
+ [18] = {0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [19] = {0x29, 0x4D, 0xFF, 0xFF, 0xB5, 0xFF, 0xFF, 0x3C, 0xFF},
+ [20] = {0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [21] = {0xFF, 0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0xFF},
+ [22] = {0x31, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0xFF},
+ [23] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x32},
+ [24] = {0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [25] = {0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [26] = {0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xFF},
+ [27] = {0x41, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x44, 0xFF},
+ [28] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x42},
+ [29] = {0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [30] = {0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [31] = {0xFF, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF},
+ [32] = {0x51, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0xFF},
+ [33] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52},
+ [34] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x58},
+ [35] = {0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [36] = {0xFF, 0x5E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0xFF},
+ [37] = {0x61, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x64, 0xFF},
+ [38] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62},
+ [39] = {0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [40] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A},
+ [41] = {0xFF, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0xFF},
+ [42] = {0x71, 0x76, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0xFF},
+ [43] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x72},
+ [44] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78},
+ [45] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7A},
+ [46] = {0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF},
+ [47] = {0x81, 0x86, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xFF},
+ [48] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x82},
+ [49] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88},
+ [50] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A},
+ [51] = {0xFF, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xFF},
+ [52] = {0x91, 0x96, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0xFF},
+ [53] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92},
+ [54] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98},
+ [55] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A},
+ [56] = {0xFF, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF},
+ [57] = {0xA1, 0xA6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF},
+ [58] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2},
+ [59] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8},
+ [60] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA},
+ [61] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE},
+ [62] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0},
+ [63] = {0xB1, 0xB6, 0xFF, 0xFF, 0x25, 0x7D, 0x7C, 0xB4, 0xFF},
+ [64] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2},
+ [65] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8},
+ [66] = {0xB9, 0xBD, 0xFF, 0xC9, 0x95, 0xFF, 0xFF, 0xBC, 0xFF},
+ [67] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA},
+ [68] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0},
+ [69] = {0xC1, 0xC6, 0x79, 0x39, 0x05, 0x5D, 0x5C, 0xC4, 0xFF},
+ [70] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5},
+ [71] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8},
+ [72] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA},
+ [73] = {0xFF, 0xCD, 0x89, 0x49, 0x15, 0x6D, 0x6C, 0xCC, 0xFF},
+ [74] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0},
+ [75] = {0xD1, 0xD6, 0x99, 0x59, 0x35, 0x8D, 0x8C, 0xD4, 0xFF},
+ [76] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5},
+ [77] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8},
+ [78] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA},
+ [79] = {0xFF, 0xDD, 0xA9, 0x69, 0x45, 0x9D, 0x9C, 0xDC, 0xFF},
+ [80] = {0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ [81] = {0xE1, 0xE6, 0xE9, 0xFF, 0x65, 0xFF, 0xFF, 0xE4, 0xFF},
+ [82] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8},
+ [83] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA},
+ [84] = {0xFF, 0xED, 0xF9, 0xFF, 0x75, 0xFF, 0xFF, 0xEC, 0xFF},
+ [85] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE},
+ [86] = {0xF1, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF},
+ [87] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2},
+ [88] = {0xFF, 0xFD, 0xFF, 0xD9, 0xA5, 0xFF, 0xFF, 0xFC, 0xFF},
+ [89] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}
+};
+
+static const char *dir_t[5] = {
+ [0] = "org",
+ [1] = "byte",
+ [2] = "word",
+ [3] = "dword",
+ [4] = "qword"
+};
+
+static const char *rs_t[4] = {
+ [0] = "",
+ [1] = ".w",
+ [2] = ".d",
+ [3] = ".q"
+};
+
+static const char *lex_tok[14] = {
+ [0x0] = "TOK_DIR",
+ [0x1] = "TOK_LABEL",
+ [0x2] = "TOK_SYM",
+ [0x3] = "TOK_PLUS",
+ [0x4] = "TOK_MINUS",
+ [0x5] = "TOK_STRING",
+ [0x6] = "TOK_CHAR",
+ [0x7] = "TOK_IMM",
+ [0x8] = "TOK_OPCODE",
+ [0x9] = "TOK_RS",
+ [0xA] = "TOK_COMMENT",
+ [0xB] = "TOK_HEX",
+ [0xC] = "TOK_DEC",
+ [0xD] = "TOK_BIN"
+};
+
+static const uint8_t bitsize[4] = {
+ [0] = 0x07,
+ [1] = 0x0F,
+ [2] = 0x1F,
+ [3] = 0x3F
+};
+
+static const uint8_t amp[8] = {
+ [0] = 0x00,
+ [1] = 0x00,
+ [2] = 0x07,
+ [4] = 0x07,
+ [5] = 0x0B,
+ [6] = 0x0B,
+ [3] = 0x0F,
+ [7] = 0x0F
+};
+
+struct line {
+ uint8_t stab;
+ uint8_t sspace;
+ uint8_t dir;
+ uint8_t mne;
+ uint8_t rs;
+ uint8_t opbase;
+ uint8_t aopbase;
+ uint8_t am;
+ uint8_t cm;
+ uint8_t etab;
+ uint8_t espace;
+ uint8_t islabel;
+ uint8_t issym;
+ uint16_t sym;
+ uint16_t com;
+ uint16_t str;
+ uint16_t linenum;
+ uint64_t op;
+ uint64_t aop;
+ uint64_t addr;
+};
+
+extern uint16_t linenum;
+extern uint16_t lineidx;
+extern uint16_t stridx;
+extern uint16_t comidx;
+
+char *string[0x1000];
+char *comment[0x1000];
+
+struct line tokline[0x1000];
+
+struct fixup {
+ struct fixup *nxt;
+ struct symbol *s;
+ uint16_t ln;
+ uint64_t adr;
+};
+
+struct symbol {
+ struct symbol* nxt;
+ uint64_t val;
+ uint8_t def;
+ char name[128];
+ uint16_t id;
+};
+
+extern struct symbol *symbols;
+extern struct fixup *fixups;
+extern uint8_t defined;
+extern uint8_t isfixup;
+
+extern struct symbol *mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, uint16_t id, uint8_t dbg);
+extern uint64_t use_symbol(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg);
+extern uint8_t set_symval(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg);
+extern char *get_symname(uint16_t id, uint8_t dbg);
+extern uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg);
+extern uint16_t get_comment(const char *cmnt, uint8_t dbg);
+extern uint16_t reslv_fixups(uint8_t dbg);
+extern uint64_t lex(char *str, uint64_t address, uint8_t dbg);
diff --git a/lexer.c b/lexer.c
new file mode 100644
index 0000000..47aea24
--- /dev/null
+++ b/lexer.c
@@ -0,0 +1,885 @@
+#include "asmmon.h"
+
+struct symbol *symbols = 0;
+struct fixup *fixups = 0;
+
+struct symbol *mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, uint16_t id, uint8_t dbg) {
+ struct symbol *s;
+ uint16_t i = 0;
+ uint8_t flag;
+ for (s = symbols; s; s = s->nxt) {
+ if (useid) {
+ flag = id == s->id;
+ } else {
+ flag = !strcmp(name, s->name);
+ }
+ if (flag) {
+ if (def) {
+ if (s->def) {
+ if (dbg) {
+ printf("mksymbol(): oof, you cannot redefine the symbol: %s\n", name);
+ }
+ defined = 1;
+ } else {
+ defined = 0;
+ }
+ s->def = def;
+ s->val = val;
+ if (dbg) {
+ printf("mksymbol(): def: %u, val: $%016llX, name: %s\n", def, val, name);
+ }
+ }
+ return s;
+ }
+ i++;
+ }
+ s = malloc(sizeof(*s) + strlen(name));
+ s->def = def;
+ s->val = val;
+ strcpy(s->name, name);
+ s->nxt = symbols;
+ s->id = i;
+ symbols = s;
+ defined = 0;
+ if (dbg) {
+ printf("mksymbol(): def: %u, val: $%016llX, name: %s, id: $%04X\n", def, val, name, i);
+ }
+ return s;
+}
+
+uint64_t use_symbol(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, useid, id, dbg);
+ val++;
+ if (s->def) {
+ return s->val;
+ } else {
+ if (dbg) {
+ printf("use_symbol(): ");
+ printf("oof, symbol ");
+ if (useid) {
+ printf("id $%04X, ", id);
+ } else {
+ printf("%s, ", name);
+ }
+ puts("does not exist, yet.");
+ }
+ return val-1;
+ }
+}
+
+uint8_t set_symval(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, useid, id, dbg);
+ if (s->def) {
+ s->val = val;
+ return 1;
+ } else {
+ if (dbg) {
+ printf("set_symval(): ");
+ printf("oof, symbol ");
+ if (useid) {
+ printf("id $%04X, ", id);
+ } else {
+ printf("%s, ", name);
+ }
+ puts("does not exist, yet.");
+ }
+ return 0;
+ }
+}
+
+char *get_symname(uint16_t id, uint8_t dbg) {
+ struct symbol *s = mksymbol("", 0, 0, 1, id, dbg);
+ if (s->def) {
+ return s->name;
+ } else {
+ if (dbg) {
+ printf("get_symname(): oof, symbol id $%04X, has not been defined, yet.\n", id);
+ }
+ return NULL;
+ }
+}
+
+uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, 0, 0, dbg);
+ if (s->def) {
+ return s->id;
+ } else {
+ if (dbg) {
+ printf("get_symid(): oof, symbol %s, does not exist, yet.\n", name);
+ }
+ struct fixup *f = malloc(sizeof(*f));
+ f->nxt = fixups;
+ f->adr = val;
+ f->ln = ln;
+ f->s = s;
+ fixups = f;
+ return 0xFFFF;
+ }
+}
+
+uint16_t get_comment(const char *cmnt, uint8_t dbg) {
+ uint16_t i = 0;
+ uint8_t iscom = 0;
+ for (; i < comidx; i++) {
+ if (comment[i] != NULL) {
+ iscom = !strcmp(cmnt, comment[i]);
+ } else {
+ break;
+ }
+ if (iscom) {
+ break;
+ }
+ }
+ if (comment[i] == NULL) {
+ if (dbg) {
+ printf("get_comment(): oof, the index $%04X is NULL.\n", i);
+ }
+ return 0xFFFF;
+ }
+ if (i == comidx) {
+ if (dbg) {
+ printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", cmnt);
+ }
+ return 0xFFFF;
+ }
+ if (dbg) {
+ printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", cmnt, i);
+ }
+ return i;
+}
+
+uint16_t reslv_fixups(uint8_t dbg) {
+ uint16_t i = 0, j = 0;
+ struct fixup *f;
+ f = fixups;
+ for (; f;) {
+ /*printf("f: $%016llX, f->nxt: $%016llX, f->s->name: %s, f->s->val: $%016llX\n", &f, &f->nxt, f->s->name, f->s->val);*/
+ if (f->s->def) {
+ if (f->ln == 0xFFFF) {
+ addr[f->adr] = f->s->val & 0xFF;
+ if (f->s->val & 0xFF00)
+ addr[f->adr+1] = f->s->val >> 8;
+ if (f->s->val & 0xFF000000) {
+ addr[f->adr+2] = f->s->val >> 16;
+ addr[f->adr+3] = f->s->val >> 24;
+ }
+ if (f->s->val & 0xFF00000000000000) {
+ addr[f->adr+4] = f->s->val >> 32;
+ addr[f->adr+5] = f->s->val >> 40;
+ addr[f->adr+6] = f->s->val >> 48;
+ addr[f->adr+7] = f->s->val >> 56;
+ }
+ } else {
+ tokline[f->ln].sym = f->s->id;
+ }
+ } else {
+ if (dbg) {
+ printf("reslv_fixups(): oof, undefined reference to '%s', at $%016llX.\n", f->s->name, f->adr);
+ }
+ i++;
+ }
+ f = f->nxt;
+ j++;
+ }
+ return i;
+
+}
+
+uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
+ uint64_t value = 0;
+ uint16_t i = 0;
+ uint16_t j = 0;
+ uint16_t flags = 0;
+ uint8_t opsize = 0;
+
+ uint16_t l = lineidx;
+ uint16_t symid = tokline[l].sym;
+ uint16_t str = tokline[l].str;
+ uint16_t com = tokline[l].com;
+ uint8_t islabel = tokline[l].islabel;
+ uint8_t issym = tokline[l].issym;
+ uint8_t opbase = tokline[l].opbase;
+ uint8_t aopbase = tokline[l].aopbase;
+ uint8_t dir = tokline[l].dir;
+ uint8_t am = tokline[l].am;
+ uint8_t cm = tokline[l].cm;
+ uint8_t rs = tokline[l].rs;
+ uint8_t mne = tokline[l].mne;
+
+ flags |= (dir != 0x00FF) << 0x00;
+ flags |= (mne != 0x00FF) << 0x01;
+ flags |= (rs != 0x00FF) << 0x02;
+ flags |= (am != 0x00FF) << 0x03;
+ flags |= (opbase != 0x00FF) << 0x04;
+ flags |= (aopbase != 0x00FF) << 0x05;
+ flags |= (symid != 0xFFFF) << 0x06;
+ flags |= (fixup > 0x0000) << 0x06;
+ flags |= (islabel ) << 0x07;
+ flags |= (issym ) << 0x07;
+ flags |= (am != 0x00FF) << 0x08;
+ flags |= (cm != 0x00FF) << 0x09;
+ flags |= (str != 0xFFFF) << 0x0A;
+
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("flags: $%04X\n", flags);
+ }
+ if (!flags || flags == 0x40) {
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("This line only contains a comment, so don't update the address.");
+ }
+ return address;
+ }
+ if (((flags & 0x53) == 0x42)) {
+ if (isfixup && symid == 0xFFFF && (opcodes[mne][IMPL] == 0xFF)) {
+ value = address;
+ } else {
+ value = use_symbol("", symid, address, 1, dbg);
+ }
+ } else {
+ value = tokline[l].op;
+ }
+ if (flags & 0x220) {
+ switch (cm) {
+ case 0: value += tokline[l].aop; break;
+ case 1: value -= tokline[l].aop; break;
+ }
+ }
+ if (dbg) {
+ printf("update_addr(): value: $%llX\n", value);
+ }
+ switch (dir) {
+ case DIR_ORG:
+ address = value;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Set the Program Counter's Origin to $%llX.\n", address);
+ }
+ break;
+ case DIR_BYTE:
+ if (flags & 0x400) {
+ for (; string[str][i] != '\0'; i++, j++, address++) {
+ i += string[str][i] == '\\';
+ }
+ j++;
+ address++;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%04X", j);
+ puts(", to make room for the string.");
+ }
+ } else {
+ address += 1;
+ }
+ break;
+ case DIR_WORD: address += 2; break;
+ case DIR_DWORD: address += 4; break;
+ case DIR_QWORD: address += 8; break;
+ }
+ if (flags & 0x01) {
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("This line contains a directive, so skip everything else.");
+ }
+ return address;
+ }
+ if ((flags & 0x15B) == 0x02 || (opcodes[mne][IMPL] != 0xFF && am == 0xFF && opbase == 0xFF && symid == 0xFFFF)) {
+ tokline[l].am = IMPL;
+ am = IMPL;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Implied.");
+ }
+ }
+ if (am == IMPL) {
+ opsize = 0;
+ } else if (am == IMM) {
+ switch (rs) {
+ case 3: address += 8; break;
+ case 2: address += 4; break;
+ case 1: address += 2; break;
+ default: address += 1; break;
+ }
+ if (dbg) {
+ if (!(flags & 0x04)) {
+ rs = 0;
+ }
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%02X", 1 << rs);
+ puts(", to make room for the operand.");
+ }
+ } else if ((flags & 0x158) && (!(flags & 0x80))) {
+ opsize = 0;
+ 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) {
+ switch (opsize-1) {
+ case 0:
+ case 2:
+ case 5:
+ case 3:
+ if (!(flags & 0x100)) {
+ am = ZM;
+ tokline[l].am = am;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Zero Matrix.");
+ }
+ /*address += !(opsize-1);*/
+ }
+ break;
+ case 1:
+ case 4:
+ case 6:
+ case 7:
+ if (!(flags & 0x100)) {
+ am = ABS;
+ tokline[l].am = am;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Absolute.");
+ }
+ }
+ break;
+ }
+ address += opsize;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%02X", opsize);
+ puts(", to make room for the address.");
+ }
+ }
+ }
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Address: $%llX\n", address);
+ }
+ return address;
+}
+
+uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
+ char sym[0x100];
+ uint16_t i = 0;
+ uint16_t j = 0;
+ uint16_t comid = 0;
+ lex_type = 0xFF;
+ uint8_t k = 0;
+ uint8_t rs = 0;
+ uint8_t isop = 0;
+ int num = 0;
+ int isch = 0;
+ int16_t ln = -1;
+ char lnum[6];
+ uint8_t islinenum;
+ uint8_t space = 0;
+ uint8_t tab = 0;
+ uint8_t isstart = 1;
+ uint8_t fall = 0;
+ tokline[lineidx].dir = 0xFF;
+ tokline[lineidx].mne = 0xFF;
+ tokline[lineidx].rs = 0xFF;
+ tokline[lineidx].am = 0xFF;
+ tokline[lineidx].cm = 0xFF;
+ tokline[lineidx].opbase = 0xFF;
+ tokline[lineidx].aopbase = 0xFF;
+ tokline[lineidx].islabel = 0;
+ tokline[lineidx].issym = 0;
+ tokline[lineidx].str = 0xFFFF;
+ tokline[lineidx].com = 0xFFFF;
+ tokline[lineidx].sym = 0xFFFF;
+ tokline[lineidx].op = 0;
+ tokline[lineidx].aop = 0;
+ tokline[lineidx].addr = address;
+
+ while (isdigit(str[i]) && !isspace(str[i])) {
+ lnum[j++] = str[i++];
+ }
+ islinenum = i;
+ if (i) {
+ lnum[j] = '\0';
+ ln = strtol(lnum, NULL, 10);
+ j = 0;
+ } else {
+ ln = linenum;
+ }
+ uint8_t done = 0;
+ while (str[i] != '\0' && str[i] != '\n') {
+ space = 0;
+ tab = 0;
+ while (isspace(str[i+j])) {
+ tab += str[i+j] == '\t';
+ space += str[i+j] == ' ';
+ j++;
+ }
+ j = 0;
+ if (dbg) {
+ printf("lex(): tab: %u, space: %u\n", tab, space);
+ }
+ if (isstart) {
+ tokline[lineidx].stab = tab;
+ tokline[lineidx].sspace = space;
+ if (dbg) {
+ printf("lex(): starting tabs: %u, starting spaces: %u\n", tokline[lineidx].stab, tokline[lineidx].sspace);
+ }
+ }
+ if (isspace(str[i])) {
+ while (isspace(str[i])) {
+ i++;
+ }
+ }
+ switch (str[i]) {
+ case '.':
+ i++;
+ while (!isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ if (!isop) {
+ for (k = 0; k < 5; k++) {
+ if (!strcasecmp(lexeme, dir_t[k])) {
+ lex_type = TOK_DIR;
+ break;
+ }
+ }
+ tokline[lineidx].dir = k;
+ } else {
+ lex_type = TOK_RS;
+ switch (tolower(lexeme[j-1])) {
+ case '2':
+ case 'w':
+ rs = 1;
+ break;
+ case '4':
+ case 'd':
+ rs = 2;
+ break;
+ case '8':
+ case 'q':
+ rs = 3;
+ break;
+ }
+ address++;
+ tokline[lineidx].rs = rs;
+ isop = 0;
+ }
+ break;
+ case '\"':
+ i++;
+ while (str[i] != '\"') {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ string[stridx] = malloc(j+1);
+ memcpy(string[stridx], lexeme, j+1);
+ tokline[lineidx].str = stridx;
+ if (dbg) {
+ printf("lex(): str[0x%04X]: %s\n", stridx, string[stridx]);
+ }
+ stridx++;
+ lex_type = TOK_STRING;
+ break;
+ case '#':
+ lexeme[j] = '#';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ tokline[lineidx].am = IMM;
+ lex_type = TOK_IMM;
+ break;
+ case '$':
+ i++;
+ while (isxdigit(str[i]) && (str[i] != '\0' && str[i] != '\n')) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 16);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_HEX;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].aopbase = BASE_HEX;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].aopbase = BASE_HEX;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].opbase = BASE_HEX;
+ }
+ break;
+
+ }
+ lex_type = TOK_HEX;
+ break;
+ case '%':
+ i++;
+ while (isdigit(str[i]) && (str[i] != '\0' && str[i] != '\n')) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 2);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_BIN;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].aopbase = BASE_BIN;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].aopbase = BASE_BIN;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].opbase = BASE_BIN;
+ }
+ break;
+
+ }
+ lex_type = TOK_BIN;
+ break;
+ case '+':
+ lexeme[j] = '+';
+ lexeme[j+1] = '\0';
+ tokline[lineidx].cm = 0;
+ lex_type = TOK_PLUS;
+ break;
+ case '-':
+ lexeme[j] = '-';
+ lexeme[j+1] = '\0';
+ tokline[lineidx].cm = 1;
+ lex_type = TOK_MINUS;
+ break;
+ case '(':
+ lexeme[j] = '(';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ tokline[lineidx].am = IND;
+ break;
+ case ')':
+ i++;
+ if (str[i] == ',') {
+ i++;
+ while (isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ if (tokline[lineidx].am == IND && tolower(str[i]) == 'y') {
+ lexeme[j++] = 'y';
+ tokline[lineidx].am = INDY;
+ }
+ lexeme[j] = '\0';
+ } else {
+ lexeme[j] = ')';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ }
+ break;
+ case ',':
+ i++;
+ while (isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ if (tokline[lineidx].am == IND && tolower(str[i]) == 'x') {
+ tokline[lineidx].am = INDX;
+ lexeme[j++] = 'x';
+ i++;
+ } else {
+ switch (tolower(str[i])) {
+ case 'x':
+ tokline[lineidx].am = ZMX;
+ lexeme[j++] = 'x';
+ break;
+ case 'y':
+ tokline[lineidx].am = ZMY;
+ lexeme[j++] = 'y';
+ break;
+ }
+ }
+ lexeme[j] = '\0';
+ break;
+ case ':':
+ i++;
+ lexeme[j] = ':';
+ lexeme[j+1] = '\0';
+ lex_type = TOK_LABEL;
+ tokline[lineidx].islabel = 1;
+ mksymbol(sym, address, 1, 0, 0, dbg);
+ if (isfixup) {
+ isfixup = reslv_fixups(dbg);
+ }
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ break;
+ case '=':
+ i++;
+ lexeme[j] = '=';
+ lexeme[j+1] = 0;
+ tokline[lineidx].issym = 1;
+ lex_type = TOK_SYM;
+ break;
+ case ';':
+ i++;
+ while (str[i] != '\0' && str[i] != '\n') {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ comid = get_comment(lexeme, dbg);
+ if (comid == 0xFFFF) {
+ comment[comidx] = malloc(j+1);
+ memcpy(comment[comidx], lexeme, j+1);
+ tokline[lineidx].com = comidx;
+ if (dbg) {
+ printf("lex(): com[0x%04X]: %s\n", comidx, comment[comidx]);
+ }
+ comidx++;
+ } else {
+ tokline[lineidx].com = comid;
+ if (dbg) {
+ printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
+ }
+ }
+ lex_type = TOK_COMMENT;
+ break;
+ default:
+ if (isalnum(str[i]) || str[i] == '_') {
+ while (!isspace(str[i])) {
+ switch (str[i]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case '=':
+ case ';':
+ case '\0':
+ case '\n':
+ isch = 0;
+ break;
+ default:
+ isch = 1;
+ lexeme[j++] = str[i++];
+ break;
+ }
+ if (!isch) {
+ break;
+ }
+ }
+ lexeme[j] = '\0';
+ isch = 0;
+ isop = 0;
+ if (j == 3 && str[i] != ':') {
+ for (k = 0; k < OPNUM; k++) {
+ if (!strcasecmp(lexeme, mne[k])) {
+ lex_type = TOK_OPCODE;
+ isop = 1;
+ tokline[lineidx].mne = k;
+ address++;
+ break;
+ }
+ }
+ }
+ if (!isop) {
+ for (k = 0; lexeme[k] != '\0';) {
+ switch (lexeme[k]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case ';':
+ case '=':
+ case '\0':
+ case '\n':
+ fall = 1;
+ break;
+ default:
+ fall = 0;
+ break;
+ }
+ if (fall) {
+ break;
+ }
+ if ((isalnum(lexeme[k]) || lexeme[k] == '_')) {
+ if (!isch) {
+ isch = isalpha(lexeme[k]);
+ }
+ num = isdigit(lexeme[k]) && !isch;
+ k++;
+ } else {
+ break;
+ }
+ }
+ if (lexeme[k] == '\0') {
+ if (num) {
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 10);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ if (isfixup) {
+ isfixup = reslv_fixups(dbg);
+ }
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_DEC;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].aopbase = BASE_DEC;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].aopbase = BASE_DEC;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].opbase = BASE_DEC;
+ }
+ break;
+
+ }
+ lex_type = TOK_DEC;
+ } else if (isch && lex_type != TOK_HEX && lex_type != TOK_BIN) {
+ lex_type = TOK_SYM;
+ memcpy(sym, lexeme, j+1);
+ uint8_t spaces = 0;
+ for (; isspace(str[i+spaces]); spaces++);
+ if (dbg) {
+ printf("lex(): spaces: %u\n", spaces);
+ }
+ if (str[i+spaces] != ':' && str[i+spaces] != '=') {
+ tokline[lineidx].sym = get_symid(lexeme, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (dbg) {
+ printf("lex(): lexeme: %s, lex_type: %s\n", lexeme, (lex_type != 0xFF) ? lex_tok[lex_type] : "TOK_NONE");
+ }
+ isstart = 0;
+ /*lex_type = 0xFF;*/
+ j = 0;
+ if (lex_type == TOK_OPCODE && !isop) {
+ j = 0;
+ } else {
+ if (lex_type == TOK_PLUS || lex_type == TOK_MINUS) {
+ i++;
+ } else {
+ switch (str[i]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case ';':
+ case '=':
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\0':
+ break;
+ default:
+ i++;
+ break;
+ }
+ }
+ }
+ if (lex_type == TOK_COMMENT) {
+ if (!isstart) {
+ tokline[lineidx].etab = tab;
+ tokline[lineidx].espace = space;
+ if (dbg) {
+ printf("lex(): ending tabs: %u, ending spaces: %u\n", tokline[lineidx].etab, tokline[lineidx].espace);
+ }
+ }
+ }
+ if (lex_type != TOK_SYM) {
+ for (k = 0; lexeme[k] != '\0';) {
+ lexeme[k] = 0;
+ ++k;
+ }
+ lex_type = 0xFF;
+ }
+ }
+ if (i) {
+ address = update_addr(address, isfixup, dbg);
+ if (dbg) {
+ printf("lex(): Next address: $%llX\n", address);
+ printf(
+ "lex(): "
+ "address: $%llX"
+ ", dir: %u"
+ ", mne: $%02X"
+ ", rs: %u"
+ ", am: %u"
+ ", cm: %u"
+ ", opbase: %u"
+ ", com: $%04X"
+ ", sym: $%04X"
+ ", op: $%016X"
+ ", aop: $%016X"
+ ", ln: %i\n"
+ , tokline[lineidx].addr
+ , tokline[lineidx].dir
+ , tokline[lineidx].mne
+ , tokline[lineidx].rs
+ , tokline[lineidx].am
+ , tokline[lineidx].cm
+ , tokline[lineidx].opbase
+ , tokline[lineidx].com
+ , tokline[lineidx].sym
+ , tokline[lineidx].op
+ , tokline[lineidx].aop
+ , lineidx);
+ }
+ if (ln > linenum) {
+ linenum+=(10+(ln & 10));
+ tokline[lineidx].linenum = ln;
+ } else if (!islinenum) {
+ tokline[lineidx].linenum = linenum;
+ linenum += 10;
+ }
+ lineidx++;
+ }
+ return address;
+}
diff --git a/opcode.h b/opcode.h
index 47fe125..c92ee67 100644
--- a/opcode.h
+++ b/opcode.h
@@ -213,22 +213,7 @@ struct sux {
uint8_t crt; /* Current running threads. */
};
-typedef struct {
- char mnemonic[4];
- uint8_t imm;
- uint8_t abs;
- uint8_t zm;
- uint8_t zmy;
- uint8_t zmx;
- uint8_t ind;
- uint8_t inx;
- uint8_t iny;
- uint8_t impl;
-} opent;
-
-opent opcodes[OPNUM];
-
-enum {IMPL, IMM, ZM, ZMX, ZMY, ABS, IND, INDX, INDY};
+enum {IMM, ZM, ZMX, ZMY, IND, INDX, INDY, ABS, IMPL};
enum {
DIR_ORG,
DIR_BYTE,
@@ -241,8 +226,11 @@ enum {
TOK_DIR,
TOK_LABEL,
TOK_SYM,
+ TOK_PLUS,
+ TOK_MINUS,
TOK_STRING,
TOK_CHAR,
+ TOK_IMM,
TOK_OPCODE,
TOK_RS,
TOK_COMMENT,
@@ -257,16 +245,28 @@ enum {
BASE_BIN
};
+
+static const uint8_t adrsize[8] = {
+ [0] = 0,
+ [1] = 2,
+ [2] = 5,
+ [3] = 3,
+ [4] = 1,
+ [5] = 4,
+ [6] = 6,
+ [7] = 7
+};
+
static const char *adrmode[9] = {
- [0] = "IMPL",
- [1] = "IMM",
- [2] = "ZM",
- [3] = "ZMX",
- [4] = "ZMY",
- [5] = "ABS",
- [6] = "IND",
- [7] = "INDX",
- [8] = "INDY"
+ [IMM ] = "IMM",
+ [ZM ] = "ZM",
+ [ZMX ] = "ZMX",
+ [ZMY ] = "ZMY",
+ [IND ] = "IND",
+ [INDX] = "INDX",
+ [INDY] = "INDY",
+ [ABS ] = "ABS",
+ [IMPL] = "IMPL"
};
static const uint8_t optype[0x100] = {
diff --git a/programs/subeditor.s b/programs/subeditor.s
index eaecab5..5e6ce08 100644
--- a/programs/subeditor.s
+++ b/programs/subeditor.s
@@ -34,43 +34,43 @@ cmd_buf:
; Initalize some variables.
-.org $0
+.org 0
scr_row:
- .byte $0
+ .byte 0
scr_col:
- .byte $0
+ .byte 0
scr_trow:
- .byte $0
+ .byte 0
scr_tcol:
- .byte $0
+ .byte 0
scr_ptr:
- .word $0
+ .word 0
scr_ptr2:
- .word $0
+ .word 0
; Registers.
a:
- .byte $0
+ .byte 0
b:
- .byte $0
+ .byte 0
c:
- .byte $0
+ .byte 0
d:
- .byte $0
+ .byte 0
e:
- .byte $0
+ .byte 0
f:
- .byte $0
+ .byte 0
; This register is always zero.
zero:
- .qword $0
+ .qword 0
; End of registers.
end:
- .byte $0
+ .byte 0
bitmask:
- .byte $0
+ .byte 0
bitabl:
- .qword $0
- .qword $0
+ .qword 0
+ .qword 0
scr_str:
.byte $0
scr_end:
@@ -1152,9 +1152,10 @@ rdrwln_done:
dec end ;
rtl ;
+
.org $FFC0
.qword reset
-r
+a
done
diff --git a/sux.c b/sux.c
index 164ca4a..6c9442f 100644
--- a/sux.c
+++ b/sux.c
@@ -4,8 +4,8 @@
#include <string.h>
#include <pthread.h>
#define bench 0
-#define debug 1
-#define IO 0
+#define debug 0
+#define IO 1
#define keypoll 0
#if bench
#include <sys/time.h>
@@ -30,10 +30,11 @@ uint64_t inst[THREADS];
uint64_t inss;
uint8_t threads_done = 0;
uint8_t kbd_rdy = 0;
-uint8_t kbd_ln = 0;
uint8_t wai = 0;
uint8_t step = 0;
uint8_t irq = 0;
+
+
#if !bench
WINDOW *scr;
#endif
@@ -41,10 +42,12 @@ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER;
+
struct suxthr {
struct sux sx;
uint8_t th;
};
+
#if bench
double ipc;
struct timeval str[THREADS], en[THREADS];
@@ -177,7 +180,6 @@ void *run(void *args) {
switch (opcode) {
case TXS:
break;
-
case PHB:
case PHP:
case PHA:
@@ -207,23 +209,31 @@ void *run(void *args) {
case ZM:
case ZMX:
case ZMY:
+ case IND:
+ case INDX:
+ case INDY:
+ tmp = 0;
address = addr[cpu->pc[thread]];
+ /* Unroll Loop by implementing Duff's Device. */
switch (addrsize) {
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
- cpu->pc[thread]+=2;
+ tmp+=2;
case 3:
address |= addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=1;
+ tmp+=1;
case 1:
address |= addr[cpu->pc[thread]+2] << 16;
address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
+ tmp+=2;
case 0:
- cpu->pc[thread]+=1;
+ tmp+=1;
}
+ cpu->pc[thread]+=tmp;
tmpaddr = address;
+ iclk++;
+ reg = 0;
switch (optype[opcode]) {
case ZMX:
address += cpu->x[thread];
@@ -233,75 +243,64 @@ void *run(void *args) {
address += cpu->y[thread];
iclk++;
break;
+ case INDX:
+ address += cpu->x[thread];
+ iclk++;
+ /* Falls Through. */
+ case INDY:
+ /* Did we fall through? */
+ if (optype[opcode] == INDX) {
+ reg = 0; /* Yes, so set reg back to zero. */
+ } else {
+ reg = cpu->y[thread]; /* No, so set reg to Y. */
+ iclk++;
+ }
+ /* Falls Through. */
+ case IND:
+ value = addr[address];
+ value += addr[address+1] << 8;
+ value += addr[address+2] << 16;
+ value += addr[address+3] << 24;
+ value += (uint64_t)addr[address+4] << 32;
+ value += (uint64_t)addr[address+5] << 40;
+ value += (uint64_t)addr[address+6] << 48;
+ value += (uint64_t)addr[address+7] << 56;
+ iclk++;
+ value += reg;
+ address = value;
+ value = 0;
+ reg = 0;
+ break;
}
- iclk++;
- break;
- case IND:
- case INDX:
- case INDY:
- address = addr[cpu->pc[thread]];
- switch (addrsize) {
- case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
- cpu->pc[thread]+=2;
- case 3:
- address |= addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=1;
- case 1:
- address |= addr[cpu->pc[thread]+2] << 16;
- address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
- case 0:
- cpu->pc[thread]+=1;
- }
- iclk++;
- tmpaddr = address;
- if (optype[opcode] == INDX) {
- address += cpu->x[thread];
- iclk++;
- }
- value = addr[address];
- value |= addr[address+1] << 8;
- value |= addr[address+2] << 16;
- value |= addr[address+3] << 24;
- value |= (uint64_t)addr[address+4] << 32;
- value |= (uint64_t)addr[address+5] << 40;
- value |= (uint64_t)addr[address+6] << 48;
- value |= (uint64_t)addr[address+7] << 56;
- iclk++;
- if (optype[opcode] == INDY) {
- value += cpu->y[thread];
- iclk++;
- }
- address = value;
- value = 0;
- iclk++;
break;
case ABS:
+ tmp = 0;
address = addr[cpu->pc[thread]];
+ /* Unroll Loop by implementing Duff's Device. */
switch (addrsize) {
case 3:
address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=1;
+ tmp+=1;
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- cpu->pc[thread]+=2;
+ tmp+=2;
iclk++;
case 1:
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
address |= addr[cpu->pc[thread]+3] << 24;
address |= addr[cpu->pc[thread]+2] << 16;
- cpu->pc[thread]+=3;
+ tmp+=3;
case 0:
address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
+ tmp+=2;
}
+ cpu->pc[thread]+=tmp;
break;
}
value = addr[address];
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
@@ -324,19 +323,11 @@ void *run(void *args) {
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';
- } else {
- postfix[0] = '.';
- if (regsize == 2)
- postfix[1] = 'W';
- else if (regsize == 4)
- postfix[1] = 'D';
- else if (regsize == 8)
- postfix[1] = 'Q';
- postfix[2] = '\0';
+ switch(regsize) {
+ case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break;
+ case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break;
+ case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break;
+ case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break;
}
switch (optype[opcode]) {
case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
@@ -351,10 +342,10 @@ void *run(void *args) {
case ZM:
case ZMX:
case ZMY:
- if (optype[opcode] == ZMX)
- tmpaddr = address - cpu->x[thread];
- else if (optype[opcode] == ZMY)
- tmpaddr = address - cpu->y[thread];
+ switch (optype[opcode]) {
+ case ZMX: tmpaddr = address - cpu->x[thread]; break;
+ case ZMY: tmpaddr = address - cpu->y[thread]; break;
+ }
switch (addrsize) {
case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 2: wprintw(scr, "%s%s $%014llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
@@ -444,17 +435,16 @@ void *run(void *args) {
case CPS: /* Clear Processor Status. */
cpu->ps &= 0;
break;
- case ADC: /* ADC Immediate. */
case AAB: /* Add Accumulator with carry by B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ADC: /* ADC Immediate. */
case ADC_AB: /* ADC Absolute. */
case ADC_Z: /* ADC Zero Matrix. */
- if (opcode == AAB)
- value = cpu->b[thread];
sum = cpu->a[thread]+value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag((sum >> 63), N);
- setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum < value), C);
break;
case PHB: /* PusH B register to stack. */
@@ -472,6 +462,7 @@ void *run(void *args) {
}
if (tmp > 7)
tmp = 7;
+ /* Unroll Loop by implementing Duff's Device. */
switch (tmp) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (6<<3);
@@ -494,20 +485,15 @@ void *run(void *args) {
case TBA: /* Transfer B to Accumulator. */
case TXS: /* Transfer X to Stack pointer. */
switch (opcode) {
- case TAY: cpu->y[thread] = cpu->a[thread]; break;
- case TAX: cpu->x[thread] = cpu->a[thread]; break;
- case TYX: cpu->x[thread] = cpu->y[thread]; break;
- case TYA: cpu->a[thread] = cpu->y[thread]; break;
- case TXA: cpu->a[thread] = cpu->x[thread]; break;
- case TXY: cpu->y[thread] = cpu->x[thread]; break;
- case TAB: cpu->b[thread] = cpu->a[thread];
- setflag(cpu->b[thread] == 0, Z);
- setflag(cpu->b[thread] >> 63, N);
- break;
- case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF;
- cpu->x[thread] = cpu->stk_st[thread] << 16;
- break;
- case TBA: cpu->a[thread] = cpu->b[thread]; break;
+ case TBA: cpu->a[thread] = cpu->b[thread]; reg = cpu->a[thread]; break;
+ case TXA: cpu->a[thread] = cpu->x[thread]; reg = cpu->a[thread]; break;
+ case TYA: cpu->a[thread] = cpu->y[thread]; reg = cpu->a[thread]; break;
+ case TAB: cpu->b[thread] = cpu->a[thread]; reg = cpu->b[thread]; break;
+ case TAY: cpu->y[thread] = cpu->a[thread]; reg = cpu->y[thread]; break;
+ case TXY: cpu->y[thread] = cpu->x[thread]; reg = cpu->y[thread]; break;
+ case TAX: cpu->x[thread] = cpu->a[thread]; reg = cpu->x[thread]; break;
+ case TYX: cpu->x[thread] = cpu->y[thread]; reg = cpu->x[thread]; break;
+ case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; break;
case TXS: cpu->sp[thread] = cpu->x[thread];
if (prefix == 0x13 && (value == thread+1 || value > 8)) {
cpu->stk_st[thread] = value & 0xFF;
@@ -516,41 +502,23 @@ void *run(void *args) {
}
break;
}
- switch (opcode) {
- case TYA:
- case TXA:
- case TBA:
- setflag(cpu->a[thread] == 0, Z);
- setflag(cpu->a[thread] >> 63, N);
- break;
- case TAY:
- case TXY:
- setflag(cpu->y[thread] == 0, Z);
- setflag(cpu->y[thread] >> 63, N);
- break;
- case TAX:
- case TYX:
- setflag(cpu->x[thread] == 0, Z);
- setflag(cpu->x[thread] >> 63, N);
- break;
- }
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
break;
case JMP: /* JMP Absolute. */
case JMP_Z: /* JMP Zero Matrix. */
case JMP_IN: /* JMP Indirect. */
cpu->pc[thread] = address;
break;
- case SBC: /* SBC Immediate. */
case SAB: /* Subtract Accumulator with carry by B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case SBC: /* SBC Immediate. */
case SBC_AB: /* SBC Absolute. */
case SBC_Z: /* SBC Zero Matrix. */
- if (opcode == SAB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread]-value-!getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum > value), C);
cpu->a[thread] = sum;
break;
@@ -571,6 +539,7 @@ void *run(void *args) {
tmp = 7;
tmp2 = 0;
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp--;
+ /* Unroll Loop by implementing Duff's Device. */
switch (tmp) {
case 6: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 5: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -580,26 +549,18 @@ void *run(void *args) {
case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
- if (opcode == PLB) {
- cpu->b[thread] = reg;
- } else if (opcode == PLP) {
- cpu->ps = reg;
- } else if (opcode == PLA) {
- cpu->a[thread] = reg;
- } else if (opcode == PLY) {
- cpu->y[thread] = reg;
- } else if (opcode == PLX) {
- cpu->x[thread] = reg;
+ switch (opcode) {
+ case PLA: cpu->a[thread] = reg; break;
+ case PLB: cpu->b[thread] = reg; break;
+ case PLX: cpu->x[thread] = reg; break;
+ case PLY: cpu->y[thread] = reg; break;
+ case PLP: cpu->ps = reg; break;
}
break;
case JSR_IN: /* JSR Indirect. */
case JSR: /* Jump to SubRoutine. */
- switch (addrsize) {
- case 3: stksize = 3; break;
- case 2: stksize = 5; break;
- case 1: stksize = 2; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize];
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (6<<3);
@@ -612,13 +573,11 @@ void *run(void *args) {
}
cpu->pc[thread] = address;
break;
- case AND: /* AND Immediate. */
case ABA: /* bitwise And with Accumulator, and B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case AND: /* AND Immediate. */
case AND_AB: /* AND Absolute. */
case AND_Z: /* AND Zero Matrix. */
- if (opcode == ABA) {
- value = cpu->b[thread];
- }
cpu->a[thread] &= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -644,13 +603,11 @@ void *run(void *args) {
if (!getflag(N))
cpu->pc[thread] = address;
break;
- case ORA: /* ORA Immediate. */
case OAB: /* bitwise Or with Accumulator, and B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ORA: /* ORA Immediate. */
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
- if (opcode == OAB) {
- value = cpu->b[thread];
- }
cpu->a[thread] |= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -663,13 +620,11 @@ void *run(void *args) {
if (getflag(N))
cpu->pc[thread] = address;
break;
- case XOR: /* XOR Immediate. */
case XAB: /* bitwise Xor with Accumulator, and B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case XOR: /* XOR Immediate. */
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
- if (opcode == XAB) {
- value = cpu->b[thread];
- }
cpu->a[thread] ^= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -682,13 +637,11 @@ void *run(void *args) {
if (getflag(C))
cpu->pc[thread] = address;
break;
- case LSL: /* LSL Immediate. */
case LLB: /* Logical shift Left accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case LSL: /* LSL Immediate. */
case LSL_AB: /* LSL Absolute. */
case LSL_Z: /* LSL Zero Matrix. */
- if (opcode == LLB) {
- value = cpu->b[thread];
- }
sum = (value < 64) ? cpu->a[thread] << value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -754,35 +707,43 @@ void *run(void *args) {
break;
}
addr[address] = value & 0xFF;
- #if IO
+ #if (IO || debug) && !branch
if (address == TX_ADDR) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
if (esc) {
- switch(addr[address]) {
+ switch(addr[TX_ADDR]) {
case 'A':
if (y > 0)
y--;
+ #if !debug
wmove(scr, y, x);
+ #endif
esc = 0;
break;
case 'B':
if (y < getmaxy(scr))
y++;
+ #if !debug
wmove(scr, y, x);
+ #endif
esc = 0;
break;
case 'C':
if (x < getmaxx(scr))
x++;
+ #if !debug
wmove(scr, y, x);
+ #endif
esc = 0;
break;
case 'D':
if (x > 0)
x--;
+ #if !debug
wmove(scr, y, x);
+ #endif
esc = 0;
break;
case 'H':
@@ -796,8 +757,14 @@ void *run(void *args) {
} else {
x = ((bcd[1]*10) + bcd[0]);
}
- idx = 3;
+ #if !debug
wmove(scr, y, x);
+ #else
+ updt = 1;
+ mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
+ mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);
+ #endif
+ idx = 3;
bcd[0] = 0;
bcd[1] = 0;
bcd[2] = 0;
@@ -805,11 +772,15 @@ void *run(void *args) {
esc = 0;
break;
case 'S':
+ #if !debug
wscrl(scr, -1);
+ #endif
esc = 0;
break;
case 'T':
+ #if !debug
wscrl(scr, 1);
+ #endif
esc = 0;
break;
case '0':
@@ -829,122 +800,58 @@ void *run(void *args) {
break;
}
} else {
- if (addr[address] == 0xC) {
- x=0,y=0;
- wclear(scr);
- wmove(scr, y, x);
- } else if (addr[address] == 0x15) {
- x=0;
- wclrtoeol(scr);
- wmove(scr, y, x);
- } else if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') {
- if (x > 0) {
- x--;
+ switch (addr[TX_ADDR]) {
+ case 0xC:
+ x=0,y=0;
+ #if !debug
+ wclear(scr);
wmove(scr, y, x);
- }
- wdelch(scr);
- } else if (addr[address] == '\033') {
- esc = 1;
- } else {
- wmove(scr, y, x);
- waddch(scr, addr[address]);
- if (addr[address] == '\n') {
- x = 0;
- y+=1;
- } else {
- x+=1;
- }
- }
- }
- #if keypoll
- pthread_mutex_unlock(&mutex);
- #endif
- }
- #else
- #if !bench
- if (address == TX_ADDR) {
- if (esc) {
- switch(addr[address]) {
- case 'A':
- if (y > 0)
- y--;
- esc = 0;
- break;
- case 'B':
- if (y < getmaxy(scr))
- y++;
- esc = 0;
+ #endif
break;
- case 'C':
- if (x < getmaxx(scr))
- x++;
- esc = 0;
- break;
- case 'D':
- if (x > 0)
+ case CURSES_BACKSPACE:
+ case '\b':
+ if (x > 0) {
x--;
- esc = 0;
- break;
- case 'H':
- if (!bcd[2] && !bcd[3])
- y = 0;
- else
- y = ((bcd[3]*10) + bcd[2]);
- if (!bcd[0] && !bcd[1])
- x = 0;
- else
- x = ((bcd[1]*10) + bcd[0]);
- mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
- mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ }
+ #if !debug
+ wdelch(scr);
+ #else
updt = 1;
- idx = 3;
- bcd[0] = 0;
- bcd[1] = 0;
- bcd[2] = 0;
- bcd[3] = 0;
- esc = 0;
- break;
- case 'S':
- case 'T':
- esc = 0;
+ #endif
break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- bcd[idx--] = (addr[address] - '0');
- break;
- default:
- iscol = (addr[address] == ';');
+ case '\033':
+ esc = 1;
break;
- }
- } else {
- if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') {
- updt = 1;
- if (x > 0) {
- x--;
- }
- } else if (addr[address] == '\033') {
- esc = 1;
- } else {
- updt = (!addr[0x16]);
- if (addr[address] == '\n') {
+ case '\n':
+ #if !debug
+ wmove(scr, y, x);
+ waddch(scr, addr[address]);
+ #else
+ updt = (!addr[0x16]);
+ #endif
x = 0;
y+=1;
- } else {
+ break;
+ default:
+ #if !debug
+ wmove(scr, y, x);
+ waddch(scr, addr[address]);
+ #else
+ updt = (!addr[0x16]);
+ #endif
x+=1;
- }
+ break;
}
}
+ #if keypoll
+ pthread_mutex_unlock(&mutex);
+ #endif
}
#endif
- #endif
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
addr[address+7] = value >> 56;
@@ -963,26 +870,23 @@ void *run(void *args) {
if (!getflag(C))
cpu->pc[thread] = address;
break;
- case LSR: /* LSR Immediate. */
case LRB: /* Logical shift Right accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case LSR: /* LSR Immediate. */
case LSR_AB: /* LSR Absolute. */
case LSR_Z: /* LSR Zero Matrix. */
- if (opcode == LRB) {
- value = cpu->b[thread];
- }
sum = (value < 64) ? cpu->a[thread] >> value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] & 1, C);
cpu->a[thread] = sum;
break;
- case ASR: /* ASR Immediate. */
case ARB: /* Arithmetic shift Right accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ASR: /* ASR Immediate. */
case ASR_AB: /* ASR Absolute. */
case ASR_Z: /* ASR Zero Matrix. */
- if (opcode == ARB)
- value = cpu->b[thread];
- sign = cpu->a[thread] & 0x8000000000000000;
+ sign = cpu->a[thread] >> 63;
sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -1031,6 +935,7 @@ void *run(void *args) {
kbd_rdy = 0;
}
value = addr[address];
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
@@ -1088,13 +993,11 @@ void *run(void *args) {
if (getflag(Z))
cpu->pc[thread] = address;
break;
- case ROL: /* ROL Immediate. */
case RLB: /* Rotate Left accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ROL: /* ROL Immediate. */
case ROL_AB: /* ROL Absolute. */
case ROL_Z: /* ROL Zero Matrix. */
- if (opcode == RLB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread] << value;
sum |= getflag(C);
setflag(sum == 0, Z);
@@ -1107,13 +1010,11 @@ void *run(void *args) {
if (!getflag(Z))
cpu->pc[thread] = address;
break;
- case ROR: /* ROR Immediate. */
case RRB: /* Rotate Right accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ROR: /* ROR Immediate. */
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
- if (opcode == RRB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread] >> value;
sum |= (uint64_t)getflag(C) << (uint64_t)64-value;
setflag(sum == 0, Z);
@@ -1126,18 +1027,16 @@ void *run(void *args) {
if (getflag(V))
cpu->pc[thread] = address;
break;
- case MUL: /* MUL Immediate. */
case MAB: /* Multiply Accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case MUL: /* MUL Immediate. */
case MUL_AB: /* MUL Absolute. */
case MUL_Z: /* MUL Zero Matrix. */
- if (opcode == MAB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread]*value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(!((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))), C);
break;
case BVC: /* BVC Absolute. */
@@ -1165,13 +1064,9 @@ void *run(void *args) {
break;
case RTS: /* ReTurn from Subroutine. */
tmp2 = 0;
- switch (addrsize) {
- case 3: stksize = 3; break;
- case 2: stksize = 5; break;
- case 1: stksize = 2; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize];
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;stksize--;
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -1180,9 +1075,10 @@ void *run(void *args) {
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
break;
+ case CAB: /* Compare Accumulator, and B. */
+ value = cpu->b[thread]; /* Falls Through. */
case CPB: /* CPB Immediate. */
case CMP: /* CMP Immediate. */
- case CAB: /* Compare Accumulator, and B. */
case CPY: /* CPY Immediate. */
case CPX: /* CPX Immediate. */
case CPY_AB: /* CPY Absolute. */
@@ -1201,9 +1097,6 @@ void *run(void *args) {
case CPB_IX: /* CPB Indexed Indirect. */
case CMP_IY: /* CMP Indirect Indexed. */
case CPB_IY: /* CPB Indirect Indexed. */
- if (opcode == CAB) {
- value = cpu->b[thread];
- }
switch (opcode) {
case CPB:
case CPB_AB:
@@ -1238,7 +1131,7 @@ void *run(void *args) {
}
sum = reg-value;
setflag(sum >> 63, N);
- setflag(((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000), V);
+ setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V);
setflag(sum == 0, Z);
setflag(reg >= value, C);
break;
@@ -1265,62 +1158,30 @@ void *run(void *args) {
case INY:
case INX:
switch (opcode) {
- case INC:
- cpu->a[thread]+=1;
- setflag(cpu->a[thread] == 0, Z);
- setflag((cpu->a[thread] >> 63), N);
- break;
- case INB:
- cpu->b[thread]+=1;
- setflag(cpu->b[thread] == 0, Z);
- setflag((cpu->b[thread] >> 63), N);
- break;
- case INY:
- cpu->y[thread]+=1;
- setflag(cpu->y[thread] == 0, Z);
- setflag((cpu->y[thread] >> 63), N);
- break;
- case INX:
- cpu->x[thread]+=1;
- setflag(cpu->x[thread] == 0, Z);
- setflag((cpu->x[thread] >> 63), N);
- break;
+ case INC: cpu->a[thread]+=1; reg = cpu->a[thread]; break;
+ case INB: cpu->b[thread]+=1; reg = cpu->b[thread]; break;
+ case INY: cpu->y[thread]+=1; reg = cpu->y[thread]; break;
+ case INX: cpu->x[thread]+=1; reg = cpu->x[thread]; break;
}
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
break;
case DEC: /* DEC Accumulator. */
case DEB:
case DEY:
case DEX:
switch (opcode) {
- case DEC:
- cpu->a[thread]-=1;
- setflag(cpu->a[thread] == 0, Z);
- setflag((cpu->a[thread] >> 63), N);
- break;
- case DEB:
- cpu->b[thread]-=1;
- setflag(cpu->b[thread] == 0, Z);
- setflag((cpu->b[thread] >> 63), N);
- break;
- case DEY:
- cpu->y[thread]-=1;
- setflag(cpu->y[thread] == 0, Z);
- setflag((cpu->y[thread] >> 63), N);
- break;
- case DEX:
- cpu->x[thread]-=1;
- setflag(cpu->x[thread] == 0, Z);
- setflag((cpu->x[thread] >> 63), N);
- break;
+ case DEC: cpu->a[thread]-=1; reg = cpu->a[thread]; break;
+ case DEB: cpu->b[thread]-=1; reg = cpu->b[thread]; break;
+ case DEY: cpu->y[thread]-=1; reg = cpu->y[thread]; break;
+ case DEX: cpu->x[thread]-=1; reg = cpu->x[thread]; break;
}
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
break;
case JSL: /* Jump to Subroutine Long. */
- switch (addrsize) {
- case 3: stksize = 7; break;
- case 2: stksize = 6; break;
- case 1: stksize = 4; break;
- case 0: stksize = 1; break;
- }
+ stksize = adrsize[addrsize+4];
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (7<<3);cpu->sp[thread]--;
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (6<<3);cpu->sp[thread]--;
@@ -1343,16 +1204,12 @@ void *run(void *args) {
break;
case RTL: /* ReTurn from subroutine Long. */
tmp2 = 1;
- switch (addrsize) {
- case 3: stksize = 7; break;
- case 2: stksize = 6; break;
- case 1: stksize = 4; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize+4];
cpu->sp[thread] += 2;
stksize -= 2;
cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] & 0xFF;
cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8;
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 5: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 4: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -1404,6 +1261,7 @@ void *run(void *args) {
}
ins++;
step = addr[STEP_ADDR];
+ #if !bench
if (step) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
@@ -1411,16 +1269,12 @@ void *run(void *args) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
- #if debug && !bench
+ #if debug
wrefresh(scr);
#endif
}
- if (!addr[CTRL_ADDR])
- kbd_ln = 0;
- else
- kbd_ln = 1;
-
- #if debug && !bench
+ #endif
+ #if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
@@ -1431,8 +1285,7 @@ void *run(void *args) {
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
- #endif
- #if bench
+ #elif bench
if (ins >= BENCH_INST) {
end = 1;
pthread_mutex_lock(&main_mutex);
@@ -1443,7 +1296,7 @@ void *run(void *args) {
pthread_mutex_unlock(&main_mutex);
gettimeofday(&en[thread], 0);
}
- #endif
+ #endif
}
free(s);
}
@@ -1466,7 +1319,7 @@ int main(int argc, char **argv) {
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
-#if !bench
+ #if !bench
if(!scr)
scr = initscr();
nodelay(stdscr, 0);
@@ -1476,13 +1329,15 @@ int main(int argc, char **argv) {
curs_set(1);
werase(scr);
scrollok(scr, 1);
- wrefresh(scr);
start_color();
use_default_colors();
init_pair(1, COLOR_WHITE, -1);
attron(COLOR_PAIR(1) | A_BOLD);
wmove(scr, 0, 0);
-#endif
+ wrefresh(scr);
+ #endif
+ pthread_t therads[THREADS];
+ int result;
for (int i = 0; i < THREADS; i++) {
thr[i].sx.sp[i] = 0xFFFF;
thr[i].sx.stk_st[i] = i+1;
@@ -1514,13 +1369,7 @@ int main(int argc, char **argv) {
| (uint64_t)addr[0xFFC7] << 56;
}
thr[i].th = i;
- }
- pthread_t therads[THREADS];
- int result;
- for (int i = 0; i < THREADS; i++) {
inst[i] = 0;
- }
- for (int i = 0; i < THREADS; i++) {
result = pthread_create(&therads[i], NULL, run, &thr[i]);
assert(!result);
}
@@ -1531,7 +1380,7 @@ int main(int argc, char **argv) {
#endif
while (threads_done < THREADS) {
#if !bench
- int x, y, i = 0;
+ int x, y;
if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) {
if ((c != EOF && c !=-1)) {
pthread_mutex_lock(&main_mutex);
@@ -1542,7 +1391,6 @@ int main(int argc, char **argv) {
c = 0;
step_key = 0;
addr[CTRL_ADDR] = 0;
- kbd_ln = 0;
#if !debug
wrefresh(scr);
#endif
@@ -1562,10 +1410,6 @@ int main(int argc, char **argv) {
switch (c) {
case ERR:
addr[CTRL_ADDR] = 0;
- wmove(scr, getmaxy(scr)-1, 0);
- wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++);
- wmove(scr, y, x);
- wrefresh(scr);
break;
default:
if (kbd_rdy && c < 0x100) {
@@ -1573,13 +1417,11 @@ int main(int argc, char **argv) {
addr[CTRL_ADDR] = 1;
#if debug && !bench
wmove(scr, getmaxy(scr)-1, 0);
- wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++);
+ wprintw(scr, "c: %i, x: %i, y: %i", c, x, y);
wmove(scr, y, x);
wrefresh(scr);
#endif
}
- if (c == '\n')
- kbd_ln = 1;
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
diff --git a/test/fib-new.s b/test/fib-new.s
index 43538a0..ed0aa50 100644
--- a/test/fib-new.s
+++ b/test/fib-new.s
@@ -7,59 +7,57 @@
; Variables for thread 0.
.org $0
x:
- .qword $0
+ .byte $0
y:
- .qword $0
+ .byte $0
z:
- .qword $0
+ .byte $0
; Variables for thread 1.
x2:
- .qword $0
+ .byte $0
y2:
- .qword $0
+ .byte $0
z2:
- .qword $0
+ .byte $0
.org $1000
init:
cps ; Clear the Processor Status register.
-
start:
lda #$0 ; Clear the accumulator.
ldy #$1 ; y=1.
- sty.q y ; Store y into memory.
+ sty y ; Store y into memory.
fib:
ldx #$0 ; x=0.
- ldx.q x ; Output the value of x.
- adc.q y ; Add x with y.
- sta.q z ; z=x+y
- ldy.q y
- sty.q x ; x=y.
- sta.q y ; y=z.
- lda.q x
+ ldx x ; Output the value of x.
+ adc y ; Add x with y.
+ sta z ; z=x+y
+ ldy y
+ sty x ; x=y.
+ sta y ; y=z.
+ lda x
bcs start ; Start all over again, if the carry flag was set.
jmp fib ; Otherwise, keep looping.
.org $2000
init2:
cps ; Clear the Processor Status register.
-
start2:
lda #$0 ; Clear the accumulator.
ldy #$1 ; y2=1.
- sty.q y2 ; Store y into memory.
+ sty y2 ; Store y into memory.
fib2:
ldx #$0 ; x2=0.
- ldx.q x2 ; Output the value of x2.
- adc.q y2 ; Add x2 with y2.
- sta.q z2 ; z2=x2+y2
- ldy.q y2
- sty.q x2 ; x2=y2.
- sta.q y2 ; y2=z2.
- lda.q x2
+ ldx x2 ; Output the value of x2.
+ adc y2 ; Add x2 with y2.
+ sta z2 ; z2=x2+y2
+ ldy y2
+ sty x2 ; x2=y2.
+ sta y2 ; y2=z2.
+ lda x2
bcs start2 ; Start all over again, if the carry flag was set.
jmp fib2 ; Otherwise, keep looping.
diff --git a/test/lex.s b/test/lex.s
new file mode 100644
index 0000000..543a3d8
--- /dev/null
+++ b/test/lex.s
@@ -0,0 +1,40 @@
+; aaaaaaaaaaaaaaaaa
+SYM = $10
+SYM1 = 10
+SYM2 = %00000010
+.org $A000
+; String Literals/Constants.
+tok:
+ .byte "dab"
+msg:
+ .byte "oof, you divided a, and b on me.\n"
+string:
+ .byte "Please, type something.\n"
+string2:
+ .byte "You typed, "
+.org $1000
+lex:
+ .byte $0
+.org $2000
+lex2:
+ .qword lex
+cmd_buf:
+ .word $0
+
+.org $8000
+reset:
+ cps ; cool, and eboc
+ lda #SYM ; nice symbols
+ sta lex ; great label
+ sta (lex2), y ; the pointers are cia niggers
+ sta (lex2, x) ; >mfw pointer to array is accessed as a pointer array
+ sta (lex2) ; normal pointer
+ sta lex, y ; arrays are good
+ sta lex, x ; same with this one
+ sta $1000 ; lol
+ lda.w #cmd_buf+8;
+
+a
+.org $A000
+v
+q
diff --git a/test/reg-transfer.s b/test/reg-transfer.s
index 580020c..abedc5b 100644
--- a/test/reg-transfer.s
+++ b/test/reg-transfer.s
@@ -2,21 +2,18 @@
;
; by mr b0nk 500 <b0nk @b0nk.xyz>
-cps
-inc ; Increment the accumulator.
-tay ; Transfer the accumulator to the y register.
-tax ; Do the same thing, but with the x register.
-jmp $1 ; Loop forever.
-
.org $8000
-cps
-inc ; Increment the accumulator.
-tay ; Transfer the accumulator to the y register.
-tax ; Do the same thing, but with the x register.
-jmp $1 ; Loop forever.
+reset:
+ cps
+bench:
+ inc ; Increment the accumulator.
+ tay ; Transfer the accumulator to the y register.
+ tax ; Do the same thing, but with the x register.
+ tab ;
+ jmp bench ; Loop forever.
-.org $FF50
-.qword $8000
+.org $FFC0
+.qword reset
; Execute the program.
done