diff --git a/Makefile b/Makefile index 3c9059d..20c9a26 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} boot_code/fibonacci.txt boot_code/gnome_sort.txt NO_ASM=1 include common.mk diff --git a/boot_code/Makefile b/boot_code/Makefile index 9f714d2..f953056 100644 --- a/boot_code/Makefile +++ b/boot_code/Makefile @@ -1,9 +1,10 @@ -SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm +SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm fibonacci.asm gnome_sort.asm BINARIES=$(subst .asm,.txt,${SOURCE}) BUILD_FILES=${BINARIES} BUILD_FILES+=$(subst .asm,.memdump,${SOURCE}) BUILD_FILES+=$(subst .asm,.fst,${SOURCE}) BUILD_FILES+=$(subst .asm,.bin,${SOURCE}) +BUILD_FILES+=$(subst .asm,.json,${SOURCE}) all: ${BINARIES} @@ -11,6 +12,9 @@ brainfuck_interpreted.bin: brainfuck_interpreter_v0.asm hello_9086.bf.asm dos_la brainfuck_compiled.bin: brainfuck_compiler_v1.asm hello_9086.bf.asm dos_layer.asm brainfuck_mandelbrot.bin: brainfuck_compiler_v1.asm mandelbrot.bf.asm dos_layer.asm +fibonacci.bin: helpers.asm +gnome_sort.bin: helpers.asm + %.bf.asm:%.bf ${Q}sed "s/[a-zA-Z\* ]//g;/^$$/d;s/^/.ASCII '/;s/\$$/'/" "$^" > $@ diff --git a/boot_code/fibonacci.asm b/boot_code/fibonacci.asm new file mode 100644 index 0000000..8c879e2 --- /dev/null +++ b/boot_code/fibonacci.asm @@ -0,0 +1,38 @@ +INCLUDE dos_layer.asm + + +org 0x100 +mov sp,#STACK + +MOV AX,#0x1 +MOV BX,#0x1 + +CALL PRINT_16_HEX + +push bx +MAIN_LOOP: +pop bx + +CALL PRINT_16_HEX + +push AX +ADD AX,BX + +JNC MAIN_LOOP +pop bx + +MOV AH,#0x02 +MOV DL,#0x0a +INT #0x21 + +hlt + + +.BLKB 200 +STACK: +INCLUDE helpers.asm + +.ORG 0xFFF0 +MOV AX,#0x0100 +JMP AX + diff --git a/boot_code/gnome_sort.asm b/boot_code/gnome_sort.asm new file mode 100644 index 0000000..5800ae6 --- /dev/null +++ b/boot_code/gnome_sort.asm @@ -0,0 +1,54 @@ +INCLUDE dos_layer.asm + +.org 0x100 +mov sp,#STACK +MOV SI,#DATA + +GNOME_SORT: +CMP SI,#DATA+31 +JZ GNOMED +MOV AX,[SI] +INC SI +CMP AH,AL +JAE GNOME_SORT + +SWAP: +MOV BL,AL +MOV AL,AH +MOV AH,BL +DEC SI +MOV [SI],AX +CMP SI,#DATA +JZ GNOME_SORT +DEC SI +JMP GNOME_SORT + +GNOMED: +MOV SI,#DATA +PRINT_LOOP: +MOV AL,[SI] +call PRINT_0_8_HEX +INC SI +CMP SI,#DATA+32 +JNZ PRINT_LOOP + +MOV AH,#0x02 +MOV DL,#0x0a +INT #0x21 + +hlt + +DATA: DB 0x51, 0x17, 0x37, 0x5d, 0x06, 0x3f, 0x51, 0x8b + DB 0xa5, 0x33, 0x54, 0xdf, 0xae, 0xee, 0x3a, 0x18 + DB 0xe9, 0xdb, 0x1f, 0x21, 0x44, 0x4f, 0x99, 0x09 + DB 0x2a, 0x23, 0x82, 0x4f, 0x52, 0xf1, 0xdc, 0x0b + +.BLKB 200 +STACK: + +INCLUDE helpers.asm + +.ORG 0xFFF0 +MOV AX,#0x0100 +JMP AX + diff --git a/boot_code/helpers.asm b/boot_code/helpers.asm new file mode 100644 index 0000000..92f063e --- /dev/null +++ b/boot_code/helpers.asm @@ -0,0 +1,93 @@ + +;Input AX +PRINT_16_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 + +PRINT_0_8_HEX: +MOV DL,AL + +PUSH AX +CALL PRINT_HIGH +POP AX + +MOV DL,AL +CALL PRINT_LOW + +PUSH AX +MOV AH,#0x02 +MOV DL,#0x20 +INT #0x21 +POP AX + +RET diff --git a/system/decoder.v b/system/decoder.v index 33d1dc0..97a6e94 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -184,19 +184,22 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel1=2'b00; OUT_MOD=3'b100; MEM_OR_IO=0; - ALU_1OP=`ALU_OP_SUB; + ALU_1OP=`ALU_OP_SUB_REVERSE; memio_address_select=0; if(IN_MOD==3'b011)begin /*compare register with param*/ in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; - next_state=`PROC_DE_LOAD_8_PARAM; end else begin /*compare register indirect access * with param */ in_alu1_sel2=2'b00; - next_state=`PROC_DE_LOAD_16_PARAM; /*will then call MEMIO_READ*/ + /*will call MEMIO_READ after EXEC_DE_LOAD..*/ end + if (Wbit) + next_state=`PROC_DE_LOAD_16_PARAM; + else + next_state=`PROC_DE_LOAD_8_PARAM; `normal_instruction; end 11'b1011_0???_??? : begin @@ -364,7 +367,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,3'b000}; OUT_MOD=3'b100; - ALU_1OP=`ALU_OP_SUB; + ALU_1OP=`ALU_OP_SUB_REVERSE; MEM_OR_IO=0; if(Wbit==1) next_state=`PROC_DE_LOAD_16_PARAM; @@ -423,6 +426,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin else next_state=`PROC_EX_STATE_ENTRY; end + 3'b001: begin + /* Jump on (not) Carry */ + if(FLAGS[0:0]==CIR[8:8]) + next_state=`PROC_IF_STATE_ENTRY; + else + next_state=`PROC_EX_STATE_ENTRY; + end default:begin `invalid_instruction; /*We don't support that condition*/ end @@ -526,6 +536,29 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin `normal_instruction; 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 + instruction_size=3; + next_state=`PROC_DE_LOAD_16_PARAM; + end else begin + instruction_size=2; + next_state=`PROC_DE_LOAD_8_PARAM; + end + in_alu1_sel1=2'b00; /* PARAM1 */ + ALU_1OP=`ALU_OP_AND; + in_alu1_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + OUT_MOD=3'b100;/*NULL*/ + `normal_instruction; + memio_address_select=0; + end 11'b0101_1???_???:begin /* POP - REG=[SP]; SP+=2 */ /* | 0 1 0 1 1 REG | */ @@ -629,6 +662,90 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin seq_addr_entry<=`UCODE_RET_ENTRY; 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 + instruction_size=4; + next_state=`PROC_DE_LOAD_16_PARAM; + end else begin + instruction_size=3; + next_state=`PROC_DE_LOAD_8_PARAM; + end + in_alu1_sel1=2'b00; /* PARAM1 */ + case(CIR[5:3]) + 3'b100: ALU_1OP=`ALU_OP_AND; + 3'b001: ALU_1OP=`ALU_OP_OR; + default:begin end + endcase + case(IN_MOD) + 3'b011:begin + in_alu1_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + reg_write_addr={Wbit,RM}; + `normal_instruction; + end + default:begin + `invalid_instruction; + end + endcase + OUT_MOD=IN_MOD; + memio_address_select=0; + end + 11'b0000_00??_???,11'b0010_10??_???,11'b0011_10??_???:begin + /* CMP - Compare Register/memory and register */ + /* 0 0 1 1 1 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */ + /* SUB - Reg/memory with register to either */ + /* 0 0 1 0 1 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */ + /* ADD - Reg/memory with register to either */ + /* 0 0 0 0 0 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */ + instruction_size=2; + opcode_size=1; + Wbit=CIR[8:8]; + Sbit=0; + IN_MOD=3'b011; + RM=CIR[2:0]; + in_alu1_sel1=2'b01;//constantly register + reg_read_port1_addr={Wbit,CIR[5:3]}; + if(IN_MOD==3'b011)begin + in_alu1_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; + reg_write_addr={Wbit,RM}; + next_state=`PROC_EX_STATE_ENTRY; + end else begin + in_alu1_sel2=2'b00; + if(Wbit) + next_state=`PROC_DE_LOAD_16_PARAM; + else + next_state=`PROC_DE_LOAD_8_PARAM; + end + MEM_OR_IO=0; + memio_address_select=0; + case (CIR[13:10]) + 4'b0000: ALU_1OP=`ALU_OP_ADD; + 4'b1010: ALU_1OP=`ALU_OP_SUB; + 4'b1110: ALU_1OP=`ALU_OP_SUB_REVERSE; + default: begin end + endcase + case (CIR[13:10]) + 4'b0000: OUT_MOD={1'b0,CIR[7:6]}; + 4'b1010: OUT_MOD={1'b0,CIR[7:6]}; + 4'b1110: OUT_MOD=3'b100; /* NULL */ + default: begin end + endcase + if(CIR[9:9]==1'b0) begin + `normal_instruction; + end else begin + `invalid_instruction + end + end default:begin `invalid_instruction end