Simplify Z80 decoder some more
authorNick Downing <nick@ndcode.org>
Sat, 30 Jul 2022 03:17:37 +0000 (13:17 +1000)
committerNick Downing <nick@ndcode.org>
Sat, 30 Jul 2022 08:46:19 +0000 (18:46 +1000)
decode_z80.py
decode_z80_pre.sed

index 834bdaf..6b6bc84 100755 (executable)
@@ -82,12 +82,6 @@ byte_rvalue_modes = {
   'iyh': 'self->regs.byte.iyh',
   'i': 'self->regs.byte.i',
   'r': 'self->regs.byte.r',
-  '(0x3412)': 'cpu_z80_read_byte(self, cpu_z80_fetch_word(self))',
-  '(bc)': 'cpu_z80_read_byte(self, self->regs.word.bc)',
-  '(de)': 'cpu_z80_read_byte(self, self->regs.word.de)',
-  '(hl)': 'cpu_z80_read_byte(self, self->regs.word.hl)',
-  '(ix+0x12)': 'cpu_z80_read_byte(self, cpu_z80_displacement(self, self->regs.word.ix))',
-  '(iy+0x12)': 'cpu_z80_read_byte(self, cpu_z80_displacement(self, self->regs.word.iy))',
   '(0x0012)': 'cpu_z80_in_byte(self, cpu_z80_fetch_byte(self))',
   '(c)': 'cpu_z80_in_byte(self, self->regs.word.bc)',
 }
@@ -114,6 +108,7 @@ byte_lvalue_modes = {
   'iyh': 'CPU_Z80_EA_IYH',
   'i': 'CPU_Z80_EA_I',
   'r': 'CPU_Z80_EA_R',
+  'sink': 'CPU_Z80_EA_SINK',
   '(0x3412)': 'cpu_z80_fetch_word(self)',
   '(bc)': 'self->regs.word.bc',
   '(de)': 'self->regs.word.de',
@@ -159,13 +154,6 @@ word_rvalue_modes = {
   'ix': 'self->regs.word.ix',
   'iy': 'self->regs.word.iy',
   'sp': 'self->regs.word.sp',
-  '(0x3412)': 'cpu_z80_read_word(self, cpu_z80_fetch_word(self))',
-  '(bc)': 'cpu_z80_read_word(self, self->regs.word.bc)',
-  '(de)': 'cpu_z80_read_word(self, self->regs.word.de)',
-  '(hl)': 'cpu_z80_read_word(self, self->regs.word.hl)',
-  '(ix)': 'cpu_z80_read_word(self, self->regs.word.ix)',
-  '(iy)': 'cpu_z80_read_word(self, self->regs.word.iy)',
-  '(sp)': 'cpu_z80_read_word(self, self->regs.word.sp)',
 }
 word_lvalue_modes = {
   'af': 'CPU_Z80_EA_AF',
@@ -180,6 +168,8 @@ word_lvalue_modes = {
   '(bc)': 'self->regs.word.bc',
   '(de)': 'self->regs.word.de',
   '(hl)': 'self->regs.word.hl',
+  '(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',
@@ -191,29 +181,6 @@ word_lvalue_modes = {
   'po': '!self->regs.bit.pvf',
 }
 
-# opcodes allowing predication need a "true" parameter when not predicated
-pred_opcodes = {
-  'jr': 3,
-  'jp': 3,
-  'call': 3,
-  'ret': 2,
-}
-
-# CB-prefixed opcodes other than "bit" need an extra lvalue parameter to
-# store a copy of the result in, for undocumented DDCB/FDCB instructions
-cb_opcodes = {
-  'rlc': 3,
-  'rrc': 3,
-  'rl': 3,
-  'rr': 3,
-  'sla': 3,
-  'sra': 3,
-  'sll': 3,
-  'srl': 3,
-  'res': 4,
-  'set': 4,
-}
-
 prefixes = [[], [0xcb], [0xdd], [0xdd, 0xcb], [0xed], [0xfd], [0xfd, 0xcb]]
 for i in prefixes:
   line = sys.stdin.readline().strip()
@@ -256,18 +223,26 @@ for i in prefixes:
       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]]
+          if instr[l] in byte_lvalue_modes:
+            instr[l] = byte_lvalue_modes[instr[l]]
         for l in range(k, len(instr)):
-          instr[l] = byte_rvalue_modes[instr[l]]
+          if instr[l] in byte_rvalue_modes:
+            instr[l] = byte_rvalue_modes[instr[l]]
+          elif instr[l] in byte_lvalue_modes:
+            instr[l] = 'cpu_z80_read_byte(self, {0:s})'.format(
+              byte_lvalue_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]]
+          if instr[l] in word_lvalue_modes:
+            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')
+          if instr[l] in word_rvalue_modes:
+            instr[l] = word_rvalue_modes[instr[l]]
+          elif instr[l] in word_lvalue_modes:
+            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 2ef5272..ce101fd 100644 (file)
@@ -1,2 +1,5 @@
 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
-s/ld \([abcdehl]\),\(\(res\|rl\|rr\|set\|sl\|sr\).*\)/\2,\1/
+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/\(ret\)$/\1 true/
+s/\(jr\|jp\|call\) \([^,]*\)$/\1 true,\2/