summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/nc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/nc.c')
-rw-r--r--src/mame/drivers/nc.c1556
1 files changed, 1556 insertions, 0 deletions
diff --git a/src/mame/drivers/nc.c b/src/mame/drivers/nc.c
new file mode 100644
index 00000000000..7bf13f6d188
--- /dev/null
+++ b/src/mame/drivers/nc.c
@@ -0,0 +1,1556 @@
+// license:GPL-2.0+
+// copyright-holders:Wilbert Pol, Kevin Thacker
+/******************************************************************************
+
+ nc.c
+
+ NC100/NC150/NC200 Notepad computer
+
+ system driver
+
+
+ Thankyou to:
+ Cliff Lawson, Russell Marks and Tim Surtel
+
+ Documentation:
+
+ NC100:
+ NC100 I/O Specification by Cliff Lawson,
+ NC100EM by Russell Marks
+ NC200:
+ Dissassembly of the NC200 ROM + e-mail
+ exchange with Russell Marks
+
+
+ NC100:
+
+ Hardware:
+ - Z80 CPU, 6 MHz
+ - memory powered by lithium batterys!
+ - 2 channel tone (programmable frequency beep's)
+ - LCD screen
+ - laptop/portable computer
+ - qwerty keyboard
+ - serial/parallel connection
+ - Amstrad custom ASIC chip
+ - tc8521 real time clock
+ - intel 8251 compatible uart
+ - PCMCIA Memory cards supported, up to 1mb!
+
+ NC200:
+
+ Hardware:
+ - Z80 CPU
+ - Intel 8251 compatible uart
+ - upd765 compatible floppy disc controller
+ - mc146818 real time clock?
+ - 720k floppy disc drive (compatible with MS-DOS)
+ (disc drive can be not ready).
+ - PCMCIA Memory cards supported, up to 1mb!
+
+ TODO:
+ - find out what the unused key bits are for
+ (checked all unused bits on nc200! - do not seem to have any use!)
+ - complete serial (xmodem protocol!)
+ - overlay would be nice!
+ - finish NC200 disc drive emulation (closer!)
+ - add NC150 driver - ROM needed!!!
+ - on/off control
+ - check values read from other ports that are not described!
+ - what is read from unmapped ports?
+ - what is read from uart when it is off?
+ - check if uart ints are generated when it is off?
+ - are ints cancelled if uart is turned off after int has been caused?
+ - check keyboard ints - are these regular or what??
+
+ PCMCIA memory cards are stored as a direct dump of the contents. There is no header
+ information. No distinction is made between RAM and ROM cards.
+
+ Memory card sizes are a power of 2 in size (e.g. 1mb, 512k, 256k etc),
+ however the code allows any size, but it limits access to power of 2 sizes, with
+ minimum access being 16k. If a file which is less than 16k is used, no memory card
+ will be present. If a file which is greater than 1mb is used, only 1mb will be accessed.
+
+ Interrupt system of NC100:
+
+ The IRQ mask is used to control the interrupt sources that can interrupt.
+
+ The IRQ status can be read to determine which devices are interrupting.
+ Some devices, e.g. serial, cannot be cleared by writing to the irq status
+ register. These can only be cleared by performing an operation on the
+ device (e.g. reading a data register).
+
+ Self Test:
+
+ - requires memory save and real time clock save to be working!
+ (i.e. for MESS nc100 driver, nc100.nv can be created)
+ - turn off nc (use NMI button)
+ - reset+FUNCTION+SYMBOL must be pressed together.
+
+ Note: NC200 Self test does not test disc hardware :(
+
+
+
+ Kevin Thacker [MESS driver]
+
+ ******************************************************************************/
+
+#include "emu.h"
+#include "emuopts.h"
+#include "cpu/z80/z80.h"
+#include "includes/nc.h"
+#include "machine/mc146818.h" /* for NC200 real time clock */
+#include "machine/rp5c01.h" /* for NC100 real time clock */
+#include "machine/upd765.h" /* for NC200 disk drive interface */
+#include "formats/pc_dsk.h" /* for NC200 disk image */
+#include "sound/beep.h"
+#include "machine/ram.h"
+#include "rendlay.h"
+
+
+#define VERBOSE 0
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+
+#define NC200_DEBUG 1
+#define LOG_DEBUG(x) do { if (NC200_DEBUG) logerror x; } while (0)
+
+
+/* the serial clock is generated by the nc hardware and connected to the i8251
+receive clock and transmit clock inputs */
+
+/*
+ Port 0x00:
+ ==========
+
+ Display memory start:
+
+ NC100:
+ bit 7 A15
+ bit 6 A14
+ bit 5 A13
+ bit 4 A12
+ bits 3-0 Not Used
+ NC200:
+ bit 7 A15
+ bit 6 A14
+ bit 5 A13
+ bits 4-0 Not Used
+
+ Port 0x010-0x013:
+ =================
+
+ Memory management control:
+
+ NC100 & NC200:
+
+ 10 controls 0000-3FFF
+ 11 controls 4000-7FFF
+ 12 controls 8000-BFFF
+ 13 controls C000-FFFF
+
+ Port 0x030:
+ ===========
+
+ NC100:
+ bit 7 select card register 1=common, 0=attribute
+ bit 6 parallel interface Strobe signal
+ bit 5 Not Used
+ bit 4 uPD4711 line driver, 1=off, 0=on
+ bit 3 UART clock and reset, 1=off, 0=on
+
+ bits 2-0 set the baud rate as follows
+
+ 000 = 150
+ 001 = 300
+ 010 = 600
+ 011 = 1200
+ 100 = 2400
+ 101 = 4800
+ 110 = 9600
+ 111 = 19200
+ NC200:
+ bit 7 select card register 1=common, 0=attribute
+ bit 6 parallel interface Strobe signal
+
+ bit 5 used in disc interface; (set to 0)
+
+ bit 4 uPD4711 line driver, 1=off, 0=on
+ bit 3 UART clock and reset, 1=off, 0=on
+
+ bits 2-0 set the baud rate as follows
+
+ 000 = 150
+ 001 = 300
+ 010 = 600
+ 011 = 1200
+ 100 = 2400
+ 101 = 4800
+ 110 = 9600
+ 111 = 19200
+
+
+ Port 0x0a0:
+ ===========
+
+ NC100:
+ bit 7: memory card present 0 = yes, 1 = no
+ bit 6: memory card write protected 1 = yes, 0 = no
+ bit 5: input voltage = 1, if >= to 4 volts
+ bit 4: mem card battery: 0 = battery low
+ bit 3: alkaline batteries. 0 if >=3.2 volts
+ bit 2: lithium battery 0 if >= 2.7 volts
+ bit 1: parallel interface busy (0 if busy)
+ bit 0: parallel interface ack (1 if ack)
+
+ NC200:
+
+ bit 7: memory card present 0 = yes, 1 = no
+ bit 6: memory card write protected 1 = yes, 0 = no
+ bit 5: lithium battery 0 if >= 2.7 volts
+ bit 4: input voltage = 1, if >= to 4 volts
+ bit 3: ??
+ bit 2: alkaline batteries. 0 if >=3.2 volts
+ bit 1: ??
+ bit 0: battery power: if 1: batteries are too low for disk usage, if 0: batteries ok for disc usage
+
+
+ Port 0x060 (IRQ MASK), Port 0x090 (IRQ STATUS):
+ ===============================================
+
+ NC100:
+ bit 7: not used
+ bit 6: not used
+ bit 5: not used
+ bit 4: not used
+ Bit 3: Key scan interrupt (10ms)
+ Bit 2: ACK from parallel interface
+ Bit 1: Tx Ready
+ Bit 0: Rx Ready
+
+ NC200:
+ bit 7: ???
+ bit 6: RTC alarm?
+ bit 5: FDC interrupt
+ bit 4: Power off interrupt
+ Bit 3: Key scan interrupt (10ms)
+ Bit 2: serial interrupt (tx ready/rx ready combined)
+ Bit 1: not used
+ Bit 0: ACK from parallel interface
+
+ Port 0x070: On/off control
+
+ NC200:
+ bit 7: nc200 power on/off: 1 = on, 0=off
+ bit 2: backlight: 1=off, 0=on
+ bit 1: disk motor: 1=off, 0=disk motor???
+ bit 0: upd765 terminal count input
+*/
+
+
+
+/* latched interrupts are interrupts that cannot be cleared by writing to the irq
+mask. latched interrupts can only be cleared by accessing the interrupting
+device e.g. serial chip, fdc */
+/* this is a mask of irqs that are latched, and it is different for nc100 and
+nc200 */
+
+void nc_state::nc_update_interrupts()
+{
+ m_irq_status &= ~m_irq_latch_mask;
+ m_irq_status |= m_irq_latch;
+
+ /* any ints set and they are not masked? */
+ if (
+ (((m_irq_status & m_irq_mask) & 0x3f)!=0)
+ )
+ {
+ logerror("int set %02x\n", m_irq_status & m_irq_mask);
+ /* set int */
+ m_maincpu->set_input_line(0, HOLD_LINE);
+ }
+ else
+ {
+ /* clear int */
+ m_maincpu->set_input_line(0, CLEAR_LINE);
+ }
+}
+
+TIMER_CALLBACK_MEMBER(nc_state::nc_keyboard_timer_callback)
+{
+ LOG(("keyboard int\n"));
+
+ /* set int */
+ m_irq_status |= (1<<3);
+
+ /* update ints */
+ nc_update_interrupts();
+
+ /* don't trigger again, but don't free it */
+ m_keyboard_timer->reset();
+}
+
+
+static const char *const nc_bankhandler_r[]={
+"bank1", "bank2", "bank3", "bank4"};
+
+static const char *const nc_bankhandler_w[]={
+"bank5", "bank6", "bank7", "bank8"};
+
+void nc_state::nc_refresh_memory_bank_config(int bank)
+{
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+ UINT8 *ptr;
+ int mem_type;
+ int mem_bank;
+ char bank1[10];
+ char bank5[10];
+ sprintf(bank1,"bank%d",bank+1);
+ sprintf(bank5,"bank%d",bank+5);
+
+ mem_type = (m_memory_config[bank]>>6) & 0x03;
+ mem_bank = m_memory_config[bank] & 0x03f;
+
+ space.install_read_bank((bank * 0x4000), (bank * 0x4000) + 0x3fff, nc_bankhandler_r[bank]);
+
+ switch (mem_type)
+ {
+ /* ROM */
+ case 3:
+ case 0:
+ {
+ mem_bank &= m_membank_rom_mask;
+ ptr = (memregion("maincpu")->base() + 0x010000) + (mem_bank << 14);
+
+ membank(bank1)->set_base(ptr);
+
+ space.nop_write((bank * 0x4000), (bank * 0x4000) + 0x3fff);
+ LOG(("BANK %d: ROM %d\n",bank,mem_bank));
+ }
+ break;
+
+ /* internal RAM */
+ case 1:
+ {
+ mem_bank &= m_membank_internal_ram_mask;
+ ptr = m_ram->pointer() + (mem_bank << 14);
+
+ membank(bank1)->set_base(ptr);
+ membank(bank5)->set_base(ptr);
+
+ space.install_write_bank((bank * 0x4000), (bank * 0x4000) + 0x3fff, nc_bankhandler_w[bank]);
+ LOG(("BANK %d: RAM\n",bank));
+ }
+ break;
+
+ /* card RAM */
+ case 2:
+ {
+ /* card connected? */
+ if (m_card_status && m_card_ram)
+ {
+ mem_bank &= m_membank_card_ram_mask;
+ ptr = m_card_ram->base() + (mem_bank << 14);
+
+ membank(bank1)->set_base(ptr);
+
+ /* write enabled? */
+ if (ioport("EXTRA")->read() & 0x02)
+ {
+ /* yes */
+ membank(bank5)->set_base(ptr);
+ space.install_write_bank((bank * 0x4000), (bank * 0x4000) + 0x3fff, nc_bankhandler_w[bank]);
+ }
+ else
+ {
+ /* no */
+ space.nop_write((bank * 0x4000), (bank * 0x4000) + 0x3fff);
+ }
+
+ LOG(("BANK %d: CARD-RAM\n",bank));
+ }
+ else
+ {
+ /* if no card connected, then writes fail */
+ space.nop_readwrite((bank * 0x4000), (bank * 0x4000) + 0x3fff);
+ }
+ }
+ break;
+ }
+}
+
+void nc_state::nc_refresh_memory_config()
+{
+ nc_refresh_memory_bank_config(0);
+ nc_refresh_memory_bank_config(1);
+ nc_refresh_memory_bank_config(2);
+ nc_refresh_memory_bank_config(3);
+}
+
+
+TIMER_DEVICE_CALLBACK_MEMBER(nc_state::dummy_timer_callback)
+{
+ int inputport_10_state;
+ int changed_bits;
+
+ inputport_10_state = ioport("EXTRA")->read();
+
+ changed_bits = inputport_10_state^m_previous_inputport_10_state;
+
+ /* on/off button changed state? */
+ if (changed_bits & 0x01)
+ {
+ if (inputport_10_state & 0x01)
+ {
+ /* on NC100 on/off button causes a nmi, on
+ nc200 on/off button causes an int */
+ switch (m_type)
+ {
+ case NC_TYPE_1xx:
+ {
+ LOG(("nmi triggered\n"));
+ m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ }
+ break;
+
+ case NC_TYPE_200:
+ {
+ m_irq_status |= (1 << 4);
+ nc_update_interrupts();
+ }
+ break;
+ }
+ }
+ }
+
+ /* memory card write enable/disable state changed? */
+ if (changed_bits & 0x02)
+ {
+ /* yes refresh memory config */
+ nc_refresh_memory_config();
+ }
+
+ m_previous_inputport_10_state = inputport_10_state;
+}
+
+
+
+void nc_state::nc_common_init_machine()
+{
+ /* setup reset state */
+ m_display_memory_start = 0;
+
+ /* setup reset state */
+ m_memory_config[0] = 0;
+ m_memory_config[1] = 0;
+ m_memory_config[2] = 0;
+ m_memory_config[3] = 0;
+
+ m_previous_inputport_10_state = ioport("EXTRA")->read();
+
+ /* setup reset state ints are masked */
+ m_irq_mask = 0;
+ /* setup reset state no ints wanting servicing */
+ m_irq_status = 0;
+ /* at reset set to 0x0ffff */
+
+ m_irq_latch = 0;
+ m_irq_latch_mask = 0;
+
+ /* setup reset state */
+ m_sound_channel_periods[0] = (m_sound_channel_periods[1] = 0x0ffff);
+
+ /* at reset set to 1 */
+ m_poweroff_control = 1;
+
+ nc_refresh_memory_config();
+ nc_update_interrupts();
+
+ /* at reset set to 0x0ff */
+ m_uart_control = 0x0ff;
+}
+
+static ADDRESS_MAP_START(nc_map, AS_PROGRAM, 8, nc_state )
+ AM_RANGE(0x0000, 0x3fff) AM_READ_BANK("bank1") AM_WRITE_BANK("bank5")
+ AM_RANGE(0x4000, 0x7fff) AM_READ_BANK("bank2") AM_WRITE_BANK("bank6")
+ AM_RANGE(0x8000, 0xbfff) AM_READ_BANK("bank3") AM_WRITE_BANK("bank7")
+ AM_RANGE(0xc000, 0xffff) AM_READ_BANK("bank4") AM_WRITE_BANK("bank8")
+ADDRESS_MAP_END
+
+
+READ8_MEMBER(nc_state::nc_memory_management_r)
+{
+ return m_memory_config[offset];
+}
+
+WRITE8_MEMBER(nc_state::nc_memory_management_w)
+{
+ LOG(("Memory management W: %02x %02x\n",offset,data));
+ m_memory_config[offset] = data;
+
+ nc_refresh_memory_config();
+}
+
+WRITE8_MEMBER(nc_state::nc_irq_mask_w)
+{
+ LOG(("irq mask w: %02x\n", data));
+ LOG_DEBUG(("irq mask nc200 w: %02x\n",data & ((1<<4) | (1<<5) | (1<<6) | (1<<7))));
+
+ /* writing mask clears ints that are to be masked? */
+ m_irq_mask = data;
+
+ nc_update_interrupts();
+}
+
+WRITE8_MEMBER(nc_state::nc_irq_status_w)
+{
+ LOG(("irq status w: %02x\n", data));
+ data = data^0x0ff;
+
+ if (m_type == NC_TYPE_200)
+ {
+ /* Russell Marks confirms that on the NC200, the key scan interrupt must be explicitly
+ cleared. It is not automatically cleared when reading 0x0b9 */
+ if ((data & (1<<3))!=0)
+ {
+ /* set timer to occur again */
+ m_keyboard_timer->reset(attotime::from_msec(10));
+
+ nc_update_interrupts();
+ }
+ }
+
+
+/* writing to status will clear int, will this re-start the key-scan? */
+#if 0
+ if (
+ /* clearing keyboard int? */
+ ((data & (1<<3))!=0) &&
+ /* keyboard int request? */
+ ((m_irq_status & (1<<3))!=0)
+ )
+ {
+ /* set timer to occur again */
+ m_keyboard_timer->reset(attotime::from_msec(10));
+ }
+#endif
+ m_irq_status &=~data;
+
+ nc_update_interrupts();
+}
+
+READ8_MEMBER(nc_state::nc_irq_status_r)
+{
+ return ~((m_irq_status & (~m_irq_latch_mask)) | m_irq_latch);
+}
+
+
+READ8_MEMBER(nc_state::nc_key_data_in_r)
+{
+ static const char *const keynames[] = {
+ "LINE0", "LINE1", "LINE2", "LINE3", "LINE4",
+ "LINE5", "LINE6", "LINE7", "LINE8", "LINE9"
+ };
+
+ if (offset==9)
+ {
+ /* reading 0x0b9 will clear int and re-start scan procedure! */
+ m_irq_status &= ~(1<<3);
+
+ /* set timer to occur again */
+ m_keyboard_timer->reset(attotime::from_msec(10));
+
+ nc_update_interrupts();
+ }
+
+ return ioport(keynames[offset])->read();
+}
+
+
+void nc_state::nc_sound_update(int channel)
+{
+ int on;
+ int frequency;
+ int period;
+ beep_device *beeper_device = NULL;
+
+ switch(channel)
+ {
+ case 0:
+ beeper_device = m_beeper1;
+ break;
+ case 1:
+ beeper_device = m_beeper2;
+ break;
+ }
+
+ period = m_sound_channel_periods[channel];
+
+ /* if top bit is 0, sound is on */
+ on = ((period & (1<<15))==0);
+
+ /* calculate frequency from period */
+ frequency = (int)(1000000.0f/((float)((period & 0x07fff)<<1) * 1.6276f));
+
+ /* set state */
+ beeper_device->set_state(on);
+ /* set frequency */
+ beeper_device->set_frequency(frequency);
+}
+
+WRITE8_MEMBER(nc_state::nc_sound_w)
+{
+ LOG(("sound w: %04x %02x\n", offset, data));
+
+ switch (offset)
+ {
+ case 0x0:
+ {
+ /* update period value */
+ m_sound_channel_periods[0] =
+ (m_sound_channel_periods[0] & 0x0ff00) | (data & 0x0ff);
+
+ nc_sound_update(0);
+ }
+ break;
+
+ case 0x01:
+ {
+ m_sound_channel_periods[0] =
+ (m_sound_channel_periods[0] & 0x0ff) | ((data & 0x0ff)<<8);
+
+ nc_sound_update(0);
+ }
+ break;
+
+ case 0x02:
+ {
+ /* update period value */
+ m_sound_channel_periods[1] =
+ (m_sound_channel_periods[1] & 0x0ff00) | (data & 0x0ff);
+
+ nc_sound_update(1);
+ }
+ break;
+
+ case 0x03:
+ {
+ m_sound_channel_periods[1] =
+ (m_sound_channel_periods[1] & 0x0ff) | ((data & 0x0ff)<<8);
+
+ nc_sound_update(1);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static const int baud_rate_table[]=
+{
+ 128, //150
+ 64, //300
+ 32, //600
+ 16, //1200
+ 8, //2400
+ 4, //4800
+ 2, //9600
+ 1, //19200
+};
+
+WRITE_LINE_MEMBER(nc_state::write_uart_clock)
+{
+ m_uart->write_txc(state);
+ m_uart->write_rxc(state);
+}
+
+WRITE8_MEMBER(nc_state::nc_uart_control_w)
+{
+ /* same for nc100 and nc200 */
+ m_centronics->write_strobe(BIT(data, 6));
+
+ /* on/off changed state? */
+ if (((m_uart_control ^ data) & (1<<3))!=0)
+ {
+ /* changed uart from off to on */
+ if ((data & (1<<3))==0)
+ {
+ machine().device("uart")->reset();
+ }
+ }
+
+ m_uart_clock->set_clock_scale((double)1 / baud_rate_table[(data & 0x07)]);
+
+ m_uart_control = data;
+}
+
+/* NC100 printer emulation */
+/* port 0x040 (write only) = 8-bit printer data */
+/* port 0x030 bit 6 = printer strobe */
+
+
+
+/********************************************************************************************************/
+/* NC100 hardware */
+
+
+
+WRITE8_MEMBER(nc_state::nc100_display_memory_start_w)
+{
+ /* bit 7: A15 */
+ /* bit 6: A14 */
+ /* bit 5: A13 */
+ /* bit 4: A12 */
+ /* bit 3-0: not used */
+ m_display_memory_start = (data & 0x0f0)<<(12-4);
+
+ LOG(("disp memory w: %04x\n", (int) m_display_memory_start));
+}
+
+
+WRITE8_MEMBER(nc_state::nc100_uart_control_w)
+{
+ nc_uart_control_w(space, offset,data);
+
+// /* is this correct?? */
+// if (data & (1<<3))
+// {
+// /* clear latched irq's */
+// m_irq_latch &= ~3;
+// nc_update_interrupts(machine);
+// }
+}
+
+
+WRITE_LINE_MEMBER(nc_state::nc100_tc8521_alarm_callback)
+{
+ // TODO
+}
+
+WRITE_LINE_MEMBER(nc_state::nc100_txrdy_callback)
+{
+ m_irq_latch &= ~(1 << 1);
+
+ /* uart on? */
+ if ((m_uart_control & (1 << 3)) == 0)
+ {
+ if (state)
+ {
+ logerror("tx ready\n");
+ m_irq_latch |= (1 << 1);
+ }
+ }
+
+ nc_update_interrupts();
+}
+
+WRITE_LINE_MEMBER(nc_state::nc100_rxrdy_callback)
+{
+ m_irq_latch &= ~(1<<0);
+
+ if ((m_uart_control & (1<<3))==0)
+ {
+ if (state)
+ {
+ logerror("rx ready\n");
+ m_irq_latch |= (1<<0);
+ }
+ }
+
+ nc_update_interrupts();
+}
+
+WRITE_LINE_MEMBER(nc_state::write_nc100_centronics_ack)
+{
+ m_centronics_ack = state;
+
+ if (state)
+ m_irq_status |= 0x04;
+ else
+ m_irq_status &= ~0x04;
+
+ /* trigger an int if the irq is set */
+ nc_update_interrupts();
+}
+
+WRITE_LINE_MEMBER(nc_state::write_centronics_busy)
+{
+ m_centronics_busy = state;
+}
+
+void nc_state::machine_reset()
+{
+ /* 256k of rom */
+ m_membank_rom_mask = 0x0f;
+
+ m_membank_internal_ram_mask = 3;
+
+ m_membank_card_ram_mask = 0x03f;
+
+ nc_common_init_machine();
+
+ /* serial */
+ m_irq_latch_mask = (1<<0) | (1<<1);
+}
+
+void nc_state::machine_start()
+{
+ m_type = NC_TYPE_1xx;
+
+ std::string region_tag;
+ m_card_ram = memregion(region_tag.assign(m_card->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+ if (m_card_ram)
+ m_card_size = m_card_ram->bytes();
+ else
+ m_card_size = 0;
+
+ /* keyboard timer */
+ m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_keyboard_timer_callback),this));
+ m_keyboard_timer->adjust(attotime::from_msec(10));
+
+ m_nvram->set_base(m_ram->pointer(), m_ram->size());
+}
+
+
+WRITE8_MEMBER(nc_state::nc100_poweroff_control_w)
+{
+ /* bits 7-1: not used */
+ /* bit 0: 1 = no effect, 0 = power off */
+ m_poweroff_control = data;
+ LOG(("nc poweroff control: %02x\n",data));
+}
+
+
+/* nc100 version of card/battery status */
+READ8_MEMBER(nc_state::nc100_card_battery_status_r)
+{
+ int nc_card_battery_status = 0x0fc;
+
+ /* printer */
+ nc_card_battery_status |= m_centronics_ack;
+ nc_card_battery_status |= m_centronics_busy << 1;
+
+ if (m_card_status)
+ {
+ /* card present */
+ nc_card_battery_status &=~(1<<7);
+ }
+
+ if (ioport("EXTRA")->read() & 0x02)
+ {
+ /* card write enable */
+ nc_card_battery_status &=~(1<<6);
+ }
+
+ /* enough power - see bit assignments where
+ nc card battery status is defined */
+ nc_card_battery_status |= (1<<5);
+ nc_card_battery_status &= ~((1<<2) | (1<<3));
+
+ return nc_card_battery_status;
+}
+
+WRITE8_MEMBER(nc_state::nc100_memory_card_wait_state_w)
+{
+ LOG(("nc100 memory card wait state: %02x\n",data));
+}
+
+
+
+static ADDRESS_MAP_START(nc100_io, AS_IO, 8, nc_state )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x00, 0x0f) AM_WRITE(nc100_display_memory_start_w)
+ AM_RANGE(0x10, 0x13) AM_READWRITE(nc_memory_management_r, nc_memory_management_w)
+ AM_RANGE(0x20, 0x20) AM_WRITE(nc100_memory_card_wait_state_w)
+ AM_RANGE(0x30, 0x30) AM_WRITE(nc100_uart_control_w)
+ AM_RANGE(0x40, 0x40) AM_DEVWRITE("cent_data_out", output_latch_device, write)
+ AM_RANGE(0x50, 0x53) AM_WRITE(nc_sound_w)
+ AM_RANGE(0x60, 0x60) AM_WRITE(nc_irq_mask_w)
+ AM_RANGE(0x70, 0x70) AM_WRITE(nc100_poweroff_control_w)
+ AM_RANGE(0x90, 0x90) AM_READWRITE(nc_irq_status_r, nc_irq_status_w)
+ AM_RANGE(0x91, 0x9f) AM_READ(nc_irq_status_r)
+ AM_RANGE(0xa0, 0xaf) AM_READ(nc100_card_battery_status_r)
+ AM_RANGE(0xb0, 0xb9) AM_READ(nc_key_data_in_r)
+ AM_RANGE(0xc0, 0xc0) AM_DEVREADWRITE("uart",i8251_device, data_r, data_w)
+ AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+ AM_RANGE(0xd0, 0xdf) AM_DEVREADWRITE("rtc", rp5c01_device, read, write)
+ADDRESS_MAP_END
+
+
+/* 2008-05 FP:
+Small note about natural keyboard support (both for nc100 and nc200): currently,
+- "Shift" (both L & R) and "Caps Lock" do not work in natural mode (to be investigated)
+- "Function" is mapped to 'Left Control'
+- "Control" is mapped to 'Right Control'
+- "Caps Lock" is mapped to 'Right Alt'
+- "On" is mapped to 'F1'
+- "Stop" is mapped to 'F2'
+- "Symbol" is mapped to 'F3'
+- "Menu" is mapped to 'F4'
+*/
+
+static INPUT_PORTS_START(nc100)
+ PORT_START("LINE0")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift (Left)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_MAMEKEY(LSHIFT))
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift (Right)") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
+ PORT_BIT(0x04, 0x00, IPT_UNUSED)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Left (Red)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, 0x00, IPT_UNUSED)
+ PORT_BIT(0x80, 0x00, IPT_UNUSED)
+
+ PORT_START("LINE1")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Function (Yellow)") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) // 5th row, 1st key on left (where 'fn' is on mac keyboards)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Stop") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(F2))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT(0x10, 0x00, IPT_UNUSED)
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT(0x80, 0x00, IPT_UNUSED)
+
+ PORT_START("LINE2")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT))
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Symbol") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(F3)) // 5th row, 3rd key (where 'Alt' usually stays)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')
+ PORT_BIT(0x10, 0x00, IPT_UNUSED)
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, 0x00, IPT_UNUSED)
+ PORT_BIT(0x80, 0x00, IPT_UNUSED)
+
+ PORT_START("LINE3")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('\xA3')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
+
+ PORT_START("LINE4")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT(0x02, 0x00, IPT_UNUSED)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
+
+ PORT_START("LINE5")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, 0x00, IPT_UNUSED)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('c') PORT_CHAR('C')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('g') PORT_CHAR('G')
+
+ PORT_START("LINE6")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Down (Blue)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del>") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Right (Green)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('#') PORT_CHAR('~')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
+
+ PORT_START("LINE7")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Menu") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(F4))
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
+
+ PORT_START("LINE8")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('@')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
+
+ PORT_START("LINE9")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del<") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR('8')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
+
+ /* these are not part of the nc100 keyboard */
+ /* extra */
+ PORT_START("EXTRA")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("On Button") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(F1))
+ /* pcmcia memory card setting */
+ PORT_DIPNAME( 0x02, 0x002, "PCMCIA Memory card write enable")
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( On ) )
+INPUT_PORTS_END
+
+/**********************************************************************************************************/
+/* NC150 hardware */
+/* to be completed! */
+
+#if 0
+void nc_state::nc150_init_machine()
+{
+ m_membank_internal_ram_mask = 7;
+
+ m_membank_card_ram_mask = 0x03f;
+
+ nc_common_init_machine(machine);
+}
+#endif
+
+
+
+/**********************************************************************************************************/
+/* NC200 hardware */
+
+#ifdef UNUSED_FUNCTION
+WRITE8_MEMBER(nc_state::nc200_display_memory_start_w)
+{
+ /* bit 7: A15 */
+ /* bit 6: A14 */
+ /* bit 5: A13 */
+ /* bit 4-0: not used */
+ m_display_memory_start = (data & 0x0e0)<<(12-4);
+
+ LOG(("disp memory w: %04x\n", (int) m_display_memory_start));
+}
+#endif
+
+
+WRITE_LINE_MEMBER(nc_state::write_nc200_centronics_ack)
+{
+ if (state)
+ m_irq_status |= 0x01;
+ else
+ m_irq_status &= ~0x01;
+
+ /* trigger an int if the irq is set */
+ nc_update_interrupts();
+}
+
+/* assumption. nc200 uses the same uart chip. The rxrdy and txrdy are combined
+together with a or to generate a single interrupt */
+
+void nc_state::nc200_refresh_uart_interrupt()
+{
+ m_irq_latch &=~(1<<2);
+
+ /* uart enabled? */
+ if ((m_uart_control & (1<<3))==0)
+ {
+ if ((m_nc200_uart_interrupt_irq & 0x03)!=0)
+ {
+ m_irq_latch |= (1<<2);
+ }
+ }
+ nc_update_interrupts();
+}
+
+WRITE_LINE_MEMBER(nc_state::nc200_txrdy_callback)
+{
+// m_nc200_uart_interrupt_irq &=~(1<<0);
+//
+// if (state)
+// {
+// m_nc200_uart_interrupt_irq |=(1<<0);
+// }
+//
+// nc200_refresh_uart_interrupt();
+}
+
+WRITE_LINE_MEMBER(nc_state::nc200_rxrdy_callback)
+{
+ m_nc200_uart_interrupt_irq &=~(1<<1);
+
+ if (state)
+ {
+ m_nc200_uart_interrupt_irq |=(1<<1);
+ }
+
+ nc200_refresh_uart_interrupt();
+}
+
+WRITE_LINE_MEMBER( nc_state::nc200_fdc_interrupt )
+{
+#if 0
+ m_irq_latch &=~(1<<5);
+
+ if (state)
+ {
+ m_irq_latch |=(1<<5);
+ }
+#endif
+ m_irq_status &=~(1<<5);
+
+ if (state)
+ {
+ m_irq_status |=(1<<5);
+ }
+
+ nc_update_interrupts();
+}
+
+#ifdef UNUSED_FUNCTION
+void nc_state::nc200_floppy_drive_index_callback(int drive_id)
+{
+ LOG_DEBUG(("nc200 index pulse\n"));
+// m_irq_status |= (1<<4);
+
+// nc_update_interrupts(Machine);
+}
+#endif
+
+MACHINE_RESET_MEMBER(nc_state, nc200)
+{
+ /* 512k of rom */
+ m_membank_rom_mask = 0x1f;
+
+ m_membank_internal_ram_mask = 7;
+
+ m_membank_card_ram_mask = 0x03f;
+
+ nc_common_init_machine();
+
+ m_nc200_uart_interrupt_irq = 0;
+
+ /* fdc, serial */
+ m_irq_latch_mask = /*(1<<5) |*/ (1<<2);
+
+ nc200_video_set_backlight(0);
+}
+
+MACHINE_START_MEMBER(nc_state, nc200)
+{
+ m_type = NC_TYPE_200;
+
+ std::string region_tag;
+ m_card_ram = memregion(region_tag.assign(m_card->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+ if (m_card_ram)
+ m_card_size = m_card_ram->bytes();
+ else
+ m_card_size = 0;
+
+ /* keyboard timer */
+ m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_keyboard_timer_callback),this));
+ m_keyboard_timer->adjust(attotime::from_msec(10));
+
+ m_nvram->set_base(m_ram->pointer(), m_ram->size());
+}
+
+/*
+NC200:
+
+ bit 7: memory card present 0 = yes, 1 = no
+ bit 6: memory card write protected 1=yes 0=no
+ bit 5: lithium battery 0 if >= 2.7 volts
+ bit 4: input voltage = 1, if >= to 4 volts
+ bit 3: ??
+ bit 2: alkaline batteries. 0 if >=3.2 volts
+ bit 1: ??
+ bit 0: battery power: if 1: batteries are too low for disk usage, if 0: batteries ok for disc usage
+*/
+
+
+/* nc200 version of card/battery status */
+READ8_MEMBER(nc_state::nc200_card_battery_status_r)
+{
+ int nc_card_battery_status = 0x0ff;
+
+ /* enough power */
+
+ /* input voltage ok */
+ nc_card_battery_status |=(1<<4);
+ /* lithium batteries and alkaline batteries have enough power,
+ and there is enough power for disk usage */
+ nc_card_battery_status &=~((1<<5) | (1<<2) | (1<<0));
+
+ if (m_card_status)
+ {
+ /* card present */
+ nc_card_battery_status&=~(1<<7);
+ }
+
+ if (ioport("EXTRA")->read() & 0x02)
+ {
+ /* card write enable */
+ nc_card_battery_status &=~(1<<6);
+ }
+
+ return nc_card_battery_status;
+}
+
+
+/* port &80:
+
+ bit 0: Parallel interface BUSY
+ */
+
+READ8_MEMBER(nc_state::nc200_printer_status_r)
+{
+ UINT8 result = 0;
+
+ result |= m_centronics_busy;
+
+ return result;
+}
+
+
+WRITE8_MEMBER(nc_state::nc200_uart_control_w)
+{
+ /* int reset_fdc = (m_uart_control^data) & (1<<5); */
+
+ nc_uart_control_w(space, offset,data);
+
+ if (data & (1<<3))
+ {
+ m_nc200_uart_interrupt_irq &=~3;
+
+ nc200_refresh_uart_interrupt();
+ }
+
+ /* bit 5 is used in disk interface */
+ LOG_DEBUG(("bit 5: PC: %04x %02x\n", m_maincpu->pc(), data & (1 << 5)));
+}
+
+
+/* bit 7: same as nc100 */
+/* bit 2: ?? */
+/* bit 1: ?? */
+/* %10000110 = 0x086 */
+/* %10000010 = 0x082 */
+/* %10000011 = 0x083 */
+/* writes 86,82 */
+
+/* bit 7: nc200 power control: 1=on, 0=off */
+/* bit 1: disk motor?? */
+/* bit 0: UPD765 Terminal Count input */
+
+WRITE8_MEMBER(nc_state::nc200_memory_card_wait_state_w)
+{
+ upd765a_device *fdc = machine().device<upd765a_device>("upd765");
+ LOG_DEBUG(("nc200 memory card wait state: PC: %04x %02x\n", m_maincpu->pc(), data));
+#if 0
+ floppy_drive_set_motor_state(0, 1);
+ floppy_drive_set_ready_state(0, 1, 1);
+#endif
+ fdc->tc_w(data & 0x01);
+}
+
+/* bit 2: backlight: 1=off, 0=on */
+/* bit 1 cleared to zero in disk code */
+/* bit 0 seems to be the same as nc100 */
+WRITE8_MEMBER(nc_state::nc200_poweroff_control_w)
+{
+ LOG_DEBUG(("nc200 power off: PC: %04x %02x\n", m_maincpu->pc(), data));
+
+ nc200_video_set_backlight(((data ^ (1 << 2)) >> 2) & 0x01);
+}
+
+static ADDRESS_MAP_START(nc200_io, AS_IO, 8, nc_state )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x0f) AM_WRITE(nc100_display_memory_start_w)
+ AM_RANGE(0x10, 0x13) AM_READWRITE(nc_memory_management_r, nc_memory_management_w)
+ AM_RANGE(0x20, 0x20) AM_WRITE(nc200_memory_card_wait_state_w)
+ AM_RANGE(0x30, 0x30) AM_WRITE(nc200_uart_control_w)
+ AM_RANGE(0x40, 0x40) AM_DEVWRITE("cent_data_out", output_latch_device, write)
+ AM_RANGE(0x50, 0x53) AM_WRITE(nc_sound_w)
+ AM_RANGE(0x60, 0x60) AM_WRITE(nc_irq_mask_w)
+ AM_RANGE(0x70, 0x70) AM_WRITE(nc200_poweroff_control_w)
+ AM_RANGE(0x80, 0x80) AM_READ(nc200_printer_status_r)
+ AM_RANGE(0x90, 0x90) AM_READWRITE(nc_irq_status_r, nc_irq_status_w)
+ AM_RANGE(0xa0, 0xa0) AM_READ(nc200_card_battery_status_r)
+ AM_RANGE(0xb0, 0xb9) AM_READ(nc_key_data_in_r)
+ AM_RANGE(0xc0, 0xc0) AM_DEVREADWRITE("uart",i8251_device, data_r, data_w)
+ AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+ AM_RANGE(0xd0, 0xd1) AM_DEVREADWRITE("mc", mc146818_device, read, write)
+ AM_RANGE(0xe0, 0xe1) AM_DEVICE("upd765", upd765a_device, map)
+ADDRESS_MAP_END
+
+static INPUT_PORTS_START(nc200)
+ PORT_START("LINE0")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift (Left)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_MAMEKEY(LSHIFT))
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift (Right)") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Left (Red)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, 0x00, IPT_UNUSED)
+ PORT_BIT(0x80, 0x00, IPT_UNUSED)
+
+ PORT_START("LINE1")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Function (Yellow)") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) // 5th row, 1st key on left (where 'fn' is on mac keyboards)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Stop") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(F2))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT(0x10, 0x00, IPT_UNUSED)
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, 0x00, IPT_UNUSED)
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
+
+ PORT_START("LINE2")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT))
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Symbol") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(F3)) // 5th row, 3rd key (where 'Alt' usually stays)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
+ PORT_BIT(0x80, 0x00, IPT_UNUSED)
+
+ PORT_START("LINE3")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('\xA3')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
+
+ PORT_START("LINE4")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
+ PORT_BIT(0x20, 0x00, IPT_UNUSED)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
+
+ PORT_START("LINE5")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, 0x00, IPT_UNUSED)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('c') PORT_CHAR('C')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('g') PORT_CHAR('G')
+
+ PORT_START("LINE6")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Down (Blue)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del>") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Right (Green)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('#') PORT_CHAR('~')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
+
+ PORT_START("LINE7")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Cursor Up (White)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Menu") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(F4))
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
+
+ PORT_START("LINE8")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('@')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
+
+ PORT_START("LINE9")
+ PORT_BIT(0x01, 0x00, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del<") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR('8')
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
+
+ /* not part of the nc200 keyboard */
+ PORT_START("EXTRA")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("On Button") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(F1))
+ /* pcmcia memory card setting */
+ PORT_DIPNAME( 0x02, 0x002, "PCMCIA Memory card write enable")
+ PORT_DIPSETTING( 0x00, DEF_STR( Off) )
+ PORT_DIPSETTING( 0x02, DEF_STR( On) )
+INPUT_PORTS_END
+
+/**********************************************************************************************************/
+
+static MACHINE_CONFIG_START( nc100, nc_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", Z80, /*6000000*/ 4606000) /* Russell Marks says this is more accurate */
+ MCFG_CPU_PROGRAM_MAP(nc_map)
+ MCFG_CPU_IO_MAP(nc100_io)
+ MCFG_QUANTUM_TIME(attotime::from_hz(60))
+
+ /* video hardware */
+ MCFG_SCREEN_ADD("screen", LCD)
+ MCFG_SCREEN_REFRESH_RATE(50)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+ MCFG_SCREEN_SIZE(480, 64)
+ MCFG_SCREEN_VISIBLE_AREA(0, 480-1, 0, 64-1)
+ MCFG_SCREEN_UPDATE_DRIVER(nc_state, screen_update_nc)
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_PALETTE_ADD("palette", NC_NUM_COLOURS)
+ MCFG_PALETTE_INIT_OWNER(nc_state, nc)
+
+ MCFG_DEFAULT_LAYOUT(layout_lcd)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("beep.1", BEEP, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+ MCFG_SOUND_ADD("beep.2", BEEP, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+
+ /* printer */
+ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer")
+ MCFG_CENTRONICS_ACK_HANDLER(WRITELINE(nc_state, write_nc100_centronics_ack))
+ MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(nc_state, write_centronics_busy))
+
+ MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics")
+
+ /* uart */
+ MCFG_DEVICE_ADD("uart", I8251, 0)
+ MCFG_I8251_RXRDY_HANDLER(WRITELINE(nc_state,nc100_rxrdy_callback))
+ MCFG_I8251_TXRDY_HANDLER(WRITELINE(nc_state,nc100_txrdy_callback))
+
+ MCFG_DEVICE_ADD("uart_clock", CLOCK, 19200)
+ MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(nc_state, write_uart_clock))
+
+ /* rtc */
+ MCFG_DEVICE_ADD("rtc", RP5C01, XTAL_32_768kHz)
+ MCFG_RP5C01_OUT_ALARM_CB(WRITELINE(nc_state, nc100_tc8521_alarm_callback))
+
+ /* cartridge */
+ MCFG_GENERIC_CARTSLOT_ADD("cardslot", generic_plain_slot, NULL)
+ MCFG_GENERIC_LOAD(nc_state, nc_pcmcia_card)
+ MCFG_GENERIC_UNLOAD(nc_state, nc_pcmcia_card)
+
+ /* internal ram */
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("64K")
+ MCFG_NVRAM_ADD_NO_FILL("nvram")
+
+ /* dummy timer */
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("dummy_timer", nc_state, dummy_timer_callback, attotime::from_hz(50))
+MACHINE_CONFIG_END
+
+static const floppy_format_type ibmpc_floppy_formats[] = {
+ FLOPPY_PC_FORMAT,
+ FLOPPY_MFI_FORMAT,
+ NULL
+};
+
+static SLOT_INTERFACE_START( ibmpc_floppies )
+ SLOT_INTERFACE( "525dd", FLOPPY_525_DD )
+SLOT_INTERFACE_END
+
+static MACHINE_CONFIG_DERIVED( nc200, nc100 )
+
+ MCFG_CPU_MODIFY( "maincpu" )
+ MCFG_CPU_IO_MAP(nc200_io)
+
+ MCFG_MACHINE_START_OVERRIDE(nc_state, nc200)
+ MCFG_MACHINE_RESET_OVERRIDE(nc_state, nc200)
+
+ /* video hardware */
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_SIZE(NC200_SCREEN_WIDTH, NC200_SCREEN_HEIGHT)
+ MCFG_SCREEN_VISIBLE_AREA(0, NC200_SCREEN_WIDTH-1, 0, NC200_SCREEN_HEIGHT-1)
+
+ MCFG_PALETTE_MODIFY("palette")
+ MCFG_PALETTE_ENTRIES(NC200_NUM_COLOURS)
+ MCFG_PALETTE_INIT_OWNER(nc_state, nc)
+
+ /* printer */
+ MCFG_DEVICE_MODIFY("centronics")
+ MCFG_CENTRONICS_ACK_HANDLER(WRITELINE(nc_state, write_nc200_centronics_ack))
+
+ /* uart */
+ MCFG_DEVICE_MODIFY("uart")
+ MCFG_I8251_RXRDY_HANDLER(WRITELINE(nc_state,nc200_rxrdy_callback))
+ MCFG_I8251_TXRDY_HANDLER(WRITELINE(nc_state,nc200_txrdy_callback))
+
+ /* no rtc */
+ MCFG_DEVICE_REMOVE("rtc")
+
+ MCFG_UPD765A_ADD("upd765", true, true)
+ MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(nc_state, nc200_fdc_interrupt))
+ MCFG_FLOPPY_DRIVE_ADD("upd765:0", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("upd765:1", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
+
+ MCFG_MC146818_ADD( "mc", XTAL_4_194304Mhz )
+
+ /* internal ram */
+ MCFG_RAM_MODIFY(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("128K")
+
+MACHINE_CONFIG_END
+
+
+/***************************************************************************
+
+ Game driver(s)
+
+***************************************************************************/
+
+ROM_START(nc100)
+ ROM_REGION(((64*1024)+(256*1024)), "maincpu",0)
+ ROM_SYSTEM_BIOS(0, "106", "ROM v1.06")
+ ROMX_LOAD("nc100a.rom", 0x010000, 0x040000, CRC(849884f9) SHA1(ff030dd334ca867d620ee4a94b142ef0d93b69b6), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(1, "102dk", "ROM v1.02 Danish")
+ ROMX_LOAD("nc100_dk_a1.rom", 0x010000, 0x040000, CRC(ebb54923) SHA1(30321011384c5e10204b9a837430c36fc63580d2), ROM_BIOS(2))
+ ROM_SYSTEM_BIOS(2, "102de", "ROM v1.02 German")
+ ROMX_LOAD("nc100_de_a1.rom", 0x010000, 0x040000, CRC(bd9ce223) SHA1(2efb26911832bf1456d76d2508e24c0733dc216d), ROM_BIOS(3))
+ ROM_SYSTEM_BIOS(3, "100", "ROM v1.00")
+ ROMX_LOAD("nc100.rom", 0x010000, 0x040000, CRC(a699eca3) SHA1(ce217d5a298b959ccc3d7bc5c93b1dba043f1339), ROM_BIOS(4))
+ROM_END
+
+
+ROM_START(dw225)
+ ROM_REGION(((64*1024)+(512*1024)), "maincpu",0)
+ ROM_LOAD("dr (1.06).ic303", 0x010000, 0x080000, CRC(fcf2f7bd) SHA1(a69951618b24e97154cb4284d215cbf4aa9fb34f))
+ROM_END
+
+
+ROM_START(nc150)
+ ROM_REGION(((64*1024)+(512*1024)), "maincpu",0)
+ ROM_SYSTEM_BIOS(0, "b2", "French B2")
+ ROMX_LOAD("nc150_fr_b2.rom", 0x010000, 0x080000, CRC(be442d14) SHA1(f141d409dc72dc1e6662c21a147231c4df3be6b8), ROM_BIOS(1)) /* French */
+ ROM_SYSTEM_BIOS(1, "b1", "Italian B1")
+ ROMX_LOAD("nc150_it_b1.rom", 0x010000, 0x080000, CRC(1b2fe2fd) SHA1(67eb6bce0b0d4668401d9c8f5a900dc6bd135c21), ROM_BIOS(2)) /* Italian */
+ROM_END
+
+
+ROM_START(nc200)
+ ROM_REGION(((64*1024)+(512*1024)), "maincpu",0)
+ ROM_LOAD("nc200.rom", 0x010000, 0x080000, CRC(bb8180e7) SHA1(fb5c93b0a3e199202c6a12548d2617f7a09bae47))
+ROM_END
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
+COMP( 1992, nc100, 0, 0, nc100, nc100, nc_state, nc, "Amstrad plc", "NC100", 0 )
+COMP( 1992, dw225, nc100, 0, nc100, nc100, nc_state, nc, "NTS Computer Systems", "DreamWriter 225", 0 )
+COMP( 1992, nc150, nc100, 0, nc100, nc100, nc_state, nc, "Amstrad plc", "NC150", 0 )
+COMP( 1993, nc200, 0, 0, nc200, nc200, nc_state, nc, "Amstrad plc", "NC200", MACHINE_NOT_WORKING ) // boot hangs while checking the MC146818 UIP (update in progress) bit