;=========================================================;
; Fdd                                            11/12/03 ;
;---------------------------------------------------------;
; Pmode floppy disk driver.                               ;                          
;                                                         ;
;=========================================================;
;include 'FddInfo.inc'
;====================================================;
; Fdd motor off         ;TURNS MOTOR OFF WITH DELAY. ;
;====================================================;
Fdd_motor_off:
	push  edx
	push  eax
	mov   dx,DorReg 				
	mov   al,0
	out   dx,al
	mov   [MotorOn],0  
	pop   eax
	pop   edx			     
	ret

;====================================================;
; Fdd Motor On           ;TURNS MOTOR ON WITH DELAY. ;
;====================================================;
FddMotorOn:
	push  edx
	push  eax					      
	mov   dx,DorReg 				
	mov   al,00011100b				
	out   dx,al
	mov   [Timer],5 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov   [MotorOn],1  
	pop   eax
	pop   edx				   
	ret


 ;----------------------------------------------------;
 ; Changed         ;Check for disk change or no disk. ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          none.                                     ;
 ;  Output:                                           ;
 ;          AH  = Status                              ;
 ;          CF  = 0 If successful                     ;
 ;              = 1 If error                          ;
 ;                                             (100%) ;
 ;....................................................;
Changed:
	pushad
	cmp   byte[MissChangTest],1
	je    notchanging
	test  [MotorOn],1
	jnz   @f
	call  FddMotorOn			       
@@:
	mov   [FddErrorStatus],0
	mov   dx,CcrReg
	in    al,dx
	test  al,10000000b			       ; Bit 7 is change line, 0=not changed
	jz    notchanging
	mov   ch,7				       ; move to reset the flipflop
	cmp   [ResultC],ch
	jne   @f
	inc   ch
@@:
	mov   [cTrack],ch
	call  FddReadWriteSeek			       ; It changed, we have to have a head
	call  FddRecalibrate			       ; Now bring us back home
	mov   [Timer],2
	mov   [TimerOn],1				
	call  WaitTimer
	mov   dx,CcrReg 			       ; Read change line again
	in    al,dx				       ;
	test  al,10000000b			       ; Bit 7 is change line, 0=not changed
	mov   [FddErrorStatus],FddChanged	       ; Assume a disk present
	jz    missing				       ; yes, get out
	mov   [FddErrorStatus],FddTimeOut	       ; Else no disk
missing:
	popad
	stc					       ; We have an error
	mov   ah,[FddErrorStatus]
	ret
notchanging:
	popad
	clc					       ; Life is fine
	ret


 ;----------------------------------------------------;
 ; FddReSet                         ;ResetController. ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          none.                                     ;
 ;  Output:                                           ;
 ;                                                    ;
 ;                                             (100%) ;
 ;....................................................;
FddReSet:
	mov   [MotorOn],0				
	mov   dx,DorReg 				
	mov   al,00001000b				
	out   dx,al				       
	mov   [Timer],5 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov   dx,CcrReg 				
	mov   al,00000000b				
	out   dx,al
	mov   dx,DorReg 				
	or    al,00001100b				
	out   dx,al
	mov   [done],0					
	call  WaitDone					
	jc    ResetControllerError			
	mov   cx,0x04					
SenseStatusLoop:					
	call  FdcSendByteReady				
	jc    ResetControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 			       
	mov   dx,DtReg					
	mov   al,0x08					
	out   dx,al
	call  FdcGetByteReady			       
	jc    ResetControllerError			
	mov   dx,DtReg					
	in    al,dx
	call  FdcGetByteReady			       
	jc    ResetControllerError		       
	mov   dx,DtReg					
	in    al,dx
	loop  SenseStatusLoop				
	call  FdcSendByteReady				
	jc    ResetControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1			       
	call  WaitTimer 				
	mov   dx,DtReg				       
	mov   al,0x03				       
	out   dx,al 
	call  FdcSendByteReady			       
	jc    ResetControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1			       
	call  WaitTimer 				
	mov  dx,DtReg					
	mov  al,0xDF					
	out  dx,al 
	call  FdcSendByteReady			       
	jc    ResetControllerError		       
	mov   [Timer],1 			       
	mov   [TimerOn],1				
	call  WaitTimer 			       
	mov  dx,DtReg					
	mov  al,0x02					
	out  dx,al
ResetControllerSuccsess:
	clc
	ret
ResetControllerError:
	stc
	ret

 ;----------------------------------------------------;
 ; Fdd seek                                           ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          none.                                     ;
 ;  Output:                                           ;
 ;                                                    ;
 ;                                             (100%) ;
 ;....................................................;
FddReadWriteSeek:
	pushad
	mov   al,[ResultC]			       
	cmp   [cTrack],al				
	je    FddSeekControllerSuccsess 		
	call  FdcSendByteReady				
	jc    FddSeekControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov   dx,DtReg					
	mov   al,0x0F					
	out   dx,al
	call  FdcSendByteReady				
	jc    FddSeekControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov  dx,DtReg					
	mov  al,[DriveHead]				
	out  dx,al 
	call  FdcSendByteReady				
	jc    FddSeekControllerError			
	mov   [Timer],1 				
	mov   [TimerOn],1			       
	call  WaitTimer 			       
	mov  dx,DtReg				       
	mov  al,[cTrack]					    
	out  dx,al
	mov   [done],0					
	call  WaitDone					
	jc    FddSeekControllerError			
	call  FdcSendByteReady			       
	jc    FddSeekControllerError		       
	mov   [Timer],1 				
	mov   [TimerOn],1			       
	call  WaitTimer 				
	mov   dx,DtReg				       
	mov   al,0x08					
	out   dx,al
	call  FdcGetByteReady				
	jc    FddSeekControllerError			
	mov   dx,DtReg					
	in    al,dx
	mov   ah,al				       
	call  FdcGetByteReady			       
	jc    FddSeekControllerError			
	mov   dx,DtReg				       
	in    al,dx
	test  ah,00100000b				
	jz    FddSeekControllerError			
	test  ah,10000000b				
	jnz    FddSeekControllerError			
FddSeekControllerSuccsess:				
	popad
	clc
	ret
FddSeekControllerError: 			       
	popad
	stc
	ret

 ;----------------------------------------------------;
 ; Fdd recalibrate                                    ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          none.                                     ;
 ;  Output:                                           ;
 ;                                                    ;
 ;                                             (100%) ;
 ;....................................................;
FddRecalibrate:
	test  [MotorOn],1
	jnz   @f
	call  FddMotorOn				
@@:
	call  FdcSendByteReady				
	jc    FddRecalibrateError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov   dx,DtReg					
	mov   al,0x07					
	out   dx,al
	call  FdcSendByteReady				
	jc    FddRecalibrateError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov  dx,DtReg					
	mov  al,00h					
	out  dx,al 
	mov   [done],0					
	call  WaitDone					
	jc    FddRecalibrateError			
	call  FdcSendByteReady				
	jc    FddRecalibrateError			
	mov   [Timer],1 				
	mov   [TimerOn],1				
	call  WaitTimer 				
	mov   dx,DtReg				       
	mov   al,0x08					
	out   dx,al
	call  FdcGetByteReady				
	jc    FddRecalibrateError			
	mov   dx,DtReg					
	in    al,dx
	mov   ah,al					
	call  FdcGetByteReady				
	jc    FddRecalibrateError			
	mov   dx,DtReg					
	in    al,dx
	test  ah,00100000b				
	jz    FddRecalibrateError			
	test  ah,00010000b				
	jnz   FddRecalibrateError			
FddRecalibrateSuccsess: 				
	mov [ResultC],0 				
	clc
	ret
FddRecalibrateError:					
	stc
	ret

 ;----------------------------------------------------;
 ; FddReadPM                ; Pmode fdd read function ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          CH  = Track/cylinder                      ;
 ;          CL  = Sector                              ;
 ;          DH  = Head                                ;
 ;          DL  = Drive (only A: drive used 00 )      ;
 ;                                                    ;
 ;  Output:                                           ;
 ;          AH  = Status                              ;
 ;          AL  = Sector number read                  ;
 ;          CF  = 0 If successful                     ;
 ;              = 1 If error                          ;
 ;                                             (100%) ;
 ;....................................................;
FddReadPM:
	pushad
	and   dh,00000001b				
	mov   [Head],dh 				
	shl   dh,2					
	mov   [DriveHead],dh				
	mov   [FddErrorStatus],0x04			
	cmp   ch,0x51					
	jae   FddReadErrorT
	mov   [cTrack],ch				
	cmp   cl,0x13					 
	jae   FddReadErrorT
	mov   [Sector],cl				
	mov   [FddMTimer],0				
	and   [FddMotorTimer0n],0			
	test  [MotorOn],1				
	jnz   @f
	call  FddMotorOn			       
@@:							
	mov   dx,CcrReg 				
	mov   al,00000000b				
	out   dx,al
	mov   [FddErrorStatus],0x80			
	;call  FddRecalibrate                           
	;jc    FddReadError
	xor    ecx,ecx					
	mov    cx,3					
@@:
	call  FddReadWriteSeek				
	jnc   @f					
	loop  @b
	jmp   FddReadErrorT
@@:
	mov   dx,MsReg					
	in    al,dx 
	test  al,00100000b				
	jnz   FddReadErrorT
	Call	Setup_DMA2_Read 			
;******************************
; 1. Read Sector Command
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,0xe6					
	out   dx,al
;******************************
; 2. Drive
;******************************        
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	mov   al,[DriveHead]				 
	out   dx,al
;******************************
; 3. Cylinder
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,[cTrack]				 
	out   dx,al
;******************************
; 4. Head
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,[Head] 				
	out   dx,al
;******************************
; 5. Sector
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,[Sector]				
	out   dx,al
;******************************
; 6. Sector Size
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,0x02					
	out   dx,al
;******************************
; 7. Sectors to a track
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	mov   al,0x12					
	out   dx,al
;******************************
; 8. Gap Length
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	mov   al,0x1B				       
	out   dx,al
;******************************
; 9. Data Length
;******************************
	call  FdcSendByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					 
	mov   al,0xFF					 
	out   dx,al 
;******************************                         
; Wait floppy int
;******************************
	mov   [done],0					
	call  WaitDone					
	jc    FddReadErrorT
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST0],al				
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST1],al				
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST2],al				
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	cmp   [cTrack],al				
	jne    @f
	mov   [ResultC],al				
@@:
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultH],al				
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultR],al			       
	call  FdcGetByteReady				
	jc    FddReadErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultN],al				
	test  [ResultST0],11000000b			
	jnz   FddReadErrorT
	mov   [FddErrorStatus],0x00			
FddReadSuccsess1:
	popad
	mov   ah,[FddErrorStatus]			
	mov   al,[ResultR]
	clc
	ret
FddReadErrorT:
	popad
	mov   ah,[FddErrorStatus]			
	stc
	ret


 ;----------------------------------------------------;
 ; FddWritePM             ; Pmode write read function ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;          CH  = Track/cylinder                      ;
 ;          CL  = Sector                              ;
 ;          DH  = Head                                ;
 ;          DL  = Drive (only A: drive used 00 )      ;
 ;                                                    ;
 ;  Output:                                           ;
 ;          AH  = Status                              ;
 ;          AL  = Sector number read                  ;
 ;          CF  = 0 If successful                     ;
 ;              = 1 If error                          ;
 ;                                             (100%) ;
 ;....................................................;
FddWritePM:
	pushad
	and   dh,00000001b				
	mov   [Head],dh 				
	shl   dh,2					
	mov   [DriveHead],dh				
	mov   [FddErrorStatus],0x04			
	cmp   ch,0x51					
	jae   FddWriteErrorT
	mov   [cTrack],ch				
	cmp   cl,0x13					 
	jae   FddWriteErrorT
	mov   [Sector],cl				
	mov   [FddMTimer],0				
	and   [FddMotorTimer0n],0			
	test  [MotorOn],1				
	jnz   @f
	call  FddMotorOn			       
@@:							
	mov   dx,CcrReg 				
	mov   al,00000000b				
	out   dx,al
	mov   [FddErrorStatus],0x80			
	;call  FddRecalibrate                           
	;jc    FddWriteError
	xor    ecx,ecx					
	mov    cx,3					
@@:
	call  FddReadWriteSeek				
	jnc   @f					
	loop  @b
	jmp   FddWriteErrorT
@@:
	mov   dx,MsReg					
	in    al,dx 
	test  al,00100000b				
	jnz   FddWriteErrorT
	Call  Setup_DMA2_Write			       
;******************************
; 1. Write Sector Command
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,0xe5					
	out   dx,al
;******************************
; 2. Drive
;******************************        
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	mov   al,[DriveHead]				 
	out   dx,al
;******************************
; 3. Cylinder
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,[cTrack]				 
	out   dx,al
;******************************
; 4. Head
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,[Head] 				
	out   dx,al
;******************************
; 5. Sector
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,[Sector]				
	out   dx,al
;******************************
; 6. Sector Size
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,0x02					
	out   dx,al
;******************************
; 7. Sectors to a track
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	mov   al,0x12					
	out   dx,al
;******************************
; 8. Gap Length
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	mov   al,0x1B				       
	out   dx,al
;******************************
; 9. Data Length
;******************************
	call  FdcSendByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					 
	mov   al,0xFF					 
	out   dx,al 
;******************************                         
; Wait floppy int
;******************************
	mov   [done],0					
	call  WaitDone					
	jc    FddWriteErrorT
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST0],al				
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST1],al				
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultST2],al				
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	cmp   [cTrack],al				
	jne    @f
	mov   [ResultC],al				
@@:
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultH],al				
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultR],al			       
	call  FdcGetByteReady				
	jc    FddWriteErrorT
	mov   dx,DtReg					
	in    al,dx
	mov   [ResultN],al				
	test  [ResultST0],11000000b			
	jnz   FddWriteErrorT
	mov   [FddErrorStatus],0x00			
FddWriteSuccsessT:
	popad
	mov   ah,[FddErrorStatus]			
	mov   al,[ResultR]
	clc
	ret
FddWriteErrorT:
	popad
	mov   ah,[FddErrorStatus]			
	stc
	ret

 ;----------------------------------------------------;
 ; FddReadBios                                        ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;       ES:BX  = Buffer address                      ;
 ;          CH  = Track/cylinder                      ;
 ;          CL  = Sector                              ;
 ;          DH  = Head                                ;
 ;          DL  = Drive                               ;
 ;          AL  = Number of sectors (normaly 1)       ;
 ;          AH  = ReadSector(02h)                     ;
 ;                                                    ;
 ;  Output:                                           ;
 ;          AH  = Status                              ;
 ;          AL  = Sector number read                  ;
 ;          CF  = 0 If successful                     ;
 ;              = 1 If error                          ;
 ;                                             (100%) ;
 ;....................................................;
FddReadB:
	pushad
	push  es
	push  ds
	mov   [FloppyTest],0
	;and   dh,00000001b
	mov   [Head],dh 				
	;mov   [DriveHead],dh                            
	mov   [FddErrorStatus],0x04			
	;cmp   ch,0x51                                   
	;jae   FddReadError                              
	mov   [cTrack],ch				
	;cmp   cl,0x13                                    
	;jae   FddReadError                              
	mov   [Sector],cl   
	mov   al,01
	;mov   dl,[FddDrive]
	mov   byte[RealModeError],0
	mov   word[RealModeAX],ax
	mov   word[RealModeBX],bx
	mov   word[RealModeCX],cx
	mov   word[RealModeDX],dx
	call  mask_irqs
	mov   al,11h
	out   0x20,al
	out   0xA0,al
	mov   al,0x08
	out   0x21,al
	mov   al,0x70
	out   0xA1,al
	mov   al,4
	out   0x21,al
	mov   al,2
	out   0xA1,al
	mov   al,1
	out   0x21,al
	out   0xA1,al
	jmp   0x20:do_16Int13h
use16
do_16Int13h:	
	mov   ax,0x28
	mov   ds,ax
	mov   ss,ax
	nop
 ;----------------------------------------------------;
 ; push real-mode CS:IP.                              ;
 ;----------------------------------------------------;  
	mov   bx,[RealModeCS]
	push  bx
	lea   bx,[do_rmInt13h]
	push  bx
 ;----------------------------------------------------;
 ; clear PE [pmode enable] bit and return to Rmode.   ;
 ;----------------------------------------------------; 
	mov   eax,cr0
	and   al,0xFE
	mov   cr0,eax
	retf
 ;----------------------------------------------------;
 ;  16-bit real mode again                            ;
 ;----------------------------------------------------;                                   
do_rmInt13h:	
	mov   ax,cs
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   fs,ax
	mov   gs,ax
 ;----------------------------------------------------;
 ; point to real-mode IDTR.                           ;
 ;----------------------------------------------------; 
	lidt  [ridtr]
	push  cs
	pop   ds
	push  ds
	pop   es
 ;----------------------------------------------------;
 ;  Do real mode interrupts                           ;
 ;----------------------------------------------------;
TryReadFloppyAgainRM:
	mov   ax,word[RealModeAX]
	mov   bx,word[RealModeBX]
	mov   cx,word[RealModeCX]
	mov   dx,word[RealModeDX]   
	mov   bx,OffsetDma2Buffer 
	mov   ah,02h
	int   13h
	jnc   @f

	inc   [FloppyTest]
	cmp   [FloppyTest],4
	jae   RmFddRReadError
	mov   dx,word[RealModeDX]
	mov   ah,00
	int   13h

	jmp   TryReadFloppyAgainRM
RmFddRReadError:
	mov   byte[RealModeError],1
@@:
	mov   word[RealModeAX],ax
	mov   word[RealModeBX],bx
	mov   word[RealModeCX],cx
	mov   word[RealModeDX],dx
 ;----------------------------------------------------;
 ;  Lets go back to pmode                             ;
 ;----------------------------------------------------;      
	lgdt  [gdtr]					  
	lidt  [idtr]
	mov   eax,cr0					  
	or    al,1
	mov   cr0,eax
 ;----------------------------------------------------;
 ;  jumps to do_pm                                    ;
 ;----------------------------------------------------;
	jmp   sys_code:do_pmInt13h
 ;----------------------------------------------------;
 ;  32-bit protected mode                             ;
 ;----------------------------------------------------;
use32
do_pmInt13h:
	mov   ax,sys_data
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   fs,ax
	mov   gs,ax
	mov   ax,8h
	mov   fs,ax
	call  remap_pic
	call  unmask_irqs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	in    al,60h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	cmp   [RealModeError],1
	je    FddReadError1
FddReadSuccsess: 
	pop   ds 
	pop   es
	popad					     
	mov   ax,word[RealModeAX]
	mov   esi,OffsetDma2Buffer
	;mov   ah,[FddErrorStatus]                       
	;mov   al,[ResultR]
	clc
	ret

FddReadError:
	pop   ds
	pop   es
	popad  
	mov   ah,[FddErrorStatus]			
	stc
	ret

FddReadError1: 
	pop   ds 
	pop   es
	popad	     
	mov  ax,word[RealModeAX]
	stc
	ret


 ;----------------------------------------------------;
 ; FddWriteBios                                       ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;   Input:                                           ;
 ;       ES:BX  = Buffer address                      ;
 ;          CH  = Track/cylinder                      ;
 ;          CL  = Sector                              ;
 ;          DH  = Head                                ;
 ;          DL  = Drive                               ;
 ;          AL  = Number of sectors (normaly 1)       ;
 ;          AH  = WriteSector(03h)                    ;
 ;                                                    ;
 ;  Output:                                           ;
 ;          AH  = Status                              ;
 ;          AL  = Sector number read                  ;
 ;          CF  = 0 If successful                     ;
 ;              = 1 If error                          ;
 ;                                             (100%) ;
 ;....................................................;
FddWriteB:
	pushad
	push  es
	mov   [FloppyTest],0
	and   dh,00000001b				
	mov   [Head],dh 				
	;mov   [DriveHead],dh                            
	mov   [FddErrorStatus],0x04			
	cmp   ch,0x51					
	jae   FddWriteError				 
	mov   [cTrack],ch				
	cmp   cl,0x13					 
	jae   FddWriteError				
	mov   [Sector],cl   
	mov   al,01
	mov   dl,[FddDrive]
	mov   byte[RealModeError],0
	mov   word[RealModeAX],ax
	mov   word[RealModeBX],bx
	mov   word[RealModeCX],cx
	mov   word[RealModeDX],dx
	call  mask_irqs
	mov   al,11h
	out   0x20,al
	out   0xA0,al
	mov   al,0x08
	out   0x21,al
	mov   al,0x70
	out   0xA1,al
	mov   al,4
	out   0x21,al
	mov   al,2
	out   0xA1,al
	mov   al,1
	out   0x21,al
	out   0xA1,al
	jmp   0x20:do_16Int13hWrite
use16
do_16Int13hWrite:	
	mov   ax,0x28
	mov   ds,ax
	mov   ss,ax
	nop
 ;----------------------------------------------------;
 ; push real-mode CS:IP.                              ;
 ;----------------------------------------------------;  
	mov   bx,[RealModeCS]
	push  bx
	lea   bx,[do_rmInt13hWrite]
	push  bx
 ;----------------------------------------------------;
 ; clear PE [pmode enable] bit and return to Rmode.   ;
 ;----------------------------------------------------; 
	mov   eax,cr0
	and   al,0xFE
	mov   cr0,eax
	retf
 ;----------------------------------------------------;
 ;  16-bit real mode again                            ;
 ;----------------------------------------------------;                                   
do_rmInt13hWrite:	
	mov   ax,cs
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   fs,ax
	mov   gs,ax
 ;----------------------------------------------------;
 ; point to real-mode IDTR.                           ;
 ;----------------------------------------------------; 
	lidt  [ridtr]
	push  cs
	pop   ds
	push  ds
	pop   es
 ;----------------------------------------------------;
 ;  Do real mode interrupts                           ;
 ;----------------------------------------------------;
TryWriteFloppyAgainRM:
	mov   ax,word[RealModeAX]
	mov   bx,word[RealModeBX]
	mov   cx,word[RealModeCX]
	mov   dx,word[RealModeDX]   
	mov   bx,OffsetDma2Buffer1 
	mov   ah,03h
							    
	int   13h
	jnc   @f
	inc   [FloppyTest]
	cmp   [FloppyTest],4
	jae   RmFddError
	mov   dx,word[RealModeDX]
	mov   ah,00
	int   13h

	jmp   TryWriteFloppyAgainRM
RmFddError:
	mov   byte[RealModeError],1
@@:
	mov   word[RealModeAX],ax
	mov   word[RealModeBX],bx
	mov   word[RealModeCX],cx
	mov   word[RealModeDX],dx
 ;----------------------------------------------------;
 ;  Lets go back to pmode                             ;
 ;----------------------------------------------------;      
	lgdt  [gdtr]					  
	lidt  [idtr]
	mov   eax,cr0					  
	or    al,1
	mov   cr0,eax
 ;----------------------------------------------------;
 ;  jumps to do_pm                                    ;
 ;----------------------------------------------------;
	jmp   sys_code:do_pmInt13hWrite
 ;----------------------------------------------------;
 ;  32-bit protected mode                             ;
 ;----------------------------------------------------;
use32
do_pmInt13hWrite:
	mov   ax,sys_data
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   fs,ax
	mov   gs,ax
	mov   ax,8h
	mov   fs,ax
	call  remap_pic
	call  unmask_irqs
	cmp   [RealModeError],1
	je    FddWriteError1
FddWriteSuccsess: 
	pop   es
	popad					     
	mov   ax,word[RealModeAX]
	;mov   ah,[FddErrorStatus]                       
	;mov   al,[ResultR]
	clc
	ret

FddWriteError: 
	pop   es
	popad  
	mov   ah,[FddErrorStatus]			
	stc
	ret

FddWriteError1:  
	pop   es
	popad	     
	mov  ax,word[RealModeAX]
	stc
	ret
 

;====================================================;
; Wait Timer.            ;waits for timer to finish. ;
;====================================================;
WaitTimer:
	push  eax
WaitTimerLoop:
	mov   al,[TimerOn]
	or    al,al
	jnz   WaitTimerLoop
	pop   eax
	ret

;====================================================;
; Wait Done                 ;waits for a floppy int. ;
;====================================================;

WaitDone:
	mov   [Timer],30				
	mov   [TimerOn],1				
WaitDoneLoop:
	mov   al,[TimerOn]				
	or    al,al					  
	jz    WaitDoneError				
	mov   ax,[done] 				
	or    ax,ax
	jz    WaitDoneLoop				
	clc						
	ret
WaitDoneError:						
	stc
	ret

;====================================================;
; FdcSendByteReady   ;floppy control  sendbyte ready ;
;====================================================;

FdcSendByteReady:
	push  eax
	push  edx
	mov   [Timer],15				
	mov   [TimerOn],1				
FdcSendByteReadyLoop:
	mov   al,[TimerOn]				
	or    al,al					 
	jz    FdcSendByteReadyError			
	mov   dx,MsReg					
	in    al,dx
	and   al,11000000b
	cmp   al,10000000b				
	jnz   FdcSendByteReadyLoop			
	pop   edx
	pop   eax
	clc						
	ret
