diff --git a/cpu.go b/cpu.go index 2fc8ea0..bc891d0 100644 --- a/cpu.go +++ b/cpu.go @@ -227,7 +227,7 @@ func (cpu *CPU) tryInterrupt() bool { return true } // check maskable interrupt. - if cpu.INT == nil { + if !cpu.IFF1 || cpu.INT == nil { return false } d := cpu.INT.CheckINT() @@ -240,6 +240,7 @@ func (cpu *CPU) tryInterrupt() bool { cpu.SP -= 2 cpu.writeU16(cpu.SP, cpu.PC) cpu.PC = 0x0038 + cpu.IFF1 = false return true case 2: if n := len(d); n != 1 { @@ -252,6 +253,7 @@ func (cpu *CPU) tryInterrupt() bool { cpu.SP -= 2 cpu.writeU16(cpu.SP, cpu.PC) cpu.PC = toU16(d[0]&0xfe, cpu.IR.Hi) + cpu.IFF1 = false return true } // interrupt with IM 0 @@ -264,6 +266,7 @@ func (cpu *CPU) tryInterrupt() bool { cpu.Memory = newIm0data(cpu.PC, d, savedMemory) cpu.executeOne() cpu.Memory = savedMemory + cpu.IFF1 = false return true } diff --git a/cpu_test.go b/cpu_test.go index 5e008c7..c3a3a69 100644 --- a/cpu_test.go +++ b/cpu_test.go @@ -142,11 +142,14 @@ func testIM0(t *testing.T, n uint8) { Memory: MapMemory{}. // HALT Put(0x0000, 0x76). - // RETI - Put(addr, 0xed, 0x4d). - // IM 0 ; HALT ; HALT (for return) + // EI ; RETI + Put(addr, + 0xfb, + 0xed, 0x4d). + // IM 0 ; EI ; HALT ; HALT (for return) Put(0x0100, 0xed, 0x46, + 0xfb, 0x76, 0x76, ), @@ -158,8 +161,8 @@ func testIM0(t *testing.T, n uint8) { if err := cpu.Run(ctx); err != nil { t.Fatalf("unexpected error: %v", err) } - if cpu.PC != 0x0102 { - t.Fatalf("unexpected PC: want=%04X got=%04X", 0x102, cpu.PC) + if cpu.PC != 0x0103 { + t.Fatalf("unexpected PC: want=%04X got=%04X", 0x103, cpu.PC) } if cpu.IM != 0 { t.Fatalf("unexpected interrupt mode: want=0 got=%d", cpu.IM) @@ -171,12 +174,19 @@ func testIM0(t *testing.T, n uint8) { if cpu.PC != addr { t.Fatalf("RST 38H not work: want=%04X got=%04X", addr, cpu.PC) } + if cpu.IFF1 { + t.Fatal("IFF1 is true, unexpectedly") + } + // Return from the interruption. if err := cpu.Run(ctx); err != nil { t.Fatalf("unexpected error: %v", err) } - if cpu.PC != 0x0103 { - t.Fatalf("unexpected PC: want=%04X got=%04X", 0x103, cpu.PC) + if cpu.PC != 0x0104 { + t.Fatalf("unexpected PC: want=%04X got=%04X", 0x104, cpu.PC) + } + if !cpu.IFF1 { + t.Fatal("IFF1 is false, unexpectedly") } if !tint.reti { t.Fatalf("RETI is not processed, unexpectedly") @@ -201,11 +211,14 @@ func TestInterruptIM1(t *testing.T) { Memory: MapMemory{}. // HALT Put(0x0000, 0x76). - // RETI - Put(0x0038, 0xed, 0x4d). - // IM 1 ; HALT ; HALT (for return) + // EI ; RETI + Put(0x0038, + 0xfb, + 0xed, 0x4d). + // IM 1 ; EI ; HALT ; HALT (for return) Put(0x0100, 0xed, 0x56, + 0xfb, 0x76, ), IO: &tForbiddenIO{}, @@ -216,8 +229,8 @@ func TestInterruptIM1(t *testing.T) { if err := cpu.Run(ctx); err != nil { t.Fatalf("unexpected error: %v", err) } - if cpu.PC != 0x0102 { - t.Fatalf("unexpected PC: want=%04X got=%04X", 0x102, cpu.PC) + if cpu.PC != 0x0103 { + t.Fatalf("unexpected PC: want=%04X got=%04X", 0x103, cpu.PC) } if cpu.IM != 1 { t.Fatalf("unexpected interrupt mode: want=1 got=%d", cpu.IM) @@ -229,12 +242,19 @@ func TestInterruptIM1(t *testing.T) { if cpu.PC != 0x0038 { t.Fatalf("IM 1 interruption not work: want=%04X got=%04X", 0x0038, cpu.PC) } + if cpu.IFF1 { + t.Fatal("IFF1 is true, unexpectedly") + } + // Return from the interruption. if err := cpu.Run(ctx); err != nil { t.Fatalf("unexpected error: %v", err) } - if cpu.PC != 0x0102 { - t.Fatalf("unexpected PC: want=%04X got=%04X", 0x102, cpu.PC) + if cpu.PC != 0x0103 { + t.Fatalf("unexpected PC: want=%04X got=%04X", 0x103, cpu.PC) + } + if !cpu.IFF1 { + t.Fatal("IFF1 is false, unexpectedly") } if !tint.reti { t.Fatalf("RETI is not processed, unexpectedly")