Added new pseudo-mnemonics to nedasm (BEQ,BNE,BGE,BGT,GLT,BLE,BMI,BPL).
authorAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 2 Jan 2019 05:14:05 +0000 (21:14 -0800)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 2 Jan 2019 05:14:05 +0000 (21:14 -0800)
docs/compat_matrix.md
nedasm/nedasm.c
nedasm/nedasm_parser_extensions.c
software/assembly_fragments/branches.asm [new file with mode: 0644]

index 5faf44f..b2a15c8 100644 (file)
@@ -13,3 +13,4 @@ Compatibility Matrix
 |      2 |      2 |      2 |          . |          . |
 |      3 |      . |      . |          . |          . |
 |      4 |      . |      . |          2 |          2 |
 |      2 |      2 |      2 |          . |          . |
 |      3 |      . |      . |          . |          . |
 |      4 |      . |      . |          2 |          2 |
+|      . |      3 |      . |          . |          . |
index c82233d..1b64a4d 100644 (file)
@@ -14,7 +14,7 @@
 #include "nedasm_parser.h"
 #include "nedasm_codegen.h"
 
 #include "nedasm_parser.h"
 #include "nedasm_codegen.h"
 
-#define VERSION 2
+#define VERSION 3
 
 void
 print_usage(char ** argv)
 
 void
 print_usage(char ** argv)