FdcSendByteReadyError:					
	pop   edx
	pop   eax
	stc
	ret


;====================================================;
; FdcGetByteReady     ;floppy control  getbyte ready ;
;====================================================;

FdcGetByteReady:
	push  eax
	push  edx
	mov   [Timer],15 ;30                            
	mov   [TimerOn],1				
FdcGetByteReadyLoop:
	mov   al,[TimerOn]				
	or    al,al					 
	jz    FdcGetByteReadyError			
	mov   dx,MsReg					
	in    al,dx
	and   al,11000000b
	cmp   al,11000000b				
	jnz   FdcGetByteReadyLoop			
	pop   edx
	pop   eax
	clc						
	ret
FdcGetByteReadyError:					
	pop   edx
	pop   eax
	stc
	ret

 ;----------------------------------------------------;
 ; FddChange                                          ;
 ;----------------------------------------------------;
FddChange:
	pushad
	push  es
	push  ds
	call  mask_irqs
	mov   al,11h
	out   0x20,al
	out   0xA0,al
	mov   al,0x08
	out   0x21,al
	mov   al,0x70
	out   0xA1,al
	mov   al,4
	out   0x21,al
	mov   al,2
	out   0xA1,al
	mov   al,1
	out   0x21,al
	out   0xA1,al
	jmp   0x20:Int13hdo_16Int13h
use16
Int13hdo_16Int13h:
	mov   ax,0x28
	mov   ds,ax
	mov   ss,ax
	nop
 ;----------------------------------------------------;
 ; push real-mode CS:IP.                              ;
 ;----------------------------------------------------;  
	mov   bx,[RealModeCS]
	push  bx
	lea   bx,[Int13hdo_rmInt13h]
	push  bx
 ;----------------------------------------------------;
 ; clear PE [pmode enable] bit and return to Rmode.   ;
 ;----------------------------------------------------; 
	mov   eax,cr0
	and   al,0xFE
	mov   cr0,eax
	retf
 ;----------------------------------------------------;
 ;  16-bit real mode again                            ;
 ;----------------------------------------------------;                                   
Int13hdo_rmInt13h:
	mov   ax,cs
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   fs,ax
	mov   gs,ax
 ;----------------------------------------------------;
 ; point to real-mode IDTR.                           ;
 ;----------------------------------------------------; 
	lidt  [ridtr]
	push  cs
	pop   ds
	push  ds
	pop   es
 ;----------------------------------------------------;
 ;  Do real mode interrupts                           ;
 ;----------------------------------------------------;

	mov   ah,0x15
	mov   al,0x00
	mov   dx,0x0000
	int   13h
	cmp   ah,1
	je    Int13hRMErrorChange1
	mov   ah,0x16
	mov   al,0x00
	mov   dx,0x0000
	int   13h
	mov   word[RealModeAX],ax
	jmp   Int13hRMErrorChange2
Int13hRMErrorChange1:
	mov   ah,0xab
	mov   word[RealModeAX],ax
Int13hRMErrorChange2:
 ;----------------------------------------------------;
 ;  Lets go back to pmode                             ;
 ;----------------------------------------------------;      
	lgdt  [gdtr]					  
	lidt  [idtr]
	mov   eax,cr0					  
	or    al,1
	mov   cr0,eax
 ;----------------------------------------------------;
 ;  jumps to do_pm                                    ;
 ;----------------------------------------------------;
	jmp   sys_code:Int13hdo_pmInt13h
 ;----------------------------------------------------;
 ;  32-bit protected mode                             ;
 ;----------------------------------------------------;
use32
Int13hdo_pmInt13h:
	mov   ax,sys_data
	mov   ds,ax
	mov   ss,ax
	nop
	mov   es,ax
	mov   gs,ax
	mov   ax,linear_sel
	mov   fs,ax
	call  remap_pic
	call  unmask_irqs
	cmp   [RealModeError],1
	je   Int13hFddWriteError
	pop   ds
	pop   es
	popad					     
	mov   ax,word[RealModeAX]
	clc
	ret

Int13hFddWriteError:
	pop   ds 
	pop   es
	popad	     
	mov  ax,word[RealModeAX]
	stc
	ret