(MESS) Rainbow updates:

* add beeper, NVRAM. LED output for keyboard, Z80 and 8088 [Bavarese]
* correct NVRAM mirroring [R. Belmont]
* DC012 48 line mode. 3 new character attributes (reverse, blink, underline) [Bavarese]
This commit is contained in:
R. Belmont 2013-08-20 03:35:47 +00:00
parent e73eaf2945
commit 122b5f9f86
5 changed files with 469 additions and 15 deletions

1
.gitattributes vendored
View File

@ -6926,6 +6926,7 @@ src/mess/layout/poly880.lay svneol=native#text/plain
src/mess/layout/pro80.lay svneol=native#text/plain
src/mess/layout/px4.lay svneol=native#text/plain
src/mess/layout/px8.lay svneol=native#text/plain
src/mess/layout/rainbow.lay svneol=native#text/plain
src/mess/layout/ravens.lay svneol=native#text/plain
src/mess/layout/savia84.lay svneol=native#text/plain
src/mess/layout/sc1.lay svneol=native#text/plain

View File

@ -64,8 +64,9 @@ DEC-100 model B
PCB # 5416206 / 5016205-01C1:
DIAGNOSTIC-
|----------- LED --|VIDEO|-|PRINTER|-|SERIAL|----|
7-6-5-4 |3-2-1
DIAGNOSTIC-LEDs |J3 | |J2 | |J1 |
|------|----8088|Z80-|-|VIDEO|-|PRINTER|-|SERIAL||
| 2 x 64 K |
| R A M NEC D7201C |P| [??]|
| |O| |
@ -91,6 +92,10 @@ W18 pulls DSR to ground and affects 8251A - port $11 (bit 7).
W18 jumper location is unverified. There is no code to pull DSR yet!
W13 - W15 affect diagnostic read register (port $0a)
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)
****************************************************************************/
#include "emu.h"
@ -101,6 +106,12 @@ W13 - W15 affect diagnostic read register (port $0a)
#include "imagedev/flopdrv.h"
#include "machine/i8251.h"
#include "machine/dec_lk201.h"
#include "sound/beep.h"
#include "machine/nvram.h"
#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
{
@ -112,6 +123,7 @@ public:
m_inp3(*this, "W15"),
m_inp4(*this, "W18"),
m_beep(*this, "beeper"),
m_crtc(*this, "vt100_video"),
m_i8088(*this, "maincpu"),
m_z80(*this, "subcpu"),
@ -119,6 +131,7 @@ public:
m_kbd8251(*this, "kbdser"),
m_lk201(*this, LK201_TAG),
m_p_ram(*this, "p_ram"),
m_p_nvram(*this, "nvram"),
m_shared(*this, "sh_ram"),
m_maincpu(*this, "maincpu") { }
@ -127,6 +140,9 @@ public:
required_ioport m_inp3;
required_ioport m_inp4;
required_device<beep_device> m_beep;
required_device<rainbow_video_device> m_crtc;
required_device<cpu_device> m_i8088;
required_device<cpu_device> m_z80;
@ -134,6 +150,7 @@ public:
required_device<i8251_device> m_kbd8251;
required_device<lk201_device> m_lk201;
required_shared_ptr<UINT8> m_p_ram;
required_shared_ptr<UINT8> m_p_nvram;
required_shared_ptr<UINT8> m_shared;
UINT8 m_diagnostic;
@ -145,11 +162,18 @@ public:
DECLARE_READ8_MEMBER(diagnostic_r);
DECLARE_WRITE8_MEMBER(diagnostic_w);
DECLARE_WRITE8_MEMBER(comm_control_w);
DECLARE_READ8_MEMBER(share_z80_r);
DECLARE_WRITE8_MEMBER(share_z80_w);
DECLARE_READ8_MEMBER(floating_bus_r);
// EMULATOR TRAP TO INTERCEPT KEYBOARD cmd in AH and PARAMETER in AL (port 90 = AL / port 91 = AH)
// TODO: beeper and led handling should better be handled by LK201 code.
DECLARE_WRITE8_MEMBER(PORT90_W);
DECLARE_WRITE8_MEMBER(PORT91_W);
DECLARE_READ8_MEMBER(i8088_latch_r);
DECLARE_WRITE8_MEMBER(i8088_latch_w);
DECLARE_READ8_MEMBER(z80_latch_r);
@ -157,7 +181,10 @@ public:
DECLARE_WRITE8_MEMBER(z80_diskdiag_read_w);
DECLARE_WRITE8_MEMBER(z80_diskdiag_write_w);
DECLARE_WRITE8_MEMBER(z80_diskcontrol_write_w);
DECLARE_READ8_MEMBER(system_parameter_r);
DECLARE_READ_LINE_MEMBER(kbd_rx);
DECLARE_WRITE_LINE_MEMBER(kbd_tx);
DECLARE_WRITE_LINE_MEMBER(kbd_rxready_w);
@ -166,6 +193,9 @@ public:
bool m_zflip; // Z80 alternate memory map with A15 inverted
bool m_z80_halted;
bool m_kbd_tx_ready, m_kbd_rx_ready;
int m_KBD;
int m_beep_counter;
private:
UINT8 m_z80_private[0x800]; // Z80 private 2K
@ -188,6 +218,34 @@ void rainbow_state::machine_start()
save_item(NAME(m_zflip));
save_item(NAME(m_kbd_tx_ready));
save_item(NAME(m_kbd_rx_ready));
UINT8 *rom = memregion("maincpu")->base();
// Enables PORT90_W + PORT91_W via BIOS call (offset +$21 in HIGH ROM)
// F8 / FC ROM REGION (CHECK + PATCH)
if(rom[0xfc000 + 0x0022] == 0x22 && rom[0xfc000 + 0x0023] == 0x28)
{
rom[0xf4303]=0x00; // Disable CRC CHECK (F0 / F4 ROM)
rom[0xfc000 + 0x0022] =0xe2; // jmp to offset $3906
rom[0xfc000 + 0x0023] =0x38;
rom[0xfc000 + 0x3906] =0xe6; // out 90,al
rom[0xfc000 + 0x3907] =0x90;
rom[0xfc000 + 0x3908] =0x86; // xchg al,ah
rom[0xfc000 + 0x3909] =0xc4;
rom[0xfc000 + 0x390a] =0xe6; // out 91,al
rom[0xfc000 + 0x390b] =0x91;
rom[0xfc000 + 0x390c] =0x86; // xchg al,ah
rom[0xfc000 + 0x390d] =0xc4;
rom[0xfc000 + 0x390e] =0xe9; // jmp (original jump offset $2846)
rom[0xfc000 + 0x390f] =0x35;
rom[0xfc000 + 0x3910] =0xef;
}
}
static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state)
@ -196,7 +254,16 @@ static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state)
AM_RANGE(0x10000, 0x1ffff) AM_RAM
AM_RANGE(0x20000, 0xdffff) AM_READ(floating_bus_r) // test at f4e1c
AM_RANGE(0x20000, 0x3ffff) AM_RAM
AM_RANGE(0xec000, 0xedfff) AM_RAM
// TODO: handle shadowing 100% correctly.
// PDF says there is a 256 x 4 bit NVRAM from 0xed000 to 0xed040.
// * SHOULD * be shadowed from $ec00 - $ecfff AND FROM $ed040 - $edfff.
// "address bits 8-12 are not decoded when accessing the NVM"
// ROM code gives an error if NVRAM isn't 256 x 8 bit
// with address bits 8-12 ignored, so do that.
AM_RANGE(0xec000, 0xec0ff) AM_MIRROR(0x1f00) AM_RAM AM_SHARE("nvram")
AM_RANGE(0xee000, 0xeffff) AM_RAM AM_SHARE("p_ram")
AM_RANGE(0xf0000, 0xfffff) AM_ROM
ADDRESS_MAP_END
@ -205,15 +272,24 @@ static ADDRESS_MAP_START( rainbow8088_io , AS_IO, 8, rainbow_state)
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE (0x00, 0x00) AM_READWRITE(i8088_latch_r, i8088_latch_w)
// 0x02 Communication status / control register (8088)
AM_RANGE (0x02, 0x02) AM_WRITE(comm_control_w)
// 0x04 Video processor DC011
AM_RANGE (0x04, 0x04) AM_DEVWRITE("vt100_video", rainbow_video_device, dc011_w)
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)
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)
AM_RANGE (0x90, 0x90) AM_WRITE(PORT90_W)
AM_RANGE (0x91, 0x91) AM_WRITE(PORT91_W)
ADDRESS_MAP_END
static ADDRESS_MAP_START(rainbowz80_mem, AS_PROGRAM, 8, rainbow_state)
@ -227,7 +303,7 @@ static ADDRESS_MAP_START( rainbowz80_io, AS_IO, 8, rainbow_state)
AM_RANGE(0x00, 0x00) AM_READWRITE(z80_latch_r, z80_latch_w)
AM_RANGE(0x20, 0x20) AM_WRITE(z80_diskdiag_read_w)
AM_RANGE(0x21, 0x21) AM_WRITE(z80_diskdiag_write_w)
AM_RANGE(0x40, 0x40) AM_WRITE(z80_diskcontrol_write_w)
AM_RANGE(0x60, 0x60) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_status_r, wd17xx_command_w)
AM_RANGE(0x61, 0x61) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_track_r, wd17xx_track_w)
AM_RANGE(0x62, 0x62) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_sector_r, wd17xx_sector_w)
@ -264,6 +340,27 @@ void rainbow_state::machine_reset()
m_kbd_tx_ready = m_kbd_rx_ready = false;
m_kbd8251->input_callback(SERIAL_STATE_CTS); // raise clear to send
m_KBD = 0;
m_beep->set_frequency(2000);
m_beep->set_state(0);
// RESET ALL LEDs
output_set_value("led1", 1);
output_set_value("led2", 1);
output_set_value("led3", 1);
output_set_value("led4", 1);
output_set_value("led5", 1);
output_set_value("led6", 1);
output_set_value("led7", 1);
output_set_value("led8", 1);
output_set_value("led9", 1);
output_set_value("led10", 1);
output_set_value("led11", 1);
output_set_value("led20", 1); // DRIVE 0 (A)
output_set_value("led21", 1); // DRIVE 1 (B)
}
UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
@ -333,6 +430,92 @@ WRITE8_MEMBER(rainbow_state::share_z80_w)
}
}
READ8_MEMBER(rainbow_state::system_parameter_r)
{
/* Info about option boards is in bits 0 - 3:
Bundle card (1) | Floppy (2) | Graphics (4) | Memory option (8)
0 1 2 3 4 5 6 7
B F G M
( 1 means NOT present )
*/
// return 0x0f;
return 0x0f - 2;
}
WRITE8_MEMBER(rainbow_state::comm_control_w)
{
/* Communication control register of -COMM- port (when written):
8088 LEDs:
5 7 6 4 <- BIT POSITION
D6 -D5-D4-D3 <- INTERNAL LED NUMBER (DEC PDF)
-4--5--6--7- <- NUMBERS EMBOSSED ON BACK OF PLASTIC HOUSING (see error chart)
*/
output_set_value("led4", BIT(data, 5)); // LED "D6"
output_set_value("led5", BIT(data, 7)); // LED "D5"
output_set_value("led6", BIT(data, 6)); // LED "D4"
output_set_value("led7", BIT(data, 4)); // LED "D3"
// printf("%02x to COMM.CONTROL REGISTER\n", data);
}
// EMULATOR TRAP (patched into ROM @ machine_start) via BIOS : call / offset +$21 (AL / AH)
WRITE8_MEMBER(rainbow_state::PORT90_W)
{
//printf("KBD COMMAND : %02x to AL (90)\n", data);
m_KBD = 0; // reset previous command.
if (data == 0xfd) { // Powerup (beep)
m_beep->set_state(1);
m_beep_counter=600; // BELL = 125 ms
}
if (data == 0xa7) {
m_beep->set_state(1);
m_beep_counter=600; // BELL = 125 ms
}
if (data == 0x9f) { // emit a keyclick (2ms)
m_beep->set_state(1);
m_beep_counter=25; // longer than calculated ( 9,6 )
}
if (data == 0x13) { // light LEDs -
m_KBD = 0x13;
}
if (data == 0x11) { // switch off LEDs -
m_KBD = 0x11;
}
}
WRITE8_MEMBER(rainbow_state::PORT91_W)
{
//printf("KBD PARAM %02x to AH (91) \n", data);
// 4 leds, represented in the low 4 bits of a byte
if (m_KBD == 0x13) { // light LEDs -
if (data & 1) { output_set_value("led8", 0); } // KEYBOARD : "Wait" LED
if (data & 2) { output_set_value("led9", 0); } // KEYBOARD : "Compose" LED
if (data & 4) { output_set_value("led10", 0); } // KEYBOARD : "Lock" LED
if (data & 8) { output_set_value("led11", 0); } // KEYBOARD : "Hold" LED
m_KBD = 0; // reset previous command.
}
if (m_KBD == 0x11) { // switch off LEDs -
if (data & 1) { output_set_value("led8", 1); } // KEYBOARD : "Wait" LED
if (data & 2) { output_set_value("led9", 1); } // KEYBOARD : "Compose" LED
if (data & 4) { output_set_value("led10", 1); } // KEYBOARD : "Lock" LED
if (data & 8) { output_set_value("led11", 1); } // KEYBOARD : "Hold" LED
m_KBD = 0; // reset previous command.
}
if (m_KBD == 0x1b) { /* enable the keyclick */
/* max volume is 0, lowest is 0x7 */
m_KBD = 0; // reset previous command.
}
}
READ8_MEMBER(rainbow_state::i8088_latch_r)
{
// printf("Read %02x from 8088 mailbox\n", m_8088_mailbox);
@ -368,9 +551,35 @@ WRITE8_MEMBER(rainbow_state::z80_diskdiag_read_w)
WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w)
{
/* Z80 LEDs:
4 5 6 <- bit #
D11 D10 -D9 <- INTERNAL LED NUMBER (see PDF)
-1 --2-- 3 <- NUMBERS EMBOSSED ON BACK OF PLASTIC HOUSING (see error chart)
*/
output_set_value("led1", BIT(data, 4)); // LED "D11"
output_set_value("led2", BIT(data, 5)); // LED "D10"
output_set_value("led3", BIT(data, 6)); // LED "D9"
m_zflip = false;
}
WRITE8_MEMBER(rainbow_state::z80_diskcontrol_write_w)
{
//printf("%02x to z80 DISK CONTROL (W)\n", data);
// TODO: this logic is a bit primitive. According to the spec, the RX-50 drive LED only turns on if
// (a) spindle motor runs (b) disk is in drive (c) door closed (d) drive side is selected
if ( (data & 1) && (data & 8) )
output_set_value("led20", 0); // DISKETTE 0 SELECTED & MOTOR 0 ON => LIGHT "DRIVE A"
else
output_set_value("led20", 1);
if ( (data & 2) && (data & 8) )
output_set_value("led21", 0); // DISKETTE 1 SELECTED & MOTOR 0 ON => LIGHT "DRIVE B"
else
output_set_value("led21", 1);
}
READ8_MEMBER( rainbow_state::read_video_ram_r )
{
return m_p_ram[offset];
@ -390,9 +599,10 @@ READ8_MEMBER( rainbow_state::diagnostic_r )
{
// printf("%02x DIP value ORed to diagnostic\n", ( m_inp1->read() | m_inp2->read() | m_inp3->read() ) );
return m_diagnostic | ( m_inp1->read() |
return ( (m_diagnostic & (0xf1)) | ( m_inp1->read() |
m_inp2->read() |
m_inp3->read() );
m_inp3->read() )
);
}
WRITE8_MEMBER( rainbow_state::diagnostic_w )
@ -457,6 +667,14 @@ TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::keyboard_tick)
{
m_kbd8251->transmit_clock();
m_kbd8251->receive_clock();
if (m_beep_counter > 1)
m_beep_counter--;
else
if ( m_beep_counter == 1 )
{ m_beep->set_state(0);
m_beep_counter = 0;
}
}
static const vt_video_interface video_interface =
@ -520,6 +738,8 @@ static const i8251_interface i8251_intf =
};
static MACHINE_CONFIG_START( rainbow, rainbow_state )
MCFG_DEFAULT_LAYOUT(layout_rainbow)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",I8088, XTAL_24_0734MHz / 5)
MCFG_CPU_PROGRAM_MAP(rainbow8088_map)
@ -534,13 +754,18 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(80*10, 25*10)
MCFG_SCREEN_SIZE(132*10, 49*10)
MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*10-1)
MCFG_SCREEN_UPDATE_DRIVER(rainbow_state, screen_update_rainbow)
MCFG_GFXDECODE(rainbow)
MCFG_PALETTE_LENGTH(2)
MCFG_PALETTE_INIT_OVERRIDE(driver_device, monochrome_green)
MCFG_RAINBOW_VIDEO_ADD("vt100_video", video_interface)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beeper", BEEP, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.50)
MCFG_FD1793_ADD("wd1793", rainbow_wd17xx_interface )
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf)
@ -550,6 +775,7 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state )
MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", rainbow_state, keyboard_tick, attotime::from_hz(4800))
MCFG_LK201_ADD()
MCFG_NVRAM_ADD_0FILL("nvram")
MACHINE_CONFIG_END
/* ROM definition */

172
src/mess/layout/rainbow.lay Normal file
View File

@ -0,0 +1,172 @@
<mamelayout version="2">
<element name="led" defstate="0">
<disk state="0">
<color red="0.75" green="0.0" blue="0.0" />
</disk>
<disk state="1">
<color red="0.20" green="0.0" blue="0.0" />
</disk>
</element>
<element name="DRIVE0">
<text string="A">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="DRIVE1">
<text string="B">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l1">
<text string="1">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l2">
<text string="2">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l3">
<text string="3">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l4">
<text string="4">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l5">
<text string="5">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l6">
<text string="6">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l7">
<text string="7">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l8">
<text string="WAIT">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l9">
<text string="COMP">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l10">
<text string="LOCK">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="l11">
<text string="HOLD">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<view name="Default Layout">
<screen index="0">
<bounds x="30" y="0" width="640" height="480" />
</screen>
<bezel name="led20" element="led">
<bounds x="15" y="3" width="10" height="10" />
</bezel>
<bezel name="led21" element="led">
<bounds x="15" y="18" width="10" height="10" />
</bezel>
<bezel name="led1" element="led">
<bounds x="15" y="43" width="10" height="10" />
</bezel>
<bezel name="led2" element="led">
<bounds x="15" y="63" width="10" height="10" />
</bezel>
<bezel name="led3" element="led">
<bounds x="15" y="83" width="10" height="10" />
</bezel>
<bezel name="led4" element="led">
<bounds x="15" y="103" width="10" height="10" />
</bezel>
<bezel name="led5" element="led">
<bounds x="15" y="123" width="10" height="10" />
</bezel>
<bezel name="led6" element="led">
<bounds x="15" y="143" width="10" height="10" />
</bezel>
<bezel name="led7" element="led">
<bounds x="15" y="163" width="10" height="10" />
</bezel>
<bezel name="led8" element="led">
<bounds x="15" y="193" width="10" height="10" />
</bezel>
<bezel name="led9" element="led">
<bounds x="15" y="213" width="10" height="10" />
</bezel>
<bezel name="led10" element="led">
<bounds x="15" y="232" width="10" height="10" />
</bezel>
<bezel name="led11" element="led">
<bounds x="15" y="252" width="10" height="10" />
</bezel>
<bezel name="label20" element="DRIVE0">
<bounds x="0" y="0" width="15" height="16" />
</bezel>
<bezel name="label21" element="DRIVE1">
<bounds x="0" y="14" width="15" height="16" />
</bezel>
<bezel name="label1" element="l1">
<bounds x="0" y="40" width="15" height="16" />
</bezel>
<bezel name="label2" element="l2">
<bounds x="0" y="60" width="15" height="16" />
</bezel>
<bezel name="label3" element="l3">
<bounds x="0" y="80" width="15" height="16" />
</bezel>
<bezel name="label4" element="l4">
<bounds x="0" y="100" width="15" height="16" />
</bezel>
<bezel name="label5" element="l5">
<bounds x="0" y="120" width="15" height="16" />
</bezel>
<bezel name="label6" element="l6">
<bounds x="0" y="140" width="15" height="16" />
</bezel>
<bezel name="label7" element="l7">
<bounds x="0" y="160" width="15" height="16" />
</bezel>
<bezel name="label8" element="l8">
<bounds x="0" y="189" width="15" height="16" />
</bezel>
<bezel name="label9" element="l9">
<bounds x="0" y="209" width="15" height="16" />
</bezel>
<bezel name="label10" element="l10">
<bounds x="0" y="229" width="15" height="16" />
</bezel>
<bezel name="label11" element="l11">
<bounds x="0" y="249" width="15" height="16" />
</bezel>
</view>
<view name="Screen Only">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
</view>
</mamelayout>

