From 1e3787256c8fb98c41e3263fe697f30557a895fe Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sat, 7 Dec 2019 18:21:05 -0500 Subject: Added support for labels to the assembly language monitor. I also rewrote the fibonacci program to include lables. --- asmmon.c | 141 +++++++++++++++++++++++++++++++++++++++++++++----- test/fib.s | 75 ++++++++++++++++++--------- test/test-stack.s | 5 +- test/test-the-tests.s | 42 +++++++++++---- 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 #include #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 +; 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 -- cgit v1.2.3-13-gbd6f