]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
ESP PIO mode FIFO emulation improvements. (Blizzard SCSI Kit II. E-Matrix and Multi...
authorToni Wilen <twilen@winuae.net>
Tue, 21 Jun 2016 13:40:31 +0000 (16:40 +0300)
committerToni Wilen <twilen@winuae.net>
Tue, 21 Jun 2016 13:40:31 +0000 (16:40 +0300)
ncr9x_scsi.cpp
qemuvga/esp.cpp
qemuvga/scsi/esp.h

index 2582754f70249e3f34de737e7dd96f35e97bbd43..4874b81c5e655cdf880ac1b15e9c79194616f295 100644 (file)
@@ -811,6 +811,20 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                                esp_dma_enable(ncr->devobject.lsistate, 1);
                        return;
                }
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230II)) {
+               addr &= 0xffff;
+               if (addr >= 0x20) {
+                       if (addr & 0x10) {
+                               ncr->dma_cnt = 0;
+                               ncr->dma_ptr = 0;
+                       }
+                       ncr->dma_ptr |= (val & 0xff) << ((3 - ncr->dma_cnt) * 8);
+                       ncr->dma_cnt++;
+                       if (ncr->dma_cnt == 4)
+                               esp_dma_enable(ncr->devobject.lsistate, 1);
+                       return;
+               }
+               reg_shift = 1;
        } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
                if (addr >= BLIZZARD_2060_DMA_OFFSET) {
                        //write_log (_T("Blizzard DMA PUT %08x %02X\n"), addr, (uae_u8)val);
@@ -1069,6 +1083,12 @@ static uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                        }
                        return 0;
                }
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230II)) {
+               addr &= 0xffff;
+               if (addr >= 0x20) {
+                       return 0;
+               }
+               reg_shift = 1;
        } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
                if (addr >= BLIZZARD_2060_DMA_OFFSET) {
                        write_log(_T("Blizzard DMA GET %08x\n"), addr);
index 8b972dd53d6ed9d2b8b57aed42a27f70ed3796ee..9fdf3d23a25cc7a433d0b56b53c96b9d97dae0dc 100644 (file)
@@ -225,6 +225,7 @@ static void write_response(ESPState *s)
        // sure wrong buffer is not read.
        s->pio_on = 0;
        s->async_buf = NULL;
+       s->fifo_on = 1;
 
        s->ti_buf[0] = s->status;
     s->ti_buf[1] = 0;
@@ -237,7 +238,7 @@ static void write_response(ESPState *s)
         s->ti_size = 2;
         s->ti_rptr = 0;
         s->ti_wptr = 0;
-        s->rregs[ESP_RFLAGS] = 2;
+        //s->rregs[ESP_RFLAGS] = 2;
     }
     esp_raise_irq(s);
 }
@@ -247,7 +248,7 @@ static void esp_dma_done(ESPState *s)
     s->rregs[ESP_RSTAT] |= STAT_TC;
     s->rregs[ESP_RINTR] = INTR_BS;
     s->rregs[ESP_RSEQ] = 0;
-    s->rregs[ESP_RFLAGS] = 0;
+    //s->rregs[ESP_RFLAGS] = 0;
     s->rregs[ESP_TCLO] = 0;
     s->rregs[ESP_TCMID] = 0;
     s->rregs[ESP_TCHI] = 0;
