1 // license:BSD-3-Clause
2 // copyright-holders:Barry Rodewald
3 /*
4  *
5  *  FM-7 header file
6  *
7  */
8 #ifndef MAME_INCLUDES_FM7_H
9 #define MAME_INCLUDES_FM7_H
10 
11 #pragma once
12 
13 
14 #include "machine/buffer.h"
15 #include "bus/centronics/ctronics.h"
16 #include "imagedev/cassette.h"
17 #include "imagedev/floppy.h"
18 #include "sound/beep.h"
19 #include "sound/2203intf.h"
20 #include "machine/wd_fdc.h"
21 #include "machine/bankdev.h"
22 #include "emupal.h"
23 
24 
25 // Interrupt flags
26 #define IRQ_FLAG_KEY      0x01
27 #define IRQ_FLAG_PRINTER  0x02
28 #define IRQ_FLAG_TIMER    0x04
29 #define IRQ_FLAG_OTHER    0x08
30 // the following are not read in port 0xfd03
31 #define IRQ_FLAG_MFD      0x10
32 #define IRQ_FLAG_TXRDY    0x20
33 #define IRQ_FLAG_RXRDY    0x40
34 #define IRQ_FLAG_SYNDET   0x80
35 
36 // system types
37 #define SYS_FM7        1
38 #define SYS_FM77AV     2
39 #define SYS_FM77AV40EX 3
40 #define SYS_FM11       4
41 #define SYS_FM16       5
42 
43 // keyboard scancode formats
44 #define KEY_MODE_FM7   0 // FM-7 ASCII type code
45 #define KEY_MODE_FM16B 1 // FM-16B (FM-77AV and later only)
46 #define KEY_MODE_SCAN  2 // Scancode Make/Break (PC-like)
47 
48 struct fm7_encoder_t
49 {
50 	uint8_t buffer[12];
51 	uint8_t tx_count;
52 	uint8_t rx_count;
53 	uint8_t command_length;
54 	uint8_t answer_length;
55 	uint8_t latch;  // 0=ready to receive
56 	uint8_t ack;
57 	uint8_t position;
58 };
59 
60 struct fm7_mmr_t
61 {
62 	uint8_t bank_addr[8][16];
63 	uint8_t segment;
64 	uint8_t window_offset;
65 	uint8_t enabled;
66 	uint8_t mode;
67 };
68 
69 struct fm7_video_t
70 {
71 	uint8_t sub_busy;
72 	uint8_t sub_halt;
73 	uint8_t sub_reset;  // high if reset caused by subrom change
74 	uint8_t attn_irq;
75 	uint8_t vram_access;  // VRAM access flag
76 	uint8_t crt_enable;
77 	uint16_t vram_offset;
78 	uint16_t vram_offset2;
79 	uint8_t fm7_pal[8];
80 	uint16_t fm77av_pal_selected;
81 	uint8_t subrom;  // currently active sub CPU ROM (AV only)
82 	uint8_t cgrom;  // currently active CGROM (AV only)
83 	uint8_t modestatus;
84 	uint8_t multi_page;
85 	uint8_t fine_offset;
86 	uint8_t nmi_mask;
87 	uint8_t active_video_page;
88 	uint8_t display_video_page;
89 	uint8_t vsync_flag;
90 };
91 
92 struct fm7_alu_t
93 {
94 	uint8_t command;
95 	uint8_t lcolour;
96 	uint8_t mask;
97 	uint8_t compare_data;
98 	uint8_t compare[8];
99 	uint8_t bank_disable;
100 	uint8_t tilepaint_b;
101 	uint8_t tilepaint_r;
102 	uint8_t tilepaint_g;
103 	uint16_t addr_offset;
104 	uint16_t line_style;
105 	uint16_t x0;
106 	uint16_t x1;
107 	uint16_t y0;
108 	uint16_t y1;
109 	uint8_t busy;
110 };
111 
112 
113 class fm7_state : public driver_device
114 {
115 public:
fm7_state(const machine_config & mconfig,device_type type,const char * tag)116 	fm7_state(const machine_config &mconfig, device_type type, const char *tag) :
117 		driver_device(mconfig, type, tag),
118 		m_shared_ram(*this, "shared_ram"),
119 		m_boot_ram(*this, "boot_ram"),
120 		m_maincpu(*this, "maincpu"),
121 		m_sub(*this, "sub"),
122 		m_x86(*this, "x86"),
123 		m_cassette(*this, "cassette"),
124 		m_beeper(*this, "beeper"),
125 		m_ym(*this, "ym"),
126 		m_psg(*this, "psg"),
127 		m_screen(*this, "screen"),
128 		m_centronics(*this, "centronics"),
129 		m_cent_data_out(*this, "cent_data_out"),
130 		m_fdc(*this, "fdc"),
131 		m_floppy0(*this, "fdc:0"),
132 		m_floppy1(*this, "fdc:1"),
133 		m_floppy(nullptr),
134 		m_ram_ptr(*this, "maincpu"),
135 		m_rom_ptr(*this, "init"),
136 		m_basic_ptr(*this, "fbasic"),
137 		m_kanji(*this, "kanji1"),
138 		m_kb_ports(*this, "key%u", 1),
139 		m_keymod(*this, "key_modifiers"),
140 		m_joy1(*this, "joy1"),
141 		m_dsw(*this, "DSW"),
142 		m_palette(*this, "palette"),
143 		m_av_palette(*this, "av_palette"),
144 		m_avbank(*this, "av_bank%u", 1)
145 	{
146 	}
147 
148 	void fm16beta(machine_config &config);
149 	void fm8(machine_config &config);
150 	void fm7(machine_config &config);
151 	void fm77av(machine_config &config);
152 	void fm11(machine_config &config);
153 
154 	void init_fm7();
155 
156 private:
157 	enum
158 	{
159 		TIMER_FM7_BEEPER_OFF,
160 		TIMER_FM77AV_ENCODER_ACK,
161 		TIMER_FM7_IRQ,
162 		TIMER_FM7_SUBTIMER_IRQ,
163 		TIMER_FM7_KEYBOARD_POLL,
164 		TIMER_FM77AV_ALU_TASK_END,
165 		TIMER_FM77AV_VSYNC
166 	};
167 
168 	virtual void machine_reset() override;
169 	virtual void video_start() override;
170 
171 	DECLARE_MACHINE_START(fm7);
172 	DECLARE_MACHINE_START(fm77av);
173 	DECLARE_MACHINE_START(fm11);
174 	DECLARE_MACHINE_START(fm16);
175 
176 	DECLARE_WRITE_LINE_MEMBER(fm7_fdc_intrq_w);
177 	DECLARE_WRITE_LINE_MEMBER(fm7_fdc_drq_w);
178 	DECLARE_WRITE_LINE_MEMBER(fm77av_fmirq);
179 
180 	uint8_t fm7_subintf_r();
181 	void fm7_subintf_w(uint8_t data);
182 	uint8_t fm7_sub_busyflag_r();
183 	void fm7_sub_busyflag_w(uint8_t data);
184 	uint8_t fm7_cancel_ack();
185 	uint8_t fm7_attn_irq_r();
186 	uint8_t fm7_vram_access_r();
187 	void fm7_vram_access_w(uint8_t data);
188 	uint8_t fm7_vram_r(offs_t offset);
189 	void fm7_vram_w(offs_t offset, uint8_t data);
190 	void fm7_vram_banked_w(offs_t offset, uint8_t data);
191 	uint8_t fm7_vram0_r(offs_t offset);
192 	uint8_t fm7_vram1_r(offs_t offset);
193 	uint8_t fm7_vram2_r(offs_t offset);
194 	uint8_t fm7_vram3_r(offs_t offset);
195 	uint8_t fm7_vram4_r(offs_t offset);
196 	uint8_t fm7_vram5_r(offs_t offset);
197 	uint8_t fm7_vram6_r(offs_t offset);
198 	uint8_t fm7_vram7_r(offs_t offset);
199 	uint8_t fm7_vram8_r(offs_t offset);
200 	uint8_t fm7_vram9_r(offs_t offset);
201 	uint8_t fm7_vramA_r(offs_t offset);
202 	uint8_t fm7_vramB_r(offs_t offset);
203 	void fm7_vram0_w(offs_t offset, uint8_t data);
204 	void fm7_vram1_w(offs_t offset, uint8_t data);
205 	void fm7_vram2_w(offs_t offset, uint8_t data);
206 	void fm7_vram3_w(offs_t offset, uint8_t data);
207 	void fm7_vram4_w(offs_t offset, uint8_t data);
208 	void fm7_vram5_w(offs_t offset, uint8_t data);
209 	void fm7_vram6_w(offs_t offset, uint8_t data);
210 	void fm7_vram7_w(offs_t offset, uint8_t data);
211 	void fm7_vram8_w(offs_t offset, uint8_t data);
212 	void fm7_vram9_w(offs_t offset, uint8_t data);
213 	void fm7_vramA_w(offs_t offset, uint8_t data);
214 	void fm7_vramB_w(offs_t offset, uint8_t data);
215 	uint8_t fm7_crt_r();
216 	void fm7_crt_w(uint8_t data);
217 	void fm7_vram_offset_w(offs_t offset, uint8_t data);
218 	void fm7_multipage_w(uint8_t data);
219 	uint8_t fm7_palette_r(offs_t offset);
220 	void fm7_palette_w(offs_t offset, uint8_t data);
221 	void fm77av_analog_palette_w(offs_t offset, uint8_t data);
222 	uint8_t fm77av_video_flags_r();
223 	void fm77av_video_flags_w(uint8_t data);
224 	uint8_t fm77av_sub_modestatus_r();
225 	void fm77av_sub_modestatus_w(uint8_t data);
226 	void fm77av_sub_bank_w(uint8_t data);
227 	uint8_t fm77av_alu_r(offs_t offset);
228 	void fm77av_alu_w(offs_t offset, uint8_t data);
229 	uint8_t fm7_sub_ram_ports_banked_r(offs_t offset);
230 	void fm7_sub_ram_ports_banked_w(offs_t offset, uint8_t data);
231 	uint8_t fm7_console_ram_banked_r(offs_t offset);
232 	void fm7_console_ram_banked_w(offs_t offset, uint8_t data);
233 	void fm7_irq_mask_w(uint8_t data);
234 	uint8_t fm7_irq_cause_r();
235 	void fm7_beeper_w(uint8_t data);
236 	uint8_t fm7_sub_beeper_r();
237 	uint8_t vector_r(offs_t offset);
238 	void vector_w(offs_t offset, uint8_t data);
239 	uint8_t fm7_fd04_r();
240 	uint8_t fm7_rom_en_r(address_space &space);
241 	void fm7_rom_en_w(address_space &space, uint8_t data);
242 	void fm7_init_en_w(address_space &space, uint8_t data);
243 	uint8_t fm7_fdc_r(offs_t offset);
244 	void fm7_fdc_w(offs_t offset, uint8_t data);
245 	uint8_t fm7_keyboard_r(offs_t offset);
246 	uint8_t fm7_sub_keyboard_r(offs_t offset);
247 	uint8_t fm77av_key_encoder_r(offs_t offset);
248 	void fm77av_key_encoder_w(offs_t offset, uint8_t data);
249 	uint8_t fm7_cassette_printer_r();
250 	void fm7_cassette_printer_w(offs_t offset, uint8_t data);
251 	uint8_t fm77av_boot_mode_r();
252 	uint8_t fm7_psg_select_r();
253 	void fm7_psg_select_w(uint8_t data);
254 	void fm77av_ym_select_w(uint8_t data);
255 	uint8_t fm7_psg_data_r();
256 	void fm7_psg_data_w(uint8_t data);
257 	void fm77av_bootram_w(offs_t offset, uint8_t data);
258 	uint8_t fm7_main_shared_r(offs_t offset);
259 	void fm7_main_shared_w(offs_t offset, uint8_t data);
260 	uint8_t fm7_fmirq_r();
261 	uint8_t fm7_unknown_r();
262 	uint8_t fm7_mmr_r(offs_t offset);
263 	void fm7_mmr_w(address_space &space, offs_t offset, uint8_t data);
264 	uint8_t fm7_kanji_r(offs_t offset);
265 	void fm7_kanji_w(offs_t offset, uint8_t data);
266 
267 	IRQ_CALLBACK_MEMBER(fm7_irq_ack);
268 	IRQ_CALLBACK_MEMBER(fm7_sub_irq_ack);
269 
270 	DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
271 	DECLARE_WRITE_LINE_MEMBER(write_centronics_fault);
272 	DECLARE_WRITE_LINE_MEMBER(write_centronics_ack);
273 	DECLARE_WRITE_LINE_MEMBER(write_centronics_perror);
274 
275 	uint32_t screen_update_fm7(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
276 
277 	void fm11_mem(address_map &map);
278 	void fm11_sub_mem(address_map &map);
279 	void fm11_x86_io(address_map &map);
280 	void fm11_x86_mem(address_map &map);
281 	void fm16_io(address_map &map);
282 	void fm16_mem(address_map &map);
283 	void fm16_sub_mem(address_map &map);
284 	void fm77av_mem(address_map &map);
285 	void fm77av_sub_mem(address_map &map);
286 	void fm7_banked_mem(address_map &map);
287 	void fm7_mem(address_map &map);
288 	void fm7_sub_mem(address_map &map);
289 	void fm8_mem(address_map &map);
290 
291 	optional_shared_ptr<uint8_t> m_shared_ram;
292 	optional_shared_ptr<uint8_t> m_boot_ram;
293 
294 	uint8_t           m_irq_flags;
295 	uint8_t           m_irq_mask;
296 	emu_timer*      m_timer;
297 	emu_timer*      m_subtimer;
298 	emu_timer*      m_keyboard_timer;
299 	uint8_t           m_basic_rom_en;
300 	uint8_t           m_init_rom_en;
301 
302 	unsigned int    m_key_delay;
303 	unsigned int    m_key_repeat;
304 	uint16_t          m_current_scancode;
305 	uint32_t          m_key_data[4];
306 	uint32_t          m_mod_data;
307 	uint8_t           m_key_scan_mode;
308 	uint8_t           m_break_flag;
309 
310 	uint8_t           m_psg_regsel;
311 	uint8_t           m_psg_data;
312 
313 	uint8_t           m_fdc_side;
314 	uint8_t           m_fdc_drive;
315 	uint8_t           m_fdc_irq_flag;
316 	uint8_t           m_fdc_drq_flag;
317 
318 	uint8_t           m_fm77av_ym_irq;
319 	uint8_t           m_speaker_active;
320 
321 	uint16_t          m_kanji_address;
322 	fm7_encoder_t   m_encoder;
323 	fm7_mmr_t       m_mmr;
324 	uint8_t           m_cp_prev;
325 
326 	std::unique_ptr<uint8_t[]>    m_video_ram;
327 	emu_timer*                  m_fm77av_vsync_timer;
328 	uint8_t m_type;
329 	fm7_video_t     m_video;
330 	fm7_alu_t       m_alu;
331 	int             m_sb_prev;
332 
333 	void fm77av_encoder_setup_command();
334 	void fm77av_encoder_handle_command();
335 	TIMER_CALLBACK_MEMBER(fm7_beeper_off);
336 	TIMER_CALLBACK_MEMBER(fm77av_encoder_ack);
337 	TIMER_CALLBACK_MEMBER(fm7_timer_irq);
338 	TIMER_CALLBACK_MEMBER(fm7_subtimer_irq);
339 	TIMER_CALLBACK_MEMBER(fm7_keyboard_poll);
340 	TIMER_CALLBACK_MEMBER(fm77av_alu_task_end);
341 	TIMER_CALLBACK_MEMBER(fm77av_vsync);
342 
343 	required_device<cpu_device> m_maincpu;
344 	required_device<cpu_device> m_sub;
345 	optional_device<cpu_device> m_x86;
346 	required_device<cassette_image_device> m_cassette;
347 	required_device<beep_device> m_beeper;
348 	optional_device<ym2203_device> m_ym;
349 	optional_device<ay8910_device> m_psg;
350 	required_device<screen_device> m_screen;
351 
352 	required_device<centronics_device> m_centronics;
353 	required_device<output_latch_device> m_cent_data_out;
354 
355 	required_device<mb8877_device> m_fdc;
356 	required_device<floppy_connector> m_floppy0;
357 	required_device<floppy_connector> m_floppy1;
358 	floppy_image_device *m_floppy;
359 
360 	optional_region_ptr<uint8_t> m_ram_ptr;
361 	optional_region_ptr<uint8_t> m_rom_ptr;
362 	optional_region_ptr<uint8_t> m_basic_ptr;
363 
364 	void fm7_alu_mask_write(uint32_t offset, int bank, uint8_t dat);
365 	void fm7_alu_function_compare(uint32_t offset);
366 	void fm7_alu_function_pset(uint32_t offset);
367 	void fm7_alu_function_or(uint32_t offset);
368 	void fm7_alu_function_and(uint32_t offset);
369 	void fm7_alu_function_xor(uint32_t offset);
370 	void fm7_alu_function_not(uint32_t offset);
371 	void fm7_alu_function_invalid(uint32_t offset);
372 	void fm7_alu_function_tilepaint(uint32_t offset);
373 	void fm7_alu_function(uint32_t offset);
374 	uint32_t fm7_line_set_pixel(int x, int y);
375 	void fm77av_line_draw();
376 	void main_irq_set_flag(uint8_t flag);
377 	void main_irq_clear_flag(uint8_t flag);
378 	void fm7_update_psg();
379 	void fm7_update_bank(address_space & space, int bank, uint8_t physical);
380 	void fm7_mmr_refresh(address_space& space);
381 	void key_press(uint16_t scancode);
382 	void fm7_keyboard_poll_scan();
383 
384 	int m_centronics_busy;
385 	int m_centronics_fault;
386 	int m_centronics_ack;
387 	int m_centronics_perror;
388 
389 	optional_memory_region m_kanji;
390 	required_ioport_array<3> m_kb_ports;
391 	required_ioport m_keymod;
392 	required_ioport m_joy1;
393 	required_ioport m_dsw;
394 	required_device<palette_device> m_palette;
395 	optional_device<palette_device> m_av_palette;
396 
397 	optional_device_array<address_map_bank_device, 16> m_avbank;
398 
399 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
400 };
401 
402 #endif // MAME_INCLUDES_FM7_H
403