Skip to content

Commit ece3e30

Browse files
committed
Rework GDB stub, general fixes
- The GDB stub and associated CPU debugging interfaces were reworked: - The stub now supports non-stop mode, proper stopping and should be generally more stable - Registers can be written to from GDB and should update the CPU's state correctly - (The CPU now automatically stops when hitting a debug hook unless restarted by the debugger) - (Undefined instruction hooks can now properly inspect the faulting instruction, to handle custom software breakpoint instructions) - Properly fixed some style inconsistencies and suppressed clippy warnings: - Functions' `const` markers were removed where unneeded/illogical - Raw pointer casts were converted from `as *const/mut T` to `.cast()` - Fixed a VRAM mapping bug that could cause panics when bank I was mapped - Fixed a panic in the code to display the CPU state debug views - Changed the behavior of the disassembly debug view to focus on the current instruction (PC - 4 or PC - 8) instead of PC - Fixed a crash on macOS due to accessing the window's associated NSView as an NSWindow instead of the window itself
1 parent f3a29da commit ece3e30

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1897
-1206
lines changed

TODO.md

-3
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,4 @@
100100
# Non-essential but wanted additions
101101

102102
## Frontends
103-
- Hardware 3D renderer
104-
- Configuration editor
105103
- General UI polish
106-
- Savestate selection and management UI

core/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[inline]
2-
const fn arm_shift_ty_to_str(shift_ty: arm_decoder::arm::ShiftTy) -> &'static str {
2+
fn arm_shift_ty_to_str(shift_ty: arm_decoder::arm::ShiftTy) -> &'static str {
33
[
44
"ShiftTy::Lsl",
55
"ShiftTy::Lsr",

core/src/audio.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,12 @@ impl Audio {
429429
.handle_sample_chunk(&mut emu.audio.sample_chunk);
430430
}
431431
}
432+
let cur_time = emu.arm7.schedule.cur_time();
432433
emu.arm7.schedule.schedule_event(
433434
arm7::event_slots::AUDIO,
434-
time + arm7::Timestamp(CYCLES_PER_SAMPLE),
435+
arm7::Timestamp(
436+
time.0.max(cur_time.0 - cur_time.0 % CYCLES_PER_SAMPLE) + CYCLES_PER_SAMPLE,
437+
),
435438
);
436439
}
437440

@@ -542,7 +545,12 @@ impl Audio {
542545
}
543546

