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