src/mame/machine/snes.c
| r9892 | r9893 | |
| 19 | 19 | #include "emu.h" |
| 20 | 20 | #include "cpu/superfx/superfx.h" |
| 21 | 21 | #include "cpu/g65816/g65816.h" |
| 22 | #include "cpu/upd7725/upd7725.h" |
| 22 | 23 | #include "includes/snes.h" |
| 23 | 24 | #include "audio/snes_snd.h" |
| 24 | 25 | |
| r9892 | r9893 | |
| 36 | 37 | struct snes_cart_info snes_cart; |
| 37 | 38 | |
| 38 | 39 | // add-on chip emulators |
| 39 | | #include "machine/snesdsp1.c" |
| 40 | | #include "machine/snesdsp2.c" |
| 41 | | #include "machine/snesdsp3.c" |
| 42 | | #include "machine/snesdsp4.c" |
| 43 | 40 | #include "machine/snesobc1.c" |
| 44 | 41 | #include "machine/snescx4.c" |
| 45 | 42 | #include "machine/snesrtc.c" |
| r9892 | r9893 | |
| 284 | 281 | |
| 285 | 282 | /************************************* |
| 286 | 283 | |
| 284 | DSP I/O |
| 285 | |
| 286 | *************************************/ |
| 287 | static UINT8 dsp_get_sr(running_machine *machine) |
| 288 | { |
| 289 | upd7725_device *upd7725 = machine->device<upd7725_device>("dsp"); |
| 290 | |
| 291 | return upd7725->snesdsp_read(false); |
| 292 | } |
| 293 | |
| 294 | static UINT8 dsp_get_dr(running_machine *machine) |
| 295 | { |
| 296 | upd7725_device *upd7725 = machine->device<upd7725_device>("dsp"); |
| 297 | |
| 298 | return upd7725->snesdsp_read(true); |
| 299 | } |
| 300 | |
| 301 | static void dsp_set_sr(running_machine *machine, UINT8 data) |
| 302 | { |
| 303 | upd7725_device *upd7725 = machine->device<upd7725_device>("dsp"); |
| 304 | |
| 305 | upd7725->snesdsp_write(false, data); |
| 306 | } |
| 307 | |
| 308 | static void dsp_set_dr(running_machine *machine, UINT8 data) |
| 309 | { |
| 310 | upd7725_device *upd7725 = machine->device<upd7725_device>("dsp"); |
| 311 | |
| 312 | upd7725->snesdsp_write(true, data); |
| 313 | } |
| 314 | |
| 315 | /************************************* |
| 316 | |
| 287 | 317 | Input Handlers |
| 288 | 318 | |
| 289 | 319 | *************************************/ |
| r9892 | r9893 | |
| 938 | 968 | else if (state->has_addon_chip == HAS_OBC1) |
| 939 | 969 | value = obc1_read(space, offset); |
| 940 | 970 | else if ((state->cart[0].mode == SNES_MODE_21) && (state->has_addon_chip == HAS_DSP1) && (offset < 0x100000)) |
| 941 | | value = (address < 0x7000) ? dsp1_get_dr() : dsp1_get_sr(); |
| 971 | value = (address < 0x7000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 942 | 972 | else if (state->has_addon_chip == HAS_CX4) |
| 943 | 973 | value = CX4_read(address - 0x6000); |
| 944 | 974 | else if (state->has_addon_chip == HAS_SPC7110 || state->has_addon_chip == HAS_SPC7110_RTC) |
| r9892 | r9893 | |
| 953 | 983 | } |
| 954 | 984 | } |
| 955 | 985 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000)) |
| 956 | | value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr(); |
| 986 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 957 | 987 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000)) |
| 958 | | value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read(); |
| 988 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 959 | 989 | else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000)) |
| 960 | | value = dsp3_read(address); |
| 990 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 961 | 991 | else |
| 962 | 992 | value = snes_ram[offset]; |
| 963 | 993 | |
| r9892 | r9893 | |
| 1017 | 1047 | } |
| 1018 | 1048 | /* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */ |
| 1019 | 1049 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1)) |
| 1020 | | value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr(); |
| 1050 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1021 | 1051 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2)) |
| 1022 | | value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read(); |
| 1052 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1023 | 1053 | else if (state->has_addon_chip == HAS_DSP3) |
| 1024 | | value = dsp3_read(address); |
| 1054 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1025 | 1055 | else if (state->has_addon_chip == HAS_DSP4) |
| 1026 | | value = (address < 0xc000) ? dsp4_read() : 0x80; |
| 1056 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1027 | 1057 | else |
| 1028 | 1058 | value = snes_ram[0x300000 + offset]; |
| 1029 | 1059 | |
| r9892 | r9893 | |
| 1100 | 1130 | value = snes_ram[0x600000 + offset]; |
| 1101 | 1131 | /* some other dsp1 games use these banks 0x60 to 0x6f at address 0x0000 */ |
| 1102 | 1132 | else if (state->has_addon_chip == HAS_DSP1) |
| 1103 | | value = (address >= 0x4000) ? dsp1_get_sr() : dsp1_get_dr(); |
| 1133 | value = (address >= 0x4000) ? dsp_get_sr(space->machine) : dsp_get_dr(space->machine); |
| 1104 | 1134 | else |
| 1105 | 1135 | { |
| 1106 | 1136 | logerror("(PC=%06x) snes_r_bank4: Unmapped external chip read: %04x\n",cpu_get_pc(space->cpu),address); |
| r9892 | r9893 | |
| 1188 | 1218 | } |
| 1189 | 1219 | } |
| 1190 | 1220 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000)) |
| 1191 | | value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr(); |
| 1221 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1192 | 1222 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000)) |
| 1193 | | value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read(); |
| 1223 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1194 | 1224 | else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000)) |
| 1195 | | value = dsp3_read(address); |
| 1225 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1196 | 1226 | else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000)) |
| 1197 | | value = (address < 0xc000) ? dsp4_read() : 0x80; |
| 1227 | value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine); |
| 1198 | 1228 | else |
| 1199 | 1229 | value = snes_ram[0x800000 + offset]; |
| 1200 | 1230 | |
| r9892 | r9893 | |
| 1284 | 1314 | else if (state->has_addon_chip == HAS_OBC1) |
| 1285 | 1315 | obc1_write(space, offset, data); |
| 1286 | 1316 | else if ((state->cart[0].mode == SNES_MODE_21) && (state->has_addon_chip == HAS_DSP1) && (offset < 0x100000)) |
| 1287 | | dsp1_set_dr(data); |
| 1317 | dsp_set_dr(space->machine, data); |
| 1288 | 1318 | else if (state->has_addon_chip == HAS_CX4) |
| 1289 | 1319 | CX4_write(space->machine, address - 0x6000, data); |
| 1290 | 1320 | else if (state->has_addon_chip == HAS_SPC7110 || state->has_addon_chip == HAS_SPC7110_RTC) |
| r9892 | r9893 | |
| 1296 | 1326 | logerror("snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data); |
| 1297 | 1327 | } |
| 1298 | 1328 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000)) |
| 1299 | | dsp1_set_dr(data); |
| 1329 | dsp_set_dr(space->machine, data); |
| 1300 | 1330 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000)) |
| 1301 | 1331 | { |
| 1302 | 1332 | if (address < 0xc000) |
| 1303 | | dsp2_dr_write(data); |
| 1333 | dsp_set_dr(space->machine, data); |
| 1304 | 1334 | else |
| 1305 | | dsp2_sr_write(data); |
| 1335 | dsp_set_sr(space->machine, data); |
| 1306 | 1336 | } |
| 1307 | 1337 | else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000)) |
| 1308 | | dsp3_write(address, data); |
| 1338 | if (address < 0xc000) |
| 1339 | dsp_set_dr(space->machine, data); |
| 1340 | else |
| 1341 | dsp_set_sr(space->machine, data); |
| 1309 | 1342 | else |
| 1310 | 1343 | logerror( "(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset ); |
| 1311 | 1344 | |
| r9892 | r9893 | |
| 1354 | 1387 | } |
| 1355 | 1388 | /* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */ |
| 1356 | 1389 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1)) |
| 1357 | | dsp1_set_dr(data); |
| 1390 | dsp_set_dr(space->machine, data); |
| 1358 | 1391 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2)) |
| 1359 | 1392 | { |
| 1360 | 1393 | if (address < 0xc000) |
| 1361 | | dsp2_dr_write(data); |
| 1394 | dsp_set_dr(space->machine, data); |
| 1362 | 1395 | else |
| 1363 | | dsp2_sr_write(data); |
| 1396 | dsp_set_sr(space->machine, data); |
| 1364 | 1397 | } |
| 1365 | 1398 | else if (state->has_addon_chip == HAS_DSP3) |
| 1366 | | dsp3_write(address, data); |
| 1367 | | else if ((state->has_addon_chip == HAS_DSP4) && (address < 0xc000)) |
| 1368 | | dsp4_write(data); |
| 1399 | if (address < 0xc000) |
| 1400 | dsp_set_dr(space->machine, data); |
| 1401 | else |
| 1402 | dsp_set_sr(space->machine, data); |
| 1403 | else if (state->has_addon_chip == HAS_DSP4) |
| 1404 | if (address < 0xc000) |
| 1405 | dsp_set_dr(space->machine, data); |
| 1406 | else |
| 1407 | dsp_set_sr(space->machine, data); |
| 1369 | 1408 | else |
| 1370 | 1409 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x300000); |
| 1371 | 1410 | |
| r9892 | r9893 | |
| 1390 | 1429 | if (address >= 0x8000) |
| 1391 | 1430 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x600000); |
| 1392 | 1431 | else if (state->has_addon_chip == HAS_DSP1) |
| 1393 | | dsp1_set_dr(data); |
| 1432 | dsp_set_dr(space->machine, data); |
| 1394 | 1433 | else |
| 1395 | 1434 | logerror("snes_w_bank4: Attempt to write to reserved address: %X = %02x\n", offset + 0x600000, data); |
| 1396 | 1435 | } |
| r9892 | r9893 | |
| 1459 | 1498 | } |
| 1460 | 1499 | } |
| 1461 | 1500 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000)) |
| 1462 | | dsp1_set_dr(data); |
| 1501 | dsp_set_dr(space->machine, data); |
| 1463 | 1502 | else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000)) |
| 1464 | 1503 | { |
| 1465 | 1504 | if (address < 0xc000) |
| 1466 | | dsp2_dr_write(data); |
| 1505 | dsp_set_dr(space->machine, data); |
| 1467 | 1506 | else |
| 1468 | | dsp2_sr_write(data); |
| 1507 | dsp_set_sr(space->machine, data); |
| 1469 | 1508 | } |
| 1470 | 1509 | else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000)) |
| 1471 | | dsp3_write(address, data); |
| 1472 | | else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000) && (address < 0xc000)) |
| 1473 | | dsp4_write(data); |
| 1510 | if (address < 0xc000) |
| 1511 | dsp_set_dr(space->machine, data); |
| 1512 | else |
| 1513 | dsp_set_sr(space->machine, data); |
| 1514 | else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000)) |
| 1515 | if (address < 0xc000) |
| 1516 | dsp_set_dr(space->machine, data); |
| 1517 | else |
| 1518 | dsp_set_sr(space->machine, data); |
| 1474 | 1519 | else |
| 1475 | 1520 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x800000); |
| 1476 | 1521 | |
| r9892 | r9893 | |
| 1663 | 1708 | snes_ram[WRIO] = 0xff; |
| 1664 | 1709 | snes_ram[VMAIN] = 0x80; |
| 1665 | 1710 | |
| 1711 | // assume no DSP and halt it... |
| 1712 | cputag_set_input_line(machine, "dsp", INPUT_LINE_RESET, ASSERT_LINE); |
| 1713 | |
| 1666 | 1714 | switch (state->has_addon_chip) |
| 1667 | 1715 | { |
| 1668 | 1716 | case HAS_DSP1: |
| 1669 | | dsp1_init(machine); |
| 1670 | | break; |
| 1671 | | |
| 1672 | 1717 | case HAS_DSP2: |
| 1673 | | dsp2_init(machine); |
| 1674 | | break; |
| 1675 | | |
| 1676 | 1718 | case HAS_DSP3: |
| 1677 | | dsp3_init(machine); |
| 1678 | | break; |
| 1679 | | |
| 1680 | 1719 | case HAS_DSP4: |
| 1681 | | dsp4_init(machine); |
| 1720 | // we do have a DSP, let 'er rip |
| 1721 | cputag_set_input_line(machine, "dsp", INPUT_LINE_RESET, CLEAR_LINE); |
| 1682 | 1722 | break; |
| 1683 | 1723 | |
| 1684 | 1724 | case HAS_RTC: |
src/emu/cpu/upd7725/upd7725.h
| r0 | r9893 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | upd7725.h |
| 4 | |
| 5 | Core implementation for the portable NEC uPD7725 emulator |
| 6 | |
| 7 | ****************************************************************************/ |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #ifndef __UPD7725_H__ |
| 12 | #define __UPD7725_H__ |
| 13 | |
| 14 | //************************************************************************** |
| 15 | // TYPE DEFINITIONS |
| 16 | //************************************************************************** |
| 17 | |
| 18 | // ======================> upd7725_device_config |
| 19 | |
| 20 | class upd7725_device_config : public cpu_device_config |
| 21 | { |
| 22 | friend class upd7725_device; |
| 23 | |
| 24 | // construction/destruction |
| 25 | upd7725_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 26 | |
| 27 | public: |
| 28 | // allocators |
| 29 | static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); |
| 30 | virtual device_t *alloc_device(running_machine &machine) const; |
| 31 | |
| 32 | protected: |
| 33 | // device_config_execute_interface overrides |
| 34 | virtual UINT32 execute_min_cycles() const; |
| 35 | virtual UINT32 execute_max_cycles() const; |
| 36 | virtual UINT32 execute_input_lines() const; |
| 37 | |
| 38 | // device_config_memory_interface overrides |
| 39 | virtual const address_space_config *memory_space_config(int spacenum = 0) const; |
| 40 | |
| 41 | // device_config_disasm_interface overrides |
| 42 | virtual UINT32 disasm_min_opcode_bytes() const; |
| 43 | virtual UINT32 disasm_max_opcode_bytes() const; |
| 44 | |
| 45 | // inline data |
| 46 | const address_space_config m_program_config, m_data_config; |
| 47 | }; |
| 48 | |
| 49 | // ======================> upd7725_device |
| 50 | |
| 51 | class upd7725_device : public cpu_device |
| 52 | { |
| 53 | friend class upd7725_device_config; |
| 54 | |
| 55 | // construction/destruction |
| 56 | upd7725_device(running_machine &_machine, const upd7725_device_config &config); |
| 57 | |
| 58 | public: |
| 59 | UINT8 snesdsp_read(bool mode); |
| 60 | void snesdsp_write(bool mode, UINT8 data); |
| 61 | |
| 62 | protected: |
| 63 | // device-level overrides |
| 64 | virtual void device_start(); |
| 65 | virtual void device_reset(); |
| 66 | |
| 67 | // device_execute_interface overrides |
| 68 | virtual void execute_run(); |
| 69 | |
| 70 | // device_state_interface overrides |
| 71 | virtual void state_import(const device_state_entry &entry); |
| 72 | virtual void state_export(const device_state_entry &entry); |
| 73 | virtual void state_string_export(const device_state_entry &entry, astring &string); |
| 74 | |
| 75 | // device_disasm_interface overrides |
| 76 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 77 | |
| 78 | private: |
| 79 | struct Flag |
| 80 | { |
| 81 | bool s1, s0, c, z, ov1, ov0; |
| 82 | |
| 83 | inline operator unsigned() const |
| 84 | { |
| 85 | return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0); |
| 86 | } |
| 87 | |
| 88 | inline unsigned operator=(unsigned d) |
| 89 | { |
| 90 | s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01; |
| 91 | return d; |
| 92 | } |
| 93 | }; |
| 94 | |
| 95 | struct Status |
| 96 | { |
| 97 | bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0; |
| 98 | |
| 99 | inline operator unsigned() const |
| 100 | { |
| 101 | return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12) |
| 102 | + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8) |
| 103 | + (ei << 7) + (p1 << 1) + (p0 << 0); |
| 104 | } |
| 105 | |
| 106 | inline unsigned operator=(unsigned d) |
| 107 | { |
| 108 | rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000; |
| 109 | dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100; |
| 110 | ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001; |
| 111 | return d; |
| 112 | } |
| 113 | }; |
| 114 | |
| 115 | struct Regs |
| 116 | { |
| 117 | UINT16 pc; //program counter |
| 118 | UINT16 stack[4]; //LIFO |
| 119 | UINT16 rp; //ROM pointer |
| 120 | UINT8 dp; //data pointer |
| 121 | INT16 k; |
| 122 | INT16 l; |
| 123 | INT16 m; |
| 124 | INT16 n; |
| 125 | INT16 a; //accumulator |
| 126 | INT16 b; //accumulator |
| 127 | Flag flaga; |
| 128 | Flag flagb; |
| 129 | UINT16 tr; //temporary register |
| 130 | UINT16 trb; //temporary register |
| 131 | Status sr; //status register |
| 132 | UINT16 dr; //data register |
| 133 | bool siack; |
| 134 | bool soack; |
| 135 | UINT16 idb; |
| 136 | } regs; |
| 137 | |
| 138 | void exec_op(UINT32 opcode); |
| 139 | void exec_rt(UINT32 opcode); |
| 140 | void exec_jp(UINT32 opcode); |
| 141 | void exec_ld(UINT32 opcode); |
| 142 | |
| 143 | void stack_push(); |
| 144 | void stack_pull(); |
| 145 | |
| 146 | UINT16 dataRAM[256]; |
| 147 | |
| 148 | int m_icount; |
| 149 | |
| 150 | address_space *m_program, *m_data; |
| 151 | direct_read_data *m_direct; |
| 152 | }; |
| 153 | |
| 154 | // device type definition |
| 155 | extern const device_type UPD7725; |
| 156 | |
| 157 | //************************************************************************** |
| 158 | // ENUMERATIONS |
| 159 | //************************************************************************** |
| 160 | |
| 161 | // registers |
| 162 | enum |
| 163 | { |
| 164 | UPD7725_PC = 1, |
| 165 | UPD7725_RP, |
| 166 | UPD7725_DP, |
| 167 | UPD7725_K, |
| 168 | UPD7725_L, |
| 169 | UPD7725_M, |
| 170 | UPD7725_N, |
| 171 | UPD7725_A, |
| 172 | UPD7725_B, |
| 173 | UPD7725_FLAGA, |
| 174 | UPD7725_FLAGB, |
| 175 | UPD7725_SR, |
| 176 | UPD7725_DR |
| 177 | }; |
| 178 | |
| 179 | #endif // UPD7725 |
src/emu/cpu/upd7725/dasm7725.c
| r0 | r9893 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | dasm7725.c |
| 4 | Disassembler for the portable uPD7725 emulator. |
| 5 | Written by byuu |
| 6 | MAME conversion by R. Belmont |
| 7 | |
| 8 | ***************************************************************************/ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "upd7725.h" |
| 12 | |
| 13 | CPU_DISASSEMBLE( upd7725 ) |
| 14 | { |
| 15 | static char output[256]; |
| 16 | UINT32 opcode = oprom[2] | (oprom[1] << 8) | (oprom[0] << 16); |
| 17 | UINT32 type = (opcode >> 22); |
| 18 | |
| 19 | // printf("dasm: PC %x opcode %08x\n", pc, opcode); |
| 20 | |
| 21 | memset(output, 0, sizeof(output)); |
| 22 | |
| 23 | if(type == 0 || type == 1) { //OP,RT |
| 24 | UINT8 pselect = (opcode >> 20)&0x3; //P select |
| 25 | UINT8 alu = (opcode >> 16)&0xf; //ALU operation mode |
| 26 | UINT8 asl = (opcode >> 15)&0x1; //accumulator select |
| 27 | UINT8 dpl = (opcode >> 13)&0x3; //DP low modify |
| 28 | UINT8 dphm = (opcode >> 9)&0xf; //DP high XOR modify |
| 29 | UINT8 rpdcr = (opcode >> 8)&0x1; //RP decrement |
| 30 | UINT8 src = (opcode >> 4)&0xf; //move source |
| 31 | UINT8 dst = (opcode >> 0)&0xf; //move destination |
| 32 | |
| 33 | switch(alu) { |
| 34 | case 0: strcat(output, "nop "); break; |
| 35 | case 1: strcat(output, "or "); break; |
| 36 | case 2: strcat(output, "and "); break; |
| 37 | case 3: strcat(output, "xor "); break; |
| 38 | case 4: strcat(output, "sub "); break; |
| 39 | case 5: strcat(output, "add "); break; |
| 40 | case 6: strcat(output, "sbb "); break; |
| 41 | case 7: strcat(output, "adc "); break; |
| 42 | case 8: strcat(output, "dec "); break; |
| 43 | case 9: strcat(output, "inc "); break; |
| 44 | case 10: strcat(output, "cmp "); break; |
| 45 | case 11: strcat(output, "shr1 "); break; |
| 46 | case 12: strcat(output, "shl1 "); break; |
| 47 | case 13: strcat(output, "shl2 "); break; |
| 48 | case 14: strcat(output, "shl4 "); break; |
| 49 | case 15: strcat(output, "xchg "); break; |
| 50 | } |
| 51 | |
| 52 | if(alu < 8) { |
| 53 | switch(pselect) { |
| 54 | case 0: strcat(output, "ram,"); break; |
| 55 | case 1: strcat(output, "idb,"); break; |
| 56 | case 2: strcat(output, "m,"); break; |
| 57 | case 3: strcat(output, "n,"); break; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | switch(asl) { |
| 62 | case 0: strcat(output, "a"); break; |
| 63 | case 1: strcat(output, "b"); break; |
| 64 | } |
| 65 | |
| 66 | if(dst) { |
| 67 | strcat(output, " | mov "); |
| 68 | |
| 69 | switch(src) { |
| 70 | case 0: strcat(output, "trb,"); break; |
| 71 | case 1: strcat(output, "a,"); break; |
| 72 | case 2: strcat(output, "b,"); break; |
| 73 | case 3: strcat(output, "tr,"); break; |
| 74 | case 4: strcat(output, "dp,"); break; |
| 75 | case 5: strcat(output, "rp,"); break; |
| 76 | case 6: strcat(output, "ro,"); break; |
| 77 | case 7: strcat(output, "sgn,"); break; |
| 78 | case 8: strcat(output, "dr,"); break; |
| 79 | case 9: strcat(output, "drnf,"); break; |
| 80 | case 10: strcat(output, "sr,"); break; |
| 81 | case 11: strcat(output, "sim,"); break; |
| 82 | case 12: strcat(output, "sil,"); break; |
| 83 | case 13: strcat(output, "k,"); break; |
| 84 | case 14: strcat(output, "l,"); break; |
| 85 | case 15: strcat(output, "mem,"); break; |
| 86 | } |
| 87 | |
| 88 | switch(dst) { |
| 89 | case 0: strcat(output, "non"); break; |
| 90 | case 1: strcat(output, "a"); break; |
| 91 | case 2: strcat(output, "b"); break; |
| 92 | case 3: strcat(output, "tr"); break; |
| 93 | case 4: strcat(output, "dp"); break; |
| 94 | case 5: strcat(output, "rp"); break; |
| 95 | case 6: strcat(output, "dr"); break; |
| 96 | case 7: strcat(output, "sr"); break; |
| 97 | case 8: strcat(output, "sol"); break; |
| 98 | case 9: strcat(output, "som"); break; |
| 99 | case 10: strcat(output, "k"); break; |
| 100 | case 11: strcat(output, "klr"); break; |
| 101 | case 12: strcat(output, "klm"); break; |
| 102 | case 13: strcat(output, "l"); break; |
| 103 | case 14: strcat(output, "trb"); break; |
| 104 | case 15: strcat(output, "mem"); break; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | if(dpl) { |
| 109 | switch(dpl) { |
| 110 | case 0: strcat(output, " | dpnop"); break; |
| 111 | case 1: strcat(output, " | dpinc"); break; |
| 112 | case 2: strcat(output, " | dpdec"); break; |
| 113 | case 3: strcat(output, " | dpclr"); break; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | if(dphm) { |
| 118 | switch(dphm) { |
| 119 | case 0: strcat(output, " | m0"); break; |
| 120 | case 1: strcat(output, " | m1"); break; |
| 121 | case 2: strcat(output, " | m2"); break; |
| 122 | case 3: strcat(output, " | m3"); break; |
| 123 | case 4: strcat(output, " | m4"); break; |
| 124 | case 5: strcat(output, " | m5"); break; |
| 125 | case 6: strcat(output, " | m6"); break; |
| 126 | case 7: strcat(output, " | m7"); break; |
| 127 | case 8: strcat(output, " | m8"); break; |
| 128 | case 9: strcat(output, " | m9"); break; |
| 129 | case 10: strcat(output, " | ma"); break; |
| 130 | case 11: strcat(output, " | mb"); break; |
| 131 | case 12: strcat(output, " | mc"); break; |
| 132 | case 13: strcat(output, " | md"); break; |
| 133 | case 14: strcat(output, " | me"); break; |
| 134 | case 15: strcat(output, " | mf"); break; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | if(rpdcr == 1) { |
| 139 | strcat(output, " | rpdec"); |
| 140 | } |
| 141 | |
| 142 | if(type == 1) { |
| 143 | strcat(output, " | ret"); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | if(type == 2) { //JP |
| 148 | UINT16 brch = (opcode >> 13) & 0x1ff; //branch |
| 149 | UINT16 na = (opcode >> 2) & 0x7ff; //next address |
| 150 | |
| 151 | switch(brch) { |
| 152 | case 0x080: strcat(output, "jnca "); break; |
| 153 | case 0x082: strcat(output, "jca "); break; |
| 154 | case 0x084: strcat(output, "jncb "); break; |
| 155 | case 0x086: strcat(output, "jcb "); break; |
| 156 | case 0x088: strcat(output, "jnza "); break; |
| 157 | case 0x08a: strcat(output, "jza "); break; |
| 158 | case 0x08c: strcat(output, "jnzb "); break; |
| 159 | case 0x08e: strcat(output, "jzb "); break; |
| 160 | case 0x090: strcat(output, "jnova0 "); break; |
| 161 | case 0x092: strcat(output, "jova0 "); break; |
| 162 | case 0x094: strcat(output, "jnovb0 "); break; |
| 163 | case 0x096: strcat(output, "jovb0 "); break; |
| 164 | case 0x098: strcat(output, "jnova1 "); break; |
| 165 | case 0x09a: strcat(output, "jova1 "); break; |
| 166 | case 0x09c: strcat(output, "jnovb1 "); break; |
| 167 | case 0x09e: strcat(output, "jovb1 "); break; |
| 168 | case 0x0a0: strcat(output, "jnsa0 "); break; |
| 169 | case 0x0a2: strcat(output, "jsa0 "); break; |
| 170 | case 0x0a4: strcat(output, "jnsb0 "); break; |
| 171 | case 0x0a6: strcat(output, "jsb0 "); break; |
| 172 | case 0x0a8: strcat(output, "jnsa1 "); break; |
| 173 | case 0x0aa: strcat(output, "jsa1 "); break; |
| 174 | case 0x0ac: strcat(output, "jnsb1 "); break; |
| 175 | case 0x0ae: strcat(output, "jsb1 "); break; |
| 176 | case 0x0b0: strcat(output, "jdpl0 "); break; |
| 177 | case 0x0b1: strcat(output, "jdpln0 "); break; |
| 178 | case 0x0b2: strcat(output, "jdplf "); break; |
| 179 | case 0x0b3: strcat(output, "jdplnf "); break; |
| 180 | case 0x0b4: strcat(output, "jnsiak "); break; |
| 181 | case 0x0b6: strcat(output, "jsiak "); break; |
| 182 | case 0x0b8: strcat(output, "jnsoak "); break; |
| 183 | case 0x0ba: strcat(output, "jsoak "); break; |
| 184 | case 0x0bc: strcat(output, "jnrqm "); break; |
| 185 | case 0x0be: strcat(output, "jrqm "); break; |
| 186 | case 0x100: strcat(output, "jmp "); break; |
| 187 | case 0x140: strcat(output, "call "); break; |
| 188 | default: strcat(output, "?????? "); break; |
| 189 | } |
| 190 | |
| 191 | char temp[16]; |
| 192 | |
| 193 | sprintf(temp, "$%x", na); |
| 194 | strcat(output, temp); |
| 195 | } |
| 196 | |
| 197 | if(type == 3) { //LD |
| 198 | strcat(output, "ld "); |
| 199 | UINT16 id = opcode >> 6; |
| 200 | UINT8 dst = (opcode >> 0) & 0xf; //destination |
| 201 | |
| 202 | char temp[16]; |
| 203 | sprintf(temp, "$%x,", id); |
| 204 | strcat(output, temp); |
| 205 | |
| 206 | switch(dst) { |
| 207 | case 0: strcat(output, "non"); break; |
| 208 | case 1: strcat(output, "a"); break; |
| 209 | case 2: strcat(output, "b"); break; |
| 210 | case 3: strcat(output, "tr"); break; |
| 211 | case 4: strcat(output, "dp"); break; |
| 212 | case 5: strcat(output, "rp"); break; |
| 213 | case 6: strcat(output, "dr"); break; |
| 214 | case 7: strcat(output, "sr"); break; |
| 215 | case 8: strcat(output, "sol"); break; |
| 216 | case 9: strcat(output, "som"); break; |
| 217 | case 10: strcat(output, "k"); break; |
| 218 | case 11: strcat(output, "klr"); break; |
| 219 | case 12: strcat(output, "klm"); break; |
| 220 | case 13: strcat(output, "l"); break; |
| 221 | case 14: strcat(output, "trb"); break; |
| 222 | case 15: strcat(output, "mem"); break; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | strcpy(buffer, output); |
| 227 | |
| 228 | return 1 | DASMFLAG_SUPPORTED; |
| 229 | } |
| 230 | |
src/emu/cpu/upd7725/upd7725.c
| r0 | r9893 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | upd7725.h |
| 4 | |
| 5 | Core implementation for the portable NEC uPD7725 emulator |
| 6 | |
| 7 | Original by byuu in the public domain. |
| 8 | MAME conversion by R. Belmont |
| 9 | |
| 10 | ****************************************************************************/ |
| 11 | |
| 12 | #include "emu.h" |
| 13 | #include "debugger.h" |
| 14 | #include "upd7725.h" |
| 15 | |
| 16 | //************************************************************************** |
| 17 | // DEVICE DEFINITIONS |
| 18 | //************************************************************************** |
| 19 | |
| 20 | const device_type UPD7725 = upd7725_device_config::static_alloc_device_config; |
| 21 | |
| 22 | //************************************************************************** |
| 23 | // UPD7725 DEVICE CONFIG |
| 24 | //************************************************************************** |
| 25 | |
| 26 | //------------------------------------------------- |
| 27 | // upd7725_device_config - constructor |
| 28 | //------------------------------------------------- |
| 29 | |
| 30 | upd7725_device_config::upd7725_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 31 | : cpu_device_config(mconfig, static_alloc_device_config, "upd7725", tag, owner, clock), |
| 32 | m_program_config("program", ENDIANNESS_BIG, 32, 13, -2), // data bus width, address bus width, -2 means DWORD-addressable |
| 33 | m_data_config("data", ENDIANNESS_BIG, 16, 11, -1) // -1 for WORD-addressable |
| 34 | { |
| 35 | } |
| 36 | |
| 37 | |
| 38 | //------------------------------------------------- |
| 39 | // static_alloc_device_config - allocate a new |
| 40 | // configuration object |
| 41 | //------------------------------------------------- |
| 42 | |
| 43 | device_config *upd7725_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 44 | { |
| 45 | return global_alloc(upd7725_device_config(mconfig, tag, owner, clock)); |
| 46 | } |
| 47 | |
| 48 | |
| 49 | //------------------------------------------------- |
| 50 | // alloc_device - allocate a new device object |
| 51 | //------------------------------------------------- |
| 52 | |
| 53 | device_t *upd7725_device_config::alloc_device(running_machine &machine) const |
| 54 | { |
| 55 | return auto_alloc(&machine, upd7725_device(machine, *this)); |
| 56 | } |
| 57 | |
| 58 | |
| 59 | //------------------------------------------------- |
| 60 | // execute_min_cycles - return minimum number of |
| 61 | // cycles it takes for one instruction to execute |
| 62 | //------------------------------------------------- |
| 63 | |
| 64 | UINT32 upd7725_device_config::execute_min_cycles() const |
| 65 | { |
| 66 | return 4; |
| 67 | } |
| 68 | |
| 69 | |
| 70 | //------------------------------------------------- |
| 71 | // execute_max_cycles - return maximum number of |
| 72 | // cycles it takes for one instruction to execute |
| 73 | //------------------------------------------------- |
| 74 | |
| 75 | UINT32 upd7725_device_config::execute_max_cycles() const |
| 76 | { |
| 77 | return 4; |
| 78 | } |
| 79 | |
| 80 | |
| 81 | //------------------------------------------------- |
| 82 | // execute_input_lines - return the number of |
| 83 | // input/interrupt lines |
| 84 | //------------------------------------------------- |
| 85 | |
| 86 | UINT32 upd7725_device_config::execute_input_lines() const |
| 87 | { |
| 88 | return 0; |
| 89 | } |
| 90 | |
| 91 | |
| 92 | //------------------------------------------------- |
| 93 | // memory_space_config - return the configuration |
| 94 | // of the specified address space, or NULL if |
| 95 | // the space doesn't exist |
| 96 | //------------------------------------------------- |
| 97 | |
| 98 | const address_space_config *upd7725_device_config::memory_space_config(int spacenum) const |
| 99 | { |
| 100 | return (spacenum == AS_PROGRAM) ? &m_program_config : &m_data_config; |
| 101 | } |
| 102 | |
| 103 | |
| 104 | //------------------------------------------------- |
| 105 | // disasm_min_opcode_bytes - return the length |
| 106 | // of the shortest instruction, in bytes |
| 107 | //------------------------------------------------- |
| 108 | |
| 109 | UINT32 upd7725_device_config::disasm_min_opcode_bytes() const |
| 110 | { |
| 111 | return 4; |
| 112 | } |
| 113 | |
| 114 | |
| 115 | //------------------------------------------------- |
| 116 | // disasm_max_opcode_bytes - return the length |
| 117 | // of the longest instruction, in bytes |
| 118 | //------------------------------------------------- |
| 119 | |
| 120 | UINT32 upd7725_device_config::disasm_max_opcode_bytes() const |
| 121 | { |
| 122 | return 4; |
| 123 | } |
| 124 | |
| 125 | |
| 126 | |
| 127 | //************************************************************************** |
| 128 | // DEVICE INTERFACE |
| 129 | //************************************************************************** |
| 130 | |
| 131 | upd7725_device::upd7725_device(running_machine &_machine, const upd7725_device_config &config) |
| 132 | : cpu_device(_machine, config), |
| 133 | m_program(NULL), |
| 134 | m_data(NULL), |
| 135 | m_direct(NULL) |
| 136 | { |
| 137 | } |
| 138 | |
| 139 | //------------------------------------------------- |
| 140 | // device_start - start up the device |
| 141 | //------------------------------------------------- |
| 142 | |
| 143 | void upd7725_device::device_start() |
| 144 | { |
| 145 | // get our address spaces |
| 146 | m_program = space(AS_PROGRAM); |
| 147 | m_data = space(AS_DATA); |
| 148 | m_direct = &m_program->direct(); |
| 149 | |
| 150 | // register our state for the debugger |
| 151 | astring tempstr; |
| 152 | state_add(STATE_GENPC, "GENPC", regs.pc).noshow(); |
| 153 | state_add(UPD7725_PC, "PC", regs.pc); |
| 154 | state_add(UPD7725_RP, "RP", regs.rp); |
| 155 | state_add(UPD7725_DP, "DP", regs.dp); |
| 156 | state_add(UPD7725_K, "K", regs.k); |
| 157 | state_add(UPD7725_L, "L", regs.l); |
| 158 | state_add(UPD7725_M, "M", regs.m); |
| 159 | state_add(UPD7725_N, "N", regs.n); |
| 160 | state_add(UPD7725_A, "A", regs.a); |
| 161 | state_add(UPD7725_B, "B", regs.b); |
| 162 | state_add(UPD7725_SR, "SR", regs.sr); |
| 163 | state_add(UPD7725_DR, "DR", regs.dr); |
| 164 | |
| 165 | m_icountptr = &m_icount; |
| 166 | } |
| 167 | |
| 168 | //------------------------------------------------- |
| 169 | // device_reset - reset the device |
| 170 | //------------------------------------------------- |
| 171 | |
| 172 | void upd7725_device::device_reset() |
| 173 | { |
| 174 | for (unsigned i = 0; i < 256; i++) |
| 175 | { |
| 176 | dataRAM[i] = 0x0000; |
| 177 | } |
| 178 | |
| 179 | regs.pc = 0x000; |
| 180 | regs.stack[0] = 0x000; |
| 181 | regs.stack[1] = 0x000; |
| 182 | regs.stack[2] = 0x000; |
| 183 | regs.stack[3] = 0x000; |
| 184 | regs.flaga = 0x00; |
| 185 | regs.flagb = 0x00; |
| 186 | regs.sr = 0x0000; |
| 187 | regs.rp = 0x3ff; |
| 188 | regs.siack = 0; |
| 189 | regs.soack = 0; |
| 190 | } |
| 191 | |
| 192 | //------------------------------------------------- |
| 193 | // state_import - import state into the device, |
| 194 | // after it has been set |
| 195 | //------------------------------------------------- |
| 196 | |
| 197 | void upd7725_device::state_import(const device_state_entry &entry) |
| 198 | { |
| 199 | } |
| 200 | |
| 201 | |
| 202 | //------------------------------------------------- |
| 203 | // state_export - export state from the device, |
| 204 | // to a known location where it can be read |
| 205 | //------------------------------------------------- |
| 206 | |
| 207 | void upd7725_device::state_export(const device_state_entry &entry) |
| 208 | { |
| 209 | } |
| 210 | |
| 211 | |
| 212 | //------------------------------------------------- |
| 213 | // state_string_export - export state as a string |
| 214 | // for the debugger |
| 215 | //------------------------------------------------- |
| 216 | |
| 217 | void upd7725_device::state_string_export(const device_state_entry &entry, astring &string) |
| 218 | { |
| 219 | switch (entry.index()) |
| 220 | { |
| 221 | case UPD7725_FLAGA: |
| 222 | string.printf("%s %s %c%c %s %s", |
| 223 | regs.flaga.s1 ? "S1" : "s1", |
| 224 | regs.flaga.s0 ? "S0" : "s0", |
| 225 | regs.flaga.c ? "C" : "c", |
| 226 | regs.flaga.z ? "Z" : "z", |
| 227 | regs.flaga.ov1 ? "OV1" : "ov1", |
| 228 | regs.flaga.ov0 ? "OV0" : "ov0"); |
| 229 | break; |
| 230 | |
| 231 | case UPD7725_FLAGB: |
| 232 | string.printf("%s %s %c%c %s %s", |
| 233 | regs.flagb.s1 ? "S1" : "s1", |
| 234 | regs.flagb.s0 ? "S0" : "s0", |
| 235 | regs.flagb.c ? "C" : "c", |
| 236 | regs.flagb.z ? "Z" : "z", |
| 237 | regs.flagb.ov1 ? "OV1" : "ov1", |
| 238 | regs.flagb.ov0 ? "OV0" : "ov0"); |
| 239 | break; |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | |
| 244 | //------------------------------------------------- |
| 245 | // disasm_disassemble - call the disassembly |
| 246 | // helper function |
| 247 | //------------------------------------------------- |
| 248 | |
| 249 | offs_t upd7725_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 250 | { |
| 251 | extern CPU_DISASSEMBLE( upd7725 ); |
| 252 | return CPU_DISASSEMBLE_NAME(upd7725)(NULL, buffer, pc, oprom, opram, 0); |
| 253 | } |
| 254 | |
| 255 | void upd7725_device::execute_run() |
| 256 | { |
| 257 | UINT32 opcode; |
| 258 | |
| 259 | do |
| 260 | { |
| 261 | // call debugger hook if necessary |
| 262 | if (device_t::m_machine.debug_flags & DEBUG_FLAG_ENABLED) |
| 263 | { |
| 264 | debugger_instruction_hook(this, regs.pc); |
| 265 | } |
| 266 | |
| 267 | opcode = m_direct->read_decrypted_dword(regs.pc<<2)>>8; |
| 268 | regs.pc++; |
| 269 | switch(opcode >> 22) |
| 270 | { |
| 271 | case 0: exec_op(opcode); break; |
| 272 | case 1: exec_rt(opcode); break; |
| 273 | case 2: exec_jp(opcode); break; |
| 274 | case 3: exec_ld(opcode); break; |
| 275 | } |
| 276 | |
| 277 | INT32 result = (INT32)regs.k * regs.l; //sign + 30-bit result |
| 278 | regs.m = result >> 15; //store sign + top 15-bits |
| 279 | regs.n = result << 1; //store low 15-bits + zero |
| 280 | |
| 281 | m_icount--; |
| 282 | |
| 283 | } while (m_icount > 0); |
| 284 | } |
| 285 | |
| 286 | void upd7725_device::exec_op(UINT32 opcode) { |
| 287 | UINT8 pselect = (opcode >> 20)&0x3; //P select |
| 288 | UINT8 alu = (opcode >> 16)&0xf; //ALU operation mode |
| 289 | UINT8 asl = (opcode >> 15)&0x1; //accumulator select |
| 290 | UINT8 dpl = (opcode >> 13)&0x3; //DP low modify |
| 291 | UINT8 dphm = (opcode >> 9)&0xf; //DP high XOR modify |
| 292 | UINT8 rpdcr = (opcode >> 8)&0x1; //RP decrement |
| 293 | UINT8 src = (opcode >> 4)&0xf; //move source |
| 294 | UINT8 dst = (opcode >> 0)&0xf; //move destination |
| 295 | |
| 296 | switch(src) { |
| 297 | case 0: regs.idb = regs.trb; break; |
| 298 | case 1: regs.idb = regs.a; break; |
| 299 | case 2: regs.idb = regs.b; break; |
| 300 | case 3: regs.idb = regs.tr; break; |
| 301 | case 4: regs.idb = regs.dp; break; |
| 302 | case 5: regs.idb = regs.rp; break; |
| 303 | case 6: regs.idb = m_data->read_word(regs.rp<<1); break; |
| 304 | case 7: regs.idb = 0x8000 - regs.flaga.s1; break; |
| 305 | case 8: regs.idb = regs.dr; regs.sr.rqm = 1; break; |
| 306 | case 9: regs.idb = regs.dr; break; |
| 307 | case 10: regs.idb = regs.sr; break; |
| 308 | //case 11: regs.idb = regs.sim; break; |
| 309 | //case 12: regs.idb = regs.sil; break; |
| 310 | case 13: regs.idb = regs.k; break; |
| 311 | case 14: regs.idb = regs.l; break; |
| 312 | case 15: regs.idb = dataRAM[regs.dp]; break; |
| 313 | } |
| 314 | |
| 315 | if(alu) { |
| 316 | UINT16 p=0, q=0, r=0; |
| 317 | Flag flag; |
| 318 | bool c=0; |
| 319 | |
| 320 | switch(pselect) { |
| 321 | case 0: p = dataRAM[regs.dp]; break; |
| 322 | case 1: p = regs.idb; break; |
| 323 | case 2: p = regs.m; break; |
| 324 | case 3: p = regs.n; break; |
| 325 | } |
| 326 | |
| 327 | switch(asl) { |
| 328 | case 0: q = regs.a; flag = regs.flaga; c = regs.flagb.c; break; |
| 329 | case 1: q = regs.b; flag = regs.flagb; c = regs.flaga.c; break; |
| 330 | } |
| 331 | |
| 332 | switch(alu) { |
| 333 | case 1: r = q | p; break; //OR |
| 334 | case 2: r = q & p; break; //AND |
| 335 | case 3: r = q ^ p; break; //XOR |
| 336 | case 4: r = q - p; break; //SUB |
| 337 | case 5: r = q + p; break; //ADD |
| 338 | case 6: r = q - p - c; break; //SBB |
| 339 | case 7: r = q + p + c; break; //ADC |
| 340 | case 8: r = q - 1; p = 1; break; //DEC |
| 341 | case 9: r = q + 1; p = 1; break; //INC |
| 342 | case 10: r = ~q; break; //CMP |
| 343 | case 11: r = (q >> 1) | (q & 0x8000); break; //SHR1 (ASR) |
| 344 | case 12: r = (q << 1) | c; break; //SHL1 (ROL) |
| 345 | case 13: r = (q << 2) | 3; break; //SHL2 |
| 346 | case 14: r = (q << 4) | 15; break; //SHL4 |
| 347 | case 15: r = (q << 8) | (q >> 8); break; //XCHG |
| 348 | } |
| 349 | |
| 350 | flag.s0 = (r & 0x8000); |
| 351 | flag.z = (r == 0); |
| 352 | |
| 353 | switch(alu) { |
| 354 | case 1: case 2: case 3: case 10: case 13: case 14: case 15: { |
| 355 | flag.c = 0; |
| 356 | flag.ov0 = 0; |
| 357 | flag.ov1 = 0; |
| 358 | break; |
| 359 | } |
| 360 | case 4: case 5: case 6: case 7: case 8: case 9: { |
| 361 | if(alu & 1) { |
| 362 | //addition |
| 363 | flag.ov0 = (q ^ r) & ~(q ^ p) & 0x8000; |
| 364 | flag.c = (r < q); |
| 365 | } else { |
| 366 | //subtraction |
| 367 | flag.ov0 = (q ^ r) & (q ^ p) & 0x8000; |
| 368 | flag.c = (r > q); |
| 369 | } |
| 370 | if(flag.ov0) { |
| 371 | flag.s1 = flag.ov1 ^ !(r & 0x8000); |
| 372 | flag.ov1 = !flag.ov1; |
| 373 | } |
| 374 | break; |
| 375 | } |
| 376 | case 11: { |
| 377 | flag.c = q & 1; |
| 378 | flag.ov0 = 0; |
| 379 | flag.ov1 = 0; |
| 380 | break; |
| 381 | } |
| 382 | case 12: { |
| 383 | flag.c = q >> 15; |
| 384 | flag.ov0 = 0; |
| 385 | flag.ov1 = 0; |
| 386 | break; |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | switch(asl) { |
| 391 | case 0: regs.a = r; regs.flaga = flag; break; |
| 392 | case 1: regs.b = r; regs.flagb = flag; break; |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | exec_ld((regs.idb << 6) + dst); |
| 397 | |
| 398 | switch(dpl) { |
| 399 | case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC |
| 400 | case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC |
| 401 | case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR |
| 402 | } |
| 403 | |
| 404 | regs.dp ^= dphm << 4; |
| 405 | |
| 406 | if(rpdcr) regs.rp--; |
| 407 | } |
| 408 | |
| 409 | void upd7725_device::exec_rt(UINT32 opcode) { |
| 410 | exec_op(opcode); |
| 411 | stack_pull(); |
| 412 | } |
| 413 | |
| 414 | void upd7725_device::exec_jp(UINT32 opcode) { |
| 415 | UINT16 brch = (opcode >> 13) & 0x1ff; //branch |
| 416 | UINT16 na = (opcode >> 2) & 0x7ff; //next address |
| 417 | |
| 418 | bool r = false; |
| 419 | |
| 420 | switch(brch) { |
| 421 | case 0x080: r = (regs.flaga.c == 0); break; //JNCA |
| 422 | case 0x082: r = (regs.flaga.c == 1); break; //JCA |
| 423 | case 0x084: r = (regs.flagb.c == 0); break; //JNCB |
| 424 | case 0x086: r = (regs.flagb.c == 1); break; //JCB |
| 425 | case 0x088: r = (regs.flaga.z == 0); break; //JNZA |
| 426 | case 0x08a: r = (regs.flaga.z == 1); break; //JZA |
| 427 | case 0x08c: r = (regs.flagb.z == 0); break; //JNZB |
| 428 | case 0x08e: r = (regs.flagb.z == 1); break; //JZB |
| 429 | case 0x090: r = (regs.flaga.ov0 == 0); break; //JNOVA0 |
| 430 | case 0x092: r = (regs.flaga.ov0 == 1); break; //JOVA0 |
| 431 | case 0x094: r = (regs.flagb.ov0 == 0); break; //JNOVB0 |
| 432 | case 0x096: r = (regs.flagb.ov0 == 1); break; //JOVB0 |
| 433 | case 0x098: r = (regs.flaga.ov1 == 0); break; //JNOVA1 |
| 434 | case 0x09a: r = (regs.flaga.ov1 == 1); break; //JOVA1 |
| 435 | case 0x09c: r = (regs.flagb.ov1 == 0); break; //JNOVB1 |
| 436 | case 0x09e: r = (regs.flagb.ov1 == 1); break; //JOVB1 |
| 437 | case 0x0a0: r = (regs.flaga.s0 == 0); break; //JNSA0 |
| 438 | case 0x0a2: r = (regs.flaga.s0 == 1); break; //JSA0 |
| 439 | case 0x0a4: r = (regs.flagb.s0 == 0); break; //JNSB0 |
| 440 | case 0x0a6: r = (regs.flagb.s0 == 1); break; //JSB0 |
| 441 | case 0x0a8: r = (regs.flaga.s1 == 0); break; //JNSA1 |
| 442 | case 0x0aa: r = (regs.flaga.s1 == 1); break; //JSA1 |
| 443 | case 0x0ac: r = (regs.flagb.s1 == 0); break; //JNSB1 |
| 444 | case 0x0ae: r = (regs.flagb.s1 == 1); break; //JSB1 |
| 445 | |
| 446 | case 0x0b0: r = (regs.dp & 0x0f) == 0x00; break; //JDPL0 |
| 447 | case 0x0b1: r = (regs.dp & 0x0f) != 0x00; break; //JDPLN0 |
| 448 | case 0x0b2: r = (regs.dp & 0x0f) == 0x0f; break; //JDPLF |
| 449 | case 0x0b3: r = (regs.dp & 0x0f) != 0x0f; break; //JDPLNF |
| 450 | |
| 451 | case 0x0b4: r = (regs.siack == 0); break; //JNSIAK |
| 452 | case 0x0b6: r = (regs.siack == 1); break; //JSIAK |
| 453 | |
| 454 | case 0x0b8: r = (regs.soack == 0); break; //JNSOAK |
| 455 | case 0x0ba: r = (regs.soack == 1); break; //JSOAK |
| 456 | |
| 457 | case 0x0bc: r = (regs.sr.rqm == 0); break; //JNRQM |
| 458 | case 0x0be: r = (regs.sr.rqm == 1); break; //JRQM |
| 459 | |
| 460 | case 0x100: r = true; break; //JMP |
| 461 | case 0x140: r = true; stack_push(); break; //CALL |
| 462 | } |
| 463 | |
| 464 | if(r) regs.pc = na; |
| 465 | } |
| 466 | |
| 467 | void upd7725_device::exec_ld(UINT32 opcode) { |
| 468 | UINT16 id = opcode >> 6; //immediate data |
| 469 | UINT8 dst = (opcode >> 0) & 0xf; //destination |
| 470 | |
| 471 | regs.idb = id; |
| 472 | |
| 473 | switch(dst) { |
| 474 | case 0: break; |
| 475 | case 1: regs.a = id; break; |
| 476 | case 2: regs.b = id; break; |
| 477 | case 3: regs.tr = id; break; |
| 478 | case 4: regs.dp = id; break; |
| 479 | case 5: regs.rp = id; break; |
| 480 | case 6: regs.dr = id; regs.sr.rqm = 1; break; |
| 481 | case 7: regs.sr = (regs.sr & 0x907c) | (id & ~0x907c); break; |
| 482 | //case 8: regs.sol = id; break; |
| 483 | //case 9: regs.som = id; break; |
| 484 | case 10: regs.k = id; break; |
| 485 | case 11: regs.k = id; regs.l = m_data->read_word(regs.rp<<1); break; |
| 486 | case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break; |
| 487 | case 13: regs.l = id; break; |
| 488 | case 14: regs.trb = id; break; |
| 489 | case 15: dataRAM[regs.dp] = id; break; |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | void upd7725_device::stack_push() { |
| 494 | regs.stack[3] = regs.stack[2]; |
| 495 | regs.stack[2] = regs.stack[1]; |
| 496 | regs.stack[1] = regs.stack[0]; |
| 497 | regs.stack[0] = regs.pc & 0x7ff; |
| 498 | } |
| 499 | |
| 500 | void upd7725_device::stack_pull() { |
| 501 | regs.pc = regs.stack[0] & 0x7ff; |
| 502 | regs.stack[0] = regs.stack[1]; |
| 503 | regs.stack[1] = regs.stack[2]; |
| 504 | regs.stack[2] = regs.stack[3]; |
| 505 | regs.stack[3] = 0x000; |
| 506 | } |
| 507 | |
| 508 | UINT8 upd7725_device::snesdsp_read(bool mode) { |
| 509 | |
| 510 | if (!mode) |
| 511 | { |
| 512 | return regs.sr >> 8; |
| 513 | } |
| 514 | |
| 515 | if (regs.sr.drc == 0) |
| 516 | { |
| 517 | //16-bit |
| 518 | if(regs.sr.drs == 0) |
| 519 | { |
| 520 | regs.sr.drs = 1; |
| 521 | return regs.dr >> 0; |
| 522 | } |
| 523 | else |
| 524 | { |
| 525 | regs.sr.rqm = 0; |
| 526 | regs.sr.drs = 0; |
| 527 | return regs.dr >> 8; |
| 528 | } |
| 529 | } |
| 530 | else |
| 531 | { |
| 532 | //8-bit |
| 533 | regs.sr.rqm = 0; |
| 534 | return regs.dr >> 0; |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | void upd7725_device::snesdsp_write(bool mode, UINT8 data) { |
| 539 | if (!mode) return; |
| 540 | |
| 541 | if (regs.sr.drc == 0) |
| 542 | { |
| 543 | //16-bit |
| 544 | if (regs.sr.drs == 0) |
| 545 | { |
| 546 | regs.sr.drs = 1; |
| 547 | regs.dr = (regs.dr & 0xff00) | (data << 0); |
| 548 | } |
| 549 | else |
| 550 | { |
| 551 | regs.sr.rqm = 0; |
| 552 | regs.sr.drs = 0; |
| 553 | regs.dr = (data << 8) | (regs.dr & 0x00ff); |
| 554 | } |
| 555 | } |
| 556 | else |
| 557 | { |
| 558 | //8-bit |
| 559 | regs.sr.rqm = 0; |
| 560 | regs.dr = (regs.dr & 0xff00) | (data << 0); |
| 561 | } |
| 562 | } |
src/mess/drivers/snes.c
| r9892 | r9893 | |
| 8 | 8 | Anthony Kruize |
| 9 | 9 | Angelo Salese |
| 10 | 10 | Fabio Priuli |
| 11 | byuu |
| 11 | 12 | Based on the original MESS driver by Lee Hammerton (aka Savoury Snax) |
| 12 | 13 | |
| 13 | 14 | Driver is preliminary right now. |
| r9892 | r9893 | |
| 31 | 32 | #include "cpu/spc700/spc700.h" |
| 32 | 33 | #include "cpu/superfx/superfx.h" |
| 33 | 34 | #include "cpu/g65816/g65816.h" |
| 35 | #include "cpu/upd7725/upd7725.h" |
| 34 | 36 | #include "includes/snes.h" |
| 35 | 37 | #include "machine/snescart.h" |
| 36 | 38 | #include "crsshair.h" |
| r9892 | r9893 | |
| 87 | 89 | AM_RANGE(0xffc0, 0xffff) AM_DEVREAD("spc700", spc_ipl_r) |
| 88 | 90 | ADDRESS_MAP_END |
| 89 | 91 | |
| 92 | static ADDRESS_MAP_START( dsp_prg_map, ADDRESS_SPACE_PROGRAM, 32 ) |
| 93 | AM_RANGE(0x0000, 0x07ff) AM_ROM AM_REGION("dspprg", 0) |
| 94 | ADDRESS_MAP_END |
| 90 | 95 | |
| 96 | static ADDRESS_MAP_START( dsp_data_map, ADDRESS_SPACE_PROGRAM, 16 ) |
| 97 | AM_RANGE(0x0000, 0x03ff) AM_ROM AM_REGION("dspdata", 0) |
| 98 | ADDRESS_MAP_END |
| 91 | 99 | |
| 92 | 100 | /************************************* |
| 93 | 101 | * |
| r9892 | r9893 | |
| 695 | 703 | MCFG_CPU_ADD("soundcpu", SPC700, 1024000) /* 1.024 MHz */ |
| 696 | 704 | MCFG_CPU_PROGRAM_MAP(spc_map) |
| 697 | 705 | |
| 706 | MCFG_CPU_ADD("dsp", UPD7725, 8000000) |
| 707 | MCFG_CPU_PROGRAM_MAP(dsp_prg_map) |
| 708 | MCFG_CPU_DATA_MAP(dsp_data_map) |
| 709 | |
| 698 | 710 | //MCFG_QUANTUM_TIME(HZ(48000)) |
| 699 | 711 | MCFG_QUANTUM_PERFECT_CPU("maincpu") |
| 700 | 712 | |
| r9892 | r9893 | |
| 774 | 786 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 775 | 787 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 776 | 788 | |
| 777 | | ROM_REGION( 0x1000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 778 | | ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) ) |
| 779 | | ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) ) |
| 789 | ROM_REGION( 0x10000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 790 | ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) ) |
| 791 | ROM_LOAD( "dsp1.bin", SNES_DSP1_OFFSET, 0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) ) |
| 792 | ROM_LOAD( "dsp2.bin", SNES_DSP2_OFFSET, 0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) ) |
| 793 | ROM_LOAD( "dsp3.bin", SNES_DSP3_OFFSET, 0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) ) |
| 794 | ROM_LOAD( "dsp4.bin", SNES_DSP4_OFFSET, 0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) ) |
| 780 | 795 | |
| 781 | 796 | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 797 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 798 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 782 | 799 | ROM_END |
| 783 | 800 | |
| 784 | 801 | ROM_START( snessfx ) |
| r9892 | r9893 | |
| 787 | 804 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 788 | 805 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 789 | 806 | |
| 790 | | ROM_REGION( 0x1000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 791 | | ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) ) |
| 807 | ROM_REGION( 0x10000, "addons", ROMREGION_ERASE00 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 792 | 808 | |
| 793 | 809 | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 810 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 811 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 794 | 812 | ROM_END |
| 795 | 813 | |
| 796 | 814 | ROM_START( snespal ) |
| r9892 | r9893 | |
| 799 | 817 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 800 | 818 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 801 | 819 | |
| 802 | | ROM_REGION( 0x1000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 803 | | ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) ) |
| 804 | | ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) ) |
| 820 | ROM_REGION( 0x10000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 821 | ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) ) |
| 822 | ROM_LOAD( "dsp1.bin", SNES_DSP1_OFFSET, 0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) ) |
| 823 | ROM_LOAD( "dsp2.bin", SNES_DSP2_OFFSET, 0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) ) |
| 824 | ROM_LOAD( "dsp3.bin", SNES_DSP3_OFFSET, 0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) ) |
| 825 | ROM_LOAD( "dsp4.bin", SNES_DSP4_OFFSET, 0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) ) |
| 805 | 826 | |
| 806 | 827 | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 828 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 829 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 807 | 830 | ROM_END |
| 808 | 831 | |
| 809 | 832 | ROM_START( snespsfx ) |
| r9892 | r9893 | |
| 812 | 835 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 813 | 836 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 814 | 837 | |
| 815 | | ROM_REGION( 0x1000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 816 | | ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) ) |
| 838 | ROM_REGION( 0x10000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 817 | 839 | |
| 818 | 840 | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 841 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 842 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 819 | 843 | ROM_END |
| 820 | 844 | |
| 821 | 845 | ROM_START( snesst ) |
| r9892 | r9893 | |
| 824 | 848 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 825 | 849 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 826 | 850 | |
| 827 | | ROM_REGION( 0x1000, "addons", ROMREGION_ERASE00 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 851 | ROM_REGION( 0x10000, "addons", ROMREGION_ERASE00 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 828 | 852 | |
| 829 | 853 | ROM_REGION( 0x40000, "sufami", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 830 | 854 | ROM_LOAD( "shvc-qh-0.bin", 0, 0x40000, CRC(9b4ca911) SHA1(ef86ea192eed03d5c413fdbbfd46043be1d7a127) ) |
| 831 | 855 | |
| 832 | 856 | ROM_REGION( MAX_SNES_CART_SIZE, "slot_a", ROMREGION_ERASE00 ) |
| 833 | 857 | ROM_REGION( MAX_SNES_CART_SIZE, "slot_b", ROMREGION_ERASE00 ) |
| 858 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 859 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 834 | 860 | ROM_END |
| 835 | 861 | |
| 836 | 862 | ROM_START( snesbsx ) |
| r9892 | r9893 | |
| 839 | 865 | ROM_REGION( 0x100, "user5", 0 ) /* IPL ROM */ |
| 840 | 866 | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 841 | 867 | |
| 842 | | ROM_REGION( 0x1000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 843 | | ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) ) |
| 844 | | ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) ) |
| 868 | ROM_REGION( 0x10000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 869 | ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) ) |
| 870 | ROM_LOAD( "dsp1.bin", SNES_DSP1_OFFSET, 0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) ) |
| 871 | ROM_LOAD( "dsp2.bin", SNES_DSP2_OFFSET, 0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) ) |
| 872 | ROM_LOAD( "dsp3.bin", SNES_DSP3_OFFSET, 0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) ) |
| 873 | ROM_LOAD( "dsp4.bin", SNES_DSP4_OFFSET, 0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) ) |
| 845 | 874 | |
| 846 | 875 | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 847 | 876 | ROM_REGION( MAX_SNES_CART_SIZE, "flash", ROMREGION_ERASE00 ) |
| 877 | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 878 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 848 | 879 | ROM_END |
| 849 | 880 | |
| 850 | 881 | |