IDE@ CDROM@

;CDROM	IDE INTERFACE
;TESTED ON MODELS CREATIVE SB CR-581-J (QUAD SPEED)
;& GOLDSTAR (LG) CRD-8400C (40X SPEED)
;
;SHORT PROGRAMME TO CONTROL A CDROM VIA THE IDE
;ONLY SENDS A FEW COMMANDS BUT ITS A START
;Ryan Pogge says:
;The next step is to read the TOC and create some type of list from that on the PIC
;looks like it is a matter of sending  8c 0 e 0 0 0 0    , and getting 9 bytes back.
;anyone who is interested I have a couple of links that may be of some use
;http://www.geocities.com/SiliconValley/Hardware/2342/mp3player.html this is a 68HC11 based MP3 player with an IDE CD-ROM, I suspect this will have mush pertinate info.
;http://www-stu.cai.cam.ac.uk/~atm26/electronics/panasoniccd.html list of error codes
;http://www.mp3ar.com/  (this is a cd based mp3 player with free source code!)
;http://www.spectsoft.com/mp3tech/  (good CD, MP3, and IDE stuff here)
;http://www.angelfire.com/ms/mp3player/page17.html
;http://www.faqs.org/faqs/pc-hardware-faq/enhanced-IDE/part2/
;http://pages.hotbot.com/cooking/anton_verheijen/main.html
;http://www.imbdev.com/ (MAS3507 proto boards)

;COMMANDS SENT DEPENDING ON PORTB PINS 5/4/3 & RE2 
;EJECT/LOAD/PLAY STATED MSF/ STOP.
;CURRENTLY SUPPORTS NO INTERRUPT HANDLING OR ERROR CONDITIONS
;RETURNED FROM IDE

;SET YOUR CDROM TO MASTER DEVICE

;**********************************************************************
;SEE DOC ATA Packet Interface for CD-ROMs SFF-8020i
                                                                     
;    Filename:	    COM1.asm                                           
;    Date:                                                           
;    File Version:    VER1                                               
;                                                                     
;    Author:ROB BOARDMAN                                                          *
;    Company:                                                         
                                                                    
;**********************************************************************
;USING 16MHZ CRYSTAL & PIC NO OTHER IC'S REQUIRED MAY WORK AT 20MHZ
;SOME PINS ON PORTB ARE SWITCH INPUTS
;IF USING RE2 AS SWITCH INPUT ADD PULLUP RESISTOR
 
;PIN CONNECTIONS
;
;	PIC	IDE                                                                  *
;	PORTA              
;	0	37	CS0
;	1	38	CS1
;	2	35	A0
;	3	33	A1
;	4	36	A2
;	5	34	PDIAG

;	PORTB
;	0	1	RESET
;	1	27	IORDY
;	2	31	IRQ
;	3	
;	4
;	5
;	6
;	7

;	PORTC	
;	0	3	D0
;	1	5	D1
;	2	7	D2
;	3	9	D4
;	4	11	D5
;	5	13	D6
;	6	15	D7
; M. Adam Davis says:
; it looks like you've almost got the listing backwards...  
; Is it supposed to be:
;       PORTC
;       0       17      D0
;       1       15      D1
;       2       13      D2
;       3       11      D3
;       4       9       D4
;       5       7       D5
;       6       5       D6
;       7       3       D7

;	PORTD		
;	0	4	D8
;	1	6	D9
;	2	8	D10
;	3	10	D11
;	4	12	D12
;	5	14	D13
;	6	16	D14
;	7	18	D15

;	PORTE
;	0	25	nDIOR
;	1	23	nDIOW

;		2	GND
;		19	GND
;		22	GND
;		24	GND
;		26	GND
;		30	GND
;		40	GND

;This example has a couple of switches connected for various CD functions as follows
;RB3	EJECT DISC	internal pullup
;RB4	STOP DISC	internal pullup
;RB5	PLAY DISC	internal pullup
;RE2	LOAD DISC 	Note use pull resistor


;*************************************************************************
;*************************************************************************
;*************************************************************************
;*************************************************************************

	list      p=16f877            ; list directive to define processor
	#include <p16f877.inc>        ; processor specific variable definitions

	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF


  
;***** VARIABLE DEFINITIONS


DELAY0 EQU 0X2C                   
DELAY1 EQU 0X2D                    
DELAY2 EQU 0X2E

