1 // license:BSD-3-Clause
2 // copyright-holders:Miodrag Milanovic
3 /***************************************************************************
4 
5 Nanos
6 
7 2009-05-12 Skeleton driver.
8 
9 Status:
10 - Waiting for a floppy disk. Need software to proceed.
11 
12 ****************************************************************************/
13 
14 #include "emu.h"
15 
16 #include "cpu/z80/z80.h"
17 #include "imagedev/floppy.h"
18 #include "machine/z80daisy.h"
19 #include "machine/timer.h"
20 #include "machine/upd765.h"
21 #include "machine/z80ctc.h"
22 #include "machine/z80sio.h"
23 #include "machine/z80pio.h"
24 
25 #include "formats/nanos_dsk.h"
26 
27 #include "emupal.h"
28 #include "screen.h"
29 
30 
31 class nanos_state : public driver_device
32 {
33 public:
nanos_state(const machine_config & mconfig,device_type type,const char * tag)34 	nanos_state(const machine_config &mconfig, device_type type, const char *tag)
35 		: driver_device(mconfig, type, tag)
36 		, m_maincpu(*this, "maincpu")
37 		, m_rom(*this, "maincpu")
38 		, m_ram(*this, "mainram")
39 		, m_bank1(*this, "bank1")
40 		, m_pio(*this, "pio")
41 		, m_pio0(*this, "pio0")
42 		, m_pio1(*this, "pio1")
43 		, m_sio0(*this, "sio0")
44 		, m_sio1(*this, "sio1")
45 		, m_ctc0(*this, "ctc0")
46 		, m_ctc1(*this, "ctc1")
47 		, m_fdc(*this, "fdc")
48 		, m_floppy(*this, "fdc:0")
49 		, m_key_t(*this, "keyboard_timer")
50 		, m_p_chargen(*this, "chargen")
51 		, m_vram(*this, "videoram")
52 		, m_io_keyboard(*this, "LINE%u", 0U)
53 		, m_io_linec(*this, "LINEC")
54 	{ }
55 
56 	void nanos(machine_config &config);
57 
58 protected:
59 	virtual void machine_reset() override;
60 	virtual void machine_start() override;
61 
62 private:
63 	void tc_w(uint8_t data);
64 	DECLARE_WRITE_LINE_MEMBER(ctc_z0_w);
65 	DECLARE_WRITE_LINE_MEMBER(ctc_z1_w);
66 	DECLARE_WRITE_LINE_MEMBER(ctc_z2_w);
67 	TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);
68 	DECLARE_WRITE_LINE_MEMBER(z80daisy_interrupt);
69 	uint8_t port_a_r();
70 	uint8_t port_b_r();
71 	void port_b_w(uint8_t data);
72 	DECLARE_FLOPPY_FORMATS(floppy_formats);
73 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
74 
75 	void io_map(address_map &map);
76 	void mem_map(address_map &map);
77 
78 	uint8_t m_key_command;
79 	uint8_t m_last_code;
80 	uint8_t m_key_pressed;
81 	uint8_t row_number(uint8_t code);
82 
83 	required_device<z80_device> m_maincpu;
84 	required_region_ptr<u8> m_rom;
85 	required_shared_ptr<u8> m_ram;
86 	required_memory_bank    m_bank1;
87 	required_device<z80pio_device> m_pio;
88 	required_device<z80pio_device> m_pio0;
89 	required_device<z80pio_device> m_pio1;
90 	required_device<z80sio_device> m_sio0;
91 	required_device<z80sio_device> m_sio1;
92 	required_device<z80ctc_device> m_ctc0;
93 	required_device<z80ctc_device> m_ctc1;
94 	required_device<upd765a_device> m_fdc;
95 	required_device<floppy_connector> m_floppy;
96 	required_device<timer_device> m_key_t;
97 	required_region_ptr<u8> m_p_chargen;
98 	required_shared_ptr<u8> m_vram;
99 	required_ioport_array<7> m_io_keyboard;
100 	required_ioport m_io_linec;
101 };
102 
103 
104 
mem_map(address_map & map)105 void nanos_state::mem_map(address_map &map)
106 {
107 	map(0x0000, 0xf7ff).ram().share("mainram");
108 	map(0x0000, 0x0fff).bankr(m_bank1);
109 	map(0xf800, 0xffff).ram().share("videoram");
110 }
111 
tc_w(uint8_t data)112 void nanos_state::tc_w(uint8_t data)
113 {
114 	m_fdc->tc_w(BIT(data,1));
115 }
116 
117 
118 /* Z80-CTC Interface */
119 
WRITE_LINE_MEMBER(nanos_state::ctc_z0_w)120 WRITE_LINE_MEMBER(nanos_state::ctc_z0_w)
121 {
122 }
123 
WRITE_LINE_MEMBER(nanos_state::ctc_z1_w)124 WRITE_LINE_MEMBER(nanos_state::ctc_z1_w)
125 {
126 }
127 
WRITE_LINE_MEMBER(nanos_state::ctc_z2_w)128 WRITE_LINE_MEMBER(nanos_state::ctc_z2_w)
129 {
130 }
131 
132 /* Z80-SIO Interface */
133 
WRITE_LINE_MEMBER(nanos_state::z80daisy_interrupt)134 WRITE_LINE_MEMBER(nanos_state::z80daisy_interrupt)
135 {
136 	m_maincpu->set_input_line(INPUT_LINE_IRQ0, state);
137 }
138 
139 /* Z80 Daisy Chain */
140 
141 static const z80_daisy_config daisy_chain[] =
142 {
143 	{ "pio" },
144 	{ "pio0" },
145 	{ "pio1" },
146 	{ "sio0" },
147 	{ "ctc0" },
148 	{ "sio1" },
149 	{ "ctc1" },
150 	{ nullptr }
151 };
152 
io_map(address_map & map)153 void nanos_state::io_map(address_map &map)
154 {
155 	map.unmap_value_high();
156 	map.global_mask(0xff);
157 	/* CPU card */
158 	map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
159 
160 	/* I/O card */
161 	map(0x80, 0x83).rw(m_pio0, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
162 	map(0x84, 0x87).rw(m_sio0, FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w));
163 	map(0x88, 0x8B).rw(m_pio1, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
164 	map(0x8C, 0x8F).rw(m_ctc0, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
165 
166 	/* FDC card */
167 	map(0x92, 0x92).w(FUNC(nanos_state::tc_w));
168 	map(0x94, 0x95).m(m_fdc, FUNC(upd765a_device::map));
169 	/* V24+IFSS card */
170 	map(0xA0, 0xA3).rw(m_sio0, FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w));
171 	map(0xA4, 0xA7).rw(m_ctc1, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
172 
173 	/* 256-k RAM card I  -  64k OS-Memory + 192k-RAM-Floppy */
174 	//map(0xC0, 0xC7)
175 
176 	/* 256-k RAM card II -  64k OS-Memory + 192k-RAM-Floppy */
177 	//map(0xC8, 0xCF)
178 }
179 
180 /* Input ports */
181 static INPUT_PORTS_START( nanos )
182 	PORT_START("LINEC")
PORT_CODE(KEYCODE_LCONTROL)183 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL)
184 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT)
185 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
186 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
187 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
188 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED)
189 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
190 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
191 
192 	PORT_START("LINE0")
193 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0)
194 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1)
195 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2)
196 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3)
197 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4)
198 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5)
199 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6)
200 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7)
201 
202 	PORT_START("LINE1")
203 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8)
204 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9)
205 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_QUOTE)
206 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON)
207 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA)
208 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS)
209 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP)
210 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH)
211 
212 	PORT_START("LINE2")
213 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_END)
214 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A)
215 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B)
216 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C)
217 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D)
218 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E)
219 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F)
220 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G)
221 
222 	PORT_START("LINE3")
223 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H)
224 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I)
225 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J)
226 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K)
227 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L)
228 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M)
229 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N)
230 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O)
231 
232 	PORT_START("LINE4")
233 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P)
234 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q)
235 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R)
236 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S)
237 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T)
238 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U)
239 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V)
240 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W)
241 
242 	PORT_START("LINE5")
243 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X)
244 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z)
245 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y)
246 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE)
247 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH)
248 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("]")  PORT_CODE(KEYCODE_CLOSEBRACE)
249 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("~")  PORT_CODE(KEYCODE_TILDE)
250 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL")PORT_CODE(KEYCODE_BACKSPACE)
251 
252 	PORT_START("LINE6")
253 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT)
254 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT)
255 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP)
256 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN)
257 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)
258 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LF") PORT_CODE(KEYCODE_RALT)
259 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB)
260 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER)
261 INPUT_PORTS_END
262 
263 
264 uint32_t nanos_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
265 {
266 //  static uint8_t framecnt=0;
267 	uint16_t sy=0,ma=0;
268 
269 //  framecnt++;
270 
271 	for (uint8_t y = 0; y < 25; y++)
272 	{
273 		for (uint8_t ra = 0; ra < 10; ra++)
274 		{
275 			uint16_t *p = &bitmap.pix(sy++);
276 
277 			for (uint16_t x = ma; x < ma + 80; x++)
278 			{
279 				uint8_t gfx;
280 				if (ra < 8)
281 				{
282 					uint8_t const chr = m_vram[x];
283 
284 					/* get pattern of pixels for that character scanline */
285 					gfx = m_p_chargen[(chr<<3) | ra ];
286 				}
287 				else
288 					gfx = 0;
289 
290 				/* Display a scanline of a character (8 pixels) */
291 				*p++ = BIT(gfx, 7);
292 				*p++ = BIT(gfx, 6);
293 				*p++ = BIT(gfx, 5);
294 				*p++ = BIT(gfx, 4);
295 				*p++ = BIT(gfx, 3);
296 				*p++ = BIT(gfx, 2);
297 				*p++ = BIT(gfx, 1);
298 				*p++ = BIT(gfx, 0);
299 			}
300 		}
301 		ma+=80;
302 	}
303 	return 0;
304 }
305 
port_a_r()306 uint8_t nanos_state::port_a_r()
307 {
308 	if (m_key_command==0)
309 		return m_key_pressed;
310 	else
311 	{
312 		uint8_t retVal = m_last_code;
313 		m_last_code = 0;
314 		return retVal;
315 	}
316 }
317 
port_b_r()318 uint8_t nanos_state::port_b_r()
319 {
320 	return 0xff;
321 }
322 
323 
port_b_w(uint8_t data)324 void nanos_state::port_b_w(uint8_t data)
325 {
326 	m_key_command = BIT(data,1);
327 
328 	m_bank1->set_entry(BIT(data,7));
329 }
330 
row_number(uint8_t code)331 uint8_t nanos_state::row_number(uint8_t code)
332 {
333 	if (BIT(code, 0)) return 0;
334 	if (BIT(code, 1)) return 1;
335 	if (BIT(code, 2)) return 2;
336 	if (BIT(code, 3)) return 3;
337 	if (BIT(code, 4)) return 4;
338 	if (BIT(code, 5)) return 5;
339 	if (BIT(code, 6)) return 6;
340 	if (BIT(code, 7)) return 7;
341 	return 0;
342 }
343 
344 // TODO: clean this up when the machine starts to work.
TIMER_DEVICE_CALLBACK_MEMBER(nanos_state::keyboard_callback)345 TIMER_DEVICE_CALLBACK_MEMBER(nanos_state::keyboard_callback)
346 {
347 	uint8_t key_code = 0;
348 	bool shift = BIT(m_io_linec->read(), 1);
349 	bool ctrl =  BIT(m_io_linec->read(), 0);
350 	m_key_pressed = 0xff;
351 	for(int i = 0; i < 7; i++)
352 	{
353 		uint8_t code = m_io_keyboard[i]->read();
354 		if (code != 0)
355 		{
356 			if (i==0 && !shift)
357 				key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
358 
359 			if (i==0 && shift)
360 				key_code = 0x20 + row_number(code) + 8*i; // for shifted numbers
361 
362 			if (i==1 && !shift)
363 			{
364 				if (row_number(code) < 4)
365 					key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
366 				else
367 					key_code = 0x20 + row_number(code) + 8*i; // for numbers and some signs
368 			}
369 
370 			if (i==1 && shift)
371 			{
372 				if (row_number(code) < 4)
373 					key_code = 0x20 + row_number(code) + 8*i; // for numbers and some signs
374 				else
375 					key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
376 			}
377 
378 			if (i>=2 && i<=4 && shift && !ctrl)
379 				key_code = 0x60 + row_number(code) + (i-2)*8; // for small letters
380 
381 			if (i>=2 && i<=4 && !shift && !ctrl)
382 				key_code = 0x40 + row_number(code) + (i-2)*8; // for big letters
383 
384 			if (i>=2 && i<=4 && ctrl)
385 				key_code = 0x00 + row_number(code) + (i-2)*8; // for CTRL + letters
386 
387 			if (i==5 && shift && !ctrl)
388 			{
389 				if (row_number(code)<7)
390 					key_code = 0x60 + row_number(code) + (i-2)*8; // for small letters
391 				else
392 					key_code = 0x40 + row_number(code) + (i-2)*8; // for signs it is switched
393 			}
394 
395 			if (i==5 && !shift && !ctrl)
396 			{
397 				if (row_number(code)<7)
398 					key_code = 0x40 + row_number(code) + (i-2)*8; // for small letters
399 				else
400 					key_code = 0x60 + row_number(code) + (i-2)*8; // for signs it is switched
401 			}
402 
403 			if (i==5 && !shift && ctrl)
404 				key_code = 0x00 + row_number(code) + (i-2)*8; // for letters + ctrl
405 
406 			if (i==6)
407 			{
408 				switch(row_number(code))
409 				{
410 					case 0: key_code = 0x11; break;
411 					case 1: key_code = 0x12; break;
412 					case 2: key_code = 0x13; break;
413 					case 3: key_code = 0x14; break;
414 					case 4: key_code = 0x20; break; // Space
415 					case 5: key_code = 0x0D; break; // Enter
416 					case 6: key_code = 0x09; break; // TAB
417 					case 7: key_code = 0x0A; break; // LF
418 				}
419 			}
420 			m_last_code = key_code;
421 		}
422 	}
423 
424 	if (key_code==0)
425 		m_key_pressed = 0xf7;
426 }
427 
machine_start()428 void nanos_state::machine_start()
429 {
430 	save_item(NAME(m_key_command));
431 	save_item(NAME(m_last_code));
432 	save_item(NAME(m_key_pressed));
433 
434 	m_bank1->configure_entry(0, m_ram);
435 	m_bank1->configure_entry(1, m_rom);
436 }
437 
machine_reset()438 void nanos_state::machine_reset()
439 {
440 	m_bank1->set_entry(1);
441 	m_floppy->get_device()->mon_w(0);
442 	m_key_pressed = 0xff;
443 }
444 
FLOPPY_FORMATS_MEMBER(nanos_state::floppy_formats)445 FLOPPY_FORMATS_MEMBER( nanos_state::floppy_formats )
446 	FLOPPY_NANOS_FORMAT
447 FLOPPY_FORMATS_END
448 
449 static void nanos_floppies(device_slot_interface &device)
450 {
451 	device.option_add("525hd", FLOPPY_525_HD);
452 }
453 
454 /* F4 Character Displayer */
455 static const gfx_layout nanos_charlayout =
456 {
457 	8, 8,                   /* 8 x 8 characters */
458 	256,                    /* 256 characters */
459 	1,                  /* 1 bits per pixel */
460 	{ 0 },                  /* no bitplanes */
461 	/* x offsets */
462 	{ 0, 1, 2, 3, 4, 5, 6, 7 },
463 	/* y offsets */
464 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
465 	8*8                 /* every char takes 8 bytes */
466 };
467 
468 static GFXDECODE_START( gfx_nanos )
469 	GFXDECODE_ENTRY( "chargen", 0x0000, nanos_charlayout, 0, 1 )
470 GFXDECODE_END
471 
nanos(machine_config & config)472 void nanos_state::nanos(machine_config &config)
473 {
474 	/* basic machine hardware */
475 	Z80(config, m_maincpu, XTAL(4'000'000));
476 	m_maincpu->set_addrmap(AS_PROGRAM, &nanos_state::mem_map);
477 	m_maincpu->set_addrmap(AS_IO, &nanos_state::io_map);
478 	m_maincpu->set_daisy_config(daisy_chain);
479 
480 	/* video hardware */
481 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
482 	screen.set_refresh_hz(50);
483 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
484 	screen.set_screen_update(FUNC(nanos_state::screen_update));
485 	screen.set_size(80*8, 25*10);
486 	screen.set_visarea(0,80*8-1,0,25*10-1);
487 	screen.set_palette("palette");
488 
489 	GFXDECODE(config, "gfxdecode", "palette", gfx_nanos);
490 	PALETTE(config, "palette", palette_device::MONOCHROME);
491 
492 	/* devices */
493 	Z80CTC(config, m_ctc0, XTAL(4'000'000));
494 	m_ctc0->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
495 	m_ctc0->zc_callback<0>().set(FUNC(nanos_state::ctc_z0_w));
496 	m_ctc0->zc_callback<1>().set(FUNC(nanos_state::ctc_z1_w));
497 	m_ctc0->zc_callback<2>().set(FUNC(nanos_state::ctc_z2_w));
498 
499 	Z80CTC(config, m_ctc1, XTAL(4'000'000));
500 	m_ctc1->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
501 	m_ctc1->zc_callback<0>().set(FUNC(nanos_state::ctc_z0_w));
502 	m_ctc1->zc_callback<1>().set(FUNC(nanos_state::ctc_z1_w));
503 	m_ctc1->zc_callback<2>().set(FUNC(nanos_state::ctc_z2_w));
504 
505 	Z80PIO(config, m_pio0, XTAL(4'000'000));
506 	m_pio0->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
507 
508 	Z80PIO(config, m_pio1, XTAL(4'000'000));
509 	m_pio1->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
510 
511 	Z80SIO(config, m_sio0, XTAL(4'000'000));
512 	m_sio0->out_int_callback().set(FUNC(nanos_state::z80daisy_interrupt));
513 
514 	Z80SIO(config, m_sio1, XTAL(4'000'000));
515 	m_sio1->out_int_callback().set(FUNC(nanos_state::z80daisy_interrupt));
516 
517 	Z80PIO(config, m_pio, XTAL(4'000'000));
518 	m_pio->in_pa_callback().set(FUNC(nanos_state::port_a_r));
519 	m_pio->in_pb_callback().set(FUNC(nanos_state::port_b_r));
520 	m_pio->out_pb_callback().set(FUNC(nanos_state::port_b_w));
521 
522 	/* UPD765 */
523 	UPD765A(config, m_fdc, 8'000'000, false, true);
524 	FLOPPY_CONNECTOR(config, m_floppy, nanos_floppies, "525hd", nanos_state::floppy_formats);
525 
526 	TIMER(config, "keyboard_timer").configure_periodic(FUNC(nanos_state::keyboard_callback), attotime::from_hz(240));
527 }
528 
529 /* ROM definition */
530 ROM_START( nanos )
531 	ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF )
532 	ROM_LOAD( "k7634_1.rom", 0x0000, 0x0800, CRC(8e34e6ac) SHA1(fd342f6effe991823c2a310737fbfcba213c4fe3))
533 	ROM_LOAD( "k7634_2.rom", 0x0800, 0x0180, CRC(4e01b02b) SHA1(8a279da886555c7470a1afcbb3a99693ea13c237))
534 
535 	ROM_REGION( 0x0800, "chargen", 0 )
536 	ROM_LOAD( "zg_nanos.rom", 0x0000, 0x0800, CRC(5682d3f9) SHA1(5b738972c815757821c050ee38b002654f8da163))
537 ROM_END
538 
539 /* Driver */
540 
541 /*    YEAR  NAME   PARENT  COMPAT  MACHINE  INPUT  CLASS        INIT        COMPANY                                                FULLNAME  FLAGS */
542 COMP( 1985, nanos, 0,      0,      nanos,   nanos, nanos_state, empty_init, "Ingenieurhochschule fur Seefahrt Warnemunde/Wustrow", "NANOS",  MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
543