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
156
157
158
159
160
161
162
163
164
|
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
/*
* An implementation of the SGA (SRX Gate Array) device found in Intergraph
* InterPro family systems. There is no public documentation on this device,
* so the implementation is being built to follow the logic of the system boot
* ROM and its diagnostic tests.
*
* Please be aware that code in here is not only broken, it's likely wrong in
* many cases.
*
* TODO
* - too long to list
*/
#include "emu.h"
#include "interpro_sga.h"
#define VERBOSE 0
#include "logmacro.h"
void interpro_sga_device::map(address_map &map)
{
map(0x00, 0x03).rw(FUNC(interpro_sga_device::gcsr_r), FUNC(interpro_sga_device::gcsr_w));
map(0x04, 0x07).rw(FUNC(interpro_sga_device::ipoll_r), FUNC(interpro_sga_device::ipoll_w));
map(0x08, 0x0b).rw(FUNC(interpro_sga_device::imask_r), FUNC(interpro_sga_device::imask_w));
map(0x0c, 0x0f).rw(FUNC(interpro_sga_device::range_base_r), FUNC(interpro_sga_device::range_base_w));
map(0x10, 0x13).rw(FUNC(interpro_sga_device::range_end_r), FUNC(interpro_sga_device::range_end_w));
map(0x14, 0x17).rw(FUNC(interpro_sga_device::cttag_r), FUNC(interpro_sga_device::cttag_w)); // aka diag1
map(0x18, 0x1b).rw(FUNC(interpro_sga_device::address_r), FUNC(interpro_sga_device::address_w)); // aka diag0
map(0x1c, 0x1f).rw(FUNC(interpro_sga_device::dmacsr_r), FUNC(interpro_sga_device::dmacsr_w));
map(0x20, 0x23).rw(FUNC(interpro_sga_device::edmacsr_r), FUNC(interpro_sga_device::edmacsr_w)); // esga
map(0x24, 0x27).rw(FUNC(interpro_sga_device::reg6_range_r), FUNC(interpro_sga_device::reg6_range_w)); // esga
map(0x80, 0x83).rw(FUNC(interpro_sga_device::ddpta0_r), FUNC(interpro_sga_device::ddpta0_w)); // dma 0 device page table address (esga)
map(0x84, 0x87).rw(FUNC(interpro_sga_device::ddpad0_r), FUNC(interpro_sga_device::ddpad0_w)); // dma 0 device page address
map(0x88, 0x8b).rw(FUNC(interpro_sga_device::ddoff0_r), FUNC(interpro_sga_device::ddoff0_w)); // dma 0 device page offset
map(0x8c, 0x8f).rw(FUNC(interpro_sga_device::ddtc0_r), FUNC(interpro_sga_device::ddtc0_w)); // dma 0 device transfer context
map(0x90, 0x93).rw(FUNC(interpro_sga_device::dspta0_r), FUNC(interpro_sga_device::dspta0_w)); // dma 0 SRX page table address (esga)
map(0x94, 0x97).rw(FUNC(interpro_sga_device::dspad0_r), FUNC(interpro_sga_device::dspad0_w)); // dma 0 SRX page address
map(0x98, 0x9b).rw(FUNC(interpro_sga_device::dsoff0_r), FUNC(interpro_sga_device::dsoff0_w)); // dma 0 SRX page offset
map(0x9c, 0x9f).rw(FUNC(interpro_sga_device::dstc0_r), FUNC(interpro_sga_device::dstc0_w)); // dma 0 SRX transfer context
map(0xa4, 0xa7).rw(FUNC(interpro_sga_device::dspad1_r), FUNC(interpro_sga_device::dspad1_w)); // dma 1 source page address
map(0xa8, 0xab).rw(FUNC(interpro_sga_device::dsoff1_r), FUNC(interpro_sga_device::dsoff1_w)); // dma 1 source page offset
map(0xac, 0xaf).rw(FUNC(interpro_sga_device::dstc1_r), FUNC(interpro_sga_device::dstc1_w)); // dma 1 source transfer count
map(0xb4, 0xb7).rw(FUNC(interpro_sga_device::ddpad1_r), FUNC(interpro_sga_device::ddpad1_w)); // dma 1 destination page address
map(0xb8, 0xbb).rw(FUNC(interpro_sga_device::ddoff1_r), FUNC(interpro_sga_device::ddoff1_w)); // dma 1 destination page offset
map(0xbc, 0xbf).rw(FUNC(interpro_sga_device::ddtc1_r), FUNC(interpro_sga_device::ddtc1_w)); // dma 1 destination transfer count
map(0xc0, 0xc3).rw(FUNC(interpro_sga_device::ddpta2_r), FUNC(interpro_sga_device::ddpta2_w)); // dma 2 device page table address (esga)
map(0xc4, 0xc7).rw(FUNC(interpro_sga_device::ddpad2_r), FUNC(interpro_sga_device::ddpad2_w)); // dma 2 device page address
map(0xc8, 0xcb).rw(FUNC(interpro_sga_device::ddoff2_r), FUNC(interpro_sga_device::ddoff2_w)); // dma 2 device page offset
map(0xcc, 0xcf).rw(FUNC(interpro_sga_device::ddtc2_r), FUNC(interpro_sga_device::ddtc2_w)); // dma 2 device transfer context
map(0xd0, 0xd3).rw(FUNC(interpro_sga_device::dspta2_r), FUNC(interpro_sga_device::dspta2_w)); // dma 2 SRX page table address (esga)
map(0xd4, 0xd7).rw(FUNC(interpro_sga_device::dspad2_r), FUNC(interpro_sga_device::dspad2_w)); // dma 2 SRX page address
map(0xd8, 0xdb).rw(FUNC(interpro_sga_device::dsoff2_r), FUNC(interpro_sga_device::dsoff2_w)); // dma 2 SRX page offset
map(0xdc, 0xdf).rw(FUNC(interpro_sga_device::dstc2_r), FUNC(interpro_sga_device::dstc2_w)); // dma 2 SRX transfer context
map(0xe0, 0xe3).rw(FUNC(interpro_sga_device::ddrd2_r), FUNC(interpro_sga_device::ddrd2_w)); // dma 2 device record descriptor (esga)
map(0xe4, 0xe7).rw(FUNC(interpro_sga_device::dsrd2_r), FUNC(interpro_sga_device::dsrd2_w)); // dma 2 SRX record descriptor (esga)
map(0xe8, 0xeb).rw(FUNC(interpro_sga_device::dcksum0_r), FUNC(interpro_sga_device::dcksum0_w)); // dma 1 device checksum register 0 (esga)
map(0xec, 0xef).rw(FUNC(interpro_sga_device::dcksum1_r), FUNC(interpro_sga_device::dcksum1_w)); // dma 1 device checksum register 1 (esga)
}
DEFINE_DEVICE_TYPE(INTERPRO_SGA, interpro_sga_device, "sga", "SRX Gate Array")
interpro_sga_device::interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, INTERPRO_SGA, tag, owner, clock)
, m_berr_func(*this)
{
}
void interpro_sga_device::device_start()
{
m_berr_func.resolve();
save_item(NAME(m_gcsr));
save_item(NAME(m_ipoll));
save_item(NAME(m_imask));
save_item(NAME(m_range_base));
save_item(NAME(m_range_end));
save_item(NAME(m_cttag));
save_item(NAME(m_address));
save_item(NAME(m_dmacsr));
save_item(NAME(m_edmacsr));
save_item(NAME(m_reg6_range));
save_item(NAME(m_ddpta0));
save_item(NAME(m_ddpad0));
save_item(NAME(m_ddoff0));
save_item(NAME(m_ddtc0));
save_item(NAME(m_dspta0));
save_item(NAME(m_dspad0));
save_item(NAME(m_dsoff0));
save_item(NAME(m_dstc0));
save_item(NAME(m_dspad1));
save_item(NAME(m_dsoff1));
save_item(NAME(m_dstc1));
save_item(NAME(m_ddpad1));
save_item(NAME(m_ddoff1));
save_item(NAME(m_ddtc1));
save_item(NAME(m_ddpta2));
save_item(NAME(m_ddpad2));
save_item(NAME(m_ddoff2));
save_item(NAME(m_ddtc2));
save_item(NAME(m_dspta2));
save_item(NAME(m_dspad2));
save_item(NAME(m_dsoff2));
save_item(NAME(m_dstc2));
save_item(NAME(m_ddrd2));
save_item(NAME(m_dsrd2));
save_item(NAME(m_dcksum0));
save_item(NAME(m_dcksum1));
}
void interpro_sga_device::device_reset()
{
}
void interpro_sga_device::ddtc1_w(u32 data)
{
m_ddtc1 = data;
// assume that when this register is written, we should start a
// memory to memory dma transfer
LOG(" gcsr = 0x%08x dmacsr = 0x%08x\n", m_gcsr, m_dmacsr);
LOG(" ipoll = 0x%08x imask = 0x%08x\n", m_ipoll, m_imask);
LOG("dspad1 = 0x%08x dsoff1 = 0x%08x dstc1 = 0x%08x\n", m_dspad1, m_dsoff1, m_dstc1);
LOG("ddpad1 = 0x%08x ddoff1 = 0x%08x ddtc1 = 0x%08x\n", m_ddpad1, m_ddoff1, m_ddtc1);
// when complete, we indicate by setting DMAEND(2) - 2 is probably the channel
// we also turn off the INTBERR and INTMMBE flags
m_ipoll &= ~(IPOLL_INTBERR | IPOLL_INTMMBE);
m_ipoll |= 0x200;
#if 0
// if the address is invalid, fake a bus error
if ((m_dspad1 & 0xfffff000) == 0x40000000 || (m_ddpad1 & 0xfffff) == 0x40000000)
{
m_ipoll |= IPOLL_INTBERR;
// error cycle - bit 0x10 indicates source address error (dspad1)
// now expecting 0x5463?
if ((m_dspad1 & 0xfffff000) == 0x40000000)
m_berr_func(space, 0x5433, m_dspad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x30 | CT(3)
else
m_berr_func(space, 0x5423, m_ddpad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x20 | CT(3)
// 0x5423 = BERR|SNAPOK | BG(ICAMMU)? | CT(23)
// 0x5433 = BERR|SNAPOK | BG(ICAMMU)? | CT(33)
// 0x5463 = BERR|SNAPOK | BG(ICAMMU)? | TAG(40=1) | CT(23)
}
#endif
}
|