FLAGREG	EQU 0X2F
                    
#DEFINE ERROR	0X2F,0	;ERROR STATUS
#DEFINE SECONDWR 0X2F,1

TEMP1  EQU 0X30
TEMP   EQU 0X31
TEMP0	EQU 0X32

REGISTER EQU 0X33
ACCA	EQU 0X34
PACK	EQU 0X35
TEXT	EQU 0X36


status_temp	EQU 0X3E
w_temp		EQU 0X3F


CTRL	EQU 0
CMD	EQU 1
DRIVE0	EQU 0
;**************************************************
;PIN ASSIGNMENTS TO IDE
#DEFINE nCS1FX	0X05,0
#DEFINE nCS3FX	0X05,1
#DEFINE	DA0	0X05,2
#DEFINE	DA1	0X05,3
#DEFINE	DA2	0X05,4
#DEFINE	nDASP	0X05,5
#DEFINE	nDIOR	0X09,0
#DEFINE	nDIOW	0X09,1
#DEFINE	INTRQ	0X06,2
#DEFINE	IORDY	0X06,1
#DEFINE	RESET	0X06,0
;***************************************************
;THESE ARE SIGNALS WHICH END UP ON PORTA
;ADDRESSES VARIOUS REGISTERS WITHIN THE IDE DEVICE
			
COMMANDREG 	EQU B'00011110'	;WRITE
STATUSREG  	EQU B'00011110'	;READ
DATAREG		EQU B'00000010'

;BITS WITHIN STATUS REG OF IDE
BSY EQU 7
DRQ EQU 3

;BITS WITHIN Interrupt Reason Register 
CoD EQU 0
IO  EQU 1

#DEFINE DELAYS

;**********************************************************************
		ORG     0x000 	
		NOP
		clrf    PCLATH            ; ensure page bits are cleared
  		goto    init            ; 
                  

		ORG     0x004             ; interrupt vector location
		movwf   w_temp            ; save off current W register contents
		movf	STATUS,w          ; move status register into W register
		movwf	status_temp       ; save off contents of STATUS register


		movf    status_temp,w     ; retrieve copy of STATUS register
		movwf	STATUS            ; restore pre-isr STATUS register contents
		swapf   w_temp,f
		swapf   w_temp,w          ; restore pre-isr W register contents
		retfie                    ; return from interrupt

;**************************************************************************
;**************************************************************************

		; initialization routine
		;SETUP ALL PORTS

init	BSF  STATUS,RP0                          ;SET PAGE 1

        MOVLW   B'00100000'                     ;
        MOVWF   TRISA

        MOVLW   B'00111110'                     ;
        MOVWF   TRISB

	MOVLW	B'11111111'
        MOVWF	TRISC   
    
	MOVLW	B'11111111'
	MOVWF	TRISD

	MOVLW	B'00000100'
	MOVWF	TRISE

       	MOVLW B'10000110'
	MOVWF ADCON1

        BCF	OPTION_REG,NOT_RBPU	;PULLUPS ON

        BCF STATUS,RP0         		;BACK TO PAGE 0
	CLRF PORTA		
	CLRF PORTB
	CLRF PORTC
	CLRF PORTD
;*********************************************************
	BCF RESET	;SETUPS IDE AND RESETS 
	CALL PAUSE
	bsf nCS1FX
	BSF nCS3FX
	BSF nDIOR
	BSF nDIOW
	CALL PAUSE
	CALL PAUSE
	BSF RESET
	call PAUSE
	CALL PAUSE
	CALL PAUSE
	CALL PAUSE
	CALL PAUSE
	CLRF FLAGREG
        GOTO START
;***************************************
;***************************************
;***************************************
PAUSE
        IFDEF DELAYS
	CLRWDT
        MOVLW   .255      ;
        MOVWF   DELAY0     ;
DELLP   DECFSZ  DELAY0     ;
        GOTO    DELLP      ;
	ENDIF
        RETURN   
;************************************************************************
WRITEIDE	BSF nDIOW	;PUTS DATA FROM TEMP0 & TEMP1 REGISTERS
	MOVF REGISTER,W		;ON TO IDE DATABUS LINE D0-D15 THEN TOGGLES
	MOVWF PORTA		;nDIOW PIN (WRITE INSTRUCTION)
	BSF  STATUS,RP0        
        MOVLW   B'00000000'    
        MOVWF   TRISC
	MOVWF	TRISD
	BCF STATUS,RP0
	MOVF TEMP0,W
	MOVWF PORTC	
	MOVF TEMP1,W
	MOVWF PORTD
	BCF nDIOW
	BSF nDIOW
	BSF  STATUS,RP0                          ;SET PAGE 1
        MOVLW   B'11111111'                     ;
        MOVWF   TRISC
	MOVWF	TRISD
	BCF STATUS,RP0
	RETURN
