Implement 386 instruction table, improve 8086/186/286 instruction table
[multi_emu.git] / decode_65c02.py
1 #!/usr/bin/env python3
2
3 import sys
4
5 # end-relative range of operands that are rvalues
6 rvalue_opcodes = {
7   'adc': (-1, 0),
8   'and': (-1, 0),
9   'bit': (-1, 0),
10   'cmp': (-2, 0),
11   'eor': (-1, 0),
12   'ld': (-1, 0),
13   'ora': (-1, 0),
14   'ph': (-1, 0),
15   'sbc': (-1, 0),
16   'st': (-2, -1),
17 }
18
19 rvalue_modes = {
20   '#$12': 'cpu_65c02_fetch_byte(self)',
21   'a': 'self->regs.byte.a',
22   'x': 'self->regs.byte.x',
23   'y': 'self->regs.byte.y',
24   's': 'self->regs.byte.s',
25   'p': 'self->regs.byte.p',
26 }
27 lvalue_modes = {
28   'ne': '!self->regs.bit.zf',
29   'eq': 'self->regs.bit.zf',
30   'cc': '!self->regs.bit.cf',
31   'cs': 'self->regs.bit.cf',
32   'vc': '!self->regs.bit.vf',
33   'vs': 'self->regs.bit.vf',
34   'pl': '!self->regs.bit.nf',
35   'mi': 'self->regs.bit.nf',
36   '$0014': 'cpu_65c02_ea_relative(self)',
37   '$12': 'cpu_65c02_ea_zero_page(self)',
38   '$12,x': 'cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)',
39   '$12,y': 'cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.y)',
40   '$3412': 'cpu_65c02_ea_absolute(self)',
41   '$3412,x': 'cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)',
42   '$3412,y': 'cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)',
43   '($12)': 'cpu_65c02_ea_zero_page_indirect(self)',
44   '($12),y': 'cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)',
45   '($12,x)': 'cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)',
46   '($3412)': 'cpu_65c02_ea_absolute_indirect(self)',
47   '($3412,x)': 'cpu_65c02_ea_absolute_indexed_indirect(self, self->regs.byte.x)',
48   'a': 'CPU_65C02_EA_A',
49   'x': 'CPU_65C02_EA_X',
50   'y': 'CPU_65C02_EA_Y',
51   'p': 'CPU_65C02_EA_P',
52   's': 'CPU_65C02_EA_S',
53   'c': 'CPU_65C02_REG_P_BIT_C',
54   'd': 'CPU_65C02_REG_P_BIT_D',
55   'i': 'CPU_65C02_REG_P_BIT_I',
56   'v': 'CPU_65C02_REG_P_BIT_V',
57 }
58
59 line = sys.stdin.readline().strip()
60 assert line == 'opcodes'
61
62 print('void cpu_65c02_execute(struct cpu_65c02 *self) {')
63 print('  switch (cpu_65c02_fetch_byte(self)) {')
64 for i in range(0x100):
65   line = sys.stdin.readline().strip()
66
67   print(f'  case 0x{i:02x}:')
68   instr = line.split()
69
70   # work out which operands are rvalue
71   j0, j1 = rvalue_opcodes.get(instr[0], (0, 0))
72   j0 += len(instr)
73   j1 += len(instr)
74
75   # translate operands
76   for k in range(1, len(instr)):
77     if k >= j0 and k < j1:
78       if instr[k] in rvalue_modes:
79         instr[k] = rvalue_modes[instr[k]]
80       elif instr[k] in lvalue_modes:
81         instr[k] = 'cpu_65c02_read_byte(self, {0:s})'.format(
82           lvalue_modes[instr[k]]
83         )
84     elif instr[k] in lvalue_modes:
85       instr[k] = lvalue_modes[instr[k]]
86
87   print(
88     '    cpu_65c02_{0:s}(self{1:s});'.format(
89       instr[0],
90       ''.join([', ' + j for j in instr[1:]])
91     )
92   )
93   print('    break;')
94
95 line = sys.stdin.readline().strip()
96 assert len(line) == 0
97
98 print('  }')
99 print('}')