// license:BSD-3-Clause // copyright-holders:Curt Coder #include "includes/newbrain.h" #include "formats/mfi_dsk.h" /* NewBrain Grundy Business Systems Ltd. 32K RAM 28K ROM Z80 @ 2MHz COP420 @ 2MHz Z80 @ 4MHz (416): INT/NMI=+5V, WAIT=EXTBUSRQ|BUSAKD, RESET=_FDC RESET, NEC 765AC @ 4 MHz (418) MC6850 ACIA (459) Z80CTC (458) ADC0809 (427) DAC0808 (461) Models according to the Software Technical Manual: Model M: 'Page Register', Expansion Port onto Z80 bus, Video, ACIA/CTC, User Port Model A: Expansion Port, Video, no User Port but has software driver serial port - s/w Printer, s/w V24 Model V: ACIA/CTC, User Port */ /* TODO: - bitmapped graphics mode - COP420 microbus access - escape key is missing - CP/M 2.2 ROMs - floppy disc controller - convert FDC into a device - convert EIM into a device - Micropage ROM/RAM card - Z80 PIO board - peripheral (PI) box - sound card */ void newbrain_state::check_interrupt() { int level = (!m_clkint || !m_copint) ? ASSERT_LINE : CLEAR_LINE; m_maincpu->set_input_line(INPUT_LINE_IRQ0, level); } /* Bank Switching */ #define memory_install_unmapped(program, bank, bank_start, bank_end) \ program.unmap_readwrite(bank_start, bank_end); #define memory_install_rom_helper(program, bank, bank_start, bank_end) \ program.install_read_bank(bank_start, bank_end, bank); \ program.unmap_write(bank_start, bank_end); #define memory_install_ram_helper(program, bank, bank_start, bank_end) \ program.install_readwrite_bank(bank_start, bank_end, bank); void newbrain_eim_state::bankswitch() { address_space &program = m_maincpu->space(AS_PROGRAM); int bank; for (bank = 1; bank < 9; bank++) { int page = (m_a16 << 3) | bank; UINT8 data = ~m_pr[page]; int ch = (data >> 3) & 0x03; int eim_bank = data & 0x07; UINT16 eim_bank_start = eim_bank * 0x2000; UINT16 bank_start = (bank - 1) * 0x2000; UINT16 bank_end = bank_start + 0x1fff; char bank_name[10]; sprintf(bank_name,"bank%d",bank); switch (ch) { case 0: /* ROM */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); membank(bank_name)->configure_entry(0, m_eim_rom->base() + eim_bank_start); break; case 2: /* RAM */ memory_install_ram_helper(program, bank_name, bank_start, bank_end); membank(bank_name)->configure_entry(0, m_eim_ram + eim_bank_start); break; default: logerror("Invalid memory channel %u!\n", ch); break; } } } void newbrain_state::bankswitch() { address_space &program = m_maincpu->space(AS_PROGRAM); int bank; for (bank = 1; bank < 9; bank++) { UINT16 bank_start = (bank - 1) * 0x2000; UINT16 bank_end = bank_start + 0x1fff; char bank_name[10]; sprintf(bank_name,"bank%d",bank); if (m_pwrup) { /* all banks point to ROM at 0xe000 */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); membank(bank_name)->configure_entry(0, m_rom->base() + 0xe000); } else { membank(bank_name)->configure_entry(0, m_rom->base() + bank_start); if (bank < 5) { /* bank is RAM */ memory_install_ram_helper(program, bank_name, bank_start, bank_end); } else if (bank == 5) { /* 0x8000-0x9fff */ if (m_eim_rom) { /* expansion interface ROM */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); membank(bank_name)->configure_entry(0, m_eim_rom->base() + 0x4000); } else { /* mirror of 0xa000-0xbfff */ if (m_rom->base()[0xa001] == 0) { /* unmapped on the M model */ memory_install_unmapped(program, bank_name, bank_start, bank_end); } else { /* bank is ROM on the A model */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); } membank(bank_name)->configure_entry(0, m_rom->base() + 0xa000); } } else if (bank == 6) { /* 0xa000-0xbfff */ if (m_rom->base()[0xa001] == 0) { /* unmapped on the M model */ memory_install_unmapped(program, bank_name, bank_start, bank_end); } else { /* bank is ROM on the A model */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); } } else { /* bank is ROM */ memory_install_rom_helper(program, bank_name, bank_start, bank_end); } } membank(bank_name)->set_entry(0); } } /* Enable/Status */ WRITE8_MEMBER( newbrain_state::enrg1_w ) { /* bit signal description 0 _CLK enable frame frequency clock interrupts 1 enable user interrupt 2 TVP enable video display 3 enable V24 4 V24 Select Receive Bit 0 5 V24 Select Receive Bit 1 6 V24 Select Transmit Bit 0 7 V24 Select Transmit Bit 1 */ m_enrg1 = data; } WRITE8_MEMBER( newbrain_state::a_enrg1_w ) { /* bit signal description 0 _CLK Clock Enable 1 2 TVP TV Enable 3 IOPOWER 4 _CTS Clear to Send V24 5 DO Transmit Data V24 6 7 PO Transmit Data Printer */ m_enrg1 = data; } READ8_MEMBER( newbrain_state::ust_r ) { /* bit signal description 0 variable 1 variable 2 MNS mains present 3 _USRINT0 user status 4 _USRINT user interrupt 5 _CLKINT clock interrupt 6 _ACINT ACIA interrupt 7 _COPINT COP interrupt */ UINT8 data = (m_copint << 7) | (m_aciaint << 6) | (m_clkint << 5) | (m_userint << 4) | 0x04; switch ((m_enrg1 & NEWBRAIN_ENRG1_UST_BIT_0_MASK) >> 6) { case 0: // excess, 1=24, 0=4 if (m_tvctl & NEWBRAIN_VIDEO_32_40) { data |= 0x01; } break; case 1: // characters per line, 1=40, 0=80 if (m_tvctl & NEWBRAIN_VIDEO_80L) { data |= 0x01; } break; case 2: // tape in break; case 3: // calling indicator break; } switch ((m_enrg1 & NEWBRAIN_ENRG1_UST_BIT_1_MASK) >> 4) { case 0: // PWRUP, if set indicates that power is supplied to Z80 and memory if (m_pwrup) { data |= 0x02; } break; case 1: // TVCNSL, if set then processor has video device as primary console output if (m_tvcnsl) { data |= 0x02; } break; case 2: // _BEE, if set then processor is Model A type if (m_bee) { data |= 0x02; } break; case 3: // _CALLIND, calling indicator data |= 0x02; break; } return data; } READ8_MEMBER( newbrain_state::a_ust_r ) { /* bit signal description 0 +5V 1 PWRUP 2 3 4 5 _CLKINT clock interrupt 6 7 _COPINT COP interrupt */ return (m_copint << 7) | (m_clkint << 5) | (m_pwrup << 1) | 0x01; } READ8_MEMBER( newbrain_state::user_r ) { /* bit signal description 0 RDDK Received Data V24 1 _CTSD _Clear to Send V24 2 3 4 5 TPIN Tape in 6 7 _CTSP _Clear to Send Printer */ m_user = 0; return 0xff; } WRITE8_MEMBER( newbrain_state::user_w ) { m_user = data; } /* Interrupts */ READ8_MEMBER( newbrain_state::clclk_r ) { m_clkint = 1; check_interrupt(); return 0xff; } WRITE8_MEMBER( newbrain_state::clclk_w ) { m_clkint = 1; check_interrupt(); } READ8_MEMBER( newbrain_state::clusr_r ) { m_userint = 1; return 0xff; } WRITE8_MEMBER( newbrain_state::clusr_w ) { m_userint = 1; } /* COP420 */ READ8_MEMBER( newbrain_state::cop_l_r ) { // connected to the Z80 data bus return m_cop_bus; } WRITE8_MEMBER( newbrain_state::cop_l_w ) { // connected to the Z80 data bus m_cop_bus = data; } WRITE8_MEMBER( newbrain_state::cop_g_w ) { /* bit description G0 _COPINT G1 _TM1 G2 not connected G3 _TM2 */ m_copint = BIT(data, 0); check_interrupt(); /* tape motor enable */ m_cassette1->change_state(BIT(data,1) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); m_cassette2->change_state(BIT(data,3) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); } READ8_MEMBER( newbrain_state::cop_g_r ) { /* bit description G0 not connected G1 K9 G2 K7 G3 K3 */ return (BIT(m_keydata, 3) << 3) | (BIT(m_keydata, 0) << 2) | (BIT(m_keydata, 1) << 1); } WRITE8_MEMBER( newbrain_state::cop_d_w ) { /* bit description D0 inverted to K4 -> CD4024 pin 2 (reset) D1 TDO D2 inverted to K6 -> CD4024 pin 1 (clock), CD4076 pin 7 (clock), inverted to DS8881 pin 3 (enable) D3 not connected */ /* keyboard row reset */ if (!BIT(data, 0)) { m_keylatch = 0; } /* tape data output */ m_cop_tdo = BIT(data, 1); m_cassette1->output(m_cop_tdo ? -1.0 : +1.0); m_cassette2->output(m_cop_tdo ? -1.0 : +1.0); /* keyboard and display clock */ if (!BIT(data, 2)) { m_keylatch++; if (m_keylatch == 16) { m_keylatch = 0; } m_keydata = m_key_row[m_keylatch]->read(); output_set_digit_value(m_keylatch, m_segment_data[m_keylatch]); } } READ8_MEMBER( newbrain_state::cop_in_r ) { /* bit description IN0 K8 IN1 _RD IN2 _COP IN3 _WR */ return (m_cop_wr << 3) | (m_cop_access << 2) | (m_cop_rd << 1) | BIT(m_keydata, 2); } WRITE8_MEMBER( newbrain_state::cop_so_w ) { // connected to K1 m_cop_so = data; } WRITE8_MEMBER( newbrain_state::cop_sk_w ) { // connected to K2 m_segment_data[m_keylatch] >>= 1; m_segment_data[m_keylatch] = (m_cop_so << 15) | (m_segment_data[m_keylatch] & 0x7fff); } READ8_MEMBER( newbrain_state::cop_si_r ) { // connected to TDI m_cop_tdi = (((m_cassette1)->input() > +1.0) || ((m_cassette2)->input() > +1.0)) ^ m_cop_tdo; return m_cop_tdi; } /* Video */ void newbrain_state::tvram_w(UINT8 data, int a6) { /* latch video address counter bits A5-A0 */ m_tvram = (m_tvctl & NEWBRAIN_VIDEO_80L) ? 0x04 : 0x02; /* latch video address counter bit A6 */ m_tvram |= a6 << 6; /* latch data to video address counter bits A14-A7 */ m_tvram = (data << 7); } READ8_MEMBER( newbrain_state::tvl_r ) { UINT8 data = 0xff; tvram_w(data, !offset); return data; } WRITE8_MEMBER( newbrain_state::tvl_w ) { tvram_w(data, !offset); } WRITE8_MEMBER( newbrain_state::tvctl_w ) { /* bit signal description 0 RV 1 reverses video over entire field, ie. black on white 1 FS 0 generates 128 characters and 128 reverse field characters from 8 bit character code. 1 generates 256 characters from 8 bit character code 2 32/_40 0 generates 320 or 640 horizontal dots in pixel graphics mode. 1 generates 256 or 512 horizontal dots in pixel graphics mode 3 UCR 0 selects 256 characters expressed in an 8x10 matrix, and 25 lines (max) displayed. 1 selects 256 characters in an 8x8 matrix, and 31 lines (max) displayed 4 5 6 80L 0 selects 40 character line length. 1 selects 80 character line length 7 */ m_tvctl = data; } /* Disc Controller */ WRITE8_MEMBER( newbrain_eim_state::fdc_auxiliary_w ) { /* bit description 0 MOTON 1 765 RESET 2 TC 3 4 5 PA15 6 7 */ m_floppy->mon_w(!BIT(data, 0)); if(BIT(data, 1)) m_fdc->reset(); m_fdc->tc_w(BIT(data, 2)); } READ8_MEMBER( newbrain_eim_state::fdc_control_r ) { /* bit description 0 1 2 3 4 5 FDC INT 6 PAGING 7 FDC ATT */ return (m_fdc_att << 7) | (m_paging << 6) | (m_fdc_int << 5); } READ8_MEMBER( newbrain_eim_state::ust2_r ) { /* bit description 0 RDDK (V24 RxD) 1 _CTSD (V24 Clear to Send) 2 3 4 5 TPIN 6 7 _CTSP (Printer Clear to Send) */ return 0; } #define NEWBRAIN_COPCMD_NULLCOM 0xd0 #define NEWBRAIN_COPCMD_DISPCOM 0xa0 //#define NEWBRAIN_COPCMD_TIMCOM 0x #define NEWBRAIN_COPCMD_PDNCOM 0xb8 #define NEWBRAIN_COPCMD_TAPECOM 0x80 #define NEWBRAIN_COP_TAPE_RECORD 0x00 #define NEWBRAIN_COP_TAPE_PLAYBK 0x04 #define NEWBRAIN_COP_TAPE_MOTOR1 0x08 #define NEWBRAIN_COP_TAPE_MOTOR2 0x02 #define NEWBRAIN_COP_TIMER0 0x01 #define NEWBRAIN_COP_NO_DATA 0x01 #define NEWBRAIN_COP_BREAK_PRESSED 0x02 #define NEWBRAIN_COP_REGINT 0x00 /*#define NEWBRAIN_COP_CASSERR 0x #define NEWBRAIN_COP_CASSIN 0x #define NEWBRAIN_COP_KBD 0x #define NEWBRAIN_COP_CASSOUT 0x*/ enum { NEWBRAIN_COP_STATE_COMMAND = 0, NEWBRAIN_COP_STATE_DATA }; READ8_MEMBER( newbrain_state::cop_r ) { m_copint = 1; check_interrupt(); return m_copdata; } WRITE8_MEMBER( newbrain_state::cop_w ) { m_copdata = data; switch (m_copstate) { case NEWBRAIN_COP_STATE_COMMAND: logerror("COP command %02x\n", data); switch (data) { case NEWBRAIN_COPCMD_NULLCOM: break; case NEWBRAIN_COPCMD_DISPCOM: m_copregint = 0; m_copbytes = 18; m_copstate = NEWBRAIN_COP_STATE_DATA; m_copdata = NEWBRAIN_COP_NO_DATA; m_copint = 0; check_interrupt(); break; #if 0 case NEWBRAIN_COPCMD_TIMCOM: m_copregint = 0; m_copbytes = 6; m_copstate = NEWBRAIN_COP_STATE_DATA; break; #endif case NEWBRAIN_COPCMD_PDNCOM: /* power down */ m_copregint = 0; break; default: if (data & NEWBRAIN_COPCMD_TAPECOM) { m_copregint = 0; } } break; case NEWBRAIN_COP_STATE_DATA: logerror("COP data %02x\n", data); m_copbytes--; if (m_copbytes == 0) { m_copstate = NEWBRAIN_COP_STATE_COMMAND; m_copregint = 1; } m_copdata = NEWBRAIN_COP_NO_DATA; m_copint = 0; check_interrupt(); break; } } TIMER_DEVICE_CALLBACK_MEMBER(newbrain_state::cop_regint_tick) { if (m_copregint) { logerror("COP REGINT\n"); m_copint = 0; check_interrupt(); } } /* Expansion Interface Module */ WRITE8_MEMBER( newbrain_eim_state::enrg2_w ) { /* bit signal description 0 _USERP 0 enables user data bus interrupt and also parallel latched data output (or centronics printer) interrupt 1 ANP 1 enables ADC conversion complete interrupt and also calling indicator interrupt 2 MLTMD 1 enables serial receive clock into multiplier input of DAC and signals data terminal not ready 3 MSPD 1 enables 50K Baud serial data rate to be obtained ie. CTC input clock of 800 kHz. 0 selects xxx.692 kHz 4 ENOR 1 enables serial receive clock to sound output summer, and also selects serial input from the printer port. 0 selects serial input from the comms port 5 ANSW 1 enables second bank of 4 analogue inputs (voltage, non-ratiometric), ie. ch4-7, and enabled sound output, 0 selects ch03 6 ENOT 1 enables serial transmit clock to sound ouput summer, and also selects serial output to the printer port. 0 selects serial output to the comms port 7 9th output bit for centronics printer port */ m_enrg2 = data; } WRITE8_MEMBER( newbrain_eim_state::pr_w ) { /* bit signal description 0 HP0 1 HP1 2 HP2 3 HP3 4 HP4 5 HP5 6 HP6 7 HP11 HP0-HP2 are decoded to _ROM0..._ROM7 signals HP3-HP4 are decoded to _CH0..._CH3 signals */ int page = (BIT(offset, 12) >> 9) | (BIT(offset, 15) >> 13) | (BIT(offset, 14) >> 13) | (BIT(offset, 13) >> 13); int bank = (BIT(offset, 11) >> 3) | (data & 0x7f); m_pr[page] = bank; bankswitch(); } READ8_MEMBER( newbrain_eim_state::user_r ) { m_user = 0xff; return 0xff; } WRITE8_MEMBER( newbrain_eim_state::user_w ) { m_user = data; } READ8_MEMBER( newbrain_eim_state::anout_r ) { return 0xff; } WRITE8_MEMBER( newbrain_eim_state::anout_w ) { } READ8_MEMBER( newbrain_eim_state::anin_r ) { // int channel = offset & 0x03; return 0; } WRITE8_MEMBER( newbrain_eim_state::anio_w ) { // int channel = offset & 0x03; } READ8_MEMBER( newbrain_eim_state::st0_r ) { /* bit signal description 0 fixed at 1 - indicates excess of 24 or 48, obsolete 1 PWRUP 1 indicates power up from 'cold' - necessary in battery machines with power switching 2 1 indicates analogue or calling indicator interrupts 3 _USRINT0 0 indicates centronics printer (latched output data) port interrupt 4 _USRINT 0 indicates parallel data bus port interrupt 5 _CLKINT 0 indicates frame frequency clock interrupt 6 _ACINT 0 indicates ACIA interrupt 7 _COPINT 0 indicates interrupt from micro-controller COP420M */ return (m_copint << 7) | (m_aciaint << 6) | (m_clkint << 5) | (m_userint << 4) | (m_userint0 << 3) | (m_pwrup) << 1 | 0x01; } READ8_MEMBER( newbrain_eim_state::st1_r ) { /* bit signal description 0 1 2 N/_RV 1 selects normal video on power up (white on black), 0 selects reversed video (appears as D0 on the first 200 EI's) 3 ANCH 1 indicates power is being taken from the mains supply 4 40/_80 1 indicates that 40 column video is selected on power up. 0 selects 80 column video 5 6 TVCNSL 1 indicates that a video display is required on power up 7 */ return (m_tvcnsl << 6) | 0x10 | 0x08 | 0x04; } READ8_MEMBER( newbrain_eim_state::st2_r ) { /* bit signal description 0 received serial data from communications port 1 0 indicates 'clear-to-send' condition at communications port 2 3 4 5 logic level tape input 6 7 0 indicates 'clear-to-send' condition at printer port */ return 0; } READ8_MEMBER( newbrain_eim_state::usbs_r ) { return 0xff; } WRITE8_MEMBER( newbrain_eim_state::usbs_w ) { } WRITE8_MEMBER( newbrain_eim_state::paging_w ) { if (BIT(offset, 8)) { // expansion interface module /* bit signal description 0 PG 1 enables paging circuits 1 WPL unused 2 A16 1 sets local A16 to 1 (ie. causes second set of 8 page registers to select addressed memory) 3 _MPM 0 selects multi-processing mode. among other effects this extends the page registers from 8 to 12 bits in length 4 HISLT 1 isolates the local machine. this is used in multi-processing mode 5 6 7 */ m_paging = BIT(data, 0); m_a16 = BIT(data, 2); m_mpm = BIT(data, 3); } else if (BIT(offset, 9)) { // disc controller /* bit signal description 0 PAGING 1 enables paging circuits 1 2 HA16 1 sets local A16 to 1 (ie. causes second set of 8 page registers to select addressed memory) 3 MPM 0 selects multi-processing mode. among other effects this extends the page registers from 8 to 12 bits in length 4 5 _FDC RESET 6 7 FDC ATT */ m_fdccpu->set_input_line(INPUT_LINE_RESET, BIT(data, 5) ? HOLD_LINE : CLEAR_LINE); m_paging = BIT(data, 0); m_a16 = BIT(data, 2); m_mpm = BIT(data, 3); m_fdc_att = BIT(data, 7); } else if (BIT(offset, 10)) { // network controller } } /* A/D Converter */ WRITE_LINE_MEMBER( newbrain_eim_state::adc_eoc_w ) { m_anint = state; } ADC0808_ANALOG_READ_CB( newbrain_eim_state::adc_vref_pos_r ) { return 5.0; } ADC0808_ANALOG_READ_CB( newbrain_eim_state::adc_vref_neg_r ) { return 0.0; } ADC0808_ANALOG_READ_CB( newbrain_eim_state::adc_input_r ) { return 0.0; } /* Memory Maps */ static ADDRESS_MAP_START( newbrain_map, AS_PROGRAM, 8, newbrain_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1") AM_RANGE(0x2000, 0x3fff) AM_RAMBANK("bank2") AM_RANGE(0x4000, 0x5fff) AM_RAMBANK("bank3") AM_RANGE(0x6000, 0x7fff) AM_RAMBANK("bank4") AM_RANGE(0x8000, 0x9fff) AM_RAMBANK("bank5") AM_RANGE(0xa000, 0xbfff) AM_RAMBANK("bank6") AM_RANGE(0xc000, 0xdfff) AM_RAMBANK("bank7") AM_RANGE(0xe000, 0xffff) AM_RAMBANK("bank8") ADDRESS_MAP_END static ADDRESS_MAP_START( newbrain_ei_io_map, AS_IO, 8, newbrain_eim_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x00) AM_MIRROR(0xff00) AM_READWRITE(clusr_r, clusr_w) AM_RANGE(0x01, 0x01) AM_MIRROR(0xff00) AM_WRITE(enrg2_w) AM_RANGE(0x02, 0x02) AM_MIRROR(0xff00) AM_MASK(0xff00) AM_WRITE(pr_w) AM_RANGE(0x03, 0x03) AM_MIRROR(0xff00) AM_READWRITE(user_r, user_w) AM_RANGE(0x04, 0x04) AM_MIRROR(0xff00) AM_READWRITE(clclk_r, clclk_w) AM_RANGE(0x05, 0x05) AM_MIRROR(0xff00) AM_READWRITE(anout_r, anout_w) AM_RANGE(0x06, 0x06) AM_MIRROR(0xff00) AM_READWRITE(cop_r, cop_w) AM_RANGE(0x07, 0x07) AM_MIRROR(0xff00) AM_WRITE(enrg1_w) AM_RANGE(0x08, 0x09) AM_MIRROR(0xff02) AM_READWRITE(tvl_r, tvl_w) AM_RANGE(0x0c, 0x0c) AM_MIRROR(0xff03) AM_WRITE(tvctl_w) AM_RANGE(0x10, 0x13) AM_MIRROR(0xff00) AM_READWRITE(anin_r, anio_w) AM_RANGE(0x14, 0x14) AM_MIRROR(0xff00) AM_READ(st0_r) AM_RANGE(0x15, 0x15) AM_MIRROR(0xff00) AM_READ(st1_r) AM_RANGE(0x16, 0x16) AM_MIRROR(0xff00) AM_READ(st2_r) AM_RANGE(0x17, 0x17) AM_MIRROR(0xff00) AM_READWRITE(usbs_r, usbs_w) AM_RANGE(0x18, 0x18) AM_MIRROR(0xff00) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, status_r, control_w) AM_RANGE(0x19, 0x19) AM_MIRROR(0xff00) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, data_r, data_w) AM_RANGE(0x1c, 0x1f) AM_MIRROR(0xff00) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write) AM_RANGE(0xff, 0xff) AM_MIRROR(0xff00) AM_MASK(0xff00) AM_WRITE(paging_w) ADDRESS_MAP_END static ADDRESS_MAP_START( newbrain_a_io_map, AS_IO, 8, newbrain_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x00) AM_MIRROR(0xffc0) AM_READWRITE(clusr_r, clusr_w) AM_RANGE(0x03, 0x03) AM_MIRROR(0xffc0) AM_WRITE(user_w) AM_RANGE(0x04, 0x04) AM_MIRROR(0xffc0) AM_READWRITE(clclk_r, clclk_w) AM_RANGE(0x06, 0x06) AM_MIRROR(0xffc0) AM_READWRITE(cop_r, cop_w) AM_RANGE(0x07, 0x07) AM_MIRROR(0xffc0) AM_WRITE(a_enrg1_w) AM_RANGE(0x08, 0x09) AM_MIRROR(0xffc2) AM_READWRITE(tvl_r, tvl_w) AM_RANGE(0x0c, 0x0c) AM_MIRROR(0xffc3) AM_WRITE(tvctl_w) AM_RANGE(0x14, 0x14) AM_MIRROR(0xffc3) AM_READ(a_ust_r) AM_RANGE(0x16, 0x16) AM_MIRROR(0xffc0) AM_READ(user_r) ADDRESS_MAP_END static ADDRESS_MAP_START( newbrain_cop_io_map, AS_IO, 8, newbrain_state ) AM_RANGE(COP400_PORT_L, COP400_PORT_L) AM_READWRITE(cop_l_r, cop_l_w) AM_RANGE(COP400_PORT_G, COP400_PORT_G) AM_READWRITE(cop_g_r, cop_g_w) AM_RANGE(COP400_PORT_D, COP400_PORT_D) AM_WRITE(cop_d_w) AM_RANGE(COP400_PORT_IN, COP400_PORT_IN) AM_READ(cop_in_r) AM_RANGE(COP400_PORT_SK, COP400_PORT_SK) AM_WRITE(cop_sk_w) AM_RANGE(COP400_PORT_SIO, COP400_PORT_SIO) AM_READWRITE(cop_si_r, cop_so_w) AM_RANGE(COP400_PORT_CKO, COP400_PORT_CKO) AM_READNOP ADDRESS_MAP_END static ADDRESS_MAP_START( newbrain_fdc_map, AS_PROGRAM, 8, newbrain_eim_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x1fff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START( newbrain_fdc_io_map, AS_IO, 8, newbrain_eim_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x01) AM_DEVICE(UPD765_TAG, upd765a_device, map) AM_RANGE(0x20, 0x20) AM_WRITE(fdc_auxiliary_w) AM_RANGE(0x40, 0x40) AM_READ(fdc_control_r) ADDRESS_MAP_END /* Input Ports */ static INPUT_PORTS_START( newbrain ) PORT_START("Y0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("STOP") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("Y1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_START("Y2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_START("Y3") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_START("Y4") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_START("Y5") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('(') PORT_CHAR('[') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') PORT_START("Y6") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(')') PORT_CHAR(']') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_START("Y7") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("* \xC2\xA3") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('*') PORT_CHAR(0x00A3) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_START("Y8") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("VIDEO TEXT") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) // Vd PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_START("Y9") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_START("Y10") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('@') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_START("Y11") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('-') PORT_CHAR('\\') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_START("Y12") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('+') PORT_CHAR('^') PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INSERT") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_START("Y13") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) // NL PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_START("Y14") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) // CH PORT_START("Y15") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // SH PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GRAPHICS") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) // GR PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("REPEAT") // RPT PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) // GL INPUT_PORTS_END /* Machine Initialization */ WRITE_LINE_MEMBER( newbrain_eim_state::acia_tx ) { m_acia_txd = state; } WRITE_LINE_MEMBER( newbrain_eim_state::acia_interrupt ) { m_aciaint = state; } WRITE_LINE_MEMBER( newbrain_eim_state::fdc_interrupt ) { m_fdc_int = state; } WRITE_LINE_MEMBER( newbrain_eim_state::ctc_z2_w ) { /* connected to CTC channel 0/1 clock inputs */ m_ctc->trg0(state); m_ctc->trg1(state); } TIMER_DEVICE_CALLBACK_MEMBER(newbrain_eim_state::ctc_c2_tick) { m_ctc->trg2(1); m_ctc->trg2(0); } inline int newbrain_state::get_reset_t() { return RES_K(220) * CAP_U(10) * 1000; // t = R128 * C125 = 2.2s } inline int newbrain_state::get_pwrup_t() { return RES_K(560) * CAP_U(10) * 1000; // t = R129 * C127 = 5.6s } //------------------------------------------------- // device_timer - handler timer events //------------------------------------------------- void newbrain_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { case TIMER_ID_RESET: m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); m_copcpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); break; case TIMER_ID_PWRUP: m_pwrup = 0; bankswitch(); break; } } void newbrain_state::machine_start() { m_copregint = 1; /* set power up timer */ timer_set(attotime::from_usec(get_pwrup_t()), TIMER_ID_PWRUP); /* initialize variables */ m_pwrup = 1; m_userint = 1; m_userint0 = 1; m_clkint = 1; m_aciaint = 1; m_copint = 1; m_bee = 1; m_tvcnsl = 1; /* set up memory banking */ bankswitch(); // find keyboard rows m_key_row[0] = m_y0; m_key_row[1] = m_y1; m_key_row[2] = m_y2; m_key_row[3] = m_y3; m_key_row[4] = m_y4; m_key_row[5] = m_y5; m_key_row[6] = m_y6; m_key_row[7] = m_y7; m_key_row[8] = m_y8; m_key_row[9] = m_y9; m_key_row[10] = m_y10; m_key_row[11] = m_y11; m_key_row[12] = m_y12; m_key_row[13] = m_y13; m_key_row[14] = m_y14; m_key_row[15] = m_y15; /* register for state saving */ save_item(NAME(m_pwrup)); save_item(NAME(m_userint)); save_item(NAME(m_userint0)); save_item(NAME(m_clkint)); save_item(NAME(m_aciaint)); save_item(NAME(m_copint)); save_item(NAME(m_anint)); save_item(NAME(m_bee)); save_item(NAME(m_enrg1)); save_item(NAME(m_enrg2)); save_item(NAME(m_cop_bus)); save_item(NAME(m_cop_so)); save_item(NAME(m_cop_tdo)); save_item(NAME(m_cop_tdi)); save_item(NAME(m_cop_rd)); save_item(NAME(m_cop_wr)); save_item(NAME(m_cop_access)); save_item(NAME(m_keylatch)); save_item(NAME(m_keydata)); save_item(NAME(m_user)); } void newbrain_eim_state::machine_start() { newbrain_state::machine_start(); /* allocate expansion RAM */ m_eim_ram.allocate(NEWBRAIN_EIM_RAM_SIZE); /* register for state saving */ save_item(NAME(m_mpm)); save_item(NAME(m_a16)); save_item(NAME(m_pr)); save_item(NAME(m_fdc_int)); save_item(NAME(m_fdc_att)); save_item(NAME(m_paging)); } void newbrain_state::machine_reset() { timer_set(attotime::from_usec(get_reset_t()), TIMER_ID_RESET); } INTERRUPT_GEN_MEMBER(newbrain_state::newbrain_interrupt) { if (!(m_enrg1 & NEWBRAIN_ENRG1_CLK)) { m_clkint = 0; check_interrupt(); } } /* Machine Drivers */ /* F4 Character Displayer */ static const gfx_layout newbrain_charlayout = { 8, 10, /* 8 x 10 characters */ 256, /* 256 characters */ 1, /* 1 bits per pixel */ { 0 }, /* no bitplanes */ /* x offsets */ { 0, 1, 2, 3, 4, 5, 6, 7 }, /* y offsets */ { 0*256*8, 1*256*8, 2*256*8, 3*256*8, 4*256*8, 5*256*8, 6*256*8, 7*256*8, 8*256*8, 9*256*8, 10*256*8, 11*256*8, 12*256*8, 13*256*8, 14*256*8, 15*256*8 }, 8 /* every char takes 16 x 1 bytes */ }; static GFXDECODE_START( newbrain ) GFXDECODE_ENTRY( "chargen", 0x0000, newbrain_charlayout, 0, 1 ) GFXDECODE_END static MACHINE_CONFIG_START( newbrain_a, newbrain_state ) // basic system hardware MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_16MHz/8) MCFG_CPU_PROGRAM_MAP(newbrain_map) MCFG_CPU_IO_MAP(newbrain_a_io_map) MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, newbrain_state, newbrain_interrupt) MCFG_CPU_ADD(COP420_TAG, COP420, XTAL_16MHz/8) // COP420-GUW/N MCFG_CPU_IO_MAP(newbrain_cop_io_map) MCFG_COP400_CONFIG( COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, COP400_MICROBUS_ENABLED ) MCFG_GFXDECODE_ADD("gfxdecode", "palette", newbrain) MCFG_TIMER_DRIVER_ADD_PERIODIC("cop_regint", newbrain_state, cop_regint_tick, attotime::from_usec(12500)) // video hardware MCFG_FRAGMENT_ADD(newbrain_video) // devices MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) MCFG_CASSETTE_ADD("cassette2") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) // internal ram MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("32K") MACHINE_CONFIG_END static SLOT_INTERFACE_START( newbrain_floppies ) SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) SLOT_INTERFACE_END static MACHINE_CONFIG_DERIVED_CLASS( newbrain_eim, newbrain_a, newbrain_eim_state ) // basic system hardware MCFG_CPU_MODIFY(Z80_TAG) MCFG_CPU_IO_MAP(newbrain_ei_io_map) MCFG_CPU_ADD(FDC_Z80_TAG, Z80, XTAL_4MHz) MCFG_CPU_PROGRAM_MAP(newbrain_fdc_map) MCFG_CPU_IO_MAP(newbrain_fdc_io_map) // devices MCFG_DEVICE_ADD(Z80CTC_TAG, Z80CTC, XTAL_16MHz/8) MCFG_Z80CTC_ZC0_CB(DEVWRITELINE(MC6850_TAG, acia6850_device, write_rxc)) MCFG_Z80CTC_ZC1_CB(DEVWRITELINE(MC6850_TAG, acia6850_device, write_txc)) MCFG_Z80CTC_ZC2_CB(WRITELINE(newbrain_eim_state, ctc_z2_w)) MCFG_TIMER_DRIVER_ADD_PERIODIC("z80ctc_c2", newbrain_eim_state, ctc_c2_tick, attotime::from_hz(XTAL_16MHz/4/13)) MCFG_DEVICE_ADD(ADC0809_TAG, ADC0808, 500000) MCFG_ADC0808_OUT_EOC_CB(WRITELINE(newbrain_eim_state, adc_eoc_w)) MCFG_ADC0808_IN_VREF_POS_CB(newbrain_eim_state, adc_vref_pos_r) MCFG_ADC0808_IN_VREF_NEG_CB(newbrain_eim_state, adc_vref_neg_r) MCFG_ADC0808_IN_IN_0_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_1_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_2_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_3_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_4_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_5_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_6_CB(newbrain_eim_state, adc_input_r) MCFG_ADC0808_IN_IN_7_CB(newbrain_eim_state, adc_input_r) MCFG_DEVICE_ADD(MC6850_TAG, ACIA6850, 0) MCFG_ACIA6850_TXD_HANDLER(WRITELINE(newbrain_eim_state, acia_tx)) MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(newbrain_eim_state, acia_interrupt)) MCFG_UPD765A_ADD(UPD765_TAG, false, true) MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", newbrain_floppies, "525dd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", newbrain_floppies, "525dd", floppy_image_device::default_floppy_formats) // internal ram MCFG_RAM_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("96K") MACHINE_CONFIG_END /* ROMs */ ROM_START( newbrain ) ROM_REGION( 0x10000, Z80_TAG, 0 ) ROM_DEFAULT_BIOS( "rom20" ) ROM_SYSTEM_BIOS( 0, "issue1", "Issue 1 (v?)" ) ROMX_LOAD( "aben.ic6", 0xa000, 0x2000, CRC(308f1f72) SHA1(a6fd9945a3dca47636887da2125fde3f9b1d4e25), ROM_BIOS(1) ) ROMX_LOAD( "cd iss 1.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(1) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "issue2", "Issue 2 (v1.9)" ) ROMX_LOAD( "aben19.ic6", 0xa000, 0x2000, CRC(d0283eb1) SHA1(351d248e69a77fa552c2584049006911fb381ff0), ROM_BIOS(2) ) ROMX_LOAD( "cdi2.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(2) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(2) ) ROM_SYSTEM_BIOS( 2, "issue3", "Issue 3 (v1.91)" ) ROMX_LOAD( "aben191.ic6", 0xa000, 0x2000, CRC(b7be8d89) SHA1(cce8d0ae7aa40245907ea38b7956c62d039d45b7), ROM_BIOS(3) ) ROMX_LOAD( "cdi3.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(3) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(3) ) ROM_SYSTEM_BIOS( 3, "series2", "Series 2 (v?)" ) ROMX_LOAD( "abs2.ic6", 0xa000, 0x2000, CRC(9a042acb) SHA1(80d83a2ea3089504aa68b6cf978d80d296cd9bda), ROM_BIOS(4) ) ROMX_LOAD( "cds2.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(4) ) ROMX_LOAD( "efs2.ic8", 0xe000, 0x2000, CRC(b222d798) SHA1(c0c816b4d4135b762f2c5f1b24209d0096f22e56), ROM_BIOS(4) ) ROM_SYSTEM_BIOS( 4, "rom20", "? (v2.0)" ) ROMX_LOAD( "aben20.rom", 0xa000, 0x2000, CRC(3d76d0c8) SHA1(753b4530a518ad832e4b81c4e5430355ba3f62e0), ROM_BIOS(5) ) ROMX_LOAD( "cd20tci.rom", 0xc000, 0x4000, CRC(f65b2350) SHA1(1ada7fbf207809537ec1ffb69808524300622ada), ROM_BIOS(5) ) ROM_REGION( 0x400, COP420_TAG, 0 ) ROM_LOAD( "cop420.419", 0x000, 0x400, NO_DUMP ) ROM_REGION( 0x1000, "chargen", ROMREGION_ERASE00 ) ROM_LOAD( "char eprom iss 1.ic453", 0x0000, 0x0a01, BAD_DUMP CRC(46ecbc65) SHA1(3fe064d49a4de5e3b7383752e98ad35a674e26dd) ) // 8248R7 ROM_END #define rom_newbraina rom_newbrain ROM_START( newbraineim ) ROM_REGION( 0x10000, Z80_TAG, 0 ) ROM_DEFAULT_BIOS( "rom20" ) ROM_SYSTEM_BIOS( 0, "issue1", "Issue 1 (v?)" ) ROMX_LOAD( "aben.ic6", 0xa000, 0x2000, CRC(308f1f72) SHA1(a6fd9945a3dca47636887da2125fde3f9b1d4e25), ROM_BIOS(1) ) ROMX_LOAD( "cd iss 1.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(1) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "issue2", "Issue 2 (v1.9)" ) ROMX_LOAD( "aben19.ic6", 0xa000, 0x2000, CRC(d0283eb1) SHA1(351d248e69a77fa552c2584049006911fb381ff0), ROM_BIOS(2) ) ROMX_LOAD( "cdi2.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(2) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(2) ) ROM_SYSTEM_BIOS( 2, "issue3", "Issue 3 (v1.91)" ) ROMX_LOAD( "aben191.ic6", 0xa000, 0x2000, CRC(b7be8d89) SHA1(cce8d0ae7aa40245907ea38b7956c62d039d45b7), ROM_BIOS(3) ) ROMX_LOAD( "cdi3.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(3) ) ROMX_LOAD( "ef iss 1.ic8", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6), ROM_BIOS(3) ) ROM_SYSTEM_BIOS( 3, "series2", "Series 2 (v?)" ) ROMX_LOAD( "abs2.ic6", 0xa000, 0x2000, CRC(9a042acb) SHA1(80d83a2ea3089504aa68b6cf978d80d296cd9bda), ROM_BIOS(4) ) ROMX_LOAD( "cds2.ic7", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a), ROM_BIOS(4) ) ROMX_LOAD( "efs2.ic8", 0xe000, 0x2000, CRC(b222d798) SHA1(c0c816b4d4135b762f2c5f1b24209d0096f22e56), ROM_BIOS(4) ) ROM_SYSTEM_BIOS( 4, "rom20", "? (v2.0)" ) ROMX_LOAD( "aben20.rom", 0xa000, 0x2000, CRC(3d76d0c8) SHA1(753b4530a518ad832e4b81c4e5430355ba3f62e0), ROM_BIOS(5) ) ROMX_LOAD( "cd20tci.rom", 0xc000, 0x4000, CRC(f65b2350) SHA1(1ada7fbf207809537ec1ffb69808524300622ada), ROM_BIOS(5) ) ROM_REGION( 0x400, COP420_TAG, 0 ) ROM_LOAD( "cop420.419", 0x000, 0x400, NO_DUMP ) ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "char eprom iss 1.ic453", 0x0000, 0x0a01, BAD_DUMP CRC(46ecbc65) SHA1(3fe064d49a4de5e3b7383752e98ad35a674e26dd) ) // 8248R7 ROM_REGION( 0x10000, "eim", 0 ) // Expansion Interface Module ROM_LOAD( "e415-2.rom", 0x4000, 0x2000, CRC(5b0e390c) SHA1(0f99cae57af2e64f3f6b02e5325138d6ba015e72) ) ROM_LOAD( "e415-3.rom", 0x4000, 0x2000, CRC(2f88bae5) SHA1(04e03f230f4b368027442a7c2084dae877f53713) ) // 18/8/83.aci ROM_LOAD( "e416-3.rom", 0x6000, 0x2000, CRC(8b5099d8) SHA1(19b0cfce4c8b220eb1648b467f94113bafcb14e0) ) // 10/8/83.mtv ROM_LOAD( "e417-2.rom", 0x8000, 0x2000, CRC(6a7afa20) SHA1(f90db4f8318777313a862b3d5bab83c2fd260010) ) ROM_REGION( 0x10000, FDC_Z80_TAG, 0 ) // Floppy Disk Controller ROM_LOAD( "d413-2.rom", 0x0000, 0x2000, CRC(097591f1) SHA1(c2aa1d27d4f3a24ab0c8135df746a4a44201a7f4) ) ROM_LOAD( "d417-1.rom", 0x0000, 0x2000, CRC(40fad31c) SHA1(5137be4cc026972c0ffd4fa6990e8583bdfce163) ) ROM_LOAD( "d417-2.rom", 0x0000, 0x2000, CRC(e8bda8b9) SHA1(c85a76a5ff7054f4ef4a472ce99ebaed1abd269c) ) ROM_END ROM_START( newbrainmd ) ROM_REGION( 0x10000, Z80_TAG, 0 ) ROM_LOAD( "cdmd.rom", 0xc000, 0x2000, CRC(6b4d9429) SHA1(ef688be4e75aced61f487c928258c8932a0ae00a) ) ROM_LOAD( "efmd.rom", 0xe000, 0x2000, CRC(20dd0b49) SHA1(74b517ca223cefb588e9f49e72ff2d4f1627efc6) ) ROM_REGION( 0x400, COP420_TAG, 0 ) ROM_LOAD( "cop420.419", 0x000, 0x400, NO_DUMP ) ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "char eprom iss 1.ic453", 0x0000, 0x0a01, BAD_DUMP CRC(46ecbc65) SHA1(3fe064d49a4de5e3b7383752e98ad35a674e26dd) ) // 8248R7 ROM_END /* System Drivers */ // YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS COMP( 1981, newbrain, 0, 0, newbrain_a, newbrain, driver_device, 0, "Grundy Business Systems Ltd", "NewBrain AD", GAME_NOT_WORKING | GAME_NO_SOUND) COMP( 1981, newbraineim,newbrain, 0, newbrain_eim, newbrain, driver_device, 0, "Grundy Business Systems Ltd", "NewBrain AD with Expansion Interface", GAME_NOT_WORKING | GAME_NO_SOUND ) COMP( 1981, newbraina, newbrain, 0, newbrain_a, newbrain, driver_device, 0, "Grundy Business Systems Ltd", "NewBrain A", GAME_NOT_WORKING | GAME_NO_SOUND) COMP( 1981, newbrainmd, newbrain, 0, newbrain_a, newbrain, driver_device, 0, "Grundy Business Systems Ltd", "NewBrain MD", GAME_NOT_WORKING | GAME_NO_SOUND )