mirror of
https://github.com/holub/mame
synced 2025-07-05 01:48:29 +03:00
New working systems
------------------- IBM 5110 [Christian Corti, Tom Stepleton]
This commit is contained in:
parent
37755dde5f
commit
2c56d783e9
@ -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 @@ public:
|
||||
, 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 @@ protected:
|
||||
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<palm_device> m_cpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<ibm5100_keyboard_device> m_kbd;
|
||||
|
||||
required_region_ptr_array<u16, 2> m_nxr;
|
||||
required_region_ptr<u8> m_j2;
|
||||
required_region_ptr_array<u16, 3> m_nxr;
|
||||
required_region_ptr<u8> 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<u16[]> 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<beep_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<u8 const>(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;
|
||||
}
|
||||
|
||||
u8 ibm5100_state::e2_sts_r()
|
||||
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::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_e2_ff ^= E2_PS;
|
||||
m_nxr_ff ^= NXR_PS;
|
||||
}
|
||||
|
||||
u8 ibm5100_state::f2_kbd_sts_r()
|
||||
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_nxr_ff ^= NXR_PS;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -19805,6 +19805,7 @@ ibm3153 //
|
||||
|
||||
@source:ibm/ibm5100.cpp
|
||||
ibm5100
|
||||
ibm5110
|
||||
|
||||
@source:ibm/ibm5550.cpp
|
||||
ibm5550 //
|
||||
|
Loading…
Reference in New Issue
Block a user