summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/jag_blitter.cpp
blob: 46f5809a8f5301ee69758fc337c600f64d52ee6b (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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/***************************************************************************

	Atari Jaguar "Blitter" device
	
	TODO:
    - Stub device, port/rewrite from jagblit;
	- actual codename/chip part number;
	- has different revs, encapsulate;

***************************************************************************/

#include "emu.h"
#include "jag_blitter.h"



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

// device type definition
DEFINE_DEVICE_TYPE(JAG_BLITTER, jag_blitter_device, "jag_blitter", "Atari Jaguar Blitter")


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  jag_blitter_device - constructor
//-------------------------------------------------

jag_blitter_device::jag_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, JAG_BLITTER, tag, owner, clock)
	, device_memory_interface(mconfig, *this)
	, m_space_config("regs", ENDIANNESS_BIG, 32, 8, 0, address_map_constructor(FUNC(jag_blitter_device::regs_map), this))
	, m_command_latch(0)
	, m_status_idle(true)
	, m_count_lines(0)
	, m_count_pixels(0)
{
	m_a1.base = 0;
	m_a1.xstep = 0;
	m_a1.ystep = 0;
}

device_memory_interface::space_config_vector jag_blitter_device::memory_space_config() const
{
	return space_config_vector {
		std::make_pair(0, &m_space_config)
	};
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void jag_blitter_device::device_start()
{
	save_item(NAME(m_status_idle));
	save_item(NAME(m_command_latch));
	save_item(NAME(m_count_lines));
	save_item(NAME(m_count_pixels));
	save_item(NAME(m_a1.base));
	save_item(NAME(m_a1.xstep));
	save_item(NAME(m_a1.ystep));

	m_command_timer = timer_alloc(0);
}


//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void jag_blitter_device::device_reset()
{
	m_command_latch = 0;
	m_status_idle = true;
	
	m_command_timer->adjust(attotime::never);
}

//--------------------------------------------------
// core workings
//--------------------------------------------------

/***************************************************************************
    FUNCTION TABLES
***************************************************************************/

const jag_blitter_device::op_func jag_blitter_device::upda_ops[8] =
{
	&jag_blitter_device::op_nop,
	&jag_blitter_device::op_unemulated, // upda1f
	&jag_blitter_device::op_upda1,
	&jag_blitter_device::op_unemulated, // upda1 + upda1f 

	&jag_blitter_device::op_unemulated, // upda2
	&jag_blitter_device::op_unemulated, // upda1f + upda2
	&jag_blitter_device::op_unemulated, // upda1 + upda2
	&jag_blitter_device::op_unemulated	// upda1 + upda1f + upda2
};

void jag_blitter_device::op_nop()
{
	// do nothing for this step
}

// common cases for unhandled, will be removed once everything is set
void jag_blitter_device::op_unemulated()
{
	throw emu_fatalerror("%s: unhandled step with command latch %08x",m_command_latch);
}

void jag_blitter_device::op_upda1()
{
	// ...
	
}

inline void jag_blitter_device::command_start()
{
	if (m_status_idle == false)
		throw emu_fatalerror("%s: inflight blitter trigger %08x", this->tag(), m_command_latch);
	m_status_idle = false;
	// TODO: to be removed, see below
	m_command_timer->adjust(attotime::from_ticks(m_count_lines * m_count_pixels, this->clock()));
}

inline void jag_blitter_device::command_run()
{
	// TODO: need to single step, have different timings between pixel and phrase modes,
	// calculate collision detection, delay a bit the kickoff due of bus chain requests,
	// take more time by virtue of using additional steps, be a civilian or not depending 
	// of BUSHI setting
	
	printf("%08x\n",m_command_latch);
	// init
	m_a1.ptr = m_a1.base;
	
	// ...
	
	command_done();
}

inline void jag_blitter_device::command_done()
{
	// m_status_idle = true;
	// ...
}

void jag_blitter_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	command_run();
}

//**************************************************************************
//  READ/WRITE HANDLERS
//**************************************************************************

void jag_blitter_device::regs_map(address_map &map)
{
	// $f02200
	map(0x00, 0x03).w(FUNC(jag_blitter_device::a1_base_w));
	map(0x10, 0x13).w(FUNC(jag_blitter_device::a1_ystep_w)).umask32(0xffff0000);
	map(0x10, 0x13).w(FUNC(jag_blitter_device::a1_xstep_w)).umask32(0x0000ffff);
	map(0x38, 0x3b).rw(FUNC(jag_blitter_device::status_r), FUNC(jag_blitter_device::command_w));
	map(0x3c, 0x3f).w(FUNC(jag_blitter_device::count_outer_w)).umask32(0xffff0000);
	map(0x3c, 0x3f).w(FUNC(jag_blitter_device::count_inner_w)).umask32(0x0000ffff);
}

void jag_blitter_device::a1_base_w(offs_t offset, u32 data, u32 mem_mask)
{
	COMBINE_DATA(&m_a1.base);
	// align to phrase
	m_a1.base &= ~7;
}

void jag_blitter_device::a1_xstep_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_a1.xstep);
}

void jag_blitter_device::a1_ystep_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_a1.ystep);
}

u32 jag_blitter_device::status_r()
{
	// TODO: stopped bit
	// TODO: diag bits 2-31
	return m_status_idle;
}

void jag_blitter_device::command_w(offs_t offset, u32 data, u32 mem_mask)
{
	COMBINE_DATA(&m_command_latch);
	// TODO: is it possible from 68k to write on this in byte units?
	// We may just do so in order to take endianness into account, or just delegate to the overlying bus framework, 
	// may be a common problem with ALL video regs for that matter.
	if (ACCESSING_BITS_0_15)
		command_start();
}

void jag_blitter_device::count_outer_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_count_lines);
	if (m_count_lines == 0)
	{
		// according to documentation, log it out
		m_count_lines = 0x10000;
		popmessage("Blitter: line count set to max, contact MAMEdev");
	}
}

void jag_blitter_device::count_inner_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_count_pixels);
	if (m_count_pixels == 0)
	{
		// according to documentation, log it out
		m_count_pixels = 0x10000;
		popmessage("Blitter: pixel count set to max, contact MAMEdev");
	}
}

u32 jag_blitter_device::iobus_r(offs_t offset, u32 mem_mask)
{
	return space().read_dword(offset*4, mem_mask);
}

void jag_blitter_device::iobus_w(offs_t offset, u32 data, u32 mem_mask)
{
	space().write_dword(offset*4, data, mem_mask);
}