More CD-ROM fixes, Little Big Adventure now looks again;
Made SCAT logging optional and disabled by default.
This commit is contained in:
@@ -9,12 +9,13 @@
|
||||
* Implementation of the CD-ROM drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)cdrom.c 1.0.43 2018/03/20
|
||||
* Version: @(#)cdrom.c 1.0.44 2018/03/21
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -732,6 +733,8 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len)
|
||||
cdrom_t *dev = cdrom[id];
|
||||
uint32_t bt;
|
||||
|
||||
uint32_t min_len = 0;
|
||||
|
||||
dev->max_transfer_len = dev->request_length;
|
||||
|
||||
/* For media access commands, make sure the requested DRQ length matches the block length. */
|
||||
@@ -741,11 +744,23 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len)
|
||||
case 0xa8:
|
||||
case 0xb9:
|
||||
case 0xbe:
|
||||
if (dev->max_transfer_len < block_len)
|
||||
dev->max_transfer_len = block_len;
|
||||
/* Make sure total length is not bigger than sum of the lengths of
|
||||
all the requested blocks. */
|
||||
bt = (dev->requested_blocks * block_len);
|
||||
if (len > bt)
|
||||
len = bt;
|
||||
|
||||
min_len = block_len;
|
||||
|
||||
if (len <= block_len) {
|
||||
/* Total length is less or equal to block length. */
|
||||
if (dev->max_transfer_len < block_len) {
|
||||
/* Transfer a minimum of (block size) bytes. */
|
||||
dev->max_transfer_len = block_len;
|
||||
dev->packet_len = block_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
dev->packet_len = len;
|
||||
break;
|
||||
@@ -756,14 +771,18 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len)
|
||||
/* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */
|
||||
if (!dev->max_transfer_len)
|
||||
dev->max_transfer_len = 65534;
|
||||
if (len <= dev->max_transfer_len)
|
||||
dev->max_transfer_len = len;
|
||||
|
||||
if ((len <= dev->max_transfer_len) && (len >= min_len)) {
|
||||
dev->request_length = dev->max_transfer_len = len;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static double cdrom_get_short_seek(uint8_t id)
|
||||
{
|
||||
switch(cdrom_drives[id].speed) {
|
||||
cdrom_t *dev = cdrom[id];
|
||||
|
||||
switch(dev->cur_speed) {
|
||||
case 0:
|
||||
fatal("CD-ROM %i: 0x speed\n", id);
|
||||
return 0.0;
|
||||
@@ -793,7 +812,9 @@ static double cdrom_get_short_seek(uint8_t id)
|
||||
|
||||
static double cdrom_get_long_seek(uint8_t id)
|
||||
{
|
||||
switch(cdrom_drives[id].speed) {
|
||||
cdrom_t *dev = cdrom[id];
|
||||
|
||||
switch(dev->cur_speed) {
|
||||
case 0:
|
||||
fatal("CD-ROM %i: 0x speed\n", id);
|
||||
return 0.0;
|
||||
@@ -857,6 +878,17 @@ static double cdrom_bus_speed(uint8_t id)
|
||||
return 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */
|
||||
}
|
||||
|
||||
static void cdrom_command_bus(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
|
||||
dev->status = BUSY_STAT;
|
||||
dev->phase = 1;
|
||||
dev->pos = 0;
|
||||
dev->callback = 1LL * CDROM_TIME;
|
||||
cdrom_set_callback(id);
|
||||
}
|
||||
|
||||
static void cdrom_command_common(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
@@ -868,6 +900,9 @@ static void cdrom_command_common(uint8_t id)
|
||||
dev->phase = 1;
|
||||
dev->pos = 0;
|
||||
dev->callback = 0LL;
|
||||
|
||||
cdrom_log("CD-ROM %i: Current speed: %ix\n", id, dev->cur_speed);
|
||||
|
||||
if (dev->packet_status == CDROM_PHASE_COMPLETE) {
|
||||
cdrom_phase_callback(id);
|
||||
dev->callback = 0LL;
|
||||
@@ -880,6 +915,7 @@ static void cdrom_command_common(uint8_t id)
|
||||
period = cdrom_seek_time(id) * ((double) TIMER_USEC);
|
||||
dev->callback += ((int64_t) period);
|
||||
cdrom_set_callback(id);
|
||||
cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", id, (int64_t) cdrom_seek_time(id));
|
||||
return;
|
||||
case 0x08:
|
||||
case 0x28:
|
||||
@@ -887,6 +923,7 @@ static void cdrom_command_common(uint8_t id)
|
||||
/* Seek time is in us. */
|
||||
period = cdrom_seek_time(id) * ((double) TIMER_USEC);
|
||||
dev->callback += ((int64_t) period);
|
||||
cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", id, (int64_t) cdrom_seek_time(id));
|
||||
case 0x25:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
@@ -898,7 +935,8 @@ static void cdrom_command_common(uint8_t id)
|
||||
case 0xb9:
|
||||
case 0xbe:
|
||||
/* bytes_per_second = 150.0 * 1024.0; */
|
||||
bytes_per_second = (1000000.0 / 12000.0) * 2048.0; /* Account for seek time. */
|
||||
/* bytes_per_second = (1000000.0 / 12000.0) * 2048.0; */ /* Account for seek time. */
|
||||
bytes_per_second = 176.0 * 1024.0;
|
||||
bytes_per_second *= (double) dev->cur_speed;
|
||||
break;
|
||||
default:
|
||||
@@ -911,8 +949,10 @@ static void cdrom_command_common(uint8_t id)
|
||||
}
|
||||
|
||||
period = 1000000.0 / bytes_per_second;
|
||||
dusec = (double) TIMER_USEC;
|
||||
dusec = dusec * period * (double) (dev->packet_len);
|
||||
cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", id, (int64_t) period);
|
||||
period = period * (double) (dev->packet_len);
|
||||
cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", id, (int64_t) period);
|
||||
dusec = period * ((double) TIMER_USEC);
|
||||
dev->callback += ((int64_t) dusec);
|
||||
}
|
||||
cdrom_set_callback(id);
|
||||
@@ -2443,7 +2483,7 @@ cdrom_readtoc_fallback:
|
||||
max_len |= cdb[8];
|
||||
msf = (cdb[1] >> 1) & 1;
|
||||
|
||||
cdrom_buf_alloc(id, 65536);
|
||||
cdrom_buf_alloc(id, 32);
|
||||
|
||||
cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA");
|
||||
if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) {
|
||||
@@ -2533,6 +2573,13 @@ cdrom_readtoc_fallback:
|
||||
len = MIN(len, max_len);
|
||||
cdrom_set_buf_len(id, BufLen, &len);
|
||||
|
||||
cdrom_log("CD-ROM %i: Read subchannel:", id);
|
||||
for (i = 0; i < 32; i += 8) {
|
||||
pclog("[%02X] %02X %02X %02X %02X %02X %02X %02X %02X\n", i,
|
||||
cdbufferb[i], cdbufferb[i + 1], cdbufferb[i + 2], cdbufferb[i + 3],
|
||||
cdbufferb[i + 4], cdbufferb[i + 5], cdbufferb[i + 6], cdbufferb[i + 7]);
|
||||
}
|
||||
|
||||
cdrom_data_command_finish(id, len, len, len, 0);
|
||||
break;
|
||||
|
||||
@@ -2983,7 +3030,6 @@ int cdrom_read_from_dma(uint8_t id)
|
||||
cdrom_t *dev = cdrom[id];
|
||||
|
||||
int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||
@@ -3001,18 +3047,9 @@ int cdrom_read_from_dma(uint8_t id)
|
||||
|
||||
ret = cdrom_phase_data_out(id);
|
||||
|
||||
if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) {
|
||||
cdrom_buf_free(id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
ui_sb_update_icon(SB_CDROM | id, 0);
|
||||
cdrom_irq_raise(id);
|
||||
if (ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
if (ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3059,6 +3096,7 @@ int cdrom_write_to_dma(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
|
||||
int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength;
|
||||
int ret = 0;
|
||||
|
||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) {
|
||||
@@ -3067,18 +3105,14 @@ int cdrom_write_to_dma(uint8_t id)
|
||||
} else
|
||||
ret = cdrom_write_to_ide_dma(cdrom_drives[id].ide_channel);
|
||||
|
||||
if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) {
|
||||
cdrom_buf_free(id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
ui_sb_update_icon(SB_CDROM | id, 0);
|
||||
cdrom_irq_raise(id);
|
||||
if (ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||
cdrom_log("CD-ROM %i: SCSI Output data length: %i\n", id, *BufLen);
|
||||
else
|
||||
cdrom_log("CD-ROM %i: ATAPI Output data length: %i\n", id, dev->packet_len);
|
||||
|
||||
if (ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3086,6 +3120,7 @@ int cdrom_write_to_dma(uint8_t id)
|
||||
void cdrom_phase_callback(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
int ret;
|
||||
|
||||
switch(dev->packet_status) {
|
||||
case CDROM_PHASE_IDLE:
|
||||
@@ -3116,7 +3151,17 @@ void cdrom_phase_callback(uint8_t id)
|
||||
return;
|
||||
case CDROM_PHASE_DATA_OUT_DMA:
|
||||
cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id);
|
||||
cdrom_read_from_dma(id);
|
||||
ret = cdrom_read_from_dma(id);
|
||||
cdrom_command_complete(id);
|
||||
|
||||
if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) {
|
||||
cdrom_log("CD-ROM %i: DMA data out phase done\n");
|
||||
cdrom_buf_free(id);
|
||||
cdrom_command_complete(id);
|
||||
} else {
|
||||
cdrom_log("CD-ROM %i: DMA data out phase failure\n");
|
||||
cdrom_command_bus(id);
|
||||
}
|
||||
return;
|
||||
case CDROM_PHASE_DATA_IN:
|
||||
cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id);
|
||||
@@ -3126,7 +3171,16 @@ void cdrom_phase_callback(uint8_t id)
|
||||
return;
|
||||
case CDROM_PHASE_DATA_IN_DMA:
|
||||
cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id);
|
||||
cdrom_write_to_dma(id);
|
||||
ret = cdrom_write_to_dma(id);
|
||||
|
||||
if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) {
|
||||
cdrom_log("CD-ROM %i: DMA data in phase done\n");
|
||||
cdrom_buf_free(id);
|
||||
cdrom_command_complete(id);
|
||||
} else {
|
||||
cdrom_log("CD-ROM %i: DMA data in phase failure\n");
|
||||
cdrom_command_bus(id);
|
||||
}
|
||||
return;
|
||||
case CDROM_PHASE_ERROR:
|
||||
cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id);
|
||||
|
||||
Reference in New Issue
Block a user