mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
sm7238: implement double-sized characters and smooth scroll.
This commit is contained in:
parent
1d027e1d22
commit
bc286f5d58
@ -9,10 +9,9 @@
|
||||
|
||||
To do:
|
||||
- handle more text_control_w bits
|
||||
- more character attributes incl. double width and height, color
|
||||
- 80/132 columns switching on the fly, reverse video
|
||||
- smooth scroll
|
||||
- graphics option
|
||||
- colors
|
||||
- run vblank from timer output?
|
||||
- document hardware and ROM variants, verify if pixel stretching is done
|
||||
|
||||
@ -76,7 +75,6 @@ public:
|
||||
, m_screen(*this, "screen")
|
||||
{ }
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER( scanline_callback );
|
||||
DECLARE_PALETTE_INIT(sm7238);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
|
||||
@ -88,17 +86,14 @@ public:
|
||||
void screen_eof(screen_device &screen, bool state);
|
||||
|
||||
private:
|
||||
uint32_t draw_scanline(uint16_t *p, uint16_t offset, uint8_t scanline);
|
||||
rectangle m_tmpclip;
|
||||
bitmap_ind16 m_tmpbmp;
|
||||
|
||||
void text_memory_clear();
|
||||
void recompute_parameters();
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint8_t control;
|
||||
uint8_t stride;
|
||||
uint16_t ptr;
|
||||
int stride;
|
||||
} m_video;
|
||||
|
||||
virtual void machine_reset() override;
|
||||
@ -155,8 +150,6 @@ void sm7238_state::machine_reset()
|
||||
|
||||
void sm7238_state::video_start()
|
||||
{
|
||||
m_tmpclip = rectangle(0, KSM_DISP_HORZ-1, 0, KSM_DISP_VERT-1);
|
||||
m_tmpbmp.allocate(KSM_DISP_HORZ, KSM_DISP_VERT);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sm7238_state::control_w)
|
||||
@ -174,7 +167,8 @@ WRITE8_MEMBER(sm7238_state::text_control_w)
|
||||
if (!BIT(data, 2) && !BIT(data, 3))
|
||||
text_memory_clear();
|
||||
|
||||
if (BIT((data ^ m_video.control), 0)) {
|
||||
if (BIT((data ^ m_video.control), 0))
|
||||
{
|
||||
m_video.stride = BIT(data, 0) ? 80 : 132;
|
||||
// recompute_parameters();
|
||||
}
|
||||
@ -194,98 +188,18 @@ WRITE_LINE_MEMBER(sm7238_state::write_printer_clock)
|
||||
m_i8251prn->write_rxc(state);
|
||||
}
|
||||
|
||||
uint32_t sm7238_state::draw_scanline(uint16_t *p, uint16_t offset, uint8_t scanline)
|
||||
{
|
||||
uint8_t attr, fg, bg, ra, gfx;
|
||||
uint16_t x, chr;
|
||||
int dw;
|
||||
|
||||
ra = scanline % 10;
|
||||
|
||||
for (x = offset; x < offset + m_video.stride; x++)
|
||||
{
|
||||
chr = m_p_videoram[x] << 4;
|
||||
attr = m_p_videoram[x + 0x1000];
|
||||
gfx = m_p_chargen[chr | ra] ^ 255;
|
||||
|
||||
bg = 0; fg = 1;
|
||||
|
||||
/* Process attributes */
|
||||
if ((BIT(attr, 1)) && (ra == 9))
|
||||
{
|
||||
gfx = 0xff; // underline
|
||||
}
|
||||
// 2 = blink
|
||||
if (BIT(attr, 3))
|
||||
{
|
||||
gfx ^= 0xff; // reverse video
|
||||
}
|
||||
if (BIT(attr, 4))
|
||||
fg = 2; // highlight
|
||||
else
|
||||
fg = 1;
|
||||
|
||||
dw = 0; // BIT(attr, 4);
|
||||
*p++ = BIT(gfx, 7) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 7) ? fg : bg;
|
||||
*p++ = BIT(gfx, 6) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 6) ? fg : bg;
|
||||
*p++ = BIT(gfx, 5) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 5) ? fg : bg;
|
||||
*p++ = BIT(gfx, 4) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 4) ? fg : bg;
|
||||
*p++ = BIT(gfx, 3) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 3) ? fg : bg;
|
||||
*p++ = BIT(gfx, 2) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 2) ? fg : bg;
|
||||
*p++ = BIT(gfx, 1) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 1) ? fg : bg;
|
||||
*p++ = BIT(gfx, 0) ? fg : bg;
|
||||
if (dw)
|
||||
*p++ = BIT(gfx, 0) ? fg : bg;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(sm7238_state::scanline_callback)
|
||||
{
|
||||
uint16_t y = m_screen->vpos();
|
||||
uint16_t o = m_video.ptr;
|
||||
|
||||
if (y < KSM_VERT_START) return;
|
||||
y -= KSM_VERT_START;
|
||||
if (y >= KSM_DISP_VERT) return;
|
||||
|
||||
if (y == 0)
|
||||
m_video.ptr = 0;
|
||||
else if (y%10 == 0) {
|
||||
m_video.ptr = m_p_videoram[m_video.ptr + m_video.stride + 1] |
|
||||
(m_p_videoram[m_video.ptr + 0x1000 + m_video.stride + 1] << 8);
|
||||
m_video.ptr &= 0x0fff;
|
||||
DBG_LOG(2,"scanline_cb",("y %d row %d old ptr %04x new ptr %04x\n", y, y%10, o, m_video.ptr));
|
||||
}
|
||||
|
||||
draw_scanline(&m_tmpbmp.pix16(y), m_video.ptr, y%10);
|
||||
}
|
||||
|
||||
void sm7238_state::text_memory_clear()
|
||||
{
|
||||
int y = 0, ptr = 0;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
memset(&m_p_videoram[ptr], 0x20, m_video.stride);
|
||||
memset(&m_p_videoram[ptr + 0x1000], 0x20, m_video.stride);
|
||||
ptr = m_p_videoram[ptr + m_video.stride + 1] | (m_p_videoram[ptr + 0x1000 + m_video.stride + 1] << 8);
|
||||
ptr &= 0x0fff;
|
||||
y++;
|
||||
} while (y<26);
|
||||
} while (y < 26);
|
||||
}
|
||||
|
||||
void sm7238_state::recompute_parameters()
|
||||
@ -300,8 +214,96 @@ void sm7238_state::recompute_parameters()
|
||||
|
||||
uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if (BIT(m_video.control, 3))
|
||||
copybitmap(bitmap, m_tmpbmp, 0, 0, KSM_HORZ_START, KSM_VERT_START, cliprect);
|
||||
uint8_t y, ra, gfx, fg, bg, attr, ctl1, ctl2 = 0;
|
||||
uint16_t chr, sy = KSM_VERT_START, ma = 0, x = 0;
|
||||
bool double_width = false, double_height = false, bottom_half = false;
|
||||
|
||||
if (!BIT(m_video.control, 3))
|
||||
{
|
||||
bitmap.fill(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (y = 0; y < 26; y++)
|
||||
{
|
||||
for (ra = 0; ra < 10; ra++)
|
||||
{
|
||||
if (y == 1 && ctl2 && ra < ctl2)
|
||||
continue;
|
||||
|
||||
uint16_t *p = &bitmap.pix16(sy++, KSM_HORZ_START);
|
||||
|
||||
for (x = ma; x < ma + m_video.stride; x++)
|
||||
{
|
||||
chr = m_p_videoram[x] << 4;
|
||||
attr = m_p_videoram[x + 0x1000];
|
||||
if (double_height)
|
||||
{
|
||||
gfx = m_p_chargen[chr | (bottom_half ? (5 + (ra >> 1)) : (ra >> 1))] ^ 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx = m_p_chargen[chr | ra] ^ 255;
|
||||
}
|
||||
|
||||
bg = 0;
|
||||
fg = 1;
|
||||
|
||||
/* Process attributes */
|
||||
if ((BIT(attr, 1)) && (ra == 9))
|
||||
{
|
||||
gfx = 0xff; // underline
|
||||
}
|
||||
// 2 = blink
|
||||
if (BIT(attr, 3))
|
||||
{
|
||||
gfx ^= 0xff; // reverse video
|
||||
}
|
||||
if (BIT(attr, 4))
|
||||
fg = 2; // highlight
|
||||
else
|
||||
fg = 1;
|
||||
|
||||
*p++ = BIT(gfx, 7) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 7) ? fg : bg;
|
||||
*p++ = BIT(gfx, 6) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 6) ? fg : bg;
|
||||
*p++ = BIT(gfx, 5) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 5) ? fg : bg;
|
||||
*p++ = BIT(gfx, 4) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 4) ? fg : bg;
|
||||
*p++ = BIT(gfx, 3) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 3) ? fg : bg;
|
||||
*p++ = BIT(gfx, 2) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 2) ? fg : bg;
|
||||
*p++ = BIT(gfx, 1) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 1) ? fg : bg;
|
||||
*p++ = BIT(gfx, 0) ? fg : bg;
|
||||
if (double_width)
|
||||
*p++ = BIT(gfx, 0) ? fg : bg;
|
||||
|
||||
if (double_width) x++;
|
||||
}
|
||||
}
|
||||
ctl1 = m_p_videoram[ma + 0x1000 + m_video.stride];
|
||||
double_width = BIT(ctl1, 6);
|
||||
double_height = BIT(ctl1, 7);
|
||||
bottom_half = BIT(ctl1, 5);
|
||||
|
||||
ctl2 = m_p_videoram[ma + 0x1000 + m_video.stride + 1] >> 4;
|
||||
|
||||
ma = m_p_videoram[ma + m_video.stride + 1] |
|
||||
(m_p_videoram[ma + 0x1000 + m_video.stride + 1] << 8);
|
||||
ma &= 0x0fff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -342,8 +344,6 @@ static MACHINE_CONFIG_START( sm7238, sm7238_state )
|
||||
MCFG_CPU_IO_MAP(sm7238_io)
|
||||
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb)
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", sm7238_state, scanline_callback, "screen", 0, 1)
|
||||
|
||||
MCFG_NVRAM_ADD_0FILL("nvram")
|
||||
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
@ -364,7 +364,7 @@ static MACHINE_CONFIG_START( sm7238, sm7238_state )
|
||||
MCFG_PALETTE_INIT_OWNER(sm7238_state, sm7238)
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", sm7238)
|
||||
|
||||
MCFG_PIC8259_ADD( "pic8259", INPUTLINE("maincpu", 0), VCC, NOOP)
|
||||
MCFG_PIC8259_ADD("pic8259", INPUTLINE("maincpu", 0), VCC, NOOP)
|
||||
|
||||
MCFG_DEVICE_ADD("t_hblank", PIT8253, 0)
|
||||
MCFG_PIT8253_CLK1(XTAL_16_384MHz/9) // XXX workaround -- keyboard is slower and doesn't sync otherwise
|
||||
@ -429,4 +429,4 @@ ROM_END
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1989, sm7238, 0, 0, sm7238, 0, driver_device, 0, "USSR", "SM 7238", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_KEYBOARD)
|
||||
COMP( 1989, sm7238, 0, 0, sm7238, 0, driver_device, 0, "USSR", "SM 7238", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_KEYBOARD)
|
||||
|
Loading…
Reference in New Issue
Block a user