summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Frodevan <32438575+Frodevan@users.noreply.github.com>2020-06-06 17:26:12 +0200
committer GitHub <noreply@github.com>2020-06-07 01:26:12 +1000
commit5dfa023808a3b37f8093052357c46b886a854025 (patch)
tree099a337ab7ba2c1e5c3074d379b3ed31c295dfc3
parent9e6b04895056a55cef1d329f2b2b5a6dd2473733 (diff)
Graphics emulation for Tiki-100 redone to be accurate down to whole scanlines. Also fixed a small inacuracy in the keyboard. (#6785)
-rw-r--r--src/mame/drivers/tiki100.cpp151
-rw-r--r--src/mame/includes/tiki100.h8
2 files changed, 86 insertions, 73 deletions
diff --git a/src/mame/drivers/tiki100.cpp b/src/mame/drivers/tiki100.cpp
index df53c4d54e9..122063589ed 100644
--- a/src/mame/drivers/tiki100.cpp
+++ b/src/mame/drivers/tiki100.cpp
@@ -1,12 +1,18 @@
// license:BSD-3-Clause
-// copyright-holders:Curt Coder
+// copyright-holders:Curt Coder, Frode van der Meeren
/***************************************************************************
Tiki 100
12/05/2009 Skeleton driver.
- http://www.djupdal.org/tiki/
+ Most of the driver is written by Curt Coder.
+
+ 2020-06-02:
+ Screen-drawing redone by Frode van der Meeren.
+ There is still some work that needs to get this
+ even more accurate, but it's mostly down to
+ triggering update at the right times.
****************************************************************************/
@@ -14,7 +20,6 @@
TODO:
- - palette RAM should be written during HBLANK
- winchester hard disk
- analog/digital I/O
- light pen
@@ -185,13 +190,13 @@ READ8_MEMBER( tiki100_state::keyboard_r )
{
uint8_t data = 0xff;
- if (m_keylatch < 12)
+ if (m_keylatch < 13)
{
data = m_y[m_keylatch]->read();
}
m_keylatch++;
- if (m_keylatch == 12) m_keylatch = 0;
+ if (m_keylatch == 16) m_keylatch = 0; // Column selected by a 4-bit counter
return data;
}
@@ -219,14 +224,6 @@ WRITE8_MEMBER( tiki100_state::video_mode_w )
*/
m_mode = data;
-
- if (BIT(data, 7))
- {
- int color = data & 0x0f;
- uint8_t colordata = ~m_palette_val;
-
- m_palette->set_pen_color(color, pal3bit(colordata >> 5), pal3bit(colordata >> 2), pal2bit(colordata >> 0));
- }
}
WRITE8_MEMBER( tiki100_state::palette_w )
@@ -258,7 +255,7 @@ WRITE8_MEMBER( tiki100_state::system_w )
0 DRIS0 drive select 0
1 DRIS1 drive select 1
2 _ROME enable ROM at 0000-3fff
- 3 VIRE enable video RAM at 0000-7fff
+ 3 VIRE enable video RAM at 0000-7fff or 4000-bfff
4 SDEN single density select (0=DD, 1=SD)
5 _LMP0 GRAFIKK key led
6 MOTON floppy motor
@@ -323,7 +320,10 @@ static INPUT_PORTS_START( tiki100 )
10 | + (num) | - (num) | * (num) | 7 (num) | 8 (num) | 9 (num) | % (num) | = (num) |
11 | 4 (num) | 5 (num) | 6 (num) | HTAB | 1 (num) | 0 (num) | . (num) | |
12 | HJEM | H?YRE | 2 (num) | 3 (num) | ENTER | | | |
+ 13 | | | | | | | | |
----+---------+---------+---------+---------+---------+---------+---------+---------+
+
+ Unused bits may return some fixed values, an undocumented system call will read and return them.
*/
PORT_START("Y1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
@@ -445,6 +445,16 @@ static INPUT_PORTS_START( tiki100 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_START("Y13")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
+
PORT_START("ST")
PORT_CONFNAME( 0x01, 0x01, "DART TxCA")
PORT_CONFSETTING( 0x00, "BAR0" )
@@ -453,71 +463,69 @@ INPUT_PORTS_END
/* Video */
-uint32_t tiki100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+TIMER_DEVICE_CALLBACK_MEMBER( tiki100_state::scanline_start )
{
- const rgb_t *palette = m_palette->palette()->entry_list_raw();
- uint16_t addr = (m_scroll << 7);
- int sx, y, pixel, mode = (m_mode >> 4) & 0x03;
-
- for (y = 0; y < 256; y++)
- {
- for (sx = 0; sx < 128; sx++)
- {
- uint8_t data = m_video_ram[addr & TIKI100_VIDEORAM_MASK];
+ // TODO: Optional assertion of VSYNC on one of the PIO-pins, as used by some demos
+ //int scanline = param;
- switch (mode)
- {
- case 0:
- for (pixel = 0; pixel < 8; pixel++)
- {
- int x = (sx * 8) + pixel;
+ // TODO: use TIMER to trigger this every 16-pixel chunk (20MHz/16) instead of once at the end of the scanline
+ m_screen->update_now();
- bitmap.pix32(y, x) = palette[0];
- }
- break;
+ // This point is by the end of a line. Changes in palette are applied here.
+ if (BIT(m_mode, 7))
+ {
+ int color = m_mode & 0x0f;
+ uint8_t colordata = ~m_palette_val;
- case 1: /* 1024x256x2 */
- for (pixel = 0; pixel < 8; pixel++)
- {
- int x = (sx * 8) + pixel;
- int color = BIT(data, 0);
+ m_palette->set_pen_color(color, pal3bit(colordata >> 5), pal3bit(colordata >> 2), pal2bit(colordata >> 0));
+ }
+}
- bitmap.pix32(y, x) = palette[color];
+uint32_t tiki100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ //
+ // Emulates the pixel-shifter and row/column counters from a
+ // starting point on screen to an ending point on screen.
+ //
+ // For the most accurate results, this should be run once for
+ // every 16-pixel chunk, but per the spring of 2020 there is
+ // only one demo that require this degree of accuracy.
+ //
+ //
- data >>= 1;
- }
- break;
+ const rgb_t *palette = m_palette->palette()->entry_list_raw();
- case 2: /* 512x256x4 */
- for (pixel = 0; pixel < 4; pixel++)
+ for (int vaddr = cliprect.min_y; vaddr <= cliprect.max_y; vaddr++)
+ {
+ // This is at the start of a line
+ int haddr = (cliprect.min_x>>4);
+ int haddr_end = (cliprect.max_x>>4);
+ for (; haddr <= haddr_end; haddr++)
+ {
+ // This is at the start of a 16-dot cluster. Changes in m_scroll and m_video_ram come into effect here.
+ uint16_t addr = ((vaddr+m_scroll)<<7) | (haddr<<1);
+ uint16_t data = (m_video_ram[(addr+1) & TIKI100_VIDEORAM_MASK]<<8) | m_video_ram[addr & TIKI100_VIDEORAM_MASK];
+ for(int dot = 0; dot < 16; dot++)
+ {
+ // This is at the start of a dot. Changes in m_mode are applied at this point.
+ int mode = (m_mode >> 4) & 0x03;
+ if((mode == 1) || (!(dot&0x01) && mode == 2) || (!(dot&0x03) && mode == 3))
{
- int x = (sx * 8) + (pixel * 2);
- int color = data & 0x03;
-
- bitmap.pix32(y, x) = palette[color];
- bitmap.pix32(y, x + 1) = palette[color];
-
- data >>= 2;
+ // This is the point when a pixel is latched from the dot-shifter.
+ //
+ // For the sake of readability:
+ // mode == 0: keep the old pixel
+ // mode == 1: latch new pixel once per dot
+ // mode == 2: latch new pixel once per 2 dots
+ // mode == 3: latch new pixel once per 4 dots
+ //
+ m_current_pixel = data&0x0F;
}
- break;
+ bitmap.pix32(vaddr, (haddr<<4) + dot) = palette[m_current_pixel&0x0F];
- case 3: /* 256x256x16 */
- for (pixel = 0; pixel < 2; pixel++)
- {
- int x = (sx * 8) + (pixel * 4);
- int color = data & 0x0f;
-
- bitmap.pix32(y, x) = palette[color];
- bitmap.pix32(y, x + 1) = palette[color];
- bitmap.pix32(y, x + 2) = palette[color];
- bitmap.pix32(y, x + 3) = palette[color];
-
- data >>= 4;
- }
- break;
+ // This will run the dot-shifter and add the TEST-pattern to the upper bits (usually hidden by palette).
+ data = (data>>1)|((haddr&0x02)<<14);
}
-
- addr++;
}
}
@@ -709,9 +717,10 @@ void tiki100_state::tiki100(machine_config &config)
m_maincpu->set_daisy_config(tiki100_daisy_chain);
/* video hardware */
- screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER));
- screen.set_raw(20_MHz_XTAL, 1280, 0, 1024, 312, 0, 256);
- screen.set_screen_update(FUNC(tiki100_state::screen_update));
+ TIMER(config, "scantimer").configure_scanline(FUNC(tiki100_state::scanline_start), "screen", 0, 1);
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_raw(20_MHz_XTAL, 1280, 0, 1024, 312, 0, 256);
+ m_screen->set_screen_update(FUNC(tiki100_state::screen_update));
PALETTE(config, m_palette).set_entries(16);
TIKI100_BUS(config, m_exp, 0);
diff --git a/src/mame/includes/tiki100.h b/src/mame/includes/tiki100.h
index acf96781504..9a6f350a0b9 100644
--- a/src/mame/includes/tiki100.h
+++ b/src/mame/includes/tiki100.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Curt Coder
+// copyright-holders:Curt Coder, Frode van der Meeren
#ifndef MAME_INCLUDES_TIKI100_H
#define MAME_INCLUDES_TIKI100_H
@@ -46,6 +46,7 @@ class tiki100_state : public driver_device
public:
tiki100_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
+ m_screen(*this, "screen"),
m_maincpu(*this, Z80_TAG),
m_ctc(*this, Z80CTC_TAG),
m_fdc(*this, FD1797_TAG),
@@ -95,6 +96,7 @@ private:
TIMER_DEVICE_CALLBACK_MEMBER( ctc_tick );
TIMER_DEVICE_CALLBACK_MEMBER( tape_tick );
+ TIMER_DEVICE_CALLBACK_MEMBER( scanline_start );
DECLARE_WRITE_LINE_MEMBER(write_centronics_ack);
DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
@@ -108,6 +110,7 @@ private:
virtual void machine_start() override;
virtual void machine_reset() override;
+ required_device<screen_device> m_screen;
required_device<z80_device> m_maincpu;
required_device<z80ctc_device> m_ctc;
required_device<fd1797_device> m_fdc;
@@ -123,7 +126,7 @@ private:
required_memory_region m_rom;
required_memory_region m_prom;
optional_shared_ptr<uint8_t> m_video_ram;
- required_ioport_array<12> m_y;
+ required_ioport_array<13> m_y;
required_ioport m_st_io;
required_device<palette_device> m_palette;
output_finder<2> m_leds;
@@ -144,6 +147,7 @@ private:
uint8_t m_scroll;
uint8_t m_mode;
uint8_t m_palette_val;
+ uint8_t m_current_pixel;
// keyboard state
int m_keylatch;