hos/io.asm

333 lines
4.6 KiB
NASM

;void writeCursorPosition(dword pos);
;dword getCursorPosition();
[global _writeCursorPosition]
[global _getCursorPosition]
[global _putc]
[global _printf]
[global _console_scroll]
[global _console_cls]
[global _putHex]
[global _putDec]
;
;void writeCursorPosition(int position)
;
_writeCursorPosition:
push ebp
mov ebp, esp
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop ebp
ret
;
;word getCursorPosition()
;
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;void putc(int chr)
;
_putc:
push ebp
mov ebp, esp
push ebx
push ecx
push edx
call _getCursorPosition
mov ebx, eax
mov ecx, ebx
mov eax, [ebp+8] ;al=character
cmp al, 10 ;newline
jz putc_newline
cmp al, 9 ;tab
jz putc_tab
shl ebx, 1
add ebx, 0xb8000
mov ah, 0x07
mov [ebx], ax
mov eax, ecx
inc eax
cmp eax, 2000
jnz putc_writeit2
call _console_scroll
mov eax, 2000-80
putc_writeit2:
push eax
call _writeCursorPosition
add esp, 4
jmp putc_done
putc_newline:
mov eax, ebx ;eax = cursor position
mov ebx, 80
xor edx, edx
div bx ;ax=dx:ax/bx, dx=remainder
mov bx, 80
sub bx, dx
mov eax, ecx
add eax, ebx ;eax = new cursor position
cmp eax, 2000
jnz putc_newline_writeit2
call _console_scroll
mov eax, 2000-80 ;beginning of last row
putc_newline_writeit2:
push eax
call _writeCursorPosition
add esp, 4
jmp putc_done
putc_tab:
mov eax, ebx ;eax = cursor position
mov ebx, 8
div bl ;al=ax/bl, ah=remainder
xor edx, edx
mov dl, ah
mov bx, 8
sub bx, dx
mov eax, ecx
add eax, ebx ;eax = new cursor position
cmp eax, 2000
jnz putc_tab_writeit2
call _console_scroll
mov eax, 2000-80 ;beginning of last row
putc_tab_writeit2:
push eax
call _writeCursorPosition
add esp, 4
putc_done:
pop edx
pop ecx
pop ebx
pop ebp
ret
;
;void printf(char *fmt, ... )
;
_printf:
push ebp
mov ebp, esp
pusha
mov ebx, [ebp+8] ;ebx = ptr in format string
mov esi, ebp
add esi, 12 ;esi = ptr to next variable arg
xor ecx, ecx ;ecx used if we encounter a '%'
printf_loop:
mov al, [ebx]
inc ebx
cmp al, 0
jz printf_done
cmp al, '%'
jz printf_percent
cmp ecx, 1
jz printf_special
push eax
call _putc
add esp, 4
jmp printf_loop
printf_special:
xor ecx, ecx
cmp al, 'd'
jz printf_decimal
cmp al, 'x'
jz printf_hex
cmp al, '%'
jz printf_ppercent
jmp printf_special_done
printf_decimal:
mov eax, [esi]
push eax
call _putDec
add esp, 4
jmp printf_special_done
printf_hex:
mov eax, [esi]
push eax
call _putHex
add esp, 4
jmp printf_special_done
printf_ppercent:
push eax
call _putc
add esp, 4
jmp printf_special_done
printf_special_done
add esi, 4 ;point to next extra argument
jmp printf_loop
printf_percent:
mov ecx, 1
jmp printf_loop
printf_done:
popa
pop ebp
ret
;
;void console_scroll()
;
_console_scroll:
pusha
mov esi, 0xb8000+160
mov edi, 0xb8000
mov ecx, 960 ;(2000-80)/2
console_scroll_loop:
lodsd
stosd
loop console_scroll_loop
mov ax, 0x0720
mov ecx, 80
console_scroll_loop2:
stosw
loop console_scroll_loop2
popa
ret
;
;void console_cls()
;
_console_cls:
pusha
mov edi, 0xb8000
mov ax, 0x0720
mov ecx, 2000
console_cls_loop:
stosw
loop console_cls_loop
push dword 0
call _writeCursorPosition
add esp, 4
popa
ret
;
;void putHex(dword number)
;
_putHex:
push ebp
mov ebp, esp
pusha
mov eax, [ebp+8] ;eax = number to print
xor ebx, ebx ;we have not printed a character yet
mov ecx, 8 ;counter for number of characters
putHex_loop:
push eax
push ecx
dec ecx
shl ecx, 2 ;edx=counter*4 (amount to shift by)
shr eax, cl
and eax, 0x0F
cmp cl, 0
jz putHex_notzero ;if number is 0
cmp al, 0
jnz putHex_notzero
cmp bl, 0
jz putHex_loop_end
putHex_notzero:
mov bl, 1
add eax, '0'
cmp eax, '9'
jbe putHex_dontadjust
add eax, 'A'-'9'-1
putHex_dontadjust:
push eax
call _putc
add esp, 4
putHex_loop_end:
pop ecx
pop eax
loop putHex_loop
popa
pop ebp
ret
;
;void putDec(dword number)
;
_putDec:
ret