summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/interpro_sga.cpp
blob: 6c7eb8f21d70f11fca97b99fd346cf3a6c307a49 (plain) (blame)
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
}