Skip to content

Instantly share code, notes, and snippets.

@boomshroom
Created February 6, 2018 14:31
Show Gist options
  • Save boomshroom/a8ae9de1e406d19e5a5d29efef08b46a to your computer and use it in GitHub Desktop.
Save boomshroom/a8ae9de1e406d19e5a5d29efef08b46a to your computer and use it in GitHub Desktop.
;
; Adapted from osdev.orgs Bare Bones tutorial http://wiki.osdev.org/Bare_Bones
;
%define TRUNCATE 1
%define SIZE 1
%define OPTIMIZE 0 ; TODO Fix
global loader
bits 32
; Multiboot stuff
MODULEALIGN equ 1<<0
MEMINFO equ 1<<1
VIDEOINFO equ 1<<2
FLAGS equ MODULEALIGN | MEMINFO | VIDEOINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)
TERM_COLOR equ 0x07
TERM_HEIGHT equ 25
TERM_WIDTH equ 80
section .multiboot
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
dd 0, 0, 0, 0, 0
dd 0
dd 0
dd 0
dd 32
section .text
loader:
cmp eax, 0x2BADB002
je .test_flags
mov edx, mberr
jmp error_msg
.test_flags:
mov eax, [ebx]
and eax, 0x109
cmp eax, 0x109
jz .test_mods
mov edx, mbflags
jmp error_msg
.test_mods:
mov eax, [ebx+20]
cmp eax, 1
je .clear_data
mov edx, nummods
jmp error_msg
.test_video:
mov al, [ebx+109] ; FrameBuffer type
cmp al, 1
jz .clear_data
.video_error:
mov edx, video_err
jmp error_msg
.clear_data:
mov ecx, 30000
%if SIZE == 4
lea ecx, [ecx*4]
%endif
mov edi, data_start
mov eax, 0
cld
rep stosb
mov ecx, 80*25
mov edi, 0xb8000
mov eax, ' ' | TERM_COLOR<<8
rep stosw
xchg bx,bx
mov ebx, [ebx + 24]
mov eax, [ebx + 4]
mov [src_end], eax
mov ebx, [ebx]
mov ecx, 0
mov eax, data_start
interp_loop:
cmp ebx, [src_end]
jge end
;cmp [ebx], byte 0
;je end
cmp [ebx], byte '>'
je inc_ptr
cmp [ebx], byte '<'
je dec_ptr
cmp [ebx], byte '+'
je inc_val
cmp [ebx], byte '-'
je dec_val
cmp [ebx], byte '.'
je output
cmp [ebx], byte ','
je input
cmp [ebx], byte '['
je while_start
cmp [ebx], byte ']'
je while_end
continue:
inc ebx
jmp interp_loop
end:
xchg bx,bx
cli
hlt
jmp end
error_msg:
mov ecx, 80*25
mov edi, 0xb8000
mov eax, ' ' | TERM_COLOR<<8
rep stosw
mov edi, 0xb8000
.loop:
mov bl, [edx],
test bl, bl
jz end
mov bl, [edx]
mov [edi], bl
inc edx
add edi, 2
jmp .loop
inc_ptr:
%if OPTIMIZE == 1
xor edi, edi
.loop:
inc ebx
inc edi
cmp [ebx], byte '>'
je .loop
%if SIZE != 1
lea edi, [edi*SIZE]
%endif
add eax, edi
jmp interp_loop
%else
%if SIZE == 1
inc eax
%else
add eax, SIZE
%endif
jmp continue
%endif
dec_ptr:
%if OPTIMIZE == 1
xor edi, edi
.loop:
inc ebx
inc edi
cmp [ebx], byte '<'
je .loop
%if SIZE != 1
lea edi, [edi*SIZE]
%endif
sub eax, edi
jmp interp_loop
%else
%if SIZE == 1
dec eax
%else
sub eax, SIZE
%endif
jmp continue
%endif
inc_val:
%if OPTIMIZE == 1
xor edi, edi
.loop:
inc ebx
inc edi
cmp [ebx], byte '+'
je .loop
%if SIZE == 1
and di, 0xff
add word [eax], di
%elif SIZE == 4
add dword [eax], edi
%endif
jmp interp_loop
%else
%if SIZE == 1
inc byte [eax]
%elif SIZE == 4
inc dword [eax]
%endif
jmp continue
%endif
dec_val:
%if OPTIMIZE == 1
xor edi, edi
.loop:
inc ebx
inc edi
cmp [ebx], byte '-'
je .loop
%if SIZE == 1
and di, 0xff
sub word [eax], di
%elif SIZE == 4
sub dword [eax], edi
%endif
jmp interp_loop
%else
%if SIZE == 1
dec byte [eax]
%elif SIZE == 4
dec dword [eax]
%endif
jmp continue
%endif
output:
;xchg bx,bx
mov dl, [eax]
cmp dl, 0xa
je .nl
%if TRUNCATE == 1
cmp cl, TERM_WIDTH
jge continue ; don't bother printing beyond screen boundary
%else
cmp cl, TERM_WIDTH
jl .end_wrap
xor cl, cl
inc ch
cmp ch, TERM_HEIGHT
jge end ; off the screen, nothing else would matter
.end_wrap:
%endif
mov edi, eax
mov esi, ebx
xor eax, eax
mov al, ch
mov ebx, TERM_WIDTH
mul bl
xor ebx, ebx
mov bl, cl
add eax, ebx
and dl, 0x7F
mov [eax*2 + 0xB8000], dl
mov eax, edi
mov ebx, esi
inc cl
test cl,cl
jnz continue
.nl:
xor cl, cl
inc ch
cmp ch, TERM_HEIGHT
jge end ; off the screen, nothing else would matter
jmp continue
input:
mov [eax], byte 0
jmp continue
while_start:
cmp word [ebx+1], '-]'
jne .not_clear
%if SIZE == 1
mov byte [eax], 0
%elif SIZE == 4
mov dword [eax], 0
%endif
jmp continue
.not_clear:
%if SIZE == 1
mov dl, byte [eax]
test dl, dl
%elif SIZE == 4
mov edx, dword [eax]
test edx, edx
%endif
jnz continue
mov edx, 1
.loop:
inc ebx
cmp [ebx], byte ']'
jne .next
dec edx
test edx, edx
jz continue
.next:
cmp [ebx], byte '['
jne .loop
inc edx
jmp .loop
while_end:
%if SIZE == 1
mov dl, byte [eax]
test dl, dl
%elif SIZE == 4
mov edx, dword [eax]
test edx, edx
%endif
jz continue
mov edx, 1
.loop:
dec ebx
cmp [ebx], byte '['
jne .next
dec edx
test edx, edx
jz continue
.next:
cmp [ebx], byte ']'
jne .loop
inc edx
jmp .loop
section .data:
mberr: db 'Error: Not Multiboot', 0
mbflags: db 'Error: Missing required Multiboot flags', 0
nummods: db 'Error: Incorrect number of modules', 0
src_end: dd 0
section .bss
data_start: resb 30000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment