1 { 2 This file is part of the Free Pascal run time library. 3 4 A file in Amiga system run time library. 5 Copyright (c) 1998 by Nils Sjoholm 6 member of the Amiga RTL development team. 7 8 See the file COPYING.FPC, included in this distribution, 9 for details about the copyright. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 15 **********************************************************************} 16 17 unit cd; 18 19 INTERFACE 20 21 uses exec; 22 { Only V40+ } 23 24 {************************************************************************* 25 * * 26 * CD Commands * 27 * * 28 *************************************************************************} 29 30 const 31 CD_RESET = 1; 32 CD_READ = 2; 33 CD_WRITE = 3; 34 CD_UPDATE = 4; 35 CD_CLEAR = 5; 36 CD_STOP = 6; 37 CD_START = 7; 38 CD_FLUSH = 8; 39 CD_MOTOR = 9; 40 CD_SEEK = 10; 41 CD_FORMAT = 11; 42 CD_REMOVE = 12; 43 CD_CHANGENUM = 13; 44 CD_CHANGESTATE = 14; 45 CD_PROTSTATUS = 15; 46 47 CD_GETDRIVETYPE = 18; 48 CD_GETNUMTRACKS = 19; 49 CD_ADDCHANGEINT = 20; 50 CD_REMCHANGEINT = 21; 51 CD_GETGEOMETRY = 22; 52 CD_EJECT = 23; 53 54 55 CD_INFO = 32; 56 CD_CONFIG = 33; 57 CD_TOCMSF = 34; 58 CD_TOCLSN = 35; 59 60 CD_READXL = 36; 61 62 CD_PLAYTRACK = 37; 63 CD_PLAYMSF = 38; 64 CD_PLAYLSN = 39; 65 CD_PAUSE = 40; 66 CD_SEARCH = 41; 67 68 CD_QCODEMSF = 42; 69 CD_QCODELSN = 43; 70 CD_ATTENUATE = 44; 71 72 CD_ADDFRAMEINT = 45; 73 CD_REMFRAMEINT = 46; 74 75 76 {************************************************************************* 77 * * 78 * Device Driver Error Codes * 79 * * 80 *************************************************************************} 81 82 CDERR_OPENFAIL = (-1); { device/unit failed to open } 83 CDERR_ABORTED = (-2); { request terminated early } 84 CDERR_NOCMD = (-3); { command not supported by device } 85 CDERR_BADLENGTH = (-4); { invalid length (IO_LENGTH/IO_OFFSET) } 86 CDERR_BADADDRESS = (-5); { invalid address (IO_DATA misaligned) } 87 CDERR_UNITBUSY = (-6); { device opens ok, but unit is busy } 88 CDERR_SELFTEST = (-7); { hardware failed self-test } 89 90 CDERR_NotSpecified = 20; { general catchall } 91 CDERR_NoSecHdr = 21; { couldn't even find a sector } 92 CDERR_BadSecPreamble = 22; { sector looked wrong } 93 CDERR_BadSecID = 23; { ditto } 94 CDERR_BadHdrSum = 24; { header had incorrect checksum } 95 CDERR_BadSecSum = 25; { data had incorrect checksum } 96 CDERR_TooFewSecs = 26; { couldn't find enough sectors } 97 CDERR_BadSecHdr = 27; { another "sector looked wrong" } 98 CDERR_WriteProt = 28; { can't write to a protected disk } 99 CDERR_NoDisk = 29; { no disk in the drive } 100 CDERR_SeekError = 30; { couldn't find track 0 } 101 CDERR_NoMem = 31; { ran out of memory } 102 CDERR_BadUnitNum = 32; { asked for a unit > NUMUNITS } 103 CDERR_BadDriveType = 33; { not a drive cd.device understands } 104 CDERR_DriveInUse = 34; { someone else allocated the drive } 105 CDERR_PostReset = 35; { user hit reset; awaiting doom } 106 CDERR_BadDataType = 36; { data on disk is wrong type } 107 CDERR_InvalidState = 37; { invalid cmd under current conditions } 108 109 CDERR_Phase = 42; { illegal or unexpected SCSI phase } 110 CDERR_NoBoard = 50; { open failed for non-existant board } 111 112 113 114 {************************************************************************* 115 * * 116 * Configuration * 117 * * 118 * The drive is configured by TagList items defined as follows: * 119 * * 120 *************************************************************************} 121 122 TAGCD_PLAYSPEED = $0001; 123 TAGCD_READSPEED = $0002; 124 TAGCD_READXLSPEED = $0003; 125 TAGCD_SECTORSIZE = $0004; 126 TAGCD_XLECC = $0005; 127 TAGCD_EJECTRESET = $0006; 128 129 130 {************************************************************************* 131 * * 132 * Information * 133 * * 134 * Information/Status structure describes current speed settings * 135 * for read and play commands, sector size, audio attenuation * 136 * precision, and drive status. * 137 * * 138 *************************************************************************} 139 140 Type 141 142 pCDInfo = ^tCDInfo; 143 tCDInfo = record 144 { Default } 145 PlaySpeed, { Audio play speed (75) } 146 ReadSpeed, { Data-rate of CD_READ command (Max) } 147 ReadXLSpeed, { Data-rate of CD_READXL command (75) } 148 SectorSize, { Number of bytes per sector (2048) } 149 XLECC, { CDXL ECC enabled/disabled } 150 EjectReset : WORD; { Reset on eject enabled/disabled } 151 Reserved1 : Array[0..3] of WORD; { Reserved for future expansion } 152 MaxSpeed, { Maximum speed drive can handle (75, 150) } 153 AudioPrecision, { 0 = no attenuator, 1 = mute only, } 154 { other = (# levels - 1) } 155 Status : WORD; { See flags below } 156 Reserved2 : Array[0..3] of WORD; { Reserved for future expansion } 157 end; 158 159 160 const 161 { Flags for Status } 162 163 CDSTSB_CLOSED = 0; { Drive door is closed } 164 CDSTSB_DISK = 1; { A disk has been detected } 165 CDSTSB_SPIN = 2; { Disk is spinning (motor is on) } 166 CDSTSB_TOC = 3; { Table of contents read. Disk is valid. } 167 CDSTSB_CDROM = 4; { Track 1 contains CD-ROM data } 168 CDSTSB_PLAYING = 5; { Audio is playing } 169 CDSTSB_PAUSED = 6; { Pause mode (pauses on play command) } 170 CDSTSB_SEARCH = 7; { Search mode (Fast Forward/Fast Reverse) } 171 CDSTSB_DIRECTION = 8; { Search direction (0 = Forward, 1 = Reverse) } 172 173 CDSTSF_CLOSED = $0001; 174 CDSTSF_DISK = $0002; 175 CDSTSF_SPIN = $0004; 176 CDSTSF_TOC = $0008; 177 CDSTSF_CDROM = $0010; 178 CDSTSF_PLAYING = $0020; 179 CDSTSF_PAUSED = $0040; 180 CDSTSF_SEARCH = $0080; 181 CDSTSF_DIRECTION = $0100; 182 183 184 { Modes for CD_SEARCH } 185 186 CDMODE_NORMAL = 0; { Normal play at current play speed } 187 CDMODE_FFWD = 1; { Fast forward play (skip-play forward)} 188 CDMODE_FREV = 2; { Fast reverse play (skip-play reverse)} 189 190 191 {************************************************************************* 192 * * 193 * Position Information * 194 * * 195 * Position information can be described in two forms: MSF and LSN * 196 * form. MSF (Minutes, Seconds, Frames) form is a time encoding. * 197 * LSN (Logical Sector Number) form is frame (sector) count. * 198 * The desired form is selected using the io_Flags field of the * 199 * IOStdReq structure. The flags and the union are described * 200 * below. * 201 * * 202 *************************************************************************} 203 204 Type 205 pRMSF = ^tRMSF; 206 tRMSF = record 207 Reserved, { Reserved (always zero) } 208 Minute, { Minutes (0-72ish) } 209 Second, { Seconds (0-59) } 210 Frame : Byte; { Frame (0-74) } 211 end; 212 213 pLSNMSF = ^tLSNMSF; 214 tLSNMSF = record 215 MSF : tRMSF; { Minute, Second, Frame } 216 LSN : ULONG; { Logical Sector Number } 217 end; 218 219 220 {************************************************************************* 221 * * 222 * CD Transfer Lists * 223 * * 224 * A CDXL node is a double link node; however only single linkage * 225 * is used by the device driver. If you wish to construct a * 226 * transfer list manually, it is only neccessary to define the * 227 * mln_Succ pointer of the MinNode. You may also use the Exec * 228 * list functions by defining a List or MinList structure and by * 229 * using the AddHead/AddTail functions to create the list. This * 230 * will create a double-linked list. Although a double-linked * 231 * list is not required by the device driver, you may wish use it * 232 * for your own purposes. Don't forget to initialize the * 233 * the List/MinList before using it! * 234 * * 235 *************************************************************************} 236 237 pCDXL = ^tCDXL; 238 tCDXL = record 239 Node : tMinNode; { double linkage } 240 Buffer : Pointer; { data destination (word aligned) } 241 Length, { must be even # bytes } 242 Actual : Longint; { bytes transferred } 243 IntData : Pointer; { interrupt server data segment } 244 IntCode : Pointer; { interrupt server code entry } 245 end; 246 247 248 {************************************************************************* 249 * * 250 * CD Table of Contents * 251 * * 252 * The CD_TOC command returns an array of CDTOC entries. * 253 * Entry zero contains summary information describing how many * 254 * tracks the disk has and the play-time of the disk. * 255 * Entries 1 through N (N = Number of tracks on disk) contain * 256 * information about the track. * 257 * * 258 *************************************************************************} 259 260 pTOCSummary = ^tTOCSummary; 261 tTOCSummary = record 262 FirstTrack, { First track on disk (always 1) } 263 LastTrack : Byte; { Last track on disk } 264 LeadOut : tLSNMSF; { Beginning of lead-out track (end of disk) } 265 end; 266 267 268 pTOCEntry = ^tTOCEntry; 269 tTOCEntry = record 270 CtlAdr, { Q-Code info } 271 Track : Byte; { Track number } 272 Position : tLSNMSF; { Start position of this track } 273 end; 274 275 276 pCDTOC = ^tCDTOC; 277 tCDTOC = record 278 Summary : tTOCSummary; { First entry (0) is summary information } 279 Entry : tTOCEntry; { Entries 1-N are track entries } 280 end; 281 282 283 284 {************************************************************************* 285 * * 286 * Q-Code Packets * 287 * * 288 * Q-Code packets are only returned when audio is playing. * 289 * Currently, only position packets are returned (ADR_POSITION) * 290 * The other ADR_ types are almost never encoded on the disk * 291 * and are of little use anyway. To avoid making the QCode * 292 * structure a union, these other ADR_ structures are not defined. * 293 * * 294 *************************************************************************} 295 296 pQCode = ^tQCode; 297 tQCode = record 298 CtlAdr, { Data type / QCode type } 299 Track, { Track number } 300 Index, { Track subindex number } 301 Zero : Byte; { The "Zero" byte of Q-Code packet } 302 TrackPosition, { Position from start of track } 303 DiskPosition : tLSNMSF; { Position from start of disk } 304 end; 305 306 const 307 CTLADR_CTLMASK = $F0; { Control field } 308 309 CTL_CTLMASK = $D0; { To be ANDed with CtlAdr before compared } 310 311 CTL_2AUD = $00; { 2 audio channels without preemphasis } 312 CTL_2AUDEMPH = $10; { 2 audio channels with preemphasis } 313 CTL_4AUD = $80; { 4 audio channels without preemphasis } 314 CTL_4AUDEMPH = $90; { 4 audio channels with preemphasis } 315 CTL_DATA = $40; { CD-ROM Data } 316 317 CTL_COPYMASK = $20; { To be ANDed with CtlAdr before compared } 318 319 CTL_COPY = $20; { When true, this audio/data can be copied } 320 321 CTLADR_ADRMASK = $0F; { Address field } 322 323 ADR_POSITION = $01; { Q-Code is position information } 324 ADR_UPC = $02; { Q-Code is UPC information (not used) } 325 ADR_ISRC = $03; { Q-Code is ISRC (not used) } 326 ADR_HYBRID = $05; { This disk is a hybrid disk } 327 328 IMPLEMENTATION 329 330 end. 331