Added new pseudo-mnemonics to nedasm (BEQ,BNE,BGE,BGT,GLT,BLE,BMI,BPL).
[ned1] / nedasm / nedasm_parser_extensions.c
/*
* © 2018 Aaron Taylor <ataylor at subgeniuskitty dot com>
* See LICENSE.txt file for copyright and license details.
*/
#include <stdlib.h>
#include <string.h>
#include "nedasm_structures.h"
#include "nedasm_misc.h"
struct instruction *
parse_pseudo_mnemonic(char * mnemonic, size_t mnemonic_index, char * data, size_t data_index,
char * label, size_t label_index, struct instruction * new_instruction)
{
uint32_t linenum = new_instruction->linenum;
if (strncmp(mnemonic, "JSR", MAX_MNEMONIC_LEN) == 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;
}
/* 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; 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->next = create_instruction_struct();
new_instruction->next->prev = new_instruction;
new_instruction = new_instruction->next;
}
}
} 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;
}