~sircmpwn/hdmg

4b1b5943bf123b45d93a2f2fc4339e1f5dfd92c8 — Drew DeVault 1 year, 6 months ago fbf938c
sm83: implement interrupts
2 files changed, 29 insertions(+), 0 deletions(-)

M sm83/cpu.ha
M sm83/exec.ha
M sm83/cpu.ha => sm83/cpu.ha +10 -0
@@ 49,6 49,16 @@ export fn reset(cpu: *sm83) void = {
	};
};

// Sets the CPU interrupt mask.
export fn imask(cpu: *sm83, mask: u8) void = {
	cpu.int_ie = mask;
};

// Triggers the provided mask of interrupts.
export fn raise(cpu: *sm83, mask: u8) void = {
	cpu.int_if |= mask;
};

fn cycles(cpu: *sm83, n: int) void = {
	cpu.cycles -= n;
};

M sm83/exec.ha => sm83/exec.ha +19 -0
@@ 3,6 3,9 @@ export fn exec(cpu: *sm83, cycles: uint) void = {
	cpu.cycles += cycles: int;

	for (cpu.cycles > 0) {
		if (cpu.int_ime == 1 && cpu.int_if & cpu.int_ie != 0) {
			interrupt(cpu);
		};
		if (cpu.int_ime == 2) {
			// EI is delayed by one instruction
			cpu.int_ime = 1;


@@ 15,3 18,19 @@ export fn exec(cpu: *sm83, cycles: uint) void = {
		};
	};
};

fn interrupt(cpu: *sm83) void = {
	cpu.cycles -= 5 * 4;
	cpu.int_ime = 0;

	let i = 0u8;
	for (i < 8; i += 1) {
		if (cpu.int_if & (1 << i) != 0) {
			break;
		};
	};

	cpu.int_if &= ~(1 << i);
	push(cpu, cpu.regs.PC);
	cpu.regs.PC = i * 8 + 0x40u16;
};