loaderStart:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100
mov ax,_GRAPH_SEG_OFFSET_
mov gs,ax
mov dh,0
call displayStr
xor ah,ah
mov dl,[BS_DrvNum]
int 0x13
mov ax,KernelBase
mov es,ax
mov bx,0
mov ax,19
mov cl,14
call readSector
xor edi,edi
anotherFile:
xor esi,esi
cmp byte [rootEntryNum],0
je noLoader
nextChar:
mov al,byte [es:edi]
cmp byte [ds:loaderName+si],al
jne notThisFile
cmp si,10
je found
inc esi
inc edi
jmp nextChar
notThisFile:
shr edi,5
inc edi
shl edi,5
dec byte [rootEntryNum]
jmp anotherFile
noLoader:
mov dh,1
call displayStr
jmp $
found:
mov dh,2
call displayStr
mov ax,word [es:edi+(0x10)]
mov cl,1
push ax
mov ax,KernelBase
mov es,ax
mov ebx,KernelOffset
pop ax
readEntry:
cmp ax,0xfff
je readEnd
push ax
add ax,19+14-2
call readSector
pop ax
add ebx,512
call getFATEntry
jmp readEntry
readEnd:
jmp toProtectMode
displayStr:
; dh: String index
push cx
push ax
push bx
push esi
push edi
mov cx,STR_LEN
mov edi,dword [screenPo]
mov esi,bootStr
xor eax,eax
mov al,dh
mov bl,STR_LEN
mul bl
add esi,eax
.1:
lodsb
mov [gs:edi],al
inc edi
inc edi
loop .1
mov dword [screenPo],edi
pop edi
pop esi
pop bx
pop ax
pop cx
ret
readSector: ;ax: starting sector cl:number of sectors
; ah 0x2 al:number of sector to read
; bx: es:bx
; ch:cylinder cl:start sector
; dh:head num dl:Drive
push bp
mov bp,sp
push cx
push dx
push ax
mov dl,[BPB_SecPerTrk]
div dl
mov cl,ah
inc cl
mov ch,al
shr ch,1
mov dh,al
and dh,1
mov dl,byte [BS_DrvNum]
.1:
mov ah,2
mov al,byte [bp-2]
int 0x13
jc .1
pop ax
pop dx
pop cx
pop bp
ret
getFATEntry:
FATBaseInMem equ 0x7000
;ax is the entry number
;return ax is the next entry
push es
push bx
push dx
push cx
mov bx,FATBaseInMem
mov es,bx
mov bx,3
mul bx ;dx:ax
mov bx,2
div bx ;dx is the rest
push dx
xor dx,dx
mov bx,[BPB_BytsPerSec]
div bx
mov cl,2
xor bx,bx
add ax,1
call readSector
mov bx,dx; mov byte index
pop dx
xor ax,ax
cmp dx,0
jne oddPart
mov ax,word [es:bx]
and ax,0x0fff
jmp after
oddPart:
mov ax,word [es:bx]
shr ax,4
after:
pop cx
pop dx
pop bx
pop es
ret
toProtectMode:
jmp start
%macro Descriptor 3
dw %2 & 0xffff
dw %1 & 0xffff
db (%1 >> 16) & 0xff
dw ((%2 & 0x0f0000) >> 8) | (%3 & 0xf0ff)
db (%1 >> 24) & 0xff
%endmacro
DummyGDT: Descriptor 0,0,0
CodeGDT: Descriptor 0,0xfffff,1100000010011010b
DataGDT: Descriptor 0,0xfffff,1000000010010010b
ScreenGDT: Descriptor 0xb8000,0xffff,0000000010010010b
GDTPtr dw $-DummyGDT-1
dd 0x9000*0x10+DummyGDT
CodeSelector equ CodeGDT-DummyGDT
DataSelector equ DataGDT-DummyGDT
ScreenSelector equ ScreenGDT-DummyGDT
start:
call killMotor
cli
mov dh,2
call displayStr
lgdt [GDTPtr]
in al,0x92
or al,10b
out 0x92,al
mov eax,cr0
or eax,1
mov cr0,eax
jmp dword CodeSelector:(0x9000*0x10+ProtectMode)
killMotor:
push dx
mov dx,0x3f2
mov al,0
out dx,al
pop dx
ret
[bits 32]
ProtectMode:
mov ax,ScreenSelector
mov gs,ax
xor edi,edi
.again:
inc byte [gs:edi]
jmp .again