1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
//! This module provides the symbolic representation of all z80 instructions //! You can construct these yourself, or you can parse binaries using `zeerust::cpu::opcodes`. use std::fmt::Display; /// Op represents a single operation. /// This representation (and backing implementation) is more expressive than /// the processor itself. /// For example `ADD8(Location8::Reg(Reg8::D), Location8::Immediate(10))` is a valid representation, but /// the Z80 features no such instruction. /// Usually executing an instruction like this will just work, but in some cases a panic will occur /// (Such as attempting to store to an immediate, which doesn't make any sense). /// It is probably best to stick to the "guide rails" of the Z80 operations. #[derive(Debug, PartialEq, Clone)] pub enum Op { /// ADd including Carry ADC(Location8, Location8), /// ADD (8-bit) ADD8(Location8, Location8), /// INCrement INC(Location8), /// SuBtract including borrow (Carry bit) SBC(Location8, Location8), /// SUBtraction (8-bit) SUB8(Location8, Location8), /// DECrement DEC(Location8), /// bitwise AND AND(Location8), /// bitwise OR OR(Location8), /// bitwise XOR XOR(Location8), /// two's ComPliment CP(Location8), /// One's ComPLiment CPL, // One's Compliment /// sign NEGation (two's compliment) NEG, // Negation (two's compliment) /// toggle the Carry Flag CCF, // toggle carry flag /// Set the Carry Flag unconditionally SCF, /// Do nothing (No-OPeration) NOP, /// HALT execution (until woken) HALT, // End execution (until woken) /// BCD nonsense. Not implemented DAA, /// Rotate Accumulator Left, set Carry RLCA, /// Rotate Accumulator Left, through carry RLA, /// Rotate Accumulator Right, set Carry RRCA, /// Rotate Accumulator Left, through carry RRA, /// Rotate Left, set Carry RLC(Location8), /// Rotate Left, through carry RL(Location8), /// Rotate Right, set Carry RRC(Location8), /// Rotate Right, through carry RR(Location8), /// Shift Left SLA(Location8), /// Shift Right SRL(Location8), /// Shift Right, preserving 7th bit SRA(Location8), /// Rotate nibbles Left through accumulator RLD, /// Rotate nibbles Right through accumulator RRD, /// set zero flag if BIT is on BIT(u8, Location8), /// SET b bit in location SET(u8, Location8), /// RESet b bit in location RES(u8, Location8), /// INput from a peripheral IN(Location8, Location8), /// OUTput to a peripheral OUT(Location8, Location8), /// JumP to the given position JP(JumpConditional, Location16), /// Jump to the given Relative position JR(JumpConditional, i8), /// Decrement register b, then Jump if register b is Non Zero DJNZ(i8), /// CALL a method CALL(JumpConditional, u16), /// RETurn from a method call RET(JumpConditional), /// Pop an address off of the stack POP(Location16), /// Push an address onto a stack PUSH(Location16), /// LoaD the given address (8-bit) LD8(Location8, Location8), /// LoaD the given address (16-bit) LD16(Location16, Location16), // TODO // CPD, // CPDR, // CPI, // CPIR, // DI, // EI, // EX, // EXX, // IM, // IN, // IND, // INDR, // INI, // INIR, // LDD, // LDDR, // LDI, // OTDR, // OTIR, // OUTD, // OUTI, // RETI, // RETN, // RST, // SLA, // SLL, // SL1, // SRA, // SRL, } /// 8 bit registers #[derive(Debug, PartialEq, Clone, Copy, Display)] pub enum Reg8 { A, F, B, C, D, E, H, L, /// A' AP, /// F' FP, /// B' BP, /// C' CP, /// D' DP, /// E' EP, /// H' HP, /// L' LP, } /// 16-bit registers #[derive(Debug, PartialEq, Clone, Display)] pub enum Reg16 { AF, BC, DE, HL, /// AF' AFP, /// BC' BCP, /// DE' DEP, /// HL' HLP, IX, IY, /// Stack Pointer SP, } /// Anywhere an 8-bit value could could come from or be stored to #[derive(Debug, PartialEq, Clone)] pub enum Location8 { /// A register Reg(Reg8), /// A location in memory, pointed to by a 16-bit register RegIndirect(Reg16), /// A location in memory, pointed to by a literal number ImmediateIndirect(u16), /// A literal number Immediate(u8), } /// Anywhere a 16-bit value could could come from or be stored to #[derive(Debug, PartialEq, Clone)] pub enum Location16 { /// A 16-bit combined register Reg(Reg16), /// A location in memory, pointed to by a 16 bit register. RegIndirect(Reg16), // Is this used anywhere? /// A location in memory, pointed to by a literal number ImmediateIndirect(u16), /// A literal number Immediate(u16), } /// Status Flags. Implemented in the Z80 as a bitfield on register F #[derive(Debug, PartialEq, Clone)] pub enum StatusFlag { /// Bit 0. Indicates carry or borrows from bit 7 Carry, /// Bit 1. Usually 0 after addition, 1 after subtraction AddSubtract, /// Bit 2. Indicates overflow after arithmetic, or parity after bitwise operations /// Parity is set if the number of 1s in the number is even, otherwise it is reset ParityOverflow, // Bit 3 unused /// Bit 4. Indicates carry or borrows from bit 3 HalfCarry, /// Bit 6. Set if result of an operation was zero Zero, /// Bit 7. Set if the 7th bit is 1 after an arithmatic operation, i.e. number is negative if considered as signed Sign, } /// Jumps and Returns can be conditional on certain flags being set #[derive(Debug, PartialEq, Copy, Clone)] pub enum JumpConditional { /// Both Jump and Return have unconditional versions. /// Rather than a seperate Op, these will have this flag. /// It always evaluates to true Unconditional, /// True if the Zero flag is reset NonZero, /// True if the Zero flag is set Zero, /// True if the Carry flag is reset NoCarry, /// True if the Carry flag is set Carry, /// True if the ParityOverflow bit is reset ParityOdd, /// True if the ParityOverflow bit is set ParityEven, /// True if the Sign bit is reset SignPositive, /// True if the Sign bit is set SignNegative, }