diff --git a/.gitignore b/.gitignore index 7b29c30..fbdf5b8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,8 @@ *.swp *.memdump *.json -boot_code/brainfuck_interpreted.bin -boot_code/brainfuck_interpreted.txt -boot_code/brainfuck_mandelbrot.bin -boot_code/brainfuck_mandelbrot.txt -boot_code/brainfuck_compiled.bin -boot_code/brainfuck_compiled.txt +boot_code/*.bin +boot_code/*.txt system/boot_code.bin system/boot_code.txt system/obj_dir/ diff --git a/Makefile b/Makefile index 3c9059d..0532b8b 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ VERILATOR_BIN=system/obj_dir/Vsystem BOOT_CODE=boot_code/brainfuck_mandelbrot.txt GTKWSAVE=./gtkwave_savefile.gtkw MICROCODE=system/ucode.txt -BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt ${BOOT_CODE} +BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt boot_code/pipeline_ideal.txt boot_code/fibonacci.txt ${BOOT_CODE} NO_ASM=1 include common.mk diff --git a/boot_code/Makefile b/boot_code/Makefile index c28dbc4..96f14c9 100644 --- a/boot_code/Makefile +++ b/boot_code/Makefile @@ -1,4 +1,4 @@ -SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm +SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm fibonacci.asm BINARIES=$(subst .asm,.txt,${SOURCE}) BUILD_FILES=${BINARIES} BUILD_FILES+=$(subst .asm,.memdump,${SOURCE}) diff --git a/boot_code/fibonacci.asm b/boot_code/fibonacci.asm new file mode 100644 index 0000000..6132c84 --- /dev/null +++ b/boot_code/fibonacci.asm @@ -0,0 +1,113 @@ +INCLUDE dos_layer.asm + + +org 0x100 +mov sp,#STACK + +MOV AX,#0x1 +MOV BX,#0x1 + +CALL PRINT_HEX + +push bx +MAIN_LOOP: +pop bx + +CALL PRINT_HEX + +push AX +ADD AX,BX + +JNC MAIN_LOOP +pop bx + +MOV AH,#0x02 +MOV DL,#0x0a +INT #0x21 + +hlt + + + +;Input AX +PRINT_HEX: +PUSH DX + +TEST AH,#0xF0 +jz NOT_FIRST_NIBBLE +MOV DL,AH +CALL PRINT_HIGH +JMP SKIP1 + +NOT_FIRST_NIBBLE: +TEST AH,#0x0F +jz NOT_SECOND_NIBBLE +SKIP1: +MOV DL,AH +CALL PRINT_LOW +JMP SKIP2 + +NOT_SECOND_NIBBLE: +TEST AL,#0xF0 +jz NOT_THIRD_NIBBLE +SKIP2: +MOV DL,AL +CALL PRINT_HIGH + +NOT_THIRD_NIBBLE: +MOV DL,AL +CALL PRINT_LOW + +PUSH AX +MOV AH,#0x02 +MOV DL,#0x20 +INT #0x21 +POP AX + +POP DX +RET + +PRINT_HIGH: +AND DL,#0xF0 +TEST DL,#0x80 +jz NOT1 +OR DL,#0x08 +NOT1: +TEST DL,#0x40 +jz NOT2 +OR DL,#0x04 +NOT2: +TEST DL,#0x20 +jz NOT3 +OR DL,#0x02 +NOT3: +TEST DL,#0x10 +jz DONE +OR DL,#0x01 +DONE: + +PRINT_LOW: +PUSH AX +AND DL,#0x0F +CMP DL,#0x0A +JNS LETTERS +ADD DL,#0x30 +MOV AH,#0x02 +INT #0x21 +POP AX +RET + +LETTERS: +ADD DL,#0x37 +MOV AH,#0x02 +INT #0x21 +POP AX +RET + +.BLKB 200 +STACK: + +.ORG 0xFFF0 +MOV AX,#0x0100 +JMP AX + diff --git a/system/decoder.v b/system/decoder.v index afa7312..6a34cd8 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -108,6 +108,7 @@ wire [`UCODE_DATA_BITS-1:0] ucode_data; microcode ucode(seq_addr_input,ucode_data); `define invalid_instruction next_state=`EXEC_WAIT;ERROR<=`ERR_UNIMPL_INSTRUCTION;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION; +`define unimpl_addressing_mode next_state=`EXEC_WAIT;ERROR <= `ERR_UNIMPL_ADDRESSING_MODE;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION; //TODO: A possible optimisation for instruction with 8bit parameter and @@ -203,7 +204,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel1=2'b00; OUT_MOD=3'b100; MEM_OR_IO=0; - ALU_OP=`ALU_OP_SUB; + ALU_OP=`ALU_OP_SUB_REVERSE; memio_address_select=0; if(IN_MOD==3'b011)begin /*compare register with param*/ @@ -379,7 +380,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel2=2'b01; reg_read_port2_addr={Wbit,3'b000}; OUT_MOD=3'b100; - ALU_OP=`ALU_OP_SUB; + ALU_OP=`ALU_OP_SUB_REVERSE; MEM_OR_IO=0; if(Wbit==1) next_state=`EXEC_DE_LOAD_16_PARAM; @@ -438,6 +439,13 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin else next_state=`EXEC_WRITE_ENTRY; end + 3'b001: begin + /* Jump on (not) Carry */ + if(FLAGS[0:0]==CIR[8:8]) + next_state=`EXEC_NEXT_INSTRUCTION; + else + next_state=`EXEC_WRITE_ENTRY; + end default:begin `invalid_instruction; /*We don't support that condition*/ end @@ -517,7 +525,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin DEPENDS_ON_PREVIOUS<=0; end 11'b1111_011?_000:begin - /* TEST - Bitwise AND affecting only flags */ + /* TEST - Bitwise AND of immediate and registers/memmory 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; Wbit=CIR[8:8]; @@ -545,6 +553,28 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin DEPENDS_ON_PREVIOUS<=0; memio_address_select=0; end + 11'b1010_100?_???:begin + /* TEST - Bitwise AND of immediate and accumulator affecting only flags */ + /* 1 0 1 0 1 0 0 W | DATA | DATA if W | */ + opcode_size=0; + Wbit=CIR[8:8]; + IN_MOD=3'b011; + RM=3'b000; + MEM_OR_IO=0; + if(Wbit==1)begin + next_state=`EXEC_DE_LOAD_16_PARAM; + end else begin + next_state=`EXEC_DE_LOAD_8_PARAM; + end + in_alu_sel1=2'b00; /* PARAM1 */ + ALU_OP=`ALU_OP_AND; + in_alu_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + OUT_MOD=3'b100;/*NULL*/ + `normal_instruction; + DEPENDS_ON_PREVIOUS<=0; + memio_address_select=0; + end 11'b0101_1???_???:begin /* POP - REG=[SP]; SP+=2 */ /* | 0 1 0 1 1 REG | */ @@ -651,6 +681,71 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin DEPENDS_ON_PREVIOUS<=0; memio_address_select=0; end + 11'b1000_000?_100,11'b1000_000?_001:begin + /* OR - Bitwise OR immediate and register/mem */ + /* 1 0 0 0 0 0 0 W | MOD 0 0 1 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */ + /* AND - Bitwise AND immediate and register/mem */ + /* 1 0 0 0 0 0 0 W | MOD 1 0 0 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */ + opcode_size=1; + Wbit=CIR[8:8]; + IN_MOD={1'b0,CIR[7:6]}; + RM={CIR[2:0]}; + MEM_OR_IO=0; + if(Wbit==1)begin + next_state=`EXEC_DE_LOAD_16_PARAM; + end else begin + next_state=`EXEC_DE_LOAD_8_PARAM; + end + in_alu_sel1=2'b00; /* PARAM1 */ + case(CIR[5:3]) + 3'b100: ALU_OP=`ALU_OP_AND; + 3'b001: ALU_OP=`ALU_OP_OR; + default:begin end + endcase + case(IN_MOD) + 3'b011:begin + in_alu_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + reg_write_addr={Wbit,RM}; + end + default:begin + `unimpl_addressing_mode + end + endcase + OUT_MOD=IN_MOD; + DEPENDS_ON_PREVIOUS<=0; + memio_address_select=0; + `normal_instruction; + end + 11'b0000_00??_???:begin + /* ADD - Reg/memory with register to either */ + /* 0 0 0 0 0 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */ + opcode_size=1; + Wbit=CIR[8:8]; + Sbit=0; + OUT_MOD={1'b0,CIR[7:6]}; + IN_MOD=3'b011; + RM=CIR[2:0]; + in_alu_sel1=2'b01;//constantly register + reg_read_port1_addr={Wbit,CIR[5:3]}; + if(IN_MOD==3'b011)begin + in_alu_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + reg_write_addr={Wbit,RM}; + next_state=`EXEC_WRITE_ENTRY; + end else begin + in_alu_sel2=2'b00; + if(Wbit) + next_state=`EXEC_DE_LOAD_16_PARAM; + else + next_state=`EXEC_DE_LOAD_8_PARAM; + end + MEM_OR_IO=0; + memio_address_select=0; + ALU_OP=`ALU_OP_ADD; + DEPENDS_ON_PREVIOUS<=0; + `normal_instruction; + end default:begin `invalid_instruction end @@ -732,6 +827,10 @@ module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT ); 11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */ 11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */ 11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */ + 11'b1000_000?_100 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* AND - Bitwise AND immediate and register/mem */ + 11'b1000_000?_001 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* OR - Bitwise OR immediate and register/mem */ + 11'b1010_100?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ + 11'b0000_00??_??? : VERDICT <= 3'd2; /* ADD - Reg/memory with register to either */ default:begin end endcase end @@ -753,3 +852,5 @@ module Is1 ( input [7:0] IN, output reg VERDICT ); end endmodule `endif + +`undef unimpl_addressing_mode diff --git a/system/execute.v b/system/execute.v index 97f74fc..a75eb9f 100644 --- a/system/execute.v +++ b/system/execute.v @@ -336,6 +336,6 @@ always @(posedge clock) begin end endcase end -`undef unimpl_addressing_mode endmodule +`undef unimpl_addressing_mode