diff --git a/8086_documentation.md b/8086_documentation.md
index af3bbd5..9901a01 100644
--- a/8086_documentation.md
+++ b/8086_documentation.md
@@ -23,6 +23,8 @@ On some instructions:
 * **V**-bit : V-bit decides the number of shifts for rotate and shift instructions. If V = 0, then count = 1; if V = 1, the count is in CL register. For example, if V = 1 and CL = 2 then shift or rotate instruction shifts or rotates 2-bits
 * **Z**-bit : Used as a compare bit with the zero flag in conditional repeat and loop instructions. ex branch if zero is set or clear.
 
+No instruction has parts of its opcode past the first 2 bytes I.e. all bytes after the first two are additional data bytes
+
 | Register ID / REG   | Register Name |
 |:-------------------:|:-------------:|
 |    0 0 0            |    AL AX      |
diff --git a/common.mk b/common.mk
index 461c107..2a61129 100644
--- a/common.mk
+++ b/common.mk
@@ -40,7 +40,7 @@ disas: $(subst .txt,.disas,${BOOT_CODE})
 
 %.run: %.txt ${SYSTEM_VVP}
 	${QUIET_VVP}
-	${Q}vvp "${SYSTEM_VVP}" +BOOT_CODE="$<"
+	${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<"
 
 %.disas: %.bin
 	objdump -D -b binary -m i8086 $^ | less
diff --git a/system/Makefile b/system/Makefile
index 2ab5780..0074b11 100644
--- a/system/Makefile
+++ b/system/Makefile
@@ -15,7 +15,7 @@
 #   You should have received a copy of the GNU General Public License
 #   along with this program.  If not, see .
 #
-SOURCES=processor.v testbench.v memory.v registers.v alu.v
+SOURCES=processor.v testbench.v memory.v registers.v alu.v decoder.v
 INCLUDES=proc_state_def.v alu_header.v config.v
 SYSTEM_VVP=system.vvp
 BOOT_CODE=boot_code.txt
diff --git a/system/decoder.v b/system/decoder.v
new file mode 100644
index 0000000..56d29af
--- /dev/null
+++ b/system/decoder.v
@@ -0,0 +1,447 @@
+/* decoder.v - Implementation of instruction opcode decoding logic
+
+   This file is part of the 9086 project.
+
+   Copyright (c) 2023 Efthymios Kritikos
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+`include "proc_state_def.v"
+`include "alu_header.v"
+
+
+module decoder(
+	input wire [15:0] CIR,input wire [15:0] FLAGS, output reg Wbit, output reg Sbit, output reg unaligning ,output reg opcode_size, output reg ERROR,output reg [`PROC_STATE_BITS-1:0]next_state
+	,output reg [1:0]MOD, output reg [2:0]RM, output reg [15:0] PARAM1,output reg [15:0] PARAM2,output reg HALT,output reg has_operands
+	,output reg [1:0]in_alu1_sel1,output reg [1:0]in_alu1_sel2,output reg [2:0]out_alu1_sel
+	,output reg [3:0]reg_read_port1_addr, output reg [3:0]reg_write_addr
+	,output reg [2:0]ALU_1OP
+);
+
+/* 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 */
+
+`define invalid_instruction next_state=`PROC_IF_STATE_ENTRY;ERROR=1;MOD=2'b11;
+`define start_aligning_instruction unaligning=0;
+`define start_unaligning_instruction unaligning=1;
+
+
+always @( CIR ) begin
+	ERROR=0;HALT=0;
+	MOD=2'b11;/*TODO:remove*/
+	case(CIR[15:10])
+		6'b000001 : begin
+			/* ADD, ... */
+			if ( CIR[9:9] == 0 )begin
+				/*       Add Immediate word/byte to accumulator           */
+				/* 0 0 0 0  0 1 0 W |       DATA       |     DATA if W   |*/
+				opcode_size=0;
+				has_operands=1;
+				Wbit=CIR[8:8];
+				if(Wbit)
+					`start_unaligning_instruction
+				else
+					`start_aligning_instruction
+				MOD=2'b11;
+				in_alu1_sel1=2'b00;
+				in_alu1_sel2=2'b01;
+				out_alu1_sel=3'b011;
+				reg_read_port1_addr={CIR[8:8],3'b000};
+				reg_write_addr={CIR[8:8],3'b000};
+				ALU_1OP=`ALU_OP_ADD;
+				if(CIR[8:8]==1)
+					next_state=`PROC_DE_LOAD_16_PARAM;
+				else begin
+					PARAM1[7:0]=CIR[7:0];
+					next_state=`PROC_EX_STATE_ENTRY;
+				end
+			end else begin
+				`invalid_instruction
+			end
+		end
+		6'b100000 : begin
+			/* ADD, ADC, SUB, SBB, CMP , AND, ... */
+			case (CIR[5:3])
+				3'b000 : begin
+					/* Add Immediate word/byte to register/memory */
+					/* 1 0 0 0  0 0 S W | MOD 0 0  0  R/M  |     < DISP LO >  |     < DISP HI >   |      DATA        |      DATA if W    |    */
+					opcode_size=1;
+					has_operands=1;
+					`start_aligning_instruction
+					Wbit=CIR[8:8];
+					MOD=2'b11;
+					in_alu1_sel1=2'b00;
+					in_alu1_sel2=2'b01;
+					out_alu1_sel={1'b0,CIR[7:6]};
+					reg_read_port1_addr={CIR[8:8],CIR[2:0]};
+					reg_write_addr={CIR[8:8],CIR[2:0]};
+					ALU_1OP=`ALU_OP_ADD;
+					next_state=`PROC_DE_LOAD_16_PARAM;
+					if(CIR[8:8]==1)
+						next_state=`PROC_DE_LOAD_16_PARAM;
+					else begin
+						`invalid_instruction /*do 8bit loads*/
+					end
+				end
+				3'b111 : begin
+					/*                                  CMP - compare Immediate with register / memory                                        */
+					/* 1 0 0 0  0 0 S W | MOD 0 0  0  R/M  |     < DISP LO >  |     < DISP HI >   |      DATA        |      DATA if W    |    */
+					opcode_size=1;
+					has_operands=1;
+					Wbit=CIR[8:8];
+					Sbit=CIR[9:9];
+					MOD=CIR[7:6];
+					if((Wbit==1)&&(CIR[9:9]==1))begin
+						`start_unaligning_instruction
+					end else begin
+						`invalid_instruction;
+					end
+					if(MOD==2'b11)begin
+						in_alu1_sel1=2'b00;
+						in_alu1_sel2=2'b01;
+						reg_read_port1_addr={CIR[8:8],CIR[2:0]};
+						out_alu1_sel=3'b100;
+						ALU_1OP=`ALU_OP_SUB;
+						next_state=`PROC_DE_LOAD_8_PARAM;
+					end else begin
+						`invalid_instruction
+					end
+
+				end
+				default:begin
+					`invalid_instruction
+				end
+			endcase
+		end
+		6'b101100,
+			6'b101101:begin
+			/*        MOV - Move Immediate byte to register            */
+			/* 1 0 1 1  W  REG  |       DATA       |     DATA if W    |*/
+			has_operands=1;
+			Wbit=CIR[11:11];
+			opcode_size=0;
+			if(Wbit)
+				`start_unaligning_instruction
+			else
+				`start_aligning_instruction
+			MOD=2'b11;
+			in_alu1_sel1=2'b00;
+			in_alu1_sel2=2'b00;
+			out_alu1_sel=3'b011;
+			reg_write_addr={1'b0,CIR[10:8]};
+			PARAM1[7:0]=CIR[7:0];
+			PARAM2=0;
+			ALU_1OP=`ALU_OP_ADD;
+			next_state=`PROC_EX_STATE_ENTRY;
+		end
+		6'b101110,
+			6'b101111 : begin
+			/*MOV - Move Immediate word to register*/
+			has_operands=1;
+			Wbit=CIR[11:11];
+			opcode_size=0;
+			if(Wbit)
+				`start_unaligning_instruction
+			else
+				`start_aligning_instruction
+			MOD=2'b11;
+			in_alu1_sel1=2'b00;
+			in_alu1_sel2=2'b00;
+			out_alu1_sel=3'b011;
+			reg_write_addr={1'b1,CIR[10:8]};
+			ALU_1OP=`ALU_OP_ADD;
+			PARAM2=0;
+			next_state=`PROC_DE_LOAD_16_PARAM;
+		end
+
+		6'b100010 : begin
+			/*                      MOV - Reg/Mem to/from register                        */
+			/* 1 0 0 0  1 0 D W | MOD   REG    RM  |    < DISP LO >   |    < DISP HI >   |*/
+			has_operands=0;
+			`start_aligning_instruction
+			opcode_size=1;
+			MOD=CIR[7:6];
+			RM=CIR[2:0];
+			Wbit=CIR[8:8];
+			in_alu1_sel2=2'b00;
+			if(CIR[9:9] == 1)begin
+				/* Mem/Reg to reg */
+				if(MOD==2'b11)begin
+					/*Reg to Reg*/
+					in_alu1_sel1=2'b01;
+					reg_read_port1_addr=CIR[2:0];
+					next_state=`PROC_EX_STATE_ENTRY;
+				end else begin
+					/*Mem to Reg*/
+					in_alu1_sel1=2'b00;
+					next_state=`RPOC_MEMIO_READ;
+				end
+				out_alu1_sel=3'b011;
+				reg_write_addr={Wbit,CIR[5:3]};
+			end else begin
+				/* Reg to Mem/Reg */
+				if(MOD==2'b11)begin
+					/*Reg to Reg*/
+					in_alu1_sel1=2'b01;
+					out_alu1_sel=3'b011;
+					reg_write_addr={Wbit,CIR[2:0]};
+					next_state=`PROC_EX_STATE_ENTRY;
+				end else begin
+					/*Reg to Mem*/
+					in_alu1_sel1=2'b00;
+					reg_read_port1_addr=CIR[5:3];
+					out_alu1_sel={1'b0,MOD};
+					next_state=`PROC_DE_LOAD_REG_TO_PARAM;
+				end
+				reg_read_port1_addr={Wbit,CIR[5:3]};
+			end
+
+			ALU_1OP=`ALU_OP_ADD;
+			PARAM2=0;
+		end
+		6'b010000,//INC
+		6'b010001,//INC
+		6'b010010,//DEC
+		6'b010011:begin//DEC
+			/* DEC - Decrement Register */
+			/*   | 0 1 0 0  1  REG  |   */
+			/* INC - Increment Register */
+			/*   | 0 1 0 0  0  REG  |   */
+			has_operands=0;
+			opcode_size=0;
+			`start_unaligning_instruction
+			Wbit=1;
+			in_alu1_sel1=2'b01;
+			in_alu1_sel2=2'b00;
+			out_alu1_sel=3'b011;
+			MOD=2'b11;
+			PARAM2=1;
+			reg_read_port1_addr={1'b1,CIR[10:8]};
+			reg_write_addr={1'b1,CIR[10:8]};
+			if(CIR[11:11]==0)
+				ALU_1OP=`ALU_OP_ADD;
+			else
+				ALU_1OP=`ALU_OP_SUB;
+			next_state=`PROC_EX_STATE_ENTRY;
+		end
+		6'b111111 : begin
+			/* INC */
+			if (CIR[9:9] == 1 ) begin
+				case (CIR[5:3])
+					3'b000,3'b001 :begin
+						/*                          INC - Register/Memory                            */
+						/* 1 1 1 1  1 1 1 W | MOD 0 0  0  R/M  |    < DISP LO>    |    < DISP HI>    */
+						/*                          DEC - Register/Memory                            */
+						/* 1 1 1 1  1 1 1 W | MOD 0 0  1  R/M  |    < DISP LO>    |    < DISP HI>    */
+						has_operands=1;
+						opcode_size=1;
+						`start_aligning_instruction
+						Wbit=CIR[8:8];
+						MOD=CIR[7:6];
+						RM=CIR[2:0];
+						in_alu1_sel1=(MOD==2'b11)? 2'b01 : 2'b00;
+						in_alu1_sel2=2'b00;/* number 1 */
+						out_alu1_sel={1'b0,MOD};
+						PARAM2=1;
+
+						/*in case MOD=11 */
+						reg_read_port1_addr={1'b0,RM};
+						reg_write_addr={1'b0,RM};
+
+						ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB:`ALU_OP_ADD;
+						if ( CIR[7:6] == 2'b11 )
+							next_state=`PROC_EX_STATE_ENTRY;
+						else
+							next_state=`RPOC_MEMIO_READ;
+					end
+					default:begin
+						`invalid_instruction
+					end
+				endcase
+			end else begin
+				`invalid_instruction
+			end
+		end
+		6'b111101 : begin
+			/*HLT, CMC, TEST, NOT, NEG, MUL, IMUL, .... */
+			case (CIR[9:8])
+				2'b00:begin
+					/*     HLT - Halt     */
+					/* 1 1 1 1  0 1 0 0 | */
+					has_operands=0;
+					opcode_size=0;
+					`start_unaligning_instruction
+					MOD=2'b11;
+					HALT=1;
+					next_state=`PROC_HALT_STATE;
+				end
+				default:begin
+					`invalid_instruction;
+				end
+			endcase
+
+		end
+		6'b001111 : begin
+			if ( CIR[9:9] == 0 ) begin
+				/*         CMP - Compare Immediate with accumulator        */
+				/* 0 0 1 1  1 1 0 W |       DATA       |     DATA if W    |*/
+				/*                                                         */
+				/* NOTE: 8086 doc doesn't show the third byte but the      */
+				/* W flag and my assembler seem to disagree                */
+				Wbit=CIR[8:8];
+				opcode_size=0;
+				has_operands=1;
+				if(Wbit)
+					`start_unaligning_instruction
+				else
+					`start_aligning_instruction
+				MOD=2'b11;
+				in_alu1_sel1=2'b00;
+				in_alu1_sel2=2'b01;
+				reg_read_port1_addr={CIR[8:8],3'b000};
+				out_alu1_sel=3'b100;
+				ALU_1OP=`ALU_OP_SUB;
+				if(CIR[8:8]==1)
+					next_state=`PROC_DE_LOAD_16_PARAM;
+				else begin
+					PARAM1[7:0]=CIR[7:0];
+					next_state=`PROC_EX_STATE_ENTRY;
+				end
+			end else begin
+				`invalid_instruction
+			end
+		end
+		6'b011100,
+			6'b011101,
+			6'b011110,
+			6'b011111:begin
+			/*     Conditional relative jumps       */
+			/*        JE/JZ - Jump on Zero          */
+			/* 0 1 1 1  0 1 0 0 |     IP-INC8      |*/
+			/*         JS - Jump on Sign            */
+			/* 0 1 1 1  1 0 0 0 |     IP-INC8      |*/
+			/*       JNS -Jump on not Sign          */
+			/* 0 1 1 1  1 0 0 1 |     IP-INC8      |*/
+			/*                ....                  */
+			has_operands=1;
+			`start_aligning_instruction
+			Wbit=1;
+			opcode_size=0;
+			in_alu1_sel1=2'b10;
+			in_alu1_sel2=2'b00;
+			PARAM2={{8{CIR[7:7]}},CIR[7:0]};
+			ALU_1OP=`ALU_OP_ADD_SIGNED_B;
+			out_alu1_sel=3'b101;
+			case(CIR[11:9])
+				4'b000: begin
+					/* Jump on (not) Overflow */
+					if(FLAGS[11:11]==CIR[8:8])
+						next_state=`PROC_IF_STATE_ENTRY;
+					else begin
+						next_state=`PROC_EX_STATE_ENTRY;
+					end
+				end
+				4'b010: begin
+					/* Jump on (not) Zero */
+					if(FLAGS[6:6]==CIR[8:8])
+						next_state=`PROC_IF_STATE_ENTRY;
+					else
+						next_state=`PROC_EX_STATE_ENTRY;
+				end
+				4'b100: begin
+					/* Jump on (not) Sign */
+					if(FLAGS[7:7]==CIR[8:8])
+						next_state=`PROC_IF_STATE_ENTRY;
+					else
+						next_state=`PROC_EX_STATE_ENTRY;
+				end
+				4'b101: begin
+					/* Jump on (not) Parity */
+					if(FLAGS[2:2]==CIR[8:8])
+						next_state=`PROC_IF_STATE_ENTRY;
+					else
+						next_state=`PROC_EX_STATE_ENTRY;
+				end
+				default:begin
+					`invalid_instruction; /*We don't support that condition*/
+				end
+			endcase
+		end
+		6'b111010:begin
+			/* JMP,CALL */
+			case(CIR[9:8])
+				2'b00: begin
+					/*            CALL - Call direct within segment            */
+					/* 1 1 1 0  1 0 0 0 |     IP-INC-LO    |     IP-INC-HI    |*/
+					`invalid_instruction
+				end
+				2'b01: begin
+					/*     JMP - Uncoditional Jump direct within segment       */
+					/* 1 1 1 0  1 0 0 1 |     IP-INC-LO    |     IP-INC-HI    |*/
+					`invalid_instruction
+				end
+				2'b10: begin
+					/*                          JMP - Unconditional jump direct intersegment                         */
+					/* 0 0 0 0  0 0 0 0 |       IP-LO      |       IP-HI      |       CS-LO      |      CS-HI      | */
+					`invalid_instruction
+				end
+				2'b11: begin
+					/* JMP - Unconditional jump direct within segment (short) */
+					/*        | 1 1 1 0  1 0 0 1 |     IP-INC-LO    |         */
+					`start_aligning_instruction
+					opcode_size=0;
+					has_operands=1;
+					Wbit=1;
+					in_alu1_sel1=2'b10;
+					in_alu1_sel2=2'b00;
+					PARAM2={{8{CIR[7:7]}},CIR[7:0]};
+					ALU_1OP=`ALU_OP_ADD_SIGNED_B;
+					out_alu1_sel=3'b101;
+					next_state=`PROC_EX_STATE_ENTRY;
+				end
+			endcase
+		end
+		6'b110011:begin
+			case(CIR[9:8])
+				2'b00:begin
+					`invalid_instruction
+				end
+				2'b01:begin
+					if(CIR[7:0]==8'h21) begin
+						/*    INT - execut interrupt handler    */
+						/* 1 1 0 0  1 1 0 1 |       DATA       |*/
+						has_operands=1;
+						opcode_size=0;
+						`start_aligning_instruction
+						/* Emulate MS-DOS print routines */
+						$write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/
+						next_state=`PROC_IF_STATE_ENTRY;
+					end else begin
+						`invalid_instruction
+					end
+				end
+				2'b10:begin
+					`invalid_instruction
+				end
+				2'b11:begin
+					`invalid_instruction
+				end
+			endcase
+		end
+		default:begin
+			`invalid_instruction
+		end
+	endcase
+end
+
+endmodule
diff --git a/system/processor.v b/system/processor.v
index 74f9db5..082f2ac 100644
--- a/system/processor.v
+++ b/system/processor.v
@@ -42,16 +42,33 @@ assign external_data_bus=read?data_bus_output_register:'hz;
 // State
 reg [`PROC_STATE_BITS-1:0] state;
 
+/* Decoder */
+wire Wbit, Sbit, unaligning_instruction;
+wire [`PROC_STATE_BITS-1:0] next_state;
+wire [1:0]MOD;
+wire [2:0]RM;
+wire [15:0]DE_PARAM1;
+wire [15:0]DE_PARAM2;
+wire DE_ERROR,DE_HALT;
+wire [3:0]DE_reg_read_port1_addr,DE_reg_write_addr;
+wire opcode_size;
+wire has_operands;
+decoder decoder(
+	CIR,FLAGS,Wbit,Sbit,unaligning_instruction,opcode_size,DE_ERROR,next_state
+	,MOD,RM,DE_PARAM1,DE_PARAM2,DE_HALT,has_operands
+	,in_alu1_sel1,in_alu1_sel2,out_alu1_sel
+	,DE_reg_read_port1_addr,DE_reg_write_addr
+	,ALU_1OP
+);
+
 // Registers
 reg [19:0] ProgCount; /*TODO consider having single circuit to increment PC instead of having possible lots of adders all over the code*/
 reg [15:0] CIR;
 reg [15:0] PARAM1;
 reg [15:0] PARAM2;
+reg one_byte_instruction;
 reg unaligned_access;
-reg [1:0]MOD;
-reg [2:0]RM;
-reg Wbit;
-reg Sbit;
+
 reg [15:0]FLAGS;
 /* . . . . O D I T S Z . A . P . C */
 // C - Carry flag : carry out or borrow into the high order bit (8bit/16bit)
@@ -90,7 +107,7 @@ always @(negedge reset) begin
 		@(posedge reset)
 		@(negedge clock);
 		state=`PROC_IF_STATE_ENTRY;
-		MOD=2'b11;
+		one_byte_instruction=0;
 		ERROR=0;
 	end
 end
@@ -144,28 +161,32 @@ wire [7:0] ALU_1FLAGS;
 ALU ALU1(ALU_1A,ALU_1B,ALU_1OE,ALU_1O,ALU_1OP,ALU_1FLAGS,Wbit);
 
 /*** Processor stages ***/
-
-`define invalid_instruction state=`PROC_IF_STATE_ENTRY;ERROR=1;MOD=2'b11;
-`define start_aligning_instruction if(unaligned_access==0)begin ProgCount=ProgCount+1; external_address_bus <= ProgCount; end /*we normally don't advance PC in case of singly byte unaligning instructions leaving us with two instructions in one read so do that here*/
-`define start_unaligning_instruction unaligned_access=~unaligned_access;
+`define invalid_instruction state=`PROC_IF_STATE_ENTRY;ERROR=1;
 
 always @(negedge clock) begin
 	case(state)
 		`PROC_IF_WRITE_CIR:begin
 			if(unaligned_access)begin
-				CIR[15:8] <= external_data_bus[7:0];
-				ProgCount=ProgCount+1;
-				state=`PROC_IF_STATE_EXTRA_FETCH_SET;
+				if(one_byte_instruction==1)begin /*TODO: have a read buffer so we can do this even with data reads */
+					CIR <= {CIR[7:0],external_data_bus[15:8]};
+					state=`PROC_DE_STATE_ENTRY;
+				end else begin
+					CIR[15:8] <= external_data_bus[7:0];
+					state=`PROC_IF_STATE_EXTRA_FETCH_SET;
+				end
 			end else begin
 				CIR <= external_data_bus;
+				ProgCount=ProgCount+1;
 				state=`PROC_DE_STATE_ENTRY;
 			end
 		end
 		`PROC_IF_STATE_EXTRA_FETCH:begin
 			CIR[7:0] <= external_data_bus[15:8];
 			state=`PROC_DE_STATE_ENTRY;
+			ALU_1OE=0;
 		end
 		`PROC_EX_STATE_EXIT:begin
+			unaligned_access=unaligning_instruction^unaligned_access;
 			case(out_alu1_sel) /*TODO: use RM*/
 				3'b000,
 					3'b001,
@@ -274,6 +295,7 @@ always @(negedge clock) begin
 	endcase
 end
 
+
 always @(posedge clock) begin
 	case(state)
 		`PROC_HALT_STATE:begin
@@ -296,431 +318,77 @@ always @(posedge clock) begin
 			reg_write_in_sel=2'b00;
 		end
 		`PROC_IF_STATE_EXTRA_FETCH_SET:begin
+			ProgCount=ProgCount+1;
 			external_address_bus <= ProgCount;
 			state=`PROC_IF_STATE_EXTRA_FETCH;
 		end
-		/* 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 | 0 0 0 0  0 0 0 0 */
-		/* AFTER THE IF STAGE WE HAVE THE FIRST BYTE OF THE
-		* INSTRUCTION AND THE ONE FOLLOWING, ALIGNED CORRECTLY TO
-		* CIR */
 		`PROC_DE_STATE_ENTRY:begin
-			case(CIR[15:10])
-				6'b000001 : begin
-					/* ADD, ... */
-					if ( CIR[9:9] == 0 )begin
-						/*       Add Immediate word/byte to accumulator           */
-						/* 0 0 0 0  0 1 0 W |       DATA       |     DATA if W   |*/
-						Wbit=CIR[8:8];
-						if(Wbit)
-							`start_unaligning_instruction
-						else
-							`start_aligning_instruction
-						MOD=2'b11;
-						in_alu1_sel1=2'b00;
-						in_alu1_sel2=2'b01;
-						out_alu1_sel=3'b011;
-						reg_read_port1_addr={CIR[8:8],3'b000};
-						reg_write_addr={CIR[8:8],3'b000};
-						ALU_1OE=0;
-						ALU_1OP=`ALU_OP_ADD;
-						if(CIR[8:8]==1)
-							state=`PROC_DE_LOAD_16_PARAM;
-						else begin
-							PARAM1[7:0]=CIR[7:0];
-							state=`PROC_EX_STATE_ENTRY;
-						end
-					end else begin
-						`invalid_instruction
-					end
-				end
-				6'b100000 : begin
-					/* ADD, ADC, SUB, SBB, CMP , AND, ... */
-					case (CIR[5:3])
-						3'b000 : begin
-							/* Add Immediate word/byte to register/memory */
-							/* 1 0 0 0  0 0 S W | MOD 0 0  0  R/M  |     < DISP LO >  |     < DISP HI >   |      DATA        |      DATA if W    |    */
-							`start_aligning_instruction
-							Wbit=CIR[8:8];
-							MOD=2'b11;
-							in_alu1_sel1=2'b00;
-							in_alu1_sel2=2'b01;
-							out_alu1_sel={1'b0,CIR[7:6]};
-							reg_read_port1_addr={CIR[8:8],CIR[2:0]};
-							reg_write_addr={CIR[8:8],CIR[2:0]};
-							ALU_1OE=0;
-							ALU_1OP=`ALU_OP_ADD;
-							state=`PROC_DE_LOAD_16_PARAM;
-							if(CIR[8:8]==1)
-								state=`PROC_DE_LOAD_16_PARAM;
-							else begin
-								`invalid_instruction /*do 8bit loads*/
-							end
-						end
-						3'b111 : begin
-							/*                                  CMP - compare Immediate with register / memory                                        */
-							/* 1 0 0 0  0 0 S W | MOD 0 0  0  R/M  |     < DISP LO >  |     < DISP HI >   |      DATA        |      DATA if W    |    */
-							Wbit=CIR[8:8];
-							Sbit=CIR[9:9];
-							MOD=CIR[7:6];
-							if((Wbit==1)&&(CIR[9:9]==1))begin
-								`start_unaligning_instruction
-							end else begin
-								`invalid_instruction;
-							end
-							if(MOD==2'b11)begin
-								in_alu1_sel1=2'b00;
-								in_alu1_sel2=2'b01;
-								reg_read_port1_addr={CIR[8:8],CIR[2:0]};
-								out_alu1_sel=3'b100;
-								ALU_1OE=0;
-								ALU_1OP=`ALU_OP_SUB;
-								state=`PROC_DE_LOAD_8_PARAM;
-							end else begin
-								`invalid_instruction
-							end
-
-						end
-						default:begin
-							`invalid_instruction
-						end
-					endcase
-				end
-				6'b101100,
-					6'b101101:begin
-					/*        MOV - Move Immediate byte to register            */
-					/* 1 0 1 1  W  REG  |       DATA       |     DATA if W    |*/
-					Wbit=CIR[11:11];
-					if(Wbit)
-						`start_unaligning_instruction
-					else
-						`start_aligning_instruction
-					MOD=2'b11;
-					in_alu1_sel1=2'b00;
-					in_alu1_sel2=2'b00;
-					out_alu1_sel=3'b011;
-					reg_write_addr={1'b0,CIR[10:8]};
-					PARAM1[7:0]=CIR[7:0];
-					PARAM2=0;
-					ALU_1OE=0;
-					ALU_1OP=`ALU_OP_ADD;
-					state=`PROC_EX_STATE_ENTRY;
-				end
-				6'b101110,
-					6'b101111 : begin
-					/*MOV - Move Immediate word to register*/
-					Wbit=CIR[11:11];
-					if(Wbit)
-						`start_unaligning_instruction
-					else
-						`start_aligning_instruction
-					MOD=2'b11;
-					in_alu1_sel1=2'b00;
-					in_alu1_sel2=2'b00;
-					out_alu1_sel=3'b011;
-					reg_write_addr={1'b1,CIR[10:8]};
-					ALU_1OE=0;
-					ALU_1OP=`ALU_OP_ADD;
-					PARAM2=0;
-					state=`PROC_DE_LOAD_16_PARAM;
-				end
-
-				6'b100010 : begin
-					/*                      MOV - Reg/Mem to/from register                        */
-					/* 1 0 0 0  1 0 D W | MOD   REG    RM  |    < DISP LO >   |    < DISP HI >   |*/
-					`start_aligning_instruction
-					MOD=CIR[7:6];
-					RM=CIR[2:0];
-					Wbit=CIR[8:8];
-					in_alu1_sel2=2'b00;
-					if(CIR[9:9] == 1)begin
-						/* Mem/Reg to reg */
-						if(MOD==2'b11)begin
-							/*Reg to Reg*/
-							in_alu1_sel1=2'b01;
-							reg_read_port1_addr=CIR[2:0];
-							state=`PROC_EX_STATE_ENTRY;
-						end else begin
-							/*Mem to Reg*/
-							in_alu1_sel1=2'b00;
-							state=`RPOC_MEMIO_READ;
-						end
-						out_alu1_sel=3'b011;
-						reg_write_addr={Wbit,CIR[5:3]};
-					end else begin
-						/* Reg to Mem/Reg */
-						if(MOD==2'b11)begin
-							/*Reg to Reg*/
-							in_alu1_sel1=2'b01;
-							out_alu1_sel=3'b011;
-							reg_write_addr={Wbit,CIR[2:0]};
-							state=`PROC_EX_STATE_ENTRY;
-						end else begin
-							/*Reg to Mem*/
-							in_alu1_sel1=2'b00;
-							reg_read_port1_addr=CIR[5:3];
-							out_alu1_sel={1'b0,MOD};
-							state=`PROC_DE_LOAD_REG_TO_PARAM;
-						end
-						reg_read_port1_addr={Wbit,CIR[5:3]};
-					end
-
-					ALU_1OE=0;
-					ALU_1OP=`ALU_OP_ADD;
-					PARAM2=0;
-				end
-				6'b010000,//INC
-				6'b010001,//INC
-				6'b010010,//DEC
-				6'b010011:begin//DEC
-					/* DEC - Decrement Register */
-					/*   | 0 1 0 0  1  REG  |   */
-					/* INC - Increment Register */
-					/*   | 0 1 0 0  0  REG  |   */
-					`start_unaligning_instruction
-					Wbit=1;
-					in_alu1_sel1=2'b01;
-					in_alu1_sel2=2'b00;
-					out_alu1_sel=3'b011;
-					MOD=2'b11;
-					PARAM2=1;
-					reg_read_port1_addr={1'b1,CIR[10:8]};
-					reg_write_addr={1'b1,CIR[10:8]};
-					ALU_1OE=0;
-					if(CIR[11:11]==0)
-						ALU_1OP=`ALU_OP_ADD;
-					else
-						ALU_1OP=`ALU_OP_SUB;
-					state=`PROC_EX_STATE_ENTRY;
-				end
-				6'b111111 : begin
-					/* INC */
-					if (CIR[9:9] == 1 ) begin
-						case (CIR[5:3])
-							3'b000,3'b001 :begin
-								/*                          INC - Register/Memory                            */
-								/* 1 1 1 1  1 1 1 W | MOD 0 0  0  R/M  |    < DISP LO>    |    < DISP HI>    */
-								/*                          DEC - Register/Memory                            */
-								/* 1 1 1 1  1 1 1 W | MOD 0 0  1  R/M  |    < DISP LO>    |    < DISP HI>    */
-								`start_aligning_instruction
-								Wbit=CIR[8:8];
-								MOD=CIR[7:6];
-								RM=CIR[2:0];
-								in_alu1_sel1=(MOD==2'b11)? 2'b01 : 2'b00;
-								in_alu1_sel2=2'b00;/* number 1 */
-								out_alu1_sel={1'b0,MOD};
-								PARAM2=1;
-
-								/*in case MOD=11 */
-								reg_read_port1_addr={1'b0,RM};
-								reg_write_addr={1'b0,RM};
-
-								ALU_1OE=0;
-								ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB:`ALU_OP_ADD;
-								if ( CIR[7:6] == 2'b11 )
-									state=`PROC_EX_STATE_ENTRY;
-								else
-									state=`RPOC_MEMIO_READ;
-							end
-							default:begin
-								`invalid_instruction
-							end
-						endcase
-					end else begin
-						`invalid_instruction
-					end
-				end
-				6'b111101 : begin
-					/*HLT, CMC, TEST, NOT, NEG, MUL, IMUL, .... */
-					case (CIR[9:8])
-						2'b00:begin
-							/*     HLT - Halt     */
-							/* 1 1 1 1  0 1 0 0 | */
-							`start_unaligning_instruction
-							MOD=2'b11;
-							HALT=1;
-							state=`PROC_HALT_STATE;
-						end
-						default:begin
-							`invalid_instruction;
-						end
-					endcase
-
-				end
-				6'b001111 : begin
-					if ( CIR[9:9] == 0 ) begin
-						/*         CMP - Compare Immediate with accumulator        */
-						/* 0 0 1 1  1 1 0 W |       DATA       |     DATA if W    |*/
-						/*                                                         */
-						/* NOTE: 8086 doc doesn't show the third byte but the      */
-						/* W flag and my assembler seem to disagree                */
-						Wbit=CIR[8:8];
-						if(Wbit)
-							`start_unaligning_instruction
-						else
-							`start_aligning_instruction
-						MOD=2'b11;
-						in_alu1_sel1=2'b00;
-						in_alu1_sel2=2'b01;
-						reg_read_port1_addr={CIR[8:8],3'b000};
-						out_alu1_sel=3'b100;
-						ALU_1OE=0;
-						ALU_1OP=`ALU_OP_SUB;
-						if(CIR[8:8]==1)
-							state=`PROC_DE_LOAD_16_PARAM;
-						else begin
-							PARAM1[7:0]=CIR[7:0];
-							state=`PROC_EX_STATE_ENTRY;
-						end
-					end else begin
-						`invalid_instruction
-					end
-				end
-				6'b011100,
-					6'b011101,
-					6'b011110,
-					6'b011111:begin
-					/*     Conditional relative jumps       */
-					/*        JE/JZ - Jump on Zero          */
-					/* 0 1 1 1  0 1 0 0 |     IP-INC8      |*/
-					/*         JS - Jump on Sign            */
-					/* 0 1 1 1  1 0 0 0 |     IP-INC8      |*/
-					/*       JNS -Jump on not Sign          */
-					/* 0 1 1 1  1 0 0 1 |     IP-INC8      |*/
-					/*                ....                  */
-					`start_aligning_instruction
-					Wbit=1;
-					in_alu1_sel1=2'b10;
-					in_alu1_sel2=2'b00;
-					PARAM2={{8{CIR[7:7]}},CIR[7:0]};
-					ALU_1OE=0;
-					ALU_1OP=`ALU_OP_ADD_SIGNED_B;
-					out_alu1_sel=3'b101;
-					case(CIR[11:9])
-						4'b000: begin
-							/* Jump on (not) Overflow */
-							if(FLAGS[11:11]==CIR[8:8])
-								state=`PROC_IF_STATE_ENTRY;
-							else begin
-								state=`PROC_EX_STATE_ENTRY;
-							end
-						end
-						4'b010: begin
-							/* Jump on (not) Zero */
-							if(FLAGS[6:6]==CIR[8:8])
-								state=`PROC_IF_STATE_ENTRY;
-							else
-								state=`PROC_EX_STATE_ENTRY;
-						end
-						4'b100: begin
-							/* Jump on (not) Sign */
-							if(FLAGS[7:7]==CIR[8:8])
-								state=`PROC_IF_STATE_ENTRY;
-							else
-								state=`PROC_EX_STATE_ENTRY;
-						end
-						4'b101: begin
-							/* Jump on (not) Parity */
-							if(FLAGS[2:2]==CIR[8:8])
-								state=`PROC_IF_STATE_ENTRY;
-							else
-								state=`PROC_EX_STATE_ENTRY;
-						end
-						default:begin
-							`invalid_instruction; /*We don't support that condition*/
-						end
-					endcase
-				end
-				6'b111010:begin
-					/* JMP,CALL */
-					case(CIR[9:8])
-						2'b00: begin
-							/*            CALL - Call direct within segment            */
-							/* 1 1 1 0  1 0 0 0 |     IP-INC-LO    |     IP-INC-HI    |*/
-							`invalid_instruction
-						end
-						2'b01: begin
-							/*     JMP - Uncoditional Jump direct within segment       */
-							/* 1 1 1 0  1 0 0 1 |     IP-INC-LO    |     IP-INC-HI    |*/
-							`invalid_instruction
-						end
-						2'b10: begin
-							/*                          JMP - Unconditional jump direct intersegment                         */
-							/* 0 0 0 0  0 0 0 0 |       IP-LO      |       IP-HI      |       CS-LO      |      CS-HI      | */
-							`invalid_instruction
-						end
-						2'b11: begin
-							/* JMP - Unconditional jump direct within segment (short) */
-							/*        | 1 1 1 0  1 0 0 1 |     IP-INC-LO    |         */
-							`start_aligning_instruction
-							Wbit=1;
-							in_alu1_sel1=2'b10;
-							in_alu1_sel2=2'b00;
-							PARAM2={{8{CIR[7:7]}},CIR[7:0]};
-							ALU_1OE=0;
-							ALU_1OP=`ALU_OP_ADD_SIGNED_B;
-							out_alu1_sel=3'b101;
-							state=`PROC_EX_STATE_ENTRY;
-						end
-					endcase
-				end
-				6'b110011:begin
-					case(CIR[9:8])
-						2'b00:begin
-							`invalid_instruction
-						end
-						2'b01:begin
-							if(CIR[7:0]==8'h21) begin
-								/*    INT - execut interrupt handler    */
-								/* 1 1 0 0  1 1 0 1 |       DATA       |*/
-								`start_aligning_instruction
-								/* Emulate MS-DOS print routines */
-								$write("%s" ,register_file.registers[2][7:0]);
-								state=`PROC_IF_STATE_ENTRY;
-							end else begin
-								`invalid_instruction
-							end
-						end
-						2'b10:begin
-							`invalid_instruction
-						end
-						2'b11:begin
-							`invalid_instruction
-						end
-					endcase
-				end
-				default:begin
-					`invalid_instruction
-				end
-			endcase
+			/* IF we are unaligned, the address bus contains the
+			 * ProgCount and points to the second word containing
+			 * the nest unread byte in extenral_data_bus[7:0]. If
+			 * we are aligned the address bus points to the first
+			 * word of the instruction which contains no useful
+			 * data anymore but the ProgCount has the correct
+			 * address so update it now so that whatever the case
+			 * external_data_bus contains at leat some unkown data */
+			one_byte_instruction=(!has_operands)&&(!opcode_size);
+			external_address_bus <= ProgCount;
+			state=next_state;
+			PARAM1=DE_PARAM1;
+			PARAM2=DE_PARAM2;
+			ERROR=DE_ERROR;
+			HALT=DE_HALT;
+			reg_read_port1_addr=DE_reg_read_port1_addr;
+			reg_write_addr=DE_reg_write_addr;
 		end
 		`PROC_DE_LOAD_REG_TO_PARAM:begin
 			PARAM1=reg_read_port1_data;
 			state=`PROC_EX_STATE_ENTRY;
 		end
 		`PROC_DE_LOAD_8_PARAM:begin
-			ProgCount=ProgCount+1;
-			if(unaligned_access==0)begin
+			if(opcode_size==0)begin
 				if({Sbit,Wbit}==2'b11)begin
-					PARAM1 = {{8{external_data_bus[7:7]}},external_data_bus[7:0]};
+					/*signed "16bit" read*/
+					PARAM1 = {{8{CIR[7:7]}},CIR[7:0]};
 				end else begin
-					PARAM1[7:0] = external_data_bus[7:0];
+					PARAM1[7:0] = CIR[7:0];
 				end
 				state=`PROC_EX_STATE_ENTRY;
 			end else begin
-				external_address_bus=ProgCount;
-				state=`PROC_DE_LOAD_8_PARAM_UNALIGNED;
+				if(unaligned_access==1)begin
+					if({Sbit,Wbit}==2'b11)begin
+						/*signed "16bit" read*/
+						PARAM1 = {{8{external_data_bus[7:7]}},external_data_bus[7:0]};
+					end else begin
+						PARAM1[7:0] = external_data_bus[7:0];
+					end
+					ProgCount=ProgCount+1;
+					state=`PROC_EX_STATE_ENTRY;
+				end else begin
+					external_address_bus=ProgCount;
+					state=`PROC_DE_LOAD_8_PARAM_UNALIGNED;
+				end
 			end
 		end
 		`PROC_DE_LOAD_16_PARAM:begin
-			if(unaligned_access==1)begin
-				PARAM1[7:0] = external_data_bus[7:0];
-				ProgCount=ProgCount+1;
-				state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET;
+			if(opcode_size==0)begin
+				if(unaligned_access==1)begin
+					PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
+					ProgCount=ProgCount+1;
+					state=`PROC_EX_STATE_ENTRY;
+				end else begin
+					PARAM1 = {external_data_bus[15:8],CIR[7:0]};
+					state=`PROC_EX_STATE_ENTRY;
+				end
 			end else begin
-				PARAM1[7:0] = external_data_bus[15:8];
-				PARAM1[15:8] = external_data_bus[7:0];
 				ProgCount=ProgCount+1;
-				state=`PROC_EX_STATE_ENTRY;
+				if(unaligned_access==1)begin
+					PARAM1[7:0] = external_data_bus[7:0];
+					state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET;
+				end else begin
+					PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
+					state=`PROC_EX_STATE_ENTRY;
+				end
 			end
 		end
 		`PROC_DE_LOAD_16_EXTRA_FETCH:begin