Merge remote-tracking branch 'origin/master' into version/4.1

This commit is contained in:
OBattler
2023-10-31 21:27:39 +01:00
39 changed files with 2457 additions and 2359 deletions

View File

@@ -236,6 +236,9 @@ int efscrnsz_y = SCREEN_RES_Y;
static wchar_t mouse_msg[3][200];
static int do_pause_ack = 0;
static volatile int pause_ack = 0;
#ifndef RELEASE_BUILD
static char buff[1024];
static int seen = 0;
@@ -1353,6 +1356,15 @@ _ui_window_title(void *s)
}
#endif
void
ack_pause(void)
{
if (do_pause_ack) {
do_pause_ack = 0;
pause_ack = 1;
}
}
void
pc_run(void)
{
@@ -1369,6 +1381,7 @@ pc_run(void)
/* Run a block of code. */
startblit();
cpu_exec((int32_t) cpu_s->rspeed / 100);
ack_pause();
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
if (gdbstub_step == GDBSTUB_EXEC) {
#endif
@@ -1562,3 +1575,16 @@ get_actual_size_y(void)
{
return (efscrnsz_y);
}
void
do_pause(int p)
{
if (p)
do_pause_ack = p;
dopause = p;
if (p) {
while (!pause_ack)
;
}
pause_ack = 0;
}

View File

@@ -1657,7 +1657,7 @@ acpi_reset(void *priv)
}
/* Power on always generates a resume event. */
dev->regs.pmsts |= 0x8000;
dev->regs.pmsts |= 0x8100;
acpi_rtc_status = 0;

View File

@@ -1112,7 +1112,7 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf)
b[len++] = 0;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/
m = ti.m;
s = ti.s;
f = ti.f;
@@ -1374,6 +1374,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
int m = 0;
int s = 0;
int f = 0;
uint32_t temp;
dev->ops->get_tracks(dev, &first_track, &last_track);
@@ -1413,11 +1414,32 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
b[3] = ti.attr;
cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr);
break;
case 3:
b[0] = 0x00; /*TODO: correct it further, mark it as CD-Audio/CD-ROM disc for now*/
b[1] = 0;
b[2] = 0;
b[3] = 0;
case 3: /*Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from Android's source code*/
switch (dev->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
dev->ops->get_track_info(dev, 1, 0, &ti);
b[0x0e] = 0;
temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
b[0x0f] = temp >> 24;
b[0x10] = temp >> 16;
b[0x11] = temp >> 8;
b[0x12] = temp;
break;
default:
dev->ops->get_track_info(dev, 1, 0, &ti);
b[0] = 0;
temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
b[1] = temp >> 24;
b[2] = temp >> 16;
b[3] = temp >> 8;
break;
}
break;
default:
break;

View File

@@ -1600,7 +1600,10 @@ piix_init(const device_t *info)
dev->port_92 = device_add(&port_92_pci_device);
cpu_set_isa_pci_div(4);
if (cpu_busspeed > 50000000)
cpu_set_isa_pci_div(4);
else
cpu_set_isa_pci_div(3);
dma_alias_set();

View File

@@ -30,6 +30,7 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/port_92.h>

View File

@@ -876,6 +876,7 @@ load_hard_disks(void)
break;
case HDD_BUS_SCSI:
case HDD_BUS_ATAPI:
max_spt = 255;
max_hpc = 255;
max_tracks = 266305;
@@ -893,6 +894,8 @@ load_hard_disks(void)
switch (hdd[c].bus) {
case HDD_BUS_IDE:
case HDD_BUS_ESDI:
case HDD_BUS_ATAPI:
case HDD_BUS_SCSI:
sprintf(tmp2, "1997_5400rpm");
break;
default:
@@ -925,7 +928,7 @@ load_hard_disks(void)
/* IDE */
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (hdd[c].bus == HDD_BUS_IDE) {
if ((hdd[c].bus == HDD_BUS_IDE) || (hdd[c].bus == HDD_BUS_ATAPI)) {
sprintf(tmp2, "%01u:%01u", c >> 1, c & 1);
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -2396,7 +2399,7 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE))
if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE) && (hdd[c].bus != HDD_BUS_ATAPI)))
ini_section_delete_var(cat, temp);
else {
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);
@@ -2439,7 +2442,8 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_speed", c + 1);
if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE && hdd[c].bus != HDD_BUS_ESDI))
if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_ESDI) && (hdd[c].bus != HDD_BUS_IDE) &&
(hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_ATAPI)))
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset));

View File

@@ -24,6 +24,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>

View File

@@ -210,7 +210,7 @@ hdd_readahead_update(hard_disk_t *hdd)
uint64_t elapsed_cycles;
double elapsed_us;
double seek_time;
uint32_t max_read_ahead;
int32_t max_read_ahead;
uint32_t space_needed;
hdd_cache_t *cache = &hdd->cache;
@@ -224,7 +224,7 @@ hdd_readahead_update(hard_disk_t *hdd)
seek_time = 0.0;
for (uint32_t i = 0; i < max_read_ahead; i++) {
for (int32_t i = 0; i < max_read_ahead; i++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;

View File

@@ -49,6 +49,8 @@
# include <unistd.h>
#endif
#define IDE_ATAPI_IS_EARLY id->sc->pad0
mo_drive_t mo_drives[MO_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
@@ -443,11 +445,11 @@ mo_init(mo_t *dev)
dev->drv->bus_mode |= 1;
mo_log("MO %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
if (dev->drv->bus_type < MO_BUS_SCSI) {
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
}
dev->status = READY_STAT | DSC_STAT;
dev->pos = 0;
dev->tf->status = READY_STAT | DSC_STAT;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0;
}
@@ -477,36 +479,9 @@ mo_current_mode(mo_t *dev)
if (!mo_supports_pio(dev) && mo_supports_dma(dev))
return 2;
if (mo_supports_pio(dev) && mo_supports_dma(dev)) {
mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO");
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
mo_atapi_phase_to_scsi(mo_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
mo_log("MO %i: Drive supports both, setting to %s\n", dev->id,
(dev->tf->features & 1) ? "DMA" : "PIO");
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -622,7 +597,7 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
int bt;
int min_len = 0;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -666,9 +641,9 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -699,9 +674,9 @@ mo_command_common(mo_t *dev)
double bytes_per_second;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0;
else {
@@ -763,8 +738,8 @@ static void
mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int direction)
{
mo_log("MO %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -793,7 +768,8 @@ mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int dir
}
mo_log("MO %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -818,14 +794,14 @@ static void
mo_cmd_error(mo_t *dev)
{
mo_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0);
mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq);
@@ -835,14 +811,14 @@ static void
mo_unit_attention(mo_t *dev)
{
mo_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0);
mo_log("MO %i: UNIT ATTENTION\n", dev->id);
@@ -928,7 +904,7 @@ mo_invalid_field(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_CMD_PACKET;
mo_ascq = 0;
mo_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -938,7 +914,7 @@ mo_invalid_field_pl(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
mo_ascq = 0;
mo_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static int
@@ -1112,7 +1088,8 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7));
mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id,
((dev->tf->request_length >> 5) & 7));
mo_invalid_lun(dev);
return 0;
}
@@ -1202,14 +1179,14 @@ mo_reset(scsi_common_t *sc)
mo_t *dev = (mo_t *) sc;
mo_rezero(dev);
dev->status = 0;
dev->callback = 0.0;
dev->tf->status = 0;
dev->callback = 0.0;
mo_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
}
static void
@@ -1302,11 +1279,11 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == MO_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
BufLen = &blen;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1319,7 +1296,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention);
mo_log("MO %i: Request length: %04X\n", dev->id, dev->request_length);
mo_log("MO %i: Request length: %04X\n", dev->id, dev->tf->request_length);
mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
@@ -1857,10 +1834,10 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
}
#if 0
mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length);
mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length);
#endif
if (mo_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
mo_buf_free(dev);
}
@@ -2099,6 +2076,9 @@ mo_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB;
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI MO, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2117,6 +2097,8 @@ mo_drive_reset(int c)
that's not attached to anything. */
if (id) {
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = mo_get_max;
id->get_timings = mo_get_timings;
id->identify = mo_identify;
@@ -2203,6 +2185,9 @@ mo_close(void)
if (dev) {
mo_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev);
mo_drives[c].priv = NULL;
}

View File

