* © 2018 Aaron Taylor <ataylor at subgeniuskitty dot com>
* See LICENSE.txt file for copyright and license details.
#include "nedasm_structures.h"
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) {
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
++) {
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;
new_instruction
->linenum
= linenum
;
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) {
/* 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
++) {
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;
new_instruction
->linenum
= linenum
;
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. */
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
++) {
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;
new_instruction
->linenum
= linenum
;
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. */
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
++) {
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;
new_instruction
->linenum
= linenum
;
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. */
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
++) {
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;
new_instruction
->linenum
= linenum
;
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. */
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
++) {
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;
new_instruction
->linenum
= linenum
;
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. */
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
++) {
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;
new_instruction
->linenum
= linenum
;
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) {
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
++) {
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;
new_instruction
->linenum
= linenum
;
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) {
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
++) {
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;
new_instruction
->linenum
= linenum
;
new_instruction
->next
= create_instruction_struct();
new_instruction
->next
->prev
= new_instruction
;
new_instruction
= new_instruction
->next
;