From c3580848dee5cca19cc3af8f149af837501110ba Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Fri, 24 Feb 2023 10:08:01 +0000 Subject: [PATCH] Added bitwise TEST instruction --- system/boot_code.asm | 14 ++++++++++++-- system/decoder.v | 43 +++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/system/boot_code.asm b/system/boot_code.asm index 51c8ba3..b70d357 100644 --- a/system/boot_code.asm +++ b/system/boot_code.asm @@ -18,5 +18,15 @@ inc [si] dec [si] dec cx cmp CX,#0x00 -jz start -HLT +MOV CH,#0x9A +TEST CH,#0x70 +jz WAZZ +mov ah,#2 +mov dl,#'1 +int #0x21 +hlt +WAZZ: +mov ah,#2 +mov dl,#'0 +int #0x21 +hlt diff --git a/system/decoder.v b/system/decoder.v index a659c7c..a84f2da 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -78,12 +78,11 @@ microcode ucode(seq_addr_input,ucode_data); always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin if (SIMPLE_MICRO==0)begin - ERROR=0;HALT=0; + ERROR=0;HALT=0;seq_addr_entry=`UCODE_NO_INSTRUCTION; casex({CIR[15:8],CIR[5:3]}) 11'b0000_010x_xxx : begin /* Add Immediate word/byte to accumulator */ /* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/ - seq_addr_entry=`UCODE_NO_INSTRUCTION; opcode_size=0; has_operands=1; Wbit=CIR[8:8]; @@ -108,7 +107,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1000_00xx_000 : 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 | */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; `start_aligning_instruction opcode_size=1; has_operands=1; @@ -131,7 +129,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1000_00xx_111 : begin /* CMP - compare Immediate with register / memory */ /* 1 0 0 0 0 0 S W | MOD 1 1 1 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; opcode_size=1; has_operands=1; Wbit=CIR[8:8]; @@ -167,7 +164,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1011_0xxx_xxx : begin /* MOV - Move Immediate byte to register */ /* 1 0 1 1 W REG | DATA | DATA if W |*/ - seq_addr_entry=`UCODE_NO_INSTRUCTION; `start_aligning_instruction has_operands=1; Wbit=CIR[11:11]; /* IS 0 */ @@ -184,7 +180,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end 11'b1011_1xxx_xxx : begin /*MOV - Move Immediate word to register*/ - seq_addr_entry=`UCODE_NO_INSTRUCTION; `start_unaligning_instruction has_operands=1; Wbit=CIR[11:11]; /*IS 1 */ @@ -202,7 +197,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1000_10xx_xxx : begin /* MOV - Reg/Mem to/from register */ /* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=0; `start_aligning_instruction opcode_size=1; @@ -249,7 +243,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* | 0 1 0 0 1 REG | */ /* INC - Increment Register */ /* | 0 1 0 0 0 REG | */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=0; opcode_size=0; `start_unaligning_instruction @@ -272,7 +265,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* 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> */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=0; opcode_size=1; `start_aligning_instruction @@ -297,7 +289,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1111_0100_xxx : begin /* HLT - Halt */ /* 1 1 1 1 0 1 0 0 | */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=0; opcode_size=0; `start_unaligning_instruction @@ -311,7 +302,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* */ /* NOTE: 8086 doc doesn't show the third byte but the */ /* W flag and my assembler seem to disagree */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; Wbit=CIR[8:8]; opcode_size=0; has_operands=1; @@ -341,7 +331,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* JNS -Jump on not Sign */ /* 0 1 1 1 1 0 0 1 | IP-INC8 |*/ /* .... */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=1; `start_aligning_instruction Wbit=1; @@ -389,7 +378,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1110_1011_xxx:begin /* JMP - Unconditional jump direct within segment (short) */ /* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */ - seq_addr_entry=`UCODE_NO_INSTRUCTION; `start_aligning_instruction opcode_size=0; has_operands=1; @@ -404,7 +392,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b1100_1101_xxx:begin /* INT - execute interrupt handler */ /* 1 1 0 0 1 1 0 1 | DATA |*/ - seq_addr_entry=`UCODE_NO_INSTRUCTION; has_operands=1; opcode_size=0; `start_aligning_instruction @@ -469,6 +456,34 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin reg_read_port2_addr={1'b1,CIR[10:8]}; seq_addr_entry=`UCODE_PUSH_ENTRY; end + 11'b1111_011x_000:begin + /* TEST - Bitwise AND affecting only flags */ + /* 1 1 1 1 0 1 1 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]; + IN_MOD={1'b0,CIR[7:6]}; + RM={CIR[2:0]}; + if(Wbit==1)begin + `start_aligning_instruction + next_state=`PROC_DE_LOAD_16_PARAM; + end else begin + `start_unaligning_instruction + next_state=`PROC_DE_LOAD_8_PARAM; + end + in_alu1_sel1=2'b00; /* PARAM1 */ + ALU_1OP=`ALU_OP_AND; + case(IN_MOD) + 2'b11:begin + in_alu1_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + end + default:begin + `invalid_instruction + end + endcase + OUT_MOD=3'b100;/*NULL*/ + end default:begin `invalid_instruction end