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:
hap 2024-01-30 00:34:55 +01:00
parent 6ff4e69b09
commit 256e42e3d8
5 changed files with 420 additions and 474 deletions

View File

@ -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);
}
//-------------------------------------------------

View File

@ -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

View File

@ -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 )

View File

@ -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);

View File

@ -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: