Service Pack 1: Added some needed instructions for what will probably be some of the V0.2.0 test programs

This commit is contained in:
(Tim) Efthimis Kritikos 2023-05-23 11:25:57 +01:00
parent 98e73af5da
commit 900610426d
6 changed files with 312 additions and 6 deletions

View File

@ -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

View File

@ -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/\$$/'/" "$^" > $@

38
boot_code/fibonacci.asm Normal file
View File

@ -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

54
boot_code/gnome_sort.asm Normal file
View File

@ -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

93
boot_code/helpers.asm Normal file
View File

@ -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

View File

@ -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