@@ -336,6 +337,7 @@ void esp_command_complete(SCSIRequest *req, uint32_t status,
 {
        ESPState *s = (ESPState*)req->hba_private;
 
+       s->fifo_on = 0;
     s->ti_size = 0;
     s->dma_left = 0;
        s->dma_pending = 0;
@@ -375,6 +377,8 @@ static int handle_ti(ESPState *s)
 {
     uint32_t dmalen, minlen;
 
+       s->fifo_on = 1;
+
     if (s->dma && !s->dma_enabled) {
         s->dma_cb = handle_ti;
         return 1;
@@ -452,30 +456,38 @@ uint64_t esp_reg_read(void *opaque, uint32_t saddr)
 
     switch (saddr) {
     case ESP_FIFO:
-        if (s->ti_size > 0) {
-            s->ti_size--;
-            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0 || s->pio_on) {
-                /* Data out.  */
-                //write_log("esp: PIO data read not implemented\n");
-                               if (s->async_buf) {
-                       s->rregs[ESP_FIFO] = s->async_buf[s->ti_rptr++];
-                                       s->pio_on = 1;
+               if (s->fifo_on) {
+                       // FIFO can be only read in PIO mode when any transfer command is active.
+                       if (s->ti_size > 0) {
+                               s->ti_size--;
+                               if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0 || s->pio_on) {
+                                       /* Data out.  */
+                                       if (s->async_buf) {
+                                               s->rregs[ESP_FIFO] = s->async_buf[s->ti_rptr++];
+                                               s->pio_on = 1;
+                                       } else {
+                                               s->rregs[ESP_FIFO] = 0;
+                                       }
+                                       if (s->ti_size <= 1 && s->current_req) {
+                                               // last byte is now going to FIFO, transfer ends.
+                                               scsiesp_req_continue(s->current_req);
+                                               // set ti_size back to 1, last byte is now in FIFO.
+                                               s->ti_size = 1;
+                                       } else {
+                                               esp_raise_irq(s);
+                                       }
                                } else {
-                                       s->rregs[ESP_FIFO] = 0;
-                               }
-                               if (s->ti_size == 1 && s->current_req) {
-                                       scsiesp_req_continue(s->current_req);
+                                       s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
+                                       esp_raise_irq(s);
                                }
-            } else {
-                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
-            }
-                       esp_raise_irq(s);
-        }
-        if (s->ti_size == 0) {
-            s->ti_rptr = 0;
-            s->ti_wptr = 0;
-                       s->pio_on = 0;
-        }
+                       }
+                       if (s->ti_size == 0) {
+                               s->ti_rptr = 0;
+                               s->ti_wptr = 0;
+                               s->pio_on = 0;
+                               s->fifo_on = 0;
+                       }
+               }
         break;
     case ESP_RINTR:
         /* Clear sequence step, interrupt register and all status bits
@@ -490,10 +502,10 @@ uint64_t esp_reg_read(void *opaque, uint32_t saddr)
        case ESP_RFLAGS:
        {
                int v;
-               if (s->ti_size >= 7)
-                       v = 31;
+               if (s->ti_size >= 16)
+                       v = 16;
                else
-                       v = (1 << s->ti_size) - 1;
+                       v = s->ti_size;
                return v | (s->rregs[ESP_RSEQ] << 5);
        }
        case ESP_RES4:
@@ -541,6 +553,7 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
             break;
         case CMD_FLUSH:
             //s->ti_size = 0;
+                       s->fifo_on = 0;
             s->rregs[ESP_RINTR] = INTR_FC;
             s->rregs[ESP_RSEQ] = 0;
             s->rregs[ESP_RFLAGS] = 0;
@@ -569,7 +582,7 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
         case CMD_MSGACC:
             s->rregs[ESP_RINTR] = INTR_DC;
             s->rregs[ESP_RSEQ] = 0;
-            s->rregs[ESP_RFLAGS] = 0;
+            //s->rregs[ESP_RFLAGS] = 0;
                        // Masoboshi driver expects phase=0!
                        s->rregs[ESP_RSTAT] &= ~7;
             esp_raise_irq(s);
index 75e1a90df3e7152d35ef0ab82d8dfc017eee48f9..54d9ce544b22ed5bf994bd8733529465801771d9 100644 (file)
@@ -40,6 +40,7 @@ struct ESPState {
     uint32_t dma_counter;
     int dma_enabled;
        int pio_on;
+       int fifo_on;
 
     uint32_t async_len;
     uint8_t *async_buf;