diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2020-04-17 22:07:14 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2020-04-17 22:07:14 -0400 |
commit | 0a7a2a7a8f95730811117bd2aa904f1843f65071 (patch) | |
tree | 24d62bbdba0df124c7fe8af781312af993236ebb | |
parent | c5150ee31f07208422f1435de9b35a0d0168cbb5 (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-- | Makefile | 1 | ||||
-rw-r--r-- | asmmon.c | 181 | ||||
-rw-r--r-- | asmmon.h | 9 | ||||
-rw-r--r-- | lexer.c | 514 | ||||
-rw-r--r-- | opcode.h | 5 | ||||
-rw-r--r-- | programs/subeditor.s | 290 | ||||
-rw-r--r-- | sux.c | 554 | ||||
-rw-r--r-- | test/asr.s | 4 | ||||
-rw-r--r-- | test/fib-new.s | 1 | ||||
-rw-r--r-- | test/fib.s | 1 | ||||
-rw-r--r-- | test/fib2.s | 37 | ||||
-rw-r--r-- | test/nop.s | 12 | ||||
-rw-r--r-- | test/reg-transfer.s | 1 | ||||
-rw-r--r-- | test/subroutine.s | 1 | ||||
-rw-r--r-- | test/test-stack.s | 15 |
15 files changed, 898 insertions, 728 deletions
@@ -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 @@ -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; } } } @@ -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); @@ -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; } @@ -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 @@ -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); @@ -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 @@ -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 |