summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/agat7.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/agat7.cpp')
-rw-r--r--src/mame/video/agat7.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/src/mame/video/agat7.cpp b/src/mame/video/agat7.cpp
new file mode 100644
index 00000000000..10ff9800a40
--- /dev/null
+++ b/src/mame/video/agat7.cpp
@@ -0,0 +1,375 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*********************************************************************
+
+ agat7video.cpp
+
+ Implementation of Agat-7 onboard video.
+
+ 5 video modes:
+ - 32x32 color text
+ - 64x32 mono text with reverse video
+ - 64x64 color graphics
+ - 128x128 color graphics
+ - 256x256 mono graphics
+
+ Character generator ROM could have 128 or 256 chars.
+
+ C7xx: video mode select
+
+*********************************************************************/
+
+#include "video/agat7.h"
+
+#include "screen.h"
+
+
+/***************************************************************************
+ PARAMETERS
+***************************************************************************/
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type AGAT7VIDEO = device_creator<agat7video_device>;
+
+MACHINE_CONFIG_FRAGMENT(agat7video)
+ MCFG_SCREEN_ADD("a7screen", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_10_5MHz, 672, 0, 512, 312, 0, 256)
+ MCFG_SCREEN_UPDATE_DRIVER(agat7video_device, screen_update)
+ MCFG_SCREEN_PALETTE("a7palette")
+
+ MCFG_PALETTE_ADD("a7palette", 16)
+ MCFG_PALETTE_INIT_OWNER(agat7video_device, agat7)
+MACHINE_CONFIG_END
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor agat7video_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( agat7video );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+agat7video_device::agat7video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, AGAT7VIDEO, "Agat-7 video", tag, owner, clock, "agat7video", __FILE__),
+ m_palette(*this, "a7palette")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void agat7video_device::device_start()
+{
+// save_item(NAME(m_video_mode));
+ save_item(NAME(m_start_address));
+}
+
+void agat7video_device::device_reset()
+{
+ // XXX to be confirmed
+ m_video_mode = TEXT_LORES;
+ m_start_address = 0x7800;
+}
+
+
+READ8_MEMBER(agat7video_device::read)
+{
+ do_io(offset);
+ return 0;
+}
+
+WRITE8_MEMBER(agat7video_device::write)
+{
+ do_io(offset);
+}
+
+
+void agat7video_device::do_io(int offset)
+{
+ switch (offset & 3)
+ {
+ case 0:
+ m_video_mode = GRAPHICS_LORES;
+ m_start_address = (offset) << 9;
+ logerror("offset %04X, video mode 0 (GRAPHICS_LORES)\n", m_start_address);
+ break;
+
+ case 1:
+ m_video_mode = GRAPHICS_HIRES;
+ m_start_address = ((offset & 0x3f) - 0x01) << 9;
+ logerror("offset %04X, video mode 1 (GRAPHICS_HIRES)\n", m_start_address);
+ break;
+
+ case 2:
+ if (offset > 0x80) {
+ m_video_mode = TEXT_HIRES;
+ m_start_address = (offset - 0x82) << 9;
+ logerror("offset %04X, video mode 2 (TEXT_HIRES)\n", m_start_address);
+ } else {
+ m_video_mode = TEXT_LORES;
+ m_start_address = (offset - 0x02) << 9;
+ logerror("offset %04X, video mode 2 (TEXT_LORES)\n", m_start_address);
+ }
+ break;
+
+ case 3:
+ m_video_mode = GRAPHICS_MONO;
+ m_start_address = ((offset & 0x3f) - 0x03) << 9;
+ logerror("offset %04X, video mode 3 (GRAPHICS_MONO)\n", m_start_address);
+ break;
+ }
+}
+
+
+void agat7video_device::plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code,
+ const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg)
+{
+ int x, y, i;
+ const uint8_t *chardata;
+ uint16_t color;
+
+ /* look up the character data */
+ chardata = &textgfx_data[(code * 8)];
+
+ for (y = 0; y < 8; y++)
+ {
+ for (x = 0; x < 8; x++)
+ {
+ color = (chardata[y] & (1 << (7-x))) ? fg : bg;
+
+ for (i = 0; i < xscale; i++)
+ {
+ bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color;
+ }
+ }
+ }
+}
+
+void agat7video_device::text_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
+{
+ int row, col;
+ uint32_t address;
+ uint8_t ch, attr;
+ int fg = 0;
+ int bg = 0;
+
+ beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
+ endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
+
+ for (row = beginrow; row <= endrow; row += 8)
+ {
+ for (col = 0; col < 32; col++)
+ {
+ /* calculate address */
+ address = m_start_address + (col * 2) + (row * 8);
+ ch = m_ram_dev->read(address);
+ attr = m_ram_dev->read(address + 1);
+ if (BIT(attr, 5)) {
+ fg = BITSWAP8(attr,7,6,5,3,4,2,1,0) & 15;
+ bg = 0;
+ } else {
+ fg = 0;
+ bg = BITSWAP8(attr,7,6,5,3,4,2,1,0) & 15;
+ }
+ plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, fg, bg);
+ }
+ }
+}
+
+void agat7video_device::text_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
+{
+ int row, col;
+ uint32_t address;
+ uint8_t ch;
+ int fg, bg;
+
+ beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
+ endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
+
+ if (m_start_address & 0x800) {
+ fg = 7; bg = 0;
+ } else {
+ fg = 0; bg = 7;
+ }
+
+ for (row = beginrow; row <= endrow; row += 8)
+ {
+ for (col = 0; col < 64; col++)
+ {
+ /* calculate address */
+ address = m_start_address + col + (row * 8);
+ ch = m_ram_dev->read(address);
+ plot_text_character(bitmap, col * 8, row, 1, ch, m_char_ptr, m_char_size, fg, bg);
+ }
+ }
+}
+
+void agat7video_device::graph_update_mono(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
+{
+ int row, col, b;
+ uint32_t address;
+ uint16_t *p;
+ uint8_t gfx, v;
+ int fg = 7, bg = 0;
+
+ beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
+ endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
+
+ for (row = beginrow; row <= endrow; row++)
+ {
+ p = &bitmap.pix16(row);
+ for (col = 0; col < 32; col++)
+ {
+ address = m_start_address + col + (row * 0x20);
+ gfx = m_ram_dev->read(address);
+
+ for (b = 0; b < 8; b++)
+ {
+ v = (gfx & 0x80);
+ gfx <<= 1;
+ *(p++) = v ? fg : bg;
+ *(p++) = v ? fg : bg;
+ }
+ }
+ }
+}
+
+void agat7video_device::graph_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
+{
+ int row, col, b;
+ uint32_t address;
+ uint16_t *p;
+ uint8_t gfx, v;
+
+ beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
+ endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
+
+ for (row = beginrow; row <= endrow; row++)
+ {
+ p = &bitmap.pix16(row);
+ for (col = 0; col < 0x40; col++)
+ {
+ address = m_start_address + col + ((row/2) * 0x40);
+ gfx = m_ram_dev->read(address);
+
+ for (b = 0; b < 2; b++)
+ {
+ v = (gfx & 0xf0) >> 4;
+ gfx <<= 4;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ }
+ }
+ }
+}
+
+void agat7video_device::graph_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
+{
+ int row, col, b;
+ uint32_t address;
+ uint16_t *p;
+ uint8_t gfx, v;
+
+ beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8));
+ endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
+
+ for (row = beginrow; row <= endrow; row++)
+ {
+ p = &bitmap.pix16(row);
+ for (col = 0; col < 0x20; col++)
+ {
+ address = m_start_address + col + ((row/4) * 0x20);
+ gfx = m_ram_dev->read(address);
+
+ for (b = 0; b < 2; b++)
+ {
+ v = (gfx & 0xf0) >> 4;
+ gfx <<= 4;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ *(p++) = v;
+ }
+ }
+ }
+}
+
+
+uint32_t agat7video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ switch (m_video_mode)
+ {
+ case TEXT_LORES:
+ text_update_lores(screen, bitmap, cliprect, 0, 255);
+ break;
+
+ case TEXT_HIRES:
+ text_update_hires(screen, bitmap, cliprect, 0, 255);
+ break;
+
+ case GRAPHICS_MONO:
+ graph_update_mono(screen, bitmap, cliprect, 0, 255);
+ break;
+
+ case GRAPHICS_LORES:
+ graph_update_lores(screen, bitmap, cliprect, 0, 255);
+ break;
+
+ case GRAPHICS_HIRES:
+ graph_update_hires(screen, bitmap, cliprect, 0, 255);
+ break;
+
+ default:
+ graph_update_mono(screen, bitmap, cliprect, 0, 255);
+ break;
+ }
+
+ return 0;
+}
+
+// per http://agatcomp.ru/Reading/IiO/87-2-077.djvu
+static const rgb_t agat7_palette[] =
+{
+ rgb_t::black(),
+ rgb_t(0xFF, 0x00, 0x00), /* White */
+ rgb_t(0x00, 0xFF, 0x00), /* White */
+ rgb_t(0xFF, 0xFF, 0x00), /* White */
+ rgb_t(0x00, 0x00, 0xFF), /* White */
+ rgb_t(0xFF, 0x00, 0xFF), /* White */
+ rgb_t(0xFF, 0xFF, 0x00), /* White */
+ rgb_t(0xFF, 0xFF, 0xFF), /* White */
+ rgb_t::black(),
+ rgb_t(0x7F, 0x00, 0x00), /* White */
+ rgb_t(0x00, 0x7F, 0x00), /* White */
+ rgb_t(0x7F, 0x7F, 0x00), /* White */
+ rgb_t(0x00, 0x00, 0x7F), /* White */
+ rgb_t(0x7F, 0x00, 0x7F), /* White */
+ rgb_t(0x7F, 0x7F, 0x00), /* White */
+ rgb_t(0x7F, 0x7F, 0x7F) /* White */
+};
+
+PALETTE_INIT_MEMBER(agat7video_device, agat7)
+{
+ palette.set_pen_colors(0, agat7_palette, ARRAY_LENGTH(agat7_palette));
+}