Added bitwise TEST instruction

This commit is contained in:
(Tim) Efthimis Kritikos 2023-02-24 10:08:01 +00:00
parent abee49d6c3
commit c3580848de
2 changed files with 41 additions and 16 deletions

View File

@ -18,5 +18,15 @@ inc [si]
dec [si] dec [si]
dec cx dec cx
cmp CX,#0x00 cmp CX,#0x00
jz start MOV CH,#0x9A
HLT TEST CH,#0x70
jz WAZZ
mov ah,#2
mov dl,#'1
int #0x21
hlt
WAZZ:
mov ah,#2
mov dl,#'0
int #0x21
hlt

View File

@ -78,12 +78,11 @@ microcode ucode(seq_addr_input,ucode_data);
always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
if (SIMPLE_MICRO==0)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]}) casex({CIR[15:8],CIR[5:3]})
11'b0000_010x_xxx : begin 11'b0000_010x_xxx : begin
/* Add Immediate word/byte to accumulator */ /* Add Immediate word/byte to accumulator */
/* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/ /* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/
seq_addr_entry=`UCODE_NO_INSTRUCTION;
opcode_size=0; opcode_size=0;
has_operands=1; has_operands=1;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
@ -108,7 +107,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1000_00xx_000 : begin 11'b1000_00xx_000 : begin
/* Add Immediate word/byte to register/memory */ /* 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 | */ /* 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 `start_aligning_instruction
opcode_size=1; opcode_size=1;
has_operands=1; has_operands=1;
@ -131,7 +129,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1000_00xx_111 : begin 11'b1000_00xx_111 : begin
/* CMP - compare Immediate with register / memory */ /* 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 | */ /* 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; opcode_size=1;
has_operands=1; has_operands=1;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
@ -167,7 +164,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1011_0xxx_xxx : begin 11'b1011_0xxx_xxx : begin
/* MOV - Move Immediate byte to register */ /* MOV - Move Immediate byte to register */
/* 1 0 1 1 W REG | DATA | DATA if W |*/ /* 1 0 1 1 W REG | DATA | DATA if W |*/
seq_addr_entry=`UCODE_NO_INSTRUCTION;
`start_aligning_instruction `start_aligning_instruction
has_operands=1; has_operands=1;
Wbit=CIR[11:11]; /* IS 0 */ Wbit=CIR[11:11]; /* IS 0 */
@ -184,7 +180,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
11'b1011_1xxx_xxx : begin 11'b1011_1xxx_xxx : begin
/*MOV - Move Immediate word to register*/ /*MOV - Move Immediate word to register*/
seq_addr_entry=`UCODE_NO_INSTRUCTION;
`start_unaligning_instruction `start_unaligning_instruction
has_operands=1; has_operands=1;
Wbit=CIR[11:11]; /*IS 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 11'b1000_10xx_xxx : begin
/* MOV - Reg/Mem to/from register */ /* MOV - Reg/Mem to/from register */
/* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/ /* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/
seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=0; has_operands=0;
`start_aligning_instruction `start_aligning_instruction
opcode_size=1; opcode_size=1;
@ -249,7 +243,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* | 0 1 0 0 1 REG | */ /* | 0 1 0 0 1 REG | */
/* INC - Increment Register */ /* INC - Increment Register */
/* | 0 1 0 0 0 REG | */ /* | 0 1 0 0 0 REG | */
seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=0; has_operands=0;
opcode_size=0; opcode_size=0;
`start_unaligning_instruction `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> */ /* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */
/* DEC - Register/Memory */ /* DEC - Register/Memory */
/* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */ /* 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; has_operands=0;
opcode_size=1; opcode_size=1;
`start_aligning_instruction `start_aligning_instruction
@ -297,7 +289,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1111_0100_xxx : begin 11'b1111_0100_xxx : begin
/* HLT - Halt */ /* HLT - Halt */
/* 1 1 1 1 0 1 0 0 | */ /* 1 1 1 1 0 1 0 0 | */
seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=0; has_operands=0;
opcode_size=0; opcode_size=0;
`start_unaligning_instruction `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 */ /* NOTE: 8086 doc doesn't show the third byte but the */
/* W flag and my assembler seem to disagree */ /* W flag and my assembler seem to disagree */
seq_addr_entry=`UCODE_NO_INSTRUCTION;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
opcode_size=0; opcode_size=0;
has_operands=1; has_operands=1;
@ -341,7 +331,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* JNS -Jump on not Sign */ /* JNS -Jump on not Sign */
/* 0 1 1 1 1 0 0 1 | IP-INC8 |*/ /* 0 1 1 1 1 0 0 1 | IP-INC8 |*/
/* .... */ /* .... */
seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=1; has_operands=1;
`start_aligning_instruction `start_aligning_instruction
Wbit=1; Wbit=1;
@ -389,7 +378,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1110_1011_xxx:begin 11'b1110_1011_xxx:begin
/* JMP - Unconditional jump direct within segment (short) */ /* JMP - Unconditional jump direct within segment (short) */
/* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */ /* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */
seq_addr_entry=`UCODE_NO_INSTRUCTION;
`start_aligning_instruction `start_aligning_instruction
opcode_size=0; opcode_size=0;
has_operands=1; has_operands=1;
@ -404,7 +392,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
11'b1100_1101_xxx:begin 11'b1100_1101_xxx:begin
/* INT - execute interrupt handler */ /* INT - execute interrupt handler */
/* 1 1 0 0 1 1 0 1 | DATA |*/ /* 1 1 0 0 1 1 0 1 | DATA |*/
seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=1; has_operands=1;
opcode_size=0; opcode_size=0;
`start_aligning_instruction `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]}; reg_read_port2_addr={1'b1,CIR[10:8]};
seq_addr_entry=`UCODE_PUSH_ENTRY; seq_addr_entry=`UCODE_PUSH_ENTRY;
end 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 default:begin
`invalid_instruction `invalid_instruction
end end