summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2013-11-25 03:46:58 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2013-11-25 03:46:58 +0000
commitf499244d53ccb07ddf500c1393ae90ea9ad2e201 (patch)
treeeda39407538681d86f46145a13fce641a37e34cd
parentd05677b0e6768bff43388e648e07c57f6ead502a (diff)
(MESS) DEC Rainbow updates: [Bavarese]
- rainbow.c: wired watchdog (MHFLU) and W18 (DSR). Dangerous W90 (PSU jumper) on PCB documented. Pallette handling changed, moved screen blank routine to vtvideo.c - dec_lk201.c: keyboard matrix from LK-201-AA (VCB02) (original 8051 version) - Vtvideo.c: monochrome palette with 4 intensities (instead of 3). Ironed out attribute bugs (-> truth table from VT100). Double-width, double-height corrected
-rw-r--r--src/mess/drivers/rainbow.c212
-rw-r--r--src/mess/machine/dec_lk201.c93
-rw-r--r--src/mess/video/vtvideo.c378
-rw-r--r--src/mess/video/vtvideo.h5
4 files changed, 509 insertions, 179 deletions
diff --git a/src/mess/drivers/rainbow.c b/src/mess/drivers/rainbow.c
index 5359553a0f2..92d73f915f9 100644
--- a/src/mess/drivers/rainbow.c
+++ b/src/mess/drivers/rainbow.c
@@ -6,32 +6,48 @@
STATE AS OF NOVEMBER 2013
--------------------------
- - FATAL: keyboard emulation needs love (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot).
- - NOT WORKING: serial (ERROR 60)
- - NOT WORKING: printer interface (ERROR 40).
+ - FATAL: keyboard emulation incomplete (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot).
+ - NOT WORKING: serial (ERROR 60).
+ - NOT WORKING: printer interface (ERROR 40). Like error 60 not mission-critical.
- - NON-CRITICAL: no code for W18 (DSR) jumper. W90 jumper probably not relevant for emulation (VBIAS pin 2 => to unknown register).
- - NON-CRITICAL: watchdog logic not implemented. MHFLU - ERROR 16 indicated hardware problems or (most often) software crashes on real hardware.
+ - NON-CRITICAL: watchdog logic (triggered after 108 ms without interrupts) still not exactly by the book.
+
+ Timer is reset by TWO sources: the VERT INT L from the DC012, or the MHFU ENB L from the enable flip-flop.
+ The MHFU gets active if the 8088 has not acknowledged a video processor interrupt within approx. 108 milliseconds.
+
+ BIOS assumes a power-up reset if MHFU detection is disabled - and assumes a MHFU reset if MHFU detection is ENABLED.
+ Therefore a 'warm boot' within MESS (F3) causes ERROR 16.
- SHOULD BE IMPLEMENTED AS SLOT DEVICES (for now, DIP settings affect 'system_parameter_r' only and are disabled):
* Color graphics option (uses NEC upd7220 GDC)
* Extended communication option (same as BUNDLE_OPTION ?)
- OTHER UPGRADES (NEC_V20 should be easy, the TURBOW is harder to come by)
- * Suitable Solutions TURBOW286 (12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter )
- / replacement for main cpu with on-board DC 7174 or DT 7174 (?) RTC and changed BOOT ROM labeled 'TBSS1.3 - 3ED4').
+ * Suitable Solutions TURBOW286: 12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter )
+ plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Changed BOOT ROM labeled 'TBSS1.3 - 3ED4'.
* NEC_V20 (requires modded BOOT ROM because of - at least 2 - hard coded timing loops):
100A: 100B/100+: 100B+ ALTERNATE RECOMMENDATION (fixes RAM size auto-detection problems when V20 is in place.
- Tested on a 30+ year old live machine. Your mileage may vary)
+ Tested on a 30+ year old live machine. Your mileage may vary)
+
Location Data Location Data Loc.|Data
- 00C6 46 [ increases 'wait for Z80' from approx. 27,5 ms (old value 40) to 30,5 ms ]
- 0303 00 [ disable CHECKSUM ]
+ .... .. .... .. ------------------ 00C6 46 [ increases 'wait for Z80' from approx. 27,5 ms (old value 40) to 30,5 ms ]
+ .... .. .... .. ------------------ 0303 00 [ disable CHECKSUM ]
043F 64 072F 64 <-----------------> 072F 73 [ increases minimum cycle time from 2600 (64) to 3000 ms (73) ]
- 067D 20 0B36 20 <-----------------> 0B36 20 [ use a value of 20 for NEC_V20 - as in the initial patch. Changes cause VFR - ERROR 10. ]
+ 067D 20 0B36 20 <-----------------> 0B36 20 [ USE A VALUE OF 20 FOR THE NEC - as in the initial patch! CHANGES CAUSE VFR-ERROR 10 ]
1FFE 2B 3FFE 1B (BIOS CHECKSUM)
1FFF 70 3FFF 88 (BIOS CHECKSUM)
+ => the 'leaked' DOS 3.10 Beta -for Rainbow- 'should not be used' on rigs with NEC V20. It possibly wasn't tested, but boots and runs well.
+ => on the NEC, auto detection (of option RAM) fails with the original V20 patch (above, left)
+ Expect RAM related system crashes after swapping CPUs and altering physical RAM _afterwards_.
+ Hard coded CPU loops are to blame. Try values from the alternate patch (right).
+ => AAD/AAM - Intel 8088 honors the second byte (operand), NEC V20 ignores it and always uses base 0Ah (10).
+ => UNDOCUMENTED: NEC V20 does not have "POP CS" (opcode 0F). There are more differences (opcode D6; the 2 byte POP: 8F Cx; FF Fx instructions)
+ Commercial programs had to be patched back then (as was the case with Loderunner for PC).
+ => NEW OPCODES: REPC, REPNC, CHKIND, PREPARE, DISPOSE; BCD string operations (ADD4S, CMP4S, SUB4S), bit-ops (NOT, SET, TEST, ROL4, ROR4)
+ WARNING: undoc'd opcodes, INS, EXT and 8080 behaviour are unemulated yet! MESS' CPU source has up-to-date info.
+
Meaning of Diagnostics LEDs (from PC100ESV1.PDF found, e.g.,
on ftp://ftp.update.uu.se/pub/rainbow/doc/rainbow-docs/
@@ -95,9 +111,9 @@ PCB # 5416206 / 5016205-01C1:
7-6-5-4 |3-2-1
DIAGNOSTIC-LEDs |J3 | |J2 | |J1 |
|------|----8088|Z80-|--|VIDEO|-|PRINTER|-|SERIAL|---|
-| 2 x 64 K |/KBD.| |
-| R A M NEC D7201C |P|[W90]|
-| |O| |
+| 2 x 64 K |/KBD.| !!!!!|
+| R A M NEC D7201C |P|!W90!|
+| |O|!!!!!|
| [W6] ROM 1 INTEL 8088 |W| |
| (23-020e5-00) |E| |
| |R| |
@@ -119,18 +135,35 @@ NOTES
W5 + W6 are out when 16K x 8 EPROMS are used
/ W5 + W6 installed => 32 K x 8 EPROMs (pin 27 = A14)
-W13, W14, W15, W18, W90 = for manufacturing tests.
+W13, W14, W15, W18 = for manufacturing tests.
=> W13 - W15 affect diagnostic read register (port $0a)
=> W18 pulls DSR to ground and affects 8251A - port $11 (bit 7)
- NOTE: THERE IS NO CODE TO PULL DSR YET.
-=> W90 connects pin 2 (Voltage Bias on PWR connector J8) with the communications control register
-(SH1 - IOWR4 L line according to page 21 of the DEC-100-B field manual)
-SEEN ON SCHEMATICS - NOT PRESENT ON THIS PCB:
-W16 pulls J2 printer port pin 1 to GND when set (otherwise pin unconnected)
-W17 pulls J1 serial port pin 1 to GND when set (otherwise pin unconnected)
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! DO NOT SHORT JUMPER / CONNECTOR [W90] ON LIVE HARDWARE !!
+!! !!
+!! WARNING: CIRCUIT DAMAGE could occur if this jumper is !!
+!! set by end users. See PDF document AA-V523A-TV. !!
+!! !!
+!! W90 connects to pin 2 (Voltage Bias on PWR connector J8)!!
+!! and is designed FOR ===> FACTORY TESTS OF THE PSU <=== !!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+WIRE CONNECTORS - SEEN ON SCHEMATICS - NOT PRESENT ON DEC-100 B (-A only?):
+W16 pulls J2 printer port pin 1 to GND when set (chassis to logical GND).
+W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
****************************************************************************/
+/*
+HARD DISC SIZES AND LIMITS
+ HARDWARE: the Rainbow winchester controller has a built-in limit of 8 heads and 1024 cylinders (67 MB). Standard geometry is 4 surfaces.
+
+ SOFTWARE: the original DEC boot loader (and FDISK from DOS 3.10) initially allowed a maximum hard disc size of 20 MB.
+ - DOS 3 has a 1024 cylinder limit (32 MB).
+ - the custom boot loader that comes with 'WUTIL 3.2' stretches limits to 117 MB and 8 surfaces.
+*/
+
+
#include "emu.h"
#include "cpu/i86/i86.h"
#include "cpu/z80/z80.h"
@@ -144,8 +177,6 @@ W17 pulls J1 serial port pin 1 to GND when set (otherwise pin unconnected)
#include "rainbow.lh" // BEZEL - LAYOUT with LEDs for diag 1-7, keyboard 8-11 and floppy 20-21
-#define DEC_B_NVMEM_SIZE (256)
-
class rainbow_state : public driver_device
{
public:
@@ -159,6 +190,7 @@ public:
m_inp6(*this, "FLOPPY CONTROLLER"),
m_inp7(*this, "GRAPHICS OPTION"),
m_inp8(*this, "MEMORY PRESENT"),
+ m_inp9(*this, "MONITOR TYPE"),
m_beep(*this, "beeper"),
m_crtc(*this, "vt100_video"),
@@ -183,6 +215,7 @@ public:
required_ioport m_inp6;
required_ioport m_inp7;
required_ioport m_inp8;
+ required_ioport m_inp9;
required_device<beep_device> m_beep;
@@ -231,13 +264,14 @@ public:
DECLARE_WRITE8_MEMBER(z80_diskcontrol_write_w);
DECLARE_READ8_MEMBER(system_parameter_r);
+ DECLARE_READ_LINE_MEMBER(dsr_r);
+
DECLARE_READ_LINE_MEMBER(kbd_rx);
DECLARE_WRITE_LINE_MEMBER(kbd_tx);
DECLARE_WRITE_LINE_MEMBER(kbd_rxready_w);
DECLARE_WRITE_LINE_MEMBER(kbd_txready_w);
bool m_SCREEN_BLANK;
- bool m_COLDBOOT;
bool m_zflip; // Z80 alternate memory map with A15 inverted
bool m_z80_halted;
@@ -246,12 +280,15 @@ public:
int m_KBD;
int m_beep_counter;
+ int MHFU_counter;
+
private:
UINT8 m_z80_private[0x800]; // Z80 private 2K
UINT8 m_z80_mailbox, m_8088_mailbox;
void update_kbd_irq();
virtual void machine_reset();
+ void MHFU_reset();
public:
UINT32 screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_irq);
@@ -262,7 +299,6 @@ public:
void rainbow_state::machine_start()
{
m_SCREEN_BLANK = false;
- m_COLDBOOT = true;
save_item(NAME(m_z80_private));
save_item(NAME(m_z80_mailbox));
@@ -315,11 +351,11 @@ static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state)
// - PC-100 A might have had a smaller (NV-)RAM (*)
// - ED000 - ED0FF is the area the _DEC-100-B BIOS_ accesses - and checks.
- // - Specs claim that the CPU has direct access to volatile RAM only.
+ // - Specs say that the CPU has direct access to volatile RAM only.
// So NVRAM is hidden now and loads & saves are triggered within the
- // 'diagnostic_w' handler (like on real hardware).
+ // 'diagnostic_w' handler (similar to real hardware).
- // - Address bits 8-12 are ignored (-> AM_MIRROR). Remove for debugging.
+ // - Address bits 8-12 are ignored (-> AM_MIRROR).
AM_RANGE(0xed000, 0xed0ff) AM_RAM AM_SHARE("vol_ram") AM_MIRROR(0x1f00)
AM_RANGE(0xed100, 0xed1ff) AM_RAM AM_SHARE("nvram")
@@ -341,8 +377,9 @@ static ADDRESS_MAP_START( rainbow8088_io , AS_IO, 8, rainbow_state)
AM_RANGE (0x08, 0x08) AM_READ(system_parameter_r)
AM_RANGE (0x0a, 0x0a) AM_READWRITE(diagnostic_r, diagnostic_w)
- // 0x0C Video processor DC012
- AM_RANGE (0x0c, 0x0c) AM_DEVWRITE("vt100_video", rainbow_video_device, dc012_w)
+
+ // 0x0C Video processor DC012
+ AM_RANGE (0x0c, 0x0c) AM_DEVWRITE("vt100_video", rainbow_video_device, dc012_w)
AM_RANGE(0x10, 0x10) AM_DEVREADWRITE("kbdser", i8251_device, data_r, data_w)
AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("kbdser", i8251_device, status_r, control_w)
@@ -371,12 +408,28 @@ ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( rainbow )
+ PORT_START("MONITOR TYPE")
+ PORT_DIPNAME( 0x03, 0x03, "MONOCHROME MONITOR")
+ PORT_DIPSETTING( 0x01, "PAPER WHITE" )
+ PORT_DIPSETTING( 0x02, "GREEN" )
+ PORT_DIPSETTING( 0x03, "AMBER" )
+
PORT_START("FLOPPY CONTROLLER")
PORT_DIPNAME( 0x02, 0x02, "FLOPPY CONTROLLER") PORT_TOGGLE
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x02, DEF_STR( On ) )
- PORT_START("MEMORY PRESENT")
+ PORT_START("GRAPHICS OPTION")
+ PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( On ) )
+
+ PORT_START("BUNDLE OPTION")
+ PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( On ) )
+
+ PORT_START("MEMORY PRESENT")
PORT_DIPNAME( 0xF000, 0x2000, "MEMORY PRESENT")
PORT_DIPSETTING( 0x2000, "128 K (BOARD DEFAULT)" ) // NOTE: 0x2000 hard coded in 'system_parameter_r'
PORT_DIPSETTING( 0x3000, "192 K (MEMORY OPTION)" )
@@ -392,36 +445,35 @@ static INPUT_PORTS_START( rainbow )
PORT_DIPSETTING( 0xD000, "832 K (MEMORY OPTION)" )
PORT_DIPSETTING( 0xE000, "896 K (MEMORY OPTION)" )
- PORT_START("GRAPHICS OPTION")
- PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x04, DEF_STR( On ) )
- PORT_START("BUNDLE OPTION")
- PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x01, DEF_STR( On ) )
-
PORT_START("W13")
- PORT_DIPNAME( 0x02, 0x02, "W13") PORT_TOGGLE
+ PORT_DIPNAME( 0x02, 0x02, "W13 (FACTORY TEST A, LEAVE OFF)") PORT_TOGGLE
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("W14")
- PORT_DIPNAME( 0x04, 0x04, "W14") PORT_TOGGLE
+ PORT_DIPNAME( 0x04, 0x04, "W14 (FACTORY TEST B, LEAVE OFF)") PORT_TOGGLE
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("W15")
- PORT_DIPNAME( 0x08, 0x08, "W15") PORT_TOGGLE
+ PORT_DIPNAME( 0x08, 0x08, "W15 (FACTORY TEST C, LEAVE OFF)") PORT_TOGGLE
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ // DSR = 1 when switch is OFF - see i8251.c (status_r)
PORT_START("W18")
- PORT_DIPNAME( 0x00, 0x04, "W18") PORT_TOGGLE
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x01, 0x00, "W18 (FACTORY TEST D, LEAVE OFF) (8251A: DSR)") PORT_TOGGLE
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( On ) )
INPUT_PORTS_END
+void rainbow_state::MHFU_reset()
+{
+ MHFU_counter = 530; // 528 = 110ms
+}
+
void rainbow_state::machine_reset()
{
+ MHFU_reset();
+
m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_zflip = true;
@@ -454,15 +506,24 @@ void rainbow_state::machine_reset()
UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- if (m_SCREEN_BLANK)
- bitmap.fill(get_black_pen(machine()), cliprect);
- else
- m_crtc->video_update(bitmap, cliprect);
+ m_crtc->palette_select( m_inp9->read() );
+
+ if ( m_SCREEN_BLANK )
+ m_crtc->video_blanking(bitmap, cliprect);
+ else
+ m_crtc->video_update(bitmap, cliprect);
return 0;
}
-// Simulate floating bus for initial RAM detection in low ROM.
-// WANTED: is a cleaner, more compatible way feasible?
+// It is no longer possible to key in the RAM size on the 100-B.
+// The DEC-100-B boot ROM probes until a 'flaky' area is found (around F400:xxxx).
+
+// Unexpected low RAM sizes are an indication of option RAM (at worst: 128 K on board) failure.
+// While motherboard errors often render the system unbootable, bad option RAM (> 128 K)
+// can be narrowed down with a diagnostic disk and codes from the 'Pocket Service Guide'
+// EK-PC100-PS-002 (APPENDIX B.2.2); pc100ps2.pdf
+
+// Simulate floating bus for initial RAM detection:
READ8_MEMBER(rainbow_state::floating_bus_r)
{
if ( m_maincpu->state_int(I8086_CS) != 0xF400)
@@ -555,17 +616,15 @@ READ8_MEMBER(rainbow_state::system_parameter_r)
}
READ8_MEMBER(rainbow_state::comm_control_r)
-{
- // Our simple COLDBOOT flag is adequate for the initial MHFU test (at BIOS location 00A8).
-
- // TODO: on real hardware, MHFU detection is disabled BY WRITING TO 0x10c (=> BIOS assumes power-up reset)
- // MHFU is enabled by writing to 0x0c.
- if (m_COLDBOOT)
- { m_COLDBOOT = 0;
- return ( 0x20 ); // bit 5 = watchdog detect.
- } else {
- return ( 0x00 ); // ERROR 16 is displayed = watchdog triggered
- }
+{
+/*
+--> What the specs says on how MHFU detection is disabled:
+ // 1. by first disabling interrupts with CLI
+ // 2. by writing 0x00 to port 0x10C (handled by 'dc012_w' in vtvideo)
+ // (3.) MHFU is re-enabled by writing to 0x0c (or automatically after STI - when under BIOS control ?)
+*/
+ return ( ( m_crtc->dc012_MHFU() << 5) // shift status of DC012 - MHFU flag to bit pos.5
+ );
}
WRITE8_MEMBER(rainbow_state::comm_control_w)
@@ -713,6 +772,8 @@ READ8_MEMBER( rainbow_state::read_video_ram_r )
INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq)
{
device.execute().set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x20);
+
+ MHFU_reset();
}
WRITE8_MEMBER( rainbow_state::clear_video_interrupt )
@@ -766,6 +827,11 @@ WRITE8_MEMBER( rainbow_state::diagnostic_w )
}
+READ_LINE_MEMBER(rainbow_state::dsr_r)
+{
+ return m_inp4->read(); // W18 (1/0)
+}
+
// KEYBOARD
void rainbow_state::update_kbd_irq()
{
@@ -810,6 +876,18 @@ TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::keyboard_tick)
m_kbd8251->transmit_clock();
m_kbd8251->receive_clock();
+ if ( m_crtc->dc012_MHFU() ) // MHFU ENABLED?
+ {
+ if (MHFU_counter)
+ MHFU_counter--;
+
+ if (MHFU_counter == 1) // resets ONCE.
+ {
+ printf("*** CPU RESET: MASSIVE HARDWARE FAILURE DETECTED (MHFU LOGIC ~108 ms)\n");
+ m_i8088->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+ }
+ }
+
if (m_beep_counter > 1)
m_beep_counter--;
else
@@ -870,7 +948,7 @@ static const i8251_interface i8251_intf =
{
DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_rx), // rxd in
DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_tx), // txd out
- DEVCB_NULL, // dsr
+ DEVCB_DRIVER_LINE_MEMBER(rainbow_state, dsr_r), // dsr
DEVCB_NULL, // dtr
DEVCB_NULL, // rts
DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_rxready_w),
@@ -897,11 +975,11 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state )
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, 25*10-1)
+ MCFG_SCREEN_VISIBLE_AREA(0, 80 * 10-1, 0, 24 * 10-1)
MCFG_SCREEN_UPDATE_DRIVER(rainbow_state, screen_update_rainbow)
MCFG_GFXDECODE(rainbow)
- MCFG_PALETTE_LENGTH(3)
- MCFG_PALETTE_INIT_OVERRIDE(driver_device, monochrome_amber)
+ MCFG_PALETTE_LENGTH(4)
+
MCFG_RAINBOW_VIDEO_ADD("vt100_video", video_interface)
/* sound hardware */
diff --git a/src/mess/machine/dec_lk201.c b/src/mess/machine/dec_lk201.c
index e14b8119252..7a6cd3e75ab 100644
--- a/src/mess/machine/dec_lk201.c
+++ b/src/mess/machine/dec_lk201.c
@@ -2,9 +2,100 @@
DEC LK-201 keyboard
Emulation by R. Belmont
- This is currently the 6805 version; there's also an 8048 version.
+ This is the later "cost-reduced" 6805 version; there's also an 8048 version.
*/
+/* LK201-AA keyboard matrix (8048 version)
+ Source: VCB02 Technical Reference.
+
+ KBD controller scan matrix (PORT 1): 8 x BCD IN => 18 DECIMAL OUT
+
+ Keyboard itself:
+ 18 x IN (KEYBOARD DRIVE) KBD 17... KBD 0 =>
+ 8 OUT (keyboard data @ D7..D0)
+
+ to => PORT 0 @ KBD controller.
+
+________|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0
+..KBD17:|[R] |F19 |[R] |F20|PF4|N--- N,| Enter
+........| | | | | | NOTE1)
+........| |G22 | |G23|E23|D23|C23| A23
+........| | | | | | <- - - - - - ? ?
+--------|----|----|----|---|---|---|---|---
+..KBD16:|F18 |PF3 |[R] |N9 |V |N6 |N3 |N
+........|G21 |E22 | |D22|B17|C22|B22|A22
+--------|----|----|----|---|---|---|---|---
+..KBD15:|F17 |PF2 |[R] |N8 |N5 |-> | N2|N0
+........| | | | | | | |NOTE 2)
+........|G20 |E21 | |D21|C21|B18|B21|
+--------|----|----|----|---|---|---|---|---
+ KBD14:|PF1 |Next|Remove ^|N7 |N4 |N1 |N0
+........| |Scrn| | || | | |
+........|E20 |D18 |E18 |C17|D20|C20|B20|A20
+--------|----|----|----|---|---|---|---|---
+..KBD13:|Ins.|--- |D0 Prev| { |" |[R]|[R]
+........|Here|- | Scrn. [ |' | |
+........|E17 |E11 |G16 |D17 D11|C11| |
+--------|----|----|----|---|---|---|---|---
+..KBD12:|Find|+ |Help|Se-| } Re- |<- |
+........| |= | |lect ] turn| |
+........|E16 |E12 |G15 |D16 D12|C13| |
+--------|----|----|----|---|---|---|---|---
+..KBD11:Addtnl <X||[R] |) |P NOTE|: |?
+.......Options Del| |0 | | 3)|; |/
+........|G14 | E13|....|E10|D10|...|C10|B10
+--------|----|----|----|---|---|---|---|---
+..KBD10:|[R] |F12 |[R] |F13| ( |O |L |.
+........|....|(BS)| |(LF) 9 | | |
+........|....|G12 |....|G13|E09|D09|C09|B09
+--------|----|----|----|---|---|---|---|---
+..KBD_9:|[R] |F11 |[R] |[R]|* |I |K | ,
+........|....|ESC | | |8 | | | ,
+........|....|G11 |....|...|E08|D08|C08|B08
+--------|----|----|----|---|---|---|---|---
+..KBD_8:|[R] |Main|[R] Exit|& |U |J |M
+........| |Scrn| | |7 | | |
+........| |G08 | |G09|E07|D07|C07|B07
+--------|----|----|----|---|---|---|---|---
+..KBD_7:|[R] Cancel[R] Resu ^ |Y |H |N
+........| | | me |6 | | |
+........|....|G07 |G06|E06|D06|C06|B06
+--------|----|----|----|---|---|---|---|---
+..KBD_6:|[R] |[R] |[R] Inter % |T |G |B
+........|....|....|....rupt| 5 | | |
+........|....|....|....|G05|E05|D05|C05|B05
+--------|----|----|----|---|---|---|---|---
+..KBD_5: F4 Break [R]|$ |R |F |V |Space
+........|.........|....|4 | | | |
+........ G02 G03 |....|E04 D04 C04 B04 A01-A09
+--------|----|----|----|---|---|---|---|---
+..KBD_4: [R] |Prt.|[R] |Set|# |E |D |C
+........|....|Scrn|....|-Up|3 | | |
+........|....|G00 |....|G01 E03 D03 C03 B03
+--------|----|----|----|---|---|---|---|---
+..KBD_3: Hold|@ |[R] |Tab|W |S |X |>
+........|Scrn|2 |....| | | | |<
+........|G99 |E02 |....|D00|D02|C02|B02|B00
+--------|----|----|----|---|---|---|---|---
+..KBD_2: [R] |[R] |[R] |~ |! |Q |A |Z
+........|..............| |1
+........|..............|E00 E01 D01 C01 B01
+--------|----|----|----|---|---|---|---|---
+..KBD_1: Ctrl|Lock|Comp|[R]
+........|C99 |C00 |A99 |
+--------|----|----|----|---|---|---|---|---
+..KBD_0: Shift
+........|B99,B11
+
+---
+ [R] = Reserved
+ NOTE 1) N0--N9, N---, N and N. refer to numeric keypad
+ NOTE 2) N0 can be divided into 2 keys.
+ Normally only the N0 keyswitch is implemented as a double-sized key.
+ NOTE 3) Return key occupies 2 positions that are
+ decoded as the Return (C13) key.
+ */
+
#include "emu.h"
#include "dec_lk201.h"
#include "cpu/m6805/m6805.h"
diff --git a/src/mess/video/vtvideo.c b/src/mess/video/vtvideo.c
index 5a88875be9c..911a6e26951 100644
--- a/src/mess/video/vtvideo.c
+++ b/src/mess/video/vtvideo.c
@@ -1,25 +1,28 @@
-/**********************************************************************
+ /**********************************************************************
DEC VT Terminal video emulation
[ DC012 and DC011 emulation ]
01/05/2009 Initial implementation [Miodrag Milanovic]
- Sept. 2013 portions by Karl-Ludwig Deisenhofer.
+ --/--/2013 portions by Karl-Ludwig Deisenhofer.
- STATE OF DEC-100 VIDEO AS OF SEPTEMBER 2013
- -------------------------------------------
- - FURTHER TESTING: do line and character attributes match real hardware? Does soft scrolling work?
- - LIKELY INCORRECT : implementation of double size attribute in 132 columns mode (additional case)
+ DEC VIDEO : STATE AS OF NOVEMBER 2013
+ -------------------------------------
+ - NOT WORKING : scrolling requires implementation of 'scrolling region'. Multiple regions could be present.
+ Split & a full screen modes exist. Scroll should be synced with beam or DMA.
+ See 4.7.4 and up in VT manual.
- - MISSING: undocumented features of DC011 / DC012 - see public domain SQUEEZE.COM pokes:
- 0f00 => PORT 0C;
- 0b00 => PORT 0C;
- 1000 => PORT 04
- (SQUEEZE compresses the display in X and Y direction on a real DEC-100 B)
+ - TESTS REQUIRED : do line and character attributes (plus combinations) match real hardware?
+
+ - UNDOCUMENTED FEATURES of DC011 / DC012 (CLUES WANTED)
+ A. (VT 100): DEC VT terminals are said to have a feature that doubles the number of lines
+ (50 real lines or just interlaced mode with 500 instead of 250 scanlines?)
+
+ B. (DEC-100-B) fun PD program SQUEEZE.COM _compresses_ display to X/2 and Y/2
+ - so picture takes a quarter of the original screen. How does it accomplish this?
- IMPROVEMENTS:
- - find a more realistic approach for intensity control (bold attribute)
- - correct phosphor colors (green, white and amber monitors were common)
+ - exact colors for different VR201 monitors ('paper white', green and amber)
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
@@ -140,12 +143,13 @@ void vt100_video_device::device_reset()
}
// ****** RAINBOW ******
-// 3 color palette, 24 and 48 line modes.
+// 4 color (= monochrome intensities) palette, 24 and 48 line modes.
void rainbow_video_device::device_reset()
{
+ DEC_MHFU = true; // SET ON COLD BOOT
+
palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black
- palette_set_color_rgb(machine(), 1, 213, 146, 82); // AMBER (not exact)
- palette_set_color_rgb(machine(), 2, 255, 193, 129); // AMBER (brighter)
+ // (rest of the palette is set in the main program)
m_height = 24; // <---- DEC-100
m_height_MAX = 48;
@@ -193,11 +197,36 @@ READ8_MEMBER( vt100_video_device::lba7_r )
return m_lba7;
}
+
// Also used by Rainbow-100 ************
WRITE8_MEMBER( vt100_video_device::dc012_w )
{
+ if (data == 0)
+ {
+ if (DEC_MHFU == true)
+ DEC_MHFU = false; // MHFU is disabled by writing 00 to port 010C.
+ } else
+ {
+ if (DEC_MHFU == false)
+ DEC_MHFU = true; // TODO: MHFU ENABLE should also reset the MHFU timer.
+ }
+
if (!(data & 0x08))
{
+ // The scroll offset put in 'm_scroll_latch' is a decimal offset controlling 10 scan lines.
+ // The BIOS first writes the least significant bits, then the 2 most significant bits.
+
+ // If scrolling up (incrementing the scroll latch), the additional line is linked in at the bottom.
+ // When the scroll latch is incremented back to 0, the top line of the scrolling region must be unlinked.
+
+ // When scrolling down (decrementing the scroll latch), new lines must be linked in at the top of the scroll region
+ // and unlinked down at the bottom.
+
+ // Note that the scroll latch value will be used during the next frame rather than the current frame.
+ // All line linking/unlinking should be done during the vertical blanking interval (< 550ms).
+
+ // More on scrolling regions: Rainbow 100 B technical documentation (QV069-GZ) April 1985 page 22
+ // Also see VT100 Technical Manual: 4.7.4 Address Shuffling to 4.7.9 Split Screen Smooth Scrolling.
if (!(data & 0x04))
{
// set lower part scroll
@@ -229,17 +258,20 @@ WRITE8_MEMBER( vt100_video_device::dc012_w )
// set reverse field off
m_reverse_field = 0;
break;
+
+ // Writing a 11XX bit combination clears the blink-flip flop (valid for 0x0C - 0x0F):
case 0x0c:
- // set basic attribute to underline
- m_basic_attribute = 0;
+ // set basic attribute to underline / blink flip-flop off
m_blink_flip_flop = 0;
+ m_basic_attribute = 0; // (VT-100 without AVO): reverse video is interpreted as underline (basic_attribute 0)
break;
+
case 0x0d:
- // set basic attribute to reverse video / blink flip-flop off
- m_basic_attribute = 1;
+ // (DEC Rainbow 100 DEFAULT) : reverse video with 24 lines / blink flip-flop off
m_blink_flip_flop = 0;
+ m_basic_attribute = 1; // (VT-100 without AVO): reverse video is interpreted as reverse (basic_attribute 1)
- if (m_height_MAX == 25) break; // VT 100.
+ if (m_height_MAX == 25) break; // Abort on VT-100 for now.
if (m_height != 24)
{
@@ -249,14 +281,17 @@ WRITE8_MEMBER( vt100_video_device::dc012_w )
break;
case 0x0e:
- break; // (DC12) : 'not supported'
+ m_blink_flip_flop = 0; // 'unsupported' DC012 command. Turn blink flip-flop off.
+ break;
- case 0x0f:
- // (DEC Rainbow 100) : set basic attribute to reverse video / blink flip-flop off
- m_basic_attribute = 1;
+ case 0x0f:
+ // (DEC Rainbow 100): reverse video with 48 lines / blink flip-flop off
m_blink_flip_flop = 0;
+ m_basic_attribute = 1;
- if (m_height_MAX == 25) break; // VT 100.
+ // 0x0f = 'reserved' on VT 100
+ // Abort on VT-100 for now.
+ if (m_height_MAX == 25) break;
if (m_height != 48)
{
@@ -435,102 +470,180 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
}
// ****** RAINBOW ******
-// 5 possible character states (normal, reverse, bold, blink, underline) are encoded into display_type.
+// 5 possible CHARACTER STATES (normal, reverse, bold, blink, underline) are encoded into display_type.
+
+// From the VT-180 specs, chapter 6-43 (where multiple attributes are described):
+// 1) reverse characters [ XOR of reverse video and reverse screen (A) ] normally have dim backgrounds with black characters (B)
+// 2) bold and reverse together give a background of normal intensity
+
+// 3) blink controls intensity: normal chars vary between A) normal and dim (B) bold chars vary between bright and normal
+// 4) blink applied to a
+// A) reverse character causes it to alternate between normal and reverse video representation
+// B) non-rev. " : alternate between usual intensity and the next lower intensity
+// 5) underline causes the 9.th scan to be forced to
+// A) white of the same intensity as the characters (for nonreversed characters),
+// b) to black (for reverse characters)
+
+// LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height'
void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type)
{
- UINT8 xsize, d_xsize;
+ UINT16 y_preset;
+ UINT16 x_preset, d_x_preset;
if (m_columns == 132)
- { xsize = 9;
- d_xsize = 18;
+ { x_preset = x * 9;
+ d_x_preset = x * 18;
} else
{
- xsize = 10;
- d_xsize = 20;
+ x_preset = x * 10;
+ d_x_preset = x * 20;
}
UINT8 line = 0;
- int bit = 0, j=0, invert, bold, blink, underline;
+ int bit = 0, j = 0;
+ int fg_intensity;
+ int back_intensity, back_default_intensity;
+
+ int invert = (display_type & 8) >> 3; // BIT 3 indicates REVERSE
+ int bold = (display_type & 16) >> 4; // BIT 4 indicates BOLD
+ int blink = display_type & 32; // BIT 5 indicates BLINK
+ int underline = display_type & 64; // BIT 6 indicates UNDERLINE
+ bool blank = (display_type & 0x80) ? true : false; // BIT 7 indicates BLANK
- invert = display_type & 8; // BIT 3 indicates REVERSE
- bold = (display_type & 16) >> 4; // BIT 4 indicates BOLD
- blink = display_type & 32; // BIT 5 indicates BLINK
- underline = display_type & 64; // BIT 6 indicates UNDERLINE
display_type = display_type & 3;
- int double_width = (display_type == 1) ? 1 : 0;
+ // CASE 1 A)
+ // SCREEN ATTRIBUTES (see VT-180 manual 6-30):
+ // 'reverse field' = reverse video over entire screen (identical on Rainbow-100)
+
+ // What does 'base attribute' do on Rainbow-100 ?
+ // VT-100 interpretation ('without AVO, eigth char.bit defines base attribute') most likely not correct!
+ // OR 'base attribute' = reverse or underline (depending on the selection of the cursor at SETUP) ??
+ // VT-100 manual 4-75 / 4-98 says: reverse = (reverse field H) XOR (reverse video H = base attribute input)
+
+ // For reference: a complete truth table can be taken from TABLE 4-6-4 / VT100 technical manual.
+ // Following simple IF statements implement it in full. Code should not be shuffled!
+ invert = invert ^ m_reverse_field ^ m_basic_attribute;
+
+ fg_intensity = bold + 2; // FOREGROUND (FG): normal (2) or bright (3)
+
+ back_intensity = 0; // DO NOT SHUFFLE CODE AROUND !!
+ if ( (blink != 0) && ( m_blink_flip_flop != 0 ) )
+ fg_intensity -= 1; // normal => dim bright => normal (when bold)
+
+ // INVERSION: background gets foreground intensity (reduced by 1).
+ // _RELIES ON_ on_ previous evaluation of the BLINK signal (fg_intensity).
+ if (invert != 0)
+ {
+ back_intensity = fg_intensity - 1; // BG: normal => dim; dim => OFF; bright => normal
+
+ if (back_intensity != 0) // FG: avoid 'black on black'
+ fg_intensity = 0;
+ else
+ fg_intensity = fg_intensity + 1; // FG: dim => normal; normal => bright
+ }
+
+ // BG: DEFAULT for entire character (underline overrides this for 1 line) -
+ back_default_intensity = back_intensity;
+
+ bool double_width = (display_type != 3) ? true : false; // all except normal: double width
+ bool double_height = (display_type & 1) ? false : true; // 0,2 = double height
for (int i = 0; i < 10; i++)
{
+ y_preset = y * 10 + i;
+
switch (display_type)
{
- case 0 : // bottom half, double height
- j = (i >> 1) + 5; break;
- case 2 : // top half, double height
- j = (i >> 1); break;
-
- default : j = i; break; // 1: double width / 3: normal
+ case 0 : // bottom half of 'double height, double width' char.
+ j = (i >> 1) + 5;
+ break;
+
+ case 2 : // top half of 'double height, double width' char.
+ j = (i >> 1);
+ break;
+
+ default : // 1: double width
+ // 3: normal
+ j = i;
+ break;
}
+
// modify line since that is how it is stored in rom
if (j == 0) j = 15; else j = j - 1;
line = m_gfx[code * 16 + j];
- if ( i == 8 )
+ // UNDERLINED CHARACTERS (CASE 5 - different in 1 line):
+ back_intensity = back_default_intensity; // 0, 1, 2
+ if ( underline != 0 )
{
- if ( underline != 0 ) line = 0xff;
- }
-
- // Code to handle basic attribute from VT-100
- if ( m_basic_attribute == 1 )
+ if ( i == 8 )
+ {
+ if (invert == 0)
+ line = 0xff; // CASE 5 A)
+ else
+ { line = 0x00; // CASE 5 B)
+ back_intensity = 0; // OVERRIDE: BLACK BACKGROUND
+ }
+ }
+ }
+
+ for (int b = 0; b < 8; b++) // 0..7
{
- if ((code & 0x80) == 0x80)
- invert = 1;
+ if (blank)
+ { bit = m_reverse_field ^ m_basic_attribute;
+ }
else
- invert = 0;
- }
-
- if (m_blink_flip_flop > 0)
- {
- if ( blink != 0 )
{
- line = line ^ 0xff;
+ bit = BIT((line << b), 7);
+
+ if (bit > 0)
+ bit = fg_intensity;
+ else
+ bit = back_intensity;
}
- }
- if (invert != 0)
- line = line ^ 0xff;
- for (int b = 0; b < 8; b++)
- {
- bit = BIT((line << b), 7) << bold;
+ // Double, 'double_height + double_width', then normal.
if (double_width)
{
- bitmap.pix16(y * 10 + i, x * d_xsize + b * 2) = bit;
- bitmap.pix16(y * 10 + i, x * d_xsize + b * 2 + 1) = bit;
+ bitmap.pix16( y_preset, d_x_preset + b * 2 + 1) = bit;
+ bitmap.pix16( y_preset, d_x_preset + b * 2) = bit;
+
+ if (double_height)
+ {
+ bitmap.pix16( 1 + y_preset, d_x_preset + b * 2 + 1) = bit;
+ bitmap.pix16( 1 + y_preset, d_x_preset + b * 2) = bit;
+ }
}
else
{
- bitmap.pix16(y * 10 + i, x * xsize + b) = bit;
+ bitmap.pix16(y_preset, x_preset + b) = bit;
}
- }
-
+ } // for (8 bit)
- // char interleave is filled with last bit
+
+ // char interleave (X) is filled with last bit
if (double_width)
- {
- bitmap.pix16(y * 10 + i, x * d_xsize + 16) = bit;
- bitmap.pix16(y * 10 + i, x * d_xsize + 17) = bit;
- bitmap.pix16(y * 10 + i, x * d_xsize + 18) = bit;
- bitmap.pix16(y * 10 + i, x * d_xsize + 19) = bit;
+ {
+ // double chars: 18 or 20 bits
+ bitmap.pix16(y_preset, d_x_preset + 16) = bit;
+ bitmap.pix16(y_preset, d_x_preset + 17) = bit;
+
+ if (m_columns == 80)
+ { bitmap.pix16(y_preset, d_x_preset + 18) = bit;
+ bitmap.pix16(y_preset, d_x_preset + 19) = bit;
+ }
}
else
- {
- bitmap.pix16(y * 10 + i, x * xsize + 8) = bit;
- if (m_columns == 80)
- bitmap.pix16(y * 10 + i, x * xsize + 9) = bit;
+ { // normal chars: 9 or 10 bits
+ bitmap.pix16(y_preset, x_preset + 8) = bit;
+
+ if (m_columns == 80)
+ bitmap.pix16(y_preset, x_preset + 9) = bit;
}
+ } // for
- }
}
// ****** RAINBOW ******
@@ -543,42 +656,42 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
int ypos = 0;
UINT8 code;
int x = 0;
- UINT8 scroll_region = 1; // binary 1
+ UINT8 scroll_region = 1; // DEFAULT TO 1 = PART OF scroll_region
UINT8 display_type = 3; // binary 11
UINT16 temp = 0;
while (line < (m_height + m_skip_lines))
{
code = m_in_ram_func(addr + xpos);
- if (code == 0xff)
+
+ if ( code == 0x00 ) // TODO: investigate side effect on regular zero character!
+ display_type |= 0x80; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked
+ else
+ display_type &= 0x7f; // else activate display.
+
+ if ( code == 0xff )
{
// end of line, fill empty till end of line
if (line >= m_skip_lines)
{
- // NOTE: display_type is already SHIFTED by 1 ( 1 = DOUBLE WIDTH 40 / 66 )
- for (x = xpos; x < ((display_type == 1) ? (m_columns / 2) : m_columns); x++)
+ // NOTE: display_type is already shifted! All except 3 is DOUBLE WIDTH 40 or 66 chars per line
+ for (x = xpos; x < ( (display_type != 3) ? (m_columns / 2) : m_columns ); x++)
{
- display_char(bitmap, code, x, ypos, scroll_region, display_type);
+ display_char(bitmap, code, x, ypos, scroll_region, display_type | 0x80);
}
+
}
- // move to new data
- temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1);
+ // LINE ATTRIBUTE - valid for all chars on next line ** DO NOT SHUFFLE **
+ attr_addr = ( 0x1000 | (addr + xpos + 1) & 0x0fff );
+
+ // MOVE TO NEW DATA
+ temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1);
addr = (temp) & 0x0fff;
- attr_addr = ((temp) & 0x1fff) - 2;
- // No AVO here.
- attr_addr |= 0x1000;
- if (attr_addr > 0x2000) // Ignore attributes beyond 8192 byte limit (SRAM).
- {
- scroll_region = 1; // binary 1 <- SET DEFAULTS
- display_type = 3; // binary 111
- } else
- {
- temp = m_in_ram_func(attr_addr);
- scroll_region = (temp) & 1;
- display_type = (temp >> 1) & 3;
- }
+ temp = m_in_ram_func(attr_addr);
+ scroll_region = (temp) & 1;
+ display_type = (temp >> 1) & 3;
if (line >= m_skip_lines)
{
@@ -588,33 +701,76 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
line++;
}
else
- {
+ {
// display regular char
if (line >= m_skip_lines)
{
attr_addr = 0x1000 | ( (addr + xpos) & 0x0fff );
temp = m_in_ram_func(attr_addr); // get character attribute
- // TODO: check if reverse bit is treated the same way on real hardware
+ // CONFIRMED: Reverse active on 1. No attributes = 0x0E
// 1 = display char. in REVERSE (encoded as 8)
// 0 = display char. in BOLD (encoded as 16)
// 0 = display char. w. BLINK (encoded as 32)
// 0 = display char. w. UNDERLINE (encoded as 64).
- display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 3 )
- | ( (2-(temp & 2)) << 3 )
- | ( (4-(temp & 4)) << 3 )
- | ( (8-(temp & 8)) << 3 )
+ display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 3 )
+ | ( (2-(temp & 2)) << 3 )
+ | ( (4-(temp & 4)) << 3 )
+ | ( (8-(temp & 8)) << 3 )
);
- }
+
+ }
xpos++;
- if (xpos > m_columns)
+
+ if (xpos > m_columns )
{
- line++;
xpos = 0;
+ line++;
}
- }
+ } // (else) valid char
+
+ } // while
+
+
+}
+
+
+void rainbow_video_device::palette_select ( int choice )
+{
+ switch(choice)
+ {
+ default:
+ case 0x01:
+ palette_set_color_rgb(machine(), 1, 0xff-100, 0xff-100, 0xff-100); // WHITE (dim)
+ palette_set_color_rgb(machine(), 2, 0xff-50, 0xff-50, 0xff-50); // WHITE NORMAL
+ palette_set_color_rgb(machine(), 3, 0xff, 0xff, 0xff); // WHITE (brighter)
+ break;
+
+ case 0x02:
+ palette_set_color_rgb(machine(), 1, 0 , 200 -50, 0); // GREEN (dim)
+ palette_set_color_rgb(machine(), 2, 0 , 200, 0); // GREEN (NORMAL)
+ palette_set_color_rgb(machine(), 3, 0, 200 +50, 0); // GREEN (brighter)
+ break;
+
+ case 0x03:
+ palette_set_color_rgb(machine(), 1, 213 - 47, 146 - 47, 82 - 47); // AMBER (dim)
+ palette_set_color_rgb(machine(), 2, 213, 146, 82); // AMBER (normal - not exact)
+ palette_set_color_rgb(machine(), 3, 255, 193, 129); // AMBER (brighter)
+ break;
}
+}
+// ****** RAINBOW ******
+void rainbow_video_device::video_blanking(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // 'In reverse screen mode, termination forces the beam to the screen background intensity'
+ // Background intensity means 'dim' (1) according to one source. Most certainly not pitch black.
+ bitmap.fill( ((m_reverse_field ^ m_basic_attribute) ? 1 : 0) , cliprect);
+}
+
+int rainbow_video_device::dc012_MHFU()
+{
+ return DEC_MHFU;
}
TIMER_CALLBACK_MEMBER( vt100_video_device::lba7_change )
diff --git a/src/mess/video/vtvideo.h b/src/mess/video/vtvideo.h
index 56514282c7e..953d2c23bc8 100644
--- a/src/mess/video/vtvideo.h
+++ b/src/mess/video/vtvideo.h
@@ -58,6 +58,7 @@ protected:
UINT8 *m_gfx; /* content of char rom */
int m_lba7;
+ bool DEC_MHFU;
// dc012 attributes
UINT8 m_scroll_latch;
@@ -71,6 +72,7 @@ protected:
UINT8 m_skip_lines;
UINT8 m_frequency;
UINT8 m_interlaced;
+
};
@@ -80,7 +82,10 @@ public:
rainbow_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual void video_update(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ virtual void video_blanking(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ int dc012_MHFU();
+ void palette_select(int choice);
protected:
virtual void display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type);
virtual void device_reset();