CDRecordLib.Mod 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. MODULE CDRecordLib;
  2. IMPORT SYSTEM, KernelLog, Ata := ATADisks, Utils := CDRecordUtils;
  3. CONST
  4. TrackLimit = 99;
  5. ResOk = 0; ResErr = 1;
  6. Trace = FALSE;
  7. Ignore* = 0H;
  8. (* Mode Pages *)
  9. (* Page Codes *)
  10. MPCapabilities* = 2AH;
  11. MPWriteParameters* = 5H;
  12. (* Page Control *)
  13. MPCurrent* = 0H;
  14. MPChangeable* = 1H;
  15. MPDefault* = 2H;
  16. MPSaved* = 3H;
  17. MPPSBit* = 7;
  18. (* Capabilities *)
  19. MPCCdrBit* = 0;
  20. MPCCdRwBit* = 1;
  21. MPCBufeBit* = 7;
  22. MPCMultisessionBit* = 5;
  23. (* Loading Mechanism *)
  24. LMTMask* = {5..7}; LMTOfs* = 5;
  25. LMTCaddy* = 0;
  26. LMTTray* = 1;
  27. LMTPopUp * = 2;
  28. (* Write Parameters *)
  29. MPWBufeBit* = 6;
  30. MPWTestWriteBit* = 4;
  31. MPWWriteTypeMask* = {0..3}; MPWWriteTypeOfs* = 0;
  32. WTPacket* = 0H;
  33. WTTao* = 1H;
  34. WTSao* = 2H;
  35. WTRaw* = 3H;
  36. WTLayerJump* = 4H;
  37. MPWTrackModeMask* = {0..3}; MPWTrackModeOfs* = 0; (* ECMA 130. p. 20 Control Nibble *)
  38. (* Track Mode is the q channel control nibble. See below *)
  39. MPWDataBlockMask* = {0..3}; MPWDataBlockOfs* = 0;
  40. DBRaw* = 0H; (* 2352 *)
  41. DBIsoMode1* = 8H;
  42. DBIsoMode2* = 9H;
  43. (* multisession *)
  44. MPWMultisessionMask* = {6,7}; MPWMultisessionOfs* = 6;
  45. MSNoNextSessNoB0* = 0H;
  46. MSNoNextSessB0* = 1H;
  47. MSNextSessB0* = 3H;
  48. (* Features *)
  49. FMorphing* = 2H;
  50. FMastering* = 2EH;
  51. FAll* = 0H;
  52. FCurrent* = 1H;
  53. FOne* = 2H;
  54. (* CD Mastering *)
  55. FDMSaoBit* = 5;
  56. (* ReadTrackInformation *)
  57. TRAdrType0 = 0H;
  58. TRAdrType1 = 1H;
  59. TRAdrType2 = 2H;
  60. TRAdrType3 = 3H;
  61. TRInvisible* = 0FFH;
  62. (* Read Toc *)
  63. TCFormatToc* = 0H;
  64. TCFormatSessionInfo* = 1H;
  65. TCFormatFullToc* = 2H;
  66. TCFormatPMA* = 3H;
  67. TCFormatATIP* = 4H;
  68. TCFormatCDText* = 5H;
  69. (* track descriptor *)
  70. (* Control is the q channel control nibble. see below *)
  71. TCControlMask* = {0..3}; TCControlOfs* = 0; (* control nibble *)
  72. (* ATIP *)
  73. ATCdRwBit* = 6;
  74. ATA1ValidBit* = 2; ATA2ValidBit* = 1; ATA3ValidBit* = 0;
  75. ATSubTypeMask* = {3..5}; ATSubTypeOfs* = 3;
  76. (* cdr subtypes orange book *)
  77. ATCdrNormal*= 0H;
  78. ATCdrHighSpeed* =1H;
  79. (* cdrw subtypes *)
  80. ATCdRwStandardSpeed* = 0H;
  81. ATCdRwHighSpeed* = 1H;
  82. ATCdRwUltraHighSpeed* = 2H;
  83. ATCdRwUltraHighSpeedPlus* = 3H;
  84. ATRefSpeedMask* ={0..2}; ATRefSpeedOfs*=0;
  85. (* A1 / A2 / A3 Values *)
  86. ATCLVHighMask* = {0..3}; ATCLVHighOfs* = 0;
  87. ATCLVLowMask* = {4..6}; ATCLVLowOfs* = 4;
  88. (* disc information block *)
  89. (* Data Type *)
  90. DTDiscInfoBlock* = 0H;
  91. DTAssignedTrack* = 1H;
  92. DIBErasableBit* = 4;
  93. (*Disc Status *)
  94. DIBDiscStatusMask* = {0,1}; DIBDiscStatusOfs* = 0;
  95. DSEmpty* = 0H;
  96. DSAppendable* = 1H;
  97. DSComplete* = 2H;
  98. DSOtherStatus* =4H;
  99. (* Last Session Status *)
  100. DIBSessionStatusMask* = {2, 3}; DIBSessionStatusOfs*= 2;
  101. LSSEmpty* = 0H;
  102. LSSIncomplete* = 1H;
  103. LSSComplete* = 3H;
  104. (* disc types *)
  105. DTCdDACdRom* = 0H;
  106. DTCdI* = 10H;
  107. DTCdRomXA* = 20H;
  108. DTUndefined* = 0FFH;
  109. (* Cue Sheet *)
  110. (* Ctl/Adr *)
  111. CTLMask* = {4..7}; CTLOfs* = 4;
  112. (* CTL is the q channel control nibble. see below *)
  113. ADRMask* = {0..3}; ADROfs* = 0;
  114. ADRTno* = 1H;
  115. ADRCatalogCode* = 2H;
  116. ADRIsrcCode* =2H;
  117. (* main data form *)
  118. DFMLeadin* = 1H;
  119. DFMLeadout* = 1H;
  120. DFMDigitalAudio* = 0H;
  121. DFMCdRomMode1* = 10H;
  122. DFMMask* = {0..5}; DFMOfs* = 0;
  123. (* Close Session *)
  124. (* Close Function *)
  125. CFTrack* = 1H;
  126. CFSession* = 2H;
  127. (* q Channel Control nibble *)
  128. QCWithPreEmphasis* = 0;
  129. QCCopyPermitted* = 1;
  130. QCDataTrack* = 2;
  131. QC4ChannelAudio* = 3;
  132. (* Blank Disc*)
  133. BDEntire* = 0H;
  134. BDQuick* = 1H;
  135. BDTrack* = 2H; (* optional *)
  136. (* get performance *)
  137. PTypeWriteSpeed* = 3H;
  138. (* Read CD *)
  139. (* sector type *)
  140. STAny* = 0;
  141. STCdDa* = 1;
  142. STMode1* = 2;
  143. STMode2* = 3;
  144. STMode2Form1* = 4;
  145. STMode2Form2*= 5;
  146. (* header *)
  147. HNone*= SYSTEM.VAL(SET, ASH(0, 5));
  148. HOnlyHeader* = SYSTEM.VAL(SET, ASH(1, 5));
  149. HOnlySubHeader* = SYSTEM.VAL(SET, ASH(2, 5));
  150. HAllHeaders* = SYSTEM.VAL(SET, ASH(3, 5));
  151. (* error flags *)
  152. EFNone* = SYSTEM.VAL(SET, ASH(0,1));
  153. EFC2* = SYSTEM.VAL(SET, ASH(1, 1));
  154. EFC2Block *= SYSTEM.VAL(SET, ASH(2, 1));
  155. EDC* = {3};
  156. Sync*= {7};
  157. UserData* = {4};
  158. (* Sub-Channel *)
  159. SCNoData* = 0;
  160. SCRaw* = 1;
  161. TYPE
  162. (* Read Toc *)
  163. TocDescriptor* = RECORD
  164. Reserved1: CHAR;
  165. Byte1*: CHAR;
  166. TNO*: CHAR;
  167. Reserved2: CHAR;
  168. TrackStartAdr*: ARRAY 4 OF CHAR;
  169. END;
  170. TocHeader* = RECORD
  171. DataLength*: ARRAY 2 OF CHAR;
  172. FirstTrackNo*: CHAR;
  173. LastTrackNo*: CHAR;
  174. END;
  175. SessionInfo* = RECORD
  176. DataLength*: ARRAY 2 OF CHAR; (* 0Ah *)
  177. FirstComplSess*: CHAR;
  178. LastComplSess*: CHAR;
  179. Reserved1: CHAR;
  180. Byte1*: CHAR;
  181. FirstTNOLastSess*: CHAR;
  182. Reserved2: CHAR;
  183. StartAdrFirstTrack*: ARRAY 4 OF CHAR;
  184. END;
  185. FullTocDescriptor* = RECORD
  186. SessionNo*: CHAR;
  187. AdrCtrl*: CHAR;
  188. TNO*: CHAR;
  189. Point*: CHAR;
  190. Min*: CHAR;
  191. Sec*: CHAR;
  192. Frame*: CHAR;
  193. Zero*: CHAR;
  194. PMin*: CHAR;
  195. PSec*: CHAR;
  196. PFrame*: CHAR;
  197. END;
  198. FullTocHeader* = RECORD
  199. DataLength: ARRAY 2 OF CHAR;
  200. FirstComplSessNo*, LastComplSessNo*: CHAR;
  201. END;
  202. PmaDescriptor* = RECORD
  203. Reserved: CHAR;
  204. AdrCtrl*: CHAR;
  205. TNO*: CHAR;
  206. Point*: CHAR;
  207. Min*: CHAR;
  208. Sec*: CHAR;
  209. Frame*: CHAR;
  210. Zero*: CHAR;
  211. PMin*: CHAR;
  212. PSec*: CHAR;
  213. PFrame*: CHAR;
  214. END;
  215. PmaHeader* = RECORD
  216. DataLength*: ARRAY 2 OF CHAR;
  217. Reserved1: ARRAY 2 OF CHAR;
  218. END;
  219. ATIPHeader* = PmaHeader;
  220. ATIPDescriptor* = RECORD
  221. Byte0*, Byte1*, Byte2*: CHAR;
  222. Reserved1: CHAR;
  223. LeadInMin*, LeadInSec*, LeadInFrame*: CHAR;
  224. Reserved2: CHAR;
  225. LastLeadOutMin*, LastLeadOutSec*, LastLeadOutFrame*: CHAR;
  226. Reserved3: CHAR;
  227. A1Values*: ARRAY 3 OF CHAR;
  228. Reserved4: CHAR;
  229. A2Values*: ARRAY 3 OF CHAR;
  230. Reserved5: CHAR;
  231. A3Values*: ARRAY 3 OF CHAR;
  232. Reserved6: CHAR;
  233. END;
  234. ATIPDescriptorPtr* = POINTER TO ATIPDescriptor;
  235. (* Read Track Information *)
  236. TrackInfo* = RECORD
  237. InfoLength*: ARRAY 2 OF CHAR;
  238. TrackNo*: CHAR;
  239. SessionNo*: CHAR;
  240. Reserved1*: CHAR;
  241. Byte5*, Byte6*, Byte7*: CHAR;
  242. StartAdr*: ARRAY 4 OF CHAR;
  243. NextWriteAdr*: ARRAY 4 OF CHAR;
  244. FreeBlocks*: ARRAY 4 OF CHAR;
  245. PacketSize*: ARRAY 4 OF CHAR;
  246. Size*: ARRAY 4 OF CHAR;
  247. END;
  248. (* Read Disc Information *)
  249. DiscInfo* = RECORD
  250. DataLength*: ARRAY 2 OF CHAR;
  251. Byte2*: CHAR;
  252. NoFirstTrack*: CHAR;
  253. NofSessions*: CHAR;
  254. FirstTNOLastSess*: CHAR;
  255. LastTNOLastSess*: CHAR;
  256. Byte7*: CHAR;
  257. DiscType*: CHAR;
  258. Reserved1*: ARRAY 3 OF CHAR; (* session/tracks <= 99 *)
  259. DiscIdent*: ARRAY 4 OF CHAR;
  260. LeadInLastSess*: ARRAY 4 OF CHAR;
  261. LastLeadOut*: ARRAY 4 OF CHAR;
  262. BarCode*: ARRAY 8 OF CHAR;
  263. END;
  264. (* mode pages *)
  265. ModeHeader* = RECORD
  266. DataLength*: ARRAY 2 OF CHAR;
  267. Obsolete*: CHAR;
  268. Reserved*: ARRAY 3 OF CHAR;
  269. DescrLength*: ARRAY 2 OF CHAR;
  270. END;
  271. CapabilityPage* = RECORD
  272. Header*: ModeHeader;
  273. Byte0*: CHAR;
  274. Length*: CHAR;
  275. Byte2*, Byte3*, Byte4*, Byte5*, Byte6*, Byte7*: CHAR;
  276. MaxReadSpeed*: ARRAY 2 OF CHAR; (* obsolete *)
  277. NoVolumeLevels*: ARRAY 2 OF CHAR;
  278. BufferSize*: ARRAY 2 OF CHAR;
  279. CurReadSpeed*: ARRAY 2 OF CHAR; (* obsolete *)
  280. Obsolete*: CHAR;
  281. Byte17*: CHAR;
  282. MaxWriteSpeed*: ARRAY 2 OF CHAR; (* obsolete*)
  283. CurWriteSpeed1*: ARRAY 2 OF CHAR; (* obsolete *)
  284. CopyManagement*: ARRAY 2 OF CHAR;
  285. Reserved1*: ARRAY 3 OF CHAR;
  286. Byte27*: CHAR;
  287. CurWriteSpeed2*: ARRAY 2 OF CHAR;
  288. NofWriteDescriptors*: ARRAY 2 OF CHAR;
  289. END;
  290. CapabilityPagePtr* = POINTER TO CapabilityPage;
  291. SpeedDescriptor* = RECORD
  292. Reserved: CHAR;
  293. Byte1*: CHAR;
  294. WriteSpeed*: ARRAY 2 OF CHAR; (* kbytes/s*)
  295. END;
  296. SpeedDescriptorPtr* = POINTER TO SpeedDescriptor;
  297. (* Write Parameters Mode Page *)
  298. WriteParameterPage* = RECORD
  299. Header*: ModeHeader;
  300. Byte0*: CHAR;
  301. Length*: CHAR;
  302. Byte2*, Byte3*, Byte4*: CHAR;
  303. LinkSize*: CHAR;
  304. Reserved1*: CHAR;
  305. Byte7*: CHAR;
  306. SessionFormat*: CHAR;
  307. Reserved2*: CHAR;
  308. PacketSize*: ARRAY 4 OF CHAR;
  309. PauseLength*: ARRAY 2 OF CHAR;
  310. CatalogNo*: ARRAY 16 OF CHAR;
  311. ISRC*: ARRAY 16 OF CHAR;
  312. SubHeader*: ARRAY 4 OF CHAR;
  313. END;
  314. (* Get Configuration *)
  315. FeatureHeader = RECORD
  316. DataLength: ARRAY 4 OF CHAR;
  317. Reserved1: CHAR;
  318. Reserved2: CHAR;
  319. CurProfile: ARRAY 2 OF CHAR;
  320. END;
  321. MasteringFeature* = RECORD
  322. Header: FeatureHeader;
  323. FeatureCode*: ARRAY 2 OF CHAR;
  324. Byte2*: CHAR;
  325. AdditionalLength*: CHAR;
  326. Byte4*: CHAR;
  327. MaxCueSheetLen*: ARRAY 3 OF CHAR;
  328. END;
  329. (* Read Buffer Capacity *)
  330. BufferCapacity* = RECORD
  331. DataLength*: ARRAY 2 OF CHAR;
  332. Reserved1*: CHAR;
  333. Reserved2*: CHAR;
  334. BufferLength*: ARRAY 4 OF CHAR;
  335. BlankLength*: ARRAY 4 OF CHAR;
  336. END;
  337. (* Get Performance *)
  338. WriteSpeedHeader* = RECORD
  339. DataLength*: ARRAY 4 OF CHAR;
  340. Reserved*: ARRAY 4 OF CHAR;
  341. END;
  342. WriteSpeedDescr* = RECORD
  343. Byte0*: CHAR;
  344. Reserved: ARRAY 3 OF CHAR;
  345. EndLba*: ARRAY 4 OF CHAR;
  346. ReadSpeed*: ARRAY 4 OF CHAR;
  347. WriteSpeed*: ARRAY 4 OF CHAR;
  348. END;
  349. WriteSpeedDescrPtr* = POINTER TO WriteSpeedDescr;
  350. PROCEDURE GetNextAddress*(dev: Ata.DeviceATAPI; VAR adr: LONGINT): WORD;
  351. VAR
  352. info: TrackInfo;
  353. res: WORD;
  354. BEGIN
  355. res := ReadTrackInformation(dev, FALSE, TRAdrType1, TRInvisible, ADDRESSOF(info), SIZEOF(TrackInfo));
  356. IF res = ResOk THEN
  357. adr := Utils.ConvertBE32Int(info.NextWriteAdr);
  358. END;
  359. RETURN res;
  360. END GetNextAddress;
  361. PROCEDURE ReadSessionInfo*(dev: Ata.DeviceATAPI; VAR info: SessionInfo): WORD;
  362. BEGIN
  363. RETURN ReadToc(dev, FALSE, TCFormatSessionInfo, 0, ADDRESSOF(info), SIZEOF(SessionInfo));
  364. END ReadSessionInfo;
  365. PROCEDURE GetTrackDescriptor*(dev: Ata.DeviceATAPI; tno: LONGINT; VAR toc: TocDescriptor): WORD;
  366. VAR
  367. buf: POINTER TO ARRAY OF CHAR;
  368. res: WORD;
  369. BEGIN
  370. NEW(buf, SIZEOF(TocHeader) + SIZEOF(TocDescriptor));
  371. res := ReadToc(dev, FALSE, TCFormatToc, tno, ADDRESSOF(buf^), LEN(buf));
  372. IF res = ResOk THEN
  373. SYSTEM.MOVE(ADDRESSOF(buf^) + SIZEOF(TocHeader), ADDRESSOF(toc), SIZEOF(TocDescriptor));
  374. END;
  375. RETURN res;
  376. END GetTrackDescriptor;
  377. PROCEDURE SetField*(VAR byte: CHAR; mask: SET; ofs, value: LONGINT);
  378. BEGIN
  379. byte := SYSTEM.VAL(CHAR, (SYSTEM.VAL(SET, byte) * (-mask)) + SYSTEM.VAL(SET, LSH(value, ofs)));
  380. END SetField;
  381. PROCEDURE GetField*(byte: CHAR; mask: SET; ofs: LONGINT) : LONGINT;
  382. BEGIN
  383. RETURN LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, byte) * mask), -ofs);
  384. END GetField;
  385. PROCEDURE SetBit*(VAR byte: CHAR; bit: SHORTINT);
  386. BEGIN
  387. ASSERT(bit < 8);
  388. byte := SYSTEM.VAL(CHAR, SYSTEM.VAL(SET, byte) + {bit});
  389. END SetBit;
  390. PROCEDURE CheckBit*(byte: CHAR; bit: SHORTINT): BOOLEAN;
  391. BEGIN
  392. RETURN bit IN SYSTEM.VAL(SET, byte);
  393. END CheckBit;
  394. PROCEDURE ClearBit*(VAR byte: CHAR; bit: SHORTINT);
  395. BEGIN
  396. ASSERT(bit < 8);
  397. byte := SYSTEM.VAL(CHAR, SYSTEM.VAL(SET, byte) *(-{bit}));
  398. END ClearBit;
  399. PROCEDURE CLVToSpeed*(clv: LONGINT): LONGINT;
  400. VAR
  401. speed: LONGINT;
  402. BEGIN
  403. CASE clv OF
  404. 1: speed := 2;
  405. | 2: speed := 4;
  406. | 3: speed := 6;
  407. | 4: speed := 8;
  408. ELSE speed := 0;
  409. END;
  410. RETURN speed;
  411. END CLVToSpeed;
  412. PROCEDURE CLVToHighSpeed*(clv: LONGINT): LONGINT;
  413. VAR
  414. speed: LONGINT;
  415. BEGIN
  416. CASE clv OF
  417. 1: speed := 2;
  418. | 2: speed := 4;
  419. | 3: speed := 6;
  420. | 4: speed := 10;
  421. ELSE speed := 0;
  422. END;
  423. RETURN speed;
  424. END CLVToHighSpeed;
  425. PROCEDURE CLVToUltraHighSpeed*(clv: LONGINT): LONGINT;
  426. VAR
  427. speed: LONGINT;
  428. BEGIN
  429. CASE clv OF
  430. 1: speed := 2;
  431. | 2: speed := 4;
  432. | 3: speed := 8;
  433. | 6: speed := 16;
  434. | 8: speed := 24;
  435. | 9: speed := 32;
  436. | 10: speed := 40;
  437. | 11: speed := 48;
  438. ELSE speed := 0;
  439. END;
  440. RETURN speed;
  441. END CLVToUltraHighSpeed;
  442. PROCEDURE SetAllocationLength(VAR command: Ata.CommandPacket; length: LONGINT);
  443. BEGIN
  444. command.packet[7] := CHR(ASH(length, -8) MOD 100H);
  445. command.packet[8] := CHR(length MOD 100H)
  446. END SetAllocationLength;
  447. (* additional ATAPI commands *)
  448. PROCEDURE ModeSense*(dev: Ata.DeviceATAPI; pageControl, pageCode: LONGINT; adr: ADDRESS; len: LONGINT) : WORD;
  449. VAR
  450. command: Ata.CommandPacket;
  451. res: WORD;
  452. status: SET;
  453. BEGIN
  454. command := dev.NewCommandPacket(5AH);
  455. command.packet[1] := 8X;
  456. SetField(command.packet[2], {6, 7}, 6, pageControl);
  457. SetField(command.packet[2], {0..5}, 0, pageCode);
  458. SetAllocationLength(command, len);
  459. command.protocol := Ata.Protocol_PacketPIO;
  460. command.read := TRUE;
  461. command.bufAdr := adr;
  462. command.size := len;
  463. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  464. IF Trace THEN
  465. KernelLog.String(dev.name); KernelLog.String(" mode sense"); KernelLog.Ln;
  466. END;
  467. RETURN res;
  468. END ModeSense;
  469. PROCEDURE Blank*(dev: Ata.DeviceATAPI; immediate: BOOLEAN; type, tno: LONGINT): WORD;
  470. VAR
  471. command: Ata.CommandPacket;
  472. res: WORD;
  473. status: SET;
  474. BEGIN
  475. command := dev.NewCommandPacket(0A1H);
  476. command.packet[1] := CHR(type);
  477. IF immediate THEN
  478. SetBit(command.packet[1], 4);
  479. END;
  480. command.packet[2] := CHR(ASH(tno, -24) MOD 100H);
  481. command.packet[3] := CHR(ASH(tno, -16) MOD 100H);
  482. command.packet[4] := CHR(ASH(tno, -8) MOD 100H);
  483. command.packet[5] := CHR(tno MOD 100H);
  484. command.protocol:= Ata.Protocol_PacketPIO;
  485. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  486. IF Trace THEN
  487. KernelLog.String(dev.name); KernelLog.String(" blank"); KernelLog.Ln;
  488. END;
  489. RETURN res;
  490. END Blank;
  491. PROCEDURE SendOPCInformation*(dev: Ata.DeviceATAPI; doOPC: BOOLEAN): WORD;
  492. VAR
  493. command: Ata.CommandPacket;
  494. res: WORD;
  495. status: SET;
  496. BEGIN
  497. command := dev.NewCommandPacket(54H);
  498. IF doOPC THEN
  499. SetBit(command.packet[1], 0);
  500. END;
  501. SetAllocationLength(command, 0);
  502. command.protocol := Ata.Protocol_PacketPIO;
  503. command.read := FALSE;
  504. command.bufAdr := 0;
  505. command.size := 0;
  506. res := dev.controller.ExecuteCommand(command, 10*Ata.ATAPITimeout, status);
  507. IF Trace THEN
  508. KernelLog.String(dev.name); KernelLog.String(" send opc information"); KernelLog.Ln;
  509. END;
  510. RETURN res;
  511. END SendOPCInformation;
  512. PROCEDURE GetConfiguration*(dev: Ata.DeviceATAPI; rt, start: LONGINT; adr: ADDRESS; len: LONGINT): WORD;
  513. VAR
  514. command: Ata.CommandPacket;
  515. res: WORD;
  516. status: SET;
  517. BEGIN
  518. command := dev.NewCommandPacket(46H);
  519. SetField(command.packet[1], {0,1}, 0, rt);
  520. command.packet[2] := CHR(ASH(start, -8) MOD 100H);
  521. command.packet[3] := CHR(start MOD 100H);
  522. SetAllocationLength(command, len);
  523. command.protocol := Ata.Protocol_PacketPIO;
  524. command.read := TRUE;
  525. command.bufAdr := adr;
  526. command.size := len;
  527. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  528. IF Trace THEN
  529. KernelLog.String(dev.name); KernelLog.String(" get configuration"); KernelLog.Ln;
  530. END;
  531. RETURN res;
  532. END GetConfiguration;
  533. PROCEDURE SynchronizeCache*(dev: Ata.DeviceATAPI; immediate: BOOLEAN): WORD;
  534. VAR
  535. command: Ata.CommandPacket;
  536. res: WORD;
  537. status: SET;
  538. BEGIN
  539. command := dev.NewCommandPacket(35H);
  540. IF immediate THEN
  541. SetBit(command.packet[1], 1);
  542. END;
  543. command.protocol:= Ata.Protocol_PacketPIO;
  544. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  545. IF Trace THEN
  546. KernelLog.String(dev.name); KernelLog.String(" synchronize cache "); KernelLog.Ln;
  547. END;
  548. RETURN res;
  549. END SynchronizeCache;
  550. PROCEDURE ModeSelect*(dev: Ata.DeviceATAPI; save: BOOLEAN; adr: ADDRESS; len: LONGINT): WORD;
  551. VAR
  552. command: Ata.CommandPacket;
  553. res: WORD;
  554. status: SET;
  555. BEGIN
  556. command := dev.NewCommandPacket(55H);
  557. SetBit(command.packet[1], 4);
  558. IF save THEN
  559. SetBit(command.packet[1], 0);
  560. END;
  561. SetAllocationLength(command, len);
  562. command.protocol := Ata.Protocol_PacketPIO;
  563. command.read := FALSE;
  564. command.bufAdr := adr;
  565. command.size := len;
  566. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  567. IF Trace THEN
  568. KernelLog.String(dev.name); KernelLog.String(" mode select"); KernelLog.Ln;
  569. END;
  570. RETURN res;
  571. END ModeSelect;
  572. PROCEDURE ReadDiscInformation*(dev: Ata.DeviceATAPI; dataType: LONGINT; adr: ADDRESS; len: LONGINT): WORD;
  573. VAR
  574. command: Ata.CommandPacket;
  575. res: WORD;
  576. status: SET;
  577. BEGIN
  578. command := dev.NewCommandPacket(51H);
  579. SetField(command.packet[1], {0..2}, 0, dataType);
  580. SetAllocationLength(command, len);
  581. command.protocol := Ata.Protocol_PacketPIO;
  582. command.read := TRUE;
  583. command.bufAdr := adr;
  584. command.size := len;
  585. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  586. IF Trace THEN
  587. KernelLog.String(dev.name); KernelLog.String(" read disc information "); KernelLog.Ln;
  588. END;
  589. RETURN res;
  590. END ReadDiscInformation;
  591. PROCEDURE ReadToc*(dev: Ata.DeviceATAPI; msf: BOOLEAN; format, tno: LONGINT; adr: ADDRESS; len: LONGINT): WORD;
  592. VAR
  593. command: Ata.CommandPacket;
  594. res: WORD;
  595. status: SET;
  596. BEGIN
  597. command := dev.NewCommandPacket(43H);
  598. IF msf THEN
  599. SetBit(command.packet[1], 1);
  600. END;
  601. SetField(command.packet[2], {0..3}, 0, format);
  602. command.packet[6] := CHR(tno);
  603. SetAllocationLength(command, len);
  604. command.protocol := Ata.Protocol_PacketPIO;
  605. command.read := TRUE;
  606. command.bufAdr := adr;
  607. command.size := len;
  608. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  609. IF Trace THEN
  610. KernelLog.String(dev.name); KernelLog.String(" read toc "); KernelLog.Ln;
  611. END;
  612. RETURN res;
  613. END ReadToc;
  614. PROCEDURE Verify*(dev: Ata.DeviceATAPI; lba, length: LONGINT): WORD;
  615. VAR
  616. command: Ata.CommandPacket;
  617. res: WORD;
  618. status: SET;
  619. BEGIN
  620. command := dev.NewCommandPacket(2FH);
  621. command.packet[2] := CHR(ASH(lba, -24) MOD 100H);
  622. command.packet[3] := CHR(ASH(lba, -16) MOD 100H);
  623. command.packet[4] := CHR(ASH(lba, -8) MOD 100H);
  624. command.packet[5] := CHR(lba MOD 100H);
  625. command.packet[7] := CHR(ASH(length, -8) MOD 100H);
  626. command.packet[8] := CHR(length MOD 100H);
  627. command.protocol := Ata.Protocol_PacketPIO;
  628. res := dev.controller.ExecuteCommand(command, Ata.IOTimeout, status);
  629. IF Trace THEN
  630. KernelLog.String(dev.name); KernelLog.String(" verify"); KernelLog.Ln;
  631. END;
  632. RETURN res;
  633. END Verify;
  634. PROCEDURE ReadCD*(dev: Ata.DeviceATAPI; lba, length, adr, size, type, subChannel: LONGINT; flags: SET; dma: BOOLEAN): WORD;
  635. VAR
  636. command: Ata.CommandPacket;
  637. res: WORD;
  638. status: SET;
  639. BEGIN
  640. command := dev.NewCommandPacket(0BEH);
  641. SetField(command.packet[1], {2..4}, 2, type);
  642. command.packet[2] := CHR(ASH(lba, -24) MOD 100H);
  643. command.packet[3] := CHR(ASH(lba, -16) MOD 100H);
  644. command.packet[4] := CHR(ASH(lba, -8) MOD 100H);
  645. command.packet[5] := CHR(lba MOD 100H);
  646. command.packet[7] := CHR(ASH(length, -16) MOD 100H);
  647. command.packet[7] := CHR(ASH(length, -8) MOD 100H);
  648. command.packet[8] := CHR(length MOD 100H);
  649. command.packet[9] := SYSTEM.VAL(CHAR, flags);
  650. SetField(command.packet[10], {0..2}, 0, subChannel);
  651. command.protocol := Ata.Protocol_PacketPIO;
  652. command.read := TRUE;
  653. command.bufAdr := adr;
  654. command.size := size;
  655. command.count := length;
  656. IF dma THEN
  657. command.protocol := Ata.Protocol_PacketDMA;
  658. INCL(command.features, Ata.ATAPI_DMA);
  659. ELSE
  660. command.protocol := Ata.Protocol_PacketPIO;
  661. END;
  662. res := dev.controller.ExecuteCommand(command, Ata.IOTimeout, status);
  663. IF Trace THEN
  664. KernelLog.String(dev.name); KernelLog.String(" read cd"); KernelLog.Ln;
  665. END;
  666. RETURN res;
  667. END ReadCD;
  668. PROCEDURE GetPerformance*(dev: Ata.DeviceATAPI; type, dataType, lba, maxDescr: LONGINT; adr: ADDRESS; len: LONGINT): WORD;
  669. VAR
  670. command: Ata.CommandPacket;
  671. res: WORD;
  672. status: SET;
  673. BEGIN
  674. command := dev.NewCommandPacket(0ACH);
  675. SetField(command.packet[1], {0..4}, 0, dataType);
  676. command.packet[2] := CHR(ASH(lba, -24) MOD 100H);
  677. command.packet[3] := CHR(ASH(lba, -16) MOD 100H);
  678. command.packet[4] := CHR(ASH(lba, -8) MOD 100H);
  679. command.packet[5] := CHR(lba MOD 100H);
  680. command.packet[8] := CHR(ASH(maxDescr, -8) MOD 100H);
  681. command.packet[9] := CHR(maxDescr MOD 100H);
  682. command.packet[10] := CHR(type);
  683. command.protocol := Ata.Protocol_PacketPIO;
  684. command.read := TRUE;
  685. command.bufAdr := adr;
  686. command.size := len;
  687. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  688. IF Trace THEN
  689. KernelLog.String(dev.name); KernelLog.String(" get performance "); KernelLog.Ln;
  690. END;
  691. RETURN res;
  692. END GetPerformance;
  693. PROCEDURE ReadTrackInformation*(dev: Ata.DeviceATAPI; appendable: BOOLEAN; adrType, adrnr: LONGINT; adr: ADDRESS; len: LONGINT): WORD;
  694. VAR
  695. command: Ata.CommandPacket;
  696. res: WORD;
  697. status: SET;
  698. BEGIN
  699. command := dev.NewCommandPacket(52H);
  700. SetField(command.packet[1], {0,1}, 0, adrType);
  701. IF appendable THEN
  702. SetBit(command.packet[1], 2);
  703. END;
  704. command.packet[2] := CHR(ASH(adrnr, -24) MOD 100H);
  705. command.packet[3] := CHR(ASH(adrnr, -16) MOD 100H);
  706. command.packet[4] := CHR(ASH(adrnr, -8) MOD 100H);
  707. command.packet[5] := CHR(adrnr MOD 100H);
  708. SetAllocationLength(command, len);
  709. command.protocol := Ata.Protocol_PacketPIO;
  710. command.read := TRUE;
  711. command.bufAdr := adr;
  712. command.size := len;
  713. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  714. IF Trace THEN
  715. KernelLog.String(dev.name); KernelLog.String(" read track information "); KernelLog.Ln;
  716. END;
  717. RETURN res;
  718. END ReadTrackInformation;
  719. PROCEDURE CloseTrackSess*(dev: Ata.DeviceATAPI; immediate: BOOLEAN; func, trackNr: LONGINT): WORD;
  720. VAR
  721. command: Ata.CommandPacket;
  722. res: WORD;
  723. status: SET;
  724. BEGIN
  725. command := dev.NewCommandPacket(5BH);
  726. IF immediate THEN
  727. SetBit(command.packet[1], 0);
  728. END;
  729. SetField(command.packet[2], {0..2}, 0, func);
  730. command.packet[4] := CHR(ASH(trackNr, -8) MOD 100H);
  731. command.packet[5] := CHR(trackNr MOD 100H);
  732. command.protocol := Ata.Protocol_PacketPIO;
  733. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  734. IF Trace THEN
  735. KernelLog.String(dev.name); KernelLog.String(" close track / Session"); KernelLog.Ln;
  736. END;
  737. RETURN res;
  738. END CloseTrackSess;
  739. PROCEDURE ReadBufferCapacity*(dev: Ata.DeviceATAPI; block: BOOLEAN; adr: ADDRESS; len: LONGINT): WORD;
  740. VAR
  741. command: Ata.CommandPacket;
  742. res: WORD;
  743. status: SET;
  744. BEGIN
  745. command := dev.NewCommandPacket(5CH);
  746. IF block THEN
  747. SetBit(command.packet[1], 0);
  748. END;
  749. SetAllocationLength(command, 12);
  750. command.protocol := Ata.Protocol_PacketPIO;
  751. command.read := TRUE;
  752. command.bufAdr := adr;
  753. command.size := len;
  754. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  755. IF Trace THEN
  756. KernelLog.String(dev.name); KernelLog.String(" read buffer capacity "); KernelLog.Ln;
  757. END;
  758. RETURN res;
  759. END ReadBufferCapacity;
  760. PROCEDURE SetCDSpeed*(dev: Ata.DeviceATAPI; readSpeed, writeSpeed, rotControl: LONGINT): WORD;
  761. VAR
  762. command: Ata.CommandPacket;
  763. res: WORD;
  764. status: SET;
  765. BEGIN
  766. command := dev.NewCommandPacket(0BBH);
  767. SetField(command.packet[1], {0,1}, 0, rotControl);
  768. command.packet[2] := CHR(ASH(readSpeed, -8) MOD 100H);
  769. command.packet[3] := CHR(readSpeed MOD 100H);
  770. command.packet[4] := CHR(ASH(writeSpeed, -8) MOD 100H);
  771. command.packet[5] := CHR(writeSpeed MOD 100H);
  772. command.protocol := Ata.Protocol_PacketPIO;
  773. res := dev.controller.ExecuteCommand(command, Ata.ATAPITimeout, status);
  774. IF Trace THEN
  775. KernelLog.String(dev.name); KernelLog.String(" set cd speed "); KernelLog.Ln;
  776. END;
  777. RETURN res;
  778. END SetCDSpeed;
  779. PROCEDURE SendCueSheet*(dev: Ata.DeviceATAPI; adr: ADDRESS; len: LONGINT): WORD;
  780. VAR
  781. command: Ata.CommandPacket;
  782. res: WORD;
  783. status: SET;
  784. BEGIN
  785. command := dev.NewCommandPacket(5DH);
  786. command.packet[6] := CHR(ASH(len, -16) MOD 100H);
  787. command.packet[7] := CHR(ASH(len, -8) MOD 100H);
  788. command.packet[8] := CHR(len MOD 100H);
  789. command.protocol := Ata.Protocol_PacketPIO;
  790. command.read := FALSE;
  791. command.bufAdr := adr;
  792. command.size :=len;
  793. res := dev.controller.ExecuteCommand(command, 4*Ata.ATAPITimeout, status);
  794. IF Trace THEN
  795. KernelLog.String(dev.name); KernelLog.String(" send cue sheet"); KernelLog.Ln;
  796. END;
  797. RETURN res;
  798. END SendCueSheet;
  799. END CDRecordLib.
  800. CDRecordLib.test~