summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-04-17 22:07:14 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-04-17 22:07:14 -0400
commit0a7a2a7a8f95730811117bd2aa904f1843f65071 (patch)
tree24d62bbdba0df124c7fe8af781312af993236ebb
parentc5150ee31f07208422f1435de9b35a0d0168cbb5 (diff)
Made both the assembly language monitor, and the
emulator smaller, and faster. I am also starting to make SuBEditor's source code more readable.
-rw-r--r--Makefile1
-rw-r--r--asmmon.c181
-rw-r--r--asmmon.h9
-rw-r--r--lexer.c514
-rw-r--r--opcode.h5
-rw-r--r--programs/subeditor.s290
-rw-r--r--sux.c554
-rw-r--r--test/asr.s4
-rw-r--r--test/fib-new.s1
-rw-r--r--test/fib.s1
-rw-r--r--test/fib2.s37
-rw-r--r--test/nop.s12
-rw-r--r--test/reg-transfer.s1
-rw-r--r--test/subroutine.s1
-rw-r--r--test/test-stack.s15
15 files changed, 898 insertions, 728 deletions
diff --git a/Makefile b/Makefile
index 4aee289..d8ca322 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,6 @@ else
PCC_CFLAGS=
endif
-
CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
OBJS = sux.o asmmon.o lexer.o
OBJS2 = subasm.o subeditor.o
diff --git a/asmmon.c b/asmmon.c
index de4b9a3..b1aead9 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -11,21 +11,24 @@ uint8_t isfixup = 0;
static char tstr[2048];
void viewmem(uint64_t address) {
+ putchar('\n');
printf("\t\t\t");
for (int ind = 0; ind < 0x10; ind++) {
printf("%02X", ind);
- if (ind < 0x0F)
- printf(" ");
+ if (ind < 0x0F) {
+ putchar(' ');
+ }
}
- printf("\n\n");
+ puts("\n");
for (int hi = 0; hi < 0x10; hi++) {
- printf("%016llX:\t", (address & ~0xF)+(hi*0x10));
+ printf("$%016"PRIX64":\t", (address & ~0xF)+(hi*0x10));
for (int lo = 0; lo < 0x10; lo++) {
printf("%02X", addr[(address & ~0xF)+lo+(hi*0x10)]);
- if (lo < 0x0F)
- printf(" ");
+ if (lo < 0x0F) {
+ putchar(' ');
+ }
}
- printf("\n");
+ putchar('\n');
}
}
@@ -38,8 +41,9 @@ void usage() {
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("\tlist, l [$%][start][-][$%][end] [d[ebug], l[inenum], a[ddress]]]");
+ puts("\t\t\t\tLists the currently written program.");
+ puts("\tviewmem, 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).");
@@ -49,11 +53,15 @@ void usage() {
void instinfo(const char *inst) {
for(int i = 0; i < OPNUM; i++) {
- if (!strcasecmp(inst, mne[i])) {
- printf("%s\t%s\n", mne[i], instdesc[i]);
- break;
- } else if (!strcasecmp(inst, "all")) {
- printf("%s\t%s\n", mne[i], instdesc[i]);
+ if (inst[0] == mne[i][0]) {
+ if (!strcasecmp(inst, mne[i])) {
+ printf("%s\t%s\n", mne[i], instdesc[i]);
+ break;
+ }
+ } else if (inst[0] == 'a') {
+ if (!strcasecmp(inst, "all")) {
+ printf("%s\t%s\n", mne[i], instdesc[i]);
+ }
}
}
}
@@ -91,7 +99,7 @@ char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg) {
}
-uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) {
+void 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;
@@ -126,7 +134,7 @@ uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t add
if (ln) {
printf("%u\t", tokline[i].linenum);
} else if (addr) {
- printf("$%llX:\t", tokline[i].addr);
+ printf("$%"PRIX64":\t", tokline[i].addr);
}
spaces = tokline[i].sspace;
tabs = tokline[i].stab;
@@ -172,7 +180,8 @@ uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t add
}
}
if (flags & 0x20) {
- printf("%s", get_symname(tokline[i].sym, 0));
+ printf("%s", symbols[tokline[i].sym]->name);
+ /*get_symname(tokline[i].sym, 0));*/
if (tokline[i].islabel) {
printf(": ");
} else if (tokline[i].issym) {
@@ -193,8 +202,8 @@ uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t add
}
switch (tokline[i].opbase) {
- case BASE_HEX: printf("$%llX", tokline[i].op); break;
- case BASE_DEC: printf("%llu", tokline[i].op); break;
+ case BASE_HEX: printf("$%"PRIX64, tokline[i].op); break;
+ case BASE_DEC: printf("%"PRIu64, tokline[i].op); break;
case BASE_BIN: printf("%%%s", showbits(tokline[i].op, bitnum, dbg)); break;
}
bitnum = 0;
@@ -217,8 +226,8 @@ uint16_t list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t add
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_HEX: printf("$%"PRIX64, tokline[i].aop); break;
+ case BASE_DEC: printf("%"PRIu64, tokline[i].aop); break;
case BASE_BIN: printf("%%%s", showbits(tokline[i].aop, bitnum, dbg)); break;
}
bitnum = 0;
@@ -298,7 +307,7 @@ uint64_t assemble(uint8_t dbg) {
for (; i < lineidx; i++) {
if (dbg) {
- printf("assemble(): i: $%llX\n", i);
+ printf("assemble(): i: $%X\n", i);
}
address = tokline[i].addr;
tmpaddr = address;
@@ -339,7 +348,7 @@ uint64_t assemble(uint8_t dbg) {
printf("%u", rs != 0x00FF);
printf("%u", ins != 0x00FF);
printf("%u", dir != 0x00FF);
- puts("");
+ putchar('\n');
printf("assemble(): ");
printf("flags: $%04X\n", flags);
@@ -354,12 +363,14 @@ uint64_t assemble(uint8_t dbg) {
opsize = 0;
skip = 0;
if ((flags & 0x53) == 0x42) {
- value = use_symbol("", symid, tmpaddr, 1, 0);
+ /*value = use_symbol("", symid, tmpaddr, 1, 0);*/
+ value = symbols[symid]->val;
} else {
value = tokline[i].op;
}
if ((flags & 0x51) == 0x41) {
- value = use_symbol("", symid, tmpaddr, 1, 0);
+ /*value = use_symbol("", symid, tmpaddr, 1, 0);*/
+ value = symbols[symid]->val;
}
if (flags & 0x220) {
switch (cm) {
@@ -368,14 +379,14 @@ uint64_t assemble(uint8_t dbg) {
}
}
if (dbg) {
- printf("assemble(): value: $%llX\n", value);
+ printf("assemble(): value: $%"PRIX64"\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);
+ printf("The Program Counter's origin is now at, $%"PRIX64".\n", value);
}
skip = 1;
break;
@@ -402,7 +413,7 @@ uint64_t assemble(uint8_t dbg) {
if (dbg) {
printf("assemble(): ");
printf("Placed string \"%s\"", string[str]);
- printf(", at address(es) $%llX-$%llX.\n", address, tmpaddr);
+ printf(", at address(es) $%"PRIX64"-$%"PRIX64".\n", address, tmpaddr);
}
} else {
addr[tmpaddr++] = value & 0xFF;
@@ -428,15 +439,15 @@ uint64_t assemble(uint8_t dbg) {
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);
+ printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
+ printf("assemble(): The address that this line ends on is, $%"PRIX64".\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);
+ printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
+ printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
}
continue;
}
@@ -547,11 +558,11 @@ uint64_t assemble(uint8_t dbg) {
}
}
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 address that this line starts at is, $%"PRIX64".\n", address);
+ printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
printf("assemble(): The program size is now at");
- printf(", %llu bytes in decimal", bytecount);
- printf(", and $%llX bytes in hex.\n", bytecount);
+ printf(", %"PRIu64" bytes in decimal", bytecount);
+ printf(", and $%"PRIX64" bytes in hex.\n", bytecount);
}
}
return bytecount;
@@ -567,9 +578,11 @@ int asmmon(const char *fn) {
}
uint8_t done = 0;
uint8_t use_lexer = 1;
- uint64_t address = 0x0000;
+ uint64_t address = 0;
uint64_t bytecount = 0;
- while (!(done & 1)) {
+ uint8_t dbg = 0;
+ init_symbol();
+ while (!done) {
/*char *buf = NULL;*/
char *cmd;
char *arg = malloc(sizeof(char *)*128);
@@ -577,7 +590,9 @@ int asmmon(const char *fn) {
char *lex_line = NULL;
size_t size;
ssize_t line_len;
- done = 0;
+ uint8_t cmds = 0;
+ /* Is shortend command. */
+ uint8_t isshcmd = 0;
if (!strcasecmp(fn, "stdin")) {
line_len = getline(&lex_line, &size, stdin);
} else {
@@ -587,17 +602,28 @@ int asmmon(const char *fn) {
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 {
- if (cmd[0] == 'q' || !strcasecmp(cmd, "quit")) {
+ isshcmd = (cmd[1] == '\0' || cmd[1] == ' ');
+ switch (cmd[0]) {
+ case 'q': cmds = (isshcmd || !strcasecmp(cmd, "quit" )) << 0; break;
+ case 'v': cmds = (isshcmd || !strcasecmp(cmd, "viewmem")) << 1; break;
+ case 'l': cmds = (isshcmd || !strcasecmp(cmd, "list" )) << 2; break;
+ case 'a': cmds = (isshcmd || !strcasecmp(cmd, "asm" )) << 3; break;
+ case 'h': cmds = (isshcmd || !strcasecmp(cmd, "help" )) << 4; break;
+ case 'i': cmds = (isshcmd || !strcasecmp(cmd, "inst" )) << 5; break;
+ case 'd': cmds = (isshcmd || !strcasecmp(cmd, "done" )) << 6; break;
+ case 's': cmds = (isshcmd || !strcasecmp(cmd, "set" )) << 7; break;
+ case ' ':
+ case '\t':
+ cmds = 0xFF;
+ break;
+ }
+ switch (cmds) {
+ case 0x01:
return 2;
- } else if (cmd[0] == 'v' || !strcasecmp(cmd, "viewmem") || !strcasecmp(cmd, "vm")) {
- done |= 4;
+ case 0x02:
viewmem(address);
- } else if (!strcasecmp(cmd, "l") || !strcasecmp(cmd, "list")) {
- done |= 4;
- /*tmp = strtok_r(lex_line, "\n", &tmp);*/
+ break;
+ case 0x04:
if (tmp != NULL) {
uint16_t i = 0;
uint16_t j = 0;
@@ -630,7 +656,7 @@ int asmmon(const char *fn) {
j = 0;
break;
}
- for (; !isspace(tmp[i]) && tmp[i] != '-'; arg[j++] = tmp[i++]);
+ for (; !isspace(tmp[i]) && tmp[i] != '-' && tmp[i] != '\0' && tmp[i] != '\n'; arg[j++] = tmp[i++]);
arg[j] = '\0';
j = 0;
if (base != 0xFF) {
@@ -662,31 +688,56 @@ int asmmon(const char *fn) {
} else {
list(0, 0, 1, 0, 0, 0);
}
- } else if (!strcasecmp(cmd, "asm") || !strcasecmp(cmd, "a")) {
- done |= 4;
+ break;
+ case 0x08:
puts("Assembling program.");
- bytecount = assemble(0);
+ bytecount = assemble(dbg);
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;
+ printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", bytecount, bytecount);
+ break;
+ case 0x10:
usage();
- } else if (!strcasecmp(cmd, "inst") || !strcasecmp(cmd, "i")) {
- done |= 64;
- done |= 6;
- strtok_r(cmd, " \t", &tmp);
+ break;
+ case 0x20:
if (tmp != NULL) {
instinfo(tmp);
} else {
instinfo("all");
}
-
- }
- if (use_lexer) {
- if (!(done & 4)) {
- address = lex(lex_line, address, 0);
+ break;
+ case 0x40:
+ done = 1;
+ break;
+ case 0x80:
+ if (tmp != NULL) {
+ uint16_t i = 0;
+ uint16_t j = 0;
+ uint8_t isdebug = 0;
+ while (tmp[i] != '\0') {
+ if (isspace(tmp[i])) {
+ for (; isspace(tmp[i]); i++);
+ }
+ for (; !isspace(tmp[i]) && tmp[i] != '\0' && tmp[i] != '\n'; arg[j++] = tmp[i++]);
+ arg[j] = '\0';
+ j = 0;
+ isdebug = (arg[j] == 'd' || !strcasecmp(arg, "debug"));
+ if (isdebug) {
+ dbg = !dbg;
+ if (dbg) {
+ puts("Debug mode has been enabled.");
+ } else {
+ puts("Debug mode has been disabled.");
+ }
+ }
+ i++;
+ }
}
- }
+ break;
+ case 0xFF:
+ break;
+ default:
+ address = lex(lex_line, address, dbg);
+ break;
}
}
}
diff --git a/asmmon.h b/asmmon.h
index cc21c14..a126f16 100644
--- a/asmmon.h
+++ b/asmmon.h
@@ -185,26 +185,25 @@ 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;
+struct symbol *symbols[0x1000];
+struct fixup *fixups[0x1000];
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 void init_symbol();
+extern uint16_t 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);
diff --git a/lexer.c b/lexer.c
index 47aea24..3e460d6 100644
--- a/lexer.c
+++ b/lexer.c
@@ -1,21 +1,28 @@
#include "asmmon.h"
-struct symbol *symbols = 0;
-struct fixup *fixups = 0;
+void init_symbol() {
+ uint16_t i = 0;
+ for (; i < 0x1000; i++) {
+ symbols[i] = 0;
+ fixups[i] = 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 sym_count = 0;
+uint16_t mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, uint16_t id, uint8_t dbg) {
uint16_t i = 0;
- uint8_t flag;
- for (s = symbols; s; s = s->nxt) {
+ uint8_t flag = 0;
+ for (; i < sym_count; i++) {
if (useid) {
- flag = id == s->id;
+ flag = id == symbols[i]->id;
} else {
- flag = !strcmp(name, s->name);
+ if (name[0] == symbols[i]->name[0]) {
+ flag = !strcmp(name, symbols[i]->name);
+ }
}
if (flag) {
if (def) {
- if (s->def) {
+ if (symbols[i]->def) {
if (dbg) {
printf("mksymbol(): oof, you cannot redefine the symbol: %s\n", name);
}
@@ -23,74 +30,86 @@ struct symbol *mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t use
} else {
defined = 0;
}
- s->def = def;
- s->val = val;
+ symbols[i]->def = def;
+ symbols[i]->val = val;
+ symbols[i]->id = i;
if (dbg) {
- printf("mksymbol(): def: %u, val: $%016llX, name: %s\n", def, val, name);
+ printf("mksymbol(): def: %u, val: $%016"PRIX64", name: %s\n", def, val, name);
+ printf("mksymbol(): i: $%X, id: $%04X\n", i, symbols[i]->id);
}
+ return symbols[i]->id;
+ } else {
+ return symbols[i]->id;
}
- 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;
+ symbols[i] = malloc(sizeof(*symbols) + strlen(name));
+ symbols[i]->def = def;
+ symbols[i]->val = val;
+ strcpy(symbols[i]->name, name);
+ symbols[i]->id = sym_count++;
defined = 0;
if (dbg) {
- printf("mksymbol(): def: %u, val: $%016llX, name: %s, id: $%04X\n", def, val, name, i);
+ printf("mksymbol(): def: %u, val: $%016"PRIX64", name: %s, id: $%04X\n", def, val, name, sym_count-1);
}
- return s;
+ return sym_count-1;
}
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);
+ uint16_t i;
+ i = mksymbol(name, 0, 0, useid, id, dbg);
+ uint8_t is_defined = (i != 0xFFFF);
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);
+ if (dbg) {
+ puts("use_symbol(): We also got here.");
+ printf("use_symbol(): i: $%X\n", i);
+ }
+ if (symbols[i] != NULL) {
+ if (symbols[i]->def) {
+ return symbols[i]->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.");
}
- puts("does not exist, yet.");
+ return val-1;
}
- return val-1;
}
+ 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);
+ uint16_t i = mksymbol(name, 0, 0, useid, id, dbg);
+ if (symbols[i] != NULL) {
+ if (symbols[i]->def) {
+ symbols[i]->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.");
}
- puts("does not exist, yet.");
+ return 0;
}
- 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;
+ /*struct symbol *s = mksymbol("", 0, 0, 1, id, dbg);*/
+ if (symbols[id]->def) {
+ return symbols[id]->name;
} else {
if (dbg) {
printf("get_symname(): oof, symbol id $%04X, has not been defined, yet.\n", id);
@@ -99,30 +118,35 @@ char *get_symname(uint16_t id, uint8_t dbg) {
}
}
+uint16_t fixup_cnt = 0;
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;
+ uint16_t i = mksymbol(name, 0, 0, 0, 0, dbg);
+ if (dbg) {
+ printf("get_symid(): Symbol ID: $%X, i: $%X.\n", symbols[i]->id, i);
+ }
+ if (symbols[i]->def) {
+ return symbols[i]->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;
+ fixups[fixup_cnt] = malloc(sizeof(*fixups));
+ fixups[fixup_cnt]->adr = val;
+ fixups[fixup_cnt]->ln = ln;
+ fixups[fixup_cnt]->s = symbols[i];
+ fixup_cnt++;
return 0xFFFF;
}
}
-uint16_t get_comment(const char *cmnt, uint8_t dbg) {
+uint16_t get_comment(const char *com, uint8_t dbg) {
uint16_t i = 0;
uint8_t iscom = 0;
for (; i < comidx; i++) {
if (comment[i] != NULL) {
- iscom = !strcmp(cmnt, comment[i]);
+ if (com[0] == comment[i][0]) {
+ iscom = !strcmp(com, comment[i]);
+ }
} else {
break;
}
@@ -138,24 +162,59 @@ uint16_t get_comment(const char *cmnt, uint8_t dbg) {
}
if (i == comidx) {
if (dbg) {
- printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", cmnt);
+ printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", com);
+ }
+ return 0xFFFF;
+ }
+ if (dbg) {
+ printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", com, i);
+ }
+ return i;
+}
+
+uint16_t get_string(const char *str, uint8_t dbg) {
+ uint16_t i = 0;
+ uint8_t isstr = 0;
+ for (; i < stridx; i++) {
+ if (string[i] != NULL) {
+ if (str[0] == string[i][0]) {
+ isstr = !strcmp(str, string[i]);
+ }
+ } else {
+ break;
+ }
+ if (isstr) {
+ break;
+ }
+ }
+ if (string[i] == NULL) {
+ if (dbg) {
+ printf("get_string(): oof, the index $%04X is NULL.\n", i);
+ }
+ return 0xFFFF;
+ }
+ if (i == stridx) {
+ if (dbg) {
+ printf("get_string(): oof, the string \"%s\", was not found in the string table.\n", str);
}
return 0xFFFF;
}
if (dbg) {
- printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", cmnt, i);
+ printf("get_string(): Found string \"%s\", in the table, at index $%04X.\n", str, 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) {
+ for (; fixups[j]; j++) {
+ /*printf("f: $%016"PRIX64", f->nxt: $%016"PRIX64", f->s->name: %s, f->s->val: $%016"PRIX64"\n", &f, &f->nxt, f->s->name, f->s->val);*/
+ if (fixups[j]->s->def) {
+ if (dbg) {
+ printf("reslv_fixups(): Symbol ID: $%X, Symbol Name: %s.\n", fixups[j]->s->id, fixups[j]->s->name);
+ }
+ tokline[fixups[j]->ln].sym = fixups[j]->s->id;
+ /*if (f->ln == 0xFFFF) {
addr[f->adr] = f->s->val & 0xFF;
if (f->s->val & 0xFF00)
addr[f->adr+1] = f->s->val >> 8;
@@ -170,29 +229,25 @@ uint16_t reslv_fixups(uint8_t dbg) {
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);
+ printf("reslv_fixups(): oof, undefined reference to '%s', at $%016"PRIX64".\n", fixups[j]->s->name, fixups[j]->adr);
}
i++;
}
- f = f->nxt;
- j++;
}
return i;
}
-uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
+uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, 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;
@@ -232,10 +287,13 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
return address;
}
if (((flags & 0x53) == 0x42)) {
- if (isfixup && symid == 0xFFFF && (opcodes[mne][IMPL] == 0xFF)) {
+ if (fixup && symid == 0xFFFF && (opcodes[mne][IMPL] == 0xFF)) {
value = address;
+ } else if (opcodes[mne][IMPL] != 0xFF && symid == 0xFFFF) {
+ value = 0;
} else {
value = use_symbol("", symid, address, 1, dbg);
+ /*value = symbols[symid]->val;*/
}
} else {
value = tokline[l].op;
@@ -247,14 +305,14 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
}
}
if (dbg) {
- printf("update_addr(): value: $%llX\n", value);
+ printf("update_addr(): value: $%"PRIX64"\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);
+ printf("Set the Program Counter's Origin to $%"PRIX64".\n", address);
}
break;
case DIR_BYTE:
@@ -359,16 +417,33 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
}
if (dbg) {
printf("update_addr(): ");
- printf("Address: $%llX\n", address);
+ printf("Address: $%"PRIX64"\n", address);
}
return address;
}
+uint16_t find_line(uint16_t ln, uint8_t dbg) {
+ uint16_t i = 0;
+ for (; i < lineidx && tokline[i].linenum != ln; i++);
+ if (tokline[i].linenum == ln) {
+ if (dbg) {
+ printf("find_line(): Found line number %u, at line index %X.\n", ln, i);
+ }
+ }
+ if (dbg) {
+ printf("find_line(): linenum: %u, i: %X\n", tokline[i].linenum, i);
+ }
+ return i;
+}
+
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;
+ uint16_t strid = 0;
+ uint16_t symid = 0;
+ uint16_t line = 0;
lex_type = 0xFF;
uint8_t k = 0;
uint8_t rs = 0;
@@ -382,21 +457,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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;
+ uint8_t done = 0;
while (isdigit(str[i]) && !isspace(str[i])) {
lnum[j++] = str[i++];
@@ -409,7 +470,26 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
} else {
ln = linenum;
}
- uint8_t done = 0;
+ for (; isspace(str[i]); i++);
+ line = find_line(ln, dbg);
+ if (line != lineidx) {
+ address = tokline[line].addr;
+ }
+ tokline[line].dir = 0xFF;
+ tokline[line].mne = 0xFF;
+ tokline[line].rs = 0xFF;
+ tokline[line].am = 0xFF;
+ tokline[line].cm = 0xFF;
+ tokline[line].opbase = 0xFF;
+ tokline[line].aopbase = 0xFF;
+ tokline[line].islabel = 0;
+ tokline[line].issym = 0;
+ tokline[line].str = 0xFFFF;
+ tokline[line].com = 0xFFFF;
+ tokline[line].sym = 0xFFFF;
+ tokline[line].op = 0;
+ tokline[line].aop = 0;
+ tokline[line].addr = address;
while (str[i] != '\0' && str[i] != '\n') {
space = 0;
tab = 0;
@@ -423,10 +503,10 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
printf("lex(): tab: %u, space: %u\n", tab, space);
}
if (isstart) {
- tokline[lineidx].stab = tab;
- tokline[lineidx].sspace = space;
+ tokline[line].stab = tab;
+ tokline[line].sspace = space;
if (dbg) {
- printf("lex(): starting tabs: %u, starting spaces: %u\n", tokline[lineidx].stab, tokline[lineidx].sspace);
+ printf("lex(): starting tabs: %u, starting spaces: %u\n", tokline[line].stab, tokline[line].sspace);
}
}
if (isspace(str[i])) {
@@ -443,12 +523,14 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
lexeme[j] = '\0';
if (!isop) {
for (k = 0; k < 5; k++) {
- if (!strcasecmp(lexeme, dir_t[k])) {
- lex_type = TOK_DIR;
- break;
+ if (tolower(lexeme[0]) == dir_t[k][0]) {
+ if (!strcasecmp(lexeme, dir_t[k])) {
+ lex_type = TOK_DIR;
+ break;
+ }
}
}
- tokline[lineidx].dir = k;
+ tokline[line].dir = k;
} else {
lex_type = TOK_RS;
switch (tolower(lexeme[j-1])) {
@@ -466,7 +548,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
break;
}
address++;
- tokline[lineidx].rs = rs;
+ tokline[line].rs = rs;
isop = 0;
}
break;
@@ -475,21 +557,33 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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]);
+ strid = get_string(lexeme, dbg);
+ if (strid == 0xFFFF) {
+ if (line != lineidx && tokline[line].str != 0xFFFF) {
+ strid = tokline[line].str;
+ } else {
+ strid = stridx;
+ }
+ string[strid] = malloc(j+1);
+ memcpy(string[strid], lexeme, j+1);
+ tokline[line].str = strid;
+ if (dbg) {
+ printf("lex(): str[0x%04X]: %s\n", strid, string[strid]);
+ }
+ stridx += (line == lineidx);
+ } else {
+ tokline[line].str = strid;
+ if (dbg) {
+ printf("lex(): str[0x%04X]: %s\n", strid, string[strid]);
+ }
}
- stridx++;
lex_type = TOK_STRING;
break;
case '#':
lexeme[j] = '#';
lexeme[j+1] = '\0';
lexeme[j+2] = '\0';
- tokline[lineidx].am = IMM;
+ tokline[line].am = IMM;
lex_type = TOK_IMM;
break;
case '$':
@@ -500,27 +594,27 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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;
+ tokline[line].op = strtoull(lexeme, NULL, 16);
+ mksymbol(sym, tokline[line].op, 1, 0, 0, dbg);
+ tokline[line].sym = get_symid(sym, address, line, dbg);
+ isfixup += (tokline[line].sym == 0xFFFF);
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
- tokline[lineidx].opbase = BASE_HEX;
+ tokline[line].opbase = BASE_HEX;
break;
case TOK_PLUS:
case TOK_MINUS:
- tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
- tokline[lineidx].aopbase = BASE_HEX;
+ tokline[line].aop = strtoull(lexeme, NULL, 16);
+ tokline[line].aopbase = BASE_HEX;
break;
default:
- if (tokline[lineidx].cm != 0xFF) {
- tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
- tokline[lineidx].aopbase = BASE_HEX;
+ if (tokline[line].cm != 0xFF) {
+ tokline[line].aop = strtoull(lexeme, NULL, 16);
+ tokline[line].aopbase = BASE_HEX;
} else {
- tokline[lineidx].op = strtoull(lexeme, NULL, 16);
- tokline[lineidx].opbase = BASE_HEX;
+ tokline[line].op = strtoull(lexeme, NULL, 16);
+ tokline[line].opbase = BASE_HEX;
}
break;
@@ -535,27 +629,27 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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;
+ tokline[line].op = strtoull(lexeme, NULL, 2);
+ mksymbol(sym, tokline[line].op, 1, 0, 0, dbg);
+ tokline[line].sym = get_symid(sym, address, line, dbg);
+ isfixup += (tokline[line].sym == 0xFFFF);
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
- tokline[lineidx].opbase = BASE_BIN;
+ tokline[line].opbase = BASE_BIN;
break;
case TOK_PLUS:
case TOK_MINUS:
- tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
- tokline[lineidx].aopbase = BASE_BIN;
+ tokline[line].aop = strtoull(lexeme, NULL, 2);
+ tokline[line].aopbase = BASE_BIN;
break;
default:
if (tokline[lineidx].cm != 0xFF) {
- tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
- tokline[lineidx].aopbase = BASE_BIN;
+ tokline[line].aop = strtoull(lexeme, NULL, 2);
+ tokline[line].aopbase = BASE_BIN;
} else {
- tokline[lineidx].op = strtoull(lexeme, NULL, 2);
- tokline[lineidx].opbase = BASE_BIN;
+ tokline[line].op = strtoull(lexeme, NULL, 2);
+ tokline[line].opbase = BASE_BIN;
}
break;
@@ -565,20 +659,20 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
case '+':
lexeme[j] = '+';
lexeme[j+1] = '\0';
- tokline[lineidx].cm = 0;
+ tokline[line].cm = 0;
lex_type = TOK_PLUS;
break;
case '-':
lexeme[j] = '-';
lexeme[j+1] = '\0';
- tokline[lineidx].cm = 1;
+ tokline[line].cm = 1;
lex_type = TOK_MINUS;
break;
case '(':
lexeme[j] = '(';
lexeme[j+1] = '\0';
lexeme[j+2] = '\0';
- tokline[lineidx].am = IND;
+ tokline[line].am = IND;
break;
case ')':
i++;
@@ -587,9 +681,9 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
while (isspace(str[i])) {
lexeme[j++] = str[i++];
}
- if (tokline[lineidx].am == IND && tolower(str[i]) == 'y') {
+ if (tokline[line].am == IND && tolower(str[i]) == 'y') {
lexeme[j++] = 'y';
- tokline[lineidx].am = INDY;
+ tokline[line].am = INDY;
}
lexeme[j] = '\0';
} else {
@@ -603,18 +697,18 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
while (isspace(str[i])) {
lexeme[j++] = str[i++];
}
- if (tokline[lineidx].am == IND && tolower(str[i]) == 'x') {
- tokline[lineidx].am = INDX;
+ if (tokline[line].am == IND && tolower(str[i]) == 'x') {
+ tokline[line].am = INDX;
lexeme[j++] = 'x';
i++;
} else {
switch (tolower(str[i])) {
case 'x':
- tokline[lineidx].am = ZMX;
+ tokline[line].am = ZMX;
lexeme[j++] = 'x';
break;
case 'y':
- tokline[lineidx].am = ZMY;
+ tokline[line].am = ZMY;
lexeme[j++] = 'y';
break;
}
@@ -626,13 +720,13 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
lexeme[j] = ':';
lexeme[j+1] = '\0';
lex_type = TOK_LABEL;
- tokline[lineidx].islabel = 1;
+ tokline[line].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;
+ tokline[line].sym = get_symid(sym, address, line, dbg);
+ isfixup += (tokline[line].sym == 0xFFFF);
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
@@ -641,7 +735,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
i++;
lexeme[j] = '=';
lexeme[j+1] = 0;
- tokline[lineidx].issym = 1;
+ tokline[line].issym = 1;
lex_type = TOK_SYM;
break;
case ';':
@@ -652,15 +746,20 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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 (line != lineidx && tokline[line].com != 0xFFFF) {
+ comid = tokline[line].com;
+ } else {
+ comid = comidx;
+ }
+ comment[comid] = malloc(j+1);
+ memcpy(comment[comid], lexeme, j+1);
+ tokline[line].com = comid;
if (dbg) {
- printf("lex(): com[0x%04X]: %s\n", comidx, comment[comidx]);
+ printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
}
- comidx++;
+ comidx += (line == lineidx);
} else {
- tokline[lineidx].com = comid;
+ tokline[line].com = comid;
if (dbg) {
printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
}
@@ -697,12 +796,14 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
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 (toupper(lexeme[0]) == mne[k][0]) {
+ if (!strcasecmp(lexeme, mne[k])) {
+ lex_type = TOK_OPCODE;
+ isop = 1;
+ tokline[line].mne = k;
+ address++;
+ break;
+ }
}
}
}
@@ -742,30 +843,30 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
if (num) {
switch (lex_type) {
case TOK_SYM:
- tokline[lineidx].op = strtoull(lexeme, NULL, 10);
- mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ tokline[line].op = strtoull(lexeme, NULL, 10);
+ mksymbol(sym, tokline[line].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;
+ tokline[line].sym = get_symid(sym, address, line, dbg);
+ isfixup += tokline[line].sym == 0xFFFF;
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
- tokline[lineidx].opbase = BASE_DEC;
+ tokline[line].opbase = BASE_DEC;
break;
case TOK_PLUS:
case TOK_MINUS:
- tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
- tokline[lineidx].aopbase = BASE_DEC;
+ tokline[line].aop = strtoull(lexeme, NULL, 10);
+ tokline[line].aopbase = BASE_DEC;
break;
default:
if (tokline[lineidx].cm != 0xFF) {
- tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
- tokline[lineidx].aopbase = BASE_DEC;
+ tokline[line].aop = strtoull(lexeme, NULL, 10);
+ tokline[line].aopbase = BASE_DEC;
} else {
- tokline[lineidx].op = strtoull(lexeme, NULL, 10);
- tokline[lineidx].opbase = BASE_DEC;
+ tokline[line].op = strtoull(lexeme, NULL, 10);
+ tokline[line].opbase = BASE_DEC;
}
break;
@@ -780,8 +881,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t 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;
+ tokline[line].sym = get_symid(lexeme, address, line, dbg);
+ isfixup += tokline[line].sym == 0xFFFF;
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
@@ -826,28 +927,25 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
}
if (lex_type == TOK_COMMENT) {
if (!isstart) {
- tokline[lineidx].etab = tab;
- tokline[lineidx].espace = space;
+ tokline[line].etab = tab;
+ tokline[line].espace = space;
if (dbg) {
- printf("lex(): ending tabs: %u, ending spaces: %u\n", tokline[lineidx].etab, tokline[lineidx].espace);
+ printf("lex(): ending tabs: %u, ending spaces: %u\n", tokline[line].etab, tokline[line].espace);
}
}
}
if (lex_type != TOK_SYM) {
- for (k = 0; lexeme[k] != '\0';) {
- lexeme[k] = 0;
- ++k;
- }
+ memset(lexeme, 0, strlen(lexeme)+1);
lex_type = 0xFF;
}
}
if (i) {
- address = update_addr(address, isfixup, dbg);
+ address = update_addr(address, isfixup, line, dbg);
if (dbg) {
- printf("lex(): Next address: $%llX\n", address);
+ printf("lex(): Next address: $%"PRIX64"\n", address);
printf(
"lex(): "
- "address: $%llX"
+ "address: $%"PRIX64
", dir: %u"
", mne: $%02X"
", rs: %u"
@@ -856,30 +954,32 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
", 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;
+ ", op: $%016"PRIX64
+ ", aop: $%016"PRIX64
+ ", ln: %u\n"
+ , tokline[line].addr
+ , tokline[line].dir
+ , tokline[line].mne
+ , tokline[line].rs
+ , tokline[line].am
+ , tokline[line].cm
+ , tokline[line].opbase
+ , tokline[line].com
+ , tokline[line].sym
+ , tokline[line].op
+ , tokline[line].aop
+ , line);
+ }
+ if (ln > linenum || islinenum) {
+ tokline[line].linenum = ln;
+ if (ln > linenum) {
+ linenum+=(10+(ln & 10));
+ }
} else if (!islinenum) {
- tokline[lineidx].linenum = linenum;
+ tokline[line].linenum = linenum;
linenum += 10;
}
- lineidx++;
+ lineidx += (line == lineidx);
}
return address;
}
diff --git a/opcode.h b/opcode.h
index c92ee67..71cae60 100644
--- a/opcode.h
+++ b/opcode.h
@@ -1,3 +1,4 @@
+#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -195,14 +196,10 @@
#define C ((uint64_t)1 << 0)
#define Z ((uint64_t)1 << 1)
#define I ((uint64_t)1 << 2)
-#define S ((uint64_t)1 << 3)
#define V ((uint64_t)1 << 6)
#define N ((uint64_t)1 << 7)
-struct sux;
-
uint8_t *addr; /* Address Space. */
-uint8_t ibcount; /* Number of bytes taken up by instruction. */
struct sux {
uint64_t ps; /* The processor status register. */
diff --git a/programs/subeditor.s b/programs/subeditor.s
index 5e6ce08..fddc729 100644
--- a/programs/subeditor.s
+++ b/programs/subeditor.s
@@ -3,6 +3,16 @@
; Writen in Sux assembly by
; mr b0nk 500 <b0nk@b0nk.xyz>
+; I/O constants.
+status = $C000 ; Keyboard status.
+scr = $C001 ; Character that is to be printed.
+kbd = $C002 ; Character from the Keyboard.
+step = $C010 ; Enables clock stepping, when set.
+
+; Screen constants.
+maxrow = 23 ; Screen's row count.
+maxcol = 79 ; Screen's column count.
+
.org $A000
; String Literals/Constants.
tok:
@@ -72,27 +82,29 @@ bitabl:
.qword 0
.qword 0
scr_str:
- .byte $0
+ .byte 0
scr_end:
- .byte $0
+ .byte 0
wrapped:
- .byte $0
+ .byte 0
; Pointers
ptr:
- .qword $0
+ .qword 0
ptr2:
- .qword $0
+ .qword 0
ptr3:
- .qword $0
+ .qword 0
ptr4:
- .qword $0
+ .qword 0
ptr5:
- .qword $0
+ .qword 0
ptr6:
- .qword $0
+ .qword 0
scr_ptr3:
- .word $0
+ .word 0
+g:
+ .byte 0
; Main program
.org $8000
@@ -101,8 +113,9 @@ reset:
ldx.w #$FFFF ; Reset the stack pointer.
txs ;
ldy #0 ; Reset the Y register.
+ sty end ;
tyx ; Reset the X register.
- lda #23 ; Set the end of the screen back to 23.
+ lda #maxrow ; Set the end of the screen to the screen's max row count.
sta scr_end ;
lda.w #buffer ; Place the address for the screen buffer
sta.q ptr5 ; into one of the pointers.
@@ -112,6 +125,7 @@ reset:
sta scr_str ; Set the start of the screen back to zero.
sta.q bitabl ; Reset the first half of the linewrap table.
sta.q bitabl+8 ; Reset the second half of the linewrap table.
+ inc end ;
jsl clr_buf ; Clear the screen buffer.
jmp start ; Goto the start of the main program.
clr_buf:
@@ -143,8 +157,7 @@ clr_buf_end:
start:
lda #0 ; TODO: Update this for the Super VIA.
- sta end ;
- sta $C000 ; Clear the controll register of the I/O adapter.
+ sta status ; Clear the controll register of the I/O adapter.
tax ; Reset X.
phy #2 ; Save the cursor index for later.
tay ; Reset the cursor index.
@@ -153,14 +166,15 @@ start:
lda.w #string ; Print the startup message.
jsl print_str ;
lda.w zero ; Reset the Accumulator.
+ sta end ;
jmp read ; Start reading the keyboard.
clr_cbuf:
phb #1 ; Start of callee preservation.
ldb #0 ; Reset the B register.
- lda.w #cmd_buf+8;
- sta.q ptr4 ;
- tba ;
+ lda.w #cmd_buf+8; Place the address of the command buffer, plus eight
+ sta.q ptr4 ; into the fourth pointer.
+ tba ; Set the Accumulator back to zero.
clr_cbuf_st:
cpy.w #$3FF ; Did we clear all of the command buffer?
bcs clr_cbuf_nd ; Yes, so we're done.
@@ -182,7 +196,10 @@ clr_cbuf_nd:
rtl ; End of clr_cbuf.
read:
- lda $C000 ; Did we get a key?
+ lda #0 ; Reset the Accumulator.
+ sta end ; Disable the dummy flag.
+ inc end ; Enable the dummy flag.
+ lda status ; Did we get a key?
beq read ; No, so try again.
jsl getchar ; Yes, and was it a newline?
beq parse ; Yes, so start parsing the line.
@@ -194,17 +211,16 @@ print_str:
tba ; Clear the Accumulator.
inb ; Enable replace mode.
stb b ;
-pntstr_st:
+pntstr_lp:
phy #2 ; Save the cursor index.
txy ; Copy the string index into Y.
- lda (ptr), y ; Are we at the end of the string?
- beq pntstr_end ; Yes, so we're done.
- ply #2 ; No, so get the cursor index back.
- inx ; Increment the string index.
+ lda (ptr), y ; Are we at the end of the string?
+ ply #2 ; Get the cursor index back.
+ beq pntstr_end ; Yes, so we're done.
+ inx ; No, so increment the string index.
jsl print_char ; Print the character.
- jmp pntstr_st ; Keep looping.
+ jmp pntstr_lp ; Keep looping.
pntstr_end:
- ply #2 ; Get the cursor index back.
ldb #0 ; Enable insert mode.
stb b ;
rtl ; End of print_str.
@@ -265,67 +281,80 @@ bitpos:
rtl ; End of bitpos.
getchar:
- lda $C002 ; Get typed character.
- ldb #0 ;
- stb e ;
- stb b ;
- pha #1 ;
- phy #2 ;
- cmp #10 ;
- beq cmd_cpy ;
+ lda kbd ; Get the character that was typed from the keyboard.
+ ldb #0 ; Reset the B register.
+ stb e ; Set the temporary row position to zero, in case we get a newline.
+ stb b ; Enable insert mode.
+ pha #1 ; Save the character.
+ phy #2 ; Save the cursor index.
+ cmp #10 ; Was the character that was typed, a newline?
+ beq cmd_cpy ; Yes, so start copying the line to the command buffer.
getchar_pnt:
- ply #2 ;
- pla #1 ;
- ldb e ;
- bne reset_row ;
+ ply #2 ; Get back the cursor index.
+ pla #1 ; Get back the character.
+ ldb e ; Is the temporary row position non zero?
+ bne reset_row ; Yes, so reset the row positon.
getchar_pt1:
- jsl print_char ;
- lda a ;
- cmp #10 ;
- beq getchar_ln ;
- jmp getchar_chr ;
+ jsl print_char ; No, so print the character.
+ lda a ; Get the return value.
+ cmp #10 ; Is the return value, a newline?
+ beq getchar_ln ; Yes, so return 0.
+ jmp getchar_chr ; No, so return 1.
reset_row:
- ldb e ;
- cpb #23 ;
- beq reset_row2 ;
- bcs reset_row1 ;
- jmp reset_row2 ;
+ ldb e ; Get the temporary row position.
+ cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen?
+ beq reset_row2 ; Yes, so leave it as is.
+ bcs reset_row1 ; No, so set it to the bottom of the screen.
+ jmp reset_row2 ; Yes, so leave it as is.
reset_row1:
- ldb #23 ;
+ ldb #maxrow ; Set the row position to the bottom of the screen.
reset_row2:
- stb scr_row ;
- jmp getchar_pt1 ;
-
+ stb scr_row ; Set the row position.
+ jmp getchar_pt1 ; Print the character.
cmd_cpy:
- lda scr_row ;
- sta scr_trow ;
- jsl findend ;
- sta scr_row ;
- sta e ;
- jsl findst ;
- clc ;
- lda scr_row ;
- adc scr_str ;
- mul #80 ;
- tay ;
- ldx.w #$0 ;
-cmd_cpy_st:
- lda (ptr5), y ;
- beq getchar_pnt ;
- phy #2 ;
- txy ;
- sta (ptr6), y ;
- inx ;
- ply #2 ;
- iny ;
- jmp cmd_cpy_st ;
+ lda scr_row ; Get the row position.
+ sta scr_trow ; Save it for later.
+ jsl findend ; Find the end of the line.
+ sta scr_row ; Set the row position to the end of the line.
+ sta e ; Save it into the temporary row posiition.
+ jsl findst ; Find the start of the line.
+ clc ; Clear the carry flag.
+ lda scr_row ; Get the row position.
+ adc scr_str ; Add it with the screen's starting row.
+ mul #maxcol+1 ; Multiply it with the width of the screen, plus one.
+ tay ; Place it into the index.
+ ldx.w #0 ; Reset the X register.
+cmd_cpy_lp:
+ ldb #0 ; Reset the B register.
+ lda.q (ptr5), y ; Get eight bytes from the current line.
+cmd_cpy_lp1:
+ phy #2 ; Save the screen index.
+ txy ; Get the command buffer index.
+ sta (ptr6), y ; Copy one byte from the screen buffer, to the command buffer.
+ inx ; Increment the command buffer index.
+ ply #2 ; Get back the screen index.
+ iny ; Increment the screen index.
+ inb ; Increment the byte count.
+ lsr #8 ; Shift in the next byte.
+ stb g ; Save the byte count.
+ tab ; Save the string buffer.
+ and #$FF ; Is this byte of the buffer, a null terminator?
+ beq cmd_cpy_nd ; Yes, so we're done.
+ tba ; No so get back the string buffer.
+ ldb g ; Get back the byte count.
+ cpb #7 ; Did we shift in eight bytes?
+ beq cmd_cpy_lp ; Yes, so get eight more bytes.
+ jmp cmd_cpy_lp1 ; No, so keep shifting in more bytes.
+cmd_cpy_nd:
+ tab ; The B register is zero, so clear the Accumulator.
+ jmp getchar_pnt ; Go back to printing the character.
getchar_ln:
- lda #0 ;
- jmp getchar_end ;
+ lda #0 ; Return zero.
+ jmp getchar_end ; We are done.
getchar_chr:
- lda #1 ;
+ lda #1 ; Return one.
getchar_end:
- rtl ;
+ rtl ; End of get char.
findst:
lda #0 ;
@@ -358,7 +387,7 @@ fndend_done:
findend:
jsl fndend ;
lda.w scr_ptr3 ;
- div #80 ;
+ div #maxcol+1 ;
rtl ;
parse:
@@ -374,7 +403,7 @@ print_char:
sta a ;
cmp #$1B ;
beq esc ;
- cmp #$A ;
+ cmp #10 ;
beq nl ; Did the user type a newline?
cmp #$C ;
beq clr_scr ;
@@ -444,32 +473,33 @@ printc_2:
ldb #1 ;
stb f ;
ldb scr_col ;
- cpb #80 ;
+ cpb #maxcol+1 ;
bcs printc_4 ;
printc_3:
- sta $C001 ; Echo typed character.
+ sta scr ; Echo typed character.
ldb f ;
beq printc_wrap ;
jmp printc_end ;
printc_4:
ldb scr_row ;
- cpb #23 ;
+ cpb #maxrow ;
bcs printc_scrl ;
printc_5:
ldb #0 ;
stb f ;
jmp printc_3 ;
printc_scrl:
- sta $C001 ; Echo typed character.
+ sta scr ; Echo typed character.
clc ;
lda #1 ;
sta wrapped ;
jsl scrl_down ;
+ jmp printc_wrap ;
printc_wrap:
- ldb #0 ;
+ ldb #0
stb scr_col ;
ldb scr_row ;
- cpb #23 ;
+ cpb #maxrow ;
bcs printc_wrp2 ;
printc_wrap1:
inc scr_row ;
@@ -493,7 +523,7 @@ nl:
nl1:
sta scr_col ;
lda scr_row ;
- cmp #23 ;
+ cmp #maxrow ;
bcc nl_inc ;
jsl scrl_down ;
lda #10 ;
@@ -507,7 +537,7 @@ nl_inc:
jmp printc_end ;
clr_scr:
- lda #23 ;
+ lda #maxrow ;
sta scr_end ;
lda #0 ;
sta scr_str ;
@@ -521,25 +551,25 @@ clr_scr:
sta scr_row ;
jsl update_pos ;
lda #$C ;
- sta $C001 ;
+ sta scr ;
jmp printc_end ;
en_step:
- lda $C010 ;
+ lda step ;
beq step_en ;
jmp printc_end ;
step_en:
lda #1 ;
- sta $C010 ;
+ sta step ;
jmp printc_end ;
dis_step:
- lda $C010 ;
+ lda step ;
bne step_dis ;
jmp printc_end ;
step_dis:
lda #0 ;
- sta $C010 ;
+ sta step ;
jmp printc_end ;
back:
@@ -566,7 +596,7 @@ back1:
stb d ;
jsl shftln ; Shift line back by one character.
lda #$7F ; Print a backspace to the screen.
- sta $C001 ;
+ sta scr ;
lda e ;
beq back3 ;
back2:
@@ -617,7 +647,7 @@ backwrp:
backwrp2:
dec scr_row ; Move up by one row.
; jsl clrbit ; Clear the wrap bit for this row.
- ldb #80 ; Move the cursor to the absolute right of the screen.
+ ldb #maxcol+1 ; Move the cursor to the absolute right of the screen.
stb scr_col ;
jsl update_pos ; Update the cursor's position.
jmp back ; Delete the previous character.
@@ -691,9 +721,9 @@ shftln_nd1:
shftln_end1:
jsl findend ; Find the ending line.
cpb #0 ; Is the remainder zero?
- beq shftln_nd01 ; Yes, so check if the ending line is greater than the starting line.
+ beq shftln_nd2 ; Yes, so check if the ending line is greater than the starting line.
jmp shftln_end2 ; No, so we're done.
-shftln_nd01:
+shftln_nd2:
cmp scr_row ; Is the ending line greater than the starting line?
beq shftln_end2 ; No, so we're done.
bcs shftln_wrp1 ; Yes, so clear the wrap bit.
@@ -701,13 +731,13 @@ shftln_end2:
rtl ; End of shftln.
esc:
- lda $C000 ; Get the next character.
- lda $C002 ;
+ lda status ; Get the next character.
+ lda kbd ;
cmp #$1B ; Is this character an escape character?
beq shftesc ; Yes, so check the other set of escape routines.
- lda $C000 ; No, so wait for the next character.
+ lda status ; No, so wait for the next character.
beq printc_end ; We have an error, so discard it, and go back to getting user input.
- lda $C002 ; Get the escape code.
+ lda kbd ; Get the escape code.
sta c ; Store the escape code, until we need it.
lda #0 ; Set the D pseudo register to zero.
sta d ;
@@ -728,10 +758,11 @@ esc_end:
jmp printc_end ; We are done.
shftesc:
- lda $C000 ; Skip the '['.
- lda $C000 ; Get the next character.
+ lda status ; Skip the '['.
+ lda kbd ;
+ lda status ; Wait for the next character.
beq printc_end ; We have an error, so discard it, and go back to getting user input.
- lda $C002 ; Get the escape code.
+ lda kbd ; Get the escape code.
sta c ; Store the escape code, until we need it.
lda #0 ; Use the D pseudo register as a skip flag.
sta d ;
@@ -769,7 +800,7 @@ isdown:
cmp #$42 ; Did the user press the down arrow key?
bne isdown_done ; No, so we're done.
lda scr_row ; Yes, so start checking the y coordinate of the cursor.
- cmp #23 ; Is the cursor at the bottom of the screen?
+ cmp #maxrow ; Is the cursor at the bottom of the screen?
beq isdown_scrl ; Yes, so scroll down.
lda c ; No, so load the escape code back into the accumulator.
cmp #$42 ; Did the user press the down arrow key?
@@ -795,7 +826,7 @@ isright:
cmp #$43 ; Did the user press the right arrow key?
bne isright_dne ; No, so we're done.
lda scr_col ; Yes, so start checking the x coordinate of the cursor.
- cmp #79 ; Is the cursor at the far right of the screen?
+ cmp #maxcol ; Is the cursor at the far right of the screen?
beq isright_wrp ; Yes, so check if this is a wrapped line.
jmp right ; No, so move the cursor right, like normal.
isright_wrp:
@@ -815,7 +846,7 @@ wrap_inc:
lda #0 ; Set the cursor to the far left of the screen.
sta scr_col ;
lda scr_row ; Get the current row number.
- cmp #23 ; Are we at the bottom of the screen?
+ cmp #maxrow ; Are we at the bottom of the screen?
beq isright_nd2 ; No, so we're done.
bcs isright_scr ; Yes, so check if we are scrolling down.
jmp isright_nd2 ; No, so we're done.
@@ -849,7 +880,7 @@ wrap_dec:
sta wrapped ;
dec scr_row ; Move the cursor up one line.
wrap_dec1:
- lda #79 ; Move the Cursor to the far right of the screen.
+ lda #maxcol ; Move the Cursor to the far right of the screen.
sta scr_col ;
lda #1 ; Tell the escape routine that we were successful.
sta d ;
@@ -937,58 +968,52 @@ update_pos:
lda scr_row ; Add the cursor's line number,
adc scr_str ; with the starting line number to get the absolute line number.
tay ; Place it in the Y regster for now.
- clc ; Clear the carry flag.
- lsl #6 ; Multiply the absolute line number by 64.
- tab ; Use it as a second operand.
- tya ; Place the absolute line number back into the Accumulator
- lsl #4 ; Multiply the absolute line number by 16.
- aab ; Add both the Accumulator, and the B register together, to multiply the line number by 80.
- clc ; Clear the carry flag.
+ mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1.
adc scr_col ; Add the cursor's column number to get the screen index.
tay ; Place the index into the Y register.
lda #$1B ; Print an escape character
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
lda #$5B ; Print '['
- sta $C001 ; to the screen, and start the escape sequence.
+ sta scr ; to the screen, and start the escape sequence.
jsl getrow ; Start printing the row number to the screen.
jsl getcol ; Start printing the column number to the screen.
lda #$48 ; Print 'H'
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
rtl ; End of update_pos.
getrow:
lda scr_row ; Get the cursor's y coordinate.
div #10 ; Divide A by 10.
adc #$30 ; Convert it to ascii, and
- sta $C001 ; print to the screen.
+ sta scr ; print to the screen.
tba ; Get the remainder.
adc #$30 ; Convert it to ascii, and
- sta $C001 ; print to the screen.
+ sta scr ; print to the screen.
rtl ; End of getrow.
getcol:
lda #$3B ; Print ';'
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
lda scr_col ; Get the cursor's x coordinate.
div #10 ; Divide A by 10.
clc
adc #$30 ; Convert it to ascii, and
- sta $C001 ; print to the screen.
+ sta scr ; print to the screen.
tba ; Get the remainder.
clc
adc #$30 ; Convert it to ascii, and
- sta $C001 ; print to the screen.
+ sta scr ; print to the screen.
rtl ; End of getrow.
scrl_down:
inc scr_str ; Increment the starting line of the screen.
inc scr_end ; Increment the ending line of the screen.
lda #$1B ; Print an escape character
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
lda #$5B ; Print '['
- sta $C001 ; to the screen, and start the escape sequence.
+ sta scr ; to the screen, and start the escape sequence.
lda #$54 ; Print 'T'
- sta $C001 ; to the screen, and end the escape sequence.
+ sta scr ; to the screen, and end the escape sequence.
lda scr_row ; Get the cursor's line number.
pha #1 ; Save it in the stack.
lda wrapped ; Was the wrapped flag set?
@@ -1018,11 +1043,11 @@ scrl_up:
dec scr_str ;
dec scr_end ;
lda #$1B ; Print an escape character
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
lda #$5B ; Print '['
- sta $C001 ; to the screen, and start the escape sequence.
+ sta scr ; to the screen, and start the escape sequence.
lda #$53 ; Print 'S'
- sta $C001 ; to the screen, and end the escape sequence.
+ sta scr ; to the screen, and end the escape sequence.
lda scr_row ;
pha #1 ;
lda scr_col ;
@@ -1045,7 +1070,7 @@ rdrw_row:
rdrow_st:
lda (ptr5), y ;
beq rdrow_inc ;
- sta $C001 ;
+ sta scr ;
rdrow_inc:
inc scr_col ;
lda (ptr5), y ;
@@ -1054,12 +1079,12 @@ rdrow_inc1:
iny ;
rdrow_inc2:
lda scr_col ;
- cmp #80 ;
+ cmp #maxcol+1 ;
bcs rdrow_end ;
jmp rdrow_st ;
rdrow_skip:
lda #$20 ;
- sta $C001 ; to the screen.
+ sta scr ; to the screen.
jmp rdrow_inc1 ;
rdrow_end:
lda #0 ;
@@ -1080,7 +1105,7 @@ rset_x:
dabbed:
ldb #0 ;
lda.w #tok ;
- sta.q ptr2 ;
+ sta.q ptr2 ;i
tba ;
dab_st:
phy #2 ;
@@ -1124,7 +1149,6 @@ cmd_clr:
rdrw_ln:
lda scr_row ;
pha #1 ;
- inc end ;
lda f ;
sta scr_row ;
lda scr_col ;
@@ -1149,13 +1173,11 @@ rdrwln_done:
lda #0 ;
sta e ;
sta f ;
- dec end ;
rtl ;
.org $FFC0
.qword reset
-
a
done
diff --git a/sux.c b/sux.c
index 6c9442f..4dffc37 100644
--- a/sux.c
+++ b/sux.c
@@ -6,6 +6,7 @@
#define bench 0
#define debug 0
#define IO 1
+#define getclk 0
#define keypoll 0
#if bench
#include <sys/time.h>
@@ -14,7 +15,7 @@
#endif
#define THREADS 1
-#define BENCH_INST 100000000 << THREADS-1
+#define BENCH_INST 100000000 << (THREADS-1)
#define CTRL_ADDR 0xC000
#define TX_ADDR 0xC001
#define RX_ADDR 0xC002
@@ -24,13 +25,16 @@
#define setflag(flag, bit) ((flag)) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3)))
#define getflag(bit) (cpu->ps & (bit << (thread << 3)))
+#if getclk
uint64_t clk[THREADS]; /* Per Thread Clock cycles. */
uint64_t tclk; /* Total Clock cycles. */
+#endif
+
+const uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */
uint64_t inst[THREADS];
uint64_t inss;
uint8_t threads_done = 0;
uint8_t kbd_rdy = 0;
-uint8_t wai = 0;
uint8_t step = 0;
uint8_t irq = 0;
@@ -58,23 +62,19 @@ void *run(void *args) {
struct sux *cpu = &thr->sx;
uint8_t thread = thr->th;
uint64_t address = 0;
- uint64_t tmpaddr = 0;
uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t end = 0;
- uint8_t stksize;
uint64_t sum = 0;
uint64_t value = 0;
uint64_t reg = 0;
+ #if getclk
uint64_t iclk = 0;
+ #endif
uint64_t ins = 0;
uint64_t sign = 0;
- uint8_t addrsize;
- uint8_t rs;
- uint8_t regsize;
uint8_t tmp;
uint8_t tmp2;
- char *s = malloc(2048);
#if !bench
uint8_t lines = (6*thread)+2;
uint8_t bcd[4];
@@ -82,13 +82,15 @@ void *run(void *args) {
int x = 0, y = 0;
uint8_t esc = 0;
#endif
- uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */
#if bench
gettimeofday(&str[thread], 0);
#endif
#if debug && !bench
uint8_t scr_row = 0xFF, scr_col = 0xFF;
uint8_t updt = 0;
+ uint64_t tmpaddr = 0;
+ addr[STEP_ADDR] = 1;
+ step = 1;
#if keypoll
pthread_mutex_lock(&mutex);
#endif
@@ -99,37 +101,13 @@ void *run(void *args) {
#endif
while (!end) {
address = 0;
- if (wai) {
- for (int8_t i = 56; i >= 0; i-=8) {
- if (i)
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 >> i;
- else
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 & 0xFF;
- cpu->sp[thread]--;
- }
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread;
- cpu->sp[thread]--;
- setflag(1, I);
- cpu->pc[thread] = (uint64_t)addr[0xFFA0]
- | (uint64_t)addr[0xFFA1] << 8
- | (uint64_t)addr[0xFFA2] << 16
- | (uint64_t)addr[0xFFA3] << 24
- | (uint64_t)addr[0xFFA4] << 32
- | (uint64_t)addr[0xFFA5] << 40
- | (uint64_t)addr[0xFFA6] << 48
- | (uint64_t)addr[0xFFA7] << 56;
- wai = 0;
- kbd_rdy &= (uint8_t)~(1 << thread);
- }
prefix = addr[cpu->pc[thread]];
- if ((prefix & 0x03) == 0x03)
- cpu->pc[thread]++;
- else
+ if ((prefix & 0x03) != 0x03) {
prefix = 0;
+ }
+ cpu->pc[thread] += ((prefix & 0x03) == 0x03);
opcode = addr[cpu->pc[thread]];
-
-
- #if debug && !bench
+ #if debug && !bench
if (lines > 24*(thread+1)) {
lines = (24*thread)+2;
}
@@ -139,11 +117,11 @@ void *run(void *args) {
wmove(scr, lines, 0);
wclrtoeol(scr);
wprintw(scr,
- "pc: $%08llX"
- ", a: $%016llX"
- ", b: $%016llX"
- ", x: $%016llX"
- ", y: $%016llX"
+ "pc: $%04"PRIX64
+ ", a: $%016"PRIX64
+ ", b: $%016"PRIX64
+ ", x: $%016"PRIX64
+ ", y: $%016"PRIX64
, cpu->pc[thread]
, cpu->a[thread]
, cpu->b[thread]
@@ -151,28 +129,23 @@ void *run(void *args) {
, cpu->y[thread]);
wprintw(scr,
", sp: $%04X"
- ", ps: $%04X"
- ", prefix: $%02x"
- ", opcode: $%02x"
+ ", ps: $%02"PRIX64
+ /*", prefix: $%02X"
+ ", opcode: $%02X"*/
", inst: "
, cpu->sp[thread]
- , cpu->ps
- , prefix
- , opcode);
+ , cpu->ps);
+ /*, prefix
+ , opcode);*/
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
- #endif
-
- addrsize = (prefix & 0x0C) >> 2;
- rs = (prefix & 0x30) >> 4;
- if (rs)
- regsize = (1 << rs);
- else
- regsize = 1;
+ #endif
address = cpu->pc[thread];
- cpu->pc[thread]++;
- iclk++;
+ ++cpu->pc[thread];
+ #if getclk
+ ++iclk;
+ #endif
switch (optype[opcode]) {
case IMPL:
break;
@@ -198,11 +171,11 @@ void *run(void *args) {
case ASR:
case ENT:
address = cpu->pc[thread];
- cpu->pc[thread]+=1;
+ ++cpu->pc[thread];
break;
default:
address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
+ cpu->pc[thread]+=(1 << (prefix >> 4));
break;
}
break;
@@ -215,37 +188,44 @@ void *run(void *args) {
tmp = 0;
address = addr[cpu->pc[thread]];
/* Unroll Loop by implementing Duff's Device. */
- switch (addrsize) {
+ switch ((prefix & 0x0C) >> 2) {
case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
- tmp+=2;
+ address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
case 3:
- address |= addr[cpu->pc[thread]+3] << 24;
- tmp+=1;
+ address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;++tmp;
case 1:
- address |= addr[cpu->pc[thread]+2] << 16;
- address |= addr[cpu->pc[thread]+1] << 8;
- tmp+=2;
+ address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+1] << 8;++tmp;
case 0:
- tmp+=1;
+ ++tmp;
}
cpu->pc[thread]+=tmp;
+ #if debug && !bench
tmpaddr = address;
+ #endif
+ #if getclk
iclk++;
+ #endif
reg = 0;
switch (optype[opcode]) {
case ZMX:
address += cpu->x[thread];
+ #if getclk
iclk++;
+ #endif
break;
case ZMY:
address += cpu->y[thread];
+ #if getclk
iclk++;
+ #endif
break;
case INDX:
address += cpu->x[thread];
+ #if getclk
iclk++;
+ #endif
/* Falls Through. */
case INDY:
/* Did we fall through? */
@@ -253,19 +233,23 @@ void *run(void *args) {
reg = 0; /* Yes, so set reg back to zero. */
} else {
reg = cpu->y[thread]; /* No, so set reg to Y. */
+ #if getclk
iclk++;
+ #endif
}
/* 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];
+ value += (uint64_t)addr[address+1] << 8;
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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;
+ #if getclk
iclk++;
+ #endif
value += reg;
address = value;
value = 0;
@@ -275,25 +259,23 @@ void *run(void *args) {
break;
case ABS:
tmp = 0;
- address = addr[cpu->pc[thread]];
+ address = addr[cpu->pc[thread]];++tmp;
/* Unroll Loop by implementing Duff's Device. */
- switch (addrsize) {
+ switch ((prefix & 0x0C) >> 2) {
case 3:
- address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;
- tmp+=1;
+ address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;++tmp;
case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- tmp+=2;
+ address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
+ #if getclk
iclk++;
+ #endif
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;
- tmp+=3;
+ address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;++tmp;
case 0:
- address |= addr[cpu->pc[thread]+1] << 8;
- tmp+=2;
+ address |= (uint64_t)addr[cpu->pc[thread]+1] << 8;++tmp;
}
cpu->pc[thread]+=tmp;
break;
@@ -301,17 +283,17 @@ void *run(void *args) {
}
value = addr[address];
/* Unroll Loop by implementing Duff's Device. */
- switch (regsize) {
+ switch (1 << (prefix >> 4)) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
value |= (uint64_t)addr[address+6] << 48;
value |= (uint64_t)addr[address+5] << 40;
value |= (uint64_t)addr[address+4] << 32;
case 4:
- value |= addr[address+3] << 24;
- value |= addr[address+2] << 16;
+ value |= (uint64_t)addr[address+3] << 24;
+ value |= (uint64_t)addr[address+2] << 16;
case 2:
- value |= addr[address+1] << 8;
+ value |= (uint64_t)addr[address+1] << 8;
}
#if debug && !bench
#if keypoll
@@ -323,7 +305,7 @@ void *run(void *args) {
op[1] = opname[opcode][1];
op[2] = opname[opcode][2];
op[3] = '\0';
- switch(regsize) {
+ switch(1 << (prefix >> 4)) {
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;
@@ -332,11 +314,11 @@ void *run(void *args) {
switch (optype[opcode]) {
case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
case IMM:
- switch(regsize) {
+ switch(1 << (prefix >> 4)) {
case 1: wprintw(scr, "%s #$%02X\r" , op, value); break;
case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break;
case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break;
- case 8: wprintw(scr, "%s%s #$%016llX\r" , op, postfix, value); break;
+ case 8: wprintw(scr, "%s%s #$%016"PRIX64"\r" , op, postfix, value); break;
}
break;
case ZM:
@@ -346,9 +328,9 @@ void *run(void *args) {
case ZMX: tmpaddr = address - cpu->x[thread]; break;
case ZMY: tmpaddr = address - cpu->y[thread]; break;
}
- switch (addrsize) {
+ switch ((prefix & 0x0C) >> 2) {
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;
+ case 2: wprintw(scr, "%s%s $%014"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
}
@@ -356,30 +338,33 @@ void *run(void *args) {
case IND:
case INDX:
case INDY:
- switch (addrsize) {
+ switch ((prefix & 0x0C) >> 2) {
case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 2: wprintw(scr, "%s%s ($%012llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 2: wprintw(scr, "%s%s ($%012"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
}
break;
case ABS:
tmpaddr = address;
- switch (addrsize) {
- case 3: wprintw(scr, "%s%s $%016llX\r" , op, postfix, tmpaddr); break;
- case 2: wprintw(scr, "%s%s $%014llX\r" , op, postfix, tmpaddr); break;
- case 1: wprintw(scr, "%s%s $%010llX\r" , op, postfix, tmpaddr); break;
- case 0: wprintw(scr, "%s%s $%04X\r" , op, postfix, tmpaddr ); break;
+ switch ((prefix & 0x0C) >> 2) {
+ case 3: wprintw(scr, "%s%s $%016"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 2: wprintw(scr, "%s%s $%014"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 1: wprintw(scr, "%s%s $%010"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 0: wprintw(scr, "%s%s $%04" PRIX64"\r" , op, postfix, tmpaddr); break;
}
break;
}
- mvwprintw(scr, 27, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]);
- mvwprintw(scr, 28, 0, "scr_ptr3: %04X\r", (addr[0x5C] << 8) | addr[0x5B]);
- mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x28], addr[0x29]);
- mvwprintw(scr, 32, 0, "bitabl: %02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\r"
- , addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D], addr[0x1E], addr[0x1F]
- , addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25], addr[0x26], addr[0x27]);
+
+ if (updt) {
+ mvwprintw(scr, 27, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]);
+ mvwprintw(scr, 28, 0, "scr_ptr3: $%04X", (addr[0x5C] << 8) | addr[0x5B]);
+ mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x28], addr[0x29]);
+ mvwprintw(scr, 32, 0, "bitabl: %02X %02X %02X %02X %02X %02X %02X %02X "
+ "%02x %02x %02x %02x %02x %02x %02x %02x\r"
+ , addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D], addr[0x1E], addr[0x1F]
+ , addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25], addr[0x26], addr[0x27]);
+ }
uint8_t ln = 33;
uint16_t line_idx = 0;
uint16_t tmpad = 0x2000;
@@ -414,17 +399,17 @@ void *run(void *args) {
}
updt = 0;
}
- /*tmpad = 0x4000;
+ /*ln = 45;
+ tmpad = 0x4000;
line_idx = 0;
mvwprintw(scr, ln++, 0, "cmd_buf:\r");
- for (uint8_t i = 0; i < 20; i++) {
- wmove(scr, ln);
+ for (uint8_t i = 0; i < 5; i++) {
+ wmove(scr, ln++, 0);
line_idx = (i << 4)+(i << 6);
- for (uint8_t j = 0; j < 0x10; j++) {
- wprintw(scr, "%02X ", addr[tmpad+j+line_idx]);
+ for (uint8_t j = 0; j < 0x50; j++) {
+ wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
}
wprintw(scr, ", i: %02X\r", i);
- ln++;
}*/
#if keypoll
pthread_mutex_unlock(&mutex);
@@ -433,7 +418,7 @@ void *run(void *args) {
#endif
switch(opcode) {
case CPS: /* Clear Processor Status. */
- cpu->ps &= 0;
+ cpu->ps = 0;
break;
case AAB: /* Add Accumulator with carry by B register. */
value = cpu->b[thread]; /* Falls Through. */
@@ -452,7 +437,7 @@ void *run(void *args) {
case PHA: /* PusH Accumulator to stack. */
case PHY: /* PusH Y register to stack. */
case PHX: /* PusH X register to stack. */
- tmp = value;
+ tmp = (value <= 7) ? value : 7;
switch (opcode) {
case PHA: reg = cpu->a[thread]; break;
case PHB: reg = cpu->b[thread]; break;
@@ -460,18 +445,16 @@ void *run(void *args) {
case PHY: reg = cpu->y[thread]; break;
case PHP: reg = cpu->ps; break;
}
- 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);
- case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (5<<3);
- case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (4<<3);
- case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (3<<3);
- case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (2<<3);
- case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (1<<3);
- case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg & 0xFF;
+ case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (7<<3);cpu->sp[thread]--;
+ case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (6<<3);cpu->sp[thread]--;
+ case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (5<<3);cpu->sp[thread]--;
+ case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (4<<3);cpu->sp[thread]--;
+ case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (3<<3);cpu->sp[thread]--;
+ case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (2<<3);cpu->sp[thread]--;
+ case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (1<<3);cpu->sp[thread]--;
+ case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg & (0xFF);cpu->sp[thread]--;
}
break;
case TAY: /* Transfer Accumulator to Y. */
@@ -527,27 +510,19 @@ void *run(void *args) {
case PLA: /* PuLl Accumulator from stack. */
case PLY: /* PuLl Y register from stack. */
case PLX: /* PuLl X register from stack. */
- tmp = value;
- switch (opcode) {
- case PLA: reg = cpu->a[thread]; break;
- case PLB: reg = cpu->b[thread]; break;
- case PLX: reg = cpu->x[thread]; break;
- case PLY: reg = cpu->y[thread]; break;
- case PLP: reg = cpu->ps; break;
- }
- if (tmp > 7)
- tmp = 7;
+ tmp = (value <= 7) ? value : 7;
+ reg = 0;
tmp2 = 0;
- cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp--;
+ cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;
/* 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);
- 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);
- case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- 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);
+ case 7: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 6: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 5: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 4: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 3: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 2: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
+ case 1: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
switch (opcode) {
case PLA: cpu->a[thread] = reg; break;
@@ -557,30 +532,14 @@ void *run(void *args) {
case PLP: cpu->ps = reg; break;
}
break;
- case JSR_IN: /* JSR Indirect. */
- case JSR: /* Jump to SubRoutine. */
- 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);
- case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (5<<3);
- case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (4<<3);
- case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (3<<3);
- case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (2<<3);
- case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (1<<3);
- case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] & 0xFF;
- }
- cpu->pc[thread] = address;
- break;
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. */
cpu->a[thread] &= value;
- setflag(value == 0, Z);
- setflag(value >> 63, N);
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
break;
case STT: /* STart Thread. */
cpu->crt |= value;
@@ -600,8 +559,9 @@ void *run(void *args) {
break;
case BPO: /* BPO Absolute. */
case BPO_Z: /* BPO Zero Matrix. */
- if (!getflag(N))
+ if (!getflag(N)) {
cpu->pc[thread] = address;
+ }
break;
case OAB: /* bitwise Or with Accumulator, and B register. */
value = cpu->b[thread]; /* Falls Through. */
@@ -609,16 +569,17 @@ void *run(void *args) {
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
cpu->a[thread] |= value;
- setflag(value == 0, Z);
- setflag(value >> 63, N);
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
break;
case SEI: /* SEt Interrupt. */
setflag(1, I);
break;
case BNG: /* BNG Absolute. */
case BNG_Z: /* BNG Zero Matrix. */
- if (getflag(N))
+ if (getflag(N)) {
cpu->pc[thread] = address;
+ }
break;
case XAB: /* bitwise Xor with Accumulator, and B register. */
value = cpu->b[thread]; /* Falls Through. */
@@ -626,16 +587,17 @@ void *run(void *args) {
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
cpu->a[thread] ^= value;
- setflag(value == 0, Z);
- setflag(value >> 63, N);
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
break;
case CLI: /* CLear Interrupt. */
setflag(0, I);
break;
case BCS: /* BCS Absolute. */
case BCS_Z: /* BCS Zero Matrix. */
- if (getflag(C))
+ if (getflag(C)) {
cpu->pc[thread] = address;
+ }
break;
case LLB: /* Logical shift Left accumulator by B. */
value = cpu->b[thread]; /* Falls Through. */
@@ -645,7 +607,7 @@ void *run(void *args) {
sum = (value < 64) ? cpu->a[thread] << value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(cpu->a[thread] >> 64-value, C);
+ setflag(cpu->a[thread] >> (64-value), C);
cpu->a[thread] = sum;
break;
case SEC: /* SEt Carry flag.*/
@@ -774,12 +736,16 @@ void *run(void *args) {
case 'S':
#if !debug
wscrl(scr, -1);
+ #else
+ updt = (!addr[0x16]);
#endif
esc = 0;
break;
case 'T':
#if !debug
wscrl(scr, 1);
+ #else
+ updt = (!addr[0x16]);
#endif
esc = 0;
break;
@@ -852,7 +818,7 @@ void *run(void *args) {
}
#endif
/* Unroll Loop by implementing Duff's Device. */
- switch (regsize) {
+ switch (1 << (prefix >> 4)) {
case 8:
addr[address+7] = value >> 56;
addr[address+6] = value >> 48;
@@ -864,11 +830,13 @@ void *run(void *args) {
case 2:
addr[address+1] = value >> 8;
}
+ step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BCC: /* BCC Absolute. */
case BCC_Z: /* BCC Zero Matrix. */
- if (!getflag(C))
+ if (!getflag(C)) {
cpu->pc[thread] = address;
+ }
break;
case LRB: /* Logical shift Right accumulator by B. */
value = cpu->b[thread]; /* Falls Through. */
@@ -936,17 +904,17 @@ void *run(void *args) {
}
value = addr[address];
/* Unroll Loop by implementing Duff's Device. */
- switch (regsize) {
+ switch (1 << (prefix >> 4)) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
value |= (uint64_t)addr[address+6] << 48;
value |= (uint64_t)addr[address+5] << 40;
value |= (uint64_t)addr[address+4] << 32;
case 4:
- value |= addr[address+3] << 24;
- value |= addr[address+2] << 16;
+ value |= (uint64_t)addr[address+3] << 24;
+ value |= (uint64_t)addr[address+2] << 16;
case 2:
- value |= addr[address+1] << 8;
+ value |= (uint64_t)addr[address+1] << 8;
}
switch (opcode) {
case LDB:
@@ -990,8 +958,9 @@ void *run(void *args) {
break;
case BEQ: /* BEQ Absolute. */
case BEQ_Z: /* BEQ Zero Matrix. */
- if (getflag(Z))
+ if (getflag(Z)) {
cpu->pc[thread] = address;
+ }
break;
case RLB: /* Rotate Left accumulator by B. */
value = cpu->b[thread]; /* Falls Through. */
@@ -1002,13 +971,14 @@ void *run(void *args) {
sum |= getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(cpu->a[thread] >> (uint64_t)64-value, C);
+ setflag(cpu->a[thread] >> (uint64_t)(64-value), C);
cpu->a[thread] = sum;
break;
case BNE: /* BNE Absolute. */
case BNE_Z: /* BNE Zero Matrix. */
- if (!getflag(Z))
+ if (!getflag(Z)) {
cpu->pc[thread] = address;
+ }
break;
case RRB: /* Rotate Right accumulator by B. */
value = cpu->b[thread]; /* Falls Through. */
@@ -1016,7 +986,7 @@ void *run(void *args) {
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
sum = cpu->a[thread] >> value;
- sum |= (uint64_t)getflag(C) << (uint64_t)64-value;
+ sum |= (uint64_t)getflag(C) << (uint64_t)(64-value);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] & 1, C);
@@ -1024,37 +994,38 @@ void *run(void *args) {
break;
case BVS: /* BVS Absolute. */
case BVS_Z: /* BVS Zero Matrix. */
- if (getflag(V))
+ if (getflag(V)) {
cpu->pc[thread] = address;
+ }
break;
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. */
- sum = cpu->a[thread]*value+getflag(C);
+ sum = cpu->a[thread]*value;
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
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. */
case BVC_Z: /* BVC Zero Matrix. */
- if (!getflag(V))
+ if (!getflag(V)) {
cpu->pc[thread] = address;
+ }
break;
case DIV: /* DIV Immediate. */
case DAB: /* Divide Accumulator by B. */
case DIV_AB: /* DIV Absolute. */
case DIV_Z: /* DIV Zero Matrix. */
+ sum = cpu->a[thread]/value;
if (opcode != DAB) {
cpu->b[thread] = cpu->a[thread] % value;
} else {
value = cpu->b[thread];
cpu->x[thread] = cpu->a[thread] % value;
}
- sum = cpu->a[thread]/value;
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag((sum >> 63), N);
@@ -1062,19 +1033,6 @@ void *run(void *args) {
case CLV: /* CLear oVerflow flag. */
setflag(0, V);
break;
- case RTS: /* ReTurn from Subroutine. */
- tmp2 = 0;
- 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);
- case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- 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);
- }
- break;
case CAB: /* Compare Accumulator, and B. */
value = cpu->b[thread]; /* Falls Through. */
case CPB: /* CPB Immediate. */
@@ -1179,19 +1137,18 @@ void *run(void *args) {
setflag(reg == 0, Z);
setflag(reg >> 63, N);
break;
+ case JSR_IN: /* JSR Indirect. */
+ case JSR: /* Jump to SubRoutine. */
case JSL: /* Jump to Subroutine Long. */
- 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]--;
- case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (5<<3);cpu->sp[thread]--;
- case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (4<<3);cpu->sp[thread]--;
- case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (3<<3);cpu->sp[thread]--;
- case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (2<<3);cpu->sp[thread]--;
- case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (1<<3);cpu->sp[thread]--;
- case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; cpu->sp[thread]--;
- }
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-0] = (uint64_t)cpu->pc[thread] >> (7<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-1] = (uint64_t)cpu->pc[thread] >> (6<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-2] = (uint64_t)cpu->pc[thread] >> (5<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-3] = (uint64_t)cpu->pc[thread] >> (4<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-4] = (uint64_t)cpu->pc[thread] >> (3<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-5] = (uint64_t)cpu->pc[thread] >> (2<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-6] = (uint64_t)cpu->pc[thread] >> (1<<3);
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-7] = (uint64_t)cpu->pc[thread] & (0xFF);
+ cpu->sp[thread] -= 8;
cpu->pc[thread] = address;
break;
case INC_AB: /* INC Absolute. */
@@ -1199,69 +1156,79 @@ void *run(void *args) {
addr[address]++;
setflag(addr[address] == 0, Z);
setflag(addr[address] >> 7, N);
+ step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case NOP: /* No OPeration. */
break;
+ case RTS: /* ReTurn from Subroutine. */
case RTL: /* ReTurn from subroutine Long. */
- tmp2 = 1;
- 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);
- case 3: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 2: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 1: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 0: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- }
- break;
+ cpu->sp[thread] += 8;
+ cpu->pc[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] & (0xFF);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] << (1<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] << (2<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] << (3<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] << (4<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] << (5<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] << (6<<3);
+ cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-0)] << (7<<3);
break;
case DEC_AB: /* DEC Absolute. */
case DEC_Z: /* DEC Zero Matrix. */
addr[address]--;
setflag(addr[address] == 0, Z);
setflag(addr[address] >> 7, N);
+ step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BRK: /* BReaK. */
+ case WAI: /* WAit for Interrupt. */
+ if (opcode == WAI) {
+ pthread_mutex_lock(&main_mutex);
+ pthread_cond_signal(&main_cond);
+ pthread_mutex_unlock(&main_mutex);
+ pthread_mutex_lock(&mutex);
+ pthread_cond_wait(&cond, &mutex);
+ pthread_mutex_unlock(&mutex);
+ }
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 56;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] = (uint64_t)cpu->pc[thread] >> 48;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] = (uint64_t)cpu->pc[thread] >> 40;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] = (uint64_t)cpu->pc[thread] >> 32;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] = (uint64_t)cpu->pc[thread] >> 24;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] = (uint64_t)cpu->pc[thread] >> 16;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] = (uint64_t)cpu->pc[thread] >> 8;
+ addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] = (uint64_t)cpu->pc[thread] >> 8;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] = (uint64_t)cpu->pc[thread] & 0xFF;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] = (uint64_t)cpu->ps >> (thread << 3);
cpu->sp[thread] -= 9;
setflag(1, I);
- cpu->pc[thread] = (uint64_t)addr[0xFFE0];
- cpu->pc[thread] += (uint64_t)addr[0xFFE1] << 8;
- cpu->pc[thread] += (uint64_t)addr[0xFFE2] << 16;
- cpu->pc[thread] += (uint64_t)addr[0xFFE3] << 24;
- cpu->pc[thread] += (uint64_t)addr[0xFFE4] << 32;
- cpu->pc[thread] += (uint64_t)addr[0xFFE5] << 40;
- cpu->pc[thread] += (uint64_t)addr[0xFFE6] << 48;
- cpu->pc[thread] += (uint64_t)addr[0xFFE7] << 56;
- break;
- case WAI: /* WAit for Interrupt. */
- wai = 1;
- pthread_mutex_lock(&main_mutex);
- pthread_cond_signal(&main_cond);
- pthread_mutex_unlock(&main_mutex);
- pthread_mutex_lock(&mutex);
- pthread_cond_wait(&cond, &mutex);
- pthread_mutex_unlock(&mutex);
+ if (opcode == BRK) {
+ cpu->pc[thread] = (uint64_t)addr[0xFFE0];
+ cpu->pc[thread] += (uint64_t)addr[0xFFE1] << 8;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE2] << 16;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE3] << 24;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE4] << 32;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE5] << 40;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE6] << 48;
+ cpu->pc[thread] += (uint64_t)addr[0xFFE7] << 56;
+ } else {
+ cpu->pc[thread] = (uint64_t)addr[0xFFA0]
+ | (uint64_t)addr[0xFFA1] << 8
+ | (uint64_t)addr[0xFFA2] << 16
+ | (uint64_t)addr[0xFFA3] << 24
+ | (uint64_t)addr[0xFFA4] << 32
+ | (uint64_t)addr[0xFFA5] << 40
+ | (uint64_t)addr[0xFFA6] << 48
+ | (uint64_t)addr[0xFFA7] << 56;
+ kbd_rdy &= (uint8_t)~(1 << thread);
+ }
break;
default:
break;
}
ins++;
- step = addr[STEP_ADDR];
#if !bench
+ #if debug
+ updt = (!addr[0x16]);
+ #endif
if (step) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
@@ -1278,7 +1245,11 @@ void *run(void *args) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- mvwprintw(scr, (6*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk);
+ wmove(scr, (6*thread)+1, 0);
+ wprintw(scr, "Instructions executed: %"PRIu64, ins);
+ #if getclk
+ wprintw(scr, ", Clock cycles: %"PRIu64, iclk);
+ #endif
if (!step) {
wrefresh(scr);
}
@@ -1291,37 +1262,41 @@ void *run(void *args) {
pthread_mutex_lock(&main_mutex);
threads_done++;
inst[thread] = ins;
+ #if getclk
clk[thread] = iclk;
+ #endif
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
gettimeofday(&en[thread], 0);
}
#endif
}
- free(s);
+ return NULL;
}
int main(int argc, char **argv) {
struct suxthr thr[THREADS];
char *tmp = malloc(2048);
- ibcount = 0;
addr = malloc(0x04000000);
inss = 0;
int v = 0;
if (argc != 2) {
- if (asmmon("stdin") == 2)
+ if (asmmon("stdin") == 2) {
return 0;
+ }
} else {
- if (asmmon(argv[1]) == 2)
+ if (asmmon(argv[1]) == 2) {
return 0;
+ }
}
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
#if !bench
- if(!scr)
+ if(!scr) {
scr = initscr();
+ }
nodelay(stdscr, 0);
crmode();
noecho();
@@ -1338,36 +1313,26 @@ int main(int argc, char **argv) {
#endif
pthread_t therads[THREADS];
int result;
+ uint16_t vec = 0xFFC0;
+ uint8_t offset;
for (int i = 0; i < THREADS; i++) {
thr[i].sx.sp[i] = 0xFFFF;
thr[i].sx.stk_st[i] = i+1;
- if (i) {
- thr[i].sx.a[i] = 0;
- thr[i].sx.b[i] = 0;
- thr[i].sx.x[i] = 0;
- thr[i].sx.y[i] = 0;
- thr[i].sx.pc[i] = (uint64_t)addr[0xFF50+(8*(i-1))]
- | (uint64_t)addr[0xFF51+(8*(i-1))] << 8
- | (uint64_t)addr[0xFF52+(8*(i-1))] << 16
- | (uint64_t)addr[0xFF53+(8*(i-1))] << 24
- | (uint64_t)addr[0xFF54+(8*(i-1))] << 32
- | (uint64_t)addr[0xFF55+(8*(i-1))] << 40
- | (uint64_t)addr[0xFF56+(8*(i-1))] << 48
- | (uint64_t)addr[0xFF57+(8*(i-1))] << 56;
- } else {
- thr[i].sx.a[i] = 0;
- thr[i].sx.b[i] = 0;
- thr[i].sx.x[i] = 0;
- thr[i].sx.y[i] = 0;
- thr[i].sx.pc[i] = (uint64_t)addr[0xFFC0]
- | (uint64_t)addr[0xFFC1] << 8
- | (uint64_t)addr[0xFFC2] << 16
- | (uint64_t)addr[0xFFC3] << 24
- | (uint64_t)addr[0xFFC4] << 32
- | (uint64_t)addr[0xFFC5] << 40
- | (uint64_t)addr[0xFFC6] << 48
- | (uint64_t)addr[0xFFC7] << 56;
- }
+ offset = (i) ? ((i-1) << 3) : 0;
+ vec = (i) ? 0xFF50 : 0xFFC0;
+ thr[i].sx.a[i] = 0;
+ thr[i].sx.b[i] = 0;
+ thr[i].sx.x[i] = 0;
+ thr[i].sx.y[i] = 0;
+ thr[i].sx.pc[i] = (uint64_t)addr[vec+0+offset]
+ | (uint64_t)addr[vec+1+offset] << 8
+ | (uint64_t)addr[vec+2+offset] << 16
+ | (uint64_t)addr[vec+3+offset] << 24
+ | (uint64_t)addr[vec+4+offset] << 32
+ | (uint64_t)addr[vec+5+offset] << 40
+ | (uint64_t)addr[vec+6+offset] << 48
+ | (uint64_t)addr[vec+7+offset] << 56;
+
thr[i].th = i;
inst[i] = 0;
result = pthread_create(&therads[i], NULL, run, &thr[i]);
@@ -1403,8 +1368,9 @@ int main(int argc, char **argv) {
c = wgetch(scr);
if (c == 19) {
step = 1;
- if (kbd_rdy)
+ if (kbd_rdy) {
c = wgetch(scr);
+ }
}
if (kbd_rdy) {
switch (c) {
@@ -1430,11 +1396,9 @@ int main(int argc, char **argv) {
break;
}
} else {
- if ((c == 19 || c == 18) && step) {
- if (c == 18)
- step = 0;
- else if (c == 19)
- step_key = 1;
+ if (step) {
+ step = !(c == 18);
+ step_key = (c == 19);
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
@@ -1455,8 +1419,10 @@ int main(int argc, char **argv) {
#if bench
if (threads_done == THREADS) {
double tm_sec, tm_usec, tm[THREADS], ttm;
+ #if getclk
double clkspd;
double mhz;
+ #endif
double ips[THREADS];
double ipst;
for (int i = 0; i < THREADS; i++) {
@@ -1468,21 +1434,33 @@ int main(int argc, char **argv) {
inss += inst[i];
ttm += tm[i];
ipst += ips[i];
+ #if getclk
tclk += clk[i];
+ #endif
} else {
inss = inst[i];
ttm = tm[i];
ipst = ips[i];
+ #if getclk
tclk = clk[i];
+ #endif
}
+ #if getclk
clkspd = (tm[i]/1000000)*1000000/clk[i];
mhz = 1000000.0/clkspd/1000000;
- sprintf(tmp, "Instructions executed for thread %i: %llu, Instructions per Second for thread %i in MIPS: %f, tm: %f\n", i, inst[i], i, ips[i], tm[i]/1000000);
+ #endif
+ sprintf(tmp, "Instructions executed for thread %i: %"PRIu64", Instructions per Second for thread %i in MIPS: %f, tm: %f\n", i, inst[i], i, ips[i], tm[i]/1000000);
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
}
+ sprintf(tmp, "Total Instructions executed: %"PRIu64", Total Instructions per Second in MIPS: %f", inss, ipst);
+ fwrite(tmp, sizeof(char), strlen(tmp), stdout);
+ #if getclk
clkspd = (ttm/1000000)*1000000/tclk;
mhz = 1000000.0/clkspd/1000000;
- sprintf(tmp, "Total Instructions executed: %llu, Total Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ipst, tclk, mhz, ttm/1000000);
+ sprintf(tmp, ", Clock cycles: %"PRIu64", Clock Speed in MHz: %f", tclk, mhz);
+ fwrite(tmp, sizeof(char), strlen(tmp), stdout);
+ #endif
+ sprintf(tmp, ", tm: %f\n", ttm/1000000);
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
free(tmp);
diff --git a/test/asr.s b/test/asr.s
index c01269e..a3b72c0 100644
--- a/test/asr.s
+++ b/test/asr.s
@@ -4,7 +4,6 @@
reset:
cps
-
start:
lda #0
sbc #$FFFF
@@ -18,6 +17,7 @@ signshft:
.org $FFC0
.qword reset
-.org $0
+
+a
done
diff --git a/test/fib-new.s b/test/fib-new.s
index ed0aa50..5a8ae83 100644
--- a/test/fib-new.s
+++ b/test/fib-new.s
@@ -67,5 +67,6 @@ fib2:
.org $FF50
.qword init2
; Execute the program.
+a
done
diff --git a/test/fib.s b/test/fib.s
index 40489ec..dd8c618 100644
--- a/test/fib.s
+++ b/test/fib.s
@@ -68,5 +68,6 @@ fib2:
.org $FF50
.qword init2
; Execute the program.
+a
done
diff --git a/test/fib2.s b/test/fib2.s
index d8c0d42..59830a2 100644
--- a/test/fib2.s
+++ b/test/fib2.s
@@ -1,26 +1,33 @@
; Variables for thread 0.
.org $1000
x:
- .qword $0
+ .qword 0
y:
- .qword $1
+ .qword 1
z:
- .qword $0
+ .qword 0
+zero:
+ .qword 0
-.org $0
+.org 0
init:
cps ; Clear the Processor Status register.
-
start:
- lda #0 ; Clear the accumulator.
- ldb.q y ; b=1.
+ lsr #63 ; Reset the accumulator.
+ tab ;
+ tax ;
+ tay ;
+ inb ;
+ clc ;
fib:
- aab ; Add x with y.
- ldb.q y
- stb.q x ; x=y.
- sta.q y ; y=z.
- tab
- lda.q x
- bcs start ; Start all over again, if the carry flag was set.
- jmp fib ; Otherwise, keep looping.
+ tya ;
+ aab ; Add x with y. But did we also carry over?
+ bcs start ; Yes, so restart.
+ tax ;
+ tya ;
+ tab ;
+ txa ;
+ tay ;
+ jmp fib ; No, so keep looping.
+a
done
diff --git a/test/nop.s b/test/nop.s
new file mode 100644
index 0000000..8fbb14f
--- /dev/null
+++ b/test/nop.s
@@ -0,0 +1,12 @@
+reset:
+ cps
+nop_loop:
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ jmp nop_loop
+a
+done
diff --git a/test/reg-transfer.s b/test/reg-transfer.s
index abedc5b..37e0d51 100644
--- a/test/reg-transfer.s
+++ b/test/reg-transfer.s
@@ -16,5 +16,6 @@ bench:
.qword reset
; Execute the program.
+a
done
diff --git a/test/subroutine.s b/test/subroutine.s
index 65e46ca..7db1b87 100644
--- a/test/subroutine.s
+++ b/test/subroutine.s
@@ -45,5 +45,6 @@ clr_buf_end:
;.byte $1
.org $FFC0
.qword reset
+a
done
diff --git a/test/test-stack.s b/test/test-stack.s
index 193cca7..b9218a0 100644
--- a/test/test-stack.s
+++ b/test/test-stack.s
@@ -1,13 +1,13 @@
init:
-cps
-ldx.w #$FFFF
-txs
+ cps
+ ldx.w #$FFFF
+ txs
loop:
-iab
-pha #$08
-ply #$08
-jmp loop
+ inc
+ pha #1
+ ply #1
+ jmp loop
.org $FFC0
.qword init
@@ -20,5 +20,6 @@ jmp loop
.qword init
.qword init
+a
done