OSDN Git Service

[VM][FMTOWNS][SCSI_HOST] Add USE_QUEUED_SCSI_TRANSFER flag, will use queued transfer...
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 18 Mar 2020 07:21:46 +0000 (16:21 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 18 Mar 2020 07:21:46 +0000 (16:21 +0900)
source/src/vm/fmtowns/fmtowns.cpp
source/src/vm/fmtowns/fmtowns.h
source/src/vm/fmtowns/scsi.cpp
source/src/vm/fmtowns/towns_dmac.cpp
source/src/vm/scsi_host.cpp
source/src/vm/scsi_host.h

index 261c069..202f0df 100644 (file)
@@ -310,6 +310,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        //dma->set_context_ch2(printer);
        //dma->set_context_ch3(cdc);
        dma->set_context_ch3(cdc_scsi);
+       dma->set_context_ube1(scsi_host, SIG_SCSI_16BIT_BUS, 0x02);
+
        dma->set_context_child_dma(extra_dma);
        
        floppy->set_context_fdc(fdc);
index 95cd3ce..71be482 100644 (file)
 #define USE_STATE
 #define USE_CPU_I386
 #define HAS_I386
+//#define USE_QUEUED_SCSI_TRANSFER
 
 #include "../../common.h"
 #include "../../fileio.h"
index 2f643e9..632d8e3 100644 (file)
@@ -65,6 +65,7 @@ void SCSI::write_io8(uint32_t addr, uint32_t data)
                        d_host->write_signal(SIG_SCSI_RST, data, CTRL_RST);
                        d_host->write_signal(SIG_SCSI_ATN, data, CTRL_ATN);
                        d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL);
+                       d_host->write_signal(SIG_SCSI_HOST_DMAE, data, CTRL_DMAE);
                }
                break;
        }
index fd296db..aa9bc6e 100644 (file)
@@ -119,6 +119,7 @@ void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data)
        case 0x0f:
                // Note: This is *temporaly* workaround for 16bit transfer mode with 8bit bus.
                // 20200318 K.O
+#if !defined(USE_QUEUED_SCSI_TRANSFER)
                if((dma[selch].is_16bit) && (b16)) {
                        if(creg_set[selch]) {
                                dma[selch].creg <<= 1;
@@ -130,12 +131,13 @@ void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data)
                                dma[selch].bcreg++;
                                bcreg_set[selch] = false;
                        }
+                       }
+#endif
+               if((data & 0x02) == 0) {
+                       out_debug_log(_T("START SCSI DMA MODE=%02X ADDR=%08X COUNT=%04X"),
+                                                 dma[1].mode, (dma[1].areg & 0xffffff) | dma_high_address[1],
+                                                 dma[1].creg);
                }
-//             if((data & 0x02) == 0) {
-//                     out_debug_log(_T("START SCSI DMA MODE=%02X ADDR=%08X COUNT=%04X"),
-//                                               dma[1].mode, (dma[1].areg & 0xffffff) | dma_high_address[1],
-//                                               dma[1].creg);
-//             }
                break;
        default:
                break;
