Import backup from 2004-03-08
This commit is contained in:
1 parent
0b9d7fde22
commit
8d0e6de040
45 files changed
+243
-219
No files matched your search
@@ -0,0 +1,30 @@
|
||||
########################
|
||||
# Author: Josh Holtrop #
|
||||
# Date: 2004-2-15 #
|
||||
########################
|
||||
|
||||
# Assembler information:
|
||||
NASM_BIN=nasm
|
||||
|
||||
#################
|
||||
# Build the IPL #
|
||||
#################
|
||||
all: stage1 stage2
|
||||
|
||||
################
|
||||
# IPL: Stage 1 #
|
||||
################
|
||||
stage1: stage1.asm
|
||||
$(NASM_BIN) stage1.asm -o stage1.bin
|
||||
|
||||
################
|
||||
# IPL: Stage 2 #
|
||||
################
|
||||
stage2: stage2.asm
|
||||
$(NASM_BIN) stage2.asm -o stage2.bin
|
||||
|
||||
#########
|
||||
# Clean #
|
||||
#########
|
||||
clean:
|
||||
rm *.bin
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
%define VERSION "0.13" ;HOS version
|
||||
|
||||
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector
|
||||
%define BOOT_ROOT_SEG 0x0900 ;right after FAT
|
||||
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
|
||||
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
|
||||
%define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
|
||||
%define BOOT_KERNEL_ADD 0x106000 ;final pmode kernel destination - physical
|
||||
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk
|
||||
|
||||
%define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
|
||||
|
||||
%define BOOT_HASRD 0x0000 ;1
|
||||
%define BOOT_VESA 0x0002 ;2 - 0 for console, otherwise VESA mode
|
||||
%define BOOT_VESA_OEM 0x0004 ;258 - null-terminated OEM identification string
|
||||
%define BOOT_VESA_VBE 0x0106 ;512 - copy of VESA VBEInfoBlock
|
||||
%define BOOT_VESA_INFO 0x0306 ;256 - copy of VESA ModeInfoBlock for selected mode
|
||||
%define BOOT_MEMENTRIES 0x040A ;4 - dword = number of memmap entries
|
||||
%define BOOT_MEMMAP 0x2000 ;? - memory map information
|
||||
|
||||
|
||||
|
||||
%define BOOT_DRIVE 0x7C24 ;1 - boot drive
|
||||
|
||||
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
|
||||
%include "bootdef.inc"
|
||||
|
||||
[bits 16]
|
||||
|
||||
org 0x7c00
|
||||
|
||||
jmp short start
|
||||
|
||||
; --------------------------------------------------
|
||||
; data portion of the "DOS BOOT RECORD"
|
||||
; ----------------------------------------------------------------------
|
||||
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
|
||||
brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B
|
||||
brBPS DW 512 ; 000Bh - Bytes per sector
|
||||
brSPC DB 1 ; 000Dh - Sector per cluster
|
||||
brSc_b4_fat DW 1 ; 000Eh - Reserved sectors
|
||||
brFATs DB 2 ; 0010h - FAT copies
|
||||
brRootEntries DW 0E0H ; 0011h - Root directory entries
|
||||
brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
|
||||
brMedia DB 240 ; 0015h - Media descriptor
|
||||
brSPF DW 9 ; 0016h - Sectors per FAT
|
||||
brSc_p_trk DW 18 ; 0018h - Sectors per head/track
|
||||
brHPC DW 2 ; 001Ah - Heads per cylinder
|
||||
brSc_b4_prt DD 0 ; 001Ch - Hidden sectors
|
||||
brSectors DD 0 ; 0020h - Total number of sectors
|
||||
brDrive DB 0 ; 0024h - Physical drive no.
|
||||
DB 0 ; 0025h - Reserved (FAT32)
|
||||
DB 29H ; 0026h - Extended boot record sig (FAT32)
|
||||
brSerialNum DD 404418EAH ; 0027h - Volume serial number
|
||||
brLabel DB 'Holtrops OS' ; 002Bh - Volume label
|
||||
brFSID DB 'FAT12 ' ; 0036h - File System ID
|
||||
;------------------------------------------------------------------------
|
||||
|
||||
start:
|
||||
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
|
||||
jmphere:
|
||||
;dl=drive number, save it!
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov [brDrive], dl
|
||||
cli
|
||||
mov ss, ax
|
||||
mov sp, 0x7Bfe ;right under boot sector
|
||||
sti
|
||||
|
||||
mov ax, 0xb800
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
||||
xor di, di
|
||||
mov ax, 0x0700
|
||||
mov cx, 2000
|
||||
cls:
|
||||
stosw
|
||||
loop cls
|
||||
|
||||
enable_a20:
|
||||
in al, 0x64
|
||||
test al, 2
|
||||
jnz enable_a20
|
||||
mov al, 0xD1
|
||||
out 0x64, al
|
||||
ea20_2: in al, 0x64
|
||||
and ax, byte 2
|
||||
jnz ea20_2
|
||||
mov al, 0xDF
|
||||
out 0x60, al
|
||||
|
||||
unreal:
|
||||
xor ax, ax
|
||||
mov es, ax
|
||||
mov ds, ax
|
||||
|
||||
lgdt [gdtr] ;load gdt
|
||||
cli
|
||||
push es
|
||||
push ds ;save segment values
|
||||
mov ebx, cr0
|
||||
inc bl
|
||||
mov cr0, ebx ;pmode!
|
||||
mov ax, KERNEL_DATA
|
||||
mov es, ax
|
||||
mov ds, ax ;load segment limits
|
||||
dec bl
|
||||
mov cr0, ebx ;back to real mode!
|
||||
pop ds
|
||||
pop es ;segments back, with 4gb limits!
|
||||
sti
|
||||
|
||||
;now lets read in the FAT and root directory so we can search for the stage2 file...
|
||||
mov ax, 0x0209 ;FAT1
|
||||
mov cx, 0x0002
|
||||
xor dh, dh
|
||||
mov dl, [brDrive]
|
||||
mov bx, BOOT_FAT_SEG
|
||||
mov es, bx
|
||||
xor bx, bx
|
||||
int 0x13
|
||||
|
||||
mov ax, 0x020E ;root directory
|
||||
mov cx, 0x0002 ;cyl/sect
|
||||
mov dh, 0x01 ;head
|
||||
mov dl, [brDrive] ;drive
|
||||
mov bx, BOOT_ROOT_SEG
|
||||
mov es, bx
|
||||
xor bx, bx
|
||||
int 0x13
|
||||
|
||||
;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, stage2
|
||||
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
|
||||
add si, 32
|
||||
loop loop_compare
|
||||
|
||||
error:
|
||||
jmp $ ;halt! no kernel file found!
|
||||
|
||||
found_file: ;ds:si points to root dir entry
|
||||
xor ax, ax
|
||||
mov gs, ax
|
||||
mov ax, BOOT_STAGE2_SEG
|
||||
mov es, ax
|
||||
|
||||
mov ax, [ds:si+26]
|
||||
mov bx, BOOT_FAT_SEG
|
||||
mov ds, bx ;ds points to beginning of FAT
|
||||
xor di, di
|
||||
|
||||
readstage2_loop:
|
||||
cmp ax, 0xff7
|
||||
jg readstage2_done
|
||||
inc di
|
||||
push ax
|
||||
call getCHSfromCluster
|
||||
mov ax, 0x0201
|
||||
mov dl, [gs:BOOT_DRIVE]
|
||||
xor bx, bx
|
||||
int 0x13
|
||||
mov bx, es
|
||||
add bx, 0x0020
|
||||
mov es, bx
|
||||
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 readstage2_loop
|
||||
|
||||
readstage2_done:
|
||||
|
||||
jmp 0:BOOT_STAGE2_ADD
|
||||
|
||||
;------------------------------------------------------
|
||||
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_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:
|
||||
|
||||
|
||||
|
||||
stage2: db "STAGE2 BIN"
|
||||
|
||||
times 510-($-$$) db 0
|
||||
|
||||
db 0x55, 0xaa
|
||||
|
||||
+971
@@ -0,0 +1,971 @@
|
||||
|
||||
%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
|
||||
add si, 32
|
||||
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
|
||||
jnz yes_rd
|
||||
jmp no_rd
|
||||
yes_rd:
|
||||
mov cx, 80
|
||||
mov edi, 0xb8000+160*4
|
||||
filler_loop: ;draw a red bar
|
||||
mov word [ds:edi], 0x0400+177
|
||||
inc edi
|
||||
inc edi
|
||||
loop filler_loop
|
||||
|
||||
mov cx, 80 ;80 cylinders to read
|
||||
xor si, si ;start at cylinder 0
|
||||
mov edi, BOOT_RD_ADD ;ram disk address
|
||||
read_cylinder:
|
||||
push cx
|
||||
|
||||
mov bx, 0x0100 ;read sectors from head 0
|
||||
mov es, bx
|
||||
xor bx, bx ;es:bx = data buffer for read
|
||||
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
|
||||
mov cx, si ;what cyl. we are on is now in cx
|
||||
mov ch, cl ;ch = cyl. number
|
||||
mov cl, 1 ;cl = sector number 1-63
|
||||
xor dx, dx ;dh = head number
|
||||
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
|
||||
int 0x13
|
||||
|
||||
mov bx, 0x0100 ;now read sectors from head 1
|
||||
mov es, bx
|
||||
mov bx, 9216 ;es:bx = data buffer for read
|
||||
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
|
||||
mov cx, si ;what cyl. we are on is now in cx
|
||||
mov ch, cl ;ch = cyl. number
|
||||
mov cl, 1 ;cl = sector number 1-63
|
||||
mov dh, 1 ;dh = head number
|
||||
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
|
||||
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_carry
|
||||
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_carry:
|
||||
dec edx
|
||||
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 boot media", 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
|
||||
db 0x00
|
||||
|
||||
gdt_end:
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
gdtr32:
|
||||
dw gdt_end32-gdt32-1
|
||||
dd gdt32
|
||||
gdt32:
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
|
||||
KERNEL_CODE32 equ $-gdt32
|
||||
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 0x40 ;base 31:24
|
||||
|
||||
KERNEL_DATA32 equ $-gdt32
|
||||
db 0xff ;segment 16 = 4gb data
|
||||
db 0xff
|
||||
db 0x00
|
||||
db 0x00
|
||||
db 0x00
|
||||
db 0x92
|
||||
db 0xcf
|
||||
db 0x40
|
||||
|
||||
gdt_end32:
|
||||
|
||||
;------------------------------------------------------
|
||||
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:
|
||||
lgdt [gdtr32]
|
||||
jmp KERNEL_CODE32:pmode_offsetted+0xC0000000
|
||||
|
||||
pmode_offsetted:
|
||||
mov ax, KERNEL_DATA32
|
||||
mov es, ax
|
||||
mov ds, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
jmp KERNEL_CODE:BOOT_KERNEL_ADD+0xC0000000
|
||||
|
||||
kernel: db "KERNEL BIN", 0
|
||||
|
||||
|
||||
Reference in new issue
Block a user