Stub 8-bit ALU and 16-bit Arithmetic opcodes.

This commit is contained in:
Rekai Musuka 2020-08-01 16:31:24 -05:00
parent 8a822437fb
commit 9032716346
3 changed files with 249 additions and 48 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/target /target
/.idea /.idea
/.vscode

View File

@ -1,10 +1,10 @@
use super::instructions::Instruction; // use super::instructions::Instruction;
// Gameboy CPU // Gameboy CPU
pub struct LR35902 { pub struct LR35902 {
sp: u16, _sp: u16,
pc: u16, _pc: u16,
reg: Registers, _reg: Registers,
} }
impl LR35902 { impl LR35902 {
@ -23,7 +23,7 @@ impl LR35902 {
// x = the opcode's 1st octal digit (i.e. bits 7-6) // x = the opcode's 1st octal digit (i.e. bits 7-6)
// y = the opcode's 2nd octal digit (i.e. bits 5-3) // y = the opcode's 2nd octal digit (i.e. bits 5-3)
// z = the opcode's 3rd octal digit (i.e. bits 2-0) // z = the opcode's 3rd octal digit (i.e. bits 2-0)
// p = y rightshifted one position (i.e. bits 5-4) // p = y right-shifted one position (i.e. bits 5-4)
// q = y modulo 2 (i.e. bit 3) // q = y modulo 2 (i.e. bit 3)
let x = opcode >> 6; let x = opcode >> 6;
@ -32,12 +32,12 @@ impl LR35902 {
let p = y >> 1; let p = y >> 1;
let q = y & 0b00000001; // 0b001 = 0x1; let q = y & 0b00000001; // 0b001 = 0x1;
let d: i8 = 0; // Displacement Byte let _d: i8 = 0; // Displacement Byte
let n: u8 = 0; // 8-bit Immediate Operand let _n: u8 = 0; // 8-bit Immediate Operand
let nn: u16 = 0; // 16-bit Immediate Operand let _nn: u16 = 0; // 16-bit Immediate Operand
match (x, z, q, y, p) { match (x, z, q, y, p) {
(0, 0, _, 0, _) => Instruction::nop(), (0, 0, _, 0, _) => {}
_ => panic!("Unexpected Opcode!"), _ => panic!("Unexpected Opcode!"),
} }
} }

View File

@ -2,10 +2,10 @@ use super::cpu::Flag;
/// Sharp SM83 Instructions /// Sharp SM83 Instructions
/// ### Definitions /// ### Definitions
/// * "Any valid 8-bit register" refers to the registers `B`, `C`, `D`, `E`, `H` and `L`. /// * "Any valid 8-bit register" refers to the registers `B`, `C`, `D`, `E`, `H` and `L`.
/// * If `A` is also a valid register, it will be **explicity** stated as such. /// * If `A` is also a valid register, it will be **explicitly** stated as such.
/// * "Any valid 16-bit register" refers to the registers BC, DE and HL. /// * "Any valid 16-bit register" refers to the registers BC, DE and HL.
/// * If `AF` is a valid register, it will be **explicitly** stated as such. /// * If `AF` is a valid register, it will be **explicitly** stated as such.
/// * If `SP` is a valid register, it will be **explicity** stated as such. /// * If `SP` is a valid register, it will be **explicitly** stated as such.
/// * the value of any 16-bit register in brackets is the value of the data located at /// * the value of any 16-bit register in brackets is the value of the data located at
/// the address of the 16-bit register. /// the address of the 16-bit register.
/// * e.g. the value of `(HL)` would be what is at `memory[cpu.reg.get_hl()]` /// * e.g. the value of `(HL)` would be what is at `memory[cpu.reg.get_hl()]`
@ -33,10 +33,10 @@ impl Instruction {
/// `LD A, n` Store value n into register A. /// `LD A, n` Store value n into register A.
/// ### Arguments /// ### Arguments
/// * `A` The A register /// * `a` The A register
/// * `n` Any valid 8-bit register (including `A`),`(BC)`, `(DE)`, `(HL)`, `(nn)`, and `#`. /// * `n` Any valid 8-bit register (including `A`),`(BC)`, `(DE)`, `(HL)`, `(nn)`, and `#`.
/// * `nn` A two byte immediate value (Least significant byte first). /// * `nn` A two byte immediate value (Least significant byte first).
pub fn ld_a_n(A: &mut u8, n: u8) { pub fn ld_a_n(a: &mut u8, n: u8) {
unimplemented!() unimplemented!()
} }
@ -44,24 +44,24 @@ impl Instruction {
/// ### Arguments /// ### Arguments
/// * `n` Any valid 8-bit register (including `A`), `(BC)`, `(DE)`, `(HL)`, and `(nn)`. /// * `n` Any valid 8-bit register (including `A`), `(BC)`, `(DE)`, `(HL)`, and `(nn)`.
/// * `nn` A two byte immediate value (Least significant byte first). /// * `nn` A two byte immediate value (Least significant byte first).
/// * `A` The A register. /// * `a` The A register.
pub fn ld_n_a(n: &mut u8, A: u8) { pub fn ld_n_a(n: &mut u8, a: u8) {
unimplemented!() unimplemented!()
} }
/// `LD A, (C)` Store value at $FF00 + register C in register A. /// `LD A, (C)` Store value at $FF00 + register C in register A.
/// ### Arguments /// ### Arguments
/// * `A` The A register. /// * `a` The A register.
/// * `C` The C register. /// * `c` The C register.
pub fn ld_a_c(A: &mut u8, C: u8) { pub fn ld_a_c(a: &mut u8, c: u8) {
unimplemented!() unimplemented!()
} }
/// `LD (C) ,A` Store the value of register A into $FF00 + register C. /// `LD (C) ,A` Store the value of register A into $FF00 + register C.
/// ### Arguments /// ### Arguments
/// * `C` The C register. /// * `c` The C register.
/// * `A` The A register. /// * `a` The A register.
pub fn ld_c_a(C: u8, A: u8) { pub fn ld_c_a(c: u8, a: u8) {
unimplemented!() unimplemented!()
} }
@ -72,9 +72,9 @@ impl Instruction {
/// ///
/// Identical to `LD A, (HLD)`, and `LD A, (HL-)`. /// Identical to `LD A, (HLD)`, and `LD A, (HL-)`.
/// ### Arguments /// ### Arguments
/// * `A The A register. /// * `a` The A register.
/// * `HL` The HL register /// * `hl` The HL register
pub fn ldd_a_hl(A: &mut u8, HL: u16) { pub fn ldd_a_hl(a: &mut u8, hl: u16) {
unimplemented!() unimplemented!()
} }
@ -85,9 +85,9 @@ impl Instruction {
/// ///
/// Identical to `LD (HLD), A`, and `LD (HL-), A` /// Identical to `LD (HLD), A`, and `LD (HL-), A`
/// ### Arguments /// ### Arguments
/// * `HL` The HL register. /// * `hl` The HL register.
/// * `A` The A register. /// * `a` The A register.
pub fn ldd_hl_a(HL: u16, A: u8) { pub fn ldd_hl_a(hl: u16, a: u8) {
unimplemented!() unimplemented!()
} }
@ -98,9 +98,9 @@ impl Instruction {
/// ///
/// Identical to `LD A, (HLI)`, and `LD A, (HL+)`. /// Identical to `LD A, (HLI)`, and `LD A, (HL+)`.
/// ### Arguments /// ### Arguments
/// * `A` The A register. /// * `a` The A register.
/// * `HL` The HL register. /// * `hl` The HL register.
pub fn ldi_a_hl(A: &mut u8, HL: u16) { pub fn ldi_a_hl(a: &mut u8, hl: u16) {
unimplemented!() unimplemented!()
} }
@ -111,25 +111,25 @@ impl Instruction {
/// ///
/// Identical to `LD (HLI), A`, and `LD (HL+), A`. /// Identical to `LD (HLI), A`, and `LD (HL+), A`.
/// ### Arguments /// ### Arguments
/// * `HL` The HL register. /// * `hl` The HL register.
/// * `A` The A register. /// * `a` The A register.
pub fn ldi_hl_a(HL: u16, A: u8) { pub fn ldi_hl_a(hl: u16, a: u8) {
unimplemented!() unimplemented!()
} }
/// `LDH (n), A` Store register A into address $FF00 + n. /// `LDH (n), A` Store register A into address $FF00 + n.
/// ### Arguments /// ### Arguments
/// * `n` An 8-bit immediate value. /// * `n` An 8-bit immediate value.
/// * `A` The A register. /// * `a` The A register.
pub fn ldh_n_a(n: u8, A: u8) { pub fn ldh_n_a(n: u8, a: u8) {
unimplemented!() unimplemented!()
} }
/// `LDH A, (n)` Store address $FF00 + n in the A register. /// `LDH A, (n)` Store address $FF00 + n in the A register.
/// ### Arguments /// ### Arguments
/// * `A` The A register. /// * `a` The A register.
/// * `n` An 8-bit immediate value /// * `n` An 8-bit immediate value
pub fn ldh_a_n(A: &mut u8, n: u8) { pub fn ldh_a_n(a: &mut u8, n: u8) {
unimplemented!() unimplemented!()
} }
@ -145,9 +145,9 @@ impl Instruction {
/// `LD SP, HL` Put HL into the stack pointer. /// `LD SP, HL` Put HL into the stack pointer.
/// ### Arguments /// ### Arguments
/// * `SP` The stack pointer register. /// * `sp` The stack pointer register.
/// * `HL` The HL register. /// * `hl` The HL register.
pub fn ld_sp_hl(SP: &mut u16, HL: u16) { pub fn ld_sp_hl(sp: &mut u16, hl: u16) {
unimplemented!() unimplemented!()
} }
@ -155,8 +155,8 @@ impl Instruction {
/// `LDHL SP, n` "Put SP + n effective address into HL". /// `LDHL SP, n` "Put SP + n effective address into HL".
/// ### Arguments /// ### Arguments
/// * `HL` The HL register. /// * `hl` The HL register.
/// * `SP` The stack pointer register. /// * `sp` The stack pointer register.
/// * `n` 8-bit **signed** integer. /// * `n` 8-bit **signed** integer.
/// * `f` CPU flags. /// * `f` CPU flags.
/// ///
@ -165,25 +165,225 @@ impl Instruction {
/// * `N` Reset. /// * `N` Reset.
/// * `H` Set / Reset depending on operation. /// * `H` Set / Reset depending on operation.
/// * `CY` Set / Reset depending on operation. /// * `CY` Set / Reset depending on operation.
pub fn ldhl_sp_n(HL: &mut u16, SP: u16, n: i8, f: &mut Flag) { pub fn ldhl_sp_n(hl: &mut u16, sp: u16, n: i8, f: &mut Flag) {
unimplemented!() unimplemented!()
} }
/// `LD (nn), SP` Store stack pointer at $nn. /// `LD (nn), SP` Store stack pointer at $nn.
/// ### Arguments /// ### Arguments
/// * `nn` A 16-bit immediate address. /// * `nn` A 16-bit immediate address.
/// * `SP` The stack pointer register. /// * `sp` The stack pointer register.
pub fn ld_nn_sp(nn: u16, SP: u16) { pub fn ld_nn_sp(nn: u16, sp: u16) {
unimplemented!() unimplemented!()
} }
/// `PUSH nn` Push 16-bit register onto the stack, then /// `PUSH nn` Push 16-bit register onto the stack, then
/// decrement the stack pointer twice. /// decrement the stack pointer twice.
/// ### Arguments /// ### Arguments
/// * `nn` Any valid 16-bit address (including AF). /// * `nn` Any valid 16-bit address (including `AF`).
/// * `SP` The stack pointer register. /// * `sp` The stack pointer register.
/// * `stack` The stack. /// * `stack` The stack.
pub fn push_nn(nn: u16, SP: &mut u16, stack: &[u16]) { pub fn push_nn(nn: u16, sp: &mut u16, stack: &[u16]) {
unimplemented!() unimplemented!()
} }
/// `POP nn` Pop two bytes of the stack into register pair nn,
/// then increment the stack pointer twice.
/// ### Arguments
/// `nn` Any valid 16-bit address (including `AF`).
/// `sp` The stack pointer register.
/// `stack` The stack.
pub fn pop_nn(nn: &mut u16, sp: &mut u16, stack: &[u16]) {
unimplemented!()
}
// *** 8-bit ALU ***
/// `ADD A, n` Add n to register A.
/// ### Arguments
/// `A` The A register
/// `nn` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero..
/// `N` Reset.
/// `H` Set if carry from bit 3.
/// `CY` Set if carry from bit 7.
pub fn add_a_n(a: &mut u8, n: u8) {
unimplemented!()
}
/// `ADC A, n` Add n + carry flag to register A.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Reset.
/// `H` Set if carry from bit 3.
/// `CY` Set if carry from bit 7.
pub fn adc_a_n(a: &mut u8, n: u8, f: &mut Flag) {
unimplemented!()
}
/// `SUB n` or `SUB A, n` Subtract n from register A.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is 0.
/// `N` Set.
/// `H` Set if no borrow from bit 4.
/// `CY` Set if no borrow.
pub fn sub_a_n(a: &mut u8, n: u8) {
unimplemented!()
}
/// `SBC A, n` Subtract n + carry flag from register A.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is 0.
/// `N` Set.
/// `H` Set if no borrow from bit 4.
/// `CY` Set if no borrow.
pub fn sbc_a_n(a: &mut u8, n: u8, f: &mut Flag) {
unimplemented!()
}
/// `AND n` or `AND A, n` AND n with register A,
/// then store the result in register A.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Reset
/// `H` Set
/// `CY` Reset
pub fn and_a_n(a: &mut u8, n: u8, f: &mut Flag) {
unimplemented!()
}
/// `OR n` or `OR A, n` OR n with register A, then store the result in register A
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Reset.
/// `H` Reset.
/// `CY` Reset.
pub fn or_a_n(a: &mut u8, n: u8, f: &mut Flag) {
unimplemented!()
}
/// `XOR n` or `XOR A, n` XOR n with register A, then store the result in register A.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid -bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Reset.
/// `H` Reset.
/// `CY` Reset.
pub fn xor_a_n(a: &mut u8, n: u8) {
unimplemented!()
}
/// `CP n` or `CP A, n` Compare register A with n.
///
/// Note: This is equivalent with `SUB A, n` except that the result of the
/// subtraction is discarded. Only the flags are mutated.
/// ### Arguments
/// `A` The A register.
/// `n` Any valid 8-bit register (including `A`), `(HL)`, and `#`.
///
/// ### Flags
/// `ZF` Set if result is zero ( A == n ).
/// `N` Set.
/// `H` Set if no borrow from bit 4.
/// `CY` Set for no borrow. ( A < n ).
pub fn cp_a_n(a: u8, n: u8) {
unimplemented!()
}
/// `INC n` Increment register n.
/// ### Arguments
/// `n` Any valid 8-bit register (including `A`), and `(HL)`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Reset.
/// `H` Set if carry from bit 3.
/// `CY` Not affected.
pub fn inc_n(n: &mut u8) {
unimplemented!()
}
/// `DEC n` decrement register n.
/// ### Arguments
/// `n` Any 8-bit register (including `A`), and `(HL)`.
///
/// ### Flags
/// `ZF` Set if result is zero.
/// `N` Set.
/// `H` Set if no borrow from bit 4.
/// `CY` Not affected.
pub fn dec_n(n: &mut u8) {
unimplemented!()
}
// *** 16-bit Arithmetic ***
/// `ADD HL, n` Add n to HL.
/// ### Arguments
/// `hl` The HL register.
/// `n` Any valid 16-bit address (including `SP`).
///
/// ### Flags
/// `ZF` Not affected
/// `N` Reset
/// `H` Set if carry from bit 11.
/// `CY` Set if carry from bit 15.
pub fn add_hl_n(hl: &mut u16, n: u16) {
unimplemented!()
}
/// `ADD SP, n` Add n to the stack pointer.
/// ### Arguments
/// `sp` The stack pointer register.
/// `n` AN 8-bit signed immediate value (#).
///
/// ### Flags
/// `ZF` Reset
/// `N` Reset
/// `H` Set or reset according to operation.
/// `CY` Set or reset according to operation.
pub fn add_sp_n(sp: &mut u16, n: i8) {
unimplemented!()
}
/// `INC nn` Increment register nn
/// ### Arguments
/// `nn` Any valid 16-bit register (including `SP`)
pub fn inc_nn(nn: &mut u16) {
unimplemented!()
}
/// `DEC nn` Increment register nn
/// ### Arguments
/// `nn` Any valid 16-bit register (including `SP`)
pub fn dec_nn(nn: &mut u16) {
unimplemented!()
}
// *** Miscellaneous ***
} }