@@ -278,10 +280,10 @@ bool TOWNS_DMAC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
        {
                my_stprintf_s(buffer, buffer_len,
                                          _T("16Bit=%s ADDR_MASK=%08X ADDR_REG=%02X ADDR_WRAP=%02X \n")
-                                         _T("%s\n")
-                                         _T("%s\n")
-                                         _T("%s\n")
-                                         _T("%s\n")
+                                         _T("%s")
+                                         _T("%s")
+                                         _T("%s")
+                                         _T("%s")
                                          , (b16) ? _T("YES") : _T("NO"),
                                          dma_addr_mask,
                                          dma_addr_reg,
index 52745ac..aefef9c 100644 (file)
@@ -36,8 +36,9 @@ void SCSI_HOST::reset()
        set_irq(false);
        set_drq(false);
        if(data_queue != NULL) data_queue->clear();
+       is_dma = false;
 }
-
+/*
 #ifdef SCSI_HOST_WIDE
 void SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data)
 #else
@@ -76,11 +77,23 @@ uint32_t SCSI_HOST::read_dma_io8(uint32_t addr)
        #endif
        return value;
 }
-
-/*
+*/
 void SCSI_HOST::write_dma_io8(uint32_t addr, uint32_t data)
 {
-       data_queue->write(data & 0xff);
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+       if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) {
+               // Data IN/OUT
+               data_queue->write(data & 0xff);
+               return;
+       }
+#endif
+       write_signals(&outputs_dat, data);
+       #ifdef SCSI_HOST_AUTO_ACK
+               // set ack to clear req signal immediately
+       if((bsy_status) && !(io_status)) {
+               this->write_signal(SIG_SCSI_ACK, 1, 1);
+       }
+       #endif
 }
 void SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data)
 {
@@ -88,12 +101,25 @@ void SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data)
                write_dma_io8(addr, data);
                return;
        }
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+       if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) {
+               // Data IN/OUT
 #if !defined(SCSI_HOST_WIDE)
-       data_queue->write(data & 0xff);
-       data_queue->write((data >> 8) & 0xff);
+               data_queue->write(data & 0xff);
+               data_queue->write((data >> 8) & 0xff);
 #else  
-       data_queue->write(data & 0xffff);
-#endif 
+               data_queue->write(data & 0xffff);
+#endif
+               return;
+       }
+#endif
+       write_signals(&outputs_dat, data);
+       #ifdef SCSI_HOST_AUTO_ACK
+               // set ack to clear req signal immediately
+       if((bsy_status) && !(io_status)) {
+               this->write_signal(SIG_SCSI_ACK, 1, 1);
+       }
+       #endif
 }
 uint32_t SCSI_HOST::read_dma_io16(uint32_t addr)
 {
@@ -101,22 +127,50 @@ uint32_t SCSI_HOST::read_dma_io16(uint32_t addr)
                return read_dma_io8(addr);
        }
        uint32_t val;
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+       if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) {
+               // Data IN/OUT
 #if !defined(SCSI_HOST_WIDE)
-       val = data_queue->read() & 0xff;
-       val = val << 8;
-       val = val | (data_queue->read() & 0xff);
+               val = data_queue->read() & 0xff;
+               val = val << 8;
+               val = val | (data_queue->read() & 0xff);
 #else
-       val = data_queue->read() & 0xffff;
+               val = data_queue->read() & 0xffff;
+#endif
+               return val;
+       }
 #endif
+       val = data_reg;
+       #ifdef SCSI_HOST_AUTO_ACK
+               // set ack to clear req signal immediately
+       if((bsy_status) && (io_status)) {
+               this->write_signal(SIG_SCSI_ACK, 1, 1);
+       }
+       #endif
        return val;
 }
 
 uint32_t SCSI_HOST::read_dma_io8(uint32_t addr)
 {
-       uint32_t val = data_queue->read() & 0xff;
+       uint32_t val;
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+       if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) {
+//     if(!(data_queue->empty())) {
+               // Data IN/OUT
+               val = data_queue->read() & 0xff;
+               return val;
+       }
+#endif
+       val = data_reg;
+       #ifdef SCSI_HOST_AUTO_ACK
+               // set ack to clear req signal immediately
+       if((bsy_status) && (io_status)) {
+               this->write_signal(SIG_SCSI_ACK, 1, 1);
+       }
+       #endif
        return val;
 }
-*/
+
 
 void SCSI_HOST::event_callback(int id, int err)
 {
@@ -169,7 +223,7 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask)
                        this->out_debug_log(_T("[SCSI_HOST] RST = %d\n"), (data & mask) ? 1 : 0);
                #endif
                write_signals(&outputs_rst, (data & mask) ? 0xffffffff : 0);
