Skip to content

Instantly share code, notes, and snippets.

@nico-abram
Created June 22, 2019 22:46
Show Gist options
  • Save nico-abram/498f3c8b77c59f91eda6b8a2a55ef458 to your computer and use it in GitHub Desktop.
Save nico-abram/498f3c8b77c59f91eda6b8a2a55ef458 to your computer and use it in GitHub Desktop.
trait AsBoolSlice {
fn is_set(self, mask: u8) -> bool;
fn is_set_n(self, n: u8) -> bool;
fn as_bools(self) -> [bool; 8];
}
impl AsBoolSlice for u8 {
fn is_set(self, mask: u8) -> bool {
(self & mask) == mask
}
fn is_set_n(self, mask: u8) -> bool {
self.is_set(1u8 << mask)
}
fn as_bools(self) -> [bool; 8] {
[
self.is_set_n(7),
self.is_set_n(6),
self.is_set_n(5),
self.is_set_n(4),
self.is_set_n(3),
self.is_set_n(2),
self.is_set_n(1),
self.is_set_n(0),
]
}
}
pub fn decode_arm(&mut self, opcode: u32) -> fn(&mut Cpu, u32) -> () {
let bits27_20 = (opcode >> 20) as u8;
let bits11_4 = (opcode >> 4) as u8;
const T: bool = true;
const F: bool = false;
let (instruction, offset): (fn(&mut Self, u32) -> (), u32) =
match (bits27_20.as_bools(), bits11_4.as_bools()) {
([F, F, F, F, F, F, _, _], [_, _, _, _, T, F, F, T]) => (MUL, 0),
([F, F, F, F, T, _, _, _], [_, _, _, _, T, F, F, T]) => (MULL, 0),
([F, F, F, T, F, _, F, F], [F, F, F, F, T, F, F, T]) => (SWP, 0),
([F, F, F, _, _, F, _, _], [F, F, F, F, T, _, _, T]) => (HDT_RO, 0),
([F, F, F, _, _, T, _, _], [F, F, F, F, T, _, _, T]) => (HDT_IO, 0),
([F, T, T, _, _, _, _, _], [_, _, _, T, _, _, _, _]) => unimplemented!(
"Invalid (Undefined) opcode {:b} ({:x}) bits 27-20: {:x} bits 11-4: {:x} at pc {:x}",
opcode,
opcode,
bits27_20,
bits11_4,
self.pc
),
([F, T, _, _, _, _, _, _], _) => (SDT, 0),
([T, F, F, _, _, _, _, _], _) => (BDT, 0),
([T, T, F, _, _, _, _, _], _) => (CDT, 0),
([T, T, T, F, _, _, _, _], [_, _, _, F, _, _, _, _]) => (CDO, 0),
([T, T, T, F, _, _, _, _], [_, _, _, T, _, _, _, _]) => (CRT, 0),
([T, T, T, T, _, _, _, _], _) => (SWI, 0),
([T, F, T, _, _, _, _, _], _) => (B, 0),
([F, F, F, T, F, F, T, F], [T, T, T, T, F, F, F, T])
if (opcode & 0x000F_F000) == 0x000F_F000 =>
{
(BX, 0)
}
([F, F, _, _, _, _, _, _], _) => (PSR, 0),
_ => unimplemented!(
"Invalid opcode {:b} ({:x}) bits 27-20: {:x} bits 11-4: {:x} at pc {:x}",
opcode,
opcode,
bits27_20,
bits11_4,
self.pc
),
};
self.pc += offset;
instruction
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment