summaryrefslogtreecommitdiff
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
parent8b20b35bf5506ff74b7337e35d6827064eace425 (diff)
Added support for labels to the assembly language
monitor. I also rewrote the fibonacci program to include lables.
-rw-r--r--asmmon.c141
-rw-r--r--test/fib.s75
-rw-r--r--test/test-stack.s5
-rw-r--r--test/test-the-tests.s42
4 files changed, 214 insertions, 49 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
}
}
diff --git a/test/fib.s b/test/fib.s
index 0d3ee03..9188a3c 100644
--- a/test/fib.s
+++ b/test/fib.s
@@ -4,42 +4,69 @@
; Written in Sux Assembly
; by mr b0nk 500 <b0nk@b0nk.xyz>
+; Variables for thread 0.
+.org $1000
+x:
+.qword $0
+y:
+.qword $0
+z:
+.qword $0
+; Variables for thread 1.
+.org $2000
+x2:
+.qword $0
+y2:
+.qword $0
+z2:
+.qword $0
+
+.org $0
+init:
cps ; Clear the Processor Status register.
+
+start:
lda #$0 ; Clear the accumulator.
ldy #$1 ; y=1.
-sty.q $1008 ; Store y into memory.
+sty.q y ; Store y into memory.
+
+fib:
ldx #$0 ; x=0.
-ldx.q $1000 ; Output the value of x.
-adc.q $1008 ; Add x with y.
-sta.q $1010 ; z=x+y
-ldy.q $1008
-sty.q $1000 ; x=y.
-sta.q $1008 ; y=z.
-lda.q $1000
-bcs $1 ; Start all over again, if the carry flag was set.
-jmp $D ; Otherwise, keep looping.
+ldx.q x ; Output the value of x.
+adc.q y ; Add x with y.
+sta.q z ; z=x+y
+ldy.q y
+sty.q x ; x=y.
+sta.q y ; y=z.
+lda.q x
+bcs start ; Start all over again, if the carry flag was set.
+jmp fib ; Otherwise, keep looping.
.org $8000
-
+init2:
cps ; Clear the Processor Status register.
+
+start2:
lda #$0 ; Clear the accumulator.
-ldy #$1 ; y=1.
-sty.q $2008 ; Store y into memory.
-ldx #$0 ; x=0.
-ldx.q $2000 ; Output the value of x.
-adc.q $2008 ; Add x with y.
-sta.q $2010 ; z=x+y
-ldy.q $2008
-sty.q $2000 ; x=y.
-sta.q $2008 ; y=z.
-lda.q $2000
-bcs $8001 ; Start all over again, if the carry flag was set.
-jmp $800D ; Otherwise, keep looping.
+ldy #$1 ; y2=1.
+sty.q y2 ; Store y into memory.
+
+fib2:
+ldx #$0 ; x2=0.
+ldx.q x2 ; Output the value of x2.
+adc.q y2 ; Add x2 with y2.
+sta.q z2 ; z2=x2+y2
+ldy.q y2
+sty.q x2 ; x2=y2.
+sta.q y2 ; y2=z2.
+lda.q x2
+bcs start2 ; Start all over again, if the carry flag was set.
+jmp fib2 ; Otherwise, keep looping.
; Set up the thread vectors.
.org $FF50
-.qword $8000
+.qword init2
; Execute the program.
done
diff --git a/test/test-stack.s b/test/test-stack.s
index e31e343..88ed25c 100644
--- a/test/test-stack.s
+++ b/test/test-stack.s
@@ -1,7 +1,10 @@
+init:
cps
+
+loop:
iax
pha #$8
ply #$8
-jmp $1
+jmp loop
done
diff --git a/test/test-the-tests.s b/test/test-the-tests.s
index 8471fab..314ed45 100644
--- a/test/test-the-tests.s
+++ b/test/test-the-tests.s
@@ -1,26 +1,48 @@
.org $0000
+init:
cps
+
+lstart:
lda #$01
+
+lshft:
lsl #$1
-bcs $13
-jmp $3
+bcs rstart
+jmp lshft
+
+rstart:
lda.q #$8000000000000000
+
+rshft:
lsr #$1
-bcs $1
-jmp $1D
+bcs lstart
+jmp rshft
+
+
.org $8000
+init2:
cps
+
+lstart2:
lda #$01
+
+lshft2:
lsl #$1
-bcs $8013
-jmp $8003
+bcs rstart2
+jmp lshft2
+
+rstart2:
lda.q #$8000000000000000
+
+rshft2:
lsr #$1
-bcs $8001
-jmp $801D
+bcs lstart2
+jmp rshft2
+
+.org $FFC0
+.qword init
.org $FF50
-.qword $8000
-.org $0
+.qword init2
done