Wrote very basic brainfuck interpreter in 8086 asm to work on making it run and prove Turing completeness
This commit is contained in:
parent
fd31eb704c
commit
d7eb4f36c0
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,4 +5,6 @@
|
||||
*.swp
|
||||
cpu/boot_code.bin
|
||||
cpu/boot_code.txt
|
||||
cpu/brainfuck.bin
|
||||
cpu/brainfuck.txt
|
||||
cpu/memdump.txt
|
||||
|
@ -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
|
||||
|
36
cpu/Makefile
36
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
|
||||
|
105
cpu/brainfuck.asm
Normal file
105
cpu/brainfuck.asm
Normal file
@ -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 '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'
|
@ -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
|
||||
|
BIN
cpu/out.bin
Normal file
BIN
cpu/out.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user