-               if(data_queue != NULL) {
+               if((data_queue != NULL) && ((data & mask) != 0)) {
                        data_queue->clear();
                }
                break;
@@ -213,53 +267,53 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask)
                        if(!prev_status && req_status) {
                                // L -> H
 //                             if(bsy_status) {
-                               /*
-                               if(((cd_status) && !(msg_status) && (io_status)) ||
-                                  (!(cd_status) && !(msg_status) && !(io_status))) { // STATUS or DATA_OUT
-                                       #if defined(SCSI_HOST_WIDE)
-                                       data_queue->write(data_reg & 0xffff);
-                                       #else
-                                       data_queue->write(data_reg & 0xff);
-                                       #endif
-                                       register_event(this, EVENT_DELAY_READ_ACK, 0.5, false, NULL);
-                               }
-                               */
                                if(!cd_status && !msg_status) {
                                        // data phase
-                                       #if 0
-                                       if(is_16bit) {
-                                               if((data_queue->count() & 1) == 0) {
-                                                       set_drq(true);
+                                       
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+                                       if((bsy_status) && (io_status) && (is_dma)) {
+                                               data_queue->write(data_reg);
+//                                             out_debug_log(_T("READ DATA=%02X"), data_reg, data_queue->count());
+                                               #ifdef SCSI_HOST_AUTO_ACK
+                                               this->write_signal(SIG_SCSI_ACK, 1, 1);
+                                               #endif
+                                       }
+#endif
+                                       
+                                       #if !defined(SCSI_HOST_WIDE) && defined(USE_QUEUED_SCSI_TRANSFER)
+                                       bool do_drq = false;
+                                       if((io_status)) {
+                                               // READ FROM TARGET
+                                               if(!(data_queue->empty())) {
+                                                       do_drq = true;
                                                }
                                        } else {
-                                               set_drq(true);
+                                               // WRITE TO TARGET
+                                               if((data_queue->empty())) {
+                                                       do_drq = true;
+                                               }
                                        }
+                                       if(do_drq) set_drq(true);
                                        #else
                                        set_drq(true);
                                        #endif
                                        access = true;
+#if defined(USE_QUEUED_SCSI_TRANSFER)
+                                       if((bsy_status) && !(io_status) && (is_dma)) {
+                                               if(!(data_queue->empty())) {
+                                                       write_signals(&outputs_dat, data_queue->read());
+                                                       #ifdef SCSI_HOST_AUTO_ACK
+                                                               this->write_signal(SIG_SCSI_ACK, 1, 1);
+                                                       #endif
+                                               }
+                                       }
+#endif
                                } else if(cd_status) {
                                        // command/status/message phase
+                                       if(!(data_queue->empty())) data_queue->clear();
                                        set_irq(true);
                                }
 //                             }
-                               /*
-                               if(((cd_status) && !(msg_status) && !(io_status)) ||
-                                  (!(cd_status) && !(msg_status) && (io_status))) { // COMMAND or DATA_IN
-                                       uint32_t val;
-                                       if(!(data_queue->empty())) {
-                                               val = data_queue->read();
-                                               data_reg = val;
-                                               #if defined(SCSI_HOST_WIDE)
-                                                       val = val & 0xffff;
-                                               #else
-                                                       val = val & 0xff;
-                                               #endif
-                                               write_signals(&outputs_dat, val);
-                                               register_event(this, EVENT_DELAY_WRITE_ACK, 0.5, false, NULL);
-                                       }
-                               }
-                               */                              
                        } else if(prev_status && !req_status) {
                                // H -> L
                                set_drq(false);
@@ -275,6 +329,9 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask)
                        write_signals(&outputs_req, req_status ? 0xffffffff : 0);
                }
                break;
+       case SIG_SCSI_HOST_DMAE:
+               is_dma = ((data & mask) != 0) ? true : false;
+               break;
        case SIG_SCSI_16BIT_BUS:
                is_16bit = ((data & mask) != 0) ? true : false;
                break;
@@ -349,6 +406,7 @@ bool SCSI_HOST::process_state(FILEIO* state_fio, bool loading)
        if(!data_queue->process_state((void *)state_fio, loading)) {
                return false;
        }
+       state_fio->StateValue(is_dma);
        return true;
 }
 
index 30129c0..9bb0e17 100644 (file)
@@ -17,6 +17,7 @@
 //class VM;
 class FIFO;
 
+#define SIG_SCSI_HOST_DMAE 1
 class SCSI_HOST : public DEVICE
 {
 protected: // Make pcotected because TOWNS's DMAC may transfer 16bit around SCSI.
@@ -40,6 +41,7 @@ protected: // Make pcotected because TOWNS's DMAC may transfer 16bit around SCSI
        uint32_t bsy_status, cd_status, io_status, msg_status, req_status, ack_status;
        bool access;
        bool is_16bit;
+       bool is_dma;
        
        virtual void __FASTCALL set_irq(bool value);
        virtual void __FASTCALL set_drq(bool value);
@@ -72,7 +74,7 @@ public:
        virtual void initialize();
        virtual void release();
        virtual void event_callback(int id, int err);
-
+/*
 #ifdef SCSI_HOST_WIDE
        virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data);
        virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr);
@@ -80,12 +82,12 @@ public:
        virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data);
        virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr);
 #endif
-/*
+*/
        virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data);
        virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data);
        virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr);
        virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr);
-*/     
+       
        virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
        virtual uint32_t __FASTCALL read_signal(int id);
        virtual bool process_state(FILEIO* state_fio, bool loading);