Created
February 6, 2018 14:31
-
-
Save boomshroom/a8ae9de1e406d19e5a5d29efef08b46a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
; 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