                                                                 
                               
                       
                  
                                                                 


	list	p=16f877,r=hex	                       

	include	"pic16f877.inc"	                             
	include	"main.inc"		                  
	include "ata.inc"		                

                                                                 
                           
                                                                 
	global	AtaUpdate
	global	AtaInit

                                                                 
                             
                                                                 
	extern	Delay1ms
	extern	Delay10ms
	extern	Delay200ms
	extern	Delay5s

_rom1 code
                                                                 
                  
                                                              
               
                
                                                                 
AtaUpdate:
	movf	KeyEvent,w		            
	xorlw	0x00
	btfsc	status,z	
	return					   
	bsf		portd,LED_STATUS	    
	movlw	D'10'			                          
	movwf	AtaErrorRetries						
                                                
                         
                    
                                                
	btfsc	KeyState,KEY_STATE_OPEN_CLOSE
	goto	Iu2
	btfss	KeyEvent,KEY_EVENT_PLAY_STOP	
	goto	Iu2
	btfsc	KeyState,KEY_STATE_PLAY_STOP
	goto	Kst
Kpl:	call	AtaCmdReadToc
	movf	TrackStartMSF_M,w
	movwf	AtaPacket+3
	movf	TrackStartMSF_S,w
	movwf	AtaPacket+4
	movf	TrackStartMSF_F,w
	movwf	AtaPacket+5
	call	AtaCmdPlayAudio
	bsf		KeyState,KEY_STATE_PLAY_STOP
	bcf		KeyState,KEY_STATE_PAUSE_ONOFF
	goto	IuEnd
Kst:	call	AtaCmdStopAudio
	bcf		KeyState,KEY_STATE_PLAY_STOP
	goto	IuEnd
                                                
                         
                    
                  
                                                
Iu2:	btfsc	KeyState,KEY_STATE_OPEN_CLOSE
	goto	Iu3
	btfsc	KeyState,KEY_STATE_PAUSE_ONOFF
	goto	Iu3
	btfss	KeyEvent,KEY_EVENT_NEXT
	goto	Iu3
	incf	TrackStartNr,f
	btfss	KeyState,KEY_STATE_PLAY_STOP
	goto	IuEnd
	call	AtaCmdReadSubChannel
	incf	TrackCurrentNr,w
	movwf	TrackStartNr
	call	AtaCmdReadToc
	movf	TrackStartMSF_M,w
	movwf	AtaPacket+3
	movf	TrackStartMSF_S,w
	movwf	AtaPacket+4
	movf	TrackStartMSF_F,w
	movwf	AtaPacket+5
	call	AtaCmdPlayAudio
	goto	IuEnd
                                                
                             
                    
                  
                                                
Iu3:	btfsc	KeyState,KEY_STATE_OPEN_CLOSE
	goto	Iu4
	btfsc	KeyState,KEY_STATE_PAUSE_ONOFF
	goto	Iu4
	btfss	KeyEvent,KEY_EVENT_PREVIOUS
	goto	Iu4
	decf	TrackStartNr,f
	btfss	KeyState,KEY_STATE_PLAY_STOP
	goto	IuEnd
	call	AtaCmdReadSubChannel
	decf	TrackCurrentNr,w
	movwf	TrackStartNr
	call	AtaCmdReadToc
	movf	TrackStartMSF_M,w
	movwf	AtaPacket+3
	movf	TrackStartMSF_S,w
	movwf	AtaPacket+4
	movf	TrackStartMSF_F,w
	movwf	AtaPacket+5
	call	AtaCmdPlayAudio
	goto	IuEnd
                                                
                               
                                                
Iu4:	btfss	KeyEvent,KEY_EVENT_OPEN_CLOSE
	goto	Iu5
	btfsc	KeyState,KEY_STATE_OPEN_CLOSE
	goto	Kcl
Kop:	btfsc	KeyState,KEY_EVENT_PLAY_STOP
	call	AtaCmdStopAudio
	call	AtaCmdOpenDoor
	bsf		KeyState,KEY_STATE_OPEN_CLOSE
	goto	IuEnd
Kcl:	call	AtaCmdCloseDoor
	call	AtaCmdStopAudio
	bcf		KeyState,KEY_STATE_PLAY_STOP
	bcf		KeyState,KEY_STATE_PAUSE_ONOFF
	bcf		KeyState,KEY_STATE_OPEN_CLOSE
	movlw	0x01
	movwf	TrackStartNr
	goto	IuEnd
                                                
                            
                    
                     
                                                
