-; vi:ft=nasm:
bits 64
org 1000h
+%include "serial.inc"
+
BOOT_SERVICES equ 96
BOOT_GET_MEMORY_MAP equ 56
BOOT_EXIT_BOOT_SERVICES equ 232
push qword start32
retfq
-
-.hang: jmp .hang
-
get_rip:
mov rax, [rsp]
ret
-
-UART_DATA equ 0x3f8
-UART_DIVLO equ 0x3f8
-UART_DIVHI equ 0x3f9
-UART_FIFO equ 0x3fa
-UART_LCTL equ 0x3fb
-UART_MCTL equ 0x3fc
-UART_LSTAT equ 0x3fd
-DIV_9600 equ 115200 / 9600
-LCTL_8N1 equ 0x03
-LCTL_DLAB equ 0x80
-FIFO_ENABLE_CLEAR equ 0x07
-MCTL_DTR_RTS_OUT2 equ 0x0b
-LST_TREG_EMPTY equ 0x20
-
; serial port setup
setup_serial:
; set clock divisor
ret
- align 8
-efihandle dq 0
-systab dq 0
-; memory map data
-mmap_size dq 4096
-mmap_key dq 0
-mmap_descsz dq 0
-mmap_descver dq 0
-
- align 4096
-mmapbuf: times 4096 db 0
-
-str_hello db 'hello!',13,10,0
-
- align 4
-gdtlim dw 31
-gdtbase dq gdt
-
- align 8
-gdt: ; 0: null segment
- dd 0, 0
- ; 1: code - base:0, lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:code/non-conf/rd
- dd 0x0000ffff
- dd 0x00cf9a00
- ; 2: data - base:0, lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:data/rw
- dd 0x0000ffff
- dd 0x00cf9200
- ; 3: code16
- dd 0x0000ffff
- dd 0x00009a00
+; ----------- 32bit code ----------
bits 32
start32:
and eax, 0fffffeffh
wrmsr
+ ; load 16bit IVT descriptor
+ cli ; just to make sure
+ lidt [rmidt]
+
; load 16bit code segment and jump to 16bit code
jmp 0x18:start16
-.hang: hlt
- jmp .hang
-
-
-ser_putchar:
- mov ah, al
- ; wait until transmit register is empty
- mov dx, UART_LSTAT
-.wait: in al, dx
- and al, LST_TREG_EMPTY
- jz .wait
- mov dx, UART_DATA
- mov al, ah
- out dx, al
- ret
-
-ser_putstr:
- mov al, [esi]
- test al, al
- jz .done
- call ser_putchar
- inc esi
- jmp ser_putstr
-.done: ret
-
-
- align 4
- ; real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
- dw 0
-rmidt: dw 3ffh
- dd 0
+; ---------- 16bit real mode code ----------
bits 16
start16:
mov ss, ax
xor sp, sp
+ call print_ivt
+
; run 16bit video bios test
mov ax, 13h
- ;int 10h
+ int 10h
mov ax, 0a000h
mov es, ax
.hang: hlt
jmp .hang
+print_ivt:
+ xor bx, bx
+.loop: mov ax, bx
+ shr ax, 2
+ call printhex8
+ mov al, ' '
+ call ser_putchar
+ mov ax, [bx + 2] ; segment
+ call printhex16
+ mov al, ':'
+ call ser_putchar
+ mov ax, [bx] ; offset
+ call printhex16
+ mov al, 13
+ call ser_putchar
+ mov al, 10
+ call ser_putchar
+ add bx, 4
+
+ cmp bx, 64 << 2
+ jnz .loop
+ ret
+
+hexdig db '0123456789abcdef'
+
+printhex8:
+ push bx
+ rol al, 4
+ mov bx, ax
+ and bx, 0fh
+ mov cx, ax
+ mov al, [bx + hexdig]
+ call ser_putchar
+ mov ax, cx
+ rol al, 4
+ mov bx, ax
+ and bx, 0fh
+ mov al, [bx + hexdig]
+ call ser_putchar
+ pop bx
+ ret
+
+printhex16:
+ push ax
+ mov al, ah
+ call printhex8
+ pop ax
+ call printhex8
+ ret
+
+ser_putchar:
+ mov ah, al
+ ; wait until transmit register is empty
+ mov dx, UART_LSTAT
+.wait: in al, dx
+ and al, LST_TREG_EMPTY
+ jz .wait
+ mov dx, UART_DATA
+ mov al, ah
+ out dx, al
+ ret
+
+ser_putstr:
+ mov al, [si]
+ test al, al
+ jz .done
+ call ser_putchar
+ inc si
+ jmp ser_putstr
+.done: ret
+
+
+; ---------- data ------------
+
+ align 8
+efihandle dq 0
+systab dq 0
+; memory map data
+mmap_size dq 4096
+mmap_key dq 0
+mmap_descsz dq 0
+mmap_descver dq 0
+
+ align 4096
+mmapbuf: times 4096 db 0
+
+str_hello db 'hello!',13,10,0
+
+ align 4
+gdtlim dw 31
+gdtbase dq gdt
+
+ align 8
+gdt: ; 0: null segment
+ dd 0, 0
+ ; 1: code - base:0, lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:code/non-conf/rd
+ dd 0x0000ffff
+ dd 0x00cf9a00
+ ; 2: data - base:0, lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:data/rw
+ dd 0x0000ffff
+ dd 0x00cf9200
+ ; 3: code16
+ dd 0x0000ffff
+ dd 0x00009a00
+
+
+ align 4
+ ; real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
+ dw 0
+rmidt: dw 3ffh
+ dd 0
+
+
align 4
end:
+; vi:ft=nasm: