summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/tms9927.h
blob: 4108f015b71b2528f221eefd3dd53c37f4d76c15 (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
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/**********************************************************************

    TI TMS9927 and compatible CRT controller emulation

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

#ifndef MAME_VIDEO_TMS9927_H
#define MAME_VIDEO_TMS9927_H


#define MCFG_TMS9927_VSYN_CALLBACK(_write) \
	devcb = &tms9927_device::set_vsyn_wr_callback(*device, DEVCB_##_write);

#define MCFG_TMS9927_HSYN_CALLBACK(_write) \
	devcb = &tms9927_device::set_hsyn_wr_callback(*device, DEVCB_##_write);

#define MCFG_TMS9927_CHAR_WIDTH(_pixels) \
	tms9927_device::set_char_width(*device, _pixels);

#define MCFG_TMS9927_REGION(_tag) \
	tms9927_device::set_region_tag(*device, "^" _tag);

#define MCFG_TMS9927_OVERSCAN(_left, _right, _top, _bottom) \
	tms9927_device::set_overscan(*device, _left, _right, _top, _bottom);

class tms9927_device : public device_t, public device_video_interface
{
public:
	tms9927_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	template <class Object> static devcb_base &set_vsyn_wr_callback(device_t &device, Object &&cb) { return downcast<tms9927_device &>(device).m_write_vsyn.set_callback(std::forward<Object>(cb)); }
	template <class Object> static devcb_base &set_hsyn_wr_callback(device_t &device, Object &&cb) { return downcast<tms9927_device &>(device).m_write_hsyn.set_callback(std::forward<Object>(cb)); }

	static void set_char_width(device_t &device, int pixels) { downcast<tms9927_device &>(device).m_hpixels_per_column = pixels; }
	static void set_region_tag(device_t &device, const char *tag) { downcast<tms9927_device &>(device).m_selfload.set_tag(tag); }
	static void set_overscan(device_t &device, int left, int right, int top, int bottom) {
		tms9927_device &dev = downcast<tms9927_device &>(device);
		dev.m_overscan_left = left;
		dev.m_overscan_right = right;
		dev.m_overscan_top = top;
		dev.m_overscan_bottom = bottom;
	}

	DECLARE_WRITE8_MEMBER(write);
	DECLARE_READ8_MEMBER(read);

	DECLARE_READ_LINE_MEMBER(bl_r);

	bool screen_reset();
	int upscroll_offset();
	bool cursor_bounds(rectangle &bounds);

protected:
	tms9927_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_stop() override;
	virtual void device_reset() override;
	virtual void device_clock_changed() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

private:
	enum
	{
		TIMER_VSYNC,
		TIMER_HSYNC
	};

	void state_postload();
	void recompute_parameters(bool postload);
	void generic_access(address_space &space, offs_t offset);

	devcb_write_line m_write_vsyn;
	devcb_write_line m_write_hsyn;

	int m_hpixels_per_column;         /* number of pixels per video memory address */
	uint16_t  m_overscan_left;
	uint16_t  m_overscan_right;
	uint16_t  m_overscan_top;
	uint16_t  m_overscan_bottom;

	// internal state
	optional_region_ptr<uint8_t> m_selfload;

	/* live state */
	uint8_t   m_reg[9];
	uint8_t   m_start_datarow;
	bool      m_reset;
	bool      m_vsyn;
	bool      m_hsyn;

	/* derived state; no need to save */
	bool      m_valid_config;
	uint16_t  m_total_hpix, m_total_vpix;
	uint16_t  m_visible_hpix, m_visible_vpix;
	uint16_t  m_vsyn_start, m_vsyn_end;
	uint16_t  m_hsyn_start, m_hsyn_end;

	emu_timer *m_vsync_timer;
	emu_timer *m_hsync_timer;
};


class crt5027_device : public tms9927_device
{
public:
	crt5027_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};


class crt5037_device : public tms9927_device
{
public:
	crt5037_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};


class crt5057_device : public tms9927_device
{
public:
	crt5057_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};


DECLARE_DEVICE_TYPE(TMS9927, tms9927_device)
DECLARE_DEVICE_TYPE(CRT5027, crt5027_device)
DECLARE_DEVICE_TYPE(CRT5037, crt5037_device)
DECLARE_DEVICE_TYPE(CRT5057, crt5057_device)

#endif // MAME_VIDEO_TMS9927_H