summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/rainbow.cpp
diff options
context:
space:
mode:
author Bavarese <Bavarese@users.noreply.github.com>2016-12-13 21:12:36 +0100
committer GitHub <noreply@github.com>2016-12-13 21:12:36 +0100
commit759f7e30488cea9d3d4807508caf89fa5dd24d7c (patch)
tree8717880f6cf0c7276963febd09175b40f1335155 /src/mame/drivers/rainbow.cpp
parent65353bf7acf6036b3e6a06165afb68d9c925787e (diff)
Implemented NMI for parity test / fix aspect ratio
Parity test on memory board uses NMI now. Fixes the 1st memory test on rx50diag.td0 as well as the 'long' BIOS self test (key 'S'). Wrong aspect ratios in graphics mode also corrected (requires 'Graphics Only' + suitable cmd. line parameters).
Diffstat (limited to 'src/mame/drivers/rainbow.cpp')
-rw-r--r--src/mame/drivers/rainbow.cpp118
1 files changed, 64 insertions, 54 deletions
diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp
index 4e8b1880f6b..09c0de945de 100644
--- a/src/mame/drivers/rainbow.cpp
+++ b/src/mame/drivers/rainbow.cpp
@@ -2,7 +2,7 @@
// ENABLE BY UNCOMMENTING. ADDITIONALLY, SET SMOOTH SCROLL IN EMULATION (DISABLE BY SETTING JUMP SCROLL. To enter SETUP hit ScrollLock)-
//#define BOOST_DEBUG_PERFORMANCE
-
+
/* GDC COLOR EMULATION
//-------------------- Differences to VT240: ---------------------------------------------------
// - Registers of graphics option not directly mapped (indirect access via mode register)
@@ -40,32 +40,34 @@ 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)
+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)
+- Rainbow 100 A palette quirks (2 bit palette... applies to certain modes only)
UNKNOWN IMPLEMENTATION DETAILS:
-// 1. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
+1. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
-// 2. UNVERIFIED DIVIDER (31.188 Mhz / 32) is at least close to 1 Mhz (as on the VT240, which uses a very similar design)
+2. UNVERIFIED DIVIDERS (31.188 Mhz / 32) is at least close to 1 Mhz (as on the VT240, which uses a very similar design)
-// 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)
+3. UPD7220 / CORE oddities
+
+To obtain pixel exact graphics use 'Graphics Only' in Video Options plus command 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)...?
- 3.2 pixels are stretched out too wide at 384 x 240 (not fixable in Rainbow driver, -keepaspect seems to have no effect)
+ 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: MMIND (MasterMind), (G)OTELO (requires GSX), PACMAN, SCRAM (last one uses scroll extensively).
*/
// license:GPL-2.0+
@@ -126,9 +128,7 @@ CURRENTY UNEMULATED
(a) the serial port does work one way only (incomplete null modem or wiring?), no reception yet.
The printer interface does not work, so a non fatal ERROR 40 (serial printer interface) will appear.
-(b1) LOOPBACK circuit not emulated, NMI from RAM card also unemulated (NMI vector 02).
-The former is used in startup tests, the latter seems less relevant (must use menu self test "S"
- or memory diagnostic test. TODO: mem.test causes a CPU crash when reaching higher RAM regions.
+(b1) LOOPBACK circuit not emulated ( used in startup tests ).
(b2) system interaction tests HALT Z80 CPU at location $0211 (forever). Boot the RX50 diag.disk
to see what happens (key 3 - individual tests, then 12 - system interaction). Uses LOOPBACK too?
@@ -308,14 +308,14 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
#define RD51_SECTORS_PER_TRACK 17 // OLD: #define RD51_SECTORS_PER_TRACK 16
#define RTC_BASE 0xFC000
-// Do not pretend to emulate newer RAM board; stick with the old one:
-// (only affects presence bit in 'system_parameter_r')
-#define OLD_RAM_BOARD_PRESENT
#ifdef ASSUME_MODEL_A_HARDWARE
// 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
// 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.
@@ -468,6 +468,7 @@ public:
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-NEW
@@ -537,6 +538,8 @@ public:
DECLARE_READ8_MEMBER(rtc_enable);
DECLARE_READ8_MEMBER(rtc_r);
+ DECLARE_WRITE8_MEMBER(ext_ram_w);
+
DECLARE_WRITE_LINE_MEMBER(mpsc_irq);
DECLARE_WRITE8_MEMBER(comm_bitrate_w);
DECLARE_WRITE8_MEMBER(printer_bitrate_w);
@@ -608,6 +611,7 @@ private:
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;
@@ -838,7 +842,7 @@ void rainbow_state::machine_start()
static ADDRESS_MAP_START(rainbow8088_map, AS_PROGRAM, 8, rainbow_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00000, 0x0ffff) AM_RAM AM_SHARE("sh_ram")
-AM_RANGE(0x10000, END_OF_RAM) AM_RAM
+AM_RANGE(0x10000, END_OF_RAM) AM_RAM AM_SHARE("ext_ram") AM_WRITE(ext_ram_w)
// There is a 2212 (256 x 4 bit) NVRAM from 0xed000 to 0xed0ff (*)
// shadowed at $ec000 - $ecfff and from $ed100 - $edfff.
@@ -1065,6 +1069,10 @@ INPUT_PORTS_END
void rainbow_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 = machine().device<cpu_device>("maincpu")->space(AS_PROGRAM);
uint32_t unmap_start = m_inp8->read();
@@ -1099,7 +1107,10 @@ void rainbow_state::machine_reset()
printf("\nNOTE: 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)
+ {
+ printf("\nUnmapping from %x to %x",unmap_start, END_OF_RAM);
program.unmap_readwrite(unmap_start, END_OF_RAM);
+ }
m_crtc->MHFU(MHFU_RESET_and_DISABLE);
@@ -1112,7 +1123,6 @@ void rainbow_state::machine_reset()
m_rtc->chip_reset(); // * Reset RTC to a defined state *
-
// *********** HARD DISK CONTROLLER...
if (m_inp5->read() == 0x01) // ...PRESENT?
{
@@ -1200,9 +1210,6 @@ void rainbow_state::machine_reset()
output().set_value("led_compose", 0); // led9
output().set_value("led_lock", 0); // led10
output().set_value("led_hold", 0); // led11
-
- if (m_POWER_GOOD) // When user presses F3, a hard reset is executed.
- machine().schedule_hard_reset(); // better ask via GUI? How...?
}
// Simulate AC_OK signal (power good) and RESET after ~ 108 ms.
@@ -1410,6 +1417,17 @@ WRITE8_MEMBER(rainbow_state::share_z80_w)
return;
}
+// NMI logic (parity test)
+WRITE8_MEMBER(rainbow_state::ext_ram_w)
+{
+ m_ext_ram[offset] = data;
+
+#ifndef OLD_RAM_BOARD_PRESENT
+ if(m_diagnostic & 0x08)
+ if( (offset + 0x10000) >= (MOTHERBOARD_RAM + 1))
+ m_i8088->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+#endif
+}
// ------------------------ClikClok (for model B; DS1315) ---------------------------------
// DESCRIPTION: version for 100-A plugs into NVRAM chip socket (unemulated yet)
@@ -1524,18 +1542,15 @@ hard_disk_file *(rainbow_state::rainbow_hdc_file(int drv))
}
else
{
- printf("\n <<< === REJECTED = (SANITY CHECK FAILED) === >>> \n");
-
uint32_t max_sector = info->cylinders * info->heads * info->sectors;
- printf("\n%u (%3.2f) MB HARD DISK REJECTED. GEOMETRY: %d HEADS (1..%d ARE OK).\n%d CYLINDERS (151 to %d ARE OK).\n%d SECTORS / TRACK (up to %d ARE OK). \n%d BYTES / SECTOR (128 to 1024 ARE OK).\n",
+ popmessage("\n%u (%3.2f) MB HARD DISK REJECTED. GEOMETRY: %d HEADS (1..%d ARE OK).\n%d CYLINDERS (151 to %d ARE OK).\n%d SECTORS / TRACK (up to %d ARE OK). \n%d BYTES / SECTOR (128 to 1024 ARE OK).\n",
max_sector * info->sectorbytes / 1000000,
(float)max_sector * (float)info->sectorbytes / 1048576.0f,
info->heads, RD51_MAX_HEAD,
info->cylinders, RD51_MAX_CYLINDER,
info->sectors, RD51_SECTORS_PER_TRACK,
info->sectorbytes);
-
- printf("\n <<< === REJECTED = (SANITY CHECK FAILED) === >>> \n");
+ printf("\n <<< === HARD DISK IMAGE REJECTED = (invalid geometry) === >>> \n");
return nullptr;
}
}
@@ -2478,7 +2493,6 @@ WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
printf(" [HINT: DUAL MONITOR (DIP SWITCH) WRONG! NO GREEN PALETTE] ");
} // color map changed?
-
} // 7220 vblank IRQ
@@ -2508,7 +2522,7 @@ WRITE_LINE_MEMBER(rainbow_state::clear_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
-{
+{
return ((m_diagnostic & (0xf1)) |
m_inp1->read() |
m_inp2->read() |
@@ -2565,13 +2579,9 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 +
printf("DATA: %x (PC=%x)\n", data, machine().device("maincpu")->safe_pc());
}
- // BIT 3: PARITY TEST (1 = enables parity test on memory option board).
- if(data & 0x08)
- {
- printf("\n*** UNEMULATED PARITY TEST [on RAM EXTENSION] - (bit 3 in diagnostic_w) ");
- // FIXME: parity test = NMI? When should NMI fire? Per RAM bank?
- // m_i8088->set_input_line_and_vector(INPUT_LINE_NMI, ASSERT_LINE, 0x02);
- }
+ // 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) ");
// 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)
@@ -3071,10 +3081,7 @@ MCFG_CPU_VBLANK_INT_DRIVER("screen", rainbow_state, vblank_irq)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
-MCFG_SCREEN_REFRESH_RATE(60)
-MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
-MCFG_SCREEN_SIZE(132 * 10, 49 * 10)
-MCFG_SCREEN_VISIBLE_AREA(0, 80 * 10 - 1, 0, 48 * 10 - 1)
+MCFG_SCREEN_RAW_PARAMS(XTAL_24_0734MHz / 6, 442, 0, 400, 264, 0, 240) // ~NTSC compatible video timing (?)
MCFG_SCREEN_UPDATE_DRIVER(rainbow_state, screen_update_rainbow)
MCFG_SCREEN_PALETTE("vt100_video:palette")
@@ -3088,7 +3095,7 @@ MCFG_VT_VIDEO_RAM_CALLBACK(READ8(rainbow_state, read_video_ram_r))
MCFG_VT_VIDEO_CLEAR_VIDEO_INTERRUPT_CALLBACK(WRITELINE(rainbow_state, clear_video_interrupt))
// *************************** COLOR GRAPHICS (OPTION) **************************************
-// While the OSC frequency is confirmed, the divider is not. Refresh rate is ~60 Hz with 32.
+// While the OSC frequency is confirmed, the divider is not (refresh rate is ~60 Hz with 32).
MCFG_DEVICE_ADD("upd7220", UPD7220, 31188000 / 32) // Duell schematics shows a 31.188 Mhz oscillator (confirmed by RFKA).
MCFG_UPD7220_VSYNC_CALLBACK(WRITELINE(rainbow_state, GDC_vblank_irq)) // "The vsync callback line needs to be below the 7220 DEVICE_ADD line."
@@ -3099,12 +3106,15 @@ MCFG_PALETTE_ADD("palette2", 32)
MCFG_SCREEN_ADD("screen2", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK | VIDEO_ALWAYS_UPDATE)
-MCFG_SCREEN_REFRESH_RATE(60)
-MCFG_SCREEN_UPDATE_DEVICE("upd7220", upd7220_device, screen_update)
-MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not accurate
-MCFG_SCREEN_SIZE(800, 256) // should be 240
-MCFG_SCREEN_VISIBLE_AREA(0, 800-1, 0, 256-1) // should be 240
+// VR241 color monitor is specified for 20 MHz bandwidth ( 60 Hz / 15.72 kHz horizontal rate )
+// - sufficient for 800 x 240 non-interlaced at 60 Hz (non interlaced).
+//MCFG_SCREEN_RAW_PARAMS(31188000 / 2 , 992, 0, 800, 262, 0, 240)
+
+// Alternate configuration:
+MCFG_SCREEN_RAW_PARAMS(31188000 / 4 , 496, 0, 400, 262, 0, 240)
+
+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)