1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Mullard SAA5050 Teletext Character Generator emulation
6 
7 **********************************************************************
8                             _____   _____
9                    Vss   1 |*    \_/     | 28  DE
10                    _SI   2 |             | 27  PO
11                  _DATA   3 |             | 26  LOSE
12                     D1   4 |   SAA5050   | 25  BLAN
13                     D2   5 |   SAA5051   | 24  R
14                     D3   6 |   SAA5052   | 23  G
15                     D4   7 |   SAA5053   | 22  B
16                     D5   8 |   SAA5054   | 21  Y
17                     D6   9 |   SAA5055   | 20  F1
18                     D7  10 |   SAA5056   | 19  TR6
19                   DLIM  11 |   SAA5057   | 18  Vdd
20                   _GLR  12 |             | 17  N/C
21                    DEW  13 |             | 16  _TLC
22                    CRS  14 |_____________| 15  _BCS
23 
24 **********************************************************************/
25 
26 #ifndef MAME_VIDEO_SAA5050_H
27 #define MAME_VIDEO_SAA5050_H
28 
29 #pragma once
30 
31 
32 //**************************************************************************
33 //  TYPE DEFINITIONS
34 //**************************************************************************
35 
36 // ======================> saa5050_device
37 
38 class saa5050_device :  public device_t
39 {
40 public:
41 	// construction/destruction
42 	saa5050_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
43 
set_screen_size(int cols,int rows,int size)44 	void set_screen_size(int cols, int rows, int size) { m_cols = cols; m_rows = rows; m_size = size; }
45 
d_cb()46 	auto d_cb() { return m_read_d.bind(); }
47 
48 	// optional information overrides
49 	virtual const tiny_rom_entry *device_rom_region() const override;
50 
51 	DECLARE_WRITE_LINE_MEMBER( crs_w );
52 	DECLARE_WRITE_LINE_MEMBER( dew_w );
53 	DECLARE_WRITE_LINE_MEMBER( lose_w );
54 	void write(uint8_t data);
55 	DECLARE_WRITE_LINE_MEMBER( f1_w );
56 	DECLARE_WRITE_LINE_MEMBER( tr6_w );
57 	int get_rgb();
58 
59 	// NOTE: the following are provided for convenience only, SAA5050 is not a display controller
60 	// this emulates the common setup where bit 7 of data inverts the display, and the
61 	// bottom half of a double height row gets the same character data as the top half
62 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
63 
64 protected:
65 	saa5050_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
66 
67 	// device-level overrides
68 	virtual void device_start() override;
69 	virtual void device_reset() override;
70 
71 private:
72 	enum
73 	{
74 		NUL = 0,
75 		ALPHA_RED,
76 		ALPHA_GREEN,
77 		ALPHA_YELLOW,
78 		ALPHA_BLUE,
79 		ALPHA_MAGENTA,
80 		ALPHA_CYAN,
81 		ALPHA_WHITE,
82 		FLASH,
83 		STEADY,
84 		END_BOX,
85 		START_BOX,
86 		NORMAL_HEIGHT,
87 		DOUBLE_HEIGHT,
88 		S0,
89 		S1,
90 		DLE,
91 		GRAPHICS_RED,
92 		GRAPHICS_GREEN,
93 		GRAPHICS_YELLOW,
94 		GRAPHICS_BLUE,
95 		GRAPHICS_MAGENTA,
96 		GRAPHICS_CYAN,
97 		GRAPHICS_WHITE,
98 		CONCEAL_DISPLAY,
99 		CONTIGUOUS_GFX,
100 		SEPARATED_GFX,
101 		ESC,
102 		BLACK_BACKGROUND,
103 		NEW_BACKGROUND,
104 		HOLD_GRAPHICS,
105 		RELEASE_GRAPHICS
106 	};
107 
108 	void process_control_character(uint8_t data);
109 	void set_next_chartype();
110 	uint16_t get_gfx_data(uint8_t data, offs_t row, bool separated);
111 	uint16_t get_rom_data(uint8_t data, offs_t row);
112 	uint16_t character_rounding(uint16_t a, uint16_t b);
113 	void get_character_data(uint8_t data);
114 
115 	required_region_ptr<uint8_t> m_char_rom;
116 
117 	devcb_read8    m_read_d;
118 
119 	uint8_t m_code;
120 	uint8_t m_held_char;
121 	uint8_t m_next_chartype;
122 	uint8_t m_curr_chartype;
123 	uint8_t m_held_chartype;
124 	uint16_t m_char_data;
125 	int m_bit;
126 	rgb_t m_color;
127 	int m_crs;
128 	int m_ra;
129 	int m_bg;
130 	int m_fg;
131 	int m_prev_col;
132 	bool m_graphics;
133 	bool m_separated;
134 	bool m_flash;
135 	bool m_boxed;
136 	bool m_double_height;
137 	bool m_double_height_old;
138 	bool m_double_height_bottom_row;
139 	bool m_double_height_prev_row;
140 	bool m_hold_char;
141 	bool m_hold_clear;
142 	bool m_hold_off;
143 	int m_frame_count;
144 
145 	int m_cols;
146 	int m_rows;
147 	int m_size;
148 };
149 
150 
151 // ======================> saa5051_device
152 
153 class saa5051_device :  public saa5050_device
154 {
155 public:
156 	// construction/destruction
157 	saa5051_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
158 
159 	// optional information overrides
160 	virtual const tiny_rom_entry *device_rom_region() const override;
161 };
162 
163 
164 // ======================> saa5052_device
165 
166 class saa5052_device :  public saa5050_device
167 {
168 public:
169 	// construction/destruction
170 	saa5052_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
171 
172 	// optional information overrides
173 	virtual const tiny_rom_entry *device_rom_region() const override;
174 };
175 
176 
177 // ======================> saa5053_device
178 
179 class saa5053_device :  public saa5050_device
180 {
181 public:
182 	// construction/destruction
183 	saa5053_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
184 
185 	// optional information overrides
186 	virtual const tiny_rom_entry *device_rom_region() const override;
187 };
188 
189 
190 // ======================> saa5054_device
191 
192 class saa5054_device :  public saa5050_device
193 {
194 public:
195 	// construction/destruction
196 	saa5054_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
197 
198 	// optional information overrides
199 	virtual const tiny_rom_entry *device_rom_region() const override;
200 };
201 
202 
203 // ======================> saa5055_device
204 
205 class saa5055_device :  public saa5050_device
206 {
207 public:
208 	// construction/destruction
209 	saa5055_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
210 
211 	// optional information overrides
212 	virtual const tiny_rom_entry *device_rom_region() const override;
213 };
214 
215 
216 // ======================> saa5056_device
217 
218 class saa5056_device :  public saa5050_device
219 {
220 public:
221 	// construction/destruction
222 	saa5056_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
223 
224 	// optional information overrides
225 	virtual const tiny_rom_entry *device_rom_region() const override;
226 };
227 
228 
229 // ======================> saa5057_device
230 
231 class saa5057_device :  public saa5050_device
232 {
233 public:
234 	// construction/destruction
235 	saa5057_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
236 
237 	// optional information overrides
238 	virtual const tiny_rom_entry *device_rom_region() const override;
239 };
240 
241 
242 // device type definition
243 DECLARE_DEVICE_TYPE(SAA5050, saa5050_device) // English
244 DECLARE_DEVICE_TYPE(SAA5051, saa5051_device) // German
245 DECLARE_DEVICE_TYPE(SAA5052, saa5052_device) // Swedish/Finnish
246 DECLARE_DEVICE_TYPE(SAA5053, saa5053_device) // Italian
247 DECLARE_DEVICE_TYPE(SAA5054, saa5054_device) // Belgian
248 DECLARE_DEVICE_TYPE(SAA5055, saa5055_device) // US ASCII
249 DECLARE_DEVICE_TYPE(SAA5056, saa5056_device) // Hebrew
250 DECLARE_DEVICE_TYPE(SAA5057, saa5057_device) // Cyrillic
251 
252 #endif // MAME_VIDEO_SAA5050_H
253