mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
173 lines
5.8 KiB
C++
173 lines
5.8 KiB
C++
// license: GPL-2.0+
|
|
// copyright-holders: Dirk Best
|
|
/***************************************************************************
|
|
|
|
DMAC
|
|
|
|
DMA controller used in Amiga systems
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef MAME_MACHINE_DMAC_H
|
|
#define MAME_MACHINE_DMAC_H
|
|
|
|
#pragma once
|
|
|
|
#include "autoconfig.h"
|
|
|
|
|
|
class amiga_dmac_device : public device_t, public amiga_autoconfig
|
|
{
|
|
public:
|
|
// callbacks
|
|
auto cfgout_cb() { return m_cfgout_cb.bind(); }
|
|
auto int_cb() { return m_int_cb.bind(); }
|
|
auto css_read_cb() { return m_css_read_cb.bind(); }
|
|
auto css_write_cb() { return m_css_write_cb.bind(); }
|
|
auto csx0_read_cb() { return m_csx0_read_cb.bind(); }
|
|
auto csx0_write_cb() { return m_csx0_write_cb.bind(); }
|
|
auto csx1_read_cb() { return m_csx1_read_cb.bind(); }
|
|
auto csx1_write_cb() { return m_csx1_write_cb.bind(); }
|
|
auto sdack_read_cb() { return m_sdack_read_cb.bind(); }
|
|
auto sdack_write_cb() { return m_sdack_write_cb.bind(); }
|
|
auto xdack_read_cb() { return m_xdack_read_cb.bind(); }
|
|
auto xdack_write_cb() { return m_xdack_write_cb.bind(); }
|
|
|
|
void set_address_space(address_space *space) { m_space = space; }
|
|
void set_rom(const char *region) { m_rom.set_tag(region); }
|
|
void set_ram(uint16_t *ram) { m_ram = ram; }
|
|
|
|
// input lines
|
|
void configin_w(int state);
|
|
void ramsz_w(int state);
|
|
void rst_w(int state);
|
|
void intx_w(int state);
|
|
void sdreq_w(int state);
|
|
void xdreq_w(int state);
|
|
|
|
protected:
|
|
amiga_dmac_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool rev1);
|
|
|
|
virtual void device_start() override ATTR_COLD;
|
|
|
|
// amiga_autoconfig overrides
|
|
virtual void autoconfig_base_address(offs_t address) override;
|
|
|
|
private:
|
|
void map(address_map &map) ATTR_COLD;
|
|
|
|
TIMER_CALLBACK_MEMBER(update_dma);
|
|
void update_interrupts();
|
|
void start_dma();
|
|
void stop_dma();
|
|
|
|
uint16_t autoconfig_r(offs_t offset, uint16_t mem_mask);
|
|
void autoconfig_w(offs_t offset, uint16_t data, uint16_t mem_mask);
|
|
|
|
uint16_t istr_r(offs_t offset, uint16_t mem_mask);
|
|
uint16_t cntr_r(offs_t offset, uint16_t mem_mask);
|
|
void cntr_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
void wtc_hi_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
void wtc_lo_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
void acr_hi_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
void acr_lo_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
void dawr_w(offs_t offset, uint16_t data,uint16_t mem_mask);
|
|
|
|
uint8_t css_r(offs_t offset);
|
|
void css_w(offs_t offset, uint8_t data);
|
|
uint8_t csx0_r(offs_t offset);
|
|
void csx0_w(offs_t offset, uint8_t data);
|
|
uint8_t csx1_r(offs_t offset);
|
|
void csx1_w(offs_t offset, uint8_t data);
|
|
|
|
// strobe register
|
|
void st_dma();
|
|
uint16_t st_dma_r(offs_t offset, uint16_t mem_mask) { st_dma(); return 0; };
|
|
void st_dma_w(offs_t offset, uint16_t data, uint16_t mem_mask) { st_dma(); };
|
|
void sp_dma();
|
|
uint16_t sp_dma_r(offs_t offset, uint16_t mem_mask) { sp_dma(); return 0; };
|
|
void sp_dma_w(offs_t offset, uint16_t data, uint16_t mem_mask) { sp_dma(); };
|
|
void cint();
|
|
uint16_t cint_r(offs_t offset, uint16_t mem_mask) { cint(); return 0; };
|
|
void cint_w(offs_t offset, uint16_t data, uint16_t mem_mask) { cint(); };
|
|
void flush();
|
|
uint16_t flush_r(offs_t offset, uint16_t mem_mask) { flush(); return 0; };
|
|
void flush_w(offs_t offset, uint16_t data, uint16_t mem_mask) { flush(); };
|
|
|
|
// control register definitions
|
|
static constexpr uint16_t CNTR_TCEN = 0x80; // terminal count enable
|
|
static constexpr uint16_t CNTR_PREST = 0x40; // peripheral reset
|
|
static constexpr uint16_t CNTR_PDMD = 0x20; // peripheral device mode select (1=scsi/0=xt)
|
|
static constexpr uint16_t CNTR_INTEN = 0x10; // interrupt enable
|
|
static constexpr uint16_t CNTR_DDIR = 0x08; // device direction (1=from host to peripheral)
|
|
|
|
// interrupt status register definitions
|
|
static constexpr uint16_t ISTR_INT_F = 0x80; // interrupt follow
|
|
static constexpr uint16_t ISTR_INTS = 0x40; // scsi peripheral interrupt
|
|
static constexpr uint16_t ISTR_E_INT = 0x20; // end-of-process interrupt
|
|
static constexpr uint16_t ISTR_INT_P = 0x10; // interrupt pending
|
|
static constexpr uint16_t ISTR_UE_INT = 0x08; // fifo underrun interrupt
|
|
static constexpr uint16_t ISTR_OE_INT = 0x04; // fifo overflow interrupt
|
|
static constexpr uint16_t ISTR_FF_FLG = 0x02; // fifo full flag
|
|
static constexpr uint16_t ISTR_FE_FLG = 0x01; // fifo empty flag
|
|
|
|
static constexpr uint16_t ISTR_INT_MASK = 0x6c;
|
|
|
|
// callbacks
|
|
devcb_write_line m_cfgout_cb;
|
|
devcb_write_line m_int_cb;
|
|
devcb_read8 m_css_read_cb;
|
|
devcb_write8 m_css_write_cb;
|
|
devcb_read8 m_csx0_read_cb;
|
|
devcb_write8 m_csx0_write_cb;
|
|
devcb_read8 m_csx1_read_cb;
|
|
devcb_write8 m_csx1_write_cb;
|
|
devcb_read8 m_sdack_read_cb;
|
|
devcb_write8 m_sdack_write_cb;
|
|
devcb_read8 m_xdack_read_cb;
|
|
devcb_write8 m_xdack_write_cb;
|
|
|
|
optional_memory_region m_rom;
|
|
address_space *m_space;
|
|
uint16_t *m_ram;
|
|
int m_ram_size;
|
|
bool m_rev1;
|
|
|
|
// internal registers
|
|
uint16_t m_cntr; // control register
|
|
uint16_t m_istr; // interrupt status register
|
|
uint32_t m_wtc; // word transfer count
|
|
uint32_t m_acr; // address control register
|
|
|
|
// state of input lines
|
|
bool m_intx;
|
|
bool m_sdreq;
|
|
bool m_xdreq;
|
|
|
|
emu_timer *m_dma_timer;
|
|
|
|
// autoconfig state
|
|
bool m_autoconfig_dmac_done;
|
|
bool m_autoconfig_ram_done;
|
|
offs_t m_dmac_address;
|
|
offs_t m_ram_address;
|
|
};
|
|
|
|
class amiga_dmac_rev1_device : public amiga_dmac_device
|
|
{
|
|
public:
|
|
amiga_dmac_rev1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
|
};
|
|
|
|
class amiga_dmac_rev2_device : public amiga_dmac_device
|
|
{
|
|
public:
|
|
amiga_dmac_rev2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
|
};
|
|
|
|
// device type definition
|
|
DECLARE_DEVICE_TYPE(AMIGA_DMAC_REV1, amiga_dmac_rev1_device)
|
|
DECLARE_DEVICE_TYPE(AMIGA_DMAC_REV2, amiga_dmac_rev2_device)
|
|
|
|
#endif // MAME_MACHINE_DMAC_H
|