;This is the second part of the Bootloader.
;@vimal

;Now that we have jumped to this point from the MBR
;our origin is 0x00:0x7E00;

[ORG 0x7E00]
[BITS 16]

;Our aim in this section:
;Scan the current drive, load the FAT into memory
;Present a prompt, for loading and executing a file.
;@vimal
;-To accomplish this, we need variables from the previous section also.
;So we might be referencing back and forth.
;Eg of vars: FAT entry at which sector

start:
	;Now, set our stack again.
	;WE have the following regs to set up:
	;es, ss, ds.
	;ES = Extended Segment
	;SS = Stack segment
	;DS = Data Segment
	;The memory regions available to us:
	;0xF000:FFFF = 0xFFFFF, is the maximum value accessible. (16 bit)
	
	
	mov si,msg1
	call printf
	
	;*************************************
	;Now copy the FAT variables, important
	;*************************************
	cld 			;Clear Direction flags
	xor ax,ax ;Copy FAT Variables
	mov ds,ax
	mov es,ax
	mov si,0x7C00
	mov di,fat_var
	;Copy DS:SI to ES:DI
	mov cx,0x5A			;Counter. 90 bytes
	rep movsb
	;*************************************
	
	mov si,msg_done
	call printf
	
		
	;Debug Now display OEMID for testing purposes
	mov si,OEMID
	call printf
		
	call load_fat			;Loads the FAT into memory
	
	mov si,msg_disp_hello
	call printf
	
	call _terminal_loop ;The main loop function
	
	hlt	;Stop
	
;****************************************
;_terminal_loop
;****************************************
_terminal_loop:
	
__loop:
	mov si,prompt
	call printf
	mov si,msg_buffer
	mov byte [ds:si],0	;Flush out the previous input
	call gets				;gets a string into the buffer 
	
	mov si,msg_buffer
	cmp byte [ds:si],'d'
	je dump
	jmp __loop
	
	ret
;****************************************
;dump function
;****************************************
dump:
	;Dumps the FAT Cache
	call endl
	mov si,FS_Type
	call printf
	ret
	;mov cx,[Size_Of_FAT_Cache]
	;mov si,FAT_Cache
;_dump_loop:
	;mov al,byte [ds:si]
	;mov ah,0x0e
	;int 0x10
	;inc si
	;dec cx
	;or cx,cx
	;jz dump_end
	;jmp _dump_loop
	;call printf
	
dump_end:
	ret
	
;****************************************
;endl function
;****************************************
endl:
	mov al,0x0d
	call putch
	mov al,0x0a
	call putch
	ret
	
;****************************************
;gets function
;****************************************
gets:
	call getch
	cmp al,0x0d		;enter?
	je gets_end
	mov [ds:si],al
	inc si
	jmp gets
gets_end:
	ret
	
;****************************************
;getch function
;****************************************	
getch:
	mov ah,0
	int 0x16
	call putch
	ret
	
;****************************************
;putch
;****************************************
putch:
	mov ah,0x0e
	int 0x10

	ret

;****************************************
;Cache_FAT
;Caches the FAT, given the cluster number
;****************************************
Function_Cache_FAT:
	;The FileEntry has a cluster.
	;Cluster starts at Sector 	
;****************************************
;load_fat function.
;****************************************

load_fat:
	;pushad
	;First, we get the sector in which
	;the FAT resides, then, tell int 0x13 to load it
	mov si,load_fat_msg1
	call printf
	
	cld
	mov ah,0x02
	mov al,0x01				;No. of sectors
	mov cx,[No_Of_Boot_Sectors] ;Starting sector
	inc cx	;Since the above is the relative sector number
	mov dh,0
	mov dl,[BIOS_Drive_Number]
	mov bx,FAT_Cache
	int 0x13
	
	mov si,load_fat_msg2
	call printf
	;popad

	ret
