From: Toni Wilen Date: Wed, 10 Feb 2016 14:26:41 +0000 (+0200) Subject: CD SCSI emulation new trap support. X-Git-Tag: 3300~89 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=6faf5705f536653ef9e67709da9dd8ef45c6f3ed;p=francis%2Fwinuae.git CD SCSI emulation new trap support. --- diff --git a/blkdev.cpp b/blkdev.cpp index be2cfd37..2d197ae1 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -1097,7 +1097,7 @@ void scsi_atapi_fixup_post (uae_u8 *scsi_cmd, int len, uae_u8 *olddata, uae_u8 * static void scsi_atapi_fixup_inquiry (struct amigascsi *as) { - uae_u8 *scsi_data = as->data_h; + uae_u8 *scsi_data = as->data; uae_u32 scsi_len = as->len; uae_u8 *scsi_cmd = as->cmd; uae_u8 cmd; @@ -2073,7 +2073,7 @@ static int execscsicmd_direct (int unitnum, int type, struct amigascsi *as) int replylen = 0; memcpy (cmd, as->cmd, as->cmd_len); - scsi_datap = scsi_datap_org = as->len ? as->data_h : 0; + scsi_datap = scsi_datap_org = as->len ? as->data : 0; if (as->sense_len > 32) as->sense_len = 32; @@ -2101,8 +2101,9 @@ static int execscsicmd_direct (int unitnum, int type, struct amigascsi *as) } else { int i; if (replylen > 0) { - for (i = 0; i < replylen; i++) + for (int i = 0; i < replylen; i++) { scsi_datap[i] = replydata[i]; + } datalen = replylen; } for (i = 0; i < as->sense_len; i++) @@ -2120,7 +2121,7 @@ static int execscsicmd_direct (int unitnum, int type, struct amigascsi *as) return io_error; } -int sys_command_scsi_direct_native (int unitnum, int type, struct amigascsi *as) +int sys_command_scsi_direct_native(int unitnum, int type, struct amigascsi *as) { struct blkdevstate *st = &state[unitnum]; if (st->scsiemu || (type >= 0 && st->type != type)) { @@ -2137,42 +2138,60 @@ int sys_command_scsi_direct_native (int unitnum, int type, struct amigascsi *as) int sys_command_scsi_direct(TrapContext *ctx, int unitnum, int type, uaecptr acmd) { - int ret, i; + int ret; struct amigascsi as = { 0 }; uaecptr ap; addrbank *bank; + uae_u8 scsicmd[30]; - ap = get_long (acmd + 0); - as.len = get_long (acmd + 4); - - bank = &get_mem_bank (ap); - if (!bank || !bank->check(ap, as.len)) - return IOERR_BADADDRESS; - as.data_h = bank->xlateaddr (ap); + trap_get_bytes(ctx, scsicmd, acmd, sizeof scsicmd); - ap = get_long (acmd + 12); - as.cmd_len = get_word (acmd + 16); + as.cmd_len = get_word_host(scsicmd + 16); if (as.cmd_len > sizeof as.cmd) return IOERR_BADLENGTH; - for (i = 0; i < as.cmd_len; i++) - as.cmd[i] = get_byte (ap++); - while (i < sizeof as.cmd) - as.cmd[i++] = 0; - as.flags = get_byte (acmd + 20); - as.sense_len = get_word (acmd + 26); + as.flags = get_byte_host(scsicmd + 20); + ap = get_long_host(scsicmd + 0); + as.len = get_long_host(scsicmd + 4); + + if (trap_is_indirect()) { + if (!(as.flags & 1)) { // write? + as.data = xmalloc(uae_u8, as.len); + trap_get_bytes(ctx, as.data, ap, as.len); + } else { + as.data = xcalloc(uae_u8, as.len); + } + } else { + bank = &get_mem_bank (ap); + if (!bank || !bank->check(ap, as.len)) + return IOERR_BADADDRESS; + as.data = bank->xlateaddr (ap); + } + + ap = get_long_host(scsicmd + 12); + trap_get_bytes(ctx, as.cmd, ap, as.cmd_len); + as.sense_len = get_word_host(scsicmd + 26); ret = sys_command_scsi_direct_native (unitnum, type, &as); - put_long (acmd + 8, as.actual); - put_word (acmd + 18, as.cmdactual); - put_byte (acmd + 21, as.status); - put_word (acmd + 28, as.sactual); + put_long_host(scsicmd + 8, as.actual); + put_word_host(scsicmd + 18, as.cmdactual); + put_byte_host(scsicmd + 21, as.status); + put_word_host(scsicmd + 28, as.sactual); if (as.flags & (2 | 4)) { // autosense - ap = get_long (acmd + 22); - for (i = 0; i < as.sactual && i < as.sense_len; i++) - put_byte (ap + i, as.sensedata[i]); + ap = get_long_host(scsicmd + 22); + trap_put_bytes(ctx, as.sensedata, ap, as.sactual > as.sense_len ? as.sense_len : as.sactual); + } + + trap_put_bytes(ctx, scsicmd, acmd, sizeof scsicmd); + + if (trap_is_indirect()) { + if (as.flags & 1) { // read? + trap_put_bytes(ctx, as.data, ap, as.len); + } + xfree(as.data); } + return ret; } diff --git a/include/blkdev.h b/include/blkdev.h index a27850d2..fc176aa3 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -91,8 +91,7 @@ struct device_info { struct amigascsi { - uae_u8 *data_h; - uaecptr data_a; + uae_u8 *data; uae_s32 len; uae_u8 cmd[16]; uae_s32 cmd_len; diff --git a/od-win32/blkdev_win32_spti.cpp b/od-win32/blkdev_win32_spti.cpp index e1de07e7..e87cbb70 100644 --- a/od-win32/blkdev_win32_spti.cpp +++ b/od-win32/blkdev_win32_spti.cpp @@ -206,7 +206,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) /* the Amiga does not tell us how long the timeout shall be, so make it _very_ long (specified in seconds) */ swb.spt.TimeOutValue = 80 * 60; - scsi_datap = scsi_datap_org = as->len ? as->data_h : 0; + scsi_datap = scsi_datap_org = as->len ? as->data : 0; swb.spt.DataIn = (as->flags & 1) ? SCSI_IOCTL_DATA_IN : SCSI_IOCTL_DATA_OUT; for (i = 0; i < as->cmd_len; i++) swb.spt.Cdb[i] = as->cmd[i]; diff --git a/scsi.cpp b/scsi.cpp index 39db30da..78f1a658 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -409,7 +409,7 @@ void scsi_emulate_cmd(struct scsi_data *sd) as.flags &= ~1; as.sense_len = 32; as.cmd_len = sd->cmd_len; - as.data_h = sd->buffer; + as.data = sd->buffer; as.len = sd->direction < 0 ? DEVICE_SCSI_BUFSIZE : sd->data_len; sys_command_scsi_direct_native(sd->nativescsiunit, -1, &as); sd->status = as.status; diff --git a/scsiemul.cpp b/scsiemul.cpp index bc10030f..7dbe0937 100644 --- a/scsiemul.cpp +++ b/scsiemul.cpp @@ -448,7 +448,7 @@ static int command_read(TrapContext *ctx, struct devstruct *dev, uaecptr data, u uae_u8 buffer[4096]; if (!sys_command_read (dev->unitnum, buffer, offset, 1)) return 20; - memcpyha_safe (data, buffer, blocksize); + trap_memcpyha_safe(ctx, data, buffer, blocksize); data += blocksize; offset++; length--; @@ -464,7 +464,7 @@ static int command_write(TrapContext *ctx, struct devstruct *dev, uaecptr data, while (length > 0) { uae_u8 buffer[4096]; int err; - memcpyah_safe (buffer, data, blocksize); + trap_memcpyah_safe(ctx, buffer, data, blocksize); err = sys_command_write (dev->unitnum, buffer, offset, 1); if (!err) return 20; @@ -498,20 +498,21 @@ static int command_cd_read(TrapContext *ctx, struct devstruct *dev, uaecptr data } if (startoffset > 0) { len = blocksize - startoffset; - if (len > length) len = length; - memcpyha_safe (data, temp + startoffset, len); + if (len > length) + len = length; + trap_memcpyha_safe(ctx, data, temp + startoffset, len); length -= len; data += len; startoffset = 0; *io_actual += len; } else if (length >= blocksize) { len = blocksize; - memcpyha_safe (data, temp, len); + trap_memcpyha_safe(ctx, data, temp, len); length -= len; data += len; *io_actual += len; } else { - memcpyha_safe (data, temp, length); + trap_memcpyha_safe(ctx, data, temp, length); *io_actual += length; length = 0; } @@ -797,11 +798,11 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf, if (sys_command_cd_toc (dev->di.unitnum, &toc)) { if (io_offset == 0 && io_length > 0) { int pos = toc.lastaddress; - put_byte (io_data, toc.first_track); - put_byte (io_data + 1, toc.last_track); + trap_put_byte(ctx, io_data, toc.first_track); + trap_put_byte(ctx, io_data + 1, toc.last_track); if (msf) pos = lsn2msf (pos); - put_long (io_data + 2, pos); + trap_put_long(ctx, io_data + 2, pos); io_offset++; io_length--; io_data += 6; @@ -810,11 +811,11 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf, for (int i = toc.first_track_offset; i < toc.last_track_offset && io_length > 0; i++) { if (io_offset == toc.toc[i].point) { int pos = toc.toc[i].paddress; - put_byte (io_data, (toc.toc[i].control << 4) | toc.toc[i].adr); - put_byte (io_data + 1, toc.toc[i].point); + trap_put_byte(ctx, io_data, (toc.toc[i].control << 4) | toc.toc[i].adr); + trap_put_byte(ctx, io_data + 1, toc.toc[i].point); if (msf) pos = lsn2msf (pos); - put_long (io_data + 2, pos); + trap_put_long(ctx, io_data + 2, pos); io_offset++; io_length--; io_data += 6; @@ -847,6 +848,7 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf, { uae_u16 status = 0; struct cd_toc_head toc; + uae_u8 cdinfo[34] = { 0 }; uae_u8 subq[SUBQ_SIZE] = { 0 }; sys_command_cd_qcode (dev->di.unitnum, subq); status |= 1 << 0; // door closed @@ -863,31 +865,32 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf, status |= 1 << 4; // data track } } - put_word (io_data + 0, 75); // PlaySpeed - put_word (io_data + 2, 1200); // ReadSpeed (randomly chose 16x) - put_word (io_data + 4, 1200); // ReadXLSpeed - put_word (io_data + 6, dev->configblocksize); // SectorSize - put_word (io_data + 8, -1); // XLECC - put_word (io_data + 10, 0); // EjectReset - put_word (io_data + 12, 0); // Reserved * 4 - put_word (io_data + 14, 0); - put_word (io_data + 16, 0); - put_word (io_data + 18, 0); - put_word (io_data + 20, 1200); // MaxSpeed - put_word (io_data + 22, 0xffff); // AudioPrecision (volume) - put_word (io_data + 24, status); // Status - put_word (io_data + 26, 0); // Reserved2 * 4 - put_word (io_data + 28, 0); - put_word (io_data + 30, 0); - put_word (io_data + 32, 0); + put_word_host(cdinfo + 0, 75); // PlaySpeed + put_word_host(cdinfo + 2, 1200); // ReadSpeed (randomly chose 16x) + put_word_host(cdinfo + 4, 1200); // ReadXLSpeed + put_word_host(cdinfo + 6, dev->configblocksize); // SectorSize + put_word_host(cdinfo + 8, -1); // XLECC + put_word_host(cdinfo + 10, 0); // EjectReset + put_word_host(cdinfo + 12, 0); // Reserved * 4 + put_word_host(cdinfo + 14, 0); + put_word_host(cdinfo + 16, 0); + put_word_host(cdinfo + 18, 0); + put_word_host(cdinfo + 20, 1200); // MaxSpeed + put_word_host(cdinfo + 22, 0xffff); // AudioPrecision (volume) + put_word_host(cdinfo + 24, status); // Status + put_word_host(cdinfo + 26, 0); // Reserved2 * 4 + put_word_host(cdinfo + 28, 0); + put_word_host(cdinfo + 30, 0); + put_word_host(cdinfo + 32, 0); io_actual = 34; + trap_put_bytes(ctx, cdinfo, io_data, io_actual); } break; case CD_CONFIG: { - while (get_long (io_data) != TAG_DONE) { - uae_u32 tag = get_long (io_data); - uae_u32 data = get_long (io_data + 4); + while (trap_get_long(ctx, io_data) != TAG_DONE) { + uae_u32 tag = trap_get_long(ctx, io_data); + uae_u32 data = trap_get_long(ctx, io_data + 4); if (tag == 4) { // TAGCD_SECTORSIZE if (data == 2048 || data == 2336 || data == 2352) @@ -947,19 +950,21 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf, uae_u8 subq[SUBQ_SIZE]; if (sys_command_cd_qcode (dev->di.unitnum, subq)) { if (subq[1] == AUDIO_STATUS_IN_PROGRESS || subq[1] == AUDIO_STATUS_PAUSED) { - put_byte (io_data + 0, subq[4 + 0]); - put_byte (io_data + 1, frombcd (subq[4 + 1])); - put_byte (io_data + 2, frombcd (subq[4 + 2])); - put_byte (io_data + 3, subq[4 + 6]); + uae_u8 subqdata[12]; + put_byte_host(subqdata + 0, subq[4 + 0]); + put_byte_host(subqdata + 1, frombcd (subq[4 + 1])); + put_byte_host(subqdata + 2, frombcd (subq[4 + 2])); + put_byte_host(subqdata + 3, subq[4 + 6]); int trackpos = fromlongbcd (subq + 4 + 3); int diskpos = fromlongbcd (subq + 4 + 7); if (command == CD_QCODELSN) { trackpos = msf2lsn (trackpos); diskpos = msf2lsn (diskpos); } - put_long (io_data + 4, trackpos); - put_long (io_data + 8, diskpos); + put_long_host(subqdata + 4, trackpos); + put_long_host(subqdata + 8, diskpos); io_actual = 12; + trap_put_bytes(ctx, subqdata, io_data, io_actual); } else { io_error = IOERR_InvalidState; }