;******************************************************************
READIDE	NOP		;READS IDE DATA BUS D0-D15
	BCF nDIOR	;PLACES DATA INTO TEMP0 & TEMP1 REGISTERS
	BSF nDIOR
	MOVF PORTC,W
	MOVWF TEMP0
	MOVF PORTD,W
	MOVWF TEMP1
	RETURN
;********************************************************************
CHKCoD	BCF ERROR		;CoD=1 IO=0
	MOVLW B'10001010'	;ERROR CHECKING NOT YET SUPPORTED
	MOVWF PORTA
	CALL READIDE
	BTFSS TEMP0,CoD
	BSF ERROR
	BTFSC TEMP0,IO
	BSF ERROR
	NOP
	BTFSC ERROR
	GOTO TEST5 
	RETURN
TEST5	INCF TEMP
	GOTO CHKCoD
;*******************************************************************
CHKDRQ	BCF ERROR	;BSY=0 DRQ=1
	CALL RDSTATUS	;;ERROR CHECKING NOT YET SUPPORTED
	BTFSC TEMP0,BSY
	BSF ERROR
	BTFSS TEMP0,DRQ
	BSF ERROR
	NOP
	BTFSC ERROR
	GOTO TEST6 
	RETURN
TEST6	INCF TEMP
	GOTO CHKDRQ


;******************************************************************

;*******************************************************************	
;ROUTINE SENDS 12 BYTE PACKET TO IDE DEVICE

SENDCOM	CALL CHKSTATUS		;DO CHECK
 			;***********************************
	MOVLW COMMANDREG	;POINT TO COMMAND REG THEN SEND 
	MOVWF REGISTER		;PACKET OPCODE COMMAND
	MOVLW 0XA0	
	MOVWF TEMP0
	CALL WRITEIDE
			;************************************

			;CHECK STATUS OF IDE
	CALL CHKCoD	;CHK CoD & IO & BSY	

	CALL CHKDRQ	;WAIT FOR DRQ=1
	

			;************************************

	MOVLW DATAREG	;POINT TO DATA REGISTER THEN SEND
	MOVWF REGISTER	;12 BYTES TO DATA REGISTER WITHIN IDE (1 PACKET)
 	CLRF ACCA
NXREG2	CALL PACKET
	MOVWF TEMP0
	INCF ACCA
	INCF PACK
	CALL PACKET
	MOVWF TEMP1
	CALL WRITEIDE
	INCF PACK
	INCF ACCA
	MOVLW   0X0C                           
        SUBWF   ACCA, 0                          
        BTFSS STATUS,Z                         
        GOTO    NXREG2                           
	RETLW 00H 

;END OF PACKET RETURN TO MAIN PROGRAM       
;*******************************************************************

  
;12 BYTE LOOKUP TABLE FOR CDROM COMMANDS
;DEPENDING ON THE VALUE OF PACK LOOKUP JUMPS TO
;RETURNS WITH 1 OF 12 BYTES
;

