mirror of
https://github.com/pnx/m16vm
synced 2026-06-16 03:44:55 +02:00
cpu: remove CPU_FLAGS_HALT (and flag variable from struct cpu_state).
we can get handle cpu halts without this flag. CPU's dont actually have these. exceptions are actually implemented as interrupts in real hardware.
This commit is contained in:
parent
76a72e6857
commit
0a58a7857f
2 changed files with 6 additions and 18 deletions
19
vm/cpu.c
19
vm/cpu.c
|
|
@ -84,7 +84,7 @@ static void execute(struct cpu_state *state, struct instr *instr) {
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
fprintf(stderr, "Invalid instruction (%.2X)\n", instr->opcode);
|
fprintf(stderr, "Invalid instruction (%.2X)\n", instr->opcode);
|
||||||
state->flags |= CPU_FLAGS_HALT;
|
state->pc = state->instr_cnt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,6 @@ static void execute(struct cpu_state *state, struct instr *instr) {
|
||||||
void cpu_init(struct cpu_state *state)
|
void cpu_init(struct cpu_state *state)
|
||||||
{
|
{
|
||||||
state->pc = 0;
|
state->pc = 0;
|
||||||
state->flags = 0;
|
|
||||||
memset(state->reg, 0, sizeof(state->reg[0]) * CPU_NUM_REGS);
|
memset(state->reg, 0, sizeof(state->reg[0]) * CPU_NUM_REGS);
|
||||||
|
|
||||||
state->instr_mem = NULL;
|
state->instr_mem = NULL;
|
||||||
|
|
@ -119,19 +118,13 @@ void cpu_instr_unload(struct cpu_state *state) {
|
||||||
|
|
||||||
void cpu_set_pc(struct cpu_state *state, uint16_t addr) {
|
void cpu_set_pc(struct cpu_state *state, uint16_t addr) {
|
||||||
|
|
||||||
if (addr > state->instr_cnt / 2) {
|
if (addr > state->instr_cnt / 2)
|
||||||
fprintf(stderr, "Runtime error: Invalid instruction address %ui\n", addr);
|
fprintf(stderr, "Runtime error: Invalid instruction address %ui\n", addr);
|
||||||
state->flags |= CPU_FLAGS_HALT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state->pc = addr;
|
state->pc = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char* instr_fetch(struct cpu_state *state) {
|
static unsigned char* instr_fetch(struct cpu_state *state) {
|
||||||
|
|
||||||
if (state->pc + 1 >= state->instr_cnt >> 1)
|
|
||||||
state->flags |= CPU_FLAGS_HALT;
|
|
||||||
|
|
||||||
return state->instr_mem + (state->pc++ << 1);
|
return state->instr_mem + (state->pc++ << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,13 +133,13 @@ int cpu_tick(struct cpu_state *state) {
|
||||||
struct instr instr;
|
struct instr instr;
|
||||||
unsigned char* next;
|
unsigned char* next;
|
||||||
|
|
||||||
if (state->flags & CPU_FLAGS_HALT) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch next instruction
|
// Fetch next instruction
|
||||||
next = instr_fetch(state);
|
next = instr_fetch(state);
|
||||||
|
|
||||||
|
// We abort if we move past the last program address.
|
||||||
|
if (state->pc > state->instr_cnt >> 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
// decode instruction.
|
// decode instruction.
|
||||||
instr_decode(next, &instr);
|
instr_decode(next, &instr);
|
||||||
|
|
||||||
|
|
|
||||||
5
vm/cpu.h
5
vm/cpu.h
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
#define CPU_NUM_REGS 16
|
#define CPU_NUM_REGS 16
|
||||||
|
|
||||||
#define CPU_FLAGS_HALT (1<<0)
|
|
||||||
|
|
||||||
struct cpu_state {
|
struct cpu_state {
|
||||||
// Registers r0, r15
|
// Registers r0, r15
|
||||||
int16_t reg[CPU_NUM_REGS];
|
int16_t reg[CPU_NUM_REGS];
|
||||||
|
|
@ -34,9 +32,6 @@ struct cpu_state {
|
||||||
// Program counter
|
// Program counter
|
||||||
uint16_t pc;
|
uint16_t pc;
|
||||||
|
|
||||||
// flags
|
|
||||||
unsigned char flags;
|
|
||||||
|
|
||||||
// Instruction
|
// Instruction
|
||||||
unsigned char *instr_mem;
|
unsigned char *instr_mem;
|
||||||
unsigned long instr_cnt;
|
unsigned long instr_cnt;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue