VIDEO_MEMORY equ 0xb8000 VIDEO_COLS equ 80 VIDEO_ROWS equ 25 CURSOR_X: dw 0 CURSOR_Y: dw 0 pm_print_newline: push eax mov [CURSOR_X], word 0 mov ax, [CURSOR_Y] inc ax mov [CURSOR_Y], ax pop eax call update_vga_cursor ret ; IN si pm_print_string: push eax _loop_pm_print_string: lodsb cmp al, 0 je pm_print_string_fini call pm_print_char jmp _loop_pm_print_string pm_print_string_fini: pop eax ret ; IN al: character to print pm_print_char: push edx push ecx push ebx push eax mov ax, [CURSOR_Y] mov cl, VIDEO_COLS mul cl mov bx, [CURSOR_X] add ax, bx shl ax, 1 mov edx, VIDEO_MEMORY add dx, ax pop eax mov ah, 0x07 mov [edx], ax pop ebx pop ecx pop edx call inc_cursor ret ; IN dx: hex value to print pm_print_hex: push bx push si mov si, HEX_TEMPLATE mov bx, dx shr bx, 12 mov bx, [HEXABET+bx] mov [HEX_TEMPLATE+2], bl mov bx, dx and bx, 0x0FFF shr bx, 8 mov bx, [HEXABET+bx] mov [HEX_TEMPLATE+3], bl mov bx, dx and bx, 0x00FF shr bx, 4 mov bx, [HEXABET+bx] mov [HEX_TEMPLATE+4], bl mov bx, dx and bx, 0x000F mov bx, [HEXABET+bx] mov [HEX_TEMPLATE+5], bl call pm_print_string pop si pop bx ret inc_cursor: push eax mov ax, [CURSOR_X] inc ax mov [CURSOR_X], ax cmp ax, VIDEO_COLS jl inc_cursor_fini mov [CURSOR_X], word 1 mov ax, [CURSOR_Y] inc ax mov [CURSOR_Y], ax cmp ax, VIDEO_ROWS jl inc_cursor_fini ; TODO: scoll one line, for now restart on top mov [CURSOR_Y], word 0 inc_cursor_fini: call update_vga_cursor pop eax ret ; update the VGA cursor on screen update_vga_cursor: push eax push ebx push ecx push edx mov al, [CURSOR_Y] mov cl, VIDEO_COLS mul cl mov bx, ax movzx ax, [CURSOR_X] add bx, ax mov cx, bx ;cursor LOW port to vga INDEX register mov al, 0fh ;Cursor Location Low Register -- mov dx, 3d4h ;VGA port 3D4h out dx, al mov ax, cx ;restore 'postion' back to AX mov dx, 3d5h ;VGA port 3D5h out dx, al ;send to VGA hardware ;cursor HIGH port to vga INDEX register mov al, 0eh mov dx, 3d4h ;VGA port 3D4h out dx, al mov ax, cx ;restore 'position' back to AX shr ax, 8 ;get high byte in 'position' mov dx, 3d5h ;VGA port 3D5h out dx, al ;send to VGA hardware pop edx pop ecx pop ebx pop eax ret ; read cursor from hardware read_hardware_vga_cursor: push eax push ebx push ecx push edx xor eax, eax xor ebx, ebx mov al, 0eh mov dx, 3d4h out dx, al mov dx, 3d5h in al, dx mov bh, al mov al, 0fh mov dx, 3d4h out dx, al mov dx, 3d5h in al, dx mov bl, al mov ax, bx mov edx, 0 mov cx, VIDEO_COLS div cx mov [CURSOR_X], dx mov [CURSOR_Y], ax pop edx pop ecx pop ebx pop eax ret ; check whether the end of the loaded image contains in fact the magic ; string (avoid truncation of image) check_magic: push ebx push ecx push edx push esi push edi mov eax, NOF_LOAD_SECTORS ; number of 512-byte sectors shl eax, 9 ; 512 bytes per sector mov edx, 0x7e00 ; offset of stage 2 add edx, eax sub edx, MAGICLEN ; subtract the length of the magic string mov esi, edx ; now use edx as first string address to compare to mov edi, COMPARE_MAGIC ; position of second string mov ecx, MAGICLEN ; length of the magic string repe cmpsb jne MAGIC_MISMATCH jmp MAGIC_OK MAGIC_MISMATCH: mov si, MAGIC_OK_MSG call pm_print_string call pm_print_newline xor eax, eax jmp MAGIC_END MAGIC_OK: mov si, MAGIC_NOT_OK_MSG call pm_print_string call pm_print_newline xor eax, eax mov eax, 1 MAGIC_END: pop edi pop esi pop edx pop ecx pop ebx ret COMPARE_MAGIC: db "ABAOSMAGIC", 0 MAGICLEN equ $ - COMPARE_MAGIC MAGIC_NOT_OK_MSG: db "Magic signature found", 0 MAGIC_OK_MSG: db "Magic signature not found!", 0