1 // license:BSD-3-Clause
2 // copyright-holders:Barry Rodewald
3 /***********************************************************************************************
4 
5     Fujitsu Micro 7 (FM-7)
6 
7     12/05/2009 Skeleton driver.
8 
9     Computers in this series:
10 
11                  | Release |    Main CPU    |  Sub CPU  |              RAM              |
12     =====================================================================================
13     FM-8         | 1981-05 | M68A09 @ 1MHz  |  M6809    |    64K (main) + 48K (VRAM)    |
14     FM-7         | 1982-11 | M68B09 @ 2MHz  |  M68B09   |    64K (main) + 48K (VRAM)    |
15     FM-NEW7      | 1984-05 | M68B09 @ 2MHz  |  M68B09   |    64K (main) + 48K (VRAM)    |
16     FM-77        | 1984-05 | M68B09 @ 2MHz  |  M68B09E  |  64/256K (main) + 48K (VRAM)  |
17     FM-77AV      | 1985-10 | M68B09E @ 2MHz |  M68B09E  | 128/192K (main) + 96K (VRAM)  |
18     FM-77AV20    | 1986-10 | M68B09E @ 2MHz |  M68B09E  | 128/192K (main) + 96K (VRAM)  |
19     FM-77AV40    | 1986-10 | M68B09E @ 2MHz |  M68B09E  | 192/448K (main) + 144K (VRAM) |
20     FM-77AV20EX  | 1987-11 | M68B09E @ 2MHz |  M68B09E  | 128/192K (main) + 96K (VRAM)  |
21     FM-77AV40EX  | 1987-11 | M68B09E @ 2MHz |  M68B09E  | 192/448K (main) + 144K (VRAM) |
22     FM-77AV40SX  | 1988-11 | M68B09E @ 2MHz |  M68B09E  | 192/448K (main) + 144K (VRAM) |
23 
24     Note: FM-77AV dumps probably come from a FM-77AV40SX. Shall we confirm that both computers
25     used the same BIOS components?
26 
27     memory map info from http://www.nausicaa.net/~lgreenf/fm7page.htm
28     see also http://retropc.net/ryu/xm7/xm7.shtml
29 
30 
31     Known issues:
32      - Beeper is not implemented
33      - Keyboard repeat is not implemented
34      - Optional Kanji ROM use is not implemented
35      - Other optional hardware is not implemented (RS232, Z80 card...)
36      - FM-77AV20 and later aren't working (extra features not yet implemented)
37 
38 ************************************************************************************************/
39 
40 #include "emu.h"
41 #include "includes/fm7.h"
42 
43 #include "cpu/m6809/m6809.h"
44 #include "cpu/i86/i86.h"
45 #include "cpu/z80/z80.h"
46 
47 #include "sound/ay8910.h"
48 #include "sound/2203intf.h"
49 #include "sound/beep.h"
50 
51 #include "bus/centronics/dsjoy.h"
52 
53 #include "imagedev/cassette.h"
54 
55 #include "formats/fm7_cas.h"
56 
57 #include "screen.h"
58 #include "softlist.h"
59 #include "speaker.h"
60 
61 
62 /* key scancode conversion table
63  * The FM-7 expects different scancodes when shift,ctrl or graph is held, or
64  * when kana is active.
65  */
66 	// TODO: fill in shift,ctrl,graph and kana code
67 static const uint16_t fm7_key_list[0x60][7] =
68 { // norm  shift ctrl  graph kana  sh.kana scan
69 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
70 	{0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x01},  // ESC
71 	{0x31, 0x21, 0xf9, 0xf9, 0xc7, 0x00, 0x02},  // 1
72 	{0x32, 0x22, 0xfa, 0xfa, 0xcc, 0x00, 0x03},  // 2
73 	{0x33, 0x23, 0xfb, 0xfb, 0xb1, 0xa7, 0x04},
74 	{0x34, 0x24, 0xfc, 0xfc, 0xb3, 0xa9, 0x05},
75 	{0x35, 0x25, 0xf2, 0xf2, 0xb4, 0xaa, 0x06},
76 	{0x36, 0x26, 0xf3, 0xf3, 0xb5, 0xab, 0x07},
77 	{0x37, 0x27, 0xf4, 0xf4, 0xd4, 0xac, 0x08},
78 	{0x38, 0x28, 0xf5, 0xf5, 0xd5, 0xad, 0x09},
79 	{0x39, 0x29, 0xf6, 0xf6, 0xd6, 0xae, 0x0a},  // 9
80 	{0x30, 0x00, 0xf7, 0xf7, 0xdc, 0xa6, 0x0b},  // 0
81 	{0x2d, 0x3d, 0x1e, 0x8c, 0xce, 0x00, 0x0c},  // -
82 	{0x5e, 0x7e, 0x1c, 0x8b, 0xcd, 0x00, 0x0d},  // ^
83 	{0x5c, 0x7c, 0xf1, 0xf1, 0xb0, 0x00, 0x0e},  // Yen
84 	{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f},  // Backspace
85 	{0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x10},  // Tab
86 	{0x71, 0x51, 0x11, 0xfd, 0xc0, 0x00, 0x11},  // Q
87 	{0x77, 0x57, 0x17, 0xf8, 0xc3, 0x00, 0x12},  // W
88 	{0x65, 0x45, 0x05, 0xe4, 0xb2, 0xa8, 0x13},  // E
89 	{0x72, 0x52, 0x12, 0xe5, 0xbd, 0x00, 0x14},
90 	{0x74, 0x54, 0x14, 0x9c, 0xb6, 0x00, 0x15},
91 	{0x79, 0x59, 0x19, 0x9d, 0xdd, 0x00, 0x16},
92 	{0x75, 0x55, 0x15, 0xf0, 0xc5, 0x00, 0x17},
93 	{0x69, 0x49, 0x09, 0xe8, 0xc6, 0x00, 0x18},
94 	{0x6f, 0x4f, 0x0f, 0xe9, 0xd7, 0x00, 0x19},
95 	{0x70, 0x50, 0x10, 0x8d, 0xbe, 0x00, 0x1a},  // P
96 	{0x40, 0x60, 0x00, 0x8a, 0xde, 0x00, 0x1b},  // @
97 	{0x5b, 0x7b, 0x1b, 0xed, 0xdf, 0xa2, 0x1c},  // [
98 	{0x0d, 0x0d, 0x00, 0x0d, 0x0d, 0x0d, 0x1d},  // Return
99 	{0x61, 0x41, 0x01, 0x95, 0xc1, 0x00, 0x1e},  // A
100 	{0x73, 0x53, 0x13, 0x96, 0xc4, 0x00, 0x1f},  // S
101 
102 	{0x64, 0x44, 0x04, 0xe6, 0xbc, 0x00, 0x20},  // D
103 	{0x66, 0x46, 0x06, 0xe7, 0xca, 0x00, 0x21},
104 	{0x67, 0x47, 0x07, 0x9e, 0xb7, 0x00, 0x22},
105 	{0x68, 0x48, 0x08, 0x9f, 0xb8, 0x00, 0x23},
106 	{0x6a, 0x4a, 0x0a, 0xea, 0xcf, 0x00, 0x24},
107 	{0x6b, 0x4b, 0x0b, 0xeb, 0xc9, 0x00, 0x25},
108 	{0x6c, 0x4c, 0x0c, 0x8e, 0xd8, 0x00, 0x26},  // L
109 	{0x3b, 0x2b, 0x00, 0x99, 0xda, 0x00, 0x27},  // ;
110 	{0x3a, 0x2a, 0x00, 0x94, 0xb9, 0x00, 0x28},  // :
111 	{0x5d, 0x7d, 0x1d, 0xec, 0xd1, 0xa3, 0x29},  // ]
112 	{0x7a, 0x5a, 0x1a, 0x80, 0xc2, 0xaf, 0x2a},  // Z
113 	{0x78, 0x58, 0x18, 0x81, 0xbb, 0x00, 0x2b},  // X
114 	{0x63, 0x43, 0x03, 0x82, 0xbf, 0x00, 0x2c},  // C
115 	{0x76, 0x56, 0x16, 0x83, 0xcb, 0x00, 0x2d},
116 	{0x62, 0x42, 0x02, 0x84, 0xba, 0x00, 0x2e},
117 	{0x6e, 0x4e, 0x0e, 0x85, 0xd0, 0x00, 0x2f},
118 	{0x6d, 0x4d, 0x0d, 0x86, 0xd3, 0x00, 0x30},  // M
119 	{0x2c, 0x3c, 0x00, 0x87, 0xc8, 0xa4, 0x31},  // <
120 	{0x2e, 0x3e, 0x00, 0x88, 0xd9, 0xa1, 0x32},  // >
121 	{0x2f, 0x3f, 0x00, 0x97, 0xd2, 0xa5, 0x33},  // /
122 	{0x22, 0x5f, 0x1f, 0xe0, 0xdb, 0x00, 0x34},  // "
123 	{0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35},  // Space
124 	{0x2a, 0x2a, 0x00, 0x98, 0x2a, 0x2a, 0x36},  // Tenkey
125 	{0x2f, 0x2f, 0x00, 0x91, 0x2f, 0x2f, 0x37},
126 	{0x2b, 0x2b, 0x00, 0x99, 0x2b, 0x2b, 0x38},
127 	{0x2d, 0x2d, 0x00, 0xee, 0x2d, 0x2d, 0x39},
128 	{0x37, 0x37, 0x00, 0xe1, 0x37, 0x37, 0x3a},
129 	{0x38, 0x38, 0x00, 0xe2, 0x38, 0x38, 0x3b},
130 	{0x39, 0x39, 0x00, 0xe3, 0x39, 0x39, 0x3c},
131 	{0x3d, 0x3d, 0x00, 0xef, 0x3d, 0x3d, 0x3d},  // Tenkey =
132 	{0x34, 0x34, 0x00, 0x93, 0x34, 0x34, 0x3e},
133 	{0x35, 0x35, 0x00, 0x8f, 0x35, 0x35, 0x3f},
134 
135 	{0x36, 0x36, 0x00, 0x92, 0x36, 0x36, 0x40},
136 	{0x2c, 0x2c, 0x00, 0x00, 0x2c, 0x2c, 0x41},
137 	{0x31, 0x31, 0x00, 0x9a, 0x31, 0x31, 0x42},
138 	{0x32, 0x32, 0x00, 0x90, 0x32, 0x32, 0x43},
139 	{0x33, 0x33, 0x00, 0x9b, 0x33, 0x33, 0x44},
140 	{0x0d, 0x0d, 0x00, 0x0d, 0x0d, 0x0d, 0x45},
141 	{0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x46},
142 	{0x2e, 0x2e, 0x00, 0x2e, 0x2e, 0x2e, 0x47},
143 	{0x12, 0x12, 0x00, 0x12, 0x12, 0x12, 0x48}, // INS
144 	{0x05, 0x05, 0x00, 0x05, 0x05, 0x05, 0x49},  // EL
145 	{0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0x4a},  // CLS
146 	{0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x4b},  // DEL
147 	{0x11, 0x11, 0x00, 0x11, 0x11, 0x11, 0x4c},  // DUP
148 	{0x1e, 0x19, 0x00, 0x1e, 0x1e, 0x19, 0x4d},  // Cursor Up
149 	{0x0b, 0x0b, 0x00, 0x0b, 0x0b, 0x0b, 0x4e},  // HOME
150 	{0x1d, 0x02, 0x00, 0x1d, 0x1d, 0x02, 0x4f},  // Cursor Left
151 	{0x1f, 0x1a, 0x00, 0x1f, 0x1f, 0x1a, 0x50},  // Cursor Down
152 	{0x1c, 0x06, 0x00, 0x1c, 0x1c, 0x16, 0x51},  // Cursor Right
153 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c},  // BREAK
154 	{0x101, 0x00, 0x101, 0x101, 0x101, 0x00, 0x5d},  // PF1
155 	{0x102, 0x00, 0x102, 0x102, 0x102, 0x00, 0x5e},
156 	{0x103, 0x00, 0x103, 0x103, 0x103, 0x00, 0x5f},
157 	{0x104, 0x00, 0x104, 0x104, 0x104, 0x00, 0x60},
158 	{0x105, 0x00, 0x105, 0x105, 0x105, 0x00, 0x61},
159 	{0x106, 0x00, 0x106, 0x106, 0x106, 0x00, 0x62},
160 	{0x107, 0x00, 0x107, 0x107, 0x107, 0x00, 0x63},
161 	{0x108, 0x00, 0x108, 0x108, 0x108, 0x00, 0x64},
162 	{0x109, 0x00, 0x109, 0x109, 0x109, 0x00, 0x65},
163 	{0x10a, 0x00, 0x10a, 0x10a, 0x10a, 0x00, 0x66},  // PF10
164 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
165 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
166 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
167 };
168 
169 
main_irq_set_flag(uint8_t flag)170 void fm7_state::main_irq_set_flag(uint8_t flag)
171 {
172 	m_irq_flags |= flag;
173 
174 	if(m_irq_flags != 0)
175 		m_maincpu->set_input_line(M6809_IRQ_LINE,ASSERT_LINE);
176 }
177 
main_irq_clear_flag(uint8_t flag)178 void fm7_state::main_irq_clear_flag(uint8_t flag)
179 {
180 	m_irq_flags &= ~flag;
181 
182 	if(m_irq_flags == 0)
183 		m_maincpu->set_input_line(M6809_IRQ_LINE,CLEAR_LINE);
184 }
185 
186 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)187 void fm7_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
188 {
189 	switch (id)
190 	{
191 	case TIMER_FM7_BEEPER_OFF:
192 		fm7_beeper_off(ptr, param);
193 		break;
194 	case TIMER_FM77AV_ENCODER_ACK:
195 		fm77av_encoder_ack(ptr, param);
196 		break;
197 	case TIMER_FM7_IRQ:
198 		fm7_timer_irq(ptr, param);
199 		break;
200 	case TIMER_FM7_SUBTIMER_IRQ:
201 		fm7_subtimer_irq(ptr, param);
202 		break;
203 	case TIMER_FM7_KEYBOARD_POLL:
204 		fm7_keyboard_poll(ptr, param);
205 		break;
206 	case TIMER_FM77AV_ALU_TASK_END:
207 		fm77av_alu_task_end(ptr, param);
208 		break;
209 	case TIMER_FM77AV_VSYNC:
210 		fm77av_vsync(ptr, param);
211 		break;
212 	default:
213 		throw emu_fatalerror("Unknown id in fm7_state::device_timer");
214 	}
215 }
216 
217 
218 /*
219  * Main CPU: I/O port 0xfd02
220  *
221  * On read: returns cassette data (bit 7) and printer status (bits 0-5)
222  * On write: sets IRQ masks
223  *   bit 0 - keypress
224  *   bit 1 - printer
225  *   bit 2 - timer
226  *   bit 3 - not used
227  *   bit 4 - MFD
228  *   bit 5 - TXRDY
229  *   bit 6 - RXRDY
230  *   bit 7 - SYNDET
231  *
232  */
fm7_irq_mask_w(uint8_t data)233 void fm7_state::fm7_irq_mask_w(uint8_t data)
234 {
235 	m_irq_mask = data;
236 	logerror("IRQ mask set: 0x%02x\n",m_irq_mask);
237 }
238 
239 /*
240  * Main CPU: I/O port 0xfd03
241  *
242  * On read: returns which IRQ is currently active (typically read by IRQ handler)
243  *   bit 0 - keypress
244  *   bit 1 - printer
245  *   bit 2 - timer
246  *   bit 3 - ???
247  * On write: Buzzer/Speaker On/Off
248  *   bit 0 - speaker on/off
249  *   bit 6 - buzzer on for 205ms
250  *   bit 7 - buzzer on/off
251  */
fm7_irq_cause_r()252 uint8_t fm7_state::fm7_irq_cause_r()
253 {
254 	uint8_t ret = ~m_irq_flags;
255 
256 	// Timer and Printer IRQ flags are cleared when this port is read
257 	// Keyboard IRQ flag is cleared when the scancode is read from
258 	// either keyboard data port (main CPU 0xfd01 or sub CPU 0xd401)
259 	if(m_irq_flags & 0x04)
260 		main_irq_clear_flag(IRQ_FLAG_TIMER);
261 	if(m_irq_flags & 0x02)
262 		main_irq_clear_flag(IRQ_FLAG_PRINTER);
263 
264 	logerror("IRQ flags read: 0x%02x\n",ret);
265 	return ret;
266 }
267 
TIMER_CALLBACK_MEMBER(fm7_state::fm7_beeper_off)268 TIMER_CALLBACK_MEMBER(fm7_state::fm7_beeper_off)
269 {
270 	m_beeper->set_state(0);
271 	logerror("timed beeper off\n");
272 }
273 
fm7_beeper_w(uint8_t data)274 void fm7_state::fm7_beeper_w(uint8_t data)
275 {
276 	m_speaker_active = data & 0x01;
277 
278 	if(!m_speaker_active)  // speaker not active, disable all beeper sound
279 	{
280 		m_beeper->set_state(0);
281 		return;
282 	}
283 
284 	if(data & 0x80)
285 	{
286 		if(m_speaker_active)
287 			m_beeper->set_state(1);
288 	}
289 	else
290 		m_beeper->set_state(0);
291 
292 	if(data & 0x40)
293 	{
294 		if(m_speaker_active)
295 		{
296 			m_beeper->set_state(1);
297 			logerror("timed beeper on\n");
298 			timer_set(attotime::from_msec(205), TIMER_FM7_BEEPER_OFF);
299 		}
300 	}
301 	logerror("beeper state: %02x\n",data);
302 }
303 
304 
305 /*
306  *  Sub CPU: port 0xd403 (read-only)
307  *  On read: timed buzzer sound
308  */
fm7_sub_beeper_r()309 uint8_t fm7_state::fm7_sub_beeper_r()
310 {
311 	if(m_speaker_active)
312 	{
313 		m_beeper->set_state(1);
314 		logerror("timed beeper on\n");
315 		timer_set(attotime::from_msec(205), TIMER_FM7_BEEPER_OFF);
316 	}
317 	return 0xff;
318 }
319 
vector_r(offs_t offset)320 uint8_t fm7_state::vector_r(offs_t offset)
321 {
322 	uint32_t init_size = m_rom_ptr.bytes();
323 
324 	if (m_init_rom_en)
325 	{
326 		return m_rom_ptr[(init_size-0x10)+offset];
327 	}
328 	else
329 	{
330 		if(m_type == SYS_FM7)
331 			return m_ram_ptr[0xfff0+offset];
332 		else
333 			return m_ram_ptr[0x3fff0+offset];
334 	}
335 }
336 
vector_w(offs_t offset,uint8_t data)337 void fm7_state::vector_w(offs_t offset, uint8_t data)
338 {
339 	if(m_type == SYS_FM7)
340 		m_ram_ptr[0xfff0+offset] = data;
341 	else
342 		m_ram_ptr[0x3fff0+offset] = data;
343 }
344 
345 /*
346  * Main CPU: I/O port 0xfd04
347  *
348  *  bit 0 - attention IRQ active, clears flag when read.
349  *  bit 1 - break key active
350  */
fm7_fd04_r()351 uint8_t fm7_state::fm7_fd04_r()
352 {
353 	uint8_t ret = 0xff;
354 
355 	if(m_video.attn_irq != 0)
356 	{
357 		ret &= ~0x01;
358 		m_video.attn_irq = 0;
359 	}
360 	if(m_break_flag != 0)
361 	{
362 		ret &= ~0x02;
363 	}
364 	return ret;
365 }
366 
367 /*
368  *  Main CPU: I/O port 0xfd0f
369  *
370  *  On read, enables BASIC ROM at 0x8000 (default)
371  *  On write, disables BASIC ROM, enables RAM (if more than 32kB)
372  */
fm7_rom_en_r(address_space & space)373 uint8_t fm7_state::fm7_rom_en_r(address_space &space)
374 {
375 	if(!machine().side_effects_disabled())
376 	{
377 		uint8_t* RAM = memregion("maincpu")->base();
378 
379 		m_basic_rom_en = 1;
380 		if(m_type == SYS_FM7)
381 		{
382 			membank("bank1")->set_base(RAM+0x38000);
383 		}
384 		else
385 			fm7_mmr_refresh(space);
386 		logerror("BASIC ROM enabled\n");
387 	}
388 	return 0x00;
389 }
390 
fm7_rom_en_w(address_space & space,uint8_t data)391 void fm7_state::fm7_rom_en_w(address_space &space, uint8_t data)
392 {
393 	uint8_t* RAM = memregion("maincpu")->base();
394 
395 	m_basic_rom_en = 0;
396 	if(m_type == SYS_FM7)
397 	{
398 		membank("bank1")->set_base(RAM+0x8000);
399 	}
400 	else
401 		fm7_mmr_refresh(space);
402 	logerror("BASIC ROM disabled\n");
403 }
404 
405 /*
406  *  Main CPU: port 0xfd10
407  *  Initiate ROM enable. (FM-77AV and later only)
408  *  Port is write-only.  Initiate ROM is on by default.
409  *
410  */
fm7_init_en_w(address_space & space,uint8_t data)411 void fm7_state::fm7_init_en_w(address_space &space, uint8_t data)
412 {
413 	if(data & 0x02)
414 	{
415 		m_init_rom_en = 0;
416 		fm7_mmr_refresh(space);
417 	}
418 	else
419 	{
420 		m_init_rom_en = 1;
421 		fm7_mmr_refresh(space);
422 	}
423 }
424 
425 /*
426  *  Main CPU: I/O ports 0xfd18 - 0xfd1f
427  *  Floppy Disk Controller (MB8877A)
428  */
WRITE_LINE_MEMBER(fm7_state::fm7_fdc_intrq_w)429 WRITE_LINE_MEMBER(fm7_state::fm7_fdc_intrq_w)
430 {
431 	m_fdc_irq_flag = state;
432 }
433 
WRITE_LINE_MEMBER(fm7_state::fm7_fdc_drq_w)434 WRITE_LINE_MEMBER(fm7_state::fm7_fdc_drq_w)
435 {
436 	m_fdc_drq_flag = state;
437 }
438 
fm7_fdc_r(offs_t offset)439 uint8_t fm7_state::fm7_fdc_r(offs_t offset)
440 {
441 	uint8_t ret = 0;
442 
443 	switch(offset)
444 	{
445 		case 0:
446 			return m_fdc->status_r();
447 		case 1:
448 			return m_fdc->track_r();
449 		case 2:
450 			return m_fdc->sector_r();
451 		case 3:
452 			return m_fdc->data_r();
453 		case 4:
454 			return m_fdc_side | 0xfe;
455 		case 5:
456 			return m_fdc_drive;
457 		case 6:
458 			// FM-7 always returns 0xff for this register
459 			return 0xff;
460 		case 7:
461 			if(m_fdc_irq_flag != 0)
462 				ret |= 0x40;
463 			if(m_fdc_drq_flag != 0)
464 				ret |= 0x80;
465 			return ret;
466 	}
467 	logerror("FDC: read from 0x%04x\n",offset+0xfd18);
468 
469 	return 0x00;
470 }
471 
fm7_fdc_w(offs_t offset,uint8_t data)472 void fm7_state::fm7_fdc_w(offs_t offset, uint8_t data)
473 {
474 	switch(offset)
475 	{
476 		case 0:
477 			m_fdc->cmd_w(data);
478 			break;
479 		case 1:
480 			m_fdc->track_w(data);
481 			break;
482 		case 2:
483 			m_fdc->sector_w(data);
484 			break;
485 		case 3:
486 			m_fdc->data_w(data);
487 			break;
488 		case 4:
489 			m_fdc_side = data & 0x01;
490 			if (m_floppy)
491 				m_floppy->ss_w(data & 0x01);
492 			logerror("FDC: wrote %02x to 0x%04x (side)\n",data,offset+0xfd18);
493 			break;
494 		case 5:
495 			m_fdc_drive = data;
496 			if((data & 0x03) > 0x01)
497 			{
498 				m_fdc_drive = 0;
499 			}
500 			else
501 			{
502 				switch (data & 0x01)
503 				{
504 				case 0: m_floppy = m_floppy0->get_device(); break;
505 				case 1: m_floppy = m_floppy1->get_device(); break;
506 				}
507 
508 				m_fdc->set_floppy(m_floppy);
509 
510 				if (m_floppy)
511 					m_floppy->mon_w(!BIT(data, 7));
512 
513 				logerror("FDC: wrote %02x to 0x%04x (drive)\n",data,offset+0xfd18);
514 			}
515 			break;
516 		case 6:
517 			// FM77AV and later only. FM-7 returns 0xff;
518 			// bit 6 = 320k(1)/640k(0) FDD
519 			// bits 2,3 = logical drive
520 			logerror("FDC: mode write - %02x\n",data);
521 			break;
522 		default:
523 			logerror("FDC: wrote %02x to 0x%04x\n",data,offset+0xfd18);
524 	}
525 }
526 
527 /*
528  *  Main CPU: I/O ports 0xfd00-0xfd01
529  *  Sub CPU: I/O ports 0xd400-0xd401
530  *
531  *  The scancode of the last key pressed is stored in fd/d401, with the 9th
532  *  bit (MSB) in bit 7 of fd/d400.  0xfd00 also holds a flag for the main
533  *  CPU clock speed in bit 0 (0 = 1.2MHz, 1 = 2MHz)
534  *  Clears keyboard IRQ flag
535  */
fm7_keyboard_r(offs_t offset)536 uint8_t fm7_state::fm7_keyboard_r(offs_t offset)
537 {
538 	uint8_t ret;
539 	switch(offset)
540 	{
541 		case 0:
542 			ret = (m_current_scancode >> 1) & 0x80;
543 			ret |= 0x01; // 1 = 2MHz, 0 = 1.2MHz
544 			return ret;
545 		case 1:
546 			main_irq_clear_flag(IRQ_FLAG_KEY);
547 			return m_current_scancode & 0xff;
548 		default:
549 			return 0x00;
550 	}
551 }
552 
fm7_sub_keyboard_r(offs_t offset)553 uint8_t fm7_state::fm7_sub_keyboard_r(offs_t offset)
554 {
555 	uint8_t ret;
556 	switch(offset)
557 	{
558 		case 0:
559 			ret = (m_current_scancode >> 1) & 0x80;
560 			return ret;
561 		case 1:
562 			main_irq_clear_flag(IRQ_FLAG_KEY);
563 			return m_current_scancode & 0xff;
564 		default:
565 			return 0x00;
566 	}
567 }
568 
569 /*
570  *  Sub CPU: port 0xd431, 0xd432
571  *  Keyboard encoder
572  *
573  *  d431 (R/W): Data register (8 bit)
574  *  d432 (R/O): Status register
575  *              bit 0 - ACK
576  *              bit 7 - LATCH (0 if ready to receive)
577  *
578  *  Encoder commands:
579  *      00 xx    : Set scancode format (FM-7, FM16B(?), Scan(Make/Break))
580  *      01       : Get scancode format
581  *      02 xx    : Set LED status
582  *      03       : Get LED status
583  *      04 xx    : Enable/Disable key repeat
584  *      05 xx xx : Set repeat rate and time
585  *      80 00    : Get RTC
586  *      80 01 xx xx xx xx xx xx xx : Set RTC
587  *      81 xx    : Video digitise
588  *      82 xx    : Set video mode(?)
589  *      83       : Get video mode(?)
590  *      84 xx    : Video brightness (monitor?)
591  *
592  *  ACK is received after 5us.
593  */
fm77av_key_encoder_r(offs_t offset)594 uint8_t fm7_state::fm77av_key_encoder_r(offs_t offset)
595 {
596 	uint8_t ret = 0xff;
597 	switch(offset)
598 	{
599 		case 0x00:  // data register
600 			if(m_encoder.rx_count > 0)
601 			{
602 				ret = m_encoder.buffer[m_encoder.position];
603 				m_encoder.position++;
604 				m_encoder.rx_count--;
605 				m_encoder.latch = 0;
606 			}
607 			if(m_encoder.rx_count > 0)
608 				m_encoder.latch = 1;  // more data to receive
609 			break;
610 		case 0x01:  // status register
611 			if(m_encoder.latch != 0)
612 				ret &= ~0x80;
613 			if(m_encoder.ack == 0)
614 				ret &= ~0x01;
615 			break;
616 	}
617 
618 	return ret;
619 }
620 
fm77av_encoder_setup_command()621 void fm7_state::fm77av_encoder_setup_command()
622 {
623 	switch(m_encoder.buffer[0])
624 	{
625 		case 0:  // set scancode format
626 			m_encoder.tx_count = 2;
627 			break;
628 		case 1:  // get scancode format
629 			m_encoder.tx_count = 1;
630 			break;
631 		case 2:  // set LED
632 			m_encoder.tx_count = 2;
633 			break;
634 		case 3:  // get LED
635 			m_encoder.tx_count = 1;
636 			break;
637 		case 4:  // enable repeat
638 			m_encoder.tx_count = 2;
639 			break;
640 		case 5:  // set repeat rate
641 			m_encoder.tx_count = 3;
642 			break;
643 		case 0x80:  // get/set RTC (at least two bytes, 9 if byte two = 0x01)
644 			m_encoder.tx_count = 2;
645 			break;
646 		case 0x81:  // digitise
647 			m_encoder.tx_count = 2;
648 			break;
649 		case 0x82:  // set screen mode
650 			m_encoder.tx_count = 2;
651 			break;
652 		case 0x83:  // get screen mode
653 			m_encoder.tx_count = 1;
654 			break;
655 		case 0x84:  // set monitor brightness
656 			m_encoder.tx_count = 2;
657 			break;
658 		default:
659 			m_encoder.tx_count = 0;
660 			m_encoder.rx_count = 0;
661 			m_encoder.position = 0;
662 			logerror("ENC: Unknown command 0x%02x sent, ignoring\n",m_encoder.buffer[0]);
663 	}
664 }
665 
TIMER_CALLBACK_MEMBER(fm7_state::fm77av_encoder_ack)666 TIMER_CALLBACK_MEMBER(fm7_state::fm77av_encoder_ack)
667 {
668 	m_encoder.ack = 1;
669 }
670 
fm77av_encoder_handle_command()671 void fm7_state::fm77av_encoder_handle_command()
672 {
673 	switch(m_encoder.buffer[0])
674 	{
675 		case 0:  // set keyboard scancode mode
676 			m_key_scan_mode = m_encoder.buffer[1];
677 			m_encoder.rx_count = 0;
678 			logerror("ENC: Keyboard set to mode %i\n",m_encoder.buffer[1]);
679 			break;
680 		case 1:  // get keyboard scancode mode
681 			m_encoder.buffer[0] = m_key_scan_mode;
682 			m_encoder.rx_count = 1;
683 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
684 			break;
685 		case 2:  // set LEDs
686 			m_encoder.rx_count = 0;
687 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
688 			break;
689 		case 3:  // get LEDs
690 			m_encoder.rx_count = 1;
691 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
692 			break;
693 		case 4:  // enable key repeat
694 			m_encoder.rx_count = 0;
695 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
696 			break;
697 		case 5:  // set key repeat rate
698 			m_key_repeat = m_encoder.buffer[2] * 10;
699 			m_key_delay = m_encoder.buffer[1] * 10;
700 			m_encoder.rx_count = 0;
701 			logerror("ENC: Keyboard repeat rate set to %i/%i\n",m_encoder.buffer[1],m_encoder.buffer[2]);
702 			break;
703 		case 0x80:  // get/set RTC
704 			if(m_encoder.buffer[1] == 0x01)
705 				m_encoder.rx_count = 0;
706 			else
707 				m_encoder.rx_count = 7;
708 			logerror("ENC: Command %02x %02x received\n",m_encoder.buffer[0],m_encoder.buffer[1]);
709 			break;
710 		case 0x81:  // digitise
711 			m_encoder.rx_count = 0;
712 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
713 			break;
714 		case 0x82:  // set screen mode
715 			m_encoder.rx_count = 0;
716 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
717 			break;
718 		case 0x83:  // get screen mode
719 			m_encoder.rx_count = 1;
720 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
721 			break;
722 		case 0x84:  // set monitor brightness
723 			m_encoder.rx_count = 0;
724 			logerror("ENC: Command %02x received\n",m_encoder.buffer[0]);
725 			break;
726 	}
727 	m_encoder.position = 0;
728 }
729 
fm77av_key_encoder_w(offs_t offset,uint8_t data)730 void fm7_state::fm77av_key_encoder_w(offs_t offset, uint8_t data)
731 {
732 	m_encoder.ack = 0;
733 	if(offset == 0) // data register
734 	{
735 		if(m_encoder.position == 0)  // first byte
736 		{
737 			fm77av_encoder_setup_command();
738 		}
739 		if(m_encoder.position == 1)  // second byte
740 		{
741 			if(m_encoder.buffer[0] == 0x80 || m_encoder.buffer[1] == 0x01)
742 			{
743 				m_encoder.tx_count = 8; // 80 01 command is 9 bytes
744 			}
745 		}
746 		m_encoder.buffer[m_encoder.position] = data;
747 		m_encoder.position++;
748 		m_encoder.tx_count--;
749 		if(m_encoder.tx_count == 0)  // last byte
750 			fm77av_encoder_handle_command();
751 
752 		// wait 5us to set ACK flag
753 		timer_set(attotime::from_usec(5), TIMER_FM77AV_ENCODER_ACK);
754 
755 		//logerror("ENC: write 0x%02x to data register, moved to pos %i\n",data,m_encoder.position);
756 	}
757 }
758 
WRITE_LINE_MEMBER(fm7_state::write_centronics_busy)759 WRITE_LINE_MEMBER(fm7_state::write_centronics_busy)
760 {
761 	m_centronics_busy = state;
762 }
763 
WRITE_LINE_MEMBER(fm7_state::write_centronics_fault)764 WRITE_LINE_MEMBER(fm7_state::write_centronics_fault)
765 {
766 	m_centronics_fault = state;
767 }
768 
WRITE_LINE_MEMBER(fm7_state::write_centronics_ack)769 WRITE_LINE_MEMBER(fm7_state::write_centronics_ack)
770 {
771 	m_centronics_ack = state;
772 }
773 
WRITE_LINE_MEMBER(fm7_state::write_centronics_perror)774 WRITE_LINE_MEMBER(fm7_state::write_centronics_perror)
775 {
776 	m_centronics_perror = state;
777 }
778 
fm7_cassette_printer_r()779 uint8_t fm7_state::fm7_cassette_printer_r()
780 {
781 	// bit 7: cassette input
782 	// bit 5: printer DET2
783 	// bit 4: printer DTT1
784 	// bit 3: printer PE
785 	// bit 2: printer acknowledge
786 	// bit 1: printer error
787 	// bit 0: printer busy
788 	uint8_t ret = 0;
789 
790 	if(m_cassette->input() > 0.03)
791 		ret |= 0x80;
792 
793 	if(m_cassette->get_state() & CASSETTE_MOTOR_DISABLED)
794 		ret |= 0x80;  // cassette input is high when not in use.
795 
796 	ret |= 0x70;
797 	ret |= m_centronics_perror << 3;
798 	ret |= m_centronics_ack << 2;
799 	ret |= m_centronics_fault << 1;
800 	ret |= m_centronics_busy;
801 
802 	return ret;
803 }
804 
fm7_cassette_printer_w(offs_t offset,uint8_t data)805 void fm7_state::fm7_cassette_printer_w(offs_t offset, uint8_t data)
806 {
807 	switch(offset)
808 	{
809 		case 0:
810 		// bit 7: SLCTIN (select?)
811 		// bit 6: printer strobe
812 		// bit 1: cassette motor
813 		// bit 0: cassette output
814 			if((data & 0x01) != (m_cp_prev & 0x01))
815 				m_cassette->output((data & 0x01) ? +1.0 : -1.0);
816 			if((data & 0x02) != (m_cp_prev & 0x02))
817 				m_cassette->change_state((data & 0x02) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
818 
819 			m_centronics->write_strobe(!BIT(data,6));
820 			m_centronics->write_select_in(!BIT(data,7));
821 			m_cp_prev = data;
822 			break;
823 		case 1:
824 		// Printer data
825 			m_cent_data_out->write(data);
826 			break;
827 	}
828 }
829 
830 /*
831  *  Main CPU: 0xfd0b
832  *   - bit 0: Boot mode: 0=BASIC, 1=DOS
833  */
fm77av_boot_mode_r()834 uint8_t fm7_state::fm77av_boot_mode_r()
835 {
836 	uint8_t ret = 0xff;
837 
838 	if(m_dsw->read() & 0x02)
839 		ret &= ~0x01;
840 
841 	return ret;
842 }
843 
844 /*
845  *  Main CPU: I/O ports 0xfd0d-0xfd0e
846  *  PSG AY-3-891x (FM-7), YM2203 - (FM-77AV and later)
847  *  0xfd0d - function select (bit 1 = BDIR, bit 0 = BC1)
848  *  0xfd0e - data register
849  *  AY I/O ports are not connected to anything.
850  */
fm7_update_psg()851 void fm7_state::fm7_update_psg()
852 {
853 	if(m_type == SYS_FM7)
854 	{
855 		switch(m_psg_regsel)
856 		{
857 			case 0x00:
858 				// High impedance
859 				break;
860 			case 0x01:
861 				// Data read
862 				m_psg_data = m_psg->data_r();
863 				break;
864 			case 0x02:
865 				// Data write
866 				m_psg->data_w(m_psg_data);
867 				break;
868 			case 0x03:
869 				// Address latch
870 				m_psg->address_w(m_psg_data);
871 				break;
872 		}
873 	}
874 	else
875 	{   // FM-77AV and later use a YM2203
876 		switch(m_psg_regsel)
877 		{
878 			case 0x00:
879 				// High impedance
880 				break;
881 			case 0x01:
882 				// Data read
883 				m_psg_data = m_ym->read(1);
884 				break;
885 			case 0x02:
886 				// Data write
887 				m_ym->write(1,m_psg_data);
888 				logerror("YM: data write 0x%02x\n",m_psg_data);
889 				break;
890 			case 0x03:
891 				// Address latch
892 				m_ym->write(0,m_psg_data);
893 				logerror("YM: address latch 0x%02x\n",m_psg_data);
894 				break;
895 			case 0x04:
896 				// Status register
897 				m_psg_data = m_ym->read(0);
898 				break;
899 			case 0x09:
900 				// Joystick port read
901 				m_psg_data = m_joy1->read();
902 				break;
903 		}
904 	}
905 }
906 
fm7_psg_select_r()907 uint8_t fm7_state::fm7_psg_select_r()
908 {
909 	return 0xff;
910 }
911 
fm7_psg_select_w(uint8_t data)912 void fm7_state::fm7_psg_select_w(uint8_t data)
913 {
914 	m_psg_regsel = data & 0x03;
915 	fm7_update_psg();
916 }
917 
fm77av_ym_select_w(uint8_t data)918 void fm7_state::fm77av_ym_select_w(uint8_t data)
919 {
920 	m_psg_regsel = data & 0x0f;
921 	fm7_update_psg();
922 }
923 
fm7_psg_data_r()924 uint8_t fm7_state::fm7_psg_data_r()
925 {
926 //  fm7_update_psg();
927 	return m_psg_data;
928 }
929 
fm7_psg_data_w(uint8_t data)930 void fm7_state::fm7_psg_data_w(uint8_t data)
931 {
932 	m_psg_data = data;
933 //  fm7_update_psg();
934 }
935 
fm77av_bootram_w(offs_t offset,uint8_t data)936 void fm7_state::fm77av_bootram_w(offs_t offset, uint8_t data)
937 {
938 	if(!(m_mmr.mode & 0x01))
939 		return;
940 	m_boot_ram[offset] = data;
941 }
942 
943 // Shared RAM is only usable on the main CPU if the sub CPU is halted
fm7_main_shared_r(offs_t offset)944 uint8_t fm7_state::fm7_main_shared_r(offs_t offset)
945 {
946 	if(m_video.sub_halt != 0)
947 		return m_shared_ram[offset];
948 	else
949 		return 0xff;
950 }
951 
fm7_main_shared_w(offs_t offset,uint8_t data)952 void fm7_state::fm7_main_shared_w(offs_t offset, uint8_t data)
953 {
954 	if(m_video.sub_halt != 0)
955 		m_shared_ram[offset] = data;
956 }
957 
fm7_fmirq_r()958 uint8_t fm7_state::fm7_fmirq_r()
959 {
960 	uint8_t ret = 0xff;
961 
962 	if(m_fm77av_ym_irq != 0)
963 		ret &= ~0x08;
964 
965 	return ret;
966 }
967 
fm7_unknown_r()968 uint8_t fm7_state::fm7_unknown_r()
969 {
970 	// Port 0xFDFC is read by Dig Dug.  Controller port, perhaps?
971 	// Must return 0xff for it to read the keyboard.
972 	// Mappy uses ports FD15 and FD16.  On the FM77AV, this is the YM2203,
973 	// but on the FM-7, this is nothing, so we return 0xff for it to
974 	// read the keyboard correctly.
975 	return 0xff;
976 }
977 
978 /*
979  * Memory Management Register
980  * Main CPU: 0xfd80 - 0xfd93  (FM-77L4, FM-77AV and later only)
981  *
982  * fd80-fd8f (R/W): RAM bank select for current segment (A19-A12)
983  * fd90 (W/O): segment select register (3-bit, default = 0)
984  * fd92 (W/O): window offset register (OA15-OA8)
985  * fd93 (R/W): mode select register
986  *              - bit 7: MMR enable/disable
987  *              - bit 6: window enable/disable
988  *              - bit 0: boot RAM read-write/read-only
989  *
990  */
fm7_mmr_r(offs_t offset)991 uint8_t fm7_state::fm7_mmr_r(offs_t offset)
992 {
993 	if(offset < 0x10)
994 	{
995 		return m_mmr.bank_addr[m_mmr.segment][offset];
996 	}
997 	if(offset == 0x13)
998 		return m_mmr.mode;
999 	return 0xff;
1000 }
1001 
fm7_update_bank(address_space & space,int bank,uint8_t physical)1002 void fm7_state::fm7_update_bank(address_space & space, int bank, uint8_t physical)
1003 {
1004 	m_avbank[bank]->set_bank(physical);
1005 /*  uint8_t* RAM = memregion("maincpu")->base();
1006     uint16_t size = 0xfff;
1007     char bank_name[10];
1008 
1009     if(bank == 15)
1010         size = 0xbff;
1011 
1012     sprintf(bank_name,"bank%d",bank+1);
1013 
1014     if(physical >= 0x10 && physical <= 0x1b)
1015     {
1016         switch(physical)
1017         {
1018             case 0x10:
1019                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram0_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram0_w)));
1020                 break;
1021             case 0x11:
1022                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram1_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram1_w)));
1023                 break;
1024             case 0x12:
1025                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram2_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram2_w)));
1026                 break;
1027             case 0x13:
1028                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram3_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram3_w)));
1029                 break;
1030             case 0x14:
1031                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram4_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram4_w)));
1032                 break;
1033             case 0x15:
1034                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram5_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram5_w)));
1035                 break;
1036             case 0x16:
1037                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram6_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram6_w)));
1038                 break;
1039             case 0x17:
1040                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram7_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram7_w)));
1041                 break;
1042             case 0x18:
1043                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram8_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram8_w)));
1044                 break;
1045             case 0x19:
1046                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vram9_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vram9_w)));
1047                 break;
1048             case 0x1a:
1049                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vramA_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vramA_w)));
1050                 break;
1051             case 0x1b:
1052                 space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_vramB_r)),write8_delegate(*this, FUNC(fm7_state::fm7_vramB_w)));
1053                 break;
1054         }
1055 //      membank(bank+1)->set_base(RAM+(physical<<12)-0x10000);
1056         return;
1057     }
1058     if(physical == 0x1c)
1059     {
1060         space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_console_ram_banked_r)),write8_delegate(*this, FUNC(fm7_state::fm7_console_ram_banked_w)));
1061         return;
1062     }
1063     if(physical == 0x1d)
1064     {
1065         space.install_readwrite_handler(bank*0x1000,(bank*0x1000)+size,read8_delegate(*this, FUNC(fm7_state::fm7_sub_ram_ports_banked_r)),write8_delegate(*this, FUNC(fm7_state::fm7_sub_ram_ports_banked_w)));
1066         return;
1067     }
1068     if(physical == 0x35)
1069     {
1070         if(m_init_rom_en && (m_type == SYS_FM11 || m_type == SYS_FM16))
1071         {
1072             RAM = memregion("init")->base();
1073             space.install_read_bank(bank*0x1000,(bank*0x1000)+size,bank_name);
1074             space.nop_write(bank*0x1000,(bank*0x1000)+size);
1075             membank(bank_name)->set_base(RAM+(physical<<12)-0x35000);
1076             return;
1077         }
1078     }
1079     if(physical == 0x36 || physical == 0x37)
1080     {
1081         if(m_init_rom_en && (m_type != SYS_FM11 && m_type != SYS_FM16))
1082         {
1083             RAM = memregion("init")->base();
1084             space.install_read_bank(bank*0x1000,(bank*0x1000)+size,bank_name);
1085             space.nop_write(bank*0x1000,(bank*0x1000)+size);
1086             membank(bank_name)->set_base(RAM+(physical<<12)-0x36000);
1087             return;
1088         }
1089     }
1090     if(physical > 0x37 && physical <= 0x3f)
1091     {
1092         if(m_basic_rom_en && (m_type != SYS_FM11 && m_type != SYS_FM16))
1093         {
1094             RAM = memregion("fbasic")->base();
1095             space.install_read_bank(bank*0x1000,(bank*0x1000)+size,bank_name);
1096             space.nop_write(bank*0x1000,(bank*0x1000)+size);
1097             membank(bank_name)->set_base(RAM+(physical<<12)-0x38000);
1098             return;
1099         }
1100     }
1101     space.install_readwrite_bank(bank*0x1000,(bank*0x1000)+size,bank_name);
1102     membank(bank_name)->set_base(RAM+(physical<<12));
1103     */
1104 }
1105 
fm7_mmr_refresh(address_space & space)1106 void fm7_state::fm7_mmr_refresh(address_space& space)
1107 {
1108 	int x;
1109 	uint16_t window_addr;
1110 	uint8_t* RAM = memregion("maincpu")->base();
1111 
1112 	if(m_mmr.enabled)
1113 	{
1114 		for(x=0;x<16;x++)
1115 			fm7_update_bank(space,x,m_mmr.bank_addr[m_mmr.segment][x]);
1116 	}
1117 	else
1118 	{
1119 		// when MMR is disabled, 0x30000-0x3ffff is banked in
1120 		for(x=0;x<16;x++)
1121 			fm7_update_bank(space,x,0x30+x);
1122 	}
1123 
1124 	if(m_mmr.mode & 0x40)
1125 	{
1126 		// Handle window offset - 0x7c00-0x7fff will show the area of extended
1127 		// memory (0x00000-0x0ffff) defined by the window address register
1128 		// 0x00 = 0x07c00, 0x04 = 0x08000 ... 0xff = 0x07400.
1129 		window_addr = ((m_mmr.window_offset << 8) + 0x7c00) & 0xffff;
1130 //      if(window_addr < 0xfc00)
1131 		{
1132 			space.install_readwrite_bank(0x7c00,0x7fff,"bank24");
1133 			membank("bank24")->set_base(RAM+window_addr);
1134 		}
1135 	}
1136 	else
1137 	{
1138 		space.install_readwrite_handler(0x7000,0x7fff,read8sm_delegate(*m_avbank[7], FUNC(address_map_bank_device::read8)),write8sm_delegate(*m_avbank[7], FUNC(address_map_bank_device::write8)));
1139 	}
1140 	if(m_init_rom_en)
1141 	{
1142 		membank("init_bank_r")->set_base(m_rom_ptr);
1143 	}
1144 	else
1145 	{
1146 		membank("init_bank_r")->set_base(m_ram_ptr + 0x36000);
1147 	}
1148 
1149 	if (m_basic_rom_en)
1150 	{
1151 		if (m_basic_ptr)
1152 		{
1153 			membank("fbasic_bank_r")->set_base(m_basic_ptr);
1154 		}
1155 	}
1156 	else
1157 	{
1158 		membank("fbasic_bank_r")->set_base(m_ram_ptr + 0x38000);
1159 	}
1160 }
1161 
fm7_mmr_w(address_space & space,offs_t offset,uint8_t data)1162 void fm7_state::fm7_mmr_w(address_space &space, offs_t offset, uint8_t data)
1163 {
1164 	if(offset < 0x10)
1165 	{
1166 		m_mmr.bank_addr[m_mmr.segment][offset] = data;
1167 		if(m_mmr.enabled)
1168 			fm7_update_bank(space,offset,data);
1169 		logerror("MMR: Segment %i, bank %i, set to  0x%02x\n",m_mmr.segment,offset,data);
1170 		return;
1171 	}
1172 	switch(offset)
1173 	{
1174 		case 0x10:
1175 			m_mmr.segment = data & 0x07;
1176 			fm7_mmr_refresh(space);
1177 			logerror("MMR: Active segment set to %i\n",m_mmr.segment);
1178 			break;
1179 		case 0x12:
1180 			m_mmr.window_offset = data;
1181 			fm7_mmr_refresh(space);
1182 			logerror("MMR: Window offset set to %02x\n",data);
1183 			break;
1184 		case 0x13:
1185 			m_mmr.mode = data;
1186 			m_mmr.enabled = data & 0x80;
1187 			fm7_mmr_refresh(space);
1188 			logerror("MMR: Mode register set to %02x\n",data);
1189 			break;
1190 	}
1191 }
1192 
1193 /*
1194  *  Main CPU: ports 0xfd20-0xfd23
1195  *  Kanji ROM read ports
1196  *  FD20 (W/O): ROM address high
1197  *  FD21 (W/O): ROM address low
1198  *  FD22 (R/O): Kanji data high
1199  *  FD23 (R/O): Kanji data low
1200  *
1201  *  Kanji ROM is visible at 0x20000 (first half only?)
1202  */
fm7_kanji_r(offs_t offset)1203 uint8_t fm7_state::fm7_kanji_r(offs_t offset)
1204 {
1205 	uint8_t* KROM = m_kanji->base();
1206 	uint32_t addr = m_kanji_address << 1;
1207 
1208 	switch(offset)
1209 	{
1210 		case 0:
1211 		case 1:
1212 			logerror("KANJI: read from invalid register %i\n",offset);
1213 			return 0xff;  // write-only
1214 		case 2:
1215 			return KROM[addr];
1216 		case 3:
1217 			return KROM[addr+1];
1218 		default:
1219 			logerror("KANJI: read from invalid register %i\n",offset);
1220 			return 0xff;
1221 	}
1222 }
1223 
fm7_kanji_w(offs_t offset,uint8_t data)1224 void fm7_state::fm7_kanji_w(offs_t offset, uint8_t data)
1225 {
1226 	uint16_t addr;
1227 
1228 	switch(offset)
1229 	{
1230 		case 0:
1231 			addr = ((data & 0xff) << 8) | (m_kanji_address & 0x00ff);
1232 			m_kanji_address = addr;
1233 			break;
1234 		case 1:
1235 			addr = (data & 0xff) | (m_kanji_address & 0xff00);
1236 			m_kanji_address = addr;
1237 			break;
1238 		case 2:
1239 		case 3:
1240 		default:
1241 			logerror("KANJI: write to invalid register %i\n",offset);
1242 	}
1243 }
1244 
TIMER_CALLBACK_MEMBER(fm7_state::fm7_timer_irq)1245 TIMER_CALLBACK_MEMBER(fm7_state::fm7_timer_irq)
1246 {
1247 	if(m_irq_mask & IRQ_FLAG_TIMER)
1248 	{
1249 		main_irq_set_flag(IRQ_FLAG_TIMER);
1250 	}
1251 }
1252 
TIMER_CALLBACK_MEMBER(fm7_state::fm7_subtimer_irq)1253 TIMER_CALLBACK_MEMBER(fm7_state::fm7_subtimer_irq)
1254 {
1255 	if(m_video.nmi_mask == 0 && m_video.sub_halt == 0)
1256 		m_sub->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
1257 }
1258 
1259 // When a key is pressed or released (in scan mode only), an IRQ is generated on the main CPU,
1260 // or an FIRQ on the sub CPU, if masked.  Both CPUs have ports to read keyboard data.
1261 // Scancodes are 9 bits in FM-7 mode, 8 bits in scan mode.
key_press(uint16_t scancode)1262 void fm7_state::key_press(uint16_t scancode)
1263 {
1264 	m_current_scancode = scancode;
1265 
1266 	if(scancode == 0)
1267 		return;
1268 
1269 	if(m_irq_mask & IRQ_FLAG_KEY)
1270 	{
1271 		main_irq_set_flag(IRQ_FLAG_KEY);
1272 	}
1273 	else
1274 	{
1275 		m_sub->set_input_line(M6809_FIRQ_LINE,ASSERT_LINE);
1276 	}
1277 	logerror("KEY: sent scancode 0x%03x\n",scancode);
1278 }
1279 
fm7_keyboard_poll_scan()1280 void fm7_state::fm7_keyboard_poll_scan()
1281 {
1282 	int bit = 0;
1283 	int x,y;
1284 	uint32_t keys;
1285 	uint32_t modifiers = m_keymod->read();
1286 	static const uint16_t modscancodes[6] = { 0x52, 0x53, 0x54, 0x55, 0x56, 0x5a };
1287 
1288 	for(x=0;x<3;x++)
1289 	{
1290 		keys = m_kb_ports[x]->read();
1291 
1292 		for(y=0;y<32;y++)  // loop through each bit in the port
1293 		{
1294 			if((keys & (1<<y)) != 0 && (m_key_data[x] & (1<<y)) == 0)
1295 			{
1296 				key_press(fm7_key_list[bit][6]); // key press
1297 			}
1298 			if((keys & (1<<y)) == 0 && (m_key_data[x] & (1<<y)) != 0)
1299 			{
1300 				key_press(fm7_key_list[bit][6] | 0x80); // key release
1301 			}
1302 			bit++;
1303 		}
1304 
1305 		m_key_data[x] = keys;
1306 	}
1307 	// check modifier keys
1308 	bit = 0;
1309 	for(y=0;x<7;x++)
1310 	{
1311 		if((modifiers & (1<<y)) != 0 && (m_mod_data & (1<<y)) == 0)
1312 		{
1313 			key_press(modscancodes[bit]); // key press
1314 		}
1315 		if((modifiers & (1<<y)) == 0 && (m_mod_data & (1<<y)) != 0)
1316 		{
1317 			key_press(modscancodes[bit] | 0x80); // key release
1318 		}
1319 		bit++;
1320 	}
1321 	m_mod_data = modifiers;
1322 }
1323 
TIMER_CALLBACK_MEMBER(fm7_state::fm7_keyboard_poll)1324 TIMER_CALLBACK_MEMBER(fm7_state::fm7_keyboard_poll)
1325 {
1326 	int x,y;
1327 	int bit = 0;
1328 	int mod = 0;
1329 	uint32_t keys;
1330 	uint32_t modifiers = m_keymod->read();
1331 
1332 	if (m_kb_ports[2]->read() & 0x40000)
1333 	{
1334 		m_break_flag = 1;
1335 		m_maincpu->set_input_line(M6809_FIRQ_LINE,ASSERT_LINE);
1336 	}
1337 	else
1338 		m_break_flag = 0;
1339 
1340 	if(m_key_scan_mode == KEY_MODE_SCAN)
1341 	{
1342 		// handle scancode mode
1343 		fm7_keyboard_poll_scan();
1344 		return;
1345 	}
1346 
1347 	// check key modifiers (Shift, Ctrl, Kana, etc...)
1348 	if(modifiers & 0x02 || modifiers & 0x04)
1349 		mod = 1;  // shift
1350 	if(modifiers & 0x10)
1351 		mod = 3;  // Graph  (shift has no effect with graph)
1352 	if(modifiers & 0x01)
1353 		mod = 2;  // ctrl (overrides shift, if also pressed)
1354 	if(modifiers & 0x20)
1355 		mod = 4;  // kana (overrides all)
1356 	if((modifiers & 0x22) == 0x22 || (modifiers & 0x24) == 0x24)
1357 		mod = 5;  // shifted kana
1358 
1359 	for(x=0;x<3;x++)
1360 	{
1361 		keys = m_kb_ports[x]->read();
1362 
1363 		for(y=0;y<32;y++)  // loop through each bit in the port
1364 		{
1365 			if((keys & (1<<y)) != 0 && (m_key_data[x] & (1<<y)) == 0)
1366 			{
1367 				key_press(fm7_key_list[bit][mod]); // key press
1368 			}
1369 			bit++;
1370 		}
1371 
1372 		m_key_data[x] = keys;
1373 	}
1374 }
1375 
IRQ_CALLBACK_MEMBER(fm7_state::fm7_irq_ack)1376 IRQ_CALLBACK_MEMBER(fm7_state::fm7_irq_ack)
1377 {
1378 	if(irqline == M6809_FIRQ_LINE)
1379 		m_maincpu->set_input_line(irqline,CLEAR_LINE);
1380 	return -1;
1381 }
1382 
IRQ_CALLBACK_MEMBER(fm7_state::fm7_sub_irq_ack)1383 IRQ_CALLBACK_MEMBER(fm7_state::fm7_sub_irq_ack)
1384 {
1385 	m_sub->set_input_line(irqline,CLEAR_LINE);
1386 	return -1;
1387 }
1388 
WRITE_LINE_MEMBER(fm7_state::fm77av_fmirq)1389 WRITE_LINE_MEMBER(fm7_state::fm77av_fmirq)
1390 {
1391 	if(state == 1)
1392 	{
1393 		// cannot be masked
1394 		main_irq_set_flag(IRQ_FLAG_OTHER);
1395 		m_fm77av_ym_irq = 1;
1396 		logerror("YM: IRQ on\n");
1397 	}
1398 	else
1399 	{
1400 		main_irq_clear_flag(IRQ_FLAG_OTHER);
1401 		m_fm77av_ym_irq = 0;
1402 		logerror("YM: IRQ off\n");
1403 	}
1404 }
1405 
1406 /*
1407    0000 - 7FFF: (RAM) BASIC working area, user's area
1408    8000 - FBFF: (ROM) F-BASIC ROM, extra user RAM
1409    FC00 - FC7F: more RAM, if 64kB is installed
1410    FC80 - FCFF: Shared RAM between main and sub CPU, available only when sub CPU is halted
1411    FD00 - FDFF: I/O space (6809 uses memory-mapped I/O)
1412    FE00 - FFEF: Boot rom
1413    FFF0 - FFFF: Interrupt vector table
1414 */
1415 // The FM-7 has only 64kB RAM, so we'll worry about banking when we do the later models
fm7_mem(address_map & map)1416 void fm7_state::fm7_mem(address_map &map)
1417 {
1418 	map(0x0000, 0x7fff).ram();
1419 	map(0x8000, 0xfbff).bankr("bank1").bankw("bank2"); // also F-BASIC ROM, when enabled
1420 	map(0xfc00, 0xfc7f).ram();
1421 	map(0xfc80, 0xfcff).rw(FUNC(fm7_state::fm7_main_shared_r), FUNC(fm7_state::fm7_main_shared_w));
1422 	// I/O space (FD00-FDFF)
1423 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1424 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1425 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1426 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1427 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1428 	map(0xfd06, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1429 	map(0xfd0d, 0xfd0d).rw(FUNC(fm7_state::fm7_psg_select_r), FUNC(fm7_state::fm7_psg_select_w));
1430 	map(0xfd0e, 0xfd0e).rw(FUNC(fm7_state::fm7_psg_data_r), FUNC(fm7_state::fm7_psg_data_w));
1431 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1432 	map(0xfd10, 0xfd17).r(FUNC(fm7_state::fm7_unknown_r));
1433 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1434 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1435 	map(0xfd24, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1436 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1437 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1438 	map(0xfd40, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1439 	// Boot ROM
1440 	map(0xfe00, 0xffdf).bankr("bank17");
1441 	map(0xffe0, 0xffef).ram();
1442 	map(0xfff0, 0xffff).rw(FUNC(fm7_state::vector_r), FUNC(fm7_state::vector_w));
1443 }
1444 
fm8_mem(address_map & map)1445 void fm7_state::fm8_mem(address_map &map)
1446 {
1447 	map(0x0000, 0x7fff).ram();
1448 	map(0x8000, 0xfbff).bankr("bank1").bankw("bank2"); // also F-BASIC ROM, when enabled
1449 	map(0xfc00, 0xfc7f).ram();
1450 	map(0xfc80, 0xfcff).rw(FUNC(fm7_state::fm7_main_shared_r), FUNC(fm7_state::fm7_main_shared_w));
1451 	// I/O space (FD00-FDFF)
1452 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1453 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1454 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1455 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1456 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1457 	map(0xfd06, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1458 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1459 	map(0xfd10, 0xfd17).r(FUNC(fm7_state::fm7_unknown_r));
1460 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1461 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1462 	map(0xfd24, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1463 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1464 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1465 	map(0xfd40, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1466 	// Boot ROM
1467 	map(0xfe00, 0xffdf).bankr("bank17");
1468 	map(0xffe0, 0xffef).ram();
1469 	map(0xfff0, 0xffff).rw(FUNC(fm7_state::vector_r), FUNC(fm7_state::vector_w));
1470 }
1471 
1472 /*
1473    0000 - 3FFF: Video RAM bank 0 (Blue plane)
1474    4000 - 7FFF: Video RAM bank 1 (Red plane)
1475    8000 - BFFF: Video RAM bank 2 (Green plane)
1476    D000 - D37F: (RAM) working area
1477    D380 - D3FF: Shared RAM between main and sub CPU
1478    D400 - D4FF: I/O ports
1479    D800 - FFDF: (ROM) Graphics command code
1480    FFF0 - FFFF: Interrupt vector table
1481 */
1482 
fm7_sub_mem(address_map & map)1483 void fm7_state::fm7_sub_mem(address_map &map)
1484 {
1485 	map(0x0000, 0xbfff).rw(FUNC(fm7_state::fm7_vram_r), FUNC(fm7_state::fm7_vram_w)); // VRAM
1486 	map(0xc000, 0xcfff).ram(); // Console RAM
1487 	map(0xd000, 0xd37f).ram(); // Work RAM
1488 	map(0xd380, 0xd3ff).ram().share("shared_ram");
1489 	// I/O space (D400-D4FF)
1490 	map(0xd400, 0xd401).r(FUNC(fm7_state::fm7_sub_keyboard_r));
1491 	map(0xd402, 0xd402).r(FUNC(fm7_state::fm7_cancel_ack));
1492 	map(0xd403, 0xd403).r(FUNC(fm7_state::fm7_sub_beeper_r));
1493 	map(0xd404, 0xd404).r(FUNC(fm7_state::fm7_attn_irq_r));
1494 	map(0xd408, 0xd408).rw(FUNC(fm7_state::fm7_crt_r), FUNC(fm7_state::fm7_crt_w));
1495 	map(0xd409, 0xd409).rw(FUNC(fm7_state::fm7_vram_access_r), FUNC(fm7_state::fm7_vram_access_w));
1496 	map(0xd40a, 0xd40a).rw(FUNC(fm7_state::fm7_sub_busyflag_r), FUNC(fm7_state::fm7_sub_busyflag_w));
1497 	map(0xd40e, 0xd40f).w(FUNC(fm7_state::fm7_vram_offset_w));
1498 	map(0xd800, 0xffff).rom();
1499 }
1500 
fm11_mem(address_map & map)1501 void fm7_state::fm11_mem(address_map &map)
1502 {
1503 	for (int bank = 0; bank < 16; bank++)
1504 	{
1505 		map(bank << 12, (bank << 12) | 0x0fff).rw(m_avbank[bank], FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8));
1506 	}
1507 	map(0xfc00, 0xfc7f).ram();
1508 	map(0xfc80, 0xfcff).rw(FUNC(fm7_state::fm7_main_shared_r), FUNC(fm7_state::fm7_main_shared_w));
1509 	// I/O space (FD00-FDFF)
1510 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1511 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1512 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1513 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1514 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1515 	map(0xfd06, 0xfd0a).r(FUNC(fm7_state::fm7_unknown_r));
1516 	map(0xfd0b, 0xfd0b).r(FUNC(fm7_state::fm77av_boot_mode_r));
1517 	map(0xfd0c, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1518 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1519 	map(0xfd10, 0xfd10).w(FUNC(fm7_state::fm7_init_en_w));
1520 	map(0xfd11, 0xfd11).r(FUNC(fm7_state::fm7_unknown_r));
1521 	map(0xfd12, 0xfd12).rw(FUNC(fm7_state::fm77av_sub_modestatus_r), FUNC(fm7_state::fm77av_sub_modestatus_w));
1522 	map(0xfd13, 0xfd13).w(FUNC(fm7_state::fm77av_sub_bank_w));
1523 	map(0xfd14, 0xfd14).r(FUNC(fm7_state::fm7_unknown_r));
1524 	map(0xfd17, 0xfd17).r(FUNC(fm7_state::fm7_fmirq_r));
1525 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1526 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1527 	map(0xfd24, 0xfd2b).r(FUNC(fm7_state::fm7_unknown_r));
1528 	map(0xfd30, 0xfd34).w(FUNC(fm7_state::fm77av_analog_palette_w));
1529 	map(0xfd35, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1530 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1531 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1532 	map(0xfd40, 0xfd7f).r(FUNC(fm7_state::fm7_unknown_r));
1533 	map(0xfd80, 0xfd93).rw(FUNC(fm7_state::fm7_mmr_r), FUNC(fm7_state::fm7_mmr_w));
1534 	map(0xfd94, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1535 	map(0xfe00, 0xffdf).ram().w(FUNC(fm7_state::fm77av_bootram_w)).share("boot_ram");
1536 	map(0xffe0, 0xffef).ram();
1537 	map(0xfff0, 0xffff).rw(FUNC(fm7_state::vector_r), FUNC(fm7_state::vector_w));
1538 }
1539 
1540 // Much of this is guesswork at the moment
fm11_sub_mem(address_map & map)1541 void fm7_state::fm11_sub_mem(address_map &map)
1542 {
1543 	map(0x0000, 0x7fff).rw(FUNC(fm7_state::fm7_vram_r), FUNC(fm7_state::fm7_vram_w)); // VRAM
1544 	map(0x8000, 0x8fff).ram(); // Console RAM(?)
1545 	map(0x9000, 0x9f7f).ram(); // Work RAM(?)
1546 	map(0x9f80, 0x9fff).ram().share("shared_ram");
1547 	map(0xafe0, 0xafe3).ram();
1548 //  map(0xafe4, 0xafe4).rw(FUNC(fm7_state::fm7_sub_busyflag_r), FUNC(fm7_state::fm7_sub_busyflag_w));
1549 	map(0xafe6, 0xafe6).rw(FUNC(fm7_state::fm77av_video_flags_r), FUNC(fm7_state::fm77av_video_flags_w));
1550 	map(0xaff0, 0xaff0).rw(FUNC(fm7_state::fm7_sub_busyflag_r), FUNC(fm7_state::fm7_sub_busyflag_w));
1551 	map(0xc000, 0xffff).rom(); // sybsystem ROM
1552 }
1553 
fm11_x86_mem(address_map & map)1554 void fm7_state::fm11_x86_mem(address_map &map)
1555 {
1556 	map.unmap_value_high();
1557 	map(0x00000, 0xfefff).ram();
1558 	map(0xff000, 0xfffff).rom();
1559 }
1560 
fm11_x86_io(address_map & map)1561 void fm7_state::fm11_x86_io(address_map &map)
1562 {
1563 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1564 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1565 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1566 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1567 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1568 	map(0xfd06, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1569 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1570 	map(0xfd10, 0xfd17).r(FUNC(fm7_state::fm7_unknown_r));
1571 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1572 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1573 	map(0xfd24, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1574 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1575 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1576 	map(0xfd40, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1577 }
1578 
fm16_mem(address_map & map)1579 void fm7_state::fm16_mem(address_map &map)
1580 {
1581 	map(0x00000, 0xfbfff).ram();
1582 	map(0xfc000, 0xfffff).rom(); // IPL
1583 }
1584 
fm16_io(address_map & map)1585 void fm7_state::fm16_io(address_map &map)
1586 {
1587 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1588 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1589 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1590 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1591 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1592 //  map(0xfd06, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1593 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1594 //  map(0xfd10, 0xfd17).r(FUNC(fm7_state::fm7_unknown_r));
1595 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1596 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1597 //  map(0xfd24, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1598 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1599 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1600 //  map(0xfd40, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1601 }
1602 
fm16_sub_mem(address_map & map)1603 void fm7_state::fm16_sub_mem(address_map &map)
1604 {
1605 	map(0x0000, 0xafff).rw(FUNC(fm7_state::fm7_vram_r), FUNC(fm7_state::fm7_vram_w)); // VRAM
1606 	map(0xb000, 0xffff).rom(); // subsystem ROM
1607 }
1608 
fm77av_mem(address_map & map)1609 void fm7_state::fm77av_mem(address_map &map)
1610 {
1611 	for (int bank = 0; bank < 16; bank++)
1612 	{
1613 		map(bank << 12, (bank << 12) | 0x0fff).rw(m_avbank[bank], FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8));
1614 	}
1615 	map(0xfc00, 0xfc7f).ram();
1616 	map(0xfc80, 0xfcff).rw(FUNC(fm7_state::fm7_main_shared_r), FUNC(fm7_state::fm7_main_shared_w));
1617 	// I/O space (FD00-FDFF)
1618 	map(0xfd00, 0xfd01).rw(FUNC(fm7_state::fm7_keyboard_r), FUNC(fm7_state::fm7_cassette_printer_w));
1619 	map(0xfd02, 0xfd02).rw(FUNC(fm7_state::fm7_cassette_printer_r), FUNC(fm7_state::fm7_irq_mask_w));  // IRQ mask
1620 	map(0xfd03, 0xfd03).rw(FUNC(fm7_state::fm7_irq_cause_r), FUNC(fm7_state::fm7_beeper_w));  // IRQ flags
1621 	map(0xfd04, 0xfd04).r(FUNC(fm7_state::fm7_fd04_r));
1622 	map(0xfd05, 0xfd05).rw(FUNC(fm7_state::fm7_subintf_r), FUNC(fm7_state::fm7_subintf_w));
1623 	map(0xfd06, 0xfd0a).r(FUNC(fm7_state::fm7_unknown_r));
1624 	map(0xfd0b, 0xfd0b).r(FUNC(fm7_state::fm77av_boot_mode_r));
1625 	map(0xfd0c, 0xfd0c).r(FUNC(fm7_state::fm7_unknown_r));
1626 	map(0xfd0d, 0xfd0d).rw(FUNC(fm7_state::fm7_psg_select_r), FUNC(fm7_state::fm7_psg_select_w));
1627 	map(0xfd0e, 0xfd0e).rw(FUNC(fm7_state::fm7_psg_data_r), FUNC(fm7_state::fm7_psg_data_w));
1628 	map(0xfd0f, 0xfd0f).rw(FUNC(fm7_state::fm7_rom_en_r), FUNC(fm7_state::fm7_rom_en_w));
1629 	map(0xfd10, 0xfd10).w(FUNC(fm7_state::fm7_init_en_w));
1630 	map(0xfd11, 0xfd11).r(FUNC(fm7_state::fm7_unknown_r));
1631 	map(0xfd12, 0xfd12).rw(FUNC(fm7_state::fm77av_sub_modestatus_r), FUNC(fm7_state::fm77av_sub_modestatus_w));
1632 	map(0xfd13, 0xfd13).w(FUNC(fm7_state::fm77av_sub_bank_w));
1633 	map(0xfd14, 0xfd14).r(FUNC(fm7_state::fm7_unknown_r));
1634 	map(0xfd15, 0xfd15).rw(FUNC(fm7_state::fm7_psg_select_r), FUNC(fm7_state::fm77av_ym_select_w));
1635 	map(0xfd16, 0xfd16).rw(FUNC(fm7_state::fm7_psg_data_r), FUNC(fm7_state::fm7_psg_data_w));
1636 	map(0xfd17, 0xfd17).r(FUNC(fm7_state::fm7_fmirq_r));
1637 	map(0xfd18, 0xfd1f).rw(FUNC(fm7_state::fm7_fdc_r), FUNC(fm7_state::fm7_fdc_w));
1638 	map(0xfd20, 0xfd23).rw(FUNC(fm7_state::fm7_kanji_r), FUNC(fm7_state::fm7_kanji_w));
1639 	map(0xfd24, 0xfd2b).r(FUNC(fm7_state::fm7_unknown_r));
1640 	map(0xfd30, 0xfd34).w(FUNC(fm7_state::fm77av_analog_palette_w));
1641 	map(0xfd35, 0xfd36).r(FUNC(fm7_state::fm7_unknown_r));
1642 	map(0xfd37, 0xfd37).w(FUNC(fm7_state::fm7_multipage_w));
1643 	map(0xfd38, 0xfd3f).rw(FUNC(fm7_state::fm7_palette_r), FUNC(fm7_state::fm7_palette_w));
1644 	map(0xfd40, 0xfd7f).r(FUNC(fm7_state::fm7_unknown_r));
1645 	map(0xfd80, 0xfd93).rw(FUNC(fm7_state::fm7_mmr_r), FUNC(fm7_state::fm7_mmr_w));
1646 	map(0xfd94, 0xfdff).r(FUNC(fm7_state::fm7_unknown_r));
1647 	// Boot ROM (RAM on FM77AV and later)
1648 	map(0xfe00, 0xffdf).ram().w(FUNC(fm7_state::fm77av_bootram_w)).share("boot_ram");
1649 	map(0xffe0, 0xffef).ram();
1650 	map(0xfff0, 0xffff).rw(FUNC(fm7_state::vector_r), FUNC(fm7_state::vector_w));
1651 }
1652 
fm77av_sub_mem(address_map & map)1653 void fm7_state::fm77av_sub_mem(address_map &map)
1654 {
1655 	map(0x0000, 0xbfff).rw(FUNC(fm7_state::fm7_vram_r), FUNC(fm7_state::fm7_vram_w)); // VRAM
1656 	map(0xc000, 0xcfff).ram().region("maincpu", 0x1c000); // Console RAM
1657 	map(0xd000, 0xd37f).ram().region("maincpu", 0x1d000); // Work RAM
1658 	map(0xd380, 0xd3ff).ram().share("shared_ram");
1659 	// I/O space (D400-D4FF)
1660 	map(0xd400, 0xd401).r(FUNC(fm7_state::fm7_sub_keyboard_r));
1661 	map(0xd402, 0xd402).r(FUNC(fm7_state::fm7_cancel_ack));
1662 	map(0xd403, 0xd403).r(FUNC(fm7_state::fm7_sub_beeper_r));
1663 	map(0xd404, 0xd404).r(FUNC(fm7_state::fm7_attn_irq_r));
1664 	map(0xd408, 0xd408).rw(FUNC(fm7_state::fm7_crt_r), FUNC(fm7_state::fm7_crt_w));
1665 	map(0xd409, 0xd409).rw(FUNC(fm7_state::fm7_vram_access_r), FUNC(fm7_state::fm7_vram_access_w));
1666 	map(0xd40a, 0xd40a).rw(FUNC(fm7_state::fm7_sub_busyflag_r), FUNC(fm7_state::fm7_sub_busyflag_w));
1667 	map(0xd40e, 0xd40f).w(FUNC(fm7_state::fm7_vram_offset_w));
1668 	map(0xd410, 0xd42b).rw(FUNC(fm7_state::fm77av_alu_r), FUNC(fm7_state::fm77av_alu_w));
1669 	map(0xd430, 0xd430).rw(FUNC(fm7_state::fm77av_video_flags_r), FUNC(fm7_state::fm77av_video_flags_w));
1670 	map(0xd431, 0xd432).rw(FUNC(fm7_state::fm77av_key_encoder_r), FUNC(fm7_state::fm77av_key_encoder_w));
1671 	map(0xd500, 0xd7ff).ram().region("maincpu", 0x1d500); // Work RAM
1672 	map(0xd800, 0xdfff).bankr("bank20");
1673 	map(0xe000, 0xffff).bankr("bank21");
1674 }
1675 
fm7_banked_mem(address_map & map)1676 void fm7_state::fm7_banked_mem(address_map &map)
1677 {
1678 	// Extended RAM
1679 	map(0x00000, 0x0ffff).ram().region("maincpu", 0x00000);
1680 
1681 	// Sub CPU space
1682 	map(0x10000, 0x1bfff).rw(FUNC(fm7_state::fm7_vram_r), FUNC(fm7_state::fm7_vram_w)); // VRAM
1683 	map(0x1c000, 0x1cfff).ram().region("maincpu", 0x1c000); // Console RAM
1684 	map(0x1d000, 0x1d37f).ram().region("maincpu", 0x1d000); // Work RAM
1685 	map(0x1d380, 0x1d3ff).ram().share("shared_ram");
1686 	// I/O space (D400-D4FF)
1687 	map(0x1d400, 0x1d401).r(FUNC(fm7_state::fm7_sub_keyboard_r));
1688 	map(0x1d402, 0x1d402).r(FUNC(fm7_state::fm7_cancel_ack));
1689 	map(0x1d403, 0x1d403).r(FUNC(fm7_state::fm7_sub_beeper_r));
1690 	map(0x1d404, 0x1d404).r(FUNC(fm7_state::fm7_attn_irq_r));
1691 	map(0x1d408, 0x1d408).rw(FUNC(fm7_state::fm7_crt_r), FUNC(fm7_state::fm7_crt_w));
1692 	map(0x1d409, 0x1d409).rw(FUNC(fm7_state::fm7_vram_access_r), FUNC(fm7_state::fm7_vram_access_w));
1693 	map(0x1d40a, 0x1d40a).rw(FUNC(fm7_state::fm7_sub_busyflag_r), FUNC(fm7_state::fm7_sub_busyflag_w));
1694 	map(0x1d40e, 0x1d40f).w(FUNC(fm7_state::fm7_vram_offset_w));
1695 	map(0x1d410, 0x1d42b).rw(FUNC(fm7_state::fm77av_alu_r), FUNC(fm7_state::fm77av_alu_w));
1696 	map(0x1d430, 0x1d430).rw(FUNC(fm7_state::fm77av_video_flags_r), FUNC(fm7_state::fm77av_video_flags_w));
1697 	map(0x1d431, 0x1d432).rw(FUNC(fm7_state::fm77av_key_encoder_r), FUNC(fm7_state::fm77av_key_encoder_w));
1698 	map(0x1d500, 0x1d7ff).ram().region("maincpu", 0x1d500); // Work RAM
1699 	map(0x1d800, 0x1dfff).bankr("bank20");
1700 	map(0x1e000, 0x1ffff).bankr("bank21");
1701 
1702 	// more RAM?
1703 	map(0x20000, 0x2ffff).ram().region("maincpu", 0x20000);
1704 
1705 	// Main CPU space
1706 	map(0x30000, 0x35fff).ram().region("maincpu", 0x30000);
1707 	map(0x36000, 0x37fff).bankr("init_bank_r").bankw("init_bank_w");
1708 	map(0x38000, 0x3fbff).bankr("fbasic_bank_r").bankw("fbasic_bank_w");
1709 	map(0x3fc00, 0x3ffff).ram().region("maincpu", 0x3fc00);
1710 
1711 }
1712 
1713 /* Input ports */
1714 INPUT_PORTS_START( fm7_keyboard )
1715 	PORT_START("key1")
1716 	PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_UNUSED)
PORT_CODE(KEYCODE_TILDE)1717 	PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(27)
1718 	PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
1719 	PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
1720 	PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
1721 	PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
1722 	PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
1723 	PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
1724 	PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
1725 	PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
1726 	PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
1727 	PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
1728 	PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')  PORT_CHAR('=')
1729 	PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^')
1730 	PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xEF\xBF\xA5") PORT_CHAR(165) PORT_CHAR('|')
1731 	PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
1732 	PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
1733 	PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
1734 	PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
1735 	PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
1736 	PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
1737 	PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
1738 	PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
1739 	PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
1740 	PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
1741 	PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
1742 	PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
1743 	PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`')
1744 	PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR('{')
1745 	PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
1746 	PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
1747 	PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
1748 
1749 	PORT_START("key2")
1750 	PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
1751 	PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
1752 	PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
1753 	PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
1754 	PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
1755 	PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
1756 	PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
1757 	PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
1758 	PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')
1759 	PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}')
1760 	PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
1761 	PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
1762 	PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
1763 	PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
1764 	PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
1765 	PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
1766 	PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
1767 	PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
1768 	PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
1769 	PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
1770 	PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("_") PORT_CHAR('"') PORT_CHAR('_')
1771 	PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
1772 	PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey *") PORT_CODE(KEYCODE_ASTERISK)
1773 	PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey /") PORT_CODE(KEYCODE_SLASH_PAD)
1774 	PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey +") PORT_CODE(KEYCODE_PLUS_PAD)
1775 	PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey -") PORT_CODE(KEYCODE_MINUS_PAD)
1776 	PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 7") PORT_CODE(KEYCODE_7_PAD)
1777 	PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 8") PORT_CODE(KEYCODE_8_PAD)
1778 	PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 9") PORT_CODE(KEYCODE_9_PAD)
1779 	PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey =")
1780 	PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 4") PORT_CODE(KEYCODE_4_PAD)
1781 	PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 5") PORT_CODE(KEYCODE_5_PAD)
1782 
1783 	PORT_START("key3")
1784 	PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 6") PORT_CODE(KEYCODE_6_PAD)
1785 	PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey ,")
1786 	PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 1") PORT_CODE(KEYCODE_1_PAD)
1787 	PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 2") PORT_CODE(KEYCODE_2_PAD)
1788 	PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 3") PORT_CODE(KEYCODE_3_PAD)
1789 	PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey Enter") PORT_CODE(KEYCODE_ENTER_PAD)
1790 	PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey 0") PORT_CODE(KEYCODE_0_PAD)
1791 	PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tenkey .") PORT_CODE(KEYCODE_DEL_PAD)
1792 	PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT)
1793 	PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("EL") PORT_CODE(KEYCODE_PGUP)
1794 	PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CLS") PORT_CODE(KEYCODE_PGDN)
1795 	PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL)
1796 	PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DUP") PORT_CODE(KEYCODE_END)
1797 	PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
1798 	PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME)
1799 	PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
1800 	PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
1801 	PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT)
1802 	PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CODE(KEYCODE_ESC)
1803 	PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1)
1804 	PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2)
1805 	PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3)
1806 	PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4)
1807 	PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF5") PORT_CODE(KEYCODE_F5)
1808 	PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF6") PORT_CODE(KEYCODE_F6)
1809 	PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF7") PORT_CODE(KEYCODE_F7)
1810 	PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF8") PORT_CODE(KEYCODE_F8)
1811 	PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF9") PORT_CODE(KEYCODE_F9)
1812 	PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF10") PORT_CODE(KEYCODE_F10)
1813 
1814 	PORT_START("key_modifiers")
1815 	PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
1816 	PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
1817 	PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT)
1818 	PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CAP") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_TOGGLE
1819 	PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_RALT)
1820 	PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Kana") PORT_CODE(KEYCODE_RCONTROL) PORT_TOGGLE
1821 
1822 	PORT_START("joy1")
1823 	PORT_BIT(0x01,IP_ACTIVE_LOW,IPT_JOYSTICK_UP) PORT_NAME("1P Joystick Up") PORT_8WAY PORT_PLAYER(1)
1824 	PORT_BIT(0x02,IP_ACTIVE_LOW,IPT_JOYSTICK_DOWN) PORT_NAME("1P Joystick Down") PORT_8WAY PORT_PLAYER(1)
1825 	PORT_BIT(0x04,IP_ACTIVE_LOW,IPT_JOYSTICK_LEFT) PORT_NAME("1P Joystick Left") PORT_8WAY PORT_PLAYER(1)
1826 	PORT_BIT(0x08,IP_ACTIVE_LOW,IPT_JOYSTICK_RIGHT) PORT_NAME("1P Joystick Right") PORT_8WAY PORT_PLAYER(1)
1827 	PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_BUTTON2) PORT_NAME("1P Joystick Button 2") PORT_PLAYER(1)
1828 	PORT_BIT(0x20,IP_ACTIVE_LOW,IPT_BUTTON1) PORT_NAME("1P Joystick Button 1") PORT_PLAYER(1)
1829 	PORT_BIT(0x40,IP_ACTIVE_LOW,IPT_UNUSED)
1830 	PORT_BIT(0x80,IP_ACTIVE_LOW,IPT_UNUSED)
1831 
1832 	PORT_START("joy2")
1833 	PORT_BIT(0x01,IP_ACTIVE_LOW,IPT_JOYSTICK_UP) PORT_NAME("2P Joystick Up") PORT_8WAY PORT_PLAYER(2)
1834 	PORT_BIT(0x02,IP_ACTIVE_LOW,IPT_JOYSTICK_DOWN) PORT_NAME("2P Joystick Down") PORT_8WAY PORT_PLAYER(2)
1835 	PORT_BIT(0x04,IP_ACTIVE_LOW,IPT_JOYSTICK_LEFT) PORT_NAME("2P Joystick Left") PORT_8WAY PORT_PLAYER(2)
1836 	PORT_BIT(0x08,IP_ACTIVE_LOW,IPT_JOYSTICK_RIGHT) PORT_NAME("2P Joystick Right") PORT_8WAY PORT_PLAYER(2)
1837 	PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_BUTTON2) PORT_NAME("2P Joystick Button 2") PORT_PLAYER(2)
1838 	PORT_BIT(0x20,IP_ACTIVE_LOW,IPT_BUTTON1) PORT_NAME("2P Joystick Button 1") PORT_PLAYER(2)
1839 	PORT_BIT(0x40,IP_ACTIVE_LOW,IPT_UNUSED)
1840 	PORT_BIT(0x80,IP_ACTIVE_LOW,IPT_UNUSED)
1841 INPUT_PORTS_END
1842 
1843 static INPUT_PORTS_START( fm7 )
1844 	PORT_INCLUDE( fm7_keyboard )
1845 
1846 	PORT_START("DSW")
1847 	PORT_DIPNAME(0x01,0x01,"Switch A") PORT_DIPLOCATION("SWA:1")
1848 	PORT_DIPSETTING(0x00,DEF_STR( Off ))
1849 	PORT_DIPSETTING(0x01,DEF_STR( On ))
1850 	PORT_DIPNAME(0x02,0x02,"Boot mode") PORT_DIPLOCATION("SWA:2")
1851 	PORT_DIPSETTING(0x00,"DOS")
1852 	PORT_DIPSETTING(0x02,"BASIC")
1853 	PORT_DIPNAME(0x04,0x00,"Switch C") PORT_DIPLOCATION("SWA:3")
1854 	PORT_DIPSETTING(0x00,DEF_STR( Off ))
1855 	PORT_DIPSETTING(0x04,DEF_STR( On ))
1856 	PORT_DIPNAME(0x08,0x00,"FM-8 Compatibility mode") PORT_DIPLOCATION("SWA:4")
1857 	PORT_DIPSETTING(0x00,DEF_STR( Off ))
1858 	PORT_DIPSETTING(0x08,DEF_STR( On ))
1859 INPUT_PORTS_END
1860 
1861 static INPUT_PORTS_START( fm8 )
1862 	PORT_INCLUDE( fm7_keyboard )
1863 
1864 	PORT_START("DSW")
1865 	PORT_DIPNAME(0x02,0x02,"Boot mode") PORT_DIPLOCATION("SWA:2")
1866 	PORT_DIPSETTING(0x00,"DOS")
1867 	PORT_DIPSETTING(0x02,"BASIC")
1868 INPUT_PORTS_END
1869 
1870 void fm7_state::init_fm7()
1871 {
1872 //  m_shared_ram = std::make_unique<uint8_t[]>(0x80);
1873 	m_video_ram = std::make_unique<uint8_t[]>(0x18000);  // 2 pages on some systems
1874 	m_timer = timer_alloc(TIMER_FM7_IRQ);
1875 	m_subtimer = timer_alloc(TIMER_FM7_SUBTIMER_IRQ);
1876 	m_keyboard_timer = timer_alloc(TIMER_FM7_KEYBOARD_POLL);
1877 	m_fm77av_vsync_timer = timer_alloc(TIMER_FM77AV_VSYNC);
1878 }
1879 
MACHINE_START_MEMBER(fm7_state,fm7)1880 MACHINE_START_MEMBER(fm7_state,fm7)
1881 {
1882 	// The FM-7 has no initialisation ROM, and no other obvious
1883 	// way to set the reset vector, so for now this will have to do.
1884 	uint8_t* RAM = memregion("maincpu")->base();
1885 
1886 	RAM[0xfffe] = 0xfe;
1887 	RAM[0xffff] = 0x00;
1888 
1889 	memset(m_shared_ram,0xff,0x80);
1890 	m_type = SYS_FM7;
1891 
1892 	m_beeper->set_state(0);
1893 }
1894 
MACHINE_START_MEMBER(fm7_state,fm77av)1895 MACHINE_START_MEMBER(fm7_state,fm77av)
1896 {
1897 	uint8_t* RAM = memregion("maincpu")->base();
1898 	uint8_t* ROM = memregion("init")->base();
1899 
1900 	memset(m_shared_ram,0xff,0x80);
1901 
1902 	// last part of Initiate ROM is visible at the end of RAM too (interrupt vectors)
1903 	memcpy(RAM+0x3fff0,ROM+0x1ff0,16);
1904 
1905 	m_video.subrom = 0;  // default sub CPU ROM is type C.
1906 	RAM = memregion("subsyscg")->base();
1907 	membank("bank20")->set_base(RAM);
1908 	RAM = memregion("subsys_c")->base();
1909 	membank("bank21")->set_base(RAM+0x800);
1910 
1911 	m_type = SYS_FM77AV;
1912 	m_beeper->set_state(0);
1913 }
1914 
MACHINE_START_MEMBER(fm7_state,fm11)1915 MACHINE_START_MEMBER(fm7_state,fm11)
1916 {
1917 	uint8_t* RAM = memregion("maincpu")->base();
1918 	uint8_t* ROM = memregion("init")->base();
1919 
1920 	memset(m_shared_ram,0xff,0x80);
1921 	m_type = SYS_FM11;
1922 	m_beeper->set_state(0);
1923 	// last part of Initiate ROM is visible at the end of RAM too (interrupt vectors)
1924 	memcpy(RAM+0x3fff0,ROM+0x0ff0,16);
1925 }
1926 
MACHINE_START_MEMBER(fm7_state,fm16)1927 MACHINE_START_MEMBER(fm7_state,fm16)
1928 {
1929 	m_type = SYS_FM16;
1930 	m_beeper->set_state(0);
1931 }
1932 
machine_reset()1933 void fm7_state::machine_reset()
1934 {
1935 	m_timer->adjust(attotime::from_nsec(2034500),0,attotime::from_nsec(2034500));
1936 	m_subtimer->adjust(attotime::from_msec(20),0,attotime::from_msec(20));
1937 	m_keyboard_timer->adjust(attotime::zero,0,attotime::from_msec(10));
1938 	if(m_type == SYS_FM77AV || m_type == SYS_FM77AV40EX || m_type == SYS_FM11)
1939 		m_fm77av_vsync_timer->adjust(m_screen->time_until_vblank_end());
1940 
1941 	m_irq_mask = 0x00;
1942 	m_irq_flags = 0x00;
1943 	m_video.attn_irq = 0;
1944 	m_video.sub_busy = 0x80;  // busy at reset
1945 	m_basic_rom_en = 1;  // enabled at reset, if in BASIC mode
1946 	if(m_type == SYS_FM11 || m_type == SYS_FM16)
1947 		m_basic_rom_en = 0;  // all FM11/16 systems have no BASIC ROM except for the FM-11 ST
1948 	if(m_type == SYS_FM77AV || m_type == SYS_FM77AV40EX)
1949 	{
1950 		m_init_rom_en = 1;
1951 		// last part of Initiate ROM is visible at the end of RAM too (interrupt vectors)
1952 		memcpy(m_ram_ptr + 0x3fff0, m_rom_ptr + 0x1ff0, 16);
1953 	}
1954 	else if (m_type == SYS_FM11)
1955 	{
1956 		m_init_rom_en = 1;
1957 		// last part of Initiate ROM is visible at the end of RAM too (interrupt vectors)
1958 		memcpy(m_ram_ptr + 0x3fff0, m_rom_ptr + 0x0ff0, 16);
1959 	}
1960 	else
1961 		m_init_rom_en = 0;
1962 	if(m_type == SYS_FM7)
1963 	{
1964 		if(!(m_dsw->read() & 0x02))
1965 		{
1966 			m_basic_rom_en = 0;  // disabled for DOS mode
1967 			membank("bank1")->set_base(m_ram_ptr + 0x08000);
1968 		}
1969 		else
1970 		{
1971 			membank("bank1")->set_base(m_ram_ptr + 0x38000);
1972 		}
1973 		membank("bank2")->set_base(m_ram_ptr + 0x08000);
1974 	}
1975 	m_key_delay = 700;  // 700ms on FM-7
1976 	m_key_repeat = 70;  // 70ms on FM-7
1977 	m_break_flag = 0;
1978 	m_key_scan_mode = KEY_MODE_FM7;
1979 	m_psg_regsel = 0;
1980 	m_psg_data = 0;
1981 	m_fdc_side = 0;
1982 	m_fdc_drive = 0;
1983 	m_mmr.mode = 0;
1984 	m_mmr.segment = 0;
1985 	m_mmr.enabled = 0;
1986 	m_fm77av_ym_irq = 0;
1987 	m_encoder.latch = 1;
1988 	m_encoder.ack = 1;
1989 	// set boot mode (FM-7 only, AV and later has boot RAM instead)
1990 	if(m_type == SYS_FM7)
1991 	{
1992 		if(!(m_dsw->read() & 0x02))
1993 		{  // DOS mode
1994 			membank("bank17")->set_base(memregion("dos")->base());
1995 		}
1996 		else
1997 		{  // BASIC mode
1998 			membank("bank17")->set_base(memregion("basic")->base());
1999 		}
2000 	}
2001 	if(m_type == SYS_FM77AV || m_type == SYS_FM77AV40EX || m_type == SYS_FM11)
2002 	{
2003 		fm7_mmr_refresh(m_maincpu->space(AS_PROGRAM));
2004 		membank("fbasic_bank_w")->set_base(m_ram_ptr + 0x38000);
2005 		membank("init_bank_w")->set_base(m_ram_ptr + 0x36000);
2006 	}
2007 	if(m_type == SYS_FM11)
2008 	{
2009 		// Probably best to halt the 8088, I'm pretty sure it and the main 6809 should not be running at the same time
2010 		m_x86->set_input_line(INPUT_LINE_HALT,ASSERT_LINE);
2011 	}
2012 
2013 	memset(m_video_ram.get(), 0, sizeof(uint8_t) * 0x18000);
2014 }
2015 
2016 
fm7_floppies(device_slot_interface & device)2017 static void fm7_floppies(device_slot_interface &device)
2018 {
2019 	device.option_add("qd", FLOPPY_525_QD);
2020 }
2021 
2022 
fm7(machine_config & config)2023 void fm7_state::fm7(machine_config &config)
2024 {
2025 	/* basic machine hardware */
2026 	MC6809(config, m_maincpu, 16.128_MHz_XTAL / 2);
2027 	m_maincpu->set_addrmap(AS_PROGRAM, &fm7_state::fm7_mem);
2028 	m_maincpu->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_irq_ack));
2029 
2030 	MC6809(config, m_sub, 16.128_MHz_XTAL / 2);
2031 	m_sub->set_addrmap(AS_PROGRAM, &fm7_state::fm7_sub_mem);
2032 	m_sub->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_sub_irq_ack));
2033 	config.set_perfect_quantum(m_sub);
2034 
2035 	SPEAKER(config, "mono").front_center();
2036 	AY8910(config, m_psg, 4.9152_MHz_XTAL / 4).add_route(ALL_OUTPUTS,"mono", 1.00);
2037 	BEEP(config, "beeper", 1200).add_route(ALL_OUTPUTS, "mono", 0.50);
2038 
2039 	MCFG_MACHINE_START_OVERRIDE(fm7_state,fm7)
2040 
2041 	/* video hardware */
2042 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2043 	m_screen->set_raw(16.128_MHz_XTAL, 1024, 0, 640, 262, 0, 200); // H = 15.75 KHz, V = 60.1145 Hz
2044 	m_screen->set_screen_update(FUNC(fm7_state::screen_update_fm7));
2045 
2046 	PALETTE(config, m_palette, palette_device::BRG_3BIT);
2047 
2048 	CASSETTE(config, m_cassette);
2049 	m_cassette->set_formats(fm7_cassette_formats);
2050 	m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
2051 	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
2052 	m_cassette->set_interface("fm7_cass");
2053 
2054 	SOFTWARE_LIST(config, "cass_list").set_original("fm7_cass");
2055 
2056 	MB8877(config, m_fdc, 8_MHz_XTAL / 8);
2057 	m_fdc->intrq_wr_callback().set(FUNC(fm7_state::fm7_fdc_intrq_w));
2058 	m_fdc->drq_wr_callback().set(FUNC(fm7_state::fm7_fdc_drq_w));
2059 
2060 	FLOPPY_CONNECTOR(config, m_floppy0, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2061 	FLOPPY_CONNECTOR(config, m_floppy1, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2062 
2063 	SOFTWARE_LIST(config, "flop_list").set_original("fm7_disk");
2064 
2065 	CENTRONICS(config, m_centronics, centronics_devices, "printer");
2066 	m_centronics->option_add("dsjoy", DEMPA_SHINBUNSHA_JOYSTICK);
2067 	m_centronics->busy_handler().set(FUNC(fm7_state::write_centronics_busy));
2068 	m_centronics->fault_handler().set(FUNC(fm7_state::write_centronics_fault));
2069 	m_centronics->ack_handler().set(FUNC(fm7_state::write_centronics_ack));
2070 	m_centronics->perror_handler().set(FUNC(fm7_state::write_centronics_perror));
2071 
2072 	OUTPUT_LATCH(config, m_cent_data_out);
2073 	m_centronics->set_output_latch(*m_cent_data_out);
2074 }
2075 
fm8(machine_config & config)2076 void fm7_state::fm8(machine_config &config)
2077 {
2078 	/* basic machine hardware */
2079 	MC6809(config, m_maincpu, 4.9152_MHz_XTAL);  // 1.2MHz 68A09
2080 	m_maincpu->set_addrmap(AS_PROGRAM, &fm7_state::fm8_mem);
2081 	m_maincpu->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_irq_ack));
2082 
2083 	MC6809(config, m_sub, 16.128_MHz_XTAL / 2);
2084 	m_sub->set_addrmap(AS_PROGRAM, &fm7_state::fm7_sub_mem);
2085 	m_sub->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_sub_irq_ack));
2086 	config.set_perfect_quantum(m_sub);
2087 
2088 	SPEAKER(config, "mono").front_center();
2089 	BEEP(config, m_beeper, 1200).add_route(ALL_OUTPUTS, "mono", 0.50);
2090 
2091 	MCFG_MACHINE_START_OVERRIDE(fm7_state,fm7)
2092 
2093 	/* video hardware */
2094 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2095 	m_screen->set_raw(16.128_MHz_XTAL, 1024, 0, 640, 262, 0, 200);
2096 	m_screen->set_screen_update(FUNC(fm7_state::screen_update_fm7));
2097 
2098 	PALETTE(config, m_palette, palette_device::BRG_3BIT);
2099 
2100 	CASSETTE(config, m_cassette);
2101 	m_cassette->set_formats(fm7_cassette_formats);
2102 	m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
2103 	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
2104 	m_cassette->set_interface("fm7_cass");
2105 
2106 	MB8877(config, m_fdc, 8_MHz_XTAL / 8);
2107 	m_fdc->intrq_wr_callback().set(FUNC(fm7_state::fm7_fdc_intrq_w));
2108 	m_fdc->drq_wr_callback().set(FUNC(fm7_state::fm7_fdc_drq_w));
2109 
2110 	FLOPPY_CONNECTOR(config, m_floppy0, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2111 	FLOPPY_CONNECTOR(config, m_floppy1, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2112 
2113 	CENTRONICS(config, m_centronics, centronics_devices, "printer");
2114 	m_centronics->busy_handler().set(FUNC(fm7_state::write_centronics_busy));
2115 	m_centronics->fault_handler().set(FUNC(fm7_state::write_centronics_fault));
2116 	m_centronics->ack_handler().set(FUNC(fm7_state::write_centronics_ack));
2117 	m_centronics->perror_handler().set(FUNC(fm7_state::write_centronics_perror));
2118 
2119 	OUTPUT_LATCH(config, m_cent_data_out);
2120 	m_centronics->set_output_latch(*m_cent_data_out);
2121 }
2122 
fm77av(machine_config & config)2123 void fm7_state::fm77av(machine_config &config)
2124 {
2125 	/* basic machine hardware */
2126 	MC6809E(config, m_maincpu, 16.128_MHz_XTAL / 8);
2127 	m_maincpu->set_addrmap(AS_PROGRAM, &fm7_state::fm77av_mem);
2128 	m_maincpu->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_irq_ack));
2129 
2130 	MC6809E(config, m_sub, 16.128_MHz_XTAL / 8);
2131 	m_sub->set_addrmap(AS_PROGRAM, &fm7_state::fm77av_sub_mem);
2132 	m_sub->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_sub_irq_ack));
2133 	config.set_perfect_quantum(m_sub);
2134 
2135 	SPEAKER(config, "mono").front_center();
2136 	YM2203(config, m_ym, 4.9152_MHz_XTAL / 4);
2137 	m_ym->irq_handler().set(FUNC(fm7_state::fm77av_fmirq));
2138 	m_ym->port_a_read_callback().set_ioport("joy1");
2139 	m_ym->port_b_read_callback().set_ioport("joy2");
2140 	m_ym->add_route(ALL_OUTPUTS,"mono", 1.00);
2141 	BEEP(config, "beeper", 1200).add_route(ALL_OUTPUTS, "mono", 0.50);
2142 
2143 	MCFG_MACHINE_START_OVERRIDE(fm7_state,fm77av)
2144 
2145 	for (int bank = 0; bank < 16; bank++)
2146 	{
2147 		ADDRESS_MAP_BANK(config, m_avbank[bank]).set_map(&fm7_state::fm7_banked_mem).set_options(ENDIANNESS_LITTLE, 8, 32, 0x1000);
2148 	}
2149 
2150 	/* video hardware */
2151 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2152 	m_screen->set_raw(16.128_MHz_XTAL, 1024, 0, 640, 262, 0, 200);
2153 	m_screen->set_screen_update(FUNC(fm7_state::screen_update_fm7));
2154 
2155 	PALETTE(config, m_palette, palette_device::BRG_3BIT);
2156 	PALETTE(config, m_av_palette).set_entries(4096);
2157 
2158 	CASSETTE(config, m_cassette);
2159 	m_cassette->set_formats(fm7_cassette_formats);
2160 	m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
2161 	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
2162 	m_cassette->set_interface("fm7_cass");
2163 
2164 	SOFTWARE_LIST(config, "cass_list").set_compatible("fm7_cass");
2165 
2166 	MB8877(config, m_fdc, 8_MHz_XTAL / 8);
2167 	m_fdc->intrq_wr_callback().set(FUNC(fm7_state::fm7_fdc_intrq_w));
2168 	m_fdc->drq_wr_callback().set(FUNC(fm7_state::fm7_fdc_drq_w));
2169 
2170 	FLOPPY_CONNECTOR(config, m_floppy0, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2171 	FLOPPY_CONNECTOR(config, m_floppy1, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2172 
2173 	SOFTWARE_LIST(config, "av_flop_list").set_original("fm77av");
2174 	SOFTWARE_LIST(config, "flop_list").set_compatible("fm7_disk");
2175 
2176 	CENTRONICS(config, m_centronics, centronics_devices, "printer");
2177 	m_centronics->busy_handler().set(FUNC(fm7_state::write_centronics_busy));
2178 	m_centronics->fault_handler().set(FUNC(fm7_state::write_centronics_fault));
2179 	m_centronics->ack_handler().set(FUNC(fm7_state::write_centronics_ack));
2180 	m_centronics->perror_handler().set(FUNC(fm7_state::write_centronics_perror));
2181 
2182 	OUTPUT_LATCH(config, m_cent_data_out);
2183 	m_centronics->set_output_latch(*m_cent_data_out);
2184 }
2185 
fm11(machine_config & config)2186 void fm7_state::fm11(machine_config &config)
2187 {
2188 	/* basic machine hardware */
2189 	MC6809E(config, m_maincpu, 2000000);  // 2MHz 68B09E
2190 	m_maincpu->set_addrmap(AS_PROGRAM, &fm7_state::fm11_mem);
2191 	m_maincpu->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_irq_ack));
2192 
2193 	MC6809(config, m_sub, 8000000);  // 2MHz 68B09
2194 	m_sub->set_addrmap(AS_PROGRAM, &fm7_state::fm11_sub_mem);
2195 	m_sub->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_sub_irq_ack));
2196 	config.set_perfect_quantum(m_sub);
2197 
2198 	I8088(config, m_x86, 8000000);  // 8MHz i8088
2199 	m_x86->set_addrmap(AS_PROGRAM, &fm7_state::fm11_x86_mem);
2200 	m_x86->set_addrmap(AS_IO, &fm7_state::fm11_x86_io);
2201 
2202 	SPEAKER(config, "mono").front_center();
2203 	BEEP(config, m_beeper, 1200).add_route(ALL_OUTPUTS, "mono", 0.50);
2204 
2205 	MCFG_MACHINE_START_OVERRIDE(fm7_state,fm11)
2206 
2207 	for (int bank = 0; bank < 16; bank++)
2208 	{
2209 		ADDRESS_MAP_BANK(config, m_avbank[bank]).set_map(&fm7_state::fm7_banked_mem).set_options(ENDIANNESS_LITTLE, 8, 32, 0x1000);
2210 	}
2211 
2212 	/* video hardware */
2213 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2214 	m_screen->set_raw(16128000, 1024, 0, 640, 262, 0, 200);
2215 	m_screen->set_screen_update(FUNC(fm7_state::screen_update_fm7));
2216 
2217 	PALETTE(config, m_palette, palette_device::BRG_3BIT);
2218 
2219 	CASSETTE(config, m_cassette);
2220 	m_cassette->set_formats(fm7_cassette_formats);
2221 	m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
2222 	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
2223 	m_cassette->set_interface("fm7_cass");
2224 
2225 	MB8877(config, m_fdc, 8_MHz_XTAL / 8);
2226 	m_fdc->intrq_wr_callback().set(FUNC(fm7_state::fm7_fdc_intrq_w));
2227 	m_fdc->drq_wr_callback().set(FUNC(fm7_state::fm7_fdc_drq_w));
2228 
2229 	FLOPPY_CONNECTOR(config, m_floppy0, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2230 	FLOPPY_CONNECTOR(config, m_floppy1, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2231 
2232 	CENTRONICS(config, m_centronics, centronics_devices, "printer");
2233 	m_centronics->busy_handler().set(FUNC(fm7_state::write_centronics_busy));
2234 	m_centronics->fault_handler().set(FUNC(fm7_state::write_centronics_fault));
2235 	m_centronics->ack_handler().set(FUNC(fm7_state::write_centronics_ack));
2236 	m_centronics->perror_handler().set(FUNC(fm7_state::write_centronics_perror));
2237 
2238 	OUTPUT_LATCH(config, m_cent_data_out);
2239 	m_centronics->set_output_latch(*m_cent_data_out);
2240 }
2241 
fm16beta(machine_config & config)2242 void fm7_state::fm16beta(machine_config &config)
2243 {
2244 	/* basic machine hardware */
2245 	I8086(config, m_maincpu, 8000000);  // 8MHz i8086
2246 	m_maincpu->set_addrmap(AS_PROGRAM, &fm7_state::fm16_mem);
2247 	m_maincpu->set_addrmap(AS_IO, &fm7_state::fm16_io);
2248 
2249 	MC6809(config, m_sub, 8000000);
2250 	m_sub->set_irq_acknowledge_callback(FUNC(fm7_state::fm7_sub_irq_ack));
2251 	m_sub->set_addrmap(AS_PROGRAM, &fm7_state::fm16_sub_mem);
2252 	config.set_perfect_quantum(m_sub);
2253 
2254 	SPEAKER(config, "mono").front_center();
2255 	BEEP(config, m_beeper, 1200).add_route(ALL_OUTPUTS, "mono", 0.50);
2256 
2257 	MCFG_MACHINE_START_OVERRIDE(fm7_state,fm16)
2258 
2259 	/* video hardware */
2260 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2261 	m_screen->set_raw(16128000, 1024, 0, 640, 262, 0, 200);
2262 	m_screen->set_screen_update(FUNC(fm7_state::screen_update_fm7));
2263 
2264 	PALETTE(config, m_palette, palette_device::BRG_3BIT);
2265 
2266 	CASSETTE(config, m_cassette);
2267 	m_cassette->set_formats(fm7_cassette_formats);
2268 	m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
2269 	m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
2270 	m_cassette->set_interface("fm7_cass");
2271 
2272 	MB8877(config, m_fdc, 8_MHz_XTAL / 8);
2273 	m_fdc->intrq_wr_callback().set(FUNC(fm7_state::fm7_fdc_intrq_w));
2274 	m_fdc->drq_wr_callback().set(FUNC(fm7_state::fm7_fdc_drq_w));
2275 
2276 	FLOPPY_CONNECTOR(config, m_floppy0, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2277 	FLOPPY_CONNECTOR(config, m_floppy1, fm7_floppies, "qd", floppy_image_device::default_floppy_formats);
2278 
2279 	CENTRONICS(config, m_centronics, centronics_devices, "printer");
2280 	m_centronics->busy_handler().set(FUNC(fm7_state::write_centronics_busy));
2281 	m_centronics->fault_handler().set(FUNC(fm7_state::write_centronics_fault));
2282 	m_centronics->ack_handler().set(FUNC(fm7_state::write_centronics_ack));
2283 	m_centronics->perror_handler().set(FUNC(fm7_state::write_centronics_perror));
2284 
2285 	OUTPUT_LATCH(config, m_cent_data_out);
2286 	m_centronics->set_output_latch(*m_cent_data_out);
2287 }
2288 
2289 /* ROM definition */
2290 ROM_START( fm8 )
2291 	ROM_REGION( 0x40000, "maincpu", 0 )
2292 	ROM_LOAD( "fbasic10.rom", 0x38000,  0x7c00, CRC(e80ed96c) SHA1(f3fa8a6adb07224ad2a1def77d5dae9662de0867) )
2293 
2294 	ROM_REGION( 0x20000, "sub", 0 )
2295 	ROM_LOAD( "subsys_8.rom", 0xd800,  0x2800, CRC(979f9046) SHA1(9c52052087bf3a41b83d437a51d89b9fcfec2515) )
2296 
2297 	// either one of these boot ROMs are selectable via DIP switch
2298 	ROM_REGION( 0x200, "basic", 0 )
2299 	ROM_LOAD( "bootbas8.rom", 0x0000,  0x0200, CRC(8260267a) SHA1(fee6fb9c52d22dd7108c68d08c74e2f3ebcb9e4d) )
2300 
2301 	ROM_REGION( 0x200, "dos", 0 )
2302 	ROM_LOAD( "bootdos8.rom", 0x0000,  0x0200, CRC(1ed5a506) SHA1(966538fa92c32fc15034576dc480cfa4a339384d) )
2303 
2304 	// optional Kanji ROM (same as for the FM-7?)
2305 	ROM_REGION( 0x20000, "kanji1", 0 )
2306 	ROM_LOAD_OPTIONAL( "kanji.rom", 0x0000, 0x20000, NO_DUMP )
2307 
2308 ROM_END
2309 
2310 
2311 ROM_START( fmnew7 )
2312 	ROM_REGION( 0x40000, "maincpu", 0 ) // at 0x7ba5 there is the ID string 0302840301, meaning it's v3.02 from 1984/03/01
2313 	ROM_LOAD( "fbasic302.rom", 0x38000,  0x7c00, CRC(a96d19b6) SHA1(8d5f0cfe7e0d39bf2ab7e4c798a13004769c28b2) )
2314 
2315 	ROM_REGION( 0x20000, "sub", 0 )
2316 	ROM_LOAD( "subsys_c.rom", 0xd800,  0x2800, CRC(24cec93f) SHA1(50b7283db6fe1342c6063fc94046283f4feddc1c) )
2317 
2318 	// either one of these boot ROMs are selectable via DIP switch
2319 	ROM_REGION( 0x200, "basic", 0 )
2320 	ROM_LOAD( "boot_bas.rom", 0x0000,  0x0200, CRC(c70f0c74) SHA1(53b63a301cba7e3030e79c59a4d4291eab6e64b0) )
2321 
2322 	ROM_REGION( 0x200, "dos", 0 )
2323 	ROM_LOAD( "boot_dos.rom", 0x0000,  0x0200, CRC(198614ff) SHA1(037e5881bd3fed472a210ee894a6446965a8d2ef) )
2324 
2325 	// optional Kanji ROM
2326 	ROM_REGION( 0x20000, "kanji1", 0 )
2327 	ROM_LOAD_OPTIONAL( "kanji.rom", 0x0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143) )
2328 
2329 ROM_END
2330 
2331 ROM_START( fm7 )
2332 	ROM_REGION( 0x40000, "maincpu", 0 ) // at 0x7ba5 there is the ID string 0300820920, meaning it's v3.00 from 1982/09/20
2333 	ROM_LOAD( "fbasic300.rom", 0x38000,  0x7c00, CRC(87c98494) SHA1(d7e3603b0a2442c7632dad45f9704d9ad71968f5) )
2334 
2335 	ROM_REGION( 0x20000, "sub", 0 )
2336 	ROM_LOAD( "subsys_c.rom", 0xd800,  0x2800, CRC(24cec93f) SHA1(50b7283db6fe1342c6063fc94046283f4feddc1c) )
2337 
2338 	// either one of these boot ROMs are selectable via DIP switch
2339 	ROM_REGION( 0x200, "basic", 0 )
2340 	ROM_LOAD( "boot_bas.rom", 0x0000,  0x0200, CRC(c70f0c74) SHA1(53b63a301cba7e3030e79c59a4d4291eab6e64b0) )
2341 
2342 	ROM_REGION( 0x200, "dos", 0 )
2343 	ROM_LOAD( "boot_dos_a.rom", 0x0000,  0x0200, CRC(bf441864) SHA1(616c17155f84fb0e3731a31ef0eb0cbb664a5600) )
2344 
2345 	// optional Kanji ROM
2346 	ROM_REGION( 0x20000, "kanji1", 0 )
2347 	ROM_LOAD_OPTIONAL( "kanji.rom", 0x0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143) )
2348 
2349 ROM_END
2350 
2351 ROM_START( fm77av )
2352 	ROM_REGION( 0x40000, "maincpu", 0 )
2353 	ROM_FILL(0x0000,0x40000,0xff)
2354 
2355 	ROM_REGION( 0x2000, "init", 0 )
2356 	ROM_LOAD( "initiate.rom", 0x0000,  0x2000, CRC(785cb06c) SHA1(b65987e98a9564a82c85eadb86f0204eee5a5c93) )
2357 
2358 	ROM_REGION( 0x7c00, "fbasic", 0 )
2359 	ROM_LOAD( "fbasic30.rom", 0x0000,  0x7c00, CRC(a96d19b6) SHA1(8d5f0cfe7e0d39bf2ab7e4c798a13004769c28b2) )
2360 
2361 	ROM_REGION( 0x10000, "sub", 0 )
2362 	ROM_FILL(0x0000,0x10000,0xff)
2363 
2364 	// sub CPU ROMs
2365 	ROM_REGION( 0x2800, "subsys_c", 0 )
2366 	ROM_LOAD( "subsys_c.rom", 0x0000,  0x2800, CRC(24cec93f) SHA1(50b7283db6fe1342c6063fc94046283f4feddc1c) )
2367 	ROM_REGION( 0x2000, "subsys_a", 0 )
2368 	ROM_LOAD( "subsys_a.rom", 0x0000,  0x2000, CRC(e8014fbb) SHA1(038cb0b42aee9e933b20fccd6f19942e2f476c83) )
2369 	ROM_REGION( 0x2000, "subsys_b", 0 )
2370 	ROM_LOAD( "subsys_b.rom", 0x0000,  0x2000, CRC(9be69fac) SHA1(0305bdd44e7d9b7b6a17675aff0a3330a08d21a8) )
2371 	ROM_REGION( 0x2000, "subsyscg", 0 )
2372 	ROM_LOAD( "subsyscg.rom", 0x0000,  0x2000, CRC(e9f16c42) SHA1(8ab466b1546d023ba54987790a79e9815d2b7bb2) )
2373 
2374 	ROM_REGION( 0x20000, "kanji1", 0 )
2375 	ROM_LOAD( "kanji.rom", 0x0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143) )
2376 
2377 	// optional dict rom?
2378 ROM_END
2379 
2380 ROM_START( fm7740sx )
2381 	ROM_REGION( 0x40000, "maincpu", 0 )
2382 	ROM_FILL(0x0000,0x40000,0xff)
2383 
2384 	ROM_REGION( 0x2000, "init", 0 )
2385 	ROM_LOAD( "initiate.rom", 0x0000,  0x2000, CRC(785cb06c) SHA1(b65987e98a9564a82c85eadb86f0204eee5a5c93) )
2386 
2387 	ROM_REGION( 0x7c00, "fbasic", 0 )
2388 	ROM_LOAD( "fbasic30.rom", 0x0000,  0x7c00, CRC(a96d19b6) SHA1(8d5f0cfe7e0d39bf2ab7e4c798a13004769c28b2) )
2389 
2390 	ROM_REGION( 0x10000, "sub", 0 )
2391 	ROM_FILL(0x0000,0x10000,0xff)
2392 
2393 	// sub CPU ROMs
2394 	ROM_REGION( 0x2800, "subsys_c", 0 )
2395 	ROM_LOAD( "subsys_c.rom", 0x0000,  0x2800, CRC(24cec93f) SHA1(50b7283db6fe1342c6063fc94046283f4feddc1c) )
2396 	ROM_REGION( 0x2000, "subsys_a", 0 )
2397 	ROM_LOAD( "subsys_a.rom", 0x0000,  0x2000, CRC(e8014fbb) SHA1(038cb0b42aee9e933b20fccd6f19942e2f476c83) )
2398 	ROM_REGION( 0x2000, "subsys_b", 0 )
2399 	ROM_LOAD( "subsys_b.rom", 0x0000,  0x2000, CRC(9be69fac) SHA1(0305bdd44e7d9b7b6a17675aff0a3330a08d21a8) )
2400 	ROM_REGION( 0x2000, "subsyscg", 0 )
2401 	ROM_LOAD( "subsyscg.rom", 0x0000,  0x2000, CRC(e9f16c42) SHA1(8ab466b1546d023ba54987790a79e9815d2b7bb2) )
2402 
2403 	ROM_REGION( 0x20000, "kanji1", 0 )
2404 	ROM_LOAD( "kanji.rom", 0x0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143) )
2405 	ROM_LOAD( "kanji2.rom", 0x0000, 0x20000, CRC(38644251) SHA1(ebfdc43c38e1380709ed08575c346b2467ad1592) )
2406 
2407 	/* These should be loaded at 2e000-2ffff of maincpu, but I'm not sure if it is correct */
2408 	ROM_REGION( 0x4c000, "additional", 0 )
2409 	ROM_LOAD( "dicrom.rom", 0x00000, 0x40000, CRC(b142acbc) SHA1(fe9f92a8a2750bcba0a1d2895e75e83858e4f97f) )
2410 	ROM_LOAD( "extsub.rom", 0x40000, 0x0c000, CRC(0f7fcce3) SHA1(a1304457eeb400b4edd3c20af948d66a04df255e) )
2411 
2412 ROM_END
2413 
2414 ROM_START( fm11 )
2415 	ROM_REGION( 0x40000, "maincpu", 0 )
2416 	ROM_FILL(0x0000,0x40000,0xff)
2417 
2418 	ROM_REGION( 0x1000, "init", 0 )
2419 	ROM_LOAD( "boot6809.rom", 0x0000, 0x1000, CRC(447caa6f) SHA1(4aa30314994c256d37ee01d11ec2bf4df3bc8cde) )
2420 
2421 	ROM_REGION( 0x10000, "sub", 0 )
2422 	ROM_LOAD( "subsys.rom", 0xc000, 0x4000, CRC(436c0618) SHA1(cd508e3e8f79737afb4384ea4b278eddf0ce935d) )
2423 
2424 	ROM_REGION( 0x100000, "x86", 0 )
2425 	ROM_LOAD( "boot8088.rom", 0xff000, 0x1000, CRC(d13096a6) SHA1(f9bd95b3b8184d0e04fba9b50f273dbb8823be77) )
2426 
2427 	ROM_REGION( 0x10000, "subsys_e", 0 )
2428 	ROM_LOAD( "subsys_e.rom", 0x00000, 0x1000, CRC(31d838aa) SHA1(86a275c27bc99985bef7a51bdab2e47d68e31c6c) )
2429 
2430 	// optional Kanji ROM
2431 	ROM_REGION( 0x20000, "kanji1", 0 )
2432 	ROM_LOAD_OPTIONAL( "kanji.rom", 0x0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143) )
2433 
2434 ROM_END
2435 
2436 ROM_START( fm16beta )
2437 	ROM_REGION( 0x100000, "maincpu", 0 )
2438 	ROM_LOAD( "ipl.rom", 0xfc000, 0x4000, CRC(25f618ea) SHA1(9c27d6ad283260e071d64a1bfca16f7d3ad61f96) )
2439 
2440 //  ROM_REGION( 0x10000, "subsys", 0 )
2441 
2442 	ROM_REGION( 0x10000, "sub", 0 )
2443 	ROM_LOAD( "sub_cg.rom", 0xa000, 0x0f80, CRC(e7928bed) SHA1(68cf604aa7a5c2ec7bd0d612cf099302c7f8c442) )
2444 	ROM_CONTINUE(0xff80,0x0080)
2445 	ROM_LOAD( "subsys.rom", 0xb000, 0x4f80, CRC(1d878514) SHA1(4673879a81e39880655b380250c6b81137028727) )
2446 ROM_END
2447 
2448 
2449 /* Driver */
2450 
2451 /*    YEAR  NAME      PARENT  COMPAT  MACHINE   INPUT  CLASS      INIT      COMPANY    FULLNAME         FLAGS */
2452 COMP( 1981, fm8,      0,      0,      fm8,      fm8,   fm7_state, init_fm7, "Fujitsu", "FM-8",          0)
2453 COMP( 1982, fm7,      0,      0,      fm7,      fm7,   fm7_state, init_fm7, "Fujitsu", "FM-7",          0)
2454 COMP( 1984, fmnew7,   fm7,    0,      fm7,      fm7,   fm7_state, init_fm7, "Fujitsu", "FM-NEW7",       0)
2455 COMP( 1985, fm77av,   fm7,    0,      fm77av,   fm7,   fm7_state, init_fm7, "Fujitsu", "FM-77AV",       MACHINE_IMPERFECT_GRAPHICS)
2456 COMP( 1985, fm7740sx, fm7,    0,      fm77av,   fm7,   fm7_state, init_fm7, "Fujitsu", "FM-77AV40SX",   MACHINE_NOT_WORKING)
2457 
2458 // These may be separated into a separate driver, depending on how different they are to the FM-8/FM-7
2459 COMP( 1982, fm11,     0,      0,      fm11,     fm7,   fm7_state, init_fm7, "Fujitsu", "FM-11 EX",      MACHINE_NOT_WORKING)
2460 COMP( 1982, fm16beta, 0,      0,      fm16beta, fm7,   fm7_state, init_fm7, "Fujitsu", "FM-16\xCE\xB2", MACHINE_NOT_WORKING)
2461