;=========================================================;
; Fat12                                        01/04/2011 ;
;---------------------------------------------------------;
; LOAD functions                                          ;
;                                                         ;
; DexOS V0.05                                             ;
; (c) Craig Bamford, All rights reserved.                 ;
;=========================================================;

;=======================================================  ;
;  RunCommand12                                           ;
;=======================================================  ;  
RunCommand12:						  ;
	pushad						  ;               
	push	es					  ;
	push	ds					  ;
	mov	eax,RootDirBuffer			  ;
	mov	[RootDirBufferVar],eax			  ;
	mov	[FddSectorsLoadedCount],0		  ;
	mov	dword[F16FileSizeB],0                     ;
	mov	dword[LoadFileToAddress],edx		  ;
	mov	dword[NameOfFileToLoad],edi		  ;
	mov	ax,sys_data				  ;             
	mov	es,ax					  ;
	mov	[FileLoadCountUP],0			  ;             
	call	DirFillRootUSB				  ;                          
	jc	ErrorFloppyUP				  ;
	xor	ecx,ecx 				  ;                    
	mov	ax,[bpbRootEntries]			  ;                     
	mov	cx, 32					  ;                     
	mul	cx					  ;                     
	div	word [bpbBytesPerSector]		  ;             
	mov	[RootSizeUP],ax 			  ;
;=======================================================  ;
;  Root Dir Location - Reserved sectors + Fat sectors     ;
;=======================================================  ;                             
	xor	eax,eax 				  ;     
	mov	al, byte [bpbNumberOfFATs]		  ;             
	mul	word [bpbSectorsPerFAT] 		  ;             
	add	ax, word [bpbReservedSectors]		  ;             
	mov	[RootStartUP],ax			  ;     
;=======================================================  ;
;  Data start Reserved sectors + FAT sectors + Root       ;
;=======================================================  ;                       
	mov	cx,[RootSizeUP] 			  ;             
	add	ax,cx					  ;                     
	mov	[DataStartUP],ax			  ;                             
	mov	ax,sys_data				  ;                     
	mov	es,ax					  ;
	mov	ds,ax					  ;
	mov	edi,[RootDirBufferVar]			  ;
	mov	esi,dword[NameOfFileToLoad]		  ;
	mov	dx,[bpbRootEntries]			  ;
;=======================================================  ;
;  FindName.                                              ;
;=======================================================  ;  
FindNameUP:						  ;
	mov	cx,11					  ;
FindNameCycleFLUP:					  ;
	cmp	byte [es:edi],ch			  ;
	je	FindNameFailedFLUP			  ;                        
	pushad						  ;                    
	repe	cmpsb					  ;
	popad						  ;                    
	je	FindNameFoundFLUP			  ;
	add	edi, 32 				  ;
	dec	dx					  ;
	jnz	FindNameCycleFLUP			  ;                        
FindNameFailedFLUP:					  ;
	jmp	ErrorFindingNameFat12			  ;
FindNameFoundFLUP:					  ;
	mov	dx,word[es:edi+1Ah]			  ;            
	mov	word [clusterUP],dx			  ;
	push	edx					  ;
	mov	edx,dword[es:edi+1ch]			  ;
	mov	dword[F16FileSizeB],edx 		  ;
	pop	edx					  ; 
	xor	eax,eax 				  ;
	mov	ax,word [bpbSectorsPerFAT]		  ;
	shl	eax,9					  ;
	shr	eax,1					  ;
	cmp	eax,4086				  ;
	jae	LoadImageFat16UP			  ;
;=======================================================  ;
;  Load entire a program.                                 ;
;=======================================================  ;  
LoadImageUP:						  ;
	mov	ax,[clusterUP]				  ;                       
	mov	[FloppyTest],0				  ;                     
ReadNextClusterUP:					  ;
	call	ClusterLBAUP				  ;
	call	ReadSectorsUP				  ;
	jc	ErrorFloppyUP				  ;
;=======================================================  ;
;  compute next cluster.                                  ;
;=======================================================  ;  
	mov	ax,word[clusterUP]			  ;                     
	mov	cx,ax					  ;                     
	mov	dx,ax					  ;                             
	shr	dx,0x0001				  ;                             
	add	cx,dx					  ;             
	mov	esi,BpbFat				  ;  
	add	esi,512 				  ;
	add	esi,ecx 				  ;             
	mov	dx,word [ds:esi]			  ;                     
	test	ax,0x0001				  ;
	jnz	OddClusterUP				  ;
EvenClusterUP:						  ;
	and	dx,0000111111111111b			  ;             
	jmp	DoneUP					  ;
