diff options
Diffstat (limited to 'asmmon.c')
-rw-r--r-- | asmmon.c | 932 |
1 files changed, 615 insertions, 317 deletions
@@ -4,7 +4,6 @@ #define debug 1 -#define OPNUM 93 #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; \ @@ -60,19 +59,6 @@ uint64_t use_label(const char *name, uint64_t adr) { struct label *l = mklabel(name, 0, 0); adr++; if (l->def) { - addr[adr] = l->adr & 0xFF; - if (l->adr & 0xFF00) - addr[adr+1] = l->adr >> 8; - if (l->adr & 0xFF000000) { - addr[adr+2] = l->adr >> 16; - addr[adr+3] = l->adr >> 24; - } - if (l->adr & 0xFF00000000000000) { - addr[adr+4] = l->adr >> 32; - addr[adr+5] = l->adr >> 40; - addr[adr+6] = l->adr >> 48; - addr[adr+7] = l->adr >> 56; - } return l->adr; } else { printf("oof, label %s, does not exist, yet.\n", name); @@ -124,102 +110,201 @@ void viewmem(uint64_t address) { printf("\n"); } } + +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("\tquit, q\t\t\tQuit the emulator."); + puts("\thelp, h\t\t\tDisplays this mesage."); +} + +void instinfo(const char *inst) { + for(int i = 0; i < OPNUM; i++) { + if (!strcasecmp(inst, mne[i])) { + printf("%s\t%s\n", mne[i], instdesc[i]); + break; + } else if (!strcasecmp(inst, "all")) { + printf("%s\t%s\n", mne[i], instdesc[i]); + } + } +} + +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'; + } 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'; + } + 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; + + } +} + int asmmon(const char *fn) { - opent opcodes[OPNUM]; /* 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, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00); SETOP( 2, "AAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02); - SETOP( 3, "PHB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06); - SETOP( 4, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP( 5, "PHA", 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP( 6, "PHY", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP( 7, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B); - SETOP( 8, "PHX", 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP( 9, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D); - SETOP(10, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E); - SETOP(11, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x04, 0x14, 0x24, 0x10, 0x00); - SETOP(12, "SBC", 0x11, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00); - SETOP(13, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12); - SETOP(14, "PLB", 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(15, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(16, "PLA", 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(17, "PLY", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(18, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B); - SETOP(19, "PLX", 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(20, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D); - SETOP(21, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E); - SETOP(22, "JSR", 0x00, 0x20, 0x00, 0x00, 0x34, 0x44, 0x54, 0x00, 0x00); - SETOP(23, "AND", 0x21, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00); - SETOP(24, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22); - SETOP(25, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(26, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26); - SETOP(27, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E); - SETOP(28, "BPO", 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); - SETOP(29, "ORA", 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00); - SETOP(30, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32); - SETOP(31, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36); - SETOP(32, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); - SETOP(33, "TXS", 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(34, "BNG", 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); - SETOP(35, "XOR", 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00); - SETOP(36, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42); - SETOP(37, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); - SETOP(38, "BCS", 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); - SETOP(39, "LSL", 0x51, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00); - SETOP(40, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52); - SETOP(41, "STB", 0x00, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0x5F, 0x00); - SETOP(42, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); - SETOP(43, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0x5B, 0x00); - SETOP(44, "STY", 0x00, 0x7D, 0x8D, 0x00, 0xAD, 0xBD, 0x00, 0x5D, 0x00); - SETOP(45, "STX", 0x00, 0x7E, 0x00, 0x9E, 0xAE, 0x00, 0xCE, 0x5E, 0x00); - SETOP(46, "BCC", 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); - SETOP(47, "LSR", 0x61, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00); - SETOP(48, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62); - SETOP(49, "LDB", 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0x56, 0x00); - SETOP(50, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); - SETOP(51, "LDA", 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0x59, 0x00); - SETOP(52, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0xAA, 0xBA, 0x00, 0x5A, 0x00); - SETOP(53, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0xAC, 0x00, 0xCC, 0x5C, 0x00); - SETOP(54, "BEQ", 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); - SETOP(55, "ROL", 0x71, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00); - SETOP(56, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72); - SETOP(57, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); - SETOP(58, "BNE", 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); - SETOP(59, "ROR", 0x81, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00); - SETOP(60, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82); - SETOP(61, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); - SETOP(62, "BVS", 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); - SETOP(63, "MUL", 0x91, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00); - SETOP(64, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92); - SETOP(65, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); - SETOP(66, "BVC", 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); - SETOP(67, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00); - SETOP(68, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2); - SETOP(69, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); - SETOP(70, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); - SETOP(71, "CMP", 0xB1, 0xB5, 0x00, 0x00, 0xE9, 0xEB, 0xED, 0xB3, 0x00); - SETOP(72, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2); - SETOP(73, "CPY", 0x2A, 0x3B, 0x00, 0x00, 0xEA, 0xFA, 0x00, 0x2B, 0x00); - SETOP(74, "CPX", 0xBC, 0x3D, 0x00, 0x00, 0xEC, 0x00, 0xFC, 0x2D, 0x00); - SETOP(75, "CPB", 0xD6, 0xF6, 0x00, 0x00, 0xDF, 0xEF, 0xFF, 0xE6, 0x00); - SETOP(76, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 3, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x04, 0x14, 0x24, 0x10, 0x00); + SETOP( 4, "PHB", 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 5, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 6, "LDA", 0x09, 0x39, 0x59, 0x79, 0x99, 0xB9, 0xD9, 0x19, 0x00); + SETOP( 7, "LDY", 0x0A, 0x3A, 0x5A, 0x00, 0x7A, 0x9A, 0x00, 0x1A, 0x00); + SETOP( 8, "LDX", 0x0B, 0x3B, 0x00, 0x5B, 0x7B, 0x00, 0x9B, 0x1B, 0x00); + SETOP( 9, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C); + SETOP(10, "LDB", 0x0E, 0x3E, 0x5E, 0x7E, 0x9E, 0xBE, 0xDE, 0x1E, 0x00); + SETOP(11, "SBC", 0x11, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00); + SETOP(12, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12); + SETOP(13, "PLB", 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(14, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(15, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C); + SETOP(16, "JSR", 0x00, 0x20, 0x00, 0x00, 0x34, 0x44, 0x54, 0x00, 0x00); + SETOP(17, "AND", 0x21, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00); + SETOP(18, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22); + SETOP(19, "CPB", 0x26, 0x46, 0x00, 0x00, 0x56, 0x66, 0x76, 0x36, 0x00); + SETOP(20, "STT", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28); + SETOP(21, "STA", 0x00, 0x49, 0x69, 0x89, 0xA9, 0xC9, 0xE9, 0x29, 0x00); + SETOP(22, "STY", 0x00, 0x4A, 0x6A, 0x00, 0x8A, 0xAA, 0x00, 0x2A, 0x00); + SETOP(23, "STX", 0x00, 0x4B, 0x00, 0x6B, 0x8B, 0x00, 0xAB, 0x2B, 0x00); + SETOP(24, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C); + SETOP(25, "STB", 0x00, 0x4E, 0x6E, 0x8E, 0xAE, 0xCE, 0xEE, 0x2E, 0x00); + SETOP(26, "BPO", 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); + SETOP(27, "ORA", 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00); + SETOP(28, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32); + SETOP(29, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); + SETOP(30, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C); + SETOP(31, "BNG", 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); + SETOP(32, "XOR", 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00); + SETOP(33, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42); + SETOP(34, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); + SETOP(35, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C); + SETOP(36, "BCS", 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); + SETOP(37, "LSL", 0x51, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00); + SETOP(38, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52); + SETOP(39, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); + SETOP(40, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C); + SETOP(41, "BCC", 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); + SETOP(42, "LSR", 0x61, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00); + SETOP(43, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62); + SETOP(44, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); + SETOP(45, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C); + SETOP(46, "BEQ", 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); + SETOP(47, "ROL", 0x71, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00); + SETOP(48, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72); + SETOP(49, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); + SETOP(50, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C); + SETOP(51, "BNE", 0x00, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); + SETOP(52, "ROR", 0x81, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00); + SETOP(53, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82); + SETOP(54, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86); + SETOP(55, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); + SETOP(56, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C); + SETOP(57, "BVS", 0x00, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); + SETOP(58, "MUL", 0x91, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00); + SETOP(59, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92); + SETOP(60, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96); + SETOP(61, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); + SETOP(62, "TXS", 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(63, "BVC", 0x00, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); + SETOP(64, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00); + SETOP(65, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2); + SETOP(66, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6); + SETOP(67, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); + SETOP(68, "PHY", 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(69, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); + SETOP(70, "CMP", 0xB1, 0xB5, 0x00, 0x00, 0xF1, 0xF3, 0xF5, 0xB3, 0x00); + SETOP(71, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2); + SETOP(72, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB6); + SETOP(73, "ENT", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8); + SETOP(74, "CPY", 0xBA, 0xDA, 0x00, 0x00, 0xEA, 0xFA, 0x00, 0xCA, 0x00); + SETOP(75, "CPX", 0xBB, 0xDB, 0x00, 0x00, 0xEB, 0x00, 0xFB, 0xCB, 0x00); + SETOP(76, "PLY", 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); SETOP(77, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); SETOP(78, "INC", 0x00, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC1); SETOP(79, "IAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); - SETOP(80, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A); - SETOP(81, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C); + SETOP(80, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8); + SETOP(81, "PHX", 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); SETOP(82, "DEC", 0x00, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xD1); SETOP(83, "DBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); - SETOP(84, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A); - SETOP(85, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C); - SETOP(86, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8); - SETOP(87, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); - SETOP(88, "ASR", 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00); - SETOP(89, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2); - SETOP(90, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); - SETOP(91, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); - SETOP(92, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); + SETOP(84, "PLX", 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(85, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); + SETOP(86, "ASR", 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00); + SETOP(87, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2); + SETOP(88, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); + SETOP(89, "PHA", 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(90, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); + SETOP(91, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); + SETOP(92, "PLA", 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); FILE *fp; if (strcasecmp(fn, "stdin") != 0) { fp = fopen(fn, "r"); @@ -228,21 +313,25 @@ int asmmon(const char *fn) { } uint8_t done = 0; uint64_t address = 0x0000; + 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 = 0; + uint8_t addrmode = IMPL; uint64_t value = 0; char *oprand; char *cmd; char ir[2] = ""; /* Index register. */ int a = 0; + int b = 0; char *tmp = malloc(sizeof(char *)*128); size_t size; - done &= ~0x1F; + prefix = 0; + done = 0; if (!strcasecmp(fn, "stdin")) { getline(&buf, &size, stdin); } else { @@ -260,7 +349,7 @@ int asmmon(const char *fn) { if (oprand != NULL) { for (int i = 0; i < strlen(oprand); i++) { if (oprand[i] == '(') - addrmode = 6; + addrmode = IND; if (oprand[i] == '"') break; if (a && oprand[a] == ',') { @@ -272,7 +361,13 @@ int asmmon(const char *fn) { 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; } @@ -287,173 +382,327 @@ int asmmon(const char *fn) { 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")) { + done |= 4; + usage(); + } if (oprand == NULL && ins == NULL && postfix == NULL) { done |= 2; } - 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 (ins[i] == ';') { - if (i && (ins[i-1] == ' ' || ins[i-1] == '\t')) - ins[i] = '\0'; - else - done |=6; - break; - } - } - if (strcasecmp(ins, ".org") == 0) { - 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 + cmd = strtok(cmd, " \n"); + if (!strcasecmp(cmd, "inst") || !strcasecmp(cmd, "i")) { + done |= 64; + done |= 6; + if (oprand != NULL) { + instinfo(oprand); + } else { + instinfo("all"); } - if (strcasecmp(ins, ".byte") == 0 || strcasecmp(ins, ".word") == 0 || strcasecmp(ins, ".dword") == 0 || strcasecmp(ins, ".qword") == 0) { - 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); + + } + 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 (oprand[i] == '"' && !strcasecmp(ins, ".byte")) { - qstr = 1; - continue; + if (cmd[i] == '$') { + cmd = strtok(cmd, "$"); + value = strtoull(cmd, NULL, 16); + break; } - if (oprand[i] == '$') { - qstr = 0; - oprand = strtok(oprand, "$"); - value = strtoull(oprand, NULL, 16); + if (cmd[i] == ';') { + done |= 16; + break; + } + } + 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); break; } - if (oprand[i] == ';') { - qstr = 0; + if (tmp[i] == ';') { done |= 16; break; } - } else if (qstr == 1) { - switch (oprand[i]) { - case 0: - puts("oof, unterminated string."); - qstr = 2; - 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'; + } + (!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 & 0x07) == 0x07) { + start+=1; + addrsize = (prefix & 8) >> 3; + 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]; + if (regsize >= 2) + value |= addr[start+1] << 8; + if (regsize >= 4) { + value |= addr[start+2] << 16; + value |= addr[start+3] << 24; + } + if (regsize >= 8) { + 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 += regsize; + break; + case ZM: + case ZMX: + case ZMY: + case IND: + case INDX: + case INDY: + value = addr[start]; + if (addrsize) { + value |= addr[start+1] << 8; + value |= addr[start+2] << 16; + value |= addr[start+3] << 24; + start+=4; + } else { + start+=1; + } + break; + case ABS: + value = addr[start]; + value |= addr[start+1] << 8; + if (addrsize) { + value |= (uint64_t)addr[start+2] << 16; + value |= (uint64_t)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; + } else { + start+=2; + } + 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 (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; - case '0': + } + if (oprand[i] == '"' && !strcasecmp(ins, ".byte")) { + qstr = 1; + continue; + } + if (oprand[i] == '$') { + qstr = 0; + oprand = strtok(oprand, "$"); + value = strtoull(oprand, NULL, 16); break; - default: - value = oprand[i]; - tmpstr[slen++] = '\\'; - tmpstr[slen++] = oprand[i]; + } + if (oprand[i] == ';') { + qstr = 0; + done |= 16; break; + } + } else if (qstr == 1) { + switch (oprand[i]) { + case 0: + puts("oof, unterminated string."); + qstr = 2; + 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; } - i++; - break; - default: - value = oprand[i]; - c = oprand[i]; - tmpstr[slen++] = c; - break; + } + 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 } - addr[address++] = value & 0xFF; } } - if (strcasecmp(ins, ".byte") == 0 && !qstr) - addr[address++] = value & 0xFF; - if (strcasecmp(ins, ".word") == 0) { - addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - address+=2; - } - if (strcasecmp(ins, ".dword") == 0) { - addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; - } - if (strcasecmp(ins, ".qword") == 0) { - addr[address] = 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 = 1; + addrmode = IMM; done |= 32; } else if (oprand != NULL && !strcasecmp(ins, "TXS")) - addr[address++] = 0x17; + prefix = 0x17; if (!(done & 2) && oprand != NULL) { mode[0] = oprand[0]; mode[1] = oprand[1]; - if (oprand[0] == '#' || oprand[0] == '$' || oprand[0] == '(') { + if (oprand[0] == '#' || oprand[0] == '$' || (oprand[0] == '(' && (oprand[1] == '$' || oprand[1] == '%'))) { oprand = strtok(oprand, "#($%"); if (mode[0] == '#') { - addrmode = 1; + addrmode = IMM; done |= 32; if (mode[1] == '$') value = strtoull(oprand, NULL, 16); @@ -468,26 +717,33 @@ int asmmon(const char *fn) { value = strtoull(oprand, NULL, 2); else value = strtoull(oprand, NULL, 10); + if (value & 0xFFFFFF00 && (ir[0] == 'x' || ir[0] == 'y')) + prefix |= 0xF; if (mode[0] != '(') { - if (value & 0xFFFFFFFF || !value) { - addrmode = 2; - } else if (value & 0xFFFFFFFF00000000) { - addrmode = 5; + if (value & 0xFFFF0000 || (value <= 0xFF) || + (value & 0xFF00 && address <= 0xFFFF && (ir[0] == 'x' || ir[0] == 'y'))) { + addrmode = ZM; + if (value & 0xFFFFFF00) + prefix |= 0xF; + } else if (value & 0xFFFFFFFF00000000 || (value & 0xFF00 && address <= 0xFFFF)) { + addrmode = ABS; + if (value & 0xFFFFFFFF00000000) + prefix |= 0xF; } } if ((addrmode == 2 || addrmode == 6) && ir != NULL) { switch (ir[0]) { case 'x': - if (addrmode == 2) - addrmode = 3; - else if (addrmode == 6) - addrmode = 7; + if (addrmode == ZM) + addrmode = ZMX; + else if (addrmode == IND) + addrmode = INDX; break; case 'y': - if (addrmode == 2) - addrmode = 4; - else if (addrmode == 6) - addrmode = 8; + if (addrmode == ZM) + addrmode = ZMY; + else if (addrmode == IND) + addrmode = INDY; break; default: done |= 32; @@ -496,6 +752,8 @@ int asmmon(const char *fn) { } } } else { + if (mode[0] == '(') + oprand = strtok(oprand, "#($%"); for (int i = 0; i < strlen(oprand); i++) { if (oprand[i] == ';') { done |= 16; @@ -503,26 +761,33 @@ int asmmon(const char *fn) { } if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') { value = use_label(oprand, address); + if (value & 0xFFFFFF00 && (ir[0] == 'x' || ir[0] == 'y')) + prefix |= 0xF; if (mode[0] != '(') { - if (value & 0xFFFFFFFF || !value) { - addrmode = 2; - } else if (value & 0xFFFFFFFF00000000) { - addrmode = 5; + if (value & 0xFFFF0000 || (value <= 0xFF) || + (value <= 0xFFFF && address <= 0xFFFF && (ir[0] == 'x' || ir[0] == 'y'))) { + addrmode = ZM; + if (value & 0xFFFFFF00) + prefix |= 0xF; + } else if (value & 0xFFFFFFFF00000000 || (value & 0xFF00 && address <= 0xFFFF)) { + addrmode = ABS; + if (value & 0xFFFFFFFF00000000) + prefix |= 0xF; } } - if ((addrmode == 2 || addrmode == 6) && ir != NULL && a) { + if ((addrmode == ZM || addrmode == IND) && ir != NULL && a) { switch (ir[0]) { case 'x': - if (addrmode == 2) - addrmode = 3; - else if (addrmode == 6) - addrmode = 7; + if (addrmode == ZM) + addrmode = ZMX; + else if (addrmode == IND) + addrmode = INDX; break; case 'y': - if (addrmode == 2) - addrmode = 4; - else if (addrmode == 6) - addrmode = 8; + if (addrmode == ZM) + addrmode = ZMY; + else if (addrmode == IND) + addrmode = INDY; break; default: done |= 32; @@ -539,14 +804,16 @@ int asmmon(const char *fn) { uint8_t i; for (i = 0; i < OPNUM; i++) { if (strcasecmp(opcodes[i].mnemonic, ins) == 0) { - if (addrmode == 0 && (opcodes[i].impl || opcodes[i].impl == CPS)) { + if (addrmode == IMPL && (opcodes[i].impl || opcodes[i].impl == CPS)) { done |= 8; - } else if (addrmode == 1) { + } 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: @@ -594,24 +861,27 @@ int asmmon(const char *fn) { } if (postfix != NULL && !(done & 8)) { if (!strcasecmp(postfix, "w") || !strcasecmp(postfix, "2")) { - addr[address++] = 0x17; + prefix |= 0x17; } else if (!strcasecmp(postfix, "d") || !strcasecmp(postfix, "4")) { - addr[address++] = 0x27; + prefix |= 0x27; } else if (!strcasecmp(postfix, "q") || !strcasecmp(postfix, "8")) { - addr[address++] = 0x37; - } else { + prefix |= 0x37; + } else if (!prefix) { done |=8; } - } else if (postfix == NULL && !(done & 8)) { + } else if (postfix == NULL && (!(done & 8) && !prefix)) { done |=8; } uint8_t r; - if (!(done & 8)) - r = addr[address-1]; - else + if (!(done & 8)) { + r = prefix; + addr[address] = prefix; + address += 1; + } else { r = 0; + } switch (addrmode) { - case 0: + case IMPL: if (op.impl || op.impl == CPS) { addr[address++] = op.impl; break; @@ -619,10 +889,10 @@ int asmmon(const char *fn) { fprintf(stderr, "oof, %s requires an operand.\n", op.mnemonic); } break; - case 1: + case IMM: if (op.imm) { - if (addr[address-1] == 0x17 && op.imm == TXS) - r = 0x17; + if ((prefix & 0x30) == 0x10 && op.imm == TXS) + r = prefix; addr[address++] = op.imm; switch (op.imm) { case PHP: @@ -643,7 +913,7 @@ int asmmon(const char *fn) { addr[address++] = value & 0xFF; break; case TXS: - if (r == 0x17) { + if ((r & 0x30) == 0x10) { addr[address] = value & 0xFF; addr[address+2] = value >> 8; address+=2; @@ -670,96 +940,124 @@ int asmmon(const char *fn) { fprintf(stderr, "oof, %s does not use Immediate data.\n", op.mnemonic); } break; - case 2: + case ZM: if (op.zm) { addr[address++] = op.zm; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix.\n", op.mnemonic); } break; - case 3: + case ZMX: if (op.zmx) { addr[address++] = op.zmx; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with x.\n", op.mnemonic); } break; - case 4: + case ZMY: if (op.zmy) { addr[address++] = op.zmy; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with y.\n", op.mnemonic); } break; - case 5: + case ABS: if (op.abs) { addr[address++] = op.abs; addr[address] = 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 ((r & 8) == 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; + } else { + address+=2; + } break; } else { fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic); } break; - case 6: + case IND: if (op.ind) { addr[address++] = op.ind; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s cannot use pointers.\n", op.mnemonic); } break; - case 7: + case INDX: if (op.inx) { addr[address++] = op.inx; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s does not use Indexed Indirect.\n", op.mnemonic); } break; - case 8: + case INDY: if (op.iny) { addr[address++] = op.iny; addr[address] = value & 0xFF; - addr[address+1] = value >> 8; - addr[address+2] = value >> 16; - addr[address+3] = value >> 24; - address+=4; + if ((r & 8) == 8) { + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + } else { + address+=1; + } break; } else { fprintf(stderr, "oof, %s does not use Indirect Indexed.\n", op.mnemonic); |