Iu5:	btfsc	KeyState,KEY_STATE_OPEN_CLOSE
	goto	IuEnd
	btfss	KeyEvent,KEY_EVENT_PAUSE_ONOFF
	goto	IuEnd
	btfss	KeyState,KEY_STATE_PLAY_STOP
	goto	IuEnd
	btfsc  	KeyState,KEY_STATE_PAUSE_ONOFF
	goto	Kpf
Kpo:	call	AtaCmdPauseOn
	bsf		KeyState,KEY_STATE_PAUSE_ONOFF	
	goto	IuEnd
Kpf:	call	AtaCmdPauseOff
	bcf		KeyState,KEY_STATE_PAUSE_ONOFF
	goto	IuEnd
IuEnd:
	bcf		portd,LED_STATUS
	return
                                                                 
                
                                           
               
                
                                                                 
AtaInit:
	bsf		portd,LED_STATUS
	call	AtaReset		                      
	call	Delay5s		                      
	call	Delay5s

	movlw	D'12'		                                   
	movwf	AtaCounter
	movlw	AtaPacket
	movwf	fsr
Ai1:	clrf	indf	
	incf	fsr,f
	decfsz	AtaCounter,f
	goto	Ai1
	call	AtaCmdStopAudio	              
#ifdef LCD
	call	AtaCmdInquiry
#endif
	bcf		portd,LED_STATUS
	return
                                                                 
                 
                                              
               
                
                                                                 
AtaReset:
	bcf		portd,ATA_RST
	call	Delay200ms
	bsf		portd,ATA_RST
	call	Delay200ms	
	return
                                                                 
                        
                                                  
               
                
                                                                 
AtaCmdStopAudio:
	movlw	0x4e
	movwf	AtaPacket
	call	AtaWritePacket
	call	AtaReadPacketEmpty
	xorlw	0x01				                       
	btfss	status,z
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdStopAudio	                    
	call	AtaReset			                              
	return
                                                                 
                      
                                                     
               
                
                                                                 
AtaCmdPauseOn:
	movlw	0x4b
	movwf	AtaPacket
	call	AtaWritePacket
	call	AtaReadPacketEmpty			
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdPauseOn		                    
	call	AtaReset			                              
	return
                                                                 
                       
                                                     
               
                
                                                                 
AtaCmdPauseOff:
	movlw	0x4b
	movwf	AtaPacket
	movlw	0x01
	movwf	AtaPacket+8
	call	AtaWritePacket
	call	AtaReadPacketEmpty
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdPauseOff	                    
	call	AtaReset			                              
	return
                                                                 
                        
                                                       
               
                
                                                                 
AtaCmdPlayAudio:
	movlw	0x47
	movwf	AtaPacket
	movf	TrackLeadOutMSF_M,w
	movwf	AtaPacket+6
	movf	TrackLeadOutMSF_S,w
	movwf	AtaPacket+7
	movf	TrackLeadOutMSF_F,w
	movwf	AtaPacket+8
	call	AtaWritePacket
	call	AtaReadPacketEmpty
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdPlayAudio	                    
	call	AtaReset			                              
	return
                                                                 
                        
                                                        
               
                
                                                                 
AtaCmdCloseDoor:
	movlw	0x1b
	movwf	AtaPacket
	movlw	0x03
	movwf	AtaPacket+4
	call	AtaWritePacket
	call	AtaReadPacketEmpty
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdCloseDoor	                    
	call	AtaReset			                              
	return
                                                                 
                       
                                                        
               
                
                                                                 
AtaCmdOpenDoor:
	movlw	0x1b
	movwf	AtaPacket
	movlw	0x02
	movwf	AtaPacket+4
	call	AtaWritePacket
	call	AtaReadPacketEmpty
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdOpenDoor	                    
	call	AtaReset			                              
	return
                                                                 
                      
                                                
               
                
                                                                 
#ifdef LCD
AtaCmdInquiry:
	movlw	0x12
	movwf	AtaPacket
	movlw	0xff
	movwf	AtaPacket+4
	call	AtaWritePacket
	call	AtaReadPacketInquiry
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdInquiry		                    
	call	AtaReset			                              
	return
#endif
                                                                 
                      
                                                               
               
                
                                                                 
AtaCmdReadToc:
	movlw	0x43
	movwf	AtaPacket
	movlw	0x02
	movwf	AtaPacket+1
	movlw	0xff
	movwf	AtaPacket+7
	movlw	0xff
	movwf	AtaPacket+8
	call	AtaWritePacket
	call	AtaReadPacketToc
	btfsc	status,z			                       
	return					    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdReadToc		                    
	call	AtaReset			                              
	return
                                                                 
                             
                                                         
               
                
                                                                 
