use16
;estoy en cs:0 offset:7c00
org 0x7c00
	jmp inicio
	nop

		db  53h,59h,53h,4Ch,49h,4Eh,55h,58h	;8 bytes
byteporsector	dw	0200h		;bytes por sector
secporcluster	db	08h		;sectores por cluster
reservados	dw	0020h		;sectores reservados
fats		db	02h		;numero de fat's
		dw	0		;entradas en root
		dw	0		;sectores
		db	0F8h		;descriptor
		dw	00h		;sectores por fat
secportrack	dw	003Eh		;sectores por track
cabezas		dw	7Ch		;cabezas
ocultos		dd	0		;sectores ocultos
		dd	00776B92h	;total de sectores
secdefat	dd	1DD0h		;sectores por fat en volumenes grandes
		dw	0		;flags??
		dw	0		;version
first 		dd	02h		;primer cluster del directorio root
		dw	01h		;FS info sector
		dw	06h		;copia de boot sector
		db	'hujikolpgyhu'	; 12 bytes
		db	0		;bios drive
		db	0		;1 byte
		db	29h		;boot sign
		dd	10B08CD1h	;SN
		db	4Dh,31h,20h,00h,00h,00h,00h,00h,00h,00h,00h	;etiqueta
		db	'FAT32   '	;sistema de archivos
inicio:
	xor	ax,	ax
	mov	ds,	ax
	mov	ss,	ax
	mov	es,	ax
	mov	sp,	0x7c00
	mov	[driver_numero],dl
	
	mov	bx,	55aah
	mov	ah,	41h
	int	013h
	jc	no_soportado
	
;calcular el primer sector de datos
	xor	edx,	edx			;preparo para multiplicar
	movzx	eax,	byte [fats]		;multiplico la cantidad de fat
	mul	dword [secdefat]		;por el numero de sectores por fat
	movzx	ebx,	word [reservados]
	add	eax,	ebx			;sumo con los sectores reservados
	add	eax,	[ocultos]		;mas los ocultos
	mov	[primer_sector_de_datos], eax	;guardo

;calcular el primer sector de directorio root
try:	mov	eax,	[first]
;traer a memoria
	mov	bx, 0x0700	;bufer lectura root
	call	traer
	; hasta aqui todo bien
	mov	si, 0x0700
	xor	dx,dx
	movzx	ax,[secporcluster]
	mul	[byteporsector]
	mov	[byteporcluster],ax
	add	ax,si
loop_compara_entrada_directorio:
  push si
  mov cx,11 ;file name
  mov di, nucleo
  rep cmpsb
  pop si
  je encontrado
  cmp	[si],byte 0
  je	no_encontrado
  add si,32
  cmp ax,si
  ja loop_compara_entrada_directorio
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;									;;
;;  aqui deberia ir el codigo para cargar el siguiente cluster de root	;;
;;   pero por ahora no es necesario desde que el nucleo estara cargado	;;
;;  		siempre en la primera entrada de root 			;;
;;									;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


no_encontrado:
	mov	si,no_esta
	jmp	asd
no_esta		db 13,10,'no esta '
nucleo		db 'NUCLEO  SYS',13,10,00h
rty 		db 'pc no soporta extencion de lectura',00h
no_soportado:
	mov	si, rty
asd:	call 	mensaje
	jmp 	$

encontrado:
;cargar nucleo en memoria 1000:0 lineal 0x10000
;obtener primer cluster
	mov	ax,[si+20]
	shl	eax,16
	mov	ax,[si+26]
	xor	bx,bx
otrom:
	mov	[actualbx],bx
	mov	cx,0x1000
	push	es
	mov	es,cx
	push	eax
	call	traer
	pop	eax
	pop	es
	
;obtener siguiente cluster
	mov 	ebx,128
	xor 	edx,edx
	div 	ebx
	movzx 	ebx,word [reservados]
	add	eax,ebx
	movzx 	ebx,word [ocultos]
	add	eax,ebx
	mov	bx,0x0700
	push	dx
	call	traer_sec_log
	pop	dx
	shl	dx,2
	add	dx,0x0700
	mov	bx,dx
	mov	eax,dword[bx]
	cmp	eax,0x0ffffff7
	jae	ejecutar_nucleo
;call mostrar
	mov	bx,[actualbx]
	add	bx,[byteporcluster]
	jmp otrom
	
ejecutar_nucleo:
;mov ax,0310h
;mov cx,0004h
;mov dh,01
;mov dl,[driver_numero]
;push 0x1000
;pop es
;xor bx,bx
;int 13h


	push word 0x1000
	push word 0x00
	retf


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
traer:		; ->	eax cluster a leer
		;	es:bx bufer

	sub	eax, 2
	movzx	ecx,[secporcluster]
	xor	edx, edx
	mul	ecx
	add	eax,[primer_sector_de_datos] ;eax tiene el primer sector
	
traer_sec_log:
	mov	[dap],10h
	mov	[dap_ini],eax
	mov	[dap_off],bx
	mov	[dap_seg],es
	movzx	cx,[secporcluster]
	mov	[dap_sec],cx
	mov	si,dap
	mov	dl,[driver_numero]
	mov	ah,42h
	int	13h
	ret

 
mensaje:
push eax
push bx
  mov ah,0eh
  mov bx,07h
@@:
  lodsb
  or al,al
  jz @f
  int 010h
  jmp @b
@@:
pop bx
pop eax
ret


;otro db '$',00h
;mostrar:
;push si
;mov	si,otro
;call mensaje
;pop si
;ret

times 0x1fe-($-07c00h) db 0ffh
db 55h,0aah


;;;;;;;;;;; datos en ram, no en el sector;;;;;;;;;;;;;;;;;;;;;;;;;;
primer_sector_de_datos	dd 0
	driver_numero	db 0
		dap	db 10h
			db 00h
		dap_sec	dw 0h
		dap_off	dw 0h
		dap_seg	dw 0h
		dap_ini	dd 0h
			dd 0h
	byteporcluster	dw 0h
	actualbx	dw 0h
