// license:BSD-3-Clause // copyright-holders:Patrick Mackinlay /* * Tektronix Intelligent Graphics Workstations (6110, 6120, 6130, 6205, 6210, 6212, 4132) * * Sources: * - http://bitsavers.trailing-edge.com/pdf/tektronix/6130/6100_Series_Hardware_Descriptions.pdf * - https://archive.org/details/tektronix_Tektronix_1985 * * TODO: * - am9516 dma controller * - slots and cards * - gpib devices * - graphics and keyboard */ /* * WIP * - novram chip select not asserted when trying to read ethernet mac address? * - aborts to firmware monitor on second serial port after failing to boot */ #include "emu.h" // cpus and memory #include "cpu/ns32000/ns32000.h" #include "machine/ram.h" // various hardware //#include "machine/am9516a.h" #include "machine/am9517a.h" #include "machine/eepromser.h" #include "machine/i82586.h" #include "machine/mm58167.h" //#include "machine/ncr5385.h" #include "machine/ns32081.h" #include "machine/ns32082.h" #include "machine/ns32202.h" #include "machine/tms9914.h" #include "machine/wd_fdc.h" #include "machine/wd1010.h" #include "machine/z80scc.h" #include "machine/input_merger.h" // busses and connectors #include "bus/ieee488/ieee488.h" #include "machine/nscsi_bus.h" #include "bus/nscsi/hd.h" #include "bus/rs232/rs232.h" #include "imagedev/floppy.h" #include "imagedev/harddriv.h" // graphics #include "cpu/mcs51/mcs51.h" #include "video/mc6845.h" #include "screen.h" #define VERBOSE 0 #include "logmacro.h" namespace { class tekigw_state_base : public driver_device { protected: tekigw_state_base(machine_config const &mconfig, device_type type, char const *tag) : driver_device(mconfig, type, tag) , m_cpu(*this, "cpu") , m_fpu(*this, "fpu") , m_mmu(*this, "mmu") , m_icu(*this, "icu") , m_ram(*this, "ram") , m_scc(*this, "scc") , m_serial(*this, "port%u", 0U) , m_rtc(*this, "rtc") , m_nov(*this, "nov%u", 0U) //, m_dma(*this, "dma") , m_lan(*this, "lan") , m_led(*this, "led") { } void common_config(machine_config &config); void common_init(); // driver_device overrides virtual void machine_start() override; virtual void machine_reset() override; // address maps template void cpu_map(address_map &map); // computer board control registers u8 nov_r() { return m_nmr; } u8 scr_r() { return m_scr; } u8 ssr_r() { return m_ssr; } void led_w(u8 data) { m_led = data; } void nov_w(u8 data); void scr_w(u8 data); // novram data out handler void nov_do(int state); void buserror(s32 param); required_device m_cpu; required_device m_fpu; required_device m_mmu; required_device m_icu; required_device m_ram; required_device m_scc; required_device_array m_serial; required_device m_rtc; optional_device_array m_nov; //required_device m_dma; required_device m_lan; output_finder<> m_led; emu_timer *m_buserror = nullptr; private: u8 m_nmr = 0; // nonvolatile memory register u16 m_per = 0; // parity error register u8 m_scr = 0; // system control register u8 m_ssr = 0; // system status register // ram parity state memory_passthrough_handler m_parity_mph; std::unique_ptr m_parity_flag; unsigned m_parity_bad = 0; bool m_parity_check = 0; }; class tek6100_state : public tekigw_state_base { public: tek6100_state(machine_config const &mconfig, device_type type, char const *tag) : tekigw_state_base(mconfig, type, tag) , m_gpib(*this, "gpib") , m_fdc(*this, "fdc") , m_fdd(*this, "fdc:%u:525dd", 0U) , m_hdc(*this, "hdc") , m_hdd(*this, "hdc:0") , m_dpu_cpu(*this, "dpu_cpu") , m_dpu_cram(*this, "dpu_cram") , m_dpu_vram(*this, "dpu_vram") { } void tek6130(machine_config &config); void init() { tekigw_state_base::common_init(); } protected: // driver_device overrides virtual void machine_start() override; virtual void machine_reset() override; // address maps template void cpu_map(address_map &map); void lan_map(address_map &map); template void dpu_cpu_map(address_map &map); private: // computer board control registers void fcr_w(u8 data); void gcr_w(u8 data); void hcr_w(u8 data); // hard disk buffer handlers template T buf_r(); template void buf_w(T data); u32 screen_update(screen_device& screen, bitmap_rgb32& bitmap, rectangle const& cliprect) { return 0; } required_device m_gpib; required_device m_fdc; optional_device_array m_fdd; required_device m_hdc; required_device m_hdd; optional_device m_dpu_cpu; optional_device m_dpu_cram; optional_device m_dpu_vram; u8 m_hcr = 0; // hard disk control register // hard disk controller buffer u16 m_hdc_ptr = 0; std::unique_ptr m_hdc_buf; }; class tek4132_state : public tekigw_state_base { public: tek4132_state(machine_config const &mconfig, device_type type, char const *tag) : tekigw_state_base(mconfig, type, tag) , m_scsibus(*this, "scsi") //, m_scsi(*this, "scsi:7:ncr5385") , m_sdma(*this, "sdma") , m_sirq(*this, "sirq") { } void tek4132(machine_config &config); void init() { tekigw_state_base::common_init(); } protected: // driver_device overrides //virtual void machine_start() override; //virtual void machine_reset() override; // address maps template void cpu_map(address_map &map); void lan_map(address_map &map); private: required_device m_scsibus; //required_device m_scsi; required_device m_sdma; required_device m_sirq; }; void tekigw_state_base::machine_start() { save_item(NAME(m_nmr)); save_item(NAME(m_per)); save_item(NAME(m_scr)); save_item(NAME(m_ssr)); m_per = 0; m_ssr = 0; m_parity_check = false; m_buserror = timer_alloc(FUNC(tek4132_state::buserror), this); } void tekigw_state_base::machine_reset() { nov_w(0); scr_w(0); } void tek6100_state::machine_start() { tekigw_state_base::machine_start(); m_hdc_buf = std::make_unique(4096); save_item(NAME(m_hcr)); save_item(NAME(m_hdc_ptr)); save_pointer(NAME(m_hdc_buf), 4096); } void tek6100_state::machine_reset() { tekigw_state_base::machine_reset(); hcr_w(0); fcr_w(0); m_icu->ir_w<0>(1); // mmu present m_icu->ir_w<3>(1); m_icu->ir_w<4>(1); m_icu->ir_w<5>(1); m_icu->ir_w<6>(1); m_icu->ir_w<7>(1); m_icu->ir_w<8>(1); m_icu->ir_w<9>(1); m_icu->ir_w<14>(1); // fpu present } void tekigw_state_base::common_init() { m_led.resolve(); m_lan->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); } enum fcr_mask : u8 { FCR_DRIVE = 0x01, // drive select FCR_SIDE = 0x02, // side select FCR_DDEN = 0x04, // double density enable FCR_FDEN = 0x08, // flexible disk enable }; void tek6100_state::fcr_w(u8 data) { floppy_image_device *fdd = nullptr; if (data & FCR_FDEN) fdd = m_fdd[data & FCR_DRIVE]; m_fdc->set_floppy(fdd); if (fdd) fdd->ss_w(bool(data & FCR_SIDE)); m_fdc->dden_w(bool(data & FCR_DDEN)); } enum gcr_mask : u8 { GCR_SYSCTL = 0x02, // gpib line driver enable }; void tek6100_state::gcr_w(u8 data) { // TODO: enable/disable line drivers } enum scr_mask : u8 { SCR_RAME = 0x01, // ram enable SCR_NMIE = 0x04, // nmi enable SCR_LLOP = 0x08, // lan loopback enable SCR_BERRE = 0x10, // bus error enable SCR_DMAE = 0x20, // dma enable SCR_PARB = 0x40, // parity bad SCR_PARE = 0x80, // parity enable }; enum ssr_mask : u8 { SSR_DMACH = 0x0f, // dma channel SSR_BERR = 0x10, // bus error SSR_PWRSW = 0x20, // power switch SSR_PFAIL = 0x40, // power fail SSR_PERR = 0x80, // parity error }; enum per_mask : u16 { PER_PARADR = 0x3fff, // parity address PER_HIERR = 0x4000, PER_LOERR = 0x8000, }; void tekigw_state_base::scr_w(u8 data) { if (!(m_scr & SCR_RAME) && (data & SCR_RAME)) m_cpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); if ((m_scr ^ data) & SCR_LLOP) m_lan->set_loopback(data & SCR_LLOP); if (m_scr & SCR_BERRE && !(data & SCR_BERRE)) m_ssr &= ~(SSR_BERR | SSR_DMACH); // install parity handlers if (!(m_scr & SCR_PARB) && (data & SCR_PARB) && !m_parity_check) { m_parity_flag = std::make_unique(m_ram->size() / 32); m_parity_bad = 0; m_parity_check = true; m_parity_mph = m_cpu->space(0).install_readwrite_tap( 0, m_ram->mask(), "parity", [this] (offs_t offset, u16 &data, u16 mem_mask) { if (m_scr & SCR_PARE) { bool error = false; // check bad parity (lo) if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) { m_ssr |= SSR_PERR; m_per &= ~PER_PARADR; m_per |= PER_LOERR | ((offset >> 9) & PER_PARADR); error = true; } // check bad parity (hi) if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) { m_ssr |= SSR_PERR; m_per &= ~PER_PARADR; m_per |= PER_HIERR | ((offset >> 9) & PER_PARADR); error = true; } if (error && (m_scr & SCR_NMIE)) m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } }, [this] (offs_t offset, u16 &data, u16 mem_mask) { if (m_scr & SCR_PARB) { // mark bad parity (lo) if ((mem_mask & 0x00ff) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) { m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 0); m_parity_bad++; } // mark bad parity (hi) if ((mem_mask & 0xff00) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) { m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 1); m_parity_bad++; } } else { // clear bad parity (lo) if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) { m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 0)); m_parity_bad--; } // clear bad parity (hi) if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) { m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 1)); m_parity_bad--; } // stop checking parity if all clear if (!m_parity_bad) { m_parity_flag.reset(); m_parity_mph.remove(); m_parity_check = false; } } }, &m_parity_mph); } // stop checking parity if all clear if ((m_scr & SCR_PARB) && !(data & SCR_PARB) && m_parity_check && !m_parity_bad) { m_parity_flag.reset(); m_parity_mph.remove(); m_parity_check = false; } if (data & SCR_PARE) m_per = 0; else m_ssr &= ~SSR_PERR; m_scr = data; } enum nov_mask : u8 { NOV_NDAT = 0x01, // nonvolatile memory data NOV_SK = 0x02, // serial clock NOV_CS0 = 0x04, // chip select 0 NOV_CS1 = 0x08, // chip select 1 NOV_LED = 0x10, // power-on led NOV_PON = 0x20, // system power enable NOV_MSK = 0x3e, }; void tekigw_state_base::nov_w(u8 data) { bool const cs0 = data & NOV_CS0; bool const cs1 = data & NOV_CS1; if (m_nov[0] && ((m_nmr ^ data) & NOV_CS0)) m_nov[0]->cs_write(cs0); if (m_nov[1] && ((m_nmr ^ data) & NOV_CS1)) m_nov[1]->cs_write(cs1); if (m_nov[0] && cs0) { m_nov[0]->di_write(bool(data & NOV_NDAT)); m_nov[0]->clk_write(bool(data & NOV_SK)); } if (m_nov[1] && cs1) { m_nov[1]->di_write(bool(data & NOV_NDAT)); m_nov[1]->clk_write(bool(data & NOV_SK)); } m_nmr = (m_nmr & ~NOV_MSK) | (data & NOV_MSK); } void tekigw_state_base::nov_do(int state) { if (state) m_nmr |= NOV_NDAT; else m_nmr &= ~NOV_NDAT; } void tekigw_state_base::buserror(s32 param) { if (m_scr & SCR_BERRE) { m_ssr |= SSR_BERR | (param & SSR_DMACH); if (m_scr & SCR_NMIE) m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } } enum hcr_mask : u8 { HCR_HDSEL = 0x0f, // head select HCR_DRSEL = 0x10, // drive select HCR_MULT = 0x20, // multiple sector HCR_BFRDY = 0x40, // buffer ready HCR_BCCLR = 0x80, // buffer counter clear }; void tek6100_state::hcr_w(u8 data) { m_hdc->drdy_w(m_hdd->exists() && bool(data & HCR_DRSEL)); m_hdc->brdy_w(bool(data & HCR_BFRDY)); if (!(data & HCR_BCCLR)) m_hdc_ptr = 0; m_hdc->head_w(data & 7); m_hdc->sc_w(bool(data & HCR_DRSEL)); m_hcr = data; } template T tek6100_state::buf_r() { T data = 0; for (unsigned i = 0; i < sizeof(T); i++) data |= T(m_hdc_buf[m_hdc_ptr++ & 0xfff]) << (i * 8); return data; } template void tek6100_state::buf_w(T data) { for (unsigned i = 0; i < sizeof(T); i++) m_hdc_buf[m_hdc_ptr++ & 0xfff] = u8(data >> (i * 8)); } template void tekigw_state_base::cpu_map(address_map &map) { map(0xfff004, 0xfff005).lw16([this](u16 data) { m_lan->ca(1); }, "lan_ca"); map(0xfff006, 0xfff006).rw(FUNC(tekigw_state_base::nov_r), FUNC(tekigw_state_base::nov_w)); map(0xfff008, 0xfff009).portr("config"); map(0xfff008, 0xfff008).w(FUNC(tekigw_state_base::led_w)); map(0xfff00a, 0xfff00b).lr16([this]() { return m_per; }, "per_r"); map(0xfff00c, 0xfff00c).rw(FUNC(tekigw_state_base::scr_r), FUNC(tekigw_state_base::scr_w)); map(0xfff00e, 0xfff00e).r(FUNC(tekigw_state_base::ssr_r)); map(0xfff800, 0xfff83f).rw(m_rtc, FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0xff); map(0xfffa00, 0xfffa07).rw(m_scc, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask16(0xff); //map(0xfffd00, 0xfffdff); // dma controller map(0xfffe00, 0xfffeff).m(m_icu, FUNC(ns32202_device::map)).umask16(0xff); } template void tek6100_state::cpu_map(address_map &map) { tekigw_state_base::cpu_map(map); map(0x000000, 0x007fff).rom().region("kernel", 0); //map(0x300000, 0x7fffff); // external bus map(0x800000, 0x807fff).rom().region("kernel", 0); //map(0x820000, 0xfdffff); // external bus map(0xfe0000, 0xfeffff).lr8( [this](address_space &space) { // FIXME: Should be 20μs according to 6100 documentation; CPU is still // too fast, and timing may differ on 4132. Also DMACH field should be // 7 for CPU, but diagnostic expects F; maybe 4132 is different? m_buserror->adjust(attotime::from_ticks(10, m_cpu->clock()), 0x7); return 0; // space.unmap(); }, "buserror"); // expansion I/O map(0xff0000, 0xff7fff).rw(FUNC(tek6100_state::buf_r), FUNC(tek6100_state::buf_w)); map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); map(0xfff900, 0xfff90f).rw(m_gpib, FUNC(tms9914_device::read), FUNC(tms9914_device::write)).umask16(0xff); map(0xfffb00, 0xfffb0f).rw(m_hdc, FUNC(wd1010_device::read), FUNC(wd1010_device::write)).umask16(0xff); map(0xfffb10, 0xfffb10).w(FUNC(tek6100_state::hcr_w)); map(0xfffc00, 0xfffc07).rw(m_fdc, FUNC(wd1770_device::read), FUNC(wd1770_device::write)).umask16(0xff); map(0xffff00, 0xffffff).rom().region("kernel", 0x7f00); } void tek6100_state::lan_map(address_map &map) { map.global_mask(0x3fffff); map(0x3fff00, 0x3fffff).rom().region("kernel", 0x7f00); // 0xf00000-0xffffff } template void tek6100_state::dpu_cpu_map(address_map &map) { map(0x000000, 0x007fff).rom().region("dpu", 0); map(0x100000, 0x107fff).rom().region("dpu", 0); map(0x20000e, 0x20000e).lr8([]() { return 0x20; }, "fpu_present"); //map(0x200026, 0x200026); map(0x200028, 0x200028).lw8( [this](u8 data) { if (!BIT(data, 7) && m_dpu_cpu) { m_dpu_cpu->space(0).install_ram(0, m_dpu_cram->mask(), m_dpu_cram->pointer()); m_dpu_cpu->space(0).install_ram(0x400000, 0x400000 | m_dpu_vram->mask(), m_dpu_vram->pointer()); } }, "ram_enable"); //map(0x20002a, 0x20002a); //map(0x20002c, 0x20002c); //map(0x300000, 0x300000); // PUbram - pattern ram map(0xc00000, 0xc0000f).ram(); // PUpixm1 (1/2 bit x 4 planes) } enum csr_mask : u8 { CSR_IDENT = 0x07, // scsi bus id (inverted) CSR_RESET = 0x08, // scsi bus reset CSR_FEOP = 0x10, // dma force eop CSR_IENBL = 0x20, // scsi interrupt enable CSR_DIPEND = 0x40, // dma interrupt pending CSR_SIPEND = 0x80, // scsi interrupt pending }; template void tek4132_state::cpu_map(address_map &map) { map(0x000000, 0xffffff).lr8( [this](address_space &space) { // FIXME: Should be 20μs according to 6100 documentation; CPU is still // too fast, and timing may differ on 4132. Also DMACH field should be // 7 for CPU, but diagnostic expects F; maybe 4132 is different? m_buserror->adjust(attotime::from_ticks(50, m_cpu->clock()), 0xf); return space.unmap(); }, "buserror"); tekigw_state_base::cpu_map(map); map(0x000000, 0x00ffff).rom().region("kernel", 0); map(0x800000, 0x80ffff).rom().region("kernel", 0); //map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); // rsaa_dmaaos serial dma address offset register //map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); // rsaa_auxlatch serial auxiliary control register map(0xfff900, 0xfff91f).rw(m_sdma, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask16(0xff); //map(0xfffa08, 0xfffa08); // rsaa_status //map(0xfffc00, 0xfffc1f); // signature map(0xfffc20, 0xfffc3f).lw8( [this](u8 data) { LOG("csr_w 0x%02x (%s)\n", data, machine().describe_context()); //m_scsi->set_own_id(~data & CSR_IDENT); //m_sirq->in_w<1>(bool(data & CSR_IENBL)); }, "csr_w"); //map(0xfffc40, 0xfffc5f).m(m_scsi, FUNC(ncr5385_device::map)).umask16(0xff); map(0xfffc60, 0xfffc61).ram(); // 9516 data map(0xfffc62, 0xfffc63).ram(); // 9516 pointer map(0xfffd00, 0xfffdff).ram(); // stub out 9516 map(0xffff00, 0xffffff).rom().region("kernel", 0xff00); } void tek4132_state::lan_map(address_map &map) { map.global_mask(0x3fffff); map(0x3fff00, 0x3fffff).rom().region("kernel", 0xff00); // 0xf00000-0xffffff } void tekigw_state_base::common_config(machine_config &config) { NS32016(config, m_cpu, 20_MHz_XTAL / 2); NS32081(config, m_fpu, 20_MHz_XTAL / 2); m_cpu->set_fpu(m_fpu); NS32082(config, m_mmu, 20_MHz_XTAL / 2); m_cpu->set_mmu(m_mmu); NS32202(config, m_icu, 20_MHz_XTAL / 1000); m_icu->out_int().set_inputline(m_cpu, INPUT_LINE_IRQ0).invert(); RAM(config, m_ram); m_ram->set_default_size("1M"); SCC8530N(config, m_scc, 16_MHz_XTAL / 4); m_scc->out_int_callback().set(m_icu, FUNC(ns32202_device::ir_w<1>)).invert(); m_scc->configure_channels(2'457'600, 0, 2'457'600, 0); RS232_PORT(config, m_serial[0], default_rs232_devices, "terminal"); m_serial[0]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w)); m_serial[0]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w)); m_serial[0]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w)); m_scc->out_dtra_callback().set(m_serial[0], FUNC(rs232_port_device::write_dtr)); m_scc->out_rtsa_callback().set(m_serial[0], FUNC(rs232_port_device::write_rts)); m_scc->out_txda_callback().set(m_serial[0], FUNC(rs232_port_device::write_txd)); RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr); m_serial[1]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w)); m_serial[1]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w)); m_serial[1]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w)); m_scc->out_dtrb_callback().set(m_serial[1], FUNC(rs232_port_device::write_dtr)); m_scc->out_rtsb_callback().set(m_serial[1], FUNC(rs232_port_device::write_rts)); m_scc->out_txdb_callback().set(m_serial[1], FUNC(rs232_port_device::write_txd)); MM58167(config, m_rtc, 32.768_kHz_XTAL); EEPROM_X24C44_16BIT(config, m_nov[0]); // X2443P m_nov[0]->do_callback().set(FUNC(tekigw_state_base::nov_do)); I82586(config, m_lan, 16_MHz_XTAL / 2); m_lan->out_irq_cb().set(m_icu, FUNC(ns32202_device::ir_w<11>)).invert(); } void tek6100_state::tek6130(machine_config &config) { tekigw_state_base::common_config(config); m_cpu->set_addrmap(0, &tek6100_state::cpu_map<0>); m_cpu->set_addrmap(6, &tek6100_state::cpu_map<6>); m_lan->set_addrmap(0, &tek6100_state::lan_map); /* * Interrupt sources * 0 interval clock * 1 serial * 2 hard disk * 3 display * 4 backplane slot 1 * 5 backplane slot 2 * 6 backplane slot 3 * 7 backplane slot 4 * 8 backplane slot 5 * 9 backplane slot 6 * 10 gpib * 11 local area network * 12 power switch * 13 flexible disk * 14 network level * 15 software clock */ WD1770(config, m_fdc, 8_MHz_XTAL); // clock? m_fdc->intrq_wr_callback().set(m_icu, FUNC(ns32202_device::ir_w<13>)); //m_fdc->drq_wr_callback().set(m_dma, FUNC(::)); FLOPPY_CONNECTOR(config, "fdc:0", "525dd", FLOPPY_525_DD, true, floppy_image_device::default_mfm_floppy_formats).enable_sound(true); WD1010(config, m_hdc, 20_MHz_XTAL / 4); m_hdc->out_intrq_callback().set(m_icu, FUNC(ns32202_device::ir_w<2>)); m_hdc->in_data_callback().set(FUNC(tek6100_state::buf_r)); m_hdc->out_data_callback().set(FUNC(tek6100_state::buf_w)); m_hdc->out_bcr_callback().set([this](int state) { if (state) m_hdc_ptr = 0; }); /* * Supported hard drives (c,h,s,bps): * - Micropolis 1302 (830,3,16,512) * - Micropolis 1304 (830,6,16,512) * - Maxtor XT-1105 (918,11,16,512) */ HARDDISK(config, m_hdd, 0); TMS9914(config, m_gpib, 20_MHz_XTAL / 4); m_gpib->int_write_cb().set(m_icu, FUNC(ns32202_device::ir_w<10>)); m_gpib->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); m_gpib->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); m_gpib->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); m_gpib->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); m_gpib->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); m_gpib->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); m_gpib->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); m_gpib->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); m_gpib->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); m_gpib->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); ieee488_device &ieee(IEEE488(config, IEEE488_TAG)); ieee.eoi_callback().set(m_gpib, FUNC(tms9914_device::eoi_w)); ieee.dav_callback().set(m_gpib, FUNC(tms9914_device::dav_w)); ieee.nrfd_callback().set(m_gpib, FUNC(tms9914_device::nrfd_w)); ieee.ndac_callback().set(m_gpib, FUNC(tms9914_device::ndac_w)); ieee.ifc_callback().set(m_gpib, FUNC(tms9914_device::ifc_w)); ieee.srq_callback().set(m_gpib, FUNC(tms9914_device::srq_w)); ieee.atn_callback().set(m_gpib, FUNC(tms9914_device::atn_w)); ieee.ren_callback().set(m_gpib, FUNC(tms9914_device::ren_w)); IEEE488_SLOT(config, "ieee_rem", 0, remote488_devices, nullptr); // TODO: graphics board disabled for now if (false) { NS32016(config, m_dpu_cpu, 0); // 8'000'000); m_dpu_cpu->set_addrmap(0, &tek6100_state::dpu_cpu_map<0>); ns32081_device &dpu_fpu(NS32081(config, "dpu_fpu", 8'000'000)); m_dpu_cpu->set_fpu(dpu_fpu); ns32202_device &dpu_icu(NS32202(config, "dpu_icu", 20'000)); dpu_icu.out_int().set_inputline(m_dpu_cpu, INPUT_LINE_IRQ0).invert(); i8744_device &dpu_mcu(I8744(config, "dpu_mcu", 0)); // 10'000'000)); // 8744H-10 (void)dpu_mcu; mc6845_device &dpu_crtc(SY6845E(config, "dpu_crtc", 25.2_MHz_XTAL)); // SYP6845EA dpu_crtc.set_screen("dpu_screen"); // 32 x HM50256-15 (256K x 1 DRAM) total 1MiB RAM(config, m_dpu_cram); m_dpu_cram->set_default_size("1MiB"); // 32 x IMS2620P-12 (16K x 4 DRAM) total 256KiB RAM(config, m_dpu_vram); m_dpu_vram->set_default_size("256KiB"); // 13-inch 640x480 60Hz 4-bit color // 15-inch 640x480 60Hz monochrome screen_device &dpu_screen(SCREEN(config, "dpu_screen", SCREEN_TYPE_RASTER)); dpu_screen.set_raw(25200000, 800, 0, 640, 525, 0, 480); dpu_screen.set_screen_update(FUNC(tek6100_state::screen_update)); } } static void scsi_devices(device_slot_interface &device) { device.option_add("harddisk", NSCSI_HARDDISK); } void tek4132_state::tek4132(machine_config &config) { tekigw_state_base::common_config(config); m_cpu->set_addrmap(0, &tek4132_state::cpu_map<0>); m_cpu->set_addrmap(6, &tek4132_state::cpu_map<6>); m_lan->set_addrmap(0, &tek4132_state::lan_map); m_scc->configure_channels(3'686'400, 0, 3'686'400, 0); /* * Interrupt sources * 0 interval clock * 1 serial * 2 display * 3 serial dma * 4 scsi controller * 5 backplane slot 1 * 6 backplane slot 2 * 7 backplane slot 3 * 8 backplane slot 4 * 9 backplane slot 5 * 10 backplane slot 6 * 11 local area network * 12 power switch interrupt * 13 time of day clock * 14 network level * 15 software clock */ m_rtc->irq().set(m_icu, FUNC(ns32202_device::ir_w<13>)); EEPROM_X24C44_16BIT(config, m_nov[1]); // X2443P m_nov[1]->do_callback().set(FUNC(tek4132_state::nov_do)); AM9517A(config, m_sdma, 4'000'000); // clock? m_sdma->dreq_active_low(); INPUT_MERGER_ALL_HIGH(config, m_sirq); //m_sirq->output_handler().set(m_icu, FUNC(ns32202_device::ir_w<4>)); NSCSI_BUS(config, m_scsibus); NSCSI_CONNECTOR(config, "scsi:0", scsi_devices, "harddisk"); NSCSI_CONNECTOR(config, "scsi:1", scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:2", scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:3", scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:4", scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:5", scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:6", scsi_devices, nullptr); #if 1 NSCSI_CONNECTOR(config, "scsi:7", scsi_devices, nullptr); #else NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5385", NCR5385).clock(10'000'000).machine_config( [this](device_t *device) { ncr5385_device &adapter = downcast(*device); //adapter.irq().set(m_sirq, FUNC(input_merger_all_high_device::in_w<0>)); adapter.irq().set(m_icu, FUNC(ns32202_device::ir_w<4>)); //adapter.drq_handler_cb().set(m_mct_adr, FUNC(mct_adr_device::drq<0>)); //subdevice(":mct_adr")->dma_r_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_r)); //subdevice(":mct_adr")->dma_w_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_w)); }); #endif } static INPUT_PORTS_START(tekigw) PORT_START("config") PORT_DIPNAME(0x80, 0x00, "Mode") PORT_DIPLOCATION("SW:1") PORT_DIPSETTING( 0x00, "Normal") PORT_DIPSETTING( 0x80, "Service") PORT_DIPNAME(0x60, 0x20, "Console") PORT_DIPLOCATION("SW:3,2") PORT_DIPSETTING( 0x00, "Display") PORT_DIPSETTING( 0x20, "9600 baud RS-232-C terminal (port 0)") PORT_DIPSETTING( 0x40, "1200 baud RS-232-C modem/terminal (port 1)") PORT_DIPSETTING( 0x60, "300 baud model/terminal (port 1)") PORT_DIPNAME(0x10, 0x00, "Boot") PORT_DIPLOCATION("SW:4") PORT_DIPSETTING( 0x00, "UTek") PORT_DIPSETTING( 0x10, "File") PORT_DIPNAME(0x0c, 0x00, "Boot Device") PORT_DIPLOCATION("SW:6,5") PORT_DIPSETTING( 0x00, "Autoboot") PORT_DIPSETTING( 0x04, "Hard disk") PORT_DIPSETTING( 0x08, "Diskette drive") PORT_DIPSETTING( 0x0c, "LAN port") PORT_DIPNAME(0x03, 0x00, "Diagnostic") PORT_DIPLOCATION("SW:8,7") PORT_DIPSETTING( 0x00, "0") PORT_DIPSETTING( 0x01, "1") PORT_DIPSETTING( 0x02, "2") PORT_DIPSETTING( 0x03, "3") INPUT_PORTS_END ROM_START(tek6130) ROM_REGION16_LE(0x8000, "kernel", 0) ROM_SYSTEM_BIOS(0, "5.107", "5.107 85/02/20 13:51:51") ROMX_LOAD("160-2921-02.bin", 0x00000, 0x4000, CRC(44688258) SHA1(645ceaa6ea9ef76ba8b557dec0387fce73f669c0), ROM_BIOS(0) | ROM_SKIP(1)) ROMX_LOAD("160-2922-02.bin", 0x00001, 0x4000, CRC(5d84dff3) SHA1(08e74f0157a5c002397b3c8644613dc0ae8355a0), ROM_BIOS(0) | ROM_SKIP(1)) ROM_SYSTEM_BIOS(1, "5.105", "5.105 85/02/16 11:03:32") ROMX_LOAD("pwr_up__5.105__adb_lo.bin", 0x00000, 0x4000, CRC(429a6a4a) SHA1(5ec5a045ec14a1b546d75e9406f0ad21163298f6), ROM_BIOS(1) | ROM_SKIP(1)) ROMX_LOAD("pwr_up__5.105__adb_hi.bin", 0x00001, 0x4000, CRC(1ad7a762) SHA1(98472c30f1148c43f43d2131ebc9644d8ebf376a), ROM_BIOS(1) | ROM_SKIP(1)) ROM_REGION16_LE(0x8000, "dpu", 0) ROMX_LOAD("l__sdpu__1.73.bin", 0x00000, 0x4000, CRC(cd1be127) SHA1(9c16ab7e8b195e9ae660288b4b26566581a029e5), ROM_SKIP(1)) ROMX_LOAD("h__sdpu__1.73.bin", 0x00001, 0x4000, CRC(1adf3130) SHA1(966f839de0b10aff3ffc6af64d94e4b19ece52c7), ROM_SKIP(1)) ROM_REGION(0x1000, "dpu_mcu", 0) ROM_LOAD("2960-01.bin", 0x0, 0x1000, CRC(5974eaec) SHA1(362cdfb7be162636429d614807b9066ca8bbab28)) ROM_END ROM_START(tek4132) ROM_REGION16_LE(0x10000, "kernel", 0) ROM_SYSTEM_BIOS(0, "1.7", "5.107 85/02/20 13:51:51") ROMX_LOAD("160-4018-00__v1.7.u3130", 0x00000, 0x8000, CRC(cdf154ab) SHA1(381d012b0ec85db03d8cb164ef22f92e33d40b57), ROM_BIOS(0) | ROM_SKIP(1)) ROMX_LOAD("160-4019-00__v1.7.u3140", 0x00001, 0x8000, CRC(5fe870b1) SHA1(369507763e37e947bbbfde080ba3d83bb6f3a7bf), ROM_BIOS(0) | ROM_SKIP(1)) ROM_END } // anonymous namespace /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ COMP(1984, tek6130, 0, 0, tek6130, tekigw, tek6100_state, init, "Tektronix", "6130", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) COMP(1984, tek4132, 0, 0, tek4132, tekigw, tek4132_state, init, "Tektronix", "4132", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW)