summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar Bavarese <Bavarese@users.noreply.github.com>2018-12-05 17:22:52 +0100
committerGravatarGravatar R. Belmont <rb6502@users.noreply.github.com>2018-12-05 11:22:52 -0500
commit2d9895e7bdfe68df8ba9f0f37d254f6a550f3fb3 (patch) (github)
tree5d6bfdc829c9469d3900bf31808eb13df63f6fc5
parent29ff589d2197794f3cea3e4a5821e33150f07c5a (diff)
downloadmame-2d9895e7bdfe68df8ba9f0f37d254f6a550f3fb3.tar.bz2
mame-2d9895e7bdfe68df8ba9f0f37d254f6a550f3fb3.zip
[Rainbow-100]: correct palette problems and silence log output (#4373)
* Correct palette problems and silence log output Monitor autodetection avoids false colors [on a real machine, this would require rewiring]. Corrected palette problems (non-working flag). Also, video levels from DEC's documentation turned out too dark. Converted printf to logerror. * Old_palette removed * More fixes that slipped through (NW) * Update rainbow.cpp * Update rainbow.cpp
-rw-r--r--src/mame/drivers/rainbow.cpp299
1 files changed, 154 insertions, 145 deletions
diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp
index 7dfcab165bb..85d5574e7ca 100644
--- a/src/mame/drivers/rainbow.cpp
+++ b/src/mame/drivers/rainbow.cpp
@@ -4,8 +4,8 @@
DEC Rainbow 100
Driver-in-progress by R. Belmont and Miodrag Milanovic.
-Keyboard & GDC fixes by Cracyc (June - Nov. 2016), Baud rate generator by Shattered (July 2016)
-Portions (2013 - 2016) by Karl-Ludwig Deisenhofer (Floppy, ClikClok RTC, NVRAM, DIPs, hard disk, Color Graphics).
+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).
@@ -24,7 +24,7 @@ PLEASE USE THE RIGHT SLOT - AND ALWAYS SAVE YOUR DATA BEFORE MOUNTING FOREIGN DI
You * should * also reassign SETUP (away from F3, where it sits on a LK201).
DATA LOSS POSSIBLE: when in partial emulation mode, F3 performs a hard reset!
-STATE AS OF JANUARY 2017
+STATE AS OF DECEMBER 2018
------------------------
Driver is based entirely on the DEC-100 'B' variant (DEC-190 and DEC-100 A models are treated as clones).
While this is OK for the compatible -190, it doesn't do justice to ancient '100 A' hardware.
@@ -103,17 +103,15 @@ COLOR EMULATION (NEC 7220 + extra hardware)
Palette takes 2 byte per palette entry. CLUT ("color map") is 32 byte long.
------------------------------------------------------------------------------------------------
-THE DEC 'R-M-B' COLOR CABLE VS. THE UNOFFICIAL 'R-G-B' MODE (A BIT OF HISTORY)
- The standard DEC "color cable" connected the green gun of a VR241 to the mono output of the Rainbow
- (DIP setting COLOR_MONITOR).
-
- An unofficial DIY cable enabled R-G-B graphics + seperate text (emulated by DIP setting DUAL MONITOR).
- As DEC decided not to endorse R-G-B, many commercial programs show incorrect colors.
- A patch from one of the archives corrects the GWBASIC palette problem when using 2 monitors [Bavarese].
+DEC 'R-M-B' COLOR CABLE VS. THE UNOFFICIAL 'R-G-B' MODE (a bit of history)
+ (1) the standard DEC "color cable" connected the green gun of a VR241 to the mono output of the Rainbow
+ (2) an unofficial DIY cable enabled R-G-B graphics + seperate text
EMULATION SPECIFIC
- DUAL MONITOR enables both screens, even if onboard graphics has been accidently shut off
- (helps debugging semi broken programs, for example Doodle).
+ (1) COLOR_MONITOR reflects DEC's recommendation (R-M-B with VR241 above)
+ (2) DUAL MONITOR enables both screens, even if onboard graphics has been accidently shut off
+ (also helps debugging semi broken programs, for example Doodle).
+ (3) AUTODETECT (DIP setting) snoops the color palette and chooses the correct 'wiring'
SCREEN 1 vs. SCREEN 2 IN EMULATION
All GDC 7220 output is displayed on the right. Be it color or monochrome, Option Graphics output is on screen 2.
@@ -145,16 +143,6 @@ UNKNOWN IMPLEMENTATION DETAILS:
To obtain pixel exact graphics use 'Graphics Only' in Video Options and cmd.line switches -nowindow -aspect1 auto -nokeepaspect
(Over-Under or Side-by-Side modes always distorted on my 1600 x 900 laptop)
-Programs with initialization / redraw / reentrance problems (invocation order after reset matters in emulation):
-
-- Canon (high resolution + vectors), Solitaire (SOLIT.EXE) and GDEMO (from GRPHCS.ARC, interactive graphics interpreter '85),
- plus 'Monitor Aligment' (from the GDC test disk). Sloppy programming or a bug related to a) to e)...?
-
- Quote from Haze: "if you have 2 screens running at different refresh rates one of them won't update properly
- (the partial update system gets very confused because it expects both the screens to end at the same time
- and if that isn't the case large parts of one screen end up not updating at all)
-
-The following games work well: Tetris, Pacman, MasterMind (MMIND), (G)otelo (needs GSX), Scram (uses scroll extensively).
CURRENTY UNEMULATED
-------------------
@@ -469,11 +457,6 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
#define COMPLEMENT_MODE 16
#define OVERLAY_MODE 32
-// MONITOR CONFIGURATION (DIP SWITCH!):
-#define MONO_MONITOR 0x01
-#define COLOR_MONITOR 0x02
-#define DUAL_MONITOR 0x03
-
// ----------------------------------------------------------------------------------------------
#define LK201_TAG "lk201"
#define FD1793_TAG "fd1793x"
@@ -481,6 +464,12 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
#define INVALID_DRIVE 255
#define MAX_FLOPPIES 4
+// Monitor configurations -> see DIP switches. New: auto-detect color palette (last option).
+static constexpr int MONO_MONITOR = 0x01; // Tetris-M and Pacman-M need this setting (no auto-detection)
+static constexpr int COLOR_MONITOR = 0x02; // DEC recommendation. GWBASIC and most old libraries. Superseded by later development
+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
{
public:
@@ -718,11 +707,12 @@ private:
uint8_t m_vpat, m_patmult, m_patcnt, m_patidx;
uint16_t m_GDC_WRITE_MASK;
- bool m_color_map_changed;
- bool m_ONBOARD_GRAPHICS_SELECTED; // (internal switch, on board video to mono out)
+ bool m_ONBOARD_GRAPHICS_SELECTED; // (internal switch, on board video to mono out)
bool m_SCREEN_BLANK;
+ uint8_t m_monitor_suggested;
+
int INT88, INTZ80;
bool m_zflip; // Z80 alternate memory map with A15 inverted
@@ -773,7 +763,6 @@ 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 };
};
@@ -795,10 +784,9 @@ if(m_patidx == 0) m_patidx = 7;
// GDC RESET MACRO - used in "machine_reset" & GDC_EXTRA_REGISTER_w !
#define OPTION_GRFX_RESET \
lower_8088_irq(IRQ_GRF_INTR_L); \
-m_PORT50 = 0; \
+m_monitor_suggested = m_inp13->read(); \
m_GDC_INDIRECT_REGISTER = 0; \
m_GDC_color_map_index = 0; \
-m_color_map_changed = true; \
for(int i=0; i <256; i++) { m_GDC_SCROLL_BUFFER[i] = i; }; \
m_GDC_scroll_index = 0; \
m_GDC_write_buffer_index = 0; \
@@ -807,7 +795,7 @@ m_GDC_ALU_PS_REGISTER = 0x0F; \
m_GDC_FG_BG = 0xF0; \
m_GDC_MODE_REGISTER &= GDC_MODE_VECTOR | GDC_MODE_HIGHRES | GDC_MODE_ENABLE_WRITES | GDC_MODE_READONLY_SCROLL_MAP;\
m_GDC_MODE_REGISTER |= GDC_MODE_ENABLE_VIDEO; \
-printf("\n** OPTION GRFX. RESET **\n");
+logerror("\n** OPTION GRFX. RESET **\n");
UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
{
@@ -817,7 +805,7 @@ UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
uint16_t plane0, plane1, plane2, plane3;
uint8_t pen;
- if(m_ONBOARD_GRAPHICS_SELECTED && (m_inp13->read() != DUAL_MONITOR) )
+ if(m_ONBOARD_GRAPHICS_SELECTED && (m_inp13->read() != DUAL_MONITOR) )
{
for(xi=0;xi<16;xi++) // blank screen when VT102 output active (..)
{
@@ -846,7 +834,7 @@ UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
plane3 = m_video_ram[((address & 0x3fff) + 0x30000) >> 1];
}
- bool mono = (m_inp13->read() == MONO_MONITOR) ? true : false; // 1 = MONO, 2 = COLOR, 3 = DUAL MONITOR
+ bool mono = (m_monitor_suggested == MONO_MONITOR) ? true : false; // 1 = MONO, 2 = COLOR, 3 = DUAL MONITOR; 4 = AUTO
for(xi=0;xi<16;xi++)
{
@@ -986,9 +974,8 @@ 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, 0x55).rw(FUNC(rainbow_state::GDC_EXTRA_REGISTER_r), FUNC(rainbow_state::GDC_EXTRA_REGISTER_w));
- map(0x56, 0x57).rw(m_hgdc, FUNC(upd7220_device::read), FUNC(upd7220_device::write)); // 56 param, 57 command
-
+ map(0x50, 0x57).rw(FUNC(rainbow_state::GDC_EXTRA_REGISTER_r), FUNC(rainbow_state::GDC_EXTRA_REGISTER_w));
+
// ===========================================================
// 0x60 -> 0x6f ***** EXTENDED COMM. OPTION / Option Select 2.
// ===========================================================
@@ -1140,7 +1127,8 @@ static INPUT_PORTS_START(rainbow100b_in)
PORT_DIPSETTING(0x01, DEF_STR(On))
PORT_START("MONITOR CONFIGURATION") // GDC
- PORT_DIPNAME(0x03, 0x03, "MONITOR CONFIGURATION")
+ PORT_DIPNAME(0x0F, 0x04, "MONITOR CONFIGURATION")
+ PORT_DIPSETTING(0x04, "AUTODETECT")
PORT_DIPSETTING(0x01, "MONO ONLY / 4 to 16 monochrome shades (single VR-201)")
PORT_DIPSETTING(0x02, "COLOR ONLY (single VR-241 with BCC-17 cable)")
PORT_DIPSETTING(0x03, "DUAL MONITOR (SCREEN 1: TEXT; SCREEN 2: R-G-B)")
@@ -1201,7 +1189,7 @@ void rainbow_state::machine_reset()
if(END_OF_RAM > unmap_start)
{
- printf("\nUnmapping from %x to %x",unmap_start, END_OF_RAM);
+ logerror("\nUnmapping from %x to %x",unmap_start, END_OF_RAM);
program.unmap_readwrite(unmap_start, END_OF_RAM);
}
@@ -1258,12 +1246,10 @@ void rainbow_state::machine_reset()
// *********** NEC 7220 DISPLAY CONTROLLER [ OPTIONAL ]
OPTION_GRFX_RESET
-
OPTION_RESET_PATTERNS
for(int i=0; i <32; i++) { m_GDC_COLOR_MAP[i] = 0x00; };
m_GDC_color_map_index = 0;
- m_color_map_changed = true;
// *********** Z80
m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
@@ -1344,13 +1330,20 @@ void rainbow_state::device_timer(emu_timer &timer, device_timer_id tid, int para
uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- static int old_palette, old_monitor;
+ static int old_monitor;
- int monitor_selected = m_inp13->read();
- if(monitor_selected != old_monitor)
+ if((m_monitor_suggested < 1) || (m_monitor_suggested > 3))
+ m_monitor_suggested = COLOR_MONITOR;
+
+ if(m_monitor_suggested != old_monitor)
{
- old_monitor = monitor_selected;
- m_color_map_changed = true;
+ old_monitor = m_monitor_suggested;
+ if(m_monitor_suggested == 1)
+ popmessage("MONOCHROME MONITOR");
+ if(m_monitor_suggested == 2)
+ popmessage("COLOR MONITOR");
+ if(m_monitor_suggested == 3)
+ popmessage("DUAL MONITOR");
}
int palette_selected;
@@ -1359,16 +1352,11 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1
else
palette_selected = m_inp9->read();
- if(palette_selected != old_palette)
- {
- old_palette = palette_selected;
- m_color_map_changed = true;
- }
-
m_crtc->palette_select(palette_selected);
+ m_crtc->video_update(bitmap, cliprect);
if( m_SCREEN_BLANK ||
- ( (!m_ONBOARD_GRAPHICS_SELECTED) && (monitor_selected != DUAL_MONITOR) ) // blank screen 1, except when in DUAL_MONITOR mode
+ ( (!m_ONBOARD_GRAPHICS_SELECTED) && (m_inp13->read() != DUAL_MONITOR) ) // dual monitor: never blank all
)
m_crtc->video_blanking(bitmap, cliprect);
else
@@ -2370,7 +2358,7 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r)
if ( fdc_ready && ((fdc_status & 0x40) == 0) && m_POWER_GOOD )
fdc_write_gate = 1; // "valid only when drive is selected" !
}
-
+ //logerror(" RDY:%x WG:%d ",fdc_ready,fdc_write_gate);
int data = (
((fdc_step) ? 0x00 : 0x80) |
((fdc_write_gate) ? 0x00 : 0x40) |
@@ -2572,17 +2560,16 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
else
lower_8088_irq(IRQ_GRF_INTR_L);
- uint8_t red, green, blue, mono;
- int xi;
+ uint8_t xi, red, green, blue, mono;
- if(m_color_map_changed)
- {
- m_color_map_changed = false;
+ m_monitor_suggested = m_inp13->read();
+ if((m_monitor_suggested < 1) || (m_monitor_suggested > 3))
+ m_monitor_suggested = COLOR_MONITOR;
- int mono_sum = 0;
- int green_sum = 0;
- for(xi=0;xi<16;xi++) // DELAYED LOAD OF PALETTE ...
- {
+ int mono_sum = 0;
+ int green_sum = 0;
+ for(xi=0;xi<16;xi++) // DELAYED LOAD OF PALETTE ...
+ {
uint8_t colordata1 = m_GDC_COLOR_MAP[xi];
uint8_t colordata2 = m_GDC_COLOR_MAP[xi + 16]; // Does it matter if the palette is incomplete...?
@@ -2602,62 +2589,62 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
green =(colordata1 & 0x0F);
green_sum += green;
- switch( m_inp13->read())
+ switch( m_monitor_suggested )
{
case MONO_MONITOR:
{
- switch( m_inp9->read() ) // - monochrome monitor (phosphor) type (1,2,3)
+ switch( m_inp9->read() ) // - monochrome monitor (phosphor) type (1,2,3)
{
case 1: // BLACK & WHITE
- mono = uint8_t( ( 205.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
- m_palette2->set_pen_color(xi + 16, rgb_t( mono, mono, mono) );
+ m_palette2->set_pen_color(xi + 16, pal4bit(mono), pal4bit(mono), pal4bit(mono) );
break;
- case 2: // SHADES OF GREEN
- red = uint8_t( ( 35.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) ); // 80 % = NORMAL *
- green = uint8_t( (145.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
- blue = uint8_t( ( 75.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
- m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
+ case 2: // GREEN SHADES. Hand picked value from vtvideo coarsly transformed into a RGB value:
+ red = uint8_t( ( 35.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ green = uint8_t( (145.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ blue = uint8_t( ( 75.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
break;
case 3: // AMBER. Assumption: "normal" value at 80 % is 213, 146, 82 (decimal)
- red = uint8_t( (213.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) ); // 80 % = NORMAL * is 3.19f (100 % would be 2.55f)
- green = uint8_t( (146.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
- blue = uint8_t( ( 82.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
- m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
+ red = uint8_t( (213.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ green = uint8_t( (146.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ blue = uint8_t( ( 82.0f / 100.0f) * ( video_levels[ mono ] / 2.55f) );
+ m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
break;
}
break;
}
case COLOR_MONITOR:
-
if(!(m_GDC_MODE_REGISTER & GDC_MODE_ENABLE_VIDEO))
- red = blue = 0; // Page 21 of PDF AA-AE36A (PDF) explains why
- red = uint8_t( red * 17 * ( (255-video_levels[ red ] ) / 255.0f) );
- green = uint8_t( mono * 17 * ( (255-video_levels[ mono ]) / 255.0f) ); // BCC-17 cable (red, mono -> green, blue)
- blue = uint8_t( blue * 17 * ( (255-video_levels[ blue ] ) / 255.0f) );
- m_palette2->set_pen_color(xi, rgb_t( red, green, blue) );
+ red = blue = 0; // Page 21 of AA-AE36A (PDF) explains why
+
+ m_palette2->set_pen_color(xi, pal4bit( red ) , pal4bit( mono ) , pal4bit( blue ) );
break;
case DUAL_MONITOR:
- red = uint8_t( red * 17 * ( (255-video_levels[ red ] ) / 255.0f) );
- green = uint8_t( green * 17 * ( (255-video_levels[ green ]) / 255.0f) ); // true R-G-B (homebrew cable only)
- blue = uint8_t( blue * 17 * ( (255-video_levels[ blue ] ) / 255.0f) );
- m_palette2->set_pen_color(xi, rgb_t( red, green, blue) );
+ m_palette2->set_pen_color(xi, pal4bit( red ), pal4bit( green ), pal4bit( blue ) );
break;
}
- } // palette (loop)
+ } // palette (loop)
- if(mono_sum == 0)
- if ( m_inp13->read() == COLOR_MONITOR)
- printf(" [HINT: COLOR MONITOR (DIP SWITCH) WRONG! NO MONO PALETTE] ");
+ if( (green_sum >0) && (green_sum == mono_sum) ) // (R-G-B + M) palette (split cable). Examples: PACMAN, AutoCad
+ {
+ if(m_monitor_suggested == MONO_MONITOR)
+ logerror("\n[HINT: COLOR PALETTE DETECTED - SUITABLE FOR DUAL MONITOR] ");
+ if(m_inp13->read() == AUTODETECT_MONITOR)
+ m_monitor_suggested = DUAL_MONITOR;
+ }
- if(green_sum == 0)
- if ( m_inp13->read() == DUAL_MONITOR)
- printf(" [HINT: DUAL MONITOR (DIP SWITCH) WRONG! NO GREEN PALETTE] ");
- } // color map changed?
+ if((green_sum == 0) && (mono_sum > 0)) // No green = original DEC spec. Example: NLANDER. All older libaries use R-M-B.
+ {
+ if(m_inp13->read() == AUTODETECT_MONITOR)
+ m_monitor_suggested = COLOR_MONITOR;
+ if (m_monitor_suggested == DUAL_MONITOR)
+ logerror("\n[HINT: SINGLE COLOR MONITOR ONLY! GREEN MISSING => NO SPLIT CABLE]");
+ }
} // 7220 vblank IRQ
@@ -2694,7 +2681,7 @@ READ8_MEMBER(rainbow_state::diagnostic_r) // 8088 (port 0A READ). Fig.4-29 + tab
WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 + table 4-15
{
- // printf("%02x to diag port (PC=%x)\n", data, m_i8088->pc());
+ // logerror("%02x to diag port (PC=%x)\n", data, m_i8088->pc());
// ZRESET from 8088 to Z80 - - HIGH at powerup!
if (!(data & 1))
@@ -2738,12 +2725,12 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
{ printf("\nALARM: GRAPHICS OPTION * SWITCHED OFF * VIA DIP. TEXT OUTPUT STILL ENABLED!\n");
m_ONBOARD_GRAPHICS_SELECTED = true;
}
- printf("DATA: %x (PC=%x)\n", data, m_i8088->pc());
+ logerror("DATA: %x (PC=%x)\n", data, m_i8088->pc());
}
// BIT 3: PARITY (1 enables parity test on memory board. Usually 64K per bank). -> ext_ram_w.
if(data & 0x08)
- printf("\n*** PARITY TEST [on RAM EXTENSION] - (bit 3 - diagnostic_w) ");
+ logerror("\n*** PARITY TEST [on RAM EXTENSION] - (bit 3 - diagnostic_w) ");
// MISSING BITS (* not vital for normal operation, see diag.disk) -
// * BIT 4: DIAG LOOPBACK (0 at power-up; 1 directs RX50 and DC12 output to printer port)
@@ -2769,7 +2756,7 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
*/
if (data & 16)
{
- printf("\nWARNING: UNEMULATED DIAG LOOPBACK (directs RX50 and DC12 output to printer port) **** ");
+ logerror("\nWARNING: UNEMULATED DIAG LOOPBACK (directs RX50 and DC12 output to printer port) **** ");
}
address_space &io = m_i8088->space(AS_IO);
@@ -2782,7 +2769,7 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
PRT RCV DATA.......KBD TXD...........PRT RDATA
KBD RCV DATA.......PRT TXD...........KBD RXD
*/
- printf("\nWARNING: UNEMULATED PORT LOOPBACK (COMM, PRINTER, KEYBOARD ports) **** ");
+ logerror("\nWARNING: UNEMULATED PORT LOOPBACK (COMM, PRINTER, KEYBOARD ports) **** ");
io.unmap_readwrite(0x40, 0x43); // unmap MPSC handlers to prevent CPU crashes ("INTERRUPTS OFF")
}
@@ -2791,7 +2778,7 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
if ( !(data & 32) && (m_diagnostic & 32) )
{
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 **** ");
+ logerror("\n **** COMM HANDLER INSTALLED **** ");
//popmessage("Autoboot from drive %c", m_p_nvram[0xab] ? (64 + m_p_nvram[0xab]) : 0x3F );
}
@@ -2870,11 +2857,11 @@ READ16_MEMBER(rainbow_state::vram_r)
int readback_plane = 0;
if( !(m_GDC_MODE_REGISTER & GDC_MODE_ENABLE_WRITES) ) // 0x10 // READBACK OPERATION - if ENABLE_WRITES NOT SET
- readback_plane = (m_GDC_MODE_REGISTER & GDC_MODE_READBACK_PLANE_MASK) >> 2; // READBACK PLANE 00..02, mask in bits 2+3
+ readback_plane = (m_GDC_MODE_REGISTER & GDC_MODE_READBACK_PLANE_MASK) >> 2; // READBACK PLANE 00..02, mask in bits 2+3
return m_video_ram[ (offset & 0x7fff) + (0x8000 * readback_plane)];
}
- return 0xffff;
+ return 0xffff;
}
// NOTE: Rainbow has separate registers for fore and background.
@@ -2891,7 +2878,7 @@ WRITE16_MEMBER(rainbow_state::vram_w)
if(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR) // VT240 : if(SELECT_VECTOR_PATTERN_REGISTER)
{
chr = bitswap<8>(m_vpat, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx);
- chr |= (chr << 8);
+ chr |= (chr << 8);
if(m_patcnt-- == 0)
{
m_patcnt = m_patmult;
@@ -2918,15 +2905,15 @@ WRITE16_MEMBER(rainbow_state::vram_w)
for(int i = 0; i <= 3; i++)
{
- if( BIT(ps,i ) )
+ if( BIT(ps,i ) ) // 1 means don't touch (bits already inverted)
{
- uint16_t mem = m_video_ram[(offset & 0xffff) + (0x8000 * i)]; // VT240
+ uint16_t mem = m_video_ram[(offset & 0xffff) + (0x8000 * i)];
uint16_t out = 0; // VT240 : uint8_t
for(int j = 0; j <= 15; j++) // REPLACE MODE : one replaced by FG, zero by BG ( 16 instead of 8 bit on VT240 )
out |= BIT(chr, j) ? ((fore & 1) << j) : ((back & 1) << j);
- switch (m_GDC_ALU_PS_REGISTER & ALU_PS_MODE_MASK)
+ switch ((m_GDC_ALU_PS_REGISTER) & ALU_PS_MODE_MASK)
{
case OVERLAY_MODE: // (OR)
out |= mem;
@@ -2941,9 +2928,9 @@ WRITE16_MEMBER(rainbow_state::vram_w)
}
if(!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR)) // 0 : Text Mode and Write Mask Batch
- out = (out & ~m_GDC_WRITE_MASK) | (mem & m_GDC_WRITE_MASK); // // M_MASK (1st use)
+ out = (out & ~m_GDC_WRITE_MASK) | (mem & m_GDC_WRITE_MASK);
else
- out = (out & ~data) | (mem & data); // vector mode
+ out = (out & ~data) | (mem & data);
if(m_GDC_MODE_REGISTER & GDC_MODE_ENABLE_WRITES) // 0x10
m_video_ram[(offset & 0xffff) + (0x8000 * i)] = out;
@@ -2954,37 +2941,45 @@ WRITE16_MEMBER(rainbow_state::vram_w)
} // plane select (LOOP)
return;
- }
+ } // if enable_writes
}
// (READ)
// Read scroll buffer (see GDC Diagnostic Disk, SCROLL BUFFER test)
READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
{
- uint8_t out = 0;
+ uint8_t data = 0;
switch(offset)
{
case 0:
- out = m_PORT50;
+ data = m_GDC_MODE_REGISTER; // ?
break;
case 1:
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_SCROLL_MAP ) // 0x80
{
// Documentation says it is always incremented (read and write):
- out = m_GDC_SCROLL_BUFFER[m_GDC_scroll_index++]; // // * READ * SCROLL_MAP ( 256 x 8 )
+ data = m_GDC_SCROLL_BUFFER[m_GDC_scroll_index++]; // // * READ * SCROLL_MAP ( 256 x 8 )
m_GDC_scroll_index &= 0xFF; // 0...255 (CPU accesses 256 bytes)
break;
}
else
- printf("\n * UNEXPECTED CASE: READ REGISTER 50..55 with INDIRECT_REGISTER $%02x and OFFSET $%02x *", m_GDC_INDIRECT_REGISTER, offset);
+ logerror("\n * UNEXPECTED CASE: READ REGISTER 50..55 with INDIRECT_REGISTER $%02x and OFFSET $%02x *", m_GDC_INDIRECT_REGISTER, offset);
+ break;
+
+ case 6:
+ data = m_hgdc->read(space, offset & 0x00);
+ break;
+
+ case 7:
+ data = m_hgdc->read(space, offset & 0x01);
break;
default:
- printf("\n * UNHANDLED CASE: READ REGISTER 50..55 with INDIRECT_REGISTER $%02x and OFFSET $%02x *", m_GDC_INDIRECT_REGISTER, offset);
+ logerror("\n * UNHANDLED CASE: READ REGISTER 50..55 with INDIRECT_REGISTER $%02x and OFFSET $%02x *", m_GDC_INDIRECT_REGISTER, offset);
break;
} // switch
- return out;
+ return data;
}
WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
@@ -2997,7 +2992,7 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
if(last_message != 1)
{
popmessage("\nCOLOR GRAPHICS ADAPTER INVOKED. PLEASE TURN ON THE APPROPRIATE DIP SWITCH, THEN REBOOT.\n");
- printf("OFFSET: %x (PC=%x)\n", 0x50 +offset , m_i8088->pc());
+ logerror("OFFSET: %x (PC=%x)\n", 0x50 +offset , m_i8088->pc());
last_message = 1;
}
return;
@@ -3017,7 +3012,7 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
}
break;
- case 1: // 51h - DATA loaded into register previously written to 53h.
+ case 1: // 51h = DATA loaded into (a register previously addressed by a write to 53h)
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_WRITE_BUFFER) // 0x01
{
m_GDC_write_buffer_index = 0; // (writing to 51h CLEARS the index counter)
@@ -3030,7 +3025,6 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
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++)
@@ -3063,81 +3057,88 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
// -----------------PATTERN + MULTIPLIER USED IN VECTOR MODE ONLY!
// SEE PAGE 37 OF AA-AE36A (PDF).
- if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN_MULTIPLIER)
+ if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN_MULTIPLIER) // 0x02
{
// On a Rainbow, 12 indicates a multiplier of 16-12 = 4 (example)
m_patmult = 16 - (data & 15); // 4 bit register // VT240: "patmult_w"
break;
}
- if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN)
+ if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN) // 0x04
{
// NOTE : Pattern Multiplier MUST BE LOADED before (!)
m_vpat = data;
break;
}
- if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_FG_BG) // 2 x 4
+ if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_FG_BG) // 0x08
{
m_GDC_FG_BG = data; // Neither bitswap nor negated (and also not both)...
- break; // Next: prepare FG / BG and PLANE in ALU - PLANE_SELECT register.
+ break; // Next: prepare FG / BG (4 bits each) + plane in ALU - PLANE_SELECT register.
}
- if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_ALU_PS)
+ if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_ALU_PS) // 0x10
{
m_GDC_ALU_PS_REGISTER = ~data; // Negated...
break;
}
- if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_MODE_REGISTER)
+ if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_MODE_REGISTER) // 0x40
{
m_GDC_MODE_REGISTER = data; // Neither bitswap nor negated (and also not both)...
- if(last_message != 2)
+ if(data & GDC_MODE_HIGHRES) // 0x01
+ {
+ if(last_message != 2)
+ {
+ last_message = 2;
+ printf(" * HIGH RESOLUTION * ");
+ }
+ }
+ else
{
- last_message = 2;
-
- if(data & GDC_MODE_HIGHRES)
- printf(" * HIGH RESOLUTION * ");
- else
- printf(" MEDIUM RESOLUTION ");
+ if(last_message != 3)
+ {
+ last_message = 3;
+ printf(" MEDIUM RESOLUTION ");
+ }
}
- if(last_mode != (data & GDC_MODE_VECTOR))
+ if(last_mode != (data & GDC_MODE_VECTOR)) // 0x02
{
last_mode = data & GDC_MODE_VECTOR;
if(data & GDC_MODE_VECTOR)
- printf(" VECTOR MODE ");
+ logerror(" VECTOR MODE ");
else
- printf(" WORD MODE ");
+ logerror(" WORD MODE ");
}
- if(last_readback != (data & GDC_MODE_ENABLE_WRITES))
+ if(last_readback != (data & GDC_MODE_ENABLE_WRITES)) // 0x10
{
last_readback = data & GDC_MODE_ENABLE_WRITES;
if(data & GDC_MODE_ENABLE_WRITES) // 0x10
- printf(" READBACK: OFF - ENABLE_WRITES ");
+ logerror(" READBACK: OFF - ENABLE_WRITES ");
else // READBACK PLANE 00..02 - mask in bits 2+3:
- printf(" READBACK MODE; plane = %02x ", m_GDC_MODE_REGISTER & GDC_MODE_READBACK_PLANE_MASK); // unsure if PLANE is set... already?!
+ logerror(" READBACK MODE; plane = %02x ", m_GDC_MODE_REGISTER & GDC_MODE_READBACK_PLANE_MASK); // unsure if PLANE is set... already?!
}
if(last_scroll_index != m_GDC_scroll_index)
{
last_scroll_index = m_GDC_scroll_index;
if(data & GDC_MODE_READONLY_SCROLL_MAP) // 0x20
- { //printf(" SCROLL MAP READ_ONLY. Index : %02x ", m_GDC_scroll_index);
- } else
- { printf(" SCROLL MAP IS WRITABLE. Index : %02x ", m_GDC_scroll_index);
- }
+ logerror(" SCROLL MAP READ_ONLY. Index : %02x ", m_GDC_scroll_index);
+ else
+ logerror(" SCROLL MAP IS WRITABLE. Index : %02x ", m_GDC_scroll_index);
}
if(!(data & GDC_MODE_ENABLE_VSYNC_IRQ)) // 0x40
lower_8088_irq(IRQ_GRF_INTR_L); // also clears the interrupt
+ // case 0x80 : If this bit is a 1 red and blue outputs are enabled. If this bit is a 0 red and blue outputs are disabled (page 20 of AA-AE36A)
break;
} // GDC_SELECT_MODE_REGISTER
- printf("\n* UNIMPLEMENTED CASE. MODE = %02x / m_GDC_INDIRECT_REGISTER = %02x\n",m_GDC_MODE_REGISTER, m_GDC_INDIRECT_REGISTER);
+ logerror("\n* UNIMPLEMENTED CASE. MODE = %02x / m_GDC_INDIRECT_REGISTER = %02x\n",m_GDC_MODE_REGISTER, m_GDC_INDIRECT_REGISTER);
break;
case 2:
@@ -3161,12 +3162,15 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
m_GDC_color_map_index = 0; // (also clears the index counter)
// NEXT: 32 BYTE COLOR MAP, LOADED TO $51
+ //if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_MODE_REGISTER) // 0x40
+ // logerror(" *** SELECT MODE REGISTER");
+
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_SCROLL_MAP ) // 0x80
{
if(last_scroll_index != m_GDC_scroll_index)
{
last_scroll_index = m_GDC_scroll_index;
- printf(" *** SCROLL INDEX COUNTER RESET, old value = %d", m_GDC_scroll_index);
+ logerror(" *** SCROLL INDEX COUNTER RESET, old value = %d", m_GDC_scroll_index);
}
m_GDC_scroll_index = 0; // (also clears the index counter)
} // NEXT: LOAD 256 BYTE SCROLL MAP INTO $51
@@ -3181,6 +3185,11 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
case 5: // 55h Write Mask HIGH
m_GDC_WRITE_MASK = ( m_GDC_WRITE_MASK & 0xFF00 ) | bitswap<8>(data, 0, 1, 2, 3, 4, 5, 6, 7);
break;
+
+ case 6:
+ case 7:
+ m_hgdc->write(space, offset & 0x01, data);
+ break;
} // switch
}
@@ -3336,7 +3345,7 @@ MACHINE_CONFIG_START(rainbow_state::rainbow)
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));
-
+
LK201(config, m_lk201, 0);
m_lk201->tx_handler().set(m_kbd8251, FUNC(i8251_device::write_rxd));