View File

@ -2581,6 +2581,7 @@ $(MESS_DRIVERS)/pro80.o: $(MESS_LAYOUT)/pro80.lh
$(MESS_DRIVERS)/px4.o: $(MESS_LAYOUT)/px4.lh
$(MESS_DRIVERS)/px8.o: $(MESS_LAYOUT)/px8.lh
$(MESS_DRIVERS)/ravens.o: $(MESS_LAYOUT)/ravens.lh
$(MESS_DRIVERS)/rainbow.o: $(MESS_LAYOUT)/rainbow.lh
$(MESS_DRIVERS)/savia84.o: $(MESS_LAYOUT)/savia84.lh
$(MESS_DRIVERS)/sc1.o: $(MESS_LAYOUT)/sc1.lh
$(MESS_DRIVERS)/sc2.o: $(MESS_LAYOUT)/sc2.lh

View File

@ -132,7 +132,7 @@ void vt100_video_device::recompute_parameters()
rectangle visarea;
horiz_pix_total = m_columns * 10;
vert_pix_total = 25 * 10;
vert_pix_total = m_height * 10;
visarea.set(0, horiz_pix_total - 1, 0, vert_pix_total - 1);
@ -190,11 +190,28 @@ WRITE8_MEMBER( vt100_video_device::dc012_w )
// set basic attribute to reverse video
m_basic_attribute = 1;
m_blink_flip_flop = 0;
if (m_height != 25)
{
m_height = 25; // -1 = 24 lines (default)
recompute_parameters();
}
break;
case 0x0e:
// (DC12) : not supported
break;
case 0x0f:
// reserved for future specification
// (VT100) : reserved for future specification
// (DEC Rainbow 100) : set basic attribute to reverse video / blink flip-flop off
m_basic_attribute = 1;
m_blink_flip_flop = 0;
// (DEC Rainbow 100) : 48 line display
if (m_height != 49)
{
m_height = 49;
recompute_parameters();
}
break;
}
}
@ -364,10 +381,20 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
}
// 5 possible character states (normal, reverse, bold, blink, underline) are encoded into display_type.
// TODO: bold not implemented yet -
void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type)
{
UINT8 line = 0;
int bit = 0, j;
int bit = 0, j, invert, blink, underline;
invert = display_type & 4; // BIT 2 indicates REVERSE
// bold = display_type & 8; // BIT 3 indicates BOLD
blink = display_type & 16; // BIT 4 indicates BLINK
underline = display_type & 32; // BIT 5 indicates UNDERLINE
display_type = display_type & 3;
int double_width = (display_type == 2) ? 1 : 0;
for (int i = 0; i < 10; i++)
@ -387,14 +414,29 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x,
if (j == 0) j = 15; else j = j - 1;
line = m_gfx[code * 16 + j];
if (m_basic_attribute == 1)
if ( i == 8 )
{
if ( underline != 0 ) line = 0xff;
}
// TODO: test if basic attribute behaves the same on DEC-100
if ( m_basic_attribute == 1 )
{
if ((code & 0x80) == 0x80)
{
line = line ^ 0xff;
}
}
if (m_blink_flip_flop > 0)
{
if ( blink != 0 )
{
line = line ^ 0xff;
}
}
if (invert != 0)
line = line ^ 0xff;
for (int b = 0; b < 8; b++)
{
bit = BIT((line << b), 7);
@ -471,7 +513,19 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
// display regular char
if (line >= m_skip_lines)
{
display_char(bitmap, code, xpos, ypos, scroll_region, display_type);
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
// 1 = display char. in REVERSE (encoded as 4)
// 0 = display char. in BOLD (encoded as 8)
// 0 = display char. w. BLINK (encoded as 16)
// 0 = display char. w. UNDERLINE (encoded as 32).
display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 2 )
| ( (2-(temp & 2)) << 2 )
| ( (4-(temp & 4)) << 2 )
| ( (8-(temp & 8)) << 2 )
);
}
xpos++;
if (xpos > m_columns)