@@ -36,6 +36,8 @@
#include <86box/hdc_ide.h>
#include <86box/zip.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
zip_drive_t zip_drives[ZIP_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
@@ -588,11 +590,11 @@ zip_init(zip_t *dev)
dev->drv->bus_mode |= 1;
zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
if (dev->drv->bus_type < ZIP_BUS_SCSI) {
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
}
dev->status = READY_STAT | DSC_STAT;
dev->pos = 0;
dev->tf->status = READY_STAT | DSC_STAT;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0;
}
@@ -622,36 +624,9 @@ zip_current_mode(zip_t *dev)
if (!zip_supports_pio(dev) && zip_supports_dma(dev))
return 2;
if (zip_supports_pio(dev) && zip_supports_dma(dev)) {
zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO");
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
zip_atapi_phase_to_scsi(zip_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id,
(dev->tf->features & 1) ? "DMA" : "PIO");
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -791,7 +766,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
int bt;
int min_len = 0;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -835,9 +810,9 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -868,9 +843,9 @@ zip_command_common(zip_t *dev)
double bytes_per_second;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0;
else {
@@ -932,8 +907,8 @@ static void
zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction)
{
zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -962,7 +937,8 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d
}
zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -987,12 +963,12 @@ static void
zip_cmd_error(zip_t *dev)
{
zip_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
@@ -1004,12 +980,12 @@ static void
zip_unit_attention(zip_t *dev)
{
zip_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
@@ -1097,7 +1073,7 @@ zip_invalid_field(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_CMD_PACKET;
zip_ascq = 0;
zip_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1107,7 +1083,7 @@ zip_invalid_field_pl(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
zip_ascq = 0;
zip_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1184,7 +1160,8 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7));
zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id,
((dev->tf->request_length >> 5) & 7));
zip_invalid_lun(dev);
return 0;
}
@@ -1274,14 +1251,14 @@ zip_reset(scsi_common_t *sc)
zip_t *dev = (zip_t *) sc;
zip_rezero(dev);
dev->status = 0;
dev->callback = 0.0;
dev->tf->status = 0;
dev->callback = 0.0;
zip_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
}
static void
@@ -1373,11 +1350,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
BufLen = &blen;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1388,7 +1365,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention);
zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length);
zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->tf->request_length);
zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
@@ -1465,8 +1442,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
break;
case GPCMD_REQUEST_SENSE:
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE
should forget about the not ready, and report unit attention straight away. */
/* If there's a unit attention condition and there's a buffered not
ready, a standalone REQUEST SENSE should forget about the not
ready, and report unit attention straight away. */
zip_set_phase(dev, SCSI_PHASE_DATA_IN);
max_len = cdb[4];
@@ -1507,7 +1485,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
switch (cdb[0]) {
case GPCMD_READ_6:
dev->sector_len = cdb[4];
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
/*
For READ (6) and WRITE (6), a length of 0 indicates a
transfer of 256 sectors.
*/
if (dev->sector_len == 0)
dev->sector_len = 256;
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) |
(((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break;
case GPCMD_READ_10:
@@ -1516,14 +1501,21 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break;
case GPCMD_READ_12:
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
(((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) |
(((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
break;
default:
break;
}
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
if (!dev->sector_len) {
zip_set_phase(dev, SCSI_PHASE_STATUS);
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */
@@ -1534,9 +1526,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
}
max_len = dev->sector_len;
dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT
matter anyway, this step should be identical and only the way the read dat is
transferred to the host should be different. */
/*
If we're reading all blocks in one go for DMA, why not also for
PIO, it should NOT matter anyway, this step should be identical
and only the way the read dat is transferred to the host should
be different.
*/
dev->requested_blocks = max_len;
dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len);
@@ -1558,10 +1554,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_VERIFY_6:
@@ -1590,9 +1583,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_6:
case GPCMD_WRITE_6:
dev->sector_len = cdb[4];
/*
For READ (6) and WRITE (6), a length of 0 indicates a
transfer of 256 sectors.
*/
if (dev->sector_len == 0)
dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
dev->sector_len = 256;
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) |
(((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
break;
case GPCMD_VERIFY_10:
case GPCMD_WRITE_10:
@@ -1604,17 +1602,17 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_12:
case GPCMD_WRITE_12:
case GPCMD_WRITE_AND_VERIFY_12:
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
(((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) |
(((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
break;
default:
break;
}
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
@@ -1629,9 +1627,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
}
max_len = dev->sector_len;
dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT
matter anyway, this step should be identical and only the way the read dat is
transferred to the host should be different. */
/*
If we're writing all blocks in one go for DMA, why not also for
PIO, it should NOT matter anyway, this step should be identical
and only the way the read dat is transferred to the host should
be different.
*/
dev->requested_blocks = max_len;
dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len);
@@ -1643,10 +1645,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_WRITE_SAME_10:
@@ -1665,9 +1664,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
dev->sector_len = (cdb[7] << 8) | cdb[8];
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
@@ -1693,10 +1690,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, 512, 512, alloc_length, 1);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_MODE_SENSE_6:
@@ -2034,10 +2028,10 @@ atapi_out:
}
#if 0
zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length);
zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length);
#endif
if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
zip_buf_free(dev);
}
@@ -2321,6 +2315,9 @@ zip_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB;
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI ZIP, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2339,6 +2336,8 @@ zip_drive_reset(int c)
that's not attached to anything. */
if (id) {
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = zip_get_max;
id->get_timings = zip_get_timings;
id->identify = zip_identify;
@@ -2425,6 +2424,9 @@ zip_close(void)
if (dev) {
zip_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev);
zip_drives[c].priv = NULL;
}

View File

@@ -213,6 +213,9 @@ extern uint16_t get_last_addr(void);
extern void sub_cycles(int c);
extern void resub_cycles(int old_cycles);
extern void ack_pause(void);
extern void do_pause(int p);
extern double isa_timing;
extern int io_delay;
extern int framecountx;

View File

@@ -86,7 +86,10 @@ enum
CDROM_TYPE_CHINON_CDS431_H42,
CDROM_TYPE_DEC_RRD45_0436,
CDROM_TYPE_MATSHITA_501_10b,
CDROM_TYPE_NEC_25_10a,
CDROM_TYPE_NEC_38_103,
CDROM_TYPE_NEC_75_103,
CDROM_TYPE_NEC_77_106,
CDROM_TYPE_NEC_211_100,
CDROM_TYPE_NEC_464_105,
CDROM_TYPE_SONY_CDU541_10i,
@@ -121,47 +124,50 @@ static const struct
const char *internal_name;
const int bus_type;
} cdrom_drive_types[] = {
{ "86BOX", "CD-ROM", "1.00", "86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_BOTH }, /*1*/
{ "AZT", "CDA46802I", "1.15", "AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE }, /*2*/
{ "BTC", "CD-ROM BCD36XH", "U1.0", "BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE }, /*3*/
{ "GOLDSTAR", "CRD-8160B", "3.14", "GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE }, /*4*/
{ "HITACHI", "CDR-8130", "0020", "HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE }, /*5*/
{ "KENWOOD", "CD-ROM UCR-421", "208E", "KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE }, /*6*/
{ "MATSHITA", "CD-ROM CR-587", "7S13", "MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE }, /*7*/
{ "MATSHITA", "CD-ROM CR-588", "LS15", "MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE }, /*8*/
{ "MATSHITA", "CR-571", "1.0e", "MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE }, /*9*/
{ "MATSHITA", "CR-572", "1.0j", "MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE }, /*10*/
{ "MITSUMI", "CRMC-FX4820T", "D02A", "MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE }, /*11*/
{ "NEC", "CD-ROM DRIVE:260", "1.00", "NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE }, /*12*/
{ "NEC", "CD-ROM DRIVE:260", "1.01", "NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE }, /*13*/
{ "NEC", "CD-ROM DRIVE:273", "4.20", "NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE }, /*14*/
{ "NEC", "CD-ROM DRIVE:280", "1.05", "NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE }, /*15*/
{ "NEC", "CD-ROM DRIVE:280", "3.08", "NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE }, /*16*/
{ "PHILIPS", "CD-ROM PCA403CD", "U31P", "PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE }, /*17*/
{ "SONY", "CD-ROM CDU76", "1.0i", "SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE }, /*18*/
{ "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE }, /*19*/
{ "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE }, /*20*/
{ "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE }, /*21*/
{ "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, /*22*/
{ "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, /*23*/
{ "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, /*24*/
{ "NEC", "CD-ROM DRIVE:38", "1.03", "NEC CD-ROM DRIVE:38 1.03", "NEC_CD-ROM_DRIVE38_1.03", BUS_TYPE_SCSI }, /*25*/
{ "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, /*26*/
{ "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, /*27*/
{ "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, /*28*/
{ "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, /*29*/
{ "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, /*30*/
{ "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, /*31*/
{ "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, /*32*/
{ "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, /*33*/
{ "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, /*34*/
{ "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, /*35*/
{ "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI }, /*36*/
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, /*37*/
{ "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, /*38*/
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, /*39*/
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, /*40*/
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, /*41*/
{ "86BOX", "CD-ROM", "1.00", "86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_BOTH },
{ "AZT", "CDA46802I", "1.15", "AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE },
{ "BTC", "CD-ROM BCD36XH", "U1.0", "BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE },
{ "GOLDSTAR", "CRD-8160B", "3.14", "GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE },
{ "HITACHI", "CDR-8130", "0020", "HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE },
{ "KENWOOD", "CD-ROM UCR-421", "208E", "KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-587", "7S13", "MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-588", "LS15", "MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE },
{ "MATSHITA", "CR-571", "1.0e", "MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE },
{ "MATSHITA", "CR-572", "1.0j", "MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE },
{ "MITSUMI", "CRMC-FX4820T", "D02A", "MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:260", "1.00", "NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:260", "1.01", "NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:273", "4.20", "NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:280", "1.05", "NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:280", "3.08", "NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE },
{ "PHILIPS", "CD-ROM PCA403CD", "U31P", "PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE },
{ "SONY", "CD-ROM CDU76", "1.0i", "SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE },
{ "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE },
{ "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI },
{ "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI },
{ "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:25", "1.0a", "NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:38", "1.00", "NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:75", "1.03", "NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:77", "1.06", "NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI },
{ "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI },
{ "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI },
{ "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI },
{ "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI },
{ "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI },
{ "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI },
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI },
{ "", "", "", "", "", BUS_TYPE_NONE },
};

View File

@@ -41,13 +41,46 @@ enum {
IDE_ATAPI
};
#ifdef SCSI_DEVICE_H
typedef struct ide_tf_s {
union {
uint8_t cylprecomp;
uint8_t features;
};
union {
uint8_t secount;
uint8_t phase;
};
union {
uint16_t cylinder;
uint16_t request_length;
};
union {
uint8_t atastat;
uint8_t status;
};
uint8_t error;
uint16_t pad;
uint32_t pos;
} ide_tf_t;
#ifdef _TIMER_H_
typedef struct ide_s {
uint8_t selected;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t cylprecomp;
uint8_t secount;
uint16_t cylinder;
uint8_t atastat;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
/* The rest. */
uint8_t selected;
uint8_t command;
uint8_t fdisk;
uint8_t head;
uint8_t sector;
int type;
int board;
int irqstat;
@@ -56,18 +89,12 @@ typedef struct ide_s {
int blockcount;
int hdd_num;
int channel;
int pos;
int sector_pos;
int lba;
int reset;
int mdma_mode;
int do_initial_read;
uint32_t secount;
uint32_t sector;
uint32_t cylinder;
uint32_t head;
uint32_t drive;
uint32_t cylprecomp;
uint32_t cfg_spt;
uint32_t cfg_hpc;
uint32_t lba_addr;
@@ -80,11 +107,19 @@ typedef struct ide_s {
pc_timer_t timer;
/* Task file. */
ide_tf_t * tf;
/* Stuff mostly used by ATAPI */
#ifdef SCSI_DEVICE_H
scsi_common_t *sc;
#else
void * sc;
#endif
int interrupt_drq;
double pending_delay;
#ifdef SCSI_DEVICE_H
int (*get_max)(int ide_has_dma, int type);
int (*get_timings)(int ide_has_dma, int type);
void (*identify)(struct ide_s *ide, int ide_has_dma);
@@ -94,10 +129,22 @@ typedef struct ide_s {
uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc);
void (*bus_master_error)(scsi_common_t *sc);
#else
void * get_max;
void * get_timings;
void * identify;
void * stop;
void * device_reset;
void * phase_data_out;
void * command_stop;
void * bus_master_error;
#endif
} ide_t;
#ifdef EMU_HDC_H
extern ide_t *ide_drives[IDE_NUM];
#endif
#endif
/* Type:
0 = PIO,
@@ -155,16 +202,9 @@ extern void ide_set_bus_master(int board,
extern void win_cdrom_eject(uint8_t id);
extern void win_cdrom_reload(uint8_t id);
extern void ide_set_base(int board, uint16_t port);
extern void ide_set_side(int board, uint16_t port);
extern void ide_set_base_addr(int board, int base, uint16_t port);
extern void ide_set_handlers(uint8_t board);
extern void ide_remove_handlers(uint8_t board);
extern void ide_pri_enable(void);
extern void ide_pri_disable(void);
extern void ide_sec_enable(void);
extern void ide_sec_disable(void);
extern void ide_handlers(uint8_t board, int set);
extern void ide_board_set_force_ata3(int board, int force_ata3);
#ifdef EMU_ISAPNP_H
@@ -183,4 +223,16 @@ extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
extern uint8_t ide_read_ali_75(void);
extern uint8_t ide_read_ali_76(void);
/* Legacy #define's. */
#define ide_set_base(board, port) ide_set_base_addr(board, 0, port)
#define ide_set_side(board, port) ide_set_base_addr(board, 1, port)
#define ide_pri_enable() ide_handlers(0, 1)
#define ide_pri_disable() ide_handlers(0, 0)
#define ide_sec_enable() ide_handlers(1, 1)
#define ide_sec_disable() ide_handlers(1, 0)
#define ide_set_handlers(board) ide_handlers(board, 1)
#define ide_remove_handlers(board) ide_handlers(board, 0)
#endif /*EMU_IDE_H*/

View File

@@ -148,7 +148,8 @@ typedef struct hard_disk_t {
uint8_t scsi_id;
};
uint8_t bus;
uint8_t res; /* Reserved for bus mode */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t wp; /* Disk has been mounted READ-ONLY */
uint8_t pad;
uint8_t pad0;

View File

@@ -128,23 +128,35 @@ typedef struct mo_t {
mode_sense_pages_t ms_pages_saved;
mo_drive_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -158,7 +170,6 @@ typedef struct mo_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} mo_t;

View File

@@ -26,24 +26,36 @@ typedef struct scsi_cdrom_t {
/* Common block. */
mode_sense_pages_t ms_pages_saved;
cdrom_t *drv;
cdrom_t * drv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t early;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -57,7 +69,6 @@ typedef struct scsi_cdrom_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;

View File

@@ -149,6 +149,7 @@
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */
/* Mode page codes for mode sense/set */
#define GPMODE_UNIT_ATN_PAGE 0x00
#define GPMODE_R_W_ERROR_PAGE 0x01
#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */
#define GPMODE_FORMAT_DEVICE_PAGE 0x03
@@ -165,6 +166,7 @@
#define GPMODE_ALL_PAGES 0x3f
/* Mode page codes for presence */
#define GPMODEP_UNIT_ATN_PAGE 0x0000000000000001LL
#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL
#define GPMODEP_DISCONNECT_PAGE 0x0000000000000004LL
#define GPMODEP_FORMAT_DEVICE_PAGE 0x0000000000000008LL
@@ -347,7 +349,12 @@ typedef struct mode_sense_pages_t {
typedef struct scsi_common_s {
mode_sense_pages_t ms_pages_saved;
void *priv;
void * priv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
#else
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices,
@@ -355,17 +362,24 @@ typedef struct scsi_common_s {
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -379,7 +393,6 @@ typedef struct scsi_common_s {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} scsi_common_t;
@@ -435,4 +448,7 @@ extern void scsi_device_init(void);
extern void scsi_reset(void);
extern uint8_t scsi_get_bus(void);
extern void scsi_bus_set_speed(uint8_t bus, double speed);
extern double scsi_bus_get_speed(uint8_t bus);
#endif /*SCSI_DEVICE_H*/

View File

@@ -20,38 +20,48 @@ typedef struct scsi_disk_t {
mode_sense_pages_t ms_pages_saved;
hard_disk_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t pad[16]; /* This is atapi_cdb in ATAPI-supporting devices,
and pad in SCSI-only devices. */
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint8_t error;
uint8_t id;
uint8_t pad0;
uint8_t cur_lun;
uint8_t pad1;
uint8_t pad2;
uint16_t request_length;
uint16_t pad4;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int pad5;
int request_pos;
int pad6;
int pad7;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} scsi_disk_t;

View File

@@ -74,23 +74,35 @@ typedef struct zip_t {
mode_sense_pages_t ms_pages_saved;
zip_drive_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -104,7 +116,6 @@ typedef struct zip_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} zip_t;

View File

@@ -75,8 +75,10 @@ Harddrives::populateSpeeds(QAbstractItemModel *model, int bus)
int num_preset;
switch (bus) {
case HDD_BUS_IDE:
case HDD_BUS_ESDI:
case HDD_BUS_IDE:
case HDD_BUS_ATAPI:
case HDD_BUS_SCSI:
num_preset = hdd_preset_get_num();
break;

View File

@@ -137,6 +137,8 @@ main_thread_fn()
}
} else {
/* Just so we dont overload the host OS. */
if (dopause)
ack_pause();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}

View File

@@ -921,16 +921,10 @@ MainWindow::on_actionSettings_triggered()
switch (settings.result()) {
case QDialog::Accepted:
/*
pc_reset_hard_close();
settings.save();
config_changed = 2;
pc_reset_hard_init();
*/
settings.save();
config_changed = 2;
pc_reset_hard();
break;
case QDialog::Rejected:
break;

View File

@@ -382,7 +382,7 @@ plat_pause(int p)
if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))
nvr_time_sync();
dopause = p;
do_pause(p);
if (p) {
if (mouse_capture)
plat_mouse_capture(0);
@@ -408,9 +408,6 @@ plat_pause(int p)
#endif
}
// because we can't include nvr.h because it's got fields named new
extern int nvr_save(void);
void
plat_power_off(void)
{

View File

@@ -42,7 +42,8 @@
#include <86box/scsi_pcscsi.h>
#include <86box/scsi_spock.h>
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 };
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0, 0, 0 };
double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 };
static uint8_t next_scsi_bus = 0;
@@ -183,3 +184,15 @@ scsi_card_init(void)
}
}
}
void
scsi_bus_set_speed(uint8_t bus, double speed)
{
scsi_bus_speed[bus] = speed;
}
double
scsi_bus_get_speed(uint8_t bus)
{
return scsi_bus_speed[bus];
}

View File

@@ -1101,6 +1101,8 @@ aha_init(const device_t *info)
break;
}
scsi_bus_set_speed(dev->bus, dev->ha_bps);
/* Initialize ROM BIOS if needed. */
aha_setbios(dev);

View File

@@ -1706,9 +1706,10 @@ buslogic_init(const device_t *info)
break;
}
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) {
scsi_bus_set_speed(dev->bus, dev->ha_bps);
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI))
x54x_io_set(dev, dev->Base, 4);
}
memset(bl->AutoSCSIROM, 0xff, 32768);

View File

@@ -41,6 +41,8 @@
#include <86box/scsi_cdrom.h>
#include <86box/version.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
#pragma pack(push, 1)
typedef struct gesn_cdb_t {
uint8_t opcode;
@@ -184,7 +186,7 @@ uint8_t scsi_cdrom_command_flags[0x100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */
};
static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES);
static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_UNIT_ATN_PAGE | GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES);
static uint64_t scsi_cdrom_mode_sense_page_flags_sony = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE_SONY | GPMODEP_CDROM_AUDIO_PAGE_SONY | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES);
static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1ULL << 0x02ULL) | (1ULL << 0x0fULL) | GPMODEP_ALL_PAGES);
@@ -281,10 +283,10 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = {
};
static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = {
{{ 0, 0 },
{{ GPMODE_UNIT_ATN_PAGE, 6, 0, 0, 0, 0, 0, 0 }, /*Guess-work*/
{ GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 },
{ GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0 },
{ GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
@@ -373,10 +375,10 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_sony_scsi =
};
static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = {
{{ 0, 0 },
{{ GPMODE_UNIT_ATN_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /*Guess-work*/
{ GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 },
{ GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 },
{ 0, 0 },
{ GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
@@ -516,15 +518,17 @@ scsi_cdrom_init(scsi_cdrom_t *dev)
dev->drv->bus_mode |= 2;
if (dev->drv->bus_type < CDROM_BUS_SCSI)
dev->drv->bus_mode |= 1;
scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n",
dev->id, dev->drv->bus_type, dev->drv->bus_mode);
dev->sense[0] = 0xf0;
dev->sense[7] = 10;
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) /*NEC only*/
dev->status = READY_STAT | DSC_STAT;
/* NEC only */
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101))
dev->tf->status = READY_STAT | DSC_STAT;
else
dev->status = 0;
dev->pos = 0;
dev->tf->status = 0;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0;
dev->drv->cur_speed = dev->drv->speed;
@@ -541,37 +545,9 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev)
return 2;
else if (dev->drv->bus_type == CDROM_BUS_ATAPI) {
scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id,
(dev->features & 1) ? "DMA" : "PIO",
(dev->tf->features & 1) ? "DMA" : "PIO",
dev->id);
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -617,7 +593,8 @@ scsi_cdrom_get_volume(void *priv, int channel)
case CDROM_TYPE_SONY_CDU561_18k:
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY :
GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
break;
default:
ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
@@ -640,13 +617,15 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi,
sizeof(mode_sense_pages_t));
memset(file_name, 0, 512);
sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id);
fp = plat_fopen(nvr_path(file_name), "rb");
if (fp) {
if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, fp) != 0x10)
if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1,
0x10, fp) != 0x10)
fatal("scsi_cdrom_mode_sense_load(): Error reading data\n");
fclose(fp);
}
@@ -654,9 +633,11 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
default:
memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t));
if (dev->drv->bus_type == CDROM_BUS_SCSI)
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi,
sizeof(mode_sense_pages_t));
else
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default,
sizeof(mode_sense_pages_t));
memset(file_name, 0, 512);
if (dev->drv->bus_type == CDROM_BUS_SCSI)
@@ -839,14 +820,14 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag
else {
if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) {
buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f;
/* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and early vendor SCSI CD-ROM models) are
caddy drives, the later ones are tray drives. */
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
/* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and
early vendor SCSI CD-ROM models) are caddy drives, the later
ones are tray drives. */
if (dev->drv->bus_type == CDROM_BUS_SCSI)
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00);
} else {
else
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) ||
((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20);
}
} else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) {
if (j & 1)
buf[pos++] = ((dev->drv->speed * 176) & 0xff);
@@ -881,7 +862,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
int32_t min_len = 0;
double dlen;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -936,9 +917,9 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -969,10 +950,11 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
double bytes_per_second = 0.0;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
dev->callback = 0;
/* MAP: BUSY_STAT, no DRQ, phase 1. */
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
dev->callback = 0;
scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed);
@@ -1000,14 +982,10 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
dev->callback += period;
fallthrough;
case 0x25:
case 0x42:
case 0x43:
case 0x44:
case 0x51:
case 0x52:
case 0x42 ... 0x44:
case 0x51 ... 0x52:
case 0xad:
case 0xb8:
case 0xb9:
case 0xb8 ... 0xb9:
case 0xbe:
if (dev->current_cdb[0] == 0x42)
dev->callback += 40.0;
@@ -1015,8 +993,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
case 0xc6:
case 0xc7:
case 0xc6 ... 0xc7:
switch (dev->drv->type) {
case CDROM_TYPE_TOSHIBA_XM_3433:
case CDROM_TYPE_TOSHIBA_XM3201B_3232:
@@ -1050,8 +1027,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
case 0xc2:
case 0xc3:
case 0xc2 ... 0xc3:
switch (dev->drv->type) {
case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_SONY_CDU541_10i:
@@ -1065,10 +1041,12 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
case 0xdd:
case 0xde:
case 0xdd ... 0xde:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
bytes_per_second = 176.0 * 1024.0;
@@ -1100,7 +1078,7 @@ scsi_cdrom_command_complete(scsi_cdrom_t *dev)
ui_sb_update_icon(SB_CDROM | dev->id, 0);
dev->packet_status = PHASE_COMPLETE;
scsi_cdrom_command_common(dev);
dev->phase = 3;
dev->tf->phase = 3;
}
static void
@@ -1108,7 +1086,7 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_IN;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
dev->tf->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -1123,7 +1101,7 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_OUT;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
dev->tf->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -1142,8 +1120,9 @@ static void
scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction)
{
scsi_cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction,
dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -1172,7 +1151,8 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al
}
scsi_cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -1197,14 +1177,14 @@ static void
scsi_cdrom_cmd_error(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
ui_sb_update_icon(SB_CDROM | dev->id, 0);
scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq);
@@ -1214,12 +1194,12 @@ static void
scsi_cdrom_unit_attention(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
@@ -1298,7 +1278,7 @@ scsi_cdrom_invalid_field(scsi_cdrom_t *dev)
scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET;
scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1308,7 +1288,7 @@ scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev)
scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1575,7 +1555,7 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb)
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n",
dev->id, ((dev->request_length >> 5) & 7));
dev->id, ((dev->tf->request_length >> 5) & 7));
scsi_cdrom_invalid_lun(dev);
return 0;
}
@@ -1674,14 +1654,14 @@ scsi_cdrom_reset(scsi_common_t *sc)
return;
scsi_cdrom_rezero(dev);
dev->status = 0;
dev->callback = 0.0;
dev->tf->status = 0;
dev->callback = 0.0;
scsi_cdrom_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0xff;
dev->cur_lun = SCSI_LUN_USE_CDB;
dev->tf->phase = 1;
dev->tf->request_length = 0xeb14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0xff;
dev->cur_lun = SCSI_LUN_USE_CDB;
}
static void
@@ -1793,10 +1773,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1814,11 +1794,12 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, dev->unit_attention);
scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length);
dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq,
dev->unit_attention);
scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->tf->request_length);
scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
cdb[8], cdb[9], cdb[10], cdb[11]);
}
@@ -1868,7 +1849,10 @@ begin:
case 0xDA: /*GPCMD_SPEED_ALT*/
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_STILL_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -2006,11 +1990,14 @@ begin:
case 0xDE:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_DISC_INFORMATION_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
scsi_cdrom_buf_alloc(dev, 4);
scsi_cdrom_buf_alloc(dev, 22); /*NEC manual claims 4 bytes, but the Android source code (namely sr_vendor.c) actually states otherwise.*/
if (!dev->drv->ops) {
scsi_cdrom_not_ready(dev);
@@ -2018,7 +2005,7 @@ begin:
}
ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3);
len = 4;
len = 22;
if (!ret) {
scsi_cdrom_invalid_field(dev);
scsi_cdrom_buf_free(dev);
@@ -2141,7 +2128,10 @@ begin:
if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) {
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
case CDROM_TYPE_TOSHIBA_XM_3433:
@@ -2583,7 +2573,10 @@ begin:
case 0xD8:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -2686,7 +2679,10 @@ begin:
case 0xD9:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_PLAY_AUDIO_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -2926,7 +2922,10 @@ begin:
case 0xDD:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
@@ -3093,7 +3092,10 @@ begin:
case 0xDC:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_CADDY_EJECT_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -3192,17 +3194,23 @@ begin:
case CDROM_TYPE_CHINON_CDS431_H42:
case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_MATSHITA_501_10b:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_SONY_CDU541_10i:
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEAC_CD50_100:
case CDROM_TYPE_TEAC_R55S_10R:
case CDROM_TYPE_TEXEL_DMXX24_100:
case CDROM_TYPE_TOSHIBA_XM3201B_3232:
dev->buffer[2] = 0x01;
dev->buffer[2] = 0x00;
dev->buffer[3] = 0x01; /*SCSI-1 compliant*/
break;
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
dev->buffer[3] = 0x00; /*SCSI unknown version per NEC manuals*/
break;
default:
dev->buffer[2] = 0x02; /*SCSI-2 compliant*/
break;
@@ -3225,6 +3233,13 @@ begin:
case CDROM_TYPE_PIONEER_DRM604X_2403:
dev->buffer[4] = 42;
break;
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
break;
default:
dev->buffer[6] = 0x01; /* 16-bit transfers supported */
dev->buffer[7] = 0x20; /* Wide bus supported */
@@ -3345,7 +3360,10 @@ atapi_out:
case 0xDB:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105: /*GPCMD_SET_STOP_TIME_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -3459,7 +3477,10 @@ atapi_out:
dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos));
if (cdb[0] == GPCMD_SEEK_10) {
switch (dev->drv->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
case CDROM_TYPE_TOSHIBA_XM_3433:
@@ -3727,9 +3748,10 @@ atapi_out:
break;
}
/* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */
/* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->tf->phase,
dev->tf->request_length); */
if (scsi_cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
scsi_cdrom_buf_free(dev);
}
@@ -3905,6 +3927,9 @@ scsi_cdrom_close(void *priv)
{
scsi_cdrom_t *dev = (scsi_cdrom_t *) priv;
if (dev->tf)
free(dev->tf);
if (dev)
free(dev);
}
@@ -4086,6 +4111,7 @@ scsi_cdrom_drive_reset(int c)
ide_t *id;
uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = drv->scsi_device_id & 0x0f;
uint8_t valid = 0;
if (drv->bus_type == CDROM_BUS_SCSI) {
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */
@@ -4118,9 +4144,12 @@ scsi_cdrom_drive_reset(int c)
drv->get_channel = scsi_cdrom_get_channel;
drv->close = scsi_cdrom_close;
scsi_cdrom_init(dev);
if (drv->bus_type == CDROM_BUS_SCSI) {
valid = 1;
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI CD-ROM, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -4140,7 +4169,12 @@ scsi_cdrom_drive_reset(int c)
otherwise, we do nothing - it's going to be a drive
that's not attached to anything. */
if (id) {
valid = 1;
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101))
IDE_ATAPI_IS_EARLY = 1;
id->get_max = scsi_cdrom_get_max;
id->get_timings = scsi_cdrom_get_timings;
id->identify = scsi_cdrom_identify;
@@ -4158,4 +4192,7 @@ scsi_cdrom_drive_reset(int c)
scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel);
}
if (valid)
scsi_cdrom_init(dev);
}

View File

@@ -23,6 +23,7 @@
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/hdd.h>
#include <86box/hdc_ide.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/plat_unused.h>
@@ -37,7 +38,7 @@ scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb)
if (dev->command) {
dev->command(dev->sc, cdb);
if (dev->sc->status & ERR_STAT)
if (dev->sc->tf->status & ERR_STAT)
return SCSI_STATUS_CHECK_CONDITION;
else
return SCSI_STATUS_OK;
@@ -140,7 +141,7 @@ scsi_device_command_phase1(scsi_device_t *dev)
} else
scsi_device_command_stop(dev);
if (dev->sc->status & ERR_STAT)
if (dev->sc->tf->status & ERR_STAT)
dev->status = SCSI_STATUS_CHECK_CONDITION;
else
dev->status = SCSI_STATUS_OK;

File diff suppressed because it is too large Load Diff

View File

@@ -1658,6 +1658,8 @@ ncr_init(const device_t *info)
}
timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0);
scsi_bus_set_speed(ncr_dev->bus, 5000000.0);
return ncr_dev;
}

View File

@@ -2623,6 +2623,8 @@ ncr53c8xx_init(const device_t *info)
timer_add(&dev->timer, ncr53c8xx_callback, dev, 0);
scsi_bus_set_speed(dev->bus, 10000000.0);
return dev;
}

View File

@@ -1870,6 +1870,8 @@ dc390_init(UNUSED(const device_t *info))
timer_add(&dev->timer, esp_callback, dev, 0);
scsi_bus_set_speed(dev->bus, 10000000.0);
return dev;
}
@@ -2040,6 +2042,8 @@ ncr53c90_mca_init(UNUSED(const device_t *info))
timer_add(&dev->timer, esp_callback, dev, 0);
scsi_bus_set_speed(dev->bus, 5000000.0);
return dev;
}

View File

@@ -1164,15 +1164,18 @@ spock_init(const device_t *info)
scsi->cmd_timer = SPOCK_TIME * 50;
scsi->status = STATUS_BUSY;
for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++) {
for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++)
scsi->dev_id[c].phys_id = -1;
}
scsi->dev_id[SCSI_ID_MAX - 1].phys_id = scsi->adapter_id;
timer_add(&scsi->callback_timer, spock_callback, scsi, 1);
scsi->callback_timer.period = 10.0;
timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC)));
timer_set_delay_u64(&scsi->callback_timer,
(uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC)));
scsi_bus_set_speed(scsi->bus, 5000000.0);
return scsi;
}

View File

@@ -158,7 +158,6 @@ static uint8_t sb_16_pnp_rom[] = {
// clang-format on
};
// #define ENABLE_SB_LOG 1
#ifdef ENABLE_SB_LOG
int sb_do_log = ENABLE_SB_LOG;
@@ -820,6 +819,14 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
sb->dsp.sb_irqm8 = 0;
sb->dsp.sb_irqm16 = 0;
sb->dsp.sb_irqm401 = 0;
mixer->regs[0xfd] = 0x10;
mixer->regs[0xfe] = 0x06;
mixer->regs[0xff] = sb->dsp.sb_16_dma_supported ? 0x05 : 0x03;
sb_dsp_setdma16_enabled(&sb->dsp, 0x01);
sb_dsp_setdma16_translate(&sb->dsp, mixer->regs[0xff] & 0x02);
} else
mixer->regs[mixer->index] = val;
@@ -938,11 +945,16 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0xff:
if (sb->dsp.sb_type >= SBAWE32) {
if (val != ISAPNP_DMA_DISABLED)
sb_dsp_setdma16_8(&sb->dsp, val & 0x07);
if (sb->dsp.sb_type >= SB16) {
/*
Bit 5: High DMA channel enabled (0 = yes, 1 = no);
Bit 2: ????;
Bit 1: ???? (16-bit to 8-bit translation?);
Bit 0: ????
Seen values: 20, 05, 04, 03
*/
sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20));
sb_dsp_setdma16_translate(&sb->dsp, val != ISAPNP_DMA_DISABLED);
sb_dsp_setdma16_translate(&sb->dsp, val & 0x02);
}
break;
@@ -1159,7 +1171,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv)
- Register FF = FF: Volume playback normal.
- Register FF = Not FF: Volume playback low unless
bit 6 of 82h is set. */
if (sb->dsp.sb_type >= SBAWE32)
if (sb->dsp.sb_type >= SB16)
ret = mixer->regs[mixer->index];
break;

View File

@@ -502,6 +502,7 @@ sb_16_write_dma(void *priv, uint16_t val)
void
sb_dsp_setirq(sb_dsp_t *dsp, int irq)
{
sb_dsp_log("IRQ now: %i\n", irq);
dsp->sb_irqnum = irq;
}

View File

@@ -223,14 +223,14 @@ typedef struct s3_t {
uint16_t subsys_cntl;
uint16_t setup_md;
uint8_t advfunc_cntl;
uint16_t cur_y, cur_y2, cur_y_bitres;
uint16_t cur_x, cur_x2, cur_x_bitres;
uint16_t cur_y, cur_y2;
uint16_t cur_x, cur_x2;
uint16_t x2, ropmix;
uint16_t pat_x, pat_y;
int16_t desty_axstp, desty_axstp2;
int16_t destx_distp;
int16_t err_term, err_term2;
int16_t maj_axis_pcnt, maj_axis_pcnt2;
int16_t err_term, err_term2;
uint16_t cmd, cmd2;
uint16_t short_stroke;
uint32_t pat_bg_color, pat_fg_color;
@@ -811,7 +811,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0x92e9:
s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
s3->accel.err_term |= ~0x3fff;
s3->accel.err_term |= ~0x1fff;
break;
case 0x914a:
case 0x92ea:
@@ -821,7 +821,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0x92eb:
s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
s3->accel.err_term2 |= ~0x3fff;
s3->accel.err_term2 |= ~0x1fff;
break;
case 0x9548:
@@ -831,8 +831,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0x9459:
case 0x96e9:
s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8);
if (val & 0x08)
s3->accel.maj_axis_pcnt |= ~0x0fff;
break;
case 0x954a:
case 0x96ea:
@@ -841,8 +839,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0x954b:
case 0x96eb:
s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8);
if (val & 0x08)
s3->accel.maj_axis_pcnt2 |= ~0x0fff;
break;
case 0x9948:
@@ -880,13 +876,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_x & 0x1000) {
s3->accel.cx |= ~0xfff;
}
if (s3->accel.cur_y & 0x1000) {
s3->accel.cy |= ~0xfff;
}
if (s3->accel.cmd & 0x1000) {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
@@ -1422,13 +1411,6 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val)
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_x & 0x1000) {
s3->accel.cx |= ~0xfff;
}
if (s3->accel.cur_y & 0x1000) {
s3->accel.cy |= ~0xfff;
}
if (s3->accel.cmd & 0x1000) {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
@@ -6364,6 +6346,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
}
s3->accel.ssv_len--;
s3->accel.cx &= 0xfff;
s3->accel.cy &= 0xfff;
}
s3->accel.cur_x = s3->accel.cx;
@@ -6375,13 +6359,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
if (!cpu_input) {
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_x & 0x1000)
s3->accel.cx |= ~0xfff;
if (s3->accel.cur_y & 0x1000)
s3->accel.cy |= ~0xfff;
s3->accel.sy = s3->accel.maj_axis_pcnt;
if (s3_cpu_src(s3))
@@ -6428,9 +6405,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
else
cpu_dat >>= 16;
if (!s3->accel.sy) {
if (!s3->accel.sy)
break;
}
switch (s3->accel.cmd & 0xe0) {
case 0x00:
@@ -6466,6 +6442,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
break;
}
s3->accel.sy--;
s3->accel.cx &= 0xfff;
s3->accel.cy &= 0xfff;
}
s3->accel.cur_x = s3->accel.cx;
s3->accel.cur_y = s3->accel.cy;
@@ -6526,9 +6504,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
cpu_dat >>= 16;
}
if (!s3->accel.sy) {
if (!s3->accel.sy)
break;
}
if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) {
s3->accel.err_term += s3->accel.destx_distp;
@@ -6597,6 +6574,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
break;
}
s3->accel.sy--;
s3->accel.cx &= 0xfff;
s3->accel.cy &= 0xfff;
}
s3->accel.cur_x = s3->accel.cx;
s3->accel.cur_y = s3->accel.cy;
@@ -6611,13 +6590,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_x & 0x1000) {
s3->accel.cx |= ~0xfff;
}
if (s3->accel.cur_y & 0x1000) {
s3->accel.cy |= ~0xfff;
}
s3->accel.dest = dstbase + s3->accel.cy * s3->width;
if (s3_cpu_src(s3)) {
@@ -6709,6 +6681,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
else
s3->accel.cx--;
s3->accel.cx &= 0xfff;
s3->accel.sx--;
if (s3->accel.sx < 0) {
if (s3->accel.cmd & 0x20)
@@ -6722,6 +6695,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
else
s3->accel.cy--;
s3->accel.cy &= 0xfff;
s3->accel.dest = dstbase + s3->accel.cy * s3->width;
s3->accel.sy--;
@@ -6840,13 +6814,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_x & 0x1000) {
s3->accel.cx |= ~0xfff;
}
if (s3->accel.cur_y & 0x1000) {
s3->accel.cy |= ~0xfff;
}
s3->accel.src = srcbase + s3->accel.cy * s3->width;
s3->accel.dest = dstbase + s3->accel.dy * s3->width;
}
@@ -6894,8 +6861,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
}
} else {
while (count-- && s3->accel.sy >= 0) {
/*This is almost required by OS/2's software cursor or we will risk writing/reading garbage around it.*/
if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && ((s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b)) {
if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && ((s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) {
if (vram_mask && (s3->accel.cmd & 0x10)) {
READ(s3->accel.src + s3->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
@@ -6952,13 +6918,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.sx--;
if (s3->accel.sx < 0) {
if (s3->accel.cmd & 0x20) {
s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
} else {
s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
}
s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff;
if (s3->accel.cmd & 0x80) {
@@ -6968,7 +6933,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cy--;
s3->accel.dy--;
}
s3->accel.src = srcbase + s3->accel.cy * s3->width;
s3->accel.dest = dstbase + s3->accel.dy * s3->width;
@@ -7000,11 +6964,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.dy |= ~0xfff;
s3->accel.cx = s3->accel.cur_x & 0xfff;
if (s3->accel.cur_x & 0x1000)
s3->accel.cx |= ~0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_y & 0x1000)
s3->accel.cy |= ~0xfff;
/*Align source with destination*/
s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx;
@@ -7078,11 +7038,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.sx--;
if (s3->accel.sx < 0) {
if (s3->accel.cmd & 0x20) {
s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7);
s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx = ((s3->accel.cx - (((s3->accel.maj_axis_pcnt & 0xfff) + 1))) & 7) | (s3->accel.cx & ~7);
s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
} else {
s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7);
s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx = ((s3->accel.cx + (((s3->accel.maj_axis_pcnt & 0xfff) + 1))) & 7) | (s3->accel.cx & ~7);
s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
}
s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff;
@@ -7124,12 +7084,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
if (s3->accel.desty_axstp & 0x1000)
s3->accel.dy |= ~0xfff;
s3->accel.cx = s3->accel.cur_x;
if (s3->accel.cur_x & 0x1000)
s3->accel.cx |= ~0xfff;
s3->accel.cy = s3->accel.cur_y;
if (s3->accel.cur_y & 0x1000)
s3->accel.cy |= ~0xfff;
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
}
if ((s3->accel.cmd & 0x100) && !cpu_input)
@@ -7159,12 +7115,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cy++;
else
s3->accel.cy--;
}
s3->accel.cy &= 0xfff;
}
if (s3->accel.destx_distp > s3->accel.cur_x)
s3->accel.cx++;
else
s3->accel.cx--;
s3->accel.cx &= 0xfff;
}
} else {
error = s3->accel.dy / 2;
@@ -7190,11 +7149,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cx++;
else
s3->accel.cx--;
s3->accel.cx &= 0xfff;
}
if (s3->accel.desty_axstp > s3->accel.cur_y)
s3->accel.cy++;
else
s3->accel.cy--;
s3->accel.cy &= 0xfff;
}
}
s3->accel.cur_x = s3->accel.cx;
@@ -7316,18 +7279,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.dy |= ~0xfff;
s3->accel.cx = s3->accel.cur_x & 0xfff;
if (s3->accel.cur_x & 0x1000)
s3->accel.cx |= ~0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cur_y & 0x1000)
s3->accel.cy |= ~0xfff;
s3->accel.px = s3->accel.pat_x & 0xfff;
if (s3->accel.pat_x & 0x1000)
s3->accel.px |= ~0xfff;
s3->accel.py = s3->accel.pat_y & 0xfff;
if (s3->accel.pat_y & 0x1000)
s3->accel.py |= ~0xfff;
s3->accel.dest = dstbase + (s3->accel.dy * s3->width);
s3->accel.src = srcbase + (s3->accel.cy * s3->width);
@@ -7428,13 +7383,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.sx--;
if (s3->accel.sx < 0) {
if (s3->accel.cmd & 0x20) {
s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.px -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.px -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
} else {
s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.px += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
s3->accel.px += ((s3->accel.maj_axis_pcnt & 0xfff) + 1);
}
s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff;
@@ -7447,7 +7402,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.dy--;
s3->accel.py--;
}
s3->accel.src = srcbase + (s3->accel.cy * s3->width);
s3->accel.dest = dstbase + (s3->accel.dy * s3->width);
s3->accel.pattern = (s3->accel.py * s3->width);

