Previous 199869 Revisions Next

r25515 Friday 4th October, 2013 at 02:53:07 UTC by R. Belmont
ncr5380n: better DRQ support, fixed arbitration-in-progress bit [R. Belmont]
[src/mess/machine]ncr5380n.c

trunk/src/mess/machine/ncr5380n.c
r25514r25515
33    ncr5380n.c
44
55    Implementation of the NCR 5380, aka the Zilog Z5380
6
6
77    TODO:
8    - IRQs (Apple doesn't use 'em)
8    - IRQs
99    - Target mode
10
10 
11    40801766 - IIx ROM waiting point for "next read fails"
12 
1113*********************************************************************/
1214
1315#include "emu.h"
r25514r25515
7678void ncr5380n_device::reset_soft()
7779{
7880   state = IDLE;
79   scsi_bus->ctrl_w(scsi_refid, 0, S_ALL); // clear any signals we're driving
81   scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);   // clear any signals we're driving
8082   scsi_bus->ctrl_wait(scsi_refid, S_ALL, S_ALL);
8183   status = 0;
8284   drq = false;
r25514r25515
9597{
9698   UINT32 ctrl = scsi_bus->ctrl_r();
9799
98//  printf("scsi_ctrl_changed: lines now %x\n", ctrl);
100//   printf("scsi_ctrl_changed: lines now %x\n", ctrl);
99101
100/*  if ((ctrl & (S_PHASE_MASK|S_SEL|S_BSY)) != last_phase)
101    {
102        printf("phase now %d, SEL %x BSY %x\n", ctrl & S_PHASE_MASK, ctrl & S_SEL, ctrl & S_BSY);
103        last_phase = (S_PHASE_MASK|S_SEL|S_BSY);
104    }*/
102/*   if ((ctrl & (S_PHASE_MASK|S_SEL|S_BSY)) != last_phase)
103   {
104      printf("phase now %d, REQ %x SEL %x BSY %x\n", ctrl & S_PHASE_MASK, ctrl & S_REQ, ctrl & S_SEL, ctrl & S_BSY);
105      last_phase = (S_PHASE_MASK|S_SEL|S_BSY);
106   }*/
105107
106108   // recalculate phase match
107109   m_busstatus &= ~BAS_PHASEMATCH;
r25514r25515
115117      // if BSY drops or the phase goes mismatch, that terminates the DMA
116118      if ((!(ctrl & S_BSY)) || !(m_busstatus & BAS_PHASEMATCH))
117119      {
118//          printf("BSY dropped or phase mismatch during DMA, ending DMA\n");
120//         printf("BSY dropped or phase mismatch during DMA, ending DMA\n");
119121         m_mode &= ~MODE_DMA;
120122         m_busstatus |= BAS_ENDOFDMA;
121123         drq_clear();
r25514r25515
160162
161163      int win;
162164      for(win=7; win>=0 && !(data & (1<<win)); win--);
163//      printf("data %02x win %02x scsi_id %02x\n", data, win, scsi_id);
165//      printf("arb complete: data %02x win %02x scsi_id %02x\n", data, win, scsi_id);
164166      if(win != scsi_id) {
165167         scsi_bus->data_w(scsi_refid, 0);
166168         scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
r25514r25515
168170         break;
169171      }
170172
171      // arbitration no longer in progress
172      m_icommand &= ~IC_ARBITRATION;
173
174173      state &= STATE_MASK;
175174      step(true);
176175      break;
r25514r25515
212211         break;
213212
214213      m_dmalatch = scsi_bus->data_r();
215      drq_set();
216214      scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
217215      state = (state & STATE_MASK) | (RECV_WAIT_REQ_0 << SUB_SHIFT);
218216      step(false);
r25514r25515
223221         break;
224222      state = state & STATE_MASK;
225223      step(false);
224
225      drq_set();   // raise DRQ now that we've completed
226226      break;
227227
228228   default:
r25514r25515
252252void ncr5380n_device::function_bus_complete()
253253{
254254   state = IDLE;
255//  istatus |= I_FUNCTION|I_BUS;
255//   istatus |= I_FUNCTION|I_BUS;
256256   check_irq();
257257}
258258
259259void ncr5380n_device::function_complete()
260260{
261261   state = IDLE;
262//  istatus |= I_FUNCTION;
262//   istatus |= I_FUNCTION;
263263   check_irq();
264264}
265265
266266void ncr5380n_device::bus_complete()
267267{
268268   state = IDLE;
269//  istatus |= I_BUS;
269//   istatus |= I_BUS;
270270   check_irq();
271271}
272272
r25514r25515
309309   // asserting to drive the data bus?
310310   if ((data & IC_DBUS) && !(m_icommand & IC_DBUS))
311311   {
312//      printf("%s: driving data bus with %02x\n", tag(), m_outdata);
312//      printf("%s: driving data bus with %02x\n", tag(), m_outdata);
313313      scsi_bus->data_w(scsi_refid, m_outdata);
314314      delay(2);
315315   }
r25514r25515
327327         (data & IC_SEL ? S_SEL : 0) |
328328         (data & IC_ATN ? S_ATN : 0);
329329
330//      printf("%s: changing control lines %04x\n", tag(), newdata);
330//      printf("%s: changing control lines %04x\n", tag(), newdata);
331331      scsi_bus->ctrl_w(scsi_refid, newdata, S_RST|S_ACK|S_BSY|S_SEL|S_ATN);
332332   }
333333
r25514r25515
342342
343343WRITE8_MEMBER(ncr5380n_device::mode_w)
344344{
345//  printf("%s: mode_w %02x (%08x)\n", tag(), data, space.device().safe_pc());
345//   printf("%s: mode_w %02x (%08x)\n", tag(), data, space.device().safe_pc());
346346   // arbitration bit being set?
347347   if ((data & MODE_ARBITRATE) && !(m_mode & MODE_ARBITRATE))
348348   {
349      // if SEL is selected and the assert SEL bit in the initiator
349      // if SEL is selected and the assert SEL bit in the initiator
350350      // command register is clear, fail
351351      if ((scsi_bus->ctrl_r() & S_SEL) && !(m_icommand & IC_SEL))
352352      {
353//          printf("arbitration lost, ctrl = %x, m_icommand&IC_SEL = %x\n", scsi_bus->ctrl_r(), m_icommand & IC_SEL);
354         m_icommand &= ~IC_ARBITRATION;
355353         m_icommand |= IC_ARBLOST;
356354      }
357355      else
358356      {
359357         seq = 0;
360//          state = DISC_SEL_ARBITRATION;
358//         state = DISC_SEL_ARBITRATION;
361359         arbitrate();
362360      }
363361   }
364
362   else if (!(data & MODE_ARBITRATE) && (m_mode & MODE_ARBITRATE))
363   {
364      // arbitration in progress bit ONLY clears when the host disables arbitration. (thanks, Zilog Z8530 manual!)
365      // the Apple II High Speed SCSI Card boot code explicitly requires this.
366      m_icommand &= ~ IC_ARBITRATION;   
367   }
365368   m_mode = data;
366369}
367370
368371READ8_MEMBER(ncr5380n_device::command_r)
369372{
370//  logerror("%s: command_r %02x (%08x)\n", tag(), m_tcommand, space.device().safe_pc());
373//   logerror("%s: command_r %02x (%08x)\n", tag(), m_tcommand, space.device().safe_pc());
371374   return m_tcommand;
372375}
373376
374377WRITE8_MEMBER(ncr5380n_device::command_w)
375378{
376//  printf("%s: command_w %02x (%08x)\n", tag(), data, space.device().safe_pc());
379//   printf("%s: command_w %02x (%08x)\n", tag(), data, space.device().safe_pc());
377380   m_tcommand = data;
378381
379382   // recalculate phase match
r25514r25515
387390void ncr5380n_device::arbitrate()
388391{
389392   m_icommand &= ~IC_ARBLOST;
390   m_icommand |= IC_ARBITRATION;
393   m_icommand |= IC_ARBITRATION;   // set in progress flag
391394   state = (state & STATE_MASK) | (ARB_COMPLETE << SUB_SHIFT);
392395   scsi_bus->data_w(scsi_refid, m_outdata);
393396   scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
r25514r25515
407410READ8_MEMBER(ncr5380n_device::status_r)
408411{
409412   UINT32 ctrl = scsi_bus->ctrl_r();
410   UINT8 res = status |
413   UINT8 res = status |
411414      (ctrl & S_RST ? ST_RST : 0) |
412415      (ctrl & S_BSY ? ST_BSY : 0) |
413416      (ctrl & S_REQ ? ST_REQ : 0) |
r25514r25515
416419      (ctrl & S_INP ? ST_IO  : 0) |
417420      (ctrl & S_SEL ? ST_SEL : 0);
418421
419//  printf("%s: status_r %02x (%08x)\n", tag(), res, space.device().safe_pc());
422//   printf("%s: status_r %02x (%08x)\n", tag(), res, space.device().safe_pc());
420423   return res;
421424}
422425
r25514r25515
431434      (ctrl & S_ATN ? BAS_ATN : 0) |
432435      (ctrl & S_ACK ? BAS_ACK : 0);
433436
434//  printf("%s: busandstatus_r %02x (%08x)\n", tag(), res, space.device().safe_pc());
437//   printf("%s: busandstatus_r %02x (%08x)\n", tag(), res, space.device().safe_pc());
435438
436439   return res;
437440}
r25514r25515
444447
445448READ8_MEMBER(ncr5380n_device::indata_r)
446449{
447   return 0;
450   return dma_r();
448451}
449452
450453WRITE8_MEMBER(ncr5380n_device::startdmatargetrx_w)
r25514r25515
459462
460463WRITE8_MEMBER(ncr5380n_device::startdmainitrx_w)
461464{
462//  printf("%02x to start dma initiator Rx\n", data);
465//   printf("%02x to start dma initiator Rx\n", data);
463466   recv_byte();
464467}
465468
r25514r25515
491494
492495void ncr5380n_device::drq_set()
493496{
494   if(!drq)
497   if(!drq)
495498   {
496499      drq = true;
497500      m_busstatus |= BAS_DMAREQUEST;
r25514r25515
501504
502505void ncr5380n_device::drq_clear()
503506{
504   if(drq)
507   if(drq)
505508   {
506509      drq = false;
507510      m_busstatus &= ~BAS_DMAREQUEST;
r25514r25515
543546
544547WRITE8_MEMBER(ncr5380n_device::write)
545548{
549//   printf("%x to 5380 @ %x\n", data, offset);
546550   switch (offset & 7)
547551   {
548552      case 0:
r25514r25515
578582         break;
579583   }
580584}
585

Previous 199869 Revisions Next


© 1997-2024 The MAME Team