use crate::preamble::*;
pub const TABINSTRFDCB: [&str; 256] = [
"RLC (IY+nn), B",
"RLC (IY+nn), C",
"RLC (IY+nn), D",
"RLC (IY+nn), E",
"RLC (IY+nn), H",
"RLC (IY+nn), L",
"RLC (IY+nn)",
"RLC (IY+nn), A",
"RRC (IY+nn), B",
"RRC (IY+nn), C",
"RRC (IY+nn), D",
"RRC (IY+nn), E",
"RRC (IY+nn), H",
"RRC (IY+nn), L",
"RRC (IY+nn)",
"RRC (IY+nn), A",
"RL (IY+nn), B",
"RL (IY+nn), C",
"RL (IY+nn), D",
"RL (IY+nn), E",
"RL (IY+nn), H",
"RL (IY+nn), L",
"RL (IY+nn)",
"RL (IY+nn), A",
"RR (IY+nn), B",
"RR (IY+nn), C",
"RR (IY+nn), D",
"RR (IY+nn), E",
"RR (IY+nn), H",
"RR (IY+nn), L",
"RR (IY+nn)",
"RR (IY+nn), A",
"SLA (IY+nn),B",
"SLA (IY+nn),C",
"SLA (IY+nn),D",
"SLA (IY+nn),E",
"SLA (IY+nn),H",
"SLA (IY+nn),L",
"SLA (IY+nn)",
"SLA (IY+nn),A",
"SRA (IY+nn), B",
"SRA (IY+nn), C",
"SRA (IY+nn), D",
"SRA (IY+nn), E",
"SRA (IY+nn), H",
"SRA (IY+nn), L",
"SRA (IY+nn)",
"SRA (IY+nn), A",
"SL1 (IY+nn), B",
"SL1 (IY+nn), C",
"SL1 (IY+nn), D",
"SL1 (IY+nn), E",
"SL1 (IY+nn), H",
"SL1 (IY+nn), L",
"SL1 (IY+nn)",
"SL1 (IY+nn), A",
"SRL (IY+nn), B",
"SRL (IY+nn), C",
"SRL (IY+nn), D",
"SRL (IY+nn), E",
"SRL (IY+nn), H",
"SRL (IY+nn), L",
"SRL (IY+nn)",
"SRL (IY+nn), A",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 0,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 1,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 2,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 3,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 4,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 5,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 6,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"BIT 7,(IY+nn)",
"RES 0,(IY+nn), B",
"RES 0,(IY+nn), C",
"RES 0,(IY+nn), D",
"RES 0,(IY+nn), E",
"RES 0,(IY+nn), H",
"RES 0,(IY+nn), L",
"RES 0,(IY+nn)",
"RES 0,(IY+nn), A",
"RES 1,(IY+nn), B",
"RES 1,(IY+nn), C",
"RES 1,(IY+nn), D",
"RES 1,(IY+nn), E",
"RES 1,(IY+nn), H",
"RES 1,(IY+nn), L",
"RES 1,(IY+nn)",
"RES 1,(IY+nn), A",
"RES 2,(IY+nn), B",
"RES 2,(IY+nn), C",
"RES 2,(IY+nn), D",
"RES 2,(IY+nn), E",
"RES 2,(IY+nn), H",
"RES 2,(IY+nn), L",
"RES 2,(IY+nn)",
"RES 2,(IY+nn), A",
"RES 3,(IY+nn), B",
"RES 3,(IY+nn), C",
"RES 3,(IY+nn), D",
"RES 3,(IY+nn), E",
"RES 3,(IY+nn), H",
"RES 3,(IY+nn), L",
"RES 3,(IY+nn)",
"RES 3,(IY+nn), A",
"RES 4,(IY+nn), B",
"RES 4,(IY+nn), C",
"RES 4,(IY+nn), D",
"RES 4,(IY+nn), E",
"RES 4,(IY+nn), H",
"RES 4,(IY+nn), L",
"RES 4,(IY+nn)",
"RES 4,(IY+nn), A",
"RES 5,(IY+nn), B",
"RES 5,(IY+nn), C",
"RES 5,(IY+nn), D",
"RES 5,(IY+nn), E",
"RES 5,(IY+nn), H",
"RES 5,(IY+nn), L",
"RES 5,(IY+nn)",
"RES 5,(IY+nn), A",
"RES 6,(IY+nn), B",
"RES 6,(IY+nn), C",
"RES 6,(IY+nn), D",
"RES 6,(IY+nn), E",
"RES 6,(IY+nn), H",
"RES 6,(IY+nn), L",
"RES 6,(IY+nn)",
"RES 6,(IY+nn), A",
"RES 7,(IY+nn), B",
"RES 7,(IY+nn), C",
"RES 7,(IY+nn), D",
"RES 7,(IY+nn), E",
"RES 7,(IY+nn), H",
"RES 7,(IY+nn), L",
"RES 7,(IY+nn)",
"RES 7,(IY+nn), A",
"SET 0,(IY+nn), B",
"SET 0,(IY+nn), C",
"SET 0,(IY+nn), D",
"SET 0,(IY+nn), E",
"SET 0,(IY+nn), H",
"SET 0,(IY+nn), L",
"SET 0,(IY+nn)",
"SET 0,(IY+nn), A",
"SET 1,(IY+nn), B",
"SET 1,(IY+nn), C",
"SET 1,(IY+nn), D",
"SET 1,(IY+nn), E",
"SET 1,(IY+nn), H",
"SET 1,(IY+nn), L",
"SET 1,(IY+nn)",
"SET 1,(IY+nn), A",
"SET 2,(IY+nn), B",
"SET 2,(IY+nn), C",
"SET 2,(IY+nn), D",
"SET 2,(IY+nn), E",
"SET 2,(IY+nn), H",
"SET 2,(IY+nn), L",
"SET 2,(IY+nn)",
"SET 2,(IY+nn), A",
"SET 3,(IY+nn), B",
"SET 3,(IY+nn), C",
"SET 3,(IY+nn), D",
"SET 3,(IY+nn), E",
"SET 3,(IY+nn), H",
"SET 3,(IY+nn), L",
"SET 3,(IY+nn)",
"SET 3,(IY+nn), A",
"SET 4,(IY+nn), B",
"SET 4,(IY+nn), C",
"SET 4,(IY+nn), D",
"SET 4,(IY+nn), E",
"SET 4,(IY+nn), H",
"SET 4,(IY+nn), L",
"SET 4,(IY+nn)",
"SET 4,(IY+nn), A",
"SET 5,(IY+nn), B",
"SET 5,(IY+nn), C",
"SET 5,(IY+nn), D",
"SET 5,(IY+nn), E",
"SET 5,(IY+nn), H",
"SET 5,(IY+nn), L",
"SET 5,(IY+nn)",
"SET 5,(IY+nn), A",
"SET 6,(IY+nn), B",
"SET 6,(IY+nn), C",
"SET 6,(IY+nn), D",
"SET 6,(IY+nn), E",
"SET 6,(IY+nn), H",
"SET 6,(IY+nn), L",
"SET 6,(IY+nn)",
"SET 6,(IY+nn), A",
"SET 7,(IY+nn), B",
"SET 7,(IY+nn), C",
"SET 7,(IY+nn), D",
"SET 7,(IY+nn), E",
"SET 7,(IY+nn), H",
"SET 7,(IY+nn), L",
"SET 7,(IY+nn)",
"SET 7,(IY+nn), A"
];
pub const TABINSTRDDCB: [&str; 256] = [
"RLC (IX+nn), B",
"RLC (IX+nn), C",
"RLC (IX+nn), D",
"RLC (IX+nn), E",
"RLC (IX+nn), H",
"RLC (IX+nn), L",
"RLC (IX+nn)",
"RLC (IX+nn), A",
"RRC (IX+nn), B",
"RRC (IX+nn), C",
"RRC (IX+nn), D",
"RRC (IX+nn), E",
"RRC (IX+nn), H",
"RRC (IX+nn), L",
"RRC (IX+nn)",
"RRC (IX+nn), A",
"RL (IX+nn), B",
"RL (IX+nn), C",
"RL (IX+nn), D",
"RL (IX+nn), E",
"RL (IX+nn), H",
"RL (IX+nn), L",
"RL (IX+nn)",
"RL (IX+nn), A",
"RR (IX+nn), B",
"RR (IX+nn), C",
"RR (IX+nn), D",
"RR (IX+nn), E",
"RR (IX+nn), H",
"RR (IX+nn), L",
"RR (IX+nn)",
"RR (IX+nn), A",
"SLA (IX+nn),B",
"SLA (IX+nn),C",
"SLA (IX+nn),D",
"SLA (IX+nn),E",
"SLA (IX+nn),H",
"SLA (IX+nn),L",
"SLA (IX+nn)",
"SLA (IX+nn),A",
"SRA (IX+nn), B",
"SRA (IX+nn), C",
"SRA (IX+nn), D",
"SRA (IX+nn), E",
"SRA (IX+nn), H",
"SRA (IX+nn), L",
"SRA (IX+nn)",
"SRA (IX+nn), A",
"SL1 (IX+nn), B",
"SL1 (IX+nn), C",
"SL1 (IX+nn), D",
"SL1 (IX+nn), E",
"SL1 (IX+nn), H",
"SL1 (IX+nn), L",
"SL1 (IX+nn)",
"SL1 (IX+nn), A",
"SRL (IX+nn), B",
"SRL (IX+nn), C",
"SRL (IX+nn), D",
"SRL (IX+nn), E",
"SRL (IX+nn), H",
"SRL (IX+nn), L",
"SRL (IX+nn)",
"SRL (IX+nn), A",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 0,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 1,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 2,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 3,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 4,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 5,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 6,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"BIT 7,(IX+nn)",
"RES 0,(IX+nn), B",
"RES 0,(IX+nn), C",
"RES 0,(IX+nn), D",
"RES 0,(IX+nn), E",
"RES 0,(IX+nn), H",
"RES 0,(IX+nn), L",
"RES 0,(IX+nn)",
"RES 0,(IX+nn), A",
"RES 1,(IX+nn), B",
"RES 1,(IX+nn), C",
"RES 1,(IX+nn), D",
"RES 1,(IX+nn), E",
"RES 1,(IX+nn), H",
"RES 1,(IX+nn), L",
"RES 1,(IX+nn)",
"RES 1,(IX+nn), A",
"RES 2,(IX+nn), B",
"RES 2,(IX+nn), C",
"RES 2,(IX+nn), D",
"RES 2,(IX+nn), E",
"RES 2,(IX+nn), H",
"RES 2,(IX+nn), L",
"RES 2,(IX+nn)",
"RES 2,(IX+nn), A",
"RES 3,(IX+nn), B",
"RES 3,(IX+nn), C",
"RES 3,(IX+nn), D",
"RES 3,(IX+nn), E",
"RES 3,(IX+nn), H",
"RES 3,(IX+nn), L",
"RES 3,(IX+nn)",
"RES 3,(IX+nn), A",
"RES 4,(IX+nn), B",
"RES 4,(IX+nn), C",
"RES 4,(IX+nn), D",
"RES 4,(IX+nn), E",
"RES 4,(IX+nn), H",
"RES 4,(IX+nn), L",
"RES 4,(IX+nn)",
"RES 4,(IX+nn), A",
"RES 5,(IX+nn), B",
"RES 5,(IX+nn), C",
"RES 5,(IX+nn), D",
"RES 5,(IX+nn), E",
"RES 5,(IX+nn), H",
"RES 5,(IX+nn), L",
"RES 5,(IX+nn)",
"RES 5,(IX+nn), A",
"RES 6,(IX+nn), B",
"RES 6,(IX+nn), C",
"RES 6,(IX+nn), D",
"RES 6,(IX+nn), E",
"RES 6,(IX+nn), H",
"RES 6,(IX+nn), L",
"RES 6,(IX+nn)",
"RES 6,(IX+nn), A",
"RES 7,(IX+nn), B",
"RES 7,(IX+nn), C",
"RES 7,(IX+nn), D",
"RES 7,(IX+nn), E",
"RES 7,(IX+nn), H",
"RES 7,(IX+nn), L",
"RES 7,(IX+nn)",
"RES 7,(IX+nn), A",
"SET 0,(IX+nn), B",
"SET 0,(IX+nn), C",
"SET 0,(IX+nn), D",
"SET 0,(IX+nn), E",
"SET 0,(IX+nn), H",
"SET 0,(IX+nn), L",
"SET 0,(IX+nn)",
"SET 0,(IX+nn), A",
"SET 1,(IX+nn), B",
"SET 1,(IX+nn), C",
"SET 1,(IX+nn), D",
"SET 1,(IX+nn), E",
"SET 1,(IX+nn), H",
"SET 1,(IX+nn), L",
"SET 1,(IX+nn)",
"SET 1,(IX+nn), A",
"SET 2,(IX+nn), B",
"SET 2,(IX+nn), C",
"SET 2,(IX+nn), D",
"SET 2,(IX+nn), E",
"SET 2,(IX+nn), H",
"SET 2,(IX+nn), L",
"SET 2,(IX+nn)",
"SET 2,(IX+nn), A",
"SET 3,(IX+nn), B",
"SET 3,(IX+nn), C",
"SET 3,(IX+nn), D",
"SET 3,(IX+nn), E",
"SET 3,(IX+nn), H",
"SET 3,(IX+nn), L",
"SET 3,(IX+nn)",
"SET 3,(IX+nn), A",
"SET 4,(IX+nn), B",
"SET 4,(IX+nn), C",
"SET 4,(IX+nn), D",
"SET 4,(IX+nn), E",
"SET 4,(IX+nn), H",
"SET 4,(IX+nn), L",
"SET 4,(IX+nn)",
"SET 4,(IX+nn), A",
"SET 5,(IX+nn), B",
"SET 5,(IX+nn), C",
"SET 5,(IX+nn), D",
"SET 5,(IX+nn), E",
"SET 5,(IX+nn), H",
"SET 5,(IX+nn), L",
"SET 5,(IX+nn)",
"SET 5,(IX+nn), A",
"SET 6,(IX+nn), B",
"SET 6,(IX+nn), C",
"SET 6,(IX+nn), D",
"SET 6,(IX+nn), E",
"SET 6,(IX+nn), H",
"SET 6,(IX+nn), L",
"SET 6,(IX+nn)",
"SET 6,(IX+nn), A",
"SET 7,(IX+nn), B",
"SET 7,(IX+nn), C",
"SET 7,(IX+nn), D",
"SET 7,(IX+nn), E",
"SET 7,(IX+nn), H",
"SET 7,(IX+nn), L",
"SET 7,(IX+nn)",
"SET 7,(IX+nn), A"
];
pub const TABINSTRCB: [&str; 256] = [
"RLC B",
"RLC C",
"RLC D",
"RLC E",
"RLC H",
"RLC L",
"RLC (HL)",
"RLC A",
"RRC B",
"RRC C",
"RRC D",
"RRC E",
"RRC H",
"RRC L",
"RRC (HL)",
"RRC A",
"RL B",
"RL C",
"RL D",
"RL E",
"RL H",
"RL L",
"RL (HL)",
"RL A",
"RR B",
"RR C",
"RR D",
"RR E",
"RR H",
"RR L",
"RR (HL)",
"RR A",
"SLA B",
"SLA C",
"SLA D",
"SLA E",
"SLA H",
"SLA L",
"SLA (HL)",
"SLA A",
"SRA B",
"SRA C",
"SRA D",
"SRA E",
"SRA H",
"SRA L",
"SRA (HL)",
"SRA A",
"SL1 B",
"SL1 C",
"SL1 D",
"SL1 E",
"SL1 H",
"SL1 L",
"SL1 (HL)",
"SL1 A",
"SRL B",
"SRL C",
"SRL D",
"SRL E",
"SRL H",
"SRL L",
"SRL (HL)",
"SRL A",
"BIT 0,B",
"BIT 0,C",
"BIT 0,D",
"BIT 0,E",
"BIT 0,H",
"BIT 0,L",
"BIT 0,(HL)",
"BIT 0,A",
"BIT 1,B",
"BIT 1,C",
"BIT 1,D",
"BIT 1,E",
"BIT 1,H",
"BIT 1,L",
"BIT 1,(HL)",
"BIT 1,A",
"BIT 2,B",
"BIT 2,C",
"BIT 2,D",
"BIT 2,E",
"BIT 2,H",
"BIT 2,L",
"BIT 2,(HL)",
"BIT 2,A",
"BIT 3,B",
"BIT 3,C",
"BIT 3,D",
"BIT 3,E",
"BIT 3,H",
"BIT 3,L",
"BIT 3,(HL)",
"BIT 3,A",
"BIT 4,B",
"BIT 4,C",
"BIT 4,D",
"BIT 4,E",
"BIT 4,H",
"BIT 4,L",
"BIT 4,(HL)",
"BIT 4,A",
"BIT 5,B",
"BIT 5,C",
"BIT 5,D",
"BIT 5,E",
"BIT 5,H",
"BIT 5,L",
"BIT 5,(HL)",
"BIT 5,A",
"BIT 6,B",
"BIT 6,C",
"BIT 6,D",
"BIT 6,E",
"BIT 6,H",
"BIT 6,L",
"BIT 6,(HL)",
"BIT 6,A",
"BIT 7,B",
"BIT 7,C",
"BIT 7,D",
"BIT 7,E",
"BIT 7,H",
"BIT 7,L",
"BIT 7,(HL)",
"BIT 7,A",
"RES 0,B",
"RES 0,C",
"RES 0,D",
"RES 0,E",
"RES 0,H",
"RES 0,L",
"RES 0,(HL)",
"RES 0,A",
"RES 1,B",
"RES 1,C",
"RES 1,D",
"RES 1,E",
"RES 1,H",
"RES 1,L",
"RES 1,(HL)",
"RES 1,A",
"RES 2,B",
"RES 2,C",
"RES 2,D",
"RES 2,E",
"RES 2,H",
"RES 2,L",
"RES 2,(HL)",
"RES 2,A",
"RES 3,B",
"RES 3,C",
"RES 3,D",
"RES 3,E",
"RES 3,H",
"RES 3,L",
"RES 3,(HL)",
"RES 3,A",
"RES 4,B",
"RES 4,C",
"RES 4,D",
"RES 4,E",
"RES 4,H",
"RES 4,L",
"RES 4,(HL)",
"RES 4,A",
"RES 5,B",
"RES 5,C",
"RES 5,D",
"RES 5,E",
"RES 5,H",
"RES 5,L",
"RES 5,(HL)",
"RES 5,A",
"RES 6,B",
"RES 6,C",
"RES 6,D",
"RES 6,E",
"RES 6,H",
"RES 6,L",
"RES 6,(HL)",
"RES 6,A",
"RES 7,B",
"RES 7,C",
"RES 7,D",
"RES 7,E",
"RES 7,H",
"RES 7,L",
"RES 7,(HL)",
"RES 7,A",
"SET 0,B",
"SET 0,C",
"SET 0,D",
"SET 0,E",
"SET 0,H",
"SET 0,L",
"SET 0,(HL)",
"SET 0,A",
"SET 1,B",
"SET 1,C",
"SET 1,D",
"SET 1,E",
"SET 1,H",
"SET 1,L",
"SET 1,(HL)",
"SET 1,A",
"SET 2,B",
"SET 2,C",
"SET 2,D",
"SET 2,E",
"SET 2,H",
"SET 2,L",
"SET 2,(HL)",
"SET 2,A",
"SET 3,B",
"SET 3,C",
"SET 3,D",
"SET 3,E",
"SET 3,H",
"SET 3,L",
"SET 3,(HL)",
"SET 3,A",
"SET 4,B",
"SET 4,C",
"SET 4,D",
"SET 4,E",
"SET 4,H",
"SET 4,L",
"SET 4,(HL)",
"SET 4,A",
"SET 5,B",
"SET 5,C",
"SET 5,D",
"SET 5,E",
"SET 5,H",
"SET 5,L",
"SET 5,(HL)",
"SET 5,A",
"SET 6,B",
"SET 6,C",
"SET 6,D",
"SET 6,E",
"SET 6,H",
"SET 6,L",
"SET 6,(HL)",
"SET 6,A",
"SET 7,B",
"SET 7,C",
"SET 7,D",
"SET 7,E",
"SET 7,H",
"SET 7,L",
"SET 7,(HL)",
"SET 7,A"
];
pub const TABINSTRED: [&str; 256] = [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"IN B,(C)",
"OUT (C),B",
"SBC HL,BC",
"LD (nnnn),BC",
"NEG",
"RETN",
"IM 0",
"LD I,A",
"IN C,(C)",
"OUT (C),C",
"ADC HL,BC",
"LD BC,(nnnn)",
"NEG",
"RETI",
"IM 0",
"LD R,A",
"IN D,(C)",
"OUT (C),D",
"SBC HL,DE",
"LD (nnnn),DE",
"NEG",
"RETN",
"IM 1",
"LD A,I",
"IN E,(C)",
"OUT (C),E",
"ADC HL,DE",
"LD DE,(nnnn)",
"NEG",
"RETN",
"IM 2",
"LD A,R",
"IN H,(C)",
"OUT (C),H",
"SBC HL,HL",
"LD (nnnn), hl",
"NEG",
"RETN",
"IM 0",
"RRD",
"IN L,(C)",
"OUT (C),L",
"ADC HL,HL",
"LD HL, (nnnn)",
"NEG",
"RETN",
"IM 0",
"RLD",
"IN 0,(C)",
"OUT (C),0",
"SBC HL,SP",
"LD (nnnn),SP",
"NEG",
"RETN",
"IM 1",
"",
"IN A,(C)",
"OUT (C),A",
"ADC HL,SP",
"LD SP,(nnnn)",
"NEG",
"RET N",
"IM 2",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LDI",
"CPI",
"INI",
"OUTI",
"",
"",
"",
"",
"LDD",
"CPD",
"IND",
"OUTD",
"",
"",
"",
"",
"LDIR",
"CPIR",
"INIR",
"OTIR",
"",
"",
"",
"",
"LDDR",
"CPDR",
"INDR",
"OTDR",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
];
pub const TABINSTRDD: [&str; 256] = [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"ADD IX,BC",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"ADD IX,DE",
"",
"",
"",
"",
"",
"",
"",
"LD IX,nnnn",
"LD (nnnn),IX",
"INC IX",
"INC IXh",
"DEC IXh",
"LD IXh,nn",
"",
"",
"ADD IX,IX",
"LD IX,(nnnn)",
"DEC IX", "INC IXl",
"DEC IXl",
"LD IXl,nn",
"",
"",
"",
"",
"",
"INC (IX+nn)",
"DEC (IX+nn)",
"LD (IX+nn),nn",
"",
"",
"ADD IX,SP",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LD B,IXh",
"LD B,IXl",
"LD B,(IX+nn)",
"",
"",
"",
"",
"",
"LD C,IXh",
"LD C,IXl",
"LD C,(IX+nn)",
"",
"",
"",
"",
"",
"LD D,IXh",
"LD D,IXl",
"LD D,(IX+nn)",
"",
"",
"",
"",
"",
"LD E,IXh",
"LD E,IXl",
"LD E,(IX+nn)",
"",
"LD IXh,B",
"LD IXh,C",
"LD IXh,D",
"LD IXh,E",
"LD IXh,IXh",
"LD IXh,IXl",
"LD H,(IX+nn)",
"LD IXh,A",
"LD IXl,B",
"LD IXl,C",
"LD IXl,D",
"LD IXl,E",
"LD IXl,IXh",
"LD IXl,IXl",
"LD L,(IX+nn)",
"LD IXl,A",
"LD (IX+nn),B",
"LD (IX+nn),C",
"LD (IX+nn),D",
"LD (IX+nn),E",
"LD (IX+nn),H",
"LD (IX+nn),L",
"",
"LD (IX+nn),A",
"",
"",
"",
"",
"LD A,IXh",
"LD A,IXl",
"LD A,(IX+nn)",
"",
"",
"",
"",
"",
"ADD A,IXh",
"ADD A,IXl",
"ADD A,(IX+nn)",
"",
"",
"",
"",
"",
"ADC A,IXh",
"ADC A,IXl",
"ADC A,(IX+nn)",
"",
"",
"",
"",
"",
"SUB IXh",
"SUB IXl",
"SUB (IX+nn)",
"",
"",
"",
"",
"",
"SBC A,IXh",
"SBC A,IXl",
"SBC A,(IX+nn)",
"",
"",
"",
"",
"",
"AND IXh",
"AND IXl",
"AND (IX+nn)",
"",
"",
"",
"",
"",
"XOR IXh",
"XOR IXl",
"XOR (IX+nn)",
"",
"",
"",
"",
"",
"OR IXh",
"OR IXl",
"OR (IX+nn)",
"",
"",
"",
"",
"",
"CP IXh",
"CP IXl",
"CP (IX+nn)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"POP IX",
"",
"EX (SP),IX",
"",
"PUSH IX",
"",
"",
"",
"JP (IX)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LD SP,IX",
"",
"",
"",
"",
"",
""
];
pub const TABINSTRFD: [&str; 256] = [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"ADD IY,BC",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"ADD IY,DE",
"",
"",
"",
"",
"",
"",
"",
"LD IY,nnnn",
"LD (nnnn),IY",
"INC IY",
"INC IYh",
"DEC IYh",
"LD IYh,nn",
"",
"",
"ADD IY,IY",
"LD IY,(nnnn)",
"DEC IY",
"INC IYl",
"DEC IYl",
"LD IYl,nn",
"", "",
"",
"",
"",
"INC (IY+nn)",
"DEC (IY+nn)",
"LD (IY+nn),nn",
"",
"",
"ADD IY,SP",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LD B,IYh",
"LD B,IYl",
"LD B,(IY+nn)",
"",
"",
"",
"",
"",
"LD C,IYh",
"LD C,IYl",
"LD C,(IY+nn)",
"",
"",
"",
"",
"",
"LD D,IYh",
"LD D,IYl",
"LD D,(IY+nn)",
"",
"",
"",
"",
"",
"LD E,IYh",
"LD E,IYl",
"LD E,(IY+nn)",
"",
"LD IYh,B",
"LD IYh,C",
"LD IYh,D",
"LD IYh,E",
"LD IYh,IYh",
"LD IYh,IYl",
"LD H,(IY+nn)",
"LD IYh,A",
"LD IYl,B",
"LD IYl,C",
"LD IYl,D",
"LD IYl,E",
"LD IYl,IYh",
"LD IYl,IYl",
"LD L,(IY+nn)",
"LD IYl,A",
"LD (IY+nn),B",
"LD (IY+nn),C",
"LD (IY+nn),D",
"LD (IY+nn),E",
"LD (IY+nn),H",
"LD (IY+nn),L",
"",
"LD (IY+nn),A",
"",
"",
"",
"",
"LD A,IYh",
"LD A,IYl",
"LD A,(IY+nn)",
"",
"",
"",
"",
"",
"ADD A,IYh",
"ADD A,IYl",
"ADD A,(IY+nn)",
"",
"",
"",
"",
"",
"ADC A,IYh",
"ADC A,IYl",
"ADC A,(IY+nn)",
"",
"",
"",
"",
"",
"SUB IYh",
"SUB IYl",
"SUB (IY+nn)",
"",
"",
"",
"",
"",
"SBC A,IYh",
"SBC A,IYl",
"SBC A,(IY+nn)",
"",
"",
"",
"",
"",
"AND IYh",
"AND IYl",
"AND (IY+nn)",
"",
"",
"",
"",
"",
"XOR IYh",
"XOR IYl",
"XOR (IY+nn)",
"",
"",
"",
"",
"",
"OR IYh",
"OR IYl",
"OR (IY+nn)",
"",
"",
"",
"",
"",
"CP IYh",
"CP IYl",
"CP (IY+nn)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"POP IY",
"",
"EX (SP),IY",
"",
"PUSH IY",
"",
"",
"",
"JP (IY)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LD SP,IY",
"",
"",
"",
"",
"",
""
];
pub const TABINSTR: [&str; 256] = [
"NOP",
"LD BC,nnnn",
"LD (BC),A",
"INC BC",
"INC B",
"DEC B",
"LD B,nn",
"RLCA",
"EX AF,AF'",
"ADD HL,BC",
"LD A,(BC)",
"DEC BC",
"INC C",
"DEC C",
"LD C,nn",
"RRCA",
"DJNZ nn",
"LD DE,nnnn",
"LD (DE),A",
"INC DE",
"INC D",
"DEC D",
"LD D,nn",
"RLA",
"JR nn",
"ADD HL,DE",
"LD A,(DE)",
"DEC DE",
"INC E",
"DEC E",
"LD E,nn",
"RRA",
"JR NZ,nn",
"LD HL,nnnn",
"LD (nnnn),HL",
"INC HL",
"INC H",
"DEC H",
"LD H,nn",
"DAA",
"JR Z,nn",
"ADD HL,HL",
"LD HL,(nnnn)",
"DEC HL",
"INC L",
"DEC L",
"LD L,nn",
"CPL",
"JR NC,nn",
"LD SP,nnnn",
"LD (nnnn),A",
"INC SP",
"INC (HL)",
"DEC (HL)",
"LD (HL),nn",
"SCF",
"JR C,nn",
"ADD HL,SP",
"LD A,(nnnn)",
"DEC SP",
"INC A",
"DEC A",
"LD A,nn",
"CCF",
"LD B,B",
"LD B,C",
"LD B,D",
"LD B,E",
"LD B,H",
"LD B,L",
"LD B,(HL)",
"LD B,A",
"LD C,B",
"LD C,C",
"LD C,D",
"LD C,E",
"LD C,H",
"LD C,L",
"LD C,(HL)",
"LD C,A",
"LD D,B",
"LD D,C",
"LD D,D",
"LD D,E",
"LD D,H",
"LD D,L",
"LD D,(HL)",
"LD D,A",
"LD E,B",
"LD E,C",
"LD E,D",
"LD E,E",
"LD E,H",
"LD E,L",
"LD E,(HL)",
"LD E,A",
"LD H,B",
"LD H,C",
"LD H,D",
"LD H,E",
"LD H,H",
"LD H,L",
"LD H,(HL)",
"LD H,A",
"LD L,B",
"LD L,C",
"LD L,D",
"LD L,E",
"LD L,H",
"LD L,L",
"LD L,(HL)",
"LD L,A",
"LD (HL),B",
"LD (HL),C",
"LD (HL),D",
"LD (HL),E",
"LD (HL),H",
"LD (HL),L",
"HALT",
"LD (HL),A",
"LD A,B",
"LD A,C",
"LD A,D",
"LD A,E",
"LD A,H",
"LD A,L",
"LD A,(HL)",
"LD A,A",
"ADD A,B",
"ADD A,C",
"ADD A,D",
"ADD A,E",
"ADD A,H",
"ADD A,L",
"ADD A,(HL)",
"ADD A,A",
"ADC A,B",
"ADC A,C",
"ADC A,D",
"ADC A,E",
"ADC A,H",
"ADC A,L",
"ADC A,(HL)",
"ADC A,A",
"SUB B",
"SUB C",
"SUB D",
"SUB E",
"SUB H",
"SUB L",
"SUB (HL)",
"SUB A",
"SBC A,B",
"SBC A,C",
"SBC A,D",
"SBC A,E",
"SBC A,H",
"SBC A,L",
"SBC A,(HL)",
"SBC A,A",
"AND B",
"AND C",
"AND D",
"AND E",
"AND H",
"AND L",
"AND (HL)",
"AND A",
"XOR B",
"XOR C",
"XOR D",
"XOR E",
"XOR H",
"XOR L",
"XOR (HL)",
"XOR A",
"OR B",
"OR C",
"OR D",
"OR E",
"OR H",
"OR L",
"OR (HL)",
"OR A",
"CP B",
"CP C",
"CP D",
"CP E",
"CP H",
"CP L",
"CP (HL)",
"CP A",
"RET NZ",
"POP BC",
"JP NZ,nnnn",
"JP nnnn",
"CALL NZ,nnnn",
"PUSH BC",
"ADD A,nn",
"RST 00",
"RET Z",
"RET",
"JP Z,nnnn",
"",
"CALL Z,nnnn",
"CALL nnnn",
"ADC A,nn",
"RST 08",
"RET NC",
"POP DE",
"JP NC,nnnn",
"OUT (nn),A",
"CALL NC,nnnn",
"PUSH DE",
"SUB nn",
"RST 10",
"RET C",
"EXX",
"JP C,nnnn",
"IN A,(nn)",
"CALL C,nnnn",
"",
"SBC A,nn",
"RST 18",
"RET PO",
"POP HL",
"JP PO,nnnn",
"EX (SP),HL", "CALL PO,nnnn",
"PUSH HL",
"AND nn",
"RST 20",
"RET PE",
"JP (HL)",
"JP PE,nnnn",
"EX DE,HL",
"CALL PE,nnnn",
"",
"XOR nn",
"RST 28",
"RET P",
"POP AF",
"JP P,nnnn",
"DI",
"CALL P,nnnn",
"PUSH AF",
"OR nn",
"RST 30",
"RET M",
"LD SP,HL",
"JP M,nnnn",
"EI",
"CALL M,nnnn",
"",
"CP nn",
"RST 38"
];
pub fn disassemble<'a>(mut bytes: &'a [u8]) -> Listing {
let mut reverse_tokens = Vec::new();
let mut continue_disassembling = |token: Token, bytes: &'a [u8]| {
reverse_tokens.push(token);
bytes
};
while !bytes.is_empty() {
bytes = match bytes {
[] => unreachable!(),
[0, rest @ ..] => continue_disassembling(nop(), rest),
[prefix, 0xCB, param, opcode, rest @ ..] if *prefix == 0xFD || *prefix == 0xDD => {
let token = disassemble_with_one_argument(
*opcode,
*param,
if *prefix == 0xFD {
&TABINSTRFDCB
}
else {
&TABINSTRDDCB
}
)
.unwrap_or_else(|_| defb_elements(&[*prefix, 0xCB, *param, *opcode]));
continue_disassembling(token, rest)
},
[prefix, opcode, rest @ ..]
if *prefix == 0xCB || *prefix == 0xED || *prefix == 0xDD || *prefix == 0xFD =>
{
let (token, rest) = disassemble_with_potential_argument(
*opcode,
match prefix {
0xCB => &TABINSTRCB,
0xED => &TABINSTRED,
0xDD => &TABINSTRDD,
0xFD => &TABINSTRFD,
_ => unreachable!()
},
rest
)
.unwrap_or_else(|_| (defb_elements(&[*prefix, *opcode]), rest));
continue_disassembling(token, rest)
},
[opcode, rest @ ..] => {
let (token, rest) = disassemble_with_potential_argument(*opcode, &TABINSTR, rest)
.unwrap_or_else(|_| (defb(*opcode), rest));
continue_disassembling(token, rest)
}
}
}
reverse_tokens.into()
}
pub fn disassemble_with_potential_argument<'stream>(
opcode: u8,
lut: &[&'static str; 256],
bytes: &'stream [u8]
) -> Result<(Token, &'stream [u8]), String> {
let representation: &'static str = lut[opcode as usize];
let (representation, bytes) = if representation.contains("nnnn") {
let word = bytes[0] as u16 + 256 * (bytes[1] as u16);
let representation = representation.replacen("nnnn", &format!("{:#03x}", word), 1);
(representation, &bytes[2..])
}
else if representation.contains("nn") {
let byte = bytes[0] as i8;
let representation =
if representation.starts_with("DJNZ") || representation.starts_with("JR") {
let byte = byte as i16 + 2;
if byte == 0 {
representation.replacen("nn", "$", 1)
}
else if byte < 0 {
representation.replacen("nn", &format!("-{}", byte.abs()), 1)
}
else {
representation.replacen("nn", &format!("+{}", byte.abs()), 1)
}
}
else {
representation.replacen("nn", &format!("{:#01x}", byte), 1)
};
(representation.to_owned(), &bytes[1..])
}
else {
(representation.to_owned(), bytes)
};
let (representation, bytes) = if representation.contains("nn") {
let byte = bytes[0];
let representation = representation.replacen("nn", &format!("{:#01x}", byte), 1);
(representation, &bytes[1..])
}
else {
(representation, bytes)
};
Ok((string_to_token(&representation)?, bytes))
}
pub fn disassemble_with_one_argument(
opcode: u8,
argument: u8,
lut: &[&'static str; 256]
) -> Result<Token, String> {
let representation: &'static str = lut[opcode as usize];
let representation = representation.replacen("nn", &format!("{:#01x}", argument), 1);
string_to_token(&representation)
}
pub fn disassemble_without_argument(
opcode: u8,
lut: &[&'static str; 256]
) -> Result<Token, String> {
let representation: &'static str = lut[opcode as usize];
string_to_token(representation)
}
pub fn string_to_token(representation: &str) -> Result<Token, String> {
if representation.is_empty() {
Err("Empty opcode".to_string())
}
else {
Token::parse_token(representation)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn disass_from_bytes() {
assert_eq!("PUSH HL", disassemble(&[0xE5]).to_string().trim());
assert_eq!("RES 0x3, E", disassemble(&[0xCB, 0x9B]).to_string().trim());
assert_eq!(
"SBC HL, DE",
disassemble(&[0xED, 0b01010010]).to_string().trim()
);
assert_eq!(
"RLC (IX + 0x1)",
disassemble(&[0xDD, 0xCB, 01, 06]).to_string().trim()
);
assert_eq!(
"RLC (IX + 0x1), B",
disassemble(&[0xDD, 0xCB, 01, 00]).to_string().trim()
);
assert_eq!(
"RLC (IY + 0x2), C",
disassemble(&[0xFD, 0xCB, 02, 01]).to_string().trim()
);
}
#[test]
fn disass_instruction_with_arg() {
assert_eq!(
"CALL NZ, 0x123",
disassemble(&[0xC4, 0x23, 0x01]).to_string().trim()
);
assert_eq!(
"LD IX, (0x4321)",
disassemble(&[0xDD, 0x2A, 0x21, 0x43]).to_string().trim()
);
assert_eq!(
"LD (IX + 0x21), 0x43",
disassemble(&[0xDD, 0x36, 0x21, 0x43]).to_string().trim()
);
assert_eq!(
"BIT 0x6, (IX + 0x1)",
disassemble(&[0xDD, 0xCB, 0x01, 0x76]).to_string().trim()
);
}
fn disass_check_representation_equality() {
disass_for_table_and_prefix(&TABINSTR, &[]);
disass_for_table_and_prefix(&TABINSTRCB, &[0xCB]);
disass_for_table_and_prefix(&TABINSTRDD, &[0xDD]);
disass_for_table_and_prefix(&TABINSTRED, &[0xED]);
disass_for_table_and_prefix(&TABINSTRFD, &[0xFD]);
disass_for_double_prefix(&TABINSTRFDCB, 0xFD, 0xCB);
disass_for_double_prefix(&TABINSTRDDCB, 0xDD, 0xCB);
}
fn disass_for_double_prefix(tab: &[&'static str; 256], first: u8, second: u8) {
for code in 0..=255 {
let repr = tab[code as usize];
if repr.is_empty() {
continue;
}
let repr = repr.replacen("nn", "0x12", 1);
let expected_bytes = [first, second, 0x12, code];
let obtained = disassemble(&expected_bytes);
println!("{:?},{:?}, {:?}", repr, expected_bytes, obtained);
assert_eq!(
repr.replace(" ", "")
.replace("0x", "")
.replace("00", "0")
.replace("08", "8")
.to_uppercase(),
obtained
.to_string()
.trim()
.replace(" ", "")
.replace("0x", "")
.to_uppercase()
);
let mut env = Env::default();
if let Token::OpCode(mnemonic, arg1, arg2, arg3) = &obtained.listing()[0] {
let obtained_bytes =
assemble_opcode(*mnemonic, arg1, arg2, arg3, &mut env).unwrap();
assert_eq!(&expected_bytes[..], &obtained_bytes[..]);
}
else {
println!("ERROR, this is not a Token {:?}", obtained);
assert!(false);
}
}
}
fn disass_for_table_and_prefix(tab: &[&'static str; 256], prefix: &[u8]) {
let merge = |list: &[&[u8]]| -> Vec<u8> {
list.iter()
.flat_map(|&bytes| bytes.iter())
.copied()
.collect()
};
for code in 0..=255 {
let repr = tab[code as usize];
if repr.is_empty() {
continue;
}
println!("0x{:x} : {}", code, repr);
let (expected, bytes) = if repr.contains("nnnn") {
(
repr.replace("nnnn", "0x3412"),
merge(&[prefix, &[code], &[0x12, 0x34]])
)
}
else if repr.contains("nn") {
let repr = repr.replacen("nn", "0x12", 1);
let (repr, bytes) = if repr.contains("nn") {
(repr.replace("nn", "0x34"), [0x12, 0x34].to_vec())
}
else {
(repr, [0x12].to_vec())
};
(repr, merge(&[prefix, &[code], &bytes]))
}
else {
(repr.to_owned(), merge(&[prefix, &[code]]))
};
let obtained = disassemble(&bytes);
if !expected.contains("RST") && !expected.contains("DJNZ") && !expected.contains("JR") {
assert_eq!(
expected
.replace(" ", "")
.replace("0x", "")
.replace("00", "0")
.replace("08", "8")
.to_uppercase(),
obtained
.to_string()
.trim()
.replace(" ", "")
.replace("0x", "")
.to_uppercase()
);
}
return;
}
}
}