AtaCmdReadSubChannel:
	movlw	0x42
	movwf	AtaPacket
	movlw	0x02
	movwf	AtaPacket+1
	movlw	0x40
	movwf	AtaPacket+2
	movlw	0x01
	movwf	AtaPacket+3
	movlw	0xff
	movwf	AtaPacket+7
	movlw	0xff
	movwf	AtaPacket+8
	call	AtaWritePacket
	call	AtaReadPacketSubChannel
	btfsc	status,z				                       
	return						    
	decfsz	AtaErrorRetries,f
	goto	AtaCmdReadSubChannel	                    
	call	AtaReset				                              
	return
                                                                 
                
                                                                 
                                                                 
                       
                                            
                                    
                
                                                                 
AtaWritePacket:
	movlw	0x0a					                       
	movwf	AtaDataLsb
	movlw	ATA_REG_DRIVEHEAD
	call	AtaWriteRegister

	clrf	AtaDataLsb			                             
	movlw	ATA_REG_FEATURES
	call	AtaWriteRegister

	clrf	AtaDataLsb			                      
	movlw	ATA_REG_CYLINDERLOW
	call	AtaWriteRegister

	clrf	AtaDataLsb
	movlw	ATA_REG_CYLINDERHIGH
	call	AtaWriteRegister

	movlw	ATA_COMMAND_PACKET	             
	movwf	AtaDataLsb
	movlw	ATA_REG_COMMAND
	call	AtaWriteRegister
	
	                                             
	call	Delay10ms 

                  
AtaWc2:
	movlw	ATA_REG_STATUS		                
	call	AtaReadRegister
	movf	AtaDataLsb,w
	andlw	0x08
	btfsc	status,z
	goto	AtaWc2
	
	bcf		status,rp1		                        
	bsf		status,rp0				
	movlw	PORTB_CONFIG2		                            
	movwf	trisb
	movlw	PORTC_CONFIG2
	movwf	trisc	
	bcf		status,rp1		                               
	bcf		status,rp0	
	bcf		porta,ATA_A0		                           
	bcf		porta,ATA_A1
	bcf		porta,ATA_A2
	movlw	0x06				                          
	movwf	AtaCounter	
	movlw	AtaPacket
	movwf	fsr
AtaWP1:
	movf	indf,w			        
	movwf	portb			
	incf	fsr,f
	movf	indf,w			        
	movwf	portc	
	call	Delay10ms
	incf	fsr,f
	bcf		porta,ATA_IOW		            
	call	Delay10ms
	bsf		porta,ATA_IOW		                
	call	Delay10ms
	decfsz	AtaCounter,f
	goto	AtaWP1			                  

	                                                     
	movlw	D'12'			
	movwf	AtaCounter
	movlw	AtaPacket
	movwf	fsr
Au1:	clrf	indf	
	incf	fsr,f
	decfsz	AtaCounter,f
	goto	Au1	
	return
                                                                 
                         
                                                    
                           
                
                
                
                                                                 
AtaWriteRegister:
	movwf	AtaRegister		                      
	bcf		status,rp1		                        
	bsf		status,rp0				
	movlw	PORTB_CONFIG2		                            
	movwf	trisb
	movlw	PORTC_CONFIG2
	movwf	trisc	
	bcf		status,rp1		                               
	bcf		status,rp0
	rlf		AtaRegister,w		                   
	iorlw	0x30				                       
	movwf	porta			                          
	call	Delay1ms
	movf	AtaDataLsb,w		          
	movwf	portb
	clrf	portc			                        
	call	Delay1ms
	bcf		porta,ATA_IOW		            
	call	Delay1ms
	bsf		porta,ATA_IOW		                
	call	Delay1ms
	return
                                                                 
                        
                                                     
                           
                      
                 
                                                                 
AtaReadRegister:
	movwf	AtaRegister		                      
	bcf		status,rp1		                        
	bsf		status,rp0				
	movlw	PORTB_CONFIG1		                           
	movwf	trisb
	movlw	PORTC_CONFIG1
	movwf	trisc	
	bcf		status,rp1		                               
	bcf		status,rp0
	rlf		AtaRegister,w	
	iorlw	0x30				                       
	movwf	porta			                          
	call	Delay1ms
	bcf		porta,ATA_IOR		            
	call	Delay1ms
	movf	portb,w			         
	movwf	AtaDataLsb
	movf	portc,w			         
	movwf	AtaDataMsb
	call	Delay1ms
	bsf		porta,ATA_IOR		                
	call	Delay1ms
	return
                                                                 
                           
                                                       
                                              
               
                                              
                         
                                                                 
