1 // license:BSD-3-Clause 2 // copyright-holders:Patrick Mackinlay 3 4 #ifndef MAME_MACHINE_DMAC_0448_H 5 #define MAME_MACHINE_DMAC_0448_H 6 7 #pragma once 8 9 class dmac_0448_device : public device_t 10 { 11 public: 12 dmac_0448_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); 13 14 // configuration set_bus(T && tag,int spacenum)15 template <typename T> void set_bus(T &&tag, int spacenum) { m_bus.set_tag(std::forward<T>(tag), spacenum); } out_int_cb()16 auto out_int_cb() { return m_out_int.bind(); } dma_r_cb()17 template <unsigned Channel> auto dma_r_cb() { return m_dma_r[Channel].bind(); } dma_w_cb()18 template <unsigned Channel> auto dma_w_cb() { return m_dma_w[Channel].bind(); } 19 20 // line handlers irq(int state)21 template <unsigned IRQ> void irq(int state) { set_irq_line(IRQ, state); } drq(int state)22 template <unsigned DRQ> void drq(int state) { set_drq_line(DRQ, state); } 23 24 void map(address_map &map); 25 26 protected: 27 // device_t overrides 28 virtual void device_start() override; 29 virtual void device_reset() override; 30 31 void set_irq_line(int number, int state); 32 void set_drq_line(int channel, int state); 33 cstat_r()34 u8 cstat_r() { return m_channel[m_gsel].cstat; } ctrcl_r()35 u8 ctrcl_r() { return u8(m_channel[m_gsel].ctrc >> 0); } ctrcm_r()36 u8 ctrcm_r() { return u8(m_channel[m_gsel].ctrc >> 8); } ctrch_r()37 u8 ctrch_r() { return u8(m_channel[m_gsel].ctrc >> 16); } ctag_r()38 u8 ctag_r() { return m_channel[m_gsel].ctag; } cwid_r()39 u8 cwid_r() { return m_channel[m_gsel].cwid; } cofsl_r()40 u8 cofsl_r() { return u8(m_channel[m_gsel].cofs >> 0); } cofsh_r()41 u8 cofsh_r() { return u8(m_channel[m_gsel].cofs >> 8); } cmap_r()42 u16 cmap_r() { return m_channel[m_gsel].cmap[m_channel[m_gsel].ctag]; } gstat_r()43 u8 gstat_r() { return m_gstat; } 44 45 void cctl_w(u8 data); ctrcl_w(u8 data)46 void ctrcl_w(u8 data) { m_channel[m_gsel].ctrc = (m_channel[m_gsel].ctrc & 0xffff00U) | (u32(data) << 0); } ctrcm_w(u8 data)47 void ctrcm_w(u8 data) { m_channel[m_gsel].ctrc = (m_channel[m_gsel].ctrc & 0xff00ffU) | (u32(data) << 8); } ctrch_w(u8 data)48 void ctrch_w(u8 data) { m_channel[m_gsel].ctrc = (m_channel[m_gsel].ctrc & 0x00ffffU) | (u32(data) << 16); } ctag_w(u8 data)49 void ctag_w(u8 data) { m_channel[m_gsel].ctag = data; } cwid_w(u8 data)50 void cwid_w(u8 data) { m_channel[m_gsel].cwid = data; } cofsl_w(u8 data)51 void cofsl_w(u8 data) { m_channel[m_gsel].cofs = (m_channel[m_gsel].cofs & 0xff00U) | (u16(data) << 0); } cofsh_w(u8 data)52 void cofsh_w(u8 data) { m_channel[m_gsel].cofs = (m_channel[m_gsel].cofs & 0x00ffU) | (u16(data & 0x0f) << 8); } cmap_w(offs_t offset,u16 data,u16 mem_mask)53 void cmap_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_channel[m_gsel].cmap[m_channel[m_gsel].ctag]); } gsel_w(u8 data)54 void gsel_w(u8 data) { m_gsel = data; } 55 56 void irq_check(void *ptr = nullptr, s32 param = 0); 57 void dma_check(void *ptr = nullptr, s32 param = 0); 58 59 required_address_space m_bus; 60 61 devcb_write_line m_out_int; 62 devcb_read8::array<4> m_dma_r; 63 devcb_write8::array<4> m_dma_w; 64 65 emu_timer *m_irq_check; 66 emu_timer *m_dma_check; 67 68 enum cstat_mask : u8 69 { 70 CS_ENABLE = 0x01, // channel enable 71 CS_MODE = 0x02, // transfer to memory 72 CS_RESET = 0x04, // reset channel 73 CS_ZINTEN = 0x08, // terminal count interrupt? 74 CS_APAD = 0x10, // auto pad 75 CS_AFIX = 0x20, 76 CS_A28 = 0x40, 77 CS_TCZ = 0x80, // transfer count zero? 78 }; 79 80 struct dma_channel 81 { 82 u8 cstat; // channel status 83 u8 cctl; // channel control 84 u32 ctrc; // channel counter 85 u8 ctag; // channel tag 86 u8 cwid; // channel width 87 u16 cofs; // channel offset 88 u16 cmap[256]; 89 } 90 m_channel[4]; 91 u8 m_gsel; // channel select 92 u8 m_gstat; // general status 93 94 bool m_out_int_state; 95 }; 96 97 DECLARE_DEVICE_TYPE(DMAC_0448, dmac_0448_device) 98 99 #endif // MAME_MACHINE_DMAC_0448_H 100