OddClusterUP:						  ;
	shr	dx,0x0004				  ;                             
DoneUP: 						  ;
	mov	word [clusterUP],dx			  ;               
	cmp	dx,0x0FF0				  ;             
	jb	LoadImageUP				  ;
	jmp	ExitSucsessUP				  ;
;=======================================================  ;
;  Fat16.                                                 ;
;=======================================================  ;  
LoadImageFat16UP:					  ;
	mov	ax,[clusterUP]				  ;
	mov	[FloppyTest],0				  ;
ReadNextClusterFat16UP: 				  ;
	call	ClusterLBAUP				  ;
	mov	[clusterSPCUP],ax			  ;
	xor	ecx,ecx 				  ;
	mov	cl,byte [bpbSectorsPerCluster]		  ;
ReadNextClusterFat16loopUP:				  ;
	push	ecx					  ;
	mov	[FloppyTest],0				  ;
	call	ReadSectorsUP				  ;
	jc	ErrorFloppyPopUP			  ;
	inc	[clusterSPCUP]				  ;
	mov	ax,[clusterSPCUP]			  ;
	pop	ecx					  ;
	loop	ReadNextClusterFat16loopUP		  ;
;=======================================================  ;
;  compute next cluster.                                  ;
;=======================================================  ;  
	xor	eax,eax 				  ;
	xor	ecx,ecx 				  ;
	mov	ax,word[clusterUP]			  ;
	mov	cx,ax					  ;
	add	ecx,eax 				  ;
	mov	esi,Fat 				  ;
	add	esi,ecx 				  ;
	mov	dx,word [ds:esi]			  ;
	mov	word [clusterUP],dx			  ;
	cmp	dx,0xFFF0				  ;
	jb	LoadImageFat16UP			  ;
;=======================================================  ;
;  ExitSucsess.                                           ;
;=======================================================  ;     
ExitSucsessUP:						  ;
	mov	[ErrorCode],0				  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ebx,dword[FddSectorsLoadedCount]	  ;
	mov	ecx,dword[F16FileSizeB] 		  ;
	mov	ah,0					  ;
	clc						  ;
	ret						  ;
;=======================================================  ;
;  ErrorFind.                                             ;
;=======================================================  ;  
ErrorFloppyPopUP:					  ;
	pop	ecx					  ;
ErrorFindUP:						  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ah,byte[ErrorCode]			  ;
	stc						  ;
	ret						  ;
;=======================================================  ;
;  ErrorFloppy.                                           ;
;=======================================================  ;   
ErrorFloppyUP:						  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ah,byte[ErrorCode]			  ;
	stc						  ;
	ret						  ;
;=======================================================  ;
;  Error file name.                                       ;
;=======================================================  ; 
ErrorFindingNameFat12:                                    ;
        mov     byte[ErrorCode],0xfc                      ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ah,byte[ErrorCode]			  ;
	stc						  ;
	ret						  ;
;=======================================================  ;
;  WriteFat12                                             ;
;=======================================================  ;  
WriteFat12:						  ;
	pushad						  ;               
	push	es					  ;
	push	ds					  ;
	mov	eax,RootDirBuffer			  ;
	mov	[RootDirBufferVar],eax			  ;
	mov	[FddSectorsLoadedCount],0		  ;
	mov	dword[F16FileSizeB],0			  ;
        mov     edi,NameOfFileToLoadBufferFat16 
	mov	dword[NameOfFileToLoad],edi		  ;
	mov	ax,18h   				  ;             
	mov	es,ax					  ;
	mov	[FileLoadCountUP],0			  ;             
	xor	ecx,ecx 				  ;                    
	mov	ax,[bpbRootEntries]			  ;                     
	mov	cx, 32					  ;                     
	mul	cx					  ;                     
	div	word [bpbBytesPerSector]		  ;             
	mov	[RootSizeUP],ax 			  ;
;=======================================================  ;
;  Root Dir Location - Reserved sectors + Fat sectors     ;
;=======================================================  ;                             
	xor	eax,eax 				  ;     
	mov	al, byte [bpbNumberOfFATs]		  ;             
	mul	word [bpbSectorsPerFAT] 		  ;             
	add	ax, word [bpbReservedSectors]		  ;             
	mov	[RootStartUP],ax			  ;     
;=======================================================  ;
;  Data start Reserved sectors + FAT sectors + Root       ;
;=======================================================  ;                       
	mov	cx,[RootSizeUP] 			  ;             
	add	ax,cx					  ;                     
	mov	[DataStartUP],ax			  ;                             
	mov	ax,18h				          ;                     
	mov	es,ax					  ;
	mov	ds,ax					  ;
	mov	edi,RootDirBuffer			  ;
	mov	esi,dword[NameOfFileToLoad]		  ;
	mov	dx,[bpbRootEntries]			  ;
