m68000/
interpreter_disassembler.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use crate::{CpuDetails, M68000, MemoryAccess};
6use crate::exception::{Exception, Vector};
7use crate::instruction::Instruction;
8use crate::interpreter::InterpreterResult;
9use crate::isa::Isa;
10
11impl<CPU: CpuDetails> M68000<CPU> {
12    /// Returns the instruction at the current Program Counter and advances it to the next instruction.
13    ///
14    /// If an error occurs when reading the next instruction, the Err variant contains the exception vector.
15    fn get_next_instruction<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M) -> Result<Instruction, u8> {
16        let mut iter = self.iter_from_pc(memory);
17        let instruction = Instruction::from_memory(&mut iter)?;
18        self.regs.pc.0 = iter.next_addr;
19        Ok(instruction)
20    }
21
22    /// Runs the interpreter loop once and disassembles the next instruction if any.
23    ///
24    /// Returns the address of the instruction, its disassembled string and the cycle count necessary to execute it.
25    /// The disassembled string is empty if no instruction has been executed.
26    ///
27    /// See [Self::interpreter] for the potential caveat.
28    pub fn disassembler_interpreter<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M) -> (u32, String, usize) {
29        let (addr, dis, cycles, exception) = self.disassembler_interpreter_exception(memory);
30        if let Some(e) = exception {
31            self.exception(Exception::from(e));
32        }
33        (addr, dis, cycles)
34    }
35
36    /// Runs the interpreter loop once and disassembles the next instruction if any.
37    ///
38    /// Returns the address of the instruction that has been executed, its disassembled string, the cycle count
39    /// necessary to execute it, and the vector of the exception that occured during the execution if any.
40    /// The disassembled string is empty if no instruction has been executed.
41    ///
42    /// To process the returned exception, call [M68000::exception].
43    ///
44    /// See [Self::interpreter_exception] for the potential caveat.
45    pub fn disassembler_interpreter_exception<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M) -> (u32, String, usize, Option<u8>) {
46        if self.stop {
47            return (0, String::from(""), 0, None);
48        }
49
50        let mut cycle_count = 0;
51
52        if !self.exceptions.is_empty() {
53            cycle_count += self.process_pending_exceptions(memory);
54        }
55
56        let instruction = match self.get_next_instruction(memory) {
57            Ok(i) => i,
58            Err(e) => return (0, String::from(""), cycle_count, Some(e)),
59        };
60
61        self.current_opcode = instruction.opcode;
62        let isa = Isa::from(instruction.opcode);
63
64        let dis = instruction.disassemble();
65        let trace = self.regs.sr.t;
66        let exception = match Execute::<CPU, M>::EXECUTE[isa as usize](self, memory, &instruction) {
67            Ok(cycles) => {
68                cycle_count += cycles;
69                if trace && !isa.is_privileged() {
70                    Some(Vector::Trace as u8)
71                } else {
72                    None
73                }
74            },
75            Err(e) => Some(e),
76        };
77
78        (instruction.pc, dis, cycle_count, exception)
79    }
80
81    fn instruction_unknown_instruction<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, _: &Instruction) -> InterpreterResult {
82        self.execute_unknown_instruction()
83    }
84
85    fn instruction_abcd<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
86        let (rx, _, mode, ry) = inst.operands.register_size_mode_register();
87        self.execute_abcd(memory, rx, mode, ry)
88    }
89
90    fn instruction_add<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
91        let (reg, dir, size, am) = inst.operands.register_direction_size_effective_address();
92        self.execute_add(memory, reg, dir, size, am)
93    }
94
95    fn instruction_adda<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
96        let (reg, size, am) = inst.operands.register_size_effective_address();
97        self.execute_adda(memory, reg, size, am)
98    }
99
100    fn instruction_addi<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
101        let (size, am, imm) = inst.operands.size_effective_address_immediate();
102        self.execute_addi(memory, size, am, imm)
103    }
104
105    fn instruction_addq<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
106        let (imm, size, am) = inst.operands.data_size_effective_address();
107        self.execute_addq(memory, imm, size, am)
108    }
109
110    fn instruction_addx<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
111        let (rx, size, mode, ry) = inst.operands.register_size_mode_register();
112        self.execute_addx(memory, rx, size, mode, ry)
113    }
114
115    fn instruction_and<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
116        let (reg, dir, size, am) = inst.operands.register_direction_size_effective_address();
117        self.execute_and(memory, reg, dir, size, am)
118    }
119
120    fn instruction_andi<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
121        let (size, am, imm) = inst.operands.size_effective_address_immediate();
122        self.execute_andi(memory, size, am, imm)
123    }
124
125    fn instruction_andiccr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
126        let imm = inst.operands.immediate();
127        self.execute_andiccr(imm)
128    }
129
130    fn instruction_andisr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
131        let imm = inst.operands.immediate();
132        self.execute_andisr(imm)
133    }
134
135    fn instruction_asm<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
136        let (dir, am) = inst.operands.direction_effective_address();
137        self.execute_asm(memory, dir, am)
138    }
139
140    fn instruction_asr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
141        let (rot, dir, size, ir, reg) = inst.operands.rotation_direction_size_mode_register();
142        self.execute_asr(rot, dir, size, ir, reg)
143    }
144
145    fn instruction_bcc<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
146        let (condition, displacement) = inst.operands.condition_displacement();
147        self.execute_bcc(inst.pc.wrapping_add(2), condition, displacement)
148    }
149
150    fn instruction_bchg<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
151        let (am, count) = inst.operands.effective_address_count();
152        self.execute_bchg(memory, am, count)
153    }
154
155    fn instruction_bclr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
156        let (am, count) = inst.operands.effective_address_count();
157        self.execute_bclr(memory, am, count)
158    }
159
160    fn instruction_bra<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
161        let disp = inst.operands.displacement();
162        self.execute_bra(inst.pc.wrapping_add(2), disp)
163    }
164
165    fn instruction_bset<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
166        let (am, count) = inst.operands.effective_address_count();
167        self.execute_bset(memory, am, count)
168    }
169
170    fn instruction_bsr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
171        let disp = inst.operands.displacement();
172        self.execute_bsr(memory, inst.pc.wrapping_add(2), disp)
173    }
174
175    fn instruction_btst<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
176        let (am, count) = inst.operands.effective_address_count();
177        self.execute_btst(memory, am, count)
178    }
179
180    /// If a CHK exception occurs, this method returns the effective address calculation time, and the
181    /// process_exception method returns the exception processing time.
182    fn instruction_chk<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
183        let (reg, am) = inst.operands.register_effective_address();
184        self.execute_chk(memory, reg, am)
185    }
186
187    fn instruction_clr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
188        let (size, am) = inst.operands.size_effective_address();
189        self.execute_clr(memory, size, am)
190    }
191
192    fn instruction_cmp<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
193        let (reg, _, size, am) = inst.operands.register_direction_size_effective_address();
194        self.execute_cmp(memory, reg, size, am)
195    }
196
197    fn instruction_cmpa<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
198        let (reg, size, am) = inst.operands.register_size_effective_address();
199        self.execute_cmpa(memory, reg, size, am)
200    }
201
202    fn instruction_cmpi<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
203        let (size, am, imm) = inst.operands.size_effective_address_immediate();
204        self.execute_cmpi(memory, size, am, imm)
205    }
206
207    fn instruction_cmpm<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
208        let (ax, size, ay) = inst.operands.register_size_register();
209        self.execute_cmpm(memory, ax, size, ay)
210    }
211
212    fn instruction_dbcc<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
213        let (cc, reg, disp) = inst.operands.condition_register_displacement();
214        self.execute_dbcc(inst.pc.wrapping_add(2), cc, reg, disp)
215    }
216
217    /// If a zero divide exception occurs, this method returns the effective address calculation time, and the
218    /// process_exception method returns the exception processing time.
219    fn instruction_divs<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
220        let (reg, am) = inst.operands.register_effective_address();
221        self.execute_divs(memory, reg, am)
222    }
223
224    /// If a zero divide exception occurs, this method returns the effective address calculation time, and the
225    /// process_exception method returns the exception processing time.
226    fn instruction_divu<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
227        let (reg, am) = inst.operands.register_effective_address();
228        self.execute_divu(memory, reg, am)
229    }
230
231    fn instruction_eor<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
232        let (reg, _, size, am) = inst.operands.register_direction_size_effective_address();
233        self.execute_eor(memory, reg, size, am)
234    }
235
236    fn instruction_eori<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
237        let (size, am, imm) = inst.operands.size_effective_address_immediate();
238        self.execute_eori(memory, size, am, imm)
239    }
240
241    fn instruction_eoriccr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
242        let imm = inst.operands.immediate();
243        self.execute_eoriccr(imm)
244    }
245
246    fn instruction_eorisr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
247        let imm = inst.operands.immediate();
248        self.execute_eorisr(imm)
249    }
250
251    fn instruction_exg<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
252        let (rx, mode, ry) = inst.operands.register_opmode_register();
253        self.execute_exg(rx, mode, ry)
254    }
255
256    fn instruction_ext<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
257        let (mode, reg) = inst.operands.opmode_register();
258        self.execute_ext(mode, reg)
259    }
260
261    fn instruction_illegal<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, _: &Instruction) -> InterpreterResult {
262        self.execute_illegal()
263    }
264
265    fn instruction_jmp<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
266        let am = inst.operands.effective_address();
267        self.execute_jmp(am)
268    }
269
270    fn instruction_jsr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
271        let am = inst.operands.effective_address();
272        self.execute_jsr(memory, am)
273    }
274
275    fn instruction_lea<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
276        let (reg, am) = inst.operands.register_effective_address();
277        self.execute_lea(reg, am)
278    }
279
280    fn instruction_link<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
281        let (reg, disp) = inst.operands.register_displacement();
282        self.execute_link(memory, reg, disp)
283    }
284
285    fn instruction_lsm<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
286        let (dir, am) = inst.operands.direction_effective_address();
287        self.execute_lsm(memory, dir, am)
288    }
289
290    fn instruction_lsr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
291        let (rot, dir, size, ir, reg) = inst.operands.rotation_direction_size_mode_register();
292        self.execute_lsr(rot, dir, size, ir, reg)
293    }
294
295    fn instruction_move<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
296        let (size, amdst, amsrc) = inst.operands.size_effective_address_effective_address();
297        self.execute_move(memory, size, amdst, amsrc)
298    }
299
300    fn instruction_movea<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
301        let (size, reg, am) = inst.operands.size_register_effective_address();
302        self.execute_movea(memory, size, reg, am)
303    }
304
305    fn instruction_moveccr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
306        let am = inst.operands.effective_address();
307        self.execute_moveccr(memory, am)
308    }
309
310    fn instruction_movefsr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
311        let am = inst.operands.effective_address();
312        self.execute_movefsr(memory, am)
313    }
314
315    fn instruction_movesr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
316        let am = inst.operands.effective_address();
317        self.execute_movesr(memory, am)
318    }
319
320    fn instruction_moveusp<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
321        let (dir, reg) = inst.operands.direction_register();
322        self.execute_moveusp(dir, reg)
323    }
324
325    fn instruction_movem<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
326        let (dir, size, am, list) = inst.operands.direction_size_effective_address_list();
327        self.execute_movem(memory, dir, size, am, list)
328    }
329
330    fn instruction_movep<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
331        let (data, dir, size, addr, disp) = inst.operands.register_direction_size_register_displacement();
332        self.execute_movep(memory, data, dir, size, addr, disp)
333    }
334
335    fn instruction_moveq<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
336        let (reg, data) = inst.operands.register_data();
337        self.execute_moveq(reg, data)
338    }
339
340    fn instruction_muls<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
341        let (reg, am) = inst.operands.register_effective_address();
342        self.execute_muls(memory, reg, am)
343    }
344
345    fn instruction_mulu<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
346        let (reg, am) = inst.operands.register_effective_address();
347        self.execute_mulu(memory, reg, am)
348    }
349
350    fn instruction_nbcd<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
351        let am = inst.operands.effective_address();
352        self.execute_nbcd(memory, am)
353    }
354
355    fn instruction_neg<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
356        let (size, am) = inst.operands.size_effective_address();
357        self.execute_neg(memory, size, am)
358    }
359
360    fn instruction_negx<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
361        let (size, am) = inst.operands.size_effective_address();
362        self.execute_negx(memory, size, am)
363    }
364
365    fn instruction_nop<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, _: &Instruction) -> InterpreterResult {
366        self.execute_nop()
367    }
368
369    fn instruction_not<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
370        let (size, am) = inst.operands.size_effective_address();
371        self.execute_not(memory, size, am)
372    }
373
374    fn instruction_or<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
375        let (reg, dir, size, am) = inst.operands.register_direction_size_effective_address();
376        self.execute_or(memory, reg, dir, size, am)
377    }
378
379    fn instruction_ori<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
380        let (size, am, imm) = inst.operands.size_effective_address_immediate();
381        self.execute_ori(memory, size, am, imm)
382    }
383
384    fn instruction_oriccr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
385        let imm = inst.operands.immediate();
386        self.execute_oriccr(imm)
387    }
388
389    fn instruction_orisr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
390        let imm = inst.operands.immediate();
391        self.execute_orisr(imm)
392    }
393
394    fn instruction_pea<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
395        let am = inst.operands.effective_address();
396        self.execute_pea(memory, am)
397    }
398
399    fn instruction_reset<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, _: &Instruction) -> InterpreterResult {
400        self.execute_reset(memory)
401    }
402
403    fn instruction_rom<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
404        let (dir, am) = inst.operands.direction_effective_address();
405        self.execute_rom(memory, dir, am)
406    }
407
408    fn instruction_ror<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
409        let (rot, dir, size, ir, reg) = inst.operands.rotation_direction_size_mode_register();
410        self.execute_ror(rot, dir, size, ir, reg)
411    }
412
413    fn instruction_roxm<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
414        let (dir, am) = inst.operands.direction_effective_address();
415        self.execute_roxm(memory, dir, am)
416    }
417
418    fn instruction_roxr<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
419        let (rot, dir, size, ir, reg) = inst.operands.rotation_direction_size_mode_register();
420        self.execute_roxr(rot, dir, size, ir, reg)
421    }
422
423    fn instruction_rte<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, _: &Instruction) -> InterpreterResult {
424        self.execute_rte(memory)
425    }
426
427    fn instruction_rtr<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, _: &Instruction) -> InterpreterResult {
428        self.execute_rtr(memory)
429    }
430
431    fn instruction_rts<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, _: &Instruction) -> InterpreterResult {
432        self.execute_rts(memory)
433    }
434
435    fn instruction_sbcd<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
436        let (ry, _, mode, rx) = inst.operands.register_size_mode_register();
437        self.execute_sbcd(memory, ry, mode, rx)
438    }
439
440    fn instruction_scc<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
441        let (cc, am) = inst.operands.condition_effective_address();
442        self.execute_scc(memory, cc, am)
443    }
444
445    fn instruction_stop<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
446        let imm = inst.operands.immediate();
447        self.execute_stop(imm)
448    }
449
450    fn instruction_sub<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
451        let (reg, dir, size, am) = inst.operands.register_direction_size_effective_address();
452        self.execute_sub(memory, reg, dir, size, am)
453    }
454
455    fn instruction_suba<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
456        let (reg, size, am) = inst.operands.register_size_effective_address();
457        self.execute_suba(memory, reg, size, am)
458    }
459
460    fn instruction_subi<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
461        let (size, am, imm) = inst.operands.size_effective_address_immediate();
462        self.execute_subi(memory, size, am, imm)
463    }
464
465    fn instruction_subq<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
466        let (imm, size, am) = inst.operands.data_size_effective_address();
467        self.execute_subq(memory, imm, size, am)
468    }
469
470    fn instruction_subx<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
471        let (ry, size, mode, rx) = inst.operands.register_size_mode_register();
472        self.execute_subx(memory, ry, size, mode, rx)
473    }
474
475    fn instruction_swap<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
476        let reg = inst.operands.register();
477        self.execute_swap(reg)
478    }
479
480    fn instruction_tas<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
481        let am = inst.operands.effective_address();
482        self.execute_tas(memory, am)
483    }
484
485    fn instruction_trap<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, inst: &Instruction) -> InterpreterResult {
486        let vector = inst.operands.vector();
487        self.execute_trap(vector)
488    }
489
490    fn instruction_trapv<M: MemoryAccess + ?Sized>(&mut self, _: &mut M, _: &Instruction) -> InterpreterResult {
491        self.execute_trapv()
492    }
493
494    fn instruction_tst<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
495        let (size, am) = inst.operands.size_effective_address();
496        self.execute_tst(memory, size, am)
497    }
498
499    fn instruction_unlk<M: MemoryAccess + ?Sized>(&mut self, memory: &mut M, inst: &Instruction) -> InterpreterResult {
500        let reg = inst.operands.register();
501        self.execute_unlk(memory, reg)
502    }
503}
504
505struct Execute<E: CpuDetails, M: MemoryAccess + ?Sized> {
506    _e: E,
507    _m: M,
508}
509
510impl<E: CpuDetails, M: MemoryAccess + ?Sized> Execute<E, M> {
511    /// Function used to execute the instruction.
512    const EXECUTE: [fn(&mut M68000<E>, &mut M, &Instruction) -> InterpreterResult; Isa::_Size as usize] = [
513        M68000::instruction_unknown_instruction,
514        M68000::instruction_abcd,
515        M68000::instruction_add,
516        M68000::instruction_adda,
517        M68000::instruction_addi,
518        M68000::instruction_addq,
519        M68000::instruction_addx,
520        M68000::instruction_and,
521        M68000::instruction_andi,
522        M68000::instruction_andiccr,
523        M68000::instruction_andisr,
524        M68000::instruction_asm,
525        M68000::instruction_asr,
526        M68000::instruction_bcc,
527        M68000::instruction_bchg,
528        M68000::instruction_bclr,
529        M68000::instruction_bra,
530        M68000::instruction_bset,
531        M68000::instruction_bsr,
532        M68000::instruction_btst,
533        M68000::instruction_chk,
534        M68000::instruction_clr,
535        M68000::instruction_cmp,
536        M68000::instruction_cmpa,
537        M68000::instruction_cmpi,
538        M68000::instruction_cmpm,
539        M68000::instruction_dbcc,
540        M68000::instruction_divs,
541        M68000::instruction_divu,
542        M68000::instruction_eor,
543        M68000::instruction_eori,
544        M68000::instruction_eoriccr,
545        M68000::instruction_eorisr,
546        M68000::instruction_exg,
547        M68000::instruction_ext,
548        M68000::instruction_illegal,
549        M68000::instruction_jmp,
550        M68000::instruction_jsr,
551        M68000::instruction_lea,
552        M68000::instruction_link,
553        M68000::instruction_lsm,
554        M68000::instruction_lsr,
555        M68000::instruction_move,
556        M68000::instruction_movea,
557        M68000::instruction_moveccr,
558        M68000::instruction_movefsr,
559        M68000::instruction_movesr,
560        M68000::instruction_moveusp,
561        M68000::instruction_movem,
562        M68000::instruction_movep,
563        M68000::instruction_moveq,
564        M68000::instruction_muls,
565        M68000::instruction_mulu,
566        M68000::instruction_nbcd,
567        M68000::instruction_neg,
568        M68000::instruction_negx,
569        M68000::instruction_nop,
570        M68000::instruction_not,
571        M68000::instruction_or,
572        M68000::instruction_ori,
573        M68000::instruction_oriccr,
574        M68000::instruction_orisr,
575        M68000::instruction_pea,
576        M68000::instruction_reset,
577        M68000::instruction_rom,
578        M68000::instruction_ror,
579        M68000::instruction_roxm,
580        M68000::instruction_roxr,
581        M68000::instruction_rte,
582        M68000::instruction_rtr,
583        M68000::instruction_rts,
584        M68000::instruction_sbcd,
585        M68000::instruction_scc,
586        M68000::instruction_stop,
587        M68000::instruction_sub,
588        M68000::instruction_suba,
589        M68000::instruction_subi,
590        M68000::instruction_subq,
591        M68000::instruction_subx,
592        M68000::instruction_swap,
593        M68000::instruction_tas,
594        M68000::instruction_trap,
595        M68000::instruction_trapv,
596        M68000::instruction_tst,
597        M68000::instruction_unlk,
598    ];
599}