544547
if let Some(custom_sample_rate) = emu.audio.custom_sample_rate {
545-
emu.audio.next_scaled_sample_index += 1;
548+
let cur_time = emu.arm7.schedule.cur_time();
549+
let next_scaled_sample_index = (emu.audio.next_scaled_sample_index + 1).max(
550+
(cur_time.0 as u128 * custom_sample_rate.get() as u128 / SYS_CLOCK_RATE as u128)
551+
as u64,
552+
);
553+
emu.audio.next_scaled_sample_index = next_scaled_sample_index;
546554
emu.arm7.schedule.schedule_event(
547555
arm7::event_slots::XQ_AUDIO,
548556
arm7::Timestamp(

core/src/cpu/arm7.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ pub struct Arm7<E: Engine> {
4545
last_dma_words: [u32; 4],
4646
#[cfg(feature = "debugger-hooks")]
4747
#[savestate(skip)]
48-
pub stopped: bool,
48+
pub is_stopped: bool,
4949
#[cfg(feature = "debugger-hooks")]
5050
#[savestate(skip)]
51-
pub(crate) stopped_by_debug_hook: bool,
51+
pub(crate) was_stopped_by_debug_hook: bool,
5252
}
5353

5454
impl<E: Engine> Arm7<E> {
@@ -118,9 +118,9 @@ impl<E: Engine> Arm7<E> {
118118
},
119119
last_dma_words: [0; 4],
120120
#[cfg(feature = "debugger-hooks")]
121-
stopped: false,
121+
is_stopped: false,
122122
#[cfg(feature = "debugger-hooks")]
123-
stopped_by_debug_hook: false,
123+
was_stopped_by_debug_hook: false,
124124
}
125125
}
126126

core/src/cpu/arm7/bus/access.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ pub fn read_8<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32) -> u8 {
1717
#[inline]
1818
pub fn read_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32) -> u16 {
1919
if let Some(ptr) = emu.arm7.bus_ptrs.read(addr) {
20-
unsafe {
21-
u16::read_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !1)) as usize) as *const _)
22-
}
20+
unsafe { u16::read_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !1)) as usize).cast()) }
2321
} else {
2422
fallback::read_16::<A, _>(emu, addr)
2523
}
@@ -28,9 +26,7 @@ pub fn read_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32) -> u16 {
2826
#[inline]
2927
pub fn read_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32) -> u32 {
3028
if let Some(ptr) = emu.arm7.bus_ptrs.read(addr) {
31-
unsafe {
32-
u32::read_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !3)) as usize) as *const _)
33-
}
29+
unsafe { u32::read_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !3)) as usize).cast()) }
3430
} else {
3531
fallback::read_32::<A, _>(emu, addr)
3632
}
@@ -49,7 +45,7 @@ pub fn write_8<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u8)
4945
pub fn write_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u16) {
5046
if let Some(ptr) = emu.arm7.bus_ptrs.write(addr) {
5147
unsafe {
52-
value.write_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !1)) as usize) as *mut _);
48+
value.write_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !1)) as usize).cast());
5349
};
5450
} else {
5551
fallback::write_16::<A, _>(emu, addr, value);
@@ -60,7 +56,7 @@ pub fn write_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u1
6056
pub fn write_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u32) {
6157
if let Some(ptr) = emu.arm7.bus_ptrs.write(addr) {
6258
unsafe {
63-
value.write_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !3)) as usize) as *mut _);
59+
value.write_le_aligned(ptr.add((addr & (Ptrs::PAGE_MASK & !3)) as usize).cast());
6460
};
6561
} else {
6662
fallback::write_32::<A, _>(emu, addr, value);

core/src/cpu/arm7/bus/fallback.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ pub fn read_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32) -> u16
296296
emu.swram
297297
.arm7_ptr()
298298
.add(addr as usize & emu.swram.arm7_mask() as usize)
299-
as *const u16,
299+
.cast(),
300300
)
301301
}
302302
} else {
@@ -516,7 +516,7 @@ pub fn read_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32) -> u32
516516
emu.swram
517517
.arm7_ptr()
518518
.add(addr as usize & emu.swram.arm7_mask() as usize)
519-
as *const u32,
519+
.cast(),
520520
)
521521
}
522522
} else {
@@ -958,7 +958,7 @@ pub fn write_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32, value
958958
emu.swram
959959
.arm7_ptr()
960960
.add(addr as usize & emu.swram.arm7_mask() as usize)
961-
as *mut u16,
961+
.cast(),
962962
);
963963
}
964964
} else {
@@ -1308,7 +1308,7 @@ pub fn write_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32, value
13081308
emu.swram
13091309
.arm7_ptr()
13101310
.add(addr as usize & emu.swram.arm7_mask() as usize)
1311-
as *mut u32,
1311+
.cast(),
13121312
);
13131313
}
13141314
} else {

core/src/cpu/arm9.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ pub struct Arm9<E: Engine> {
6262
pub sqrt_engine: SqrtEngine,
6363
#[cfg(feature = "debugger-hooks")]
6464
#[savestate(skip)]
65-
pub stopped: bool,
65+
pub is_stopped: bool,
6666
#[cfg(feature = "debugger-hooks")]
6767
#[savestate(skip)]
68-
pub(crate) stopped_by_debug_hook: bool,
68+
pub(crate) was_stopped_by_debug_hook: bool,
6969
}
7070

7171
impl<E: Engine> Arm9<E> {
@@ -137,9 +137,9 @@ impl<E: Engine> Arm9<E> {
137137
div_engine,
138138
sqrt_engine,
139139
#[cfg(feature = "debugger-hooks")]
140-
stopped: false,
140+
is_stopped: false,
141141
#[cfg(feature = "debugger-hooks")]
142-
stopped_by_debug_hook: false,
142+
was_stopped_by_debug_hook: false,
143143
}
144144
}
145145

core/src/cpu/arm9/bus/access.rs

+44-32
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,17 @@ pub fn read_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32) -> u16 {
9797
emu.arm9.cp15.ptrs.read_data(addr)
9898
} {
9999
unsafe {
100-
u16::read_le_aligned(ptr.add(
101-
(addr
102-
& (if A::IS_DMA {
103-
SysBusPtrs::PAGE_MASK
104-
} else {
105-
Ptrs::PAGE_MASK
106-
} & !1)) as usize,
107-
) as *const _)
100+
u16::read_le_aligned(
101+
ptr.add(
102+
(addr
103+
& (if A::IS_DMA {
104+
SysBusPtrs::PAGE_MASK
105+
} else {
106+
Ptrs::PAGE_MASK
107+
} & !1)) as usize,
108+
)
109+
.cast(),
110+
)
108111
}
109112
} else {
110113
#[cfg(feature = "debugger-hooks")]
@@ -126,14 +129,17 @@ pub fn read_32<A: AccessType, E: Engine, const CODE: bool>(emu: &mut Emu<E>, add
126129
emu.arm9.cp15.ptrs.read_data(addr)
127130
} {
128131
unsafe {
129-
u32::read_le_aligned(ptr.add(
130-
(addr
131-
& (if A::IS_DMA {
132-
SysBusPtrs::PAGE_MASK
133-
} else {
134-
Ptrs::PAGE_MASK
135-
} & !3)) as usize,
136-
) as *const _)
132+
u32::read_le_aligned(
133+
ptr.add(
134+
(addr
135+
& (if A::IS_DMA {
136+
SysBusPtrs::PAGE_MASK
137+
} else {
138+
Ptrs::PAGE_MASK
139+
} & !3)) as usize,
140+
)
141+
.cast(),
142+
)
137143
}
138144
} else {
139145
#[cfg(feature = "debugger-hooks")]
@@ -182,14 +188,17 @@ pub fn write_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u1
182188
emu.arm9.cp15.ptrs.write_16_32(addr)
183189
} {
184190
unsafe {
185-
value.write_le_aligned(ptr.add(
186-
(addr
187-
& (if A::IS_DMA {
188-
SysBusPtrs::PAGE_MASK
189-
} else {
190-
Ptrs::PAGE_MASK
191-
} & !1)) as usize,
192-
) as *mut _);
191+
value.write_le_aligned(
192+
ptr.add(
193+
(addr
194+
& (if A::IS_DMA {
195+
SysBusPtrs::PAGE_MASK
196+
} else {
197+
Ptrs::PAGE_MASK
198+
} & !1)) as usize,
199+
)
200+
.cast(),
201+
);
193202
}
194203
} else {
195204
emu.arm9.engine_data.invalidate_word(addr);
@@ -210,14 +219,17 @@ pub fn write_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, addr: u32, value: u3
210219
emu.arm9.cp15.ptrs.write_16_32(addr)
211220
} {
212221
unsafe {
213-
value.write_le_aligned(ptr.add(
214-
(addr
215-
& (if A::IS_DMA {
216-
SysBusPtrs::PAGE_MASK
217-
} else {
218-
Ptrs::PAGE_MASK
219-
} & !3)) as usize,
220-
) as *mut _);
222+
value.write_le_aligned(
223+
ptr.add(
224+
(addr
225+
& (if A::IS_DMA {
226+
SysBusPtrs::PAGE_MASK
227+
} else {
228+
Ptrs::PAGE_MASK
229+
} & !3)) as usize,
230+
)
231+
.cast(),
232+
);
221233
}
222234
} else {
223235
emu.arm9.engine_data.invalidate_word(addr);

core/src/cpu/arm9/bus/fallback.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ pub fn read_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32) -> u16
257257
emu.swram
258258
.arm9_r_ptr()
259259
.add(addr as usize & emu.swram.arm9_mask() as usize)
260-
as *const u16,
260+
.cast(),
261261
)
262262
},
263263

