Compare commits

..

8 Commits

Author SHA1 Message Date
5848bdcdce Refactor and improve instruction execution behavior
Standardize instruction cycle handling and update return types for better clarity and accuracy. Add cycle count assertions in tests to ensure proper execution timings. Minor formatting fixes and typo corrections throughout the codebase.
2025-05-15 17:22:46 +01:00
cc0278508e Refactor CPU execution flow and improve program counter handling
Introduced `ExecutionReturn` struct to standardize program counter and cycle updates across instructions. Removed redundant handling of program counter increments and refactored control flow for clarity. Also removed unused `Address` target variant from `Target` enum.
2025-05-15 16:43:42 +01:00
03c3c8a4ac Add LCDControlRegister for LCD control bit manipulation
Introduce a new `LCDControlRegister` struct to manage and manipulate individual bits of the LCD control register. Implement `From<u8>` and `Into<u8>` conversions for seamless integration with byte-level operations. This enhances code clarity and simplifies bitwise operations related to LCD control.
2025-05-14 16:33:35 +01:00
b8c49682e2 Refactor instruction parsing logic into separate module
The implementation of instruction parsing has been moved out of `main.rs` into a dedicated `instructions` module. This improves code readability, reduces clutter, and promotes modularity, making it easier to maintain and extend the instruction set functionality.
2025-05-14 16:08:50 +01:00
11f0bb06d6 Refactor CPU instruction set and cleanup unused code
Removed unused instructions (CopyHN16A, CopyHCA, etc.), simplified PC increment logic, and cleaned up test and execution code. Updated dictionaries and Cargo.lock to reflect recent changes in project structure and dependencies.
2025-05-14 08:59:12 +01:00
e9a40bd9f7 Refactor and extend CPU and memory emulation.
Added and refactored several instructions and memory operations, improving accuracy and functionality for emulation. Introduced new dependencies (`serde_json`, `glob`) and submodule for test framework integration. Enhanced debugging, flat RAM handling, and opcode parsing while fixing multiple calculation and flag-setting issues.
2025-05-09 13:47:26 +01:00
9be93f4aa9 Refactor boot process and instruction execution
Introduce clearer boot ROM handling and streamline `execute_next_instruction` for better readability and accuracy. Add program counter (`pc`) updates within each instruction, improving program flow consistency.
2025-05-06 16:20:23 +01:00
74e86f1ab7 Add GameRom struct with MBC1 support and integrate with MemoryBus
Introduced `GameRom` struct and implemented support for MBC1 cartridges, including ROM and RAM banking. Modified `MemoryBus` and `CPU` to use `GameRom` for cartridge interactions, replacing raw game ROM handling. Added logic to load, read, and write cartridge memory based on type and address.
2025-05-06 12:00:52 +01:00
9 changed files with 1330 additions and 773 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "sm83"]
path = sm83
url = https://github.com/SingleStepTests/sm83.git

View File

@@ -6,7 +6,9 @@
<w>addhl</w> <w>addhl</w>
<w>addsp</w> <w>addsp</w>
<w>dechl</w> <w>dechl</w>
<w>gameboy</w>
<w>inchl</w> <w>inchl</w>
<w>incu</w>
<w>instrs</w> <w>instrs</w>
<w>jpcc</w> <w>jpcc</w>
<w>jphl</w> <w>jphl</w>
@@ -14,6 +16,7 @@
<w>reti</w> <w>reti</w>
<w>rrca</w> <w>rrca</w>
<w>rrla</w> <w>rrla</w>
<w>tama</w>
<w>vram</w> <w>vram</w>
</words> </words>
</dictionary> </dictionary>

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/sm83" vcs="Git" />
</component> </component>
</project> </project>

97
Cargo.lock generated
View File

@@ -1,7 +1,102 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]]
name = "glob"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]] [[package]]
name = "untitled" name = "untitled"
version = "0.1.0" version = "0.1.0"
dependencies = [
"glob",
"serde_json",
]

View File

@@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
serde_json = "1.0.140"
glob = "0.3.2"

1
sm83 Submodule

Submodule sm83 added at f9c3021024

609
src/instructions.rs Normal file
View File

