%macro jzfar 1 jnz %%skip jmp %1 %%skip: %endmacro [global _writeCursorPosition] [global _getCursorPosition] [global _putc] [global _printf] [global _console_scroll] [global _console_cls] [global _putHex] [global _putDec] [global _putDecu] ; ;void writeCursorPosition(word pos) ; _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 ; ;int 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 = in format string mov esi, ebp add esi, 12 ;esi = to next variable arg xor ecx, ecx ;ecx used if we encounter a '%' printf_loop: mov al, [ebx] inc ebx cmp al, 0 jzfar printf_done cmp al, '%' jzfar 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, 'u' jz printf_decimalu cmp al, 'x' jz printf_hex cmp al, '%' jz printf_ppercent cmp al, 's' jz printf_string cmp al, 'c' jz printf_char jmp printf_special_done printf_decimal: mov eax, [esi] push eax call _putDec add esp, 4 jmp printf_special_done printf_decimalu: mov eax, [esi] push eax call _putDecu 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_string: mov eax, [esi] push eax call _puts add esp, 4 jmp printf_special_done printf_char: mov eax, [esi] 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 ; ;int 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 ; ;int puts(char *str) ; _puts: push ebp mov ebp, esp push esi push eax mov esi, [ebp+8] ;esi = to string puts_loop: lodsb cmp al, 0 jz puts_done push eax call _putc add esp, 4 jmp puts_loop puts_done: pop eax pop esi pop ebp ret _putDecu: push ebp mov ebp, esp sub esp, 24 mov DWORD [ebp-4], 1 mov BYTE [ebp-5], 0 L2: mov edx, DWORD [ebp+8] mov eax, -858993459 mul edx mov eax, edx shr eax, 3 cmp eax, DWORD [ebp-4] jae L4 jmp L3 L4: mov eax, DWORD [ebp-4] mov edx, eax sal edx, 2 add edx, eax lea eax, [edx+edx] mov DWORD [ebp-4], eax jmp L2 L3: nop L5: cmp DWORD [ebp-4], 1 ja L7 jmp L6 L7: mov edx, DWORD [ebp+8] mov eax, edx mov edx, 0 div DWORD [ebp-4] mov DWORD [ebp-12], eax mov al, BYTE [ebp-12] mov BYTE [ebp-5], al mov eax, 0 mov al, BYTE [ebp-5] imul eax, DWORD [ebp-4] sub DWORD [ebp+8], eax mov edx, DWORD [ebp-4] mov eax, -858993459 mul edx mov eax, edx shr eax, 3 mov DWORD [ebp-4], eax lea eax, [ebp-5] add BYTE [eax], 48 sub esp, 12 mov eax, 0 mov al, BYTE [ebp-5] push eax call _putc add esp, 16 jmp L5 L6: sub esp, 12 mov al, BYTE [ebp+8] add eax, 48 and eax, 255 push eax call _putc add esp, 16 leave ret _putDec: push ebp mov ebp, esp sub esp, 24 cmp DWORD [ebp+8], 0 jns L9 sub esp, 12 push 45 call _putc add esp, 16 neg DWORD [ebp+8] L9: mov DWORD [ebp-4], 1 mov BYTE [ebp-5], 0 L10: mov eax, DWORD [ebp+8] cmp eax, DWORD [ebp-4] jae L12 jmp L11 L12: mov eax, DWORD [ebp-4] mov edx, eax sal edx, 2 add edx, eax lea eax, [edx+edx] mov DWORD [ebp-4], eax jmp L10 L11: mov edx, DWORD [ebp-4] mov eax, -858993459 mul edx mov eax, edx shr eax, 3 mov DWORD [ebp-4], eax L13: cmp DWORD [ebp-4], 1 ja L15 jmp L14 L15: mov edx, DWORD [ebp+8] mov eax, edx mov edx, 0 div DWORD [ebp-4] mov DWORD [ebp-12], eax mov al, BYTE [ebp-12] mov BYTE [ebp-5], al mov eax, 0 mov al, BYTE [ebp-5] imul eax, DWORD [ebp-4] sub DWORD [ebp+8], eax mov edx, DWORD [ebp-4] mov eax, -858993459 mul edx mov eax, edx shr eax, 3 mov DWORD [ebp-4], eax lea eax, [ebp-5] add BYTE [eax], 48 sub esp, 12 mov eax, 0 mov al, BYTE [ebp-5] push eax call _putc add esp, 16 jmp L13 L14: sub esp, 12 mov al, BYTE [ebp+8] add eax, 48 and eax, 255 push eax call _putc add esp, 16 leave ret