|
|
|
|
@ -216,25 +216,52 @@ main:
|
|
|
|
|
mov ax, msg_boot1_loaded
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
mov ecx, 0xa1b2c3d4
|
|
|
|
|
call vga_dump_reg
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
call test_a20
|
|
|
|
|
test ax, ax
|
|
|
|
|
jnz .a20_enabled
|
|
|
|
|
|
|
|
|
|
mov ax, msg_a20_disabled
|
|
|
|
|
mov cx, MSG_A20_DISABLED_LEN
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
; TODO: enable a20
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
.a20_enabled
|
|
|
|
|
.a20_enabled:
|
|
|
|
|
mov ax, msg_a20_enabled
|
|
|
|
|
mov cx, MSG_A20_ENABLED_LEN
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Wrapper function around panic_fancy which provides default arguments.
|
|
|
|
|
; Arguments: none
|
|
|
|
|
; Does not return
|
|
|
|
|
panic_default:
|
|
|
|
|
push bp
|
|
|
|
|
mov bp, sp
|
|
|
|
|
push word 0
|
|
|
|
|
push word 0
|
|
|
|
|
; Spoof return address
|
|
|
|
|
push dword [bp]
|
|
|
|
|
jmp panic_fancy
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Print a panic message then terminate.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - [sp - 2]: pointer to panic message
|
|
|
|
|
; - [sp]: panic message length
|
|
|
|
|
; Does not return
|
|
|
|
|
panic_fancy:
|
|
|
|
|
push bp
|
|
|
|
|
mov bp, sp
|
|
|
|
|
mov word [GLOBALS + VGA_COL], 0x4f00
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Clear the VGA text buffer.
|
|
|
|
|
; Arguments: none
|
|
|
|
|
; Return: none
|
|
|
|
|
@ -311,7 +338,8 @@ vga_scroll:
|
|
|
|
|
; of null-termination so this function only takes one argument, so it's slightly less of a faff to
|
|
|
|
|
; call in most cases.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - ax: pointer to the string to print, null-terminated
|
|
|
|
|
; - es: output string segment
|
|
|
|
|
; - ax: output string offset
|
|
|
|
|
; Return: none
|
|
|
|
|
; Clobber: ax
|
|
|
|
|
vga_println:
|
|
|
|
|
@ -319,7 +347,7 @@ vga_println:
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push dx
|
|
|
|
|
push es
|
|
|
|
|
push fs
|
|
|
|
|
|
|
|
|
|
cmp word [GLOBALS + TEXTBUF_LINE], VGA_HEIGHT
|
|
|
|
|
jb .scroll_done
|
|
|
|
|
@ -335,7 +363,7 @@ vga_println:
|
|
|
|
|
mov di, ax
|
|
|
|
|
|
|
|
|
|
mov ax, 0xb800
|
|
|
|
|
mov es, ax
|
|
|
|
|
mov fs, ax
|
|
|
|
|
mov ah, [GLOBALS + VGA_COL + 1]
|
|
|
|
|
|
|
|
|
|
mov dx, VGA_WIDTH
|
|
|
|
|
@ -344,10 +372,10 @@ vga_println:
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .done
|
|
|
|
|
dec dx
|
|
|
|
|
mov al, [si]
|
|
|
|
|
mov al, es:[si]
|
|
|
|
|
test al, al
|
|
|
|
|
jz .done
|
|
|
|
|
mov es:[di], ax
|
|
|
|
|
mov fs:[di], ax
|
|
|
|
|
add di, 2
|
|
|
|
|
inc si
|
|
|
|
|
dec cx
|
|
|
|
|
@ -356,13 +384,100 @@ vga_println:
|
|
|
|
|
.done:
|
|
|
|
|
inc word [GLOBALS + TEXTBUF_LINE]
|
|
|
|
|
|
|
|
|
|
pop es
|
|
|
|
|
pop fs
|
|
|
|
|
pop dx
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vga_dump_reg:
|
|
|
|
|
fnstart
|
|
|
|
|
sub sp, VGA_WIDTH
|
|
|
|
|
push es
|
|
|
|
|
push bx
|
|
|
|
|
|
|
|
|
|
mov ax, ss
|
|
|
|
|
mov es, ax
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
call dump_reg
|
|
|
|
|
mov bx, ax
|
|
|
|
|
mov byte es:[bx], 0
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
pop bx
|
|
|
|
|
pop es
|
|
|
|
|
add sp, VGA_WIDTH
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Convert the value in ecx to hex and write it to the buffer at es:ax. The buffer should be at
|
|
|
|
|
; least 8 bytes long.
|
|
|
|
|
; - es: output buffer segment
|
|
|
|
|
; - ax: output buffer offset
|
|
|
|
|
; - ecx: value to convert to hex and print
|
|
|
|
|
; Return:
|
|
|
|
|
; - ax: the address one after the last byte that was written
|
|
|
|
|
; Clobber: none
|
|
|
|
|
dump_reg:
|
|
|
|
|
fnstart
|
|
|
|
|
push bx
|
|
|
|
|
push dx
|
|
|
|
|
push ecx
|
|
|
|
|
|
|
|
|
|
mov bx, ax
|
|
|
|
|
mov dx, 4
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .done
|
|
|
|
|
dec dx
|
|
|
|
|
|
|
|
|
|
rol ecx, 8
|
|
|
|
|
|
|
|
|
|
mov al, cl
|
|
|
|
|
shr al, 4
|
|
|
|
|
call nybble_to_hex_char
|
|
|
|
|
mov es:[bx], al
|
|
|
|
|
inc bx
|
|
|
|
|
|
|
|
|
|
mov al, cl
|
|
|
|
|
call nybble_to_hex_char
|
|
|
|
|
mov es:[bx], al
|
|
|
|
|
inc bx
|
|
|
|
|
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
mov ax, bx
|
|
|
|
|
|
|
|
|
|
pop ecx
|
|
|
|
|
pop dx
|
|
|
|
|
pop bx
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Convert nybble to lowercase ascii hex char.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - al: value to convert
|
|
|
|
|
; Return:
|
|
|
|
|
; - al: converted ascii hex value
|
|
|
|
|
; Clobber: none
|
|
|
|
|
nybble_to_hex_char:
|
|
|
|
|
; We don't use the stack, so no need to change bp.
|
|
|
|
|
and al, 0x0f
|
|
|
|
|
cmp al, 9
|
|
|
|
|
jbe .0_to_9
|
|
|
|
|
add al, (0x61 - 0x0a)
|
|
|
|
|
jmp .done
|
|
|
|
|
.0_to_9:
|
|
|
|
|
add al, 0x30
|
|
|
|
|
.done:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enable_a20:
|
|
|
|
|
fnstart
|
|
|
|
|
fnret
|
|
|
|
|
@ -407,7 +522,7 @@ test_a20:
|
|
|
|
|
|
|
|
|
|
msg_boot1_loaded db "boot1 loaded. hello!", 0
|
|
|
|
|
msg_a20_enabled db "a20 enabled", 0
|
|
|
|
|
msg_a20_disabled db "a20 disabled", 0
|
|
|
|
|
msg_a20_disabled db "a20 not enabled", 0
|
|
|
|
|
msg_panic db "panic!", 0
|
|
|
|
|
|
|
|
|
|
boot1_magic dd BOOT1_MAGIC
|
|
|
|
|
|