|
| 1 | +#[derive(Debug)] |
| 2 | +#[allow(non_camel_case_types)] |
| 3 | +pub enum Instruction { |
| 4 | + ADC_A_B, |
| 5 | + ADC_A_C, |
| 6 | + ADC_A_d8, |
| 7 | + ADD_A__HL_, |
| 8 | + ADD_A_E, |
| 9 | + AND_L, |
| 10 | + CALL_a16, |
| 11 | + CALL_Z_a16, |
| 12 | + CP__HL_, |
| 13 | + CP_C, |
| 14 | + CP_d8, |
| 15 | + CP_E, |
| 16 | + DEC_A, |
| 17 | + DEC_B, |
| 18 | + DEC_BC, |
| 19 | + DEC_C, |
| 20 | + DEC_D, |
| 21 | + DEC_E, |
| 22 | + EI, |
| 23 | + Illegal(u8), |
| 24 | + INC_A, |
| 25 | + INC_B, |
| 26 | + INC_BC, |
| 27 | + INC_C, |
| 28 | + INC_DE, |
| 29 | + INC_H, |
| 30 | + INC_HL, |
| 31 | + INC_SP, |
| 32 | + JR_NZ_r8, |
| 33 | + JR_r8, |
| 34 | + JR_Z_r8, |
| 35 | + LD__a16__A, |
| 36 | + LD__a16__SP, |
| 37 | + LD__C__A, |
| 38 | + LD__HL__A, |
| 39 | + LD__HL__E, |
| 40 | + LD_A__DE_, |
| 41 | + LD_A_B, |
| 42 | + LD_A_d8, |
| 43 | + LD_A_E, |
| 44 | + LD_A_H, |
| 45 | + LD_A_L, |
| 46 | + LD_B_D, |
| 47 | + LD_B_d8, |
| 48 | + LD_C_A, |
| 49 | + LD_C_d8, |
| 50 | + LD_D_A, |
| 51 | + LD_D_d8, |
| 52 | + LD_DE_d16, |
| 53 | + LD_E_d8, |
| 54 | + LD_H__HL_, |
| 55 | + LD_H_A, |
| 56 | + LD_H_E, |
| 57 | + LD_HL_d16, |
| 58 | + LD_HL_minus_A, |
| 59 | + LD_HL_plus_A, |
| 60 | + LD_L__HL_, |
| 61 | + LD_L_d8, |
| 62 | + LD_SP_A, |
| 63 | + LDH__a8__A, |
| 64 | + LDH_A__a8__, |
| 65 | + NOP, |
| 66 | + Prefix, |
| 67 | + PUSH_BC, |
| 68 | + RET_NZ, |
| 69 | + RET, |
| 70 | + RETI, |
| 71 | + RLA, |
| 72 | + SBC_A_A, |
| 73 | + SBC_A_C, |
| 74 | + SUB_B, |
| 75 | + XOR_A, |
| 76 | +} |
| 77 | + |
| 78 | +/* |
| 79 | +0x00 LD SP, 0xFFFE |
| 80 | +0x03 XOR A |
| 81 | +0x04 LD HL, 0x9FFF |
| 82 | +0x07 LD (HL-), A |
| 83 | +0x08 BIT 7, H |
| 84 | +0x0A JR NZ, 0xFB |
| 85 | +0x0C LD HL, 0xFF26 |
| 86 | +0x0F LD C, 0x11 |
| 87 | +0x11 LD A, 0x80 |
| 88 | +0x13 LD (HL-), A |
| 89 | +0x14 LD (C), A |
| 90 | +0x15 INC C |
| 91 | +
|
| 92 | +00000000 31 fe ff af 21 ff 9f 32 cb 7c 20 fb 21 26 ff 0e |
| 93 | +00000010 11 3e 80 32 e2 0c 3e f3 e2 32 3e 77 77 3e fc e0 |
| 94 | +
|
| 95 | +*/ |
| 96 | + |
| 97 | +#[derive(Debug)] |
| 98 | +pub struct DecodedInstruction { |
| 99 | + pub address: u16, |
| 100 | + pub instruction: Instruction, |
| 101 | + pub instruction_size: u8, |
| 102 | +} |
| 103 | + |
| 104 | +pub fn decode_next_instruction(address: u16, slice_at_program_counter: &[u8]) -> DecodedInstruction { |
| 105 | + let (i, s) = match slice_at_program_counter[0] { |
| 106 | + 0x00 => (Instruction::NOP, 1), |
| 107 | + 0x03 => (Instruction::INC_BC, 1), |
| 108 | + 0x04 => (Instruction::INC_B, 1), |
| 109 | + 0x05 => (Instruction::DEC_B, 1), |
| 110 | + 0x06 => (Instruction::LD_B_d8, 2), |
| 111 | + 0x08 => (Instruction::LD__a16__SP, 3), |
| 112 | + 0x0B => (Instruction::DEC_BC, 1), |
| 113 | + 0x0C => (Instruction::INC_C, 1), |
| 114 | + 0x0D => (Instruction::DEC_C, 1), |
| 115 | + 0x0E => (Instruction::LD_C_d8, 2), |
| 116 | + 0x11 => (Instruction::LD_DE_d16, 3), |
| 117 | + 0x13 => (Instruction::INC_DE, 1), |
| 118 | + 0x15 => (Instruction::DEC_D, 1), |
| 119 | + 0x16 => (Instruction::LD_D_d8, 2), |
| 120 | + 0x17 => (Instruction::RLA, 1), |
| 121 | + 0x18 => (Instruction::JR_r8, 2), |
| 122 | + 0x1A => (Instruction::LD_A__DE_, 1), |
| 123 | + 0x1D => (Instruction::DEC_E, 1), |
| 124 | + 0x1E => (Instruction::LD_E_d8, 2), |
| 125 | + 0x20 => (Instruction::JR_NZ_r8, 2), |
| 126 | + 0x21 => (Instruction::LD_HL_d16, 3), |
| 127 | + 0x22 => (Instruction::LD_HL_plus_A, 1), |
| 128 | + 0x23 => (Instruction::INC_HL, 1), |
| 129 | + 0x24 => (Instruction::INC_H, 1), |
| 130 | + 0x28 => (Instruction::JR_Z_r8, 2), |
| 131 | + 0x2E => (Instruction::LD_L_d8, 2), |
| 132 | + 0x31 => (Instruction::LD_SP_A, 3), |
| 133 | + 0x32 => (Instruction::LD_HL_minus_A, 1), |
| 134 | + 0x33 => (Instruction::INC_SP, 1), |
| 135 | + 0x3C => (Instruction::INC_A, 1), |
| 136 | + 0x3D => (Instruction::DEC_A, 1), |
| 137 | + 0x3E => (Instruction::LD_A_d8, 2), |
| 138 | + 0x42 => (Instruction::LD_B_D, 1), |
| 139 | + 0x4F => (Instruction::LD_C_A, 1), |
| 140 | + 0x57 => (Instruction::LD_D_A, 1), |
| 141 | + 0x63 => (Instruction::LD_H_E, 1), |
| 142 | + 0x66 => (Instruction::LD_H__HL_, 1), |
| 143 | + 0x67 => (Instruction::LD_H_A, 1), |
| 144 | + 0x6E => (Instruction::LD_L__HL_, 1), |
| 145 | + 0x73 => (Instruction::LD__HL__E, 1), |
| 146 | + 0x77 => (Instruction::LD__HL__A, 1), |
| 147 | + 0x78 => (Instruction::LD_A_B, 1), |
| 148 | + 0x7B => (Instruction::LD_A_E, 1), |
| 149 | + 0x7C => (Instruction::LD_A_H, 1), |
| 150 | + 0x7D => (Instruction::LD_A_L, 1), |
| 151 | + 0x83 => (Instruction::ADD_A_E, 1), |
| 152 | + 0x86 => (Instruction::ADD_A__HL_, 1), |
| 153 | + 0x88 => (Instruction::ADC_A_B, 1), |
| 154 | + 0x89 => (Instruction::ADC_A_C, 1), |
| 155 | + 0x90 => (Instruction::SUB_B, 1), |
| 156 | + 0x99 => (Instruction::SBC_A_C, 1), |
| 157 | + 0x9F => (Instruction::SBC_A_A, 1), |
| 158 | + 0xA5 => (Instruction::AND_L, 1), |
| 159 | + 0xAF => (Instruction::XOR_A, 1), |
| 160 | + 0xB9 => (Instruction::CP_C, 1), |
| 161 | + 0xBB => (Instruction::CP_E, 1), |
| 162 | + 0xBE => (Instruction::CP__HL_, 1), |
| 163 | + 0xC1 => (Instruction::RET_NZ, 1), |
| 164 | + 0xC9 => (Instruction::RET, 1), |
| 165 | + 0xCB => match slice_at_program_counter[1] { |
| 166 | + _ => { |
| 167 | + (Instruction::Prefix, 2) // 1 for prefix, 1 for extension? |
| 168 | + // println!("TODO: CB-prefixed opcode 0x{:x}", slice_at_program_counter[1]); |
| 169 | + // todo!() |
| 170 | + } |
| 171 | + }, |
| 172 | + 0xC5 => (Instruction::PUSH_BC, 1), |
| 173 | + 0xCC => (Instruction::CALL_Z_a16, 3), |
| 174 | + 0xCD => (Instruction::CALL_a16, 3), |
| 175 | + 0xCE => (Instruction::ADC_A_d8, 2), |
| 176 | + 0xD9 => (Instruction::RETI, 1), |
| 177 | + 0xE0 => (Instruction::LDH__a8__A, 2), |
| 178 | + 0xE2 => (Instruction::LD__C__A, 1), |
| 179 | + 0xEA => (Instruction::LD__a16__A, 3), |
| 180 | + 0xF0 => (Instruction::LDH_A__a8__, 2), |
| 181 | + 0xFB => (Instruction::EI, 1), |
| 182 | + 0xFE => (Instruction::CP_d8, 2), |
| 183 | + b => (Instruction::Illegal(b), 1), |
| 184 | + }; |
| 185 | + DecodedInstruction { |
| 186 | + instruction: i, |
| 187 | + instruction_size: s, |
| 188 | + address, |
| 189 | + } |
| 190 | +} |
| 191 | + |
| 192 | +impl Instruction { |
| 193 | + // /// Returns the number of cycles to execute this [`Instruction`]. |
| 194 | + // pub fn get_cycles(self: &Instruction) -> i8 { |
| 195 | + // match self { |
| 196 | + // Instruction::LD_SP_A => todo!(), |
| 197 | + // Instruction::XOR_A => todo!(), |
| 198 | + // Instruction::LD_HL_d16 => todo!(), |
| 199 | + // Instruction::LD_HL_minus_A => todo!(), |
| 200 | + // Instruction::Prefix => todo!(), |
| 201 | + // Instruction::EI => todo!(), |
| 202 | + // Instruction::LD_C_d8 => todo!(), |
| 203 | + // Instruction::LD_A_d8 => todo!(), |
| 204 | + // Instruction::LD__C__A => todo!(), |
| 205 | + // } |
| 206 | + // } |
| 207 | +} |
0 commit comments