From c5150ee31f07208422f1435de9b35a0d0168cbb5 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 9 Apr 2020 02:06:50 -0400 Subject: Completely changed the assembler. It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller. --- asmmon.c | 1883 ++++++++++++++++++++------------------------------------------ 1 file changed, 600 insertions(+), 1283 deletions(-) (limited to 'asmmon.c') diff --git a/asmmon.c b/asmmon.c index 3f715ac..de4b9a3 100644 --- a/asmmon.c +++ b/asmmon.c @@ -1,97 +1,15 @@ -#include "opcode.h" -#include -#include - -#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; } -- cgit v1.2.3-13-gbd6f