1pub fn instruction_str(opcode: u8, alt1: bool, alt2: bool) -> String {
2    match opcode {
3        0x00 => "STOP".into(),
4        0x01 => "NOP".into(),
5        0x02 => "CACHE".into(),
6        0x03 => "LSR".into(),
7        0x04 => "ROL".into(),
8        0x05 => "BRA e".into(),
9        0x06 => "BGE e".into(),
10        0x07 => "BLT e".into(),
11        0x08 => "BNE e".into(),
12        0x09 => "BEQ e".into(),
13        0x0A => "BPL e".into(),
14        0x0B => "BMI e".into(),
15        0x0C => "BCC e".into(),
16        0x0D => "BCS e".into(),
17        0x0E => "BVC e".into(),
18        0x0F => "BVS e".into(),
19        0x10..=0x1F => format!("TO R{}", opcode & 0x0F),
20        0x20..=0x2F => format!("WITH R{}", opcode & 0x0F),
21        0x30..=0x3B => {
22            if alt1 {
23                format!("STB (R{})", opcode & 0x0F)
24            } else {
25                format!("STW (R{})", opcode & 0x0F)
26            }
27        }
28        0x3C => "LOOP".into(),
29        0x3D => "ALT1".into(),
30        0x3E => "ALT2".into(),
31        0x3F => "ALT3".into(),
32        0x40..=0x4B => {
33            if alt1 {
34                format!("LDB (R{})", opcode & 0x0F)
35            } else {
36                format!("LDW (R{})", opcode & 0x0F)
37            }
38        }
39        0x4C => {
40            if alt1 {
41                "RPIX".into()
42            } else {
43                "PLOT".into()
44            }
45        }
46        0x4D => "SWAP".into(),
47        0x4E => {
48            if alt1 {
49                "CMODE".into()
50            } else {
51                "COLOR".into()
52            }
53        }
54        0x4F => "NOT".into(),
55        0x50..=0x5F => match (alt2, alt1) {
56            (false, false) => format!("ADD R{}", opcode & 0x0F),
57            (false, true) => format!("ADC R{}", opcode & 0x0F),
58            (true, false) => format!("ADD #{}", opcode & 0x0F),
59            (true, true) => format!("ADC #{}", opcode & 0x0F),
60        },
61        0x60..=0x6F => match (alt2, alt1) {
62            (false, false) => format!("SUB R{}", opcode & 0x0F),
63            (false, true) => format!("SBC R{}", opcode & 0x0F),
64            (true, false) => format!("SUB #{}", opcode & 0x0F),
65            (true, true) => format!("CMP R{}", opcode & 0x0F),
66        },
67        0x70 => "MERGE".into(),
68        0x71..=0x7F => match (alt2, alt1) {
69            (false, false) => format!("AND R{}", opcode & 0x0F),
70            (false, true) => format!("BIC R{}", opcode & 0x0F),
71            (true, false) => format!("AND #{}", opcode & 0x0F),
72            (true, true) => format!("BIC #{}", opcode & 0x0F),
73        },
74        0x80..=0x8F => match (alt2, alt1) {
75            (false, false) => format!("MULT R{}", opcode & 0x0F),
76            (false, true) => format!("UMULT R{}", opcode & 0x0F),
77            (true, false) => format!("MULT #{}", opcode & 0x0F),
78            (true, true) => format!("UMULT #{}", opcode & 0x0F),
79        },
80        0x90 => "SBK".into(),
81        0x91..=0x94 => format!("LINK #{}", opcode & 0x0F),
82        0x95 => "SEX".into(),
83        0x96 => {
84            if alt1 {
85                "DIV2".into()
86            } else {
87                "ASR".into()
88            }
89        }
90        0x97 => "ROR".into(),
91        0x98..=0x9D => {
92            if alt1 {
93                format!("LJMP R{}", opcode & 0x0F)
94            } else {
95                format!("JMP R{}", opcode & 0x0F)
96            }
97        }
98        0x9E => "LOB".into(),
99        0x9F => {
100            if alt1 {
101                "LMULT".into()
102            } else {
103                "FMULT".into()
104            }
105        }
106        0xA0..=0xAF => match (alt2, alt1) {
107            (false, false) => format!("IBT R{}, #pp", opcode & 0x0F),
108            (_, true) => format!("LMS R{}, (yy)", opcode & 0x0F),
109            (true, false) => format!("SMS (yy), R{}", opcode & 0x0F),
110        },
111        0xB0..=0xBF => format!("FROM R{}", opcode & 0x0F),
112        0xC0 => "HIB".into(),
113        0xC1..=0xCF => match (alt2, alt1) {
114            (false, false) => format!("OR R{}", opcode & 0x0F),
115            (false, true) => format!("XOR R{}", opcode & 0x0F),
116            (true, false) => format!("OR #{}", opcode & 0x0F),
117            (true, true) => format!("XOR #{}", opcode & 0x0F),
118        },
119        0xD0..=0xDE => format!("INC R{}", opcode & 0x0F),
120        0xDF => match (alt2, alt1) {
121            (false, _) => "GETC".into(),
122            (true, false) => "RAMB".into(),
123            (true, true) => "ROMB".into(),
124        },
125        0xE0..=0xEE => format!("DEC R{}", opcode & 0x0F),
126        0xEF => match (alt2, alt1) {
127            (false, false) => "GETB".into(),
128            (false, true) => "GETBH".into(),
129            (true, false) => "GETBL".into(),
130            (true, true) => "GETBS".into(),
131        },
132        0xF0..=0xFF => match (alt2, alt1) {
133            (false, false) => format!("IWT R{}, #xx", opcode & 0x0F),
134            (_, true) => format!("LM R{}, (xx)", opcode & 0x0F),
135            (true, false) => format!("SM (xx), R{}", opcode & 0x0F),
136        },
137    }
138}