;=======================================================  ;
;  FindName.                                              ;
;=======================================================  ;  
FindNameUPWriteFat12:					  ;
	mov	cx,11					  ;
FindNameCycleFLUPWriteFat12:				  ;
	cmp	byte [es:edi],ch			  ;
	je	FindNameFailedFLUPWriteFat12		  ;                        
	pushad						  ;                    
	repe	cmpsb					  ;
	popad						  ;                    
	je	FindNameFoundFLUPWriteFat12		  ;
	add	edi, 32 				  ;
	dec	dx					  ;
	jnz	FindNameCycleFLUPWriteFat12		  ;                        
FindNameFailedFLUPWriteFat12:				  ;
	jmp	ErrorFindUPWriteFat12			  ;
FindNameFoundFLUPWriteFat12:				  ;
	mov	dx,word[es:edi+1Ah]			  ;            
	mov	word [clusterUP],dx			  ;
	xor	eax,eax 				  ;
	mov	ax,word [bpbSectorsPerFAT]		  ;
	shl	eax,9					  ;
	shr	eax,1					  ;
;=======================================================  ;
;  Load entire a program.                                 ;
;=======================================================  ;  
LoadImageUPWriteFat12:					  ;
	mov	ax,[clusterUP]				  ;                       
	mov	[FloppyTest],0				  ;                     
ReadNextClusterUPWriteFat12:				  ;
	call	ClusterLBAUP				  ;
	call	WriteSectorsUP12			  ;
	jc	ErrorFloppyUPWriteFat12 		  ;
;=======================================================  ;
;  compute next cluster.                                  ;
;=======================================================  ;  
	mov	ax,word[clusterUP]			  ;                     
	mov	cx,ax					  ;                     
	mov	dx,ax					  ;                             
	shr	dx,0x0001				  ;                             
	add	cx,dx					  ;             
	mov	esi,BpbFat				  ;  
	add	esi,512 				  ;
	add	esi,ecx 				  ;             
	mov	dx,word [ds:esi]			  ;                     
	test	ax,0x0001				  ;
	jnz	OddClusterUPWriteFat12			  ;
EvenClusterUPWriteFat12:				  ;
	and	dx,0000111111111111b			  ;             
	jmp	DoneUPWriteFat12			  ;
OddClusterUPWriteFat12: 				  ;
	shr	dx,0x0004				  ;                             
DoneUPWriteFat12:					  ;
	mov	word [clusterUP],dx			  ;               
	cmp	dx,0x0FF0				  ;             
	jb	LoadImageUPWriteFat12			  ;
	jmp	ExitSucsessUPWriteFat12 		  ;
;=======================================================  ;
;  ExitSucsess.                                           ;
;=======================================================  ;     
ExitSucsessUPWriteFat12:				  ;
	mov	[ErrorCode],0				  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ebx,dword[FddSectorsLoadedCount]	  ;
	clc						  ;
	ret						  ;
;=======================================================  ;
;  ErrorFind.                                             ;
;=======================================================  ;  
ErrorFloppyPopUPWriteFat12:				  ;
	pop	ecx					  ;
ErrorFindUPWriteFat12:					  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ah,byte[ErrorCode]			  ;
	stc						  ;
	ret						  ;
;=======================================================  ;
;  ErrorFloppy.                                           ;
;=======================================================  ;   
ErrorFloppyUPWriteFat12:				  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ah,byte[ErrorCode]			  ;
	stc						  ;
	ret						  ;

;=======================================================  ;
;  ReadSectors.                                           ;
;=======================================================  ;  
WriteSectorsUP12:					  ;
	pushad						  ;
	push	es					  ;
	push	ds					  ;
	pushad						  ;
	push	es					  ;
	push	ds					  ;
	mov	ecx,SectorSize				  ;
	mov	ax,18h					  ;
	mov	ds,ax					  ;
	mov	es,ax					  ;
	mov	edi,OffsetDma2Buffer1			  ;                     
	mov	esi,dword[LoadFileFromAddressFat16]       ;
	add	esi,[FileLoadCountUP]			  ;
	rep	movsb					  ;
	add	[FileLoadCountUP],SectorSize		  ;
	add	[FddSectorsLoadedCount],1		  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	call	LBAcHsUP				  ;
	push	ax					  ;
	mov	ch,byte [absoluteTrackUP]		  ;
	mov	cl,byte [absoluteSectorUP]		  ;  
	mov	dh,byte [absoluteHeadUP]		  ;       
	mov	dl,byte [bsDriveNumber] 		  ;
	pop	ax					  ;
	call	FddWriteB				  ;                            
	jc	@f					  ;
