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