trunk/src/emu/cpu/nec/v53.c
| r244830 | r244831 | |
| 10 | 10 | #include "emu.h" |
| 11 | 11 | #include "v53.h" |
| 12 | 12 | |
| 13 | | #include "machine/pit8253.h" |
| 13 | |
| 14 | 14 | const device_type V53 = &device_creator<v53_device>; |
| 15 | 15 | const device_type V53A =&device_creator<v53a_device>; |
| 16 | 16 | |
| r244830 | r244831 | |
| 191 | 191 | void v53_base_device::install_peripheral_io() |
| 192 | 192 | { |
| 193 | 193 | // unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config) |
| 194 | | space(AS_IO).unmap_readwrite(0x0000, 0xfeff); |
| 194 | space(AS_IO).unmap_readwrite(0x1000, 0xfeff); // todo, we need to have a way to NOT unmap things defined in the drivers, but instead have this act as an overlay mapping / unampping only!! |
| 195 | 195 | |
| 196 | 196 | // IOAG determines if the handlers used 8-bit or 16-bit access |
| 197 | 197 | // the hng64.c games first set everything up in 8-bit mode, then |
| r244830 | r244831 | |
| 201 | 201 | |
| 202 | 202 | if (m_OPSEL & 0x01) // DMA Unit available |
| 203 | 203 | { |
| 204 | UINT16 base = (m_OPHA << 8) | m_DULA; |
| 205 | |
| 204 | 206 | if (m_SCTL & 0x02) // uPD71037 mode |
| 205 | 207 | { |
| 206 | 208 | if (IOAG) // 8-bit |
| r244830 | r244831 | |
| 209 | 211 | } |
| 210 | 212 | else |
| 211 | 213 | { |
| 212 | | |
| 213 | 214 | } |
| 214 | 215 | } |
| 215 | | else |
| 216 | else // uPD71071 mode |
| 216 | 217 | { |
| 217 | | |
| 218 | space(AS_IO).install_readwrite_handler(base+0x00, base+0x0f, read8_delegate(FUNC(upd71071_device::read), (upd71071_device*)m_dma_71071mode), write8_delegate(FUNC(upd71071_device::write), (upd71071_device*)m_dma_71071mode), 0xffff); |
| 218 | 219 | } |
| 219 | 220 | } |
| 220 | 221 | |
| r244830 | r244831 | |
| 350 | 351 | READ8_MEMBER(v53_base_device::tmu_tst1_r) { return m_pit->read(space, 1); } |
| 351 | 352 | READ8_MEMBER(v53_base_device::tmu_tst2_r) { return m_pit->read(space, 2); } |
| 352 | 353 | |
| 354 | /*** DMA ***/ |
| 353 | 355 | |
| 356 | // could be wrong / nonexistent |
| 357 | int v53_base_device::dmarq(int state, int channel) |
| 358 | { |
| 359 | return m_dma_71071mode->dmarq(state, channel); |
| 360 | } |
| 361 | |
| 354 | 362 | /* General stuff */ |
| 355 | 363 | |
| 356 | 364 | static ADDRESS_MAP_START( v53_internal_port_map, AS_IO, 16, v53_base_device ) |
| r244830 | r244831 | |
| 392 | 400 | MCFG_DEVICE_ADD("pit", PIT8254, 0) // functionality identical to uPD71054 |
| 393 | 401 | MCFG_PIT8253_CLK0(16000000/2/8) |
| 394 | 402 | //MCFG_PIT8253_OUT0_HANDLER(WRITELINE(v53_base_device, pit_out0)) |
| 403 | |
| 404 | MCFG_DEVICE_ADD("upd71071dma", UPD71071, 0) |
| 405 | // MCFG_UPD71071_CPU("audiocpu") // should use owner name |
| 406 | MCFG_UPD71071_CLOCK(4000000) |
| 407 | // MCFG_UPD71071_DMA_READ_0_CB(READ16(towns_state, towns_fdc_dma_r)) |
| 408 | // MCFG_UPD71071_DMA_READ_1_CB(READ16(towns_state, towns_scsi_dma_r)) |
| 409 | // MCFG_UPD71071_DMA_READ_3_CB(READ16(towns_state, towns_cdrom_dma_r)) |
| 410 | // MCFG_UPD71071_DMA_WRITE_0_CB(WRITE16(towns_state, towns_fdc_dma_w)) |
| 411 | // MCFG_UPD71071_DMA_WRITE_1_CB(WRITE16(towns_state, towns_scsi_dma_w)) |
| 412 | |
| 395 | 413 | MACHINE_CONFIG_END |
| 396 | 414 | |
| 397 | 415 | machine_config_constructor v53_base_device::device_mconfig_additions() const |
| r244830 | r244831 | |
| 403 | 421 | v53_base_device::v53_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, offs_t fetch_xor, UINT8 prefetch_size, UINT8 prefetch_cycles, UINT32 chip_type) |
| 404 | 422 | : nec_common_device(mconfig, type, name, tag, owner, clock, shortname, true, fetch_xor, prefetch_size, prefetch_cycles, chip_type), |
| 405 | 423 | m_io_space_config( "io", ENDIANNESS_LITTLE, 16, 16, 0, ADDRESS_MAP_NAME( v53_internal_port_map ) ), |
| 406 | | m_pit(*this, "pit") |
| 424 | m_pit(*this, "pit"), |
| 425 | m_dma_71071mode(*this, "upd71071dma") |
| 407 | 426 | { |
| 408 | 427 | } |
| 409 | 428 | |
trunk/src/emu/machine/upd71071.c
| r244830 | r244831 | |
| 29 | 29 | Self-explanatory, I hope. :) |
| 30 | 30 | NOTE: Datasheet clearly shows this as 24-bit, with register 7 unused. |
| 31 | 31 | But the FM-Towns definitely uses reg 7 as bits 24-31. |
| 32 | The documentation on the V53A manual doesn't show these bits either, maybe it's |
| 33 | an external connection on the FMT? might be worth checking overflow behavior etc. |
| 32 | 34 | |
| 33 | 35 | 0x08: |
| 34 | 36 | 0x09: Device Control register (16-bit) |
| r244830 | r244831 | |
| 73 | 75 | 0x0f: Mask register |
| 74 | 76 | bit 0-3: DMARQ mask |
| 75 | 77 | bits 1 and 0 only in MTM transfers |
| 78 | |
| 79 | Note, the uPD71071 compatible mode of the V53 CPU differs from a real uPD71071 in the following ways |
| 76 | 80 | |
| 77 | 81 | |
| 82 | V53 Real uPD71071 |
| 83 | Software Reqs No Yes |
| 84 | Memory-to-Memory DMA No Yes |
| 85 | DMARQ active level High High or Low |
| 86 | DMAAK active level Low High or Low |
| 87 | Bus Cycle 4 4 or 3 |
| 88 | |
| 89 | we don't currently handle the differences |
| 90 | |
| 78 | 91 | */ |
| 79 | 92 | |
| 80 | 93 | #include "emu.h" |
| r244830 | r244831 | |
| 162 | 175 | TIMER_CALLBACK_MEMBER(upd71071_device::dma_transfer_timer) |
| 163 | 176 | { |
| 164 | 177 | // single byte or word transfer |
| 165 | | address_space& space = m_cpu->space(AS_PROGRAM); |
| 166 | 178 | int channel = param; |
| 167 | 179 | UINT16 data = 0; // data to transfer |
| 168 | 180 | |
| r244830 | r244831 | |
| 190 | 202 | data = m_dma_read_3_cb(0); |
| 191 | 203 | break; |
| 192 | 204 | } |
| 193 | | space.write_byte(m_reg.address_current[channel], data & 0xff); |
| 205 | |
| 206 | if (m_cpu) |
| 207 | { |
| 208 | address_space& space = m_cpu->space(AS_PROGRAM); |
| 209 | space.write_byte(m_reg.address_current[channel], data & 0xff); |
| 210 | } |
| 211 | else |
| 212 | { |
| 213 | printf("upd71071_device: dma_transfer_timer - write to memory, no dest space %02x\n", data & 0xff); |
| 214 | } |
| 215 | |
| 194 | 216 | if (m_reg.mode_control[channel] & 0x20) // Address direction |
| 195 | 217 | m_reg.address_current[channel]--; |
| 196 | 218 | else |
| r244830 | r244831 | |
| 208 | 230 | } |
| 209 | 231 | break; |
| 210 | 232 | case 0x08: // memory -> I/O |
| 211 | | data = space.read_byte(m_reg.address_current[channel]); |
| 233 | if (m_cpu) |
| 234 | { |
| 235 | address_space& space = m_cpu->space(AS_PROGRAM); |
| 236 | data = space.read_byte(m_reg.address_current[channel]); |
| 237 | } |
| 238 | else |
| 239 | { |
| 240 | printf("upd71071_device: dma_transfer_timer - read from memory, no src space\n"); |
| 241 | data = 0x00; |
| 242 | } |
| 243 | |
| 212 | 244 | switch (channel) |
| 213 | 245 | { |
| 214 | 246 | case 0: |
trunk/src/mame/audio/hng64.c
| r244830 | r244831 | |
| 147 | 147 | AM_RANGE(0xf0000, 0xfffff) AM_RAMBANK("bank1") |
| 148 | 148 | ADDRESS_MAP_END |
| 149 | 149 | |
| 150 | WRITE16_MEMBER(hng64_state::hng64_sound_port_0008_w) |
| 151 | { |
| 152 | printf("hng64_sound_port_0008_w %04x %04x\n", data, mem_mask); |
| 153 | // just a guess, the v53 docs seem to indicate no software requests tho?? buriki sets up the DMA, then writes here, then waits for the counter to expire? |
| 154 | // Maybe it's automatic? I see no way to trigger an actual DMA in the uPD71071 code at present otherwise tho? |
| 155 | m_audiocpu->dmarq(1, 0); |
| 156 | m_audiocpu->dmarq(1, 1); |
| 157 | m_audiocpu->dmarq(1, 2); |
| 158 | m_audiocpu->dmarq(1, 3); |
| 159 | |
| 160 | } |
| 161 | |
| 150 | 162 | static ADDRESS_MAP_START( hng_sound_io, AS_IO, 16, hng64_state ) |
| 151 | | AM_RANGE(0xc002, 0xc003) AM_NOP // buriki one fills the log, wants 0xffff |
| 163 | AM_RANGE(0x0008, 0x0009) AM_WRITE( hng64_sound_port_0008_w ) |
| 152 | 164 | ADDRESS_MAP_END |
| 153 | 165 | |
| 166 | |
| 154 | 167 | MACHINE_CONFIG_FRAGMENT( hng64_audio ) |
| 155 | 168 | MCFG_CPU_ADD("audiocpu", V53A, 16000000) // V53A, 16? mhz! |
| 156 | 169 | MCFG_CPU_PROGRAM_MAP(hng_sound_map) |