index d02e62b..b85de47 100644 (file)
@@ -27,26 +27,15 @@ parse_pseudo_mnemonic(char * mnemonic, size_t mnemonic_index, char * data, size_
         /* JSR must expand to exactly one word (five syllables).                        */
         /* Otherwise, trailing syllables in the same word are skipped when RTS returns. */
         // TODO: This should be on a word boundary, regardless of whether a WORD preceded it.
         /* JSR must expand to exactly one word (five syllables).                        */
         /* Otherwise, trailing syllables in the same word are skipped when RTS returns. */
         // TODO: This should be on a word boundary, regardless of whether a WORD preceded it.
+        // TODO: Add a "word boundary" syllable type that I can add to the instruction list.
         for (int i=0; i<5; i++) {
             switch (i) {
         for (int i=0; i<5; i++) {
             switch (i) {
-                case 0:
-                    new_instruction->syllable = IM;
-                    new_instruction->data = 0x08; /* Address of PC register */
-                    break;
-                case 1:
-                    new_instruction->syllable = LOAD;
-                    break;
-                case 2:
-                    new_instruction->syllable = SWAP;
-                    break;
-                case 3:
-                    new_instruction->syllable = JMP;
-                    break;
-                case 4:
-                    new_instruction->syllable = NOP;
-                    break;
-                default:
-                    break;
+                case 0: new_instruction->syllable = IM;   new_instruction->data = 0x08; break;
+                case 1: new_instruction->syllable = LOAD;                               break;
+                case 2: new_instruction->syllable = SWAP;                               break;
+                case 3: new_instruction->syllable = JMP;                                break;
+                case 4: new_instruction->syllable = NOP;                                break;
+                default:                                                                break;
             }
             new_instruction->linenum = linenum;
             if (i<4) {
             }
             new_instruction->linenum = linenum;
             if (i<4) {
@@ -57,6 +46,273 @@ parse_pseudo_mnemonic(char * mnemonic, size_t mnemonic_index, char * data, size_
         }
     } else if (strncmp(mnemonic, "RTS", MAX_MNEMONIC_LEN) == 0) {
         new_instruction->syllable = JMP;
         }
     } else if (strncmp(mnemonic, "RTS", MAX_MNEMONIC_LEN) == 0) {
         new_instruction->syllable = JMP;
+    } else if (strncmp(mnemonic, "BEQ", MAX_MNEMONIC_LEN) == 0) {
+        if (label_index) {
+        /* Branch if NOS == TOS. */
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<9; i++) {
+            switch (i) {
+                case 0:  new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:  new_instruction->syllable = SWAP;                               break;
+                case 2:  new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:  new_instruction->syllable = NOT;                                break;
+                case 4:  new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 5:  new_instruction->syllable = ADD;                                break;
+                case 6:  new_instruction->syllable = ADD;                                break;
+                case 7:  new_instruction->syllable = SWAP;                               break;
+                case 8:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                 break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<8) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BNE", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if NOS != TOS. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<14; i++) {
+            switch (i) {
+                case 0:   new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:   new_instruction->syllable = SWAP;                               break;
+                case 2:   new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:   new_instruction->syllable = NOT;                                break;
+                case 4:   new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 5:   new_instruction->syllable = ADD;                                break;
+                case 6:   new_instruction->syllable = ADD;                                break;
+                case 7:   new_instruction->syllable = TEST;                               break;
+                case 8:   new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 9:   new_instruction->syllable = LOAD;                               break;
+                case 10:  new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 11:  new_instruction->syllable = AND;                                break;
+                case 12:  new_instruction->syllable = SWAP;                               break;
+                case 13:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                  break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<13) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BGE", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if NOS >= TOS. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<15; i++) {
+            switch (i) {
+                case 0:   new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:   new_instruction->syllable = SWAP;                               break;
+                case 2:   new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:   new_instruction->syllable = SWAP;                               break;
+                case 4:   new_instruction->syllable = NOT;                                break;
+                case 5:   new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 6:   new_instruction->syllable = ADD;                                break;
+                case 7:   new_instruction->syllable = ADD;                                break;
+                case 8:   new_instruction->syllable = TEST;                               break;
+                case 9:   new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 10:  new_instruction->syllable = LOAD;                               break;
+                case 11:  new_instruction->syllable = IM;   new_instruction->data = 0x02; break;
+                case 12:  new_instruction->syllable = AND;                                break;
+                case 13:  new_instruction->syllable = SWAP;                               break;
+                case 14:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                  break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<14) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BLT", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if NOS < TOS. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<14; i++) {
+            switch (i) {
+                case 0:   new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:   new_instruction->syllable = SWAP;                               break;
+                case 2:   new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:   new_instruction->syllable = NOT;                                break;
+                case 4:   new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 5:   new_instruction->syllable = ADD;                                break;
+                case 6:   new_instruction->syllable = ADD;                                break;
+                case 7:   new_instruction->syllable = TEST;                               break;
+                case 8:   new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 9:   new_instruction->syllable = LOAD;                               break;
+                case 10:  new_instruction->syllable = IM;   new_instruction->data = 0x03; break;
+                case 11:  new_instruction->syllable = AND;                                break;
+                case 12:  new_instruction->syllable = SWAP;                               break;
+                case 13:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                  break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<13) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BGT", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if NOS > TOS. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<15; i++) {
+            switch (i) {
+                case 0:   new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:   new_instruction->syllable = SWAP;                               break;
+                case 2:   new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:   new_instruction->syllable = SWAP;                               break;
+                case 4:   new_instruction->syllable = NOT;                                break;
+                case 5:   new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 6:   new_instruction->syllable = ADD;                                break;
+                case 7:   new_instruction->syllable = ADD;                                break;
+                case 8:   new_instruction->syllable = TEST;                               break;
+                case 9:   new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 10:  new_instruction->syllable = LOAD;                               break;
+                case 11:  new_instruction->syllable = IM;   new_instruction->data = 0x03; break;
+                case 12:  new_instruction->syllable = AND;                                break;
+                case 13:  new_instruction->syllable = SWAP;                               break;
+                case 14:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                  break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<14) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BLE", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if NOS <= TOS. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<14; i++) {
+            switch (i) {
+                case 0:   new_instruction->syllable = LDSP; new_instruction->data = 0x02; break;
+                case 1:   new_instruction->syllable = SWAP;                               break;
+                case 2:   new_instruction->syllable = STSP; new_instruction->data = 0x02; break;
+                case 3:   new_instruction->syllable = NOT;                                break;
+                case 4:   new_instruction->syllable = IM;   new_instruction->data = 0x01; break;
+                case 5:   new_instruction->syllable = ADD;                                break;
+                case 6:   new_instruction->syllable = ADD;                                break;
+                case 7:   new_instruction->syllable = TEST;                               break;
+                case 8:   new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 9:   new_instruction->syllable = LOAD;                               break;
+                case 10:  new_instruction->syllable = IM;   new_instruction->data = 0x02; break;
+                case 11:  new_instruction->syllable = AND;                                break;
+                case 12:  new_instruction->syllable = SWAP;                               break;
+                case 13:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                  break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<13) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BPL", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if TOS > 0. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<8; i++) {
+            switch (i) {
+                case 0:  new_instruction->syllable = SWAP;                               break;
+                case 1:  new_instruction->syllable = TEST;                               break;
+                case 2:  new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 3:  new_instruction->syllable = LOAD;                               break;
+                case 4:  new_instruction->syllable = IM;   new_instruction->data = 0x03; break;
+                case 5:  new_instruction->syllable = AND;                                break;
+                case 6:  new_instruction->syllable = SWAP;                               break;
+                case 7:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                 break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<7) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
+    } else if (strncmp(mnemonic, "BMI", MAX_MNEMONIC_LEN) == 0) {
+        /* Branch if TOS < 0. */
+        if (label_index) {
+            new_instruction->syllable = WORD;
+            new_instruction->target = malloc(label_index+1);
+            strncpy(new_instruction->target, label, label_index+1);
+            new_instruction->next = create_instruction_struct();
+            new_instruction->next->prev = new_instruction;
+            new_instruction = new_instruction->next;
+        }
+        for (int i=0; i<10; i++) {
+            switch (i) {
+                case 0:  new_instruction->syllable = SWAP;                               break;
+                case 1:  new_instruction->syllable = TEST;                               break;
+                case 2:  new_instruction->syllable = IM;   new_instruction->data = 0x0c; break;
+                case 3:  new_instruction->syllable = LOAD;                               break;
+                case 4:  new_instruction->syllable = IM;   new_instruction->data = 0x02; break;
+                case 5:  new_instruction->syllable = AND;                                break;
+                case 6:  new_instruction->syllable = IM;   new_instruction->data = 0x02; break;
+                case 7:  new_instruction->syllable = XOR;                                break;
+                case 8:  new_instruction->syllable = SWAP;                               break;
+                case 9:  new_instruction->syllable = BRZ;                                break;
+                default:                                                                 break;
+            }
+            new_instruction->linenum = linenum;
+            if (i<9) {
+                new_instruction->next = create_instruction_struct();
+                new_instruction->next->prev = new_instruction;
+                new_instruction = new_instruction->next;
+            }
+        }
     }
 
     return new_instruction;
     }
 
     return new_instruction;
diff --git a/software/assembly_fragments/branches.asm b/software/assembly_fragments/branches.asm
new file mode 100644 (file)
index 0000000..417e6c7
--- /dev/null
@@ -0,0 +1,238 @@
+# A test of the non-native branch instructions in nedasm.
+
+WORD_1026
+
+#---------------------
+
+beqtest
+
+IM_4
+IM_4
+
+BEQ>beqskip
+
+    HALT
+
+beqskip
+
+IM_4
+IM_2
+
+BEQ>beqend
+
+WORD_1028
+JMP>bnetest
+
+beqend
+    HALT
+
+#---------------------
+
+bnetest
+
+IM_4
+IM_2
+
+BNE>bneskip
+
+HALT
+
+bneskip
+
+IM_4
+IM_4
+
+BNE>bneend
+
+WORD_1030
+JMP>bgetest
+
+bneend
+    HALT
+
+#---------------------
+
+bgetest
+
+IM_4
+IM_4
+
+BGE>bgeskipa
+
+HALT
+
+bgeskipa
+
+IM_4
+IM_2
+
+BGE>bgeskipb
+
+HALT
+
+bgeskipb
+
+IM_2
+IM_4
+
+BGE>bgeend
+
+WORD_1032
+JMP>bletest
+
+bgeend
+    HALT
+
+#---------------------
+
+bletest
+
+IM_4
+IM_4
+
+BLE>bleskipa
+
+HALT
+
+bleskipa
+
+IM_2
+IM_4
+
+BLE>bleskipb
+
+HALT
+
+bleskipb
+
+IM_4
+IM_2
+
+BLE>bleend
+
+WORD_1034
+JMP>bgttest
+
+bleend
+    HALT
+
+#---------------------
+
+bgttest
+
+IM_4
+IM_2
+
+BGT>bgtskip
+
+    HALT
+
+bgtskip
+
+IM_2
+IM_4
+
+BGT>bgtend
+
+IM_4
+IM_4
+
+BGT>bgtend
+
+WORD_1036
+JMP>blttest
+
+bgtend
+    HALT
+
+#---------------------
+
+blttest
+
+IM_2
+IM_4
+
+BLT>bltskip
+
+    HALT
+
+bltskip
+
+IM_4
+IM_2
+
+BLT>bltend
+
+IM_4
+IM_4
+
+BLT>bltend
+
+WORD_1038
+JMP>bpltest
+
+bltend
+    HALT
+
+#---------------------
+
+bpltest
+
+IM_2
+
+BPL>bplskip
+
+    HALT
+
+bplskip
+
+IM_0
+
+BPL>bplend
+
+IM_2
+NOT
+IM_1
+ADD
+
+BPL>bplend
+
+WORD_1040
+JMP>bmitest
+
+bplend
+    HALT
+
+#---------------------
+
+bmitest
+
+IM_2
+NOT
+IM_1
+ADD
+
+BMI>bmiskip
+
+    HALT
+
+bmiskip
+
+IM_0
+
+BMI>bmiend
+
+IM_2
+
+BMI>bmiend
+
+WORD_1042
+JMP>end
+
+bmiend
+    HALT
+
+#---------------------
+
+end
+    HALT