From 2c56d783e9f814d9303d38b50b16e82229938e12 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Thu, 4 Apr 2024 17:31:36 +0700 Subject: [PATCH] New working systems ------------------- IBM 5110 [Christian Corti, Tom Stepleton] --- src/mame/ibm/ibm5100.cpp | 483 +++++++++++++++++++++++++++++++-------- src/mame/mame.lst | 1 + 2 files changed, 395 insertions(+), 89 deletions(-) diff --git a/src/mame/ibm/ibm5100.cpp b/src/mame/ibm/ibm5100.cpp index 35be65063d4be..533cfd814871c 100644 --- a/src/mame/ibm/ibm5100.cpp +++ b/src/mame/ibm/ibm5100.cpp @@ -11,10 +11,11 @@ * - display registers * - device address f * - tape controller + * - disk controller * - printer * - communications cards * - expansion feature - * - later models (5110, 5120, 5130) + * - feature ROS (K4) */ #include "emu.h" @@ -22,8 +23,11 @@ #include "ibm5100_kbd.h" #include "cpu/palm/palm.h" +#include "sound/beep.h" +#include "emupal.h" #include "screen.h" +#include "speaker.h" //#define VERBOSE (LOG_GENERAL) #include "logmacro.h" @@ -38,12 +42,12 @@ class ibm5100_state : public driver_device , m_cpu(*this, "cpu") , m_screen(*this, "screen") , m_kbd(*this, "kbd") - , m_nxr(*this, { "apl", "basic" }) - , m_j2(*this, "j2") + , m_nxr(*this, { "common", "basic", "apl" }) + , m_cgr(*this, "cgr") + , m_ros(*this, "ros") , m_conf(*this, "CONF") , m_disp(*this, "DISP") , m_lang(*this, "LANG") - , m_ros(*this, "ros") { } @@ -54,59 +58,110 @@ class ibm5100_state : public driver_device virtual void machine_start() override; virtual void machine_reset() override; - void cpu_ros_map(address_map &map); - void cpu_rws_map(address_map &map); - void cpu_ioc_map(address_map &map); - void cpu_iod_map(address_map &map); + virtual void cpu_ros_map(address_map &map); + virtual void cpu_rws_map(address_map &map); + virtual void cpu_ioc_map(address_map &map); + virtual void cpu_iod_map(address_map &map); u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect); - // e2 - ros control card - u8 e2_sts_r(); - void e2_ctl_w(u8 data); - u8 e2_r(); - void e2_w(u8 data); + virtual void da0_ctl_w(u8 data); + + // non-executable ROS control + u8 nxr_sts_r(); + void nxr_ctl_w(u8 data); + virtual u8 nxr_r(); + virtual void nxr_w(u8 data); + + // keyboard + u8 kbd_sts_r(); + void kbd_ctl_w(u8 data); - // f2 - base i/o card - u8 f2_kbd_sts_r(); - void f2_kbd_ctl_w(u8 data); - void da0_ctl_w(u8 data); void daf_ctl_w(u8 data); -private: required_device m_cpu; required_device m_screen; required_device m_kbd; - required_region_ptr_array m_nxr; - required_region_ptr m_j2; + required_region_ptr_array m_nxr; + required_region_ptr m_cgr; // character generator ROS + + memory_view m_ros; required_ioport m_conf; required_ioport m_disp; required_ioport m_lang; - memory_view m_ros; - u8 m_getb_bus; - u8 m_e2_ff; // e2 card flip-flops - u8 m_f2_ff; // f2 card flip-flops - u16 m_e2_address; + u8 m_nxr_ff; // non-executable ROS control flip-flops + u8 m_bio_ff; // base I/O card flip-flops + u16 m_nxr_address; std::unique_ptr m_rws; }; -enum e2_ff_mask : u8 +class ibm5110_state : public ibm5100_state { - E2_RS = 0x01, // ROS select (0=APL, 1=BASIC/common) - E2_PS = 0x02, // put strobe - E2_B0 = 0x04, // data address bit 0 +public: + ibm5110_state(machine_config const &mconfig, device_type type, char const *tag) + : ibm5100_state(mconfig, type, tag) + , m_alarm(*this, "alarm") + , m_exr(*this, "exr") + , m_jmp(*this, { "L2_1", "L2_2", "K4" }) + { + } + + void ibm5110(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + + virtual void cpu_ros_map(address_map &map) override; + virtual void cpu_ioc_map(address_map &map) override; + + virtual void da0_ctl_w(u8 data) override; + + // executable ROS control + u8 exr_sts_r(); + void exr_ctl_w(u8 data); + + // non-executable ROS control + virtual u8 nxr_r() override; + virtual void nxr_w(u8 data) override; + +private: + required_device m_alarm; + + memory_view m_exr; + + required_ioport_array<3> m_jmp; + + u8 m_exr_ff; // executable ROS flip-flops }; -enum f2_ff_mask : u8 +enum nxr_ff_mask : u8 { - F2_KIE = 0x01, // keyboard interrupt enable - F2_DO = 0x10, // display off + NXR_RS = 0x03, // ROS select + NXR_PS = 0x04, // put strobe + NXR_B0 = 0x08, // data address bit 0 + + NXR_COMMON = 0x00, + NXR_BASIC = 0x01, + NXR_APL = 0x02, +}; + +enum bio_ff_mask : u8 +{ + BIO_KIE = 0x01, // keyboard interrupt enable + BIO_KI = 0x08, // keyboard interrupt active + BIO_DO = 0x10, // display off +}; + +enum exr_ff_mask : u8 +{ + EXR_ROS2 = 0x01, // ROS2 enable }; void ibm5100_state::machine_start() @@ -116,19 +171,26 @@ void ibm5100_state::machine_start() save_item(NAME(m_getb_bus)); - save_item(NAME(m_e2_ff)); - save_item(NAME(m_f2_ff)); - save_item(NAME(m_e2_address)); + save_item(NAME(m_nxr_ff)); + save_item(NAME(m_bio_ff)); + save_item(NAME(m_nxr_address)); save_pointer(NAME(m_rws), 0x8000); } +void ibm5110_state::machine_start() +{ + ibm5100_state::machine_start(); + + save_item(NAME(m_exr_ff)); +} + void ibm5100_state::machine_reset() { - m_e2_ff = 0; - m_f2_ff = 0; + m_nxr_ff = 0; + m_bio_ff = 0; - m_e2_address = 0; + m_nxr_address = 0; // install configured rws unsigned const rws_cards = (m_conf->read() & 3) + 1; @@ -136,12 +198,29 @@ void ibm5100_state::machine_reset() m_ros[1].install_ram(0x80, 0x4000 * rws_cards - 1, &m_rws[0x40]); } +void ibm5110_state::machine_reset() +{ + ibm5100_state::machine_reset(); + + m_exr.disable(); + m_exr_ff = 0; +} + void ibm5100_state::cpu_ros_map(address_map &map) { map(0x0000, 0xffff).view(m_ros); m_ros[0](0x0000, 0xffff).rom().region("ros", 0); } +void ibm5110_state::cpu_ros_map(address_map &map) +{ + map(0x0000, 0xffff).view(m_ros); + m_ros[0](0x0000, 0x7fff).rom().region("l2_1", 0); + m_ros[0](0x0000, 0x7fff).view(m_exr); + m_exr[0](0x0000, 0x7fff).rom().region("l2_2a", 0); + m_exr[1](0x0000, 0x7fff).rom().region("l2_2b", 0); +} + void ibm5100_state::cpu_rws_map(address_map &map) { map.unmap_value_high(); @@ -150,9 +229,9 @@ void ibm5100_state::cpu_rws_map(address_map &map) void ibm5100_state::cpu_ioc_map(address_map &map) { map(0x0, 0x0).w(FUNC(ibm5100_state::da0_ctl_w)); - map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_sts_r), FUNC(ibm5100_state::e2_ctl_w)); + map(0x1, 0x1).rw(FUNC(ibm5100_state::nxr_sts_r), FUNC(ibm5100_state::nxr_ctl_w)); map(0x2, 0x3).noprw(); - map(0x4, 0x4).rw(FUNC(ibm5100_state::f2_kbd_sts_r), FUNC(ibm5100_state::f2_kbd_ctl_w)); + map(0x4, 0x4).rw(FUNC(ibm5100_state::kbd_sts_r), FUNC(ibm5100_state::kbd_ctl_w)); // 5 printer r:not used w:control map(0x6, 0x7).noprw(); // 8 expansion r:status w:control @@ -161,14 +240,21 @@ void ibm5100_state::cpu_ioc_map(address_map &map) map(0xf, 0xf).nopr().w(FUNC(ibm5100_state::daf_ctl_w)); } +void ibm5110_state::cpu_ioc_map(address_map &map) +{ + ibm5100_state::cpu_ioc_map(map); + + map(0x2, 0x2).rw(FUNC(ibm5110_state::exr_sts_r), FUNC(ibm5110_state::exr_ctl_w)); +} + void ibm5100_state::cpu_iod_map(address_map &map) { map.unmap_value_high(); map(0x0, 0x0).noprw(); - map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_r), FUNC(ibm5100_state::e2_w)); + map(0x1, 0x1).rw(FUNC(ibm5100_state::nxr_r), FUNC(ibm5100_state::nxr_w)); map(0x2, 0x3).noprw(); - map(0x4, 0x4).r(m_kbd, FUNC(ibm5100_keyboard_device::read)).nopw(); + map(0x4, 0x4).r(m_kbd, FUNC(ibm5100_keyboard_device::read)); // 5 r:printer w:print data map(0x6, 0x7).noprw(); // 8 expansion r:not used w:data @@ -193,18 +279,66 @@ void ibm5100_state::ibm5100(machine_config &config) * pixels of each character cell line and every other scan line are blank. */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_raw(15'091'200, 64*10, 0, 64*10, 16*12*2, 0, 16*12*2); + m_screen->set_raw(15'091'200, 64*10+15, 0, 64*10, 16*12*2, 0, 16*12*2); m_screen->set_screen_update(FUNC(ibm5100_state::screen_update)); IBM5100_KEYBOARD(config, m_kbd); m_kbd->strobe().set( [this](int state) { - if ((m_f2_ff & F2_KIE) && !state) + if ((m_bio_ff & BIO_KIE) && !state) m_cpu->set_input_line(palm_device::IRPT_REQ3, 0); }); } +void ibm5110_state::ibm5110(machine_config &config) +{ + ibm5100_state::ibm5100(config); + + m_cpu->program_level().set( + [this](int state) + { + if (state || !(m_exr_ff & EXR_ROS2)) + m_exr.disable(); + else + m_exr.select(BIT(m_lang->read(), 6)); + }); + + IBM5110_KEYBOARD(config.replace(), m_kbd); + m_kbd->strobe().set( + [this](int state) + { + if (!state) + { + m_bio_ff |= BIO_KI; + + if (m_bio_ff & BIO_KIE) + m_cpu->set_input_line(palm_device::IRPT_REQ3, 0); + } + }); + + SPEAKER(config, "mono").front_center(); + BEEP(config, m_alarm, 3'885); // FIXME: frequency + m_alarm->add_route(ALL_OUTPUTS, "mono", 0.25); + + // gfxdecode is only used to show the font data in the tile viewer + static const gfx_layout g2_layout = + { + 8, 12, 256, 1, + { 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0 * 8, 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 9 * 8, 10 * 8, 11 * 8 }, + 8 * 16 + }; + + static GFXDECODE_START(g2) + GFXDECODE_ENTRY("cgr", 0, g2_layout, 0, 1) + GFXDECODE_END + + PALETTE(config, "palette", palette_device::MONOCHROME); + GFXDECODE(config, "gfx", "palette", g2); +} + u32 ibm5100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) { static rgb_t const c[] = { rgb_t::white(), rgb_t::black() }; @@ -219,11 +353,14 @@ u32 ibm5100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, re // start with a blank screen bitmap.fill(c[reverse]); - // then generate characters + if (m_bio_ff & BIO_DO) + return 0; + + // generate characters auto const rws = util::big_endian_cast(m_rws.get()); for (unsigned char_y = 0; char_y < 16; char_y++) { - // every other scan line is blank + // every alternate scan line is blank int const y = screen.visible_area().min_y + char_y * 12 * 2; // compute offset into rws for each row @@ -233,17 +370,31 @@ u32 ibm5100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, re { int const x = screen.visible_area().min_x + char_x * 10; - // read next character if display is on and normal mode or even column + // read next character if normal mode or even column u8 char_data = 0; - if (!(m_f2_ff & F2_DO) && (n64 || !(char_x & 1))) + if (n64 || !(char_x & 1)) char_data = rws[offset++]; // draw 8x12 character cell for (unsigned cell_y = 0; cell_y < 12; cell_y++) { - // index into character font data - unsigned const underline = ((cell_y > 7) && BIT(char_data, 7)) ? 4 : 0; - u8 const cell_data = m_j2[(char_data & 0x7f) * 16 + cell_y + underline]; + u8 cell_data = 0; + + /* + * The J2 (5100) display adapter has 2KiB of character ROS used + * to produce 128 unique characters with normal and underlined + * variants. The G2 (5110) has 4KiB with 256 unique character + * patterns, with only selected characters having underlined + * variations. + */ + if (m_cgr.bytes() < 4096) + { + unsigned const underline = ((cell_y > 7) && BIT(char_data, 7)) ? 4 : 0; + + cell_data = m_cgr[(char_data & 0x7f) * 16 + cell_y + underline]; + } + else + cell_data = m_cgr[char_data * 16 + cell_y]; bitmap.pix(y + cell_y * 2, x + 0) = c[BIT(cell_data, 7) ^ reverse]; bitmap.pix(y + cell_y * 2, x + 1) = c[BIT(cell_data, 6) ^ reverse]; @@ -265,49 +416,94 @@ void ibm5100_state::da0_ctl_w(u8 data) LOG("da0_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); // bit 4: 0=display off + // bit 3: 0=display on if (!BIT(data, 4)) - m_f2_ff |= F2_DO; - else - m_f2_ff &= ~F2_DO; + m_bio_ff |= BIO_DO; + else if (!BIT(data, 3)) + m_bio_ff &= ~BIO_DO; +} + +void ibm5110_state::da0_ctl_w(u8 data) +{ + ibm5100_state::da0_ctl_w(data); + + // bit 0: 0=alarm on + // bit 1: 0=alarm off + if (!BIT(data, 0)) + m_alarm->set_state(1); + else if (!BIT(data, 1)) + m_alarm->set_state(0); +} + +u8 ibm5110_state::exr_sts_r() +{ + LOG("exr_sts_r 0x%02x (%s)\n", m_getb_bus, machine().describe_context()); + + switch (m_getb_bus) + { + case 0x80: return m_jmp[0]->read(); + case 0x40: return m_jmp[1]->read(); + case 0x20: return m_jmp[2]->read(); + default: + return 0; + } +} + +void ibm5110_state::exr_ctl_w(u8 data) +{ + LOG("exr_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + + if (BIT(data, 7)) + { + m_exr.select(BIT(m_lang->read(), 6)); + m_exr_ff |= EXR_ROS2; + } + else if (BIT(data, 6)) + { + m_exr.disable(); + m_exr_ff &= ~EXR_ROS2; + } } -u8 ibm5100_state::e2_sts_r() +u8 ibm5100_state::nxr_sts_r() { u8 data = 0xff; if (!machine().side_effects_disabled()) { - data = (m_e2_ff & E2_PS) ? u8(m_e2_address) : (m_e2_address >> 8); + data = (m_nxr_ff & NXR_PS) ? u8(m_nxr_address) : (m_nxr_address >> 8); - m_e2_ff ^= E2_PS; + m_nxr_ff ^= NXR_PS; } return data; } -void ibm5100_state::e2_ctl_w(u8 data) +void ibm5100_state::nxr_ctl_w(u8 data) { - LOG("e2_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + LOG("nxr_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); - if (!BIT(data, 3)) - m_e2_ff &= ~E2_RS; - else if (!BIT(data, 2)) - m_e2_ff |= E2_RS; + m_nxr_ff &= ~(NXR_B0 | NXR_PS | NXR_RS); - m_e2_ff &= ~(E2_B0 | E2_PS); - m_e2_address = 0; + if (BIT(data, 3)) + m_nxr_ff |= NXR_BASIC; + else if (BIT(data, 2)) + m_nxr_ff |= NXR_APL; + + m_nxr_address = 0; } -u8 ibm5100_state::e2_r() +u8 ibm5100_state::nxr_r() { u8 data = 0xff; if (!machine().side_effects_disabled()) { - bool const basic = m_e2_ff & E2_RS; + unsigned const rs = m_nxr_ff & NXR_RS; + bool const basic = !(rs & NXR_APL); // check model has selected ROS (all models have common) - if (BIT(m_conf->read(), 2 + basic) || (basic && m_e2_address >= 0x9000)) + if (BIT(m_conf->read(), 2 + basic) || (basic && m_nxr_address >= 0x9000)) { /* * APL non-executable ROS is addressed with an unshifted 16-bit @@ -315,41 +511,79 @@ u8 ibm5100_state::e2_r() * giving 64KiB. Even and odd bytes are selected by a flip-flop * which is toggled with each read. */ - data = BIT(m_nxr[basic][m_e2_address >> basic], (m_e2_ff & E2_B0) ? 0 : 8, 8); + data = BIT(m_nxr[rs][m_nxr_address >> basic], (m_nxr_ff & NXR_B0) ? 0 : 8, 8); } // always increment address for BASIC, only on odd bytes for APL - if (basic || (m_e2_ff & E2_B0)) - m_e2_address++; + if (basic || (m_nxr_ff & NXR_B0)) + m_nxr_address++; // toggle even/odd byte flip-flop - m_e2_ff ^= E2_B0; + m_nxr_ff ^= NXR_B0; } return data; } -void ibm5100_state::e2_w(u8 data) +u8 ibm5110_state::nxr_r() { - m_e2_address = (m_e2_address << 8) | data; + u8 data = 0xff; - if (m_e2_ff & E2_PS) + if (!machine().side_effects_disabled()) { - LOG("e2_address 0x%04x (%s)\n", m_e2_address, machine().describe_context()); + unsigned const rs = m_nxr_ff & NXR_RS; + + // check model has selected ROS (all models have common) + if (!(rs & NXR_APL) || BIT(m_conf->read(), 2)) + data = BIT(m_nxr[rs][m_nxr_address], (m_nxr_ff & NXR_B0) ? 0 : 8, 8); + + // increment after odd bytes + if (m_nxr_ff & NXR_B0) + m_nxr_address++; + + // toggle even/odd byte flip-flop + m_nxr_ff ^= NXR_B0; + } + + return data; +} + +void ibm5100_state::nxr_w(u8 data) +{ + m_nxr_address = (m_nxr_address << 8) | data; + + if (m_nxr_ff & NXR_PS) + { + LOG("nxr_address 0x%04x (%s)\n", m_nxr_address, machine().describe_context()); // data byte even/odd flip-flop is cleared except when BASIC is // selected and the address is odd - if ((m_e2_ff & E2_RS) && (m_e2_address & 1)) - m_e2_ff |= E2_B0; + if (!(m_nxr_ff & NXR_APL) && (m_nxr_address & 1)) + m_nxr_ff |= NXR_B0; else - m_e2_ff &= ~E2_B0; + m_nxr_ff &= ~NXR_B0; + } + + // toggle put strobe flip-flop + m_nxr_ff ^= NXR_PS; +} + +void ibm5110_state::nxr_w(u8 data) +{ + m_nxr_address = (m_nxr_address << 8) | data; + + if (m_nxr_ff & NXR_PS) + { + LOG("nxr_address 0x%04x (%s)\n", m_nxr_address, machine().describe_context()); + + m_nxr_ff &= ~NXR_B0; } // toggle put strobe flip-flop - m_e2_ff ^= E2_PS; + m_nxr_ff ^= NXR_PS; } -u8 ibm5100_state::f2_kbd_sts_r() +u8 ibm5100_state::kbd_sts_r() { if (!machine().side_effects_disabled()) { @@ -357,12 +591,13 @@ u8 ibm5100_state::f2_kbd_sts_r() { case 0x40: // keyboard data gate + m_bio_ff &= ~BIO_KI; return m_kbd->read(); case 0x80: // keyboard status gate - return m_lang->read(); + return m_lang->read() | (m_bio_ff & BIO_KI); default: - LOG("f2_kbd_sts_r: unknown 0x%02x (%s)\n", m_getb_bus, machine().describe_context()); + LOG("kbd_sts_r: unknown 0x%02x (%s)\n", m_getb_bus, machine().describe_context()); break; } } @@ -370,14 +605,14 @@ u8 ibm5100_state::f2_kbd_sts_r() return 0xff; } -void ibm5100_state::f2_kbd_ctl_w(u8 data) +void ibm5100_state::kbd_ctl_w(u8 data) { - LOG("f2_kbd_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + LOG("kbd_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); // bit 6: 0=reset and disable keyboard interrupts if (!BIT(data, 6)) { - m_f2_ff &= ~F2_KIE; + m_bio_ff &= ~BIO_KIE; m_cpu->set_input_line(palm_device::IRPT_REQ3, 1); } @@ -391,9 +626,9 @@ void ibm5100_state::f2_kbd_ctl_w(u8 data) // bit 0: 0=enable keyboard interrupt if (!BIT(data, 0)) - m_f2_ff |= F2_KIE; + m_bio_ff |= BIO_KIE; else - m_f2_ff &= ~F2_KIE; + m_bio_ff &= ~BIO_KIE; } void ibm5100_state::daf_ctl_w(u8 data) @@ -404,8 +639,15 @@ void ibm5100_state::daf_ctl_w(u8 data) // 7 expansion da=8 // 6 tape da=e // 5 keyboard da=4 + if (BIT(data, 5)) + { + m_bio_ff &= ~(BIO_KI | BIO_KIE); + m_cpu->set_input_line(palm_device::IRPT_REQ3, 1); + } // 4 printer da=5 // 3 enable cycle steal + if (BIT(data, 3)) + m_bio_ff &= ~BIO_DO; // 2 reset da=b // 1 reset da=c // 0 reset da=d @@ -423,6 +665,11 @@ ROM_START(ibm5100) * BASIC card, however it is selected together with the BASIC ROS and * logically appended to the address space. */ + ROM_REGION16_BE(0x10000, "common", 0) + ROM_LOAD("c4.ros", 0x0000, 0x9000, CRC(b1abeb4a) SHA1(e0151fefe63c43c8912599615ddfb7c06f111c72)) + ROM_LOAD("e2.ros", 0x9000, 0x4800, CRC(be4289c3) SHA1(008ea7bb25fda94540bf5e02eff5a59bb1c86aac)) + ROM_FILL(0xd800, 0x2800, 0xff) + ROM_REGION16_BE(0x10000, "basic", 0) ROM_LOAD("c4.ros", 0x0000, 0x9000, CRC(b1abeb4a) SHA1(e0151fefe63c43c8912599615ddfb7c06f111c72)) ROM_LOAD("e2.ros", 0x9000, 0x4800, CRC(be4289c3) SHA1(008ea7bb25fda94540bf5e02eff5a59bb1c86aac)) @@ -442,10 +689,49 @@ ROM_START(ibm5100) * 8x8 cell, then 2x4 byte entries contain the normal and underlined lower * 4 rows of the total 8x12 cell respectively. */ - ROM_REGION(0x800, "j2", 0) + ROM_REGION(0x800, "cgr", 0) ROM_LOAD("j2.ros", 0x000, 0x800, CRC(428e5b66) SHA1(9def68eed9dc2b8f08581387f8b74b49b3faf7e7) BAD_DUMP) ROM_END +ROM_START(ibm5110) + // Executable ROS + ROM_REGION16_BE(0x8000, "l2_1", 0) + ROM_LOAD("l2_1.ros", 0x0000, 0x8000, CRC(0355894f) SHA1(c76a91cbbec226feb942ccde93ecb1637c88a01b)) + + // APL Executable ROS + ROM_REGION16_BE(0x8000, "l2_2a", 0) + ROM_LOAD("l2_2a.ros", 0x0000, 0x5000, CRC(46918be9) SHA1(bf45a44f77104c55f2ccfa462af06944e6bffe1a)) + ROM_FILL(0x5000, 0x3000, 0xff) + + // BASIC Executable ROS + ROM_REGION16_BE(0x8000, "l2_2b", 0) + ROM_LOAD("l2_2b.ros", 0x0000, 0x4000, CRC(a69dd0c1) SHA1(ecdc1363e25b72b695c517af145c50a069b6e8dc)) + ROM_FILL(0x4000, 0x3000, 0xff) + + // Common and Language non-executable ROS + ROM_REGION16_BE(0x20000, "common", 0) + ROM_LOAD("f2_c.ros", 0x0000, 0x4000, CRC(83beafb2) SHA1(80ad07a2a83ff395d918b69d5c81a6e94ac7af37)) + ROM_FILL(0x4000, 0x1c000, 0xff) + + // BASIC non-executable ROS + ROM_REGION16_BE(0x20000, "basic", 0) + ROM_LOAD("f2_b.ros", 0x0000, 0x12000, CRC(3ffb79b6) SHA1(254f5a7ae739b7bf6a800e8380cf3b6686ee9768)) + ROM_FILL(0x12000, 0x8000, 0xff) + + // APL non-executable ROS + ROM_REGION16_BE(0x20000, "apl", 0) + ROM_LOAD("e4.ros", 0x00000, 0x20000, CRC(1e28db20) SHA1(cf12893bb76c44756a9554828d42299b169e560a)) + + // Display Adapter ROS + /* + * This data was hand-made based on the character map in the documentation. + * It was assumed that the first 12 bytes of each character store the 8x12 + * cell, followed by 8x4 empty bytes. + */ + ROM_REGION(0x1000, "cgr", 0) + ROM_LOAD("g2.ros", 0x000, 0x1000, CRC(1f55161c) SHA1(eb22f3177060bd7cb4ba8facaa293147ffeceabc) BAD_DUMP) +ROM_END + static INPUT_PORTS_START(ibm5100) PORT_START("CONF") PORT_CONFNAME(0x0f, 0x0f, "Model") @@ -482,7 +768,26 @@ static INPUT_PORTS_START(ibm5100) PORT_CONFSETTING(0x40, "BASIC") PORT_CONDITION("CONF", 0x08, EQUALS, 0x08) INPUT_PORTS_END +static INPUT_PORTS_START(ibm5110) + PORT_INCLUDE(ibm5100) + + PORT_START("L2_1") + PORT_DIPNAME(0xf0, 0xf0, "Model") PORT_DIPLOCATION("L2_1:4,3,2,1") + PORT_DIPSETTING(0xf0, "5110-X1X") + PORT_DIPSETTING(0xe0, "5110-X2X") + + PORT_START("L2_2") + PORT_DIPNAME(0xf0, 0xc0, "L2_2") PORT_DIPLOCATION("L2_2:4,3,2,1") + PORT_DIPSETTING(0xc0, DEF_STR(Unknown)) + + PORT_START("K4") + PORT_DIPNAME(0x80, 0x80, "Feature ROS") PORT_DIPLOCATION("K4:1") + PORT_DIPSETTING(0x80, "Absent") + PORT_DIPSETTING(0x00, "Present") +INPUT_PORTS_END + } // anonymous namespace /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ COMP(1975, ibm5100, 0, 0, ibm5100, ibm5100, ibm5100_state, empty_init, "International Business Machines", "IBM 5100", MACHINE_NO_SOUND_HW) +COMP(1978, ibm5110, 0, 0, ibm5110, ibm5110, ibm5110_state, empty_init, "International Business Machines", "IBM 5110", 0) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ffe861bf97175..ca3126bd15c8b 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -19805,6 +19805,7 @@ ibm3153 // @source:ibm/ibm5100.cpp ibm5100 +ibm5110 @source:ibm/ibm5550.cpp ibm5550 //