#!/usr/bin/env python3
-import z80dis.z80
import sys
# for these opcodes, the last operand is rvalue (any other is lvalue)
}
prefixes = [[], [0xcb], [0xdd], [0xdd, 0xcb], [0xed], [0xfd], [0xfd, 0xcb]]
-for i in range(0x700):
- if (i & 0xff) == 0:
- print(
- 'void cpu_z80_execute{0:s}(struct cpu_z80 *self) {{'.format(
- ''.join([f'_{j:02x}' for j in prefixes[i >> 8]])
- )
+for i in prefixes:
+ line = sys.stdin.readline().strip()
+ assert line == 'opcodes{0:s}'.format(''.join([f' 0x{j:02x}' for j in i]))
+
+ print(
+ 'void cpu_z80_execute{0:s}(struct cpu_z80 *self) {{'.format(
+ ''.join([f'_{j:02x}' for j in i])
)
- print(' switch (cpu_z80_fetch_byte(self)) {')
- print(f' case 0x{i & 0xff:02x}:')
- opcodes = prefixes[i >> 8] + [i & 0xff]
- if opcodes in prefixes:
- print(
- ' cpu_z80_execute{0:s}(self);'.format(
- ''.join([f'_{j:02x}' for j in opcodes])
+ )
+ print(' switch (cpu_z80_fetch_byte(self)) {')
+
+ for j in range(0x100):
+ line = sys.stdin.readline().strip()
+
+ print(f' case 0x{j:02x}:')
+ k = i + [j]
+ if k in prefixes:
+ print(
+ ' cpu_z80_execute{0:s}(self);'.format(
+ ''.join([f'_{k:02x}' for k in k])
+ )
)
- )
- else:
- instr = z80dis.z80.disasm(
- # for DDCB and FDCB the displacement goes before the next opcode
- bytes(opcodes[:2] + [0x12] + opcodes[2:] + [0x34])
- ).lower().split()
- if len(instr) == 0:
- instr = ['ill']
- elif len(instr) >= 2:
- instr[1:] = [k for j in instr[1:] for k in j.split(',')]
- if len(instr) >= 4: # the undocumented DDCB and FDCB variants
- assert instr[0] == 'ld'
- instr = instr[2:] + instr[1:2] # "ld a,op (ix+n)" to "op (ix+n),a"
- #print('xxx', instr)
- suffix = ''
- if instr[0] not in byte_opcodes and instr[0] not in word_opcodes:
- for j in instr[1:]:
- if j in byte_operands:
- assert suffix != '_word'
- suffix = '_byte'
- elif j in word_operands:
- assert suffix != '_byte'
- suffix = '_word'
- j = len(instr) - int(instr[0] in rvalue_opcodes)
- if suffix == '_byte' or instr[0] in byte_opcodes:
- for k in range(1, j):
- instr[k] = byte_lvalue_modes[instr[k]]
- for k in range(j, len(instr)):
- instr[k] = byte_rvalue_modes[instr[k]]
- elif suffix == '_word' or instr[0] in word_opcodes:
- for k in range(1, j):
- instr[k] = word_lvalue_modes[instr[k]]
- for k in range(j, len(instr)):
- instr[k] = word_rvalue_modes[instr[k]]
- if len(instr) < pred_opcodes.get(instr[0], 0):
- instr[1:1] = ['true']
- if len(instr) < cb_opcodes.get(instr[0], 0):
- instr.append('CPU_Z80_EA_SINK')
- print(
- ' cpu_z80_{0:s}{1:s}(self{2:s});'.format(
- instr[0],
- suffix,
- ''.join([', ' + j for j in instr[1:]])
+ else:
+ instr = line.lower().split()
+ if len(instr) == 0:
+ instr = ['ill']
+ elif len(instr) >= 2:
+ instr[1:] = [l for k in instr[1:] for l in k.split(',')]
+ if len(instr) >= 4: # the undocumented DDCB and FDCB variants
+ assert instr[0] == 'ld'
+ instr = instr[2:] + instr[1:2] # "ld a,op (ix+n)" to "op (ix+n),a"
+ #print('xxx', instr)
+ suffix = ''
+ if instr[0] not in byte_opcodes and instr[0] not in word_opcodes:
+ for k in instr[1:]:
+ if k in byte_operands:
+ assert suffix != '_word'
+ suffix = '_byte'
+ elif k in word_operands:
+ assert suffix != '_byte'
+ suffix = '_word'
+ k = len(instr) - int(instr[0] in rvalue_opcodes)
+ if suffix == '_byte' or instr[0] in byte_opcodes:
+ for l in range(1, k):
+ instr[l] = byte_lvalue_modes[instr[l]]
+ for l in range(k, len(instr)):
+ instr[l] = byte_rvalue_modes[instr[l]]
+ elif suffix == '_word' or instr[0] in word_opcodes:
+ for l in range(1, k):
+ instr[l] = word_lvalue_modes[instr[l]]
+ for l in range(k, len(instr)):
+ instr[l] = word_rvalue_modes[instr[l]]
+ if len(instr) < pred_opcodes.get(instr[0], 0):
+ instr[1:1] = ['true']
+ if len(instr) < cb_opcodes.get(instr[0], 0):
+ instr.append('CPU_Z80_EA_SINK')
+ print(
+ ' cpu_z80_{0:s}{1:s}(self{2:s});'.format(
+ instr[0],
+ suffix,
+ ''.join([', ' + k for k in instr[1:]])
+ )
)
- )
- print(' break;')
- if (i & 0xff) == 0xff:
- print(' }')
- print('}')
- print()
+ print(' break;')
+
+ line = sys.stdin.readline().strip()
+ assert len(line) == 0
+
+ print(' }')
+ print('}')
+ print()