vga print helpers
This commit is contained in:
1 parent
592826e8cd
commit
bd3063a80d
2 files changed
+229
-49
No files matched your search
@@ -37,17 +37,17 @@ self_load:
|
||||
|
||||
; Panic if the partition / boot1 starting LBA overflows 16 bits.
|
||||
or ebx, ebx
|
||||
jnz panic
|
||||
jnz panic_simple
|
||||
ror eax, 16
|
||||
or ax, ax
|
||||
jnz panic
|
||||
jnz panic_simple
|
||||
ror eax, 16
|
||||
|
||||
; Calculate the boot1 end LBA and panic if it overflows 16 bits.
|
||||
; n.b. ebx is zero before this so both bx and ebx can be used as the boot1 end LBA.
|
||||
mov bx, ax
|
||||
add bx, BOOT1_TOTAL_SECTORS
|
||||
jc panic
|
||||
jc panic_simple
|
||||
|
||||
; Panic if the boot1 end LBA is after the partition end LBA.
|
||||
; If the upper 32 bits of the partition end LBA are nonzero, then it must be greater than our
|
||||
@@ -56,7 +56,7 @@ self_load:
|
||||
jnz .end_lba_ok
|
||||
; Compare the boot1 end LBA to the lower 32 bits of the partition end LBA.
|
||||
cmp ebx, ecx
|
||||
ja panic
|
||||
ja panic_simple
|
||||
|
||||
.end_lba_ok:
|
||||
|
||||
@@ -74,7 +74,7 @@ self_load:
|
||||
|
||||
mov ecx, ebx
|
||||
call read_sector
|
||||
jc panic
|
||||
jc panic_simple
|
||||
|
||||
add ebx, 512
|
||||
inc word [bp - 0x02]
|
||||
@@ -82,32 +82,15 @@ self_load:
|
||||
|
||||
.self_load_done:
|
||||
|
||||
mov ebx, cafebabe
|
||||
; Check the magic bytes at the end of boot1.
|
||||
push es
|
||||
mov ebx, boot1_magic
|
||||
call addr32_to_addr16
|
||||
mov eax, es:[ebx]
|
||||
hlt
|
||||
cmp dword es:[bx], BOOT1_MAGIC
|
||||
pop es
|
||||
jne panic_simple
|
||||
|
||||
call test_a20
|
||||
add al, 0x30
|
||||
mov byte fs:[0x0000], al
|
||||
hlt
|
||||
|
||||
pr_womble:
|
||||
; Reveal the true nature of jen
|
||||
xor bx, bx
|
||||
.loop:
|
||||
cmp bx, WOMBLE_LEN
|
||||
jae .done
|
||||
lea si, [womble + bx]
|
||||
mov dh, [si]
|
||||
mov di, bx
|
||||
shl di, 1
|
||||
mov byte fs:[di], dh
|
||||
mov byte fs:[di + 0x01], 0x1f
|
||||
inc bx
|
||||
jmp .loop
|
||||
.done:
|
||||
hlt
|
||||
jmp main
|
||||
|
||||
|
||||
; Converts a 32-bit address to a 16-bit sector and offset.
|
||||
@@ -119,8 +102,7 @@ pr_womble:
|
||||
; - cf: unset on success, set on failure
|
||||
; Clobber: none
|
||||
addr32_to_addr16:
|
||||
push bp
|
||||
mov bp, sp
|
||||
fnstart
|
||||
push es
|
||||
push eax
|
||||
|
||||
@@ -152,9 +134,8 @@ addr32_to_addr16:
|
||||
.fail:
|
||||
pop eax
|
||||
pop es
|
||||
pop bp
|
||||
stc
|
||||
ret
|
||||
fnret
|
||||
|
||||
|
||||
; Reads a single sector at the given LBA into memory.
|
||||
@@ -170,8 +151,7 @@ read_sector:
|
||||
; head = temp % n_heads
|
||||
; cylinder = temp / n_heads
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
fnstart
|
||||
push es
|
||||
push ebx
|
||||
|
||||
@@ -203,8 +183,14 @@ read_sector:
|
||||
.return:
|
||||
pop ebx
|
||||
pop es
|
||||
pop bp
|
||||
ret
|
||||
fnret
|
||||
|
||||
|
||||
panic_simple:
|
||||
mov ax, 0x0003
|
||||
int 0x10
|
||||
mov word fs:[0x0000], 0x4f21
|
||||
hlt
|
||||
|
||||
|
||||
%if ($ - $$) > 512
|
||||
@@ -212,7 +198,183 @@ read_sector:
|
||||
%endif
|
||||
|
||||
|
||||
main:
|
||||
; Set VGA mode
|
||||
; https://mendelson.org/wpdos/videomodes.txt
|
||||
mov ax, 0x0003
|
||||
int 0x10
|
||||
|
||||
; Disable the cursor (don't want to look at the blink blink blink)
|
||||
mov ax, 0x0100
|
||||
mov cx, 0x3f00
|
||||
int 0x10
|
||||
|
||||
mov word [GLOBALS + VGA_COL], 0x1f00
|
||||
|
||||
call vga_clear
|
||||
|
||||
mov ax, msg_boot1_loaded
|
||||
mov cx, MSG_BOOT1_LOADED_LEN
|
||||
call vga_println
|
||||
|
||||
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
|
||||
mov ax, msg_a20_enabled
|
||||
mov cx, MSG_A20_ENABLED_LEN
|
||||
call vga_println
|
||||
|
||||
hlt
|
||||
|
||||
|
||||
; Clear the VGA text buffer.
|
||||
; Arguments: none
|
||||
; Return: none
|
||||
; Clobber: none
|
||||
vga_clear:
|
||||
fnstart
|
||||
push di
|
||||
push es
|
||||
push ax
|
||||
push cx
|
||||
|
||||
mov ax, 0xb800
|
||||
mov es, ax
|
||||
mov ax, [GLOBALS + VGA_COL]
|
||||
mov cx, VGA_WIDTH * VGA_HEIGHT
|
||||
xor di, di
|
||||
rep stosw
|
||||
mov word [GLOBALS + TEXTBUF_LINE], 0
|
||||
|
||||
pop cx
|
||||
pop ax
|
||||
pop es
|
||||
pop di
|
||||
fnret
|
||||
|
||||
|
||||
; Scroll the VGA text buffer up one line.
|
||||
; Arguments: none
|
||||
; Return: none
|
||||
; Clobber: none
|
||||
vga_scroll:
|
||||
fnstart
|
||||
push si
|
||||
push di
|
||||
push ax
|
||||
push cx
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax, 0xb800
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
||||
; Copy everything up one line.
|
||||
mov cx, VGA_WIDTH * (VGA_HEIGHT - 1)
|
||||
mov si, VGA_WIDTH * 2
|
||||
mov di, 0
|
||||
rep movsw
|
||||
|
||||
; Clear the last line.
|
||||
mov ax, [GLOBALS + VGA_COL]
|
||||
mov cx, VGA_WIDTH
|
||||
mov di, VGA_WIDTH * (VGA_HEIGHT - 1) * 2
|
||||
rep stosw
|
||||
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
; Decrement the current textbuf line if it's greater than 0.
|
||||
mov cx, [GLOBALS + TEXTBUF_LINE]
|
||||
xor ax, ax
|
||||
sub cx, 1
|
||||
cmovae ax, cx
|
||||
mov [GLOBALS + TEXTBUF_LINE], ax
|
||||
|
||||
pop cx
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
fnret
|
||||
|
||||
|
||||
; Write one line to the VGA text buffer.
|
||||
; Arguments:
|
||||
; - ax: pointer to the string to print
|
||||
; - cx: string length
|
||||
; Return: none
|
||||
; Clobber: ax, cx
|
||||
vga_println:
|
||||
fnstart
|
||||
push si
|
||||
push di
|
||||
push dx
|
||||
push es
|
||||
|
||||
cmp word [GLOBALS + TEXTBUF_LINE], VGA_HEIGHT
|
||||
jb .scroll_done
|
||||
call vga_scroll
|
||||
.scroll_done:
|
||||
|
||||
mov si, ax
|
||||
mov ax, VGA_WIDTH
|
||||
cmp cx, ax
|
||||
cmova cx, ax
|
||||
mov di, VGA_WIDTH * (VGA_HEIGHT - 1) * 2
|
||||
|
||||
xor dx, dx
|
||||
mov ax, [GLOBALS + TEXTBUF_LINE]
|
||||
mov di, VGA_WIDTH * 2
|
||||
mul di
|
||||
mov di, ax
|
||||
|
||||
mov ax, 0xb800
|
||||
mov es, ax
|
||||
mov ah, [GLOBALS + VGA_COL + 1]
|
||||
|
||||
.loop:
|
||||
or cx, cx
|
||||
jz .done
|
||||
mov al, [si]
|
||||
mov es:[di], ax
|
||||
add di, 2
|
||||
inc si
|
||||
dec cx
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
inc word [GLOBALS + TEXTBUF_LINE]
|
||||
|
||||
pop es
|
||||
pop dx
|
||||
pop di
|
||||
pop si
|
||||
fnret
|
||||
|
||||
|
||||
enable_a20:
|
||||
fnstart
|
||||
fnret
|
||||
|
||||
|
||||
; Check whether the A20 line is enabled. Writes to the boot sector identifier.
|
||||
; Arguments: none
|
||||
; Return:
|
||||
; - ax: 0 if A20 disabled, nonzero if A20 enabled
|
||||
; Clobber: none
|
||||
test_a20:
|
||||
push bp
|
||||
mov bp, sp
|
||||
push gs
|
||||
|
||||
; Restore the boot sector identifier in case it was overwritten by anything.
|
||||
@@ -238,22 +400,20 @@ test_a20:
|
||||
|
||||
.return:
|
||||
pop gs
|
||||
pop bp
|
||||
ret
|
||||
|
||||
|
||||
panic:
|
||||
mov ax, 0x0003
|
||||
int 0x10
|
||||
mov word fs:[0x0000], 0x4f21
|
||||
hlt
|
||||
msg_boot1_loaded db "boot1 loaded. hello!"
|
||||
MSG_BOOT1_LOADED_LEN equ $ - msg_boot1_loaded
|
||||
msg_a20_enabled db "a20 enabled"
|
||||
MSG_A20_ENABLED_LEN equ $ - msg_a20_enabled
|
||||
msg_a20_disabled db "a20 disabled"
|
||||
MSG_A20_DISABLED_LEN equ $ - msg_a20_disabled
|
||||
msg_panic db "fuck"
|
||||
MSG_PANIC_LEN equ $ - msg_panic
|
||||
|
||||
|
||||
womble db "jen is a womble!"
|
||||
WOMBLE_LEN equ $ - womble
|
||||
|
||||
times 409600 db 0
|
||||
cafebabe:
|
||||
dd 0xfeedface
|
||||
boot1_magic dd BOOT1_MAGIC
|
||||
|
||||
BOOT1_TOTAL_LEN equ $ - $$
|
||||
BOOT1_TOTAL_SECTORS equ (BOOT1_TOTAL_LEN + 511) / 512
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
|
||||
%define EBDA_START 0x080000
|
||||
|
||||
%define BOOT1_MAGIC 0x544e4150
|
||||
|
||||
%define VGA_WIDTH 80
|
||||
%define VGA_HEIGHT 25
|
||||
|
||||
; boot0 base stack frame variable offsets / globals
|
||||
; (we use the same offsets once we copy the variables to the globals section)
|
||||
; -------------------------------------------------------------------------------------------------
|
||||
@@ -29,3 +34,18 @@
|
||||
%define GPT_SECTORS_LOADED 0x16
|
||||
%define GPT_CURRENT_LBA 0x18
|
||||
%define BOOT1_GPT_ENTRY_ADDR 0x1a
|
||||
|
||||
; Globals
|
||||
; ------------------------------------------------------------------------------------------------
|
||||
%define VGA_COL 0x1c
|
||||
%define TEXTBUF_LINE 0x1e
|
||||
|
||||
%macro fnstart 0
|
||||
push bp
|
||||
mov bp, sp
|
||||
%endmacro
|
||||
|
||||
%macro fnret 0
|
||||
pop bp
|
||||
ret
|
||||
%endmacro
|
||||
Reference in new issue
Block a user