summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/i8244.h
blob: 245907fd6042d401aaf158cc96f0f34bbe32145b (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
// license:BSD-3-Clause
// copyright-holders:Peter Trauner, Wilbert Pol, hap
/***************************************************************************

    Intel 8244 (NTSC)/8245 (PAL) Graphics and sound chip

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

#ifndef MAME_VIDEO_I8244_H
#define MAME_VIDEO_I8244_H

#pragma once

#include "emupal.h"


// pinout reference

/*
            ___   ___
    CLK  1 |*  \_/   | 28 Vcc
  _INTR  2 |         | 27 SND
    STB  3 |         | 26 ALE
     BG  4 |         | 25 D0
    CSY  5 |         | 24 D1
    M/S  6 |         | 23 D2
    HBL  7 |  P8244  | 22 D3
    VBL  8 |  P8245  | 21 D4
     CX  9 |         | 20 B
      L 10 |         | 19 G
    _CS 11 |         | 18 R
    _WR 12 |         | 17 D5
    _RD 13 |         | 16 D6
    Vss 14 |_________| 15 D7

*/

DECLARE_DEVICE_TYPE(I8244, i8244_device)
DECLARE_DEVICE_TYPE(I8245, i8245_device)


class i8244_device :  public device_t
					, public device_sound_interface
					, public device_video_interface
{
public:
	// construction/destruction
	i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);

	// configuration helpers
	auto irq_cb() { return m_irq_func.bind(); }
	i8244_device &set_screen_size(int width, int height, int cropx = 0, int cropy = 0);

	u8 read(offs_t offset);
	void write(offs_t offset, u8 data);
	void write_cx(int x, bool cx); // CX pin on current scanline

	int vblank();
	int hblank();
	void i8244_palette(palette_device &palette) const;

	u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);

protected:
	union vdc_t {
		u8 reg[0x100];
		struct {
			// 0x00
			struct {
				u8 y,x,color,unused;
			} sprites[4];

			// 0x10
			struct {
				u8 y,x,ptr,color;
			} foreground[12];

			// 0x40
			struct {
				struct {
					u8 y,x,ptr,color;
				} single[4];
			} quad[4];

			// 0x80
			u8 shape[4][8];

			// 0xa0
			u8 control;
			u8 status;
			u8 collision;
			u8 color;
			u8 y;
			u8 x;
			u8 unused;
			u8 shift1;
			u8 shift2;
			u8 shift3;
			u8 sound;
			u8 unused2[5+0x10];

			// 0xc0
			u8 hgrid[2][0x10];
			u8 vgrid[0x10];
			u8 unused3[0x10];
		} s;
	};

	i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);

	// device-level overrides
	virtual void device_config_complete() override;
	virtual void device_start() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
	virtual const tiny_rom_entry *device_rom_region() const override;

	// device_sound_interface overrides
	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;

	virtual void set_default_params();
	inline bool is_ntsc() { return m_vtotal == 263; }

	int get_y_beam();
	int get_x_beam();
	offs_t fix_register_mirrors(offs_t offset);

	void draw_grid(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void draw_major(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void draw_minor(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void char_pixel(u8 index, int x, int y, u8 pixel, u16 color, bitmap_ind16 &bitmap, const rectangle &cliprect);

	/* timers */
	static constexpr device_timer_id TIMER_VBLANK_START = 0;
	static constexpr device_timer_id TIMER_HBLANK_START = 1;

	// callbacks
	devcb_write_line m_irq_func;

	required_region_ptr<u8> m_charset;

	emu_timer *m_hblank_timer;
	emu_timer *m_vblank_timer;
	sound_stream *m_stream;

	void sound_update();

	int m_htotal;
	int m_vtotal;
	int m_width;
	int m_height;
	int m_cropx;
	int m_cropy;

	int m_vblank_start;
	int m_vblank_end;
	int m_hblank_start;
	int m_hblank_end;
	int m_bgate_start;

	vdc_t m_vdc;
	u8 m_collision_map[0x200];
	u8 m_priority_map[0x200];

	u8 m_x_beam_pos = 0;
	u8 m_y_beam_pos = 0;
	u8 m_control_status = 0;
	u8 m_collision_status = 0;

	bool m_sh_written = false;
	bool m_sh_pending = false;
	u8 m_sh_prescaler = 0;
	u8 m_sh_count = 0;
	int m_sh_output = 0;
	u8 m_sh_duty = 0;
};


class i8245_device : public i8244_device
{
public:
	// construction/destruction
	i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);

	static auto parent_rom_device_type() { return &I8244; }

protected:
	virtual void set_default_params() override;
};


#endif // MAME_VIDEO_I8244_H