From: Aaron Taylor Date: Wed, 2 Jan 2019 05:14:05 +0000 (-0800) Subject: Added new pseudo-mnemonics to nedasm (BEQ,BNE,BGE,BGT,GLT,BLE,BMI,BPL). X-Git-Url: http://git.subgeniuskitty.com/ned1/.git/commitdiff_plain/02ea54e3ae9294284fe597ccc65676a7ecc11670 Added new pseudo-mnemonics to nedasm (BEQ,BNE,BGE,BGT,GLT,BLE,BMI,BPL). --- diff --git a/docs/compat_matrix.md b/docs/compat_matrix.md index 5faf44f..b2a15c8 100644 --- a/docs/compat_matrix.md +++ b/docs/compat_matrix.md @@ -13,3 +13,4 @@ Compatibility Matrix | 2 | 2 | 2 | . | . | | 3 | . | . | . | . | | 4 | . | . | 2 | 2 | +| . | 3 | . | . | . | diff --git a/nedasm/nedasm.c b/nedasm/nedasm.c index c82233d..1b64a4d 100644 --- a/nedasm/nedasm.c +++ b/nedasm/nedasm.c @@ -14,7 +14,7 @@ #include "nedasm_parser.h" #include "nedasm_codegen.h" -#define VERSION 2 +#define VERSION 3 void print_usage(char ** argv) diff --git a/nedasm/nedasm_parser_extensions.c b/nedasm/nedasm_parser_extensions.c index d02e62b..b85de47 100644 --- a/nedasm/nedasm_parser_extensions.c +++ b/nedasm/nedasm_parser_extensions.c @@ -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. + // TODO: Add a "word boundary" syllable type that I can add to the instruction list. 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) { @@ -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, "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; diff --git a/software/assembly_fragments/branches.asm b/software/assembly_fragments/branches.asm new file mode 100644 index 0000000..417e6c7 --- /dev/null +++ b/software/assembly_fragments/branches.asm @@ -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