PACKET	MOVF PACK,W 
	BCF PCLATH,0 
        BCF PCLATH,1                  
        MOVF    PACK,0                   
        ADDWF   PCL
	
	;*************************
	RETLW	0X1B	;0	STOP DISC COMMAND
	RETLW	0X00	;1
	RETLW	0X00	;2
	RETLW	0X00	;3
	RETLW	0X00	;4
	RETLW	0X00	;5
	RETLW	0X00	;6
	RETLW	0X00	;7	
	RETLW	0X00	;8
	RETLW	0X00	;9
	RETLW	0X00	;10
	RETLW	0X00	;11
	;******************************************
	RETLW	0X47	;0		0XC0
	RETLW	0X00	;1	THIS EXAMPLE PLAYS AT 1min in for 30sec's
	RETLW	0X00	;2	PLAY DISC AT TIME STATED MIN SEC 1/75/SEC
	RETLW	0X01	;3	MINUTES STARTING POINT 
	RETLW	0X00	;4	SECONDS STARTING POINT
	RETLW	0X00	;5	1/75 SEC STARTING POINT (N/A)
	RETLW	0X01	;6	MINUTES STOPING POINT
	RETLW	0X1E	;7	SECONDS STOPING POINT
	RETLW	0X00	;8	1/75 STOPPING POINT	(N/A)
	RETLW	0X00	;9
	RETLW	0X00	;10
	RETLW	0X00	;11
	;******************************************
	RETLW	0X1B	;0	0X18
	RETLW	0X00	;1	EJECT DISC COMMAND
	RETLW	0X00	;2	
	RETLW	0X00	;3
	RETLW	0X02	;4
	RETLW	0X00	;5
	RETLW	0X00	;6
	RETLW	0X00	;7	
	RETLW	0X00	;8
	RETLW	0X00	;9
	RETLW	0X00	;10
	RETLW	0X00	;11
	;******************************************
	RETLW	0X1B	;0	0X24
	RETLW	0X00	;1	LOAD DISC COMMAND
	RETLW	0X00	;2
	RETLW	0X00	;3
	RETLW	0X03	;4
	RETLW	0X00	;5
	RETLW	0X00	;6
	RETLW	0X00	;7	
	RETLW	0X00	;8
	RETLW	0X00	;9
	RETLW	0X00	;10
	RETLW	0X00	;11
	;******************************************
	RETLW	0X43	;0	0X30
	RETLW	0X00	;1	
	RETLW	0X00	;2
	RETLW	0X00	;3	
	RETLW	0X00	;4
	RETLW	0X00	;5
	RETLW	0X00	;6	
	RETLW	0X00	;7	
	RETLW	0X08	;8	
	RETLW	0X00	;9
	RETLW	0X00	;10
	RETLW	0X00	;11
;******************************************
;******************************************

WRITEHD	MOVLW B'10011010'	;WRITE TO HEAD DEVICE REG WITHIN IDE
	MOVWF REGISTER
	MOVLW B'10100000'	;SET CDROM HEAD REG TO MASTER
	MOVWF TEMP0
	CLRF TEMP1
	CALL WRITEIDE
	RETURN

RDHD	MOVLW B'10011010'	;READS HEAD REG
	MOVWF PORTA		;I USED THIS TO CHECK
	CALL READIDE		;IF CDROM WAS SET AS MASTER
	RETURN	

RDSTATUS MOVLW B'10011110'	;READS STATUS REGISTER WITHIN IDE
	 MOVWF PORTA
	CALL READIDE
	RETURN

CHKSTATUS	BCF ERROR
		CALL RDSTATUS
		BTFSC TEMP0,BSY
		BSF ERROR
		BTFSC TEMP0,DRQ
		BSF ERROR
		NOP
		BTFSC ERROR
		GOTO TEST4 
		RETURN

TEST4		INCF TEMP
		GOTO CHKSTATUS
	

;*****************************************
;LOADS PACK REGISTER FOR LOOKUP TABLE
;THEN CALLS ROUTINE TO SEND 12 BYTES (1 PACKET)

PLAY	MOVLW 0X0C
	MOVWF PACK
	CALL SENDCOM
	RETURN

STOP	MOVLW 0X00
	MOVWF PACK
	CALL SENDCOM
	RETURN

EJECT	MOVLW 0X18
	MOVWF PACK
	CALL SENDCOM
	RETURN

LOADDISC	MOVLW 0X24
		MOVWF PACK
		CALL SENDCOM
		RETURN

;****************************************************************************
START	CALL PAUSE
	CALL CHKSTATUS
	CALL PAUSE
	NOP
	CALL WRITEHD	;SETUP FOR MASTER DRIVE
	NOP
	CALL PAUSE
	CALL RDHD	;READ DRIVEHEAD (CHECKING MASTER DRIVE SETTING)OPTIONAL
	CALL PAUSE

	;NOTE THERE IS NO DEBOUNCE SOFTWARE AT THE MOMENT
	;SO RELEASE THE BUTTON QUICKLY
	
TEST1	BTFSS PORTB,5
	CALL PLAY
	BTFSS PORTB,4
	CALL STOP
	BTFSS PORTB,3
	CALL EJECT
	BCF ERROR
	BTFSS PORTE,2
	CALL LOADDISC
	CALL PAUSE
	CALL RDSTATUS
	GOTO TEST1


	END