from ROB BOARDMAN [rob at BOARDMANR.FREESERVE.CO.UK]
;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 $2C DELAY1 equ $2D DELAY2 equ $2E FLAGREG equ $2F #DEFINE ERROR 0X2F,0 ;ERROR STATUS #DEFINE SECONDWR 0X2F,1 TEMP1 equ $30 TEMP equ $31 TEMP0 equ $32 REGISTER equ $33 ACCA equ $34 PACK equ $35 TEXT equ $36 status_temp equ $3E w_temp equ $3F 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 %00011110 ;WRITE STATUSREG equ %00011110 ;READ DATAREG equ %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 $000 nop ;*** WARNING: PCLATH register bits are in STATUS PAx bits. Or use PAGE/IREAD if possible ; clrf PCLATH ; ensure page bits are cleared clr PCLATH ; ensure page bits are cleared jmp init ; org $004 ; interrupt vector location mov w_temp, W ; save off current W register contents mov W, STATUS ; move status register into W register mov status_temp, W ; save off contents of STATUS register mov W, status_temp ; retrieve copy of STATUS register mov STATUS, W ; restore pre-isr STATUS register contents swap w_temp mov W, <>w_temp ; restore pre-isr W register contents ;*** WARNING: SX saves/restores W, STATUS, and FSR automatically. ; retfie ; return from interrupt reti ; return from interrupt ;************************************************************************** ;************************************************************************** ; initialization routine ;SETUP ALL PORTS init setb STATUS.RP0 ;SET PAGE 1 mov W, #%00100000 ; ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISA mov TRISA, W mov W, #%00111110 ; ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISB mov TRISB, W mov W, #%11111111 ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISC mov TRISC, W mov W, #%11111111 ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISD mov TRISD, W mov W, #%00000100 ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISE mov TRISE, W mov W, #%10000110 mov ADCON1, W ;*** WARNING: OPTION register is accessed only by MOV !OPTION, W. ; BCF OPTION_REG,NOT_RBPU ;PULLUPS ON clrb OPTION_REG.NOT_RBPU ;PULLUPS ON clrb STATUS.RP0 ;BACK TO PAGE 0 clr RA clr RB clr RC clr RD ;********************************************************* clrb RESET ;SETUPS IDE AND RESETS call PAUSE setb nCS1FX setb nCS3FX setb nDIOR setb nDIOW call PAUSE call PAUSE setb RESET call PAUSE call PAUSE call PAUSE call PAUSE call PAUSE clr FLAGREG jmp START ;*************************************** ;*************************************** ;*************************************** PAUSE IFDEF DELAYS clr !WDT mov W, #255 ; mov DELAY0, W ; DELLP decsz DELAY0 ; jmp DELLP ; ENDIF ret ;************************************************************************ WRITEIDE setb nDIOW ;PUTS DATA FROM TEMP0 & TEMP1 REGISTERS mov W, REGISTER ;ON TO IDE DATABUS LINE D0-D15 THEN TOGGLES mov RA, W ;nDIOW PIN (WRITE INSTRUCTION) setb STATUS.RP0 mov W, #%00000000 ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISC mov TRISC, W ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISD mov TRISD, W clrb STATUS.RP0 mov W, TEMP0 mov RC, W mov W, TEMP1 mov RD, W clrb nDIOW setb nDIOW setb STATUS.RP0 ;SET PAGE 1 mov W, #%11111111 ; ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISC mov TRISC, W ;*** WARNING: TRIS registers are accessed by MOV !Rx, W (M = $0F or $1F). ; MOVWF TRISD mov TRISD, W clrb STATUS.RP0 ret ;****************************************************************** READIDE nop ;READS IDE DATA BUS D0-D15 clrb nDIOR ;PLACES DATA INTO TEMP0 & TEMP1 REGISTERS setb nDIOR mov W, RC mov TEMP0, W mov W, RD mov TEMP1, W ret ;******************************************************************** CHKCoD clrb ERROR ;CoD=1 IO=0 mov W, #%10001010 ;ERROR CHECKING NOT YET SUPPORTED mov RA, W call READIDE sb TEMP0.CoD setb ERROR snb TEMP0.IO setb ERROR nop snb ERROR jmp TEST5 ret TEST5 inc TEMP jmp CHKCoD ;******************************************************************* CHKDRQ clrb ERROR ;BSY=0 DRQ=1 call RDSTATUS ;;ERROR CHECKING NOT YET SUPPORTED snb TEMP0.BSY setb ERROR sb TEMP0.DRQ setb ERROR nop snb ERROR jmp TEST6 ret TEST6 inc TEMP jmp CHKDRQ ;****************************************************************** ;******************************************************************* ;ROUTINE SENDS 12 BYTE PACKET TO IDE DEVICE SENDCOM call CHKSTATUS ;DO CHECK ;*********************************** mov W, #COMMANDREG ;POINT TO COMMAND REG THEN SEND mov REGISTER, W ;PACKET OPCODE COMMAND mov W, #$A0 mov TEMP0, W call WRITEIDE ;************************************ ;CHECK STATUS OF IDE call CHKCoD ;CHK CoD & IO & BSY call CHKDRQ ;WAIT FOR DRQ=1 ;************************************ mov W, #DATAREG ;POINT TO DATA REGISTER THEN SEND mov REGISTER, W ;12 BYTES TO DATA REGISTER WITHIN IDE (1 PACKET) clr ACCA NXREG2 call PACKET mov TEMP0, W inc ACCA inc PACK call PACKET mov TEMP1, W call WRITEIDE inc PACK inc ACCA mov W, #$0C mov W, ACCA-w sb Z jmp NXREG2 retw #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 mov W, PACK ;*** WARNING: PCLATH register bits are in STATUS PAx bits. Or use PAGE/IREAD if possible ; BCF PCLATH,0 clrb PCLATH.0 ;*** WARNING: PCLATH register bits are in STATUS PAx bits. Or use PAGE/IREAD if possible ; BCF PCLATH,1 clrb PCLATH.1 mov W, PACK add PC, W ;************************* retw #$1B ;0 STOP DISC COMMAND retw #$00 ;1 retw #$00 ;2 retw #$00 ;3 retw #$00 ;4 retw #$00 ;5 retw #$00 ;6 retw #$00 ;7 retw #$00 ;8 retw #$00 ;9 retw #$00 ;10 retw #$00 ;11 ;****************************************** retw #$47 ;0 0XC0 retw #$00 ;1 THIS EXAMPLE PLAYS AT 1min in for 30sec's retw #$00 ;2 PLAY DISC AT TIME STATED MIN SEC 1/75/SEC retw #$01 ;3 MINUTES STARTING POINT retw #$00 ;4 SECONDS STARTING POINT retw #$00 ;5 1/75 SEC STARTING POINT (N/A) retw #$01 ;6 MINUTES STOPING POINT retw #$1E ;7 SECONDS STOPING POINT retw #$00 ;8 1/75 STOPPING POINT (N/A) retw #$00 ;9 retw #$00 ;10 retw #$00 ;11 ;****************************************** retw #$1B ;0 0X18 retw #$00 ;1 EJECT DISC COMMAND retw #$00 ;2 retw #$00 ;3 retw #$02 ;4 retw #$00 ;5 retw #$00 ;6 retw #$00 ;7 retw #$00 ;8 retw #$00 ;9 retw #$00 ;10 retw #$00 ;11 ;****************************************** retw #$1B ;0 0X24 retw #$00 ;1 LOAD DISC COMMAND retw #$00 ;2 retw #$00 ;3 retw #$03 ;4 retw #$00 ;5 retw #$00 ;6 retw #$00 ;7 retw #$00 ;8 retw #$00 ;9 retw #$00 ;10 retw #$00 ;11 ;****************************************** retw #$43 ;0 0X30 retw #$00 ;1 retw #$00 ;2 retw #$00 ;3 retw #$00 ;4 retw #$00 ;5 retw #$00 ;6 retw #$00 ;7 retw #$08 ;8 retw #$00 ;9 retw #$00 ;10 retw #$00 ;11 ;****************************************** ;****************************************** WRITEHD mov W, #%10011010 ;WRITE TO HEAD DEVICE REG WITHIN IDE mov REGISTER, W mov W, #%10100000 ;SET CDROM HEAD REG TO MASTER mov TEMP0, W clr TEMP1 call WRITEIDE ret RDHD mov W, #%10011010 ;READS HEAD REG mov RA, W ;I USED THIS TO CHECK call READIDE ;IF CDROM WAS SET AS MASTER ret RDSTATUS mov W, #%10011110 ;READS STATUS REGISTER WITHIN IDE mov RA, W call READIDE ret CHKSTATUS clrb ERROR call RDSTATUS snb TEMP0.BSY setb ERROR snb TEMP0.DRQ setb ERROR nop snb ERROR jmp TEST4 ret TEST4 inc TEMP jmp CHKSTATUS ;***************************************** ;LOADS PACK REGISTER FOR LOOKUP TABLE ;THEN CALLS ROUTINE TO SEND 12 BYTES (1 PACKET) PLAY mov W, #$0C mov PACK, W call SENDCOM ret STOP mov W, #$00 mov PACK, W call SENDCOM ret EJECT mov W, #$18 mov PACK, W call SENDCOM ret LOADDISC mov W, #$24 mov PACK, W call SENDCOM ret ;**************************************************************************** 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 sb RB.5 call PLAY sb RB.4 call STOP sb RB.3 call EJECT clrb ERROR sb RE.2 call LOADDISC call PAUSE call RDSTATUS jmp TEST1 END
Also: