mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Rainbow-100: use Z80SIO instead of Z80DART; make UCSD Pascal boot again (#2524)
Incorporates change from Z80DART to Z80SIO proposed by Edstrom. Also make UCSD Pascal boot again.
This commit is contained in:
parent
bb252484f1
commit
9551023313
@ -1,7 +1,3 @@
|
||||
// Define suppresses costly smooth scroll / updates when debugging:
|
||||
// ENABLE BY UNCOMMENTING. ADDITIONALLY, SET SMOOTH SCROLL IN EMULATION (DISABLE BY SETTING JUMP SCROLL. To enter SETUP hit ScrollLock)-
|
||||
//#define BOOST_DEBUG_PERFORMANCE
|
||||
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Miodrag Milanovic,Karl-Ludwig Deisenhofer
|
||||
/***************************************************************************************************
|
||||
@ -356,10 +352,12 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
|
||||
#include "machine/wd2010.h"
|
||||
#include "machine/corvushd.h"
|
||||
|
||||
#include "machine/z80dart.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "imagedev/bitbngr.h"
|
||||
#include "machine/com8116.h"
|
||||
#include "bus/rs232/terminal.h"
|
||||
#include "bus/rs232/ser_mouse.h"
|
||||
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/clock.h"
|
||||
@ -614,7 +612,7 @@ public:
|
||||
IRQ_CALLBACK_MEMBER(irq_callback);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(motor_tick);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(hd_motor_tick);
|
||||
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
@ -665,9 +663,10 @@ private:
|
||||
|
||||
required_device<corvus_hdc_device> m_corvus_hdc;
|
||||
|
||||
required_device<upd7201_device> m_mpsc;
|
||||
required_device<upd7201_new_device> m_mpsc;
|
||||
required_device<com8116_device> m_dbrg_A;
|
||||
required_device<com8116_device> m_dbrg_B;
|
||||
|
||||
required_device<i8251_device> m_kbd8251;
|
||||
required_device<lk201_device> m_lk201;
|
||||
required_shared_ptr<uint8_t> m_p_ram;
|
||||
@ -720,8 +719,6 @@ private:
|
||||
bool m_kbd_tx_ready, m_kbd_rx_ready;
|
||||
int m_KBD;
|
||||
|
||||
int MOTOR_DISABLE_counter;
|
||||
|
||||
uint8_t m_diagnostic;
|
||||
|
||||
uint8_t m_z80_private[0x800]; // Z80 private 2K
|
||||
@ -730,7 +727,7 @@ private:
|
||||
void update_kbd_irq();
|
||||
virtual void machine_reset() override;
|
||||
|
||||
int m_unit;
|
||||
int m_present_drive;
|
||||
floppy_image_device *m_floppy;
|
||||
|
||||
int m_irq_high;
|
||||
@ -751,6 +748,7 @@ private:
|
||||
|
||||
bool m_POWER_GOOD;
|
||||
emu_timer *cmd_timer;
|
||||
emu_timer *switch_off_timer;
|
||||
|
||||
const int vectors[9] = { 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x02 };
|
||||
|
||||
@ -761,6 +759,8 @@ private:
|
||||
// FULL RANGE video levels for 100-B model, taken from page 46 of PDF
|
||||
const uint8_t video_levels[16] = { 255, 217, 201,186, 171, 156, 140, 125, 110, 97, 79, 66, 54, 31, 18, 0 };
|
||||
uint8_t m_PORT50;
|
||||
|
||||
const int comm_rates[16] = { 50,75,110,134,150,200,300,600,1200,1800,2000,2400,3600,4800,9600,19200 };
|
||||
};
|
||||
|
||||
|
||||
@ -796,15 +796,6 @@ printf("\n** OPTION GRFX. RESET **\n");
|
||||
|
||||
UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
|
||||
{
|
||||
#ifdef BOOST_DEBUG_PERFORMANCE
|
||||
uint8_t *ram = memregion("maincpu")->base();
|
||||
if( !(m_p_vol_ram[0x84] == 0x00) )
|
||||
{
|
||||
if( (MOTOR_DISABLE_counter) || (ram[0xEFFFE] & 16) ) // if HDD/FDD ACTIVITY -OR- SMOOTH SCROLL IN PROGRESS
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const rgb_t *paletteX = m_palette2->palette()->entry_list_raw();
|
||||
|
||||
int xi;
|
||||
@ -864,8 +855,11 @@ FLOPPY_FORMATS_END
|
||||
static SLOT_INTERFACE_START(rainbow_floppies)
|
||||
SLOT_INTERFACE("525qd0", FLOPPY_525_QD) // QD means 80 tracks with DD data rate (single or double sided).
|
||||
SLOT_INTERFACE("525qd1", FLOPPY_525_QD)
|
||||
//SLOT_INTERFACE("525qd2", FLOPPY_525_QD)
|
||||
//SLOT_INTERFACE("525qd3", FLOPPY_525_QD)
|
||||
SLOT_INTERFACE("525dd", FLOPPY_525_DD) // mimic a 5.25" PC (40 track) drive. Requires IDrive5.SYS.
|
||||
SLOT_INTERFACE("35dd", FLOPPY_35_DD) // mimic 3.5" PC drive (720K, double density). Use Impdrv3.SYS.
|
||||
SLOT_INTERFACE("525ssdd", FLOPPY_525_SSDD) // to read a single sided, (160K) PC-DOS 1 disk with MediaMaster
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
void rainbow_state::machine_start()
|
||||
@ -874,7 +868,8 @@ void rainbow_state::machine_start()
|
||||
cmd_timer = timer_alloc(0);
|
||||
cmd_timer->adjust(attotime::from_msec(MS_TO_POWER_GOOD));
|
||||
|
||||
MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs
|
||||
switch_off_timer = timer_alloc(1);
|
||||
switch_off_timer->adjust(attotime::from_msec(10));
|
||||
|
||||
m_SCREEN_BLANK = false;
|
||||
|
||||
@ -980,7 +975,7 @@ AM_RANGE(0x56, 0x57) AM_DEVREADWRITE("upd7220", upd7220_device, read, write) //
|
||||
// 0x60 -> 0x6f ***** EXTENDED COMM. OPTION / Option Select 2.
|
||||
// ===========================================================
|
||||
// 0x60 -> 0x6f ***** RD51 HD. CONTROLLER / Option Select 2.
|
||||
AM_RANGE(0x60, 0x67) AM_DEVREADWRITE("hdc", wd2010_device, read, write)
|
||||
AM_RANGE(0x60, 0x67) AM_DEVREADWRITE("hdc", wd2010_device, read, write) AM_MIRROR(0x100)
|
||||
AM_RANGE(0x68, 0x68) AM_READWRITE(hd_status_68_r, hd_status_68_w)
|
||||
AM_RANGE(0x69, 0x69) AM_READ(hd_status_69_r)
|
||||
// ===========================================================
|
||||
@ -1073,12 +1068,12 @@ PORT_DIPSETTING(0xE0000, "896 K (100-B MAX. MEMORY)")
|
||||
|
||||
// EXT.COMM.card -or- RD51 HD. controller (marketed later).
|
||||
PORT_START("DEC HARD DISK") // BUNDLE_OPTION
|
||||
PORT_DIPNAME(0x01, 0x00, "DEC HARD DISK") PORT_TOGGLE
|
||||
PORT_DIPNAME(0x01, 0x00, "DEC HARD DISK (#1)") PORT_TOGGLE
|
||||
PORT_DIPSETTING(0x00, DEF_STR(Off))
|
||||
PORT_DIPSETTING(0x01, DEF_STR(On))
|
||||
|
||||
PORT_START("CORVUS HARD DISKS")
|
||||
PORT_DIPNAME(0x01, 0x00, "CORVUS HARD DISKS") PORT_TOGGLE
|
||||
PORT_DIPNAME(0x01, 0x00, "CORVUS HARD DISKS (#2 to #5)") PORT_TOGGLE
|
||||
PORT_DIPSETTING(0x00, DEF_STR(Off))
|
||||
PORT_DIPSETTING(0x01, DEF_STR(On))
|
||||
|
||||
@ -1142,7 +1137,6 @@ void rainbow_state::machine_reset()
|
||||
uint32_t unmap_start = m_inp8->read();
|
||||
|
||||
// Verify RAM size matches hardware (DIP switches)
|
||||
uint8_t *nv = memregion("maincpu")->base();
|
||||
uint8_t NVRAM_LOCATION;
|
||||
uint32_t check;
|
||||
|
||||
@ -1155,7 +1149,7 @@ void rainbow_state::machine_reset()
|
||||
}
|
||||
|
||||
check = (unmap_start >> 16)-1; // guess.
|
||||
NVRAM_LOCATION = nv[0xed084]; // location not verified yet. DMT RAM check tests offset $84 !
|
||||
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' ***************************************
|
||||
@ -1173,7 +1167,7 @@ void rainbow_state::machine_reset()
|
||||
}
|
||||
|
||||
check = (unmap_start >> 16) - 2;
|
||||
NVRAM_LOCATION = nv[0xed0db];
|
||||
NVRAM_LOCATION = m_p_nvram[0xdb];
|
||||
|
||||
#ifdef RTC_ENABLED
|
||||
// *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' ***************************************
|
||||
@ -1212,6 +1206,8 @@ void rainbow_state::machine_reset()
|
||||
local_hard_disk = rainbow_hdc_file(0); // one hard disk for now.
|
||||
|
||||
output().set_value("led1", 0);
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
if (local_hard_disk)
|
||||
{
|
||||
hard_disk_info *info;
|
||||
@ -1231,11 +1227,11 @@ void rainbow_state::machine_reset()
|
||||
}
|
||||
}
|
||||
|
||||
if (m_inp6->read() == 0x00) // Unmap port if Corvus not present
|
||||
if (m_inp6->read() == 0x00) // Unmap port if Corvus not present
|
||||
io.unmap_readwrite(0x20, 0x20);
|
||||
|
||||
// *********** FLOPPY DISK CONTROLLER [ NOT OPTIONAL ]
|
||||
m_unit = INVALID_DRIVE;
|
||||
m_present_drive = INVALID_DRIVE;
|
||||
m_fdc->reset();
|
||||
m_fdc->set_floppy(nullptr);
|
||||
m_fdc->dden_w(0);
|
||||
@ -1306,7 +1302,23 @@ void rainbow_state::device_timer(emu_timer &timer, device_timer_id tid, int para
|
||||
printf("\n**** WATCHDOG: CPU RESET ****\n");
|
||||
m_i8088->reset(); // gives 'ERROR_16 - INTERRUPTS OFF' (indicates hardware failure or software bug).
|
||||
}
|
||||
} // switch
|
||||
break; // case 0
|
||||
|
||||
case 1:
|
||||
|
||||
switch_off_timer->adjust(attotime::never);
|
||||
|
||||
output().set_value("driveled0", 0); // DRIVE 0 (A)
|
||||
output().set_value("driveled1", 0); // DRIVE 1 (B)
|
||||
output().set_value("driveled2", 0); // DRIVE 2 (C)
|
||||
output().set_value("driveled3", 0); // DRIVE 3 (D)
|
||||
|
||||
output().set_value("led1", 1); // 1 = OFF (One of the CPU LEDs as drive LED for DEC hard disk)
|
||||
output().set_value("led2", 1); // 1 = OFF (One of the CPU LEDs as drive LED for Corvus HD)
|
||||
|
||||
break; // case 1
|
||||
|
||||
} // switch (timer ID)
|
||||
}
|
||||
|
||||
uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
@ -1332,15 +1344,6 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1
|
||||
m_color_map_changed = true;
|
||||
}
|
||||
|
||||
#ifdef BOOST_DEBUG_PERFORMANCE
|
||||
uint8_t *ram = memregion("maincpu")->base();
|
||||
if( !(m_p_vol_ram[0x84] == 0x00) )
|
||||
{
|
||||
if( (MOTOR_DISABLE_counter) || (ram[0xEFFFE] & 16) ) // if HDD/FDD ACTIVITY -OR- SMOOTH SCROLL IN PROGRESS
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_crtc->palette_select(palette_selected);
|
||||
|
||||
if( m_SCREEN_BLANK ||
|
||||
@ -1405,10 +1408,10 @@ WRITE_LINE_MEMBER(rainbow_state::mpsc_irq)
|
||||
WRITE8_MEMBER(rainbow_state::comm_bitrate_w)
|
||||
{
|
||||
m_dbrg_A->str_w(data & 0x0f); // PDF is wrong, low nibble is RECEIVE clock (verified in SETUP).
|
||||
printf("\nRECEIVE bitrate = %02x HEX\n",data & 0x0f);
|
||||
logerror("\n(COMM.) receive bitrate = %d ($%02x)\n", comm_rates[data & 0x0f] , data & 0x0f);
|
||||
|
||||
m_dbrg_A->stt_w( ((data & 0xf0) >> 4) );
|
||||
printf("\nTRANSMIT bitrate = %02x HEX\n",(data & 0xf0) >> 4);
|
||||
logerror("(COMM.) transmit bitrate = %d ($%02x)\n", comm_rates[((data & 0xf0) >> 4)] ,(data & 0xf0) >> 4);
|
||||
}
|
||||
|
||||
// PORT 0x0e : Printer bit rates
|
||||
@ -1416,15 +1419,15 @@ WRITE8_MEMBER(rainbow_state::printer_bitrate_w)
|
||||
{
|
||||
m_dbrg_B->str_w(data & 7); // bits 0 - 2
|
||||
m_dbrg_B->stt_w(data & 7); // TX and RX rate cannot be programmed independently.
|
||||
printf("\n(PRINTER) RECEIVE / TRANSMIT bitrate = %02x HEX\n",data & 7);
|
||||
logerror("\n(PRINTER) receive = transmit bitrate: %d ($%02x)", 9600 / ( 1 << (7 - (data & 7))) , data & 7);
|
||||
|
||||
// "bit 3 controls the communications port clock (RxC,TxC). External clock when 1, internal when 0"
|
||||
printf(" - CLOCK (0 = internal): %02x", data & 8);
|
||||
logerror(" - CLOCK (0 = internal): %02x", data & 8);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(rainbow_state::com8116_a_fr_w)
|
||||
{
|
||||
m_mpsc->rxca_w(state);
|
||||
m_mpsc->rxca_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(rainbow_state::com8116_a_ft_w)
|
||||
@ -1609,13 +1612,13 @@ READ8_MEMBER(rainbow_state::corvus_status_r)
|
||||
{
|
||||
if(m_inp6->read() == 0) // Corvus controller
|
||||
{
|
||||
popmessage("Corvus controller invoked - but not switched on. Check DIP and perform a reset.");
|
||||
popmessage("Corvus controller invoked - but switched OFF.\nCheck DIP and perform a reset.\n\nIncompatible software also triggers this warning (illegal access to port $21)");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
output().set_value("led2", 0);
|
||||
MOTOR_DISABLE_counter = 5;
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
uint8_t status = m_corvus_hdc->status_r(space, 0);
|
||||
uint8_t data = (status & 0x80) ? 1 : 0; // 0x80 BUSY (Set = Busy, Clear = Ready)
|
||||
@ -1727,6 +1730,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_read_sector)
|
||||
{
|
||||
read_status = 2; // logerror("\nTRYING TO READ");
|
||||
output().set_value("led1", 0);
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
int hi = (m_hdc->read(generic_space(), 0x05)) & 0x07;
|
||||
uint16_t cylinder = (m_hdc->read(generic_space(), 0x04)) | (hi << 8);
|
||||
@ -1797,7 +1801,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_write_sector)
|
||||
)
|
||||
{
|
||||
output().set_value("led1", 0); // (1 = OFF ) =HARD DISK ACTIVITY =
|
||||
MOTOR_DISABLE_counter = 20;
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
if (rainbow_hdc_file(0) != nullptr)
|
||||
{
|
||||
@ -1834,6 +1838,7 @@ int rainbow_state::do_write_sector()
|
||||
{
|
||||
int feedback = 0; // no error
|
||||
output().set_value("led1", 0); // ON
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
hard_disk_file *local_hard_disk;
|
||||
local_hard_disk = rainbow_hdc_file(0); // one hard disk for now.
|
||||
@ -1989,7 +1994,7 @@ WRITE8_MEMBER(rainbow_state::hd_status_68_w)
|
||||
if (data & 0x01)
|
||||
{
|
||||
output().set_value("led1", 0); // 1 = OFF (One of the CPU LEDs as DRIVE LED) = HARD DISK ACTIVITY =
|
||||
MOTOR_DISABLE_counter = 20;
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
m_hdc->buffer_ready(true);
|
||||
}
|
||||
@ -2057,7 +2062,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_step)
|
||||
m_hdc_step_latch = true;
|
||||
|
||||
output().set_value("led1", 0); // 1 = OFF (One of the CPU LEDs as DRIVE LED) = HARD DISK ACTIVITY =
|
||||
MOTOR_DISABLE_counter = 20;
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(rainbow_state::hdc_direction)
|
||||
@ -2177,11 +2182,12 @@ READ8_MEMBER(rainbow_state::comm_control_r)
|
||||
if (m_POWER_GOOD)
|
||||
is_mhfu_enabled = m_crtc->MHFU(MHFU_IS_ENABLED);
|
||||
|
||||
return (
|
||||
return (
|
||||
(is_mhfu_enabled ? 0x00 : 0x20) | // (L) status of MHFU flag => bit pos.5
|
||||
((INT88) ? 0x00 : 0x40) | // (L)
|
||||
((INTZ80) ? 0x00 : 0x80) // (L)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// ******* TODO: 4 control bits * MISSING * ********************************************************
|
||||
@ -2193,7 +2199,7 @@ READ8_MEMBER(rainbow_state::comm_control_r)
|
||||
// 3 COMM RTS (controls request to send line of COMM)
|
||||
WRITE8_MEMBER(rainbow_state::comm_control_w)
|
||||
{
|
||||
printf("%02x to COMM.CONTROL REGISTER ", data);
|
||||
logerror("%02x to COMM.CONTROL REGISTER ", data);
|
||||
|
||||
/* 8088 LEDs:
|
||||
5 7 6 4 <- BIT POSITION
|
||||
@ -2206,13 +2212,11 @@ WRITE8_MEMBER(rainbow_state::comm_control_w)
|
||||
output().set_value("led7", BIT(data, 4)); // LED "D3"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 8088 writes to port 0x00 (interrupts Z80)
|
||||
// See page 133 (4-34)
|
||||
WRITE8_MEMBER(rainbow_state::i8088_latch_w)
|
||||
{
|
||||
// printf("%02x to Z80 mailbox\n", data);
|
||||
// logerror("%02x to Z80 mailbox\n", data);
|
||||
|
||||
// The interrupt vector address(F7H) placed on the bus is hardwired into the Z80A interrupt vector encoder.
|
||||
// The F7H interrupt vector address causes the Z80A processor to perform an RST 30 instruction in
|
||||
@ -2227,7 +2231,7 @@ WRITE8_MEMBER(rainbow_state::i8088_latch_w)
|
||||
// See page 134 (4-35)
|
||||
READ8_MEMBER(rainbow_state::z80_latch_r)
|
||||
{
|
||||
// printf("Read %02x from Z80 mailbox\n", m_z80_mailbox);
|
||||
// logerror("Read %02x from Z80 mailbox\n", m_z80_mailbox);
|
||||
m_z80->set_input_line(0, CLEAR_LINE);
|
||||
|
||||
INTZ80 = false;
|
||||
@ -2238,7 +2242,7 @@ READ8_MEMBER(rainbow_state::z80_latch_r)
|
||||
// See page 134 (4-35)
|
||||
WRITE8_MEMBER(rainbow_state::z80_latch_w)
|
||||
{
|
||||
// printf("%02x to 8088 mailbox\n", data);
|
||||
// logerror("%02x to 8088 mailbox\n", data);
|
||||
raise_8088_irq(IRQ_8088_MAILBOX);
|
||||
m_8088_mailbox = data;
|
||||
|
||||
@ -2248,7 +2252,7 @@ WRITE8_MEMBER(rainbow_state::z80_latch_w)
|
||||
// 8088 reads port 0x00. See page 133 (4-34)
|
||||
READ8_MEMBER(rainbow_state::i8088_latch_r)
|
||||
{
|
||||
// printf("Read %02x from 8088 mailbox\n", m_8088_mailbox);
|
||||
// logerror("Read %02x from 8088 mailbox\n", m_8088_mailbox);
|
||||
lower_8088_irq(IRQ_8088_MAILBOX);
|
||||
|
||||
INT88 = false;
|
||||
@ -2297,37 +2301,36 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r)
|
||||
D0 : ZFLIP L: (read from the diagnostic control register of Z80A)
|
||||
*/
|
||||
static int last_track;
|
||||
|
||||
int track = 0;
|
||||
|
||||
int fdc_step = 0;
|
||||
int fdc_ready = 0;
|
||||
int tk00 = 0;
|
||||
int fdc_write_gate = 0;
|
||||
int last_dir = 0;
|
||||
|
||||
// printf("\nFLOPPY %02d - ", m_unit);
|
||||
if (m_fdc)
|
||||
uint8_t fdc_status;
|
||||
|
||||
if(m_fdc)
|
||||
{
|
||||
track = m_fdc->track_r(space, 0);
|
||||
if (track != last_track)
|
||||
fdc_step = 1; // calculate STEP (sic)
|
||||
track = m_fdc->track_r(space, 0);
|
||||
if(track == 0)
|
||||
tk00 = 1;
|
||||
|
||||
last_dir = track > last_track ? 0 : 1; // see WD_FDC
|
||||
last_track = track;
|
||||
}
|
||||
if (track != last_track)
|
||||
fdc_step = 1; // calculate STEP (sic)
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
if (!m_floppy->ready_r()) // weird (see wd_fdc)
|
||||
fdc_ready = 1;
|
||||
last_dir = track > last_track ? 0 : 1; // see WD_FDC
|
||||
last_track = track;
|
||||
|
||||
if ((fdc_ready) && (m_floppy->wpt_r() != 1) && m_POWER_GOOD)
|
||||
fdc_write_gate = 1; // * FAKE * WRITE GATE !
|
||||
fdc_status = m_fdc->status_r();
|
||||
|
||||
// "valid only when drive is selected" !
|
||||
if (!m_floppy->trk00_r()) // weird (see wd_fdc)
|
||||
tk00 = 1;
|
||||
}
|
||||
if ( (fdc_status & 0x80) == 0) // (see WD_FDC: S_WP = 0x40, S_NRDY = 0x80, S_TR00 = 0x04)
|
||||
fdc_ready = 1;
|
||||
|
||||
if ( fdc_ready && ((fdc_status & 0x40) == 0) && m_POWER_GOOD )
|
||||
fdc_write_gate = 1; // "valid only when drive is selected" !
|
||||
}
|
||||
|
||||
int data = (
|
||||
((fdc_step) ? 0x00 : 0x80) |
|
||||
@ -2348,41 +2351,40 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r)
|
||||
// 40H diskette status Register **** READ ONLY *** ( 4-60 of TM100.pdf )
|
||||
READ8_MEMBER(rainbow_state::z80_diskstatus_r)
|
||||
{
|
||||
int track = 0;
|
||||
int data = m_z80_diskcontrol & (255 - 0x80 - 0x40 - 0x20 - 4);
|
||||
int track = 0xEE;
|
||||
int data = m_z80_diskcontrol & (255 - 0x80 - 0x40 - 0x20 - 0x04); // 00011011
|
||||
|
||||
// D7: DRQ: reflects status of DATA REQUEST signal from FDC.
|
||||
// '1' indicates that FDC has read data OR requires new write data.
|
||||
if (m_fdc)
|
||||
data |= m_fdc->drq_r() ? 0x80 : 0x00;
|
||||
|
||||
// D6: IRQ: indicates INTERRUPT REQUEST signal from FDC. Indicates that a
|
||||
// status bit has changed. Set to 1 at the completion of any
|
||||
// command (.. see page 207 or 5-25).
|
||||
if (m_fdc)
|
||||
{
|
||||
data |= m_fdc->drq_r() ? 0x80 : 0x00;
|
||||
data |= m_fdc->intrq_r() ? 0x40 : 0x00;
|
||||
track = m_fdc->track_r(space, 0);
|
||||
|
||||
// D2: TG43 * LOW ACTIVE * : 0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE.
|
||||
// (asserted when writing data to tracks 44 through 79)
|
||||
data |= (track > 43) ? 0x00 : 0x04; // ! LOW ACTIVE !
|
||||
}
|
||||
|
||||
// D5: SIDE 0 * HIGH ACTIVE *: status of side select signal at J2 + J3 of RX50 controller.
|
||||
// For 1 sided drives, this bit will always read low (0).
|
||||
if (m_floppy)
|
||||
if (m_floppy != nullptr)
|
||||
data |= m_floppy->ss_r() ? 0x20 : 0x00;
|
||||
|
||||
// *LOW ACTIVE *
|
||||
// D4: MOTOR 1 ON L: 0 = indicates MOTOR 1 ON bit is set in drive control reg.
|
||||
// D3: MOTOR 0 ON L: 0 = indicates MOTOR 0 ON bit is set in drive "
|
||||
|
||||
if (m_fdc)
|
||||
track = m_fdc->track_r(space, 0);
|
||||
|
||||
// Print HEX track number
|
||||
static uint8_t bcd2hex[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 };
|
||||
// 0...9 ,A (0x77), b (0x7c), C (0x39) , d (0x5e), E (0x79), F (0x71)
|
||||
output().set_digit_value(0, bcd2hex[(track >> 4) & 0x0f]);
|
||||
output().set_digit_value(1, bcd2hex[(track - ((track >> 4) << 4)) & 0x0f]);
|
||||
|
||||
// D2: TG43 * LOW ACTIVE * : 0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE.
|
||||
// (asserted when writing data to tracks 44 through 79)
|
||||
data |= (track > 43) ? 0x00 : 0x04; // ! LOW ACTIVE !
|
||||
output().set_digit_value(1, bcd2hex[ track & 0x0f]);
|
||||
|
||||
// D1: DS1 H: reflect status of bits 0 and 1 from disk.control reg.
|
||||
// D0: DS0 H: "
|
||||
@ -2397,6 +2399,9 @@ READ8_MEMBER(rainbow_state::z80_diskstatus_r)
|
||||
// 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)
|
||||
{
|
||||
int enable_start;
|
||||
int disable_start; // set defaults
|
||||
|
||||
int selected_drive = INVALID_DRIVE;
|
||||
static const char *names[] = { FD1793_TAG ":0", FD1793_TAG ":1", FD1793_TAG ":2", FD1793_TAG ":3" };
|
||||
|
||||
@ -2415,31 +2420,14 @@ WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w)
|
||||
m_floppy = con->get_device();
|
||||
if (m_floppy)
|
||||
selected_drive = drive;
|
||||
// printf("%i <- SELECTED DRIVE...\n", m_unit);
|
||||
}
|
||||
|
||||
if (selected_drive == INVALID_DRIVE)
|
||||
{
|
||||
printf("(m_unit = %i) ** SELECTED DRIVE ** INVALID. (selected drive = %i)\n", m_unit, selected_drive);
|
||||
m_unit = INVALID_DRIVE;
|
||||
m_floppy = nullptr;
|
||||
}
|
||||
logerror("(m_present_drive = %i) ** SELECTED DRIVE ** INVALID. (selected drive = %i)\n", m_present_drive, selected_drive);
|
||||
|
||||
if (m_floppy != nullptr)
|
||||
{
|
||||
m_fdc->set_floppy(m_floppy); // Sets new _image device_
|
||||
m_fdc->dden_w(0); // 0 = MFM
|
||||
if (!m_floppy->exists()) // invalidate selection
|
||||
{
|
||||
m_floppy = nullptr;
|
||||
printf("(m_unit = %i) SELECTED IMAGE *** DOES NOT EXIST *** (selected drive = %i)\n", m_unit, selected_drive);
|
||||
selected_drive = m_unit;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_floppy->ss_w((data & 0x20) ? 1 : 0); // RX50 board in Rainbow has 'side select'
|
||||
m_floppy->set_rpm(300.);
|
||||
}
|
||||
m_present_drive = INVALID_DRIVE;
|
||||
m_floppy = nullptr;
|
||||
}
|
||||
|
||||
output().set_value("driveled0", (selected_drive == 0) ? 1 : 0);
|
||||
@ -2447,59 +2435,58 @@ WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w)
|
||||
|
||||
output().set_value("driveled2", (selected_drive == 2) ? 1 : 0);
|
||||
output().set_value("driveled3", (selected_drive == 3) ? 1 : 0);
|
||||
switch_off_timer->adjust(attotime::from_msec(500));
|
||||
|
||||
if (selected_drive < 4)
|
||||
if (m_floppy != nullptr)
|
||||
{
|
||||
m_unit = selected_drive;
|
||||
m_fdc->set_floppy(m_floppy); // Sets new _image device_
|
||||
m_fdc->dden_w(0); // 0 = MFM
|
||||
m_floppy->ss_w((data & 0x20) ? 1 : 0); // RX50 board in Rainbow has 'side select'
|
||||
m_floppy->set_rpm(300.);
|
||||
|
||||
if (MOTOR_DISABLE_counter == 0) // "one shot"
|
||||
MOTOR_DISABLE_counter = 20;
|
||||
if ( !m_floppy->exists() && (selected_drive > 1) )
|
||||
popmessage("NO IMAGE ATTACHED TO %c\n", 65 + selected_drive );
|
||||
}
|
||||
|
||||
if(selected_drive < MAX_FLOPPIES)
|
||||
{
|
||||
m_present_drive = selected_drive;
|
||||
|
||||
// FORCE_READY = 1 : assert DRIVE READY on FDC (diagnostic override; USED BY BIOS!)
|
||||
bool force_ready = ((data & 4) == 0) ? true : false;
|
||||
m_fdc->set_force_ready(force_ready);
|
||||
}
|
||||
m_fdc->set_force_ready(force_ready); // 1 : assert DRIVE READY on FDC (diagnostic override)
|
||||
|
||||
int enable_start = 0;
|
||||
int disable_start = 2; // set defaults
|
||||
if (selected_drive < 2)
|
||||
{ data |= 8;
|
||||
enable_start = 0;
|
||||
disable_start = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data |= 16;
|
||||
|
||||
bool motor_on = false;
|
||||
if (selected_drive < 2)
|
||||
{
|
||||
motor_on = true;
|
||||
data |= 8;
|
||||
}
|
||||
enable_start = 2;
|
||||
disable_start = 4;
|
||||
}
|
||||
|
||||
if (selected_drive > 1)
|
||||
{
|
||||
motor_on = true;
|
||||
data |= 16;
|
||||
|
||||
enable_start = 2;
|
||||
disable_start = 4;
|
||||
}
|
||||
|
||||
if (motor_on)
|
||||
{
|
||||
// RX-50 has head A and head B (1 for each of the 2 disk slots in a RX-50).
|
||||
// Assume the other one is switched off -
|
||||
for (int f_num = 0; f_num < MAX_FLOPPIES; f_num++)
|
||||
{
|
||||
floppy_connector *con = machine().device<floppy_connector>(names[f_num]);
|
||||
floppy_image_device *tmp_floppy = con->get_device();
|
||||
floppy_connector *con = machine().device<floppy_connector>(names[f_num]);
|
||||
floppy_image_device *tmp_floppy = con->get_device();
|
||||
|
||||
tmp_floppy->mon_w(ASSERT_LINE);
|
||||
if ((f_num >= enable_start) && (f_num < disable_start))
|
||||
tmp_floppy->mon_w(CLEAR_LINE); // enable
|
||||
tmp_floppy->mon_w(ASSERT_LINE);
|
||||
if ((f_num >= enable_start) && (f_num < disable_start))
|
||||
tmp_floppy->mon_w(CLEAR_LINE); // enable
|
||||
}
|
||||
}
|
||||
|
||||
data = (data & (255 - 3)); // invalid drive = DRIVE 0 ?!
|
||||
|
||||
if (m_unit == INVALID_DRIVE)
|
||||
if (m_present_drive == INVALID_DRIVE)
|
||||
printf("\n**** INVALID DRIVE ****");
|
||||
else
|
||||
data = data | m_unit;
|
||||
data = data | m_present_drive;
|
||||
|
||||
m_z80_diskcontrol = data;
|
||||
}
|
||||
@ -2528,8 +2515,9 @@ IRQ_CALLBACK_MEMBER(rainbow_state::irq_callback)
|
||||
if (i == IRQ_8088_VBL) // If VBL IRQ acknowledged...
|
||||
m_crtc->MHFU(MHFU_RESET); // ...reset counter (also: DC012_W)
|
||||
|
||||
if (i == IRQ_COMM_PTR_INTR_L)
|
||||
m_mpsc->m1_r(); // serial interrupt acknowledge
|
||||
// Edstrom: "The call to m1_r() on line 2571 is not needed as the 7201 does not have an M1 input, instead it expects to get a software iack."
|
||||
// if (i == IRQ_COMM_PTR_INTR_L)
|
||||
// m_mpsc->m1_r(); // serial interrupt acknowledge
|
||||
|
||||
intnum = vectors[i] | m_irq_high;
|
||||
break;
|
||||
@ -2771,8 +2759,9 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
|
||||
// Install 8088 read / write handler once loopback test is over
|
||||
if ( !(data & 32) && (m_diagnostic & 32) )
|
||||
{
|
||||
io.install_readwrite_handler(0x40, 0x43, READ8_DEVICE_DELEGATE(m_mpsc, upd7201_device,cd_ba_r), WRITE8_DEVICE_DELEGATE(m_mpsc, upd7201_device, cd_ba_w) );
|
||||
io.install_readwrite_handler(0x40, 0x43, READ8_DEVICE_DELEGATE(m_mpsc, upd7201_new_device,cd_ba_r), WRITE8_DEVICE_DELEGATE(m_mpsc, upd7201_new_device, cd_ba_w) );
|
||||
printf("\n **** COMM HANDLER INSTALLED **** ");
|
||||
//popmessage("Autoboot from drive %c", m_p_nvram[0xab] ? (64 + m_p_nvram[0xab]) : 0x3F );
|
||||
}
|
||||
|
||||
// BIT 6: Transfer data from volatile memory to NVM (PROGRAM: 1 => 0 BIT 6)
|
||||
@ -2818,26 +2807,12 @@ WRITE_LINE_MEMBER(rainbow_state::write_keyboard_clock)
|
||||
m_kbd8251->write_rxc(state);
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::motor_tick)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::hd_motor_tick)
|
||||
{
|
||||
if (m_POWER_GOOD)
|
||||
m_crtc->MHFU(MHFU_COUNT); // // Increment IF ENABLED and POWER_GOOD, return count
|
||||
|
||||
m_hdc_index_latch = true; // HDC drive index signal (not working ?)
|
||||
|
||||
if (MOTOR_DISABLE_counter)
|
||||
MOTOR_DISABLE_counter--;
|
||||
|
||||
if (MOTOR_DISABLE_counter < 2)
|
||||
{
|
||||
output().set_value("driveled0", 0); // DRIVE 0 (A)
|
||||
output().set_value("driveled1", 0); // DRIVE 1 (B)
|
||||
output().set_value("driveled2", 0); // DRIVE 2 (C)
|
||||
output().set_value("driveled3", 0); // DRIVE 3 (D)
|
||||
|
||||
output().set_value("led1", 1); // 1 = OFF (One of the CPU LEDs as DRIVE LED)
|
||||
output().set_value("led2", 1); // 1 = OFF (One of the CPU LEDs as DRIVE LED)
|
||||
}
|
||||
}
|
||||
|
||||
// on 100-B, DTR from the keyboard 8051 controls bit 7 of IRQ vectors
|
||||
@ -3026,12 +3001,11 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
|
||||
|
||||
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_COLOR_MAP ) // 0x20
|
||||
{
|
||||
m_color_map_changed = true;
|
||||
|
||||
m_GDC_COLOR_MAP[m_GDC_color_map_index++] = ~data; // tilde data verified by DIAGNOSTIC!
|
||||
if(m_GDC_color_map_index == 32)
|
||||
{
|
||||
m_GDC_color_map_index = 0; // 0...31 (CPU accesses 32 bytes
|
||||
m_color_map_changed = true;
|
||||
|
||||
printf("\n * COLOR MAP FULLY LOADED *");
|
||||
for(int zi =0; zi <16; zi++)
|
||||
@ -3074,7 +3048,6 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
|
||||
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN)
|
||||
{
|
||||
// NOTE : Pattern Multiplier MUST BE LOADED before (!)
|
||||
OPTION_RESET_PATTERNS
|
||||
m_vpat = data;
|
||||
break;
|
||||
}
|
||||
@ -3183,7 +3156,8 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
|
||||
case 5: // 55h Write Mask HIGH
|
||||
m_GDC_WRITE_MASK = ( m_GDC_WRITE_MASK & 0xFF00 ) | BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -3263,6 +3237,8 @@ MCFG_SCREEN_UPDATE_DEVICE("upd7220", upd7220_device, screen_update)
|
||||
MCFG_FD1793_ADD(FD1793_TAG, XTAL_24_0734MHz / 24) // no separate 1 Mhz quartz
|
||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":0", rainbow_floppies, "525qd0", rainbow_state::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525qd1", rainbow_state::floppy_formats)
|
||||
//MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525qd2", rainbow_state::floppy_formats)
|
||||
//MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "525qd3", rainbow_state::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_state::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_state::floppy_formats)
|
||||
MCFG_SOFTWARE_LIST_ADD("flop_list", "rainbow")
|
||||
@ -3312,28 +3288,30 @@ MCFG_COM8116_FR_HANDLER(WRITELINE(rainbow_state, com8116_b_fr_w))
|
||||
MCFG_COM8116_FT_HANDLER(WRITELINE(rainbow_state, com8116_b_ft_w))
|
||||
|
||||
MCFG_UPD7201_ADD("upd7201", XTAL_2_5MHz, 0, 0, 0, 0) // 2.5 Mhz from schematics
|
||||
MCFG_Z80DART_OUT_INT_CB(WRITELINE(rainbow_state, mpsc_irq))
|
||||
MCFG_Z80SIO_OUT_INT_CB(WRITELINE(rainbow_state, mpsc_irq))
|
||||
|
||||
MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd))
|
||||
MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr))
|
||||
MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_rts))
|
||||
MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd))
|
||||
MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr))
|
||||
MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_rts))
|
||||
|
||||
MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd))
|
||||
MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_dtr))
|
||||
MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_rts))
|
||||
MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd))
|
||||
MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_dtr))
|
||||
MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_rts))
|
||||
|
||||
MCFG_RS232_PORT_ADD("rs232_a", default_rs232_devices, nullptr)
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, rxa_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_device, ctsa_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, dcda_w))
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, rxa_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, ctsa_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, dcda_w))
|
||||
|
||||
MCFG_RS232_PORT_ADD("rs232_b", default_rs232_devices, nullptr)
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, rxb_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_device, ctsb_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, dcdb_w))
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, rxb_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, ctsb_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, dcdb_w))
|
||||
|
||||
MCFG_DEVICE_MODIFY("rs232_a")
|
||||
MCFG_SLOT_DEFAULT_OPTION("null_modem")
|
||||
MCFG_SLOT_OPTION_ADD("microsoft_mouse", MSFT_SERIAL_MOUSE)
|
||||
MCFG_SLOT_OPTION_ADD("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE)
|
||||
MCFG_SLOT_DEFAULT_OPTION("microsoft_mouse")
|
||||
|
||||
MCFG_DEVICE_MODIFY("rs232_b")
|
||||
MCFG_SLOT_DEFAULT_OPTION("printer")
|
||||
@ -3349,7 +3327,7 @@ MCFG_LK201_TX_HANDLER(DEVWRITELINE("kbdser", i8251_device, write_rxd))
|
||||
MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4800 * 16) // 8251 is set to /16 on the clock input
|
||||
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(rainbow_state, write_keyboard_clock))
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("motor", rainbow_state, motor_tick, attotime::from_hz(60))
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("motor", rainbow_state, hd_motor_tick, attotime::from_hz(60))
|
||||
|
||||
MCFG_NVRAM_ADD_0FILL("nvram")
|
||||
MACHINE_CONFIG_END
|
||||
@ -3462,3 +3440,4 @@ ROM_END
|
||||
COMP(1982, rainbow100a, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 100-A", MACHINE_IS_SKELETON)
|
||||
COMP(1983, rainbow, 0, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 100-B", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS)
|
||||
COMP(1985, rainbow190, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 190-B", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_COLORS)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user