Added partial support for the software interrupt INT instruction

This commit is contained in:
(Tim) Efthimis Kritikos 2023-03-08 07:26:28 +00:00
parent d93c92c005
commit 9de83fd7c1
13 changed files with 166 additions and 80 deletions

View File

@ -23,6 +23,9 @@ GTKWSAVE=./gtkwave_savefile.gtkw
MICROCODE=system/ucode.txt
BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt ${BOOT_CODE}
shim:
@echo The processor\'s output handling is being rewritten so the usual mandelbrot program isn\'t working. please git checkout d93c92c00572d812c76d1b42969741d8cfce8d4d
NO_ASM=1
include common.mk

View File

@ -1,5 +1,10 @@
org 0x100
INCLUDE brainfuck_compiler_v1.asm
prog:
INCLUDE hello_9086.bf.asm
output_program:
.ORG 0xFFF0
MOV AX,#0x0100
JMP AX

View File

@ -1,4 +1,9 @@
ORG 0x100
INCLUDE brainfuck_interpreter_v0.asm
prog:
INCLUDE hello_9086.bf.asm
.ORG 0xFFF0
MOV AX,#0x0100
JMP AX

View File

@ -1,6 +1,11 @@
ORG 0x100
INCLUDE brainfuck_compiler_v1.asm
prog:
INCLUDE mandelbrot.bf.asm
output_program:
.ORG 0xFFF0
MOV AX,#0x0100
JMP AX

View File

@ -35,7 +35,7 @@ disas: $(subst .txt,.disas,${BOOT_CODE})
# Assembling code
%.txt:%.bin
${Q}dd if=/dev/zero bs=1 count=32768 of="$(subst .bin,.stage,$<)" status=none
${Q}dd if=/dev/zero bs=1 count=65536 of="$(subst .bin,.stage,$<)" status=none
${Q}dd if="$<" of="$(subst .bin,.stage,$<)" conv=notrunc,nocreat status=none
${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
${Q}rm "$(subst .bin,.stage,$<)"

View File

@ -38,10 +38,7 @@ always @ ( * ) begin
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
default:begin
OUT=0;
C_FLAG=0;
end
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h8000)==16'h8000;OUT=A<<B; end
endcase
end else begin
case (op)
@ -52,10 +49,7 @@ always @ ( * ) begin
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
default:begin
OUT=0;
C_FLAG=0;
end
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h80)==16'h80;OUT=A<<B; end
endcase
end
end

View File

@ -25,3 +25,4 @@
`define ALU_OP_XOR 3'b100
`define ALU_OP_ADD_SIGNED_B 3'b101
`define ALU_OP_SUB_REVERSE 3'b110
`define ALU_OP_SHIFT_LEFT 3'b111

View File

@ -1,3 +1,8 @@
.ORG 0x84 /* INT 21 */
DW 0xFFFF /*Code Segment*/
DW 0x014c /*Program Counter*/
.ORG 0x0100
start:
MOV SP,#STACK
MOV AX,#0x0000
@ -37,3 +42,7 @@ RET
.BLKB 10
STACK:
.ORG 0xFFF0
MOV AX,#0x0100
JMP AX

View File

