Newer
Older
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 11] = [
// 0x0 opcodes
(nop, 4, "NOP"),
(ld_bc_u16, 12, "LD BC, NN"),
(ld_mbc_a, 8, "LD [BC], A"),
(inc_bc, 8, "INC BC"),
(inc_b, 4, "INC B"),
(dec_b, 4, "DEC B"),
(ld_b_u8, 8, "LD B, N"),
(rlca, 4, "RLCA"),
(ld_mu16_sp, 20, "LD [u16], SP"),
(add_hl_bc, 8, "ADD HL, BC"),
// 0x2 opcodes
(ld_sp_u16, 12, "LD SP, NN"),
];
a: u8,
b: u8,
c: u8,
d: u8,
e: u8,
h: u8,
l: u8,
zero: bool,
sub: bool,
half_carry: bool,
carry: bool,
pub fn new() -> Cpu {
Cpu {
pc: 0x0,
sp: 0x0,
a: 0x0,
b: 0x0,
c: 0x0,
d: 0x0,
e: 0x0,
h: 0x0,
l: 0x0,
zero: false,
sub: false,
half_carry: false,
carry: false,
ram: [0u8; RAM_SIZE],
}
}
pub fn clock(&mut self) {
// fetches the current instruction and increments
// the PC (program counter) accordingly
let _instruction = self.ram[self.pc as usize];
fn af(&self) -> u16 {
(self.a as u16) << 8 | self.f() as u16
fn bc(&self) -> u16 {
(self.b as u16) << 8 | self.c as u16
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn f(&self) -> u8 {
let mut f = 0x0u8;
if self.zero {
f |= 0x80;
}
if self.sub {
f |= 0x40;
}
if self.half_carry {
f |= 0x20;
}
if self.carry {
f |= 0x10;
}
f
}
#[inline(always)]
fn set_bc(&mut self, value: u16) {
self.b = (value >> 8) as u8;
self.c = value as u8;
}
#[inline(always)]
fn de(&self) -> u16 {
(self.d as u16) << 8 | self.e as u16
}
#[inline(always)]
fn set_de(&mut self, value: u16) {
self.d = (value >> 8) as u8;
self.e = value as u8;
fn hl(&self) -> u16 {
(self.h as u16) << 8 | self.l as u16
}
#[inline(always)]
fn set_hl(&mut self, value: u16) {
self.h = (value >> 8) as u8;
self.l = value as u8;
fn read_u8(&mut self) -> u8 {
let byte = self.ram[self.pc as usize];
byte
}
#[inline(always)]
fn read_u16(&mut self) -> u16 {
let byte1 = self.read_u8();
let byte2 = self.read_u8();
let word = byte1 as u16 | ((byte2 as u16) << 8);
word
}
#[inline(always)]
fn get_zero(&self) -> bool {
self.zero
}
#[inline(always)]
fn set_zero(&mut self, value: bool) {
self.zero = value
self.sub
}
#[inline(always)]
fn set_sub(&mut self, value: bool) {
self.sub = value;
self.half_carry
}
#[inline(always)]
fn set_half_carry(&mut self, value: bool) {
self.half_carry = value
self.carry
}
#[inline(always)]
fn set_carry(&mut self, value: bool) {
self.carry = value;
fn nop(_cpu: &mut Cpu) {}
fn ld_bc_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_bc(word);
}
fn ld_mbc_a(cpu: &mut Cpu) {
cpu.ram[cpu.bc() as usize] = cpu.a;
}
fn inc_bc(cpu: &mut Cpu) {
cpu.set_bc(cpu.bc().wrapping_add(1));
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
fn inc_b(cpu: &mut Cpu) {
let value = cpu.b.wrapping_add(1);
cpu.set_sub(false);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn dec_b(cpu: &mut Cpu) {
let value = cpu.b.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn ld_b_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.b = byte;
}
fn rlca(cpu: &mut Cpu) {
let carry = cpu.a >> 7;
cpu.a = cpu.a << 1 | carry;
cpu.set_sub(false);
cpu.set_zero(false);
cpu.set_half_carry(false);
cpu.set_carry(carry == 1);
}
fn ld_mu16_sp(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.ram[word as usize] = cpu.sp as u8;
cpu.ram[word as usize + 1] = (cpu.sp >> 8) as u8;
}
fn add_hl_bc(cpu: &mut Cpu) {
let value = add_u16_u16(cpu, cpu.hl(), cpu.bc());
cpu.set_hl(value);
}
fn ld_sp_u16(cpu: &mut Cpu) {
cpu.sp = cpu.read_u16();
}
fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
let first = first as u32;
let second = second as u32;
let value = first.wrapping_add(second);
cpu.set_sub(false);
cpu.set_carry(value & 0x1000 == 0x1000);
cpu.set_half_carry((first ^ second ^ value) & 0x1000 == 0x1000);
value as u16
}