@@ -0,0 +1,609 @@
#[derive(Clone, Copy, Debug)]
pub enum TargetRegister { A, B, C, D, E, H, L, }
#[derive(Clone, Copy, Debug)]
pub enum TargetU16Register {AF, BC, DE, HL, SP, PC}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Condition {
NZ, // Not Zero
Z, // Zero
NC, // Not Carry
C, // Carry
None,
}
#[derive(Clone, Copy, Debug)]
pub enum Target {
U8Register(TargetRegister),
U16Register(TargetU16Register),
Immediate(u8)
}
#[derive(Clone, Copy, Debug)]
pub enum LoadTarget{
CopyR8R8(TargetRegister, TargetRegister),
CopyR8N8(TargetRegister, u8),
CopyR16N16(TargetU16Register, u16),
CopyHLR8(TargetRegister),
CopyHLN8(u8),
CopyR8HL(TargetRegister),
CopyR16A(TargetU16Register),
CopyN16A(u16),
CopyAR16(TargetU16Register),
CopyAN16(u16),
CopyHLIA,
CopyHLDA,
CopyAHLD,
CopyAHLI,
CopySPN16(u16),
CopyN16SP(u16),
CopyHLSPE8(i8),
CopySPHL,
CopyPortA(Target),
CopyAPort(Target)
}
#[derive(Debug)]
pub enum Instruction {
ADC(Target),
ADD(Target),
ADDHL(TargetU16Register),
ADDSP(i8),
AND(Target),
BIT(u8, Target),
CALL(Condition, u16),
CCF,
CP(Target),
CPL,
DAA,
DEC(Target),
DECU16(TargetU16Register),
DI,
EI,
HALT,
INC(Target),
INCU16(TargetU16Register),
JP(Condition, u16),
JPHL,
JR(Condition, i8),
LD(LoadTarget),
NOP,
OR(Target),
POP(TargetU16Register),
PUSH(TargetU16Register),
RES(u8, Target),
RET(Condition),
RETI,
RL(Target),
RLC(Target),
RR(Target),
RRC(Target),
RST(u8),
SBC(Target),
SCF,
SET(u8, Target),
SLA(Target),
SRA(Target),
SRL(Target),
STOP(u8),
SUB(Target),
SWAP(Target),
XOR(Target),
}
fn get_u16(low: u8, high: u8) -> u16 {
((high as u16) << 8) | low as u16
}
pub fn parse_instruction(opcode: u8, arg1: u8, arg2: u8) -> Instruction {
match opcode {
0x00 => { Instruction::NOP }
0x01 => { Instruction::LD(LoadTarget::CopyR16N16(TargetU16Register::BC, get_u16(arg1, arg2))) }
0x02 => { Instruction::LD(LoadTarget::CopyR16A(TargetU16Register::BC)) }
0x03 => { Instruction::INCU16(TargetU16Register::BC) }
0x04 => { Instruction::INC(Target::U8Register(TargetRegister::B)) }
0x05 => { Instruction::DEC(Target::U8Register(TargetRegister::B)) }
0x06 => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::B, arg1)) }
0x07 => { Instruction::RLC(Target::U8Register(TargetRegister::A)) }
0x08 => { Instruction::LD(LoadTarget::CopyN16SP(get_u16(arg1, arg2))) }
0x09 => { Instruction::ADDHL(TargetU16Register::BC) }
0x0A => { Instruction::LD(LoadTarget::CopyAR16(TargetU16Register::BC)) }
0x0B => { Instruction::DECU16(TargetU16Register::BC) }
0x0C => { Instruction::INC(Target::U8Register(TargetRegister::C)) }
0x0D => { Instruction::DEC(Target::U8Register(TargetRegister::C)) }
0x0E => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::C, arg1)) }
0x0F => { Instruction::RRC(Target::U8Register(TargetRegister::A)) }
0x10 => { Instruction::STOP(arg1) }
0x11 => { Instruction::LD(LoadTarget::CopyR16N16(TargetU16Register::DE, get_u16(arg1, arg2))) }
0x12 => { Instruction::LD(LoadTarget::CopyR16A(TargetU16Register::DE)) }
0x13 => { Instruction::INCU16(TargetU16Register::DE) }
0x14 => { Instruction::INC(Target::U8Register(TargetRegister::D)) }
0x15 => { Instruction::DEC(Target::U8Register(TargetRegister::D)) }
0x16 => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::D, arg1)) }
0x17 => { Instruction::RL(Target::U8Register(TargetRegister::A)) }
0x18 => { Instruction::JR(Condition::None, arg1 as i8) }
0x19 => { Instruction::ADDHL(TargetU16Register::DE) }
0x1A => { Instruction::LD(LoadTarget::CopyAR16(TargetU16Register::DE)) }
0x1B => { Instruction::DECU16(TargetU16Register::DE) }
0x1C => { Instruction::INC(Target::U8Register(TargetRegister::E)) }
0x1D => { Instruction::DEC(Target::U8Register(TargetRegister::E)) }
0x1E => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::E, arg1)) }
0x1F => { Instruction::RR(Target::U8Register(TargetRegister::A)) }
0x20 => { Instruction::JR(Condition::NZ, arg1 as i8) }
0x21 => { Instruction::LD(LoadTarget::CopyR16N16(TargetU16Register::HL, get_u16(arg1, arg2))) }
0x22 => { Instruction::LD(LoadTarget::CopyHLIA) }
0x23 => { Instruction::INCU16(TargetU16Register::HL) }
0x24 => { Instruction::INC(Target::U8Register(TargetRegister::H)) }
0x25 => { Instruction::DEC(Target::U8Register(TargetRegister::H)) }
0x26 => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::H, arg1)) }
0x27 => { Instruction::DAA }
0x28 => { Instruction::JR(Condition::Z, arg1 as i8) }
0x29 => { Instruction::ADDHL(TargetU16Register::HL) }
0x2A => { Instruction::LD(LoadTarget::CopyAHLI) }
0x2B => { Instruction::DECU16(TargetU16Register::HL) }
0x2C => { Instruction::INC(Target::U8Register(TargetRegister::L)) }
0x2D => { Instruction::DEC(Target::U8Register(TargetRegister::L)) }
0x2E => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::L, arg1)) }
0x2F => { Instruction::CPL }
0x30 => { Instruction::JR(Condition::NC, arg1 as i8) }
0x31 => { Instruction::LD(LoadTarget::CopySPN16(get_u16(arg1, arg2))) }
0x32 => { Instruction::LD(LoadTarget::CopyHLDA) }
0x33 => { Instruction::INCU16(TargetU16Register::SP) }
0x34 => { Instruction::INC(Target::U16Register(TargetU16Register::HL)) }
0x35 => { Instruction::DEC(Target::U16Register(TargetU16Register::HL)) }
0x36 => { Instruction::LD(LoadTarget::CopyHLN8(arg1)) }
0x37 => { Instruction::SCF }
0x38 => { Instruction::JR(Condition::C, arg1 as i8) }
0x39 => { Instruction::ADDHL(TargetU16Register::SP) }
0x3A => { Instruction::LD(LoadTarget::CopyAHLD)}
0x3B => { Instruction::DECU16(TargetU16Register::SP) }
0x3C => { Instruction::INC(Target::U8Register(TargetRegister::A)) }
0x3D => { Instruction::DEC(Target::U8Register(TargetRegister::A)) }
0x3E => { Instruction::LD(LoadTarget::CopyR8N8(TargetRegister::A, arg1)) }
0x3F => { Instruction::CCF }
0x40 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::B)) }
0x41 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::C)) }
0x42 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::D)) }
0x43 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::E)) }
0x44 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::H)) }
0x45 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::L)) }
0x46 => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::B)) }
0x47 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::B, TargetRegister::A)) }
0x48 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::B)) }
0x49 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::C)) }
0x4A => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::D)) }
0x4B => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::E)) }
0x4C => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::H)) }
0x4D => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::L)) }
0x4E => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::C)) }
0x4F => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::C, TargetRegister::A)) }
0x50 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::B)) }
0x51 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::C)) }
0x52 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::D)) }
0x53 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::E)) }
0x54 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::H)) }
0x55 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::L)) }
0x56 => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::D)) }
0x57 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::D, TargetRegister::A)) }
0x58 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::B)) }
0x59 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::C)) }
0x5A => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::D)) }
0x5B => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::E)) }
0x5C => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::H)) }
0x5D => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::L)) }
0x5E => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::E)) }
0x5F => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::E, TargetRegister::A)) }
0x60 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::B)) }
0x61 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::C)) }
0x62 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::D)) }
0x63 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::E)) }
0x64 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::H)) }
0x65 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::L)) }
0x66 => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::H)) }
0x67 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::H, TargetRegister::A)) }
0x68 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::B)) }
0x69 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::C)) }
0x6A => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::D)) }
0x6B => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::E)) }
0x6C => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::H)) }
0x6D => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::L)) }
0x6E => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::L)) }
0x6F => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::L, TargetRegister::A)) }
0x70 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::B)) }
0x71 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::C)) }
0x72 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::D)) }
0x73 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::E)) }
0x74 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::H)) }
0x75 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::L)) }
0x76 => { Instruction::HALT }
0x77 => { Instruction::LD(LoadTarget::CopyHLR8(TargetRegister::A)) }
0x78 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::B)) }
0x79 => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::C)) }
0x7A => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::D)) }
0x7B => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::E)) }
0x7C => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::H)) }
0x7D => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::L)) }
0x7E => { Instruction::LD(LoadTarget::CopyR8HL(TargetRegister::A)) }
0x7F => { Instruction::LD(LoadTarget::CopyR8R8(TargetRegister::A, TargetRegister::A)) }
0x80 => { Instruction::ADD(Target::U8Register(TargetRegister::B)) }
0x81 => { Instruction::ADD(Target::U8Register(TargetRegister::C)) }
0x82 => { Instruction::ADD(Target::U8Register(TargetRegister::D)) }
0x83 => { Instruction::ADD(Target::U8Register(TargetRegister::E)) }
0x84 => { Instruction::ADD(Target::U8Register(TargetRegister::H)) }
0x85 => { Instruction::ADD(Target::U8Register(TargetRegister::L)) }
0x86 => { Instruction::ADD(Target::U16Register(TargetU16Register::HL)) }
0x87 => { Instruction::ADD(Target::U8Register(TargetRegister::A)) }
0x88 => { Instruction::ADC(Target::U8Register(TargetRegister::B)) }
0x89 => { Instruction::ADC(Target::U8Register(TargetRegister::C)) }
0x8A => { Instruction::ADC(Target::U8Register(TargetRegister::D)) }
0x8B => { Instruction::ADC(Target::U8Register(TargetRegister::E)) }
0x8C => { Instruction::ADC(Target::U8Register(TargetRegister::H)) }
0x8D => { Instruction::ADC(Target::U8Register(TargetRegister::L)) }
0x8E => { Instruction::ADC(Target::U16Register(TargetU16Register::HL)) }
0x8F => { Instruction::ADC(Target::U8Register(TargetRegister::A)) }
0x90 => { Instruction::SUB(Target::U8Register(TargetRegister::B)) }
0x91 => { Instruction::SUB(Target::U8Register(TargetRegister::C)) }
0x92 => { Instruction::SUB(Target::U8Register(TargetRegister::D)) }
0x93 => { Instruction::SUB(Target::U8Register(TargetRegister::E)) }
0x94 => { Instruction::SUB(Target::U8Register(TargetRegister::H)) }
0x95 => { Instruction::SUB(Target::U8Register(TargetRegister::L)) }
0x96 => { Instruction::SUB(Target::U16Register(TargetU16Register::HL)) }
0x97 => { Instruction::SUB(Target::U8Register(TargetRegister::A)) }
0x98 => { Instruction::SBC(Target::U8Register(TargetRegister::B)) }
0x99 => { Instruction::SBC(Target::U8Register(TargetRegister::C)) }
0x9A => { Instruction::SBC(Target::U8Register(TargetRegister::D)) }
0x9B => { Instruction::SBC(Target::U8Register(TargetRegister::E)) }
0x9C => { Instruction::SBC(Target::U8Register(TargetRegister::H)) }
0x9D => { Instruction::SBC(Target::U8Register(TargetRegister::L)) }
0x9E => { Instruction::SBC(Target::U16Register(TargetU16Register::HL)) }
0x9F => { Instruction::SBC(Target::U8Register(TargetRegister::A)) }
0xA0 => { Instruction::AND(Target::U8Register(TargetRegister::B)) }
0xA1 => { Instruction::AND(Target::U8Register(TargetRegister::C)) }
0xA2 => { Instruction::AND(Target::U8Register(TargetRegister::D)) }
0xA3 => { Instruction::AND(Target::U8Register(TargetRegister::E)) }
0xA4 => { Instruction::AND(Target::U8Register(TargetRegister::H)) }
0xA5 => { Instruction::AND(Target::U8Register(TargetRegister::L)) }
0xA6 => { Instruction::AND(Target::U16Register(TargetU16Register::HL)) }
0xA7 => { Instruction::AND(Target::U8Register(TargetRegister::A)) }
0xA8 => { Instruction::XOR(Target::U8Register(TargetRegister::B)) }
0xA9 => { Instruction::XOR(Target::U8Register(TargetRegister::C)) }
0xAA => { Instruction::XOR(Target::U8Register(TargetRegister::D)) }
0xAB => { Instruction::XOR(Target::U8Register(TargetRegister::E)) }
0xAC => { Instruction::XOR(Target::U8Register(TargetRegister::H)) }
0xAD => { Instruction::XOR(Target::U8Register(TargetRegister::L)) }
0xAE => { Instruction::XOR(Target::U16Register(TargetU16Register::HL)) }
0xAF => { Instruction::XOR(Target::U8Register(TargetRegister::A)) }
0xB0 => { Instruction::OR(Target::U8Register(TargetRegister::B)) }
0xB1 => { Instruction::OR(Target::U8Register(TargetRegister::C)) }
0xB2 => { Instruction::OR(Target::U8Register(TargetRegister::D)) }
0xB3 => { Instruction::OR(Target::U8Register(TargetRegister::E)) }
0xB4 => { Instruction::OR(Target::U8Register(TargetRegister::H)) }
0xB5 => { Instruction::OR(Target::U8Register(TargetRegister::L)) }
0xB6 => { Instruction::OR(Target::U16Register(TargetU16Register::HL)) }
0xB7 => { Instruction::OR(Target::U8Register(TargetRegister::A)) }
0xB8 => { Instruction::CP(Target::U8Register(TargetRegister::B)) }
0xB9 => { Instruction::CP(Target::U8Register(TargetRegister::C)) }
0xBA => { Instruction::CP(Target::U8Register(TargetRegister::D)) }
0xBB => { Instruction::CP(Target::U8Register(TargetRegister::E)) }
0xBC => { Instruction::CP(Target::U8Register(TargetRegister::H)) }
0xBD => { Instruction::CP(Target::U8Register(TargetRegister::L)) }
0xBE => { Instruction::CP(Target::U16Register(TargetU16Register::HL)) }
0xBF => { Instruction::CP(Target::U8Register(TargetRegister::A)) }
0xC0 => { Instruction::RET(Condition::NZ) }
0xC1 => { Instruction::POP(TargetU16Register::BC) }
0xC2 => { Instruction::JP(Condition::NZ, get_u16(arg1, arg2)) }
0xC3 => { Instruction::JP(Condition::None, get_u16(arg1, arg2)) }
0xC4 => { Instruction::CALL(Condition::NZ, get_u16(arg1, arg2)) }
0xC5 => { Instruction::PUSH(TargetU16Register::BC) }
0xC6 => { Instruction::ADD(Target::Immediate(arg1)) }
0xC7 => { Instruction::RST(0x00) }
0xC8 => { Instruction::RET(Condition::Z) }
0xC9 => { Instruction::RET(Condition::None) }
0xCA => { Instruction::JP(Condition::Z, get_u16(arg1, arg2)) }
0xCB => {match_cb_instruction(arg1)},
0xCC => { Instruction::CALL(Condition::Z, get_u16(arg1, arg2)) }
0xCD => { Instruction::CALL(Condition::None, get_u16(arg1, arg2)) }
0xCE => { Instruction::ADC(Target::Immediate(arg1)) }
0xCF => { Instruction::RST(0x01) }
0xD0 => { Instruction::RET(Condition::NC) }
0xD1 => { Instruction::POP(TargetU16Register::DE) }
0xD2 => { Instruction::JP(Condition::NC, get_u16(arg1, arg2)) }
0xD4 => { Instruction::CALL(Condition::NC, get_u16(arg1, arg2)) }
0xD5 => { Instruction::PUSH(TargetU16Register::DE) }
0xD6 => { Instruction::SUB(Target::Immediate(arg1)) }
0xD7 => { Instruction::RST(0x02) }
0xD8 => { Instruction::RET(Condition::C) }
0xD9 => { Instruction::RETI }
0xDA => { Instruction::JP(Condition::C, get_u16(arg1, arg2)) }
0xDC => { Instruction::CALL(Condition::C, get_u16(arg1, arg2)) }
0xDE => { Instruction::SBC(Target::Immediate(arg1)) }
0xDF => { Instruction::RST(0x03) }
0xE0 => { Instruction::LD(LoadTarget::CopyPortA(Target::Immediate(arg1))) }
0xE1 => { Instruction::POP(TargetU16Register::HL) }
0xE2 => { Instruction::LD(LoadTarget::CopyPortA(Target::U8Register(TargetRegister::C))) }
0xE5 => { Instruction::PUSH(TargetU16Register::HL) }
0xE6 => { Instruction::AND(Target::Immediate(arg1)) }
0xE7 => { Instruction::RST(0x04) }
0xE8 => { Instruction::ADDSP(arg1 as i8) }
0xE9 => { Instruction::JPHL }
0xEA => { Instruction::LD(LoadTarget::CopyN16A(get_u16(arg1, arg2))) }
0xEE => { Instruction::XOR(Target::Immediate(arg1)) }
0xEF => { Instruction::RST(0x05) }
0xF0 => { Instruction::LD(LoadTarget::CopyAPort(Target::Immediate(arg1))) }
0xF1 => { Instruction::POP(TargetU16Register::AF) }
0xF2 => { Instruction::LD(LoadTarget::CopyAPort(Target::U8Register(TargetRegister::C))) }
0xF3 => { Instruction::DI }
0xF5 => { Instruction::PUSH(TargetU16Register::AF) }
0xF6 => { Instruction::OR(Target::Immediate(arg1)) }
0xF7 => { Instruction::RST(0x06) }
0xF8 => { Instruction::LD(LoadTarget::CopyHLSPE8(arg1 as i8)) }
0xF9 => { Instruction::LD(LoadTarget::CopySPHL) }
0xFA => { Instruction::LD(LoadTarget::CopyAN16(get_u16(arg1, arg2))) }
0xFB => { Instruction::EI }
0xFE => { Instruction::CP(Target::Immediate(arg1)) }
0xFF => { Instruction::RST(0x07) }
_ => { panic!("Invalid u8 opcode: {:02X}", opcode); }
}
}
fn match_cb_instruction(opcode: u8) -> Instruction {
match opcode {
0x00 => { Instruction::RLC(Target::U8Register(TargetRegister::B)) }
0x01 => { Instruction::RLC(Target::U8Register(TargetRegister::C)) }
0x02 => { Instruction::RLC(Target::U8Register(TargetRegister::D)) }
0x03 => { Instruction::RLC(Target::U8Register(TargetRegister::E)) }
0x04 => { Instruction::RLC(Target::U8Register(TargetRegister::H)) }
0x05 => { Instruction::RLC(Target::U8Register(TargetRegister::L)) }
0x06 => { Instruction::RLC(Target::U16Register(TargetU16Register::HL)) }
0x07 => { Instruction::RLC(Target::U8Register(TargetRegister::A)) }
0x08 => { Instruction::RRC(Target::U8Register(TargetRegister::B)) }
0x09 => { Instruction::RRC(Target::U8Register(TargetRegister::C)) }
0x0A => { Instruction::RRC(Target::U8Register(TargetRegister::D)) }
0x0B => { Instruction::RRC(Target::U8Register(TargetRegister::E)) }
0x0C => { Instruction::RRC(Target::U8Register(TargetRegister::H)) }
0x0D => { Instruction::RRC(Target::U8Register(TargetRegister::L)) }
0x0E => { Instruction::RRC(Target::U16Register(TargetU16Register::HL)) }
0x0F => { Instruction::RRC(Target::U8Register(TargetRegister::A)) }
0x10 => { Instruction::RL(Target::U8Register(TargetRegister::B)) }
0x11 => { Instruction::RL(Target::U8Register(TargetRegister::C)) }
0x12 => { Instruction::RL(Target::U8Register(TargetRegister::D)) }
0x13 => { Instruction::RL(Target::U8Register(TargetRegister::E)) }
0x14 => { Instruction::RL(Target::U8Register(TargetRegister::H)) }
0x15 => { Instruction::RL(Target::U8Register(TargetRegister::L)) }
0x16 => { Instruction::RL(Target::U16Register(TargetU16Register::HL)) }
0x17 => { Instruction::RL(Target::U8Register(TargetRegister::A)) }
0x18 => { Instruction::RR(Target::U8Register(TargetRegister::B)) }
0x19 => { Instruction::RR(Target::U8Register(TargetRegister::C)) }
0x1A => { Instruction::RR(Target::U8Register(TargetRegister::D)) }
0x1B => { Instruction::RR(Target::U8Register(TargetRegister::E)) }
0x1C => { Instruction::RR(Target::U8Register(TargetRegister::H)) }
0x1D => { Instruction::RR(Target::U8Register(TargetRegister::L)) }
0x1E => { Instruction::RR(Target::U16Register(TargetU16Register::HL)) }
0x1F => { Instruction::RR(Target::U8Register(TargetRegister::A)) }
0x20 => { Instruction::SLA(Target::U8Register(TargetRegister::B)) }
0x21 => { Instruction::SLA(Target::U8Register(TargetRegister::C)) }
0x22 => { Instruction::SLA(Target::U8Register(TargetRegister::D)) }
0x23 => { Instruction::SLA(Target::U8Register(TargetRegister::E)) }
0x24 => { Instruction::SLA(Target::U8Register(TargetRegister::H)) }
0x25 => { Instruction::SLA(Target::U8Register(TargetRegister::L)) }
0x26 => { Instruction::SLA(Target::U16Register(TargetU16Register::HL)) }
0x27 => { Instruction::SLA(Target::U8Register(TargetRegister::A)) }
0x28 => { Instruction::SRA(Target::U8Register(TargetRegister::B)) }
0x29 => { Instruction::SRA(Target::U8Register(TargetRegister::C)) }
0x2A => { Instruction::SRA(Target::U8Register(TargetRegister::D)) }
0x2B => { Instruction::SRA(Target::U8Register(TargetRegister::E)) }
0x2C => { Instruction::SRA(Target::U8Register(TargetRegister::H)) }
0x2D => { Instruction::SRA(Target::U8Register(TargetRegister::L)) }
0x2E => { Instruction::SRA(Target::U16Register(TargetU16Register::HL)) }
0x2F => { Instruction::SRA(Target::U8Register(TargetRegister::A)) }
0x30 => { Instruction::SWAP(Target::U8Register(TargetRegister::B)) }
0x31 => { Instruction::SWAP(Target::U8Register(TargetRegister::C)) }
0x32 => { Instruction::SWAP(Target::U8Register(TargetRegister::D)) }
0x33 => { Instruction::SWAP(Target::U8Register(TargetRegister::E)) }
0x34 => { Instruction::SWAP(Target::U8Register(TargetRegister::H)) }
0x35 => { Instruction::SWAP(Target::U8Register(TargetRegister::L)) }
0x36 => { Instruction::SWAP(Target::U16Register(TargetU16Register::HL)) }
0x37 => { Instruction::SWAP(Target::U8Register(TargetRegister::A)) }
0x38 => { Instruction::SRL(Target::U8Register(TargetRegister::B)) }
0x39 => { Instruction::SRL(Target::U8Register(TargetRegister::C)) }
0x3A => { Instruction::SRL(Target::U8Register(TargetRegister::D)) }
0x3B => { Instruction::SRL(Target::U8Register(TargetRegister::E)) }
0x3C => { Instruction::SRL(Target::U8Register(TargetRegister::H)) }
0x3D => { Instruction::SRL(Target::U8Register(TargetRegister::L)) }
0x3E => { Instruction::SRL(Target::U16Register(TargetU16Register::HL)) }
0x3F => { Instruction::SRL(Target::U8Register(TargetRegister::A)) }
0x40 => { Instruction::BIT(0, Target::U8Register(TargetRegister::B)) }
0x41 => { Instruction::BIT(0, Target::U8Register(TargetRegister::C)) }
0x42 => { Instruction::BIT(0, Target::U8Register(TargetRegister::D)) }
0x43 => { Instruction::BIT(0, Target::U8Register(TargetRegister::E)) }
0x44 => { Instruction::BIT(0, Target::U8Register(TargetRegister::H)) }
0x45 => { Instruction::BIT(0, Target::U8Register(TargetRegister::L)) }
0x46 => { Instruction::BIT(0, Target::U16Register(TargetU16Register::HL)) }
0x47 => { Instruction::BIT(0, Target::U8Register(TargetRegister::A)) }
0x48 => { Instruction::BIT(1, Target::U8Register(TargetRegister::B)) }
0x49 => { Instruction::BIT(1, Target::U8Register(TargetRegister::C)) }
0x4A => { Instruction::BIT(1, Target::U8Register(TargetRegister::D)) }
0x4B => { Instruction::BIT(1, Target::U8Register(TargetRegister::E)) }
0x4C => { Instruction::BIT(1, Target::U8Register(TargetRegister::H)) }
0x4D => { Instruction::BIT(1, Target::U8Register(TargetRegister::L)) }
0x4E => { Instruction::BIT(1, Target::U16Register(TargetU16Register::HL)) }
0x4F => { Instruction::BIT(1, Target::U8Register(TargetRegister::A)) }
0x50 => { Instruction::BIT(2, Target::U8Register(TargetRegister::B)) }
0x51 => { Instruction::BIT(2, Target::U8Register(TargetRegister::C)) }
0x52 => { Instruction::BIT(2, Target::U8Register(TargetRegister::D)) }
0x53 => { Instruction::BIT(2, Target::U8Register(TargetRegister::E)) }
0x54 => { Instruction::BIT(2, Target::U8Register(TargetRegister::H)) }
0x55 => { Instruction::BIT(2, Target::U8Register(TargetRegister::L)) }
0x56 => { Instruction::BIT(2, Target::U16Register(TargetU16Register::HL)) }
0x57 => { Instruction::BIT(2, Target::U8Register(TargetRegister::A)) }
0x58 => { Instruction::BIT(3, Target::U8Register(TargetRegister::B)) }
0x59 => { Instruction::BIT(3, Target::U8Register(TargetRegister::C)) }
0x5A => { Instruction::BIT(3, Target::U8Register(TargetRegister::D)) }
0x5B => { Instruction::BIT(3, Target::U8Register(TargetRegister::E)) }
0x5C => { Instruction::BIT(3, Target::U8Register(TargetRegister::H)) }
0x5D => { Instruction::BIT(3, Target::U8Register(TargetRegister::L)) }
0x5E => { Instruction::BIT(3, Target::U16Register(TargetU16Register::HL)) }
0x5F => { Instruction::BIT(3, Target::U8Register(TargetRegister::A)) }
0x60 => { Instruction::BIT(4, Target::U8Register(TargetRegister::B)) }
0x61 => { Instruction::BIT(4, Target::U8Register(TargetRegister::C)) }
0x62 => { Instruction::BIT(4, Target::U8Register(TargetRegister::D)) }
0x63 => { Instruction::BIT(4, Target::U8Register(TargetRegister::E)) }
0x64 => { Instruction::BIT(4, Target::U8Register(TargetRegister::H)) }
0x65 => { Instruction::BIT(4, Target::U8Register(TargetRegister::L)) }
0x66 => { Instruction::BIT(4, Target::U16Register(TargetU16Register::HL)) }
0x67 => { Instruction::BIT(4, Target::U8Register(TargetRegister::A)) }
0x68 => { Instruction::BIT(5, Target::U8Register(TargetRegister::B)) }
0x69 => { Instruction::BIT(5, Target::U8Register(TargetRegister::C)) }
0x6A => { Instruction::BIT(5, Target::U8Register(TargetRegister::D)) }
0x6B => { Instruction::BIT(5, Target::U8Register(TargetRegister::E)) }
0x6C => { Instruction::BIT(5, Target::U8Register(TargetRegister::H)) }
0x6D => { Instruction::BIT(5, Target::U8Register(TargetRegister::L)) }
0x6E => { Instruction::BIT(5, Target::U16Register(TargetU16Register::HL)) }
0x6F => { Instruction::BIT(5, Target::U8Register(TargetRegister::A)) }
0x70 => { Instruction::BIT(6, Target::U8Register(TargetRegister::B)) }
0x71 => { Instruction::BIT(6, Target::U8Register(TargetRegister::C)) }
0x72 => { Instruction::BIT(6, Target::U8Register(TargetRegister::D)) }
0x73 => { Instruction::BIT(6, Target::U8Register(TargetRegister::E)) }
0x74 => { Instruction::BIT(6, Target::U8Register(TargetRegister::H)) }
0x75 => { Instruction::BIT(6, Target::U8Register(TargetRegister::L)) }
0x76 => { Instruction::BIT(6, Target::U16Register(TargetU16Register::HL)) }
0x77 => { Instruction::BIT(6, Target::U8Register(TargetRegister::A)) }
0x78 => { Instruction::BIT(7, Target::U8Register(TargetRegister::B)) }
0x79 => { Instruction::BIT(7, Target::U8Register(TargetRegister::C)) }
0x7A => { Instruction::BIT(7, Target::U8Register(TargetRegister::D)) }
0x7B => { Instruction::BIT(7, Target::U8Register(TargetRegister::E)) }
0x7C => { Instruction::BIT(7, Target::U8Register(TargetRegister::H)) }
0x7D => { Instruction::BIT(7, Target::U8Register(TargetRegister::L)) }
0x7E => { Instruction::BIT(7, Target::U16Register(TargetU16Register::HL)) }
0x7F => { Instruction::BIT(7, Target::U8Register(TargetRegister::A)) }
0x80 => { Instruction::RES(0, Target::U8Register(TargetRegister::B)) }
0x81 => { Instruction::RES(0, Target::U8Register(TargetRegister::C)) }
0x82 => { Instruction::RES(0, Target::U8Register(TargetRegister::D)) }
0x83 => { Instruction::RES(0, Target::U8Register(TargetRegister::E)) }
0x84 => { Instruction::RES(0, Target::U8Register(TargetRegister::H)) }
0x85 => { Instruction::RES(0, Target::U8Register(TargetRegister::L)) }
0x86 => { Instruction::RES(0, Target::U16Register(TargetU16Register::HL)) }
0x87 => { Instruction::RES(0, Target::U8Register(TargetRegister::A)) }
0x88 => { Instruction::RES(1, Target::U8Register(TargetRegister::B)) }
0x89 => { Instruction::RES(1, Target::U8Register(TargetRegister::C)) }
0x8A => { Instruction::RES(1, Target::U8Register(TargetRegister::D)) }
0x8B => { Instruction::RES(1, Target::U8Register(TargetRegister::E)) }
0x8C => { Instruction::RES(1, Target::U8Register(TargetRegister::H)) }
0x8D => { Instruction::RES(1, Target::U8Register(TargetRegister::L)) }
0x8E => { Instruction::RES(1, Target::U16Register(TargetU16Register::HL)) }
0x8F => { Instruction::RES(1, Target::U8Register(TargetRegister::A)) }
0x90 => { Instruction::RES(2, Target::U8Register(TargetRegister::B)) }
0x91 => { Instruction::RES(2, Target::U8Register(TargetRegister::C)) }
0x92 => { Instruction::RES(2, Target::U8Register(TargetRegister::D)) }
0x93 => { Instruction::RES(2, Target::U8Register(TargetRegister::E)) }
0x94 => { Instruction::RES(2, Target::U8Register(TargetRegister::H)) }
0x95 => { Instruction::RES(2, Target::U8Register(TargetRegister::L)) }
0x96 => { Instruction::RES(2, Target::U16Register(TargetU16Register::HL)) }
0x97 => { Instruction::RES(2, Target::U8Register(TargetRegister::A)) }
0x98 => { Instruction::RES(3, Target::U8Register(TargetRegister::B)) }
0x99 => { Instruction::RES(3, Target::U8Register(TargetRegister::C)) }
0x9A => { Instruction::RES(3, Target::U8Register(TargetRegister::D)) }
0x9B => { Instruction::RES(3, Target::U8Register(TargetRegister::E)) }
0x9C => { Instruction::RES(3, Target::U8Register(TargetRegister::H)) }
0x9D => { Instruction::RES(3, Target::U8Register(TargetRegister::L)) }
0x9E => { Instruction::RES(3, Target::U16Register(TargetU16Register::HL)) }
0x9F => { Instruction::RES(3, Target::U8Register(TargetRegister::A)) }
0xA0 => { Instruction::RES(4, Target::U8Register(TargetRegister::B)) }
0xA1 => { Instruction::RES(4, Target::U8Register(TargetRegister::C)) }
0xA2 => { Instruction::RES(4, Target::U8Register(TargetRegister::D)) }
0xA3 => { Instruction::RES(4, Target::U8Register(TargetRegister::E)) }
0xA4 => { Instruction::RES(4, Target::U8Register(TargetRegister::H)) }
0xA5 => { Instruction::RES(4, Target::U8Register(TargetRegister::L)) }
0xA6 => { Instruction::RES(4, Target::U16Register(TargetU16Register::HL)) }
0xA7 => { Instruction::RES(4, Target::U8Register(TargetRegister::A)) }
0xA8 => { Instruction::RES(5, Target::U8Register(TargetRegister::B)) }
0xA9 => { Instruction::RES(5, Target::U8Register(TargetRegister::C)) }
0xAA => { Instruction::RES(5, Target::U8Register(TargetRegister::D)) }
0xAB => { Instruction::RES(5, Target::U8Register(TargetRegister::E)) }
0xAC => { Instruction::RES(5, Target::U8Register(TargetRegister::H)) }
0xAD => { Instruction::RES(5, Target::U8Register(TargetRegister::L)) }
0xAE => { Instruction::RES(5, Target::U16Register(TargetU16Register::HL)) }
0xAF => { Instruction::RES(5, Target::U8Register(TargetRegister::A)) }
0xB0 => { Instruction::RES(6, Target::U8Register(TargetRegister::B)) }
0xB1 => { Instruction::RES(6, Target::U8Register(TargetRegister::C)) }
0xB2 => { Instruction::RES(6, Target::U8Register(TargetRegister::D)) }
0xB3 => { Instruction::RES(6, Target::U8Register(TargetRegister::E)) }
0xB4 => { Instruction::RES(6, Target::U8Register(TargetRegister::H)) }
0xB5 => { Instruction::RES(6, Target::U8Register(TargetRegister::L)) }
0xB6 => { Instruction::RES(6, Target::U16Register(TargetU16Register::HL)) }
0xB7 => { Instruction::RES(6, Target::U8Register(TargetRegister::A)) }
0xB8 => { Instruction::RES(7, Target::U8Register(TargetRegister::B)) }
0xB9 => { Instruction::RES(7, Target::U8Register(TargetRegister::C)) }
0xBA => { Instruction::RES(7, Target::U8Register(TargetRegister::D)) }
0xBB => { Instruction::RES(7, Target::U8Register(TargetRegister::E)) }
0xBC => { Instruction::RES(7, Target::U8Register(TargetRegister::H)) }
0xBD => { Instruction::RES(7, Target::U8Register(TargetRegister::L)) }
0xBE => { Instruction::RES(7, Target::U16Register(TargetU16Register::HL)) }
0xBF => { Instruction::RES(7, Target::U8Register(TargetRegister::A)) }
0xC0 => { Instruction::SET(0, Target::U8Register(TargetRegister::B)) }
0xC1 => { Instruction::SET(0, Target::U8Register(TargetRegister::C)) }
0xC2 => { Instruction::SET(0, Target::U8Register(TargetRegister::D)) }
0xC3 => { Instruction::SET(0, Target::U8Register(TargetRegister::E)) }
0xC4 => { Instruction::SET(0, Target::U8Register(TargetRegister::H)) }
0xC5 => { Instruction::SET(0, Target::U8Register(TargetRegister::L)) }
0xC6 => { Instruction::SET(0, Target::U16Register(TargetU16Register::HL)) }
0xC7 => { Instruction::SET(0, Target::U8Register(TargetRegister::A)) }
0xC8 => { Instruction::SET(1, Target::U8Register(TargetRegister::B)) }
0xC9 => { Instruction::SET(1, Target::U8Register(TargetRegister::C)) }
0xCA => { Instruction::SET(1, Target::U8Register(TargetRegister::D)) }
0xCB => { Instruction::SET(1, Target::U8Register(TargetRegister::E)) }
0xCC => { Instruction::SET(1, Target::U8Register(TargetRegister::H)) }
0xCD => { Instruction::SET(1, Target::U8Register(TargetRegister::L)) }
0xCE => { Instruction::SET(1, Target::U16Register(TargetU16Register::HL)) }
0xCF => { Instruction::SET(1, Target::U8Register(TargetRegister::A)) }
0xD0 => { Instruction::SET(2, Target::U8Register(TargetRegister::B)) }
0xD1 => { Instruction::SET(2, Target::U8Register(TargetRegister::C)) }
0xD2 => { Instruction::SET(2, Target::U8Register(TargetRegister::D)) }
0xD3 => { Instruction::SET(2, Target::U8Register(TargetRegister::E)) }
0xD4 => { Instruction::SET(2, Target::U8Register(TargetRegister::H)) }
0xD5 => { Instruction::SET(2, Target::U8Register(TargetRegister::L)) }
0xD6 => { Instruction::SET(2, Target::U16Register(TargetU16Register::HL)) }
0xD7 => { Instruction::SET(2, Target::U8Register(TargetRegister::A)) }
0xD8 => { Instruction::SET(3, Target::U8Register(TargetRegister::B)) }
0xD9 => { Instruction::SET(3, Target::U8Register(TargetRegister::C)) }
0xDA => { Instruction::SET(3, Target::U8Register(TargetRegister::D)) }
0xDB => { Instruction::SET(3, Target::U8Register(TargetRegister::E)) }
0xDC => { Instruction::SET(3, Target::U8Register(TargetRegister::H)) }
0xDD => { Instruction::SET(3, Target::U8Register(TargetRegister::L)) }
0xDE => { Instruction::SET(3, Target::U16Register(TargetU16Register::HL)) }
0xDF => { Instruction::SET(3, Target::U8Register(TargetRegister::A)) }
0xE0 => { Instruction::SET(4, Target::U8Register(TargetRegister::B)) }
0xE1 => { Instruction::SET(4, Target::U8Register(TargetRegister::C)) }
0xE2 => { Instruction::SET(4, Target::U8Register(TargetRegister::D)) }
0xE3 => { Instruction::SET(4, Target::U8Register(TargetRegister::E)) }
0xE4 => { Instruction::SET(4, Target::U8Register(TargetRegister::H)) }
0xE5 => { Instruction::SET(4, Target::U8Register(TargetRegister::L)) }
0xE6 => { Instruction::SET(4, Target::U16Register(TargetU16Register::HL)) }
0xE7 => { Instruction::SET(4, Target::U8Register(TargetRegister::A)) }
0xE8 => { Instruction::SET(5, Target::U8Register(TargetRegister::B)) }
0xE9 => { Instruction::SET(5, Target::U8Register(TargetRegister::C)) }
0xEA => { Instruction::SET(5, Target::U8Register(TargetRegister::D)) }
0xEB => { Instruction::SET(5, Target::U8Register(TargetRegister::E)) }
0xEC => { Instruction::SET(5, Target::U8Register(TargetRegister::H)) }
0xED => { Instruction::SET(5, Target::U8Register(TargetRegister::L)) }
0xEE => { Instruction::SET(5, Target::U16Register(TargetU16Register::HL)) }
0xEF => { Instruction::SET(5, Target::U8Register(TargetRegister::A)) }
0xF0 => { Instruction::SET(6, Target::U8Register(TargetRegister::B)) }
0xF1 => { Instruction::SET(6, Target::U8Register(TargetRegister::C)) }
0xF2 => { Instruction::SET(6, Target::U8Register(TargetRegister::D)) }
0xF3 => { Instruction::SET(6, Target::U8Register(TargetRegister::E)) }
0xF4 => { Instruction::SET(6, Target::U8Register(TargetRegister::H)) }
0xF5 => { Instruction::SET(6, Target::U8Register(TargetRegister::L)) }
0xF6 => { Instruction::SET(6, Target::U16Register(TargetU16Register::HL)) }
0xF7 => { Instruction::SET(6, Target::U8Register(TargetRegister::A)) }
0xF8 => { Instruction::SET(7, Target::U8Register(TargetRegister::B)) }
0xF9 => { Instruction::SET(7, Target::U8Register(TargetRegister::C)) }
0xFA => { Instruction::SET(7, Target::U8Register(TargetRegister::D)) }
0xFB => { Instruction::SET(7, Target::U8Register(TargetRegister::E)) }
0xFC => { Instruction::SET(7, Target::U8Register(TargetRegister::H)) }
0xFD => { Instruction::SET(7, Target::U8Register(TargetRegister::L)) }
0xFE => { Instruction::SET(7, Target::U16Register(TargetU16Register::HL)) }
0xFF => { Instruction::SET(7, Target::U8Register(TargetRegister::A)) }
_ => { panic!("Invalid u16 opcode: {:02X}", opcode); }
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,61 @@
#[derive(Clone, Copy)] const LCD_ENABLED_BIT: u8 = 7;
const WINDOW_TILE_MAP_AREA_BIT: u8 = 6;
const WINDOW_ENABLE_BIT: u8 = 5;
const BG_AND_WINDOW_TILE_DATA_AREA_BIT: u8 = 4;
const BG_TILE_MAP_AREA_BIT: u8 = 3;
const OBJECT_SIZE_BIT: u8 = 2;
const OBJECT_ENABLE_BIT: u8 = 1;
const BG_AND_WINDOW_ENABLE_BIT: u8 = 0;
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct LCDControlRegister {
pub(crate) lcd_enabled: bool,
pub(crate) window_tile_map_area: bool,
pub(crate) window_enable: bool,
pub(crate) bg_and_window_tile_area: bool,
pub(crate) bg_tile_map_area: bool,
pub(crate) object_size: bool,
pub(crate) object_enable: bool,
pub(crate) bg_and_window_enable: bool,
}
impl From<LCDControlRegister> for u8 {
fn from(flag: LCDControlRegister) -> u8 {
(if flag.lcd_enabled { 1 } else { 0 }) << LCD_ENABLED_BIT |
(if flag.window_tile_map_area { 1 } else { 0 }) << WINDOW_TILE_MAP_AREA_BIT |
(if flag.window_enable { 1 } else { 0 }) << WINDOW_ENABLE_BIT |
(if flag.bg_and_window_tile_area{ 1 } else { 0 }) << BG_AND_WINDOW_TILE_DATA_AREA_BIT |
(if flag.bg_tile_map_area { 1 } else { 0 }) << BG_TILE_MAP_AREA_BIT |
(if flag.object_size { 1 } else { 0 }) << OBJECT_SIZE_BIT |
(if flag.object_enable { 1 } else { 0 }) << OBJECT_ENABLE_BIT |
(if flag.bg_and_window_enable { 1 } else { 0 }) << BG_AND_WINDOW_ENABLE_BIT
}
}
impl From<u8> for LCDControlRegister {
fn from(byte: u8) -> Self {
let lcd_enabled = ((byte >> LCD_ENABLED_BIT) & 0b1) != 0;
let window_tile_map_area = ((byte >> WINDOW_TILE_MAP_AREA_BIT) & 0b1) != 0;
let window_enable = ((byte >> WINDOW_ENABLE_BIT) & 0b1) != 0;
let bg_and_window_tile_area = ((byte >> BG_AND_WINDOW_TILE_DATA_AREA_BIT) & 0b1) != 0;
let bg_tile_map_area = ((byte >> BG_TILE_MAP_AREA_BIT) & 0b1) != 0;
let object_size = ((byte >> OBJECT_SIZE_BIT) & 0b1) != 0;
let object_enable = ((byte >> OBJECT_ENABLE_BIT) & 0b1) != 0;
let bg_and_window_enable = ((byte >> BG_AND_WINDOW_ENABLE_BIT) & 0b1) != 0;
LCDControlRegister {
lcd_enabled,
window_tile_map_area,
window_enable,
bg_and_window_tile_area,
bg_tile_map_area,
object_size,
object_enable,
bg_and_window_enable,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct FlagsRegister { pub(crate) struct FlagsRegister {
pub(crate) zero: bool, pub(crate) zero: bool,
pub(crate) subtract: bool, pub(crate) subtract: bool,
@@ -7,6 +63,7 @@ pub(crate) struct FlagsRegister {
pub(crate) carry: bool pub(crate) carry: bool
} }
const ZERO_FLAG_BYTE_POSITION: u8 = 7; const ZERO_FLAG_BYTE_POSITION: u8 = 7;
const SUBTRACT_FLAG_BYTE_POSITION: u8 = 6; const SUBTRACT_FLAG_BYTE_POSITION: u8 = 6;
const HALF_CARRY_FLAG_BYTE_POSITION: u8 = 5; const HALF_CARRY_FLAG_BYTE_POSITION: u8 = 5;
@@ -36,6 +93,7 @@ impl From<u8> for FlagsRegister {
} }
} }
} }
#[derive(Debug)]
pub(crate) struct Registers { pub(crate) struct Registers {
pub(crate) a: u8, pub(crate) a: u8,
pub(crate) b: u8, pub(crate) b: u8,