Fix RL(A) instruction

This commit is contained in:
Kevin Hamacher 2016-05-27 13:48:08 +02:00
parent f962fd76b6
commit c733c05e38
3 changed files with 65 additions and 9 deletions

View File

@ -102,8 +102,24 @@ impl CPU {
if self.debug {
println!("RL {}", REG_NAMES[reg_id]);
}
self.regs[REG_A].rotate_left(val as u32);
}
let carry = self.flags & FLAG_C > 0;
if !carry {
// No carry before, now we got a carry => set it
if self.regs[REG_A] & 0x80 == 0x80 {
self.set_flag(FLAG_C);
}
self.regs[REG_A] = val << 1;
} else {
if self.regs[REG_A] & 0x80 == 0 {
self.clear_flag(FLAG_C);
}
self.regs[REG_A] = val << 1 | 1;
}
self.clear_flag(FLAG_Z);
self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H);
},
0x40 ... 0x47 => {
// Test 0th bit
let reg_id = (instruction - 0x40) as usize;
@ -393,19 +409,22 @@ impl CPU {
if self.debug {
println!("RLA");
}
let carry = self.flags & FLAG_C == FLAG_C;
let carry = self.flags & FLAG_C > 0;
if !carry {
// No carry before, now we got a carry => set it
if self.regs[REG_A] & 0x80 == 0x80 {
self.flags |= FLAG_C
self.set_flag(FLAG_C);
}
self.regs[REG_A] = self.regs[REG_A] << 1;
} else {
if self.regs[REG_A] & 0x80 == 0 {
self.flags &= !FLAG_C;
self.clear_flag(FLAG_C);
}
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
},
0x18 => {

View File

@ -93,7 +93,10 @@ impl Display {
pub fn write_byte(&mut self, addr: u16, val: u8) {
match addr {
0x8000 ... 0x9FFF => self.vram[(addr - 0x8000) as usize] = val,
0x8000 ... 0x9FFF => {
println!("VRAM: Write {:02X} to {:04X}", val, addr);
self.vram[(addr - 0x8000) as usize] = val;
}
0xFF40 => self.control = val,
0xFF41 => self.status = val,
0xFF42 => self.scrolly = val,

View File

@ -9,6 +9,15 @@ use super::sound;
use super::timer;
use super::serial;
#[derive(Debug)]
enum MemoryBankControllerType {
None,
MBC1,
MBC2,
MBC3,
HuC1,
}
pub struct Interconnect {
bios: Box<[u8]>,
rom: Box<[u8]>,
@ -22,10 +31,24 @@ pub struct Interconnect {
infrared_com_port: u8,
serial: serial::Serial,
timer: timer::Timer,
bank_no: u16,
mbc_type: MemoryBankControllerType,
}
impl Interconnect {
pub fn new(bios: Box<[u8]>, rom: Box<[u8]>) -> Interconnect {
let mbc: MemoryBankControllerType = match rom[0x0147] {
0x00 | 0x08 ... 0x09 => MemoryBankControllerType::None,
// 0x01 ... 0x03 => MemoryBankControllerType::MBC1,
// 0x05 ... 0x06 => MemoryBankControllerType::MBC2,
// 0x0F ... 0x13 => MemoryBankControllerType::MBC3,
// 0xFF => MemoryBankControllerType::HuC1,
_ => panic!("Unsupported MBC type"),
};
println!("MBC Type: {:?}", &mbc);
Interconnect {
bios: bios,
rom: rom,
@ -40,6 +63,9 @@ impl Interconnect {
disable_bootrom: 0,
timer: timer::Timer::new(),
serial: serial::Serial::new(),
bank_no: 0,
mbc_type: mbc,
}
}
@ -65,14 +91,22 @@ impl Interconnect {
// TODO: if some flag set, use bios, otherwise only use rom
// For now, just use bios
match addr {
0x0000 ... 0x7FFF => {
0x0000 ... 0x3FFF => {
// TODO: Check if bios or cartridge (additional condition: isEnabled)
if addr < 0x100 && self.disable_bootrom == 0 {
self.bios[addr as usize]
} else {
self.rom[addr as usize]
let val: u8 = self.rom[addr as usize];
println!("Access {:04X} = {:02X}", addr, val);
val
}
}
},
0x4000 ... 0x7FFF => {
let abs_addr: usize = addr as usize + self.bank_no as usize * 0x4000;
let val: u8 = self.rom[abs_addr];
println!("Access {:04X}{:04X} = {:02X}", self.bank_no, addr, val);
val
},
0x8000 ... 0x9FFF => self.display.read_byte(addr),
0xC000 ... 0xDFFF => {
self.ram[(addr - 0xC000) as usize]