View File

@@ -113,7 +113,7 @@ typedef struct tgui_t {
struct
{
int32_t src_x, src_y;
int16_t src_x, src_y;
int16_t src_x_clip, src_y_clip;
int16_t dst_x, dst_y;
int16_t dst_y_clip, dst_x_clip;
@@ -129,9 +129,9 @@ typedef struct tgui_t {
int offset;
uint16_t ger22;
int32_t err;
int16_t err;
int16_t top, left, bottom, right;
int x, y, dx, dy;
int16_t x, y, cx, cy, dx, dy;
uint32_t src, dst, src_old, dst_old;
int pat_x, pat_y;
int use_src;
@@ -1699,49 +1699,47 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
break;
case TGUI_SCANLINE:
{
if (count == -1) {
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch);
tgui->accel.src = tgui->accel.src_old;
if (count == -1) {
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch);
tgui->accel.src = tgui->accel.src_old;
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch);
tgui->accel.dst = tgui->accel.dst_old;
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch);
tgui->accel.dst = tgui->accel.dst_old;
tgui->accel.pat_x = tgui->accel.dst_x;
tgui->accel.pat_y = tgui->accel.dst_y;
tgui->accel.pat_x = tgui->accel.dst_x;
tgui->accel.pat_y = tgui->accel.dst_y;
}
while (count--) {
READ(tgui->accel.src, src_dat);
READ(tgui->accel.dst, dst_dat);
pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)];
if (tgui->accel.bpp == 0)
pat_dat &= 0xff;
else if (tgui->accel.bpp == 1)
pat_dat &= 0xffff;
if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) {
MIX();
WRITE(tgui->accel.dst, out);
}
while (count--) {
READ(tgui->accel.src, src_dat);
READ(tgui->accel.dst, dst_dat);
tgui->accel.src += xdir;
tgui->accel.dst += xdir;
tgui->accel.pat_x += xdir;
pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)];
tgui->accel.x++;
if (tgui->accel.x > tgui->accel.size_x) {
tgui->accel.x = 0;
if (tgui->accel.bpp == 0)
pat_dat &= 0xff;
else if (tgui->accel.bpp == 1)
pat_dat &= 0xffff;
if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) {
MIX();
WRITE(tgui->accel.dst, out);
}
tgui->accel.src += xdir;
tgui->accel.dst += xdir;
tgui->accel.pat_x += xdir;
tgui->accel.x++;
if (tgui->accel.x > tgui->accel.size_x) {
tgui->accel.x = 0;
tgui->accel.pat_x = tgui->accel.dst_x;
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
tgui->accel.pat_y += ydir;
return;
}
tgui->accel.pat_x = tgui->accel.dst_x;
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
tgui->accel.pat_y += ydir;
return;
}
}
break;
@@ -1750,11 +1748,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
if (count == -1) {
tgui->accel.dx = tgui->accel.dst_x & 0xfff;
tgui->accel.dy = tgui->accel.dst_y & 0xfff;
if (tgui->accel.dst_x & 0x1000)
tgui->accel.dx |= ~0xfff;
if (tgui->accel.dst_y & 0x1000)
tgui->accel.dy |= ~0xfff;
tgui->accel.y = tgui->accel.size_y;
tgui->accel.left = tgui->accel.src_x_clip & 0xfff;
tgui->accel.right = tgui->accel.dst_x_clip & 0xfff;
@@ -1770,113 +1764,74 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
}
}
#if 0
pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y);
#endif
while (count-- && (tgui->accel.y <= (tgui->accel.size_y))) {
#if 0
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat);
#endif
while (count--) {
/*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) {
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) {
READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat);
pat_dat = tgui->accel.fg_col;
if (tgui->accel.bpp == 0)
pat_dat &= 0xff;
else if (tgui->accel.bpp == 1)
pat_dat &= 0xffff;
MIX();
WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out);
}
if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) {
if (!tgui->accel.y)
break;
}
if (tgui->accel.err >= (tgui->accel.size_y & 0xfff)) {
#if 0
pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y);
#endif
if ((tgui->accel.src_x >= 2048) && (tgui->accel.src_x < 4096))
tgui->accel.err -= (4096 - tgui->accel.src_x);
else if ((tgui->accel.src_x >= 4096) && (tgui->accel.src_x < 32768))
tgui->accel.err -= (32768 - tgui->accel.src_x);
else
tgui->accel.err += tgui->accel.src_x;
if (tgui->accel.size_x >= 0) {
tgui->accel.size_x += tgui->accel.src_x;
/*Step minor axis*/
switch (tgui->accel.flags & 0x700) {
case 0x300:
tgui->accel.dy--;
break;
case 0x100:
tgui->accel.dy--;
break;
case 0x700:
tgui->accel.dx--;
break;
case 0x500:
tgui->accel.dx++;
break;
case 0x200:
switch ((tgui->accel.flags >> 8) & 7) {
case 0:
case 2:
tgui->accel.dy++;
break;
case 0x000:
tgui->accel.dy++;
case 1:
case 3:
tgui->accel.dy--;
break;
case 0x600:
tgui->accel.dx--;
break;
case 0x400:
case 4:
case 5:
tgui->accel.dx++;
break;
case 6:
case 7:
tgui->accel.dx--;
break;
default:
break;
}
} else {
#if 0
pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y);
#endif
tgui->accel.err += tgui->accel.src_y;
}
}
} else
tgui->accel.size_x += tgui->accel.src_y;
/*Step major axis*/
switch (tgui->accel.flags & 0x700) {
case 0x300:
tgui->accel.dx--;
break;
case 0x100:
switch ((tgui->accel.flags >> 8) & 7) {
case 0:
case 1:
tgui->accel.dx++;
break;
case 0x700:
tgui->accel.dy--;
break;
case 0x500:
tgui->accel.dy--;
break;
case 0x200:
case 2:
case 3:
tgui->accel.dx--;
break;
case 0x000:
tgui->accel.dx++;
break;
case 0x600:
case 4:
case 6:
tgui->accel.dy++;
break;
case 0x400:
tgui->accel.dy++;
case 5:
case 7:
tgui->accel.dy--;
break;
default:
break;
}
tgui->accel.y++;
tgui->accel.y--;
tgui->accel.dx &= 0xfff;
tgui->accel.dy &= 0xfff;
}
break;
@@ -1884,11 +1839,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
if (count == -1) {
tgui->accel.dx = tgui->accel.dst_x & 0xfff;
tgui->accel.dy = tgui->accel.dst_y & 0xfff;
if (tgui->accel.dst_x & 0x1000)
tgui->accel.dx |= ~0xfff;
if (tgui->accel.dst_y & 0x1000)
tgui->accel.dy |= ~0xfff;
tgui->accel.y = tgui->accel.sv_size_y & 0xfff;
tgui->accel.left = tgui->accel.src_x_clip & 0xfff;
tgui->accel.right = tgui->accel.dst_x_clip & 0xfff;
@@ -1904,28 +1855,19 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
}
}
while (count-- && (tgui->accel.y <= (tgui->accel.sv_size_y & 0xfff))) {
#if 0
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat);
#endif
while (count--) {
/*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) {
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) {
READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat);
pat_dat = tgui->accel.fg_col;
if (tgui->accel.bpp == 0)
pat_dat &= 0xff;
else if (tgui->accel.bpp == 1)
pat_dat &= 0xffff;
MIX();
WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out);
}
if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff))
if (!tgui->accel.y)
break;
switch ((tgui->accel.sv_size_y >> 8) & 0xe0) {
@@ -1962,7 +1904,9 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
break;
}
tgui->accel.y++;
tgui->accel.y--;
tgui->accel.dx &= 0xfff;
tgui->accel.dy &= 0xfff;
}
break;
@@ -1973,11 +1917,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
if (count == -1) {
tgui->accel.dx = tgui->accel.dst_x & 0xfff;
tgui->accel.dy = tgui->accel.dst_y & 0xfff;
if (tgui->accel.dst_x & 0x1000)
tgui->accel.dx |= ~0xfff;
if (tgui->accel.dst_y & 0x1000)
tgui->accel.dy |= ~0xfff;
tgui->accel.y = tgui->accel.size_y;
tgui->accel.left = tgui->accel.src_x_clip & 0xfff;
tgui->accel.right = tgui->accel.dst_x_clip & 0xfff;
@@ -1993,28 +1933,19 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
}
}
while (count-- && (tgui->accel.y <= (tgui->accel.size_y & 0xfff))) {
#if 0
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat);
#endif
while (count--) {
/*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/
if (tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom) {
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) {
READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat);
pat_dat = tgui->accel.fg_col;
if (tgui->accel.bpp == 0)
pat_dat &= 0xff;
else if (tgui->accel.bpp == 1)
pat_dat &= 0xffff;
MIX();
WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out);
}
if (tgui->accel.y == (tgui->accel.size_y & 0xfff))
if (!tgui->accel.y)
break;
switch ((tgui->accel.size_y >> 8) & 0xe0) {
@@ -2051,7 +1982,9 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
break;
}
tgui->accel.y++;
tgui->accel.y--;
tgui->accel.dx &= 0xfff;
tgui->accel.dy &= 0xfff;
}
break;
@@ -2182,36 +2115,37 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv)
tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8);
break;
case 0x213c: /*Src X*/
tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val;
case 0x213c: /*Src X, Diagonal Step Constant*/
tgui->accel.src_x = (tgui->accel.src_x & 0x3f00) | val;
break;
case 0x213d: /*Src X*/
tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8);
case 0x213d: /*Src X, Diagonal Step Constant*/
tgui->accel.src_x = (tgui->accel.src_x & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
tgui->accel.src_x |= ~0x3fff;
break;
case 0x213e: /*Src Y*/
tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val;
case 0x213e: /*Src Y, Axial Step Constant*/
tgui->accel.src_y = (tgui->accel.src_y & 0x3f00) | val;
break;
case 0x213f: /*Src Y*/
tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8);
case 0x213f: /*Src Y, Axial Step Constant*/
tgui->accel.src_y = (tgui->accel.src_y & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
tgui->accel.src_y |= ~0x3fff;
break;
case 0x2140: /*Size X*/
tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val;
case 0x2140: /*Size X, Line Error Term*/
tgui->accel.size_x = (tgui->accel.size_x & 0x3f00) | val;
break;
case 0x2141: /*Size X*/
tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8);
tgui->accel.err = tgui->accel.size_x;
if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096))
tgui->accel.err -= 4096;
else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768))
tgui->accel.err -= 32768;
case 0x2141: /*Size X, Line Error Term*/
tgui->accel.size_x = (tgui->accel.size_x & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
tgui->accel.size_x |= ~0x1fff;
break;
case 0x2142: /*Size Y*/
tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
case 0x2142: /*Size Y, Major Axis Pixel Count*/
tgui->accel.size_y = (tgui->accel.size_y & 0xf00) | val;
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val;
break;
case 0x2143: /*Size Y*/
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
case 0x2143: /*Size Y, Major Axis Pixel Count*/
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | ((val & 0x0f) << 8);
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8);
break;
@@ -2717,311 +2651,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv)
return;
}
switch (addr & 0xff) {
case 0x22:
tgui_accel_out(0x2122, val, tgui);
break;
case 0x23:
tgui_accel_out(0x2123, val, tgui);
break;
case 0x24: /*Command*/
tgui->accel.command = val;
tgui_accel_command(-1, 0, tgui);
break;
case 0x27: /*ROP*/
tgui->accel.rop = val;
tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
break;
case 0x28: /*Flags*/
tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val;
break;
case 0x29: /*Flags*/
tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8);
break;
case 0x2a: /*Flags*/
tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16);
break;
case 0x2b: /*Flags*/
tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24);
break;
case 0x2c: /*Foreground colour*/
case 0x78:
tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val;
break;
case 0x2d: /*Foreground colour*/
case 0x79:
tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8);
break;
case 0x2e: /*Foreground colour*/
case 0x7a:
tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16);
break;
case 0x2f: /*Foreground colour*/
case 0x7b:
tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24);
break;
case 0x30: /*Background colour*/
case 0x7c:
tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val;
break;
case 0x31: /*Background colour*/
case 0x7d:
tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8);
break;
case 0x32: /*Background colour*/
case 0x7e:
tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16);
break;
case 0x33: /*Background colour*/
case 0x7f:
tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24);
break;
case 0x34: /*Pattern location*/
tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val;
break;
case 0x35: /*Pattern location*/
tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8);
break;
case 0x38: /*Dest X*/
tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val;
break;
case 0x39: /*Dest X*/
tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8);
break;
case 0x3a: /*Dest Y*/
tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val;
break;
case 0x3b: /*Dest Y*/
tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8);
break;
case 0x3c: /*Src X*/
tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val;
break;
case 0x3d: /*Src X*/
tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8);
break;
case 0x3e: /*Src Y*/
tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val;
break;
case 0x3f: /*Src Y*/
tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8);
break;
case 0x40: /*Size X*/
tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val;
break;
case 0x41: /*Size X*/
tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8);
tgui->accel.err = tgui->accel.size_x;
if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096))
tgui->accel.err -= 4096;
else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768))
tgui->accel.err -= 32768;
break;
case 0x42: /*Size Y*/
tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val;
break;
case 0x43: /*Size Y*/
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8);
break;
case 0x44: /*Style*/
tgui->accel.style = (tgui->accel.style & 0xffffff00) | val;
break;
case 0x45: /*Style*/
tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8);
break;
case 0x46: /*Style*/
tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16);
break;
case 0x47: /*Style*/
tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24);
break;
case 0x48: /*Clip Src X*/
tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val;
break;
case 0x49: /*Clip Src X*/
tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8);
break;
case 0x4a: /*Clip Src Y*/
tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val;
break;
case 0x4b: /*Clip Src Y*/
tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8);
break;
case 0x4c: /*Clip Dest X*/
tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val;
break;
case 0x4d: /*Clip Dest X*/
tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8);
break;
case 0x4e: /*Clip Dest Y*/
tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val;
break;
case 0x4f: /*Clip Dest Y*/
tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8);
break;
case 0x68: /*CKey*/
tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val;
break;
case 0x69: /*CKey*/
tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8);
break;
case 0x6a: /*CKey*/
tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16);
break;
case 0x6b: /*CKey*/
tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24);
break;
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87:
case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
case 0xa0:
case 0xa1:
case 0xa2:
case 0xa3:
case 0xa4:
case 0xa5:
case 0xa6:
case 0xa7:
case 0xa8:
case 0xa9:
case 0xaa:
case 0xab:
case 0xac:
case 0xad:
case 0xae:
case 0xaf:
case 0xb0:
case 0xb1:
case 0xb2:
case 0xb3:
case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
case 0xb8:
case 0xb9:
case 0xba:
case 0xbb:
case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
case 0xc0:
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
case 0xca:
case 0xcb:
case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
case 0xd0:
case 0xd1:
case 0xd2:
case 0xd3:
case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
case 0xd8:
case 0xd9:
case 0xda:
case 0xdb:
case 0xdc:
case 0xdd:
case 0xde:
case 0xdf:
case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
case 0xe8:
case 0xe9:
case 0xea:
case 0xeb:
case 0xec:
case 0xed:
case 0xee:
case 0xef:
case 0xf0:
case 0xf1:
case 0xf2:
case 0xf3:
case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
case 0xf8:
case 0xf9:
case 0xfa:
case 0xfb:
case 0xfc:
case 0xfd:
case 0xfe:
case 0xff:
tgui->accel.pattern[addr & 0x7f] = val;
break;
default:
break;
}
tgui_accel_out((addr & 0xff) + 0x2100, val, tgui);
}
static void