mirror of
https://github.com/holub/mame
synced 2025-10-07 09:25:34 +03:00
Enhance DEC Rainbow 100 Option Graphics
Colors in highres mode and video levels
This commit is contained in:
parent
ba2cf306fe
commit
9d137d160e
@ -7,8 +7,8 @@
|
|||||||
//-------------------- Differences to VT240: ---------------------------------------------------
|
//-------------------- Differences to VT240: ---------------------------------------------------
|
||||||
// - Registers of graphics option not directly mapped (indirect access via mode register)
|
// - Registers of graphics option not directly mapped (indirect access via mode register)
|
||||||
// - write mask is 16 bits wide (not only 8)
|
// - write mask is 16 bits wide (not only 8)
|
||||||
// - scroll register is 8 bits wide - not 16. Probably also different semantics (see UNTESTED *)
|
// - scroll register is 8 bits wide - not 16.
|
||||||
// - There appears to be NO "DMA scroll mode" and no "line erase mode" (so code sections were deleted). Really?
|
// - no "DMA SCROLL", "LINE ERASE MODE", no ZOOM hardware (factor must always be 1)
|
||||||
|
|
||||||
// Two modes: highres and medres mode (different bank length..?)
|
// Two modes: highres and medres mode (different bank length..?)
|
||||||
// - MEDRES: palette of 16 colors out of 4096. 384 x 240
|
// - MEDRES: palette of 16 colors out of 4096. 384 x 240
|
||||||
@ -25,8 +25,6 @@ THE DEC 'R-M-B' COLOR CABLE VS. THE UNOFFICIAL 'R-G-B' MODE (A BIT OF HISTORY)
|
|||||||
// A patch from one of the archives corrects the GWBASIC palette problem when using 2 monitors [Bavarese].
|
// A patch from one of the archives corrects the GWBASIC palette problem when using 2 monitors [Bavarese].
|
||||||
|
|
||||||
EMULATION SPECIFIC
|
EMULATION SPECIFIC
|
||||||
// If a program disables text output (via port $0A), a log message is given.
|
|
||||||
|
|
||||||
// DUAL MONITOR enables both screens, even if onboard graphics has been accidently shut off
|
// DUAL MONITOR enables both screens, even if onboard graphics has been accidently shut off
|
||||||
// (helps debugging semi broken programs, for example Doodle).
|
// (helps debugging semi broken programs, for example Doodle).
|
||||||
|
|
||||||
@ -37,13 +35,16 @@ SCREEN 1 vs. SCREEN 2 IN EMULATION
|
|||||||
|
|
||||||
BUGS
|
BUGS
|
||||||
- MEDRES LOOKS CORRECT
|
- MEDRES LOOKS CORRECT
|
||||||
- HIRES-MODE UNTESTED.
|
- HIRES-MODE SEMI BROKEN (colors OK, else untested).
|
||||||
- VECTOR MODE SEEMS TO DISPLAY NOTHING AT ALL (16 bit access botched?) Examples: MMIND (MasterMind, after BMP logo), SOLIT (Solitair).
|
- GDC diagnostic disk bails out on 10 of 13 low level tests. Separate SCROLL CHECK crashes CPU. Readback from GDC fails?
|
||||||
- GDC diagnostic disk bails out on 11 of 13 low level tests. SCROLL CHECK crashes CPU.
|
- VECTOR MODE SEEMS TO DISPLAY NOTHING AT ALL (16 bit access botched here in driver?)
|
||||||
|
Interaction of Upd7220 and Rainbow.cpp:
|
||||||
|
- FIG directions / params appear to be odd (lines go 45 degrees up or down instead of straight dir.),
|
||||||
|
- RDAT with MOD 2 is unimplemented. WDAT appears to set "m_bitmap_mod" wrongly ("2" means all pixels will be reset)...
|
||||||
|
Some examples to try: MMIND (MasterMind, after BMP logo), SOLIT (Solitaire), CANON (all freeware games).
|
||||||
|
|
||||||
UNIMPLEMENTED:
|
UNIMPLEMENTED:
|
||||||
// - Video levels for color modes.
|
// - Rainbow 100 A palette quirks (2 bit palette... applies to certain modes only)
|
||||||
// - Rainbow 100 A palette quirks (2 bit palette... in MEDRES only...?)
|
|
||||||
|
|
||||||
UNKNOWN IMPLEMENTATION DETAILS:
|
UNKNOWN IMPLEMENTATION DETAILS:
|
||||||
// a. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
|
// a. READBACK (hard copy programs like JOBSDUMP definitely use it. See also GDC diagnostics). VRAM_R ?
|
||||||
@ -72,7 +73,7 @@ DEC Rainbow 100
|
|||||||
|
|
||||||
Driver-in-progress by R. Belmont and Miodrag Milanovic.
|
Driver-in-progress by R. Belmont and Miodrag Milanovic.
|
||||||
Keyboard fix by Cracyc (June 2016), Baud rate generator by Shattered (July 2016)
|
Keyboard fix by Cracyc (June 2016), Baud rate generator by Shattered (July 2016)
|
||||||
Portions (2013 - 2016) by Karl-Ludwig Deisenhofer (Floppy, ClikClok RTC, NVRAM, DIPs, hard disk).
|
Portions (2013 - 2016) by Karl-Ludwig Deisenhofer (Floppy, ClikClok RTC, NVRAM, DIPs, hard disk, Color Graphics).
|
||||||
|
|
||||||
To unlock floppy drives A-D compile with WORKAROUND_RAINBOW_B (prevents a side effect of ERROR 13).
|
To unlock floppy drives A-D compile with WORKAROUND_RAINBOW_B (prevents a side effect of ERROR 13).
|
||||||
|
|
||||||
@ -91,8 +92,8 @@ 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).
|
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!
|
DATA LOSS POSSIBLE: when in partial emulation mode, F3 performs a hard reset!
|
||||||
|
|
||||||
STATE AS OF JULY 2016
|
STATE AS OF OCTOBER 2016
|
||||||
---------------------
|
------------------------
|
||||||
Driver is based entirely on the DEC-100 'B' variant (DEC-190 and DEC-100 A models are treated as clones).
|
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.
|
While this is OK for the compatible -190, it doesn't do justice to ancient '100 A' hardware.
|
||||||
The public domain file RBCONVERT.ZIP documents how model 'A' differs from version B.
|
The public domain file RBCONVERT.ZIP documents how model 'A' differs from version B.
|
||||||
@ -538,6 +539,7 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER( com8116_a_ft_w );
|
DECLARE_WRITE_LINE_MEMBER( com8116_a_ft_w );
|
||||||
|
|
||||||
DECLARE_WRITE8_MEMBER(GDC_EXTRA_REGISTER_w);
|
DECLARE_WRITE8_MEMBER(GDC_EXTRA_REGISTER_w);
|
||||||
|
DECLARE_READ8_MEMBER(GDC_EXTRA_REGISTER_r);
|
||||||
|
|
||||||
uint32_t screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
uint32_t screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
INTERRUPT_GEN_MEMBER(vblank_irq);
|
INTERRUPT_GEN_MEMBER(vblank_irq);
|
||||||
@ -680,6 +682,13 @@ private:
|
|||||||
emu_timer *cmd_timer;
|
emu_timer *cmd_timer;
|
||||||
|
|
||||||
const int vectors[9] = { 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x02 };
|
const int vectors[9] = { 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x02 };
|
||||||
|
|
||||||
|
// VIDEO LEVELS: 0 is 100 % output; F is 0 % output. Range of 0...255.
|
||||||
|
// LIMITED RANGE levels for 100-A model (valid only for all mono + green out on COLOR MONITOR):
|
||||||
|
//const uint8_t A_MONO_GREEN_video_levels[16] = { 255 , 185, 166, 21, 255 , 185, 166, 21, 255 , 185, 166, 21, 255 , 185, 166, 21};
|
||||||
|
|
||||||
|
// 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 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -689,17 +698,17 @@ m_GDC_INDIRECT_REGISTER = 0; \
|
|||||||
m_GDC_MODE_REGISTER = 0; \
|
m_GDC_MODE_REGISTER = 0; \
|
||||||
m_GDC_WRITE_MASK = 0; \
|
m_GDC_WRITE_MASK = 0; \
|
||||||
m_GDC_write_buffer_index = 0; \
|
m_GDC_write_buffer_index = 0; \
|
||||||
m_GDC_scroll_index = 0; \
|
|
||||||
m_GDC_color_map_index = 0; \
|
m_GDC_color_map_index = 0; \
|
||||||
m_GDC_ALU_PS_REGISTER = 0; \
|
m_GDC_ALU_PS_REGISTER = 0; \
|
||||||
m_vpat = 0; \
|
m_vpat = 0; \
|
||||||
m_patmult = 0; \
|
m_patmult = 1; \
|
||||||
m_patcnt = 0; \
|
m_patcnt = 0; \
|
||||||
m_patidx = 7; \
|
m_patidx = 7; \
|
||||||
m_GDC_FG_BG = 0; \
|
m_GDC_FG_BG = 0; \
|
||||||
m_color_map_changed = true; \
|
m_color_map_changed = true; \
|
||||||
for(int i=0; i <256; i++) { m_GDC_SCROLL_BUFFER[i] = m_GDC_SCROLL_BUFFER_PRELOAD[i] = i; };\
|
for(int i=0; i <256; i++) { m_GDC_SCROLL_BUFFER[i] = m_GDC_SCROLL_BUFFER_PRELOAD[i] = i; };\
|
||||||
m_scroll_buffer_changed = true; \
|
m_GDC_scroll_index = 255; \
|
||||||
|
m_scroll_buffer_changed = true; \
|
||||||
printf("\n** NEC 7220 GDC RESET **\n");
|
printf("\n** NEC 7220 GDC RESET **\n");
|
||||||
|
|
||||||
UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
|
UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
|
||||||
@ -723,28 +732,22 @@ UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels )
|
|||||||
return; // no output from graphics option
|
return; // no output from graphics option
|
||||||
|
|
||||||
// ********************* GET BITMAP DATA FOR 4 PLANES ***************************************
|
// ********************* 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
|
// _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)
|
if(m_GDC_MODE_REGISTER & GDC_MODE_HIGHRES)
|
||||||
{
|
{
|
||||||
// HIGH RES (2 planes, 2 color bits, 4 color map entries / 4 MONOCHROME SHADES)
|
plane0 = m_video_ram[((address & 0x7fff) + 0x00000) >> 1];
|
||||||
// MANUAL: (GDC "sees" 2 planes X 16 bits X 16K words)!
|
plane1 = m_video_ram[((address & 0x7fff) + 0x10000) >> 1];
|
||||||
|
plane2 = plane3 = 0;
|
||||||
// !!! m_video_ram is defined as uint16_t !!!
|
|
||||||
plane0 = m_video_ram[ ((address & 0x7fff) + 0x00000) >> 1 ]; // Video Ram is defined as LITTLE_ENDIAN, 16 (?):
|
|
||||||
plane1 = m_video_ram[ ((address & 0x7fff) + 0x20000) >> 1 ]; // 8 x 32 K is 0x40000, see page 16
|
|
||||||
plane2 = 0;
|
|
||||||
plane3 = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// MED.RESOLUTION (4 planes, 4 color bits, 16 color map entries / 16 (4) MONOCHROME SHADES)
|
// MED.RESOLUTION (4 planes, 4 color bits, 16 color map entries / 16 (4) MONOCHROME SHADES)
|
||||||
// MANUAL SAYS: (GDC "sees" 4 planes X 16 bits X 8K words)!
|
// MANUAL SAYS: (GDC "sees" 4 planes X 16 bits X 8K words)!
|
||||||
plane0 = m_video_ram[((address & 0x3fff) + 0x00000) >> 1];
|
plane0 = m_video_ram[((address & 0x3fff) + 0x00000) >> 1];
|
||||||
plane1 = m_video_ram[((address & 0x3fff) + 0x10000) >> 1]; // 8 x 16 K is 0x20000, see page 16 // OLD: 0x10000
|
plane1 = m_video_ram[((address & 0x3fff) + 0x10000) >> 1];
|
||||||
plane2 = m_video_ram[((address & 0x3fff) + 0x20000) >> 1]; // OLD: 0x20000
|
plane2 = m_video_ram[((address & 0x3fff) + 0x20000) >> 1];
|
||||||
plane3 = m_video_ram[((address & 0x3fff) + 0x30000) >> 1]; // OLD: 0x30000
|
plane3 = m_video_ram[((address & 0x3fff) + 0x30000) >> 1];
|
||||||
}
|
}
|
||||||
// ********************* GET BITMAP DATA per PLANE ***************************************
|
|
||||||
|
|
||||||
bool mono = (m_inp13->read() == MONO_MONITOR) ? true : false; // 1 = MONO, 2 = COLOR, 3 = DUAL MONITOR
|
bool mono = (m_inp13->read() == MONO_MONITOR) ? true : false; // 1 = MONO, 2 = COLOR, 3 = DUAL MONITOR
|
||||||
|
|
||||||
@ -770,7 +773,6 @@ FLOPPY_FORMATS_END
|
|||||||
static SLOT_INTERFACE_START(rainbow_floppies)
|
static SLOT_INTERFACE_START(rainbow_floppies)
|
||||||
SLOT_INTERFACE("525qd0", FLOPPY_525_QD) // QD means 80 tracks with DD data rate (single or double sided).
|
SLOT_INTERFACE("525qd0", FLOPPY_525_QD) // QD means 80 tracks with DD data rate (single or double sided).
|
||||||
SLOT_INTERFACE("525qd1", FLOPPY_525_QD)
|
SLOT_INTERFACE("525qd1", FLOPPY_525_QD)
|
||||||
//SLOT_INTERFACE("525sd", FLOPPY_525_SD) // mimic a 5.25 DEC Robin (40 track SINGLE SIDED drive). BIOS DETECTED?
|
|
||||||
SLOT_INTERFACE("525dd", FLOPPY_525_DD) // mimic a 5.25" PC (40 track) drive. Requires IDrive5.SYS.
|
SLOT_INTERFACE("525dd", FLOPPY_525_DD) // mimic a 5.25" PC (40 track) drive. Requires IDrive5.SYS.
|
||||||
SLOT_INTERFACE("35dd", FLOPPY_35_DD) // mimic 3.5" PC drive (720K, double density). Use Impdrv3.SYS.
|
SLOT_INTERFACE("35dd", FLOPPY_35_DD) // mimic 3.5" PC drive (720K, double density). Use Impdrv3.SYS.
|
||||||
SLOT_INTERFACE_END
|
SLOT_INTERFACE_END
|
||||||
@ -877,6 +879,7 @@ AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("kbdser", i8251_device, status_r, control_w
|
|||||||
|
|
||||||
// EXTRA HARDWARE (Write Buffer, Pattern Register/Multiplier, ALU/PS, Color Map, readback and offset/scroll hardware):
|
// EXTRA HARDWARE (Write Buffer, Pattern Register/Multiplier, ALU/PS, Color Map, readback and offset/scroll hardware):
|
||||||
AM_RANGE(0x50, 0x55) AM_WRITE(GDC_EXTRA_REGISTER_w)
|
AM_RANGE(0x50, 0x55) AM_WRITE(GDC_EXTRA_REGISTER_w)
|
||||||
|
AM_RANGE(0x50, 0x55) AM_READ(GDC_EXTRA_REGISTER_r)
|
||||||
|
|
||||||
// 56h Data written is loaded into the GDC's FIFO and flagged as a parameter.
|
// 56h Data written is loaded into the GDC's FIFO and flagged as a parameter.
|
||||||
// 57h Data written is loaded into the GDC's FIFO and flagged as a command.
|
// 57h Data written is loaded into the GDC's FIFO and flagged as a command.
|
||||||
@ -1031,8 +1034,8 @@ PORT_DIPSETTING(0x01, DEF_STR(On))
|
|||||||
|
|
||||||
PORT_START("MONITOR CONFIGURATION") // GDC-NEW
|
PORT_START("MONITOR CONFIGURATION") // GDC-NEW
|
||||||
PORT_DIPNAME(0x03, 0x03, "MONITOR CONFIGURATION")
|
PORT_DIPNAME(0x03, 0x03, "MONITOR CONFIGURATION")
|
||||||
PORT_DIPSETTING(0x01, "MONO ONLY (SCREEN 2: 16 monochrome shades)")
|
PORT_DIPSETTING(0x01, "MONO ONLY / 4 to 16 monochrome shades (single VR-201)")
|
||||||
PORT_DIPSETTING(0x02, "COLOR ONLY (SCREEN 2: R-G-B; mono -> green)")
|
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)")
|
PORT_DIPSETTING(0x03, "DUAL MONITOR (SCREEN 1: TEXT; SCREEN 2: R-G-B)")
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
@ -1210,7 +1213,12 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1
|
|||||||
m_color_map_changed = true;
|
m_color_map_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int palette_selected = m_inp9->read();
|
int palette_selected;
|
||||||
|
if( m_ONBOARD_GRAPHICS_SELECTED && (monitor_selected == COLOR_MONITOR) )
|
||||||
|
palette_selected = 2; // Color monitor; green text
|
||||||
|
else
|
||||||
|
palette_selected = m_inp9->read();
|
||||||
|
|
||||||
if(palette_selected != old_palette)
|
if(palette_selected != old_palette)
|
||||||
{
|
{
|
||||||
old_palette = palette_selected;
|
old_palette = palette_selected;
|
||||||
@ -1219,12 +1227,8 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1
|
|||||||
|
|
||||||
m_crtc->palette_select(palette_selected);
|
m_crtc->palette_select(palette_selected);
|
||||||
|
|
||||||
// GDC-NEW
|
if( m_SCREEN_BLANK ||
|
||||||
// NEC 7220 output (MONO or COLOR) can only be shown on the RIGHT hand side,
|
( (!m_ONBOARD_GRAPHICS_SELECTED) && (monitor_selected != DUAL_MONITOR) ) // blank screen 1, except when in DUAL_MONITOR mode
|
||||||
// so disable TEXT out if 'dual monitor' is unselected.
|
|
||||||
// BLANK SCREEN : ONLY IF 1) graphics option output selected AND 2) no multi monitor setup selected
|
|
||||||
if( m_SCREEN_BLANK ||
|
|
||||||
( (!m_ONBOARD_GRAPHICS_SELECTED) && (monitor_selected != 3))
|
|
||||||
)
|
)
|
||||||
m_crtc->video_blanking(bitmap, cliprect);
|
m_crtc->video_blanking(bitmap, cliprect);
|
||||||
else
|
else
|
||||||
@ -2344,88 +2348,103 @@ IRQ_CALLBACK_MEMBER(rainbow_state::irq_callback)
|
|||||||
// VERIFY: SCROLL_MAP & COLOR_MAP are updated at the next VSYNC (not immediately)... Are there more registers?
|
// VERIFY: SCROLL_MAP & COLOR_MAP are updated at the next VSYNC (not immediately)... Are there more registers?
|
||||||
WRITE_LINE_MEMBER(rainbow_state::GDC_vblank_irq)
|
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);
|
||||||
|
|
||||||
uint8_t red, green, blue, mono;
|
uint8_t red, green, blue, mono;
|
||||||
int xi;
|
int xi;
|
||||||
|
|
||||||
// VIDEO LEVELS: 0 is 100 % output; F is 0 % output
|
|
||||||
// Levels for 100-B model, taken from page 46 of PDF, multiplied by 2.55 to obtain a range of 0...255
|
|
||||||
const uint8_t v_levels[16] = { 255, 217, 201,186, 171, 156, 140, 125, 110, 97, 79, 66, 54, 31, 18, 0 };
|
|
||||||
|
|
||||||
if(m_scroll_buffer_changed)
|
if(m_scroll_buffer_changed)
|
||||||
{
|
{
|
||||||
m_scroll_buffer_changed = false;
|
m_scroll_buffer_changed = false;
|
||||||
|
|
||||||
for(xi = 0; xi < 256; xi++) // LOAD REAL SCROLL BUFFER FROM PRELOAD BUFFER:
|
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];
|
m_GDC_SCROLL_BUFFER[xi] = m_GDC_SCROLL_BUFFER_PRELOAD[xi];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_color_map_changed)
|
if(m_color_map_changed)
|
||||||
{
|
{
|
||||||
m_color_map_changed = false;
|
m_color_map_changed = false;
|
||||||
|
|
||||||
|
int mono_sum = 0;
|
||||||
|
int green_sum = 0;
|
||||||
for(xi=0;xi<16;xi++) // DELAYED LOAD OF PALETTE ...
|
for(xi=0;xi<16;xi++) // DELAYED LOAD OF PALETTE ...
|
||||||
{
|
{
|
||||||
uint8_t colordata1 = m_GDC_COLOR_MAP[xi];
|
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...?
|
uint8_t colordata2 = m_GDC_COLOR_MAP[xi + 16]; // Does it matter if the palette is incomplete...?
|
||||||
|
|
||||||
|
// Color map: 32 x 8
|
||||||
|
// 2nd 16 Byte 1st 16 Bytes (colordata1)
|
||||||
|
// ----------- ------------
|
||||||
|
// 7..4 3..0 7..4 3..0
|
||||||
|
// Mono Blue Red Green
|
||||||
|
// NOTE: 2nd 16 BYTES ARE MONO PALETTE, 1st 16 ARE COLOR PALETTE * HERE * (on the VT240 driver, it is the other way round)
|
||||||
|
|
||||||
// Color map: 32 x 8
|
|
||||||
// 2nd 16 Byte 1st 16 Bytes (colordata1)
|
|
||||||
// ----------- ------------
|
|
||||||
// 7..4 3..0 7..4 3..0
|
|
||||||
// Mono Blue Red Green
|
|
||||||
mono = (colordata2 & 0xF0) >> 4; // FIXME: limit palette in appropriate modes on 100-A
|
mono = (colordata2 & 0xF0) >> 4; // FIXME: limit palette in appropriate modes on 100-A
|
||||||
|
mono_sum += mono;
|
||||||
|
|
||||||
blue = (colordata2 & 0x0F);
|
blue = (colordata2 & 0x0F);
|
||||||
|
|
||||||
red = (colordata1 & 0xF0) >> 4;
|
red = (colordata1 & 0xF0) >> 4;
|
||||||
green =(colordata1 & 0x0F);
|
green =(colordata1 & 0x0F);
|
||||||
// NOTE: SECOND 16 BYTES ARE MONO PALETTE, _FIRST_ 16 ARE COLOR PALETTE * HERE * (on the VT240 driver, it is the other way round)
|
green_sum += green;
|
||||||
|
|
||||||
switch( m_inp13->read())
|
switch( m_inp13->read())
|
||||||
{
|
{
|
||||||
case MONO_MONITOR: // FIXME: bad colors!
|
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
|
case 1: // BLACK & WHITE
|
||||||
m_palette2->set_pen_color(xi + 16, pal4bit(mono), pal4bit(mono), pal4bit(mono) );
|
mono = uint8_t( ( 205.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
|
||||||
|
m_palette2->set_pen_color(xi + 16, rgb_t( mono, mono, mono) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // SHADES OF GREEN
|
case 2: // SHADES OF GREEN
|
||||||
// For now, a hand picked value from VTVIDEO * is coarsly transformed into a RGB value.
|
red = uint8_t( ( 35.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) ); // 80 % = NORMAL *
|
||||||
red = uint8_t( ( 35.0f / 80.0f) * ( v_levels[ mono ] / 3.19f) ); // 80 % = NORMAL *
|
green = uint8_t( (145.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
|
||||||
green = uint8_t( (145.0f / 80.0f) * ( v_levels[ mono ] / 3.19f) );
|
blue = uint8_t( ( 75.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
|
||||||
blue = uint8_t( ( 75.0f / 80.0f) * ( v_levels[ mono ] / 3.19f) );
|
m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
|
||||||
m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // AMBER. Assumption: "normal" value at 80 % is 213, 146, 82 (decimal)
|
case 3: // AMBER. Assumption: "normal" value at 80 % is 213, 146, 82 (decimal)
|
||||||
red = uint8_t( (213.0f / 80.0f) * ( v_levels[ mono ] / 3.19f) ); // 80 % = NORMAL * is 3.19f (100 % would be 2.55f)
|
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) * ( v_levels[ mono ] / 3.19f) );
|
green = uint8_t( (146.0f / 80.0f) * ( video_levels[ mono ] / 3.19f) );
|
||||||
blue = uint8_t( ( 82.0f / 80.0f) * ( v_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) );
|
m_palette2->set_pen_color(xi + 16, rgb_t( red, green, blue) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 255 durch 2.55 ist 100 255 durch x ist 80
|
break;
|
||||||
}
|
}
|
||||||
case COLOR_MONITOR: // w.official COLOR CABLE (mono out wired to green gun)
|
|
||||||
m_palette2->set_pen_color(xi, pal4bit( red ) , pal4bit( mono ) , pal4bit( blue ) );
|
case COLOR_MONITOR:
|
||||||
|
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) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DUAL_MONITOR: // Dual monitor configuration with homebrew cable (R G B, separate onboard circuit is mono)
|
case DUAL_MONITOR:
|
||||||
m_palette2->set_pen_color(xi, pal4bit( red ), pal4bit( green ), pal4bit( blue ) );
|
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) );
|
||||||
break;
|
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)
|
||||||
|
if ( m_inp13->read() == DUAL_MONITOR)
|
||||||
|
printf(" [HINT: DUAL MONITOR (DIP SWITCH) WRONG! NO GREEN PALETTE] ");
|
||||||
} // color map changed?
|
} // color map changed?
|
||||||
|
} // 7220 vblank IRQ
|
||||||
|
|
||||||
// Raising it aftwards seems more reasonable.
|
|
||||||
// ....but there is a chance to introduce timing issues with the current code -
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq)
|
INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq)
|
||||||
{
|
{
|
||||||
@ -2652,24 +2671,18 @@ READ16_MEMBER(rainbow_state::vram_r)
|
|||||||
{
|
{
|
||||||
if((!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR)) || space.debugger_access()) // (NOT VECTOR MODE)
|
if((!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR)) || space.debugger_access()) // (NOT VECTOR MODE)
|
||||||
{
|
{
|
||||||
//offset = ((offset & 0x18000) >> 1) | (offset & 0x3fff); // VT 240
|
// SCROLL_MAP IN BITMAP MODE ONLY...?
|
||||||
|
if(m_GDC_MODE_REGISTER & GDC_MODE_HIGHRES)
|
||||||
//*******************************************************************************************************************************
|
offset = ( m_GDC_SCROLL_BUFFER[ (offset & 0x3FC0) >> 6 ] << 6) | (offset & 0x3F);
|
||||||
// NEW SCROLL_MAP - "valid for reading, writing, and refreshing"
|
else
|
||||||
// SEE PAGE 48 OF PDF FOR A DESCRIPTION OF THE SCROLL_MAP / SCROLL BUFFER:
|
offset = ( m_GDC_SCROLL_BUFFER[ (offset & 0x1FC0) >> 6 ] << 6) | (offset & 0x3F);
|
||||||
offset = ( m_GDC_SCROLL_BUFFER[ ( (offset & 0x3FC0) >> 6 ) ] << 6) | (offset & 0x3F);
|
|
||||||
//*******************************************************************************************************************************
|
|
||||||
|
|
||||||
int readback_plane = 0;
|
int readback_plane = 0;
|
||||||
|
|
||||||
// READBACK CODE DISABLED, FOR BETTER DEBUGGING (CANT SEE ANYTHING...):
|
if( !(m_GDC_MODE_REGISTER & GDC_MODE_ENABLE_WRITES) ) // 0x10 // READBACK OPERATION - if ENABLE_WRITES NOT SET
|
||||||
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)];
|
||||||
// printf(" READBACK MODE * ON *; plane selected: %02x ", readback_plane);
|
|
||||||
}
|
|
||||||
return m_video_ram[ (offset & 0xffff) + (0x8000 * readback_plane)];
|
|
||||||
//return m_video_ram[(offset & 0x7fff) + (0x8000 * readback_plane)]; // VT240
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2681,18 +2694,13 @@ READ16_MEMBER(rainbow_state::vram_r)
|
|||||||
// Rainbow has separate registers for fore and background.
|
// Rainbow has separate registers for fore and background.
|
||||||
WRITE16_MEMBER(rainbow_state::vram_w)
|
WRITE16_MEMBER(rainbow_state::vram_w)
|
||||||
{
|
{
|
||||||
//uint8_t *video_ram8 = (uint8_t *)(&m_video_ram[0]);
|
if(!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR))
|
||||||
|
|
||||||
if(!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR)) // NOT VECTOR MODE
|
|
||||||
{
|
{
|
||||||
|
// SCROLL_MAP IN BITMAP MODE ONLY...?
|
||||||
//*******************************************************************************************************************************
|
if(m_GDC_MODE_REGISTER & GDC_MODE_HIGHRES)
|
||||||
// NEW SCROLL_MAP - "valid for reading, writing, and refreshing"
|
offset = ( m_GDC_SCROLL_BUFFER[ (offset & 0x3FC0) >> 6 ] << 6) | (offset & 0x3F);
|
||||||
// SEE PAGE 48 OF PDF FOR A DESCRIPTION OF THE SCROLL_MAP / SCROLL BUFFER:
|
else
|
||||||
offset = ( m_GDC_SCROLL_BUFFER[ ( (offset & 0x3FC0) >> 6 ) ] << 6) | (offset & 0x3F);
|
offset = ( m_GDC_SCROLL_BUFFER[ (offset & 0x1FC0) >> 6 ] << 6) | (offset & 0x3F);
|
||||||
//*******************************************************************************************************************************
|
|
||||||
|
|
||||||
offset |= BIT(offset, 16); // leftover from VT240 (GDC has 18 bit, Duell schematics dont show if A16 und A17 are connected...)
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2773,21 +2781,35 @@ WRITE16_MEMBER(rainbow_state::vram_w)
|
|||||||
back >>= 1;
|
back >>= 1;
|
||||||
|
|
||||||
} // plane select (LOOP)
|
} // plane select (LOOP)
|
||||||
return; // ??
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!(m_GDC_MODE_REGISTER & GDC_MODE_VECTOR))
|
|
||||||
data = (chr & ~m_GDC_WRITE_MASK) | (m_video_ram[offset] & m_GDC_WRITE_MASK);
|
|
||||||
else
|
|
||||||
data = (chr & data) | (m_video_ram[offset] & ~data);
|
|
||||||
|
|
||||||
// < scroll thingy from VT240 omitted >
|
|
||||||
|
|
||||||
m_video_ram[offset] = data;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (READ)
|
||||||
|
// Read _preloaded_ scroll buffer (see GDC Diagnostic Disk, SCROLL BUFFER test)
|
||||||
|
READ8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_r)
|
||||||
|
{
|
||||||
|
uint8_t out = 0;
|
||||||
|
switch(offset)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_SCROLL_MAP ) // 0x80
|
||||||
|
{
|
||||||
|
// Documentation says it is always incremented, no matter if read or write:
|
||||||
|
out = m_GDC_SCROLL_BUFFER_PRELOAD[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);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("\n * UNHANDLED CASE: READ REGISTER 50..55 with INDIRECT_REGISTER $%02x and OFFSET $%02x *", m_GDC_INDIRECT_REGISTER, offset);
|
||||||
|
break;
|
||||||
|
} // switch
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
|
WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w)
|
||||||
{
|
{
|
||||||
@ -3061,7 +3083,6 @@ MCFG_SCREEN_VISIBLE_AREA(0, 800-1, 0, 256-1) // should be 240
|
|||||||
MCFG_FD1793_ADD(FD1793_TAG, XTAL_24_0734MHz / 24) // no separate 1 Mhz quartz
|
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)
|
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":0", rainbow_floppies, "525qd0", rainbow_state::floppy_formats)
|
||||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525qd1", rainbow_state::floppy_formats)
|
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525qd1", rainbow_state::floppy_formats)
|
||||||
//MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525sd", rainbow_state::floppy_formats)
|
|
||||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_state::floppy_formats)
|
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_state::floppy_formats)
|
||||||
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_state::floppy_formats)
|
MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_state::floppy_formats)
|
||||||
MCFG_SOFTWARE_LIST_ADD("flop_list", "rainbow")
|
MCFG_SOFTWARE_LIST_ADD("flop_list", "rainbow")
|
||||||
|
Loading…
Reference in New Issue
Block a user