From c04f918bf17190c41271fca8f692fc6b11c92c11 Mon Sep 17 00:00:00 2001 From: Stovent Date: Sun, 14 Apr 2024 01:25:11 -0400 Subject: [PATCH] Update ffi with new exceptions + changelog --- CHANGELOG.md | 5 +++++ include/m68000/m68000-ffi.h | 6 +++--- include/m68000/m68000.h | 13 ++++++++++--- m68000-ffi/src/lib.rs | 35 +++++++++++++++++++---------------- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f62e33..b85ca26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Push the current opcode in SCC68070 long exception stack frame. + +### Changed +- Use `exception::Vector` instead of u8 for exceptions. ## [0.2.1] - 2023-08-28 ### Fixed diff --git a/include/m68000/m68000-ffi.h b/include/m68000/m68000-ffi.h index 6c6396d..ebb2215 100644 --- a/include/m68000/m68000-ffi.h +++ b/include/m68000/m68000-ffi.h @@ -21,7 +21,7 @@ typedef struct m68000_memory_result_t * * If used as the return value of `m68000_*_peek_next_word`, this field contains the exception vector that occured when trying to read the next word. */ - uint8_t exception; + m68000_vector_t exception; } m68000_memory_result_t; /** @@ -58,7 +58,7 @@ typedef struct m68000_exception_result_t /** * 0 if no exception occured, the vector number that occured otherwise. */ - uint8_t exception; + m68000_vector_t exception; } m68000_exception_result_t; /** @@ -92,7 +92,7 @@ typedef struct m68000_disassembler_exception_result_t /** * 0 if no exception occured, the vector number that occured otherwise. */ - uint8_t exception; + m68000_vector_t exception; } m68000_disassembler_exception_result_t; #ifdef __cplusplus diff --git a/include/m68000/m68000.h b/include/m68000/m68000.h index 423aeda..200af83 100644 --- a/include/m68000/m68000.h +++ b/include/m68000/m68000.h @@ -98,7 +98,11 @@ typedef enum m68000_size_t * * The `FormatError` and `OnChipInterrupt` vectors are only used by the SCC68070. */ -typedef enum m68000_vector_t +enum m68000_vector_t +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { ResetSspPc = 0, /** @@ -151,7 +155,10 @@ typedef enum m68000_vector_t Level6OnChipInterrupt, Level7OnChipInterrupt, UserInterrupt, -} m68000_vector_t; +}; +#ifndef __cplusplus +typedef uint8_t m68000_vector_t; +#endif // __cplusplus /** * Raw Brief Extension Word. @@ -565,7 +572,7 @@ typedef struct RotationDirectionSizeModeRegister_Body uint8_t _0; enum m68000_direction_t _1; enum m68000_size_t _2; - uint8_t _3; + bool _3; uint8_t _4; } RotationDirectionSizeModeRegister_Body; diff --git a/m68000-ffi/src/lib.rs b/m68000-ffi/src/lib.rs index caad7d0..2b45ade 100644 --- a/m68000-ffi/src/lib.rs +++ b/m68000-ffi/src/lib.rs @@ -118,7 +118,7 @@ pub struct m68000_exception_result_t { /// The number of cycles executed. pub cycles: usize, /// 0 if no exception occured, the vector number that occured otherwise. - pub exception: u8, + pub exception: Vector, } /// Return type of the `m68000_*_disassembler_interpreter` functions. @@ -140,7 +140,7 @@ pub struct m68000_disassembler_exception_result_t { /// The address of the instruction that has been executed if any. pub pc: u32, /// 0 if no exception occured, the vector number that occured otherwise. - pub exception: u8, + pub exception: Vector, } /// Return type of the memory callback functions. @@ -152,9 +152,12 @@ pub struct m68000_memory_result_t { /// Set to 0 if read successfully, set to 2 (Access Error) otherwise (Address errors are automatically detected by the library). /// /// If used as the return value of `m68000_*_peek_next_word`, this field contains the exception vector that occured when trying to read the next word. - pub exception: u8, + pub exception: Vector, } +/// No exception is 0 (same as Reset). +const NO_EXCEPTION: Vector = unsafe { Vector::from_raw(0) }; + /// Memory callbacks sent to the interpreter methods. /// /// Every member must be a valid function pointer, no pointer checks are done when calling the callbacks. @@ -181,7 +184,7 @@ pub struct m68000_callbacks_t { impl MemoryAccess for m68000_callbacks_t { fn get_byte(&mut self, addr: u32) -> Option { let res = (self.get_byte)(addr, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(res.data as u8) } else { None @@ -190,7 +193,7 @@ impl MemoryAccess for m68000_callbacks_t { fn get_word(&mut self, addr: u32) -> Option { let res = (self.get_word)(addr, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(res.data as u16) } else { None @@ -200,7 +203,7 @@ impl MemoryAccess for m68000_callbacks_t { fn get_long(&mut self, addr: u32) -> Option { let res = (self.get_long)(addr, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(res.data) } else { None @@ -209,7 +212,7 @@ impl MemoryAccess for m68000_callbacks_t { fn set_byte(&mut self, addr: u32, value: u8) -> Option<()> { let res = (self.set_byte)(addr, value, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(()) } else { None @@ -218,7 +221,7 @@ impl MemoryAccess for m68000_callbacks_t { fn set_word(&mut self, addr: u32, value: u16) -> Option<()> { let res = (self.set_word)(addr, value, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(()) } else { None @@ -227,7 +230,7 @@ impl MemoryAccess for m68000_callbacks_t { fn set_long(&mut self, addr: u32, value: u32) -> Option<()> { let res = (self.set_long)(addr, value, self.user_data); - if res.exception == 0 { + if res.exception == NO_EXCEPTION { Some(()) } else { None @@ -292,7 +295,7 @@ macro_rules! cinterface { pub extern "C" fn [](m68000: *mut M68000<$cpu_details>, memory: *mut m68000_callbacks_t, cycles: usize) -> m68000_exception_result_t { unsafe { let (cycles, vector) = (*m68000).cycle_until_exception(&mut *memory, cycles); - m68000_exception_result_t { cycles, exception: vector.unwrap_or(0) } + m68000_exception_result_t { cycles, exception: vector.unwrap_or(NO_EXCEPTION) } } } @@ -304,7 +307,7 @@ macro_rules! cinterface { pub extern "C" fn [](m68000: *mut M68000<$cpu_details>, memory: *mut m68000_callbacks_t) -> m68000_exception_result_t { unsafe { let (cycles, vector) = (*m68000).loop_until_exception_stop(&mut *memory); - m68000_exception_result_t { cycles, exception: vector.unwrap_or(0) } + m68000_exception_result_t { cycles, exception: vector.unwrap_or(NO_EXCEPTION) } } } @@ -324,7 +327,7 @@ macro_rules! cinterface { pub extern "C" fn [](m68000: *mut M68000<$cpu_details>, memory: *mut m68000_callbacks_t) -> m68000_exception_result_t { unsafe { let (cycles, vector) = (*m68000).interpreter_exception(&mut *memory); - m68000_exception_result_t { cycles, exception: vector.unwrap_or(0) } + m68000_exception_result_t { cycles, exception: vector.unwrap_or(NO_EXCEPTION) } } } @@ -381,7 +384,7 @@ macro_rules! cinterface { m68000_disassembler_exception_result_t { cycles, pc, - exception: vector.unwrap_or(0) , + exception: vector.unwrap_or(NO_EXCEPTION) , } } } @@ -401,7 +404,7 @@ macro_rules! cinterface { match (*m68000).get_next_word(&mut *memory) { Ok(data) => m68000_memory_result_t { data: data as u32, - exception: 0, + exception: NO_EXCEPTION, }, Err(vec) => m68000_memory_result_t { data: 0, @@ -418,7 +421,7 @@ macro_rules! cinterface { match (*m68000).get_next_long(&mut *memory) { Ok(data) => m68000_memory_result_t { data: data, - exception: 0, + exception: NO_EXCEPTION, }, Err(vec) => m68000_memory_result_t { data: 0, @@ -435,7 +438,7 @@ macro_rules! cinterface { match (*m68000).peek_next_word(&mut *memory) { Ok(data) => m68000_memory_result_t { data: data as u32, - exception: 0, + exception: NO_EXCEPTION, }, Err(vec) => m68000_memory_result_t { data: 0,