summaryrefslogtreecommitdiff
path: root/asmmon.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-12-07 18:21:05 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-12-07 18:23:08 -0500
commit1e3787256c8fb98c41e3263fe697f30557a895fe (patch)
tree6a61ce87767a5c7f7eeeb80d0231019ec95c9013 /asmmon.c
parent8b20b35bf5506ff74b7337e35d6827064eace425 (diff)
Added support for labels to the assembly language
monitor. I also rewrote the fibonacci program to include lables.
Diffstat (limited to 'asmmon.c')
-rw-r--r--asmmon.c141
1 files changed, 127 insertions, 14 deletions
diff --git a/asmmon.c b/asmmon.c
index 73697d1..8d899cc 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -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
}
}