@@ -469,7 +469,7 @@ pub fn read_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32) -> u32
469469
emu.swram
470470
.arm9_r_ptr()
471471
.add(addr as usize & emu.swram.arm9_mask() as usize)
472-
as *const u32,
472+
.cast(),
473473
)
474474
},
475475

@@ -946,7 +946,7 @@ pub fn write_16<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32, value
946946
emu.swram
947947
.arm9_w_ptr()
948948
.add(addr as usize & emu.swram.arm9_mask() as usize)
949-
as *mut u16,
949+
.cast(),
950950
);
951951
},
952952

@@ -1370,7 +1370,7 @@ pub fn write_32<A: AccessType, E: Engine>(emu: &mut Emu<E>, mut addr: u32, mut v
13701370
emu.swram
13711371
.arm9_w_ptr()
13721372
.add(addr as usize & emu.swram.arm9_mask() as usize)
1373-
as *mut u32,
1373+
.cast(),
13741374
);
13751375
},
13761376

core/src/cpu/arm9/cp15/perms.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ macro_rules! def_checks {
4343
($($fn_ident: ident, $unpriv_mask_ident: ident);*$(;)?) => {
4444
$(
4545
#[inline]
46-
pub const fn $fn_ident(&self, addr: u32, privileged: bool) -> bool {
46+
pub fn $fn_ident(&self, addr: u32, privileged: bool) -> bool {
4747
self.0[(addr >> Self::PAGE_SHIFT) as usize]
4848
& perms::$unpriv_mask_ident >> ((privileged as u8) << 2)
4949
!= 0

core/src/cpu/arm9/cp15/ptrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ impl Ptrs {
361361
self.$arr_ident[i] = unsafe {
362362
sys_bus_ptrs.ptrs()[i / Self::ENTRIES_PER_SYS_ENTRY]
363363
.add((i & (Self::ENTRIES_PER_SYS_ENTRY - 1)) << Self::PAGE_SHIFT)
364-
} as _;
364+
};
365365
}
366366
}};
367367
}

core/src/cpu/debug.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ macro_rules! check_watchpoints {
5151
{
5252
use $crate::cpu::Schedule;
5353
$core.schedule.set_target_time($core.schedule.cur_time());
54-
$core.stopped_by_debug_hook = true;
54+
$core.was_stopped_by_debug_hook = true;
55+
$core.is_stopped = true;
5556
}
5657
}
5758
}
@@ -182,7 +183,7 @@ impl<T: ?Sized> Drop for Hook<T> {
182183
}
183184

184185
pub type SwiHook<E> = Hook<dyn FnMut(&mut Emu<E>, u8) -> bool>;
185-
pub type UndefHook<E> = Hook<dyn FnMut(&mut Emu<E>) -> bool>;
186+
pub type UndefHook<E> = Hook<dyn FnMut(&mut Emu<E>, u32, bool) -> bool>;
186187
pub type PrefetchAbortHook<E> = Hook<dyn FnMut(&mut Emu<E>) -> bool>;
187188
pub type DataAbortHook<E> = Hook<dyn FnMut(&mut Emu<E>, u32) -> bool>;
188189
pub type BreakpointHook<E> = Hook<dyn FnMut(&mut Emu<E>, u32) -> bool>;

0 commit comments

Comments
 (0)