home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
Utilities
/
ACDPlay
/
src
/
V1.5
/
pickcdid
/
Quick.s
< prev
Wrap
Text File
|
1997-04-26
|
27KB
|
657 lines
*
* Quick.s V0.2 für PickCDID V0.4
*
include 'exec/ports.i'
include 'exec/memory.i'
include 'devices/scsidisk.i'
include 'devices/cd.i'
include 'dos/dos.i'
include 'dos/dosextens.i'
include 'intuition/intuition.i'
include 'libraries/gadtools.i'
include 'libraries/locale.i'
include 'lvo/dos.i'
include 'lvo/exec.i'
include 'lvo/intuition.i'
include "CD-ROM.i"
xref __wbflag
xref _DOSBase
xref _IntuitionBase
xref _ReqToolsBase
_LVOrtEZRequestA equ -66
FALSE equ 0
TRUE equ 1
NULL equ 0
;include "CD-ROM.s"
************************** ListLengthA *****************************
*
* ULONG ListLengthA(register __a0 struct List *list);
*
CNOP 0,2
xdef _ListLengthA
_ListLengthA: movem.l d1/a0,-(sp) ; Register sichern
moveq #-2,d0 ; Zähler auf -2 setzen
.Loop addq.l #1,d0 ; Nodezähler erhöhen
move.l (a0),a0 ; lh_Head/ln_Succ in a0
move.l a0,d1 ; für Condition-Flags
bne.s .Loop ; bis Liste zu Ende ist
.EXIT movem.l (sp)+,d1/a0 ; Register restaurieren
rts
************************** FormatA ********************************
*
* void FormatA(register __a0 char *buffer, register __a1 char *formatstr, ...);
*
* Kopiert den formatierten Text formatstr nach buffer und benutzt dabei
* die Werte bzw. Adressen der Argumente vom Stack.
*
CNOP 0,2
xdef _FormatA
_FormatA: movem.l d0-d1/a0-a3/a6,-(sp) ; Register sichern
movea.l 4.w,a6 ; SysBase laden
; Argumente für RawDoFmt()
movea.l a0,a3 ; PutChData -> a3
movea.l a1,a0 ; FormatString -> a0
movea.l a7,a1 ; DataStream -> a1
lea 32(a1),a1 ; Offset da Register auf dem Stack sind
lea PutChProc(pc),a2 ; Copy-Routine
jsr _LVORawDoFmt(a6)
.EXIT movem.l (sp)+,d0-d1/a0-a3/a6 ; Register restaurieren
rts
PutChProc: move.b d0,(a3)+ ; wird von RawDoFMt aufgerufen
rts ; soll ich einen Overflowtest einbauen?
************************* ShowMsgA ********************************
*
* void ShowMsgA(char *ReqTitle, char *ReqBody, ...);
*
* Zeigt eine Nachricht Abhängig von __wbflag auf der Workbench als Requester
* oder im CLI an.
*
CNOP 0,2
xdef _ShowMsgA
_ShowMsgA: movem.l d0-d2/a0-a4/a6,-(sp)
tst.w __wbflag ; von WB gestartet?
beq .CLIMsg ; nein: in CLI schreiben
.WBMsg move.l _ReqToolsBase,d1 ; ReqToolsLib geöffnet?
beq .asl
movea.l d1,a6 ; ReqToolsBase laden
suba.l a0,a0 ; taglist=NULL
move.l 44(a7),a1 ; ReqBody
lea Okay(pc),a2 ; GadgetBody
suba.l a3,a3 ; *reqInfo=NULL
movea.l a7,a4 ; * auf restliche
adda.l #48,a4 ; Argumente nach a4
jsr _LVOrtEZRequestA(a6)
bra .EXIT
.asl lea MsgEasyStruct(pc),a1 ; a1=*EasyStruct
move.l 40(a7), es_Title(a1) ; Titel eintragen
move.l 44(a7), es_TextFormat(a1) ; Text eintragen
lea Okay(pc),a0
move.l a0, es_GadgetFormat(a1) ; Gadgettext eintragen
suba.l a0,a0 ; *Window=NULL
suba.l a2,a2 ; a2=NULL (IDCMP)
movea.l a7,a3 ; * auf restliche
adda.l #48,a3 ; Argumente nach a3
move.l _IntuitionBase, a6 ; IBase laden
jsr _LVOEasyRequestArgs(a6) ; Requester darstellen
bra .EXIT ; das wars
.CLIMsg suba.l #88,a7 ; 88 bytes auf´m Stack
move.l a7,d1 ; freimachen damit 87
moveq #87,d2 ; Zeichen da reinpassen
move.l _DOSBase, a6 ; DOSBase laden
jsr _LVOGetProgramName(a6) ; ProgNamen in Puffer schreiben
tst.w d0 ; geklappt ?
beq .WriteMsg ; nö: Msg ausgeben
move.l a7,d1
jsr _LVOPutStr(a6) ; Prognamen ausgeben
lea Colon(pc),a1
move.l a1,d1
jsr _LVOPutStr(a6) ; ": " ausgeben
.WriteMsg adda.l #88,a7 ; Stack zurücksetzen
move.l 44(a7),d1 ; ReqBody als Arg für VPrintf
move.l a7,d2
addi.b #48,d2 ; Rest als Argument
jsr _LVOVPrintf(a6) ; Msg ausgeben
lea LineFeed(pc),a1 ; erst mit dem LF
move.l a1,d1 ; erscheint alles im
jsr _LVOPutStr(a6) ; CON-CLI-Window
.EXIT movem.l (sp)+, d0-d2/a0-a4/a6 ; Register wiederherstellen
rts
MsgEasyStruct: dc.l 20 ; es_StructSize
dc.l 0 ; es_Flags
dc.l 0 ; es_Title
dc.l 0 ; es_TextFormat
dc.l 0 ; es_GadgetFormat
Okay: dc.b "Okay",0
Colon: dc.b ": ",0
LineFeed: dc.b 10,0
************************* GetVecA *********************************
*
* APTR GetVecA(register __d0 ULONG bytesize, register __d1 ULONG requirements);
*
* Versucht 'bytesize' Bytes RAM zu erhalten und Zeigt im Fehlerfall eine
* Fehlermeldung an.
*
CNOP 0,2
xdef _GetVecA
_GetVecA: movem.l d1-d2/a0-a1/a6,-(sp) ; alte Register speichern
move.l d0,d2 ; bytesize für Fehlerfall sichern
move.l 4.w,a6 ; SysBase laden
jsr _LVOAllocVec(a6) ; AllocVec bytesize requiements
tst.l d0 ; erfolgreich?
bne .EXIT ; mem <> 0 -->.EXIT
move.l d2,-(a7) ; Argumente für ShowMsgA
lea NoMem(pc),a0 ; auf den Stack schieben
move.l a0,-(a7)
lea Error(pc),a0
move.l a0,-(a7)
bsr _ShowMsgA ; Error anzeigen
lea 12(a7),a7 ; Stack wieder runtersetzen
.EXIT movem.l (sp)+,d1-d2/a0-a1/a6 ; alte Register restaurieren
rts
Error: dc.b "Error",0
NoMem: dc.b "Could not get %lU bytes of memory",0
*********************** FlushMessagesA *****************************
*
* void FlushMessagesA(register __a0 struct MsgPort *port);
*
* Leert den MsgPort 'port', der auch NULL sein kann.
*
CNOP 0,2
xdef _FlushMessagesA
_FlushMessagesA: movem.l d0-d2/a0-a1/a6,-(sp)
move.l a0,d2 ; MsgPort sichern und testen
beq .EXIT
move.l 4.w,a6 ; SysBase laden
.loop jsr _LVOGetMsg(a6) ; Msg holen
tst.l d0 ; vorhanden?
beq .EXIT ; nein: Ende
move.l d0,a1
jsr _LVOReplyMsg(a6) ; ja: antworten
movea.l d2,a0 ; MsgPort zurückholen
bra .loop ; nächste Msg holen
.EXIT movem.l (sp)+,d0-d2/a0-a1/a6
rts
*////*---------------- CDOpenDeviceA() ----------------------------< >-*/
*/
* struct CDxRequest *CDOpenDeviceA(register __a0 char *devicename, register __d0 ULONG unitnumber, register __d1 ULONG lun);
*
* Öffnet das übergebene SCSI-Device und gibt einen Zeiger auf eine
* ausgefüllte CDx-Struktur zurück. Konnte das Device nicht geöffnet werden,
* wird der Fehler angezeigt und die Funktion gibt NULL zurück.
* Achtung: Der Devicename wird nicht kopiert, und muß für CDChangeDeviceA()
* unbedingt erhalten bleiben!
*
CNOP 0,2
xdef _CDOpenDeviceA
_CDOpenDeviceA: movem.l d1-d7/a0-a6,-(sp)
move.l 4.w,a6 ; a6 = SysBase
move.l a0,a4 ; a4 = devicename
move.l d0,d2 ; d2 = unitnumber
move.l d1,d3 ; d3 = lun
moveq #0,d4
.GetCDxStruct move.l #cdx_SIZEOF+CDTOC_SIZEOF+AUDIOPAGE_SIZEOF,d0 ; Speicher für CDxRequest, cdx_TOCData
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1 ; und cdx_ValidAudioPage
bsr _GetVecA
tst.l d0
beq .EXIT
move.l d0,a3 ; a3 = CDxRequest
addi.l #cdx_SIZEOF,d0
move.l d0,cdx_TOCData(a3) ; alle Adressen eintragen
addi.l #CDTOC_SIZEOF,d0
move.l d0,cdx_ValidAudioPage(a3)
.InitCDxStruct move.b d2,cdx_Unit(a3)
move.b d3,cdx_LUN(a3)
move.l a4,cdx_DeviceName(a3)
.GetBufMem move.l #DATA_LEN+SENSE_LEN,d0 ; 2 Puffer-Blöcke
move.l #MEMF_PUBLIC|MEMF_24BITDMA|MEMF_CLEAR,d1
bsr _GetVecA
move.l d0,cdx_SCSIData(a3) ; Data-Block
beq FreeCDxStruct
addi.l #DATA_LEN,d0 ; Sense-Block errechnen
move.l d0,cdx_SCSISense(a3)
.CreateIOPort jsr _LVOCreateMsgPort(a6)
move.l d0,cdx_IOPort(a3)
bne .CreateIOReq
lea NoPort(pc),a0 ; auf den Stack schieben
move.l a0,-(a7)
lea Error(pc),a0
move.l a0,-(a7)
bsr _ShowMsgA ; Error anzeigen
lea 8(a7),a7 ; Stack wieder runtersetzen
bra FreeBufMem
.CreateIOReq movea.l d0,a0
moveq #IOSTD_SIZE,d0
jsr _LVOCreateIORequest(a6)
move.l d0,cdx_IORequest(a3)
beq DeleteIOPort
move.l d0,a2 ; a2 = cdx_IORequest
.OpenDevice move.l d3,d0
mulu.w #10,d0
add.l d2,d0 ; d0 = unit + lun*10
moveq #0,d1 ; Flags
move.l a4,a0 ; devicename
move.l a2,a1 ; io_request
jsr _LVOOpenDevice(a6)
tst.l d0
beq .GetCmdStruct
move.l d3,-(a7) ; Argumente für ShowMsgA
move.l d2,-(a7)
move.l a4,-(a7)
lea NoDevice(pc),a0 ; auf den Stack schieben
move.l a0,-(a7)
lea Error(pc),a0
move.l a0,-(a7)
bsr _ShowMsgA ; Error anzeigen
lea 20(a7),a7 ; Stack wieder runtersetzen
bra DeleteIOReq
.GetCmdStruct move.l #scsi_SIZEOF,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1 ; RAM für die SCSICmd-
bsr _GetVecA ; Struktur
move.l d0,cdx_Cmd(a3)
beq CloseDevice
move.l d0,a1 ; a1 = SCSICmd
move.l a3,a0
bsr _CDInitDeviceA ; CDx Rest ausfüllen
move.l a3,d0 ; Return CDxRequest
.EXIT movem.l (sp)+,d1-d7/a0-a6
rts
NoDevice: dc.b "Could not open SCSI device '%s' Unit %ld LUN %ld",0
NoPort: dc.b 'Failed to create message port',0
********************* CDInitDeviceA() *********************************
*
* LONG CDInitDeviceA(register __a0 struct CDxRequest);
*
*
CNOP 0,2
_CDInitDeviceA: movem.l d1-d7/a0-a6,-(sp)
move.l a0,a3 ; a3 = cdx
move.l cdx_IORequest(a0),a1
move.w #HD_SCSICMD,IO_COMMAND(a1) ; IOStdRequest füllen
move.l cdx_Cmd(a0),IO_DATA(a1)
move.l #scsi_SIZEOF,IO_LENGTH(a1)
.DoInquiry moveq #6,d0
moveq #SCSIF_AUTOSENSE|SCSIF_READ,d1
lea CMDInquiry,a1
bsr CDDoSCSIA ; Inquiry schicken
bne .EXIT
move.l cdx_SCSIData(a3),a2
move.b (a2),d0
andi.l #%00011111,d0 ; nur Bits 0-4
move.b d0,cdx_DeviceType(a3) ; Peripheral Device Type
adda.l #8,a2 ; a2 = CDROM-VendorID
.VendorUnknown lea UnknownVendor(pc),a0
move.l a0,cdx_Vendor(a3)
move.l (a2)+,(a0)+
move.l (a2),(a0)
.CopyRest adda.l #8,a2 ; nächte Bytes der Inquirydaten
lea cdx_Product(a3),a0 ; Product Identification
moveq #3,d0 ; 16 Bytes (4 Langworte)
.l1 move.l (a2)+,(a0)+ ; kopieren
dbra d0,.l1
lea cdx_Revision(a3),a0 ; Product Revision Level
move.l (a2)+,(a0) ; nur 4 Bytes groß
lea cdx_Specific(a3),a0 ; Vendor Specific
moveq #4,d0 ; 20 Bytes (5 Langworte)
.l2 move.l (a2)+,(a0)+ ; kopieren
dbra d0,.l2
.FillCDx move.b #AUDIO_STAT_NO_DISK,cdx_AudioStatus(a3)
move.b #AUDIO_STAT_NO_DISK,cdx_Active(a3)
move.l a3,a0
bsr _CDUpdateA ; Rest der CDx-Struktur füllen
bsr _CDReadTOCA ; TOC einlesen
.EXIT movem.l (sp)+,d1-d7/a0-a6
rts
CMDInquiry: dc.b $12, 0, 0, 0, 96, 0
*********************** CDCloseDeviceA() *****************************
*
* BOOL CDCloseDeviceA(register __a0 struct CDxRequest);
*
* Schließt ein SCSI-Device, das mit CDOpenDeviceA() geöffnet wurde. Das
* Ergebnis ist dabei immer NULL.
*
CNOP 0,2
xdef _CDCloseDeviceA
_CDCloseDeviceA: movem.l d1-d7/a0-a6,-(sp)
move.l 4.w,a6
move.l a0,a3 ; a3 = MyCDxReq
CloseCmdStruct move.l cdx_Cmd(a3),a1
jsr _LVOFreeVec(a6)
CloseDevice move.l cdx_IORequest(a3),a1
jsr _LVOCloseDevice(a6)
DeleteIOReq move.l cdx_IORequest(a3),a0
jsr _LVODeleteIORequest(a6)
DeleteIOPort move.l cdx_IOPort(a3),a0
jsr _LVODeleteMsgPort(a6)
FreeBufMem move.l cdx_SCSIData(a3),a1
jsr _LVOFreeVec(a6)
FreeCDxStruct move.l a3,a1
jsr _LVOFreeVec(a6)
.EXIT moveq #NULL,d0
movem.l (sp)+,d1-d7/a0-a6
rts
************************ CDDoSCSIA() *********************************
*
* LONG CDDoSCSIA(register __a0 struct CDxRequest *cdx, a1 APTR Command, d0 cmdlen. d1 flags);
*
* Führt das übergebene SCSI Direktkommando aus und gibt im Fehlerfall einen
* Wert zurück, der sich aus dem Sense Key (Bit 16-31), dem Additional Sense
* Code (Bit 8-15) und dem Additional Sense Code Qualifier (Bit 0-7)
* zusammensetzt. Ist keine CD eingelegt werden alle CD-abhängigen Daten auf
* 0 gesetzt. Die Conditioncodes werden in Abhängigkeit von d0 gesetzt.
*
CNOP 0,2
CDDoSCSIA: movem.l d1/a0-a2/a6,-(sp)
move.l 4.w,a6 ; SysBase...
move.l cdx_Cmd(a0),a2 ; a2=SCSICmd
move.l cdx_SCSIData(a0),(a2)+ ; scsi_Data;
move.l #DATA_LEN,(a2)+ ; scsi_Length;
clr.l (a2)+ ; scsi_Actual;
move.l a1,(a2)+ ; scsi_Command;
move.w d0,(a2)+ ; scsi_CmdLength;
clr.w (a2)+ ; scsi_CmdActual;
move.b d1,(a2)+ ; scsi_Flags;
clr.b (a2)+ ; scsi_Status;
move.l cdx_SCSISense(a0),(a2)+ ; scsi_SenseData;
move.w #SENSE_LEN,(a2)+ ; scsi_SenseLength;
clr.w (a2) ; scsi_SenseActual;
move.l a0,a2 ; CDxRequest retten
move.l cdx_IORequest(a0),a1
jsr _LVODoIO(a6) ; Kommando schicken und warten
moveq #0,d0 ; Return = 0
move.l cdx_Cmd(a2),a1 ; a1=SCSICmd
tst.w scsi_SenseActual(a1) ; Sense Daten da?
beq .EXIT
move.l scsi_SenseData(a1),a1 ; a1=SenseData
move.b (a1),d1 ; Error Code ($70 oder $71)
andi.b #%01111111,d1 ; Valid-Bit auslassen
cmp.b #$70,d1 ; Current Error ($70) ?
bne .EXIT
move.b 2(a1),d0 ; d0=Sense Key
andi.b #%00001111,d0 ; nur 4 Bits
tst.b d0 ; NO SENSE ($0) ?
beq .EXIT
move.b d0,cdx_SenseKey(a2) ; in cdx schreiben (für ARexx)
swap.w d0 ; Returnwert berechnen
cmp.b #6,7(a1) ; ASC und ASCQ vorhanden?
blt .EXIT
move.w 12(a1),d0 ; ASC und ASCQ zu Returnwert
move.w d0,cdx_AddSenseCode(a2) ; in cdx schreiben
.EXIT movem.l (sp)+,d1/a0-a2/a6
tst.l d0 ; Conditioncodes setzen
rts
************************ CDUpdateA() **********************************
*
* LONG CDUpdateA(register __a0 struct CDxRequest *cdx);
*
* Aktualisiert den Track, Index, Adresssen und Audiostatus der übergebenen
* CDx-Struktur. Tritt ein Fehler auf, liefert die Funktion einen Wert in
* dem in CDDoSCSIA beschriebenem Format zurück. Wurde seit dem letztem
* Update eine CD eingelegt, wird der TOC neu eingelesen. Entspricht der
* aktuelle Audiostatus AUDIO_STAT_NO_DISK, AUDIO_STAT_NOT_VALID oder
* AUDIO_STAT_NONE, werden die Positionsfelder der CDx-Struktur auf 0 gesetzt.
*
CNOP 0,2
xdef _CDUpdateA
_CDUpdateA: movem.l d1-d3/a0-a2,-(sp)
moveq #10,d0 ; 10 Byte Kommando
moveq #SCSIF_AUTOSENSE|SCSIF_READ,d1
lea CMDReadSubCh(pc),a1
bsr CDDoSCSIA ; Kommando ausführen
beq .DiscChanged ; alles korrekt
cmp.l #$023A00,d0 ; NO MEDIA PRESENT ?
bne .EXIT ; unerwarteter Fehler
move.b #AUDIO_STAT_NO_DISK,cdx_AudioStatus(a0)
move.b #AUDIO_STAT_NO_DISK,cdx_Active(a0)
.NoCD move.l cdx_TOCData(a0),a1 ; keine CD eingelegt: alles
moveq #3,d1 ; CD spezifische löschen
.loop clr.l (a1)+ ; FirstTrack/LastTrack/FirstAudioTrack/reserved3/FirstAudioAddress
dbra d1,.loop ; und Entry[0] löschen
.Stopped clr.w (a0)+ ; cdx_CurrentTrack/CurrentIndex
moveq #4,d1
.loop2 clr.l (a0)+ ; cdx_CurrentAbsAddr/CurrentRelAddr/RelRemainBlocks/AbsRemainBlocks/TrackLength
dbra d1,.loop2
bra .EXIT
.SetSimpleStat move.b #AUDIO_STAT_STOPPED,cdx_Active(a0)
bra .Stopped
.DiscChanged cmp.b #AUDIO_STAT_NO_DISK,cdx_AudioStatus(a0) ; neue Disk eingelegt?
bne .UpdateCDx
bsr _CDReadTOCA ; ja: Table Of Contents neu einlesen
.UpdateCDx move.l cdx_SCSIData(a0),a1
addq.l #1,a1
move.b (a1)+,d0 ; Audio Status lesen
move.b d0,cdx_AudioStatus(a0) ; und setzen
move.b d0,cdx_Active(a0)
beq .SetSimpleStat ; AUDIO_STAT_NOT_VALID (=0)
cmp.b #AUDIO_STAT_COMPLETED,d0
bcc .SetSimpleStat ; d0 >= AUDIO_STAT_COMPLETED (STOPPED/NONE)
; übrig bleibt PLAY und PAUSE: Positionen lesen
moveq #0,d0 ; alles okay: RETURN_OK
.EXIT movem.l (sp)+,d1-d3/a0-a2
rts
CMDReadSubCh: dc.b $42, 0, $40, 1, 0, 0, 0, 0, 16, 0
************************ CDReadTOCA() ********************************
*
* LONG CDReadTOCA(register __a0 struct CDxRequest *cdx);
*
CNOP 0,2
xdef _CDReadTOCA
_CDReadTOCA: movem.l d1-d3/a0-a3/a6,-(sp)
moveq #10,d0
moveq #SCSIF_AUTOSENSE|SCSIF_READ,d1
lea CMDReadTOC(pc),a1
bsr CDDoSCSIA
bne .EXIT
move.l cdx_SCSIData(a0),a1
move.w (a1)+,d0 ; TOC Data Length
beq .EXIT
move.l cdx_TOCData(a0),a0 ; da soll alles hin
move.w (a1),(a0)+ ; First und Last Track
move.b (a1)+,d1 ; FirstTrack
moveq #0,d3
move.b (a1)+,d3 ; LastTrack
sub.b d1,d3
addq.b #1,d3 ; d3=Track Anzahl
move.l a0,a3 ; für später
clr.w (a0)+ ; wird nachher gefüllt...
clr.l (a0)+ ; (TrackNum/FirstAudioTrack/FirstAudioAddress)
move.l a0,a2 ; Track 0 gibt's nicht, da kommt
clr.l (a0)+ ; nacher die logical block
clr.l (a0)+ ; address der lead-out area rein
clr.l 16(a0) ; Entry für Track 3 sicherheitshalber löschen
clr.l 20(a0) ; (für ID Berechnung :-)
lsr.l #3,d0 ; durch 8 (pro Entry 8 bytes)
; die 2 bytes für F. und L. Track fallen raus
subq.l #1,d0 ; dbra endet bei -1
bmi .Good ; jetzt schon -1?
moveq #-1,d2 ; noch keinen AudioTrack gefunden...
.loop move.l (a1)+,d1
move.l d1,(a0)+ ; ersten 4 bytes (8 bytes / Entry) kopieren
tst.b d2 ; schon AudioTrack gefunden?
beq .loopend
btst.l #18,d1 ; AudioTrack?
bne .loopend
move.b d3,(a3)+ ; TrackNum
lsr.w #8,d1
move.b d1,(a3)+ ; FirstAudioTrack
move.l (a1),-4(a2) ; FirstAudioAddress
moveq #0,d2
.loopend move.l (a1)+,(a0)+ ; letzten 4 Bytes kopieren
dbra d0,.loop
.LeadOut subq.l #8,a1 ; letzten Entry nochmal holen
cmp.b #$AA,2(a1) ; wirklich lead out area? (Tracknr. $AA)
bne .Good
move.l (a1)+,(a2)+ ; ja: nochmal nach Entry[0] kopieren
move.l (a1),(a2)
.CalcID move.l 4.w,a6
lea IDFormat(pc),a0
move.l (a2),-(a7) ; Entry[0].Address
move.l 24(a2),-(a7) ; Entry[3].Address
move.l d3,-(a7) ; LastTrack-FirstTrack+1
move.l a7,a1
lea CDID-(Entry+4)(a2),a3
lea PutChProc(pc),a2
jsr _LVORawDoFmt(a6) ; ID formatieren
lea 12(a7),a7
.Good moveq #0,d0
.EXIT movem.l (sp)+,d1-d3/a0-a3/a6
rts
CMDReadTOC: dc.b $43, 0, 0, 0, 0, 0, 0, $3, $24, 0
IDFormat: dc.b '%02ld%06lx%06lx',0
************************ CDTestUnitA() ******************************
*
* LONG CDTestUnitA(register __a0 struct CDxRequest *cdx);
*
* Testet die logical unit ob sie bereit ist. Wenn sie das ist, wird GOOD (0)
* zurückgegeben, ansonsten ein Returncode im in CDDoSCSIA beschriebenem
* Format.
*
CNOP 0,2
xdef _CDTestUnitA
_CDTestUnitA: movem.l d1/a0-a1,-(sp)
moveq #6,d0 ; 6 Byte Kommando
moveq #SCSIF_AUTOSENSE,d1 ; REQUEST SENSE ausführen lassen
lea CMDReadSubCh(pc),a1
bsr CDDoSCSIA ; Kommando ausführen
.EXIT movem.l (sp)+,d1/a0-a1
rts
CMDTestUnitReady: dc.b $0, 0, 0, 0, 0, 0
************************ CDEjectA() *********************************
*
* LONG CDEjectA(register __a0 struct CDxRequest *cdx, register __d0 BOOL really);
*
* TRUE öffnet die Schublade, FALSE schließt sie. Im Fehlerfall (Schublade
* schon offen/geschlossen) wird ein Fehlercode zurückgegeben. Außerdem
* wird das Flag JUSTCLOSED gesetzt, wenn die Schublade geschlossen werden
* soll, sonst wird es gelöscht.
*
CNOP 0,2
xdef _CDEjectA
_CDEjectA: movem.l d1/a0-a1,-(sp)
lea CMDStartStopUnit(pc),a1
.eject moveq #2,d1
and.b #~SPECIALF_JUSTCLOSED,cdx_Flags(a0)
tst.l d0
bne .goon
.load moveq #3,d1
or.b #SPECIALF_JUSTCLOSED,cdx_Flags(a0)
.goon move.b d1,4(a1)
moveq #6,d0
moveq #SCSIF_AUTOSENSE|SCSIF_READ,d1
bsr CDDoSCSIA
.EXIT movem.l (sp)+,d1/a0-a1
rts
CMDStartStopUnit: dc.b $1B, 1, 0, 0, 2, 0
UnknownVendor: dcb.b 9