9086/boot_code/brainfuck_compiler_v1.asm

280 lines
4.1 KiB
NASM
Raw Normal View History

; brainfuck_compiler_v1.asm - Brainfuck compiler for the 8086 employing some optimisations
;
; This file is part of the 9086 project.
;
; Copyright (c) 2023 Efthymios Kritikos
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
; 0x0000-0x0100 int vector 0x0100-0x0700 data 0x0700-0xC000 program data
mov sp,#STACK_COMPILER
mov bx,#bootup_msg
mov ah,#0x02
print1:
mov dl,[bx]
int #0x21
inc bx
cmp dl,#0x0A
jne print1
MOV DI,#0x0200
MOV AX,#0x0000
MOV bl,#0x00
CLEAR:
STOSW
INC BL
JNZ CLEAR
mov bx,#compiling
mov ah,#0x02
print2:
mov dl,[bx]
cmp dl,#0
je exit
int #0x21
inc bx
jmp print2
exit:
MOV SI,#prog
MOV DI,#0x0700
;CL: write concat CH: move concat
MOV CX,#0
JMP COMPILE ; Moving some functions above the main switch to make shot jumps work
;;;;;;;;; ] ;;;;;;;;;
WAS_PR:
CALL FLUSH_MOVES
CALL FLUSH_WRITES
MOV AX,#0x078a ; mov (%bx),%al
STOSW
MOV AX,#0x003C ; cmp $0x0,%al
STOSW
MOV AX,#0x0574 ; je [after the absolute short jump instruction]
STOSW
MOV AL,#0xb8 ; [opcode only] mov 0x????,%ax
STOSB
POP BX
ADD BX,#4
MOV [DI],BX
INC DI
INC DI
SUB BX,#4
MOV AX,#0xE0FF ; jmp *%ax
STOSW
MOV [BX],DI
JMP COMPILE
;;;;;;;;; [ ;;;;;;;;;
WAS_PL:
CALL FLUSH_MOVES
; optimise [-]
CMP WORD [SI],#0x5D2D
JNZ ACTUAL_LOOP
MOV CL,#0
INC SI
INC SI
MOV AX,#0x07C6
STOSW
MOV AL,#0
STOSB
JMP COMPILE
ACTUAL_LOOP:
CALL FLUSH_WRITES
MOV AX,#0x078a ; mov (%bx),%al
STOSW
MOV AX,#0x003c ; cmp $0x0,%al
STOSW
MOV AX,#0x0575 ; jne [after the absolute short jump instruction]
STOSW
MOV AL,#0xb8 ; [opcode only] mov 0x????,%ax
STOSB
PUSH DI
INC DI
INC DI
MOV AX,#0xe0ff ; jmp *%ax
STOSW
JMP COMPILE
;;;;;;;;;;; ACTUAL START ;;;;;;;;;;;;;;;
COMPILE:
MOV AL,[SI]
INC 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
mov bx,#compiled
mov ah,#0x02
print3:
mov dl,[bx]
int #0x21
inc bx
cmp dl,#0x0A
jne print3
MOV AL,#0xF4 ; hlt
MOV [DI],AL
; From 0x100 its free but i'll do 0x200 in case it start writing earlier
MOV BX,#0x0200
MOV AX,#0x0700
JMP AX
;;;;;;;;; . ;;;;;;;;;
WAS_PRINT:
CALL FLUSH_MOVES
CALL FLUSH_WRITES
MOV AX,#0x02B4 ; mov $0x2,%ah
STOSW
MOV AX,#0x178A ; mov (%bx),%dl
STOSW
MOV AX,#0x21CD ; int $0x21
STOSW
JMP COMPILE
;;;;;;;;; + ;;;;;;;;;
WAS_PLUS:
CALL FLUSH_MOVES
INC CL
JMP COMPILE
;;;;;;;;; - ;;;;;;;;;
WAS_MINUS:
CALL FLUSH_MOVES
DEC CL
JMP COMPILE
;;;;;;;;; > ;;;;;;;;;
WAS_MR:
CALL FLUSH_WRITES
INC CH
JMP COMPILE
;;;;;;;;; < ;;;;;;;;;
WAS_ML:
CALL FLUSH_WRITES
DEC CH
JMP COMPILE
FLUSH_WRITES:
CMP CL,#0
JZ WRITES_FLUSHED
CMP CL,#1
JZ WRITES_ADD_ONE
CMP CL,#0xFF
JZ WRITES_DEC_ONE
;; General case
MOV AX,#0x0780 ; add %cl,(%bx)
STOSW
MOV AL,CL
STOSB
JMP WRITES_FLUSHED
WRITES_ADD_ONE:
MOV AX,#0x07fe ; incb (%bx)
STOSW
JMP WRITES_FLUSHED
WRITES_DEC_ONE:
MOV AX,#0x0ffe ; incb (%bx)
STOSW
JMP WRITES_FLUSHED
WRITES_FLUSHED:
MOV CL,#0
RET
FLUSH_MOVES:
CMP CH,#0
JZ MOVES_FLUSHED
CMP CH,#1
JZ MOVES_ONE_RIGHT
CMP CH,#0XFF
JZ MOVES_ONE_LEFT
;; General case
MOV AX,#0xC381 ; ADD $....,%bx
STOSW
MOV AL,CH
STOSB
TEST CH,#0x80
jz POSITIVE
MOV AL,#0xFF
STOSB
JMP MOVES_FLUSHED
POSITIVE:
MOV AL,#0x00
STOSB
JMP MOVES_FLUSHED
MOVES_ONE_RIGHT:
MOV AL,#0x43 ; inc %bx
STOSB
JMP MOVES_FLUSHED
MOVES_ONE_LEFT:
MOV AL,#0x4b ; dec %bx
STOSB
JMP MOVES_FLUSHED
MOVES_FLUSHED:
MOV CH,#0
RET
compiled: .ASCII '\rCompiled! \n'
compiling: .ASCII 'Compiling...\0'
bootup_msg: .ASCII 'Native 8086 brainfuck compiler v1\n'
.BLKB 10 ; Using the text as stack space for the compiled program
STACK_COMPILER: ; brainfuck_mandelbrot depends on stack being at the end