;****************************************
;Cluster_To_Sector conversion
;call with eax = Cluster number.
;return with eax = Sector number
;Remember: Cluster 1 is the reserved region
;Cluster 2 is the root directory region. So, DATA starts from here
;****************************************
Cluster_To_Sector:
	mul byte [Sectors_Per_Cluster]
	add eax,No_Of_Boot_Sectors
	ret	
;****************************************
;printf function.
;****************************************
printf:
	lodsb
	or al,al
	jz printf_done
	mov ah,0x0e
	int 0x10
	jmp printf
printf_done:
	ret
;****************************************
;----------------------------------------
;Data part below
msg_disp_hello:
	db 0x0d,0x0a,'Welcome to the Kernel Loader. ',0x0d,0x0a
	db 'Supports loading from FAT32 file system',0x0d,0x0a,0
	
msg1:
	db 'Loading ...',0
msg2:
	db 'Complete.',0
msg_done: 
db 'Done copying values ... ',0
load_fat_msg1: db 0x0d,0x0a,'Loading 2 sectors of FAT ... ',0
load_fat_msg2: db 'Done!',0x0d,0x0a,0

fat_var:
	Jump_Code TIMES 3 db 0
	OEMID		TIMES 8 db 0
	Bytes_Per_Sector			dw 0
	Sectors_Per_Cluster			db 0
	No_Of_Boot_Sectors	dw 0 ;AKA No_Of_Reserved_Sectors
	No_Of_FATs dw 0
	No_Of_Root_Dir_Entries db 0
	Total_Sectors_16  dw 0
	Media_ID db 0
	No_Of_Sectors_Per_FAT dw 0
	No_Of_Sectors_Per_Track dw 0
	No_Of_Heads	dw 0
	No_Of_Hidden_Sectors dd 0
	Total_Sectors_32 dd 0
fat32_BPB: ;Bios Parameter Block
	No_Of_Sectors_Per_FAT32 dd 0
	Extension_Flags dw 0
	FS_Version dw 0 ;FS = FileSystem
	Start_Root_Cluster dd 0
	FS_Info dw 0
	Sector_Backup_Bootsector dw 0
	Reserved TIMES 12 db 0
	BIOS_Drive_Number db 0
	Reserved1 db 0
	Boot_Signature db 0
	Volume_ID dd 0
	Volume_Label TIMES 11 db 0
	FS_Type TIMES 8 db 0
db 0
Directory_Entry: ;DOS Format. 8.3 Names
	Entry_Name TIMES 8 db 0
	Entry_Extension TIMES 3 db 0
	Entry_Attribute db 0
	Entry_Create_Time TIMES 24 db 0
	Entry_Create_Date TIMES 16 db 0
	Entry_Last_Date TIMES 16 db 0
	Entry_Mod_Time TIMES 24 db 0
	Entry_Mod_Date TIMES 16 db 0
	Entry_Start_Cluster dd 0
	Entry_File_Size dd 0 

Directory_Entry_LFN: ;Long File Name format. Really nice hack, still maintains
										 ;compatibility with drivers that read only normal file names
	LFN_Ordinal_Field db 0
	LFN_Name TIMES 5 dw 0
	LFN_Attribute db 0
	LFN_Reserved1 db 0
	LFN_Checksum db 0 ;Simple Checksum algorithm. Calc using the DOS File name
	LFN_Name2 TIMES 6 db 0
	LFN_Cluster dw 0
	LFN_Name3 TIMES 4 db 0

;Checksum:
;Base = array[0]
;i = 1 to n
;Base += Base >> 1 + array[i]

FAT_Value dd 0		;Each entry is a 32 bit value. 
Size_Of_FAT_Cache dw 0x200
prompt db 0x0d,0x0a,'#:',0

msg_buffer TIMES 255 db 0

;Variables_To_Calculate:
;	Sector_FAT1 dw 0 
	;DATA Region IMMEDIATELY follows FAT copies

align 4
;*********************************************
FAT_Cache: ;Small cache to speed up operations. Stores 1 sectors of the FAT => .5 KB
	TIMES 512 db 0
;*********************************************

TIMES 2048-($-$$)-5 db 0	
db 'VIMAL'