1 |
|
/* |
2 |
|
* sys_amiga.cpp - System dependent routines, Amiga implementation |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-2000 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2001 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
52 |
|
ULONG block_size; // Block size of device (must be a power of two) |
53 |
|
bool is_nsd; // New style device? |
54 |
|
bool does_64bit; // Supports 64 bit trackdisk commands? |
55 |
+ |
bool is_ejected; // Volume has been (logically) ejected |
56 |
+ |
bool is_2060scsi; // Enable workaround for 2060scsi.device CD-ROM TD_READ bug |
57 |
|
}; |
58 |
|
|
59 |
|
|
78 |
|
the_port = CreateMsgPort(); |
79 |
|
tmp_buf = (UBYTE *)AllocMem(TMP_BUF_SIZE, MEMF_CHIP | MEMF_PUBLIC); |
80 |
|
if (the_port == NULL || tmp_buf == NULL) { |
81 |
< |
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
81 |
> |
ErrorAlert(STR_NO_MEM_ERR); |
82 |
|
QuitEmulator(); |
83 |
|
} |
84 |
|
} |
91 |
|
void SysExit(void) |
92 |
|
{ |
93 |
|
// Delete port and temporary buffer |
94 |
< |
if (the_port) |
94 |
> |
if (the_port) { |
95 |
|
DeleteMsgPort(the_port); |
96 |
< |
if (tmp_buf) |
96 |
> |
the_port = NULL; |
97 |
> |
} |
98 |
> |
if (tmp_buf) { |
99 |
|
FreeMem(tmp_buf, TMP_BUF_SIZE); |
100 |
+ |
tmp_buf = NULL; |
101 |
+ |
} |
102 |
|
} |
103 |
|
|
104 |
|
|
109 |
|
|
110 |
|
void SysAddFloppyPrefs(void) |
111 |
|
{ |
106 |
– |
#if 0 |
112 |
|
for (int i=0; i<4; i++) { |
113 |
|
ULONG id = GetUnitID(i); |
114 |
|
if (id == DRT_150RPM) { // We need an HD drive |
115 |
|
char str[256]; |
116 |
< |
sprintf(str, "/dev/mfm.device/%d/0/0/1474560/512", i); |
116 |
> |
sprintf(str, "/dev/mfm.device/%d/0/0/2880/512", i); |
117 |
|
PrefsAddString("floppy", str); |
118 |
|
} |
119 |
|
} |
115 |
– |
#endif |
120 |
|
} |
121 |
|
|
122 |
|
|
261 |
|
fh->block_size = dev_bsize; |
262 |
|
fh->is_nsd = is_nsd; |
263 |
|
fh->does_64bit = does_64bit; |
264 |
+ |
fh->is_ejected = false; |
265 |
+ |
fh->is_2060scsi = (strcmp(dev_name, "2060scsi.device") == 0); |
266 |
|
return fh; |
267 |
|
} |
268 |
|
} |
319 |
|
fh->io->io_Length = length; |
320 |
|
fh->io->io_Offset = offset; |
321 |
|
fh->io->io_Data = data; |
322 |
< |
if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != length) |
323 |
< |
return 0; |
324 |
< |
return fh->io->io_Actual; |
322 |
> |
|
323 |
> |
if (fh->is_2060scsi && fh->block_size == 2048) { |
324 |
> |
|
325 |
> |
// 2060scsi.device has serious problems reading CD-ROMs via TD_READ |
326 |
> |
static struct SCSICmd scsi; |
327 |
> |
const int SENSE_LENGTH = 256; |
328 |
> |
static UBYTE sense_buffer[SENSE_LENGTH]; // Buffer for autosense data |
329 |
> |
static UBYTE cmd_buffer[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
330 |
> |
|
331 |
> |
D(bug("send_io_request length=%lu offset=%lu\n", length, (ULONG) offset)); |
332 |
> |
|
333 |
> |
memset(sense_buffer, 0, sizeof(sense_buffer)); |
334 |
> |
|
335 |
> |
scsi.scsi_Command = cmd_buffer; |
336 |
> |
scsi.scsi_CmdLength = sizeof(cmd_buffer); |
337 |
> |
scsi.scsi_SenseData = sense_buffer; |
338 |
> |
scsi.scsi_SenseLength = SENSE_LENGTH; |
339 |
> |
scsi.scsi_Flags = SCSIF_AUTOSENSE | (writing ? SCSIF_WRITE : SCSIF_READ); |
340 |
> |
scsi.scsi_Data = (UWORD *) data; |
341 |
> |
scsi.scsi_Length = length; |
342 |
> |
|
343 |
> |
ULONG block_offset = (ULONG) offset / fh->block_size; |
344 |
> |
ULONG block_length = length / fh->block_size; |
345 |
> |
|
346 |
> |
cmd_buffer[2] = block_offset >> 24; |
347 |
> |
cmd_buffer[3] = block_offset >> 16; |
348 |
> |
cmd_buffer[4] = block_offset >> 8; |
349 |
> |
cmd_buffer[5] = block_offset & 0xff; |
350 |
> |
|
351 |
> |
cmd_buffer[7] = block_length >> 8; |
352 |
> |
cmd_buffer[8] = block_length & 0xff; |
353 |
> |
|
354 |
> |
fh->io->io_Command = HD_SCSICMD; |
355 |
> |
fh->io->io_Actual = 0; |
356 |
> |
fh->io->io_Offset = 0; |
357 |
> |
fh->io->io_Data = &scsi; |
358 |
> |
fh->io->io_Length = sizeof(scsi); |
359 |
> |
|
360 |
> |
BYTE result = DoIO((struct IORequest *)fh->io); |
361 |
> |
|
362 |
> |
if (result) { |
363 |
> |
D(bug("send_io_request SCSI FAIL result=%lu\n", result)); |
364 |
> |
|
365 |
> |
if (result == HFERR_BadStatus) { |
366 |
> |
D(bug("send_io_request SCSI Status=%lu\n", scsi.scsi_Status)); |
367 |
> |
if (scsi.scsi_Status == 2) { |
368 |
> |
D(bug("send_io_request Sense Key=%02lx\n", sense_buffer[2] & 0x0f)); |
369 |
> |
D(bug("send_io_request ASC=%02lx ASCQ=%02lx\n", sense_buffer[12], sense_buffer[13])); |
370 |
> |
} |
371 |
> |
} |
372 |
> |
return 0; |
373 |
> |
} |
374 |
> |
|
375 |
> |
D(bug("send_io_request SCSI Actual=%lu\n", scsi.scsi_Actual)); |
376 |
> |
|
377 |
> |
if (scsi.scsi_Actual != length) |
378 |
> |
return 0; |
379 |
> |
|
380 |
> |
return scsi.scsi_Actual; |
381 |
> |
|
382 |
> |
} else { |
383 |
> |
|
384 |
> |
if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != length) |
385 |
> |
return 0; |
386 |
> |
return fh->io->io_Actual; |
387 |
> |
} |
388 |
|
} |
389 |
|
|
390 |
|
|
597 |
|
fh->io->io_Command = TD_EJECT; |
598 |
|
fh->io->io_Length = 1; |
599 |
|
DoIO((struct IORequest *)fh->io); |
600 |
+ |
|
601 |
+ |
fh->is_ejected = true; |
602 |
|
} |
603 |
|
} |
604 |
|
|
636 |
|
} else { |
637 |
|
|
638 |
|
// Device, check write protection |
568 |
– |
fh->io->io_Flags = IOF_QUICK; |
639 |
|
fh->io->io_Command = TD_PROTSTATUS; |
640 |
< |
BeginIO((struct IORequest *)fh->io); |
640 |
> |
DoIO((struct IORequest *)fh->io); |
641 |
|
if (fh->io->io_Actual) |
642 |
|
return true; |
643 |
|
else |
675 |
|
else { |
676 |
|
|
677 |
|
// Check medium status |
608 |
– |
fh->io->io_Flags = IOF_QUICK; |
678 |
|
fh->io->io_Command = TD_CHANGESTATE; |
679 |
|
fh->io->io_Actual = 0; |
680 |
< |
BeginIO((struct IORequest *)fh->io); |
681 |
< |
return fh->io->io_Actual == 0; |
680 |
> |
DoIO((struct IORequest *)fh->io); |
681 |
> |
bool inserted = (fh->io->io_Actual == 0); |
682 |
> |
|
683 |
> |
if (!inserted) { |
684 |
> |
// Disk was ejected and has now been taken out |
685 |
> |
fh->is_ejected = false; |
686 |
> |
} |
687 |
> |
|
688 |
> |
if (fh->is_ejected) { |
689 |
> |
// Disk was ejected but has not yet been taken out, report it as |
690 |
> |
// no longer in the drive |
691 |
> |
return false; |
692 |
> |
} else |
693 |
> |
return inserted; |
694 |
|
} |
695 |
|
} |
696 |
|
|