@ -51,6 +51,7 @@ module decoder(
,output reg [2:0]ALU_1OP
,output reg [`UCODE_ADDR_BITS-1:0] seq_addr_entry, input wire SIMPLE_MICRO, input wire [`UCODE_ADDR_BITS-1:0] seq_addr_input
,output reg [2:0]instruction_size
,output reg memio_address_select
);
// verilator lint_on UNUSEDSIGNAL
@ -109,6 +110,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
reg_read_port2_addr={Wbit,3'b000};
reg_write_addr={Wbit,3'b000};
ALU_1OP=`ALU_OP_ADD;
memio_address_select=0;
if(Wbit)
next_state=`PROC_DE_LOAD_16_PARAM;
else
@ -135,6 +137,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu1_sel2=2'b00;
end
OUT_MOD=IN_MOD;
memio_address_select=0;
case({Sbit,Wbit})
2'b00,2'b11:begin
next_state=`PROC_DE_LOAD_8_PARAM;
@ -180,6 +183,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu1_sel1=2'b00;
OUT_MOD=3'b100;
ALU_1OP=`ALU_OP_SUB;
memio_address_select=0;
if(IN_MOD==3'b011)begin
/*compare register with param*/
in_alu1_sel2=2'b01;
@ -209,6 +213,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_ADD;
next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
memio_address_select=0;
end
11'b1011_1???_??? : begin
/*MOV - Move Immediate word to register*/
@ -224,6 +229,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=0;
next_state=`PROC_DE_LOAD_16_PARAM;
`normal_instruction;
memio_address_select=0;
end
11'b1000_10??_??? : begin
/* MOV - Reg/Mem to/from register */
@ -268,6 +274,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_ADD;
`normal_instruction;
memio_address_select=0;
end
11'b0100_????_???:begin//DEC
/* DEC - Decrement Register */
@ -290,6 +297,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_SUB;
next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
memio_address_select=0;
end
11'b1111_111?_00? : begin
/* INC - Register/Memory */
@ -316,6 +324,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
else
next_state=`PROC_MEMIO_READ;
`normal_instruction;
memio_address_select=0;
end
11'b1111_0100_??? : begin
/* HLT - Halt */
@ -327,7 +336,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ERROR<=0;
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
next_state=`PROC_HALT_STATE;
memio_address_select=0;
end
11'b0011_110?_??? : begin
/* CMP - Compare Immediate with accumulator */
@ -355,6 +364,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
next_state=`PROC_EX_STATE_ENTRY;
end
`normal_instruction;
memio_address_select=0;
end
11'b0111_????_???:begin
/* Conditional relative jumps */
@ -408,6 +418,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end
endcase
`normal_instruction;
memio_address_select=0;
end
11'b1110_1011_???:begin
/* JMP - Unconditional jump direct within segment (short) */
@ -422,18 +433,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
OUT_MOD=3'b101;
next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
end
11'b1100_1101_???:begin
/* INT - execute interrupt handler */
/* 1 1 0 0 1 1 0 1 | DATA |*/
instruction_size=2;
opcode_size=0;
/* Emulate MS-DOS print routines */
if(CIR[7:0]==8'h21 && register_file.registers[0][15:8]==8'h02)begin
$write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/
end
next_state=`PROC_IF_STATE_ENTRY;
`normal_instruction;
memio_address_select=0;
end
11'b1110_1000_???:begin
/* CALL - Direct call within segment */
@ -446,6 +446,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
Sbit=1;
PARAM2=2; //subtract from sp
seq_addr_entry<=`UCODE_CALL_ENTRY;
memio_address_select=0;
end
11'b1100_0011_???:begin
/* RET - Return from call within segment */
@ -458,6 +459,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
Sbit=0;
PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY;
memio_address_select=0;
end
11'b1010_101?_???:begin
/* STOS - Write byte/word to [DI] and increment accordingly */
@ -469,6 +471,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
RM=3'b101;
seq_addr_entry<=`UCODE_STOS_ENTRY;
PARAM2=(Wbit==1)?2:1;
memio_address_select=0;
end
11'b0101_0???_???:begin
/* PUSH - SP-=2; [SP]=REG */
@ -480,6 +483,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=2;
reg_read_port2_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_PUSH_ENTRY;
memio_address_select=0;
end
11'b1111_011?_000:begin
/* TEST - Bitwise AND affecting only flags */
@ -508,6 +512,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
endcase
OUT_MOD=3'b100;/*NULL*/
`normal_instruction;
memio_address_select=0;
end
11'b0101_1???_???:begin
/* POP - REG=[SP]; SP+=2 */
@ -519,6 +524,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1=2;
reg_write_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_POP_ENTRY;
memio_address_select=0;
end
11'b1111_1111_100:begin
/* JMP - Unconditional indirect within segment jump */
@ -540,6 +546,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_ADD;
OUT_MOD=3'b101;
`normal_instruction;
memio_address_select=0;
end
11'b1100_011?_000:begin
/* MOV - Move immediate to register/memory */
@ -560,6 +567,31 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
IN_MOD=3'b011;
RM=CIR[2:0];
`normal_instruction;
memio_address_select=0;
end
11'b1100_1101_???:begin
/* INT - execute interrupt handler */
/* 1 1 0 0 1 1 0 1 | DATA |*/
// [skiped] 1) push flags
// [skiped] 2) clear trap and interrupt enable flag
// [skiped] 3) push CS
// [skiped] 4) fetch CS from interrupt table
// 5) push ProgCount
// 6) fetch ProgCount from interrupt table
instruction_size=2;
opcode_size=0;
Wbit=1;
Sbit=0;
PARAM2=2;
seq_addr_entry<=`UCODE_INT_ENTRY;
memio_address_select=0;
///* Emulate MS-DOS print routines */
//if(CIR[7:0]==8'h21 && register_file.registers[0][15:8]==8'h02)begin
// $write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/
//end
//next_state=`PROC_IF_STATE_ENTRY;
//`normal_instruction;
//memio_address_select=0;
end
default:begin
`invalid_instruction
@ -570,20 +602,22 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
//Sbit, Wbit, opcode_size and the others are still latched
//from when we ordered the switch to microcode
seq_addr_entry <= ucode_data[`UCODE_ADDR_BITS-1:0];
case(ucode_data[7:6])
2'b00: next_state=`PROC_EX_STATE_ENTRY;
2'b01: next_state=`PROC_DE_LOAD_16_PARAM;
2'b10: next_state=`PROC_DE_LOAD_8_PARAM;
2'b11: next_state=`PROC_MEMIO_READ;
case(ucode_data[8:6])
3'b000: next_state=`PROC_EX_STATE_ENTRY;
3'b001: next_state=`PROC_DE_LOAD_16_PARAM;
3'b010: next_state=`PROC_DE_LOAD_8_PARAM;
3'b011: next_state=`PROC_MEMIO_READ;
3'b100: next_state=`PROC_MEMIO_READ_SETADDR;
default: begin end /*impossible*/
endcase
if(ucode_data[35:35]==0)
reg_write_addr=ucode_data[11:8 ];
in_alu1_sel1 =ucode_data[13:12];
in_alu1_sel2 =ucode_data[15:14];
OUT_MOD =ucode_data[18:16];
if(ucode_data[36:36]==0)
reg_write_addr=ucode_data[12:9 ];
in_alu1_sel1 =ucode_data[14:13];
in_alu1_sel2 =ucode_data[16:15];
OUT_MOD =ucode_data[19:17];
/*1:1 map essentially but I want to keep the spec for these bits separate
* from the alu op select bits*/
case(ucode_data[21:19])
case(ucode_data[22:20])
3'b000: ALU_1OP=`ALU_OP_ADD;
3'b001: ALU_1OP=`ALU_OP_SUB;
3'b010: ALU_1OP=`ALU_OP_AND;
@ -591,15 +625,17 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
3'b100: ALU_1OP=`ALU_OP_XOR;
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
3'b111: ALU_1OP=`ALU_OP_SHIFT_LEFT;
default: begin end
endcase
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[37:37]==1)
Wbit=ucode_data[36:36];
reg_read_port1_addr=ucode_data[26:23];
IN_MOD=ucode_data[29:27];
if(ucode_data[35:35]==0)
reg_read_port2_addr=ucode_data[33:30];
if(ucode_data[38:38]==1)
Wbit=ucode_data[37:37];
memio_address_select=ucode_data[39:39];
end
end
`undef invalid_instruction

View File

@ -57,6 +57,7 @@ wire [2:0] DE_instruction_size;
reg instruction_size_init;
wire [2:0] instruction_size;
assign instruction_size = instruction_size_init ? 3'b010 : DE_instruction_size;
wire memio_address_select;
decoder decoder(
.CIR(CIR),
@ -76,7 +77,8 @@ decoder decoder(
.seq_addr_entry(ucode_seq_addr_entry),
.SIMPLE_MICRO(SIMPLE_MICRO),
.seq_addr_input(ucode_seq_addr),
.instruction_size(DE_instruction_size)
.instruction_size(DE_instruction_size),
.memio_address_select(memio_address_select)
);
assign Wbit=INSTRUCTION_INFO[2:2];
@ -194,7 +196,7 @@ always @(posedge clock) begin
case(state)
`PROC_RESET:begin
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
ProgCount <= 0;//TODO: Reset Vector
ProgCount <= 'hFFF0;//TODO: Implement Segmentation and set to zero
HALT <= 0;
ERROR <= 0;
IOMEM <= 0;
@ -438,7 +440,10 @@ always @(posedge clock) begin
endcase
end
`PROC_MEMIO_READ_SETADDR:begin
external_address_bus <= {4'b0,reg_read_port1_data[15:0]};
if(memio_address_select==0)
external_address_bus <= {4'b0,reg_read_port1_data[15:0]};
else
external_address_bus <= {4'b0,ALU_1O};
state <= reg_read_port1_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA;
end
`PROC_MEMIO_GET_ALIGNED_DATA:begin
@ -531,6 +536,13 @@ always @(posedge clock) begin
reg_read_port1_addr <= 4'b1100;
state <= `PROC_MEMIO_WRITE;
end
3'b111:begin /* Write to PRAM1 (for microcode calculations) */
PARAM1 <= ALU_1O;
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
state <= `PROC_IF_STATE_ENTRY;
else
state <= `PROC_NEXT_MICROCODE;
end
default:begin
`invalid_instruction
end

View File

@ -3,6 +3,7 @@
module system ( input clock,input reset, output [19:0]address_bus, inout [15:0]data_bus,output BHE, output rd, output wr, output IOMEM, output HALT, output ERROR);
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
string waveform_name;

View File

@ -17,6 +17,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
//mas: MemIo Address Select
// 0: register file output 1: alu output
//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
@ -38,8 +40,9 @@
// 100:ALU_OP_XOR
// 101:ALU_OP_ADD_SIGNED_B
// 110:ALU_OP_SUB_REVERSE
// 111:ALU_OP_SHIFT_LEFT
//
//a1o: OUT_MOD. Handled in `PROC_EX_STATE_EXIT
//a1o: OUT_MOD. Handled in `PROC_EX_STATE_ENTRY
//
//a12: In ALU 1 sel 2
//
@ -48,38 +51,49 @@
//rwa: Register Write Address
//
//nxs: Next State
// 00: PROC_EX_STATE_ENTRY
// 01: PROC_DE_LOAD_16_PARAM
// 10: PROC_DE_LOAD_8_PARAM
// 11: PROC_MEMIO_READ
// 000: PROC_EX_STATE_ENTRY
// 001: PROC_DE_LOAD_16_PARAM
// 010: PROC_DE_LOAD_8_PARAM
// 011: PROC_MEMIO_READ
// 100: PROC_MEMIO_READ_SETADDR (used when addressing based on ALU_OUT
//
//Nxt M: Next microcode address
@000 _00_000_0000_000_0000_000_000__00__00_0000__00_000000
// 36 34 32 28 25 21 18 15 13 11 7 5 0
// CALL
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@001 _00_000_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_000_0000_011_xxxx_000_110__10__11_xxxx__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
@003 _00_000_0000_011_xxxx_000_101__10__00_xxxx__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
// RET
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@004 _00_000_0000_110_xxxx_000_101__00__11_xxxx__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
@005 _00_000_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
// STOS
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@006 _00_000_1000_011_xxxx_000_000__01__11_xxxx__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
@007 _11_000_xxxx_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_010_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_010_0000_011_xxxx_000_110__01__11_xxxx__00_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
// 39 38 36 33 29 26 22 19 16 14 12 8 5 0
// INT
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@00c __0__00_000_0000_011_1100_001_011__00__01_1100_010_001101 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
@00d __0__00_000_0000_011_xxxx_000_110__10__11_xxxx_000_001110 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
/* We read the parameter and get the address to jump on ALU_OUT */
@00e __0__00_000_xxxx_011_xxxx_111_111__00__00_xxxx_000_001111 // ALU_1: PARAM1 (arg) ALU_2: PARAM2 (2) ALU_OP:SHIFT ALU_out: PARAM1
@00f __1__00_000_xxxx_011_xxxx_000_100__00__00_xxxx_100_010000 // ALU_1: PARAM1 (base int table addr) ALU_2: PARAM2 (2) ALU_OP:ADD ALU_out: NULL
@010 __0__00_000_xxxx_011_xxxx_000_101__00__11_xxxx_000_000000 // ALU_1: 0 ALU_2: PARAM2 (address) ALU_OP:SHIFT ALU_out: PC
// POP
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@00a _00_100_0000_110_xxxx_011_011__00__11_xxxx__11_001011 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: REG
@00b _00_000_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@00a __0__00_100_0000_110_xxxx_011_011__00__11_xxxx_011_001011 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: REG
@00b __0__00_000_1100_011_0000_000_011__01__00_1100_000_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
// PUSH
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@008 __0__00_010_0000_011_1100_001_011__00__01_1100_000_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
@009 __0__00_010_0000_011_xxxx_000_110__01__11_xxxx_000_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
// STOS
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@006 __0__00_000_1000_011_xxxx_000_000__01__11_xxxx_000_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
@007 __0__11_000_xxxx_011_1111_000_011__00__01_1111_000_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
// RET
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@004 __0__00_000_0000_110_xxxx_000_101__00__11_xxxx_011_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
@005 __0__00_000_1100_011_0000_000_011__01__00_1100_000_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
// CALL
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@001 __0__00_000_0000_011_1100_001_011__00__01_1100_001_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
@002 __0__00_000_0000_011_xxxx_000_110__10__11_xxxx_000_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
@003 __0__00_000_0000_011_xxxx_000_101__10__00_xxxx_000_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
@000 __0__00_000_0000_000_0000_000_000__00__00_0000_000_000000

View File

@ -17,14 +17,15 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
`define UCODE_SIZE 12
`define UCODE_DATA_BITS 38
`define UCODE_SIZE 17
`define UCODE_DATA_BITS 40
`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE)
/* DEFINE ADDRESSES IN THE MICROCODE */
`define UCODE_NO_INSTRUCTION 4'b0000
`define UCODE_CALL_ENTRY 4'b0001
`define UCODE_RET_ENTRY 4'b0100
`define UCODE_STOS_ENTRY 4'b0110
`define UCODE_PUSH_ENTRY 4'b1000
`define UCODE_POP_ENTRY 4'b1010
`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
`define UCODE_POP_ENTRY 5'b01010
`define UCODE_INT_ENTRY 5'b01100