Previous 15994 Revisions Next

r9037 Sunday 5th September, 2010 at 00:43:06 UTC by R. Belmont
Converted NCR5380 to modern device, adapted Mac driver to match.
[src/mess/drivers]mac.c
[src/mess/includes]mac.h
[src/mess/machine]mac.c ncr5380.c ncr5380.h

src/mess/machine/ncr5380.c
r9036r9037
33 *
44 * NCR 5380 SCSI controller, as seen in many 680x0 Macs,
55 * official Apple add-on cards for the Apple II series,
6 * and probably some PC cards as well.
6 * and probably some PC and Amiga cards as well.
77 *
8 * Preliminary emulation by R. Belmont.
8 * Emulation by R. Belmont.
99 *
1010 * References:
1111 * Zilog 5380 manual
12 * "Inside Macintosh: Devices" (online at http://www.manolium.org/dev/techsupport/insidemac/Devices/Devices-2.html )
12 * "Inside Macintosh: Devices" (formerly online at http://www.manolium.org/dev/techsupport/insidemac/Devices/Devices-2.html )
1313 *
1414 * NOTES:
1515 * This implementation is tied closely to the drivers found in the Mac Plus ROM and the routines in Mac
16 * System 6.0.3 that it patches out the ROM traps with.  While attempts have been made to
16 * System 6 and 7 that it patches out the ROM traps with.  While attempts have been made to
1717 * have the behavior work according to the manual and not the specific Apple driver code,
1818 * there are almost certainly areas where that is true.  In particular, IRQs are not implemented
1919 * as they are unused on the Mac Plus.
r9036r9037
2222
2323#include "emu.h"
2424#include "ncr5380.h"
25#include "machine/devhelpr.h"
2526
2627#define VERBOSE   (0)
2728
r9036r9037
4950   "DMA initiator rec"
5051};
5152
52static SCSIInstance *devices[8];   // SCSI IDs 0-7
53static const struct NCR5380interface *intf;
54
55static UINT8 n5380_Registers[8];
56static UINT8 last_id;
57static UINT8 n5380_Command[32];
58static INT32 cmd_ptr, d_ptr, d_limit, next_req_flag;
59static UINT8 n5380_Data[512];
60
6153// get the length of a SCSI command based on it's command byte type
6254static int get_cmd_len(int cbyte)
6355{
r9036r9037
7466   return 6;
7567}
7668
77WRITE8_HANDLER(ncr5380_w)
69//**************************************************************************
70//  DEVICE CONFIGURATION
71//**************************************************************************
72
73ncr5380_device_config::ncr5380_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
74    : device_config(mconfig, static_alloc_device_config, "5380 SCSI", tag, owner, clock)
7875{
76}
77
78device_config *ncr5380_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
79{
80   return global_alloc(ncr5380_device_config(mconfig, tag, owner, clock));
81}
82
83device_t *ncr5380_device_config::alloc_device(running_machine &machine) const
84{
85   return auto_alloc(&machine, ncr5380_device(machine, *this));
86}
87
88//-------------------------------------------------
89//  device_config_complete - perform any
90//  operations now that the configuration is
91//  complete
92//-------------------------------------------------
93
94void ncr5380_device_config::device_config_complete()
95{
96   // inherit a copy of the static data
97   const NCR5380interface *intf = reinterpret_cast<const NCR5380interface *>(static_config());
98   if (intf != NULL)
99      *static_cast<NCR5380interface *>(this) = *intf;
100
101   // or initialize to defaults if none provided
102   else
103   {
104      scsidevs = NULL;
105      irq_callback = NULL;
106   }
107}
108
109//**************************************************************************
110//  LIVE DEVICE
111//**************************************************************************
112
113const device_type NCR5380 = ncr5380_device_config::static_alloc_device_config;
114
115//-------------------------------------------------
116//  ncr5380_device - constructor/destructor
117//-------------------------------------------------
118
119ncr5380_device::ncr5380_device(running_machine &_machine, const ncr5380_device_config &config)
120    : device_t(_machine, config),
121      m_config(config)
122{
123}
124
125//-------------------------------------------------
126//  device_start - device-specific startup
127//-------------------------------------------------
128
129void ncr5380_device::device_start()
130{
131   int i;
132
133   memset(m_5380_Registers, 0, sizeof(m_5380_Registers));
134   memset(m_5380_Data, 0, sizeof(m_5380_Data));
135   memset(m_scsi_devices, 0, sizeof(m_scsi_devices));
136
137   m_next_req_flag = 0;
138
139   // try to open the devices
140   for (i = 0; i < m_config.scsidevs->devs_present; i++)
141   {
142      SCSIAllocInstance( machine,
143            m_config.scsidevs->devices[i].scsiClass,
144            &m_scsi_devices[m_config.scsidevs->devices[i].scsiID],
145            m_config.scsidevs->devices[i].diskregion );
146   }
147
148   state_save_register_device_item_array(this, 0, m_5380_Registers);
149   state_save_register_device_item_array(this, 0, m_5380_Command);
150   state_save_register_device_item_array(this, 0, m_5380_Data);
151   state_save_register_device_item(this, 0, m_last_id);
152   state_save_register_device_item(this, 0, m_cmd_ptr);
153   state_save_register_device_item(this, 0, m_d_ptr);
154   state_save_register_device_item(this, 0, m_d_limit);
155   state_save_register_device_item(this, 0, m_next_req_flag);
156}
157
158//-------------------------------------------------
159//  device_reset - device-specific reset
160//-------------------------------------------------
161
162void ncr5380_device::device_reset()
163{
164   memset(m_5380_Registers, 0, sizeof(m_5380_Registers));
165   memset(m_5380_Data, 0, sizeof(m_5380_Data));
166   memset(m_scsi_devices, 0, sizeof(m_scsi_devices));
167
168   m_next_req_flag = 0;
169   m_cmd_ptr = 0;
170   m_d_ptr = 0;
171   m_d_limit = 0;
172   m_last_id = 0;
173}
174
175//-------------------------------------------------
176//  device_stop - device-specific stop/shutdown
177//-------------------------------------------------
178void ncr5380_device::device_stop()
179{
180   int i;
181
182   // clean up the devices
183   for (i = 0; i < m_config.scsidevs->devs_present; i++)
184   {
185      SCSIDeleteInstance( m_scsi_devices[m_config.scsidevs->devices[i].scsiID] );
186   }
187}
188
189//-------------------------------------------------
190//  Public API
191//-------------------------------------------------
192READ8_DEVICE_HANDLER_TRAMPOLINE(ncr5380, ncr5380_read_reg)
193{
79194   int reg = offset & 7;
195   UINT8 rv = 0;
80196
197   switch( reg )
198   {
199      case R5380_CURDATA:
200      case R5380_INPUTDATA:
201         rv = m_5380_Registers[reg];
202
203         // if we're in the data transfer phase or DMA, readback device data instead
204         if (((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x04) || (m_5380_Registers[R5380_BUSSTATUS] & 0x40))
205         {
206            rv = m_5380_Data[m_d_ptr];
207
208            // if the limit's less than 512, only read "limit" bytes
209            if (m_d_limit < 512)
210            {
211               if (m_d_ptr < (m_d_limit-1))
212               {
213                  m_d_ptr++;
214               }
215               else
216               {
217                  m_next_req_flag = 1;
218               }
219            }
220            else
221            {
222               if (m_d_ptr < 511)
223               {
224                  m_d_ptr++;
225               }
226               else
227               {
228                  m_d_limit -= 512;
229                  m_d_ptr = 0;
230
231                  m_next_req_flag = 1;
232
233                  // don't issue a "false" read
234                  if (m_d_limit > 0)
235                  {
236                     ncr5380_read_data((m_d_limit < 512) ? m_d_limit : 512, m_5380_Data);
237                  }
238                  else
239                  {
240                     // if this is DMA, signal DMA end
241                     if (m_5380_Registers[R5380_BUSSTATUS] & 0x40)
242                     {
243                        m_5380_Registers[R5380_BUSSTATUS] |= 0x80;
244                     }
245
246                     // drop /REQ
247                     m_5380_Registers[R5380_BUSSTATUS] &= ~0x20;
248
249                     // clear phase match
250                     m_5380_Registers[R5380_BUSANDSTAT] &= ~0x08;
251                  }
252               }
253            }
254
255         }
256         break;
257
258      default:
259         rv = m_5380_Registers[reg];
260
261         // temporarily drop /REQ
262         if ((reg == R5380_BUSSTATUS) && (m_next_req_flag))
263         {
264            rv &= ~0x20;
265            m_next_req_flag = 0;
266         }
267         break;
268   }
269
81270   if (VERBOSE)
82      logerror("NCR5380: %02x to %s (reg %d) [PC=%x]\n", data, wnames[reg], reg, cpu_get_pc(space->machine->firstcpu));
271      logerror("NCR5380: read %s (reg %d) = %02x [PC=%x]\n", rnames[reg], reg, rv, cpu_get_pc(machine->firstcpu));
83272
273   return rv;
274}
275
276WRITE8_DEVICE_HANDLER_TRAMPOLINE(ncr5380, ncr5380_write_reg)
277{
278   int reg = offset & 7;
279
280   if (VERBOSE)
281      logerror("NCR5380: %02x to %s (reg %d) [PC=%x]\n", data, wnames[reg], reg, cpu_get_pc(machine->firstcpu));
282
84283   switch( reg )
85284   {
86285      case R5380_OUTDATA:
87286         // if we're in the command phase, collect the command bytes
88         if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
287         if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
89288         {
90            n5380_Command[cmd_ptr++] = data;
289            m_5380_Command[m_cmd_ptr++] = data;
91290         }
92291
93292         // if we're in the select phase, this is the target id
94         if (n5380_Registers[R5380_INICOMMAND] == 0x04)
293         if (m_5380_Registers[R5380_INICOMMAND] == 0x04)
95294         {
96295            data &= 0x7f;   // clear the high bit
97296            if (data == 0x40)
98297            {
99               last_id = 6;
298               m_last_id = 6;
100299            }
101300            else if (data == 0x20)
102301            {
103               last_id = 5;
302               m_last_id = 5;
104303            }
105304            else if (data == 0x10)
106305            {
107               last_id = 4;
306               m_last_id = 4;
108307            }
109308            else if (data == 0x08)
110309            {
111               last_id = 3;
310               m_last_id = 3;
112311            }
113312            else if (data == 0x04)
114313            {
115               last_id = 2;
314               m_last_id = 2;
116315            }
117316            else if (data == 0x02)
118317            {
119               last_id = 1;
318               m_last_id = 1;
120319            }
121320            else if (data == 0x01)
122321            {
123               last_id = 0;
322               m_last_id = 0;
124323            }
125324         }
126325
127326         // if this is a write, accumulate accordingly
128         if (((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x00) && (n5380_Registers[R5380_INICOMMAND] == 1))
327         if (((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x00) && (m_5380_Registers[R5380_INICOMMAND] == 1))
129328         {
130            n5380_Data[d_ptr] = data;
329            m_5380_Data[m_d_ptr] = data;
131330
132331            // if we've hit a sector, flush
133            if (d_ptr == 511)
332            if (m_d_ptr == 511)
134333            {
135               ncr5380_write_data(512, &n5380_Data[0]);
334               ncr5380_write_data(512, &m_5380_Data[0]);
136335
137               d_limit -= 512;
138               d_ptr = 0;
336               m_d_limit -= 512;
337               m_d_ptr = 0;
139338
140339               // no more data?  set DMA END flag
141               if (d_limit <= 0)
340               if (m_d_limit <= 0)
142341               {
143                  n5380_Registers[R5380_BUSANDSTAT] = 0xc8;
342                  m_5380_Registers[R5380_BUSANDSTAT] = 0xc8;
144343               }
145344            }
146345            else
147346            {
148               d_ptr++;
347               m_d_ptr++;
149348            }
150349
151350            // make sure we don't upset the status readback
r9036r9037
157356         if (data == 0)   // dropping the bus
158357         {
159358            // make sure it's not busy
160            n5380_Registers[R5380_BUSSTATUS] &= ~0x40;
359            m_5380_Registers[R5380_BUSSTATUS] &= ~0x40;
161360
162361            // are we in the command phase?
163            if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
362            if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
164363            {
165364               // is the current command complete?
166               if (get_cmd_len(n5380_Command[0]) == cmd_ptr)
365               if (get_cmd_len(m_5380_Command[0]) == m_cmd_ptr)
167366               {
168367                  if (VERBOSE)
169                     logerror("NCR5380: Command (to ID %d): %x %x %x %x %x %x %x %x %x %x (PC %x)\n", last_id, n5380_Command[0], n5380_Command[1], n5380_Command[2], n5380_Command[3], n5380_Command[4], n5380_Command[5], n5380_Command[6], n5380_Command[7], n5380_Command[8], n5380_Command[9], cpu_get_pc(space->cpu));
368                     logerror("NCR5380: Command (to ID %d): %x %x %x %x %x %x %x %x %x %x (PC %x)\n", m_last_id, m_5380_Command[0], m_5380_Command[1], m_5380_Command[2], m_5380_Command[3], m_5380_Command[4], m_5380_Command[5], m_5380_Command[6], m_5380_Command[7], m_5380_Command[8], m_5380_Command[9], cpu_get_pc(machine->firstcpu));
170369
171                  SCSISetCommand(devices[last_id], &n5380_Command[0], 16);
172                  SCSIExecCommand(devices[last_id], &d_limit);
370                  SCSISetCommand(m_scsi_devices[m_last_id], &m_5380_Command[0], 16);
371                  SCSIExecCommand(m_scsi_devices[m_last_id], &m_d_limit);
173372
174373                  if (VERBOSE)
175                     logerror("NCR5380: Command returned %d bytes\n",  d_limit);
374                     logerror("NCR5380: Command returned %d bytes\n",  m_d_limit);
176375
177                  d_ptr = 0;
376                  m_d_ptr = 0;
178377
179378                  // is data available?
180                  if (d_limit > 0)
379                  if (m_d_limit > 0)
181380                  {
182381                     // make sure for transfers under 512 bytes that we always pad with a zero
183                     if (d_limit < 512)
382                     if (m_d_limit < 512)
184383                     {
185                        n5380_Data[d_limit] = 0;
384                        m_5380_Data[m_d_limit] = 0;
186385                     }
187386
188387                     // read back the amount available, or 512 bytes, whichever is smaller
189                     ncr5380_read_data((d_limit < 512) ? d_limit : 512, n5380_Data);
388                     ncr5380_read_data((m_d_limit < 512) ? m_d_limit : 512, m_5380_Data);
190389
191390                     // raise REQ to indicate data is available
192                     n5380_Registers[R5380_BUSSTATUS] |= 0x20;
391                     m_5380_Registers[R5380_BUSSTATUS] |= 0x20;
193392                  }
194393               }
195394            }
r9036r9037
201400            // if the device exists, make the bus busy.
202401            // otherwise don't.
203402
204            if (devices[last_id])
403            if (m_scsi_devices[m_last_id])
205404            {
206405               if (VERBOSE)
207                  logerror("NCR5380: Giving the bus for ID %d\n", last_id);
208               n5380_Registers[R5380_BUSSTATUS] |= 0x40;
406                  logerror("NCR5380: Giving the bus for ID %d\n", m_last_id);
407               m_5380_Registers[R5380_BUSSTATUS] |= 0x40;
209408            }
210409            else
211410            {
212411               if (VERBOSE)
213                  logerror("NCR5380: Rejecting the bus for ID %d\n", last_id);
214               n5380_Registers[R5380_BUSSTATUS] &= ~0x40;
412                  logerror("NCR5380: Rejecting the bus for ID %d\n", m_last_id);
413               m_5380_Registers[R5380_BUSSTATUS] &= ~0x40;
215414            }
216415         }
217416
218417         if (data == 1)   // data bus (prelude to command?)
219418         {
220419            // raise REQ
221            n5380_Registers[R5380_BUSSTATUS] |= 0x20;
420            m_5380_Registers[R5380_BUSSTATUS] |= 0x20;
222421         }
223422
224423         if (data & 0x10)   // ACK drops REQ
225424         {
226425            // drop REQ
227            n5380_Registers[R5380_BUSSTATUS] &= ~0x20;
426            m_5380_Registers[R5380_BUSSTATUS] &= ~0x20;
228427         }
229428         break;
230429
r9036r9037
232431         if (data == 2)   // DMA
233432         {
234433            // put us in DMA mode
235            n5380_Registers[R5380_BUSANDSTAT] |= 0x40;
434            m_5380_Registers[R5380_BUSANDSTAT] |= 0x40;
236435         }
237436
238437         if (data == 1)   // arbitrate?
239438         {
240            n5380_Registers[R5380_INICOMMAND] |= 0x40;   // set arbitration in progress
241            n5380_Registers[R5380_INICOMMAND] &= ~0x20;   // clear "lost arbitration"
439            m_5380_Registers[R5380_INICOMMAND] |= 0x40;   // set arbitration in progress
440            m_5380_Registers[R5380_INICOMMAND] &= ~0x20;   // clear "lost arbitration"
242441         }
243442
244443         if (data == 0)
245444         {
246445            // drop DMA mode
247            n5380_Registers[R5380_BUSANDSTAT] &= ~0x40;
446            m_5380_Registers[R5380_BUSANDSTAT] &= ~0x40;
248447         }
249448         break;
250449
251450      case R5380_TARGETCMD:
252451         // sync the bus phase with what was just written
253         n5380_Registers[R5380_BUSSTATUS] &= ~0x1c;
254         n5380_Registers[R5380_BUSSTATUS] |= (data & 7)<<2;
452         m_5380_Registers[R5380_BUSSTATUS] &= ~0x1c;
453         m_5380_Registers[R5380_BUSSTATUS] |= (data & 7)<<2;
255454
256455         // and set the "phase match" flag
257         n5380_Registers[R5380_BUSANDSTAT] |= 0x08;
456         m_5380_Registers[R5380_BUSANDSTAT] |= 0x08;
258457
259458         // and set /REQ
260         n5380_Registers[R5380_BUSSTATUS] |= 0x20;
459         m_5380_Registers[R5380_BUSSTATUS] |= 0x20;
261460
262461         // if we're entering the command phase, start accumulating the data
263         if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
462         if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08)
264463         {
265            cmd_ptr = 0;
464            m_cmd_ptr = 0;
266465         }
267466         break;
268467
r9036r9037
270469         break;
271470   }
272471
273   n5380_Registers[reg] = data;
472   m_5380_Registers[reg] = data;
274473
275474   // note: busandstat overlaps startdma, so we need to do this here!
276475   if (reg == R5380_STARTDMA)
277476   {
278      n5380_Registers[R5380_BUSANDSTAT] = 0x48;
477      m_5380_Registers[R5380_BUSANDSTAT] = 0x48;
279478   }
280479}
281480
282READ8_HANDLER(ncr5380_r)
283{
284   int reg = offset & 7;
285   UINT8 rv = 0;
286481
287   switch( reg )
288   {
289      case R5380_CURDATA:
290      case R5380_INPUTDATA:
291         rv = n5380_Registers[reg];
292
293         // if we're in the data transfer phase or DMA, readback device data instead
294         if (((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x04) || (n5380_Registers[R5380_BUSSTATUS] & 0x40))
295         {
296            rv = n5380_Data[d_ptr];
297
298            // if the limit's less than 512, only read "limit" bytes
299            if (d_limit < 512)
300            {
301               if (d_ptr < (d_limit-1))
302               {
303                  d_ptr++;
304               }
305               else
306               {
307                  next_req_flag = 1;
308               }
309            }
310            else
311            {
312               if (d_ptr < 511)
313               {
314                  d_ptr++;
315               }
316               else
317               {
318                  d_limit -= 512;
319                  d_ptr = 0;
320
321                  next_req_flag = 1;
322
323                  // don't issue a "false" read
324                  if (d_limit > 0)
325                  {
326                     ncr5380_read_data((d_limit < 512) ? d_limit : 512, n5380_Data);
327                  }
328                  else
329                  {
330                     // if this is DMA, signal DMA end
331                     if (n5380_Registers[R5380_BUSSTATUS] & 0x40)
332                     {
333                        n5380_Registers[R5380_BUSSTATUS] |= 0x80;
334                     }
335
336                     // drop /REQ
337                     n5380_Registers[R5380_BUSSTATUS] &= ~0x20;
338
339                     // clear phase match
340                     n5380_Registers[R5380_BUSANDSTAT] &= ~0x08;
341                  }
342               }
343            }
344
345         }
346         break;
347
348      default:
349         rv = n5380_Registers[reg];
350
351         // temporarily drop /REQ
352         if ((reg == R5380_BUSSTATUS) && (next_req_flag))
353         {
354            rv &= ~0x20;
355            next_req_flag = 0;
356         }
357         break;
358   }
359
360   if (VERBOSE)
361      logerror("NCR5380: read %s (reg %d) = %02x [PC=%x]\n", rnames[reg], reg, rv, cpu_get_pc(space->machine->firstcpu));
362
363   return rv;
364}
365
366void ncr5380_init( running_machine *machine, const struct NCR5380interface *interface )
482void ncr5380_device::ncr5380_read_data(int bytes, UINT8 *pData)
367483{
368   // save interface pointer for later
369   intf = interface;
370
371   memset(n5380_Registers, 0, sizeof(n5380_Registers));
372   memset(n5380_Data, 0, sizeof(n5380_Data));
373   memset(devices, 0, sizeof(devices));
374
375   next_req_flag = 0;
376   state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Registers);
377   state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Command);
378   state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Data);
379   state_save_register_item(machine, "ncr5380", NULL, 0, last_id);
380   state_save_register_item(machine, "ncr5380", NULL, 0, cmd_ptr);
381   state_save_register_item(machine, "ncr5380", NULL, 0, d_ptr);
382   state_save_register_item(machine, "ncr5380", NULL, 0, d_limit);
383   state_save_register_item(machine, "ncr5380", NULL, 0, next_req_flag);
384}
385
386void ncr5380_scan_devices( running_machine *machine )
387{
388   int i;
389
390   // try to open the devices
391   for (i = 0; i < intf->scsidevs->devs_present; i++)
484   if (m_scsi_devices[m_last_id])
392485   {
393      // if a device wasn't already allocated
394      if (!devices[intf->scsidevs->devices[i].scsiID])
395      {
396         SCSIAllocInstance( machine,
397               intf->scsidevs->devices[i].scsiClass,
398               &devices[intf->scsidevs->devices[i].scsiID],
399               intf->scsidevs->devices[i].diskregion );
400      }
401   }
402}
403
404void ncr5380_exit( const struct NCR5380interface *interface )
405{
406   int i;
407
408   // clean up the devices
409   for (i = 0; i < interface->scsidevs->devs_present; i++)
410   {
411      SCSIDeleteInstance( devices[interface->scsidevs->devices[i].scsiID] );
412   }
413}
414
415void ncr5380_read_data(int bytes, UINT8 *pData)
416{
417   if (devices[last_id])
418   {
419486      if (VERBOSE)
420487         logerror("NCR5380: issuing read for %d bytes\n", bytes);
421      SCSIReadData(devices[last_id], pData, bytes);
488      SCSIReadData(m_scsi_devices[m_last_id], pData, bytes);
422489   }
423490   else
424491   {
425      logerror("ncr5380: read unknown device SCSI ID %d\n", last_id);
492      logerror("ncr5380: read unknown device SCSI ID %d\n", m_last_id);
426493   }
427494}
428495
429void ncr5380_write_data(int bytes, UINT8 *pData)
430{
431   if (devices[last_id])
432   {
433      SCSIWriteData(devices[last_id], pData, bytes);
434   }
435   else
436   {
437      logerror("ncr5380: write to unknown device SCSI ID %d\n", last_id);
438   }
439}
440496
441void *ncr5380_get_device(int id)
497void ncr5380_device::ncr5380_write_data(int bytes, UINT8 *pData)
442498{
443   void *ret;
444
445   if (devices[id])
499   if (m_scsi_devices[m_last_id])
446500   {
447      logerror("ncr5380: fetching dev pointer for SCSI ID %d\n", id);
448      SCSIGetDevice(devices[id], &ret);
449
450      return ret;
501      SCSIWriteData(m_scsi_devices[m_last_id], pData, bytes);
451502   }
452
453   return NULL;
454}
455
456#if USE_5380_DEVICE
457//**************************************************************************
458//  DEVICE CONFIGURATION
459//**************************************************************************
460
461ncr5380_device_config::ncr5380_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
462    : device_config(mconfig, static_alloc_device_config, "5380 SCSI", tag, owner, clock)
463{
464}
465
466device_config *ncr5380_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
467{
468   return global_alloc(ncr5380_device_config(mconfig, tag, owner, clock));
469}
470
471device_t *ncr5380_device_config::alloc_device(running_machine &machine) const
472{
473   return auto_alloc(&machine, ncr5380_device(machine, *this));
474}
475
476//-------------------------------------------------
477//  device_config_complete - perform any
478//  operations now that the configuration is
479//  complete
480//-------------------------------------------------
481
482void ncr5380_device_config::device_config_complete()
483{
484   // inherit a copy of the static data
485   const NCR5380interface *intf = reinterpret_cast<const NCR5380interface *>(static_config());
486   if (intf != NULL)
487      *static_cast<NCR5380interface *>(this) = *intf;
488
489   // or initialize to defaults if none provided
490503   else
491504   {
492      scsidevs = NULL;
493      irq_callback = NULL;
505      logerror("ncr5380: write to unknown device SCSI ID %d\n", m_last_id);
494506   }
495507}
496508
497//**************************************************************************
498//  LIVE DEVICE
499//**************************************************************************
500
501const device_type NCR5380 = ncr5380_device_config::static_alloc_device_config;
502
503//-------------------------------------------------
504//  via6522_device - constructor
505//-------------------------------------------------
506
507ncr5380_device::ncr5380_device(running_machine &_machine, const ncr5380_device_config &config)
508    : device_t(_machine, config),
509      m_config(config)
509void ncr5380_device::ncr5380_scan_devices()
510510{
511}
512
513//-------------------------------------------------
514//  device_start - device-specific startup
515//-------------------------------------------------
516
517void ncr5380_device::device_start()
518{
519511   int i;
520512
521   memset(m_5380_Registers, 0, sizeof(m_5380_Registers));
522   memset(m_5380_Data, 0, sizeof(m_5380_Data));
523   memset(m_scsi_devices, 0, sizeof(m_scsi_devices));
524
525   m_next_req_flag = 0;
526
527513   // try to open the devices
528514   for (i = 0; i < m_config.scsidevs->devs_present; i++)
529515   {
530      SCSIAllocInstance( machine,
531            m_config.scsidevs->devices[i].scsiClass,
532            &m_scsi_devices[m_config.scsidevs->devices[i].scsiID],
533            m_config.scsidevs->devices[i].diskregion );
516      // if a device wasn't already allocated
517      if (!m_scsi_devices[m_config.scsidevs->devices[i].scsiID])
518      {
519         SCSIAllocInstance( machine,
520               m_config.scsidevs->devices[i].scsiClass,
521               &m_scsi_devices[m_config.scsidevs->devices[i].scsiID],
522               m_config.scsidevs->devices[i].diskregion );
523      }
534524   }
535
536   state_save_register_device_item_array(this, 0, m_5380_Registers);
537   state_save_register_device_item_array(this, 0, m_Command);
538   state_save_register_device_item_array(this, 0, m_5380_Data);
539   state_save_register_device_item(this, 0, m_last_id);
540   state_save_register_device_item(this, 0, m_cmd_ptr);
541   state_save_register_device_item(this, 0, m_d_ptr);
542   state_save_register_device_item(this, 0, m_d_limit);
543   state_save_register_device_item(this, 0, m_next_req_flag);
544525}
545526
546//-------------------------------------------------
547//  device_reset - device-specific reset
548//-------------------------------------------------
549
550void ncr5380_device::device_reset()
527void ncr5380_read_data(running_device *dev, UINT8 bytes, UINT8 *pData)
551528{
552   memset(m_5380_Registers, 0, sizeof(m_5380_Registers));
553   memset(m_5380_Data, 0, sizeof(m_5380_Data));
554   memset(m_scsi_devices, 0, sizeof(m_scsi_devices));
555
556   m_next_req_flag = 0;
557   m_cmd_ptr = 0;
558   m_d_ptr = 0;
559   m_d_limit = 0;
560   m_last_id = 0;
529   return downcast<ncr5380_device*>(dev)->ncr5380_read_data(bytes, pData);
561530}
562531
563UINT8 ncr5380_device::read(UINT8 offset)
532void ncr5380_write_data(running_device *dev, UINT8 bytes, UINT8 *pData)
564533{
565   return 0;
534   downcast<ncr5380_device*>(dev)->ncr5380_write_data(bytes, pData);
566535}
567536
568void ncr5380_device::write(UINT8 offset, UINT8 data)
537void ncr5380_scan_devices(running_device *dev)
569538{
539   downcast<ncr5380_device*>(dev)->ncr5380_scan_devices();
570540}
571541
572void ncr5380_device::read_data(int bytes, UINT8 *pData)
573{
574}
575
576void ncr5380_device::write_data(int bytes, UINT8 *pData)
577{
578}
579
580void *ncr5380_device::get_scsi_device(int id)
581{
582   return NULL;
583}
584#endif
src/mess/machine/ncr5380.h
r9036r9037
88
99#include "machine/scsidev.h"
1010
11#define USE_5380_DEVICE (0)
12
1311struct NCR5380interface
1412{
1513   const SCSIConfigTable *scsidevs;      /* SCSI devices */
r9036r9037
3836#define R5380_OUTDATA_DTACK   (R5380_OUTDATA | 0x10)
3937#define R5380_CURDATA_DTACK   (R5380_CURDATA | 0x10)
4038
41extern void ncr5380_init( running_machine *machine, const struct NCR5380interface *interface );
42extern void ncr5380_exit( const struct NCR5380interface *interface );
43extern void ncr5380_read_data(int bytes, UINT8 *pData);
44extern void ncr5380_write_data(int bytes, UINT8 *pData);
45extern void *ncr5380_get_device(int id);
46extern void ncr5380_scan_devices( running_machine *machine );
47extern READ8_HANDLER(ncr5380_r);
48extern WRITE8_HANDLER(ncr5380_w);
49
5039// device stuff
51#if USE_5380_DEVICE
5240#define MDRV_NCR5380_ADD(_tag, _clock, _intrf) \
5341    MDRV_DEVICE_ADD(_tag, NCR5380, _clock) \
5442    MDRV_DEVICE_CONFIG(_intrf)
r9036r9037
7866   ncr5380_device(running_machine &_machine, const ncr5380_device_config &_config);
7967
8068public:
81   UINT8 read(UINT8 offset);
82   void write(UINT8 offset, UINT8 data);
69   // our API
70   UINT8 ncr5380_read_reg(UINT32 offset);
71   void ncr5380_write_reg(UINT32 offset, UINT8 data);
8372
84   void read_data(int bytes, UINT8 *pData);
85   void write_data(int bytes, UINT8 *pData);
73   void ncr5380_read_data(int bytes, UINT8 *pData);
74   void ncr5380_write_data(int bytes, UINT8 *pData);
8675
87   void *get_scsi_device(int id);
76   void *ncr5380_get_scsi_device(int id);
8877
78   void ncr5380_scan_devices();
8979protected:
9080   // device-level overrides
9181   virtual void device_start();
9282   virtual void device_reset();
83   virtual void device_stop();
9384
9485private:
9586   SCSIInstance *m_scsi_devices[8];
9687
9788   UINT8 m_5380_Registers[8];
9889   UINT8 m_last_id;
99   UINT8 m_Command[32];
90   UINT8 m_5380_Command[32];
10091   INT32 m_cmd_ptr, m_d_ptr, m_d_limit, m_next_req_flag;
10192   UINT8 m_5380_Data[512];
10293
10394   const ncr5380_device_config &m_config;
10495};
96
97// device type definition
98extern const device_type NCR5380;
99
100/***************************************************************************
101    PROTOTYPES
102***************************************************************************/
103READ8_DEVICE_HANDLER(ncr5380_read_reg);
104WRITE8_DEVICE_HANDLER(ncr5380_write_reg);
105
106void ncr5380_read_data(running_device *dev, int bytes, UINT8 *pData);
107void ncr5380_write_data(running_device *dev, int bytes, UINT8 *pData);
108void ncr5380_scan_devices(running_device *dev);
109
105110#endif
106#endif
src/mess/machine/mac.c
r9036r9037
911911READ16_HANDLER ( macplus_scsi_r )
912912{
913913   int reg = (offset>>3) & 0xf;
914   running_device *ncr = space->machine->device("ncr5380");
914915
915916//  logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask);
916917
r9036r9037
919920      reg = R5380_CURDATA_DTACK;
920921   }
921922
922   return ncr5380_r(space, reg)<<8;
923   return ncr5380_read_reg(ncr, reg)<<8;
923924}
924925
925926READ32_HANDLER (macii_scsi_drq_r)
926927{
928   running_device *ncr = space->machine->device("ncr5380");
929
927930   switch (mem_mask)
928931   {
929932      case 0xff000000:
930         return ncr5380_r(space, R5380_CURDATA_DTACK)<<24;
933         return ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24;
931934
932935      case 0xffff0000:
933         return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16);
936         return (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<16);
934937
935938      case 0xffffffff:
936         return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<8) | ncr5380_r(space, R5380_CURDATA_DTACK);
939         return (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<16) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<8) | ncr5380_read_reg(ncr, R5380_CURDATA_DTACK);
937940
938941      default:
939942         logerror("macii_scsi_drq_r: unknown mem_mask %08x\n", mem_mask);
r9036r9037
944947
945948WRITE32_HANDLER (macii_scsi_drq_w)
946949{
950   running_device *ncr = space->machine->device("ncr5380");
951
947952   switch (mem_mask)
948953   {
949954      case 0xff000000:
950         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24);
955         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24);
951956         break;
952957
953958      case 0xffff0000:
954         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24);
955         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>16);
959         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24);
960         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>16);
956961         break;
957962
958963      case 0xffffffff:
959         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24);
960         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>16);
961         ncr5380_w(space, R5380_OUTDATA_DTACK, data>>8);
962         ncr5380_w(space, R5380_OUTDATA_DTACK, data&0xff);
964         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24);
965         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>16);
966         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>8);
967         ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data&0xff);
963968         break;
964969
965970      default:
r9036r9037
971976WRITE16_HANDLER ( macplus_scsi_w )
972977{
973978   int reg = (offset>>3) & 0xf;
979   running_device *ncr = space->machine->device("ncr5380");
974980
975981//  logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
976982
r9036r9037
979985      reg = R5380_OUTDATA_DTACK;
980986   }
981987
982   ncr5380_w(space, reg, data);
988   ncr5380_write_reg(ncr, reg, data);
983989}
984990
985991WRITE16_HANDLER ( macii_scsi_w )
986992{
987993   int reg = (offset>>3) & 0xf;
994   running_device *ncr = space->machine->device("ncr5380");
988995
989996//  logerror("macplus_scsi_w: data %x offset %x mask %x (PC=%x)\n", data, offset, mem_mask, cpu_get_pc(space->cpu));
990997
r9036r9037
9931000      reg = R5380_OUTDATA_DTACK;
9941001   }
9951002
996   ncr5380_w(space, reg, data>>8);
1003   ncr5380_write_reg(ncr, reg, data>>8);
9971004}
9981005
999static void mac_scsi_irq(running_machine *machine, int state)
1006void mac_scsi_irq(running_machine *machine, int state)
10001007{
10011008   mac_state *mac = machine->driver_data<mac_state>();
10021009
r9036r9037
27482755 * Main
27492756 * *************************************************************************/
27502757
2751static const SCSIConfigTable dev_table =
2752{
2753   2,                                      /* 2 SCSI devices */
2754   {
2755    { SCSI_ID_6, "harddisk1", SCSI_DEVICE_HARDDISK },  /* SCSI ID 6, using disk1, and it's a harddisk */
2756    { SCSI_ID_5, "harddisk2", SCSI_DEVICE_HARDDISK }   /* SCSI ID 5, using disk2, and it's a harddisk */
2757   }
2758};
2759
2760static const struct NCR5380interface macplus_5380intf =
2761{
2762   &dev_table,   // SCSI device table
2763   mac_scsi_irq   // IRQ (unconnected on the Mac Plus)
2764};
2765
2766static void macscsi_exit(running_machine &machine)
2767{
2768   ncr5380_exit(&macplus_5380intf);
2769}
2770
27712758MACHINE_START( mac )
27722759{
27732760   mac_state *mac = machine->driver_data<mac_state>();
r9036r9037
28162803
28172804   if (mac->mac_model >= MODEL_MAC_PLUS)
28182805   {
2819      ncr5380_scan_devices(machine);
2806      ncr5380_scan_devices(machine->device("ncr5380"));
28202807   }
28212808
28222809   if ((mac->mac_model == MODEL_MAC_SE) || (mac->mac_model == MODEL_MAC_CLASSIC))
r9036r9037
29522939   mac_driver_init(machine, MODEL_MAC_512KE);
29532940}
29542941
2955MACHINE_START( macscsi )
2956{
2957   MACHINE_START_CALL(mac);
2958
2959   ncr5380_init(machine, &macplus_5380intf);
2960   machine->add_notifier(MACHINE_NOTIFY_EXIT, macscsi_exit);
2961}
2962
29632942DRIVER_INIT(macplus)
29642943{
29652944//  UINT32 *ROM = (UINT32 *)memory_region(machine, "bootrom");
src/mess/includes/mac.h
r9036r9037
146146
147147void mac_nubus_slot_interrupt(running_machine *machine, UINT8 slot, UINT32 state);
148148
149void mac_scsi_irq(running_machine *machine, int state);
150
149151/*----------- defined in video/mac.c -----------*/
150152
151153extern UINT32 *mac_se30_vram;
src/mess/drivers/mac.c
r9036r9037
640640   sony_read_status
641641};
642642
643static const SCSIConfigTable dev_table =
644{
645   2,                                      /* 2 SCSI devices */
646   {
647    { SCSI_ID_6, "harddisk1", SCSI_DEVICE_HARDDISK },  /* SCSI ID 6, using disk1, and it's a harddisk */
648    { SCSI_ID_5, "harddisk2", SCSI_DEVICE_HARDDISK }   /* SCSI ID 5, using disk2, and it's a harddisk */
649   }
650};
643651
652static const struct NCR5380interface macplus_5380intf =
653{
654   &dev_table,   // SCSI device table
655   mac_scsi_irq   // IRQ (unconnected on the Mac Plus)
656};
644657
645658/***************************************************************************
646659    MACHINE DRIVERS
r9036r9037
726739   MDRV_CPU_MODIFY( "maincpu" )
727740   MDRV_CPU_PROGRAM_MAP(macplus_map)
728741
729   MDRV_MACHINE_START(macscsi)
742   MDRV_NCR5380_ADD("ncr5380", 7833600, macplus_5380intf)
730743
731744   MDRV_HARDDISK_ADD( "harddisk1" )
732745   MDRV_HARDDISK_ADD( "harddisk2" )
r9036r9037
792805   // dot clock, htotal, hstart, hend, vtotal, vstart, vend
793806   MDRV_SCREEN_RAW_PARAMS(25175000, 800, 0, 640, 525, 0, 480)
794807
795   MDRV_MACHINE_START(macscsi)
808   MDRV_MACHINE_START( mac )
796809   MDRV_MACHINE_RESET( mac )
797810
798811        /* video hardware */
r9036r9037
820833   MDRV_NVRAM_HANDLER(mac)
821834
822835   /* devices */
836   MDRV_NCR5380_ADD("ncr5380", 7833600, macplus_5380intf)
837
823838   MDRV_IWM_ADD("fdc", mac_iwm_interface)
824839   MDRV_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_config)
825840
r9036r9037
899914   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1260))
900915   MDRV_QUANTUM_TIME(HZ(60))
901916
902   MDRV_MACHINE_START(macscsi)
917   MDRV_MACHINE_START( mac )
903918   MDRV_MACHINE_RESET( mac )
904919
905920        /* video hardware */
r9036r9037
928943   MDRV_NVRAM_HANDLER(mac)
929944
930945   /* devices */
946   MDRV_NCR5380_ADD("ncr5380", 7833600, macplus_5380intf)
947
931948   MDRV_IWM_ADD("fdc", mac_iwm_interface)
932949   MDRV_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_config)
933950
r9036r9037
9991016   // dot clock, htotal, hstart, hend, vtotal, vstart, vend
10001017   MDRV_SCREEN_RAW_PARAMS(25175000, 800, 0, 640, 525, 0, 480)
10011018
1002   MDRV_MACHINE_START(macscsi)
1003   MDRV_MACHINE_RESET(mac)
1019   MDRV_MACHINE_START( mac )
1020   MDRV_MACHINE_RESET( mac )
10041021
10051022        /* video hardware */
10061023   MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
r9036r9037
10271044   MDRV_NVRAM_HANDLER(mac)
10281045
10291046   /* devices */
1047   MDRV_NCR5380_ADD("ncr5380", 7833600, macplus_5380intf)
1048
10301049   MDRV_IWM_ADD("fdc", mac_iwm_interface)
10311050   MDRV_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_config)
10321051

Previous 15994 Revisions Next


© 1998-2018 The MESS Team