1 stable release
1.0.0 | Feb 17, 2019 |
---|
#186 in #emulator
5MB
101K
SLoC
Contains (WOFF font, 24KB) glyphicons-halflings-regular.woff
rust-armv6k
ARMv6K emulator for Rust. Uses Dynarmic.
Coprocessors or page tables aren't supported.
Usage Example
use armv6k;
static mut MEMORY: [u8; 2048] = [0; 2048];
static mut TICKS_LEFT: u64 = 0;
unsafe extern fn read_8(vaddr: usize) -> u8 {
if vaddr >= MEMORY.len() {
panic!("Invalid address: {:08X}", vaddr);
}
MEMORY[vaddr]
}
unsafe extern fn read_16(vaddr: usize) -> u16 {
(read_8(vaddr) as u16) | (read_8(vaddr + 1) as u16) << 8
}
unsafe extern fn read_32(vaddr: usize) -> u32 {
(read_16(vaddr) as u32) | (read_16(vaddr + 2) as u32) << 16
}
unsafe extern fn read_64(vaddr: usize) -> u64 {
(read_32(vaddr) as u64) | (read_16(vaddr + 4) as u64) << 32
}
unsafe extern fn write_8(vaddr: usize, value: u8) {
if vaddr >= MEMORY.len() {
panic!("Invalid address: {:08X}", vaddr);
}
MEMORY[vaddr] = value;
}
unsafe extern fn write_16(vaddr: usize, value: u16) {
write_8(vaddr, value as u8);
write_8(vaddr + 1, (value >> 8) as u8);
}
unsafe extern fn write_32(vaddr: usize, value: u32) {
write_16(vaddr, value as u16);
write_16(vaddr + 2, (value >> 16) as u16);
}
unsafe extern fn write_64(vaddr: usize, value: u64) {
write_32(vaddr, value as u32);
write_32(vaddr + 4, (value >> 32) as u32);
}
unsafe extern fn add_ticks(ticks: u64) {
if ticks > TICKS_LEFT {
TICKS_LEFT = 0;
return;
}
TICKS_LEFT -= ticks;
}
unsafe extern fn call_svc(_swi: u32) {}
unsafe extern fn exception_raised(_pc: u32, _exception: i32) {}
unsafe extern fn get_ticks_remaining() -> u64 {
return TICKS_LEFT
}
unsafe extern fn interpreter_fallback(_pc: u32, _num_instructions: usize) {}
fn main() {
unsafe {
armv6k::Initialize(true, true);
write_16(0, 0x0088);
write_16(2, 0xE7FE);
armv6k::SetRegister(0, 1);
armv6k::SetRegister(1, 2);
armv6k::SetRegister(15, 0);
armv6k::SetCpsr(0x00000030);
armv6k::SetAddTicks(add_ticks);
armv6k::SetCallSVC(call_svc);
armv6k::SetExceptionRaised(exception_raised);
armv6k::SetMemoryRead8(read_8);
armv6k::SetMemoryRead16(read_16);
armv6k::SetMemoryRead32(read_32);
armv6k::SetMemoryRead64(read_64);
armv6k::SetMemoryWrite8(write_8);
armv6k::SetMemoryWrite16(write_16);
armv6k::SetMemoryWrite32(write_32);
armv6k::SetMemoryWrite64(write_64);
armv6k::SetGetTicksRemaining(get_ticks_remaining);
armv6k::SetInterpreterFallback(interpreter_fallback);
armv6k::Run();
println!("R0: {}", armv6k::GetRegister(0));
}
}