void handle_instruction(instruction i) { int skip = 0; switch (i.type) { case BASIC: skip = basic_op_code_map[i.op_code].instruction(i.a, i.b); break; case NONBASIC: skip = nonbasic_op_code_map[i.op_code].instruction(i.a); break; } while (skip > 0) { /* need to skip the next intruction, including it's values */ word value = cpu.memory[cpu.PC]; cpu.PC += instruction_length(value); skip--; } }
void test_instruction_length(void) { Instruction* rr = new_instruction_rr(op("add", ADD), 3, 2); Instruction* ri = new_instruction_ri(op("xor", XOR), 0, addr_from_immediate(234)); Instruction* memi = new_instruction_memi( op("ld", LD), 3, 4, addr_from_immediate(1234), false, false); Instruction* shift = new_instruction_ri(op("shl", SHL), 3, addr_from_immediate(2)); Instruction* mov_special = new_instruction_ri(op("mov", MOV), 3, addr_from_immediate(24)); Instruction* mov_general = new_instruction_ri(op("mov", MOV), 5, addr_from_immediate(1456)); Instruction* jmpi = new_instruction_jmpi(op("jmp", JMP), addr_from_immediate(34), AL); TEST_ASSERT_EQUAL_INT_MESSAGE(2, instruction_length(rr), "Incorrect RR instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(4, instruction_length(ri), "Incorrect RI instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(4, instruction_length(memi), "Incorrect MemI instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(4, instruction_length(shift), "Incorrect Shift instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(2, instruction_length(mov_special), "Incorrect Special movi instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(4, instruction_length(mov_general), "Incorrect General movi instruction length"); TEST_ASSERT_EQUAL_INT_MESSAGE(4, instruction_length(jmpi), "Incorrect JmpI instruction length"); free(rr); free(ri); free(memi); free(shift); free(mov_special); free(mov_general); free(jmpi); }
void parseline(list *instructions, list *labels) { start: ;; dcpu16token tok = nexttoken(); if (tok == T_COLON) { /* Label definition */ if ((tok = nexttoken()) == T_IDENTIFIER) { dcpu16label *l = getnewlabel(labels, cur_tok.string); if (l->defined) error("Redefinition of label '%s' (%04X -> %04X) forbidden", l->label, l->pc, pc); l->pc = pc; l->defined = 1; goto start; } else { error("Expected label, got %s", toktostr(tok)); } } else if (is_instruction(tok)) { dcpu16instruction instr, *newinstr; instr.opcode = tok; instr.a = parseoperand(labels); if (!is_nonbasic_instruction(tok)) { if ((tok = nexttoken()) == T_COMMA) { instr.b = parseoperand(labels); } else { error("Expected ',', got %s", toktostr(tok)); } } if ((tok = nexttoken()) != T_NEWLINE) error("Expected EOL, got %s", toktostr(tok)); /* * All tokens valid, store instructions, advance PC */ newinstr = malloc(sizeof(dcpu16instruction)); memcpy(newinstr, &instr, sizeof(dcpu16instruction)); newinstr->pc = pc; newinstr->line = curline; list_push_back(instructions, newinstr); pc += instruction_length(newinstr); } else if (is_macro(tok)) { if (tok == T_ORG) { if ((tok = nexttoken()) == T_NUMBER) { if (flag_paranoid && (cur_tok.number < pc)) { warning("new origin precedes old origin! " "This could cause already written code to be " "overriden."); } pc = cur_tok.number; } else { error("Expected numeric, got %s", toktostr(tok)); } } else if (tok == T_DAT) { /* All of the stuff we are about to read, neatly packed * into words */ list_node *p = NULL; list *data = list_create(); do { if ((tok = nexttoken()) == T_STRING) { char *ptr = cur_tok.string; while (*ptr != '\0') { uint16_t *dat = malloc(sizeof(uint16_t)); *dat = *ptr++; list_push_back(data, dat); } } else if (tok == T_NUMBER) { uint16_t *dat = malloc(sizeof(uint16_t)); *dat = cur_tok.number; list_push_back(data, dat); } else { error("Expected string or numeric, got %s", toktostr(tok)); } if ((tok = nexttoken()) == T_COMMA) continue; else if (tok == T_NEWLINE) break; else error("Expected ',' or EOL, got %s", toktostr(tok)); } while (1); /* ram[pc++] = cur_tok.number; */ for (p = list_get_root(data); p != NULL; p = p->next) { ram[pc++] = *((uint16_t*)p->data); } list_dispose(&data, &free); } } else if (tok == T_NEWLINE) { return; } else { error("Expected label-definition or opcode, got %s", toktostr(tok)); } }