diff options
Diffstat (limited to 'kernel.asm')
-rw-r--r-- | kernel.asm | 305 |
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: + |