]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CD SCSI emulation new trap support.
authorToni Wilen <twilen@winuae.net>
Wed, 10 Feb 2016 14:26:41 +0000 (16:26 +0200)
committerToni Wilen <twilen@winuae.net>
Wed, 10 Feb 2016 14:26:41 +0000 (16:26 +0200)
blkdev.cpp
include/blkdev.h
od-win32/blkdev_win32_spti.cpp
scsi.cpp
scsiemul.cpp

index be2cfd377042e0aede332f34d8050822c1634911..2d197ae147f8ed6a0cac8c3dee44d197d099778c 100644 (file)
@@ -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;
 }
 
index a27850d2a9a388e57f5bf7b6f93f1625747f768a..fc176aa3dba100fc68ece48e60710029981ae5c2 100644 (file)
@@ -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;
index e1de07e7e45339288e37540272287054355cb2b2..e87cbb7079a6d6b051ae89e0050116bbedf7ea5e 100644 (file)
@@ -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];
index 39db30da9fe84a30cad08509c92e60439a3051fc..78f1a65867c6a0f23d68bb80711f96a525ae223d 100644 (file)
--- 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;
index bc10030f87cfa065470b9aec198a3c4ff9ca53cb..7dbe0937b9eff0eaac19a7e220e840a644ed1d1d 100644 (file)
@@ -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;
                        }