/****************************************************************************** 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, 6mhz - 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 - nec765 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 "driver.h" #include "machine/mc146818.h" /* for NC200 real time clock */ #include "includes/nc.h" #include "includes/tc8521.h" /* for NC100 real time clock */ #include "includes/msm8251.h" /* for NC100 uart */ #include "machine/nec765.h" /* for NC200 disk drive interface */ #include "devices/mflopimg.h" /* for NC200 disk image */ #include "formats/pc_dsk.h" /* for NC200 disk image */ #include "includes/serial.h" /* for serial data transfers */ #include "devices/cartslot.h" #include "sound/beep.h" /* uncomment for verbose debugging information */ /* #define VERBOSE */ #define NC200_DEBUG #include "includes/centroni.h" #include "devices/printer.h" /* the serial clock is generated by the nc hardware and connected to the msm8251 receive clock and transmit clock inputs */ static mame_timer *nc_serial_timer; static void nc_printer_update(int); UINT8 nc_type; static char nc_memory_config[4]; unsigned long nc_display_memory_start; static mame_timer *nc_keyboard_timer = NULL; static int nc_membank_rom_mask; static int nc_membank_internal_ram_mask; int nc_membank_card_ram_mask; static void nc100_machine_stop(running_machine *machine); static void nc200_machine_stop(running_machine *machine); /* 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: nec765 terminal count input */ static UINT8 nc_poweroff_control; /* this is not a real register, it is used to record card status */ /* ==0, card not inserted, !=0 card is inserted */ static int nc_card_status = 0; /* set pcmcia card present state */ void nc_set_card_present_state(int state) { nc_card_status = state; } /* card ram */ unsigned char *nc_card_ram = NULL; static unsigned char nc_uart_control; static int nc_irq_mask; static int nc_irq_status; /* 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 */ static int nc_irq_latch; /* this is a mask of irqs that are latched, and it is different for nc100 and nc200 */ static int nc_irq_latch_mask; static int nc_sound_channel_periods[2]; static void nc_update_interrupts(void) { nc_irq_status &= ~nc_irq_latch_mask; nc_irq_status |= nc_irq_latch; /* any ints set and they are not masked? */ if ( (((nc_irq_status & nc_irq_mask) & 0x3f)!=0) ) { logerror("int set %02x\n",nc_irq_status & nc_irq_mask); /* set int */ cpunum_set_input_line(0,0, HOLD_LINE); } else { /* clear int */ cpunum_set_input_line(0,0, CLEAR_LINE); } } static TIMER_CALLBACK(nc_keyboard_timer_callback) { #ifdef VERBOSE logerror("keyboard int\n"); #endif /* set int */ nc_irq_status |= (1<<3); /* update ints */ nc_update_interrupts(); /* don't trigger again, but don't free it */ mame_timer_reset(nc_keyboard_timer, time_never); } static read8_handler nc_bankhandler_r[]={ MRA8_BANK1, MRA8_BANK2, MRA8_BANK3, MRA8_BANK4}; static write8_handler nc_bankhandler_w[]={ MWA8_BANK5, MWA8_BANK6, MWA8_BANK7, MWA8_BANK8}; static void nc_refresh_memory_bank_config(int bank) { int mem_type; int mem_bank; read8_handler read_handler; write8_handler write_handler = NULL; mem_type = (nc_memory_config[bank]>>6) & 0x03; mem_bank = nc_memory_config[bank] & 0x03f; read_handler = nc_bankhandler_r[bank]; switch (mem_type) { /* ROM */ case 3: case 0: { unsigned char *addr; mem_bank = mem_bank & nc_membank_rom_mask; addr = (memory_region(REGION_CPU1)+0x010000) + (mem_bank<<14); memory_set_bankptr(bank+1, addr); write_handler = MWA8_NOP; #ifdef VERBOSE logerror("BANK %d: ROM %d\n",bank,mem_bank); #endif } break; /* internal RAM */ case 1: { unsigned char *addr; mem_bank = mem_bank & nc_membank_internal_ram_mask; addr = mess_ram + (mem_bank<<14); memory_set_bankptr(bank+1, addr); memory_set_bankptr(bank+5, addr); write_handler = nc_bankhandler_w[bank]; #ifdef VERBOSE logerror("BANK %d: RAM\n",bank); #endif } break; /* card RAM */ case 2: { /* card connected? */ if ((nc_card_status) && (nc_card_ram!=NULL)) { unsigned char *addr; mem_bank = mem_bank & nc_membank_card_ram_mask; addr = nc_card_ram + (mem_bank<<14); memory_set_bankptr(bank+1, addr); /* write enabled? */ if (readinputport(10) & 0x02) { /* yes */ memory_set_bankptr(bank+5, addr); write_handler = nc_bankhandler_w[bank]; } else { /* no */ write_handler = MWA8_NOP; } #ifdef VERBOSE logerror("BANK %d: CARD-RAM\n",bank); #endif } else { /* if no card connected, then writes fail */ read_handler = MRA8_NOP; write_handler = MWA8_NOP; } } break; } memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, (bank * 0x4000), (bank * 0x4000) + 0x3fff, 0, 0, read_handler); if (write_handler) { memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, (bank * 0x4000), (bank * 0x4000) + 0x3fff, 0, 0, write_handler); } } static void nc_refresh_memory_config(void) { nc_refresh_memory_bank_config(0); nc_refresh_memory_bank_config(1); nc_refresh_memory_bank_config(2); nc_refresh_memory_bank_config(3); } static mame_file *file; /* restore a block of memory from the nvram file */ static void nc_common_restore_memory_from_stream(void) { unsigned long stored_size; unsigned long restore_size; if (!file) return; #ifdef VERBOSE logerror("restoring nc memory\n"); #endif /* get size of memory data stored */ mame_fread(file, &stored_size, sizeof(unsigned long)); if (stored_size > mess_ram_size) restore_size = mess_ram_size; else restore_size = stored_size; /* read as much as will fit into memory */ mame_fread(file, mess_ram, restore_size); /* seek over remaining data */ mame_fseek(file, SEEK_CUR,stored_size - restore_size); } /* store a block of memory to the nvram file */ static void nc_common_store_memory_to_stream(void) { if (!file) return; #ifdef VERBOSE logerror("storing nc memory\n"); #endif /* write size of memory data */ mame_fwrite(file, &mess_ram_size, sizeof(unsigned long)); /* write data block */ mame_fwrite(file, mess_ram, mess_ram_size); } static void nc_common_open_stream_for_reading(void) { char filename[MAX_DRIVER_NAME_CHARS + 5]; sprintf(filename,"%s.nv", Machine->gamedrv->name); mame_fopen(SEARCHPATH_MEMCARD, filename, OPEN_FLAG_READ, &file); } static void nc_common_open_stream_for_writing(void) { char filename[MAX_DRIVER_NAME_CHARS + 5]; sprintf(filename,"%s.nv", Machine->gamedrv->name); mame_fopen(SEARCHPATH_MEMCARD, filename, OPEN_FLAG_WRITE, &file); } static void nc_common_close_stream(void) { if (file) mame_fclose(file); } static int previous_inputport_10_state; static TIMER_CALLBACK(dummy_timer_callback) { int inputport_10_state; int changed_bits; inputport_10_state = readinputport(10); changed_bits = inputport_10_state^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 (nc_type) { case NC_TYPE_1xx: { #ifdef VERBOSE logerror("nmi triggered\n"); #endif cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE); } break; case NC_TYPE_200: { nc_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(); } previous_inputport_10_state = inputport_10_state; } static TIMER_CALLBACK(nc_serial_timer_callback); static void nc_common_init_machine(void) { /* setup reset state */ nc_display_memory_start = 0; /* setup reset state */ nc_memory_config[0] = 0; nc_memory_config[1] = 0; nc_memory_config[2] = 0; nc_memory_config[3] = 0; previous_inputport_10_state = readinputport(10); /* setup reset state ints are masked */ nc_irq_mask = 0; /* setup reset state no ints wanting servicing */ nc_irq_status = 0; /* at reset set to 0x0ffff */ nc_irq_latch = 0; nc_irq_latch_mask = 0; /* setup reset state */ nc_sound_channel_periods[0] = (nc_sound_channel_periods[1] = 0x0ffff); /* at reset set to 1 */ nc_poweroff_control = 1; nc_refresh_memory_config(); nc_update_interrupts(); /* keyboard timer */ nc_keyboard_timer = mame_timer_alloc(nc_keyboard_timer_callback); mame_timer_adjust(nc_keyboard_timer, MAME_TIME_IN_MSEC(10), 0, time_zero); /* dummy timer */ mame_timer_pulse(MAME_TIME_IN_HZ(50), 0, dummy_timer_callback); /* serial timer */ nc_serial_timer = mame_timer_alloc(nc_serial_timer_callback); /* at reset set to 0x0ff */ nc_uart_control = 0x0ff; } static ADDRESS_MAP_START(nc_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x3fff) AM_READWRITE(MRA8_BANK1, MWA8_BANK5) AM_RANGE(0x4000, 0x7fff) AM_READWRITE(MRA8_BANK2, MWA8_BANK6) AM_RANGE(0x8000, 0xbfff) AM_READWRITE(MRA8_BANK3, MWA8_BANK7) AM_RANGE(0xc000, 0xffff) AM_READWRITE(MRA8_BANK4, MWA8_BANK8) ADDRESS_MAP_END static READ8_HANDLER(nc_memory_management_r) { return nc_memory_config[offset]; } static WRITE8_HANDLER(nc_memory_management_w) { #ifdef VERBOSE logerror("Memory management W: %02x %02x\n",offset,data); #endif nc_memory_config[offset] = data; nc_refresh_memory_config(); } static WRITE8_HANDLER(nc_irq_mask_w) { #ifdef VERBOSE logerror("irq mask w: %02x\n", data); #endif #ifdef NC200_DEBUG logerror("irq mask nc200 w: %02x\n",data & ((1<<4) | (1<<5) | (1<<6) | (1<<7))); #endif /* writing mask clears ints that are to be masked? */ nc_irq_mask = data; nc_update_interrupts(); } static WRITE8_HANDLER(nc_irq_status_w) { #ifdef VERBOSE logerror("irq status w: %02x\n", data); #endif data = data^0x0ff; if (nc_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 */ mame_timer_reset(nc_keyboard_timer, MAME_TIME_IN_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? */ ((nc_irq_status & (1<<3))!=0) ) { /* set timer to occur again */ mame_timer_reset(nc_keyboard_timer, MAME_TIME_IN_MSEC(10)); } #endif nc_irq_status &=~data; nc_update_interrupts(); } static READ8_HANDLER(nc_irq_status_r) { return ~((nc_irq_status & (~nc_irq_latch_mask)) | nc_irq_latch); } static READ8_HANDLER(nc_key_data_in_r) { if (offset==9) { /* reading 0x0b9 will clear int and re-start scan procedure! */ nc_irq_status &= ~(1<<3); /* set timer to occur again */ mame_timer_reset(nc_keyboard_timer, MAME_TIME_IN_MSEC(10)); nc_update_interrupts(); } return readinputport(offset); } static void nc_sound_update(int channel) { int on; int frequency; int period; period = nc_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 */ beep_set_state(channel, on); /* set frequency */ beep_set_frequency(channel, frequency); } static WRITE8_HANDLER(nc_sound_w) { #ifdef VERBOSE logerror("sound w: %04x %02x\n", offset, data); #endif switch (offset) { case 0x0: { /* update period value */ nc_sound_channel_periods[0] = (nc_sound_channel_periods[0] & 0x0ff00) | (data & 0x0ff); nc_sound_update(0); } break; case 0x01: { nc_sound_channel_periods[0] = (nc_sound_channel_periods[0] & 0x0ff) | ((data & 0x0ff)<<8); nc_sound_update(0); } break; case 0x02: { /* update period value */ nc_sound_channel_periods[1] = (nc_sound_channel_periods[1] & 0x0ff00) | (data & 0x0ff); nc_sound_update(1); } break; case 0x03: { nc_sound_channel_periods[1] = (nc_sound_channel_periods[1] & 0x0ff) | ((data & 0x0ff)<<8); nc_sound_update(1); } break; default: break; } } static unsigned long baud_rate_table[]= { 150, 300, 600, 1200, 2400, 4800, 9600, 19200 }; static TIMER_CALLBACK(nc_serial_timer_callback) { msm8251_transmit_clock(); msm8251_receive_clock(); } static WRITE8_HANDLER(nc_uart_control_w) { /* update printer state */ nc_printer_update(data); /* on/off changed state? */ if (((nc_uart_control ^ data) & (1<<3))!=0) { /* changed uart from off to on */ if ((data & (1<<3))==0) { msm8251_reset(); } } mame_timer_adjust(nc_serial_timer, time_zero, 0, MAME_TIME_IN_HZ(baud_rate_table[(data & 0x07)])); nc_uart_control = data; } /* NC100 printer emulation */ /* port 0x040 (write only) = 8-bit printer data */ /* port 0x030 bit 6 = printer strobe */ /* same for nc100 and nc200 */ static WRITE8_HANDLER(nc_printer_data_w) { #ifdef VERBOSE logerror("printer write %02x\n",data); #endif centronics_write_data(0,data); } /* same for nc100 and nc200 */ static void nc_printer_update(int port0x030) { int handshake = 0; if (port0x030 & (1<<6)) { handshake = CENTRONICS_STROBE; } /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); centronics_write_handshake(0, handshake, CENTRONICS_STROBE); } /********************************************************************************************************/ /* NC100 hardware */ static int previous_alarm_state; static WRITE8_HANDLER(nc100_display_memory_start_w) { /* bit 7: A15 */ /* bit 6: A14 */ /* bit 5: A13 */ /* bit 4: A12 */ /* bit 3-0: not used */ nc_display_memory_start = (data & 0x0f0)<<(12-4); #ifdef VERBOSE logerror("disp memory w: %04x\n", (int) nc_display_memory_start); #endif } static WRITE8_HANDLER(nc100_uart_control_w) { nc_uart_control_w(offset,data); // /* is this correct?? */ // if (data & (1<<3)) // { // /* clear latched irq's */ // nc_irq_latch &= ~3; // nc_update_interrupts(); // } } static void nc100_tc8521_alarm_callback(int state) { /* I'm assuming that the nmi is edge triggered */ /* a interrupt from the fdc will cause a change in line state, and the nmi will be triggered, but when the state changes because the int is cleared this will not cause another nmi */ /* I'll emulate it like this to be sure */ if (state!=previous_alarm_state) { if (state) { /* I'll pulse it because if I used hold-line I'm not sure it would clear - to be checked */ cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE); } } previous_alarm_state = state; } static void nc100_txrdy_callback(int state) { nc_irq_latch &= ~(1<<1); /* uart on? */ if ((nc_uart_control & (1<<3))==0) { if (state) { // #ifdef VERBOSE logerror("tx ready\n"); // #endif nc_irq_latch |= (1<<1); } } nc_update_interrupts(); } static void nc100_rxrdy_callback(int state) { nc_irq_latch &= ~(1<<0); if ((nc_uart_control & (1<<3))==0) { if (state) { //#ifdef VERBOSE logerror("rx ready\n"); //#endif nc_irq_latch |= (1<<0); } } nc_update_interrupts(); } static struct tc8521_interface nc100_tc8521_interface= { nc100_tc8521_alarm_callback, }; static struct msm8251_interface nc100_uart_interface= { nc100_txrdy_callback, NULL, nc100_rxrdy_callback }; static void nc100_printer_handshake_in(int number, int data, int mask) { nc_irq_status &= ~(1<<2); if (mask & CENTRONICS_ACKNOWLEDGE) { if (data & CENTRONICS_ACKNOWLEDGE) { nc_irq_status|=(1<<2); } } /* trigger an int if the irq is set */ nc_update_interrupts(); } static CENTRONICS_CONFIG nc100_cent_config[1]={ { PRINTER_CENTRONICS, nc100_printer_handshake_in }, }; static void nc100_machine_reset(running_machine *machine) { /* 256k of rom */ nc_membank_rom_mask = 0x0f; nc_membank_internal_ram_mask = 3; nc_membank_card_ram_mask = 0x03f; nc_common_init_machine(); tc8521_init(&nc100_tc8521_interface); msm8251_init(&nc100_uart_interface); centronics_config(0, nc100_cent_config); /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); nc_common_open_stream_for_reading(); tc8521_load_stream(file); nc_common_restore_memory_from_stream(); nc_common_close_stream(); /* serial */ nc_irq_latch_mask = (1<<0) | (1<<1); } static void nc100_machine_stop(running_machine *machine) { nc_common_open_stream_for_writing(); tc8521_save_stream(file); nc_common_store_memory_to_stream(); nc_common_close_stream(); } static MACHINE_START( nc100 ) { nc_type = NC_TYPE_1xx; add_reset_callback(machine, nc100_machine_reset); add_exit_callback(machine, nc100_machine_stop); } static WRITE8_HANDLER(nc100_poweroff_control_w) { /* bits 7-1: not used */ /* bit 0: 1 = no effect, 0 = power off */ nc_poweroff_control = data; #ifdef VERBOSE logerror("nc poweroff control: %02x\n",data); #endif } /* nc100 version of card/battery status */ static READ8_HANDLER(nc100_card_battery_status_r) { int nc_card_battery_status = 0x0ff; int printer_handshake; if (nc_card_status) { /* card present */ nc_card_battery_status &=~(1<<7); } if (readinputport(10) & 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)); /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); printer_handshake = centronics_read_handshake(0); nc_card_battery_status |=(1<<1); /* if printer is not online, it is busy */ if ((printer_handshake & CENTRONICS_ONLINE)!=0) { nc_card_battery_status &=~(1<<1); } nc_card_battery_status &=~(1<<0); if (printer_handshake & CENTRONICS_ACKNOWLEDGE) { nc_card_battery_status |=(1<<0); } return nc_card_battery_status; } static WRITE8_HANDLER(nc100_memory_card_wait_state_w) { #ifdef VERBOSE logerror("nc100 memory card wait state: %02x\n",data); #endif } static ADDRESS_MAP_START(nc100_io, ADDRESS_SPACE_IO, 8) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) ADDRESS_MAP_FLAGS( AMEF_UNMAP(1) ) 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_WRITE(nc_printer_data_w) 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_READWRITE(msm8251_data_r, msm8251_data_w) AM_RANGE(0xc1, 0xc1) AM_READWRITE(msm8251_status_r, msm8251_control_w) AM_RANGE(0xd0, 0xdf) AM_READWRITE(tc8521_r, tc8521_w) ADDRESS_MAP_END INPUT_PORTS_START(nc100) /* 0 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_BIT (0x004, 0x00, IPT_UNUSED) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT/RED") PORT_CODE(KEYCODE_LEFT) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT (0x040, 0x00, IPT_UNUSED) PORT_BIT (0x080, 0x00, IPT_UNUSED) /* 1 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("YELLOW/FUNCTION") PORT_CODE(KEYCODE_RALT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_RCONTROL) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ESCAPE/STOP") PORT_CODE(KEYCODE_ESC) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_BIT (0x010, 0x00, IPT_UNUSED) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_BIT (0x080, 0x00, IPT_UNUSED) /* 2 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SYMBOL") PORT_CODE(KEYCODE_HOME) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_BIT (0x010, 0x00, IPT_UNUSED) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT (0x040, 0x00, IPT_UNUSED) PORT_BIT (0x080, 0x00, IPT_UNUSED) /* 3 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) /* 4 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_BIT (0x002, 0x00, IPT_UNUSED) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) /* 5 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT (0x002, 0x00, IPT_UNUSED) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) /* 6 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DOWN/BLUE") PORT_CODE(KEYCODE_DOWN) PORT_BIT (0x004, 0x00, IPT_UNUSED) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT/GREEN") PORT_CODE(KEYCODE_RIGHT) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("#") PORT_CODE(KEYCODE_TILDE) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("?") PORT_CODE(KEYCODE_SLASH) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) /* 7 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("+ =") PORT_CODE(KEYCODE_EQUALS) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_PGUP) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) /* 8 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("} ]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("{ [") PORT_CODE(KEYCODE_OPENBRACE) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) /* 9 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(": ;") PORT_CODE(KEYCODE_COLON) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) /* these are not part of the nc100 keyboard */ /* extra */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON BUTTON") PORT_CODE(KEYCODE_END) /* pcmcia memory card setting */ PORT_DIPNAME(0x002, 0x002, "PCMCIA Memory card write enable") PORT_DIPSETTING(0x000, DEF_STR( Off) ) PORT_DIPSETTING(0x002, DEF_STR( On) ) INPUT_PORTS_END /**********************************************************************************************************/ /* NC150 hardware */ /* to be completed! */ #if 0 void nc150_init_machine(void) { nc_membank_internal_ram_mask = 7; nc_membank_card_ram_mask = 0x03f; nc_common_init_machine(); } #endif /**********************************************************************************************************/ /* NC200 hardware */ #ifdef UNUSED_FUNCTION static WRITE8_HANDLER(nc200_display_memory_start_w) { /* bit 7: A15 */ /* bit 6: A14 */ /* bit 5: A13 */ /* bit 4-0: not used */ nc_display_memory_start = (data & 0x0e0)<<(12-4); #ifdef VERBOSE logerror("disp memory w: %04x\n", (int) nc_display_memory_start); #endif } #endif static void nc200_printer_handshake_in(int number, int data, int mask) { nc_irq_status &= ~(1<<0); if (mask & CENTRONICS_ACKNOWLEDGE) { if (data & CENTRONICS_ACKNOWLEDGE) { nc_irq_status|=(1<<0); } } /* trigger an int if the irq is set */ nc_update_interrupts(); } static CENTRONICS_CONFIG nc200_cent_config[1]={ { PRINTER_CENTRONICS, nc200_printer_handshake_in }, }; /* assumption. nc200 uses the same uart chip. The rxrdy and txrdy are combined together with a or to generate a single interrupt */ static UINT8 nc200_uart_interrupt_irq; static void nc200_refresh_uart_interrupt(void) { nc_irq_latch &=~(1<<2); /* uart enabled? */ if ((nc_uart_control & (1<<3))==0) { if ((nc200_uart_interrupt_irq & 0x03)!=0) { nc_irq_latch |= (1<<2); } } nc_update_interrupts(); } static void nc200_txrdy_callback(int state) { // nc200_uart_interrupt_irq &=~(1<<0); // // if (state) // { // nc200_uart_interrupt_irq |=(1<<0); // } // // nc200_refresh_uart_interrupt(); } static void nc200_rxrdy_callback(int state) { nc200_uart_interrupt_irq &=~(1<<1); if (state) { nc200_uart_interrupt_irq |=(1<<1); } nc200_refresh_uart_interrupt(); } static struct msm8251_interface nc200_uart_interface= { nc200_rxrdy_callback, NULL, nc200_txrdy_callback, }; static void nc200_fdc_interrupt(int state) { #if 0 nc_irq_latch &=~(1<<5); if (state) { nc_irq_latch |=(1<<5); } #endif nc_irq_status &=~(1<<5); if (state) { nc_irq_status |=(1<<5); } nc_update_interrupts(); } static struct nec765_interface nc200_nec765_interface= { nc200_fdc_interrupt, NULL, }; #ifdef UNUSED_FUNCTION static void nc200_floppy_drive_index_callback(int drive_id) { #ifdef NC200_DEBUG logerror("nc200 index pulse\n"); #endif // nc_irq_status |= (1<<4); // nc_update_interrupts(); } #endif static void nc200_machine_reset(running_machine *machine) { /* 512k of rom */ nc_membank_rom_mask = 0x1f; nc_membank_internal_ram_mask = 7; nc_membank_card_ram_mask = 0x03f; nc_common_init_machine(); nec765_init(&nc200_nec765_interface, NEC765A); /* double sided, 80 track drive */ floppy_drive_set_geometry(image_from_devtype_and_index(IO_FLOPPY, 0), FLOPPY_DRIVE_DS_80); //floppy_drive_set_index_pulse_callback(image_from_devtype_and_index(IO_FLOPPY, 0), nc200_floppy_drive_index_callback); mc146818_init(MC146818_STANDARD); nc200_uart_interrupt_irq = 0; msm8251_init(&nc200_uart_interface); centronics_config(0, nc200_cent_config); /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); nc_common_open_stream_for_reading(); if (file) { mc146818_load_stream(file); } nc_common_restore_memory_from_stream(); nc_common_close_stream(); /* fdc, serial */ nc_irq_latch_mask = /*(1<<5) |*/ (1<<2); nc200_video_set_backlight(0); } static void nc200_machine_stop(running_machine *machine) { nc_common_open_stream_for_writing(); if (file) { mc146818_save_stream(file); } nc_common_store_memory_to_stream(); nc_common_close_stream(); } static MACHINE_START( nc200 ) { nc_type = NC_TYPE_200; add_reset_callback(machine, nc200_machine_reset); add_exit_callback(machine, nc200_machine_stop); } /* 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 */ static READ8_HANDLER(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 (nc_card_status) { /* card present */ nc_card_battery_status&=~(1<<7); } if (readinputport(10) & 0x02) { /* card write enable */ nc_card_battery_status &=~(1<<6); } return nc_card_battery_status; } /* port &80: bit 0: Parallel interface BUSY */ static READ8_HANDLER(nc200_printer_status_r) { unsigned char nc200_printer_status = 0x0ff; int printer_handshake; /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); printer_handshake = centronics_read_handshake(0); nc200_printer_status |=(1<<0); /* if printer is not online, it is busy */ if ((printer_handshake & CENTRONICS_ONLINE)!=0) { nc200_printer_status &=~(1<<0); } return nc200_printer_status; } static WRITE8_HANDLER(nc200_uart_control_w) { int reset_fdc; reset_fdc = (nc_uart_control^data) & (1<<5); nc_uart_control_w(offset,data); if (data & (1<<3)) { nc200_uart_interrupt_irq &=~3; nc200_refresh_uart_interrupt(); } /* bit 5 is used in disk interface */ #ifdef NC200_DEBUG logerror("bit 5: PC: %04x %02x\n",activecpu_get_pc(), data & (1<<5)); #endif } /* 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: NEC765 Terminal Count input */ static WRITE8_HANDLER(nc200_memory_card_wait_state_w) { #ifdef NC200_DEBUG logerror("nc200 memory card wait state: PC: %04x %02x\n",activecpu_get_pc(),data); #endif floppy_drive_set_motor_state(0,1); floppy_drive_set_ready_state(0,1,1); nec765_set_tc_state((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 */ static WRITE8_HANDLER(nc200_poweroff_control_w) { #ifdef NC200_DEBUG logerror("nc200 power off: PC: %04x %02x\n", activecpu_get_pc(),data); #endif nc200_video_set_backlight(((data^(1<<2))>>2) & 0x01); } static ADDRESS_MAP_START(nc200_io, ADDRESS_SPACE_IO, 8) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) 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_WRITE(nc_printer_data_w) 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_READWRITE(msm8251_data_r, msm8251_data_w) AM_RANGE(0xc1, 0xc1) AM_READWRITE(msm8251_status_r, msm8251_control_w) AM_RANGE(0xd0, 0xd1) AM_READWRITE(mc146818_port_r, mc146818_port_w) AM_RANGE(0xe0, 0xe0) AM_READ(nec765_status_r) AM_RANGE(0xe1, 0xe1) AM_READWRITE(nec765_data_r, nec765_data_w) ADDRESS_MAP_END INPUT_PORTS_START(nc200) /* 0 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LEFT/RED") PORT_CODE(KEYCODE_LEFT) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT (0x040, 0x00, IPT_UNUSED) PORT_BIT (0x080, 0x00, IPT_UNUSED) /* 1 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("YELLOW/FUNCTION") PORT_CODE(KEYCODE_RALT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_RCONTROL) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ESCAPE/STOP") PORT_CODE(KEYCODE_ESC) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_BIT (0x010, 0x00, IPT_UNUSED) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT (0x040, 0x00, IPT_UNUSED) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) /* 2 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SYMBOL") PORT_CODE(KEYCODE_HOME) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_BIT (0x080, 0x00, IPT_UNUSED) /* 3 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) /* 4 */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_BIT (0x020, 0x00, IPT_UNUSED) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) /* 5 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT (0x002, 0x00, IPT_UNUSED) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) /* 6 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DOWN/BLUE") PORT_CODE(KEYCODE_DOWN) PORT_BIT (0x004, 0x00, IPT_UNUSED) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIGHT/GREEN") PORT_CODE(KEYCODE_RIGHT) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("#") PORT_CODE(KEYCODE_TILDE) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("?") PORT_CODE(KEYCODE_SLASH) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) /* 7 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("+ =") PORT_CODE(KEYCODE_EQUALS) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MENU") PORT_CODE(KEYCODE_PGUP) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) /* 8 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("} ]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("{ [") PORT_CODE(KEYCODE_OPENBRACE) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) /* 9 */ PORT_START PORT_BIT (0x001, 0x00, IPT_UNUSED) PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(": ;") PORT_CODE(KEYCODE_COLON) PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) /* not part of the nc200 keyboard */ PORT_START PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON BUTTON") PORT_CODE(KEYCODE_END) /* pcmcia memory card setting */ PORT_DIPNAME(0x002, 0x002, "PCMCIA Memory card write enable") PORT_DIPSETTING(0x000, DEF_STR( Off) ) PORT_DIPSETTING(0x002, DEF_STR( On) ) INPUT_PORTS_END /**********************************************************************************************************/ static MACHINE_DRIVER_START( nc100 ) /* basic machine hardware */ MDRV_CPU_ADD_TAG("main", Z80, /*6000000*/ 4606000) /* Russell Marks says this is more accurate */ MDRV_CPU_PROGRAM_MAP(nc_map, 0) MDRV_CPU_IO_MAP(nc100_io, 0) MDRV_SCREEN_REFRESH_RATE(50) MDRV_SCREEN_VBLANK_TIME(DEFAULT_REAL_60HZ_VBLANK_DURATION) MDRV_INTERLEAVE(1) MDRV_MACHINE_START( nc100 ) /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) MDRV_SCREEN_SIZE(640 /*NC_SCREEN_WIDTH*/, 480 /*NC_SCREEN_HEIGHT*/) MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) MDRV_PALETTE_LENGTH(NC_NUM_COLOURS) MDRV_COLORTABLE_LENGTH(NC_NUM_COLOURS) MDRV_PALETTE_INIT( nc ) MDRV_VIDEO_START( nc ) MDRV_VIDEO_UPDATE( nc ) /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SOUND_ADD(BEEP, 0) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) MDRV_SOUND_ADD(BEEP, 0) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) MACHINE_DRIVER_END static MACHINE_DRIVER_START( nc200 ) MDRV_IMPORT_FROM( nc100 ) MDRV_CPU_MODIFY( "main" ) MDRV_CPU_IO_MAP(nc200_io, 0) MDRV_MACHINE_START( nc200 ) /* video hardware */ MDRV_SCREEN_SIZE(NC200_SCREEN_WIDTH, NC200_SCREEN_HEIGHT) MDRV_SCREEN_VISIBLE_AREA(0, NC200_SCREEN_WIDTH-1, 0, NC200_SCREEN_HEIGHT-1) MDRV_PALETTE_LENGTH(NC200_NUM_COLOURS) MDRV_COLORTABLE_LENGTH(NC200_NUM_COLOURS) MACHINE_DRIVER_END /*************************************************************************** Game driver(s) ***************************************************************************/ ROM_START(nc100) ROM_REGION(((64*1024)+(256*1024)), REGION_CPU1,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, "100", "ROM v1.00") ROMX_LOAD("nc100.rom", 0x010000, 0x040000, CRC(a699eca3) SHA1(ce217d5a298b959ccc3d7bc5c93b1dba043f1339), ROM_BIOS(2)) ROM_END ROM_START(nc200) ROM_REGION(((64*1024)+(512*1024)), REGION_CPU1,0) ROM_LOAD("nc200.rom", 0x010000, 0x080000, CRC(bb8180e7) SHA1(fb5c93b0a3e199202c6a12548d2617f7a09bae47)) ROM_END static void nc_common_printer_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* printer */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 1; break; default: printer_device_getinfo(devclass, state, info); break; } } static void nc_common_cartslot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* cartslot */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 1; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_PTR_INIT: info->init = device_init_nc_pcmcia_card; break; case DEVINFO_PTR_LOAD: info->load = device_load_nc_pcmcia_card; break; case DEVINFO_PTR_UNLOAD: info->unload = device_unload_nc_pcmcia_card; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "crd,card"); break; default: cartslot_device_getinfo(devclass, state, info); break; } } static void nc_common_serial_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* serial */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_TYPE: info->i = IO_SERIAL; break; case DEVINFO_INT_READABLE: info->i = 1; break; case DEVINFO_INT_WRITEABLE: info->i = 0; break; case DEVINFO_INT_CREATABLE: info->i = 0; break; case DEVINFO_INT_COUNT: info->i = 1; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_PTR_INIT: info->init = serial_device_init; break; case DEVINFO_PTR_LOAD: info->load = device_load_nc_serial; break; case DEVINFO_PTR_UNLOAD: info->unload = serial_device_unload; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "txt"); break; } } SYSTEM_CONFIG_START(nc_common) CONFIG_DEVICE(nc_common_printer_getinfo) CONFIG_DEVICE(nc_common_cartslot_getinfo) CONFIG_DEVICE(nc_common_serial_getinfo) SYSTEM_CONFIG_END SYSTEM_CONFIG_START(nc100) CONFIG_IMPORT_FROM(nc_common) CONFIG_RAM_DEFAULT(64 * 1024) SYSTEM_CONFIG_END static void nc200_floppy_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* floppy */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 1; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_PTR_FLOPPY_OPTIONS: info->p = (void *) floppyoptions_pc; break; default: floppy_device_getinfo(devclass, state, info); break; } } SYSTEM_CONFIG_START(nc200) CONFIG_IMPORT_FROM(nc_common) CONFIG_RAM_DEFAULT(128 * 1024) CONFIG_DEVICE(nc200_floppy_getinfo) SYSTEM_CONFIG_END /* YEAR NAME PARENT BIOS COMPAT MACHINE INPUT INIT CONFIG, COMPANY FULLNAME */ COMPB(1992, nc100, 0, nc100, 0, nc100, nc100, 0, nc100, "Amstrad plc", "NC100", 0) COMP( 1993, nc200, 0, 0, nc200, nc200, 0, nc200, "Amstrad plc", "NC200", 0)