summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Sergey Svishchev <shattered@users.noreply.github.com>2017-03-02 10:02:18 +0300
committer Sergey Svishchev <shattered@users.noreply.github.com>2017-03-12 17:16:55 +0300
commitbc286f5d585f0108457eb1584dea809cd751f578 (patch)
tree3268d405e43b7d8e60d9621bb4141e0f1265898f
parent1d027e1d22bea481f6ac12470457d418b790dbfb (diff)
sm7238: implement double-sized characters and smooth scroll.
-rw-r--r--src/mame/drivers/sm7238.cpp202
1 files changed, 101 insertions, 101 deletions
diff --git a/src/mame/drivers/sm7238.cpp b/src/mame/drivers/sm7238.cpp
index 299c6330cdb..4382341dbdf 100644
--- a/src/mame/drivers/sm7238.cpp
+++ b/src/mame/drivers/sm7238.cpp
@@ -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)