summaryrefslogtreecommitdiff
path: root/kernel.asm
diff options
context:
space:
mode:
Diffstat (limited to 'kernel.asm')
-rw-r--r--kernel.asm305
1 files changed, 305 insertions, 0 deletions
diff --git a/kernel.asm b/kernel.asm
new file mode 100644
index 0000000..490273c
--- /dev/null
+++ b/kernel.asm
@@ -0,0 +1,305 @@
+section .text
+align 4
+global kmain
+global interrupt_handler
+extern idt_init
+extern pio_read
+extern pio_write
+
+interrupt_handler:
+ mov ebx, [esp + 34]
+ shr ebx, 16
+ cmp ebx, 0x21
+ je .int21
+
+ jmp .end
+
+.int21:
+
+ cmp ah, 0x1
+ je .int21.kprint
+ jmp .end
+
+.int21.kprint:
+ ;sub esp, 4
+ ;mov [esp - 4], bx
+
+ ;shr bx, 8
+ ;push word bx
+
+ ;mov bx, [esp - 4]
+ ;and bx, 0xff
+ ;push bx
+
+ ;call screen_gotoxy
+ ;add esp, 8
+
+ push edx
+ call kprint
+ add esp, 4
+
+.end:
+ ret
+
+cursor_move:
+ push ebp
+ mov ebp, esp
+
+ sub ebp, 4
+ call screen_getxy
+ mov [ebp - 4], eax
+
+ push 0x3D4
+ push 14
+ call pio_write
+
+ mov ebx, [ebp + 4]
+ shr ebx, 8
+ push 0x3D5
+ push word [ebx]
+ call pio_write
+
+ push 0x3D4
+ push 15
+ call pio_write
+
+ mov ebx, [ebp + 4]
+ push 0x3D5
+ push word [ebx]
+ call pio_write
+
+ add ebp, 4
+ leave
+ ret
+
+screen_fill:
+ ; = purpose
+ ; Fills the screen with a character and color
+ ;
+ ; = stack arguments (order of use)
+ ; push ' ' ; character
+ ; push 0x07 ; color attribute
+
+ push ebp
+ mov ebp, esp
+
+ xor eax, eax ; clear eax
+ mov eax, [ebp + 8] ; get character
+ shl eax, 8 ; shift character into MSB
+ or eax, [ebp + 12] ; set color attribute
+
+ mov ecx, CONSOLE_SIZE ; use entire screen
+ mov edi, screen_buffer ; destination = screen_buffer
+ cld ; will increment esi and edi
+ rep stosw ; char+color -> screen_buffer
+
+ mov esp, ebp
+ pop ebp
+
+ ret
+
+screen_refresh:
+ push ebp
+ mov ebp, esp
+ pusha
+
+ mov ecx, CONSOLE_SIZE ; use entire screen
+ mov esi, screen_buffer ; source = screen_buffer
+ mov edi, VIDEO_RAM ; destination = video RAM
+ cld ; will increment esi and edi
+ rep movsw ; char+color -> screen_buffer
+
+ popa
+ mov esp, ebp
+ pop ebp
+ ret
+
+screen_gotoxy:
+ push ebp
+ mov ebp, esp
+ pusha
+
+ ; y * width + x
+ mov ebx, CONSOLE_W * 2
+ mov eax, [ebp + 12]
+ mul ebx
+ add eax, [ebp + 8]
+ mov [screen_pos], eax
+
+ popa
+ leave
+ ret
+
+screen_getxy:
+ push ebp
+ mov ebp, esp
+
+ mov eax, [screen_pos]
+
+ leave
+ ret
+
+screen_updatexy:
+ push ebp
+ mov ebp, esp
+
+ add word [screen_pos], 2
+
+ cmp word [screen_pos], CONSOLE_SIZE
+ call screen_scroll_up
+
+ leave
+ ret
+
+screen_scroll_up:
+ push ebp
+ mov ebp, esp
+
+ nop
+
+ leave
+ ret
+
+screen_scroll_down:
+ push ebp
+ mov ebp, esp
+
+ nop
+
+ leave
+ ret
+
+
+kprint:
+ ; = purpose
+ ; Writes a buffer to the screen
+ ;
+ ; = globals
+ ; kprint_delay: if != 0; echo slowly
+ ;
+ ; = stack arguments (order of use)
+ ; push buffer
+
+ push ebp
+ mov ebp, esp
+
+ xor ebx, ebx
+ xor esi, esi
+ xor edi, edi
+
+ mov esi, [ebp + 8] ; source buffer
+ mov edi, screen_buffer ; output to screen buffer
+ mov ebx, [screen_pos] ; get current screen position
+ add edi, ebx ; move to current screen position
+ mov ecx, 0xff ; delay counter
+
+.write:
+
+ cmp byte [kprint_delay], 0 ; determine if we want a delay
+ je .nodelay ; if kprint_nodelay == 0:
+ ; nodelay()
+ ; else:
+ ; delay()
+
+.delay:
+ dec ecx ; while ecx != 0: ecx--
+ call screen_refresh
+ jne .delay
+
+.nodelay:
+ mov ebx, [esi] ; get value from source buffer
+ mov [edi], bl ; write value to screen buffer
+ inc esi ; next char in source buffer
+ add edi, 2 ; skip over screen attribute byte
+ call screen_updatexy ; update screen_pos
+
+ cmp bl, 0 ; if ch != 0: write
+ jne .write
+
+ call screen_refresh ; dump screen buffer to video ram
+
+ leave
+ ret
+
+kputc:
+ push ebp
+ mov ebp, esp
+
+ mov esi, [screen_pos]
+ mov edi, screen_buffer
+ add edi, esi
+
+ mov [edi], dl
+ call screen_updatexy
+ call screen_refresh
+
+ leave
+ ret
+
+kprintnl:
+ push ebp
+ mov ebp, esp
+
+ nop
+
+ leave
+ ret
+
+kmain:
+ push ebp
+ mov ebp, esp
+
+ mov byte [screen_pos], 2 ; Initialize screen position
+ ;call cursor_move
+
+ call idt_init
+
+ ; Fill screen with
+ push ' ' ; spaces &&
+ push 0x07 ; white forground on blue background
+ call screen_fill ; fill the screen buffer
+ call screen_refresh ; dump screen buffer to video ram
+
+ ;push 12
+ ;push 30
+ ;call screen_gotoxy
+
+ ;mov byte [kprint_delay], 1 ; tell kprint to delay writes
+ push message ; push message address as argument
+ call kprint ; print message
+
+ call kprintnl
+
+ mov dl, 'A'
+ call kputc
+
+ mov word [VIDEO_RAM + CONSOLE_SIZE - 6], \
+ 0x4F << 8 | 'I' ; END OF MAIN MARKER
+ ;mov ah, 1
+ ;mov bh, 2
+ ;mov bl, 2
+ ;mov edx, message2
+ ;int 21h ; here goes nothing
+
+ mov word [VIDEO_RAM + CONSOLE_SIZE - 6], \
+ 0x2F << 8 | 'I' ; END OF MAIN MARKER
+
+ mov word [VIDEO_RAM + CONSOLE_SIZE - 4], \
+ 0x2F << 8 | 'K' ; END OF MAIN MARKER
+
+ mov esp, ebp
+ pop ebp
+ ret
+
+section .data
+%include 'constants.asm'
+
+message: db 'Kernel programming is fun!', 0
+message2: db 'This is a test.', 0
+
+section .bss
+kprint_delay: resb 1
+screen_pos: resd 1
+screen_buffer: resb CONSOLE_SIZE
+screen_buffer_end:
+