diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index e351206..c1ea46d 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -133,6 +133,21 @@ impl M68k { pub fn exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { debug!("{}: raising exception {}", DEV_NAME, number); + + if number == Exceptions::BusError as u8 || number == Exceptions::AddressError as u8 { + let result = self.setup_group0_exception(number); + if let Err(err) = result { + self.state.status = Status::Stopped; + return Err(err); + } + } else { + self.setup_normal_exception(number, is_interrupt)?; + } + + Ok(()) + } + + pub fn setup_group0_exception(&mut self, number: u8) -> Result<(), Error> { let ins_word = self.decoder.instruction_word; let extra_code = self.state.request.get_type_code(); let fault_size = self.state.request.size.in_bytes(); @@ -143,17 +158,32 @@ impl M68k { self.push_word(offset)?; } - // If BusError or AddressError - if number == 2 || number == 3 { - self.push_long(self.state.pc - fault_size)?; - self.push_word(self.state.sr)?; - self.push_word(ins_word)?; - self.push_long(fault_address)?; - self.push_word((ins_word & 0xFFF0) | extra_code)?; - } else { - self.push_long(self.state.pc)?; - self.push_word(self.state.sr)?; + self.push_long(self.state.pc - fault_size)?; + self.push_word(self.state.sr)?; + self.push_word(ins_word)?; + self.push_long(fault_address)?; + self.push_word((ins_word & 0xFFF0) | extra_code)?; + + // Changes to the flags must happen after the previous value has been pushed to the stack + self.set_flag(Flags::Supervisor, true); + self.set_flag(Flags::Tracing, false); + + let vector = self.state.vbr + offset as u32; + let addr = self.port.read_beu32(vector as Address)?; + self.set_pc(addr)?; + + Ok(()) + } + + pub fn setup_normal_exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { + self.state.request.i_n_bit = true; + + let offset = (number as u16) << 2; + if self.cputype >= M68kType::MC68010 { + self.push_word(offset)?; } + self.push_long(self.state.pc)?; + self.push_word(self.state.sr)?; // Changes to the flags must happen after the previous value has been pushed to the stack self.set_flag(Flags::Supervisor, true); @@ -164,15 +194,7 @@ impl M68k { let vector = self.state.vbr + offset as u32; let addr = self.port.read_beu32(vector as Address)?; - let result = self.set_pc(addr); - - // If BusError or AddressError, and another AddressError occurs, then halt - if number == 2 || number == 3 { - if let Err(err) = result { - self.state.status = Status::Stopped; - return Err(err); - } - } + self.set_pc(addr)?; Ok(()) } @@ -398,7 +420,12 @@ impl M68k { } }, Instruction::CLR(target, size) => { - self.set_target_value(target, 0, size, Used::Once)?; + if self.cputype == M68kType::MC68000 { + self.get_target_value(target, size, Used::Twice)?; + self.set_target_value(target, 0, size, Used::Twice)?; + } else { + self.set_target_value(target, 0, size, Used::Once)?; + } // Clear flags except Zero flag self.state.sr = (self.state.sr & 0xFFF0) | (Flags::Zero as u16); }, @@ -1142,7 +1169,7 @@ impl M68k { } pub fn start_instruction_request(&mut self, addr: u32) -> Result { - self.state.request.is_instruction = true; + self.state.request.i_n_bit = false; self.state.request.code = FunctionCode::program(self.state.sr); self.state.request.access = MemAccess::Read; self.state.request.address = addr; @@ -1151,7 +1178,7 @@ impl M68k { } pub fn start_request(&mut self, addr: u32, size: Size, access: MemAccess, mtype: MemType) -> Result { - self.state.request.is_instruction = false; + self.state.request.i_n_bit = false; self.state.request.code = match mtype { MemType::Program => FunctionCode::program(self.state.sr), MemType::Data => FunctionCode::data(self.state.sr), diff --git a/src/cpus/m68k/state.rs b/src/cpus/m68k/state.rs index 74dc8db..bfded15 100644 --- a/src/cpus/m68k/state.rs +++ b/src/cpus/m68k/state.rs @@ -98,7 +98,7 @@ pub enum MemAccess { #[derive(Copy, Clone, Debug, PartialEq)] pub struct MemoryRequest { - pub is_instruction: bool, + pub i_n_bit: bool, pub access: MemAccess, pub code: FunctionCode, pub size: Size, @@ -229,7 +229,7 @@ impl FunctionCode { impl MemoryRequest { pub fn new() -> Self { Self { - is_instruction: false, + i_n_bit: false, access: MemAccess::Read, code: FunctionCode::Reserved0, size: Size::Word, @@ -238,7 +238,7 @@ impl MemoryRequest { } pub fn get_type_code(&self) -> u16 { - let ins = match self.is_instruction { + let ins = match self.i_n_bit { false => 0x0000, true => 0x0008, }; diff --git a/tests/harte_tests/latest.txt b/tests/harte_tests/latest.txt index 2129a5e..f614edc 100644 --- a/tests/harte_tests/latest.txt +++ b/tests/harte_tests/latest.txt @@ -1,4 +1,4 @@ -Last run on 2022-09-14 at commit a3fbcc7c16f80dd7801ceacf1d4a22a7bf88e9e1 +Last run on 2022-09-16 at commit ef6fde2a4f7e79310a749d2e10e470bca435e90c ABCD.json completed: 301 passed, 7764 FAILED ADD.b.json completed, all passed! @@ -28,8 +28,8 @@ BTST.json completed: 8052 passed, 13 FAILED Bcc.json completed: 5865 passed, 2200 FAILED CHK.json completed: 7744 passed, 321 FAILED CLR.b.json completed, all passed! -CLR.l.json completed: 6882 passed, 1183 FAILED -CLR.w.json completed: 6862 passed, 1203 FAILED +CLR.l.json completed: 7472 passed, 593 FAILED +CLR.w.json completed: 7465 passed, 600 FAILED CMP.b.json completed, all passed! CMP.l.json completed, all passed! CMP.w.json completed, all passed! @@ -50,12 +50,12 @@ JMP.json completed: 4259 passed, 3806 FAILED JSR.json completed: 4183 passed, 3882 FAILED LEA.json completed, all passed! LINK.json completed, all passed! -LSL.b.json completed: 7774 passed, 291 FAILED -LSL.l.json completed: 7017 passed, 1048 FAILED -LSL.w.json completed: 7494 passed, 571 FAILED -LSR.b.json completed: 7797 passed, 268 FAILED -LSR.l.json completed: 7044 passed, 1021 FAILED -LSR.w.json completed: 7512 passed, 553 FAILED +LSL.b.json completed: 7809 passed, 256 FAILED +LSL.l.json completed: 7056 passed, 1009 FAILED +LSL.w.json completed: 7523 passed, 542 FAILED +LSR.b.json completed: 7817 passed, 248 FAILED +LSR.l.json completed: 7072 passed, 993 FAILED +LSR.w.json completed: 7541 passed, 524 FAILED MOVE.b.json completed, all passed! MOVE.l.json completed: 5827 passed, 2238 FAILED MOVE.q.json completed, all passed! @@ -103,7 +103,7 @@ ROXL.w.json completed: 7892 passed, 173 FAILED ROXR.b.json completed: 8037 passed, 28 FAILED ROXR.l.json completed: 8022 passed, 43 FAILED ROXR.w.json completed: 7880 passed, 185 FAILED -RTE.json completed: 2047 passed, 6018 FAILED +RTE.json completed: 4011 passed, 4054 FAILED RTR.json completed: 4038 passed, 4027 FAILED RTS.json completed: 4008 passed, 4057 FAILED SBCD.json completed: 884 passed, 7181 FAILED @@ -125,5 +125,5 @@ TST.l.json completed, all passed! TST.w.json completed, all passed! UNLINK.json completed, all passed! -passed: 896112, failed: 103948, total 90% -completed in 15m 7s +passed: 899449, failed: 100611, total 90% +completed in 14m 6s diff --git a/tests/harte_tests/previous.txt b/tests/harte_tests/previous.txt index 6306094..2129a5e 100644 --- a/tests/harte_tests/previous.txt +++ b/tests/harte_tests/previous.txt @@ -1,4 +1,4 @@ -Last run on 2022-09-13 at commit 099b2fcb559afef16c91a65d084c00595a637597 +Last run on 2022-09-14 at commit a3fbcc7c16f80dd7801ceacf1d4a22a7bf88e9e1 ABCD.json completed: 301 passed, 7764 FAILED ADD.b.json completed, all passed! @@ -14,12 +14,12 @@ AND.l.json completed: 7779 passed, 286 FAILED AND.w.json completed: 7764 passed, 301 FAILED ANDItoCCR.json completed, all passed! ANDItoSR.json completed, all passed! -ASL.b.json completed: 7205 passed, 860 FAILED -ASL.l.json completed: 6446 passed, 1619 FAILED -ASL.w.json completed: 7035 passed, 1030 FAILED -ASR.b.json completed: 6316 passed, 1749 FAILED -ASR.l.json completed: 7007 passed, 1058 FAILED -ASR.w.json completed: 6740 passed, 1325 FAILED +ASL.b.json completed: 7238 passed, 827 FAILED +ASL.l.json completed: 6471 passed, 1594 FAILED +ASL.w.json completed: 7053 passed, 1012 FAILED +ASR.b.json completed: 6347 passed, 1718 FAILED +ASR.l.json completed: 7040 passed, 1025 FAILED +ASR.w.json completed: 6763 passed, 1302 FAILED BCHG.json completed, all passed! BCLR.json completed, all passed! BSET.json completed, all passed! @@ -37,7 +37,7 @@ CMPA.l.json completed, all passed! CMPA.w.json completed, all passed! DBcc.json completed: 6101 passed, 1964 FAILED DIVS.json completed: 3685 passed, 4380 FAILED -DIVU.json completed: 4368 passed, 3697 FAILED +DIVU.json completed: 5595 passed, 2470 FAILED EOR.b.json completed, all passed! EOR.l.json completed: 7519 passed, 546 FAILED EOR.w.json completed: 7525 passed, 540 FAILED @@ -49,7 +49,7 @@ EXT.w.json completed, all passed! JMP.json completed: 4259 passed, 3806 FAILED JSR.json completed: 4183 passed, 3882 FAILED LEA.json completed, all passed! -LINK.json completed: 7060 passed, 1005 FAILED +LINK.json completed, all passed! LSL.b.json completed: 7774 passed, 291 FAILED LSL.l.json completed: 7017 passed, 1048 FAILED LSL.w.json completed: 7494 passed, 571 FAILED @@ -125,5 +125,5 @@ TST.l.json completed, all passed! TST.w.json completed, all passed! UNLINK.json completed, all passed! -passed: 893717, failed: 106343, total 89% -completed in 14m 2s +passed: 896112, failed: 103948, total 90% +completed in 15m 7s