diff options
Diffstat (limited to 'asmmon.c')
-rw-r--r-- | asmmon.c | 209 |
1 files changed, 166 insertions, 43 deletions
@@ -4,7 +4,7 @@ #define debug 1 -#define OPNUM 87 +#define OPNUM 88 #define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _ABS, _IMPL) \ {opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \ opcodes[num].imm = _IMM; \ @@ -24,6 +24,7 @@ struct label { uint8_t def; char name[1]; }; +static char tstr[2048]; struct label *labels = 0; struct fixup *fixups = 0; uint8_t defined = 0; @@ -190,28 +191,29 @@ int asmmon() { SETOP(62, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); SETOP(63, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00); SETOP(64, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); - SETOP(65, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); - SETOP(66, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00); - SETOP(67, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00); - SETOP(68, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3); - SETOP(69, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00); - SETOP(70, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5); - SETOP(71, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(72, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); - SETOP(73, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1); - SETOP(74, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); - SETOP(75, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); - SETOP(76, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); - SETOP(77, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); - SETOP(78, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1); - SETOP(79, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); - SETOP(80, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3); - SETOP(81, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); - SETOP(82, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); - SETOP(83, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); - SETOP(84, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); - SETOP(85, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); - SETOP(86, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); + SETOP(65, "ASR", 0xA9, 0xAD, 0x00, 0x00, 0xAB, 0x00); + SETOP(66, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); + SETOP(67, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00); + SETOP(68, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00); + SETOP(69, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3); + SETOP(70, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00); + SETOP(71, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5); + SETOP(72, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(73, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); + SETOP(74, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1); + SETOP(75, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); + SETOP(76, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); + SETOP(77, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); + SETOP(78, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); + SETOP(79, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1); + SETOP(80, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); + SETOP(81, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3); + SETOP(82, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); + SETOP(83, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); + SETOP(84, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); + SETOP(85, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); + SETOP(86, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); + SETOP(87, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); uint8_t done = 0; uint64_t address = 0x0000; while (!(done & 1)) { @@ -224,6 +226,8 @@ int asmmon() { uint64_t value = 0; char *oprand; char *cmd; + char ir[2] = ""; /* Index register. */ + int a = 0; char *tmp = malloc(sizeof(char *)*128); size_t size; done &= ~0x1F; @@ -235,8 +239,29 @@ int asmmon() { } else { ins = strtok(buf, "\t\n "); if (ins != NULL) { - oprand = strtok(NULL, "\t\n "); + oprand = strtok(NULL, "\t\n"); strtok_r(ins, ".", &postfix); + if (oprand != NULL) { + for (int i = 0; i < strlen(oprand); i++) { + if (oprand[i] == '"') + break; + if (oprand[i] == 'x' || oprand[i] == 'X') { + ir[0] = 'x'; + ir[1] = '\0'; + break; + } + if (oprand[i] == 'y' || oprand[i] == 'Y') { + ir[0] = 'y'; + ir[1] = '\0'; + break; + } + if (oprand[i] == ',' || oprand[i] == ';') { + a = i; + } + } + if (a) + oprand[a] = '\0'; + } } if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0) { return 2; @@ -277,23 +302,86 @@ int asmmon() { } 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 (oprand[i] == '$') { - oprand = strtok(oprand, "$"); - value = strtoull(oprand, NULL, 16); - break; - } - if (oprand[i] == ';') { - done |= 16; - break; - } - if (isalnum(oprand[i]) || oprand[i] == '_') { - use_label(oprand, address); - sprintf(oprand, "%llx", value); - break; + if (!qstr) { + if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') { + qstr = 0; + value = use_label(oprand, address); + sprintf(oprand, "%llx", value); + break; + } + if (oprand[i] == '"' && !strcasecmp(ins, ".byte")) { + qstr = 1; + 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 = 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++] = value & 0xFF; } } - if (strcasecmp(ins, ".byte") == 0) + if (strcasecmp(ins, ".byte") == 0 && !qstr) addr[address++] = value & 0xFF; if (strcasecmp(ins, ".word") == 0) { addr[address] = value & 0xFF; @@ -319,7 +407,19 @@ int asmmon() { address+=8; } #if debug - printf("The value $%llx was placed at address $%llx.\n", value, address); + 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 } } @@ -362,6 +462,16 @@ int asmmon() { } else if (value & 0xFFFFFFFF00000000) { addrmode = 5; } + if (addrmode == 2 && ir != NULL) { + switch (ir[0]) { + case 'x': + addrmode = 3; + break; + case 'y': + addrmode = 4; + break; + } + } } } else { for (int i = 0; i < strlen(oprand); i++) { @@ -369,7 +479,7 @@ int asmmon() { done |= 16; break; } - if (isalnum(oprand[i]) || oprand[i] == '_') { + if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') { value = use_label(oprand, address); if (value == 0) addrmode = 2; @@ -383,10 +493,19 @@ int asmmon() { addrmode = 2; } } - } else if (value & 0xFFFFFFFF00000000) { addrmode = 5; } + if (addrmode == 2 && ir != NULL) { + switch (ir[0]) { + case 'x': + addrmode = 3; + break; + case 'y': + addrmode = 4; + break; + } + } sprintf(oprand, "%llx", value); break; } @@ -415,6 +534,7 @@ int asmmon() { case LSR: case ROL: case ROR: + case ASR: case ENT: done |= 8; break; @@ -495,6 +615,7 @@ int asmmon() { case LSR: case ROL: case ROR: + case ASR: case ENT: addr[address++] = value & 0xFF; break; @@ -541,7 +662,7 @@ int asmmon() { break; case 3: if (op.zmx) { - addr[address++] = op.zmy; + addr[address++] = op.zmx; addr[address] = value & 0xFF; addr[address+1] = value >> 8; addr[address+2] = value >> 16; @@ -591,7 +712,9 @@ int asmmon() { #else printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none"); #endif - printf("Operand: %s, Address: $%llx\n", (oprand != NULL && !(done & 16)) ? oprand : "none", address); + printf("Operand: %s, ", (oprand != NULL && !(done & 16)) ? oprand : "none"); + printf("Index Register: %s, ", (ir != NULL) ? ir : "none"); + printf("Address: $%llx\n", address); } #endif } |