Implement 386 instruction table, improve 8086/186/286 instruction table
[multi_emu.git] / decode_6800.py
1 #!/usr/bin/env python3
2
3 import sys
4
5 # end-relative range of operands that are rvalues
6 rvalue_opcodes = {
7   'add': (-1, 0),
8   'adc': (-1, 0),
9   'and': (-1, 0),
10   'bit': (-2, 0),
11   'cmp': (-2, 0),
12   'cmp_byte': (-2, 0),
13   'eor': (-1, 0),
14   'ld': (-1, 0),
15   'ora': (-1, 0),
16   'psh': (-1, 0),
17   'sub': (-1, 0),
18   'sbc': (-1, 0),
19   'st': (-2, -1),
20 }
21
22 # if it is in byte_opcodes it is treated as byte and has no suffix
23 byte_opcodes = {
24   'add',
25   'adc',
26   'and',
27   'asl',
28   'asr',
29   'bit',
30   'cl',
31   'clr',
32   'cmp_byte',
33   'com',
34   'dec_byte',
35   'eor',
36   'inc_byte',
37   'lsr',
38   'neg',
39   'ora',
40   'pul',
41   'psh',
42   'rol',
43   'ror',
44   'sub',
45   'sbc',
46   'se',
47 }
48 # if any operand is in byte_operands it is treated as byte and has suffix
49 # in this case it is mandatory that no operand also be in word_operands
50 byte_operands = {
51   '#12',
52   'a',
53   'b',
54 }
55 byte_rvalue_modes = {
56   '#12': 'cpu_6800_fetch_byte(self)',
57   'a': 'self->regs.byte.a',
58   'b': 'self->regs.byte.b',
59 }
60 byte_lvalue_modes = {
61   '12': 'cpu_6800_ea_direct(self)',
62   '12,x': 'cpu_6800_ea_direct_indexed(self, self->regs.word.x)',
63   '1234': 'cpu_6800_ea_extended(self)',
64   '1234,x': 'cpu_6800_ea_extended_indexed(self, self->regs.word.x)',
65   'a': 'CPU_6800_EA_A',
66   'b': 'CPU_6800_EA_B',
67   'c': 'CPU_6800_REG_P_BIT_C',
68   'i': 'CPU_6800_REG_P_BIT_I',
69   'v': 'CPU_6800_REG_P_BIT_V',
70 }
71
72 # if it is in word_opcodes it is treated as word and has no suffix
73 # in this case the operands "c" and "(hl)" do not imply a byte opcode
74 word_opcodes = {
75   'bra',
76   'bsr',
77   'dec_word_zf',
78   'inc_word_zf',
79   'jmp',
80   'jsr',
81 }
82 # if any operand is in word_operands it is treated as word and has suffix
83 # in this case it is mandatory that no operand also be in byte_operands
84 word_operands = {
85   '#1234',
86   's',
87   'x',
88 }
89 word_rvalue_modes = {
90   '#1234': 'cpu_6800_fetch_word(self)',
91   's': 'self->regs.word.s',
92   'x': 'self->regs.word.x',
93 }
94 word_lvalue_modes = {
95   'ne': '!self->regs.bit.zf',
96   'eq': 'self->regs.bit.zf',
97   'cc': '!self->regs.bit.cf',
98   'cs': 'self->regs.bit.cf',
99   'vc': '!self->regs.bit.vf',
100   'vs': 'self->regs.bit.vf',
101   'pl': '!self->regs.bit.nf',
102   'mi': 'self->regs.bit.nf',
103   'ge': '!self->regs.bit.nf && !self->regs.bit.vf',
104   'gt': '!self->regs.bit.nf && !self->regs.bit.vf && !self->regs.bit.zf',
105   'hi': '!self->regs.bit.cf && !self->regs.bit.zf',
106   'le': 'self->regs.bit.nf || self->regs.bit.vf || self->regs.bit.zf',
107   'ls': 'self->regs.bit.cf || self->regs.bit.zf',
108   'lt': 'self->regs.bit.nf || self->regs.bit.vf',
109   '0014': 'cpu_6800_ea_relative(self)',
110   '12': 'cpu_6800_ea_direct(self)',
111   '12,x': 'cpu_6800_ea_direct_indexed(self, self->regs.word.x)',
112   '1234': 'cpu_6800_ea_extended(self)',
113   '1234,x': 'cpu_6800_ea_extended_indexed(self, self->regs.word.x)',
114   's': 'CPU_6800_EA_S',
115   'x': 'CPU_6800_EA_X',
116 }
117
118 line = sys.stdin.readline().strip()
119 assert line == 'opcodes'
120
121 print('void cpu_6800_execute(struct cpu_6800 *self) {')
122 print('  switch (cpu_6800_fetch_byte(self)) {')
123
124 for i in range(0x100):
125   line = sys.stdin.readline().strip()
126
127   print(f'  case 0x{i:02x}:')
128   instr = line.split()
129
130   # detect operation size (byte or word)
131   suffix = ''
132   if instr[0] not in byte_opcodes and instr[0] not in word_opcodes:
133     for j in instr[1:]:
134       if j in byte_operands:
135         assert suffix != '_word'
136         suffix = '_byte'
137       elif j in word_operands:
138         assert suffix != '_byte'
139         suffix = '_word'
140
141   # work out which operands are rvalue
142   j0, j1 = rvalue_opcodes.get(instr[0], (0, 0))
143   j0 += len(instr)
144   j1 += len(instr)
145
146   # translate operands
147   if suffix == '_byte' or instr[0] in byte_opcodes:
148     for k in range(1, len(instr)):
149       if k >= j0 and k < j1:
150         if instr[k] in byte_rvalue_modes:
151           instr[k] = byte_rvalue_modes[instr[k]]
152         elif instr[k] in byte_lvalue_modes:
153           instr[k] = 'cpu_6800_read_byte(self, {0:s})'.format(
154             byte_lvalue_modes[instr[k]]
155           )
156       elif instr[k] in byte_lvalue_modes:
157         instr[k] = byte_lvalue_modes[instr[k]]
158   elif suffix == '_word' or instr[0] in word_opcodes:
159     for k in range(1, len(instr)):
160       if k >= j0 and k < j1:
161         if instr[k] in word_rvalue_modes:
162           instr[k] = word_rvalue_modes[instr[k]]
163         elif instr[k] in word_lvalue_modes:
164           instr[k] = 'cpu_6800_read_word(self, {0:s})'.format(
165             word_lvalue_modes[instr[k]]
166           )
167       elif instr[k] in word_lvalue_modes:
168         instr[k] = word_lvalue_modes[instr[k]]
169
170   print(
171     '    cpu_6800_{0:s}{1:s}(self{2:s});'.format(
172       instr[0],
173       suffix,
174       ''.join([', ' + k for k in instr[1:]])
175     )
176   )
177   print('    break;')
178
179 line = sys.stdin.readline().strip()
180 assert len(line) == 0
181
182 print('  }')
183 print('}')
184 print()