919 lines
16 KiB
NASM
919 lines
16 KiB
NASM
|
|
%include "bootdef.inc"
|
|
|
|
%define VESA_MODEINFO_SEG 0x0120
|
|
%define VESA_MODELIST_SEG 0x0140
|
|
%define GOOD_MODELIST_SEG 0x0160
|
|
|
|
[bits 16]
|
|
|
|
org BOOT_STAGE2_ADD
|
|
|
|
|
|
;k now read root directory
|
|
mov bx, BOOT_ROOT_SEG
|
|
mov ds, bx
|
|
xor si, si ;k now ds:si points to beginning of root directory
|
|
mov es, si
|
|
mov cx, 224 ;max root entries
|
|
loop_compare:
|
|
mov di, kernel
|
|
push cx
|
|
push si ;save pointer to root dir entry
|
|
mov cx, 11
|
|
loop_name:
|
|
cmpsb
|
|
loopz loop_name
|
|
jnz goon ;cx didn't get to zero, bad file
|
|
pop si
|
|
pop cx
|
|
jmp found_file ;good file, ds:si points to start of root directory entry
|
|
goon:
|
|
pop si
|
|
pop cx
|
|
loop loop_compare
|
|
|
|
error:
|
|
jmp $ ;halt! no kernel file found!
|
|
|
|
found_file: ;ds:si points to root dir entry of kernel file
|
|
xor ax, ax
|
|
mov gs, ax
|
|
mov ax, [ds:si+26]
|
|
mov bx, BOOT_FAT_SEG
|
|
mov ds, bx ;ds points to beginning of FAT
|
|
mov edi, BOOT_KERNEL_ADD
|
|
|
|
readkernel_loop:
|
|
cmp ax, 0xff7
|
|
jg readkernel_done
|
|
push ax
|
|
call getCHSfromCluster
|
|
mov ax, 0x0201
|
|
mov dl, [gs:BOOT_DRIVE]
|
|
mov bx, BOOT_KERNEL_SEG
|
|
mov es, bx
|
|
xor bx, bx
|
|
int 0x13
|
|
mov cx, 256
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov esi, BOOT_KERNEL_SEG*16
|
|
copykernel_loop:
|
|
mov ax, [es:esi]
|
|
mov [es:edi], ax
|
|
inc esi
|
|
inc esi
|
|
inc edi
|
|
inc edi
|
|
loop copykernel_loop
|
|
|
|
pop ax ;current logical cluster #
|
|
|
|
mov cx, ax ;cx=logical cluster
|
|
mov dx, 3
|
|
mul dx
|
|
shr ax, 1 ;ax=logical cluster * 3 / 2
|
|
mov si, ax
|
|
test cl, 1 ;is bit0 set?
|
|
jnz odd_cluster
|
|
even_cluster:
|
|
lodsw
|
|
and ax, 0x0fff
|
|
jmp got_cluster
|
|
odd_cluster:
|
|
lodsw
|
|
shr ax, 4
|
|
got_cluster:
|
|
jmp readkernel_loop
|
|
|
|
;------------------------------------------------------
|
|
readkernel_done: ;-------------put more real mode init stuff here!
|
|
;----ask to load RD from floppy
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
xor ax, ax
|
|
mov ds, ax
|
|
xor di, di
|
|
mov cx, 2000
|
|
mov ax, 0x0700
|
|
cls_loop:
|
|
stosw
|
|
loop cls_loop
|
|
|
|
mov dx, 0x3d4 ;move cursor off screen...
|
|
mov al, 0x0e
|
|
out dx, al
|
|
inc dx
|
|
mov al, 0xff
|
|
out dx, al
|
|
dec dx
|
|
mov al, 0x0f
|
|
out dx, al
|
|
inc dx
|
|
out dx, al
|
|
|
|
xor di, di
|
|
mov si, txt_welcome
|
|
mov ah, 0x1f
|
|
call puts
|
|
|
|
mov di, 160
|
|
mov si, txt_rd1
|
|
mov ah, 7
|
|
call puts
|
|
|
|
mov si, txt_rd2
|
|
mov di, 160*2
|
|
call puts
|
|
|
|
mov di, 160*3
|
|
mov si, txt_input
|
|
call puts
|
|
|
|
get_rd:
|
|
xor ax, ax
|
|
int 0x16
|
|
cmp al, '1'
|
|
jz got_rd
|
|
cmp al, '2'
|
|
jnz get_rd
|
|
got_rd:
|
|
stosb
|
|
sub al, '1'
|
|
push ds
|
|
mov bx, BOOT_DATA_SEG ;segment for data to send kernel
|
|
mov ds, bx
|
|
mov [ds:BOOT_HASRD], al
|
|
pop ds ;ds=0
|
|
cmp al, 0 ;dont load rd
|
|
jz no_rd
|
|
|
|
mov cx, 80
|
|
mov edi, 0xb8000+160*4
|
|
filler_loop:
|
|
mov word [ds:edi], 0x0400+177
|
|
inc edi
|
|
inc edi
|
|
loop filler_loop
|
|
mov cx, 80 ;80 cylinders to read
|
|
xor si, si
|
|
mov edi, BOOT_RD_ADD ;ram disk address
|
|
read_cylinder:
|
|
push cx
|
|
mov bx, 0x0100
|
|
mov es, bx
|
|
xor bx, bx
|
|
mov ax, 0x0224
|
|
mov cx, si
|
|
mov ch, cl
|
|
mov cl, 1
|
|
xor dx, dx
|
|
mov dl, [gs:BOOT_DRIVE]
|
|
int 0x13
|
|
|
|
mov ebx, 0xb8000
|
|
add bx, si
|
|
shl bl, 1
|
|
mov word [ds:ebx+160*4], 0x0200+219
|
|
|
|
push si
|
|
mov esi, 0x1000
|
|
mov cx, 0x2400
|
|
copydisk_loop:
|
|
mov ax, [ds:esi]
|
|
inc esi
|
|
inc esi
|
|
mov [ds:edi], ax
|
|
inc edi
|
|
inc edi
|
|
loop copydisk_loop
|
|
|
|
pop si ;what cylinder# we are on...
|
|
inc si
|
|
pop cx
|
|
loop read_cylinder
|
|
|
|
;------------------------------------------------------
|
|
no_rd:
|
|
mov ax, BOOT_DATA_SEG
|
|
mov es, ax
|
|
mov di, BOOT_MEMMAP ;store memmap info in es:di for kernel
|
|
xor edx, edx
|
|
mov ax, 0x0100
|
|
mov ds, ax
|
|
xor ebx, ebx
|
|
getmemmap_loop:
|
|
push es
|
|
push di
|
|
push edx
|
|
mov ax, 0x0100 ;get memory map
|
|
mov es, ax
|
|
xor di, di
|
|
mov eax, 0x0000E820
|
|
mov ecx, 0x00000014
|
|
;mov ebx, 0x00000000
|
|
mov edx, 0x534D4150 ;'SMAP'
|
|
int 0x15
|
|
jc getmemmap_done
|
|
cmp eax, 0x534D4150 ;eax should be 'SMAP' on return...
|
|
jnz getmemmap_error
|
|
cmp ebx, 0
|
|
jz getmemmap_done
|
|
|
|
pop edx ;now, copy memmap entry to es:di on the stack
|
|
pop di
|
|
pop es
|
|
xor si, si
|
|
mov cx, 20
|
|
getmemmap_copymem_loop:
|
|
lodsb
|
|
stosb
|
|
loop getmemmap_copymem_loop
|
|
inc edx
|
|
jmp getmemmap_loop
|
|
|
|
getmemmap_error:
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov di, 160*24
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_memerror
|
|
mov ah, 0x04
|
|
call puts
|
|
hlt
|
|
jmp $
|
|
|
|
getmemmap_done:
|
|
pop edx
|
|
pop di
|
|
pop es
|
|
|
|
xor si, si
|
|
mov cx, 20
|
|
getmemmap_done_copymem_loop:
|
|
lodsb
|
|
stosb
|
|
loop getmemmap_done_copymem_loop
|
|
inc edx
|
|
|
|
mov di, BOOT_MEMENTRIES
|
|
mov [es:di], edx ;save # of memmap entries for kernel
|
|
|
|
;on to vesa info...
|
|
xor ax, ax
|
|
mov gs, ax
|
|
mov ds, ax
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov di, 160
|
|
mov cx, 2000-80
|
|
mov ax, 0x0700
|
|
cls_vesa_loop:
|
|
stosw
|
|
loop cls_vesa_loop
|
|
mov si, txt_vesa
|
|
mov di, 160*1
|
|
mov ah, 7
|
|
call puts
|
|
|
|
push di
|
|
mov ax, 0x0100
|
|
mov es, ax
|
|
xor di, di
|
|
mov dword [es:di], "2EBV"
|
|
mov ax, 0x4F00
|
|
|
|
int 0x10
|
|
pop di
|
|
cmp ax, 0x004F
|
|
jz vesa_good
|
|
mov si, txt_novesa
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov ah, 7
|
|
call puts
|
|
mov ax, BOOT_DATA_SEG
|
|
mov ds, ax
|
|
mov word [ds:BOOT_VESA], 0
|
|
jmp vesa_done
|
|
vesa_good:
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov ax, 0x0100
|
|
mov ds, ax
|
|
xor si, si
|
|
mov bx, [4]
|
|
mov al, bh
|
|
call puthex
|
|
mov al, '.'
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
mov al, bl
|
|
call puthex
|
|
add di, 4
|
|
cmp bh, 2
|
|
jge vesa_good2
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_vesaold
|
|
mov ah, 7
|
|
call puts
|
|
mov ax, BOOT_DATA_SEG
|
|
mov ds, ax
|
|
mov word [ds:BOOT_VESA], 0
|
|
jmp vesa_done
|
|
vesa_good2:
|
|
mov ebx, [6] ;something like 0x00000E60
|
|
mov edx, [14]
|
|
mov si, bx
|
|
shr ebx, 16
|
|
mov ds, bx ;ds:si points to null-terminated OEM identification string
|
|
mov ah, 2
|
|
push si
|
|
call puts
|
|
pop si
|
|
mov ax, BOOT_DATA_SEG
|
|
mov es, ax
|
|
mov di, BOOT_VESA_OEM
|
|
vesa_copyoem:
|
|
lodsb
|
|
stosb
|
|
or al, al
|
|
jnz vesa_copyoem
|
|
mov ax, 0x0100
|
|
mov ds, ax
|
|
xor si, si
|
|
mov di, BOOT_VESA_VBE
|
|
mov cx, 512
|
|
vesa_copyvbe:
|
|
lodsb
|
|
stosb
|
|
loop vesa_copyvbe
|
|
|
|
mov si, dx
|
|
shr edx, 16
|
|
mov ds, dx ;ds:si points to video mode list
|
|
mov ax, VESA_MODELIST_SEG
|
|
mov es, ax
|
|
xor di, di
|
|
vesa_copymodes:
|
|
lodsw
|
|
stosw
|
|
cmp ax, 0xffff
|
|
jnz vesa_copymodes
|
|
|
|
mov ax, GOOD_MODELIST_SEG
|
|
mov es, ax
|
|
xor di, di
|
|
mov cx, 256
|
|
mov ax, 0xffff
|
|
clear_good_mode_list_loop:
|
|
stosw
|
|
loop clear_good_mode_list_loop
|
|
|
|
mov ax, VESA_MODELIST_SEG
|
|
mov ds, ax
|
|
xor si, si ;ds:si points to video mode list where we can edit it :)
|
|
mov ax, GOOD_MODELIST_SEG
|
|
mov es, ax
|
|
xor di, di
|
|
xor dx, dx ;dx=what good mode # we are on
|
|
vesa_readmodeinfo_loop:
|
|
lodsw
|
|
cmp ax, 0xffff
|
|
jz vesa_endofmodes
|
|
push ax ;save mode#
|
|
call checkmode
|
|
cmp ax, 0
|
|
jz vesa_readmodeinfo_good
|
|
pop ax
|
|
jmp vesa_readmodeinfo_loop
|
|
vesa_readmodeinfo_good:
|
|
pop ax ;restore mode#
|
|
stosw
|
|
call vesa_showmodeinfo
|
|
inc dx
|
|
jmp vesa_readmodeinfo_loop
|
|
|
|
vesa_endofmodes: ;here we have a list of good modes at GOOD_MODELIST_SEG:0
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_consolemode
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov di, 160*2
|
|
mov ah, 7
|
|
call puts
|
|
mov di, 160*3
|
|
mov cx, dx
|
|
mov al, 'b'
|
|
vesa_displaylabels:
|
|
stosb
|
|
push ax
|
|
mov al, 7
|
|
stosb
|
|
mov al, '.'
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
inc al
|
|
add di, 160-4
|
|
loop vesa_displaylabels ;done drawing screen of VESA choices, now ask for one
|
|
;valid options are 'a' through (al-1)
|
|
mov bl, al
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov di, 160*24
|
|
mov si, txt_input
|
|
mov ah, 14
|
|
call puts
|
|
vesa_getchoice:
|
|
xor ax, ax
|
|
int 0x16
|
|
cmp al, 'a'
|
|
jl vesa_getchoice
|
|
cmp al, bl
|
|
jge vesa_getchoice
|
|
stosb
|
|
push ax
|
|
mov al, 14
|
|
stosb
|
|
pop ax
|
|
xor ah, ah
|
|
sub ax, 'a'
|
|
cmp ax, 0
|
|
jz vesa_consolemode_only
|
|
mov cx, ax ;cx holds good mode# (1=first good vesa mode)
|
|
dec cx
|
|
mov ax, GOOD_MODELIST_SEG
|
|
mov ds, ax
|
|
shl cx, 1
|
|
mov si, cx ;ds:si points to word containing selected mode#
|
|
lodsw
|
|
mov cx, ax
|
|
mov dx, ax ;cx and dx hold mode#
|
|
|
|
mov ax, VESA_MODEINFO_SEG
|
|
mov es, ax
|
|
xor di, di
|
|
mov ax, 0x4F01
|
|
int 0x10
|
|
call checkvesa
|
|
|
|
mov ax, VESA_MODEINFO_SEG
|
|
mov ds, ax
|
|
xor si, si
|
|
mov ax, BOOT_DATA_SEG
|
|
mov es, ax
|
|
mov di, BOOT_VESA_INFO
|
|
mov cx, 256
|
|
vesa_copymodeinfo_loop:
|
|
lodsb
|
|
stosb
|
|
loop vesa_copymodeinfo_loop ;store ModeInfoBlock for current
|
|
|
|
mov [es:BOOT_VESA], dx ;store mode# for kernel
|
|
|
|
; mov ax, 0xb800
|
|
; mov es, ax
|
|
; xor di, di
|
|
; mov al, dh
|
|
; call puthex2
|
|
; mov al, dl
|
|
; call puthex2
|
|
|
|
mov bx, dx
|
|
or bx, 0x4000 ;set "use LFB" bit of mode#
|
|
mov ax, 0x4F02
|
|
int 0x10 ;switch to graphics mode!!!
|
|
call checkvesa
|
|
|
|
jmp vesa_done
|
|
|
|
vesa_consolemode_only:
|
|
mov ax, BOOT_DATA_SEG
|
|
mov es, ax
|
|
mov word [es:BOOT_VESA], 0
|
|
|
|
jmp vesa_done
|
|
|
|
;------------------------------------------------------
|
|
vesa_showmodeinfo:
|
|
pusha
|
|
push es
|
|
push ds
|
|
mov ax, VESA_MODEINFO_SEG
|
|
mov ds, ax
|
|
xor si, si
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
|
|
mov cx, dx
|
|
|
|
mov ax, 160
|
|
mul dx ;ax=160*mod#
|
|
add ax, 160*3+6 ;offset first line of modes and room on left for label
|
|
mov di, ax
|
|
|
|
mov ax, [ds:18]
|
|
call console_putDec
|
|
add di, 10
|
|
mov al, 'x'
|
|
call console_putChar
|
|
inc di
|
|
inc di
|
|
mov ax, [ds:20]
|
|
call console_putDec
|
|
add di, 10
|
|
mov al, 'x'
|
|
call console_putChar
|
|
inc di
|
|
inc di
|
|
xor ah, ah
|
|
mov al, [ds:25]
|
|
call console_putDec
|
|
add di, 8
|
|
mov al, [ds:0]
|
|
test al, 0x80
|
|
jz vesa_showmodeinfo_done
|
|
mov al, 'L'
|
|
call console_putChar
|
|
mov al, 'F'
|
|
call console_putChar
|
|
mov al, 'B'
|
|
call console_putChar
|
|
inc di
|
|
inc di
|
|
mov ebx, [ds:40]
|
|
mov eax, ebx
|
|
shr eax, 24
|
|
call puthex2
|
|
mov eax, ebx
|
|
shr eax, 16
|
|
call puthex2
|
|
mov al, bh
|
|
call puthex2
|
|
mov al, bl
|
|
call puthex2
|
|
vesa_showmodeinfo_done:
|
|
pop ds
|
|
pop es
|
|
popa
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
checkmode:
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push es
|
|
push ds
|
|
push di
|
|
push si
|
|
mov cx, ax ;cx=modenumber
|
|
mov ax, VESA_MODEINFO_SEG
|
|
mov es, ax
|
|
xor di, di
|
|
mov ax, 0x4F01
|
|
int 0x10
|
|
call checkvesa
|
|
xor di, di ;es:di -> ModeInfoBlock struc
|
|
mov ax, [es:di] ;ModeAttributes
|
|
test al, 1 ;mode supported
|
|
jz vesa_modenogood
|
|
test al, 8 ;color mode
|
|
jz vesa_modenogood
|
|
test al, 0x10 ;graphics mode
|
|
jz vesa_modenogood
|
|
test al, 0x80 ;Linear Frame Buffer supported
|
|
jz vesa_modenogood
|
|
mov al, [es:di+25] ;BitsPerPixel
|
|
cmp al, 16
|
|
jz vesa_bppok
|
|
cmp al, 24
|
|
jz vesa_bppok
|
|
cmp al, 32
|
|
jnz vesa_modenogood
|
|
vesa_bppok:
|
|
mov ax, [es:di+18] ;XResolution
|
|
mov bx, [es:di+20] ;YResolution
|
|
cmp ax, 640 ;640x480
|
|
jnz res_goon1
|
|
cmp bx, 480
|
|
jnz vesa_modenogood
|
|
jmp vesa_modegood
|
|
res_goon1:
|
|
cmp ax, 800
|
|
jnz res_goon2
|
|
cmp bx, 600
|
|
jnz vesa_modenogood
|
|
jmp vesa_modegood
|
|
res_goon2:
|
|
cmp ax, 1024
|
|
jnz res_goon3
|
|
cmp bx, 768
|
|
jnz vesa_modenogood
|
|
jmp vesa_modegood
|
|
res_goon3:
|
|
cmp ax, 1280
|
|
jnz res_goon4
|
|
cmp bx, 1024
|
|
jz vesa_modegood
|
|
cmp bx, 960
|
|
jz vesa_modegood
|
|
jmp vesa_modenogood
|
|
res_goon4:
|
|
cmp ax, 1600
|
|
jnz vesa_modenogood
|
|
cmp bx, 1200
|
|
jnz vesa_modenogood
|
|
vesa_modegood:
|
|
pop si
|
|
pop di
|
|
pop ds
|
|
pop es
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
xor ax, ax
|
|
ret
|
|
vesa_modenogood:
|
|
pop si
|
|
pop di
|
|
pop ds
|
|
pop es
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
mov ax, 0xffff
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
vesa_done:
|
|
|
|
; xor ax, ax ;wait for keypress...
|
|
; int 0x16
|
|
|
|
jmp go_pm
|
|
|
|
;------------------------------------------------------
|
|
puts:
|
|
lodsb
|
|
or al, al
|
|
jz puts_done
|
|
stosb
|
|
mov al, ah
|
|
stosb
|
|
jmp puts
|
|
puts_done:
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
checkvesa:
|
|
cmp ax, 0x004F
|
|
jnz vesaerror
|
|
ret
|
|
vesaerror:
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_vesaerror
|
|
mov di, 160*24
|
|
mov ah, 4
|
|
call puts
|
|
cli
|
|
hlt
|
|
|
|
;-------Function console_putDec
|
|
;input:
|
|
; AX = number to display
|
|
;output:
|
|
; number written in decimal to es:di
|
|
console_putDec:
|
|
pusha
|
|
xor dx, dx
|
|
xor bh, bh ;no characters written yet
|
|
mov cx, 10000
|
|
div cx ;ax=quotiont, dx=remainder
|
|
add ax, '0'
|
|
cmp ax, '0'
|
|
je .goon1
|
|
call console_putChar
|
|
mov bh, 1
|
|
|
|
.goon1:
|
|
mov ax, dx ;load remainder to ax
|
|
xor dx, dx
|
|
mov cx, 1000
|
|
div cx ;ax=quotiont, dx=remainder
|
|
add ax, '0'
|
|
cmp ax, '0'
|
|
je .goon11
|
|
call console_putChar
|
|
mov bh, 1
|
|
jmp .goon2
|
|
.goon11:
|
|
cmp bh, 0
|
|
je .goon2
|
|
call console_putChar
|
|
|
|
.goon2:
|
|
mov ax, dx ;load remainder to ax
|
|
xor dx, dx
|
|
mov cx, 100
|
|
div cx ;ax=quotiont, dx=remainder
|
|
add ax, '0'
|
|
cmp ax, '0'
|
|
je .goon21
|
|
call console_putChar
|
|
mov bh, 1
|
|
jmp .goon3
|
|
.goon21:
|
|
cmp bh, 0
|
|
je .goon3
|
|
call console_putChar
|
|
|
|
.goon3:
|
|
mov ax, dx ;load remainder to ax
|
|
xor dx, dx
|
|
mov cx, 10
|
|
div cx ;ax=quotiont, dx=remainder
|
|
add ax, '0'
|
|
cmp ax, '0'
|
|
je .goon31
|
|
call console_putChar
|
|
mov bh, 1
|
|
jmp .goon4
|
|
.goon31:
|
|
cmp bh, 0
|
|
je .goon4
|
|
call console_putChar
|
|
.goon4: ;here dx contains last remainder
|
|
mov ax, dx
|
|
add ax, '0'
|
|
call console_putChar
|
|
|
|
popa
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
console_putChar:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
puthex:
|
|
;es:di points to video memory
|
|
;al holds hex value
|
|
|
|
push ax
|
|
mov ah, al
|
|
shr ax, 4
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex_goon1
|
|
add al, 'A'-'9'-1
|
|
puthex_goon1:
|
|
cmp al, '0'
|
|
jz puthex_skipzero
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
puthex_skipzero:
|
|
pop ax
|
|
push ax
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex_goon2
|
|
add al, 'A'-'9'-1
|
|
puthex_goon2:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
puthex2:
|
|
;es:di points to video memory, always displays 2 characters!
|
|
;al holds hex value
|
|
|
|
push ax
|
|
mov ah, al
|
|
shr ax, 4
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex2_goon1
|
|
add al, 'A'-'9'-1
|
|
puthex2_goon1:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
push ax
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex2_goon2
|
|
add al, 'A'-'9'-1
|
|
puthex2_goon2:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
ret
|
|
|
|
;------------------------------------------------------
|
|
txt_welcome: db " Welcome to HOS v", VERSION, "! ", 0
|
|
txt_rd1: db "1. Do not load an initial ram disk", 0
|
|
txt_rd2: db "2. Load initial ram disk from floppy", 0
|
|
txt_input: db "Enter your selection: ", 0
|
|
txt_vesa: db "VESA version: ", 0
|
|
txt_vesaerror: db "VESA function call error! Halting system!", 0
|
|
txt_novesa: db "VESA not found. Starting in console mode...", 0
|
|
txt_vesaold: db "VESA version 2.0 required. Starting in console mode...", 0
|
|
txt_consolemode: db "a. Console mode only.", 0
|
|
txt_memerror: db "Extended Memory Map information unavailable! Halting system...", 0
|
|
|
|
;------------------------------------------------------
|
|
getCHSfromCluster:
|
|
;input: ax=lba of sector on floppy (0-2879)
|
|
add ax, 31 ;convert logical cluster# to lba#
|
|
xor dx, dx ;lba->chs
|
|
mov bx, 18
|
|
div bx
|
|
inc dx
|
|
mov cl, dl ;sector# (1-18)
|
|
xor dx, dx
|
|
mov bx, 2
|
|
div bx
|
|
mov ch, al ;cylinder# (0-79)
|
|
mov dh, dl ;head# (0-1)
|
|
ret
|
|
|
|
|
|
;-------------------------------------------------------
|
|
gdtr:
|
|
dw gdt_end-gdt-1
|
|
dd gdt
|
|
gdt:
|
|
dd 0
|
|
dd 0
|
|
|
|
KERNEL_CODE equ $-gdt
|
|
db 0xff ;limit 7:0
|
|
db 0xff ;limit 15:8
|
|
db 0x00 ;base 7:0
|
|
db 0x00 ;base 15:8
|
|
db 0x00 ;base 23:16
|
|
db 0x9a ;access
|
|
db 0xcf ;flags / limit 19:16
|
|
db 0x00 ;base 31:24
|
|
|
|
KERNEL_DATA equ $-gdt
|
|
db 0xff ;segment 16 = 4gb data
|
|
db 0xff
|
|
db 0x00
|
|
db 0x00
|
|
db 0x00
|
|
db 0x92
|
|
db 0xcf ;cf
|
|
db 0x00
|
|
|
|
gdt_end:
|
|
|
|
;------------------------------------------------------
|
|
go_pm:
|
|
xor ax, ax
|
|
mov ds, ax
|
|
lgdt [gdtr]
|
|
cli
|
|
mov eax, cr0
|
|
inc eax
|
|
mov cr0, eax
|
|
|
|
jmp KERNEL_CODE:pmode
|
|
|
|
bits 32
|
|
pmode:
|
|
mov ax, KERNEL_DATA
|
|
mov es, ax
|
|
mov ds, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
jmp KERNEL_CODE:BOOT_KERNEL_ADD
|
|
|
|
kernel: db "KERNEL BIN", 0
|
|
|
|
|