From d7eb4f36c0be566b1cdc3d4825c18cc71ebe15d7 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Sat, 11 Feb 2023 01:11:37 +0000 Subject: [PATCH] Wrote very basic brainfuck interpreter in 8086 asm to work on making it run and prove Turing completeness --- .gitignore | 2 + README.md | 2 +- cpu/Makefile | 36 +++++++++------- cpu/brainfuck.asm | 105 ++++++++++++++++++++++++++++++++++++++++++++++ cpu/memory.v | 7 +++- cpu/out.bin | Bin 0 -> 212 bytes 6 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 cpu/brainfuck.asm create mode 100644 cpu/out.bin diff --git a/.gitignore b/.gitignore index fea44ca..6d90a58 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ *.swp cpu/boot_code.bin cpu/boot_code.txt +cpu/brainfuck.bin +cpu/brainfuck.txt cpu/memdump.txt diff --git a/README.md b/README.md index 71e5f3d..4762640 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A CPU that aims to be binary compatible with the 8086 and with as many optimisat ### Progress * [X] Executing code -* [ ] can calculate the sieve of Eratosthenes +* [ ] Is turing complete * [ ] can boot up MS-DOS / FreeDOS * [ ] Is completely binary compatible * [ ] Is pipelined diff --git a/cpu/Makefile b/cpu/Makefile index abdc911..0c9f5e1 100644 --- a/cpu/Makefile +++ b/cpu/Makefile @@ -2,34 +2,38 @@ SOURCES=processor.v testbench.v memory.v registers.v alu.v INCLUDES=proc_state_def.v VVP=processor.vvp +.PHONY: brainf +brainf: ${VVP} brainfuck.txt + vvp ${VVP} +BOOT_CODE=brainfuck.txt + .PHONY: run -run: ${VVP} +run: ${VVP} boot_code.txt vvp ${VVP} .PHONY: build build: ${VVP} .PHONY: wave -wave: ${VVP} - vvp ${VVP} -lxt2 +wave: ${VVP} brainfuck.txt + vvp ${VVP} -lxt2 +BOOT_CODE=brainfuck.txt gtkwave test.lx2 gtkwave_savefile.gtkw -${VVP} : ${SOURCES} ${INCLUDES} boot_code.txt +${VVP} : ${SOURCES} ${INCLUDES} iverilog -g2012 ${SOURCES} -o $@ -.PHONY: clean -clean: - rm -f ${VVP} test.lx2 boot_code.txt boot_code.bin +%.txt:%.bin + dd if=/dev/zero bs=1 count=1200 of=$(subst .bin,.stage,$^) status=none + dd if=$^ of=$(subst .bin,.stage,$^) conv=notrunc,nocreat status=none + xxd -ps -c 2 $(subst .bin,.stage,$^) > $@ + rm $(subst .bin,.stage,$^) -boot_code.txt:boot_code.bin - dd if=/dev/zero bs=1 count=256 of=boot_code.stage status=none - dd if=boot_code.bin of=boot_code.stage conv=notrunc,nocreat status=none - xxd -ps -c 2 boot_code.stage > boot_code.txt - rm boot_code.stage - -boot_code.bin:boot_code.asm +%.bin:%.asm as86 -0 $< -b $@ .PHONY: disas -disas: boot_code.bin - objdump -D -b binary -m i8086 boot_code.bin +disas: brainfuck.bin + objdump -D -b binary -m i8086 $^ + +.PHONY: clean +clean: + rm -f ${VVP} test.lx2 boot_code.txt boot_code.bin brainfuck.txt brainfuck.bin diff --git a/cpu/brainfuck.asm b/cpu/brainfuck.asm new file mode 100644 index 0000000..67a965f --- /dev/null +++ b/cpu/brainfuck.asm @@ -0,0 +1,105 @@ +mov si,#prog +mov BX,#data +mov CX,#bracket +dec si +INTERPRET: +inc si +mov al,[si] +cmp al,#'+ +jz WAS_PLUS +cmp al,#'- +jz WAS_MINUS +cmp al,#'> +jz WAS_MR +cmp al,#'< +jz WAS_ML +cmp al,#'[ +jz WAS_PL +cmp al,#'] +jz WAS_PR +cmp al,#'. +jz WAS_PRINT +jmp PROG_END + +WAS_PLUS: +inc BYTE [BX] +JMP INTERPRET + +WAS_MINUS: +dec BYTE [BX] +JMP INTERPRET + +WAS_MR: +inc bx +JMP INTERPRET + +WAS_ML: +dec bx +JMP INTERPRET + +WAS_PL: +MOV AL,[BX] +cmp AL,#0 +jz SKIP_CODE_BLOCK +;have to enter loop +MOV AX,SI +inc CX +inc CX +push SI +MOV SI,CX +mov [SI],AX +POP SI +JMP INTERPRET + +SKIP_CODE_BLOCK: +;have to skip loop +MOV DX,#0 +SKIP_LOOP: +INC SI +mov AL,[SI] +CMP AL,#'] +JZ WAS_CLOSE1 +CMP AL,#'[ +JZ WAS_OPEN1 +JMP SKIP_LOOP + +WAS_CLOSE1: +CMP DX,#0 +JZ INTERPRET +DEC DX +JMP SKIP_LOOP +WAS_OPEN1: +INC DX +JMP SKIP_LOOP + +WAS_PR: +mov AL,[BX] +cmp AL,#0 +JZ EXIT_PR +push SI +MOV SI,CX +mov ax,[SI] +POP SI +mov si,ax +JMP INTERPRET + + +EXIT_PR: +DEC CX +DEC CX +jmp INTERPRET + + +WAS_PRINT: +mov ah, #0x02 +MOV DL,[BX] +int #0x21 +JMP INTERPRET + +PROG_END: +hlt + +bracket: .BLKB 280 +data: .BLKB 560 +;prog db '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.f' +prog:.ASCII '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.' diff --git a/cpu/memory.v b/cpu/memory.v index 2761a47..65bc442 100644 --- a/cpu/memory.v +++ b/cpu/memory.v @@ -1,7 +1,10 @@ module rom(input [19:0] address,output wire [15:0] data ,input rd,input cs); -reg [15:0] memory [0:127]; +reg [15:0] memory [0:599]; initial begin - $readmemh("boot_code.txt", memory); + string boot_code; + if(!$value$plusargs("BOOT_CODE=%s",boot_code)) + boot_code="boot_code.txt"; + $readmemh(boot_code, memory); end assign data = !rd & !cs ? memory[address]: 'hz; endmodule diff --git a/cpu/out.bin b/cpu/out.bin new file mode 100644 index 0000000000000000000000000000000000000000..a68632870113bc888f5fd9d8b426496f44c33664 GIT binary patch literal 212 zcmchP!41GL3!%ExN{89#{%nPoAK8$I7$EG3!QWpc>n+a literal 0 HcmV?d00001