;=======================================================  ;
;  ExitSucsess.                                           ;
;=======================================================  ;  
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	clc						  ;
	ret						  ;
;=======================================================  ;
;  Error.                                                 ;
;=======================================================  ;  
@@:							  ;
	mov	[RealModeErrorCode],ax			  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ax,[RealModeErrorCode]			  ;
	stc						  ;
	ret						  ;

;=======================================================  ;
;  ReadSectors.                                           ;
;=======================================================  ;  
ReadSectorsUP:						  ;
	pushad						  ;
	push	es					  ;
	push	ds					  ;
	call	LBAcHsUP				  ;
TryReadFloppyAgainUP:					  ;
	mov	ch,byte [absoluteTrackUP]		  ;
	mov	cl,byte [absoluteSectorUP]		  ;  
	mov	dh,byte [absoluteHeadUP]		  ;       
	mov	dl,byte [bsDriveNumber] 		  ;
	call	FddReadB				  ;                                    
	jc	@f					  ;
FloppyReadOKUP: 					  ;
	mov	cx,512					  ;
	mov	ax,sys_data				  ;
	mov	ds,ax					  ;
	mov	es,ax					  ;
	mov	esi,OffsetDma2Buffer			  ;
	mov	edi,[LoadFileToAddress] 		  ;  
	add	edi,[FileLoadCountUP]			  ;
	rep	movsb					  ;
	add	[FileLoadCountUP],512			  ;
	add	[FddSectorsLoadedCount],1		  ;
;=======================================================  ;
;  ExitSucsess.                                           ;
;=======================================================  ;  
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	clc						  ;
	ret						  ;
;=======================================================  ;
;  Error.                                                 ;
;=======================================================  ;  
@@:							  ;
	mov	[RealModeErrorCode],ax			  ;
	pop	ds					  ;
	pop	es					  ;
	popad						  ;
	mov	ax,[RealModeErrorCode]			  ;
	stc						  ;
	ret						  ;
;=======================================================  ;
;  LBAcHs.                                                ;
;=======================================================  ;         
LBAcHsUP:						  ;            
	div	word [bpbSectorsPerTrack]		  ;             
	inc	dl					  ;     
	mov	byte [absoluteSectorUP],dl		  ;
	xor	dx,dx					  ;     
	div	word [bpbHeadsPerCylinder]		  ;
	mov	byte [absoluteHeadUP],dl		  ;
	mov	byte [absoluteTrackUP],al		  ;
	ret						  ;

;=======================================================  ;
;  ClusterLBA.                                            ;
;=======================================================  ;  
ClusterLBAUP:						  ;
	sub	ax,2					  ;                             
	xor	cx,cx					  ;                             
	mov	cl,byte [bpbSectorsPerCluster]		  ;             
	mul	cx					  ;                     
	add	ax, word [DataStartUP]			  ;            
	ret						  ;

;=======================================================  ;
;  ReleaseClusterChain12.                                 ;
;=======================================================  ;  
ReleaseClusterChain12:                                    ;
	pushad                                            ;
	mov     word [clusterUP],ax                       ;
ReleaseClusterChainLoop12:                                ;
	mov     ax,word [clusterUP]                       ;
	mov     bx,0x00                                   ;
	call    UpdateClusterValue12                      ;
	mov     dx,[ClustOrigValue]                       ;
	mov     word [clusterUP],dx			  ;  
	cmp     dx,0x0FF0 			          ;	
	jb      ReleaseClusterChainLoop12                 ;
;=======================================================  ;
;  Exit.                                                  ;
;=======================================================  ;  
ReleaseClusterChainExit12:                                ;
	popad                                             ;
	ret                                               ;

;=======================================================  ;
;  data                                                   ;
;=======================================================  ;  
RootDirBufferVar  dd 0					  ;
RootStartUP	  dw 0					  ;
DataStartUP	  dw 0					  ;
clusterUP	  dw 0					  ;
clusterSPCUP	  dw 0					  ;
absoluteSectorUP  db 0					  ;
absoluteHeadUP	  db 0					  ;
absoluteTrackUP   db 0					  ;
RealModeErrorCode dw 0					  ;
RootSizeUP	  dw 0					  ;
FileLoadCountUP   dd 0					  ;
LoadFileToAddress dd 0					  ;
NameOfFileToLoad  dd 0					  ;
NameOfFileToLoadBuffer	 rb   16			  ;
