diff --git a/system/decoder.v b/system/decoder.v
index 4659a81..a659c7c 100644
--- a/system/decoder.v
+++ b/system/decoder.v
@@ -273,7 +273,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* 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=1;
+ has_operands=0;
opcode_size=1;
`start_aligning_instruction
Wbit=CIR[8:8];
@@ -414,7 +414,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end
next_state=`PROC_IF_STATE_ENTRY;
end
- 11'b11101000_xxx:begin
+ 11'b1110_1000_xxx:begin
/* CALL - Direct call within segment */
/* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/
@@ -427,7 +427,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=2; //substract from sp
seq_addr_entry=`UCODE_CALL_ENTRY;
end
- 11'b11000011_xxx:begin
+ 11'b1100_0011_xxx:begin
/* RET - Return from call within segment */
/* | 1 1 0 0 0 0 1 1 | */
@@ -442,10 +442,10 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
has_operands=1;
Wbit=1;
Sbit=0;
- PARAM2=2;
+ PARAM1=2;
seq_addr_entry=`UCODE_RET_ENTRY;
end
- 11'b1010101x_xxx:begin
+ 11'b1010_101x_xxx:begin
/* STOS - Write byte/word to [DI] and increment accordingly */
/* | 1 0 1 0 1 0 1 W | */
`start_unaligning_instruction
@@ -457,6 +457,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
seq_addr_entry=`UCODE_STOS_ENTRY;
PARAM2=(Wbit==1)?2:1;
end
+ 11'b0101_0xxx_xxx:begin
+ /* PUSH - SP-=2; [SP]=REG */
+ /* | 0 1 0 1 0 REG | */
+ `start_unaligning_instruction
+ opcode_size=0;
+ has_operands=0;
+ Wbit=1;
+ Sbit=0;
+ PARAM2=2;
+ reg_read_port2_addr={1'b1,CIR[10:8]};
+ seq_addr_entry=`UCODE_PUSH_ENTRY;
+ end
default:begin
`invalid_instruction
end
@@ -487,9 +499,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
endcase
- reg_read_port1_addr=ucode_data[25:22];
- IN_MOD =ucode_data[28:26];
- reg_read_port2_addr=ucode_data[32:29];
+ if(ucode_data[33:33]==0)
+ reg_read_port1_addr=ucode_data[25:22];
+ IN_MOD=ucode_data[28:26];
+ if(ucode_data[34:34]==0)
+ reg_read_port2_addr=ucode_data[32:29];
+ if(ucode_data[36:36]==1)
+ Wbit=ucode_data[35:35];
end
end
diff --git a/system/processor.v b/system/processor.v
index 3c17cb0..3282f75 100644
--- a/system/processor.v
+++ b/system/processor.v
@@ -185,7 +185,7 @@ always @(negedge clock) begin
* be done by decode at the end*/
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
unaligned_access=unaligning_instruction^unaligned_access;
- case(OUT_MOD) /*TODO: use RM*/
+ case(OUT_MOD)
3'b000,
3'b001,
3'b010 : begin
@@ -507,7 +507,7 @@ always @(posedge clock) begin
end
end
`PROC_EX_STATE_ENTRY:begin
- FLAGS[7:0] = ALU_1FLAGS[7:0];
+ FLAGS[7:0] = ALU_1FLAGS[7:0]; //TODO, we should probably move all the ...STATE_EXIT stuff here
state=`PROC_EX_STATE_EXIT;
end
`PROC_MEMIO_WRITE:begin
diff --git a/system/registers.v b/system/registers.v
index d6d36cb..c527fc1 100644
--- a/system/registers.v
+++ b/system/registers.v
@@ -32,11 +32,13 @@ input write_port1_we;
reg [15:0] registers [7:0];
-assign read_port1_data = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]] :
- ( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[2:0]][15:8]} : {8'b0,registers[read_port1_addr[2:0]][7:0]} ) );
+assign read_port1_data[15:8] = read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][15:8] : 8'hz ;
+assign read_port1_data[7:0] = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][7:0] :
+ ( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[1:0]][15:8]} : {8'b0,registers[read_port1_addr[1:0]][7:0]} ) );
-assign read_port2_data = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]] :
- ( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[2:0]][15:8]} : {8'b0,registers[read_port2_addr[2:0]][7:0]} ) );
+assign read_port2_data[15:8] = read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][15:8] : 8'hz ;
+assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][7:0] :
+ ( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[1:0]][15:8]} : {8'b0,registers[read_port2_addr[1:0]][7:0]} ) );
`ifdef DEBUG_REG_WRITES
string debug_name;
diff --git a/system/ucode.txt b/system/ucode.txt
index 9bb43da..c0984bc 100644
--- a/system/ucode.txt
+++ b/system/ucode.txt
@@ -17,6 +17,13 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
+//wbo: Wbit overwrite, {VALUE,ENABLE}. ex 11 would force one, 10 wouldn't do anything
+//
+//krs: Keep registers, selects weather the register port 1 and/or 2
+// addresses is set on that microcoded instruction or kept as it
+// was before allowing for registers to be parameterised.
+// {Register_port2, Register_port1}
+//
//rr2: reg_read_port2_addr
//
//imd: IN_MOD
@@ -50,19 +57,24 @@
@000 0000_000_000__00__00_0000__00_000000
-// 32 28 25 21 18 15 13 11 7 5 0
+// 36 34 32 28 25 21 18 15 13 11 7 5 0
// CALL
-// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
-@001 0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
-@002 0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
-@003 0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
+// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
+@001 _00_00_0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
+@002 _00_00_0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
+@003 _00_00_0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
// RET
-// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
-@004 0000_110_zzzz_000_101__00__11_zzzz__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
-@005 0000_011_1100_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
+// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
+@004 _00_00_0000_110_zzzz_000_101__00__11_zzzz__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
+@005 _00_00_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
// STOS
-// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
-@006 1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
-@007 zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
+// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
+@006 _00_00_1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
+@007 _11_00_zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
+
+// PUSH
+// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
+@008 _00_10_0000_011_1100_001_011__00__01_1100__00_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
+@009 _00_10_0000_011_zzzz_000_110__01__11_zzzz__00_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
diff --git a/system/ucode_header.v b/system/ucode_header.v
index 5fe32d8..9c31d9e 100644
--- a/system/ucode_header.v
+++ b/system/ucode_header.v
@@ -18,11 +18,12 @@
along with this program. If not, see . */
`define UCODE_ADDR_BITS 5
-`define UCODE_DATA_BITS 33
-`define UCODE_SIZE 8
+`define UCODE_DATA_BITS 37
+`define UCODE_SIZE 10
/* DEFINE ADDRESSES IN THE MICROCODE */
`define UCODE_NO_INSTRUCTION 5'b00000
`define UCODE_CALL_ENTRY 5'b00001
`define UCODE_RET_ENTRY 5'b00100
`define UCODE_STOS_ENTRY 5'b00110
+`define UCODE_PUSH_ENTRY 5'b01000