- added instructions how to update the online documentation
[bochs-mirror.git] / iodev / cdrom_amigaos.cc
blob4cf65b6ababb7cf6a30c85d3156c46473b2cbe1a
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: cdrom_amigaos.cc,v 1.14 2008/01/26 22:24:00 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2000 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // These are the low-level CDROM functions which are called
29 // from 'harddrv.cc'. They effect the OS specific functionality
30 // needed by the CDROM emulation in 'harddrv.cc'. Mostly, just
31 // ioctl() calls and such. Should be fairly easy to add support
32 // for your OS if it is not supported yet.
35 #include "bochs.h"
36 #include "scsi_commands.h"
37 #include "cdrom.h"
39 #include <exec/types.h>
40 #include <exec/memory.h>
41 #include <devices/trackdisk.h>
42 #include <devices/scsidisk.h>
43 #include <dos/dos.h>
44 #include <proto/dos.h>
45 #include <proto/exec.h>
46 #include <clib/alib_protos.h>
47 #include <stdio.h>
49 #define LOG_THIS /* no SMF tricks here, not needed */
51 #define BX_CD_FRAMESIZE 2048
52 #define CD_FRAMESIZE 2048
53 #define SENSELEN 32
54 #define MAX_DATA_LEN 252
56 int amiga_cd_unit;
57 char amiga_cd_device[256];
59 struct MsgPort *CDMP; /* Pointer for message port */
60 struct IOExtTD *CDIO; /* Pointer for IORequest */
61 int cd_error;
63 typedef struct {
64 UBYTE pad0;
65 UBYTE trackType;
66 UBYTE trackNum;
67 UBYTE pad1;
68 ULONG startFrame;
69 } TOCENTRY;
71 typedef struct {
72 UWORD length;
73 UBYTE firstTrack;
74 UBYTE lastTrack;
75 TOCENTRY tocs[100];
76 } TOC;
78 typedef struct {
79 ULONG sectors;
80 ULONG blocksize;
81 } CAPACITY;
83 unsigned char sensebuf[SENSELEN];
85 int DoSCSI (UBYTE * data, int datasize, UBYTE * cmd, int cmdsize, UBYTE flags);
87 cdrom_interface::cdrom_interface(char *dev)
89 char buf[256];
91 sscanf(dev, "%s%s", amiga_cd_device, buf);
92 amiga_cd_unit = atoi(buf);
94 CDMP = CreateMsgPort();
95 if (CDMP != NULL) {
96 CDIO = (struct IOExtTD *)CreateIORequest(CDMP, sizeof(struct IOExtTD));
97 if (CDIO != NULL) {
98 cd_error = OpenDevice(amiga_cd_device, amiga_cd_unit, (struct IORequest *)CDIO, 0);
99 if (cd_error != 0)
100 BX_PANIC(("CD_Open: could not open device %s unit %d\n", amiga_cd_device, amiga_cd_unit));
105 cdrom_interface::~cdrom_interface(void)
107 if (cd_error == 0) {
108 CloseDevice((struct IORequest *)CDIO);
110 if (CDIO != NULL) {
111 DeleteIORequest((struct IORequest *)CDIO);
113 if (CDMP != NULL) {
114 DeleteMsgPort(CDMP);
118 bx_bool
119 cdrom_interface::insert_cdrom(char *dev)
121 Bit8u cdb[6];
122 Bit8u buf[2*BX_CD_FRAMESIZE];
123 Bit8u i = 0;
125 memset(cdb,0,sizeof(cdb));
127 cdb[0] = SCSI_DA_START_STOP_UNIT;
128 cdb[4] = 1 | 2;
130 DoSCSI(0, 0,cdb,sizeof(cdb),SCSIF_READ);
132 /*Check if there's a valid media present in the drive*/
133 CDIO->iotd_Req.io_Data = buf;
134 CDIO->iotd_Req.io_Command = CMD_READ;
135 CDIO->iotd_Req.io_Length = BX_CD_FRAMESIZE;
136 CDIO->iotd_Req.io_Offset = BX_CD_FRAMESIZE;
138 for(i = 0; i < 200; i++) /*it takes a while for the cdrom to validate*/
140 DoIO((struct IORequest *)CDIO);
141 if (CDIO->iotd_Req.io_Error == 0)
142 break;
143 Delay (10);
146 if (CDIO->iotd_Req.io_Error != 0)
147 return false;
148 else
149 return true;
153 void
154 cdrom_interface::eject_cdrom()
156 Bit8u cdb[6];
158 memset(cdb,0,sizeof(cdb));
160 cdb[0] = SCSI_DA_START_STOP_UNIT;
161 cdb[4] = 0 | 2;
163 DoSCSI(0, 0,cdb,sizeof(cdb),SCSIF_READ);
167 bx_bool
168 cdrom_interface::read_toc(Bit8u* buf, int* length, bx_bool msf, int start_track, int format)
170 Bit8u cdb[10];
171 TOC *toc;
172 toc = (TOC*) buf;
174 if (format != 0)
175 return false;
177 memset(cdb,0,sizeof(cdb));
179 cdb[0] = SCSI_CD_READ_TOC;
181 if (msf)
182 cdb[1] = 2;
183 else
184 cdb[1] = 0;
186 cdb[6] = start_track;
187 cdb[7] = sizeof(TOC)>>8;
188 cdb[8] = sizeof(TOC)&0xFF;
190 DoSCSI((UBYTE *)buf, sizeof(TOC), cdb, sizeof(cdb), SCSIF_READ);
192 *length = toc->length + 4;
194 return true;
198 Bit32u
199 cdrom_interface::capacity()
201 CAPACITY cap;
202 Bit8u cdb[10];
204 memset(cdb,0,sizeof(cdb));
205 cdb[0] = SCSI_DA_READ_CAPACITY;
207 int err;
209 if ((err = DoSCSI((UBYTE *)&cap, sizeof(cap),
210 cdb, sizeof (cdb),
211 (SCSIF_READ | SCSIF_AUTOSENSE))) == 0)
212 return(cap.sectors);
213 else
214 BX_PANIC (("Couldn't get media capacity"));
217 bx_bool
218 cdrom_interface::read_block(Bit8u* buf, int lba, int blocksize)
220 CDIO->iotd_Req.io_Data = buf;
221 CDIO->iotd_Req.io_Command = CMD_READ;
222 CDIO->iotd_Req.io_Length = BX_CD_FRAMESIZE;
223 CDIO->iotd_Req.io_Offset = lba * BX_CD_FRAMESIZE;
224 DoIO((struct IORequest *)CDIO);
226 if (CDIO->iotd_Req.io_Error != 0) {
227 BX_PANIC(("Error %d reading CD data sector: %ld", CDIO->iotd_Req.io_Error, lba));
228 return 0;
230 return 1;
233 bx_bool
234 cdrom_interface::start_cdrom()
236 // Spin up the cdrom drive.
238 if (fd >= 0) {
239 BX_INFO(("start_cdrom: your OS is not supported yet."));
240 return 0; // OS not supported yet, return 0 always.
242 return 0;
246 int DoSCSI(UBYTE *data, int datasize, Bit8u *cmd,int cmdsize, UBYTE direction)
248 struct SCSICmd scmd;
250 CDIO->iotd_Req.io_Command = HD_SCSICMD;
251 CDIO->iotd_Req.io_Data = &scmd;
252 CDIO->iotd_Req.io_Length = sizeof(scmd);
254 scmd.scsi_Data = (UWORD *)data;
255 scmd.scsi_Length = datasize;
256 scmd.scsi_SenseActual = 0;
257 scmd.scsi_SenseData = sensebuf;
258 scmd.scsi_SenseLength = SENSELEN;
259 scmd.scsi_Command = cmd;
260 scmd.scsi_CmdLength = cmdsize;
261 scmd.scsi_Flags = SCSIF_AUTOSENSE | direction;
263 DoIO((struct IORequest *)CDIO);
265 if (CDIO->iotd_Req.io_Error != 0) {
266 BX_PANIC(("DoSCSI: error %d", CDIO->iotd_Req.io_Error));
269 return CDIO->iotd_Req.io_Error;
272 void cdrom_interface::seek(int lba)
274 unsigned char buffer[BX_CD_FRAMESIZE];
276 read_block(buffer, lba, BX_CD_FRAMESIZE);