diff options
Diffstat (limited to 'asmmon.c')
-rw-r--r-- | asmmon.c | 141 |
1 files changed, 127 insertions, 14 deletions
@@ -1,4 +1,5 @@ #include "opcode.h" +#include <ctype.h> #include <string.h> #define debug 1 @@ -10,6 +11,62 @@ opcodes[num].imm = _IMM; \ opcodes[num].zm = _ZM; opcodes[num].zmx = _ZMX; opcodes[num].zmy = _ZMY; \ opcodes[num].abs = _ABS; opcodes[num].impl = _IMPL;} + +struct fixup { + struct fixup *nxt; + struct label *l; + uint64_t adr; +}; + +struct label { + struct label* nxt; + uint64_t adr; + uint8_t def; + char name[1]; +}; +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; +} + +void use_label(const char *name, uint64_t *adr) { + struct label *l = mklabel(name, 0, 0); + if (l->def) { + *adr = l->adr; + } else { + struct fixup *f = malloc(sizeof(*f)); + f->nxt = fixups; + f->adr = *adr; + f->l = l; + fixups = f; + } +} + int asmmon() { opent opcodes[OPNUM]; /* mne IMM ZM ZMX ZMY ABS IMPL*/ @@ -112,16 +169,16 @@ int asmmon() { char *cmd; char *tmp = malloc(sizeof(char *)*128); size_t size; - done &= ~14; + done &= ~0x1F; getline(&buf, &size, stdin); cmd = strtok_r(buf, "\n", &tmp); if (cmd != NULL) { if (strcasecmp(cmd, "done") == 0) { done |= 1; } else { - ins = strtok(buf, " \n\t"); + ins = strtok(buf, "\t\n "); if (ins != NULL) { - oprand = strtok(NULL, "\t\n;, "); + oprand = strtok(NULL, "\t\n "); strtok_r(ins, ".", &postfix); } if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0) @@ -150,8 +207,20 @@ int asmmon() { } 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] == ';') { - done |=6; + if (i && (ins[i-1] == ' ' || ins[i-1] == '\t')) + ins[i] = '\0'; + else + done |=6; break; } } @@ -165,8 +234,22 @@ int asmmon() { } if (strcasecmp(ins, ".byte") == 0 || strcasecmp(ins, ".word") == 0 || strcasecmp(ins, ".dword") == 0 || strcasecmp(ins, ".qword") == 0) { done |= 6; - oprand = strtok(oprand, "$"); - value = strtoull(oprand, NULL, 16); + 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, &value); + sprintf(oprand, "%llx", value); + break; + } + } if (strcasecmp(ins, ".byte") == 0) addr[address++] = value & 0xFF; if (strcasecmp(ins, ".word") == 0) { @@ -217,6 +300,8 @@ int asmmon() { } if (mode[0] == '$') { value = strtoull(oprand, NULL, 16); + if (value == 0) + addrmode = 2; if (value & 0xFFFFFFFF) { char *stf[] = {"BPO", "BNG", "BCS", "BCC", "BEQ", "BNE", "BVS", "BVC"}; for (int i = 0; i < 8; i++) { @@ -231,6 +316,33 @@ int asmmon() { addrmode = 5; } } + } else { + for (int i = 0; i < strlen(oprand); i++) { + if (oprand[i] == ';') { + done |= 16; + break; + } + if (isalnum(oprand[i]) || oprand[i] == '_') { + use_label(oprand, &value); + if (value == 0) + addrmode = 2; + if (value & 0xFFFFFFFF) { + char *stf[] = {"BPO", "BNG", "BCS", "BCC", "BEQ", "BNE", "BVS", "BVC"}; + for (int i = 0; i < 8; i++) { + if (strcasecmp(ins, stf[i]) == 0) { + addrmode = 5; + break; + } else { + addrmode = 2; + } + } + } else if (value & 0xFFFFFFFF00000000) { + addrmode = 5; + } + sprintf(oprand, "%llx", value); + break; + } + } } } if (ins != NULL && !(done & 6)) { @@ -415,14 +527,15 @@ int asmmon() { break; } #if debug - if (!(done & 6)) - printf("instruction: %s, ", ins); - #if (!__GLIBC__) || (__TINYC__) - printf("Postfix: %s, ", (postfix != NULL) ? postfix : "none"); - #else - printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none"); - #endif - printf("Operand: %s, Address: $%llx\n", (oprand != NULL) ? oprand : "none", address); + if (!(done & 6)) { + printf("instruction: %s, ", ins); + #if (!__GLIBC__) || (__TINYC__) + printf("Postfix: %s, ", (postfix != NULL) ? postfix : "none"); + #else + printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none"); + #endif + printf("Operand: %s, Address: $%llx\n", (oprand != NULL && !(done & 16)) ? oprand : "none", address); + } #endif } } |