Previous 199869 Revisions Next

r23588 Monday 10th June, 2013 at 08:42:39 UTC by smf
Decoupled the IDE bus master emulation from the hard drive emulation [smf]
[src/emu/machine]idectrl.c idectrl.h

trunk/src/emu/machine/idectrl.c
r23587r23588
9090#define IDE_ERROR_BAD_LOCATION              0x10
9191#define IDE_ERROR_BAD_SECTOR                0x80
9292
93#define IDE_BUSMASTER_STATUS_ACTIVE         0x01
94#define IDE_BUSMASTER_STATUS_ERROR          0x02
95#define IDE_BUSMASTER_STATUS_IRQ            0x04
9693
97
98void ide_controller_device::signal_interrupt()
94void ide_controller_device::set_irq(int state)
9995{
100   LOG(("IDE interrupt assert\n"));
101
96   if (state == ASSERT_LINE)
97      LOG(("IDE interrupt assert\n"));
98   else
99      LOG(("IDE interrupt clear\n"));
100   
102101   /* signal an interrupt */
103   m_irq_handler(ASSERT_LINE);
104   interrupt_pending = 1;
105   bus_master_status |= IDE_BUSMASTER_STATUS_IRQ;
102   m_irq_handler(state);
103   interrupt_pending = state;
106104}
107105
108
109void ide_controller_device::clear_interrupt()
106void ide_controller_device::set_dmarq(int state)
110107{
111   LOG(("IDE interrupt clear\n"));
112
113   /* clear an interrupt */
114   m_irq_handler(CLEAR_LINE);
115   interrupt_pending = 0;
116108}
117109
118110
r23587r23588
125117{
126118   ide_controller_device *ide = (ide_controller_device *)ptr;
127119   ide->status &= ~IDE_STATUS_BUSY;
128   ide->signal_interrupt();
120   ide->set_irq(ASSERT_LINE);
129121}
130122
131123
r23587r23588
134126   ide_controller_device *ide = (ide_controller_device *)ptr;
135127   ide->status &= ~IDE_STATUS_BUSY;
136128   ide->status |= IDE_STATUS_BUFFER_READY;
137   ide->signal_interrupt();
129   ide->set_irq(ASSERT_LINE);
138130}
139131
140132
r23587r23588
265257 *
266258 *************************************/
267259
268void ide_controller_device::continue_read()
260void ide_controller_device::read_buffer_empty()
269261{
270262   /* reset the totals */
271263   buffer_offset = 0;
r23587r23588
273265   /* clear the buffer ready and busy flag */
274266   status &= ~IDE_STATUS_BUFFER_READY;
275267   status &= ~IDE_STATUS_BUSY;
268   error = IDE_ERROR_DEFAULT;
269   set_dmarq(0);
276270
277271   if (master_password_enable || user_password_enable)
278272   {
279273      security_error();
280274
281275      sector_count = 0;
282      bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
283      dma_active = 0;
284276
285277      return;
286278   }
r23587r23588
290282      sector_count--;
291283   if (sector_count > 0)
292284      read_next_sector();
293   else
294   {
295      bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
296      dma_active = 0;
297   }
298285}
299286
300287
301void ide_controller_device::write_buffer_to_dma()
302{
303   int bytesleft = IDE_DISK_SECTOR_SIZE;
304   UINT16 data = 0;
305
306//  LOG(("Writing sector to %08X\n", dma_address));
307
308   /* loop until we've consumed all bytes */
309   while (bytesleft--)
310   {
311      data >>= 8;
312
313      if (bytesleft & 1)
314         data = read_dma();
315
316      /* if we're out of space, grab the next descriptor */
317      if (dma_bytes_left == 0)
318      {
319         /* if we're out of buffer space, that's bad */
320         if (dma_last_buffer)
321         {
322            LOG(("DMA Out of buffer space!\n"));
323            return;
324         }
325
326         /* fetch the address */
327         dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
328         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
329         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
330         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
331         dma_address &= 0xfffffffe;
332
333         /* fetch the length */
334         dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
335         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
336         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
337         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
338         dma_last_buffer = (dma_bytes_left >> 31) & 1;
339         dma_bytes_left &= 0xfffe;
340         if (dma_bytes_left == 0)
341            dma_bytes_left = 0x10000;
342
343//          LOG(("New DMA descriptor: address = %08X  bytes = %04X  last = %d\n", dma_address, dma_bytes_left, dma_last_buffer));
344      }
345
346      /* write the next byte */
347      dma_space->write_byte(dma_address++, data & 0xff);
348      dma_bytes_left--;
349   }
350}
351
352
353288void ide_controller_device::read_sector_done()
354289{
355290   ide_device_interface *dev = slot[cur_drive]->dev();
r23587r23588
390325      if (sectors_until_int == 0 || sector_count == 1)
391326      {
392327         sectors_until_int = ((command == IDE_COMMAND_READ_MULTIPLE_BLOCK) ? block_count : 1);
393         signal_interrupt();
328         set_irq(ASSERT_LINE);
394329      }
395330
396331      /* handle DMA */
397332      if (dma_active)
398         write_buffer_to_dma();
333         set_dmarq(1);
399334
400335      /* if we're just verifying we can read the next sector */
401336      if (verify_only)
402         continue_read();
337         read_buffer_empty();
403338   }
404339
405340   /* if we got an error, we need to report it */
r23587r23588
408343      /* set the error flag and the error */
409344      status |= IDE_STATUS_ERROR;
410345      error = IDE_ERROR_BAD_SECTOR;
411      bus_master_status |= IDE_BUSMASTER_STATUS_ERROR;
412      bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
413346
414347      /* signal an interrupt */
415      signal_interrupt();
348      set_irq(ASSERT_LINE);
416349   }
417350}
418351
r23587r23588
509442}
510443
511444
512void ide_controller_device::read_buffer_from_dma()
445void ide_controller_device::write_buffer_full()
513446{
514   int bytesleft = IDE_DISK_SECTOR_SIZE;
515   UINT16 data = 0;
447   ide_device_interface *dev = slot[cur_drive]->dev();
516448
517//  LOG(("Reading sector from %08X\n", dma_address));
518
519   /* loop until we've consumed all bytes */
520   while (bytesleft--)
449   set_dmarq(0);
450   if (command == IDE_COMMAND_SECURITY_UNLOCK)
521451   {
522      /* if we're out of space, grab the next descriptor */
523      if (dma_bytes_left == 0)
452      if (user_password_enable && memcmp(buffer, user_password, 2 + 32) == 0)
524453      {
525         /* if we're out of buffer space, that's bad */
526         if (dma_last_buffer)
454         LOGPRINT(("IDE Unlocked user password\n"));
455         user_password_enable = 0;
456      }
457      if (master_password_enable && memcmp(buffer, master_password, 2 + 32) == 0)
458      {
459         LOGPRINT(("IDE Unlocked master password\n"));
460         master_password_enable = 0;
461      }
462      if (PRINTF_IDE_PASSWORD)
463      {
464         int i;
465
466         for (i = 0; i < 34; i += 2)
527467         {
528            LOG(("DMA Out of buffer space!\n"));
529            return;
530         }
468            if (i % 8 == 2)
469               mame_printf_debug("\n");
531470
532         /* fetch the address */
533         dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
534         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
535         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
536         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
537         dma_address &= 0xfffffffe;
538
539         /* fetch the length */
540         dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
541         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
542         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
543         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
544         dma_last_buffer = (dma_bytes_left >> 31) & 1;
545         dma_bytes_left &= 0xfffe;
546         if (dma_bytes_left == 0)
547            dma_bytes_left = 0x10000;
548
549//          LOG(("New DMA descriptor: address = %08X  bytes = %04X  last = %d\n", dma_address, dma_bytes_left, dma_last_buffer));
471            mame_printf_debug("0x%02x, 0x%02x, ", buffer[i], buffer[i + 1]);
472            //mame_printf_debug("0x%02x%02x, ", buffer[i], buffer[i + 1]);
473         }
474         mame_printf_debug("\n");
550475      }
551476
552      /* read the next byte */
553      data |= dma_space->read_byte(dma_address++) << 8;
554      dma_bytes_left --;
477      /* clear the busy and error flags */
478      status &= ~IDE_STATUS_ERROR;
479      status &= ~IDE_STATUS_BUSY;
480      status &= ~IDE_STATUS_BUFFER_READY;
555481
556      if((bytesleft & 1) == 0)
557         write_dma(data);
482      if (master_password_enable || user_password_enable)
483         security_error();
484      else
485         status |= IDE_STATUS_DRIVE_READY;
486   }
487   else if (command == IDE_COMMAND_TAITO_GNET_UNLOCK_2)
488   {
489      UINT8 key[5] = { 0 };
490      int i, bad = 0;
491      dev->read_key(key);
558492
559      data >>= 8;
493      for (i=0; !bad && i<512; i++)
494         bad = ((i < 2 || i >= 7) && buffer[i]) || ((i >= 2 && i < 7) && buffer[i] != key[i-2]);
495
496      status &= ~IDE_STATUS_BUSY;
497      status &= ~IDE_STATUS_BUFFER_READY;
498      if (bad)
499         status |= IDE_STATUS_ERROR;
500      else {
501         status &= ~IDE_STATUS_ERROR;
502         gnetreadlock= 0;
503      }
560504   }
505   else
506   {
507      continue_write();
508   }
561509}
562510
563511
r23587r23588
592540      if (--sectors_until_int == 0 || sector_count == 1)
593541      {
594542         sectors_until_int = ((command == IDE_COMMAND_WRITE_MULTIPLE_BLOCK) ? block_count : 1);
595         signal_interrupt();
543         set_irq(ASSERT_LINE);
596544      }
597545
598546      /* signal an interrupt if there's more data needed */
r23587r23588
604552      /* keep going for DMA */
605553      if (dma_active && sector_count != 0)
606554      {
607         read_buffer_from_dma();
555         set_dmarq(1);
608556      }
609      else
610         dma_active = 0;
611557   }
612558
613559   /* if we got an error, we need to report it */
r23587r23588
616562      /* set the error flag and the error */
617563      status |= IDE_STATUS_ERROR;
618564      error = IDE_ERROR_BAD_SECTOR;
619      bus_master_status |= IDE_BUSMASTER_STATUS_ERROR;
620      bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
621565
622566      /* signal an interrupt */
623      signal_interrupt();
567      set_irq(ASSERT_LINE);
624568   }
625569}
626570
r23587r23588
644588   UINT8 key[5];
645589   ide_device_interface *dev = slot[cur_drive]->dev();
646590
647   /* implicitly clear interrupts here */
648   clear_interrupt();
591   /* implicitly clear interrupts & dmarq here */
592   set_irq(CLEAR_LINE);
593   set_dmarq(0);
649594   command = _command;
650595   switch (command)
651596   {
r23587r23588
704649         verify_only = 0;
705650
706651         /* start the read going */
707         if (bus_master_command & 1)
708            read_first_sector();
652         read_first_sector();
709653         break;
710654
711655      case IDE_COMMAND_WRITE_MULTIPLE:
r23587r23588
745689         dma_active = 1;
746690
747691         /* start the read going */
748         if (bus_master_command & 1)
749         {
750            read_buffer_from_dma();
751         }
692         set_dmarq(1);
752693         break;
753694
754695      case IDE_COMMAND_SECURITY_UNLOCK:
r23587r23588
761702
762703         /* mark the buffer ready */
763704         status |= IDE_STATUS_BUFFER_READY;
764         signal_interrupt();
705         set_irq(ASSERT_LINE);
765706         break;
766707
767708      case IDE_COMMAND_GET_INFO:
r23587r23588
811752         /* for timeout disabled value is 0 */
812753         sector_count = 0;
813754         /* signal an interrupt */
814         signal_interrupt();
755         set_irq(ASSERT_LINE);
815756         break;
816757
817758      case IDE_COMMAND_SET_CONFIG:
r23587r23588
829770         LOGPRINT(("IDE unknown command (F9)\n"));
830771
831772         /* signal an interrupt */
832         signal_interrupt();
773         set_irq(ASSERT_LINE);
833774         break;
834775
835776      case IDE_COMMAND_SET_FEATURES:
r23587r23588
847788         status |= IDE_STATUS_DRIVE_READY;
848789
849790         /* signal an interrupt */
850         signal_interrupt();
791         set_irq(ASSERT_LINE);
851792         break;
852793
853794      case IDE_COMMAND_TAITO_GNET_UNLOCK_1:
r23587r23588
856797         sector_count = 1;
857798         status |= IDE_STATUS_DRIVE_READY;
858799         status &= ~IDE_STATUS_ERROR;
859         signal_interrupt();
800         set_irq(ASSERT_LINE);
860801         break;
861802
862803      case IDE_COMMAND_TAITO_GNET_UNLOCK_2:
r23587r23588
869810
870811         /* mark the buffer ready */
871812         status |= IDE_STATUS_BUFFER_READY;
872         signal_interrupt();
813         set_irq(ASSERT_LINE);
873814         break;
874815
875816      case IDE_COMMAND_TAITO_GNET_UNLOCK_3:
r23587r23588
885826         /* update flags */
886827         status |= IDE_STATUS_DRIVE_READY;
887828         status &= ~IDE_STATUS_ERROR;
888         signal_interrupt();
829         set_irq(ASSERT_LINE);
889830         break;
890831
891832      case IDE_COMMAND_SEEK:
r23587r23588
900841         /* for timeout disabled value is 0 */
901842         sector_count = 0;
902843         /* signal an interrupt */
903         signal_interrupt();
844         set_irq(ASSERT_LINE);
904845         break;
905846
906847
r23587r23588
908849         LOGPRINT(("IDE unknown command (%02X)\n", command));
909850         status |= IDE_STATUS_ERROR;
910851         error = IDE_ERROR_UNKNOWN_COMMAND;
911         signal_interrupt();
852         set_irq(ASSERT_LINE);
912853         //debugger_break(device->machine());
913854         break;
914855   }
r23587r23588
10661007            result |= IDE_STATUS_HIT_INDEX;
10671008            last_status_timer->adjust(attotime::never);
10681009         }
1069         if (interrupt_pending)
1070            clear_interrupt();
1010         if (interrupt_pending == ASSERT_LINE)
1011            set_irq(CLEAR_LINE);
10711012         break;
10721013
10731014      /* log anything else */
r23587r23588
10831024}
10841025
10851026
1086void ide_controller_device::write_buffer_full()
1087{
1088   ide_device_interface *dev = slot[cur_drive]->dev();
1089
1090   if (command == IDE_COMMAND_SECURITY_UNLOCK)
1091   {
1092      if (user_password_enable && memcmp(buffer, user_password, 2 + 32) == 0)
1093      {
1094         LOGPRINT(("IDE Unlocked user password\n"));
1095         user_password_enable = 0;
1096      }
1097      if (master_password_enable && memcmp(buffer, master_password, 2 + 32) == 0)
1098      {
1099         LOGPRINT(("IDE Unlocked master password\n"));
1100         master_password_enable = 0;
1101      }
1102      if (PRINTF_IDE_PASSWORD)
1103      {
1104         int i;
1105
1106         for (i = 0; i < 34; i += 2)
1107         {
1108            if (i % 8 == 2)
1109               mame_printf_debug("\n");
1110
1111            mame_printf_debug("0x%02x, 0x%02x, ", buffer[i], buffer[i + 1]);
1112            //mame_printf_debug("0x%02x%02x, ", buffer[i], buffer[i + 1]);
1113         }
1114         mame_printf_debug("\n");
1115      }
1116
1117      /* clear the busy and error flags */
1118      status &= ~IDE_STATUS_ERROR;
1119      status &= ~IDE_STATUS_BUSY;
1120      status &= ~IDE_STATUS_BUFFER_READY;
1121
1122      if (master_password_enable || user_password_enable)
1123         security_error();
1124      else
1125         status |= IDE_STATUS_DRIVE_READY;
1126   }
1127   else if (command == IDE_COMMAND_TAITO_GNET_UNLOCK_2)
1128   {
1129      UINT8 key[5] = { 0 };
1130      int i, bad = 0;
1131      dev->read_key(key);
1132
1133      for (i=0; !bad && i<512; i++)
1134         bad = ((i < 2 || i >= 7) && buffer[i]) || ((i >= 2 && i < 7) && buffer[i] != key[i-2]);
1135
1136      status &= ~IDE_STATUS_BUSY;
1137      status &= ~IDE_STATUS_BUFFER_READY;
1138      if (bad)
1139         status |= IDE_STATUS_ERROR;
1140      else {
1141         status &= ~IDE_STATUS_ERROR;
1142         gnetreadlock= 0;
1143      }
1144   }
1145   else
1146      continue_write();
1147}
1148
1149void ide_controller_device::read_buffer_empty()
1150{
1151   continue_read();
1152   error = IDE_ERROR_DEFAULT;
1153}
1154
11551027READ16_MEMBER( ide_controller_device::read_cs1_pc )
11561028{
11571029   if (mem_mask == 0xff00)
r23587r23588
13891261}
13901262
13911263
1392/*************************************
1393 *
1394 *  Bus master read
1395 *
1396 *************************************/
1397
1398READ32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_r )
1399{
1400   LOG(("%s:ide_bus_master32_r(%d, %08x)\n", machine().describe_context(), offset, mem_mask));
1401
1402   switch( offset )
1403   {
1404   case 0:
1405      /* command register/status register */
1406      return bus_master_command | (bus_master_status << 16);
1407
1408   case 1:
1409      /* descriptor table register */
1410      return bus_master_descriptor;
1411   }
1412
1413   return 0xffffffff;
1414}
1415
1416
1417
1418/*************************************
1419 *
1420 *  Bus master write
1421 *
1422 *************************************/
1423
1424WRITE32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_w )
1425{
1426   LOG(("%s:ide_bus_master32_w(%d, %08x, %08X)\n", machine().describe_context(), offset, mem_mask, data));
1427
1428   switch( offset )
1429   {
1430   case 0:
1431      if( ACCESSING_BITS_0_7 )
1432      {
1433         /* command register */
1434         UINT8 old = bus_master_command;
1435         UINT8 val = data & 0xff;
1436
1437         /* save the read/write bit and the start/stop bit */
1438         bus_master_command = (old & 0xf6) | (val & 0x09);
1439         bus_master_status = (bus_master_status & ~IDE_BUSMASTER_STATUS_ACTIVE) | (val & 0x01);
1440
1441         /* handle starting a transfer */
1442         if (!(old & 1) && (val & 1))
1443         {
1444            /* reset all the DMA data */
1445            dma_bytes_left = 0;
1446            dma_last_buffer = 0;
1447            dma_descriptor = bus_master_descriptor;
1448
1449            /* if we're going live, start the pending read/write */
1450            if (dma_active)
1451            {
1452               if (bus_master_command & 8)
1453                  read_next_sector();
1454               else
1455               {
1456                  read_buffer_from_dma();
1457               }
1458            }
1459         }
1460      }
1461
1462      if( ACCESSING_BITS_16_23 )
1463      {
1464         /* status register */
1465         UINT8 old = bus_master_status;
1466         UINT8 val = (data >> 16) & 0xff;
1467
1468         /* save the DMA capable bits */
1469         bus_master_status = (old & 0x9f) | (val & 0x60);
1470
1471         /* clear interrupt and error bits */
1472         if (val & IDE_BUSMASTER_STATUS_IRQ)
1473            bus_master_status &= ~IDE_BUSMASTER_STATUS_IRQ;
1474         if (val & IDE_BUSMASTER_STATUS_ERROR)
1475            bus_master_status &= ~IDE_BUSMASTER_STATUS_ERROR;
1476      }
1477      break;
1478
1479   case 1:
1480      /* descriptor table register */
1481      bus_master_descriptor = data & 0xfffffffc;
1482      break;
1483   }
1484}
1485
1486
14871264SLOT_INTERFACE_START(ide_devices)
14881265   SLOT_INTERFACE("hdd", IDE_HARDDISK)
14891266SLOT_INTERFACE_END
r23587r23588
14911268ide_controller_device::ide_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
14921269   device_t(mconfig, type, name, tag, owner, clock),
14931270   status(0),
1494   bmcpu(NULL),
1495   bmspace(0),
1496   dma_space(NULL),
1497   dma_active(0),
1498   dma_address_xor(0),
1499   dma_last_buffer(0),
1500   dma_address(0),
1501   dma_descriptor(0),
1502   dma_bytes_left(0),
1503   bus_master_command(0),
1504   bus_master_status(0),
1505   bus_master_descriptor(0),
15061271   adapter_control(0),
15071272   error(0),
15081273   command(0),
r23587r23588
15301295
15311296ide_controller_device::ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
15321297   device_t(mconfig, IDE_CONTROLLER, "IDE Controller", tag, owner, clock),
1533   bmcpu(NULL),
1534   bmspace(0),
1535   dma_space(NULL),
1536   dma_active(0),
1537   dma_address_xor(0),
1538   dma_last_buffer(0),
1539   dma_address(0),
1540   dma_descriptor(0),
1541   dma_bytes_left(0),
1542   bus_master_command(0),
1543   bus_master_status(0),
1544   bus_master_descriptor(0),
15451298   adapter_control(0),
15461299   error(0),
15471300   command(0),
r23587r23588
15641317{
15651318}
15661319
1567const device_type BUS_MASTER_IDE_CONTROLLER = &device_creator<bus_master_ide_controller_device>;
1568
1569bus_master_ide_controller_device::bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
1570   ide_controller_device(mconfig, BUS_MASTER_IDE_CONTROLLER, "Bus Master IDE Controller", tag, owner, clock)
1571{
1572}
1573
15741320//-------------------------------------------------
15751321//  device_start - device-specific startup
15761322//-------------------------------------------------
r23587r23588
15831329   slot[0] = owner()->subdevice<ide_slot_device>("drive_0");
15841330   slot[1] = owner()->subdevice<ide_slot_device>("drive_1");
15851331
1586   /* find the bus master space */
1587   if (bmcpu != NULL)
1588   {
1589      device_t *bmtarget = machine().device(bmcpu);
1590      if (bmtarget == NULL)
1591         throw emu_fatalerror("IDE controller '%s' bus master target '%s' doesn't exist!", tag(), bmcpu);
1592      device_memory_interface *memory;
1593      if (!bmtarget->interface(memory))
1594         throw emu_fatalerror("IDE controller '%s' bus master target '%s' has no memory!", tag(), bmcpu);
1595      dma_space = &memory->space(bmspace);
1596      dma_address_xor = (dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3;
1597   }
1598
15991332   /* create a timer for timing status */
16001333   last_status_timer = machine().scheduler().timer_alloc(FUNC_NULL);
16011334   reset_timer = machine().scheduler().timer_alloc(FUNC(reset_callback), this);
r23587r23588
16161349   save_item(NAME(sectors_until_int));
16171350
16181351   save_item(NAME(dma_active));
1619   save_item(NAME(dma_last_buffer));
1620   save_item(NAME(dma_address));
1621   save_item(NAME(dma_descriptor));
1622   save_item(NAME(dma_bytes_left));
16231352
1624   save_item(NAME(bus_master_command));
1625   save_item(NAME(bus_master_status));
1626   save_item(NAME(bus_master_descriptor));
1627
16281353   save_item(NAME(config_unknown));
16291354   save_item(NAME(config_register));
16301355   save_item(NAME(config_register_num));
r23587r23588
16501375   gnetreadlock = 0;
16511376   master_password_enable = (master_password != NULL);
16521377   user_password_enable = (user_password != NULL);
1653   clear_interrupt();
1378   set_irq(CLEAR_LINE);
1379   set_dmarq(0);
16541380}
16551381
16561382
r23587r23588
16911417void ide_slot_device::device_start()
16921418{
16931419}
1420
1421
1422
1423#define IDE_BUSMASTER_STATUS_ACTIVE         0x01
1424#define IDE_BUSMASTER_STATUS_ERROR          0x02
1425#define IDE_BUSMASTER_STATUS_IRQ            0x04
1426
1427const device_type BUS_MASTER_IDE_CONTROLLER = &device_creator<bus_master_ide_controller_device>;
1428
1429bus_master_ide_controller_device::bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
1430   ide_controller_device(mconfig, BUS_MASTER_IDE_CONTROLLER, "Bus Master IDE Controller", tag, owner, clock),
1431   dma_address(0),
1432   dma_bytes_left(0),
1433   dma_descriptor(0),
1434   dma_last_buffer(0),
1435   bus_master_command(0),
1436   bus_master_status(0),
1437   bus_master_descriptor(0)
1438{
1439}
1440
1441void bus_master_ide_controller_device::device_start()
1442{
1443   ide_controller_device::device_start();
1444
1445   /* find the bus master space */
1446   if (bmcpu != NULL)
1447   {
1448      device_t *bmtarget = machine().device(bmcpu);
1449      if (bmtarget == NULL)
1450         throw emu_fatalerror("IDE controller '%s' bus master target '%s' doesn't exist!", tag(), bmcpu);
1451      device_memory_interface *memory;
1452      if (!bmtarget->interface(memory))
1453         throw emu_fatalerror("IDE controller '%s' bus master target '%s' has no memory!", tag(), bmcpu);
1454      dma_space = &memory->space(bmspace);
1455      dma_address_xor = (dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3;
1456   }
1457
1458   save_item(NAME(dma_address));
1459   save_item(NAME(dma_bytes_left));
1460   save_item(NAME(dma_descriptor));
1461   save_item(NAME(dma_last_buffer));
1462   save_item(NAME(bus_master_command));
1463   save_item(NAME(bus_master_status));
1464   save_item(NAME(bus_master_descriptor));
1465}
1466
1467void bus_master_ide_controller_device::set_irq(int state)
1468{
1469   ide_controller_device::set_irq(state);
1470
1471   if (m_irq != state)
1472   {
1473      m_irq = state;
1474
1475      if( m_irq )
1476         bus_master_status |= IDE_BUSMASTER_STATUS_IRQ;
1477   }
1478}
1479
1480void bus_master_ide_controller_device::set_dmarq(int state)
1481{
1482   if (m_dmarq != state)
1483   {
1484      m_dmarq = state;
1485
1486      execute_dma();
1487   }
1488}
1489
1490/*************************************
1491 *
1492 *  Bus master read
1493 *
1494 *************************************/
1495
1496READ32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_r )
1497{
1498   LOG(("%s:ide_bus_master32_r(%d, %08x)\n", machine().describe_context(), offset, mem_mask));
1499
1500   switch( offset )
1501   {
1502   case 0:
1503      /* command register/status register */
1504      return bus_master_command | (bus_master_status << 16);
1505
1506   case 1:
1507      /* descriptor table register */
1508      return bus_master_descriptor;
1509   }
1510
1511   return 0xffffffff;
1512}
1513
1514
1515
1516/*************************************
1517 *
1518 *  Bus master write
1519 *
1520 *************************************/
1521
1522WRITE32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_w )
1523{
1524   LOG(("%s:ide_bus_master32_w(%d, %08x, %08X)\n", machine().describe_context(), offset, mem_mask, data));
1525
1526   switch( offset )
1527   {
1528   case 0:
1529      if( ACCESSING_BITS_0_7 )
1530      {
1531         /* command register */
1532         UINT8 old = bus_master_command;
1533         UINT8 val = data & 0xff;
1534
1535         /* save the read/write bit and the start/stop bit */
1536         bus_master_command = (old & 0xf6) | (val & 0x09);
1537
1538         if ((old ^ bus_master_command) & 1)
1539         {
1540            if (bus_master_command & 1)
1541            {
1542               /* handle starting a transfer */
1543               bus_master_status |= IDE_BUSMASTER_STATUS_ACTIVE;
1544
1545               /* reset all the DMA data */
1546               dma_bytes_left = 0;
1547               dma_descriptor = bus_master_descriptor;
1548
1549               /* if we're going live, start the pending read/write */
1550               execute_dma();
1551            }
1552            else if (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE)
1553            {
1554               bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
1555
1556               LOG(("DMA Aborted!\n"));
1557            }
1558         }
1559      }
1560
1561      if( ACCESSING_BITS_16_23 )
1562      {
1563         /* status register */
1564         UINT8 old = bus_master_status;
1565         UINT8 val = data >> 16;
1566
1567         /* save the DMA capable bits */
1568         bus_master_status = (old & 0x9f) | (val & 0x60);
1569
1570         /* clear interrupt and error bits */
1571         if (val & IDE_BUSMASTER_STATUS_IRQ)
1572            bus_master_status &= ~IDE_BUSMASTER_STATUS_IRQ;
1573         if (val & IDE_BUSMASTER_STATUS_ERROR)
1574            bus_master_status &= ~IDE_BUSMASTER_STATUS_ERROR;
1575      }
1576      break;
1577
1578   case 1:
1579      /* descriptor table register */
1580      bus_master_descriptor = data & 0xfffffffc;
1581      break;
1582   }
1583}
1584
1585void bus_master_ide_controller_device::execute_dma()
1586{
1587   while (m_dmarq && (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE))
1588   {
1589      /* if we're out of space, grab the next descriptor */
1590      if (dma_bytes_left == 0)
1591      {
1592         /* fetch the address */
1593         dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
1594         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
1595         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
1596         dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
1597         dma_address &= 0xfffffffe;
1598
1599         /* fetch the length */
1600         dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor);
1601         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8;
1602         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16;
1603         dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24;
1604         dma_last_buffer = (dma_bytes_left >> 31) & 1;
1605         dma_bytes_left &= 0xfffe;
1606         if (dma_bytes_left == 0)
1607            dma_bytes_left = 0x10000;
1608
1609//          LOG(("New DMA descriptor: address = %08X  bytes = %04X  last = %d\n", dma_address, dma_bytes_left, dma_last_buffer));
1610      }
1611
1612      if (bus_master_command & 8)
1613      {
1614         // read from ata bus
1615         UINT16 data = read_dma();
1616
1617         // write to memory
1618         dma_space->write_byte(dma_address++, data & 0xff);
1619         dma_space->write_byte(dma_address++, data >> 8);
1620      }
1621      else
1622      {
1623         // read from memory;
1624         UINT16 data = dma_space->read_byte(dma_address++);
1625         data |= dma_space->read_byte(dma_address++) << 8;
1626
1627         // write to ata bus
1628         write_dma(data);
1629      }
1630
1631      dma_bytes_left -= 2;
1632
1633      if (dma_bytes_left == 0 && dma_last_buffer)
1634      {
1635         bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE;
1636
1637         if (m_dmarq)
1638         {
1639            LOG(("DMA Out of buffer space!\n"));
1640         }
1641      }
1642   }
1643}
trunk/src/emu/machine/idectrl.h
r23587r23588
101101   DECLARE_WRITE16_MEMBER(write_cs0_pc);
102102   DECLARE_WRITE16_MEMBER(write_cs1_pc);
103103   
104   void signal_interrupt();
105   void clear_interrupt();
104   virtual void set_irq(int state);
105   virtual void set_dmarq(int state);
106106   void read_sector_done();
107107   void write_sector_done();
108108
r23587r23588
113113   virtual void device_start();
114114   virtual void device_reset();
115115
116   const char *bmcpu;
117   UINT32 bmspace;
118   address_space * dma_space;
119   UINT8           dma_active;
120   UINT8           dma_address_xor;
121   UINT8           dma_last_buffer;
122   offs_t          dma_address;
123   offs_t          dma_descriptor;
124   UINT32          dma_bytes_left;
125   UINT8           bus_master_command;
126   UINT8           bus_master_status;
127   UINT32          bus_master_descriptor;
128
129116   void read_next_sector();
130   void read_buffer_from_dma();
131117   void continue_write();
132118
133119private:
r23587r23588
135121   void next_sector();
136122   void security_error();
137123   void continue_read();
138   void write_buffer_to_dma();
139124   void read_first_sector();
140125   void handle_command(UINT8 _command);
141126   void read_buffer_empty();
142127   void write_buffer_full();
143128
129   UINT8           dma_active;
144130   UINT8           adapter_control;
145131   UINT8           error;
146132   UINT8           command;
r23587r23588
194180
195181   DECLARE_READ32_MEMBER( ide_bus_master32_r );
196182   DECLARE_WRITE32_MEMBER( ide_bus_master32_w );
183
184   virtual void set_irq(int state);
185   virtual void set_dmarq(int state);
186
187protected:
188   virtual void device_start();
189
190private:
191   void execute_dma();
192
193   const char *bmcpu;
194   UINT32 bmspace;
195   address_space * dma_space;
196   UINT8           dma_address_xor;
197
198   offs_t          dma_address;
199   UINT32          dma_bytes_left;
200   offs_t          dma_descriptor;
201   UINT8           dma_last_buffer;
202   UINT8           bus_master_command;
203   UINT8           bus_master_status;
204   UINT32          bus_master_descriptor;
205   int m_irq;
206   int m_dmarq;
197207};
198208
199209extern const device_type BUS_MASTER_IDE_CONTROLLER;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team