cpu_z80_ill(self);
break;
case 0x40:
- cpu_z80_in_test(self, CPU_Z80_EA_B, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_B, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x41:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.b);
cpu_z80_ld_byte(self, CPU_Z80_EA_I, self->regs.byte.a);
break;
case 0x48:
- cpu_z80_in_test(self, CPU_Z80_EA_C, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_C, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x49:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.c);
cpu_z80_ld_byte(self, CPU_Z80_EA_R, self->regs.byte.a);
break;
case 0x50:
- cpu_z80_in_test(self, CPU_Z80_EA_D, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_D, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x51:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.d);
cpu_z80_ld_byte(self, CPU_Z80_EA_A, self->regs.byte.i);
break;
case 0x58:
- cpu_z80_in_test(self, CPU_Z80_EA_E, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_E, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x59:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.e);
cpu_z80_ld_byte(self, CPU_Z80_EA_A, self->regs.byte.r);
break;
case 0x60:
- cpu_z80_in_test(self, CPU_Z80_EA_H, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_H, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x61:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.h);
cpu_z80_rrd(self);
break;
case 0x68:
- cpu_z80_in_test(self, CPU_Z80_EA_L, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_L, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x69:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.l);
cpu_z80_rld(self);
break;
case 0x70:
- cpu_z80_in_test(self, CPU_Z80_EA_SINK, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_SINK, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x71:
cpu_z80_out(self, self->regs.word.bc, 0);
cpu_z80_nop(self);
break;
case 0x78:
- cpu_z80_in_test(self, CPU_Z80_EA_A, cpu_z80_in_byte(self, self->regs.word.bc));
+ cpu_z80_in_z80(self, CPU_Z80_EA_A, cpu_z80_in_byte(self, self->regs.word.bc));
break;
case 0x79:
cpu_z80_out(self, self->regs.word.bc, self->regs.byte.a);
cpu_z80_write_byte(self, lvalue, rvalue);
}
-static ALWAYS_INLINE void cpu_z80_in_test(struct cpu_z80 *self, int lvalue, int rvalue) {
+static ALWAYS_INLINE void cpu_z80_in_z80(struct cpu_z80 *self, int lvalue, int rvalue) {
int parity = rvalue;
parity ^= parity >> 4;
parity ^= parity >> 2;
'call',
'djnz',
'in',
- 'in_f',
+ 'in_z80',
'out',
'push',
'bit',
'xor',
'cp',
'in',
+ 'in_z80',
'out',
'bit',
'res',
'(iy+0x12)',
}
byte_rvalue_modes = {
- '0': '0', # used for the undocumented "out (c),0" instruction
'0x12': 'cpu_z80_fetch_byte(self)',
'0x34': 'cpu_z80_fetch_byte(self)',
'a': 'self->regs.byte.a',
'(c)': 'cpu_z80_in_byte(self, self->regs.word.bc)',
}
byte_lvalue_modes = {
- '0': '0',
- '1': '1',
- '2': '2',
- '3': '3',
- '4': '4',
- '5': '5',
- '6': '6',
- '7': '7',
'f': 'CPU_Z80_EA_F',
'a': 'CPU_Z80_EA_A',
'b': 'CPU_Z80_EA_B',
'sp': 'self->regs.word.sp',
}
word_lvalue_modes = {
+ 'z': 'self->regs.bit.zf',
+ 'nz': '!self->regs.bit.zf',
+ 'c': 'self->regs.bit.cf',
+ 'nc': '!self->regs.bit.cf',
+ 'm': 'self->regs.bit.sf',
+ 'p': '!self->regs.bit.sf',
+ 'pe': 'self->regs.bit.pvf',
+ 'po': '!self->regs.bit.pvf',
'af': 'CPU_Z80_EA_AF',
'af\'': 'CPU_Z80_EA_AF_PRIME',
'bc': 'CPU_Z80_EA_BC',
'(ix)': 'self->regs.word.ix',
'(iy)': 'self->regs.word.iy',
'(sp)': 'self->regs.word.sp',
- 'z': 'self->regs.bit.zf',
- 'nz': '!self->regs.bit.zf',
- 'c': 'self->regs.bit.cf',
- 'nc': '!self->regs.bit.cf',
- 'm': 'self->regs.bit.sf',
- 'p': '!self->regs.bit.sf',
- 'pe': 'self->regs.bit.pvf',
- 'po': '!self->regs.bit.pvf',
}
prefixes = [[], [0xcb], [0xdd], [0xdd, 0xcb], [0xed], [0xfd], [0xfd, 0xcb]]
elif len(instr) >= 2:
instr[1:] = [l for k in instr[1:] for l in k.split(',')]
#print('xxx', instr)
+
+ # detect operation size (byte or word)
suffix = ''
if instr[0] not in byte_opcodes and instr[0] not in word_opcodes:
for k in instr[1:]:
elif k in word_operands:
assert suffix != '_byte'
suffix = '_word'
+
+ # translate operands
+ # use lvalue by default, but last operand can be rvalue
k = len(instr) - int(instr[0] in rvalue_opcodes)
if suffix == '_byte' or instr[0] in byte_opcodes:
+ # operands [1, k) are lvalue
for l in range(1, k):
if instr[l] in byte_lvalue_modes:
instr[l] = byte_lvalue_modes[instr[l]]
+
+ # operands [k, n) are rvalue
for l in range(k, len(instr)):
if instr[l] in byte_rvalue_modes:
instr[l] = byte_rvalue_modes[instr[l]]
byte_lvalue_modes[instr[l]]
)
elif suffix == '_word' or instr[0] in word_opcodes:
+ # operands [1, k] are lvalue
for l in range(1, k):
if instr[l] in word_lvalue_modes:
instr[l] = word_lvalue_modes[instr[l]]
+
+ # operands [k, n) are rvalue
for l in range(k, len(instr)):
if instr[l] in word_rvalue_modes:
instr[l] = word_rvalue_modes[instr[l]]
instr[l] = 'cpu_z80_read_word(self, {0:s})'.format(
word_lvalue_modes[instr[l]]
)
+
print(
' cpu_z80_{0:s}{1:s}(self{2:s});'.format(
instr[0],
-s/cpu_z80_rst(self/cpu_z80_call(self, true/
-s/(self, true, \(!\?self->regs\.bit\.\)/(self, \1/
-s/cpu_z80_in(self/cpu_z80_in_test(self/
-s/cpu_z80_in_test(self, CPU_Z80_EA_A, cpu_z80_in_byte(self, cpu_z80_fetch_byte(self)))/cpu_z80_in(self, CPU_Z80_EA_A, cpu_z80_in_byte(self, cpu_z80_port_word(self)))/
-s/cpu_z80_in_test(self, CPU_Z80_EA_F/cpu_z80_in_test(self, CPU_Z80_EA_SINK/
s/cpu_z80_out(self, cpu_z80_fetch_byte(self), self->regs\.byte\.a)/cpu_z80_out(self, cpu_z80_port_word(self), self->regs.byte.a)/
s/^ \(cpu_z80_ld_byte(self, \)\(cpu_z80_displacement(self, self->regs\.word\.i[xy])\)\(, cpu_z80_fetch_byte(self));\)$/ {\n int ea = \2;\n \1ea\3\n }/
s/^ cpu_z80_exx(self);$/ cpu_z80_ex(self, CPU_Z80_EA_BC, CPU_Z80_EA_BC_PRIME);\n cpu_z80_ex(self, CPU_Z80_EA_DE, CPU_Z80_EA_DE_PRIME);\n cpu_z80_ex(self, CPU_Z80_EA_HL, CPU_Z80_EA_HL_PRIME);/
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/\(\(res\|rl\|rlc\|rr\|rrc\|set\|sla\|sll\|sra\|srl\) .*\)/\1,sink/
s/ld \([abcdehl]\),\(\(res\|rl\|rlc\|rr\|rrc\|set\|sla\|sll\|sra\|srl\) .*\),sink/\2,\1/
+s/rst/call/
s/\(ret\)$/\1 true/
s/\(jr\|jp\|call\) \([^,]*\)$/\1 true,\2/
+s/\(in\) \([abcdehl],(c)\)/\1_z80 \2/
+s/\(in\) f,\((c)\)/\1_z80 sink,\2/