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 $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