diff z80inst.c @ 1044:1625555e346e

Properly handle redundant prefixes
author Michael Pavone <pavone@retrodev.com>
date Mon, 25 Jul 2016 23:16:04 -0700
parents 103d5cabbe14
children 8519b54f9413
line wrap: on
line diff
--- a/z80inst.c	Sun Jul 24 18:53:22 2016 -0700
+++ b/z80inst.c	Mon Jul 25 23:16:04 2016 -0700
@@ -6,9 +6,10 @@
 #include "z80inst.h"
 #include <string.h>
 #include <stdio.h>
+#include <stddef.h>
 
-#define NOP {Z80_NOP, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 1}
-#define NOP2 {Z80_NOP, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 2}
+#define NOP {Z80_NOP, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0}
+#define USE_MAIN {Z80_USE_MAIN, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0}
 
 z80inst z80_tbl_a[256] = {
 	//0
@@ -345,7 +346,7 @@
 	{Z80_NEG, Z80_A, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_RETN, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_IM, Z80_UNUSED, Z80_IMMED, Z80_UNUSED, 1},
-	NOP2,
+	NOP,
 	{Z80_IN, Z80_A, Z80_REG_INDIRECT, Z80_C, 0},
 	{Z80_OUT, Z80_A, Z80_REG_INDIRECT | Z80_DIR, Z80_C, 0},
 	{Z80_ADC, Z80_HL, Z80_REG, Z80_SP, 0},
@@ -353,75 +354,75 @@
 	{Z80_NEG, Z80_A, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_RETN, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_IM, Z80_UNUSED, Z80_IMMED, Z80_UNUSED, 2},
-	NOP2,
+	NOP,
 	//8
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
 	//9
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
 	//A
 	{Z80_LDI, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_CPI, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INI, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_OUTI, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
 	{Z80_LDD, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_CPD, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_IND, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_OUTD, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
 	//B
 	{Z80_LDIR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_CPIR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INIR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_OTIR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	NOP,
+	NOP,
+	NOP,
+	NOP,
 	{Z80_LDDR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_CPDR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INDR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_OTDR, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2
+	NOP,
+	NOP,
+	NOP,
+	NOP
 };
 
 #define SHIFT_BLOCK(op) \
@@ -497,107 +498,107 @@
 
 z80inst z80_tbl_ix[256] = {
 	//0
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IX, Z80_REG, Z80_BC, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//1
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IX, Z80_REG, Z80_DE, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//2
-	NOP2,
+	USE_MAIN,
 	{Z80_LD, Z80_IX, Z80_IMMED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IX, Z80_IMMED_INDIRECT | Z80_DIR, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IXH, Z80_IMMED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IX, Z80_REG, Z80_IX, 0},
 	{Z80_LD, Z80_IX, Z80_IMMED_INDIRECT, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IXL, Z80_IMMED, Z80_UNUSED, 0},
-	NOP2,
+	USE_MAIN,
 	//3
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_INC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0},
 	{Z80_DEC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0},
 	{Z80_LD, Z80_USE_IMMED, Z80_IX_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IX, Z80_REG, Z80_SP, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//4
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_B, Z80_REG, Z80_IXH, 0},
 	{Z80_LD, Z80_B, Z80_REG, Z80_IXL, 0},
 	{Z80_LD, Z80_B, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_C, Z80_REG, Z80_IXH, 0},
 	{Z80_LD, Z80_C, Z80_REG, Z80_IXL, 0},
 	{Z80_LD, Z80_C, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//5
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_D, Z80_REG, Z80_IXH, 0},
 	{Z80_LD, Z80_D, Z80_REG, Z80_IXL, 0},
 	{Z80_LD, Z80_D, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_E, Z80_REG, Z80_IXH, 0},
 	{Z80_LD, Z80_E, Z80_REG, Z80_IXL, 0},
 	{Z80_LD, Z80_E, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//6
 	{Z80_LD, Z80_IXH, Z80_REG, Z80_B, 0},
 	{Z80_LD, Z80_IXH, Z80_REG, Z80_C, 0},
@@ -622,152 +623,152 @@
 	{Z80_LD, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 0},
 	{Z80_LD, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 0},
 	{Z80_LD, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_LD, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_LD, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_LD, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//8
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_ADD, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_ADD, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADC, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_ADC, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_ADC, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//9
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_SUB, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_SUB, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_SUB, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_SBC, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_SBC, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_SBC, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//A
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_AND, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_AND, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_AND, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_XOR, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_XOR, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_XOR, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//B
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_OR, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_OR, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_OR, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_CP, Z80_A, Z80_REG, Z80_IXH, 0},
 	{Z80_CP, Z80_A, Z80_REG, Z80_IXL, 0},
 	{Z80_CP, Z80_A, Z80_IX_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//C
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//D
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//E
-	NOP2,
+	USE_MAIN,
 	{Z80_POP, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_EX, Z80_IX, Z80_REG_INDIRECT | Z80_DIR, Z80_SP, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_PUSH, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_JP, Z80_UNUSED, Z80_REG_INDIRECT, Z80_IX, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//F
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_SP, Z80_REG, Z80_IX, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN
 };
 
 #define SHIFT_BLOCK_IX(op) \
@@ -853,107 +854,107 @@
 
 z80inst z80_tbl_iy[256] = {
 	//0
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IY, Z80_REG, Z80_BC, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//1
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IY, Z80_REG, Z80_DE, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//2
-	NOP2,
+	USE_MAIN,
 	{Z80_LD, Z80_IY, Z80_IMMED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IY, Z80_IMMED_INDIRECT | Z80_DIR, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IY, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IYH, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IYH, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IYH, Z80_IMMED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IY, Z80_REG, Z80_IY, 0},
 	{Z80_LD, Z80_IY, Z80_IMMED_INDIRECT, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IY, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_INC, Z80_IYL, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_DEC, Z80_IYL, Z80_UNUSED, Z80_UNUSED, 0},
 	{Z80_LD, Z80_IYL, Z80_IMMED, Z80_UNUSED, 0},
-	NOP2,
+	USE_MAIN,
 	//3
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_INC, Z80_UNUSED, Z80_IY_DISPLACE, 0, 0},
 	{Z80_DEC, Z80_UNUSED, Z80_IY_DISPLACE, 0, 0},
 	{Z80_LD, Z80_USE_IMMED, Z80_IY_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_IY, Z80_REG, Z80_SP, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//4
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_B, Z80_REG, Z80_IYH, 0},
 	{Z80_LD, Z80_B, Z80_REG, Z80_IYL, 0},
 	{Z80_LD, Z80_B, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_C, Z80_REG, Z80_IYH, 0},
 	{Z80_LD, Z80_C, Z80_REG, Z80_IYL, 0},
 	{Z80_LD, Z80_C, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//5
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_D, Z80_REG, Z80_IYH, 0},
 	{Z80_LD, Z80_D, Z80_REG, Z80_IYL, 0},
 	{Z80_LD, Z80_D, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_E, Z80_REG, Z80_IYH, 0},
 	{Z80_LD, Z80_E, Z80_REG, Z80_IYL, 0},
 	{Z80_LD, Z80_E, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//6
 	{Z80_LD, Z80_IYH, Z80_REG, Z80_B, 0},
 	{Z80_LD, Z80_IYH, Z80_REG, Z80_C, 0},
@@ -978,154 +979,152 @@
 	{Z80_LD, Z80_E, Z80_IY_DISPLACE | Z80_DIR, 0, 0},
 	{Z80_LD, Z80_H, Z80_IY_DISPLACE | Z80_DIR, 0, 0},
 	{Z80_LD, Z80_L, Z80_IY_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_LD, Z80_A, Z80_IY_DISPLACE | Z80_DIR, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_LD, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_LD, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//8
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADD, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_ADD, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_ADD, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_ADC, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_ADC, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_ADC, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//9
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_SUB, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_SUB, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_SUB, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_SBC, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_SBC, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_SBC, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//A
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_AND, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_AND, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_AND, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_XOR, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_XOR, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_XOR, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//B
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_OR, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_OR, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_OR, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_CP, Z80_A, Z80_REG, Z80_IYH, 0},
 	{Z80_CP, Z80_A, Z80_REG, Z80_IYL, 0},
 	{Z80_CP, Z80_A, Z80_IY_DISPLACE, 0, 0},
-	NOP2,
+	USE_MAIN,
 	//C
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//D
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//E
-	NOP2,
+	USE_MAIN,
 	{Z80_POP, Z80_IY, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_EX, Z80_IY, Z80_REG_INDIRECT | Z80_DIR, Z80_SP, 0},
-	NOP2,
+	USE_MAIN,
 	{Z80_PUSH, Z80_IY, Z80_UNUSED, Z80_UNUSED, 0},
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_JP, Z80_UNUSED, Z80_REG_INDIRECT, Z80_IY, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	//F
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
 	{Z80_LD, Z80_SP, Z80_REG, Z80_IY, 0},
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	NOP2,
-	//TODO: Enable this based on a define
-	{Z80_NOP, Z80_UNUSED, Z80_UNUSED, Z80_UNUSED, 42}
-	//NOP2
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN,
+	USE_MAIN
 };
 
 #define SHIFT_BLOCK_IY(op) \
@@ -1209,49 +1208,78 @@
 	BIT_BLOCK_IY_REG(Z80_SET, 7),
 };
 
+enum {
+	NORMAL,
+	USE_IX,
+	USE_IY
+};
+
 uint8_t * z80_decode(uint8_t * istream, z80inst * decoded)
 {
 	uint8_t tmp;
-	if (*istream == 0xCB) {
-		istream++;
-		memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst));
-	} else if (*istream == 0xDD) {
-		istream++;
-		if (*istream == 0xCB) {
-			tmp = *(++istream);
+	uint8_t *start = istream;
+	uint8_t ixiy = NORMAL;
+	uint16_t ixiy_disp = 0x100;
+	z80inst *base = NULL;
+	while(!base)
+	{
+		switch (*istream)
+		{
+		case 0xCB:
+			istream++;
+			if (ixiy == NORMAL) {
+				base = z80_tbl_bit + *istream;
+			} else if (ixiy == USE_IX) {
+				ixiy_disp = *(istream++);
+				base = z80_tbl_ix_bit + *istream;
+			} else {
+				ixiy_disp = *(istream++);
+				base = z80_tbl_iy_bit + *istream;
+			}
+			break;
+		case 0xED:
 			istream++;
-			memcpy(decoded, z80_tbl_ix_bit + *istream, sizeof(z80inst));
-			decoded->ea_reg = tmp;
-		} else {
-			memcpy(decoded, z80_tbl_ix + *istream, sizeof(z80inst));
-			if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE) {
-				decoded->ea_reg = *(++istream);
+			ixiy = NORMAL;
+			if (*istream < 0x40 || *istream >= 0xC0) {
+				base = z80_tbl_extd + 0xBF;
+			} else {
+				base = z80_tbl_extd + *istream - 0x40;
+			}
+			break;
+		case 0xDD:
+			istream++;
+			ixiy = USE_IX;
+			break;
+		case 0xFD:
+			istream++;
+			ixiy = USE_IY;
+			break;
+		default:
+			if (ixiy == NORMAL) {
+				base = z80_tbl_a + *istream;
+			} else if (ixiy == USE_IX) {
+				base = z80_tbl_ix + *istream;
+			} else {
+				base = z80_tbl_iy + *istream;
 			}
 		}
-	} else if (*istream == 0xED) {
-		istream++;
-		if (*istream < 0x40 || *istream >= 0xC0) {
-			memcpy(decoded, z80_tbl_extd + 0xBF, sizeof(z80inst));
-		} else {
-			memcpy(decoded, z80_tbl_extd + *istream-0x40, sizeof(z80inst));
+	}
+	if (base->op == Z80_USE_MAIN) {
+		base = z80_tbl_a + *istream;
+		ixiy = NORMAL;
+	}
+	memcpy(decoded, base, offsetof(z80inst, opcode_bytes));
+	decoded->opcode_bytes = istream - start + 1;
+	if (ixiy != NORMAL) {
+		if (ixiy_disp < 0x100) {
+			decoded->ea_reg = ixiy_disp;
+			//don't count displacement byte as an opcode byte
+			decoded->opcode_bytes--;
+		} else if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE || (decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) {
+			decoded->ea_reg = *(++istream);
 		}
-	} else if (*istream == 0xFD) {
-		istream++;
-		if (*istream == 0xCB) {
-			tmp = *(++istream);
-			istream++;
-			memcpy(decoded, z80_tbl_iy_bit + *istream, sizeof(z80inst));
-			decoded->ea_reg = tmp;
-		} else {
-			memcpy(decoded, z80_tbl_iy + *istream, sizeof(z80inst));
-			if ((decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) {
-				decoded->ea_reg = *(++istream);
-			}
-		}
-	} else {
-		memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst));
-
 	}
+	
 	if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) {
 		decoded->immed = *(++istream);
 		if ((decoded->reg >= Z80_BC && decoded->reg < Z80_UNUSED) || decoded->op == Z80_CALL || decoded->op == Z80_CALLCC || decoded->op == Z80_JP || decoded->op == Z80_JPCC) {