Simplify Z80 decoder even more
authorNick Downing <nick@ndcode.org>
Sat, 30 Jul 2022 03:34:19 +0000 (13:34 +1000)
committerNick Downing <nick@ndcode.org>
Sat, 30 Jul 2022 08:46:19 +0000 (18:46 +1000)
cpu_z80.c
cpu_z80.h
decode_z80.py
decode_z80_post.sed
decode_z80_pre.sed

index 11aeef6..50b1ebd 100644 (file)
--- a/cpu_z80.c
+++ b/cpu_z80.c
@@ -3377,7 +3377,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3401,7 +3401,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3425,7 +3425,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3449,7 +3449,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3473,7 +3473,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3497,7 +3497,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3521,7 +3521,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
@@ -3545,7 +3545,7 @@ void cpu_z80_execute_ed(struct cpu_z80 *self) {
     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);
index 28c3eea..66fcf6f 100644 (file)
--- a/cpu_z80.h
+++ b/cpu_z80.h
@@ -624,7 +624,7 @@ static ALWAYS_INLINE void cpu_z80_in(struct cpu_z80 *self, int lvalue, int rvalu
   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;
index 6b6bc84..fd7965a 100755 (executable)
@@ -18,7 +18,7 @@ rvalue_opcodes = {
   'call',
   'djnz',
   'in',
-  'in_f',
+  'in_z80',
   'out',
   'push',
   'bit',
@@ -32,6 +32,7 @@ byte_opcodes = {
   'xor',
   'cp',
   'in',
+  'in_z80',
   'out',
   'bit',
   'res',
@@ -66,7 +67,6 @@ byte_operands = {
   '(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',
@@ -86,14 +86,6 @@ byte_rvalue_modes = {
   '(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',
@@ -156,6 +148,14 @@ word_rvalue_modes = {
   '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',
@@ -171,14 +171,6 @@ word_lvalue_modes = {
   '(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]]
@@ -211,6 +203,8 @@ for i in prefixes:
       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:]:
@@ -220,11 +214,17 @@ for i in prefixes:
           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]]
@@ -233,9 +233,12 @@ for i in prefixes:
               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]]
@@ -243,6 +246,7 @@ for i in prefixes:
             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],
index 92a217b..d5c0df1 100644 (file)
@@ -1,8 +1,3 @@
-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);/
index ce101fd..98c96be 100644 (file)
@@ -1,5 +1,8 @@
 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/