summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/generalplus_gpl16250soc.h
blob: 93c097e2d82a0e010cbf04f81e0fcf818e9df9ad (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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
// license:BSD-3-Clause
// copyright-holders:David Haywood
/*****************************************************************************

  SunPlus "GCM394" (based on die pictures)

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

#ifndef MAME_MACHINE_GENERALPLUS_GPL16250SOC_H
#define MAME_MACHINE_GENERALPLUS_GPL16250SOC_H

#pragma once

#include "cpu/unsp/unsp.h"
#include "screen.h"
#include "emupal.h"
#include "generalplus_gpl16250soc_video.h"
#include "spg2xx_audio.h"

typedef device_delegate<void (uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)> sunplus_gcm394_cs_callback_device;

class sunplus_gcm394_base_device : public unsp_20_device, public device_mixer_interface
{
public:
	sunplus_gcm394_base_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) :
		sunplus_gcm394_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(sunplus_gcm394_base_device::gcm394_internal_map), this))
	{
	}

	sunplus_gcm394_base_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal) :
		unsp_20_device(mconfig, type, tag, owner, clock, internal),
		device_mixer_interface(mconfig, *this, 2),
		m_screen(*this, finder_base::DUMMY_TAG),
		m_spg_video(*this, "spgvideo"),
		m_spg_audio(*this, "spgaudio"),
		m_internalrom(*this, "internal"),
		m_mainram(*this, "mainram"),
		m_porta_in(*this),
		m_portb_in(*this),
		m_portc_in(*this),
		m_portd_in(*this),
		m_porta_out(*this),
		m_portb_out(*this),
		m_portc_out(*this),
		m_portd_out(*this),
		m_nand_read_cb(*this),
		m_csbase(0x20000),
		m_romtype(0),
		m_space_read_cb(*this),
		m_space_write_cb(*this),
		m_boot_mode(0),
		m_cs_callback(*this, DEVICE_SELF, FUNC(sunplus_gcm394_base_device::default_cs_callback))
	{
	}

	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return m_spg_video->screen_update(screen, bitmap, cliprect); }

	auto porta_in() { return m_porta_in.bind(); }
	auto portb_in() { return m_portb_in.bind(); }
	auto portc_in() { return m_portc_in.bind(); }
	auto portd_in() { return m_portd_in.bind(); }

	auto porta_out() { return m_porta_out.bind(); }
	auto portb_out() { return m_portb_out.bind(); }
	auto portc_out() { return m_portc_out.bind(); }
	auto portd_out() { return m_portd_out.bind(); }

	auto space_read_callback() { return m_space_read_cb.bind(); }
	auto space_write_callback() { return m_space_write_cb.bind(); }

	auto nand_read_callback() { return m_nand_read_cb.bind(); }

	DECLARE_WRITE_LINE_MEMBER(vblank) { m_spg_video->vblank(state); }

	virtual void device_add_mconfig(machine_config& config) override;

	void set_bootmode(int mode) { m_boot_mode = mode; }

	IRQ_CALLBACK_MEMBER(irq_vector_cb);
	template <typename... T> void set_cs_config_callback(T &&... args) { m_cs_callback.set(std::forward<T>(args)...); }
	void default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4 );

	void set_cs_space(address_space* csspace) { m_cs_space = csspace; }

	//void set_paldisplaybank_high_hack(int pal_displaybank_high) { m_spg_video->set_paldisplaybank_high(pal_displaybank_high); }
	void set_alt_tile_addressing_hack(int alt_tile_addressing) { m_spg_video->set_alt_tile_addressing(alt_tile_addressing); }
	//void set_pal_sprites_hack(int pal_sprites) { m_spg_video->set_pal_sprites(pal_sprites); }
	//void set_pal_back_hack(int pal_back) { m_spg_video->set_pal_back(pal_back); }
	void set_alt_extrasprite_hack(int alt_extrasprite_hack) { m_spg_video->set_alt_extrasprite(alt_extrasprite_hack); }

	void set_romtype(int romtype) { m_romtype = romtype; }

	inline uint16_t get_ram_addr(uint32_t addr) { return m_mainram[addr]; }

protected:

	virtual void device_start() override;
	virtual void device_reset() override;

	virtual void device_post_load() override;

	void gcm394_internal_map(address_map &map);
	void base_internal_map(address_map &map);

	required_device<screen_device> m_screen;
	required_device<gcm394_video_device> m_spg_video;
	required_device<sunplus_gcm394_audio_device> m_spg_audio;
	optional_memory_region m_internalrom;
	required_shared_ptr<u16> m_mainram;

	devcb_read16 m_porta_in;
	devcb_read16 m_portb_in;
	devcb_read16 m_portc_in;
	devcb_read16 m_portd_in;

	devcb_write16 m_porta_out;
	devcb_write16 m_portb_out;
	devcb_write16 m_portc_out;
	devcb_write16 m_portd_out;

	uint16_t m_dma_params[8][4];
	bool m_dma_latched[4];

	// unk 78xx
	uint16_t m_7803;

	uint16_t m_7807;

	uint16_t m_membankswitch_7810;

	uint16_t m_7816;
	uint16_t m_7817;

	uint16_t m_7819;

	uint16_t m_782x[5];

	uint16_t m_782d;

	uint16_t m_7835;

	uint16_t m_7860;

	uint16_t m_7861;

	uint16_t m_7862_porta_direction;
	uint16_t m_7863_porta_attribute;

	uint16_t m_786a_portb_direction;
	uint16_t m_786b_portb_attribute;

	uint16_t m_7872_portc_direction;
	uint16_t m_7873_portc_attribute;

	uint16_t m_787a_portd_direction;
	uint16_t m_787b_portd_attribute;

	uint16_t m_7870;

	//uint16_t m_7871;


	uint16_t m_7882;
	uint16_t m_7883;

	uint16_t m_78a0;

	uint16_t m_78a4;
	uint16_t m_78a5;
	uint16_t m_78a6;

	uint16_t m_78a8;

	uint16_t m_78b0;
	uint16_t m_78b1;
	uint16_t m_78b2;

	uint16_t m_78b8;

	uint16_t m_78f0;

	uint16_t m_78fb;

	// unk 79xx
	uint16_t m_7934;
	uint16_t m_7935;
	uint16_t m_7936;

	uint16_t m_7960;
	uint16_t m_7961;

	uint16_t m_system_dma_memtype;

	devcb_read16 m_nand_read_cb;
	int m_csbase;

	uint16_t internalrom_lower32_r(offs_t offset);

	address_space* m_cs_space;

	uint16_t cs_space_r(offs_t offset);
	void cs_space_w(offs_t offset, uint16_t data);
	uint16_t cs_bank_space_r(offs_t offset);
	void cs_bank_space_w(offs_t offset, uint16_t data);
	int m_romtype;

private:
	devcb_read16 m_space_read_cb;
	devcb_write16 m_space_write_cb;

	uint16_t unk_r(offs_t offset);
	void unk_w(offs_t offset, uint16_t data);

	void write_dma_params(int channel, int offset, uint16_t data);
	uint16_t read_dma_params(int channel, int offset);
	void trigger_systemm_dma(int channel);

	uint16_t system_dma_params_channel0_r(offs_t offset);
	void system_dma_params_channel0_w(offs_t offset, uint16_t data);
	uint16_t system_dma_params_channel1_r(offs_t offset);
	void system_dma_params_channel1_w(offs_t offset, uint16_t data);
	uint16_t system_dma_params_channel2_r(offs_t offset);
	void system_dma_params_channel2_w(offs_t offset, uint16_t data);
	uint16_t system_dma_params_channel3_r(offs_t offset);
	void system_dma_params_channel3_w(offs_t offset, uint16_t data);
	uint16_t system_dma_status_r();
	void system_dma_7abf_unk_w(uint16_t data);
	uint16_t system_dma_memtype_r();
	void system_dma_memtype_w(uint16_t data);

	uint16_t unkarea_780f_status_r();
	uint16_t unkarea_78fb_status_r();

	uint16_t unkarea_7803_r();
	void unkarea_7803_w(uint16_t data);

	void unkarea_7807_w(uint16_t data);

	void waitmode_enter_780c_w(uint16_t data);

	uint16_t membankswitch_7810_r();
	void membankswitch_7810_w(uint16_t data);

	void unkarea_7816_w(uint16_t data);
	void unkarea_7817_w(uint16_t data);

	uint16_t unkarea_7819_r();
	void unkarea_7819_w(uint16_t data);

	void chipselect_csx_memory_device_control_w(offs_t offset, uint16_t data);

	void unkarea_7835_w(uint16_t data);

	uint16_t unkarea_782d_r();
	void unkarea_782d_w(uint16_t data);

	// Port A
	uint16_t ioarea_7860_porta_r();
	void ioarea_7860_porta_w(uint16_t data);
	uint16_t ioarea_7861_porta_buffer_r();
	void ioarea_7861_porta_buffer_w(uint16_t data);
	uint16_t ioarea_7862_porta_direction_r();
	void ioarea_7862_porta_direction_w(uint16_t data);
	uint16_t ioarea_7863_porta_attribute_r();
	void ioarea_7863_porta_attribute_w(uint16_t data);

	// Port B
	uint16_t ioarea_7868_portb_r();
	void ioarea_7868_portb_w(uint16_t data);
	uint16_t ioarea_7869_portb_buffer_r();
	void ioarea_7869_portb_buffer_w(uint16_t data);
	uint16_t ioarea_786a_portb_direction_r();
	void ioarea_786a_portb_direction_w(uint16_t data);
	uint16_t ioarea_786b_portb_attribute_r();
	void ioarea_786b_portb_attribute_w(uint16_t data);

	// Port C
	uint16_t ioarea_7870_portc_r();
	void ioarea_7870_portc_w(uint16_t data);
	uint16_t ioarea_7871_portc_buffer_r();
	void ioarea_7871_portc_buffer_w(uint16_t data);
	uint16_t ioarea_7872_portc_direction_r();
	void ioarea_7872_portc_direction_w(uint16_t data);
	uint16_t ioarea_7873_portc_attribute_r();
	void ioarea_7873_portc_attribute_w(uint16_t data);

	// Port D
	uint16_t ioarea_7878_portd_r();
	void ioarea_7878_portd_w(uint16_t data);
	uint16_t ioarea_7879_portd_buffer_r();
	void ioarea_7879_portd_buffer_w(uint16_t data);
	uint16_t ioarea_787a_portd_direction_r();
	void ioarea_787a_portd_direction_w(uint16_t data);
	uint16_t ioarea_787b_portd_attribute_r();
	void ioarea_787b_portd_attribute_w(uint16_t data);

	uint16_t unkarea_7882_r();
	void unkarea_7882_w(uint16_t data);
	uint16_t unkarea_7883_r();
	void unkarea_7883_w(uint16_t data);

	void unkarea_78a0_w(uint16_t data);

	uint16_t unkarea_78a0_r();
	uint16_t unkarea_78a1_r();

	void unkarea_78a4_w(uint16_t data);
	void unkarea_78a5_w(uint16_t data);
	void unkarea_78a6_w(uint16_t data);

	void unkarea_78a8_w(uint16_t data);

	void unkarea_78b0_w(uint16_t data);
	void unkarea_78b1_w(uint16_t data);

	uint16_t unkarea_78b2_r();
	void unkarea_78b2_w(uint16_t data);

	void unkarea_78b8_w(uint16_t data);

	uint16_t unkarea_78d0_r();
	uint16_t unkarea_78d8_r();

	void unkarea_78f0_w(uint16_t data);

	uint16_t unkarea_7904_r();

	uint16_t unkarea_7934_r();
	void unkarea_7934_w(uint16_t data);

	uint16_t unkarea_7935_r();
	void unkarea_7935_w(uint16_t data);

	uint16_t unkarea_7936_r();
	void unkarea_7936_w(uint16_t data);

	uint16_t spi_7944_rxdata_r();
	uint16_t spi_7945_misc_control_reg_r();
	void spi_7942_txdata_w(uint16_t data);

	void unkarea_7960_w(uint16_t data);
	uint16_t unkarea_7961_r();
	void unkarea_7961_w(uint16_t data);


	DECLARE_WRITE_LINE_MEMBER(videoirq_w);
	DECLARE_WRITE_LINE_MEMBER(audioirq_w);

	uint16_t system_7a35_r();
	uint16_t system_7a37_r();
	uint16_t system_7a39_r();
	uint16_t system_7a3a_r();
	uint16_t system_7a46_r();
	uint16_t system_7a54_r();

	void checkirq6();

	emu_timer *m_unk_timer;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	inline uint16_t read_space(uint32_t offset);
	inline void write_space(uint32_t offset, uint16_t data);

	// config registers (external pins)
	int m_boot_mode; // 2 pins determine boot mode, likely only read at power-on
	sunplus_gcm394_cs_callback_device m_cs_callback;
};



class sunplus_gcm394_device : public sunplus_gcm394_base_device
{
public:
	template <typename T>
	sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) :
		sunplus_gcm394_device(mconfig, tag, owner, clock)
	{
		m_screen.set_tag(std::forward<T>(screen_tag));
	}

	sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};


class generalplus_gpac800_device : public sunplus_gcm394_base_device
{
public:
	template <typename T>
	generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) :
		generalplus_gpac800_device(mconfig, tag, owner, clock)
	{
		m_screen.set_tag(std::forward<T>(screen_tag));
		m_csbase = 0x30000;
	}

	generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	void gpac800_internal_map(address_map &map);

	//virtual void device_start() override;
	virtual void device_reset() override;

private:
	void recalculate_calculate_effective_nand_address();

	uint16_t nand_7850_status_r();
	uint16_t nand_7854_r();
	void nand_dma_ctrl_w(uint16_t data);
	void nand_7850_w(uint16_t data);
	void nand_command_w(uint16_t data);
	void nand_addr_low_w(uint16_t data);
	void nand_addr_high_w(uint16_t data);
	uint16_t nand_ecc_low_byte_error_flag_1_r();
	void nand_7856_type_w(uint16_t data);
	void nand_7857_w(uint16_t data);
	void nand_785b_w(uint16_t data);
	void nand_785c_w(uint16_t data);
	void nand_785d_w(uint16_t data);
	uint16_t nand_785e_r();

	uint16_t m_nandcommand;

	uint16_t m_nand_addr_low;
	uint16_t m_nand_addr_high;

	uint16_t m_nand_dma_ctrl;
	uint16_t m_nand_7850;
	uint16_t m_nand_785d;
	uint16_t m_nand_785c;
	uint16_t m_nand_785b;
	uint16_t m_nand_7856;
	uint16_t m_nand_7857;

	int m_curblockaddr;
	uint32_t m_effectiveaddress;
};


class generalplus_gpspispi_device : public sunplus_gcm394_base_device
{
public:
	template <typename T>
	generalplus_gpspispi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) :
		generalplus_gpspispi_device(mconfig, tag, owner, clock)
	{
		m_screen.set_tag(std::forward<T>(screen_tag));
		m_csbase = 0x30000;
	}

	generalplus_gpspispi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	void gpspispi_internal_map(address_map &map);

	//virtual void device_start() override;
	//virtual void device_reset() override;

private:
	uint16_t spi_unk_7943_r();
};



DECLARE_DEVICE_TYPE(GCM394, sunplus_gcm394_device)
DECLARE_DEVICE_TYPE(GPAC800, generalplus_gpac800_device)
DECLARE_DEVICE_TYPE(GP_SPISPI, generalplus_gpspispi_device)

#endif // MAME_MACHINE_GENERALPLUS_GPL16250SOC_H