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 ; 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