ngen: mapped DMA controller, no idea what DMA channels map to what devices, yet.

This commit is contained in:
mahlemiut 2014-11-18 00:35:05 +13:00
parent 056dced923
commit 04caecd693

View File

@ -41,6 +41,13 @@ public:
DECLARE_READ16_MEMBER(peripheral_r);
DECLARE_WRITE16_MEMBER(port00_w);
DECLARE_READ16_MEMBER(port00_r);
DECLARE_WRITE_LINE_MEMBER(dma_hrq_changed);
DECLARE_WRITE_LINE_MEMBER(dack0_w);
DECLARE_WRITE_LINE_MEMBER(dack1_w);
DECLARE_WRITE_LINE_MEMBER(dack2_w);
DECLARE_WRITE_LINE_MEMBER(dack3_w);
DECLARE_READ8_MEMBER(dma_read_byte);
DECLARE_WRITE8_MEMBER(dma_write_byte);
MC6845_UPDATE_ROW(crtc_update_row);
protected:
@ -55,11 +62,15 @@ private:
optional_shared_ptr<UINT16> m_vram;
optional_shared_ptr<UINT16> m_fontram;
void set_dma_channel(int channel, int state);
UINT16 m_peripheral;
UINT16 m_upper;
UINT16 m_middle;
UINT16 m_port00;
UINT16 m_periph141;
UINT8 m_dma_offset[4];
INT8 m_dma_channel;
};
WRITE_LINE_MEMBER(ngen_state::pit_out0_w)
@ -117,6 +128,33 @@ WRITE16_MEMBER(ngen_state::peripheral_w)
{
switch(offset)
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
if(mem_mask & 0x00ff)
m_dmac->write(space,offset,data & 0xff);
//logerror("(PC=%06x) DMA write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask);
break;
case 0x80: // DMA page offset?
case 0x81:
case 0x82:
case 0x83:
if(mem_mask & 0x00ff)
m_dma_offset[offset-0x80] = data & 0xff;
break;
case 0x110:
if(mem_mask & 0x00ff)
m_pit->write(space,0,data & 0x0ff);
@ -151,6 +189,9 @@ WRITE16_MEMBER(ngen_state::peripheral_w)
case 0x147:
//logerror("Video write offset 0x147 data %04x mask %04x\n",data,mem_mask);
break;
case 0x1a0: // serial?
logerror("(PC=%06x) Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask);
break;
default:
logerror("(PC=%06x) Unknown 80186 peripheral write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask);
}
@ -161,6 +202,33 @@ READ16_MEMBER(ngen_state::peripheral_r)
UINT16 ret = 0xffff;
switch(offset)
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
if(mem_mask & 0x00ff)
ret = m_dmac->read(space,offset);
logerror("(PC=%06x) DMA read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret);
break;
case 0x80: // DMA page offset?
case 0x81:
case 0x82:
case 0x83:
if(mem_mask & 0x00ff)
ret = m_dma_offset[offset-0x80] & 0xff;
break;
case 0x110:
if(mem_mask & 0x00ff)
ret = m_pit->read(space,0);
@ -189,15 +257,20 @@ READ16_MEMBER(ngen_state::peripheral_r)
ret = m_crtc->register_r(space,0);
break;
case 0x146:
if(mem_mask & 0x00ff)
ret = m_iouart->ba_cd_r(space,0);
break;
case 0x147: // definitely video related, likely UART sending data to the video board
if(mem_mask & 0x00ff)
ret = m_iouart->ba_cd_r(space,1);
case 0x147: // definitely video related, maybe UART sending data to the monitor?
// expects bit 0 to be set (Video ready signal?)
ret = 0;
ret |= 1;
break;
case 0x1a0: // status?
ret = 0;
ret |= 0x02; // end of DMA transfer?
break;
case 0x1b1:
ret = 0;
ret |= 0x02; // also checked after DMA transfer ends
break;
default:
logerror("(PC=%06x) Unknown 80186 peripheral read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret);
}
@ -220,6 +293,51 @@ READ16_MEMBER(ngen_state::port00_r)
return m_port00;
}
WRITE_LINE_MEMBER( ngen_state::dma_hrq_changed )
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
}
void ngen_state::set_dma_channel(int channel, int state)
{
if(!state)
m_dma_channel = channel;
else if(m_dma_channel == channel)
m_dma_channel = -1;
}
WRITE_LINE_MEMBER( ngen_state::dack0_w ) { set_dma_channel(0, state); }
WRITE_LINE_MEMBER( ngen_state::dack1_w ) { set_dma_channel(1, state); }
WRITE_LINE_MEMBER( ngen_state::dack2_w ) { set_dma_channel(2, state); }
WRITE_LINE_MEMBER( ngen_state::dack3_w ) { set_dma_channel(3, state); }
READ8_MEMBER(ngen_state::dma_read_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
UINT8 result;
if(m_dma_channel == -1)
return 0xff;
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000;
result = prog_space.read_byte(page_offset + offset);
popmessage("DMA byte address %06x read %02x\n",page_offset+offset,result);
return result;
}
WRITE8_MEMBER(ngen_state::dma_write_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if(m_dma_channel == -1)
return;
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000;
prog_space.write_byte(page_offset + offset, data);
popmessage("DMA byte address %06x write %02x\n",page_offset+offset,data);
}
MC6845_UPDATE_ROW( ngen_state::crtc_update_row )
{
UINT16 addr = ma;
@ -286,9 +404,16 @@ static MACHINE_CONFIG_START( ngen, ngen_state )
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(ngen_state, pit_out2_w))
MCFG_DEVICE_ADD("dmac", AM9517A, XTAL_14_7456MHz / 3) // NEC D8237A, divisor unknown
MCFG_I8237_OUT_HREQ_CB(WRITELINE(ngen_state, dma_hrq_changed))
MCFG_I8237_IN_MEMR_CB(READ8(ngen_state, dma_read_byte))
MCFG_I8237_OUT_MEMW_CB(WRITE8(ngen_state, dma_write_byte))
MCFG_I8237_OUT_DACK_0_CB(WRITELINE(ngen_state, dack0_w))
MCFG_I8237_OUT_DACK_1_CB(WRITELINE(ngen_state, dack1_w))
MCFG_I8237_OUT_DACK_2_CB(WRITELINE(ngen_state, dack2_w))
MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ngen_state, dack3_w))
// I/O board
MCFG_UPD7201_ADD("iouart",0, 0,0,0,0) // clocked by PIT channel 2?
MCFG_UPD7201_ADD("iouart",0,0,0,0,0) // clocked by PIT channel 2?
MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd))
MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd))
MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr))