|
|
|
|
@ -216,9 +216,9 @@ main:
|
|
|
|
|
mov ax, msg_boot1_loaded
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
mov ecx, 0xa1b2c3d4
|
|
|
|
|
call vga_dump_reg
|
|
|
|
|
hlt
|
|
|
|
|
mov eax, 0xa1b2c3d4
|
|
|
|
|
mov ebx, 0x12345678
|
|
|
|
|
call panic_fancy
|
|
|
|
|
|
|
|
|
|
call test_a20
|
|
|
|
|
test ax, ax
|
|
|
|
|
@ -252,14 +252,50 @@ panic_default:
|
|
|
|
|
|
|
|
|
|
; Print a panic message then terminate.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - [sp - 2]: pointer to panic message
|
|
|
|
|
; - [sp]: panic message length
|
|
|
|
|
; - [sp - 2]: panic message segment
|
|
|
|
|
; - [sp]: panic message offset
|
|
|
|
|
; Does not return
|
|
|
|
|
panic_fancy:
|
|
|
|
|
push bp
|
|
|
|
|
mov bp, sp
|
|
|
|
|
|
|
|
|
|
sub sp, 16 ; Buffer: bp - 16
|
|
|
|
|
|
|
|
|
|
push eax ; bp - 20
|
|
|
|
|
push ebx ; bp - 24
|
|
|
|
|
push ecx ; bp - 28
|
|
|
|
|
push edx ; bp - 32
|
|
|
|
|
push esi ; bp - 36
|
|
|
|
|
push edi ; bp - 40
|
|
|
|
|
|
|
|
|
|
mov word [GLOBALS + VGA_COL], 0x4f00
|
|
|
|
|
call vga_clear
|
|
|
|
|
|
|
|
|
|
mov ax, ss
|
|
|
|
|
mov es, ax
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - 16]
|
|
|
|
|
push ax
|
|
|
|
|
mov ecx, [bp - 20]
|
|
|
|
|
call dump_reg
|
|
|
|
|
pop cx
|
|
|
|
|
xor ax, ax
|
|
|
|
|
mov dx, 8
|
|
|
|
|
call vga_print_raw
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - 16]
|
|
|
|
|
push ax
|
|
|
|
|
mov ecx, [bp - 24]
|
|
|
|
|
call dump_reg
|
|
|
|
|
pop cx
|
|
|
|
|
mov ax, VGA_WIDTH
|
|
|
|
|
mov dx, 8
|
|
|
|
|
call vga_print_raw
|
|
|
|
|
|
|
|
|
|
.halt:
|
|
|
|
|
hlt
|
|
|
|
|
; Handle non-maskable interrupts
|
|
|
|
|
jmp .halt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Clear the VGA text buffer.
|
|
|
|
|
@ -334,40 +370,42 @@ vga_scroll:
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Write one line to the VGA text buffer. The string should be null-terminated; we embrace the evil
|
|
|
|
|
; of null-termination so this function only takes one argument, so it's slightly less of a faff to
|
|
|
|
|
; call in most cases.
|
|
|
|
|
; Write a null-terminated string to the given position in the VGA text buffer.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - es: output string segment
|
|
|
|
|
; - ax: output string offset
|
|
|
|
|
; Return: none
|
|
|
|
|
; Clobber: ax
|
|
|
|
|
vga_println:
|
|
|
|
|
; - ax: vga buffer index
|
|
|
|
|
; - cx: output string offset
|
|
|
|
|
; - dx: maximum length of string to print
|
|
|
|
|
; Return:
|
|
|
|
|
; - ax: vga buffer index after last character written
|
|
|
|
|
; Clobber: none
|
|
|
|
|
vga_print_raw:
|
|
|
|
|
fnstart
|
|
|
|
|
push fs
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
push fs
|
|
|
|
|
|
|
|
|
|
cmp word [GLOBALS + TEXTBUF_LINE], VGA_HEIGHT
|
|
|
|
|
jb .scroll_done
|
|
|
|
|
call vga_scroll
|
|
|
|
|
.scroll_done:
|
|
|
|
|
|
|
|
|
|
mov si, ax
|
|
|
|
|
|
|
|
|
|
xor dx, dx
|
|
|
|
|
mov ax, [GLOBALS + TEXTBUF_LINE]
|
|
|
|
|
mov di, VGA_WIDTH * 2
|
|
|
|
|
mul di
|
|
|
|
|
mov di, ax
|
|
|
|
|
|
|
|
|
|
mov si, cx
|
|
|
|
|
xchg ax, cx
|
|
|
|
|
|
|
|
|
|
; Find the distance between the starting index and the end of the buffer.
|
|
|
|
|
mov ax, (VGA_WIDTH * VGA_HEIGHT)
|
|
|
|
|
sub ax, cx
|
|
|
|
|
; If the starting index is past the end of the buffer, return early.
|
|
|
|
|
jc .done
|
|
|
|
|
; Clamp the maximum length to the distance between the starting index and the end of the buffer.
|
|
|
|
|
cmp ax, dx
|
|
|
|
|
cmovb dx, ax
|
|
|
|
|
|
|
|
|
|
mov di, cx
|
|
|
|
|
shl di, 1
|
|
|
|
|
|
|
|
|
|
mov ax, 0xb800
|
|
|
|
|
mov fs, ax
|
|
|
|
|
mov ah, [GLOBALS + VGA_COL + 1]
|
|
|
|
|
|
|
|
|
|
mov dx, VGA_WIDTH
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .done
|
|
|
|
|
@ -378,38 +416,58 @@ vga_println:
|
|
|
|
|
mov fs:[di], ax
|
|
|
|
|
add di, 2
|
|
|
|
|
inc si
|
|
|
|
|
dec cx
|
|
|
|
|
inc cx
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
inc word [GLOBALS + TEXTBUF_LINE]
|
|
|
|
|
|
|
|
|
|
pop fs
|
|
|
|
|
xchg ax, cx
|
|
|
|
|
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop fs
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vga_dump_reg:
|
|
|
|
|
; Write one line to the VGA text buffer. The string should be null-terminated; we embrace the evil
|
|
|
|
|
; of null-termination so this function only takes one argument, so it's slightly less of a faff to
|
|
|
|
|
; call in most cases.
|
|
|
|
|
; Arguments:
|
|
|
|
|
; - es: output string segment
|
|
|
|
|
; - ax: output string offset
|
|
|
|
|
; Return: none
|
|
|
|
|
; Clobber: none
|
|
|
|
|
vga_println:
|
|
|
|
|
fnstart
|
|
|
|
|
sub sp, VGA_WIDTH
|
|
|
|
|
push es
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
|
|
|
|
|
cmp word [GLOBALS + TEXTBUF_LINE], VGA_HEIGHT
|
|
|
|
|
jb .scroll_done
|
|
|
|
|
call vga_scroll
|
|
|
|
|
.scroll_done:
|
|
|
|
|
|
|
|
|
|
mov ax, ss
|
|
|
|
|
mov es, ax
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
call dump_reg
|
|
|
|
|
mov bx, ax
|
|
|
|
|
mov byte es:[bx], 0
|
|
|
|
|
|
|
|
|
|
xor dx, dx
|
|
|
|
|
mov ax, [GLOBALS + TEXTBUF_LINE]
|
|
|
|
|
mov cx, VGA_WIDTH
|
|
|
|
|
mul cx
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
call vga_println
|
|
|
|
|
mov dx, VGA_WIDTH
|
|
|
|
|
mov cx, bx
|
|
|
|
|
|
|
|
|
|
call vga_print_raw
|
|
|
|
|
|
|
|
|
|
inc word [GLOBALS + TEXTBUF_LINE]
|
|
|
|
|
|
|
|
|
|
pop bx
|
|
|
|
|
pop es
|
|
|
|
|
add sp, VGA_WIDTH
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|