Inlining performance critical functions
This commit is contained in:
parent
2499eedfd2
commit
47a4b0c720
36
src/cpu.rs
36
src/cpu.rs
@ -58,10 +58,12 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn read_byte(&self, addr: u16) -> u8 {
|
fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.interconnect.read_byte(addr)
|
self.interconnect.read_byte(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn load_args(&mut self, num_args: u8) -> Box<[u8]> {
|
fn load_args(&mut self, num_args: u8) -> Box<[u8]> {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
for i in 0..num_args {
|
for i in 0..num_args {
|
||||||
@ -71,6 +73,7 @@ impl CPU {
|
|||||||
args.into_boxed_slice()
|
args.into_boxed_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_8bit_reg(&mut self, reg_id: usize, value: u8) {
|
fn set_8bit_reg(&mut self, reg_id: usize, value: u8) {
|
||||||
// Make sure that we skip the (HL) part.
|
// Make sure that we skip the (HL) part.
|
||||||
if reg_id == REG_N_A {
|
if reg_id == REG_N_A {
|
||||||
@ -85,6 +88,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_8bit_reg(&self, reg_id: usize) -> u8 {
|
fn get_8bit_reg(&self, reg_id: usize) -> u8 {
|
||||||
// Make sure that we skip the (HL) part.
|
// Make sure that we skip the (HL) part.
|
||||||
if reg_id == REG_N_A {
|
if reg_id == REG_N_A {
|
||||||
@ -99,6 +103,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn run_prefix_instruction(&mut self) {
|
fn run_prefix_instruction(&mut self) {
|
||||||
let instruction = self.read_byte(self.ip);
|
let instruction = self.read_byte(self.ip);
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
@ -464,10 +469,12 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_pair_value(&self, a: usize, b: usize) -> u16 {
|
fn get_pair_value(&self, a: usize, b: usize) -> u16 {
|
||||||
(self.get_8bit_reg(a) as u16) << 8 | self.get_8bit_reg(b) as u16
|
(self.get_8bit_reg(a) as u16) << 8 | self.get_8bit_reg(b) as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_pair_value(&mut self, a: usize, b: usize, value: u16) {
|
fn set_pair_value(&mut self, a: usize, b: usize, value: u16) {
|
||||||
self.set_8bit_reg(a, (value >> 8) as u8);
|
self.set_8bit_reg(a, (value >> 8) as u8);
|
||||||
self.set_8bit_reg(b, value as u8);
|
self.set_8bit_reg(b, value as u8);
|
||||||
@ -479,6 +486,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn call(&mut self, dst: u16) {
|
fn call(&mut self, dst: u16) {
|
||||||
let ip = self.ip;
|
let ip = self.ip;
|
||||||
self.push(ip);
|
self.push(ip);
|
||||||
@ -486,6 +494,7 @@ impl CPU {
|
|||||||
self.ip = dst;
|
self.ip = dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn call_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
fn call_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
||||||
let dst = to_u16(self.load_args(2));
|
let dst = to_u16(self.load_args(2));
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -499,6 +508,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ret_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
fn ret_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("RET {}", cond_str);
|
println!("RET {}", cond_str);
|
||||||
@ -511,6 +521,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn jmp_r(&mut self, addr: u8) {
|
fn jmp_r(&mut self, addr: u8) {
|
||||||
let off: i8 = addr as i8;
|
let off: i8 = addr as i8;
|
||||||
if off < 0 {
|
if off < 0 {
|
||||||
@ -520,6 +531,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn jmp_r_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
fn jmp_r_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
||||||
let t = self.load_args(1)[0];
|
let t = self.load_args(1)[0];
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -533,10 +545,12 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn jmp_p(&mut self, addr: u16) {
|
fn jmp_p(&mut self, addr: u16) {
|
||||||
self.ip = addr;
|
self.ip = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn jmp_p_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
fn jmp_p_condition(&mut self, cond_str: String, cond: bool) -> u8 {
|
||||||
let t = to_u16(self.load_args(2));
|
let t = to_u16(self.load_args(2));
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -550,6 +564,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn rst(&mut self, val: u8) -> u8 {
|
fn rst(&mut self, val: u8) -> u8 {
|
||||||
// Make sure this is correct.
|
// Make sure this is correct.
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -559,6 +574,7 @@ impl CPU {
|
|||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn pop_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
fn pop_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("POP {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
println!("POP {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
||||||
@ -567,6 +583,8 @@ impl CPU {
|
|||||||
self.set_pair_value(r1, r2, val);
|
self.set_pair_value(r1, r2, val);
|
||||||
12
|
12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn push_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
fn push_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
||||||
@ -576,6 +594,7 @@ impl CPU {
|
|||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn dec_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
fn dec_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("DEC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
println!("DEC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
||||||
@ -586,6 +605,7 @@ impl CPU {
|
|||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn inc_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
fn inc_rr(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("INC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
println!("INC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
|
||||||
@ -596,17 +616,20 @@ impl CPU {
|
|||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn push(&mut self, val: u16) {
|
fn push(&mut self, val: u16) {
|
||||||
self.interconnect.write_word(self.sp - 1, val);
|
self.interconnect.write_word(self.sp - 1, val);
|
||||||
self.sp -= 2;
|
self.sp -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn pop(&mut self) -> u16 {
|
fn pop(&mut self) -> u16 {
|
||||||
let v: u16 = self.interconnect.read_word(self.sp + 1);
|
let v: u16 = self.interconnect.read_word(self.sp + 1);
|
||||||
self.sp += 2;
|
self.sp += 2;
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 {
|
fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
// println!("LD {}, {}", REG_NAMES[reg_dst], REG_NAMES[reg_src])
|
// println!("LD {}, {}", REG_NAMES[reg_dst], REG_NAMES[reg_src])
|
||||||
@ -620,6 +643,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ld_r_v(&mut self, r: usize) -> u8 {
|
fn ld_r_v(&mut self, r: usize) -> u8 {
|
||||||
let val: u8 = self.load_args(1)[0];
|
let val: u8 = self.load_args(1)[0];
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -633,6 +657,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ld_rr_vv(&mut self, r1: usize, r2: usize) -> u8 {
|
fn ld_rr_vv(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
let val: u16 = to_u16(self.load_args(2));
|
let val: u16 = to_u16(self.load_args(2));
|
||||||
if self.debug {
|
if self.debug {
|
||||||
@ -642,6 +667,7 @@ impl CPU {
|
|||||||
12
|
12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn reg_inc(&mut self, reg_id: usize) -> u8 {
|
fn reg_inc(&mut self, reg_id: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("INC {}", REG_NAMES[reg_id]);
|
println!("INC {}", REG_NAMES[reg_id]);
|
||||||
@ -654,6 +680,7 @@ impl CPU {
|
|||||||
4
|
4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn add_rr_rr(&mut self, r1: usize, r2: usize, r3: usize, r4: usize) -> u8 {
|
fn add_rr_rr(&mut self, r1: usize, r2: usize, r3: usize, r4: usize) -> u8 {
|
||||||
let val1 = self.get_pair_value(r1, r2);
|
let val1 = self.get_pair_value(r1, r2);
|
||||||
let val2 = self.get_pair_value(r3, r4);
|
let val2 = self.get_pair_value(r3, r4);
|
||||||
@ -661,6 +688,7 @@ impl CPU {
|
|||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn reg_dec(&mut self, reg_id: usize) -> u8 {
|
fn reg_dec(&mut self, reg_id: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("DEC {}", REG_NAMES[reg_id]);
|
println!("DEC {}", REG_NAMES[reg_id]);
|
||||||
@ -674,6 +702,7 @@ impl CPU {
|
|||||||
4
|
4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ld_dref_rr_a(&mut self, r1: usize, r2: usize) -> u8 {
|
fn ld_dref_rr_a(&mut self, r1: usize, r2: usize) -> u8 {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("LD ({}{}), A", REG_NAMES[r1], REG_NAMES[r2]);
|
println!("LD ({}{}), A", REG_NAMES[r1], REG_NAMES[r2]);
|
||||||
@ -684,14 +713,17 @@ impl CPU {
|
|||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_flag(&mut self, flag: u8) {
|
fn set_flag(&mut self, flag: u8) {
|
||||||
self.flags |= flag;
|
self.flags |= flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn clear_flag(&mut self, flag: u8) {
|
fn clear_flag(&mut self, flag: u8) {
|
||||||
self.flags &= !flag;
|
self.flags &= !flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_clear_flag(&mut self, flag: u8, dep: bool) {
|
fn set_clear_flag(&mut self, flag: u8, dep: bool) {
|
||||||
if dep {
|
if dep {
|
||||||
self.set_flag(flag);
|
self.set_flag(flag);
|
||||||
@ -700,6 +732,7 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn int_(&mut self, val: u8){
|
fn int_(&mut self, val: u8){
|
||||||
if self.debug {
|
if self.debug {
|
||||||
println!("INT {:02X}", val);
|
println!("INT {:02X}", val);
|
||||||
@ -709,18 +742,21 @@ impl CPU {
|
|||||||
self.call(val as u16);
|
self.call(val as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ret(&mut self) {
|
fn ret(&mut self) {
|
||||||
let new_ip: u16 = self.pop();
|
let new_ip: u16 = self.pop();
|
||||||
//self.dump_stack();
|
//self.dump_stack();
|
||||||
self.ip = new_ip;
|
self.ip = new_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn reti(&mut self) -> u8 {
|
fn reti(&mut self) -> u8 {
|
||||||
self.ret();
|
self.ret();
|
||||||
self.ime = true;
|
self.ime = true;
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn handle_interrupt(&mut self, offset: u8, flag: u8) {
|
fn handle_interrupt(&mut self, offset: u8, flag: u8) {
|
||||||
// Remove interrupt requested flag
|
// Remove interrupt requested flag
|
||||||
let new_flag = self.interconnect.read_byte(0xFF0F) & !flag;
|
let new_flag = self.interconnect.read_byte(0xFF0F) & !flag;
|
||||||
|
|||||||
@ -112,11 +112,13 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_pixel(&mut self, x: u8, y: u8, color: sdl2::pixels::Color) {
|
fn set_pixel(&mut self, x: u8, y: u8, color: sdl2::pixels::Color) {
|
||||||
self.renderer.set_draw_color(color);
|
self.renderer.set_draw_color(color);
|
||||||
self.renderer.fill_rect(sdl2::rect::Rect::new((x as i32) * SCALE as i32, (y as i32) * SCALE as i32, SCALE as u32, SCALE as u32));
|
self.renderer.fill_rect(sdl2::rect::Rect::new((x as i32) * SCALE as i32, (y as i32) * SCALE as i32, SCALE as u32, SCALE as u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn vblank_interrupt(&mut self) -> bool {
|
pub fn vblank_interrupt(&mut self) -> bool {
|
||||||
// Returns whether or not a vblank interrupt should be done
|
// Returns whether or not a vblank interrupt should be done
|
||||||
// Yes, this is polling, and yes, this sucks.\
|
// Yes, this is polling, and yes, this sucks.\
|
||||||
@ -128,6 +130,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn stat_interrupt(&mut self) -> bool {
|
pub fn stat_interrupt(&mut self) -> bool {
|
||||||
if self.stat_interrupt {
|
if self.stat_interrupt {
|
||||||
self.stat_interrupt = false;
|
self.stat_interrupt = false;
|
||||||
@ -137,6 +140,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
||||||
match addr {
|
match addr {
|
||||||
0x8000 ... 0x9FFF => {
|
0x8000 ... 0x9FFF => {
|
||||||
@ -162,6 +166,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub fn read_byte(&self, addr: u16) -> u8 {
|
||||||
match addr {
|
match addr {
|
||||||
0x8000 ... 0x9FFF => self.vram[(addr - 0x8000) as usize],
|
0x8000 ... 0x9FFF => self.vram[(addr - 0x8000) as usize],
|
||||||
@ -181,7 +186,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we want to have a time delta here?
|
#[inline]
|
||||||
pub fn tick(&mut self, ticks: u16) {
|
pub fn tick(&mut self, ticks: u16) {
|
||||||
self.status &= 0xFC;
|
self.status &= 0xFC;
|
||||||
if self.control & CTRL_LCD_DISPLAY_ENABLE == 0 {
|
if self.control & CTRL_LCD_DISPLAY_ENABLE == 0 {
|
||||||
@ -270,6 +275,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn renderscan(&mut self) {
|
fn renderscan(&mut self) {
|
||||||
// Points to the background map offset to use.
|
// Points to the background map offset to use.
|
||||||
let background_map: usize;
|
let background_map: usize;
|
||||||
|
|||||||
@ -167,10 +167,12 @@ impl Interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_boot_rom(&self) -> bool {
|
pub fn is_boot_rom(&self) -> bool {
|
||||||
self.disable_bootrom == 0
|
self.disable_bootrom == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub fn read_byte(&self, addr: u16) -> u8 {
|
||||||
// TODO: Make this more beautiful.
|
// TODO: Make this more beautiful.
|
||||||
// TODO: if some flag set, use bios, otherwise only use rom
|
// TODO: if some flag set, use bios, otherwise only use rom
|
||||||
@ -241,6 +243,7 @@ impl Interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
||||||
// TODO: Make this more beautful
|
// TODO: Make this more beautful
|
||||||
/*
|
/*
|
||||||
@ -336,11 +339,13 @@ impl Interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn write_word(&mut self, addr: u16, val: u16) {
|
pub fn write_word(&mut self, addr: u16, val: u16) {
|
||||||
self.write_byte(addr, val as u8);
|
self.write_byte(addr, val as u8);
|
||||||
self.write_byte(addr + 1, (val >> 8) as u8);
|
self.write_byte(addr + 1, (val >> 8) as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn read_word(&self, addr: u16) -> u16 {
|
pub fn read_word(&self, addr: u16) -> u16 {
|
||||||
self.read_byte(addr) as u16 | (self.read_byte(addr + 1) as u16) << 8
|
self.read_byte(addr) as u16 | (self.read_byte(addr + 1) as u16) << 8
|
||||||
// (self.read_byte(addr) as u16) << 8 | (self.read_byte(addr + 1) as u16)
|
// (self.read_byte(addr) as u16) << 8 | (self.read_byte(addr + 1) as u16)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user