summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/rainbow.cpp
diff options
context:
space:
mode:
author Ryan Holtz <ryan.holtz@arrowheadgs.com>2019-11-07 17:41:52 +0100
committer Ryan Holtz <ryan.holtz@arrowheadgs.com>2019-11-07 17:42:56 +0100
commit07d757a2ed72d7793060773f48d6d029b5547ff6 (patch)
tree2dc34d2157280a4a1a01db509d6ad48341b172b3 /src/mame/drivers/rainbow.cpp
parent0b0dadd8359a6cb8093bb8892f74477504282a34 (diff)
-rainbow: Separated Model A and Model B to coexist without needing an #ifdef. [Ryan Holtz]
Diffstat (limited to 'src/mame/drivers/rainbow.cpp')
-rw-r--r--src/mame/drivers/rainbow.cpp612
1 files changed, 330 insertions, 282 deletions
diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp
index 627e08732ba..c90352dc918 100644
--- a/src/mame/drivers/rainbow.cpp
+++ b/src/mame/drivers/rainbow.cpp
@@ -7,7 +7,7 @@ Driver-in-progress by R. Belmont and Miodrag Milanovic.
Portions (2013 - 2018) by Karl-Ludwig Deisenhofer (Floppy, ClikClok RTC, NVRAM, DIPs, hard disk, Color Graphics).
Baud rate generator by AJR (2018) and Shattered (2016), keyboard & GDC fixes by Cracyc (June - Nov. 2016).
-To unlock floppy drives A-D compile with WORKAROUND_RAINBOW_B (prevents a side effect of ERROR 13).
+Model B implementation has a workaround prevents a side effect of ERROR 13 to unlock floppy drives A-D.
Native single sided 5.25" images with 80 tracks, 10 sectors are well tested (*.IMD / *.TD0=TeleDisk / *.IMG with 400 K).
VT180 images (184.320 Bytes) are very unreliable in CP/M - though a real machine can read them.
@@ -144,7 +144,7 @@ To obtain pixel exact graphics use 'Graphics Only' in Video Options and cmd.line
CURRENTY UNEMULATED
-------------------
(a) the serial printer on port B prints garbage. It is worth to mention that port B relies on XON/XOFF,
- while DTR_L (CTS B) means 'printer ready'. There is also a ROM patch in place (WORKAROUND macro)...
+ while DTR_L (CTS B) means 'printer ready'. There is also a ROM patch in place...
(b1) LOOPBACK circuit not emulated (used in startup tests).
@@ -349,6 +349,7 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
#include "machine/nvram.h"
#include "machine/ripple_counter.h"
#include "machine/timer.h"
+#include "machine/ram.h"
#include "machine/ds1315.h"
#include "emupal.h"
@@ -372,26 +373,7 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
// (Y2K) DS1315 unit only holds 2 digits, so Vincent Esser's freeware employs a windowing technique.
// While Suitable's DOS 3.10 accepts dates > 2000, don't take that for granted with software from the 80s.
-#ifdef ASSUME_MODEL_A_HARDWARE
- #define RTC_BASE 0xED000
-
- // Define standard and maximum RAM sizes (A model):
- #define MOTHERBOARD_RAM 0x0ffff // 64 K base RAM (100-A)
- #define END_OF_RAM 0xcffff // Very last byte (theretical; on 100-A) DO NOT CHANGE.
-
- // Pretend to emulate older RAM board (no NMI, also affects presence bit in 'system_parameter_r'):
- #define OLD_RAM_BOARD_PRESENT
-#else
- #define RTC_BASE 0xFC000 // (default configuration, also covers FE000+)
-// #define RTC_BASE 0xF4000 // (alternate configuration) - ClikClok V1.0 / CLIKF4.COM
-
- // DEC-100-B probes until a 'flaky' area is found (BOOT ROM around F400:0E04).
- // It is no longer possible to key in the RAM size from within the 100-B BIOS.
- #define MOTHERBOARD_RAM 0x1ffff // 128 K base RAM (100-B)
- #define END_OF_RAM 0xdffff // very last byte (100-B theoretical max.) DO NOT CHANGE.
-
- #define WORKAROUND_RAINBOW_B // work around DRIVE ERROR (tested on 100-B ROM only)
- #endif
+// Model B can have an RTC mapped at 0xF4000 instead - ClikClok V1.0 / CLIKF4.COM
// ----------------------------------------------------------------------------------------------
// * MHFU disabled by writing a _sensible_ value to port 0x10C (instead of port 0x0c)
@@ -466,10 +448,10 @@ static constexpr int COLOR_MONITOR = 0x02; // DEC recommendation. GWBASIC and mo
static constexpr int DUAL_MONITOR = 0x03; // Debugging, AutoCad, 'newer' freeware. Green is missing with unpatched software (for technical reasons)
static constexpr int AUTODETECT_MONITOR = 0x04; // Snoop palette, then choose best output.
-class rainbow_state : public driver_device
+class rainbow_base_state : public driver_device
{
public:
- rainbow_state(const machine_config &mconfig, device_type type, const char *tag) :
+ rainbow_base_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_inp1(*this, "W13"),
@@ -479,7 +461,6 @@ public:
m_inp5(*this, "DEC HARD DISK"), // DO NOT CHANGE ORDER
m_inp6(*this, "CORVUS HARD DISKS"), // DO NOT CHANGE ORDER
m_inp7(*this, "GRAPHICS OPTION"), // DO NOT CHANGE ORDER
- m_inp8(*this, "MEMORY PRESENT"), // DO NOT CHANGE ORDER
m_inp9(*this, "MONO MONITOR TYPE"),
m_inp10(*this, "J17"),
m_inp11(*this, "CLIKCLOK"),
@@ -490,6 +471,7 @@ public:
m_i8088(*this, "maincpu"),
m_z80(*this, "subcpu"),
+ m_ram(*this, "ram"),
m_fdc(*this, FD1793_TAG),
m_floppies(*this, FD1793_TAG ":%u", 0U),
@@ -508,9 +490,6 @@ public:
m_p_vol_ram(*this, "vol_ram"),
m_p_nvram(*this, "nvram"),
- m_shared(*this, "sh_ram"),
- m_ext_ram(*this, "ext_ram"),
-
m_rtc(*this, "rtc"),
m_hgdc(*this, "upd7220"), // GDC
@@ -522,13 +501,19 @@ public:
{
}
- void rainbow(machine_config &config);
+ void rainbow_base(machine_config &config);
protected:
virtual void machine_start() override;
+ virtual void machine_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-private:
+ void rainbow8088_base_map(address_map &map);
+ void rainbow8088_base_io(address_map &map);
+
+ DECLARE_READ8_MEMBER(ext_ram_r);
+
+ DECLARE_WRITE8_MEMBER(rtc_w);
DECLARE_READ8_MEMBER(read_video_ram_r);
DECLARE_WRITE_LINE_MEMBER(video_interrupt);
@@ -579,20 +564,12 @@ private:
DECLARE_READ8_MEMBER(z80_diskstatus_r);
DECLARE_WRITE8_MEMBER(z80_diskcontrol_w);
- DECLARE_READ8_MEMBER(system_parameter_r);
-
DECLARE_WRITE_LINE_MEMBER(kbd_tx);
DECLARE_WRITE_LINE_MEMBER(kbd_rxready_w);
DECLARE_WRITE_LINE_MEMBER(kbd_txready_w);
- DECLARE_WRITE_LINE_MEMBER(irq_hi_w);
-
DECLARE_READ8_MEMBER(rtc_reset);
DECLARE_READ8_MEMBER(rtc_enable);
- DECLARE_READ8_MEMBER(rtc_r);
- DECLARE_WRITE8_MEMBER(rtc_w);
-
- DECLARE_WRITE8_MEMBER(ext_ram_w);
DECLARE_WRITE_LINE_MEMBER(mpsc_irq);
DECLARE_WRITE8_MEMBER(comm_bitrate_w);
@@ -616,8 +593,6 @@ private:
DECLARE_WRITE16_MEMBER(vram_w);
DECLARE_WRITE_LINE_MEMBER(GDC_vblank_irq);
- void rainbow8088_io(address_map &map);
- void rainbow8088_map(address_map &map);
void rainbowz80_io(address_map &map);
void rainbowz80_mem(address_map &map);
void upd7220_map(address_map &map);
@@ -643,7 +618,6 @@ private:
required_ioport m_inp5;
required_ioport m_inp6;
required_ioport m_inp7;
- required_ioport m_inp8;
required_ioport m_inp9;
required_ioport m_inp10;
required_ioport m_inp11;
@@ -652,6 +626,7 @@ private:
required_device<rainbow_video_device> m_crtc;
required_device<cpu_device> m_i8088;
required_device<cpu_device> m_z80;
+ required_device<ram_device> m_ram;
required_device<fd1793_device> m_fdc;
required_device_array<floppy_connector, 4> m_floppies;
@@ -668,8 +643,6 @@ private:
required_shared_ptr<uint8_t> m_p_ram;
required_shared_ptr<uint8_t> m_p_vol_ram;
required_shared_ptr<uint8_t> m_p_nvram;
- required_shared_ptr<uint8_t> m_shared;
- required_shared_ptr<uint8_t> m_ext_ram;
optional_device<ds1315_device> m_rtc;
@@ -732,7 +705,6 @@ private:
uint8_t m_z80_mailbox, m_8088_mailbox;
void update_kbd_irq();
- virtual void machine_reset() override;
int m_present_drive;
floppy_image_device *m_floppy;
@@ -769,6 +741,50 @@ private:
const int comm_rates[16] = { 50,75,110,134,150,200,300,600,1200,1800,2000,2400,3600,4800,9600,19200 };
};
+class rainbow_modela_state : public rainbow_base_state
+{
+public:
+ rainbow_modela_state(const machine_config &mconfig, device_type type, const char *tag) :
+ rainbow_base_state(mconfig, type, tag)
+ {
+ }
+
+ void rainbow_modela(machine_config &config);
+
+private:
+ virtual void machine_reset() override;
+
+ void rainbow8088_map(address_map &map);
+ void rainbow8088_io(address_map &map);
+
+ DECLARE_WRITE8_MEMBER(ext_ram_w);
+ DECLARE_READ8_MEMBER(rtc_r);
+ DECLARE_WRITE_LINE_MEMBER(irq_hi_w);
+ DECLARE_READ8_MEMBER(system_parameter_r);
+};
+
+class rainbow_modelb_state : public rainbow_base_state
+{
+public:
+ rainbow_modelb_state(const machine_config &mconfig, device_type type, const char *tag) :
+ rainbow_base_state(mconfig, type, tag)
+ {
+ }
+
+ void rainbow_modelb(machine_config &config);
+
+private:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ void rainbow8088_map(address_map &map);
+ void rainbow8088_io(address_map &map);
+
+ DECLARE_WRITE8_MEMBER(ext_ram_w);
+ DECLARE_READ8_MEMBER(rtc_r);
+ DECLARE_WRITE_LINE_MEMBER(irq_hi_w);
+ DECLARE_READ8_MEMBER(system_parameter_r);
+};
// It * should be * OK to RESET the SCROLL_BUFFER and the COLOR_MAP (at least with WELL WRITTEN programs)
@@ -800,7 +816,7 @@ private:
m_gdc_mode_register |= GDC_MODE_ENABLE_VIDEO; \
logerror("\n** OPTION GRFX. RESET **\n");
-UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
+UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_base_state::hgdc_display_pixels )
{
if(m_inp7->read() == 0)
return;
@@ -853,7 +869,7 @@ UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
}
}
-FLOPPY_FORMATS_MEMBER(rainbow_state::floppy_formats)
+FLOPPY_FORMATS_MEMBER(rainbow_base_state::floppy_formats)
FLOPPY_RX50IMG_FORMAT,
FLOPPY_TD0_FORMAT,
FLOPPY_IMD_FORMAT,
@@ -868,7 +884,7 @@ static void rainbow_floppies(device_slot_interface &device)
device.option_add("525ssdd", FLOPPY_525_SSDD); // to read a single sided, (160K) PC-DOS 1 disk with MediaMaster
}
-void rainbow_state::machine_start()
+void rainbow_base_state::machine_start()
{
m_power_good = false; // Simulate AC_OK signal from power supply.
cmd_timer = timer_alloc(0);
@@ -894,8 +910,12 @@ void rainbow_state::machine_start()
save_item(NAME(m_kbd_rx_ready));
save_item(NAME(m_irq_high));
save_item(NAME(m_irq_mask));
+}
+
+void rainbow_modelb_state::machine_start()
+{
+ rainbow_base_state::machine_start();
-#ifdef WORKAROUND_RAINBOW_B
uint8_t *rom = memregion("maincpu")->base();
if (rom[0xf4000 + 0x3ffc] == 0x31) // 100-B (5.01) 0x35 would test for V5.05
{
@@ -908,14 +928,11 @@ void rainbow_state::machine_start()
rom[0xf4000 + 0x315E] = 0xe2;
rom[0xf4000 + 0x315F] = 0x02;
}
-#endif
}
-void rainbow_state::rainbow8088_map(address_map &map)
+void rainbow_base_state::rainbow8088_base_map(address_map &map)
{
map.unmap_value_high();
- map(0x00000, 0x0ffff).ram().share("sh_ram");
- map(0x10000, END_OF_RAM).ram().share("ext_ram").w(FUNC(rainbow_state::ext_ram_w));
// There is a 2212 (256 x 4 bit) NVRAM from 0xed000 to 0xed0ff (*)
// shadowed at $ec000 - $ecfff and from $ed100 - $edfff.
@@ -934,21 +951,48 @@ void rainbow_state::rainbow8088_map(address_map &map)
map(0xf0000, 0xfffff).rom();
}
-void rainbow_state::rainbow8088_io(address_map &map)
+void rainbow_modela_state::rainbow8088_map(address_map &map)
+{
+ rainbow8088_base_map(map);
+ map(0x00000, 0xcffff).rw(FUNC(rainbow_modela_state::ext_ram_r), FUNC(rainbow_modela_state::ext_ram_w));
+
+#ifdef RTC_ENABLED
+ // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-A' ***************************************
+ map(0xed000, 0xed000).r(FUNC(rainbow_modela_state::rtc_r));
+ map(0xed0fe, 0xed0ff).w(FUNC(rainbow_modela_state::rtc_w));
+ // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-A' ***************************************
+#endif
+}
+
+// DEC-100-B probes until a 'flaky' area is found (BOOT ROM around F400:0E04).
+// It is no longer possible to key in the RAM size from within the 100-B BIOS.
+void rainbow_modelb_state::rainbow8088_map(address_map &map)
+{
+ rainbow8088_base_map(map);
+ map(0x00000, 0xdffff).rw(FUNC(rainbow_modelb_state::ext_ram_r), FUNC(rainbow_modelb_state::ext_ram_w));
+
+#ifdef RTC_ENABLED
+ // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' ***************************************
+ // No address space needed ( -> IRQs must be disabled to block ROM accesses during reads ).
+ map(0xfc000, 0xfe104).r(FUNC(rainbow_modelb_state::rtc_r));
+ // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' ***************************************
+#endif
+}
+
+void rainbow_base_state::rainbow8088_base_io(address_map &map)
{
map.unmap_value_high();
map.global_mask(0x1ff);
- map(0x00, 0x00).rw(FUNC(rainbow_state::i8088_latch_r), FUNC(rainbow_state::i8088_latch_w));
- map(0x02, 0x02).rw(FUNC(rainbow_state::comm_control_r), FUNC(rainbow_state::comm_control_w)); // Communication status / control register (8088)
+ map(0x00, 0x00).rw(FUNC(rainbow_base_state::i8088_latch_r), FUNC(rainbow_base_state::i8088_latch_w));
+ map(0x02, 0x02).rw(FUNC(rainbow_base_state::comm_control_r), FUNC(rainbow_base_state::comm_control_w)); // Communication status / control register (8088)
map(0x04, 0x04).w(m_crtc, FUNC(rainbow_video_device::dc011_w));
- map(0x06, 0x06).w(FUNC(rainbow_state::comm_bitrate_w));
+ map(0x06, 0x06).w(FUNC(rainbow_base_state::comm_bitrate_w));
- map(0x08, 0x08).r(FUNC(rainbow_state::system_parameter_r));
- map(0x0a, 0x0a).rw(FUNC(rainbow_state::diagnostic_r), FUNC(rainbow_state::diagnostic_w));
+ map(0x0a, 0x0a).rw(FUNC(rainbow_base_state::diagnostic_r), FUNC(rainbow_base_state::diagnostic_w));
map(0x0c, 0x0c).select(0x100).w(m_crtc, FUNC(rainbow_video_device::dc012_w));
- map(0x0e, 0x0e).w(FUNC(rainbow_state::printer_bitrate_w));
+ map(0x0e, 0x0e).w(FUNC(rainbow_base_state::printer_bitrate_w));
map(0x10, 0x11).rw(m_kbd8251, FUNC(i8251_device::read), FUNC(i8251_device::write));
@@ -964,7 +1008,7 @@ void rainbow_state::rainbow8088_io(address_map &map)
// Corvus B/H harddisk controller (incompatible with EXT.COMM OPTION):
map(0x20, 0x20).rw(m_corvus_hdc, FUNC(corvus_hdc_device::read), FUNC(corvus_hdc_device::write));
- map(0x21, 0x21).r(FUNC(rainbow_state::corvus_status_r));
+ map(0x21, 0x21).r(FUNC(rainbow_base_state::corvus_status_r));
// ===========================================================
// 0x30 -> 0x3f ***** Option Select 3
@@ -979,15 +1023,15 @@ void rainbow_state::rainbow8088_io(address_map &map)
// * Color graphics option (NEC upd7220 GDC plus external hw.). See Programmer's Reference AA-AE36A-TV.
// Either 384 x 240 x 16 or 800 x 240 x 4 colors (out of 4096). 8 x 64 K video RAM.
// (Write Buffer, Pattern Register/Multiplier, ALU/PS, Color Map, readback and offset/scroll hardware):
- map(0x50, 0x57).rw(FUNC(rainbow_state::GDC_EXTRA_REGISTER_r), FUNC(rainbow_state::GDC_EXTRA_REGISTER_w));
+ map(0x50, 0x57).rw(FUNC(rainbow_base_state::GDC_EXTRA_REGISTER_r), FUNC(rainbow_base_state::GDC_EXTRA_REGISTER_w));
// ===========================================================
// 0x60 -> 0x6f ***** EXTENDED COMM. OPTION / Option Select 2.
// ===========================================================
// 0x60 -> 0x6f ***** RD51 HD. CONTROLLER / Option Select 2.
map(0x60, 0x67).rw(m_hdc, FUNC(wd2010_device::read), FUNC(wd2010_device::write)).mirror(0x100);
- map(0x68, 0x68).rw(FUNC(rainbow_state::hd_status_68_r), FUNC(rainbow_state::hd_status_68_w));
- map(0x69, 0x69).r(FUNC(rainbow_state::hd_status_69_r));
+ map(0x68, 0x68).rw(FUNC(rainbow_base_state::hd_status_68_r), FUNC(rainbow_base_state::hd_status_68_w));
+ map(0x69, 0x69).r(FUNC(rainbow_base_state::hd_status_69_r));
// ===========================================================
// THE RD51 CONTROLLER: WD1010AL - 00 (WDC '83)
// + 2 K x 8 SRAM (SY2128-4 or Japan 8328) 21-17872-01
@@ -1025,27 +1069,39 @@ void rainbow_state::rainbow8088_io(address_map &map)
// 0x10c -> (MHFU disable register handled by 0x0c + select())
}
-void rainbow_state::rainbowz80_mem(address_map &map)
+void rainbow_modela_state::rainbow8088_io(address_map &map)
+{
+ rainbow_base_state::rainbow8088_base_io(map);
+ map(0x08, 0x08).r(FUNC(rainbow_modela_state::system_parameter_r));
+}
+
+void rainbow_modelb_state::rainbow8088_io(address_map &map)
+{
+ rainbow_base_state::rainbow8088_base_io(map);
+ map(0x08, 0x08).r(FUNC(rainbow_modelb_state::system_parameter_r));
+}
+
+void rainbow_base_state::rainbowz80_mem(address_map &map)
{
map.unmap_value_high();
- map(0x0000, 0xffff).rw(FUNC(rainbow_state::share_z80_r), FUNC(rainbow_state::share_z80_w));
+ map(0x0000, 0xffff).rw(FUNC(rainbow_base_state::share_z80_r), FUNC(rainbow_base_state::share_z80_w));
}
-void rainbow_state::rainbowz80_io(address_map &map)
+void rainbow_base_state::rainbowz80_io(address_map &map)
{
map.unmap_value_high();
map.global_mask(0xff);
- map(0x00, 0x00).rw(FUNC(rainbow_state::z80_latch_r), FUNC(rainbow_state::z80_latch_w));
- map(0x20, 0x20).rw(FUNC(rainbow_state::z80_generalstat_r), FUNC(rainbow_state::z80_diskdiag_read_w)); // read to port 0x20 used by MS-DOS 2.x diskette loader.
- map(0x21, 0x21).rw(FUNC(rainbow_state::z80_generalstat_r), FUNC(rainbow_state::z80_diskdiag_write_w));
- map(0x40, 0x40).rw(FUNC(rainbow_state::z80_diskstatus_r), FUNC(rainbow_state::z80_diskcontrol_w));
+ map(0x00, 0x00).rw(FUNC(rainbow_base_state::z80_latch_r), FUNC(rainbow_base_state::z80_latch_w));
+ map(0x20, 0x20).rw(FUNC(rainbow_base_state::z80_generalstat_r), FUNC(rainbow_base_state::z80_diskdiag_read_w)); // read to port 0x20 used by MS-DOS 2.x diskette loader.
+ map(0x21, 0x21).rw(FUNC(rainbow_base_state::z80_generalstat_r), FUNC(rainbow_base_state::z80_diskdiag_write_w));
+ map(0x40, 0x40).rw(FUNC(rainbow_base_state::z80_diskstatus_r), FUNC(rainbow_base_state::z80_diskcontrol_w));
map(0x60, 0x63).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write));
// Z80 I/O shadow area > $80
- map(0x80, 0x80).rw(FUNC(rainbow_state::z80_latch_r), FUNC(rainbow_state::z80_latch_w));
- map(0xA0, 0xA0).rw(FUNC(rainbow_state::z80_generalstat_r), FUNC(rainbow_state::z80_diskdiag_read_w)); // read to port 0x20 used by MS-DOS 2.x diskette loader.
- map(0xA1, 0xA1).rw(FUNC(rainbow_state::z80_generalstat_r), FUNC(rainbow_state::z80_diskdiag_write_w));
- map(0xC0, 0xC0).rw(FUNC(rainbow_state::z80_diskstatus_r), FUNC(rainbow_state::z80_diskcontrol_w));
+ map(0x80, 0x80).rw(FUNC(rainbow_base_state::z80_latch_r), FUNC(rainbow_base_state::z80_latch_w));
+ map(0xA0, 0xA0).rw(FUNC(rainbow_base_state::z80_generalstat_r), FUNC(rainbow_base_state::z80_diskdiag_read_w)); // read to port 0x20 used by MS-DOS 2.x diskette loader.
+ map(0xA1, 0xA1).rw(FUNC(rainbow_base_state::z80_generalstat_r), FUNC(rainbow_base_state::z80_diskdiag_write_w));
+ map(0xC0, 0xC0).rw(FUNC(rainbow_base_state::z80_diskstatus_r), FUNC(rainbow_base_state::z80_diskcontrol_w));
map(0xE0, 0xE3).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write));
}
@@ -1060,23 +1116,7 @@ static INPUT_PORTS_START(rainbow100b_in)
PORT_DIPSETTING(0x02, "GREEN (VR201-B)")
PORT_DIPSETTING(0x03, "AMBER (VR201-C)")
- // MEMORY, FLOPPY, BUNDLE, GRAPHICS affect 'system_parameter_r':
- PORT_START("MEMORY PRESENT")
- PORT_DIPNAME(0xF0000, 0x20000, "MEMORY PRESENT")
- PORT_DIPSETTING(0x10000, "64 K (MINIMUM ON 100-A)") // see MOTHERBOARD_RAM
- PORT_DIPSETTING(0x20000, "128 K (MINIMUM ON 100-B)")
- PORT_DIPSETTING(0x30000, "192 K (w. MEMORY OPTION)")
- PORT_DIPSETTING(0x40000, "256 K (w. MEMORY OPTION)")
- PORT_DIPSETTING(0x50000, "320 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0x60000, "384 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0x70000, "448 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0x80000, "512 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0x90000, "576 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0xA0000, "640 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0xB0000, "704 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0xC0000, "768 K (100-B MEMORY OPTION)")
- PORT_DIPSETTING(0xD0000, "832 K (100-B MEMORY OPTION)") // see END_OF_RAM
- PORT_DIPSETTING(0xE0000, "896 K (100-B MAX. MEMORY)")
+ // FLOPPY, BUNDLE, GRAPHICS affect 'system_parameter_r':
// EXT.COMM.card -or- RD51 HD. controller (marketed later).
PORT_START("DEC HARD DISK") // BUNDLE_OPTION
@@ -1139,63 +1179,12 @@ static INPUT_PORTS_START(rainbow100b_in)
PORT_DIPSETTING(0x03, "DUAL MONITOR (SCREEN 1: TEXT; SCREEN 2: R-G-B)")
INPUT_PORTS_END
-void rainbow_state::machine_reset()
+void rainbow_base_state::machine_reset()
{
// 'F3' (in partial emulation) here replaces 'CTRL-SETUP' (soft reboot on an original Rainbow)
// FIXME: BIOS reports error 19 when CTRL-SETUP is pressed (Z80 or flags aren't fully reset then?)
popmessage("Reset");
- // Configure RAM
- address_space &program = m_i8088->space(AS_PROGRAM);
- uint32_t unmap_start = m_inp8->read();
-
- // Verify RAM size matches hardware (DIP switches)
-
-#ifdef ASSUME_RAINBOW_A_HARDWARE
- logerror("*** RAINBOW A MODEL ASSUMED (64 - 832 K RAM).\n");
- if (unmap_start > 0xD0000)
- {
- unmap_start = 0xD0000; // hardware limit 832 K (possibly as low as 256 K) [?]
- logerror("WARNING: 896 K is not a valid memory configuration on Rainbow 100 A!\n");
- }
-
- uint32_t check = (unmap_start >> 16)-1; // guess.
- uint8_t nvram_location = m_p_nvram[0x84]; // location not verified yet. DMT RAM check tests offset $84 !
-
- #ifdef RTC_ENABLED
- // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-A' ***************************************
- program.install_read_handler(RTC_BASE, RTC_BASE, read8_delegate(*this, FUNC(rainbow_state::rtc_r)));
- program.install_write_handler(RTC_BASE + 0xFE, RTC_BASE + 0xFF, write8_delegate(*this, FUNC(rainbow_state::rtc_w)));
- // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-A' ***************************************
- #endif
-
-#else
- logerror("*** RAINBOW B MODEL ASSUMED (128 - 896 K RAM)\n");
- if (unmap_start < 0x20000)
- {
- unmap_start = 0x20000; // 128 K minimum
- logerror("WARNING: 64 K is not a valid memory size on Rainbow 100-B!\n");
- }
-
- uint32_t check = (unmap_start >> 16) - 2;
- uint8_t nvram_location = m_p_nvram[0xdb];
-
- #ifdef RTC_ENABLED
- // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' ***************************************
- // No address space needed ( -> IRQs must be disabled to block ROM accesses during reads ).
- program.install_read_handler(RTC_BASE, RTC_BASE + 0x2104, read8_delegate(*this, FUNC(rainbow_state::rtc_r)));
- // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' ***************************************
- #endif
-#endif
- if (check != nvram_location)
- logerror("NOTE: RAM configuration does not match NVRAM.\nUNMAP_START = %05x NVRAM VALUE = %02x SHOULD BE: %02x\n", unmap_start, nvram_location, check);
-
- if (END_OF_RAM > unmap_start)
- {
- logerror("Unmapping from %x to %x\n",unmap_start, END_OF_RAM);
- program.unmap_readwrite(unmap_start, END_OF_RAM);
- }
-
m_crtc->MHFU(MHFU_RESET_and_DISABLE);
m_rtc->chip_reset(); // * Reset RTC to a defined state *
@@ -1206,8 +1195,8 @@ void rainbow_state::machine_reset()
{
// Install 8088 read / write handler
io.unmap_readwrite(0x60, 0x60);
- io.install_read_handler(0x60, 0x60, read8_delegate(*this, FUNC(rainbow_state::hd_status_60_r)));
- io.install_write_handler(0x60, 0x60, write8_delegate(*this, FUNC(rainbow_state::hd_status_60_w)));
+ io.install_read_handler(0x60, 0x60, read8_delegate(*this, FUNC(rainbow_base_state::hd_status_60_r)));
+ io.install_write_handler(0x60, 0x60, write8_delegate(*this, FUNC(rainbow_base_state::hd_status_60_w)));
hdc_reset();
m_hdc_drive_ready = true;
@@ -1294,8 +1283,20 @@ void rainbow_state::machine_reset()
output().set_value("led_hold", 0); // led11
}
+void rainbow_modela_state::machine_reset()
+{
+ rainbow_base_state::machine_reset();
+ logerror("*** RAINBOW A MODEL ASSUMED (64 - 832 K RAM).\n");
+}
+
+void rainbow_modelb_state::machine_reset()
+{
+ rainbow_base_state::machine_reset();
+ logerror("*** RAINBOW B MODEL ASSUMED (128 - 896 K RAM)\n");
+}
+
// Simulate AC_OK signal (power good) and RESET after ~ 108 ms.
-void rainbow_state::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
+void rainbow_base_state::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
{
switch (tid)
{
@@ -1331,7 +1332,7 @@ void rainbow_state::device_timer(emu_timer &timer, device_timer_id tid, int para
} // switch (timer ID)
}
-uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+uint32_t rainbow_base_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
static int old_monitor;
@@ -1366,7 +1367,7 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1
}
// Interrupt handling and arbitration. See 3.1.3.8 OF PC-100 spec.
-void rainbow_state::update_8088_irqs()
+void rainbow_base_state::update_8088_irqs()
{
if (m_irq_mask != 0)
{
@@ -1386,13 +1387,13 @@ void rainbow_state::update_8088_irqs()
}
-void rainbow_state::raise_8088_irq(int ref)
+void rainbow_base_state::raise_8088_irq(int ref)
{
m_irq_mask |= (1 << ref);
update_8088_irqs();
}
-void rainbow_state::lower_8088_irq(int ref)
+void rainbow_base_state::lower_8088_irq(int ref)
{
m_irq_mask &= ~(1 << ref);
update_8088_irqs();
@@ -1400,7 +1401,7 @@ void rainbow_state::lower_8088_irq(int ref)
// IRQ service for 7201 (commm / printer)
-void rainbow_state::update_mpsc_irq()
+void rainbow_base_state::update_mpsc_irq()
{
if (m_mpsc_irq == 0)
lower_8088_irq(IRQ_COMM_PTR_INTR_L);
@@ -1408,14 +1409,14 @@ void rainbow_state::update_mpsc_irq()
raise_8088_irq(IRQ_COMM_PTR_INTR_L);
}
-WRITE_LINE_MEMBER(rainbow_state::mpsc_irq)
+WRITE_LINE_MEMBER(rainbow_base_state::mpsc_irq)
{
m_mpsc_irq = state;
update_mpsc_irq();
}
// PORT 0x06 : Communication bit rates (see page 21 of PC 100 SPEC)
-WRITE8_MEMBER(rainbow_state::comm_bitrate_w)
+WRITE8_MEMBER(rainbow_base_state::comm_bitrate_w)
{
m_dbrg->str_w(data & 0x0f); // PDF is wrong, low nibble is RECEIVE clock (verified in SETUP).
logerror("\n(COMM.) receive bitrate = %d ($%02x)\n", comm_rates[data & 0x0f] , data & 0x0f);
@@ -1425,7 +1426,7 @@ WRITE8_MEMBER(rainbow_state::comm_bitrate_w)
}
// PORT 0x0e : Printer bit rates
-WRITE8_MEMBER(rainbow_state::printer_bitrate_w)
+WRITE8_MEMBER(rainbow_base_state::printer_bitrate_w)
{
m_printer_bitrate = data & 7;
// bits 0 - 2 = 0: nominally 75 bps, actually 75.35 bps
@@ -1443,17 +1444,17 @@ WRITE8_MEMBER(rainbow_state::printer_bitrate_w)
logerror(" - CLOCK (0 = internal): %02x", data & 8);
}
-WRITE_LINE_MEMBER(rainbow_state::dbrg_fr_w)
+WRITE_LINE_MEMBER(rainbow_base_state::dbrg_fr_w)
{
m_mpsc->rxca_w(state);
}
-WRITE_LINE_MEMBER(rainbow_state::dbrg_ft_w)
+WRITE_LINE_MEMBER(rainbow_base_state::dbrg_ft_w)
{
m_mpsc->txca_w(state);
}
-WRITE8_MEMBER(rainbow_state::bitrate_counter_w)
+WRITE8_MEMBER(rainbow_base_state::bitrate_counter_w)
{
bool prt_rxtxc = BIT(data, 7 - m_printer_bitrate);
bool kbd_rxtxc = BIT(data, 1);
@@ -1470,20 +1471,20 @@ WRITE8_MEMBER(rainbow_state::bitrate_counter_w)
// Shared memory is contended by refresh, concurrent
// 8088 accesses and arbitration logic (DMA).
-READ8_MEMBER(rainbow_state::share_z80_r)
+READ8_MEMBER(rainbow_base_state::share_z80_r)
{
if (m_zflip)
{
if (offset < 0x8000)
{
- return m_shared[offset + 0x8000];
+ return m_ram->read(offset + 0x8000);
}
else if (offset < 0x8800)
{
return m_z80_private[offset & 0x7ff]; // SRAM
}
- return m_shared[offset ^ 0x8000];
+ return m_ram->read(offset ^ 0x8000);
}
else
{
@@ -1492,17 +1493,17 @@ READ8_MEMBER(rainbow_state::share_z80_r)
return m_z80_private[offset]; // SRAM
}
- return m_shared[offset];
+ return m_ram->read(offset);
}
}
-WRITE8_MEMBER(rainbow_state::share_z80_w)
+WRITE8_MEMBER(rainbow_base_state::share_z80_w)
{
if (m_zflip)
{
if (offset < 0x8000)
{
- m_shared[offset + 0x8000] = data;
+ m_ram->write(offset + 0x8000, data);
return; // [!]
}
else if (offset < 0x8800)
@@ -1511,28 +1512,40 @@ WRITE8_MEMBER(rainbow_state::share_z80_w)
return; // [!]
}
- m_shared[offset ^ 0x8000] = data;
+ m_ram->write(offset ^ 0x8000, data);
}
else
{
if (offset < 0x800)
m_z80_private[offset] = data; // SRAM
else
- m_shared[offset] = data;
+ m_ram->write(offset, data);
}
return;
}
+READ8_MEMBER(rainbow_base_state::ext_ram_r)
+{
+ if (offset < m_ram->size())
+ return m_ram->read(offset);
+ return 0;
+}
+
+WRITE8_MEMBER(rainbow_modela_state::ext_ram_w)
+{
+ if (offset < m_ram->size())
+ m_ram->write(offset, data);
+}
+
// NMI logic (parity test)
-WRITE8_MEMBER(rainbow_state::ext_ram_w)
+WRITE8_MEMBER(rainbow_modelb_state::ext_ram_w)
{
- m_ext_ram[offset] = data;
+ if (offset < m_ram->size())
+ m_ram->write(offset, data);
-#ifndef OLD_RAM_BOARD_PRESENT
if (m_diagnostic & 0x08)
- if ((offset + 0x10000) >= (MOTHERBOARD_RAM + 1))
+ if (offset >= 0x10000)
m_i8088->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
-#endif
}
// ------------------------ClikClok (for 100-A; DS1315) ------------------------------------------
@@ -1540,7 +1553,7 @@ WRITE8_MEMBER(rainbow_state::ext_ram_w)
// Requires a short program from the Suitable Solutions ClikClok distribution disk (CLIKA.COM)
// - also needed to set time/date (*). Reads $ed000, writes ed0fe/ed0ff.
-WRITE8_MEMBER(rainbow_state::rtc_w)
+WRITE8_MEMBER(rainbow_base_state::rtc_w)
{
if (m_inp11->read() == 0x01) // if enabled...
{
@@ -1567,19 +1580,28 @@ WRITE8_MEMBER(rainbow_state::rtc_w)
// ------------------------ClikClok (for 100-B; DS1315) ------------------------------------------------
// Add-on hardware, occupies one of the EPROM sockets of the 100-B. TODO: check address decoders on board
// Requires CLIKCLOK.COM or RBCLIK21.COM (freeware from Latrobe). Uses FC000/FE000.
-READ8_MEMBER(rainbow_state::rtc_r)
+READ8_MEMBER(rainbow_modela_state::rtc_r)
{
if (m_inp11->read() == 0x01) // if enabled...
{
- switch (offset)
+ if (offset == 0x00) // read time/date from 0xED000 (ClikClok for 100-A)
{
-#ifdef ASSUME_RAINBOW_A_HARDWARE
- case 0x00: // read time/date from 0xED000 (ClikClok for 100-A)
if (m_rtc->chip_enable())
return m_rtc->read_data() & 0x01;
else
m_rtc->chip_reset();
-#else
+ }
+ }
+
+ return m_p_vol_ram[offset]; // return volatile RAM
+}
+
+READ8_MEMBER(rainbow_modelb_state::rtc_r)
+{
+ if (m_inp11->read() == 0x01) // if enabled...
+ {
+ switch (offset)
+ {
// Transfer data to DS1315 (data = offset):
case 0x0000: // RTC_WRITE_DATA_0 0xFC000
case 0x2000: // RTC_WRITE_DATA_0 0xFE000 (MIRROR)
@@ -1612,23 +1634,18 @@ READ8_MEMBER(rainbow_state::rtc_r)
case 0x2104: // 0xFE104 (MIRROR)
m_rtc->chip_reset();
break;
-#endif
}
}
-#ifdef ASSUME_RAINBOW_A_HARDWARE
- return m_p_vol_ram[offset]; // return volatile RAM
-#else
uint8_t *rom = memregion("maincpu")->base();
- return rom[RTC_BASE + offset]; // return ROM
-#endif
+ return rom[0xfc000 + offset]; // return ROM
}
// ------------------------/ ClikClok (for model B; DS1315) -------------------------------
// --------------------------------- Corvus (B/H) -----------------------------------------
// PORT 0x21 : Corvus status register (ready / direction)
-READ8_MEMBER(rainbow_state::corvus_status_r)
+READ8_MEMBER(rainbow_base_state::corvus_status_r)
{
if (m_inp6->read() == 0) // Corvus controller
{
@@ -1652,7 +1669,7 @@ READ8_MEMBER(rainbow_state::corvus_status_r)
// ---------------------------- RD51 HARD DISK CONTROLLER ----------------------------------
static const int SECTOR_SIZES[4] = { 256, 512, 1024, 128 };
-void rainbow_state::hdc_reset()
+void rainbow_base_state::hdc_reset()
{
// logerror(">> HARD DISC CONTROLLER RESET <<\n");
m_hdc->reset();
@@ -1672,7 +1689,7 @@ void rainbow_state::hdc_reset()
// Return 'hard_disk_file' object for harddisk 1 (fixed).
// < nullptr if geometry is insane or other errors occured >
-hard_disk_file *rainbow_state::rainbow_hdc_file(int drv)
+hard_disk_file *rainbow_base_state::rainbow_hdc_file(int drv)
{
m_hdc_drive_ready = false;
@@ -1734,7 +1751,7 @@ static uint32_t get_and_print_lbasector(device_t *device, hard_disk_info *info,
}
// READ SECTOR (on BCS 1 -> 0 transition)
-WRITE_LINE_MEMBER(rainbow_state::hdc_read_sector)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_read_sector)
{
static int last_state;
int read_status = 1;
@@ -1802,7 +1819,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_read_sector)
// ...IF WRITE_GATE (WG) TRANSITS FROM 1 -> 0
// NO PROVISIONS for sector sizes != 512 or MULTIPLE DRIVES (> 0) !!!
-WRITE_LINE_MEMBER(rainbow_state::hdc_write_sector)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_write_sector)
{
int success = 0;
static int wg_last;
@@ -1850,7 +1867,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_write_sector)
// 99 = SUCCESS : SECTOR WRITTEN
// * RELIES * ON THE FACT THAT THERE WILL BE NO MULTI SECTOR TRANSFERS (!)
-int rainbow_state::do_write_sector()
+int rainbow_base_state::do_write_sector()
{
int feedback = 0; // no error
output().set_value("led1", 0); // ON
@@ -1899,7 +1916,7 @@ int rainbow_state::do_write_sector()
}
-READ8_MEMBER(rainbow_state::hd_status_60_r)
+READ8_MEMBER(rainbow_base_state::hd_status_60_r)
{
int data = m_hdc_buffer[m_hdc_buf_offset];
//logerror("HARD DISK DISK BUFFER: READ offset %04x | data = %02x\n", m_hdc_buf_offset, data); // ! DO NOT CHANGE ORDER !
@@ -1913,7 +1930,7 @@ READ8_MEMBER(rainbow_state::hd_status_60_r)
return data;
}
-WRITE8_MEMBER(rainbow_state::hd_status_60_w)
+WRITE8_MEMBER(rainbow_base_state::hd_status_60_w)
{
//logerror("HARD DISK BUFFER: WRITE offset %04x | data = %02x\n", m_hdc_buf_offset, data);
@@ -1935,7 +1952,7 @@ WRITE8_MEMBER(rainbow_state::hd_status_60_w)
// - 3 hard-wired controller module identification bits.
// - signals from the WD1010 chip,
// - disk drive(latched status signals)
-READ8_MEMBER(rainbow_state::hd_status_68_r)
+READ8_MEMBER(rainbow_base_state::hd_status_68_r)
{
// (*) Bits 5-7 : HARD WIRED IDENTIFICATION BITS, bits 5+7 = 1 and bit 6 = 0 (= 101 f?r RD51 module)
int data = 0xe0; // 111 gives DRIVE NOT READY (when W is pressed on boot screen)
@@ -1981,7 +1998,7 @@ READ8_MEMBER(rainbow_state::hd_status_68_r)
// 68 (WRITE): Secondary Command Registers (68H) - - "write-only register for commands"
// - see TABLE 4.8 (4-24)
-WRITE8_MEMBER(rainbow_state::hd_status_68_w)
+WRITE8_MEMBER(rainbow_base_state::hd_status_68_w)
{
// Bit 4-7 : --- not used / reserved
@@ -2041,7 +2058,7 @@ inhibited.
7 Track 0 - The disk drive sets this bit high (1) when the R/W heads are
positioned over cylinder 0 (the data track furthest away from the spindle).
*/
-READ8_MEMBER(rainbow_state::hd_status_69_r)
+READ8_MEMBER(rainbow_base_state::hd_status_69_r)
{
int hs = m_hdc->read(0x06) & (1 + 2 + 4); // SDH bits 0-2 = HEAD #
// logerror("(x69 READ) %i = HEAD SELECT WD1010\n", hs);
@@ -2071,7 +2088,7 @@ READ8_MEMBER(rainbow_state::hd_status_69_r)
}
// TREAT SIGNALS FROM / TO CONTROLLER
-WRITE_LINE_MEMBER(rainbow_state::hdc_step)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_step)
{
m_hdc_step_latch = true;
@@ -2079,23 +2096,23 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_step)
switch_off_timer->adjust(attotime::from_msec(500));
}
-WRITE_LINE_MEMBER(rainbow_state::hdc_direction)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_direction)
{
m_hdc_direction = state; // (0 = OUT)
}
-READ_LINE_MEMBER(rainbow_state::hdc_drive_ready)
+READ_LINE_MEMBER(rainbow_base_state::hdc_drive_ready)
{
return m_hdc_drive_ready;
}
-READ_LINE_MEMBER(rainbow_state::hdc_write_fault)
+READ_LINE_MEMBER(rainbow_base_state::hdc_write_fault)
{
return m_hdc_write_fault;
}
// Buffer counter reset when BCR goes from 0 -> 1
-WRITE_LINE_MEMBER(rainbow_state::hdc_bcr)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_bcr)
{
static int bcr_state;
if (bcr_state == 0 && state == 1)
@@ -2103,7 +2120,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_bcr)
bcr_state = state;
}
-void rainbow_state::hdc_buffer_counter_reset()
+void rainbow_base_state::hdc_buffer_counter_reset()
{
m_hdc->buffer_ready(false);
m_hdc_buf_offset = 0;
@@ -2115,7 +2132,7 @@ void rainbow_state::hdc_buffer_counter_reset()
// On a WRITE / FORMAT command, signal goes high when the WD1010
// chip is READY TO ACCESS the information in the sector buffer.
-WRITE_LINE_MEMBER(rainbow_state::hdc_bdrq)
+WRITE_LINE_MEMBER(rainbow_base_state::hdc_bdrq)
{
static int old_state;
// logerror("BDRQ - BUFFER DATA REQUEST OBTAINED: %u\n", state);
@@ -2133,7 +2150,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_bdrq)
// IRQ service for both RD51 and COMM. OPTION
-void rainbow_state::update_bundle_irq()
+void rainbow_base_state::update_bundle_irq()
{
if (m_bdl_irq == 0)
{
@@ -2148,14 +2165,14 @@ void rainbow_state::update_bundle_irq()
}
}
-WRITE_LINE_MEMBER(rainbow_state::bundle_irq)
+WRITE_LINE_MEMBER(rainbow_base_state::bundle_irq)
{
m_bdl_irq = state;
update_bundle_irq();
}
-READ8_MEMBER(rainbow_state::system_parameter_r)
+READ8_MEMBER(rainbow_modela_state::system_parameter_r)
{
/* Info about option boards is in bits 0 - 3:
SYSTEM PARAMETER INFORMATION: see AA-P308A-TV page 92 section 14.0
@@ -2171,12 +2188,27 @@ READ8_MEMBER(rainbow_state::system_parameter_r)
*/
return ((m_inp5->read() == 1 ? 0 : 1) |
(m_inp7->read() == 1 ? 0 : 4) | // Floppy is always present (bit 1 zero)
-#ifdef OLD_RAM_BOARD_PRESENT
- (m_inp8->read() > MOTHERBOARD_RAM ? 0 : 8) |
-#else
- 8 | // unverified
-#endif
- 16 | 32 | 64 | 128); // unverified
+ (m_ram->size() > 0x10000 ? 0 : 8) |
+ 0xf0); // unverified
+}
+
+READ8_MEMBER(rainbow_modelb_state::system_parameter_r)
+{
+ /* Info about option boards is in bits 0 - 3:
+ SYSTEM PARAMETER INFORMATION: see AA-P308A-TV page 92 section 14.0
+ Bundle card (1) | Floppy (2) | Graphics (4) | Memory option (8)
+ 0 1 2 3 4 5 6 7
+ B F G M
+ (bit SET means NOT present; 4-7 reserved )
+
+ B : no separation between the 2 available 'bundle cards' (HD controller / COMM.OPTION) ?
+
+ M : old RAM extension (128 / 192 K ?) detected with OPTION_PRESENT bit, newer models 'by presence'.
+ BIOS uses a seperate IRQ vector for RAM board detection (at least on a 100-B).
+ */
+ return ((m_inp5->read() == 1 ? 0 : 1) |
+ (m_inp7->read() == 1 ? 0 : 4) | // Floppy is always present (bit 1 zero)
+ 0xf8); // unverified
}
// [02] COMMUNICATIONS STATUS REGISTER - PAGE 154 (**** READ **** )
@@ -2188,7 +2220,7 @@ READ8_MEMBER(rainbow_state::system_parameter_r)
// 2 COMM DSR (reflects status of DSR at COMM)
// 3 COMM CTS (reflects status of CTS at COMM)
// 4 COMM RLSD (receive line signal detect at COMM; also connected to DCDA on MPSC)
-READ8_MEMBER(rainbow_state::comm_control_r)
+READ8_MEMBER(rainbow_base_state::comm_control_r)
{
bool is_mhfu_enabled = false;
if (m_power_good)
@@ -2211,7 +2243,7 @@ READ8_MEMBER(rainbow_state::comm_control_r)
// 1 COMM SRTS H (controls secondary request to send line of COMM)
// 2 COMM DTR L (controls terminal ready line of COMM)
// 3 COMM RTS (controls request to send line of COMM)
-WRITE8_MEMBER(rainbow_state::comm_control_w)
+WRITE8_MEMBER(rainbow_base_state::comm_control_w)
{
logerror("%02x to COMM.CONTROL REGISTER ", data);
@@ -2233,7 +2265,7 @@ WRITE8_MEMBER(rainbow_state::comm_control_w)
// 8088 writes to port 0x00 (interrupts Z80)
// See page 133 (4-34)
-WRITE8_MEMBER(rainbow_state::i8088_latch_w)
+WRITE8_MEMBER(rainbow_base_state::i8088_latch_w)
{
// logerror("%02x to Z80 mailbox\n", data);
@@ -2248,7 +2280,7 @@ WRITE8_MEMBER(rainbow_state::i8088_latch_w)
// Z80 reads port 0x00
// See page 134 (4-35)
-READ8_MEMBER(rainbow_state::z80_latch_r)
+READ8_MEMBER(rainbow_base_state::z80_latch_r)
{
// logerror("Read %02x from Z80 mailbox\n", m_z80_mailbox);
m_z80->set_input_line(0, CLEAR_LINE);
@@ -2259,7 +2291,7 @@ READ8_MEMBER(rainbow_state::z80_latch_r)
// Z80 writes to port 0x00 (interrupts 8088)
// See page 134 (4-35)
-WRITE8_MEMBER(rainbow_state::z80_latch_w)
+WRITE8_MEMBER(rainbow_base_state::z80_latch_w)
{
// logerror("%02x to 8088 mailbox\n", data);
raise_8088_irq(IRQ_8088_MAILBOX);
@@ -2269,7 +2301,7 @@ WRITE8_MEMBER(rainbow_state::z80_latch_w)
}
// 8088 reads port 0x00. See page 133 (4-34)
-READ8_MEMBER(rainbow_state::i8088_latch_r)
+READ8_MEMBER(rainbow_base_state::i8088_latch_r)
{
// logerror("Read %02x from 8088 mailbox\n", m_8088_mailbox);
lower_8088_irq(IRQ_8088_MAILBOX);
@@ -2279,13 +2311,13 @@ READ8_MEMBER(rainbow_state::i8088_latch_r)
}
// (Z80) : WRITE to 0x20
-WRITE8_MEMBER(rainbow_state::z80_diskdiag_read_w)
+WRITE8_MEMBER(rainbow_base_state::z80_diskdiag_read_w)
{
m_zflip = true; // "a write to 20H will _SET_ ZFLIP"
}
// (Z80) : PORT 21H * WRITE *
-WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w)
+WRITE8_MEMBER(rainbow_base_state::z80_diskdiag_write_w)
{
/* Z80 LEDs:
4 5 6 <- bit #
@@ -2300,7 +2332,7 @@ WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w)
}
// (Z80) : PORT 20H / 21H _READ_
-READ8_MEMBER(rainbow_state::z80_generalstat_r)
+READ8_MEMBER(rainbow_base_state::z80_generalstat_r)
{
/*
General / diag.status register Z80 / see page 157 (table 4-18).
@@ -2366,7 +2398,7 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r)
// (Z80) : PORT 40H _READ_
// 40H diskette status Register **** READ ONLY *** ( 4-60 of TM100.pdf )
-READ8_MEMBER(rainbow_state::z80_diskstatus_r)
+READ8_MEMBER(rainbow_base_state::z80_diskstatus_r)
{
int track = 0xEE;
int data = m_z80_diskcontrol & (255 - 0x80 - 0x40 - 0x20 - 0x04); // 00011011
@@ -2414,7 +2446,7 @@ READ8_MEMBER(rainbow_state::z80_diskstatus_r)
// ALL SIGNALS ARE HIGH ACTIVE (H), EXCEPT:
// BIT 5 : SIDE 0 L : For single sided drives, this bit is always set to 0 for side O.
-WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w)
+WRITE8_MEMBER(rainbow_base_state::z80_diskcontrol_w)
{
int enable_start;
int disable_start; // set defaults
@@ -2505,7 +2537,7 @@ WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w)
}
// --------- END OF Z80 --------------------
-READ8_MEMBER(rainbow_state::read_video_ram_r)
+READ8_MEMBER(rainbow_base_state::read_video_ram_r)
{
return m_p_ram[offset];
}
@@ -2518,7 +2550,7 @@ READ8_MEMBER(rainbow_state::read_video_ram_r)
// **************************************************
// CPU acknowledge of VBL IRQ resets counter
-IRQ_CALLBACK_MEMBER(rainbow_state::irq_callback)
+IRQ_CALLBACK_MEMBER(rainbow_base_state::irq_callback)
{
int intnum = -1;
for (int i = IRQ_8088_VBL; i >= 0; i--)
@@ -2538,7 +2570,7 @@ IRQ_CALLBACK_MEMBER(rainbow_state::irq_callback)
// NEC7220 Vsync IRQ ***************************************** GDC
// VERIFY: SCROLL_MAP & COLOR_MAP are updated at the next VSYNC (not immediately)... Are there more registers?
-WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
+WRITE_LINE_MEMBER(rainbow_base_state::GDC_vblank_irq)
{
// VERIFICATION NEEDED: IRQ raised before or after new palette loaded...?
if (m_gdc_mode_register & GDC_MODE_ENABLE_VSYNC_IRQ) // 0x40
@@ -2630,7 +2662,7 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
} // 7220 vblank IRQ
-WRITE_LINE_MEMBER(rainbow_state::video_interrupt)
+WRITE_LINE_MEMBER(rainbow_base_state::video_interrupt)
{
if (state == ASSERT_LINE)
raise_8088_irq(IRQ_8088_VBL);
@@ -2651,12 +2683,12 @@ WRITE_LINE_MEMBER(rainbow_state::video_interrupt)
}
// Reflects bits from 'diagnostic_w' (1:1), except test jumpers
-READ8_MEMBER(rainbow_state::diagnostic_r) // 8088 (port 0A READ). Fig.4-29 + table 4-15
+READ8_MEMBER(rainbow_base_state::diagnostic_r) // 8088 (port 0A READ). Fig.4-29 + table 4-15
{
return ((m_diagnostic & 0xf1) | m_inp1->read() | m_inp2->read() | m_inp3->read());
}
-WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 + table 4-15
+WRITE8_MEMBER(rainbow_base_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 + table 4-15
{
// logerror("%02x to diag port (PC=%x)\n", data, m_i8088->pc());
@@ -2773,7 +2805,7 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
}
// KEYBOARD
-void rainbow_state::update_kbd_irq()
+void rainbow_base_state::update_kbd_irq()
{
if ((m_kbd_rx_ready) || (m_kbd_tx_ready))
raise_8088_irq(IRQ_8088_KBD);
@@ -2781,24 +2813,24 @@ void rainbow_state::update_kbd_irq()
lower_8088_irq(IRQ_8088_KBD);
}
-WRITE_LINE_MEMBER(rainbow_state::kbd_tx)
+WRITE_LINE_MEMBER(rainbow_base_state::kbd_tx)
{
m_lk201->rx_w(state);
}
-WRITE_LINE_MEMBER(rainbow_state::kbd_rxready_w)
+WRITE_LINE_MEMBER(rainbow_base_state::kbd_rxready_w)
{
m_kbd_rx_ready = (state == 1) ? true : false;
update_kbd_irq();
}
-WRITE_LINE_MEMBER(rainbow_state::kbd_txready_w)
+WRITE_LINE_MEMBER(rainbow_base_state::kbd_txready_w)
{
m_kbd_tx_ready = (state == 1) ? true : false;
update_kbd_irq();
}
-TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::hd_motor_tick)
+TIMER_DEVICE_CALLBACK_MEMBER(rainbow_base_state::hd_motor_tick)
{
if (m_power_good)
m_crtc->MHFU(MHFU_COUNT); // // Increment IF ENABLED and POWER_GOOD, return count
@@ -2806,14 +2838,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::hd_motor_tick)
m_hdc_index_latch = true; // HDC drive index signal (not working ?)
}
-// on 100-B, DTR from the keyboard 8051 controls bit 7 of IRQ vectors
-WRITE_LINE_MEMBER(rainbow_state::irq_hi_w)
+WRITE_LINE_MEMBER(rainbow_modela_state::irq_hi_w)
{
-#ifdef ASSUME_MODEL_A_HARDWARE
m_irq_high = 0;
-#else
+}
+
+// on 100-B, DTR from the keyboard 8051 controls bit 7 of IRQ vectors
+WRITE_LINE_MEMBER(rainbow_modelb_state::irq_hi_w)
+{
m_irq_high = (state == ASSERT_LINE) ? 0x80 : 0;
-#endif
}
@@ -2823,7 +2856,7 @@ WRITE_LINE_MEMBER(rainbow_state::irq_hi_w)
// NOTE: "More than one plane at a time can be enabled for a write operation; however,
// only one plane can be enabled for a read operation at anyone time."
-READ16_MEMBER(rainbow_state::vram_r)
+READ16_MEMBER(rainbow_base_state::vram_r)
{
if ((!(m_gdc_mode_register & GDC_MODE_VECTOR)) || machine().side_effects_disabled()) // (NOT VECTOR MODE)
{
@@ -2844,7 +2877,7 @@ READ16_MEMBER(rainbow_state::vram_r)
}
// NOTE: Rainbow has separate registers for fore and background.
-WRITE16_MEMBER(rainbow_state::vram_w)
+WRITE16_MEMBER(rainbow_base_state::vram_w)
{
if (m_gdc_mode_register & GDC_MODE_HIGHRES)
offset = (m_gdc_scroll_buffer[(offset & 0x3FC0) >> 6] << 6) | (offset & 0x3F);
@@ -2925,7 +2958,7 @@ WRITE16_MEMBER(rainbow_state::vram_w)
// (READ)
// Read scroll buffer (see GDC Diagnostic Disk, SCROLL BUFFER test)
-READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
+READ8_MEMBER(rainbow_base_state::GDC_EXTRA_REGISTER_r)
{
uint8_t data = 0;
switch (offset)
@@ -2958,7 +2991,7 @@ READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
return data;
}
-WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
+WRITE8_MEMBER(rainbow_base_state::GDC_EXTRA_REGISTER_w)
{
static int last_message, last_mode, last_readback, last_scroll_index;
@@ -3192,45 +3225,43 @@ static GFXDECODE_START(gfx_rainbow)
GFXDECODE_END
// Allocate 512 K (4 x 64 K x 16 bit) of memory (GDC):
-void rainbow_state::upd7220_map(address_map &map)
+void rainbow_base_state::upd7220_map(address_map &map)
{
- map(0x00000, 0x3ffff).rw(FUNC(rainbow_state::vram_r), FUNC(rainbow_state::vram_w)).share("vram");
+ map(0x00000, 0x3ffff).rw(FUNC(rainbow_base_state::vram_r), FUNC(rainbow_base_state::vram_w)).share("vram");
}
-void rainbow_state::rainbow(machine_config &config)
+void rainbow_base_state::rainbow_base(machine_config &config)
{
config.set_default_layout(layout_rainbow);
/* basic machine hardware */
I8088(config, m_i8088, 24.0734_MHz_XTAL / 5); // approximately 4.815 MHz
- m_i8088->set_addrmap(AS_PROGRAM, &rainbow_state::rainbow8088_map);
- m_i8088->set_addrmap(AS_IO, &rainbow_state::rainbow8088_io);
- m_i8088->set_irq_acknowledge_callback(FUNC(rainbow_state::irq_callback));
+ m_i8088->set_irq_acknowledge_callback(FUNC(rainbow_base_state::irq_callback));
Z80(config, m_z80, 24.0734_MHz_XTAL / 6);
- m_z80->set_addrmap(AS_PROGRAM, &rainbow_state::rainbowz80_mem);
- m_z80->set_addrmap(AS_IO, &rainbow_state::rainbowz80_io);
+ m_z80->set_addrmap(AS_PROGRAM, &rainbow_base_state::rainbowz80_mem);
+ m_z80->set_addrmap(AS_IO, &rainbow_base_state::rainbowz80_io);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(24.0734_MHz_XTAL / 6, 442, 0, 400, 264, 0, 240); // ~NTSC compatible video timing (?)
- screen.set_screen_update(FUNC(rainbow_state::screen_update_rainbow));
+ screen.set_screen_update(FUNC(rainbow_base_state::screen_update_rainbow));
screen.set_palette("vt100_video:palette");
GFXDECODE(config, "gfxdecode", "vt100_video:palette", gfx_rainbow);
RAINBOW_VIDEO(config, m_crtc, 24.0734_MHz_XTAL);
m_crtc->set_screen("screen");
m_crtc->set_chargen("chargen");
- m_crtc->ram_rd_callback().set(FUNC(rainbow_state::read_video_ram_r));
- m_crtc->vert_freq_intr_wr_callback().set(FUNC(rainbow_state::video_interrupt));
+ m_crtc->ram_rd_callback().set(FUNC(rainbow_base_state::read_video_ram_r));
+ m_crtc->vert_freq_intr_wr_callback().set(FUNC(rainbow_base_state::video_interrupt));
// *************************** COLOR GRAPHICS (OPTION) **************************************
// While the OSC frequency is confirmed, the divider is not (refresh rate is ~60 Hz with 32).
UPD7220(config, m_hgdc, 31188000 / 32); // Duell schematics shows a 31.188 Mhz oscillator (confirmed by RFKA).
- m_hgdc->vsync_wr_callback().set(FUNC(rainbow_state::GDC_vblank_irq)); // "The vsync callback line needs to be below the 7220 DEVICE_ADD line."
+ m_hgdc->vsync_wr_callback().set(FUNC(rainbow_base_state::GDC_vblank_irq)); // "The vsync callback line needs to be below the 7220 DEVICE_ADD line."
- m_hgdc->set_addrmap(0, &rainbow_state::upd7220_map);
- m_hgdc->set_display_pixels(FUNC(rainbow_state::hgdc_display_pixels));
+ m_hgdc->set_addrmap(0, &rainbow_base_state::upd7220_map);
+ m_hgdc->set_display_pixels(FUNC(rainbow_base_state::hgdc_display_pixels));
m_hgdc->set_screen(m_screen2); // set_screen needs to be added after 7720 device in the machine config, not after the screen.
PALETTE(config, m_palette2).set_entries(32);
@@ -3248,30 +3279,30 @@ void rainbow_state::rainbow(machine_config &config)
m_screen2->set_screen_update("upd7220", FUNC(upd7220_device::screen_update));
FD1793(config, m_fdc, 24.0734_MHz_XTAL / 24); // no separate 1 Mhz quartz
- FLOPPY_CONNECTOR(config, FD1793_TAG ":0", rainbow_floppies, "525qd", rainbow_state::floppy_formats);
- FLOPPY_CONNECTOR(config, FD1793_TAG ":1", rainbow_floppies, "525qd", rainbow_state::floppy_formats);
- FLOPPY_CONNECTOR(config, FD1793_TAG ":2", rainbow_floppies, "525qd", rainbow_state::floppy_formats);
- FLOPPY_CONNECTOR(config, FD1793_TAG ":3", rainbow_floppies, "525qd", rainbow_state::floppy_formats);
- //FLOPPY_CONNECTOR(config, FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_state::floppy_formats);
- //FLOPPY_CONNECTOR(config, FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_state::floppy_formats);
+ FLOPPY_CONNECTOR(config, FD1793_TAG ":0", rainbow_floppies, "525qd", rainbow_base_state::floppy_formats);
+ FLOPPY_CONNECTOR(config, FD1793_TAG ":1", rainbow_floppies, "525qd", rainbow_base_state::floppy_formats);
+ FLOPPY_CONNECTOR(config, FD1793_TAG ":2", rainbow_floppies, "525qd", rainbow_base_state::floppy_formats);
+ FLOPPY_CONNECTOR(config, FD1793_TAG ":3", rainbow_floppies, "525qd", rainbow_base_state::floppy_formats);
+ //FLOPPY_CONNECTOR(config, FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_base_state::floppy_formats);
+ //FLOPPY_CONNECTOR(config, FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_base_state::floppy_formats);
SOFTWARE_LIST(config, "flop_list").set_original("rainbow");
/// ********************************* HARD DISK CONTROLLER *****************************************
WD2010(config, m_hdc, 5000000); // 10 Mhz quartz on controller (divided by 2 for WCLK)
- m_hdc->out_intrq_callback().set(FUNC(rainbow_state::bundle_irq)); // FIRST IRQ SOURCE (OR'ed with DRQ)
- m_hdc->out_bdrq_callback().set(FUNC(rainbow_state::hdc_bdrq)); // BUFFER DATA REQUEST
+ m_hdc->out_intrq_callback().set(FUNC(rainbow_base_state::bundle_irq)); // FIRST IRQ SOURCE (OR'ed with DRQ)
+ m_hdc->out_bdrq_callback().set(FUNC(rainbow_base_state::hdc_bdrq)); // BUFFER DATA REQUEST
// SIGNALS -FROM- WD CONTROLLER:
- m_hdc->out_bcs_callback().set(FUNC(rainbow_state::hdc_read_sector)); // Problem: OUT_BCS_CB = WRITE8 ... (!)
- m_hdc->out_bcr_callback().set(FUNC(rainbow_state::hdc_bcr)); // BUFFER COUNTER RESET (pulses)
+ m_hdc->out_bcs_callback().set(FUNC(rainbow_base_state::hdc_read_sector)); // Problem: OUT_BCS_CB = WRITE8 ... (!)
+ m_hdc->out_bcr_callback().set(FUNC(rainbow_base_state::hdc_bcr)); // BUFFER COUNTER RESET (pulses)
- m_hdc->out_wg_callback().set(FUNC(rainbow_state::hdc_write_sector)); // WRITE GATE
- m_hdc->out_step_callback().set(FUNC(rainbow_state::hdc_step)); // STEP PULSE
- m_hdc->out_dirin_callback().set(FUNC(rainbow_state::hdc_direction));
+ m_hdc->out_wg_callback().set(FUNC(rainbow_base_state::hdc_write_sector)); // WRITE GATE
+ m_hdc->out_step_callback().set(FUNC(rainbow_base_state::hdc_step)); // STEP PULSE
+ m_hdc->out_dirin_callback().set(FUNC(rainbow_base_state::hdc_direction));
// WF + DRDY are actually wired to a routine here:
- m_hdc->in_wf_callback().set(FUNC(rainbow_state::hdc_write_fault)); // WRITE FAULT (fatal until next reset)
- m_hdc->in_drdy_callback().set(FUNC(rainbow_state::hdc_drive_ready)); // DRIVE_READY (VCC = ready)
+ m_hdc->in_wf_callback().set(FUNC(rainbow_base_state::hdc_write_fault)); // WRITE FAULT (fatal until next reset)
+ m_hdc->in_drdy_callback().set(FUNC(rainbow_base_state::hdc_drive_ready)); // DRIVE_READY (VCC = ready)
// Always set seek complete and track 00 signal (not super clean, but does not affect operation):
m_hdc->in_sc_callback().set_constant(1); // SEEK COMPLETE (VCC = complete)
@@ -3289,11 +3320,11 @@ void rainbow_state::rainbow(machine_config &config)
DS1315(config, m_rtc, 0); // DS1315 (ClikClok for DEC-100 B) * OPTIONAL *
COM8116_003(config, m_dbrg, 24.0734_MHz_XTAL / 4); // 6.01835 MHz (nominally 6 MHz)
- m_dbrg->fr_handler().set(FUNC(rainbow_state::dbrg_fr_w));
- m_dbrg->ft_handler().set(FUNC(rainbow_state::dbrg_ft_w));
+ m_dbrg->fr_handler().set(FUNC(rainbow_base_state::dbrg_fr_w));
+ m_dbrg->ft_handler().set(FUNC(rainbow_base_state::dbrg_ft_w));
UPD7201_NEW(config, m_mpsc, 24.0734_MHz_XTAL / 5 / 2); // 2.4073 MHz (nominally 2.5 MHz)
- m_mpsc->out_int_callback().set(FUNC(rainbow_state::mpsc_irq));
+ m_mpsc->out_int_callback().set(FUNC(rainbow_base_state::mpsc_irq));
m_mpsc->out_txda_callback().set(m_comm_port, FUNC(rs232_port_device::write_txd));
m_mpsc->out_txdb_callback().set("printer", FUNC(rs232_port_device::write_txd));
// RTS and DTR outputs are not connected
@@ -3315,10 +3346,9 @@ void rainbow_state::rainbow(machine_config &config)
printer.set_default_option("printer");
I8251(config, m_kbd8251, 24.0734_MHz_XTAL / 5 / 2);
- m_kbd8251->txd_handler().set(FUNC(rainbow_state::kbd_tx));
- m_kbd8251->dtr_handler().set(FUNC(rainbow_state::irq_hi_w));
- m_kbd8251->rxrdy_handler().set(FUNC(rainbow_state::kbd_rxready_w));
- m_kbd8251->txrdy_handler().set(FUNC(rainbow_state::kbd_txready_w));
+ m_kbd8251->txd_handler().set(FUNC(rainbow_base_state::kbd_tx));
+ m_kbd8251->rxrdy_handler().set(FUNC(rainbow_base_state::kbd_rxready_w));
+ m_kbd8251->txrdy_handler().set(FUNC(rainbow_base_state::kbd_txready_w));
LK201(config, m_lk201, 0);
m_lk201->tx_handler().set(m_kbd8251, FUNC(i8251_device::write_rxd));
@@ -3326,13 +3356,31 @@ void rainbow_state::rainbow(machine_config &config)
ripple_counter_device &prtbrg(RIPPLE_COUNTER(config, "prtbrg", 24.0734_MHz_XTAL / 6 / 13)); // 74LS393 at E17 (both halves)
// divided clock should ideally be 307.2 kHz, but is actually approximately 308.6333 kHz
prtbrg.set_stages(8);
- prtbrg.count_out_cb().set(FUNC(rainbow_state::bitrate_counter_w));
+ prtbrg.count_out_cb().set(FUNC(rainbow_base_state::bitrate_counter_w));
- TIMER(config, "motor").configure_periodic(FUNC(rainbow_state::hd_motor_tick), attotime::from_hz(60));
+ TIMER(config, "motor").configure_periodic(FUNC(rainbow_base_state::hd_motor_tick), attotime::from_hz(60));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
}
+void rainbow_modela_state::rainbow_modela(machine_config &config)
+{
+ rainbow_base(config);
+ m_i8088->set_addrmap(AS_PROGRAM, &rainbow_modela_state::rainbow8088_map);
+ m_i8088->set_addrmap(AS_IO, &rainbow_modela_state::rainbow8088_io);
+ RAM(config, m_ram).set_default_size("64K").set_extra_options("64K,128K,192K,256K,320K,384K,448K,512K,576K,640K,704K,768K");
+ m_kbd8251->dtr_handler().set(FUNC(rainbow_modela_state::irq_hi_w));
+}
+
+void rainbow_modelb_state::rainbow_modelb(machine_config &config)
+{
+ rainbow_base(config);
+ m_i8088->set_addrmap(AS_PROGRAM, &rainbow_modelb_state::rainbow8088_map);
+ m_i8088->set_addrmap(AS_IO, &rainbow_modelb_state::rainbow8088_io);
+ RAM(config, m_ram).set_default_size("128K").set_extra_options("128K,192K,256K,320K,384K,448K,512K,576K,640K,704K,768K,832K,896K");
+ m_kbd8251->dtr_handler().set(FUNC(rainbow_modelb_state::irq_hi_w));
+}
+
//----------------------------------------------------------------------------------------
// 'Rainbow 100-A' (system module 70-19974-00, PSU H7842-A)
// - first generation hardware (introduced May '82) with ROM 04.03.11
@@ -3437,7 +3485,7 @@ ROM_END
/* Driver */
-/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */
-COMP(1982, rainbow100a, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, empty_init, "Digital Equipment Corporation", "Rainbow 100-A", MACHINE_IS_SKELETON)
-COMP(1983, rainbow, 0, 0, rainbow, rainbow100b_in, rainbow_state, empty_init, "Digital Equipment Corporation", "Rainbow 100-B", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS)
-COMP(1985, rainbow190, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, empty_init, "Digital Equipment Corporation", "Rainbow 190-B", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_COLORS)
+/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */
+COMP(1982, rainbow100a, rainbow, 0, rainbow_modela, rainbow100b_in, rainbow_modela_state, empty_init, "Digital Equipment Corporation", "Rainbow 100-A", MACHINE_IS_SKELETON)
+COMP(1983, rainbow, 0, 0, rainbow_modelb, rainbow100b_in, rainbow_modelb_state, empty_init, "Digital Equipment Corporation", "Rainbow 100-B", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS)
+COMP(1985, rainbow190, rainbow, 0, rainbow_modelb, rainbow100b_in, rainbow_modelb_state, empty_init, "Digital Equipment Corporation", "Rainbow 190-B", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_COLORS)