trunk/src/mess/drivers/fmtowns.c
| r21429 | r21430 | |
| 419 | 419 | case TIMER_WAIT: |
| 420 | 420 | wait_end(); |
| 421 | 421 | break; |
| 422 | case TIMER_CDSTATUS: |
| 423 | towns_cd_status_ready(); |
| 424 | break; |
| 425 | case TIMER_CDDA: |
| 426 | towns_delay_cdda((cdrom_image_device*)ptr); |
| 427 | break; |
| 422 | 428 | } |
| 423 | 429 | } |
| 424 | 430 | void towns_state::freerun_inc() |
| r21429 | r21430 | |
| 1364 | 1370 | } |
| 1365 | 1371 | } |
| 1366 | 1372 | |
| 1367 | | TIMER_CALLBACK_MEMBER(towns_state::towns_cd_status_ready) |
| 1373 | void towns_state::towns_cd_status_ready() |
| 1368 | 1374 | { |
| 1369 | 1375 | m_towns_cd.status |= 0x02; // status read request |
| 1370 | 1376 | m_towns_cd.status |= 0x01; // ready |
| r21429 | r21430 | |
| 1372 | 1378 | towns_cdrom_set_irq((running_machine&)machine(),TOWNS_CD_IRQ_MPU,1); |
| 1373 | 1379 | } |
| 1374 | 1380 | |
| 1375 | | static void towns_cd_set_status(running_machine &machine, UINT8 st0, UINT8 st1, UINT8 st2, UINT8 st3) |
| 1381 | void towns_state::towns_cd_set_status(UINT8 st0, UINT8 st1, UINT8 st2, UINT8 st3) |
| 1376 | 1382 | { |
| 1377 | | towns_state* state = machine.driver_data<towns_state>(); |
| 1378 | | state->m_towns_cd.cmd_status[0] = st0; |
| 1379 | | state->m_towns_cd.cmd_status[1] = st1; |
| 1380 | | state->m_towns_cd.cmd_status[2] = st2; |
| 1381 | | state->m_towns_cd.cmd_status[3] = st3; |
| 1383 | m_towns_cd.cmd_status[0] = st0; |
| 1384 | m_towns_cd.cmd_status[1] = st1; |
| 1385 | m_towns_cd.cmd_status[2] = st2; |
| 1386 | m_towns_cd.cmd_status[3] = st3; |
| 1382 | 1387 | // wait a bit |
| 1383 | | machine.scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(towns_state::towns_cd_status_ready),state), 0, &machine); |
| 1388 | m_towns_status_timer->adjust(attotime::from_msec(1),0,attotime::never); |
| 1384 | 1389 | } |
| 1385 | 1390 | |
| 1386 | 1391 | static UINT8 towns_cd_get_track(running_machine &machine) |
| r21429 | r21430 | |
| 1431 | 1436 | if(m_towns_cd.lba_current >= m_towns_cd.lba_last) |
| 1432 | 1437 | { |
| 1433 | 1438 | m_towns_cd.extra_status = 0; |
| 1434 | | towns_cd_set_status(device->machine(),0x06,0x00,0x00,0x00); |
| 1439 | towns_cd_set_status(0x06,0x00,0x00,0x00); |
| 1435 | 1440 | towns_cdrom_set_irq(device->machine(),TOWNS_CD_IRQ_DMA,1); |
| 1436 | 1441 | m_towns_cd.buffer_ptr = -1; |
| 1437 | 1442 | m_towns_cd.status |= 0x01; // ready |
| r21429 | r21430 | |
| 1439 | 1444 | else |
| 1440 | 1445 | { |
| 1441 | 1446 | m_towns_cd.extra_status = 0; |
| 1442 | | towns_cd_set_status(device->machine(),0x22,0x00,0x00,0x00); |
| 1447 | towns_cd_set_status(0x22,0x00,0x00,0x00); |
| 1443 | 1448 | towns_cdrom_set_irq(device->machine(),TOWNS_CD_IRQ_DMA,1); |
| 1444 | 1449 | cdrom_read_data(m_cdrom->get_cdrom_file(),++m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1); |
| 1445 | 1450 | m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); |
| r21429 | r21430 | |
| 1465 | 1470 | if(m_towns_cd.lba_current >= m_towns_cd.lba_last) |
| 1466 | 1471 | { |
| 1467 | 1472 | m_towns_cd.extra_status = 0; |
| 1468 | | towns_cd_set_status(machine(),0x06,0x00,0x00,0x00); |
| 1473 | towns_cd_set_status(0x06,0x00,0x00,0x00); |
| 1469 | 1474 | towns_cdrom_set_irq(machine(),TOWNS_CD_IRQ_DMA,1); |
| 1470 | 1475 | m_towns_cd.buffer_ptr = -1; |
| 1471 | 1476 | m_towns_cd.status |= 0x01; // ready |
| r21429 | r21430 | |
| 1474 | 1479 | { |
| 1475 | 1480 | cdrom_read_data(m_cdrom->get_cdrom_file(),++m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1); |
| 1476 | 1481 | m_towns_cd.extra_status = 0; |
| 1477 | | towns_cd_set_status(machine(),0x21,0x00,0x00,0x00); |
| 1482 | towns_cd_set_status(0x21,0x00,0x00,0x00); |
| 1478 | 1483 | towns_cdrom_set_irq(machine(),TOWNS_CD_IRQ_DMA,1); |
| 1479 | 1484 | m_towns_cd.status &= ~0x10; |
| 1480 | 1485 | m_towns_cd.status |= 0x20; |
| r21429 | r21430 | |
| 1484 | 1489 | return ret; |
| 1485 | 1490 | } |
| 1486 | 1491 | |
| 1487 | | static void towns_cdrom_read(cdrom_image_device* device) |
| 1492 | void towns_state::towns_cdrom_read(cdrom_image_device* device) |
| 1488 | 1493 | { |
| 1489 | 1494 | // MODE 1 read |
| 1490 | 1495 | // load data into buffer to be sent via DMA1 channel 3 |
| r21429 | r21430 | |
| 1493 | 1498 | // parameters: |
| 1494 | 1499 | // 3 bytes: MSF of first sector to read |
| 1495 | 1500 | // 3 bytes: MSF of last sector to read |
| 1496 | | towns_state* state = device->machine().driver_data<towns_state>(); |
| 1497 | 1501 | UINT32 lba1,lba2,track; |
| 1498 | 1502 | |
| 1499 | | lba1 = state->m_towns_cd.parameter[7] << 16; |
| 1500 | | lba1 += state->m_towns_cd.parameter[6] << 8; |
| 1501 | | lba1 += state->m_towns_cd.parameter[5]; |
| 1502 | | lba2 = state->m_towns_cd.parameter[4] << 16; |
| 1503 | | lba2 += state->m_towns_cd.parameter[3] << 8; |
| 1504 | | lba2 += state->m_towns_cd.parameter[2]; |
| 1505 | | state->m_towns_cd.lba_current = msf_to_lbafm(lba1); |
| 1506 | | state->m_towns_cd.lba_last = msf_to_lbafm(lba2); |
| 1503 | lba1 = m_towns_cd.parameter[7] << 16; |
| 1504 | lba1 += m_towns_cd.parameter[6] << 8; |
| 1505 | lba1 += m_towns_cd.parameter[5]; |
| 1506 | lba2 = m_towns_cd.parameter[4] << 16; |
| 1507 | lba2 += m_towns_cd.parameter[3] << 8; |
| 1508 | lba2 += m_towns_cd.parameter[2]; |
| 1509 | m_towns_cd.lba_current = msf_to_lbafm(lba1); |
| 1510 | m_towns_cd.lba_last = msf_to_lbafm(lba2); |
| 1507 | 1511 | |
| 1508 | 1512 | // first track starts at 00:02:00 - this is hardcoded in the boot procedure |
| 1509 | | track = cdrom_get_track(device->get_cdrom_file(),state->m_towns_cd.lba_current); |
| 1513 | track = cdrom_get_track(device->get_cdrom_file(),m_towns_cd.lba_current); |
| 1510 | 1514 | if(track < 2) |
| 1511 | 1515 | { // recalculate LBA |
| 1512 | | state->m_towns_cd.lba_current -= 150; |
| 1513 | | state->m_towns_cd.lba_last -= 150; |
| 1516 | m_towns_cd.lba_current -= 150; |
| 1517 | m_towns_cd.lba_last -= 150; |
| 1514 | 1518 | } |
| 1515 | 1519 | |
| 1516 | 1520 | // parameter 7 = sector count? |
| 1517 | | if(state->m_towns_cd.parameter[1] != 0) |
| 1518 | | state->m_towns_cd.lba_last += state->m_towns_cd.parameter[1]; |
| 1521 | if(m_towns_cd.parameter[1] != 0) |
| 1522 | m_towns_cd.lba_last += m_towns_cd.parameter[1]; |
| 1519 | 1523 | |
| 1520 | | logerror("CD: Mode 1 read from LBA next:%i last:%i track:%i\n",state->m_towns_cd.lba_current,state->m_towns_cd.lba_last,track); |
| 1524 | logerror("CD: Mode 1 read from LBA next:%i last:%i track:%i\n",m_towns_cd.lba_current,m_towns_cd.lba_last,track); |
| 1521 | 1525 | |
| 1522 | | if(state->m_towns_cd.lba_current > state->m_towns_cd.lba_last) |
| 1526 | if(m_towns_cd.lba_current > m_towns_cd.lba_last) |
| 1523 | 1527 | { |
| 1524 | | state->m_towns_cd.extra_status = 0; |
| 1525 | | towns_cd_set_status(device->machine(),0x01,0x00,0x00,0x00); |
| 1528 | m_towns_cd.extra_status = 0; |
| 1529 | towns_cd_set_status(0x01,0x00,0x00,0x00); |
| 1526 | 1530 | } |
| 1527 | 1531 | else |
| 1528 | 1532 | { |
| 1529 | | cdrom_read_data(device->get_cdrom_file(),state->m_towns_cd.lba_current,state->m_towns_cd.buffer,CD_TRACK_MODE1); |
| 1530 | | if(state->m_towns_cd.software_tx) |
| 1533 | cdrom_read_data(device->get_cdrom_file(),m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1); |
| 1534 | if(m_towns_cd.software_tx) |
| 1531 | 1535 | { |
| 1532 | | state->m_towns_cd.status &= ~0x10; // not a DMA transfer |
| 1533 | | state->m_towns_cd.status |= 0x20; // software transfer |
| 1536 | m_towns_cd.status &= ~0x10; // not a DMA transfer |
| 1537 | m_towns_cd.status |= 0x20; // software transfer |
| 1534 | 1538 | } |
| 1535 | 1539 | else |
| 1536 | 1540 | { |
| 1537 | | state->m_towns_cd.status |= 0x10; // DMA transfer begin |
| 1538 | | state->m_towns_cd.status &= ~0x20; // not a software transfer |
| 1541 | m_towns_cd.status |= 0x10; // DMA transfer begin |
| 1542 | m_towns_cd.status &= ~0x20; // not a software transfer |
| 1539 | 1543 | } |
| 1540 | | // state->m_towns_cd.buffer_ptr = 0; |
| 1541 | | // state->m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); |
| 1542 | | if(state->m_towns_cd.command & 0x20) |
| 1544 | // m_towns_cd.buffer_ptr = 0; |
| 1545 | // m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1); |
| 1546 | if(m_towns_cd.command & 0x20) |
| 1543 | 1547 | { |
| 1544 | | state->m_towns_cd.extra_status = 2; |
| 1545 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1548 | m_towns_cd.extra_status = 2; |
| 1549 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1546 | 1550 | } |
| 1547 | 1551 | else |
| 1548 | 1552 | { |
| 1549 | | state->m_towns_cd.extra_status = 0; |
| 1550 | | if(state->m_towns_cd.software_tx) |
| 1551 | | towns_cd_set_status(device->machine(),0x21,0x00,0x00,0x00); |
| 1553 | m_towns_cd.extra_status = 0; |
| 1554 | if(m_towns_cd.software_tx) |
| 1555 | towns_cd_set_status(0x21,0x00,0x00,0x00); |
| 1552 | 1556 | else |
| 1553 | | towns_cd_set_status(device->machine(),0x22,0x00,0x00,0x00); |
| 1557 | towns_cd_set_status(0x22,0x00,0x00,0x00); |
| 1554 | 1558 | } |
| 1555 | 1559 | } |
| 1556 | 1560 | } |
| 1557 | 1561 | |
| 1558 | | static void towns_cdrom_play_cdda(cdrom_image_device* device) |
| 1562 | void towns_state::towns_cdrom_play_cdda(cdrom_image_device* device) |
| 1559 | 1563 | { |
| 1560 | 1564 | // PLAY AUDIO |
| 1561 | 1565 | // Plays CD-DA audio from the specified MSF |
| 1562 | 1566 | // Parameters: |
| 1563 | 1567 | // 3 bytes: starting MSF of audio to play |
| 1564 | 1568 | // 3 bytes: ending MSF of audio to play (can span multiple tracks) |
| 1565 | | towns_state* state = device->machine().driver_data<towns_state>(); |
| 1566 | 1569 | UINT32 lba1,lba2; |
| 1567 | | device_t* cdda = state->m_cdda; |
| 1568 | 1570 | |
| 1569 | | lba1 = state->m_towns_cd.parameter[7] << 16; |
| 1570 | | lba1 += state->m_towns_cd.parameter[6] << 8; |
| 1571 | | lba1 += state->m_towns_cd.parameter[5]; |
| 1572 | | lba2 = state->m_towns_cd.parameter[4] << 16; |
| 1573 | | lba2 += state->m_towns_cd.parameter[3] << 8; |
| 1574 | | lba2 += state->m_towns_cd.parameter[2]; |
| 1575 | | state->m_towns_cd.cdda_current = msf_to_lbafm(lba1); |
| 1576 | | state->m_towns_cd.cdda_length = msf_to_lbafm(lba2) - state->m_towns_cd.cdda_current; |
| 1571 | lba1 = m_towns_cd.parameter[7] << 16; |
| 1572 | lba1 += m_towns_cd.parameter[6] << 8; |
| 1573 | lba1 += m_towns_cd.parameter[5]; |
| 1574 | lba2 = m_towns_cd.parameter[4] << 16; |
| 1575 | lba2 += m_towns_cd.parameter[3] << 8; |
| 1576 | lba2 += m_towns_cd.parameter[2]; |
| 1577 | m_towns_cd.cdda_current = msf_to_lbafm(lba1); |
| 1578 | m_towns_cd.cdda_length = msf_to_lbafm(lba2) - m_towns_cd.cdda_current; |
| 1577 | 1579 | |
| 1578 | | cdda_set_cdrom(cdda,device->get_cdrom_file()); |
| 1579 | | cdda_start_audio(cdda,state->m_towns_cd.cdda_current,state->m_towns_cd.cdda_length); |
| 1580 | | logerror("CD: CD-DA start from LBA:%i length:%i\n",state->m_towns_cd.cdda_current,state->m_towns_cd.cdda_length); |
| 1581 | | if(state->m_towns_cd.command & 0x20) |
| 1580 | cdda_set_cdrom(m_cdda,device->get_cdrom_file()); |
| 1581 | cdda_start_audio(m_cdda,m_towns_cd.cdda_current,m_towns_cd.cdda_length); |
| 1582 | logerror("CD: CD-DA start from LBA:%i length:%i\n",m_towns_cd.cdda_current,m_towns_cd.cdda_length); |
| 1583 | if(m_towns_cd.command & 0x20) |
| 1582 | 1584 | { |
| 1583 | | state->m_towns_cd.extra_status = 1; |
| 1584 | | towns_cd_set_status(device->machine(),0x00,0x03,0x00,0x00); |
| 1585 | m_towns_cd.extra_status = 1; |
| 1586 | towns_cd_set_status(0x00,0x03,0x00,0x00); |
| 1585 | 1587 | } |
| 1586 | 1588 | } |
| 1587 | 1589 | |
| 1588 | | TIMER_CALLBACK_MEMBER(towns_state::towns_delay_cdda) |
| 1590 | void towns_state::towns_delay_cdda(cdrom_image_device* dev) |
| 1589 | 1591 | { |
| 1590 | | towns_cdrom_play_cdda((cdrom_image_device*)ptr); |
| 1592 | towns_cdrom_play_cdda(dev); |
| 1591 | 1593 | } |
| 1592 | 1594 | |
| 1593 | | static void towns_cdrom_execute_command(cdrom_image_device* device) |
| 1595 | void towns_state::towns_cdrom_execute_command(cdrom_image_device* device) |
| 1594 | 1596 | { |
| 1595 | | towns_state* state = device->machine().driver_data<towns_state>(); |
| 1596 | | |
| 1597 | 1597 | if(device->get_cdrom_file() == NULL) |
| 1598 | 1598 | { // No CD in drive |
| 1599 | | if(state->m_towns_cd.command & 0x20) |
| 1599 | if(m_towns_cd.command & 0x20) |
| 1600 | 1600 | { |
| 1601 | | state->m_towns_cd.extra_status = 0; |
| 1602 | | towns_cd_set_status(device->machine(),0x10,0x00,0x00,0x00); |
| 1601 | m_towns_cd.extra_status = 0; |
| 1602 | towns_cd_set_status(0x10,0x00,0x00,0x00); |
| 1603 | 1603 | } |
| 1604 | 1604 | } |
| 1605 | 1605 | else |
| 1606 | 1606 | { |
| 1607 | | state->m_towns_cd.status &= ~0x02; |
| 1608 | | switch(state->m_towns_cd.command & 0x9f) |
| 1607 | m_towns_cd.status &= ~0x02; |
| 1608 | switch(m_towns_cd.command & 0x9f) |
| 1609 | 1609 | { |
| 1610 | 1610 | case 0x00: // Seek |
| 1611 | | if(state->m_towns_cd.command & 0x20) |
| 1611 | if(m_towns_cd.command & 0x20) |
| 1612 | 1612 | { |
| 1613 | | state->m_towns_cd.extra_status = 1; |
| 1614 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1613 | m_towns_cd.extra_status = 1; |
| 1614 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1615 | 1615 | } |
| 1616 | 1616 | logerror("CD: Command 0x00: SEEK\n"); |
| 1617 | 1617 | break; |
| 1618 | 1618 | case 0x01: // unknown |
| 1619 | | if(state->m_towns_cd.command & 0x20) |
| 1619 | if(m_towns_cd.command & 0x20) |
| 1620 | 1620 | { |
| 1621 | | state->m_towns_cd.extra_status = 0; |
| 1622 | | towns_cd_set_status(device->machine(),0x00,0xff,0xff,0xff); |
| 1621 | m_towns_cd.extra_status = 0; |
| 1622 | towns_cd_set_status(0x00,0xff,0xff,0xff); |
| 1623 | 1623 | } |
| 1624 | 1624 | logerror("CD: Command 0x01: unknown\n"); |
| 1625 | 1625 | break; |
| r21429 | r21430 | |
| 1629 | 1629 | break; |
| 1630 | 1630 | case 0x04: // Play Audio Track |
| 1631 | 1631 | logerror("CD: Command 0x04: PLAY CD-DA\n"); |
| 1632 | | device->machine().scheduler().timer_set(attotime::from_msec(1), timer_expired_delegate(FUNC(towns_state::towns_delay_cdda),state), 0, device); |
| 1632 | m_towns_cdda_timer->set_ptr(device); |
| 1633 | m_towns_cdda_timer->adjust(attotime::from_msec(1),0,attotime::never); |
| 1633 | 1634 | break; |
| 1634 | 1635 | case 0x05: // Read TOC |
| 1635 | 1636 | logerror("CD: Command 0x05: READ TOC\n"); |
| 1636 | | state->m_towns_cd.extra_status = 1; |
| 1637 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1637 | m_towns_cd.extra_status = 1; |
| 1638 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1638 | 1639 | break; |
| 1639 | 1640 | case 0x06: // Read CD-DA state? |
| 1640 | 1641 | logerror("CD: Command 0x06: READ CD-DA STATE\n"); |
| 1641 | | state->m_towns_cd.extra_status = 1; |
| 1642 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1642 | m_towns_cd.extra_status = 1; |
| 1643 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1643 | 1644 | break; |
| 1644 | 1645 | case 0x80: // set state |
| 1645 | 1646 | logerror("CD: Command 0x80: set state\n"); |
| 1646 | | if(state->m_towns_cd.command & 0x20) |
| 1647 | if(m_towns_cd.command & 0x20) |
| 1647 | 1648 | { |
| 1648 | | state->m_towns_cd.extra_status = 0; |
| 1649 | | if(cdda_audio_active(state->m_cdda) && !cdda_audio_paused(state->m_cdda)) |
| 1650 | | towns_cd_set_status(device->machine(),0x00,0x03,0x00,0x00); |
| 1649 | m_towns_cd.extra_status = 0; |
| 1650 | if(cdda_audio_active(m_cdda) && !cdda_audio_paused(m_cdda)) |
| 1651 | towns_cd_set_status(0x00,0x03,0x00,0x00); |
| 1651 | 1652 | else |
| 1652 | | towns_cd_set_status(device->machine(),0x00,0x01,0x00,0x00); |
| 1653 | towns_cd_set_status(0x00,0x01,0x00,0x00); |
| 1653 | 1654 | |
| 1654 | 1655 | } |
| 1655 | 1656 | break; |
| 1656 | 1657 | case 0x81: // set state (CDDASET) |
| 1657 | | if(state->m_towns_cd.command & 0x20) |
| 1658 | if(m_towns_cd.command & 0x20) |
| 1658 | 1659 | { |
| 1659 | | state->m_towns_cd.extra_status = 0; |
| 1660 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1660 | m_towns_cd.extra_status = 0; |
| 1661 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1661 | 1662 | } |
| 1662 | 1663 | logerror("CD: Command 0x81: set state (CDDASET)\n"); |
| 1663 | 1664 | break; |
| 1664 | 1665 | case 0x84: // Stop CD audio track -- generates no status output? |
| 1665 | | if(state->m_towns_cd.command & 0x20) |
| 1666 | if(m_towns_cd.command & 0x20) |
| 1666 | 1667 | { |
| 1667 | | state->m_towns_cd.extra_status = 1; |
| 1668 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1668 | m_towns_cd.extra_status = 1; |
| 1669 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1669 | 1670 | } |
| 1670 | | cdda_pause_audio(state->m_cdda,1); |
| 1671 | cdda_pause_audio(m_cdda,1); |
| 1671 | 1672 | logerror("CD: Command 0x84: STOP CD-DA\n"); |
| 1672 | 1673 | break; |
| 1673 | 1674 | case 0x85: // Stop CD audio track (difference from 0x84?) |
| 1674 | | if(state->m_towns_cd.command & 0x20) |
| 1675 | if(m_towns_cd.command & 0x20) |
| 1675 | 1676 | { |
| 1676 | | state->m_towns_cd.extra_status = 1; |
| 1677 | | towns_cd_set_status(device->machine(),0x00,0x00,0x00,0x00); |
| 1677 | m_towns_cd.extra_status = 1; |
| 1678 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1678 | 1679 | } |
| 1679 | | cdda_pause_audio(state->m_cdda,1); |
| 1680 | cdda_pause_audio(m_cdda,1); |
| 1680 | 1681 | logerror("CD: Command 0x85: STOP CD-DA\n"); |
| 1681 | 1682 | break; |
| 1682 | 1683 | case 0x87: // Resume CD-DA playback |
| 1683 | | if(state->m_towns_cd.command & 0x20) |
| 1684 | if(m_towns_cd.command & 0x20) |
| 1684 | 1685 | { |
| 1685 | | state->m_towns_cd.extra_status = 1; |
| 1686 | | towns_cd_set_status(device->machine(),0x00,0x03,0x00,0x00); |
| 1686 | m_towns_cd.extra_status = 1; |
| 1687 | towns_cd_set_status(0x00,0x03,0x00,0x00); |
| 1687 | 1688 | } |
| 1688 | | cdda_pause_audio(state->m_cdda,0); |
| 1689 | cdda_pause_audio(m_cdda,0); |
| 1689 | 1690 | logerror("CD: Command 0x87: RESUME CD-DA\n"); |
| 1690 | 1691 | break; |
| 1691 | 1692 | default: |
| 1692 | | state->m_towns_cd.extra_status = 0; |
| 1693 | | towns_cd_set_status(device->machine(),0x10,0x00,0x00,0x00); |
| 1694 | | logerror("CD: Unknown or unimplemented command %02x\n",state->m_towns_cd.command); |
| 1693 | m_towns_cd.extra_status = 0; |
| 1694 | towns_cd_set_status(0x10,0x00,0x00,0x00); |
| 1695 | logerror("CD: Unknown or unimplemented command %02x\n",m_towns_cd.command); |
| 1695 | 1696 | } |
| 1696 | 1697 | } |
| 1697 | 1698 | } |
| r21429 | r21430 | |
| 1726 | 1727 | switch(m_towns_cd.command & 0x9f) |
| 1727 | 1728 | { |
| 1728 | 1729 | case 0x00: // seek |
| 1729 | | towns_cd_set_status(space.machine(),0x04,0x00,0x00,0x00); |
| 1730 | towns_cd_set_status(0x04,0x00,0x00,0x00); |
| 1730 | 1731 | m_towns_cd.extra_status = 0; |
| 1731 | 1732 | break; |
| 1732 | 1733 | case 0x02: // read |
| 1733 | 1734 | if(m_towns_cd.extra_status == 2) |
| 1734 | | towns_cd_set_status(space.machine(),0x22,0x00,0x00,0x00); |
| 1735 | towns_cd_set_status(0x22,0x00,0x00,0x00); |
| 1735 | 1736 | m_towns_cd.extra_status = 0; |
| 1736 | 1737 | break; |
| 1737 | 1738 | case 0x04: // play cdda |
| 1738 | | towns_cd_set_status(space.machine(),0x07,0x00,0x00,0x00); |
| 1739 | towns_cd_set_status(0x07,0x00,0x00,0x00); |
| 1739 | 1740 | m_towns_cd.extra_status = 0; |
| 1740 | 1741 | break; |
| 1741 | 1742 | case 0x05: // read toc |
| r21429 | r21430 | |
| 1743 | 1744 | { |
| 1744 | 1745 | case 1: |
| 1745 | 1746 | case 3: |
| 1746 | | towns_cd_set_status(space.machine(),0x16,0x00,0x00,0x00); |
| 1747 | towns_cd_set_status(0x16,0x00,0x00,0x00); |
| 1747 | 1748 | m_towns_cd.extra_status++; |
| 1748 | 1749 | break; |
| 1749 | 1750 | case 2: // st1 = first track number (BCD) |
| 1750 | | towns_cd_set_status(space.machine(),0x17,0x01,0x00,0x00); |
| 1751 | towns_cd_set_status(0x17,0x01,0x00,0x00); |
| 1751 | 1752 | m_towns_cd.extra_status++; |
| 1752 | 1753 | break; |
| 1753 | 1754 | case 4: // st1 = last track number (BCD) |
| 1754 | | towns_cd_set_status(space.machine(),0x17, |
| 1755 | towns_cd_set_status(0x17, |
| 1755 | 1756 | byte_to_bcd(cdrom_get_last_track(m_cdrom->get_cdrom_file())), |
| 1756 | 1757 | 0x00,0x00); |
| 1757 | 1758 | m_towns_cd.extra_status++; |
| 1758 | 1759 | break; |
| 1759 | 1760 | case 5: // st1 = control/adr of track 0xaa? |
| 1760 | | towns_cd_set_status(space.machine(),0x16, |
| 1761 | towns_cd_set_status(0x16, |
| 1761 | 1762 | cdrom_get_adr_control(m_cdrom->get_cdrom_file(),0xaa), |
| 1762 | 1763 | 0xaa,0x00); |
| 1763 | 1764 | m_towns_cd.extra_status++; |
| r21429 | r21430 | |
| 1765 | 1766 | case 6: // st1/2/3 = address of track 0xaa? (BCD) |
| 1766 | 1767 | addr = cdrom_get_track_start(m_cdrom->get_cdrom_file(),0xaa); |
| 1767 | 1768 | addr = lba_to_msf(addr); |
| 1768 | | towns_cd_set_status(space.machine(),0x17, |
| 1769 | towns_cd_set_status(0x17, |
| 1769 | 1770 | (addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff); |
| 1770 | 1771 | m_towns_cd.extra_status++; |
| 1771 | 1772 | break; |
| 1772 | 1773 | default: // same as case 5 and 6, but for each individual track |
| 1773 | 1774 | if(m_towns_cd.extra_status & 0x01) |
| 1774 | 1775 | { |
| 1775 | | towns_cd_set_status(space.machine(),0x16, |
| 1776 | towns_cd_set_status(0x16, |
| 1776 | 1777 | ((cdrom_get_adr_control(m_cdrom->get_cdrom_file(),(m_towns_cd.extra_status/2)-3) & 0x0f) << 4) |
| 1777 | 1778 | | ((cdrom_get_adr_control(m_cdrom->get_cdrom_file(),(m_towns_cd.extra_status/2)-3) & 0xf0) >> 4), |
| 1778 | 1779 | (m_towns_cd.extra_status/2)-3,0x00); |
| r21429 | r21430 | |
| 1782 | 1783 | { |
| 1783 | 1784 | addr = cdrom_get_track_start(m_cdrom->get_cdrom_file(),(m_towns_cd.extra_status/2)-4); |
| 1784 | 1785 | addr = lba_to_msf(addr); |
| 1785 | | towns_cd_set_status(space.machine(),0x17, |
| 1786 | towns_cd_set_status(0x17, |
| 1786 | 1787 | (addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff); |
| 1787 | 1788 | if(((m_towns_cd.extra_status/2)-3) >= cdrom_get_last_track(m_cdrom->get_cdrom_file())) |
| 1788 | 1789 | { |
| r21429 | r21430 | |
| 1798 | 1799 | switch(m_towns_cd.extra_status) |
| 1799 | 1800 | { |
| 1800 | 1801 | case 1: // st2 = track number |
| 1801 | | towns_cd_set_status(space.machine(),0x18, |
| 1802 | towns_cd_set_status(0x18, |
| 1802 | 1803 | 0x00,towns_cd_get_track(space.machine()),0x00); |
| 1803 | 1804 | m_towns_cd.extra_status++; |
| 1804 | 1805 | break; |
| 1805 | 1806 | case 2: // st0/1/2 = MSF from beginning of current track |
| 1806 | 1807 | addr = cdda_get_audio_lba(m_cdda); |
| 1807 | 1808 | addr = lba_to_msf(addr - m_towns_cd.cdda_current); |
| 1808 | | towns_cd_set_status(space.machine(),0x19, |
| 1809 | towns_cd_set_status(0x19, |
| 1809 | 1810 | (addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff); |
| 1810 | 1811 | m_towns_cd.extra_status++; |
| 1811 | 1812 | break; |
| 1812 | 1813 | case 3: // st1/2 = current MSF |
| 1813 | 1814 | addr = cdda_get_audio_lba(m_cdda); |
| 1814 | 1815 | addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found |
| 1815 | | towns_cd_set_status(space.machine(),0x19, |
| 1816 | towns_cd_set_status(0x19, |
| 1816 | 1817 | 0x00,(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8); |
| 1817 | 1818 | m_towns_cd.extra_status++; |
| 1818 | 1819 | break; |
| 1819 | 1820 | case 4: |
| 1820 | 1821 | addr = cdda_get_audio_lba(m_cdda); |
| 1821 | 1822 | addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found |
| 1822 | | towns_cd_set_status(space.machine(),0x20, |
| 1823 | towns_cd_set_status(0x20, |
| 1823 | 1824 | addr & 0x0000ff,0x00,0x00); |
| 1824 | 1825 | m_towns_cd.extra_status = 0; |
| 1825 | 1826 | break; |
| 1826 | 1827 | } |
| 1827 | 1828 | break; |
| 1828 | 1829 | case 0x84: |
| 1829 | | towns_cd_set_status(space.machine(),0x11,0x00,0x00,0x00); |
| 1830 | towns_cd_set_status(0x11,0x00,0x00,0x00); |
| 1830 | 1831 | m_towns_cd.extra_status = 0; |
| 1831 | 1832 | break; |
| 1832 | 1833 | case 0x85: |
| 1833 | | towns_cd_set_status(space.machine(),0x12,0x00,0x00,0x00); |
| 1834 | towns_cd_set_status(0x12,0x00,0x00,0x00); |
| 1834 | 1835 | m_towns_cd.extra_status = 0; |
| 1835 | 1836 | break; |
| 1836 | 1837 | } |
| r21429 | r21430 | |
| 2564 | 2565 | m_towns_wait_timer = timer_alloc(TIMER_WAIT); |
| 2565 | 2566 | m_towns_freerun_counter = timer_alloc(TIMER_FREERUN); |
| 2566 | 2567 | m_towns_intervaltimer2 = timer_alloc(TIMER_INTERVAL2); |
| 2568 | m_towns_status_timer = timer_alloc(TIMER_CDSTATUS); |
| 2569 | m_towns_cdda_timer = timer_alloc(TIMER_CDDA); |
| 2567 | 2570 | |
| 2568 | 2571 | // CD-ROM init |
| 2569 | 2572 | m_towns_cd.read_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(towns_state::towns_cdrom_read_byte),this), (void*)machine().device("dma_1")); |
| r21429 | r21430 | |
| 2856 | 2859 | |
| 2857 | 2860 | static MACHINE_CONFIG_DERIVED( townssj, towns ) |
| 2858 | 2861 | |
| 2859 | | MCFG_CPU_REPLACE("maincpu",I486, 66000000) |
| 2862 | MCFG_CPU_REPLACE("maincpu",PENTIUM, 66000000) |
| 2860 | 2863 | MCFG_CPU_PROGRAM_MAP(towns_mem) |
| 2861 | 2864 | MCFG_CPU_IO_MAP(towns_io) |
| 2862 | 2865 | MCFG_CPU_VBLANK_INT_DRIVER("screen", towns_state, towns_vsync_irq) |