shelves/new_menus/src/mame/machine/inder_sb.c
| r0 | r29302 | |
| 1 | /* Inder / Dinamic Sound Board */ |
| 2 | |
| 3 | |
| 4 | #include "emu.h" |
| 5 | #include "machine/inder_sb.h" |
| 6 | |
| 7 | |
| 8 | |
| 9 | extern const device_type INDER_AUDIO = &device_creator<inder_sb_device>; |
| 10 | |
| 11 | |
| 12 | inder_sb_device::inder_sb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 13 | : device_t(mconfig, INDER_AUDIO, "Inder 4xDAC Sound Board", tag, owner, clock, "indersb", __FILE__), |
| 14 | device_mixer_interface(mconfig, *this, 2), |
| 15 | m_audiocpu(*this, "audiocpu"), |
| 16 | m_ctc(*this, "ctc"), |
| 17 | m_dac0(*this, "dac0" ), |
| 18 | m_dac1(*this, "dac1" ), |
| 19 | m_dac2(*this, "dac2" ), |
| 20 | m_dac3(*this, "dac3" ) |
| 21 | { |
| 22 | } |
| 23 | |
| 24 | |
| 25 | |
| 26 | // hacks for test purposes, these are installed over the program rom so we know when irqs are actually taken |
| 27 | READ8_MEMBER(inder_sb_device::megaphx_02cc_hack_r) { /*logerror("%04x audicpu IRQ hack 0x02cc\n", machine().device("audiocpu")->safe_pc());*/ int bank = m_soundbank[0] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x02cc]; }; |
| 28 | READ8_MEMBER(inder_sb_device::megaphx_02e6_hack_r) { /*logerror("%04x audicpu IRQ hack 0x02e6\n", machine().device("audiocpu")->safe_pc());*/ int bank = m_soundbank[1] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x02e6]; }; |
| 29 | READ8_MEMBER(inder_sb_device::megaphx_0309_hack_r) { /*logerror("%04x audicpu IRQ hack 0x0309\n", machine().device("audiocpu")->safe_pc());*/ int bank = m_soundbank[2] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x0309]; }; |
| 30 | READ8_MEMBER(inder_sb_device::megaphx_0323_hack_r) { /*logerror("%04x audicpu IRQ hack 0x0323\n", machine().device("audiocpu")->safe_pc());*/ int bank = m_soundbank[3] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x0323]; }; |
| 31 | |
| 32 | |
| 33 | |
| 34 | READ16_MEMBER(inder_sb_device::megaphx_0x050002_r) |
| 35 | { |
| 36 | space.machine().scheduler().synchronize(); |
| 37 | // int pc = machine().device("maincpu")->safe_pc(); |
| 38 | int ret = m_soundback; |
| 39 | m_soundback = 0; |
| 40 | //logerror("(%06x) megaphx_0x050002_r (from z80?) %04x\n", pc, mem_mask); |
| 41 | return ret; |
| 42 | } |
| 43 | |
| 44 | WRITE16_MEMBER(inder_sb_device::megaphx_0x050000_w) |
| 45 | { |
| 46 | // int pc = machine().device("maincpu")->safe_pc(); |
| 47 | space.machine().scheduler().synchronize(); |
| 48 | |
| 49 | //logerror("(%06x) megaphx_0x050000_w (to z80?) %04x %04x\n", pc, data, mem_mask); |
| 50 | m_soundsent = 0xff; |
| 51 | m_sounddata = data; |
| 52 | |
| 53 | } |
| 54 | |
| 55 | void inder_sb_device::install_sound_hacks(void) |
| 56 | { |
| 57 | address_space &space = m_audiocpu->space(AS_PROGRAM); |
| 58 | space.install_read_handler(0x02cc, 0x02cc, read8_delegate(FUNC(inder_sb_device::megaphx_02cc_hack_r), this)); |
| 59 | space.install_read_handler(0x02e6, 0x02e6, read8_delegate(FUNC(inder_sb_device::megaphx_02e6_hack_r), this)); |
| 60 | space.install_read_handler(0x0309, 0x0309, read8_delegate(FUNC(inder_sb_device::megaphx_0309_hack_r), this)); |
| 61 | space.install_read_handler(0x0323, 0x0323, read8_delegate(FUNC(inder_sb_device::megaphx_0323_hack_r), this)); |
| 62 | } |
| 63 | |
| 64 | void inder_sb_device::update_sound_irqs(void) |
| 65 | { |
| 66 | if (m_soundirq) m_audiocpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); |
| 67 | else m_audiocpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); |
| 68 | } |
| 69 | |
| 70 | WRITE_LINE_MEMBER(inder_sb_device::z80ctc_ch0) |
| 71 | { |
| 72 | // int bank = m_soundbank[0] & 7; membank("snddata")->set_entry(bank); |
| 73 | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 74 | if (state) m_soundirq |= 0x1; |
| 75 | else m_soundirq &= ~0x1; |
| 76 | |
| 77 | update_sound_irqs(); |
| 78 | } |
| 79 | |
| 80 | |
| 81 | WRITE_LINE_MEMBER(inder_sb_device::z80ctc_ch1) |
| 82 | { |
| 83 | // int bank = m_soundbank[1] & 7; membank("snddata")->set_entry(bank); |
| 84 | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 85 | if (state) m_soundirq |= 0x2; |
| 86 | else m_soundirq &= ~0x2; |
| 87 | |
| 88 | update_sound_irqs(); |
| 89 | } |
| 90 | |
| 91 | |
| 92 | WRITE_LINE_MEMBER(inder_sb_device::z80ctc_ch2) |
| 93 | { |
| 94 | // int bank = m_soundbank[2] & 7; membank("snddata")->set_entry(bank); |
| 95 | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 96 | if (state) m_soundirq |= 0x4; |
| 97 | else m_soundirq &= ~0x4; |
| 98 | |
| 99 | update_sound_irqs(); |
| 100 | } |
| 101 | |
| 102 | |
| 103 | |
| 104 | |
| 105 | WRITE_LINE_MEMBER(inder_sb_device::z80ctc_ch3) |
| 106 | { |
| 107 | // int bank = m_soundbank[3] & 7; membank("snddata")->set_entry(bank); |
| 108 | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 109 | if (state) m_soundirq |= 0x8; |
| 110 | else m_soundirq &= ~0x8; |
| 111 | |
| 112 | update_sound_irqs(); |
| 113 | } |
| 114 | |
| 115 | |
| 116 | |
| 117 | |
| 118 | static Z80CTC_INTERFACE( z80ctc_intf ) // runs in IM2 , vector set to 0x20 , values there are 0xCC, 0x02, 0xE6, 0x02, 0x09, 0x03, 0x23, 0x03 (so 02cc, 02e6, 0309, 0323, all of which are valid irq handlers) |
| 119 | { |
| 120 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, inder_sb_device, z80ctc_ch0), // for channel 0 |
| 121 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, inder_sb_device, z80ctc_ch1), // for channel 1 |
| 122 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, inder_sb_device, z80ctc_ch2), // for channel 2 |
| 123 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, inder_sb_device, z80ctc_ch3), // for channel 3 |
| 124 | }; |
| 125 | |
| 126 | static const z80_daisy_config daisy_chain[] = |
| 127 | { |
| 128 | { "ctc" }, |
| 129 | { NULL } |
| 130 | }; |
| 131 | |
| 132 | |
| 133 | static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, inder_sb_device ) |
| 134 | AM_RANGE(0x0000, 0x1fff) AM_ROM |
| 135 | AM_RANGE(0x4000, 0x7fff) AM_RAM |
| 136 | AM_RANGE(0x8000, 0xffff) AM_ROMBANK("snddata") |
| 137 | ADDRESS_MAP_END |
| 138 | |
| 139 | READ8_MEMBER(inder_sb_device::megaphx_sound_cmd_r) |
| 140 | { |
| 141 | space.machine().scheduler().synchronize(); |
| 142 | return m_sounddata; |
| 143 | } |
| 144 | |
| 145 | READ8_MEMBER(inder_sb_device::megaphx_sound_sent_r) |
| 146 | { |
| 147 | space.machine().scheduler().synchronize(); |
| 148 | int ret = m_soundsent; |
| 149 | m_soundsent = 0; |
| 150 | return ret; |
| 151 | } |
| 152 | |
| 153 | WRITE8_MEMBER(inder_sb_device::megaphx_sound_to_68k_w) |
| 154 | { |
| 155 | // int pc = machine().device("audiocpu")->safe_pc(); |
| 156 | space.machine().scheduler().synchronize(); |
| 157 | //logerror("(%04x) megaphx_sound_to_68k_w (to 68k?) %02x\n", pc, data); |
| 158 | |
| 159 | m_soundback = data; |
| 160 | } |
| 161 | |
| 162 | WRITE8_MEMBER(inder_sb_device::dac0_value_write) |
| 163 | { |
| 164 | // printf("dac0_data_write %02x\n", data); |
| 165 | m_dac0->write_unsigned8(data); |
| 166 | } |
| 167 | |
| 168 | WRITE8_MEMBER(inder_sb_device::dac0_gain_write) |
| 169 | { |
| 170 | // printf("dac0_gain_write %02x\n", data); |
| 171 | dac_gain[0] = data; |
| 172 | } |
| 173 | |
| 174 | WRITE8_MEMBER(inder_sb_device::dac1_value_write) |
| 175 | { |
| 176 | // printf("dac1_data_write %02x\n", data); |
| 177 | m_dac1->write_unsigned8(data); |
| 178 | } |
| 179 | |
| 180 | WRITE8_MEMBER(inder_sb_device::dac1_gain_write) |
| 181 | { |
| 182 | // printf("dac1_gain_write %02x\n", data); |
| 183 | dac_gain[1] = data; |
| 184 | } |
| 185 | |
| 186 | WRITE8_MEMBER(inder_sb_device::dac2_value_write) |
| 187 | { |
| 188 | // printf("dac2_data_write %02x\n", data); |
| 189 | m_dac2->write_unsigned8(data); |
| 190 | } |
| 191 | |
| 192 | WRITE8_MEMBER(inder_sb_device::dac2_gain_write) |
| 193 | { |
| 194 | // printf("dac2_gain_write %02x\n", data); |
| 195 | dac_gain[2] = data; |
| 196 | } |
| 197 | |
| 198 | WRITE8_MEMBER(inder_sb_device::dac3_value_write) |
| 199 | { |
| 200 | // printf("dac3_data_write %02x\n", data); |
| 201 | m_dac3->write_unsigned8(data); |
| 202 | } |
| 203 | |
| 204 | WRITE8_MEMBER(inder_sb_device::dac3_gain_write) |
| 205 | { |
| 206 | // printf("dac3_gain_write %02x\n", data); |
| 207 | dac_gain[3] = data; |
| 208 | } |
| 209 | |
| 210 | WRITE8_MEMBER(inder_sb_device::dac0_rombank_write) |
| 211 | { |
| 212 | m_soundbank[0] = data; |
| 213 | |
| 214 | // printf("dac0_rombank_write %02x", data); |
| 215 | } |
| 216 | |
| 217 | WRITE8_MEMBER(inder_sb_device::dac1_rombank_write) |
| 218 | { |
| 219 | m_soundbank[1] = data; |
| 220 | // printf("dac1_rombank_write %02x", data); |
| 221 | |
| 222 | } |
| 223 | |
| 224 | WRITE8_MEMBER(inder_sb_device::dac2_rombank_write) |
| 225 | { |
| 226 | m_soundbank[2] = data; |
| 227 | // printf("dac2_rombank_write %02x", data); |
| 228 | } |
| 229 | |
| 230 | WRITE8_MEMBER(inder_sb_device::dac3_rombank_write) |
| 231 | { |
| 232 | m_soundbank[3] = data; |
| 233 | // printf("dac3_rombank_write %02x", data); |
| 234 | |
| 235 | } |
| 236 | |
| 237 | |
| 238 | static ADDRESS_MAP_START( sound_io, AS_IO, 8, inder_sb_device ) |
| 239 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 240 | AM_RANGE(0x00, 0x00) AM_WRITE(dac0_value_write) |
| 241 | AM_RANGE(0x01, 0x01) AM_WRITE(dac0_gain_write) |
| 242 | AM_RANGE(0x02, 0x02) AM_WRITE(dac1_value_write) |
| 243 | AM_RANGE(0x03, 0x03) AM_WRITE(dac1_gain_write) |
| 244 | AM_RANGE(0x04, 0x04) AM_WRITE(dac2_value_write) |
| 245 | AM_RANGE(0x05, 0x05) AM_WRITE(dac2_gain_write) |
| 246 | AM_RANGE(0x06, 0x06) AM_WRITE(dac3_value_write) |
| 247 | AM_RANGE(0x07, 0x07) AM_WRITE(dac3_gain_write) |
| 248 | |
| 249 | // not 100% sure how rom banking works.. but each channel can specify a different bank for the 0x8000 range. Maybe the bank happens when the interrupt triggers so each channel reads the correct data? (so we'd need to put the actual functions in the CTC callbacks) |
| 250 | AM_RANGE(0x10, 0x10) AM_WRITE(dac0_rombank_write) |
| 251 | AM_RANGE(0x11, 0x11) AM_WRITE(dac1_rombank_write) |
| 252 | AM_RANGE(0x12, 0x12) AM_WRITE(dac2_rombank_write) |
| 253 | AM_RANGE(0x13, 0x13) AM_WRITE(dac3_rombank_write) |
| 254 | |
| 255 | |
| 256 | |
| 257 | |
| 258 | AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) |
| 259 | |
| 260 | AM_RANGE(0x30, 0x30) AM_READWRITE(megaphx_sound_cmd_r, megaphx_sound_to_68k_w) |
| 261 | AM_RANGE(0x31, 0x31) AM_READ(megaphx_sound_sent_r) |
| 262 | ADDRESS_MAP_END |
| 263 | |
| 264 | |
| 265 | |
| 266 | static MACHINE_CONFIG_FRAGMENT( inder_sb ) |
| 267 | MCFG_CPU_ADD("audiocpu", Z80, 8000000) // unk freq |
| 268 | MCFG_CPU_CONFIG(daisy_chain) |
| 269 | MCFG_CPU_PROGRAM_MAP(sound_map) |
| 270 | MCFG_CPU_IO_MAP(sound_io) |
| 271 | |
| 272 | MCFG_Z80CTC_ADD( "ctc", 4000000, z80ctc_intf ) // unk freq |
| 273 | |
| 274 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 275 | MCFG_DAC_ADD("dac0") |
| 276 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 277 | MCFG_DAC_ADD("dac1") |
| 278 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 279 | MCFG_DAC_ADD("dac2") |
| 280 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 281 | MCFG_DAC_ADD("dac3") |
| 282 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 283 | |
| 284 | |
| 285 | MACHINE_CONFIG_END |
| 286 | |
| 287 | machine_config_constructor inder_sb_device::device_mconfig_additions() const |
| 288 | { |
| 289 | return MACHINE_CONFIG_NAME( inder_sb ); |
| 290 | } |
| 291 | |
| 292 | void inder_sb_device::device_start() |
| 293 | { |
| 294 | membank("snddata")->configure_entries(0, 8, memregion("user2")->base(), 0x8000); |
| 295 | membank("snddata")->set_entry(0); |
| 296 | |
| 297 | install_sound_hacks(); |
| 298 | } |
| 299 | |
| 300 | void inder_sb_device::device_reset() |
| 301 | { |
| 302 | m_soundirq = 0; |
| 303 | } |
shelves/new_menus/src/mame/machine/inder_vid.c
| r0 | r29302 | |
| 1 | /* Inder / Dinamic Video */ |
| 2 | |
| 3 | /* Inder / Dinamic Sound Board */ |
| 4 | |
| 5 | |
| 6 | #include "emu.h" |
| 7 | #include "machine/inder_vid.h" |
| 8 | |
| 9 | |
| 10 | |
| 11 | extern const device_type INDER_VIDEO = &device_creator<inder_vid_device>; |
| 12 | |
| 13 | |
| 14 | inder_vid_device::inder_vid_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 15 | : device_t(mconfig, INDER_VIDEO, "Inder / Dinamic TMS Video", tag, owner, clock, "indervd", __FILE__), |
| 16 | /* device_video_interface(mconfig, *this, false), */ |
| 17 | m_vram(*this, "vram"), |
| 18 | m_palette(*this, "palette"), |
| 19 | m_tms(*this, "tms") |
| 20 | { |
| 21 | } |
| 22 | |
| 23 | static ADDRESS_MAP_START( megaphx_tms_map, AS_PROGRAM, 16, inder_vid_device ) |
| 24 | |
| 25 | AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("vram") // vram? |
| 26 | |
| 27 | AM_RANGE(0x04000000, 0x0400000f) AM_DEVWRITE8("ramdac",ramdac_device,index_w,0x00ff) |
| 28 | AM_RANGE(0x04000010, 0x0400001f) AM_DEVREADWRITE8("ramdac",ramdac_device,pal_r,pal_w,0x00ff) |
| 29 | AM_RANGE(0x04000030, 0x0400003f) AM_DEVWRITE8("ramdac",ramdac_device,index_r_w,0x00ff) |
| 30 | AM_RANGE(0x04000090, 0x0400009f) AM_WRITENOP |
| 31 | |
| 32 | AM_RANGE(0xc0000000, 0xc00001ff) AM_DEVREADWRITE("tms", tms34010_device, io_register_r, io_register_w) |
| 33 | AM_RANGE(0xffc00000, 0xffffffff) AM_RAM |
| 34 | ADDRESS_MAP_END |
| 35 | |
| 36 | |
| 37 | static void megaphx_scanline(screen_device &screen, bitmap_rgb32 &bitmap, int scanline, const tms34010_display_params *params) |
| 38 | { |
| 39 | inder_vid_device *state = (inder_vid_device*)screen.machine().device("inder_vid"); |
| 40 | |
| 41 | UINT16 *vram = &state->m_vram[(params->rowaddr << 8) & 0x3ff00]; |
| 42 | UINT32 *dest = &bitmap.pix32(scanline); |
| 43 | |
| 44 | const pen_t *paldata = state->m_palette->pens(); |
| 45 | |
| 46 | int coladdr = params->coladdr; |
| 47 | int x; |
| 48 | |
| 49 | for (x = params->heblnk; x < params->hsblnk; x += 2) |
| 50 | { |
| 51 | UINT16 pixels = vram[coladdr++ & 0xff]; |
| 52 | dest[x + 0] = paldata[pixels & 0xff]; |
| 53 | dest[x + 1] = paldata[pixels >> 8]; |
| 54 | } |
| 55 | |
| 56 | } |
| 57 | |
| 58 | |
| 59 | static void megaphx_to_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 60 | { |
| 61 | inder_vid_device *state = (inder_vid_device*)space.machine().device("inder_vid"); |
| 62 | |
| 63 | if (state->m_shiftfull == 0) |
| 64 | { |
| 65 | //printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); |
| 66 | |
| 67 | memcpy(shiftreg, &state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], TOBYTE(0x2000)); // & ~TOWORD(0x1fff) is needed for round 6 |
| 68 | state->m_shiftfull = 1; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | static void megaphx_from_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 73 | { |
| 74 | // printf("write from shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); |
| 75 | |
| 76 | inder_vid_device *state = (inder_vid_device*)space.machine().device("inder_vid"); |
| 77 | |
| 78 | memcpy(&state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], shiftreg, TOBYTE(0x2000)); |
| 79 | |
| 80 | state->m_shiftfull = 0; |
| 81 | } |
| 82 | |
| 83 | |
| 84 | |
| 85 | static void m68k_gen_int(device_t *device, int state) |
| 86 | { |
| 87 | cpu_device *maincpu = (cpu_device*)device->machine().device("maincpu"); |
| 88 | if (state) maincpu->set_input_line(4, ASSERT_LINE); |
| 89 | else maincpu->set_input_line(4, CLEAR_LINE); |
| 90 | |
| 91 | } |
| 92 | |
| 93 | |
| 94 | static const tms34010_config tms_config_megaphx = |
| 95 | { |
| 96 | TRUE, /* halt on reset */ |
| 97 | "inder_vid:inder_screen", /* the screen operated on */ |
| 98 | XTAL_40MHz/12, /* pixel clock */ |
| 99 | 2, /* pixels per clock */ |
| 100 | NULL, /* scanline callback (indexed16) */ |
| 101 | megaphx_scanline, /* scanline callback (rgb32) */ |
| 102 | m68k_gen_int, /* generate interrupt */ |
| 103 | megaphx_to_shiftreg, /* write to shiftreg function */ |
| 104 | megaphx_from_shiftreg /* read from shiftreg function */ |
| 105 | }; |
| 106 | |
| 107 | |
| 108 | static ADDRESS_MAP_START( ramdac_map, AS_0, 8, inder_vid_device ) |
| 109 | AM_RANGE(0x000, 0x3ff) AM_DEVREADWRITE("ramdac",ramdac_device,ramdac_pal_r,ramdac_rgb888_w) |
| 110 | ADDRESS_MAP_END |
| 111 | |
| 112 | static RAMDAC_INTERFACE( ramdac_intf ) |
| 113 | { |
| 114 | 1 |
| 115 | }; |
| 116 | |
| 117 | static MACHINE_CONFIG_FRAGMENT( inder_vid ) |
| 118 | MCFG_CPU_ADD("tms", TMS34010, XTAL_40MHz) |
| 119 | MCFG_CPU_CONFIG(tms_config_megaphx) |
| 120 | MCFG_CPU_PROGRAM_MAP(megaphx_tms_map) |
| 121 | |
| 122 | MCFG_SCREEN_ADD("inder_screen", RASTER) |
| 123 | MCFG_SCREEN_RAW_PARAMS(XTAL_40MHz/12, 424, 0, 338-1, 262, 0, 246-1) |
| 124 | MCFG_SCREEN_UPDATE_DEVICE("tms", tms34010_device, tms340x0_rgb32) |
| 125 | |
| 126 | |
| 127 | MCFG_PALETTE_ADD("palette", 256) |
| 128 | |
| 129 | MCFG_RAMDAC_ADD("ramdac", ramdac_intf, ramdac_map, "palette") |
| 130 | |
| 131 | |
| 132 | MACHINE_CONFIG_END |
| 133 | |
| 134 | machine_config_constructor inder_vid_device::device_mconfig_additions() const |
| 135 | { |
| 136 | return MACHINE_CONFIG_NAME( inder_vid ); |
| 137 | } |
| 138 | |
| 139 | void inder_vid_device::device_start() |
| 140 | { |
| 141 | |
| 142 | } |
| 143 | |
| 144 | void inder_vid_device::device_reset() |
| 145 | { |
| 146 | m_shiftfull = 0; |
| 147 | } |
shelves/new_menus/src/mame/drivers/littlerb.c
| r29301 | r29302 | |
| 66 | 66 | |
| 67 | 67 | #include "emu.h" |
| 68 | 68 | #include "cpu/m68000/m68000.h" |
| 69 | | #include "video/ramdac.h" |
| 70 | 69 | #include "sound/dac.h" |
| 71 | | #include "cpu/tms34010/tms34010.h" |
| 70 | #include "machine/inder_vid.h" |
| 72 | 71 | |
| 73 | 72 | class littlerb_state : public driver_device |
| 74 | 73 | { |
| r29301 | r29302 | |
| 76 | 75 | littlerb_state(const machine_config &mconfig, device_type type, const char *tag) |
| 77 | 76 | : driver_device(mconfig, type, tag), |
| 78 | 77 | m_maincpu(*this, "maincpu"), |
| 79 | | m_screen(*this, "screen"), |
| 78 | m_indervid(*this, "inder_vid"), |
| 80 | 79 | m_dacl(*this, "dacl"), |
| 81 | 80 | m_dacr(*this, "dacr"), |
| 82 | | |
| 83 | | m_vram(*this, "vram"), |
| 84 | | m_palette(*this, "palette"), |
| 85 | | m_shiftfull(0) |
| 86 | | |
| 81 | m_soundframe(0) |
| 87 | 82 | { |
| 88 | 83 | } |
| 89 | 84 | |
| r29301 | r29302 | |
| 91 | 86 | |
| 92 | 87 | |
| 93 | 88 | required_device<cpu_device> m_maincpu; |
| 94 | | required_device<screen_device> m_screen; |
| 89 | required_device<inder_vid_device> m_indervid; |
| 90 | |
| 91 | |
| 95 | 92 | required_device<dac_device> m_dacl; |
| 96 | 93 | required_device<dac_device> m_dacr; |
| 97 | 94 | UINT8 m_sound_index_l,m_sound_index_r; |
| 98 | 95 | UINT16 m_sound_pointer_l,m_sound_pointer_r; |
| 96 | int m_soundframe; |
| 97 | |
| 99 | 98 | DECLARE_CUSTOM_INPUT_MEMBER(littlerb_frame_step_r); |
| 100 | 99 | DECLARE_WRITE16_MEMBER(littlerb_l_sound_w); |
| 101 | 100 | DECLARE_WRITE16_MEMBER(littlerb_r_sound_w); |
| 102 | 101 | UINT8 sound_data_shift(); |
| 103 | | TIMER_DEVICE_CALLBACK_MEMBER(littlerb_scanline); |
| 102 | |
| 103 | TIMER_DEVICE_CALLBACK_MEMBER(littlerb_scanline_sound); |
| 104 | 104 | |
| 105 | | |
| 106 | | required_shared_ptr<UINT16> m_vram; |
| 107 | | required_device<palette_device> m_palette; |
| 108 | | int m_shiftfull; // this might be a driver specific hack for a TMS bug. |
| 109 | | |
| 110 | 105 | }; |
| 111 | 106 | |
| 112 | 107 | |
| 113 | | |
| 114 | | static ADDRESS_MAP_START( ramdac_map, AS_0, 8, littlerb_state ) |
| 115 | | AM_RANGE(0x000, 0x3ff) AM_DEVREADWRITE("ramdac",ramdac_device,ramdac_pal_r,ramdac_rgb888_w) |
| 116 | | ADDRESS_MAP_END |
| 117 | | |
| 118 | | static RAMDAC_INTERFACE( ramdac_intf ) |
| 119 | | { |
| 120 | | 0 |
| 121 | | }; |
| 122 | | |
| 123 | | |
| 124 | | |
| 125 | 108 | /* could be slightly different (timing wise, directly related to the irqs), but certainly they smoked some bad pot for this messy way ... */ |
| 126 | 109 | UINT8 littlerb_state::sound_data_shift() |
| 127 | 110 | { |
| 128 | | return ((m_screen->frame_number() % 16) == 0) ? 8 : 0; |
| 111 | return ((m_soundframe % 16) == 0) ? 8 : 0; |
| 129 | 112 | } |
| 130 | 113 | |
| 131 | 114 | /* l is SFX, r is BGM (they doesn't seem to share the same data ROM) */ |
| r29301 | r29302 | |
| 151 | 134 | AM_RANGE(0x000000, 0x0fffff) AM_ROM |
| 152 | 135 | AM_RANGE(0x200000, 0x203fff) AM_RAM // main ram? |
| 153 | 136 | |
| 154 | | AM_RANGE(0x700000, 0x700007) AM_DEVREADWRITE("tms", tms34010_device, host_r, host_w) |
| 137 | AM_RANGE(0x700000, 0x700007) AM_DEVREADWRITE("inder_vid:tms", tms34010_device, host_r, host_w) |
| 155 | 138 | |
| 156 | 139 | AM_RANGE(0x740000, 0x740001) AM_WRITE(littlerb_l_sound_w) |
| 157 | 140 | AM_RANGE(0x760000, 0x760001) AM_WRITE(littlerb_r_sound_w) |
| r29301 | r29302 | |
| 164 | 147 | /* guess according to DASM code and checking the gameplay speed, could be different */ |
| 165 | 148 | CUSTOM_INPUT_MEMBER(littlerb_state::littlerb_frame_step_r) |
| 166 | 149 | { |
| 167 | | UINT32 ret = m_screen->frame_number(); |
| 150 | UINT32 ret = m_soundframe; |
| 168 | 151 | |
| 169 | 152 | return (ret) & 7; |
| 170 | 153 | } |
| r29301 | r29302 | |
| 246 | 229 | PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 247 | 230 | INPUT_PORTS_END |
| 248 | 231 | |
| 249 | | TIMER_DEVICE_CALLBACK_MEMBER(littlerb_state::littlerb_scanline) |
| 232 | TIMER_DEVICE_CALLBACK_MEMBER(littlerb_state::littlerb_scanline_sound) |
| 250 | 233 | { |
| 251 | 234 | int scanline = param; |
| 252 | 235 | |
| r29301 | r29302 | |
| 265 | 248 | m_sound_pointer_r&=0x3ff; |
| 266 | 249 | } |
| 267 | 250 | |
| 251 | if (scanline == 0) m_soundframe++; |
| 268 | 252 | |
| 269 | | // the TMS generates the main interrupt |
| 270 | | |
| 253 | // printf("scanline %d\n", scanline); |
| 271 | 254 | } |
| 272 | 255 | |
| 273 | 256 | |
| 274 | 257 | |
| 275 | | static ADDRESS_MAP_START( littlerb_tms_map, AS_PROGRAM, 16, littlerb_state ) |
| 276 | | AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("vram") |
| 277 | | AM_RANGE(0x04000000, 0x0400000f) AM_DEVWRITE8("ramdac",ramdac_device,index_w,0x00ff) |
| 278 | | AM_RANGE(0x04000010, 0x0400001f) AM_DEVREADWRITE8("ramdac",ramdac_device,pal_r,pal_w,0x00ff) |
| 279 | | AM_RANGE(0x04000030, 0x0400003f) AM_DEVWRITE8("ramdac",ramdac_device,index_r_w,0x00ff) |
| 280 | | AM_RANGE(0xc0000000, 0xc00001ff) AM_DEVREADWRITE("tms", tms34010_device, io_register_r, io_register_w) |
| 281 | | AM_RANGE(0xffc00000, 0xffffffff) AM_RAM |
| 282 | | ADDRESS_MAP_END |
| 283 | | |
| 284 | | |
| 285 | | static void littlerb_scanline(screen_device &screen, bitmap_rgb32 &bitmap, int scanline, const tms34010_display_params *params) |
| 286 | | { |
| 287 | | littlerb_state *state = screen.machine().driver_data<littlerb_state>(); |
| 288 | | |
| 289 | | UINT16 *vram = &state->m_vram[(((params->rowaddr << 8)) & 0x3ff00) ]; |
| 290 | | UINT32 *dest = &bitmap.pix32(scanline); |
| 291 | | |
| 292 | | const pen_t *paldata = state->m_palette->pens(); |
| 293 | | |
| 294 | | int coladdr = params->coladdr; |
| 295 | | int x; |
| 296 | | |
| 297 | | for (x = params->heblnk; x < params->hsblnk; x += 2) |
| 298 | | { |
| 299 | | UINT16 pixels = vram[coladdr++ & 0xff]; |
| 300 | | dest[x + 0] = paldata[pixels & 0xff]; |
| 301 | | dest[x + 1] = paldata[pixels >> 8]; |
| 302 | | } |
| 303 | | |
| 304 | | } |
| 305 | | |
| 306 | | static void littlerb_to_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 307 | | { |
| 308 | | littlerb_state *state = space.machine().driver_data<littlerb_state>(); |
| 309 | | |
| 310 | | if (state->m_shiftfull == 0) |
| 311 | | { |
| 312 | | //printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); |
| 313 | | memcpy(shiftreg, &state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], TOBYTE(0x2000)); |
| 314 | | state->m_shiftfull = 1; |
| 315 | | } |
| 316 | | } |
| 317 | | |
| 318 | | static void littlerb_from_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 319 | | { |
| 320 | | littlerb_state *state = space.machine().driver_data<littlerb_state>(); |
| 321 | | memcpy(&state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], shiftreg, TOBYTE(0x2000)); |
| 322 | | |
| 323 | | state->m_shiftfull = 0; |
| 324 | | } |
| 325 | | |
| 326 | | |
| 327 | | |
| 328 | | |
| 329 | | static void m68k_gen_int(device_t *device, int state) |
| 330 | | { |
| 331 | | littlerb_state *drvstate = device->machine().driver_data<littlerb_state>(); |
| 332 | | if (state) drvstate->m_maincpu->set_input_line(4, ASSERT_LINE); |
| 333 | | else drvstate->m_maincpu->set_input_line(4, CLEAR_LINE); |
| 334 | | } |
| 335 | | |
| 336 | | |
| 337 | | static const tms34010_config tms_config_littlerb = |
| 338 | | { |
| 339 | | TRUE, /* halt on reset */ |
| 340 | | "screen", /* the screen operated on */ |
| 341 | | XTAL_40MHz/12, /* pixel clock */ |
| 342 | | 2, /* pixels per clock */ |
| 343 | | NULL, /* scanline callback (indexed16) */ |
| 344 | | littlerb_scanline, /* scanline callback (rgb32) */ |
| 345 | | m68k_gen_int, /* generate interrupt */ |
| 346 | | littlerb_to_shiftreg, /* write to shiftreg function */ |
| 347 | | littlerb_from_shiftreg /* read from shiftreg function */ |
| 348 | | }; |
| 349 | | |
| 350 | | |
| 351 | | |
| 352 | | |
| 353 | 258 | static MACHINE_CONFIG_START( littlerb, littlerb_state ) |
| 354 | 259 | MCFG_CPU_ADD("maincpu", M68000, 12000000) |
| 355 | 260 | MCFG_CPU_PROGRAM_MAP(littlerb_main) |
| 356 | | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", littlerb_state, littlerb_scanline, "screen", 0, 1) |
| 357 | 261 | |
| 262 | MCFG_INDER_VIDEO_ADD("inder_vid") |
| 358 | 263 | |
| 359 | | MCFG_CPU_ADD("tms", TMS34010, XTAL_40MHz) |
| 360 | | MCFG_CPU_CONFIG(tms_config_littlerb) |
| 361 | | MCFG_CPU_PROGRAM_MAP(littlerb_tms_map) |
| 264 | // should probably be done with a timer rather than relying on screen(!) |
| 265 | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", littlerb_state, littlerb_scanline_sound, "inder_vid:inder_screen", 0, 1) |
| 362 | 266 | |
| 363 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 364 | | MCFG_SCREEN_RAW_PARAMS(XTAL_40MHz/12, 424, 0, 338-1, 262, 0, 246-1) |
| 365 | | MCFG_SCREEN_UPDATE_DEVICE("tms", tms34010_device, tms340x0_rgb32) |
| 366 | | |
| 367 | | |
| 368 | | MCFG_PALETTE_ADD("palette", 0x100) |
| 369 | | |
| 370 | | MCFG_RAMDAC_ADD("ramdac", ramdac_intf, ramdac_map, "palette") |
| 371 | | |
| 372 | | // MCFG_PALETTE_INIT_OWNER(littlerb_state,littlerb) |
| 373 | 267 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker") |
| 374 | 268 | |
| 375 | 269 | MCFG_DAC_ADD("dacl") |
shelves/new_menus/src/mame/drivers/megaphx.c
| r29301 | r29302 | |
| 55 | 55 | */ |
| 56 | 56 | |
| 57 | 57 | #include "emu.h" |
| 58 | | #include "cpu/tms34010/tms34010.h" |
| 59 | 58 | #include "cpu/m68000/m68000.h" |
| 60 | | #include "cpu/z80/z80.h" |
| 61 | | #include "video/ramdac.h" |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 62 | 63 | #include "machine/i8255.h" |
| 63 | | #include "machine/z80ctc.h" |
| 64 | | #include "cpu/z80/z80daisy.h" |
| 65 | | #include "sound/dac.h" |
| 64 | #include "machine/inder_sb.h" |
| 65 | #include "machine/inder_vid.h" |
| 66 | 66 | |
| 67 | 67 | |
| 68 | |
| 68 | 69 | class megaphx_state : public driver_device |
| 69 | 70 | { |
| 70 | 71 | public: |
| 71 | 72 | megaphx_state(const machine_config &mconfig, device_type type, const char *tag) |
| 72 | 73 | : driver_device(mconfig, type, tag), |
| 73 | 74 | m_maincpu(*this, "maincpu"), |
| 74 | | m_audiocpu(*this, "audiocpu"), |
| 75 | 75 | m_mainram(*this, "mainram"), |
| 76 | | m_vram(*this, "vram"), |
| 77 | | m_ctc(*this, "ctc"), |
| 78 | | m_dac0(*this, "dac0" ), |
| 79 | | m_dac1(*this, "dac1" ), |
| 80 | | m_dac2(*this, "dac2" ), |
| 81 | | m_dac3(*this, "dac3" ), |
| 82 | 76 | port_c_value(0), |
| 83 | | m_palette(*this, "palette"), |
| 84 | | m_tms(*this, "tms") |
| 77 | m_indersb(*this, "inder_sb"), |
| 78 | m_indervid(*this, "inder_vid") |
| 79 | |
| 85 | 80 | { |
| 86 | | m_shiftfull = 0; |
| 87 | | m_soundirq = 0; |
| 81 | |
| 88 | 82 | } |
| 89 | 83 | |
| 90 | 84 | required_device<cpu_device> m_maincpu; |
| 91 | | required_device<cpu_device> m_audiocpu; |
| 92 | 85 | required_shared_ptr<UINT16> m_mainram; |
| 93 | | required_shared_ptr<UINT16> m_vram; |
| 94 | | required_device<z80ctc_device> m_ctc; |
| 95 | 86 | |
| 96 | | required_device<dac_device> m_dac0; |
| 97 | | required_device<dac_device> m_dac1; |
| 98 | | required_device<dac_device> m_dac2; |
| 99 | | required_device<dac_device> m_dac3; |
| 100 | 87 | |
| 101 | 88 | |
| 102 | 89 | |
| 90 | |
| 103 | 91 | DECLARE_DRIVER_INIT(megaphx); |
| 104 | | DECLARE_MACHINE_RESET(megaphx); |
| 105 | 92 | |
| 106 | | DECLARE_READ16_MEMBER(megaphx_0x050002_r); |
| 107 | | DECLARE_WRITE16_MEMBER(megaphx_0x050000_w); |
| 108 | | DECLARE_READ8_MEMBER(megaphx_sound_sent_r); |
| 109 | | DECLARE_READ8_MEMBER(megaphx_sound_cmd_r); |
| 110 | | DECLARE_WRITE8_MEMBER(megaphx_sound_to_68k_w); |
| 111 | | |
| 112 | | |
| 113 | | DECLARE_WRITE8_MEMBER(dac0_value_write); |
| 114 | | DECLARE_WRITE8_MEMBER(dac0_gain_write); |
| 115 | | DECLARE_WRITE8_MEMBER(dac1_value_write); |
| 116 | | DECLARE_WRITE8_MEMBER(dac1_gain_write); |
| 117 | | DECLARE_WRITE8_MEMBER(dac2_value_write); |
| 118 | | DECLARE_WRITE8_MEMBER(dac2_gain_write); |
| 119 | | DECLARE_WRITE8_MEMBER(dac3_value_write); |
| 120 | | DECLARE_WRITE8_MEMBER(dac3_gain_write); |
| 121 | | |
| 122 | | DECLARE_WRITE8_MEMBER(dac0_rombank_write); |
| 123 | | DECLARE_WRITE8_MEMBER(dac1_rombank_write); |
| 124 | | DECLARE_WRITE8_MEMBER(dac2_rombank_write); |
| 125 | | DECLARE_WRITE8_MEMBER(dac3_rombank_write); |
| 126 | | |
| 127 | | UINT8 dac_gain[4]; |
| 128 | | UINT8 m_soundbank[4]; |
| 129 | | |
| 130 | | |
| 131 | | |
| 132 | | DECLARE_WRITE_LINE_MEMBER(z80ctc_ch0); |
| 133 | | DECLARE_WRITE_LINE_MEMBER(z80ctc_ch1); |
| 134 | | DECLARE_WRITE_LINE_MEMBER(z80ctc_ch2); |
| 135 | | DECLARE_WRITE_LINE_MEMBER(z80ctc_ch3); |
| 136 | | |
| 137 | | |
| 138 | 93 | DECLARE_READ8_MEMBER(port_c_r); |
| 139 | 94 | DECLARE_WRITE8_MEMBER(port_c_w); |
| 140 | 95 | |
| r29301 | r29302 | |
| 148 | 103 | UINT16 m_pic_result; |
| 149 | 104 | |
| 150 | 105 | UINT8 port_c_value; |
| 151 | | required_device<palette_device> m_palette; |
| 152 | | required_device<tms34010_device> m_tms; |
| 153 | | int m_soundsent; |
| 154 | | UINT8 m_sounddata; |
| 155 | | UINT8 m_soundback; |
| 156 | 106 | |
| 157 | | int m_shiftfull; // this might be a driver specific hack for a TMS bug. |
| 107 | required_device<inder_sb_device> m_indersb; |
| 108 | required_device<inder_vid_device> m_indervid; |
| 158 | 109 | |
| 159 | | // hacks for test purposes, these are installed over the program rom so we know when irqs are actually taken |
| 160 | | DECLARE_READ8_MEMBER(megaphx_02cc_hack_r) { logerror("%04x audicpu IRQ hack 0x02cc\n", machine().device("audiocpu")->safe_pc()); int bank = m_soundbank[0] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x02cc]; }; |
| 161 | | DECLARE_READ8_MEMBER(megaphx_02e6_hack_r) { logerror("%04x audicpu IRQ hack 0x02e6\n", machine().device("audiocpu")->safe_pc()); int bank = m_soundbank[1] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x02e6]; }; |
| 162 | | DECLARE_READ8_MEMBER(megaphx_0309_hack_r) { logerror("%04x audicpu IRQ hack 0x0309\n", machine().device("audiocpu")->safe_pc()); int bank = m_soundbank[2] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x0309]; }; |
| 163 | | DECLARE_READ8_MEMBER(megaphx_0323_hack_r) { logerror("%04x audicpu IRQ hack 0x0323\n", machine().device("audiocpu")->safe_pc()); int bank = m_soundbank[3] & 7; membank("snddata")->set_entry(bank); return memregion("audiocpu")->base()[0x0323]; }; |
| 164 | 110 | |
| 165 | | void install_sound_hacks(void) |
| 166 | | { |
| 167 | | address_space &space = m_audiocpu->space(AS_PROGRAM); |
| 168 | | space.install_read_handler(0x02cc, 0x02cc, read8_delegate(FUNC(megaphx_state::megaphx_02cc_hack_r), this)); |
| 169 | | space.install_read_handler(0x02e6, 0x02e6, read8_delegate(FUNC(megaphx_state::megaphx_02e6_hack_r), this)); |
| 170 | | space.install_read_handler(0x0309, 0x0309, read8_delegate(FUNC(megaphx_state::megaphx_0309_hack_r), this)); |
| 171 | | space.install_read_handler(0x0323, 0x0323, read8_delegate(FUNC(megaphx_state::megaphx_0323_hack_r), this)); |
| 172 | | } |
| 173 | 111 | |
| 174 | | int m_soundirq; |
| 175 | | void update_sound_irqs(void) |
| 176 | | { |
| 177 | | if (m_soundirq) m_audiocpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); |
| 178 | | else m_audiocpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); |
| 179 | | } |
| 180 | | |
| 181 | | |
| 182 | 112 | }; |
| 183 | 113 | |
| 184 | 114 | |
| 185 | | |
| 186 | | |
| 187 | | |
| 188 | | READ16_MEMBER(megaphx_state::megaphx_0x050002_r) |
| 189 | | { |
| 190 | | space.machine().scheduler().synchronize(); |
| 191 | | // int pc = machine().device("maincpu")->safe_pc(); |
| 192 | | int ret = m_soundback; |
| 193 | | m_soundback = 0; |
| 194 | | //logerror("(%06x) megaphx_0x050002_r (from z80?) %04x\n", pc, mem_mask); |
| 195 | | return ret; |
| 196 | | } |
| 197 | | |
| 198 | | WRITE16_MEMBER(megaphx_state::megaphx_0x050000_w) |
| 199 | | { |
| 200 | | // int pc = machine().device("maincpu")->safe_pc(); |
| 201 | | space.machine().scheduler().synchronize(); |
| 202 | | |
| 203 | | //logerror("(%06x) megaphx_0x050000_w (to z80?) %04x %04x\n", pc, data, mem_mask); |
| 204 | | m_soundsent = 0xff; |
| 205 | | m_sounddata = data; |
| 206 | | |
| 207 | | } |
| 208 | | |
| 209 | | |
| 210 | 115 | static ADDRESS_MAP_START( megaphx_68k_map, AS_PROGRAM, 16, megaphx_state ) |
| 211 | 116 | AM_RANGE(0x000000, 0x0013ff) AM_RAM AM_SHARE("mainram") // maps over part of the rom?? |
| 212 | 117 | |
| 213 | 118 | AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_REGION("roms67", 0x00000) // or the rom doesn't map here? it contains the service mode grid amongst other things.. |
| 214 | 119 | |
| 215 | | AM_RANGE(0x040000, 0x040007) AM_DEVREADWRITE("tms", tms34010_device, host_r, host_w) |
| 120 | AM_RANGE(0x040000, 0x040007) AM_DEVREADWRITE("inder_vid:tms", tms34010_device, host_r, host_w) |
| 216 | 121 | |
| 217 | | AM_RANGE(0x050000, 0x050001) AM_WRITE(megaphx_0x050000_w) // z80 comms? |
| 218 | | AM_RANGE(0x050002, 0x050003) AM_READ(megaphx_0x050002_r) // z80 comms? |
| 122 | AM_RANGE(0x050000, 0x050001) AM_DEVWRITE("inder_sb", inder_sb_device, megaphx_0x050000_w) |
| 123 | AM_RANGE(0x050002, 0x050003) AM_DEVREAD("inder_sb", inder_sb_device, megaphx_0x050002_r) |
| 219 | 124 | |
| 220 | 125 | |
| 221 | 126 | AM_RANGE(0x060004, 0x060005) AM_READ8( port_c_r, 0x00ff ) |
| 222 | | |
| 223 | 127 | AM_RANGE(0x060006, 0x060007) AM_WRITE8( port_c_w, 0x00ff ) |
| 224 | | |
| 225 | 128 | AM_RANGE(0x060000, 0x060003) AM_DEVREADWRITE8("ppi8255_0", i8255_device, read, write, 0x00ff) |
| 226 | 129 | |
| 227 | 130 | AM_RANGE(0x800000, 0x83ffff) AM_ROM AM_REGION("roms01", 0x00000) // code + bg gfx are in here |
| r29301 | r29302 | |
| 231 | 134 | ADDRESS_MAP_END |
| 232 | 135 | |
| 233 | 136 | |
| 234 | | static ADDRESS_MAP_START( megaphx_tms_map, AS_PROGRAM, 16, megaphx_state ) |
| 235 | 137 | |
| 236 | | AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("vram") // vram? |
| 237 | | // AM_RANGE(0x00100000, 0x002fffff) AM_RAM // vram? |
| 238 | | // AM_RANGE(0x00300000, 0x003fffff) AM_RAM |
| 239 | | // AM_RANGE(0x04000000, 0x040000ff) AM_WRITENOP |
| 240 | 138 | |
| 241 | | AM_RANGE(0x04000000, 0x0400000f) AM_DEVWRITE8("ramdac",ramdac_device,index_w,0x00ff) |
| 242 | | AM_RANGE(0x04000010, 0x0400001f) AM_DEVREADWRITE8("ramdac",ramdac_device,pal_r,pal_w,0x00ff) |
| 243 | | AM_RANGE(0x04000030, 0x0400003f) AM_DEVWRITE8("ramdac",ramdac_device,index_r_w,0x00ff) |
| 244 | | AM_RANGE(0x04000090, 0x0400009f) AM_WRITENOP |
| 245 | | |
| 246 | | AM_RANGE(0xc0000000, 0xc00001ff) AM_DEVREADWRITE("tms", tms34010_device, io_register_r, io_register_w) |
| 247 | | AM_RANGE(0xffc00000, 0xffffffff) AM_RAM |
| 248 | | ADDRESS_MAP_END |
| 249 | | |
| 250 | | static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, megaphx_state ) |
| 251 | | AM_RANGE(0x0000, 0x1fff) AM_ROM |
| 252 | | AM_RANGE(0x4000, 0x7fff) AM_RAM |
| 253 | | AM_RANGE(0x8000, 0xffff) AM_ROMBANK("snddata") |
| 254 | | ADDRESS_MAP_END |
| 255 | | |
| 256 | | READ8_MEMBER(megaphx_state::megaphx_sound_cmd_r) |
| 257 | | { |
| 258 | | space.machine().scheduler().synchronize(); |
| 259 | | return m_sounddata; |
| 260 | | } |
| 261 | | |
| 262 | | READ8_MEMBER(megaphx_state::megaphx_sound_sent_r) |
| 263 | | { |
| 264 | | space.machine().scheduler().synchronize(); |
| 265 | | int ret = m_soundsent; |
| 266 | | m_soundsent = 0; |
| 267 | | return ret; |
| 268 | | } |
| 269 | | |
| 270 | | WRITE8_MEMBER(megaphx_state::megaphx_sound_to_68k_w) |
| 271 | | { |
| 272 | | // int pc = machine().device("audiocpu")->safe_pc(); |
| 273 | | space.machine().scheduler().synchronize(); |
| 274 | | //logerror("(%04x) megaphx_sound_to_68k_w (to 68k?) %02x\n", pc, data); |
| 275 | | |
| 276 | | m_soundback = data; |
| 277 | | } |
| 278 | | |
| 279 | | WRITE8_MEMBER(megaphx_state::dac0_value_write) |
| 280 | | { |
| 281 | | // printf("dac0_data_write %02x\n", data); |
| 282 | | m_dac0->write_unsigned8(data); |
| 283 | | } |
| 284 | | |
| 285 | | WRITE8_MEMBER(megaphx_state::dac0_gain_write) |
| 286 | | { |
| 287 | | // printf("dac0_gain_write %02x\n", data); |
| 288 | | dac_gain[0] = data; |
| 289 | | } |
| 290 | | |
| 291 | | WRITE8_MEMBER(megaphx_state::dac1_value_write) |
| 292 | | { |
| 293 | | // printf("dac1_data_write %02x\n", data); |
| 294 | | m_dac1->write_unsigned8(data); |
| 295 | | } |
| 296 | | |
| 297 | | WRITE8_MEMBER(megaphx_state::dac1_gain_write) |
| 298 | | { |
| 299 | | // printf("dac1_gain_write %02x\n", data); |
| 300 | | dac_gain[1] = data; |
| 301 | | } |
| 302 | | |
| 303 | | WRITE8_MEMBER(megaphx_state::dac2_value_write) |
| 304 | | { |
| 305 | | // printf("dac2_data_write %02x\n", data); |
| 306 | | m_dac2->write_unsigned8(data); |
| 307 | | } |
| 308 | | |
| 309 | | WRITE8_MEMBER(megaphx_state::dac2_gain_write) |
| 310 | | { |
| 311 | | // printf("dac2_gain_write %02x\n", data); |
| 312 | | dac_gain[2] = data; |
| 313 | | } |
| 314 | | |
| 315 | | WRITE8_MEMBER(megaphx_state::dac3_value_write) |
| 316 | | { |
| 317 | | // printf("dac3_data_write %02x\n", data); |
| 318 | | m_dac3->write_unsigned8(data); |
| 319 | | } |
| 320 | | |
| 321 | | WRITE8_MEMBER(megaphx_state::dac3_gain_write) |
| 322 | | { |
| 323 | | // printf("dac3_gain_write %02x\n", data); |
| 324 | | dac_gain[3] = data; |
| 325 | | } |
| 326 | | |
| 327 | | WRITE8_MEMBER(megaphx_state::dac0_rombank_write) |
| 328 | | { |
| 329 | | m_soundbank[0] = data; |
| 330 | | |
| 331 | | // printf("dac0_rombank_write %02x", data); |
| 332 | | } |
| 333 | | |
| 334 | | WRITE8_MEMBER(megaphx_state::dac1_rombank_write) |
| 335 | | { |
| 336 | | m_soundbank[1] = data; |
| 337 | | // printf("dac1_rombank_write %02x", data); |
| 338 | | |
| 339 | | } |
| 340 | | |
| 341 | | WRITE8_MEMBER(megaphx_state::dac2_rombank_write) |
| 342 | | { |
| 343 | | m_soundbank[2] = data; |
| 344 | | // printf("dac2_rombank_write %02x", data); |
| 345 | | } |
| 346 | | |
| 347 | | WRITE8_MEMBER(megaphx_state::dac3_rombank_write) |
| 348 | | { |
| 349 | | m_soundbank[3] = data; |
| 350 | | // printf("dac3_rombank_write %02x", data); |
| 351 | | |
| 352 | | } |
| 353 | | |
| 354 | | |
| 355 | | static ADDRESS_MAP_START( sound_io, AS_IO, 8, megaphx_state ) |
| 356 | | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 357 | | AM_RANGE(0x00, 0x00) AM_WRITE(dac0_value_write) |
| 358 | | AM_RANGE(0x01, 0x01) AM_WRITE(dac0_gain_write) |
| 359 | | AM_RANGE(0x02, 0x02) AM_WRITE(dac1_value_write) |
| 360 | | AM_RANGE(0x03, 0x03) AM_WRITE(dac1_gain_write) |
| 361 | | AM_RANGE(0x04, 0x04) AM_WRITE(dac2_value_write) |
| 362 | | AM_RANGE(0x05, 0x05) AM_WRITE(dac2_gain_write) |
| 363 | | AM_RANGE(0x06, 0x06) AM_WRITE(dac3_value_write) |
| 364 | | AM_RANGE(0x07, 0x07) AM_WRITE(dac3_gain_write) |
| 365 | | |
| 366 | | // not 100% sure how rom banking works.. but each channel can specify a different bank for the 0x8000 range. Maybe the bank happens when the interrupt triggers so each channel reads the correct data? (so we'd need to put the actual functions in the CTC callbacks) |
| 367 | | AM_RANGE(0x10, 0x10) AM_WRITE(dac0_rombank_write) |
| 368 | | AM_RANGE(0x11, 0x11) AM_WRITE(dac1_rombank_write) |
| 369 | | AM_RANGE(0x12, 0x12) AM_WRITE(dac2_rombank_write) |
| 370 | | AM_RANGE(0x13, 0x13) AM_WRITE(dac3_rombank_write) |
| 371 | | |
| 372 | | |
| 373 | | |
| 374 | | |
| 375 | | AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) |
| 376 | | |
| 377 | | AM_RANGE(0x30, 0x30) AM_READWRITE(megaphx_sound_cmd_r, megaphx_sound_to_68k_w) |
| 378 | | AM_RANGE(0x31, 0x31) AM_READ(megaphx_sound_sent_r) |
| 379 | | ADDRESS_MAP_END |
| 380 | | |
| 381 | | |
| 382 | | static void megaphx_scanline(screen_device &screen, bitmap_rgb32 &bitmap, int scanline, const tms34010_display_params *params) |
| 383 | | { |
| 384 | | megaphx_state *state = screen.machine().driver_data<megaphx_state>(); |
| 385 | | |
| 386 | | UINT16 *vram = &state->m_vram[(params->rowaddr << 8) & 0x3ff00]; |
| 387 | | UINT32 *dest = &bitmap.pix32(scanline); |
| 388 | | |
| 389 | | const pen_t *paldata = state->m_palette->pens(); |
| 390 | | |
| 391 | | int coladdr = params->coladdr; |
| 392 | | int x; |
| 393 | | |
| 394 | | for (x = params->heblnk; x < params->hsblnk; x += 2) |
| 395 | | { |
| 396 | | UINT16 pixels = vram[coladdr++ & 0xff]; |
| 397 | | dest[x + 0] = paldata[pixels & 0xff]; |
| 398 | | dest[x + 1] = paldata[pixels >> 8]; |
| 399 | | } |
| 400 | | |
| 401 | | } |
| 402 | | |
| 403 | | |
| 404 | | static void megaphx_to_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 405 | | { |
| 406 | | megaphx_state *state = space.machine().driver_data<megaphx_state>(); |
| 407 | | |
| 408 | | if (state->m_shiftfull == 0) |
| 409 | | { |
| 410 | | //printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); |
| 411 | | |
| 412 | | memcpy(shiftreg, &state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], TOBYTE(0x2000)); // & ~TOWORD(0x1fff) is needed for round 6 |
| 413 | | state->m_shiftfull = 1; |
| 414 | | } |
| 415 | | } |
| 416 | | |
| 417 | | static void megaphx_from_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg) |
| 418 | | { |
| 419 | | // printf("write from shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); |
| 420 | | |
| 421 | | megaphx_state *state = space.machine().driver_data<megaphx_state>(); |
| 422 | | memcpy(&state->m_vram[TOWORD(address) & ~TOWORD(0x1fff)], shiftreg, TOBYTE(0x2000)); |
| 423 | | |
| 424 | | state->m_shiftfull = 0; |
| 425 | | } |
| 426 | | |
| 427 | | MACHINE_RESET_MEMBER(megaphx_state,megaphx) |
| 428 | | { |
| 429 | | } |
| 430 | | |
| 431 | | static void m68k_gen_int(device_t *device, int state) |
| 432 | | { |
| 433 | | megaphx_state *drvstate = device->machine().driver_data<megaphx_state>(); |
| 434 | | if (state) drvstate->m_maincpu->set_input_line(4, ASSERT_LINE); |
| 435 | | else drvstate->m_maincpu->set_input_line(4, CLEAR_LINE); |
| 436 | | |
| 437 | | } |
| 438 | | |
| 439 | | |
| 440 | | static const tms34010_config tms_config_megaphx = |
| 441 | | { |
| 442 | | TRUE, /* halt on reset */ |
| 443 | | "screen", /* the screen operated on */ |
| 444 | | XTAL_40MHz/12, /* pixel clock */ |
| 445 | | 2, /* pixels per clock */ |
| 446 | | NULL, /* scanline callback (indexed16) */ |
| 447 | | megaphx_scanline, /* scanline callback (rgb32) */ |
| 448 | | m68k_gen_int, /* generate interrupt */ |
| 449 | | megaphx_to_shiftreg, /* write to shiftreg function */ |
| 450 | | megaphx_from_shiftreg /* read from shiftreg function */ |
| 451 | | }; |
| 452 | | |
| 453 | | |
| 454 | | |
| 455 | 139 | static INPUT_PORTS_START( megaphx ) |
| 456 | 140 | PORT_START("P0") // verified in test mode |
| 457 | 141 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) // shield |
| r29301 | r29302 | |
| 547 | 231 | PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) |
| 548 | 232 | INPUT_PORTS_END |
| 549 | 233 | |
| 550 | | static ADDRESS_MAP_START( ramdac_map, AS_0, 8, megaphx_state ) |
| 551 | | AM_RANGE(0x000, 0x3ff) AM_DEVREADWRITE("ramdac",ramdac_device,ramdac_pal_r,ramdac_rgb888_w) |
| 552 | | ADDRESS_MAP_END |
| 553 | 234 | |
| 554 | | static RAMDAC_INTERFACE( ramdac_intf ) |
| 555 | | { |
| 556 | | 1 |
| 557 | | }; |
| 558 | 235 | |
| 559 | 236 | /* why don't the port_c read/writes work properly when hooked through the 8255? */ |
| 560 | 237 | |
| r29301 | r29302 | |
| 687 | 364 | }; |
| 688 | 365 | |
| 689 | 366 | |
| 690 | | WRITE_LINE_MEMBER(megaphx_state::z80ctc_ch0) |
| 691 | | { |
| 692 | | // int bank = m_soundbank[0] & 7; membank("snddata")->set_entry(bank); |
| 693 | | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 694 | | if (state) m_soundirq |= 0x1; |
| 695 | | else m_soundirq &= ~0x1; |
| 696 | 367 | |
| 697 | | update_sound_irqs(); |
| 698 | | } |
| 699 | | |
| 700 | | |
| 701 | | WRITE_LINE_MEMBER(megaphx_state::z80ctc_ch1) |
| 702 | | { |
| 703 | | // int bank = m_soundbank[1] & 7; membank("snddata")->set_entry(bank); |
| 704 | | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 705 | | if (state) m_soundirq |= 0x2; |
| 706 | | else m_soundirq &= ~0x2; |
| 707 | | |
| 708 | | update_sound_irqs(); |
| 709 | | } |
| 710 | | |
| 711 | | |
| 712 | | WRITE_LINE_MEMBER(megaphx_state::z80ctc_ch2) |
| 713 | | { |
| 714 | | // int bank = m_soundbank[2] & 7; membank("snddata")->set_entry(bank); |
| 715 | | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 716 | | if (state) m_soundirq |= 0x4; |
| 717 | | else m_soundirq &= ~0x4; |
| 718 | | |
| 719 | | update_sound_irqs(); |
| 720 | | } |
| 721 | | |
| 722 | | |
| 723 | | |
| 724 | | |
| 725 | | WRITE_LINE_MEMBER(megaphx_state::z80ctc_ch3) |
| 726 | | { |
| 727 | | // int bank = m_soundbank[3] & 7; membank("snddata")->set_entry(bank); |
| 728 | | // m_audiocpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); |
| 729 | | if (state) m_soundirq |= 0x8; |
| 730 | | else m_soundirq &= ~0x8; |
| 731 | | |
| 732 | | update_sound_irqs(); |
| 733 | | } |
| 734 | | |
| 735 | | |
| 736 | | |
| 737 | | |
| 738 | | static Z80CTC_INTERFACE( z80ctc_intf ) // runs in IM2 , vector set to 0x20 , values there are 0xCC, 0x02, 0xE6, 0x02, 0x09, 0x03, 0x23, 0x03 (so 02cc, 02e6, 0309, 0323, all of which are valid irq handlers) |
| 739 | | { |
| 740 | | DEVCB_DRIVER_LINE_MEMBER(megaphx_state, z80ctc_ch0), // for channel 0 |
| 741 | | DEVCB_DRIVER_LINE_MEMBER(megaphx_state, z80ctc_ch1), // for channel 1 |
| 742 | | DEVCB_DRIVER_LINE_MEMBER(megaphx_state, z80ctc_ch2), // for channel 2 |
| 743 | | DEVCB_DRIVER_LINE_MEMBER(megaphx_state, z80ctc_ch3), // for channel 3 |
| 744 | | }; |
| 745 | | |
| 746 | | static const z80_daisy_config daisy_chain[] = |
| 747 | | { |
| 748 | | { "ctc" }, |
| 749 | | { NULL } |
| 750 | | }; |
| 751 | | |
| 752 | | |
| 753 | | // just for debug.. so we can see what is in each of the roms |
| 754 | | static GFXLAYOUT_RAW( megaphxlay, 336, 1, 336*8, 336*8 ) |
| 755 | | |
| 756 | | static GFXDECODE_START( megaphx ) |
| 757 | | GFXDECODE_ENTRY( "roms01", 0, megaphxlay, 0x0000, 1 ) |
| 758 | | GFXDECODE_ENTRY( "roms23", 0, megaphxlay, 0x0000, 1 ) |
| 759 | | GFXDECODE_ENTRY( "roms45", 0, megaphxlay, 0x0000, 1 ) |
| 760 | | GFXDECODE_ENTRY( "roms67", 0, megaphxlay, 0x0000, 1 ) |
| 761 | | GFXDECODE_END |
| 762 | | |
| 763 | | |
| 764 | 368 | static MACHINE_CONFIG_START( megaphx, megaphx_state ) |
| 765 | 369 | |
| 766 | 370 | MCFG_CPU_ADD("maincpu", M68000, 8000000) // ?? can't read xtal due to reflections, CPU is an 8Mhz part |
| 767 | 371 | MCFG_CPU_PROGRAM_MAP(megaphx_68k_map) |
| 768 | | // MCFG_CPU_VBLANK_INT_DRIVER("screen", megaphx_state, irq6_line_hold) |
| 769 | 372 | |
| 770 | 373 | |
| 771 | | MCFG_CPU_ADD("tms", TMS34010, XTAL_40MHz) |
| 772 | | MCFG_CPU_CONFIG(tms_config_megaphx) |
| 773 | | MCFG_CPU_PROGRAM_MAP(megaphx_tms_map) |
| 374 | MCFG_INDER_AUDIO_ADD("inder_sb") |
| 774 | 375 | |
| 775 | | MCFG_CPU_ADD("audiocpu", Z80, 8000000) // unk freq |
| 776 | | MCFG_CPU_CONFIG(daisy_chain) |
| 777 | | MCFG_CPU_PROGRAM_MAP(sound_map) |
| 778 | | MCFG_CPU_IO_MAP(sound_io) |
| 779 | | |
| 780 | 376 | MCFG_I8255A_ADD( "ppi8255_0", ppi8255_intf_0 ) |
| 781 | | MCFG_Z80CTC_ADD( "ctc", 4000000, z80ctc_intf ) // unk freq |
| 782 | 377 | |
| 783 | | MCFG_MACHINE_RESET_OVERRIDE(megaphx_state,megaphx) |
| 378 | MCFG_INDER_VIDEO_ADD("inder_vid") |
| 784 | 379 | |
| 785 | | // MCFG_QUANTUM_PERFECT_CPU("tms") |
| 786 | 380 | |
| 787 | | |
| 788 | | // MCFG_NVRAM_ADD_0FILL("nvram") |
| 789 | | |
| 790 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 791 | | MCFG_SCREEN_RAW_PARAMS(XTAL_40MHz/12, 424, 0, 338-1, 262, 0, 246-1) |
| 792 | | MCFG_SCREEN_UPDATE_DEVICE("tms", tms34010_device, tms340x0_rgb32) |
| 793 | | |
| 794 | | MCFG_PALETTE_ADD("palette", 256) |
| 795 | | |
| 796 | | MCFG_GFXDECODE_ADD("gfxdecode", "palette", megaphx) |
| 797 | | |
| 798 | | MCFG_RAMDAC_ADD("ramdac", ramdac_intf, ramdac_map, "palette") |
| 799 | | |
| 800 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 801 | | MCFG_DAC_ADD("dac0") |
| 802 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 803 | | MCFG_DAC_ADD("dac1") |
| 804 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 805 | | MCFG_DAC_ADD("dac2") |
| 806 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 807 | | MCFG_DAC_ADD("dac3") |
| 808 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 809 | | |
| 810 | | |
| 811 | 381 | MACHINE_CONFIG_END |
| 812 | 382 | |
| 813 | 383 | DRIVER_INIT_MEMBER(megaphx_state,megaphx) |
| r29301 | r29302 | |
| 816 | 386 | // copy vector table? - it must be writable because the game write the irq vector.. |
| 817 | 387 | memcpy(m_mainram, src, 0x80); |
| 818 | 388 | |
| 819 | | membank("snddata")->configure_entries(0, 8, memregion("user2")->base(), 0x8000); |
| 820 | | membank("snddata")->set_entry(0); |
| 821 | 389 | |
| 822 | | install_sound_hacks(); |
| 823 | 390 | } |
| 824 | 391 | |
| 825 | 392 | |
| r29301 | r29302 | |
| 840 | 407 | ROM_LOAD16_BYTE( "mph4.u36", 0x000001, 0x20000, CRC(c8e0725e) SHA1(b3af315b9a94a692e81e0dbfd4035036c2af4f50) ) |
| 841 | 408 | ROM_LOAD16_BYTE( "mph5.u25", 0x000000, 0x20000, CRC(c95ccb69) SHA1(9d14cbfafd943f6ff461a7f373170a35e36eb695) ) |
| 842 | 409 | |
| 843 | | ROM_REGION( 0x200000, "user2", 0 ) |
| 410 | ROM_REGION( 0x200000, "inder_sb:user2", 0 ) |
| 844 | 411 | ROM_LOAD( "sonido_mph1.u39", 0x00000, 0x20000, CRC(f5e65557) SHA1(5ae759c2bcef96fbda42f088c02b6dec208030f3) ) |
| 845 | 412 | ROM_LOAD( "sonido_mph2.u38", 0x20000, 0x20000, CRC(7444d0f9) SHA1(9739b48993bccea5530533b67808d13d6155ffe3) ) |
| 846 | 413 | |
| 847 | | ROM_REGION( 0x100000, "audiocpu", 0 ) |
| 414 | ROM_REGION( 0x100000, "inder_sb:audiocpu", 0 ) |
| 848 | 415 | ROM_LOAD( "sonido_mph0.u35", 0x000000, 0x2000, CRC(abc1b140) SHA1(8384a162d85cf9ea870d22f44b1ca64001c6a083) ) |
| 849 | 416 | |
| 850 | 417 | ROM_REGION( 0x100000, "pals", 0 ) // jedutil won't convert these? are they bad? |