1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// 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"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_DMAC_ADD(_tag, _clock) \
MCFG_DEVICE_ADD(_tag, AMIGA_DMAC, _clock)
#define MCFG_DMAC_CFGOUT_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_cfgout_handler(DEVCB_##_devcb);
#define MCFG_DMAC_INT_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_int_handler(DEVCB_##_devcb);
#define MCFG_DMAC_XDACK_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_xdack_handler(DEVCB_##_devcb);
#define MCFG_DMAC_SCSI_READ_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_scsi_read_handler(DEVCB_##_devcb);
#define MCFG_DMAC_SCSI_WRITE_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_scsi_write_handler(DEVCB_##_devcb);
#define MCFG_DMAC_IO_READ_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_io_read_handler(DEVCB_##_devcb);
#define MCFG_DMAC_IO_WRITE_HANDLER(_devcb) \
devcb = &downcast<amiga_dmac_device &>(*device).set_io_write_handler(DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> amiga_dmac_device
class amiga_dmac_device : public device_t, public amiga_autoconfig
{
public:
// construction/destruction
amiga_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// callbacks
template <class Object> devcb_base &set_cfgout_handler(Object &&cb) { return m_cfgout_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_int_handler(Object &&cb) { return m_int_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_xdack_handler(Object &&cb) { return m_xdack_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_scsi_read_handler(Object &&cb) { return m_scsi_read_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_scsi_write_handler(Object &&cb) { return m_scsi_write_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_io_read_handler(Object &&cb) { return m_io_read_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_io_write_handler(Object &&cb) { return m_io_write_handler.set_callback(std::forward<Object>(cb)); }
void set_address_space(address_space *space) { m_space = space; }
void set_rom(uint8_t *rom) { m_rom = rom; }
void set_ram(uint8_t *ram) { m_ram = ram; }
// input lines
DECLARE_WRITE_LINE_MEMBER( configin_w );
DECLARE_WRITE_LINE_MEMBER( ramsz_w );
DECLARE_WRITE_LINE_MEMBER( rst_w );
DECLARE_WRITE_LINE_MEMBER( intx_w );
DECLARE_WRITE_LINE_MEMBER( xdreq_w );
// dmac register access
DECLARE_READ16_MEMBER( register_read );
DECLARE_WRITE16_MEMBER( register_write );
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// amiga_autoconfig overrides
virtual void autoconfig_base_address(offs_t address) override;
private:
// control register flags
enum
{
CNTR_TCEN = 0x80, // terminal count enable
CNTR_PREST = 0x40, // peripheral reset
CNTR_PDMD = 0x20, // peripheral device mode select (1=scsi, 0=xt)
CNTR_INTEN = 0x10, // interrupt enable
CNTR_DDIR = 0x08 // device direction (1=rd host, wr to peripheral)
};
// interrupt status register
enum
{
ISTR_INTX = 0x100, // xt interrupt pending
ISTR_INT_F = 0x080, // interrupt follow
ISTR_INTS = 0x040, // scsi peripheral interrupt
ISTR_E_INT = 0x020, // end-of-process interrupt
ISTR_INT_P = 0x010, // interrupt pending
ISTR_UE_INT = 0x008, // under-run fifo error interrupt
ISTR_OE_INT = 0x004, // over-run fifo error interrupt
ISTR_FF_FLG = 0x002, // fifo-full flag
ISTR_FE_FLG = 0x001 // fifo-empty flag
};
static constexpr int ISTR_INT_MASK = 0x1ec;
// callbacks
devcb_write_line m_cfgout_handler;
devcb_write_line m_int_handler;
devcb_write_line m_xdack_handler;
devcb_read8 m_scsi_read_handler;
devcb_write8 m_scsi_write_handler;
devcb_read8 m_io_read_handler;
devcb_write8 m_io_write_handler;
address_space *m_space;
uint8_t *m_rom;
uint8_t *m_ram;
int m_ram_size;
// autoconfig state
bool m_configured;
// state of lines
int m_rst;
// register
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
bool m_dma_active;
void check_interrupts();
void start_dma();
void stop_dma();
};
// device type definition
DECLARE_DEVICE_TYPE(AMIGA_DMAC, amiga_dmac_device)
#endif // MAME_MACHINE_DMAC_H
|