Add input; Add RLCA
This commit is contained in:
parent
44c8b2e7d8
commit
1ad3d47c88
@ -112,7 +112,7 @@ impl Cartridge {
|
|||||||
match val {
|
match val {
|
||||||
0x0A => self.ram_rtc_enabled = true,
|
0x0A => self.ram_rtc_enabled = true,
|
||||||
0x00 => self.ram_rtc_enabled = false,
|
0x00 => self.ram_rtc_enabled = false,
|
||||||
_ => panic!("Unknown MBC value {:02X} for {:04X}", val, addr)
|
_ => println!("Unknown MBC value {:02X} for {:04X}", val, addr)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
0x2000 ... 0x3FFF => self.bank_no = val & 0x7F,
|
0x2000 ... 0x3FFF => self.bank_no = val & 0x7F,
|
||||||
|
|||||||
16
src/cpu.rs
16
src/cpu.rs
@ -790,7 +790,21 @@ impl CPU {
|
|||||||
0x05 => self.reg_dec(REG_N_B),
|
0x05 => self.reg_dec(REG_N_B),
|
||||||
0x06 => self.ld_r_v(REG_N_B),
|
0x06 => self.ld_r_v(REG_N_B),
|
||||||
0x07 => {
|
0x07 => {
|
||||||
panic!("RLCA, not implemented");
|
if self.debug {
|
||||||
|
println!("RLCA");
|
||||||
|
}
|
||||||
|
let val = self.regs[REG_A];
|
||||||
|
let carry = val & 0x80 == 0x80;
|
||||||
|
self.set_clear_flag(FLAG_C, carry);
|
||||||
|
if !carry {
|
||||||
|
self.regs[REG_A] = self.regs[REG_A] << 1;
|
||||||
|
} else {
|
||||||
|
self.regs[REG_A] = self.regs[REG_A] << 1 | 1;
|
||||||
|
}
|
||||||
|
self.clear_flag(FLAG_Z);
|
||||||
|
self.clear_flag(FLAG_N);
|
||||||
|
self.clear_flag(FLAG_H);
|
||||||
|
4
|
||||||
}
|
}
|
||||||
0x08 => {
|
0x08 => {
|
||||||
let a: u16 = to_u16(self.load_args(2));
|
let a: u16 = to_u16(self.load_args(2));
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
extern crate sdl2;
|
extern crate sdl2;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use self::sdl2::event::Event;
|
|
||||||
use self::sdl2::keyboard::Keycode;
|
|
||||||
|
|
||||||
// Internal ram size
|
// Internal ram size
|
||||||
const VRAM_SIZE: usize = 0x2000;
|
const VRAM_SIZE: usize = 0x2000;
|
||||||
|
|
||||||
@ -67,7 +64,7 @@ pub struct Display {
|
|||||||
|
|
||||||
renderer: sdl2::render::Renderer<'static>,
|
renderer: sdl2::render::Renderer<'static>,
|
||||||
|
|
||||||
event_pump: sdl2::EventPump,
|
pub event_pump: sdl2::EventPump,
|
||||||
|
|
||||||
vblank_fired: bool,
|
vblank_fired: bool,
|
||||||
stat_fired: bool,
|
stat_fired: bool,
|
||||||
@ -242,16 +239,6 @@ impl Display {
|
|||||||
} else {
|
} else {
|
||||||
self.status &= !(1 << 2);
|
self.status &= !(1 << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the window is responsive:
|
|
||||||
for event in self.event_pump.poll_iter() {
|
|
||||||
match event {
|
|
||||||
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
|
||||||
panic!("TODO: Proper shutdown");
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderscan(&mut self) {
|
fn renderscan(&mut self) {
|
||||||
|
|||||||
@ -6,12 +6,35 @@ pub const INTERRUPT_TIMER_OVERFLOW: u8 = 1 << 2;
|
|||||||
pub const INTERRUPT_DISPLAY_STAT: u8 = 1 << 1;
|
pub const INTERRUPT_DISPLAY_STAT: u8 = 1 << 1;
|
||||||
pub const INTERRUPT_DISPLAY_VBLANK: u8 = 1 << 0;
|
pub const INTERRUPT_DISPLAY_VBLANK: u8 = 1 << 0;
|
||||||
|
|
||||||
|
const KEY_SPECIAL: u8 = 1 << 5;
|
||||||
|
const KEY_REGULAR: u8 = 1 << 4;
|
||||||
|
|
||||||
|
const KEY_DOWN: u8 = 1 << 3;
|
||||||
|
const KEY_UP: u8 = 1 << 2;
|
||||||
|
const KEY_LEFT: u8 = 1 << 1;
|
||||||
|
const KEY_RIGHT: u8 = 1 << 0;
|
||||||
|
|
||||||
|
const KEY_START: u8 = 1 << 3;
|
||||||
|
const KEY_SELECT: u8 = 1 << 2;
|
||||||
|
const KEY_B: u8 = 1 << 1;
|
||||||
|
const KEY_A: u8 = 1 << 0;
|
||||||
|
|
||||||
use super::display;
|
use super::display;
|
||||||
use super::sound;
|
use super::sound;
|
||||||
use super::timer;
|
use super::timer;
|
||||||
use super::serial;
|
use super::serial;
|
||||||
use super::cartridge;
|
use super::cartridge;
|
||||||
|
|
||||||
|
extern crate sdl2;
|
||||||
|
|
||||||
|
use self::sdl2::event::Event;
|
||||||
|
use self::sdl2::keyboard::Keycode;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Key {
|
||||||
|
UP, LEFT, DOWN, RIGHT, START, SELECT, A, B
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Interconnect {
|
pub struct Interconnect {
|
||||||
bios: Box<[u8]>,
|
bios: Box<[u8]>,
|
||||||
cartridge: cartridge::Cartridge,
|
cartridge: cartridge::Cartridge,
|
||||||
@ -31,6 +54,10 @@ pub struct Interconnect {
|
|||||||
vram_dma_source_low: u8,
|
vram_dma_source_low: u8,
|
||||||
vram_dma_destination_high: u8,
|
vram_dma_destination_high: u8,
|
||||||
vram_dma_destination_low: u8,
|
vram_dma_destination_low: u8,
|
||||||
|
|
||||||
|
joy_regular_keys: u8,
|
||||||
|
joy_special_keys: u8,
|
||||||
|
joy_switch: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interconnect {
|
impl Interconnect {
|
||||||
@ -55,6 +82,39 @@ impl Interconnect {
|
|||||||
vram_dma_source_low: 0,
|
vram_dma_source_low: 0,
|
||||||
vram_dma_destination_high: 0,
|
vram_dma_destination_high: 0,
|
||||||
vram_dma_destination_low: 0,
|
vram_dma_destination_low: 0,
|
||||||
|
|
||||||
|
// No keys pushed by default
|
||||||
|
joy_regular_keys: 0x0F,
|
||||||
|
joy_special_keys: 0x0F,
|
||||||
|
joy_switch: 0x30,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn press_key(&mut self, key: Key) {
|
||||||
|
println!("Press key {:?}", &key);
|
||||||
|
match key {
|
||||||
|
Key::UP => self.joy_regular_keys &= !KEY_UP,
|
||||||
|
Key::DOWN => self.joy_regular_keys &= !KEY_DOWN,
|
||||||
|
Key::RIGHT => self.joy_regular_keys &= !KEY_RIGHT,
|
||||||
|
Key::LEFT => self.joy_regular_keys &= !KEY_LEFT,
|
||||||
|
Key::START => self.joy_special_keys &= !KEY_START,
|
||||||
|
Key::SELECT => self.joy_special_keys &= !KEY_SELECT,
|
||||||
|
Key::A => self.joy_special_keys &= !KEY_A,
|
||||||
|
Key::B => self.joy_special_keys &= !KEY_B,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release_key(&mut self, key: Key) {
|
||||||
|
println!("Release key {:?}", &key);
|
||||||
|
match key {
|
||||||
|
Key::UP => self.joy_regular_keys |= KEY_UP,
|
||||||
|
Key::DOWN => self.joy_regular_keys |= KEY_DOWN,
|
||||||
|
Key::RIGHT => self.joy_regular_keys |= KEY_RIGHT,
|
||||||
|
Key::LEFT => self.joy_regular_keys |= KEY_LEFT,
|
||||||
|
Key::START => self.joy_special_keys |= KEY_START,
|
||||||
|
Key::SELECT => self.joy_special_keys |= KEY_SELECT,
|
||||||
|
Key::A => self.joy_special_keys |= KEY_A,
|
||||||
|
Key::B => self.joy_special_keys |= KEY_B,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +134,37 @@ impl Interconnect {
|
|||||||
if self.timer.timer_interrupt() {
|
if self.timer.timer_interrupt() {
|
||||||
self.interrupt_request_flags |= INTERRUPT_TIMER_OVERFLOW;
|
self.interrupt_request_flags |= INTERRUPT_TIMER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the window is responsive:
|
||||||
|
loop {
|
||||||
|
if let Some(event) = self.display.event_pump.poll_event(){
|
||||||
|
match event {
|
||||||
|
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||||
|
panic!("TODO: Proper shutdown");
|
||||||
|
},
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Left), .. } => self.press_key(Key::LEFT),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Down), .. } => self.press_key(Key::DOWN),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Up), .. } => self.press_key(Key::UP),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Right), .. } => self.press_key(Key::RIGHT),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::A), .. } => self.press_key(Key::START),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::S), .. } => self.press_key(Key::SELECT),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Z), .. } => self.press_key(Key::A),
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::X), .. } => self.press_key(Key::B),
|
||||||
|
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::Left), .. } => self.release_key(Key::LEFT),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::Down), .. } => self.release_key(Key::DOWN),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::Up), .. } => self.release_key(Key::UP),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::Right), .. } => self.release_key(Key::RIGHT),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::A), .. } => self.release_key(Key::START),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::S), .. } => self.release_key(Key::SELECT),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::Z), .. } => self.release_key(Key::A),
|
||||||
|
Event::KeyUp { keycode: Some(Keycode::X), .. } => self.release_key(Key::B),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_boot_rom(&self) -> bool {
|
pub fn is_boot_rom(&self) -> bool {
|
||||||
@ -101,7 +192,16 @@ impl Interconnect {
|
|||||||
0xD000 ... 0xDFFF => {
|
0xD000 ... 0xDFFF => {
|
||||||
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000]
|
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000]
|
||||||
}
|
}
|
||||||
0xFF00 => 0xFF, // TODO: This is the input stuff
|
0xFF00 => {
|
||||||
|
if self.joy_switch & KEY_REGULAR == 0 {
|
||||||
|
self.joy_regular_keys
|
||||||
|
} else if self.joy_switch & KEY_SPECIAL == 0 {
|
||||||
|
self.joy_special_keys
|
||||||
|
} else {
|
||||||
|
println!("Reading none from joystick?");
|
||||||
|
0xFF
|
||||||
|
}
|
||||||
|
}
|
||||||
0xFF01 ... 0xFF02 => self.serial.read_byte(addr),
|
0xFF01 ... 0xFF02 => self.serial.read_byte(addr),
|
||||||
0xFF04 ... 0xFF07 => self.timer.read_byte(addr),
|
0xFF04 ... 0xFF07 => self.timer.read_byte(addr),
|
||||||
0xFF0F => {
|
0xFF0F => {
|
||||||
@ -166,6 +266,10 @@ impl Interconnect {
|
|||||||
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000] = val;
|
self.ram[(addr - 0xD000) as usize + self.wram_bank as usize * 0x1000] = val;
|
||||||
}
|
}
|
||||||
0xFE00 ... 0xFE9F => self.display.write_byte(addr, val), // OAM
|
0xFE00 ... 0xFE9F => self.display.write_byte(addr, val), // OAM
|
||||||
|
0xFF00 => {
|
||||||
|
// Joystick select
|
||||||
|
self.joy_switch = val;
|
||||||
|
}
|
||||||
0xFF01 ... 0xFF02 => self.serial.write_byte(addr, val),
|
0xFF01 ... 0xFF02 => self.serial.write_byte(addr, val),
|
||||||
0xFF04 ... 0xFF07 => self.timer.write_byte(addr, val),
|
0xFF04 ... 0xFF07 => self.timer.write_byte(addr, val),
|
||||||
0xFF0F => {
|
0xFF0F => {
|
||||||
@ -213,7 +317,11 @@ impl Interconnect {
|
|||||||
if val > 7 {
|
if val > 7 {
|
||||||
panic!("R u sure this is correct?");
|
panic!("R u sure this is correct?");
|
||||||
}
|
}
|
||||||
self.wram_bank = val;
|
if val == 0 {
|
||||||
|
self.wram_bank = 1;
|
||||||
|
} else {
|
||||||
|
self.wram_bank = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0xFF80 ... 0xFFFE => {
|
0xFF80 ... 0xFFFE => {
|
||||||
self.hiram[(addr - 0xFF80) as usize] = val;
|
self.hiram[(addr - 0xFF80) as usize] = val;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user