summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/rainbow.cpp
diff options
context:
space:
mode:
author Bavarese <Bavarese@users.noreply.github.com>2016-12-05 15:16:30 +0100
committer GitHub <noreply@github.com>2016-12-05 15:16:30 +0100
commit65f752e4cb3932bee490a791ab4c30196b095d6a (patch)
tree7236440fa7645f53b528aa4ca479777b7f462fd6 /src/mame/drivers/rainbow.cpp
parent1e91807ebed80b9d3722f3a0e89c56c9a1a4677d (diff)
DEC Rainbow 100: scroll fully functional / address reentrace problems
Address reentrace problems (reset procedure). Make scroll fully functional (deeper SCRAM levels & GDC diag test #9). Details and credits: see driver.
Diffstat (limited to 'src/mame/drivers/rainbow.cpp')
-rw-r--r--src/mame/drivers/rainbow.cpp133
1 files changed, 77 insertions, 56 deletions
diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp
index 22fd8db8cee..db06c7ddf86 100644
--- a/src/mame/drivers/rainbow.cpp
+++ b/src/mame/drivers/rainbow.cpp
@@ -34,32 +34,38 @@ SCREEN 1 vs. SCREEN 2 IN EMULATION
// The type of monochrome monitor (VR-210 A, B or C) is selectable via another DIP (coarsly simulates a phosphor color).
BUGS
-- MEDRES and HIRES MODE APPEAR TO BE CORRECT
-- GDC diagnostic disk bails out on 9 of 13 tests (tests 4 and 6 - 13). Scroll check doesn't...
+- GDC diagnostic disk fails on 9 of 13 tests (tests 4 and 6 - 13).
-Interaction of Upd7220 and Rainbow.cpp:
-- RDAT with MOD 2 is unimplemented (other modes than 00). Effect of missing R-M-W...?
-Software to try: MMIND (MasterMind, after BMP logo), SOLIT (Solitaire), CANON (high resolution + vectors), GDC Test Disk.
+Details
+a. (Rainbow driver) : interaction between DEC's external hardware and the NEC 7220 isn't fully understood (see page 173 of AA-AE36A)
+ It is also unclear what port $50 actually does when it 'synchronizes R-M-W cycles'.
+ For now, we provide sane defaults for both vector and bitmap units without disturbing display mode(s) or the NEC 7220.
+b. the HBLANK / VBLANK ratio is plainly wrong (QUICK TEST / subtest #6),
+c. IRQs are flagged as 'erratic' (QUICK TEST / subtest #12).
+d. (7220) : incorrect fifo stati are handed out (GDC reports FIFO_EMPTY instead of _FULL when QUICK TEST #4 floods the queue)
+e. (7220) : RDAT with MOD 2 used extensively here, but unimplemented (modes other than 0 undocumented by NEC / Intel)
+
+Programs with initialization / redraw / reentrance problems (invocation order after reset * matters *, at least in emulation):
+- CANON (high resolution + vectors), Solitaire (SOLIT.EXE) and GDEMO (from GRPHCS.ARC, interactive graphics interpreter '85),
+ plus the Monitor Aligment Test (from the GDC test disk).
+
+Graphical apps. that work well: MMIND (MasterMind), PACMAN, SCRAM, (G)OTELO.
UNIMPLEMENTED:
// - Rainbow 100 A palette quirks (2 bit palette... applies to certain modes only)
UNKNOWN IMPLEMENTATION DETAILS:
-// a. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
-
-// b. SCROLL BUFFER details unclear. What happens when a programs does not write all 256 bytes? Value of uninitialized areas?
- Play, then retry (y) SCRAM to see the effect. Scram doesn't seem to write all (256) bytes, a GDC RESET is only executed ONCE.
- (PAGE 48 OF PDF HAS A SUPERFICIAL DESCRIPTION OF THE SCROLL BUFFER)
+// 1. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
-// c. UNVERIFIED DIVIDER (31.188 Mhz / 32) is at least close to 1 Mhz (as seen on the VT240)
+// 2. UNVERIFIED DIVIDER (31.188 Mhz / 32) is at least close to 1 Mhz (as on the VT240, which uses a very similar design)
-// d. UPD7220 / CORE oddities:
- * pixels are stretched out too wide at 384 x 240 (not fixable here). -KEEPASPECT?
+// 3. UPD7220 / CORE oddities:
+// 3.1. occasional redraw problems (only when screen 1 runs at 60 Hz and screen 2 at 29.99 Hz interlaced = HIRES ?).
+// 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)
-// * (MAME core): what happens when the left screen is at 50 Hz and the right at 60 Hz?
-// According to 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)
+ 3.2 pixels are stretched out too wide at 384 x 240 (not fixable in Rainbow driver, -keepaspect seems to have no effect)
*/
// license:GPL-2.0+
@@ -88,7 +94,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 DECE;BER 2016
+STATE AS OF DECEMBER 2016
-------------------------
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.
@@ -626,7 +632,6 @@ private:
uint8_t m_GDC_WRITE_BUFFER[16]; // 16 x 8 bits for CPU, 8 x 16 for GDC
uint8_t m_GDC_COLOR_MAP[32];
- uint8_t m_GDC_SCROLL_BUFFER_PRELOAD[256];
uint8_t m_GDC_SCROLL_BUFFER[256];
uint8_t m_GDC_INDIRECT_REGISTER, m_GDC_MODE_REGISTER, m_GDC_scroll_index, m_GDC_color_map_index, m_GDC_write_buffer_index;
@@ -634,7 +639,7 @@ private:
uint8_t m_vpat, m_patmult, m_patcnt, m_patidx;
uint16_t m_GDC_WRITE_MASK;
- bool m_scroll_buffer_changed, m_color_map_changed;
+ bool m_color_map_changed;
bool m_ONBOARD_GRAPHICS_SELECTED; // (internal switch, on board video to mono out)
bool m_SCREEN_BLANK;
@@ -692,25 +697,35 @@ private:
};
+// It * should be * OK to RESET the SCROLL_BUFFER and the COLOR_MAP (at least with WELL WRITTEN programs)
+
+// Situation less clear for vector mode (some programs work extensively * before * OPTION_GRFX_RESET
+
+// THIS MACRO * RESETS * the PATTERN TO DEFAULT.
+// NOTE 2: m_patmult MUST BE LOADED BEFORE !!
+#define OPTION_RESET_PATTERNS \
+m_vpat = 0xff; \
+if(m_patmult == 0) m_patmult = 0x01;\
+if(m_patcnt == 0) m_patcnt = m_patmult;\
+if(m_patidx == 0) m_patidx = 7;
+
+
// GDC RESET MACRO - used in "machine_reset" & GDC_EXTRA_REGISTER_w !
-#define GDC_RESET_MACRO \
+#define OPTION_GRFX_RESET \
+lower_8088_irq(IRQ_GRF_INTR_L); \
m_PORT50 = 0; \
m_GDC_INDIRECT_REGISTER = 0; \
-m_GDC_MODE_REGISTER = 0; \
-m_GDC_WRITE_MASK = 0; \
-m_GDC_write_buffer_index = 0; \
m_GDC_color_map_index = 0; \
-m_GDC_ALU_PS_REGISTER = 0; \
-m_vpat = 0; \
-m_patmult = 1; \
-m_patcnt = 0; \
-m_patidx = 7; \
-m_GDC_FG_BG = 0; \
m_color_map_changed = true; \
-for(int i=0; i <256; i++) { m_GDC_SCROLL_BUFFER[i] = m_GDC_SCROLL_BUFFER_PRELOAD[i] = i; };\
-m_GDC_scroll_index = 255; \
-m_scroll_buffer_changed = true; \
-printf("\n** NEC 7220 GDC RESET **\n");
+for(int i=0; i <256; i++) { m_GDC_SCROLL_BUFFER[i] = i; }; \
+m_GDC_scroll_index = 0; \
+m_GDC_write_buffer_index = 0; \
+m_GDC_WRITE_MASK = 0x00; \
+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");
UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
{
@@ -739,6 +754,9 @@ UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
return; // no output from graphics option
}
+ // IF-ABFRAGE AUF VEKTOR-MODUS MUSS AUSKOMMENTIERT WERDEN, WENN DER GRAFISCHE SCROLL_TEST FUNKTIONIEREN SOLL:
+ address = ( m_GDC_SCROLL_BUFFER[ ((address & 0x7FC0) >> 7) & 0xff ] << 7) | (address & 0x7F);
+
// ********************* GET BITMAP DATA FOR 4 PLANES ***************************************
// _READ_ BIT MAP from 2 or 4 planes (plane 0 is least, plane 3 most significant). See page 42 / 43
if(m_GDC_MODE_REGISTER & GDC_MODE_HIGHRES)
@@ -1140,8 +1158,13 @@ void rainbow_state::machine_reset()
m_fdc->dden_w(0);
// *********** NEC 7220 DISPLAY CONTROLLER [ OPTIONAL ]
- GDC_RESET_MACRO
+ 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);
@@ -2129,7 +2152,7 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r)
int fdc_write_gate = 0;
int last_dir = 0;
- printf("\nFLOPPY %02d - ", m_unit);
+// printf("\nFLOPPY %02d - ", m_unit);
if (m_fdc)
{
track = m_fdc->track_r(space, 0);
@@ -2367,18 +2390,12 @@ WRITE_LINE_MEMBER(rainbow_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
raise_8088_irq(IRQ_GRF_INTR_L);
+ else
+ lower_8088_irq(IRQ_GRF_INTR_L);
uint8_t red, green, blue, mono;
int xi;
- if(m_scroll_buffer_changed)
- {
- m_scroll_buffer_changed = false;
-
- for(xi = 0; xi < m_GDC_scroll_index; xi++) // LOAD REAL SCROLL BUFFER FROM PRELOAD (up to scroll_index...?)
- m_GDC_SCROLL_BUFFER[xi] = m_GDC_SCROLL_BUFFER_PRELOAD[xi];
- }
-
if(m_color_map_changed)
{
m_color_map_changed = false;
@@ -2435,6 +2452,7 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
}
case COLOR_MONITOR:
+ // Doesnt work as intended, so diabled:
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) );
@@ -2461,6 +2479,8 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
if ( m_inp13->read() == DUAL_MONITOR)
printf(" [HINT: DUAL MONITOR (DIP SWITCH) WRONG! NO GREEN PALETTE] ");
} // color map changed?
+
+
} // 7220 vblank IRQ
@@ -2790,7 +2810,7 @@ WRITE16_MEMBER(rainbow_state::vram_w)
}
// (READ)
-// Read _preloaded_ scroll buffer (see GDC Diagnostic Disk, SCROLL BUFFER test)
+// Read scroll buffer (see GDC Diagnostic Disk, SCROLL BUFFER test)
READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
{
uint8_t out = 0;
@@ -2804,7 +2824,7 @@ READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_SCROLL_MAP ) // 0x80
{
// Documentation says it is always incremented (read and write):
- out = m_GDC_SCROLL_BUFFER_PRELOAD[m_GDC_scroll_index++]; // // * READ * SCROLL_MAP ( 256 x 8 )
+ out = 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;
}
@@ -2840,10 +2860,14 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
case 0: // Mode register must be reloaded following any write to port 50 (software reset).
// FIXME: "Any write to this port also resynchronizes the
// read/modify/write memory cycles of the Graphics Option to those of the GDC." (?)
- if( data & 1 ) // PDF QV069 suggests 1 -> 0 -> 1; most programs just set bit 0.
- {
- GDC_RESET_MACRO // Graphics option software reset (separate from GDC reset...)
- printf("(PC=%x)\n", machine().device("maincpu")->safe_pc());
+
+ //if( (!(m_PORT50 & 1)) && (data & 1)) // PDF QV069 suggests 1 -> 0 -> 1
+ if( data & 1 ) // ; most programs just set bit 0 (PACMAN).
+ {
+ // Graphics option software reset (separate from GDC reset...)
+ OPTION_GRFX_RESET
+
+ OPTION_RESET_PATTERNS
}
m_PORT50 = data;
break;
@@ -2883,21 +2907,18 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
{
if(!( m_GDC_MODE_REGISTER & GDC_MODE_READONLY_SCROLL_MAP)) // ? READONLY / WRITE logic correct...?
{
- m_GDC_SCROLL_BUFFER_PRELOAD[m_GDC_scroll_index] = data; // // WRITE TO SCROLL_MAP ( 256 x 8 )
+ m_GDC_SCROLL_BUFFER[m_GDC_scroll_index] = data; // // WRITE TO SCROLL_MAP ( 256 x 8 )
if(m_GDC_scroll_index == 255)
printf("\n ---- SCROLL MAP FULLY LOADED ---*");
m_GDC_scroll_index++;
m_GDC_scroll_index &= 0xFF; // 0...255 (CPU accesses 256 bytes)
-
- m_scroll_buffer_changed = true;
}
break;
}
// -----------------PATTERN + MULTIPLIER USED IN VECTOR MODE ONLY!
// SEE PAGE 37 OF AA-AE36A (PDF).
- // NOTE : Pattern Multiplier MUST BE LOADED before loading PATTERN.
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN_MULTIPLIER)
{
// On a Rainbow, 12 indicates a multiplier of 16-12 = 4 (example)
@@ -2907,9 +2928,9 @@ 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;
- m_patcnt = m_patmult;
- m_patidx = 7; // correct...?
break;
}