trunk/src/mame/machine/stvcd.c
| r20800 | r20801 | |
| 23 | 23 | |
| 24 | 24 | #include "emu.h" |
| 25 | 25 | #include "imagedev/chd_cd.h" |
| 26 | #include "includes/stv.h" |
| 26 | 27 | #include "cdrom.h" |
| 27 | 28 | #include "stvcd.h" |
| 28 | 29 | #include "sound/cdda.h" |
| r20800 | r20801 | |
| 36 | 37 | #define CDROM_LOG(x) |
| 37 | 38 | #endif |
| 38 | 39 | |
| 39 | | static cdrom_file *cdrom = (cdrom_file *)NULL; |
| 40 | | |
| 41 | | static void cd_readTOC(void); |
| 42 | | static void cd_readblock(UINT32 fad, UINT8 *dat); |
| 43 | | static void cd_playdata(running_machine &machine); |
| 44 | | |
| 45 | | #define MAX_FILTERS (24) |
| 46 | | #define MAX_BLOCKS (200) |
| 47 | | #define MAX_DIR_SIZE (256*1024) |
| 48 | | |
| 49 | | struct direntryT |
| 50 | | { |
| 51 | | UINT8 record_size; |
| 52 | | UINT8 xa_record_size; |
| 53 | | UINT32 firstfad; // first sector of file |
| 54 | | UINT32 length; // length of file |
| 55 | | UINT8 year; |
| 56 | | UINT8 month; |
| 57 | | UINT8 day; |
| 58 | | UINT8 hour; |
| 59 | | UINT8 minute; |
| 60 | | UINT8 second; |
| 61 | | UINT8 gmt_offset; |
| 62 | | UINT8 flags; // iso9660 flags |
| 63 | | UINT8 file_unit_size; |
| 64 | | UINT8 interleave_gap_size; |
| 65 | | UINT16 volume_sequencer_number; |
| 66 | | UINT8 name[128]; |
| 67 | | }; |
| 68 | | |
| 69 | | struct filterT |
| 70 | | { |
| 71 | | UINT8 mode; |
| 72 | | UINT8 chan; |
| 73 | | UINT8 smmask; |
| 74 | | UINT8 cimask; |
| 75 | | UINT8 fid; |
| 76 | | UINT8 smval; |
| 77 | | UINT8 cival; |
| 78 | | UINT8 condtrue; |
| 79 | | UINT8 condfalse; |
| 80 | | UINT32 fad; |
| 81 | | UINT32 range; |
| 82 | | }; |
| 83 | | |
| 84 | | struct blockT |
| 85 | | { |
| 86 | | INT32 size; // size of block |
| 87 | | INT32 FAD; // FAD on disc |
| 88 | | UINT8 data[CD_MAX_SECTOR_DATA]; |
| 89 | | UINT8 chan; // channel |
| 90 | | UINT8 fnum; // file number |
| 91 | | UINT8 subm; // subchannel mode |
| 92 | | UINT8 cinf; // coding information |
| 93 | | }; |
| 94 | | |
| 95 | | struct partitionT |
| 96 | | { |
| 97 | | INT32 size; |
| 98 | | blockT *blocks[MAX_BLOCKS]; |
| 99 | | UINT8 bnum[MAX_BLOCKS]; |
| 100 | | UINT8 numblks; |
| 101 | | }; |
| 102 | | |
| 103 | | // 16-bit transfer types |
| 104 | | enum transT |
| 105 | | { |
| 106 | | XFERTYPE_INVALID, |
| 107 | | XFERTYPE_TOC, |
| 108 | | XFERTYPE_FILEINFO_1, |
| 109 | | XFERTYPE_FILEINFO_254, |
| 110 | | XFERTYPE_SUBQ, |
| 111 | | XFERTYPE_SUBRW |
| 112 | | }; |
| 113 | | |
| 114 | | // 32-bit transfer types |
| 115 | | enum trans32T |
| 116 | | { |
| 117 | | XFERTYPE32_INVALID, |
| 118 | | XFERTYPE32_GETSECTOR, |
| 119 | | XFERTYPE32_GETDELETESECTOR |
| 120 | | }; |
| 121 | | |
| 122 | | // local variables |
| 123 | | static timer_device *sector_timer; |
| 124 | | static timer_device *sh1_timer; |
| 125 | | static partitionT partitions[MAX_FILTERS]; |
| 126 | | static partitionT *transpart; |
| 127 | | |
| 128 | | static blockT blocks[MAX_BLOCKS]; |
| 129 | | static blockT curblock; |
| 130 | | |
| 131 | | static UINT8 tocbuf[102*4]; |
| 132 | | static UINT8 subqbuf[5*2]; |
| 133 | | static UINT8 subrwbuf[12*2]; |
| 134 | | static UINT8 finfbuf[256]; |
| 135 | | |
| 136 | | static INT32 sectlenin, sectlenout; |
| 137 | | |
| 138 | | static UINT8 lastbuf, playtype; |
| 139 | | |
| 140 | | static transT xfertype; |
| 141 | | static trans32T xfertype32; |
| 142 | | static UINT32 xfercount, calcsize; |
| 143 | | static UINT32 xferoffs, xfersect, xfersectpos, xfersectnum, xferdnum; |
| 144 | | |
| 145 | | static filterT filters[MAX_FILTERS]; |
| 146 | | static filterT *cddevice; |
| 147 | | static int cddevicenum; |
| 148 | | |
| 149 | | static UINT16 cr1, cr2, cr3, cr4; |
| 150 | | static UINT16 hirqmask, hirqreg; |
| 151 | | static UINT16 cd_stat; |
| 152 | | static UINT32 cd_curfad = 0; |
| 153 | | static UINT32 fadstoplay = 0; |
| 154 | | static UINT32 in_buffer = 0; // amount of data in the buffer |
| 155 | | static int oddframe = 0; |
| 156 | | static int buffull, sectorstore, freeblocks; |
| 157 | | static int cur_track; |
| 158 | | static UINT8 cmd_pending; |
| 159 | | static UINT8 cd_speed; |
| 160 | | static UINT8 cdda_maxrepeat; |
| 161 | | static UINT8 cdda_repeat_count; |
| 162 | | static UINT8 tray_is_closed; |
| 163 | | |
| 164 | | // iso9660 utilities |
| 165 | | static void read_new_dir(running_machine &machine, UINT32 fileno); |
| 166 | | static void make_dir_current(running_machine &machine, UINT32 fad); |
| 167 | | |
| 168 | | static direntryT curroot; // root entry of current filesystem |
| 169 | | static direntryT *curdir; // current directory |
| 170 | | static int numfiles; // # of entries in current directory |
| 171 | | static int firstfile; // first non-directory file |
| 172 | | |
| 173 | 40 | // HIRQ definitions |
| 174 | 41 | #define CMOK 0x0001 // command dispatch possible |
| 175 | 42 | #define DRDY 0x0002 // data transfer preparations complete |
| r20800 | r20801 | |
| 205 | 72 | #define CD_STAT_REJECT 0xff00 // ultra-fatal error. |
| 206 | 73 | |
| 207 | 74 | /* FIXME: assume Saturn CD-ROMs to have a 2 secs pre-gap for now. */ |
| 208 | | static int get_track_index(void) |
| 75 | int saturn_state::get_track_index(void) |
| 209 | 76 | { |
| 210 | 77 | UINT32 rel_fad; |
| 211 | 78 | UINT8 track; |
| r20800 | r20801 | |
| 223 | 90 | return 1; |
| 224 | 91 | } |
| 225 | 92 | |
| 226 | | static void cr_standard_return(UINT16 cur_status) |
| 93 | void saturn_state::cr_standard_return(UINT16 cur_status) |
| 227 | 94 | { |
| 228 | 95 | cr1 = cur_status | (playtype << 7) | 0x00 | (cdda_repeat_count & 0xf); //options << 4 | repeat & 0xf |
| 229 | 96 | cr2 = (cur_track == 0xff) ? 0xffff : (cdrom_get_adr_control(cdrom, cur_track)<<8 | cur_track); // TODO: fix current track |
| r20800 | r20801 | |
| 232 | 99 | cd_stat |= CD_STAT_PERI; |
| 233 | 100 | } |
| 234 | 101 | |
| 235 | | static void cd_free_block(blockT *blktofree); |
| 236 | | static void cd_defragblocks(partitionT *part); |
| 237 | | static void cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum); |
| 238 | | |
| 239 | | static void cd_exec_command(running_machine &machine) |
| 102 | void saturn_state::cd_exec_command( void ) |
| 240 | 103 | { |
| 241 | 104 | UINT32 temp; |
| 242 | 105 | |
| r20800 | r20801 | |
| 537 | 400 | // cdda |
| 538 | 401 | if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) == CD_TRACK_AUDIO) |
| 539 | 402 | { |
| 540 | | cdda_pause_audio( machine.device( "cdda" ), 0 ); |
| 403 | cdda_pause_audio( machine().device( "cdda" ), 0 ); |
| 541 | 404 | //cdda_start_audio( machine.device( "cdda" ), cd_curfad, fadstoplay ); |
| 542 | 405 | //cdda_repeat_count = 0; |
| 543 | 406 | } |
| r20800 | r20801 | |
| 564 | 427 | if (temp == 0xffffff) |
| 565 | 428 | { |
| 566 | 429 | cd_stat = CD_STAT_PAUSE; |
| 567 | | cdda_pause_audio( machine.device( "cdda" ), 1 ); |
| 430 | cdda_pause_audio( machine().device( "cdda" ), 1 ); |
| 568 | 431 | } |
| 569 | 432 | else |
| 570 | 433 | { |
| r20800 | r20801 | |
| 580 | 443 | cd_stat = CD_STAT_PAUSE; |
| 581 | 444 | cur_track = cr2>>8;; |
| 582 | 445 | cd_curfad = cdrom_get_track_start(cdrom, cur_track-1); |
| 583 | | cdda_pause_audio( machine.device( "cdda" ), 1 ); |
| 446 | cdda_pause_audio( machine().device( "cdda" ), 1 ); |
| 584 | 447 | // (index is cr2 low byte) |
| 585 | 448 | } |
| 586 | 449 | else // error! |
| r20800 | r20801 | |
| 588 | 451 | cd_stat = CD_STAT_STANDBY; |
| 589 | 452 | cd_curfad = 0xffffffff; |
| 590 | 453 | cur_track = 0xff; |
| 591 | | cdda_stop_audio( machine.device( "cdda" ) ); //stop any pending CD-DA |
| 454 | cdda_stop_audio( machine().device( "cdda" ) ); //stop any pending CD-DA |
| 592 | 455 | } |
| 593 | 456 | } |
| 594 | 457 | |
| r20800 | r20801 | |
| 1224 | 1087 | temp = (cr3&0xff)<<16; |
| 1225 | 1088 | temp |= cr4; |
| 1226 | 1089 | |
| 1227 | | read_new_dir(machine, temp); |
| 1090 | read_new_dir(temp); |
| 1228 | 1091 | cr_standard_return(cd_stat); |
| 1229 | 1092 | break; |
| 1230 | 1093 | |
| r20800 | r20801 | |
| 1240 | 1103 | cddevice = (filterT *)NULL; |
| 1241 | 1104 | |
| 1242 | 1105 | /* TODO: */ |
| 1243 | | //read_new_dir(machine, read_dir - 2); |
| 1106 | //read_new_dir(read_dir - 2); |
| 1244 | 1107 | |
| 1245 | 1108 | cr_standard_return(cd_stat); |
| 1246 | 1109 | hirqreg |= (CMOK|EFLS); |
| r20800 | r20801 | |
| 1387 | 1250 | } |
| 1388 | 1251 | } |
| 1389 | 1252 | |
| 1390 | | TIMER_DEVICE_CALLBACK( stv_sh1_sim ) |
| 1253 | TIMER_DEVICE_CALLBACK_MEMBER( saturn_state::stv_sh1_sim ) |
| 1391 | 1254 | { |
| 1392 | 1255 | sh1_timer->adjust(attotime::from_hz(16667)); |
| 1393 | 1256 | |
| 1394 | 1257 | if((cmd_pending == 0xf) && (!(hirqreg & CMOK))) |
| 1395 | 1258 | { |
| 1396 | | cd_exec_command(timer.machine()); |
| 1259 | cd_exec_command(); |
| 1397 | 1260 | return; |
| 1398 | 1261 | } |
| 1399 | 1262 | |
| r20800 | r20801 | |
| 1408 | 1271 | } |
| 1409 | 1272 | } |
| 1410 | 1273 | |
| 1411 | | TIMER_DEVICE_CALLBACK( stv_sector_cb ) |
| 1274 | TIMER_DEVICE_CALLBACK_MEMBER( saturn_state::stv_sector_cb ) |
| 1412 | 1275 | { |
| 1413 | 1276 | //sector_timer->reset(); |
| 1414 | 1277 | |
| 1415 | 1278 | //popmessage("%08x %08x %d %d",cd_curfad,fadstoplay,cmd_pending,cd_speed); |
| 1416 | 1279 | |
| 1417 | | cd_playdata(timer.machine()); |
| 1280 | cd_playdata(); |
| 1418 | 1281 | |
| 1419 | 1282 | if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) == CD_TRACK_AUDIO) |
| 1420 | 1283 | sector_timer->adjust(attotime::from_hz(75)); // 75 sectors / second = 150kBytes/second (cdda track ignores cd_speed setting) |
| r20800 | r20801 | |
| 1423 | 1286 | } |
| 1424 | 1287 | |
| 1425 | 1288 | // global functions |
| 1426 | | void stvcd_reset(running_machine &machine) |
| 1289 | void saturn_state::stvcd_reset( void ) |
| 1427 | 1290 | { |
| 1428 | 1291 | INT32 i, j; |
| 1429 | 1292 | |
| r20800 | r20801 | |
| 1438 | 1301 | cur_track = 0xff; |
| 1439 | 1302 | |
| 1440 | 1303 | if (curdir != (direntryT *)NULL) |
| 1441 | | auto_free(machine, curdir); |
| 1304 | auto_free(machine(), curdir); |
| 1442 | 1305 | curdir = (direntryT *)NULL; // no directory yet |
| 1443 | 1306 | |
| 1444 | 1307 | xfertype = XFERTYPE_INVALID; |
| r20800 | r20801 | |
| 1480 | 1343 | cdrom = (cdrom_file *)NULL; |
| 1481 | 1344 | } |
| 1482 | 1345 | |
| 1483 | | cdrom_image_device *cddevice = machine.device<cdrom_image_device>("cdrom"); |
| 1346 | cdrom_image_device *cddevice = machine().device<cdrom_image_device>("cdrom"); |
| 1484 | 1347 | if (cddevice!=NULL) |
| 1485 | 1348 | { |
| 1486 | 1349 | // MESS case |
| r20800 | r20801 | |
| 1489 | 1352 | else |
| 1490 | 1353 | { |
| 1491 | 1354 | // MAME case |
| 1492 | | cdrom = cdrom_open(get_disk_handle(machine, "cdrom")); |
| 1355 | cdrom = cdrom_open(get_disk_handle(machine(), "cdrom")); |
| 1493 | 1356 | } |
| 1494 | 1357 | |
| 1495 | | cdda_set_cdrom( machine.device("cdda"), cdrom ); |
| 1358 | cdda_set_cdrom( machine().device("cdda"), cdrom ); |
| 1496 | 1359 | |
| 1497 | 1360 | if (cdrom) |
| 1498 | 1361 | { |
| 1499 | 1362 | CDROM_LOG(("Opened CD-ROM successfully, reading root directory\n")) |
| 1500 | | read_new_dir(machine, 0xffffff); // read root directory |
| 1363 | read_new_dir(0xffffff); // read root directory |
| 1501 | 1364 | } |
| 1502 | 1365 | else |
| 1503 | 1366 | { |
| r20800 | r20801 | |
| 1508 | 1371 | cdda_repeat_count = 0; |
| 1509 | 1372 | tray_is_closed = 1; |
| 1510 | 1373 | |
| 1511 | | sector_timer = machine.device<timer_device>("sector_timer"); |
| 1374 | sector_timer = machine().device<timer_device>("sector_timer"); |
| 1512 | 1375 | sector_timer->adjust(attotime::from_hz(150)); // 150 sectors / second = 300kBytes/second |
| 1513 | | sh1_timer = machine.device<timer_device>("sh1_cmd"); |
| 1376 | sh1_timer = machine().device<timer_device>("sh1_cmd"); |
| 1514 | 1377 | sh1_timer->adjust(attotime::from_hz(16667)); |
| 1515 | 1378 | } |
| 1516 | 1379 | |
| 1517 | | static blockT *cd_alloc_block(UINT8 *blknum) |
| 1380 | saturn_state::blockT *saturn_state::cd_alloc_block(UINT8 *blknum) |
| 1518 | 1381 | { |
| 1519 | 1382 | INT32 i; |
| 1520 | 1383 | |
| r20800 | r20801 | |
| 1542 | 1405 | return (blockT *)NULL; |
| 1543 | 1406 | } |
| 1544 | 1407 | |
| 1545 | | static void cd_free_block(blockT *blktofree) |
| 1408 | void saturn_state::cd_free_block(blockT *blktofree) |
| 1546 | 1409 | { |
| 1547 | 1410 | INT32 i; |
| 1548 | 1411 | |
| r20800 | r20801 | |
| 1567 | 1430 | hirqreg &= ~BFUL; |
| 1568 | 1431 | } |
| 1569 | 1432 | |
| 1570 | | static void cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum) |
| 1433 | void saturn_state::cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum) |
| 1571 | 1434 | { |
| 1572 | 1435 | if (*sectoffs == 0xffff) |
| 1573 | 1436 | { |
| r20800 | r20801 | |
| 1580 | 1443 | } |
| 1581 | 1444 | } |
| 1582 | 1445 | |
| 1583 | | static void cd_defragblocks(partitionT *part) |
| 1446 | void saturn_state::cd_defragblocks(partitionT *part) |
| 1584 | 1447 | { |
| 1585 | 1448 | UINT32 i, j; |
| 1586 | 1449 | blockT *temp; |
| r20800 | r20801 | |
| 1604 | 1467 | } |
| 1605 | 1468 | } |
| 1606 | 1469 | |
| 1607 | | static UINT16 cd_readWord(UINT32 addr) |
| 1470 | UINT16 saturn_state::cd_readWord(UINT32 addr) |
| 1608 | 1471 | { |
| 1609 | 1472 | UINT16 rv; |
| 1610 | 1473 | |
| r20800 | r20801 | |
| 1758 | 1621 | |
| 1759 | 1622 | } |
| 1760 | 1623 | |
| 1761 | | static UINT32 cd_readLong(UINT32 addr) |
| 1624 | UINT32 saturn_state::cd_readLong(UINT32 addr) |
| 1762 | 1625 | { |
| 1763 | 1626 | UINT32 rv = 0; |
| 1764 | 1627 | |
| r20800 | r20801 | |
| 1773 | 1636 | if (xfersect < xfersectnum) |
| 1774 | 1637 | { |
| 1775 | 1638 | // get next longword |
| 1776 | | rv = transpart->blocks[xfersectpos+xfersect]->data[xferoffs]<<24 | |
| 1777 | | transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 1]<<16 | |
| 1778 | | transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 2]<<8 | |
| 1779 | | transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 3]; |
| 1639 | rv = (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 0]<<24) | |
| 1640 | (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 1]<<16) | |
| 1641 | (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 2]<<8) | |
| 1642 | (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 3]<<0); |
| 1780 | 1643 | |
| 1781 | 1644 | xferdnum += 4; |
| 1782 | 1645 | xferoffs += 4; |
| r20800 | r20801 | |
| 1831 | 1694 | } |
| 1832 | 1695 | } |
| 1833 | 1696 | |
| 1834 | | static void cd_writeWord(running_machine &machine, UINT32 addr, UINT16 data) |
| 1697 | void saturn_state::cd_writeWord(UINT32 addr, UINT16 data) |
| 1835 | 1698 | { |
| 1836 | 1699 | switch(addr & 0xffff) |
| 1837 | 1700 | { |
| 1838 | 1701 | case 0x0008: |
| 1839 | 1702 | case 0x000a: |
| 1840 | | // CDROM_LOG(("%s:WW HIRQ: %04x & %04x => %04x\n", machine.describe_context(), hirqreg, data, hirqreg & data)) |
| 1703 | // CDROM_LOG(("%s:WW HIRQ: %04x & %04x => %04x\n", machine().describe_context(), hirqreg, data, hirqreg & data)) |
| 1841 | 1704 | hirqreg &= data; |
| 1842 | 1705 | if(!(hirqreg & CMOK)) |
| 1843 | 1706 | { |
| r20800 | r20801 | |
| 1853 | 1716 | return; |
| 1854 | 1717 | case 0x0018: |
| 1855 | 1718 | case 0x001a: |
| 1856 | | // CDROM_LOG(("WW CR1: %04x\n", data)) |
| 1719 | // CDROM_LOG(("WW CR1: %04x\n", data)) |
| 1857 | 1720 | cr1 = data; |
| 1858 | 1721 | cd_stat &= ~CD_STAT_PERI; |
| 1859 | 1722 | cmd_pending |= 1; |
| 1860 | 1723 | break; |
| 1861 | 1724 | case 0x001c: |
| 1862 | 1725 | case 0x001e: |
| 1863 | | // CDROM_LOG(("WW CR2: %04x\n", data)) |
| 1726 | // CDROM_LOG(("WW CR2: %04x\n", data)) |
| 1864 | 1727 | cr2 = data; |
| 1865 | 1728 | cmd_pending |= 2; |
| 1866 | 1729 | break; |
| 1867 | 1730 | case 0x0020: |
| 1868 | 1731 | case 0x0022: |
| 1869 | | // CDROM_LOG(("WW CR3: %04x\n", data)) |
| 1732 | // CDROM_LOG(("WW CR3: %04x\n", data)) |
| 1870 | 1733 | cr3 = data; |
| 1871 | 1734 | cmd_pending |= 4; |
| 1872 | 1735 | break; |
| 1873 | 1736 | case 0x0024: |
| 1874 | 1737 | case 0x0026: |
| 1875 | | // CDROM_LOG(("WW CR4: %04x\n", data)) |
| 1738 | // CDROM_LOG(("WW CR4: %04x\n", data)) |
| 1876 | 1739 | cr4 = data; |
| 1877 | 1740 | cmd_pending |= 8; |
| 1878 | 1741 | break; |
| r20800 | r20801 | |
| 1882 | 1745 | } |
| 1883 | 1746 | } |
| 1884 | 1747 | |
| 1885 | | READ32_HANDLER( stvcd_r ) |
| 1748 | READ32_MEMBER( saturn_state::stvcd_r ) |
| 1886 | 1749 | { |
| 1887 | 1750 | UINT32 rv = 0; |
| 1888 | 1751 | |
| r20800 | r20801 | |
| 1934 | 1797 | return rv; |
| 1935 | 1798 | } |
| 1936 | 1799 | |
| 1937 | | WRITE32_HANDLER( stvcd_w ) |
| 1800 | WRITE32_MEMBER( saturn_state::stvcd_w ) |
| 1938 | 1801 | { |
| 1939 | 1802 | offset <<= 2; |
| 1940 | 1803 | |
| r20800 | r20801 | |
| 1952 | 1815 | case 0x90022: |
| 1953 | 1816 | case 0x90024: |
| 1954 | 1817 | case 0x90026: |
| 1955 | | cd_writeWord(space.machine(), offset, data>>16); |
| 1818 | cd_writeWord(offset, data>>16); |
| 1956 | 1819 | break; |
| 1957 | 1820 | |
| 1958 | 1821 | default: |
| r20800 | r20801 | |
| 1962 | 1825 | } |
| 1963 | 1826 | |
| 1964 | 1827 | // iso9660 parsing |
| 1965 | | static void read_new_dir(running_machine &machine, UINT32 fileno) |
| 1828 | void saturn_state::read_new_dir(UINT32 fileno) |
| 1966 | 1829 | { |
| 1967 | 1830 | int foundpd, i; |
| 1968 | 1831 | UINT32 cfad;//, dirfad; |
| r20800 | r20801 | |
| 2029 | 1892 | } |
| 2030 | 1893 | |
| 2031 | 1894 | // done with all that, read the root directory now |
| 2032 | | make_dir_current(machine, curroot.firstfad); |
| 1895 | make_dir_current(curroot.firstfad); |
| 2033 | 1896 | } |
| 2034 | 1897 | } |
| 2035 | 1898 | else |
| r20800 | r20801 | |
| 2038 | 1901 | { |
| 2039 | 1902 | mame_printf_error("ERROR: new directory too big (%d)!\n", curdir[fileno].length); |
| 2040 | 1903 | } |
| 2041 | | make_dir_current(machine, curdir[fileno].firstfad); |
| 1904 | make_dir_current(curdir[fileno].firstfad); |
| 2042 | 1905 | } |
| 2043 | 1906 | } |
| 2044 | 1907 | |
| 2045 | 1908 | // makes the directory pointed to by FAD current |
| 2046 | | static void make_dir_current(running_machine &machine, UINT32 fad) |
| 1909 | void saturn_state::make_dir_current(UINT32 fad) |
| 2047 | 1910 | { |
| 2048 | 1911 | int i; |
| 2049 | 1912 | UINT32 nextent, numentries; |
| r20800 | r20801 | |
| 2077 | 1940 | |
| 2078 | 1941 | if (curdir != (direntryT *)NULL) |
| 2079 | 1942 | { |
| 2080 | | auto_free(machine, curdir); |
| 1943 | auto_free(machine(), curdir); |
| 2081 | 1944 | } |
| 2082 | 1945 | |
| 2083 | | curdir = auto_alloc_array(machine, direntryT, numentries); |
| 1946 | curdir = auto_alloc_array(machine(), direntryT, numentries); |
| 2084 | 1947 | curentry = curdir; |
| 2085 | 1948 | numfiles = numentries; |
| 2086 | 1949 | |
| r20800 | r20801 | |
| 2149 | 2012 | free(sect); |
| 2150 | 2013 | } |
| 2151 | 2014 | |
| 2152 | | void stvcd_exit(running_machine& machine) |
| 2015 | void saturn_state::stvcd_exit( void ) |
| 2153 | 2016 | { |
| 2154 | 2017 | if (curdir != (direntryT *)NULL) |
| 2155 | 2018 | { |
| 2156 | | auto_free(machine, curdir); |
| 2019 | auto_free(machine(), curdir); |
| 2157 | 2020 | curdir = (direntryT *)NULL; |
| 2158 | 2021 | } |
| 2159 | 2022 | |
| 2160 | 2023 | if (cdrom) |
| 2161 | 2024 | { |
| 2162 | | cdrom_image_device *cddevice = machine.device<cdrom_image_device>("cdrom"); |
| 2025 | cdrom_image_device *cddevice = machine().device<cdrom_image_device>("cdrom"); |
| 2163 | 2026 | if (cddevice==NULL) |
| 2164 | 2027 | { |
| 2165 | 2028 | cdrom_close(cdrom); |
| r20800 | r20801 | |
| 2168 | 2031 | } |
| 2169 | 2032 | } |
| 2170 | 2033 | |
| 2171 | | static void cd_readTOC(void) |
| 2034 | void saturn_state::cd_readTOC(void) |
| 2172 | 2035 | { |
| 2173 | 2036 | int i, ntrks, tocptr, fad; |
| 2174 | 2037 | |
| r20800 | r20801 | |
| 2258 | 2121 | tocbuf[tocptr+11] = fad&0xff; |
| 2259 | 2122 | } |
| 2260 | 2123 | |
| 2261 | | static partitionT *cd_filterdata(filterT *flt, int trktype, UINT8 *p_ok) |
| 2124 | saturn_state::partitionT *saturn_state::cd_filterdata(filterT *flt, int trktype, UINT8 *p_ok) |
| 2262 | 2125 | { |
| 2263 | 2126 | int match = 1, keepgoing = 2; |
| 2264 | 2127 | partitionT *filterprt = (partitionT *)NULL; |
| r20800 | r20801 | |
| 2411 | 2274 | } |
| 2412 | 2275 | |
| 2413 | 2276 | // read a single sector off the CD, applying the current filter(s) as necessary |
| 2414 | | static partitionT *cd_read_filtered_sector(INT32 fad, UINT8 *p_ok) |
| 2277 | saturn_state::partitionT *saturn_state::cd_read_filtered_sector(INT32 fad, UINT8 *p_ok) |
| 2415 | 2278 | { |
| 2416 | 2279 | int trktype; |
| 2417 | 2280 | |
| r20800 | r20801 | |
| 2460 | 2323 | } |
| 2461 | 2324 | |
| 2462 | 2325 | // loads in data set up by a CD-block PLAY command |
| 2463 | | static void cd_playdata(running_machine &machine) |
| 2326 | void saturn_state::cd_playdata( void ) |
| 2464 | 2327 | { |
| 2465 | 2328 | if ((cd_stat & 0x0f00) == CD_STAT_PLAY) |
| 2466 | 2329 | { |
| r20800 | r20801 | |
| 2475 | 2338 | if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) != CD_TRACK_AUDIO) |
| 2476 | 2339 | { |
| 2477 | 2340 | cd_read_filtered_sector(cd_curfad,&p_ok); |
| 2478 | | cdda_stop_audio( machine.device( "cdda" ) ); //stop any pending CD-DA |
| 2341 | cdda_stop_audio( machine().device( "cdda" ) ); //stop any pending CD-DA |
| 2479 | 2342 | } |
| 2480 | 2343 | else |
| 2481 | 2344 | { |
| 2482 | 2345 | p_ok = 1; // TODO |
| 2483 | | cdda_start_audio( machine.device( "cdda" ), cd_curfad, 1 ); |
| 2346 | cdda_start_audio( machine().device( "cdda" ), cd_curfad, 1 ); |
| 2484 | 2347 | } |
| 2485 | 2348 | |
| 2486 | 2349 | if(p_ok) |
| r20800 | r20801 | |
| 2521 | 2384 | } |
| 2522 | 2385 | |
| 2523 | 2386 | // loads a single sector off the CD, anywhere from FAD 150 on up |
| 2524 | | static void cd_readblock(UINT32 fad, UINT8 *dat) |
| 2387 | void saturn_state::cd_readblock(UINT32 fad, UINT8 *dat) |
| 2525 | 2388 | { |
| 2526 | 2389 | if (cdrom) |
| 2527 | 2390 | { |
| r20800 | r20801 | |
| 2529 | 2392 | } |
| 2530 | 2393 | } |
| 2531 | 2394 | |
| 2532 | | void stvcd_set_tray_open(running_machine &machine) |
| 2395 | void saturn_state::stvcd_set_tray_open( void ) |
| 2533 | 2396 | { |
| 2534 | 2397 | if(!tray_is_closed) |
| 2535 | 2398 | return; |
| r20800 | r20801 | |
| 2543 | 2406 | popmessage("Tray Open"); |
| 2544 | 2407 | } |
| 2545 | 2408 | |
| 2546 | | void stvcd_set_tray_close(running_machine &machine) |
| 2409 | void saturn_state::stvcd_set_tray_close( void ) |
| 2547 | 2410 | { |
| 2548 | 2411 | /* avoid user attempts to load a CD-ROM without opening the tray first (emulation asserts anyway with current framework) */ |
| 2549 | 2412 | if(tray_is_closed) |
| r20800 | r20801 | |
| 2551 | 2414 | |
| 2552 | 2415 | hirqreg |= DCHG; |
| 2553 | 2416 | |
| 2554 | | cdrom_image_device *cddevice = machine.device<cdrom_image_device>("cdrom"); |
| 2417 | cdrom_image_device *cddevice = machine().device<cdrom_image_device>("cdrom"); |
| 2555 | 2418 | if (cddevice!=NULL) |
| 2556 | 2419 | { |
| 2557 | 2420 | // MESS case |
| r20800 | r20801 | |
| 2560 | 2423 | else |
| 2561 | 2424 | { |
| 2562 | 2425 | // MAME case |
| 2563 | | cdrom = cdrom_open(get_disk_handle(machine, "cdrom")); |
| 2426 | cdrom = cdrom_open(get_disk_handle(machine(), "cdrom")); |
| 2564 | 2427 | } |
| 2565 | 2428 | |
| 2566 | | cdda_set_cdrom( machine.device("cdda"), cdrom ); |
| 2429 | cdda_set_cdrom( machine().device("cdda"), cdrom ); |
| 2567 | 2430 | |
| 2568 | 2431 | if (cdrom) |
| 2569 | 2432 | { |
| 2570 | 2433 | CDROM_LOG(("Opened CD-ROM successfully, reading root directory\n")) |
| 2571 | | //read_new_dir(machine, 0xffffff); // read root directory |
| 2434 | //read_new_dir(0xffffff); // read root directory |
| 2572 | 2435 | cd_stat = CD_STAT_PAUSE; |
| 2573 | 2436 | } |
| 2574 | 2437 | else |
trunk/src/mame/includes/stv.h
| r20800 | r20801 | |
| 1 | 1 | /*----------- defined in drivers/stv.c -----------*/ |
| 2 | #include "cdrom.h" |
| 2 | 3 | |
| 4 | #define MAX_FILTERS (24) |
| 5 | #define MAX_BLOCKS (200) |
| 6 | #define MAX_DIR_SIZE (256*1024) |
| 7 | |
| 3 | 8 | class saturn_state : public driver_device |
| 4 | 9 | { |
| 5 | 10 | public: |
| r20800 | r20801 | |
| 284 | 289 | int y2s(int v); |
| 285 | 290 | void vdp1_fill_quad(const rectangle &cliprect, int patterndata, int xsize, const struct spoint *q); |
| 286 | 291 | void vdp1_fill_line(const rectangle &cliprect, int patterndata, int xsize, INT32 y, INT32 x1, INT32 x2, INT32 u1, INT32 u2, INT32 v1, INT32 v2); |
| 287 | | // void (*drawpixel)(int x, int y, int patterndata, int offsetcnt); |
| 288 | | // void drawpixel_poly(int x, int y, int patterndata, int offsetcnt); |
| 289 | | // void drawpixel_8bpp_trans(int x, int y, int patterndata, int offsetcnt); |
| 290 | | // void drawpixel_4bpp_notrans(int x, int y, int patterndata, int offsetcnt); |
| 291 | | // void drawpixel_4bpp_trans(int x, int y, int patterndata, int offsetcnt); |
| 292 | | // void drawpixel_generic(int x, int y, int patterndata, int offsetcnt); |
| 292 | void (saturn_state::*drawpixel)(int x, int y, int patterndata, int offsetcnt); |
| 293 | void drawpixel_poly(int x, int y, int patterndata, int offsetcnt); |
| 294 | void drawpixel_8bpp_trans(int x, int y, int patterndata, int offsetcnt); |
| 295 | void drawpixel_4bpp_notrans(int x, int y, int patterndata, int offsetcnt); |
| 296 | void drawpixel_4bpp_trans(int x, int y, int patterndata, int offsetcnt); |
| 297 | void drawpixel_generic(int x, int y, int patterndata, int offsetcnt); |
| 293 | 298 | void vdp1_fill_slope(const rectangle &cliprect, int patterndata, int xsize, |
| 294 | 299 | INT32 x1, INT32 x2, INT32 sl1, INT32 sl2, INT32 *nx1, INT32 *nx2, |
| 295 | 300 | INT32 u1, INT32 u2, INT32 slu1, INT32 slu2, INT32 *nu1, INT32 *nu2, |
| r20800 | r20801 | |
| 515 | 520 | |
| 516 | 521 | } stv_rbg_cache_data; |
| 517 | 522 | |
| 523 | /* stvcd */ |
| 524 | DECLARE_READ32_MEMBER( stvcd_r ); |
| 525 | DECLARE_WRITE32_MEMBER( stvcd_w ); |
| 518 | 526 | |
| 527 | TIMER_DEVICE_CALLBACK_MEMBER( stv_sector_cb ); |
| 528 | TIMER_DEVICE_CALLBACK_MEMBER( stv_sh1_sim ); |
| 529 | |
| 530 | struct direntryT |
| 531 | { |
| 532 | UINT8 record_size; |
| 533 | UINT8 xa_record_size; |
| 534 | UINT32 firstfad; // first sector of file |
| 535 | UINT32 length; // length of file |
| 536 | UINT8 year; |
| 537 | UINT8 month; |
| 538 | UINT8 day; |
| 539 | UINT8 hour; |
| 540 | UINT8 minute; |
| 541 | UINT8 second; |
| 542 | UINT8 gmt_offset; |
| 543 | UINT8 flags; // iso9660 flags |
| 544 | UINT8 file_unit_size; |
| 545 | UINT8 interleave_gap_size; |
| 546 | UINT16 volume_sequencer_number; |
| 547 | UINT8 name[128]; |
| 548 | }; |
| 549 | |
| 550 | struct filterT |
| 551 | { |
| 552 | UINT8 mode; |
| 553 | UINT8 chan; |
| 554 | UINT8 smmask; |
| 555 | UINT8 cimask; |
| 556 | UINT8 fid; |
| 557 | UINT8 smval; |
| 558 | UINT8 cival; |
| 559 | UINT8 condtrue; |
| 560 | UINT8 condfalse; |
| 561 | UINT32 fad; |
| 562 | UINT32 range; |
| 563 | }; |
| 564 | |
| 565 | struct blockT |
| 566 | { |
| 567 | INT32 size; // size of block |
| 568 | INT32 FAD; // FAD on disc |
| 569 | UINT8 data[CD_MAX_SECTOR_DATA]; |
| 570 | UINT8 chan; // channel |
| 571 | UINT8 fnum; // file number |
| 572 | UINT8 subm; // subchannel mode |
| 573 | UINT8 cinf; // coding information |
| 574 | }; |
| 575 | |
| 576 | struct partitionT |
| 577 | { |
| 578 | INT32 size; |
| 579 | blockT *blocks[MAX_BLOCKS]; |
| 580 | UINT8 bnum[MAX_BLOCKS]; |
| 581 | UINT8 numblks; |
| 582 | }; |
| 583 | |
| 584 | // 16-bit transfer types |
| 585 | enum transT |
| 586 | { |
| 587 | XFERTYPE_INVALID, |
| 588 | XFERTYPE_TOC, |
| 589 | XFERTYPE_FILEINFO_1, |
| 590 | XFERTYPE_FILEINFO_254, |
| 591 | XFERTYPE_SUBQ, |
| 592 | XFERTYPE_SUBRW |
| 593 | }; |
| 594 | |
| 595 | // 32-bit transfer types |
| 596 | enum trans32T |
| 597 | { |
| 598 | XFERTYPE32_INVALID, |
| 599 | XFERTYPE32_GETSECTOR, |
| 600 | XFERTYPE32_GETDELETESECTOR |
| 601 | }; |
| 602 | |
| 603 | |
| 604 | void stvcd_reset(void); |
| 605 | void stvcd_exit(void); |
| 606 | void stvcd_set_tray_open(void); |
| 607 | void stvcd_set_tray_close(void); |
| 608 | |
| 609 | int get_track_index(void); |
| 610 | void cr_standard_return(UINT16 cur_status); |
| 611 | void cd_free_block(blockT *blktofree); |
| 612 | void cd_defragblocks(partitionT *part); |
| 613 | void cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum); |
| 614 | |
| 615 | UINT16 cd_readWord(UINT32 addr); |
| 616 | void cd_writeWord(UINT32 addr, UINT16 data); |
| 617 | UINT32 cd_readLong(UINT32 addr); |
| 618 | |
| 619 | void cd_readTOC(void); |
| 620 | void cd_readblock(UINT32 fad, UINT8 *dat); |
| 621 | void cd_playdata(void); |
| 622 | |
| 623 | void cd_exec_command( void ); |
| 624 | // iso9660 utilities |
| 625 | void make_dir_current(UINT32 fad); |
| 626 | void read_new_dir(UINT32 fileno); |
| 627 | |
| 628 | blockT *cd_alloc_block(UINT8 *blknum); |
| 629 | partitionT *cd_filterdata(filterT *flt, int trktype, UINT8 *p_ok); |
| 630 | partitionT *cd_read_filtered_sector(INT32 fad, UINT8 *p_ok); |
| 631 | |
| 632 | cdrom_file *cdrom;// = (cdrom_file *)NULL; |
| 633 | |
| 634 | // local variables |
| 635 | timer_device *sector_timer; |
| 636 | timer_device *sh1_timer; |
| 637 | partitionT partitions[MAX_FILTERS]; |
| 638 | partitionT *transpart; |
| 639 | |
| 640 | blockT blocks[MAX_BLOCKS]; |
| 641 | blockT curblock; |
| 642 | |
| 643 | UINT8 tocbuf[102*4]; |
| 644 | UINT8 subqbuf[5*2]; |
| 645 | UINT8 subrwbuf[12*2]; |
| 646 | UINT8 finfbuf[256]; |
| 647 | |
| 648 | INT32 sectlenin, sectlenout; |
| 649 | |
| 650 | UINT8 lastbuf, playtype; |
| 651 | |
| 652 | transT xfertype; |
| 653 | trans32T xfertype32; |
| 654 | UINT32 xfercount, calcsize; |
| 655 | UINT32 xferoffs, xfersect, xfersectpos, xfersectnum, xferdnum; |
| 656 | |
| 657 | filterT filters[MAX_FILTERS]; |
| 658 | filterT *cddevice; |
| 659 | int cddevicenum; |
| 660 | |
| 661 | UINT16 cr1, cr2, cr3, cr4; |
| 662 | UINT16 hirqmask, hirqreg; |
| 663 | UINT16 cd_stat; |
| 664 | UINT32 cd_curfad;// = 0; |
| 665 | UINT32 fadstoplay;// = 0; |
| 666 | UINT32 in_buffer;// = 0; // amount of data in the buffer |
| 667 | int oddframe;// = 0; |
| 668 | int buffull, sectorstore, freeblocks; |
| 669 | int cur_track; |
| 670 | UINT8 cmd_pending; |
| 671 | UINT8 cd_speed; |
| 672 | UINT8 cdda_maxrepeat; |
| 673 | UINT8 cdda_repeat_count; |
| 674 | UINT8 tray_is_closed; |
| 675 | |
| 676 | direntryT curroot; // root entry of current filesystem |
| 677 | direntryT *curdir; // current directory |
| 678 | int numfiles; // # of entries in current directory |
| 679 | int firstfile; // first non-directory file |
| 519 | 680 | }; |
| 520 | 681 | |
| 521 | 682 | #define MASTER_CLOCK_352 57272720 |
| r20800 | r20801 | |
| 552 | 713 | |
| 553 | 714 | /*----------- defined in video/stvvdp1.c -----------*/ |
| 554 | 715 | |
| 555 | | extern UINT16 **stv_framebuffer_display_lines; |
| 556 | | extern int stv_framebuffer_double_interlace; |
| 557 | | extern int stv_framebuffer_mode; |
| 558 | | extern UINT8* stv_vdp1_gfx_decode; |
| 716 | //extern UINT16 **stv_framebuffer_display_lines; |
| 717 | //extern int stv_framebuffer_double_interlace; |
| 718 | //extern int stv_framebuffer_mode; |
| 719 | //extern UINT8* stv_vdp1_gfx_decode; |
| 559 | 720 | |
| 560 | | int stv_vdp1_start ( running_machine &machine ); |
| 561 | | void video_update_vdp1(running_machine &machine); |
| 562 | | void stv_vdp2_dynamic_res_change(running_machine &machine); |
| 721 | //int stv_vdp1_start ( running_machine &machine ); |
| 722 | //void video_update_vdp1(running_machine &machine); |
| 723 | //void stv_vdp2_dynamic_res_change(running_machine &machine); |
| 563 | 724 | |
trunk/src/mame/video/stvvdp1.c
| r20800 | r20801 | |
| 826 | 826 | why they would want to */ |
| 827 | 827 | |
| 828 | 828 | |
| 829 | | static void (*drawpixel)(running_machine &machine, int x, int y, int patterndata, int offsetcnt); |
| 830 | 829 | |
| 831 | | static void drawpixel_poly(running_machine &machine, int x, int y, int patterndata, int offsetcnt) |
| 830 | void saturn_state::drawpixel_poly(int x, int y, int patterndata, int offsetcnt) |
| 832 | 831 | { |
| 833 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 834 | | |
| 835 | 832 | /* Capcom Collection Dai 4 uses a dummy polygon to clear VDP1 framebuffer that goes over our current max size ... */ |
| 836 | 833 | if(x >= 1024 || y >= 512) |
| 837 | 834 | return; |
| 838 | 835 | |
| 839 | | state->m_vdp1.framebuffer_draw_lines[y][x] = state->stv2_current_sprite.CMDCOLR; |
| 836 | m_vdp1.framebuffer_draw_lines[y][x] = stv2_current_sprite.CMDCOLR; |
| 840 | 837 | } |
| 841 | 838 | |
| 842 | | static void drawpixel_8bpp_trans(running_machine &machine, int x, int y, int patterndata, int offsetcnt) |
| 839 | void saturn_state::drawpixel_8bpp_trans(int x, int y, int patterndata, int offsetcnt) |
| 843 | 840 | { |
| 844 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 845 | 841 | UINT16 pix; |
| 846 | 842 | |
| 847 | | pix = state->m_vdp1.gfx_decode[patterndata+offsetcnt]; |
| 843 | pix = m_vdp1.gfx_decode[patterndata+offsetcnt]; |
| 848 | 844 | if ( pix & 0xff ) |
| 849 | 845 | { |
| 850 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix | state->m_sprite_colorbank; |
| 846 | m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank; |
| 851 | 847 | } |
| 852 | 848 | } |
| 853 | 849 | |
| 854 | | static void drawpixel_4bpp_notrans(running_machine &machine, int x, int y, int patterndata, int offsetcnt) |
| 850 | void saturn_state::drawpixel_4bpp_notrans(int x, int y, int patterndata, int offsetcnt) |
| 855 | 851 | { |
| 856 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 857 | 852 | UINT16 pix; |
| 858 | 853 | |
| 859 | | pix = state->m_vdp1.gfx_decode[patterndata+offsetcnt/2]; |
| 854 | pix = m_vdp1.gfx_decode[patterndata+offsetcnt/2]; |
| 860 | 855 | pix = offsetcnt&1 ? (pix & 0x0f):((pix & 0xf0)>>4) ; |
| 861 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix | state->m_sprite_colorbank; |
| 856 | m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank; |
| 862 | 857 | } |
| 863 | 858 | |
| 864 | | static void drawpixel_4bpp_trans(running_machine &machine, int x, int y, int patterndata, int offsetcnt) |
| 859 | void saturn_state::drawpixel_4bpp_trans(int x, int y, int patterndata, int offsetcnt) |
| 865 | 860 | { |
| 866 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 867 | 861 | UINT16 pix; |
| 868 | 862 | |
| 869 | | pix = state->m_vdp1.gfx_decode[patterndata+offsetcnt/2]; |
| 863 | pix = m_vdp1.gfx_decode[patterndata+offsetcnt/2]; |
| 870 | 864 | pix = offsetcnt&1 ? (pix & 0x0f):((pix & 0xf0)>>4) ; |
| 871 | 865 | if ( pix ) |
| 872 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix | state->m_sprite_colorbank; |
| 866 | m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank; |
| 873 | 867 | } |
| 874 | 868 | |
| 875 | | static void drawpixel_generic(running_machine &machine, int x, int y, int patterndata, int offsetcnt) |
| 869 | void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcnt) |
| 876 | 870 | { |
| 877 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 878 | | int pix,mode,transmask, spd = state->stv2_current_sprite.CMDPMOD & 0x40; |
| 879 | | int mesh = state->stv2_current_sprite.CMDPMOD & 0x100; |
| 871 | int pix,mode,transmask, spd = stv2_current_sprite.CMDPMOD & 0x40; |
| 872 | int mesh = stv2_current_sprite.CMDPMOD & 0x100; |
| 880 | 873 | int pix2; |
| 881 | 874 | |
| 882 | 875 | if ( mesh && !((x ^ y) & 1) ) |
| r20800 | r20801 | |
| 884 | 877 | return; |
| 885 | 878 | } |
| 886 | 879 | |
| 887 | | if ( state->stv2_current_sprite.ispoly ) |
| 880 | if ( stv2_current_sprite.ispoly ) |
| 888 | 881 | { |
| 889 | | pix = state->stv2_current_sprite.CMDCOLR&0xffff; |
| 882 | pix = stv2_current_sprite.CMDCOLR&0xffff; |
| 890 | 883 | |
| 891 | 884 | transmask = 0xffff; |
| 892 | 885 | if ( pix & 0x8000 ) |
| r20800 | r20801 | |
| 900 | 893 | } |
| 901 | 894 | else |
| 902 | 895 | { |
| 903 | | switch (state->stv2_current_sprite.CMDPMOD&0x0038) |
| 896 | switch (stv2_current_sprite.CMDPMOD&0x0038) |
| 904 | 897 | { |
| 905 | 898 | case 0x0000: // mode 0 16 colour bank mode (4bits) (hanagumi blocks) |
| 906 | 899 | // most of the shienryu sprites use this mode |
| 907 | | pix = state->m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; |
| 900 | pix = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; |
| 908 | 901 | pix = offsetcnt&1 ? (pix & 0x0f):((pix & 0xf0)>>4) ; |
| 909 | | pix = pix+((state->stv2_current_sprite.CMDCOLR&0xfff0)); |
| 902 | pix = pix+((stv2_current_sprite.CMDCOLR&0xfff0)); |
| 910 | 903 | mode = 0; |
| 911 | 904 | transmask = 0xf; |
| 912 | 905 | break; |
| 913 | 906 | case 0x0008: // mode 1 16 colour lookup table mode (4bits) |
| 914 | 907 | // shienryu explosisons (and some enemies) use this mode |
| 915 | | pix2 = state->m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; |
| 908 | pix2 = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; |
| 916 | 909 | pix2 = offsetcnt&1 ? (pix2 & 0x0f):((pix2 & 0xf0)>>4); |
| 917 | 910 | pix = pix2&1 ? |
| 918 | | ((((state->m_vdp1_vram[(((state->stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0x0000ffff) >> 0): |
| 919 | | ((((state->m_vdp1_vram[(((state->stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0xffff0000) >> 16); |
| 911 | ((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0x0000ffff) >> 0): |
| 912 | ((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0xffff0000) >> 16); |
| 920 | 913 | |
| 921 | 914 | mode = 5; |
| 922 | 915 | transmask = 0xffff; |
| r20800 | r20801 | |
| 934 | 927 | } |
| 935 | 928 | break; |
| 936 | 929 | case 0x0010: // mode 2 64 colour bank mode (8bits) (character select portraits on hanagumi) |
| 937 | | pix = state->m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 930 | pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 938 | 931 | mode = 2; |
| 939 | | pix = pix+(state->stv2_current_sprite.CMDCOLR&0xffc0); |
| 932 | pix = pix+(stv2_current_sprite.CMDCOLR&0xffc0); |
| 940 | 933 | transmask = 0x3f; |
| 941 | 934 | break; |
| 942 | 935 | case 0x0018: // mode 3 128 colour bank mode (8bits) (little characters on hanagumi use this mode) |
| 943 | | pix = state->m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 944 | | pix = pix+(state->stv2_current_sprite.CMDCOLR&0xff80); |
| 936 | pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 937 | pix = pix+(stv2_current_sprite.CMDCOLR&0xff80); |
| 945 | 938 | transmask = 0x7f; |
| 946 | 939 | mode = 3; |
| 947 | 940 | break; |
| 948 | 941 | case 0x0020: // mode 4 256 colour bank mode (8bits) (hanagumi title) |
| 949 | | pix = state->m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 950 | | pix = pix+(state->stv2_current_sprite.CMDCOLR&0xff00); |
| 942 | pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; |
| 943 | pix = pix+(stv2_current_sprite.CMDCOLR&0xff00); |
| 951 | 944 | transmask = 0xff; |
| 952 | 945 | mode = 4; |
| 953 | 946 | break; |
| 954 | 947 | case 0x0028: // mode 5 32,768 colour RGB mode (16bits) |
| 955 | | pix = state->m_vdp1.gfx_decode[(patterndata+offsetcnt*2+1) & 0xfffff] | (state->m_vdp1.gfx_decode[(patterndata+offsetcnt*2) & 0xfffff]<<8) ; |
| 948 | pix = m_vdp1.gfx_decode[(patterndata+offsetcnt*2+1) & 0xfffff] | (m_vdp1.gfx_decode[(patterndata+offsetcnt*2) & 0xfffff]<<8) ; |
| 956 | 949 | mode = 5; |
| 957 | 950 | transmask = -1; /* TODO: check me */ |
| 958 | 951 | break; |
| 959 | 952 | default: // other settings illegal |
| 960 | | pix = machine.rand(); |
| 953 | pix = machine().rand(); |
| 961 | 954 | mode = 0; |
| 962 | 955 | transmask = 0xff; |
| 963 | 956 | popmessage("Illegal Sprite Mode, contact MAMEdev"); |
| r20800 | r20801 | |
| 965 | 958 | |
| 966 | 959 | |
| 967 | 960 | // preliminary end code disable support |
| 968 | | if ( ((state->stv2_current_sprite.CMDPMOD & 0x80) == 0) && |
| 961 | if ( ((stv2_current_sprite.CMDPMOD & 0x80) == 0) && |
| 969 | 962 | ((pix & transmask) == transmask) ) |
| 970 | 963 | { |
| 971 | 964 | return; |
| r20800 | r20801 | |
| 973 | 966 | } |
| 974 | 967 | |
| 975 | 968 | /* MSBON */ |
| 976 | | pix |= state->stv2_current_sprite.CMDPMOD & 0x8000; |
| 969 | pix |= stv2_current_sprite.CMDPMOD & 0x8000; |
| 977 | 970 | if ( mode != 5 ) |
| 978 | 971 | { |
| 979 | 972 | if ( (pix & transmask) || spd ) |
| 980 | 973 | { |
| 981 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 974 | m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 982 | 975 | } |
| 983 | 976 | } |
| 984 | 977 | else |
| 985 | 978 | { |
| 986 | 979 | if ( (pix & transmask) || spd ) |
| 987 | 980 | { |
| 988 | | switch( state->stv2_current_sprite.CMDPMOD & 0x7 ) |
| 981 | switch( stv2_current_sprite.CMDPMOD & 0x7 ) |
| 989 | 982 | { |
| 990 | 983 | case 0: /* replace */ |
| 991 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 984 | m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 992 | 985 | break; |
| 993 | 986 | case 1: /* shadow */ |
| 994 | | if ( state->m_vdp1.framebuffer_draw_lines[y][x] & 0x8000 ) |
| 987 | if ( m_vdp1.framebuffer_draw_lines[y][x] & 0x8000 ) |
| 995 | 988 | { |
| 996 | | state->m_vdp1.framebuffer_draw_lines[y][x] = ((state->m_vdp1.framebuffer_draw_lines[y][x] & ~0x8421) >> 1) | 0x8000; |
| 989 | m_vdp1.framebuffer_draw_lines[y][x] = ((m_vdp1.framebuffer_draw_lines[y][x] & ~0x8421) >> 1) | 0x8000; |
| 997 | 990 | } |
| 998 | 991 | break; |
| 999 | 992 | case 2: /* half luminance */ |
| 1000 | | state->m_vdp1.framebuffer_draw_lines[y][x] = ((pix & ~0x8421) >> 1) | 0x8000; |
| 993 | m_vdp1.framebuffer_draw_lines[y][x] = ((pix & ~0x8421) >> 1) | 0x8000; |
| 1001 | 994 | break; |
| 1002 | 995 | case 3: /* half transparent */ |
| 1003 | | if ( state->m_vdp1.framebuffer_draw_lines[y][x] & 0x8000 ) |
| 996 | if ( m_vdp1.framebuffer_draw_lines[y][x] & 0x8000 ) |
| 1004 | 997 | { |
| 1005 | | state->m_vdp1.framebuffer_draw_lines[y][x] = alpha_blend_r16( state->m_vdp1.framebuffer_draw_lines[y][x], pix, 0x80 ) | 0x8000; |
| 998 | m_vdp1.framebuffer_draw_lines[y][x] = alpha_blend_r16( m_vdp1.framebuffer_draw_lines[y][x], pix, 0x80 ) | 0x8000; |
| 1006 | 999 | } |
| 1007 | 1000 | else |
| 1008 | 1001 | { |
| 1009 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 1002 | m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 1010 | 1003 | } |
| 1011 | 1004 | break; |
| 1012 | 1005 | case 4: /* Gouraud shading */ |
| 1013 | | state->m_vdp1.framebuffer_draw_lines[y][x] = state->stv_vdp1_apply_gouraud_shading( x, y, pix ); |
| 1006 | m_vdp1.framebuffer_draw_lines[y][x] = stv_vdp1_apply_gouraud_shading( x, y, pix ); |
| 1014 | 1007 | break; |
| 1015 | 1008 | default: |
| 1016 | | state->m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 1009 | m_vdp1.framebuffer_draw_lines[y][x] = pix; |
| 1017 | 1010 | break; |
| 1018 | 1011 | } |
| 1019 | 1012 | } |
| r20800 | r20801 | |
| 1031 | 1024 | |
| 1032 | 1025 | if ( mesh || !ecd || ((stv2_current_sprite.CMDPMOD & 0x7) != 0) ) |
| 1033 | 1026 | { |
| 1034 | | drawpixel = drawpixel_generic; |
| 1027 | drawpixel = &saturn_state::drawpixel_generic; |
| 1035 | 1028 | return; |
| 1036 | 1029 | } |
| 1037 | 1030 | |
| 1038 | 1031 | if (sprite_type == 4 && ((stv2_current_sprite.CMDPMOD & 0x7) == 0)) |
| 1039 | 1032 | { |
| 1040 | | drawpixel = drawpixel_poly; |
| 1033 | drawpixel = &saturn_state::drawpixel_poly; |
| 1041 | 1034 | } |
| 1042 | 1035 | else if ( (sprite_mode == 0x20) && !spd ) |
| 1043 | 1036 | { |
| 1044 | 1037 | m_sprite_colorbank = (stv2_current_sprite.CMDCOLR&0xff00); |
| 1045 | | drawpixel = drawpixel_8bpp_trans; |
| 1038 | drawpixel = &saturn_state::drawpixel_8bpp_trans; |
| 1046 | 1039 | } |
| 1047 | 1040 | else if ((sprite_mode == 0x00) && spd) |
| 1048 | 1041 | { |
| 1049 | 1042 | m_sprite_colorbank = (stv2_current_sprite.CMDCOLR&0xfff0); |
| 1050 | | drawpixel = drawpixel_4bpp_notrans; |
| 1043 | drawpixel = &saturn_state::drawpixel_4bpp_notrans; |
| 1051 | 1044 | } |
| 1052 | 1045 | else if (sprite_mode == 0x00 && !spd ) |
| 1053 | 1046 | { |
| 1054 | 1047 | m_sprite_colorbank = (stv2_current_sprite.CMDCOLR&0xfff0); |
| 1055 | | drawpixel = drawpixel_4bpp_trans; |
| 1048 | drawpixel = &saturn_state::drawpixel_4bpp_trans; |
| 1056 | 1049 | } |
| 1057 | 1050 | else |
| 1058 | 1051 | { |
| 1059 | | drawpixel = drawpixel_generic; |
| 1052 | drawpixel = &saturn_state::drawpixel_generic; |
| 1060 | 1053 | } |
| 1061 | 1054 | } |
| 1062 | 1055 | |
| r20800 | r20801 | |
| 1151 | 1144 | xx2 = cliprect.max_x; |
| 1152 | 1145 | |
| 1153 | 1146 | while(xx1 <= xx2) { |
| 1154 | | drawpixel(machine(),xx1,_y1, |
| 1155 | | patterndata, |
| 1156 | | (v>>FRAC_SHIFT)*xsize+(u>>FRAC_SHIFT)); |
| 1147 | (this->*drawpixel)(xx1,_y1, patterndata, (v>>FRAC_SHIFT)*xsize+(u>>FRAC_SHIFT)); |
| 1157 | 1148 | xx1++; |
| 1158 | 1149 | u += slux; |
| 1159 | 1150 | v += slvx; |
| r20800 | r20801 | |
| 1205 | 1196 | xx2 = cliprect.max_x; |
| 1206 | 1197 | |
| 1207 | 1198 | while(xx1 <= xx2) { |
| 1208 | | drawpixel(machine(), xx1,y, |
| 1209 | | patterndata, |
| 1210 | | (v>>FRAC_SHIFT)*xsize+(u>>FRAC_SHIFT)); |
| 1199 | (this->*drawpixel)(xx1,y,patterndata,(v>>FRAC_SHIFT)*xsize+(u>>FRAC_SHIFT)); |
| 1211 | 1200 | xx1++; |
| 1212 | 1201 | u += slux; |
| 1213 | 1202 | v += slvx; |
| r20800 | r20801 | |
| 1725 | 1714 | su = u; |
| 1726 | 1715 | for (drawxpos = x; drawxpos <= maxdrawxpos; drawxpos++ ) |
| 1727 | 1716 | { |
| 1728 | | drawpixel( machine(), drawxpos, drawypos, patterndata, u ); |
| 1717 | (this->*drawpixel)( drawxpos, drawypos, patterndata, u ); |
| 1729 | 1718 | u += dux; |
| 1730 | 1719 | } |
| 1731 | 1720 | u = su + duy; |
trunk/src/mame/drivers/saturn.c
| r20800 | r20801 | |
| 781 | 781 | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 782 | 782 | // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated |
| 783 | 783 | AM_RANGE(0x04fffffc, 0x04ffffff) AM_READ8(saturn_cart_type_r,0x000000ff) |
| 784 | | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE_LEGACY(stvcd_r, stvcd_w) |
| 784 | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) |
| 785 | 785 | /* Sound */ |
| 786 | 786 | AM_RANGE(0x05a00000, 0x05a7ffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) |
| 787 | 787 | AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16_LEGACY("scsp", scsp_r, scsp_w, 0xffffffff) |
| r20800 | r20801 | |
| 810 | 810 | AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(minit_w) |
| 811 | 811 | AM_RANGE(0x01800000, 0x01ffffff) AM_WRITE(sinit_w) |
| 812 | 812 | AM_RANGE(0x02000000, 0x04ffffff) AM_ROM AM_SHARE("share7") AM_REGION("abus", 0) // cartridge |
| 813 | | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE_LEGACY(stvcd_r, stvcd_w) |
| 813 | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) |
| 814 | 814 | /* Sound */ |
| 815 | 815 | AM_RANGE(0x05a00000, 0x05afffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) |
| 816 | 816 | AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16_LEGACY("scsp", scsp_r, scsp_w, 0xffffffff) |
| r20800 | r20801 | |
| 930 | 930 | INPUT_CHANGED_MEMBER(saturn_state::tray_open) |
| 931 | 931 | { |
| 932 | 932 | if(newval) |
| 933 | | stvcd_set_tray_open(machine()); |
| 933 | stvcd_set_tray_open(); |
| 934 | 934 | } |
| 935 | 935 | |
| 936 | 936 | INPUT_CHANGED_MEMBER(saturn_state::tray_close) |
| 937 | 937 | { |
| 938 | 938 | if(newval) |
| 939 | | stvcd_set_tray_close(machine()); |
| 939 | stvcd_set_tray_close(); |
| 940 | 940 | } |
| 941 | 941 | |
| 942 | 942 | static INPUT_PORTS_START( saturn ) |
| r20800 | r20801 | |
| 1797 | 1797 | |
| 1798 | 1798 | stv_register_protection_savestates(machine()); // machine/stvprot.c |
| 1799 | 1799 | |
| 1800 | | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine())); |
| 1800 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(saturn_state::stvcd_exit), this)); |
| 1801 | 1801 | |
| 1802 | 1802 | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 1803 | 1803 | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| r20800 | r20801 | |
| 1842 | 1842 | state_save_register_global_array(machine(), m_smpc.SMEM); |
| 1843 | 1843 | state_save_register_global_pointer(machine(), m_cart_dram, 0x400000/4); |
| 1844 | 1844 | |
| 1845 | | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine())); |
| 1845 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(saturn_state::stvcd_exit), this)); |
| 1846 | 1846 | |
| 1847 | 1847 | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 1848 | 1848 | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| r20800 | r20801 | |
| 2062 | 2062 | machine().device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 2063 | 2063 | machine().device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 2064 | 2064 | |
| 2065 | | stvcd_reset( machine() ); |
| 2065 | stvcd_reset(); |
| 2066 | 2066 | |
| 2067 | 2067 | m_cart_type = ioport("CART_AREA")->read() & 7; |
| 2068 | 2068 | |
| r20800 | r20801 | |
| 2138 | 2138 | machine().device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 2139 | 2139 | machine().device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 2140 | 2140 | |
| 2141 | | stvcd_reset(machine()); |
| 2141 | stvcd_reset(); |
| 2142 | 2142 | |
| 2143 | 2143 | m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); |
| 2144 | 2144 | m_prev_bankswitch = 0xff; |
| r20800 | r20801 | |
| 2213 | 2213 | |
| 2214 | 2214 | MCFG_NVRAM_HANDLER(saturn) |
| 2215 | 2215 | |
| 2216 | | MCFG_TIMER_ADD("sector_timer", stv_sector_cb) |
| 2217 | | MCFG_TIMER_ADD("sh1_cmd", stv_sh1_sim) |
| 2216 | MCFG_TIMER_DRIVER_ADD("sector_timer", saturn_state, stv_sector_cb) |
| 2217 | MCFG_TIMER_DRIVER_ADD("sh1_cmd", saturn_state, stv_sh1_sim) |
| 2218 | 2218 | |
| 2219 | 2219 | /* video hardware */ |
| 2220 | 2220 | MCFG_SCREEN_ADD("screen", RASTER) |
| r20800 | r20801 | |
| 2296 | 2296 | |
| 2297 | 2297 | MCFG_EEPROM_93C46_ADD("eeprom") /* Actually 93c45 */ |
| 2298 | 2298 | |
| 2299 | | MCFG_TIMER_ADD("sector_timer", stv_sector_cb) |
| 2300 | | MCFG_TIMER_ADD("sh1_cmd", stv_sh1_sim) |
| 2299 | MCFG_TIMER_DRIVER_ADD("sector_timer", saturn_state, stv_sector_cb) |
| 2300 | MCFG_TIMER_DRIVER_ADD("sh1_cmd", saturn_state, stv_sh1_sim) |
| 2301 | 2301 | |
| 2302 | 2302 | /* video hardware */ |
| 2303 | 2303 | MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK) |