mirror of
https://github.com/holub/mame
synced 2025-07-03 00:56:03 +03:00
mc6847: s68047 has different colors from mc6847, and graphics mode 5 has a different resolution,
sv8000: add custom palette, small cleanup/organize
This commit is contained in:
parent
6ff4e69b09
commit
256e42e3d8
@ -142,24 +142,24 @@ constexpr int BMP_ACTIVE_VIDEO = CLOCKS_ACTIVE_VIDEO * 2;
|
||||
|
||||
const uint32_t mc6847_base_device::s_palette[mc6847_base_device::PALETTE_LENGTH] =
|
||||
{
|
||||
rgb_t(0x30, 0xd2, 0x00), /* GREEN */
|
||||
rgb_t(0xc1, 0xe5, 0x00), /* YELLOW */
|
||||
rgb_t(0x4c, 0x3a, 0xb4), /* BLUE */
|
||||
rgb_t(0x9a, 0x32, 0x36), /* RED */
|
||||
rgb_t(0xbf, 0xc8, 0xad), /* BUFF */
|
||||
rgb_t(0x41, 0xaf, 0x71), /* CYAN */
|
||||
rgb_t(0xc8, 0x4e, 0xf0), /* MAGENTA */
|
||||
rgb_t(0xd4, 0x7f, 0x00), /* ORANGE */
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0xc1, 0xe5, 0x00), // YELLOW
|
||||
rgb_t(0x4c, 0x3a, 0xb4), // BLUE
|
||||
rgb_t(0x9a, 0x32, 0x36), // RED
|
||||
rgb_t(0xbf, 0xc8, 0xad), // BUFF
|
||||
rgb_t(0x41, 0xaf, 0x71), // CYAN
|
||||
rgb_t(0xc8, 0x4e, 0xf0), // MAGENTA
|
||||
rgb_t(0xd4, 0x7f, 0x00), // ORANGE
|
||||
|
||||
rgb_t(0x26, 0x30, 0x16), /* BLACK */
|
||||
rgb_t(0x30, 0xd2, 0x00), /* GREEN */
|
||||
rgb_t(0x26, 0x30, 0x16), /* BLACK */
|
||||
rgb_t(0xbf, 0xc8, 0xad), /* BUFF */
|
||||
rgb_t(0x26, 0x30, 0x16), // BLACK
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0x26, 0x30, 0x16), // BLACK
|
||||
rgb_t(0xbf, 0xc8, 0xad), // BUFF
|
||||
|
||||
rgb_t(0x00, 0x7c, 0x00), /* ALPHANUMERIC DARK GREEN */
|
||||
rgb_t(0x30, 0xd2, 0x00), /* ALPHANUMERIC BRIGHT GREEN */
|
||||
rgb_t(0x6b, 0x27, 0x00), /* ALPHANUMERIC DARK ORANGE */
|
||||
rgb_t(0xff, 0xb7, 0x00) /* ALPHANUMERIC BRIGHT ORANGE */
|
||||
rgb_t(0x00, 0x7c, 0x00), // ALPHANUMERIC DARK GREEN
|
||||
rgb_t(0x30, 0xd2, 0x00), // ALPHANUMERIC BRIGHT GREEN
|
||||
rgb_t(0x6b, 0x27, 0x00), // ALPHANUMERIC DARK ORANGE
|
||||
rgb_t(0xff, 0xb7, 0x00) // ALPHANUMERIC BRIGHT ORANGE
|
||||
};
|
||||
|
||||
|
||||
@ -341,7 +341,7 @@ TIMER_CALLBACK_MEMBER(mc6847_friend_device::change_horizontal_sync)
|
||||
if (m_partial_scanline_clocks > 0)
|
||||
record_partial_body_scanline(m_physical_scanline, m_logical_scanline, m_partial_scanline_clocks, CLOCKS_HSYNC_PERIOD);
|
||||
else
|
||||
record_body_scanline(m_physical_scanline, m_logical_scanline);
|
||||
record_full_body_scanline(m_physical_scanline, m_logical_scanline);
|
||||
m_recording_scanline = false;
|
||||
break;
|
||||
|
||||
@ -628,14 +628,7 @@ mc6847_base_device::mc6847_base_device(
|
||||
m_fixed_mode(0),
|
||||
m_fixed_mode_mask(0)
|
||||
{
|
||||
m_palette = s_palette;
|
||||
|
||||
for (int i = 0; i < std::size(s_palette); i++)
|
||||
{
|
||||
m_bw_palette[i] = black_and_white(s_palette[i]);
|
||||
}
|
||||
|
||||
m_artifacter.create_color_blend_table( s_palette );
|
||||
set_palette(s_palette);
|
||||
}
|
||||
|
||||
|
||||
@ -713,7 +706,15 @@ void mc6847_base_device::device_start()
|
||||
save_item(NAME(m_mode));
|
||||
|
||||
/* colors */
|
||||
m_palette = m_black_and_white ? m_bw_palette : s_palette;
|
||||
if (m_black_and_white)
|
||||
{
|
||||
for (int i = 0; i < PALETTE_LENGTH; i++)
|
||||
m_bw_palette[i] = black_and_white(m_palette[i]);
|
||||
|
||||
m_palette = m_bw_palette;
|
||||
}
|
||||
|
||||
m_artifacter.create_color_blend_table(m_palette);
|
||||
}
|
||||
|
||||
|
||||
@ -792,14 +793,14 @@ void mc6847_base_device::record_scanline_res(int scanline, int32_t start_pos, in
|
||||
// record_body_scanline
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void mc6847_base_device::record_body_scanline(uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos)
|
||||
void mc6847_base_device::record_body_scanline(uint8_t mode, uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos)
|
||||
{
|
||||
// sanity checks
|
||||
assert(scanline < LINES_ACTIVE_VIDEO);
|
||||
|
||||
if (m_mode & MODE_AG)
|
||||
if (mode & MODE_AG)
|
||||
{
|
||||
switch(m_mode & (MODE_GM2|MODE_GM1|MODE_GM0))
|
||||
switch(mode & (MODE_GM2|MODE_GM1|MODE_GM0))
|
||||
{
|
||||
case 0:
|
||||
case MODE_GM0:
|
||||
@ -844,9 +845,9 @@ inline void mc6847_base_device::record_body_scanline(uint16_t physical_scanline,
|
||||
// record_body_scanline
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc6847_base_device::record_body_scanline(uint16_t physical_scanline, uint16_t scanline)
|
||||
void mc6847_base_device::record_full_body_scanline(uint16_t physical_scanline, uint16_t scanline)
|
||||
{
|
||||
record_body_scanline(physical_scanline, scanline, 0, 32);
|
||||
record_body_scanline(m_mode, physical_scanline, scanline, 0, 32);
|
||||
}
|
||||
|
||||
|
||||
@ -861,7 +862,7 @@ void mc6847_base_device::record_partial_body_scanline(uint16_t physical_scanline
|
||||
int32_t end_pos = std::min(scanline_position_from_clock(end_clock), 42);
|
||||
|
||||
if (start_pos < end_pos)
|
||||
record_body_scanline(physical_scanline, scanline, start_pos, end_pos);
|
||||
record_body_scanline(m_mode, physical_scanline, scanline, start_pos, end_pos);
|
||||
}
|
||||
|
||||
|
||||
@ -919,27 +920,18 @@ void mc6847_base_device::field_sync_changed(bool line)
|
||||
// border_value
|
||||
//-------------------------------------------------
|
||||
|
||||
inline mc6847_base_device::pixel_t mc6847_base_device::border_value(uint8_t mode, const pixel_t *palette, bool is_mc6847t1)
|
||||
uint8_t mc6847_base_device::border_value(uint8_t mode)
|
||||
{
|
||||
pixel_t result;
|
||||
switch(mc6847_friend_device::border_value(mode, is_mc6847t1))
|
||||
if (mode & MODE_AG)
|
||||
{
|
||||
case BORDER_COLOR_BLACK:
|
||||
result = palette[8];
|
||||
break;
|
||||
case BORDER_COLOR_GREEN:
|
||||
result = palette[0];
|
||||
break;
|
||||
case BORDER_COLOR_WHITE:
|
||||
result = palette[4];
|
||||
break;
|
||||
case BORDER_COLOR_ORANGE:
|
||||
result = palette[7];
|
||||
break;
|
||||
default:
|
||||
fatalerror("Should not get here\n");
|
||||
// graphics, green or white
|
||||
return (~mode & MODE_CSS) ? 0 : 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text, black
|
||||
return 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -950,7 +942,6 @@ inline mc6847_base_device::pixel_t mc6847_base_device::border_value(uint8_t mode
|
||||
|
||||
uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
const bool is_mc6847t1 = (type() == MC6847T1_NTSC) || (type() == MC6847T1_PAL);
|
||||
int base_x = BMP_L_OR_R_BORDER;
|
||||
int base_y = m_lines_top_border;
|
||||
int min_x = USE_HORIZONTAL_CLIP ? cliprect.min_x : 0;
|
||||
@ -968,8 +959,8 @@ uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &
|
||||
{
|
||||
// PAL padding is always black, even when border isn't
|
||||
const pixel_t color = is_top_pal_padding_line(y)
|
||||
? palette[8]
|
||||
: border_value(m_data[0].m_mode[0], palette, is_mc6847t1);
|
||||
? palette[8]
|
||||
: palette[border_value(m_data[0].m_mode[0])];
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
@ -982,7 +973,7 @@ uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &
|
||||
/* left border */
|
||||
for (int x = min_x; x < base_x; x++)
|
||||
{
|
||||
*bitmap_addr(bitmap, y + base_y, x) = border_value(m_data[y].m_mode[0], palette, is_mc6847t1);
|
||||
*bitmap_addr(bitmap, y + base_y, x) = palette[border_value(m_data[y].m_mode[0])];
|
||||
}
|
||||
|
||||
/* body */
|
||||
@ -996,7 +987,7 @@ uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &
|
||||
;
|
||||
|
||||
/* emit the samples */
|
||||
pixels += emit_mc6847_samples<1>(
|
||||
pixels += emit_samples(
|
||||
m_data[y].m_mode[x],
|
||||
&m_data[y].m_data[x],
|
||||
x2 - x,
|
||||
@ -1013,7 +1004,7 @@ uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &
|
||||
/* right border */
|
||||
if (width)
|
||||
for (int x = base_x + BMP_ACTIVE_VIDEO; x <= max_x; x++)
|
||||
*bitmap_addr(bitmap, y + base_y, x) = border_value(m_data[y].m_mode[width - 1], palette, is_mc6847t1);
|
||||
*bitmap_addr(bitmap, y + base_y, x) = palette[border_value(m_data[y].m_mode[width - 1])];
|
||||
|
||||
/* artifacting */
|
||||
if (m_artifacter.get_pal_artifacting())
|
||||
@ -1037,7 +1028,7 @@ uint32_t mc6847_base_device::screen_update(screen_device &screen, bitmap_rgb32 &
|
||||
// PAL padding is always black, even when border isn't
|
||||
pixel_t color = is_bottom_pal_padding_line(y)
|
||||
? palette[8]
|
||||
: border_value(m_data[LINES_ACTIVE_VIDEO - 1].m_mode[width - 1], palette, is_mc6847t1);
|
||||
: palette[border_value(m_data[LINES_ACTIVE_VIDEO - 1].m_mode[width - 1])];
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
@ -1635,7 +1626,7 @@ bool mc6847_base_device::artifacter::poll_config()
|
||||
void mc6847_base_device::artifacter::update_colors(pixel_t c0, pixel_t c1)
|
||||
{
|
||||
/* Boy this code sucks; this code was adapted from the old M6847
|
||||
* artifacting implmentation. The only reason that it didn't look as
|
||||
* artifacting implementation. The only reason that it didn't look as
|
||||
* horrible was because the code around it sucked as well. Now that I
|
||||
* have cleaned everything up, the ugliness is much more prominent.
|
||||
*
|
||||
@ -1756,7 +1747,7 @@ DEFINE_DEVICE_TYPE(MC6847Y_NTSC, mc6847y_ntsc_device, "mc6847y_ntsc", "Motoro
|
||||
DEFINE_DEVICE_TYPE(MC6847Y_PAL, mc6847y_pal_device, "mc6847y_pal", "Motorola MC6847Y VDG (PAL)")
|
||||
DEFINE_DEVICE_TYPE(MC6847T1_NTSC, mc6847t1_ntsc_device, "mc6847t1_ntsc", "Motorola MC6847T1 VDG (NTSC)")
|
||||
DEFINE_DEVICE_TYPE(MC6847T1_PAL, mc6847t1_pal_device, "mc6847t1_pal", "Motorola MC6847T1 VDG (PAL)")
|
||||
DEFINE_DEVICE_TYPE(S68047, s68047_device, "s68047", "AMI S68047")
|
||||
DEFINE_DEVICE_TYPE(S68047, s68047_device, "s68047", "AMI S68047 VDG")
|
||||
DEFINE_DEVICE_TYPE(M5C6847P1, m5c6847p1_device, "m5c6847p1", "Mitsubishi M5C6847P-1 VDG")
|
||||
|
||||
|
||||
@ -1811,11 +1802,35 @@ mc6847y_pal_device::mc6847y_pal_device(const machine_config &mconfig, const char
|
||||
// mc6847t1_ntsc_device
|
||||
//-------------------------------------------------
|
||||
|
||||
mc6847t1_ntsc_device::mc6847t1_ntsc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mc6847_base_device(mconfig, MC6847T1_NTSC, tag, owner, clock, vdg_t1_fontdata8x12, 262.0, false)
|
||||
mc6847t1_ntsc_device::mc6847t1_ntsc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint8_t *fontdata, double tpfs, bool pal)
|
||||
: mc6847_base_device(mconfig, type, tag, owner, clock, fontdata, tpfs, pal)
|
||||
{
|
||||
}
|
||||
|
||||
mc6847t1_ntsc_device::mc6847t1_ntsc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mc6847t1_ntsc_device(mconfig, MC6847T1_NTSC, tag, owner, clock, vdg_t1_fontdata8x12, 262.0, false)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t mc6847t1_ntsc_device::border_value(uint8_t mode)
|
||||
{
|
||||
if (mode & MODE_AG)
|
||||
{
|
||||
// graphics, green or white
|
||||
return (~mode & MODE_CSS) ? 0 : 4;
|
||||
}
|
||||
else if (mode & MODE_GM2)
|
||||
{
|
||||
// text, green or orange
|
||||
return (~mode & MODE_CSS) ? 0 : 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text, black
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -1823,7 +1838,7 @@ mc6847t1_ntsc_device::mc6847t1_ntsc_device(const machine_config &mconfig, const
|
||||
//-------------------------------------------------
|
||||
|
||||
mc6847t1_pal_device::mc6847t1_pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mc6847_base_device(mconfig, MC6847T1_PAL, tag, owner, clock, vdg_t1_fontdata8x12, 312.0, true)
|
||||
: mc6847t1_ntsc_device(mconfig, MC6847T1_PAL, tag, owner, clock, vdg_t1_fontdata8x12, 312.0, true)
|
||||
{
|
||||
m_artifacter.set_pal_artifacting(true);
|
||||
}
|
||||
@ -1837,46 +1852,69 @@ mc6847t1_pal_device::mc6847t1_pal_device(const machine_config &mconfig, const ch
|
||||
s68047_device::s68047_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mc6847_base_device(mconfig, S68047, tag, owner, clock, s68047_fontdata8x12, 262.0, false)
|
||||
{
|
||||
set_palette(s_s68047_palette);
|
||||
}
|
||||
|
||||
// AMI S68047 colors are different from MC6847
|
||||
|
||||
//
|
||||
// In the Bandai Super Vision 8000 there is a video setting
|
||||
// bit which causes black to be displayed as blue when css=1.
|
||||
//
|
||||
// This is probably done through circuitry outside the s68047,
|
||||
// but lacking schematics we don't know how it is hooked up
|
||||
// exactly.
|
||||
//
|
||||
// See https://www.youtube.com/watch?v=QCo24GLyff4
|
||||
//
|
||||
void s68047_device::hack_black_becomes_blue(bool flag)
|
||||
const uint32_t s68047_device::s_s68047_palette[16] =
|
||||
{
|
||||
set_custom_palette( flag ? s_s68047_hack_palette : nullptr );
|
||||
}
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0xc1, 0xe5, 0x00), // YELLOW
|
||||
rgb_t(0x41, 0xaf, 0x71), // CYAN
|
||||
rgb_t(0x9a, 0x32, 0x36), // RED
|
||||
rgb_t(0x4c, 0x3a, 0xb4), // BLUE
|
||||
rgb_t(0x20, 0xd8, 0xe0), // CYAN/BLUE
|
||||
rgb_t(0xc8, 0x4e, 0xf0), // MAGENTA
|
||||
rgb_t(0xd4, 0x7f, 0x00), // ORANGE
|
||||
|
||||
const uint32_t s68047_device::s_s68047_hack_palette[16] =
|
||||
{
|
||||
rgb_t(0x07, 0xff, 0x00), /* GREEN */
|
||||
rgb_t(0xff, 0xff, 0x00), /* YELLOW */
|
||||
rgb_t(0x3b, 0x08, 0xff), /* BLUE */
|
||||
rgb_t(0xcc, 0x00, 0x3b), /* RED */
|
||||
rgb_t(0xff, 0xff, 0xff), /* BUFF */
|
||||
rgb_t(0x07, 0xe3, 0x99), /* CYAN */
|
||||
rgb_t(0xff, 0x1c, 0xff), /* MAGENTA */
|
||||
rgb_t(0xff, 0x81, 0x00), /* ORANGE */
|
||||
rgb_t(0x26, 0x30, 0x16), // BLACK
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0x26, 0x30, 0x16), // BLACK
|
||||
rgb_t(0x20, 0xd8, 0xe0), // CYAN/BLUE
|
||||
|
||||
rgb_t(0x00, 0x00, 0x00), /* BLACK */
|
||||
rgb_t(0x07, 0xff, 0x00), /* GREEN */
|
||||
rgb_t(0x3b, 0x08, 0xff), /* BLUE */
|
||||
rgb_t(0xff, 0xff, 0xff), /* BUFF */
|
||||
|
||||
rgb_t(0x00, 0x7c, 0x00), /* ALPHANUMERIC DARK GREEN */
|
||||
rgb_t(0x07, 0xff, 0x00), /* ALPHANUMERIC BRIGHT GREEN */
|
||||
rgb_t(0x91, 0x00, 0x00), /* ALPHANUMERIC DARK ORANGE */
|
||||
rgb_t(0xff, 0x81, 0x00) /* ALPHANUMERIC BRIGHT ORANGE */
|
||||
rgb_t(0x00, 0x7c, 0x00), // BLACK
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0x00, 0x00, 0x6a), // BLACK
|
||||
rgb_t(0x4c, 0x3a, 0xb4) // BLUE
|
||||
};
|
||||
|
||||
uint8_t s68047_device::border_value(uint8_t mode)
|
||||
{
|
||||
if (mode & MODE_AG)
|
||||
{
|
||||
// graphics, green or cyan/blue
|
||||
return (~mode & MODE_CSS) ? 9 : 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text, same as text background
|
||||
return (~mode & MODE_CSS) ? 12 : 14;
|
||||
}
|
||||
}
|
||||
|
||||
// GRAPHICS 5 mode (GM0 + GM2) is 256*96 instead of 128*192
|
||||
|
||||
void s68047_device::record_body_scanline(uint8_t mode, uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos)
|
||||
{
|
||||
if ((mode & (MODE_AG|MODE_GM2|MODE_GM1|MODE_GM0)) == (MODE_AG|MODE_GM2|MODE_GM0))
|
||||
record_scanline_res<32, 96>(scanline, start_pos, end_pos);
|
||||
else
|
||||
mc6847_base_device::record_body_scanline(mode, physical_scanline, scanline, start_pos, end_pos);
|
||||
}
|
||||
|
||||
uint32_t s68047_device::emit_samples(uint8_t mode, const uint8_t *data, int length, pixel_t *RESTRICT pixels,
|
||||
const pixel_t *RESTRICT palette, get_char_rom_delegate const &get_char_rom, int x, int y)
|
||||
{
|
||||
if ((mode & (MODE_AG|MODE_GM2|MODE_GM1|MODE_GM0)) == (MODE_AG|MODE_GM2|MODE_GM0))
|
||||
{
|
||||
emit_graphics<1, 1>(data, length, pixels, (mode & MODE_CSS) ? 10 : 8, palette);
|
||||
return length * 8;
|
||||
}
|
||||
else
|
||||
return emit_mc6847_samples<1>(mode, data, length, pixels, palette, get_char_rom, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -212,11 +212,11 @@ protected:
|
||||
for (x = 0; x < 256; x += 2)
|
||||
{
|
||||
uint8_t val = ((pixels[(x - 2) * xscale] == c1) ? 0x20 : 0x00)
|
||||
| ((pixels[(x - 1) * xscale] == c1) ? 0x10 : 0x00)
|
||||
| ((pixels[(x + 0) * xscale] == c1) ? 0x08 : 0x00)
|
||||
| ((pixels[(x + 1) * xscale] == c1) ? 0x04 : 0x00)
|
||||
| ((pixels[(x + 2) * xscale] == c1) ? 0x02 : 0x00)
|
||||
| ((pixels[(x + 3) * xscale] == c1) ? 0x01 : 0x00);
|
||||
| ((pixels[(x - 1) * xscale] == c1) ? 0x10 : 0x00)
|
||||
| ((pixels[(x + 0) * xscale] == c1) ? 0x08 : 0x00)
|
||||
| ((pixels[(x + 1) * xscale] == c1) ? 0x04 : 0x00)
|
||||
| ((pixels[(x + 2) * xscale] == c1) ? 0x02 : 0x00)
|
||||
| ((pixels[(x + 3) * xscale] == c1) ? 0x01 : 0x00);
|
||||
|
||||
new_line[x + 0] = m_expanded_colors[val * 2 + 0];
|
||||
new_line[x + 1] = m_expanded_colors[val * 2 + 1];
|
||||
@ -246,14 +246,6 @@ protected:
|
||||
static pixel_t mix_color(double factor, uint8_t c0, uint8_t c1);
|
||||
};
|
||||
|
||||
enum border_color_t
|
||||
{
|
||||
BORDER_COLOR_BLACK,
|
||||
BORDER_COLOR_GREEN,
|
||||
BORDER_COLOR_WHITE,
|
||||
BORDER_COLOR_ORANGE
|
||||
};
|
||||
|
||||
// callbacks
|
||||
devcb_write_line m_write_hsync;
|
||||
devcb_write_line m_write_fsync;
|
||||
@ -277,7 +269,7 @@ protected:
|
||||
virtual void field_sync_changed(bool line);
|
||||
virtual void enter_bottom_border();
|
||||
virtual void record_border_scanline(uint16_t physical_scanline);
|
||||
virtual void record_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline) = 0;
|
||||
virtual void record_full_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline) = 0;
|
||||
virtual void record_partial_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline, int32_t start_clock, int32_t end_clock) = 0;
|
||||
|
||||
// miscellaneous
|
||||
@ -305,29 +297,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// calculates the border color
|
||||
static ATTR_FORCE_INLINE border_color_t border_value(uint8_t mode, bool is_mc6847t1)
|
||||
{
|
||||
border_color_t result;
|
||||
|
||||
if (mode & MODE_AG)
|
||||
{
|
||||
// graphics
|
||||
result = mode & MODE_CSS ? BORDER_COLOR_WHITE : BORDER_COLOR_GREEN;
|
||||
}
|
||||
else if (!is_mc6847t1 || ((mode & MODE_GM2) == 0))
|
||||
{
|
||||
// text, black border
|
||||
result = BORDER_COLOR_BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text, green or orange border
|
||||
result = mode & MODE_CSS ? BORDER_COLOR_ORANGE : BORDER_COLOR_GREEN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// checks to see if the video has changed
|
||||
ATTR_FORCE_INLINE bool has_video_changed()
|
||||
{
|
||||
@ -532,6 +501,9 @@ public:
|
||||
void intext_w(int state) { change_mode(MODE_INTEXT, state); }
|
||||
void inv_w(int state) { change_mode(MODE_INV, state); }
|
||||
|
||||
// palette
|
||||
void set_palette(const uint32_t *palette) { m_palette = (palette) ? palette : default_palette(); }
|
||||
|
||||
protected:
|
||||
mc6847_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint8_t *fontdata, double tpfs, bool pal);
|
||||
|
||||
@ -543,16 +515,23 @@ protected:
|
||||
|
||||
// other overrides
|
||||
virtual void field_sync_changed(bool line) override;
|
||||
virtual void record_body_scanline(uint16_t physical_scanline, uint16_t scanline) override;
|
||||
virtual void record_full_body_scanline(uint16_t physical_scanline, uint16_t scanline) override;
|
||||
virtual void record_partial_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline, int32_t start_clock, int32_t end_clock) override;
|
||||
|
||||
void set_custom_palette(const pixel_t *custom_palette)
|
||||
virtual uint32_t emit_samples(uint8_t mode, const uint8_t *data, int length, pixel_t *RESTRICT pixels, const pixel_t *RESTRICT palette,
|
||||
get_char_rom_delegate const &get_char_rom, int x, int y)
|
||||
{
|
||||
if (m_palette != m_bw_palette)
|
||||
{
|
||||
m_palette = custom_palette ? custom_palette : s_palette;
|
||||
}
|
||||
return emit_mc6847_samples<1>(mode, data, length, pixels, palette, get_char_rom, x, y);
|
||||
}
|
||||
virtual const uint32_t* default_palette() { return s_palette; }
|
||||
|
||||
// runtime functions
|
||||
virtual void record_body_scanline(uint8_t mode, uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos);
|
||||
virtual uint8_t border_value(uint8_t mode);
|
||||
|
||||
// template function for doing video update collection
|
||||
template<int sample_count, int yres>
|
||||
void record_scanline_res(int scanline, int32_t start_pos, int32_t end_pos);
|
||||
|
||||
private:
|
||||
struct video_scanline
|
||||
@ -566,8 +545,6 @@ private:
|
||||
static const int PALETTE_LENGTH = 16;
|
||||
static const uint32_t s_palette[PALETTE_LENGTH];
|
||||
|
||||
// callbacks
|
||||
|
||||
/* if specified, this gets called whenever reading a byte (offs_t ~0 specifies DA* entering the tristate mode) */
|
||||
devcb_read8 m_input_cb;
|
||||
|
||||
@ -616,14 +593,6 @@ private:
|
||||
// setup functions
|
||||
void setup_fixed_mode();
|
||||
|
||||
// runtime functions
|
||||
void record_body_scanline(uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos);
|
||||
pixel_t border_value(uint8_t mode, const pixel_t *palette, bool is_mc6847t1);
|
||||
|
||||
// template function for doing video update collection
|
||||
template<int sample_count, int yres>
|
||||
void record_scanline_res(int scanline, int32_t start_pos, int32_t end_pos);
|
||||
|
||||
// miscellaneous
|
||||
uint8_t input(uint16_t address);
|
||||
int32_t scanline_position_from_clock(int32_t clocks_since_hsync);
|
||||
@ -662,9 +631,14 @@ class mc6847t1_ntsc_device : public mc6847_base_device
|
||||
{
|
||||
public:
|
||||
mc6847t1_ntsc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
mc6847t1_ntsc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint8_t *fontdata, double tpfs, bool pal);
|
||||
|
||||
virtual uint8_t border_value(uint8_t mode) override;
|
||||
};
|
||||
|
||||
class mc6847t1_pal_device : public mc6847_base_device
|
||||
class mc6847t1_pal_device : public mc6847t1_ntsc_device
|
||||
{
|
||||
public:
|
||||
mc6847t1_pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -675,10 +649,16 @@ class s68047_device : public mc6847_base_device
|
||||
public:
|
||||
s68047_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void hack_black_becomes_blue(bool flag);
|
||||
protected:
|
||||
virtual uint32_t emit_samples(uint8_t mode, const uint8_t *data, int length, pixel_t *RESTRICT pixels, const pixel_t *RESTRICT palette,
|
||||
get_char_rom_delegate const &get_char_rom, int x, int y) override;
|
||||
virtual const uint32_t* default_palette() override { return s_s68047_palette; }
|
||||
|
||||
virtual void record_body_scanline(uint8_t mode, uint16_t physical_scanline, uint16_t scanline, int32_t start_pos, int32_t end_pos) override;
|
||||
virtual uint8_t border_value(uint8_t mode) override;
|
||||
|
||||
private:
|
||||
static const uint32_t s_s68047_hack_palette[16];
|
||||
static const uint32_t s_s68047_palette[16];
|
||||
};
|
||||
|
||||
class m5c6847p1_device : public mc6847_base_device
|
||||
|
@ -2,10 +2,12 @@
|
||||
// copyright-holders:Wilbert Pol, Robbbert
|
||||
/***************************************************************************
|
||||
|
||||
Bandai Super Vision 8000 (TV Jack 8000)
|
||||
driver by Wilbert Pol, Robbbert, ranger_lennier, and Charles McDonald
|
||||
Bandai Super Vision 8000 (TV-Jack Micro Computer System) (aka TV Jack 8000)
|
||||
TV JACK スーパービジョン8000
|
||||
|
||||
2014/01/07 Skeleton driver.
|
||||
driver by Wilbert Pol, Robbbert, ranger_lennier, and Charles McDonald
|
||||
|
||||
2014/01/07 Skeleton driver.
|
||||
|
||||
The Bandai Super Vision 8000 contains:
|
||||
- NEC D780C (Z80)
|
||||
@ -17,21 +19,23 @@ Looking at the code of the cartridges it seems there is:
|
||||
- 1KB of main system RAM
|
||||
- 3KB of video RAM
|
||||
|
||||
TODO:
|
||||
- Check configuration of S68047P pins through 8910 port A against
|
||||
schematics
|
||||
- Verify clock
|
||||
TODO:
|
||||
- Check configuration of S68047P pins through 8910 port A against PCB
|
||||
- Verify clocks, verify exact model of soundchip
|
||||
- Verify colors, it kind of matches videos/photos, but it's much worse with
|
||||
the default S68047P palette
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "video/mc6847.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/generic/carts.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
@ -48,165 +52,53 @@ public:
|
||||
, m_s68047p(*this, "s68047p")
|
||||
, m_cart(*this, "cartslot")
|
||||
, m_videoram(*this, "videoram")
|
||||
, m_io_row0(*this, "ROW0")
|
||||
, m_io_row1(*this, "ROW1")
|
||||
, m_io_row2(*this, "ROW2")
|
||||
, m_io_joy(*this, "JOY")
|
||||
, m_io_row(*this, "ROW%u", 0)
|
||||
{ }
|
||||
|
||||
void sv8000(machine_config &config);
|
||||
|
||||
private:
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( cart_load );
|
||||
|
||||
uint8_t ay_port_a_r();
|
||||
uint8_t ay_port_b_r();
|
||||
void ay_port_a_w(uint8_t data);
|
||||
void ay_port_b_w(uint8_t data);
|
||||
|
||||
uint8_t i8255_porta_r();
|
||||
void i8255_porta_w(uint8_t data);
|
||||
uint8_t i8255_portb_r();
|
||||
void i8255_portb_w(uint8_t data);
|
||||
uint8_t i8255_portc_r();
|
||||
void i8255_portc_w(uint8_t data);
|
||||
|
||||
uint8_t mc6847_videoram_r(offs_t offset);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
|
||||
|
||||
void ay_port_a_w(u8 data);
|
||||
|
||||
u8 i8255_porta_r();
|
||||
u8 i8255_portb_r();
|
||||
void i8255_portc_w(u8 data);
|
||||
|
||||
u8 mc6847_videoram_r(offs_t offset);
|
||||
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<s68047_device> m_s68047p;
|
||||
required_device<generic_slot_device> m_cart;
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
required_ioport m_io_row0;
|
||||
required_ioport m_io_row1;
|
||||
required_ioport m_io_row2;
|
||||
required_ioport m_io_joy;
|
||||
required_shared_ptr<u8> m_videoram;
|
||||
required_ioport_array<3> m_io_row;
|
||||
|
||||
uint8_t m_column = 0U;
|
||||
|
||||
// graphics signals
|
||||
uint8_t m_ag = 0U;
|
||||
uint8_t m_gm2 = 0U;
|
||||
uint8_t m_gm1 = 0U;
|
||||
uint8_t m_gm0 = 0U;
|
||||
uint8_t m_as = 0U;
|
||||
uint8_t m_css = 0U;
|
||||
uint8_t m_intext = 0U;
|
||||
uint8_t m_inv = 0U;
|
||||
u8 m_column = 0xff;
|
||||
u8 m_ag = 0U;
|
||||
};
|
||||
|
||||
|
||||
void sv8000_state::mem_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
//map(0x0000, 0x0fff) // mapped by the cartslot
|
||||
map(0x8000, 0x83ff).ram(); // Work RAM??
|
||||
map(0xc000, 0xcbff).ram().share("videoram");
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::io_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x80, 0x83).rw("i8255", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0xc0, 0xc0).w("ay8910", FUNC(ay8910_device::data_w)); // Not sure yet
|
||||
map(0xc1, 0xc1).w("ay8910", FUNC(ay8910_device::address_w)); // Not sure yet
|
||||
}
|
||||
|
||||
|
||||
/* Input ports */
|
||||
// On the main console:
|
||||
//
|
||||
// 1 2 3 1 2 3
|
||||
// 4 5 6 4 5 6
|
||||
// 7 8 9 7 8 9
|
||||
// * 0 # * 0 #
|
||||
//
|
||||
// Button/dial? POWER RESET Button/dial?
|
||||
//
|
||||
static INPUT_PORTS_START( sv8000 )
|
||||
PORT_START("ROW0")
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Left 1")
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Left 4") // Guess
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Left 7") // Guess
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Left *") // Guess
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Right 1")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Right 4") // Guess
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Right 7") // Guess
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Right *") // Guess
|
||||
|
||||
PORT_START("ROW1")
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Left 2")
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Left 5") // Guess
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Left 8") // Guess
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Left 0")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Right 2")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Right 5") // Guess
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Right 8") // Guess
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Right 0")
|
||||
|
||||
PORT_START("ROW2")
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Left 3")
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Left 6") // Guess
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Left 9") // Guess
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Left #") // Guess
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Right 3")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Right 6") // Guess
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Right 9") // Guess
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Right #") // Guess
|
||||
|
||||
PORT_START("JOY")
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_STOP) PORT_NAME("Left Right")
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Left Left")
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("Left Down")
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Left Up")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_NAME("Right Right")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_NAME("Right Left")
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_NAME("Right Down")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_NAME("Right Up")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void sv8000_state::machine_start()
|
||||
{
|
||||
if (m_cart->exists())
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0x0000, 0x0fff, read8sm_delegate(*m_cart, FUNC(generic_slot_device::read_rom)));
|
||||
|
||||
save_item(NAME(m_column));
|
||||
save_item(NAME(m_ag));
|
||||
save_item(NAME(m_gm2));
|
||||
save_item(NAME(m_gm1));
|
||||
save_item(NAME(m_gm0));
|
||||
save_item(NAME(m_as));
|
||||
save_item(NAME(m_css));
|
||||
save_item(NAME(m_intext));
|
||||
save_item(NAME(m_inv));
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::machine_reset()
|
||||
{
|
||||
m_column = 0xff;
|
||||
m_ag = 0;
|
||||
m_gm2 = 0;
|
||||
m_gm1 = 0;
|
||||
m_gm0 = 0;
|
||||
m_as = 0;
|
||||
m_css = 0;
|
||||
m_intext = 0;
|
||||
m_inv = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Cartridge
|
||||
*******************************************************************************/
|
||||
|
||||
DEVICE_IMAGE_LOAD_MEMBER( sv8000_state::cart_load )
|
||||
DEVICE_IMAGE_LOAD_MEMBER(sv8000_state::cart_load)
|
||||
{
|
||||
uint32_t size = m_cart->common_get_size("rom");
|
||||
u32 size = m_cart->common_get_size("rom");
|
||||
|
||||
if (size != 0x1000)
|
||||
return std::make_pair(image_error::INVALIDLENGTH, "Incorrect or unsupported cartridge size (must be 4K)");
|
||||
@ -218,212 +110,250 @@ DEVICE_IMAGE_LOAD_MEMBER( sv8000_state::cart_load )
|
||||
}
|
||||
|
||||
|
||||
uint8_t sv8000_state::i8255_porta_r()
|
||||
|
||||
/*******************************************************************************
|
||||
Video
|
||||
*******************************************************************************/
|
||||
|
||||
// Palette, most notably for the 2nd color set it expects a blue background instead of black
|
||||
|
||||
static const u32 sv8000_palette[16] =
|
||||
{
|
||||
//logerror("i8255_porta_r\n");
|
||||
return m_io_joy->read();
|
||||
rgb_t(0x30, 0xd2, 0x00), // GREEN
|
||||
rgb_t(0xc1, 0xe5, 0x00), // YELLOW
|
||||
rgb_t(0x41, 0xaf, 0x71), // CYAN
|
||||
rgb_t(0x9a, 0x32, 0x36), // RED
|
||||
rgb_t(0x4c, 0x3a, 0xb4), // BLUE
|
||||
rgb_t(0x20, 0xd8, 0xe0), // CYAN/BLUE
|
||||
rgb_t(0xc8, 0x4e, 0xf0), // MAGENTA
|
||||
rgb_t(0xd4, 0x7f, 0x00), // ORANGE
|
||||
|
||||
rgb_t(0x20, 0x40, 0x00), // BLACK -> DARK GREEN
|
||||
rgb_t(0xff, 0xf8, 0x70), // GREEN -> YELLOW
|
||||
rgb_t(0x18, 0x30, 0xb0), // BLACK -> BLUE
|
||||
rgb_t(0xf0, 0xff, 0xff), // CYAN/BLUE -> BRIGHT CYAN
|
||||
|
||||
rgb_t(0x20, 0x40, 0x00), // BLACK -> DARK GREEN
|
||||
rgb_t(0xff, 0xf8, 0x70), // GREEN -> YELLOW
|
||||
rgb_t(0x18, 0x30, 0xb0), // BLACK -> BLUE
|
||||
rgb_t(0xf0, 0xff, 0xff), // BLUE -> BRIGHT CYAN
|
||||
};
|
||||
|
||||
void sv8000_state::ay_port_a_w(u8 data)
|
||||
{
|
||||
// Lacking schematics, these are all wild guesses, see below for values written
|
||||
/*
|
||||
misvader:
|
||||
0x42 01000010 text
|
||||
0x5A 01011010 graphics
|
||||
|
||||
spfire:
|
||||
0x42 01000010 text
|
||||
0x5A 01011010 graphics
|
||||
|
||||
othello:
|
||||
0x02 00000010 text
|
||||
0x58 01011000 graphics
|
||||
|
||||
gunprof:
|
||||
0x00 00000000 text
|
||||
0x38 00111000 graphics
|
||||
|
||||
pacpac:
|
||||
0x00 00000000 text
|
||||
0x5A 01011010 graphics
|
||||
|
||||
submar:
|
||||
0x00 00000000 text
|
||||
0x5A 01011010 graphics
|
||||
|
||||
beamgala:
|
||||
0x5A 01011010 graphics
|
||||
*/
|
||||
|
||||
m_s68047p->css_w(BIT(data, 1));
|
||||
m_s68047p->ag_w(BIT(data, 3));
|
||||
m_s68047p->gm0_w(BIT(data, 4));
|
||||
m_s68047p->gm1_w(BIT(data, 5));
|
||||
m_s68047p->gm2_w(BIT(data, 6));
|
||||
|
||||
m_ag = BIT(data, 3);
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::i8255_porta_w(uint8_t data)
|
||||
{
|
||||
//logerror("i8255_porta_w: %02X\n", data);
|
||||
}
|
||||
|
||||
|
||||
uint8_t sv8000_state::i8255_portb_r()
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
//logerror("i8255_portb_r\n");
|
||||
|
||||
if (!BIT(m_column, 0))
|
||||
{
|
||||
data &= m_io_row0->read();
|
||||
}
|
||||
if (!BIT(m_column, 1))
|
||||
{
|
||||
data &= m_io_row1->read();
|
||||
}
|
||||
if (!BIT(m_column, 2))
|
||||
{
|
||||
data &= m_io_row2->read();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::i8255_portb_w(uint8_t data)
|
||||
{
|
||||
//logerror("i8255_portb_w: %02X\n", data);
|
||||
}
|
||||
|
||||
|
||||
uint8_t sv8000_state::i8255_portc_r()
|
||||
{
|
||||
//logerror("i8255_portc_r\n");
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::i8255_portc_w(uint8_t data)
|
||||
{
|
||||
//logerror("i8255_portc_w: %02X\n", data);
|
||||
m_column = data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t sv8000_state::ay_port_a_r()
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
//logerror("ay_port_a_r\n");
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t sv8000_state::ay_port_b_r()
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
//logerror("ay_port_b_r\n");
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
// Possibly connected to S68047P for selecting text/graphics modes
|
||||
// misvader:
|
||||
// 0x42 01000010 set on normal text screen
|
||||
// 0x5A 01011010 set for a 256x192 bit mapped screen 3KB in 6KB mode?
|
||||
//
|
||||
// spfire:
|
||||
// 0x42 01000010 text
|
||||
// 0x5A 01011010 graphics 3KB in 6KB mode?
|
||||
//
|
||||
// othello:
|
||||
// 0x02 00000010 normal text screen
|
||||
// 0x58 01011000 graphics 3KB in 6KB mode?
|
||||
//
|
||||
// gunprof:
|
||||
// 0x00 00000000 text
|
||||
// 0x38 00111000 graphics 3KB mode
|
||||
//
|
||||
// pacpac:
|
||||
// 0x00 00000000 text
|
||||
// 0x5A 01011010 graphics 3KB in 6KB mode?
|
||||
//
|
||||
// submar:
|
||||
// 0x00 00000000 text
|
||||
// 0x5A 01011010 graphics 3KB in 6KB mode?
|
||||
//
|
||||
// beamgala:
|
||||
// 0x5A 01011010 graphics 3KB in 6KB mode?
|
||||
//
|
||||
void sv8000_state::ay_port_a_w(uint8_t data)
|
||||
{
|
||||
//logerror("ay_port_a_w: %02X\n", data);
|
||||
|
||||
// Lacking schematics, these are all wild guesses
|
||||
// Having bit 1 set makes black display as blue??
|
||||
m_ag = BIT(data, 4);
|
||||
m_gm2 = BIT(data, 6);
|
||||
m_gm1 = BIT(data, 3);
|
||||
m_gm0 = BIT(data, 3);
|
||||
m_css = m_ag;
|
||||
|
||||
m_s68047p->ag_w( m_ag ? ASSERT_LINE : CLEAR_LINE );
|
||||
m_s68047p->gm2_w( m_gm2 ? ASSERT_LINE : CLEAR_LINE );
|
||||
m_s68047p->gm1_w( m_gm1 ? ASSERT_LINE : CLEAR_LINE );
|
||||
m_s68047p->gm0_w( m_gm0 ? ASSERT_LINE : CLEAR_LINE );
|
||||
m_s68047p->css_w( m_css ? ASSERT_LINE : CLEAR_LINE );
|
||||
m_s68047p->hack_black_becomes_blue( BIT(data, 1) );
|
||||
}
|
||||
|
||||
|
||||
void sv8000_state::ay_port_b_w(uint8_t data)
|
||||
{
|
||||
//logerror("ay_port_b_w: %02X\n", data);
|
||||
}
|
||||
|
||||
uint8_t sv8000_state::mc6847_videoram_r(offs_t offset)
|
||||
u8 sv8000_state::mc6847_videoram_r(offs_t offset)
|
||||
{
|
||||
if (offset == ~0) return 0xff;
|
||||
|
||||
// Graphics
|
||||
if (m_ag)
|
||||
{
|
||||
if (m_gm2)
|
||||
{
|
||||
// 256 x 192 / 6KB
|
||||
offset = ((offset & 0x1fc0) >> 1) | (offset & 0x1f);
|
||||
return m_videoram[offset % 0xc00];
|
||||
}
|
||||
else
|
||||
{
|
||||
// 256 x 96 / 3KB
|
||||
return m_videoram[offset % 0xc00];
|
||||
}
|
||||
}
|
||||
return m_videoram[offset & 0xfff];
|
||||
|
||||
// Standard text
|
||||
uint8_t data = m_videoram[offset % 0xc00];
|
||||
if (!data) data = 0x20; //bodge
|
||||
u8 data = m_videoram[offset & 0xfff];
|
||||
if (!data) data = 0x20; // bodge
|
||||
|
||||
m_s68047p->inv_w((data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_s68047p->inv_w(BIT(data, 7));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Address Maps
|
||||
*******************************************************************************/
|
||||
|
||||
void sv8000_state::mem_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x0fff).r(m_cart, FUNC(generic_slot_device::read_rom));
|
||||
map(0x8000, 0x83ff).ram(); // Work RAM
|
||||
map(0xc000, 0xcfff).ram().share(m_videoram);
|
||||
}
|
||||
|
||||
void sv8000_state::io_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x80, 0x83).rw("i8255", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0xc0, 0xc0).w("ay8910", FUNC(ay8910_device::data_w));
|
||||
map(0xc1, 0xc1).w("ay8910", FUNC(ay8910_device::address_w));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Input Ports
|
||||
*******************************************************************************/
|
||||
|
||||
// Keypad I/O
|
||||
|
||||
u8 sv8000_state::i8255_portb_r()
|
||||
{
|
||||
u8 data = 0xff;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (!BIT(m_column, i))
|
||||
data &= m_io_row[i]->read();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void sv8000_state::i8255_portc_w(u8 data)
|
||||
{
|
||||
m_column = data;
|
||||
}
|
||||
|
||||
/*
|
||||
On the main console:
|
||||
|
||||
1 2 3 1 2 3
|
||||
4 5 6 4 5 6
|
||||
7 8 9 7 8 9
|
||||
* 0 # * 0 #
|
||||
|
||||
Joypad POWER RESET Joypad
|
||||
*/
|
||||
static INPUT_PORTS_START( sv8000 )
|
||||
PORT_START("ROW0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Right *")
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Right 7")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Right 4")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Right 1")
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Left *")
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Left 7") // Guess
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Left 4") // Guess
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Left 1")
|
||||
|
||||
PORT_START("ROW1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Right 0")
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Right 8")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Right 5")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Right 2")
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Left 0")
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Left 8") // Guess
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Left 5") // Guess
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Left 2")
|
||||
|
||||
PORT_START("ROW2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Right #")
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Right 9") // Guess
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Right 6")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Right 3")
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Left #") // Guess
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Left 9") // Guess
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Left 6") // Guess
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Left 3")
|
||||
|
||||
PORT_START("JOY")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_NAME("Right Up")
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_NAME("Right Down")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_NAME("Right Left")
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_NAME("Right Right")
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Left Up")
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("Left Down")
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("Left Left")
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Left Right")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Machine Configs
|
||||
*******************************************************************************/
|
||||
|
||||
void sv8000_state::sv8000(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, XTAL(10'738'635)/3/2); /* Not verified */
|
||||
// basic machine hardware
|
||||
Z80(config, m_maincpu, 3.579545_MHz_XTAL/2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &sv8000_state::mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &sv8000_state::io_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(sv8000_state::irq0_line_hold));
|
||||
|
||||
i8255_device &ppi(I8255(config, "i8255"));
|
||||
ppi.in_pa_callback().set(FUNC(sv8000_state::i8255_porta_r));
|
||||
ppi.out_pa_callback().set(FUNC(sv8000_state::i8255_porta_w));
|
||||
ppi.in_pa_callback().set_ioport("JOY");
|
||||
ppi.in_pb_callback().set(FUNC(sv8000_state::i8255_portb_r));
|
||||
ppi.out_pb_callback().set(FUNC(sv8000_state::i8255_portb_w));
|
||||
ppi.in_pc_callback().set(FUNC(sv8000_state::i8255_portc_r));
|
||||
ppi.out_pc_callback().set(FUNC(sv8000_state::i8255_portc_w));
|
||||
|
||||
/* video hardware */
|
||||
// S68047P - Unknown whether the internal or an external character rom is used
|
||||
S68047(config, m_s68047p, XTAL(10'738'635)/3); // Clock not verified
|
||||
// video hardware
|
||||
S68047(config, m_s68047p, 3.579545_MHz_XTAL);
|
||||
m_s68047p->input_callback().set(FUNC(sv8000_state::mc6847_videoram_r));
|
||||
m_s68047p->set_palette(sv8000_palette);
|
||||
m_s68047p->set_screen("screen");
|
||||
|
||||
SCREEN(config, "screen", SCREEN_TYPE_RASTER);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
ay8910_device &ay8910(AY8910(config, "ay8910", XTAL(10'738'635)/3/2)); /* Exact model and clock not verified */
|
||||
ay8910.port_a_read_callback().set(FUNC(sv8000_state::ay_port_a_r));
|
||||
ay8910.port_b_read_callback().set(FUNC(sv8000_state::ay_port_b_r));
|
||||
ay8910_device &ay8910(AY8910(config, "ay8910", 3.579545_MHz_XTAL/2));
|
||||
ay8910.port_a_write_callback().set(FUNC(sv8000_state::ay_port_a_w));
|
||||
ay8910.port_b_write_callback().set(FUNC(sv8000_state::ay_port_b_w));
|
||||
ay8910.add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
/* cartridge */
|
||||
// cartridge
|
||||
generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "sv8000_cart"));
|
||||
cartslot.set_must_be_loaded(true);
|
||||
cartslot.set_device_load(FUNC(sv8000_state::cart_load));
|
||||
|
||||
/* software lists */
|
||||
SOFTWARE_LIST(config, "cart_list").set_original("sv8000");
|
||||
}
|
||||
|
||||
/* ROM definition */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
ROM Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
ROM_START( sv8000 )
|
||||
ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) // Mapped by the cartridge slot
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */
|
||||
CONS( 1979, sv8000, 0, 0, sv8000, sv8000, sv8000_state, empty_init, "Bandai", "Super Vision 8000 (TV Jack 8000)", MACHINE_SUPPORTS_SAVE )
|
||||
/*******************************************************************************
|
||||
Drivers
|
||||
*******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
|
||||
CONS( 1979, sv8000, 0, 0, sv8000, sv8000, sv8000_state, empty_init, "Bandai", "Super Vision 8000", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_COLORS )
|
||||
|
@ -1283,22 +1283,20 @@ void gime_device::update_border(uint16_t physical_scanline)
|
||||
if (m_legacy_video)
|
||||
{
|
||||
/* legacy video */
|
||||
switch(border_value(m_ff22_value, true))
|
||||
if (m_ff22_value & MODE_AG)
|
||||
{
|
||||
case BORDER_COLOR_GREEN:
|
||||
border = 0x12; /* green */
|
||||
break;
|
||||
case BORDER_COLOR_WHITE:
|
||||
border = 0x3F; /* white */
|
||||
break;
|
||||
case BORDER_COLOR_BLACK:
|
||||
border = 0x00; /* black */
|
||||
break;
|
||||
case BORDER_COLOR_ORANGE:
|
||||
border = 0x26; /* orange */
|
||||
break;
|
||||
default:
|
||||
fatalerror("Should not get here\n");
|
||||
// graphics, green or white
|
||||
border = (~m_ff22_value & MODE_CSS) ? 0x12 : 0x3F;
|
||||
}
|
||||
else if (m_ff22_value & MODE_GM2)
|
||||
{
|
||||
// text, green or orange
|
||||
border = (~m_ff22_value & MODE_CSS) ? 0x12 : 0x26;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text, black
|
||||
border = 0x00;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1502,7 +1500,7 @@ uint32_t gime_device::get_data_with_attributes(uint32_t video_position, uint8_t
|
||||
// record_body_scanline
|
||||
//-------------------------------------------------
|
||||
|
||||
void gime_device::record_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline)
|
||||
void gime_device::record_full_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline)
|
||||
{
|
||||
/* update the border first */
|
||||
update_border(physical_scanline);
|
||||
|
@ -75,7 +75,7 @@ protected:
|
||||
virtual TIMER_CALLBACK_MEMBER(horizontal_sync_changed) override;
|
||||
virtual void enter_bottom_border() override;
|
||||
virtual void record_border_scanline(uint16_t physical_scanline) override;
|
||||
virtual void record_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline) override;
|
||||
virtual void record_full_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline) override;
|
||||
virtual void record_partial_body_scanline(uint16_t physical_scanline, uint16_t logical_scanline, int32_t start_clock, int32_t end_clock) override;
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user