AtaReadPacketEmpty:
                  
AtaRe1:	
	movlw	ATA_REG_SECTORCOUNT	                     
	call	AtaReadRegister
	movf	AtaDataLsb,w
	andlw	0x03
	xorlw	0x03
	btfss	status,z
	goto	AtaRe1

AtaReadNachamble:
	call	Delay200ms	
                  
AtaRe2:
	movlw	ATA_REG_STATUS		                             
	call	AtaReadRegister
	movf	AtaDataLsb,w
	andlw	0xc8					
	xorlw	0x40
	btfss	status,z
	goto	AtaRe2

	movf	AtaDataLsb,w
	xorlw	0x50					                     
	return
                                                                 
                             
                                                 
               
            
                                                                 
#ifdef LCD
AtaReadIdentifyDrive:

	return
#endif

                                                                 
                             
                                          
               
            
                                                                 
#ifdef LCD
AtaReadPacketInquiry:

	return
#endif

                                                                 
                                
                                                               
                                           
               
                                                              
                                                                 
AtaReadPacketSubChannel:
	call	AtaReadPreamble
	                                        
	bcf		porta,ATA_IOR		            
	movf	portc,w			             
	movwf	TrackStatus
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                                              
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                                               
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                                                        
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	movf	portb,w			             
	movwf	TrackCurrentNr
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                         
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	movf	portc,w			                  
	movwf	TrackCurrentMSF_M
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                             
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	movf	portb,w			                  
	movwf	TrackCurrentMSF_S
	movf	portc,w			                   
	movwf	TrackCurrentMSF_F
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                               
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	                               
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	call	AtaReadNachamble
	return
                                                                 
                         
                                                      
                                                
                               
                       
                                     
                                                
                                                                 
AtaReadPacketToc:
	call	AtaReadPreamble
	                                         
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	                                      
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	movf	portb,w			                  
	movwf	TrackFirstNr
	movf	portc,w			                   
	movwf	TrackLastNr
	bsf		porta,ATA_IOR		                

AtaRt1:
	call	Delay10ms
	                                       
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	                                           
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	movf	portb,w			                  
	movwf	TrackTempNr
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	movf	TrackTempNr,w		                        
	xorwf	TrackStartNr,w			
	btfsc	status,z
	goto	AtaRSave1		    
	movf	TrackTempNr,w		                           
	xorlw	0xaa				
	btfsc	status,z
	goto	AtaRSave2		    

	                               
	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	bcf		porta,ATA_IOR		            
	call	Delay10ms
	bsf		porta,ATA_IOR		                
	goto	AtaRt1

AtaRSave1:	                     
	bcf		porta,ATA_IOR		            
	call	Delay10ms	
	movf	portc,w			                  
	movwf	TrackStartMSF_M
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	bcf		porta,ATA_IOR		            
	call	Delay10ms	
	movf	portb,w			                  
	movwf	TrackStartMSF_S
	movf	portc,w			                  
	movwf	TrackStartMSF_F
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	goto	AtaRt1

AtaRSave2:	                  
	bcf		porta,ATA_IOR		            
	call	Delay10ms	
	movf	portc,w			                     
	movwf	TrackLeadOutMSF_M	
	bsf		porta,ATA_IOR		                
	call	Delay10ms

	bcf		porta,ATA_IOR		            
	call	Delay10ms	
	movf	portb,w			                     
	movwf	TrackLeadOutMSF_S
	movf	portc,w			                     
	movwf	TrackLeadOutMSF_F
	bsf		porta,ATA_IOR		                
	call	Delay10ms
	call	AtaReadNachamble
	return					                                      

                                                                 
                        
                                           
               
                
                                                                 
AtaReadPreamble:
                  
AtaRp1:	
	movlw	ATA_REG_SECTORCOUNT	                     
	call	AtaReadRegister
	movf	AtaDataLsb,w
	andlw	0x03
	xorlw	0x02
	btfss	status,z
	goto	AtaRp1	

	bcf		status,rp1		                        
	bsf		status,rp0				
	movlw	PORTB_CONFIG1		                           
	movwf	trisb
	movlw	PORTC_CONFIG1
	movwf	trisc	
	bcf		status,rp1		                               
	bcf		status,rp0

	bcf		porta,ATA_A0		                           
	bcf		porta,ATA_A1
	bcf		porta,ATA_A2

	END


