mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
Add topcat asic (#3558)
* add topcat template HP topcat was an ASIC used on HP900/300 graphics cards. Signed-off-by: Sven Schnelle <svens@stackframe.org> * hook up topcat asic to HP98544 Signed-off-by: Sven Schnelle <svens@stackframe.org> * topcat: add basic configuration macros for fb planes, height and width Signed-off-by: Sven Schnelle <svens@stackframe.org> * hp98544: move logic to topcat video driver Preparation to support multi plane graphic cards like the HP98543/98545/98547. Signed-off-by: Sven Schnelle <svens@stackframe.org> * xtal: add 35.904MHz XTAL
This commit is contained in:
parent
718b23d773
commit
e6b55ad7a6
@ -1069,3 +1069,14 @@ if (VIDEOS["BT45X"]~=null) then
|
||||
MAME_DIR .. "src/devices/video/bt45x.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/topcat.h,VIDEOS["TOPCAT"] = true
|
||||
--------------------------------------------------
|
||||
if (VIDEOS["TOPCAT"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/video/topcat.cpp",
|
||||
MAME_DIR .. "src/devices/video/topcat.h",
|
||||
}
|
||||
end
|
||||
|
@ -15,8 +15,6 @@
|
||||
#define HP98544_SCREEN_NAME "98544_screen"
|
||||
#define HP98544_ROM_REGION "98544_rom"
|
||||
|
||||
#define VRAM_SIZE (0x100000)
|
||||
|
||||
ROM_START( hp98544 )
|
||||
ROM_REGION( 0x2000, HP98544_ROM_REGION, 0 )
|
||||
ROM_LOAD( "98544_1818-1999.bin", 0x000000, 0x002000, CRC(8c7d6480) SHA1(d2bcfd39452c38bc652df39f84c7041cfdf6bd51) )
|
||||
@ -39,6 +37,11 @@ MACHINE_CONFIG_START(dio16_98544_device::device_add_mconfig)
|
||||
MCFG_SCREEN_SIZE(1024,768)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 1024-1, 0, 768-1)
|
||||
MCFG_SCREEN_REFRESH_RATE(70)
|
||||
|
||||
MCFG_DEVICE_ADD("topcat", TOPCAT, XTAL(35904000))
|
||||
MCFG_TOPCAT_FB_WIDTH(1024)
|
||||
MCFG_TOPCAT_FB_HEIGHT(768)
|
||||
MCFG_TOPCAT_PLANES(1)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -65,7 +68,8 @@ dio16_98544_device::dio16_98544_device(const machine_config &mconfig, const char
|
||||
|
||||
dio16_98544_device::dio16_98544_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_dio16_card_interface(mconfig, *this)
|
||||
device_dio16_card_interface(mconfig, *this),
|
||||
m_topcat(*this, "topcat")
|
||||
{
|
||||
}
|
||||
|
||||
@ -80,7 +84,6 @@ void dio16_98544_device::device_start()
|
||||
|
||||
m_rom = device().machine().root_device().memregion(this->subtag(HP98544_ROM_REGION).c_str())->base();
|
||||
|
||||
m_vram.resize(VRAM_SIZE);
|
||||
m_dio->install_memory(
|
||||
0x200000, 0x2fffff,
|
||||
read16_delegate(FUNC(dio16_98544_device::vram_r), this),
|
||||
@ -93,8 +96,6 @@ void dio16_98544_device::device_start()
|
||||
0x564000, 0x567fff,
|
||||
read16_delegate(FUNC(dio16_98544_device::ctrl_r), this),
|
||||
write16_delegate(FUNC(dio16_98544_device::ctrl_w), this));
|
||||
m_cursor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dio16_98544_device::cursor_callback),this));
|
||||
m_cursor_timer->adjust(attotime::from_hz(3));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -103,49 +104,16 @@ void dio16_98544_device::device_start()
|
||||
|
||||
void dio16_98544_device::device_reset()
|
||||
{
|
||||
memset(&m_vram[0], 0, VRAM_SIZE);
|
||||
|
||||
m_palette[1] = rgb_t(255, 255, 255);
|
||||
m_palette[0] = rgb_t(0, 0, 0);
|
||||
m_pixel_replacement_rule = TOPCAT_REPLACE_RULE_SRC;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dio16_98544_device::cursor_callback)
|
||||
{
|
||||
m_cursor_timer->adjust(attotime::from_hz(5));
|
||||
m_cursor_state ^= true;
|
||||
|
||||
if (m_cursor_ctrl & 0x02) {
|
||||
for(int i = 0; i < m_cursor_width; i++) {
|
||||
m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dio16_98544_device::update_cursor(int x, int y, uint8_t ctrl, uint8_t width)
|
||||
{
|
||||
for(int i = 0; i < m_cursor_width; i++) {
|
||||
m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
}
|
||||
m_cursor_x_pos = x;
|
||||
m_cursor_y_pos = y;
|
||||
m_cursor_ctrl = ctrl;
|
||||
m_cursor_width = width;
|
||||
}
|
||||
|
||||
READ16_MEMBER(dio16_98544_device::vram_r)
|
||||
{
|
||||
return m_vram[offset];
|
||||
return m_topcat->vram_r(space, offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(dio16_98544_device::vram_w)
|
||||
{
|
||||
// execute_rule(data, (replacement_rule_t)m_pixel_replacement_rule, &data);
|
||||
COMBINE_DATA(&m_vram[offset]);
|
||||
m_topcat->vram_w(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
READ16_MEMBER(dio16_98544_device::rom_r)
|
||||
@ -158,249 +126,17 @@ WRITE16_MEMBER(dio16_98544_device::rom_w)
|
||||
{
|
||||
}
|
||||
|
||||
void dio16_98544_device::execute_rule(uint16_t src, replacement_rule_t rule, uint16_t *dst)
|
||||
{
|
||||
switch(rule & 0x0f) {
|
||||
case TOPCAT_REPLACE_RULE_CLEAR:
|
||||
*dst = 0;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_AND_DST:
|
||||
*dst &= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_AND_NOT_DST:
|
||||
*dst = ~(*dst) & src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC:
|
||||
*dst = src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_AND_DST:
|
||||
*dst &= ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOP:
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_XOR_DST:
|
||||
*dst ^= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_OR_DST:
|
||||
*dst |= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_AND_NOT_DST:
|
||||
*dst = ~(*dst) & ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_XOR_DST:
|
||||
*dst ^= ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_DST:
|
||||
*dst ^= 0xffff;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_OR_NOT_DST:
|
||||
*dst = src | ~(*dst);
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC:
|
||||
*dst = ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_OR_DST:
|
||||
*dst = ~src | *dst;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_OR_NOT_DST:
|
||||
*dst = ~src | ~(*dst);
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SET:
|
||||
*dst = 0xffff;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void dio16_98544_device::window_move(void)
|
||||
{
|
||||
for(int line = 0; line < m_block_mover_pixel_height; line++) {
|
||||
for(int column = 0; column < m_block_mover_pixel_width; column++) {
|
||||
uint16_t sdata = m_vram[((m_source_y_pixel + line) * 1024 + (m_source_x_pixel + column))/2];
|
||||
uint16_t *ddata = &m_vram[((m_dst_y_pixel + line) * 1024 + (m_dst_x_pixel + column))/2];
|
||||
execute_rule(sdata, (replacement_rule_t)((m_move_replacement_rule >> 4) & 0x0f), ddata);
|
||||
execute_rule(sdata, (replacement_rule_t)(m_move_replacement_rule & 0x0f), ddata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(dio16_98544_device::ctrl_w)
|
||||
{
|
||||
if (mem_mask == 0xff00)
|
||||
data >>= 8;
|
||||
|
||||
if (mem_mask == 0x00ff) {
|
||||
logerror("%s: write ignored\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(offset) {
|
||||
case TOPCAT_REG_VBLANK:
|
||||
m_vblank = data & 0xff;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_ACTIVE:
|
||||
break;
|
||||
case TOPCAT_REG_VERT_RETRACE_INTRQ:
|
||||
m_vert_retrace_intrq = data;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_INTRQ:
|
||||
m_wmove_intrq = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
|
||||
m_display_enable_planes = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
|
||||
m_write_enable_plane = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
|
||||
m_read_enable_plane = data;
|
||||
break;
|
||||
case TOPCAT_REG_FB_WRITE_ENABLE:
|
||||
m_fb_write_enable = data;
|
||||
break;
|
||||
case TOPCAT_REG_START_WMOVE:
|
||||
window_move();
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_BLINK_PLANES:
|
||||
logerror("ENABLE_BLINK_PLANES: %04x\n", data);
|
||||
m_enable_blink_planes = data;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_ALT_FRAME:
|
||||
logerror("ENABLE_ALT_PLANE: %04x\n", data);
|
||||
m_enable_alt_frame = data;
|
||||
break;
|
||||
case TOPCAT_REG_PIXEL_REPLACE_RULE:
|
||||
logerror("PIXEL RR: data %04X mask %04X\n", data, mem_mask);
|
||||
m_pixel_replacement_rule = data;
|
||||
break;
|
||||
case TOPCAT_REG_MOVE_REPLACE_RULE:
|
||||
logerror("MOVE RR: data %04X mask %04X\n", data, mem_mask);
|
||||
m_move_replacement_rule = data;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_X_PIXEL:
|
||||
m_source_x_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_Y_PIXEL:
|
||||
m_source_y_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_DST_X_PIXEL:
|
||||
m_dst_x_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_DST_Y_PIXEL:
|
||||
m_dst_y_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
|
||||
m_block_mover_pixel_width = data;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
|
||||
m_block_mover_pixel_height = data;
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_CNTL:
|
||||
update_cursor(m_cursor_x_pos, m_cursor_y_pos, data, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_X_POS:
|
||||
update_cursor(data, m_cursor_y_pos, m_cursor_ctrl, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_Y_POS:
|
||||
update_cursor(m_cursor_x_pos, data, m_cursor_ctrl, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_WIDTH:
|
||||
update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_ctrl, data);
|
||||
break;
|
||||
default:
|
||||
logerror("unknown register: %02X = %04x\n", offset, data, mem_mask);
|
||||
break;
|
||||
}
|
||||
return m_topcat->ctrl_w(space, offset, data);
|
||||
}
|
||||
|
||||
READ16_MEMBER(dio16_98544_device::ctrl_r)
|
||||
{
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
switch(offset) {
|
||||
case TOPCAT_REG_VBLANK:
|
||||
ret = m_vblank;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_ACTIVE:
|
||||
ret = m_wmove_active;
|
||||
break;
|
||||
case TOPCAT_REG_VERT_RETRACE_INTRQ:
|
||||
ret = m_vert_retrace_intrq;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_INTRQ:
|
||||
ret = m_wmove_intrq;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
|
||||
ret = m_display_enable_planes;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
|
||||
ret = m_write_enable_plane;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
|
||||
ret = m_read_enable_plane;
|
||||
break;
|
||||
case TOPCAT_REG_FB_WRITE_ENABLE:
|
||||
ret = m_fb_write_enable;
|
||||
break;
|
||||
case TOPCAT_REG_START_WMOVE:
|
||||
ret = 0;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_BLINK_PLANES:
|
||||
ret = m_enable_blink_planes;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_ALT_FRAME:
|
||||
ret = m_enable_alt_frame;
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_CNTL:
|
||||
ret = m_cursor_ctrl;
|
||||
break;
|
||||
case TOPCAT_REG_PIXEL_REPLACE_RULE:
|
||||
ret = m_pixel_replacement_rule;
|
||||
break;
|
||||
case TOPCAT_REG_MOVE_REPLACE_RULE:
|
||||
ret = m_move_replacement_rule;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_X_PIXEL:
|
||||
ret = m_source_x_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_Y_PIXEL:
|
||||
ret = m_source_y_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_DST_X_PIXEL:
|
||||
ret = m_dst_x_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_DST_Y_PIXEL:
|
||||
ret = m_dst_y_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
|
||||
ret = m_block_mover_pixel_width;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
|
||||
ret = m_block_mover_pixel_height;
|
||||
break;
|
||||
default:
|
||||
logerror("unknown register read %02x\n", offset);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
return m_topcat->ctrl_r(space, offset);
|
||||
}
|
||||
|
||||
uint32_t dio16_98544_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint32_t *scanline;
|
||||
int x, y;
|
||||
uint32_t pixels;
|
||||
|
||||
for (y = 0; y < 768; y++)
|
||||
{
|
||||
scanline = &bitmap.pix32(y);
|
||||
for (x = 0; x < 1024/2; x++)
|
||||
{
|
||||
pixels = m_vram[(y * 512) + x];
|
||||
|
||||
*scanline++ = m_palette[(pixels>>8) & 1];
|
||||
*scanline++ = m_palette[(pixels & 1)];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return m_topcat->screen_update(screen, bitmap, cliprect);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hp_dio.h"
|
||||
|
||||
#include "video/topcat.h"
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
@ -29,8 +29,8 @@ public:
|
||||
DECLARE_READ16_MEMBER(ctrl_r);
|
||||
DECLARE_WRITE16_MEMBER(ctrl_w);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cursor_callback);
|
||||
|
||||
required_device<topcat_device> m_topcat;
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
protected:
|
||||
dio16_98544_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
@ -41,87 +41,8 @@ public:
|
||||
// optional information overrides
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
typedef enum {
|
||||
TOPCAT_REPLACE_RULE_CLEAR, /* 0 */
|
||||
TOPCAT_REPLACE_RULE_SRC_AND_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_AND_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_AND_DST,
|
||||
TOPCAT_REPLACE_RULE_NOP,
|
||||
TOPCAT_REPLACE_RULE_SRC_XOR_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_OR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_AND_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_XOR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_OR_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_OR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_OR_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SET,
|
||||
} replacement_rule_t;
|
||||
|
||||
private:
|
||||
enum topcat_reg {
|
||||
TOPCAT_REG_VBLANK=0x20,
|
||||
TOPCAT_REG_WMOVE_ACTIVE=0x22,
|
||||
TOPCAT_REG_VERT_RETRACE_INTRQ=0x24,
|
||||
TOPCAT_REG_WMOVE_INTRQ=0x26,
|
||||
TOPCAT_REG_DISPLAY_PLANE_ENABLE=0x40,
|
||||
TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE=0x44,
|
||||
TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE=0x46,
|
||||
TOPCAT_REG_FB_WRITE_ENABLE=0x48,
|
||||
TOPCAT_REG_START_WMOVE=0x4e,
|
||||
TOPCAT_REG_ENABLE_BLINK_PLANES=0x50,
|
||||
TOPCAT_REG_ENABLE_ALT_FRAME=0x54,
|
||||
TOPCAT_REG_CURSOR_CNTL=0x56,
|
||||
TOPCAT_REG_PIXEL_REPLACE_RULE=0x75,
|
||||
TOPCAT_REG_MOVE_REPLACE_RULE=0x77,
|
||||
TOPCAT_REG_SOURCE_X_PIXEL=0x79,
|
||||
TOPCAT_REG_SOURCE_Y_PIXEL=0x7b,
|
||||
TOPCAT_REG_DST_X_PIXEL=0x7d,
|
||||
TOPCAT_REG_DST_Y_PIXEL=0x7f,
|
||||
TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH=0x81,
|
||||
TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT=0x83,
|
||||
TOPCAT_REG_CURSOR_X_POS=0x85,
|
||||
TOPCAT_REG_CURSOR_Y_POS=0x87,
|
||||
TOPCAT_REG_CURSOR_WIDTH=0x89,
|
||||
};
|
||||
|
||||
void window_move(void);
|
||||
void execute_rule(uint16_t src, replacement_rule_t rule, uint16_t *dst);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
void update_cursor(int x, int y, uint8_t ctrl, uint8_t width);
|
||||
std::vector<uint16_t> m_vram;
|
||||
uint32_t m_palette[2];
|
||||
uint8_t *m_rom;
|
||||
|
||||
uint8_t m_vblank;
|
||||
uint8_t m_wmove_active;
|
||||
uint8_t m_vert_retrace_intrq;
|
||||
uint8_t m_wmove_intrq;
|
||||
uint8_t m_display_enable_planes;
|
||||
uint8_t m_write_enable_plane;
|
||||
uint8_t m_read_enable_plane;
|
||||
uint8_t m_fb_write_enable;
|
||||
uint8_t m_enable_blink_planes;
|
||||
uint8_t m_enable_alt_frame;
|
||||
uint8_t m_cursor_ctrl;
|
||||
uint8_t m_move_replacement_rule;
|
||||
uint8_t m_pixel_replacement_rule;
|
||||
uint16_t m_source_x_pixel;
|
||||
uint16_t m_source_y_pixel;
|
||||
uint16_t m_dst_x_pixel;
|
||||
uint16_t m_dst_y_pixel;
|
||||
uint16_t m_block_mover_pixel_width;
|
||||
uint16_t m_block_mover_pixel_height;
|
||||
|
||||
emu_timer *m_cursor_timer;
|
||||
bool m_cursor_state;
|
||||
uint16_t m_cursor_x_pos;
|
||||
uint16_t m_cursor_y_pos;
|
||||
uint16_t m_cursor_width;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
324
src/devices/video/topcat.cpp
Normal file
324
src/devices/video/topcat.cpp
Normal file
@ -0,0 +1,324 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sven Schnelle
|
||||
|
||||
#include "emu.h"
|
||||
#include "topcat.h"
|
||||
|
||||
// define VERBOSE 1
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(TOPCAT, topcat_device, "topcat", "HP Topcat ASIC")
|
||||
|
||||
#define VRAM_SIZE (0x100000)
|
||||
|
||||
topcat_device::topcat_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
topcat_device::topcat_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: topcat_device(mconfig, TOPCAT, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void topcat_device::device_start()
|
||||
{
|
||||
m_vram.resize(VRAM_SIZE);
|
||||
|
||||
m_cursor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(topcat_device::cursor_callback),this));
|
||||
m_cursor_timer->adjust(attotime::from_hz(3));
|
||||
}
|
||||
|
||||
void topcat_device::device_reset()
|
||||
{
|
||||
memset(&m_vram[0], 0, VRAM_SIZE);
|
||||
|
||||
m_palette[1] = rgb_t(255, 255, 255);
|
||||
m_palette[0] = rgb_t(0, 0, 0);
|
||||
m_pixel_replacement_rule = TOPCAT_REPLACE_RULE_SRC;
|
||||
}
|
||||
|
||||
READ16_MEMBER(topcat_device::vram_r)
|
||||
{
|
||||
return m_vram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(topcat_device::vram_w)
|
||||
{
|
||||
COMBINE_DATA(&m_vram[offset]);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(topcat_device::cursor_callback)
|
||||
{
|
||||
m_cursor_timer->adjust(attotime::from_hz(5));
|
||||
m_cursor_state ^= true;
|
||||
|
||||
if (m_cursor_ctrl & 0x02) {
|
||||
for(int i = 0; i < m_cursor_width; i++) {
|
||||
m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void topcat_device::update_cursor(int x, int y, uint8_t ctrl, uint8_t width)
|
||||
{
|
||||
for(int i = 0; i < m_cursor_width; i++) {
|
||||
m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = 0;
|
||||
}
|
||||
m_cursor_x_pos = x;
|
||||
m_cursor_y_pos = y;
|
||||
m_cursor_ctrl = ctrl;
|
||||
m_cursor_width = width;
|
||||
}
|
||||
|
||||
void topcat_device::execute_rule(uint16_t src, replacement_rule_t rule, uint16_t *dst)
|
||||
{
|
||||
switch(rule & 0x0f) {
|
||||
case TOPCAT_REPLACE_RULE_CLEAR:
|
||||
*dst = 0;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_AND_DST:
|
||||
*dst &= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_AND_NOT_DST:
|
||||
*dst = ~(*dst) & src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC:
|
||||
*dst = src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_AND_DST:
|
||||
*dst &= ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOP:
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_XOR_DST:
|
||||
*dst ^= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_OR_DST:
|
||||
*dst |= src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_AND_NOT_DST:
|
||||
*dst = ~(*dst) & ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_XOR_DST:
|
||||
*dst ^= ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_DST:
|
||||
*dst ^= 0xffff;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SRC_OR_NOT_DST:
|
||||
*dst = src | ~(*dst);
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC:
|
||||
*dst = ~src;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_OR_DST:
|
||||
*dst = ~src | *dst;
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_NOT_SRC_OR_NOT_DST:
|
||||
*dst = ~src | ~(*dst);
|
||||
break;
|
||||
case TOPCAT_REPLACE_RULE_SET:
|
||||
*dst = 0xffff;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void topcat_device::window_move(void)
|
||||
{
|
||||
for(int line = 0; line < m_block_mover_pixel_height; line++) {
|
||||
for(int column = 0; column < m_block_mover_pixel_width; column++) {
|
||||
uint16_t sdata = m_vram[((m_source_y_pixel + line) * 1024 + (m_source_x_pixel + column))/2];
|
||||
uint16_t *ddata = &m_vram[((m_dst_y_pixel + line) * 1024 + (m_dst_x_pixel + column))/2];
|
||||
execute_rule(sdata, (replacement_rule_t)((m_move_replacement_rule >> 4) & 0x0f), ddata);
|
||||
execute_rule(sdata, (replacement_rule_t)(m_move_replacement_rule & 0x0f), ddata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ16_MEMBER(topcat_device::ctrl_r)
|
||||
{
|
||||
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
switch(offset) {
|
||||
case TOPCAT_REG_VBLANK:
|
||||
ret = m_vblank;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_ACTIVE:
|
||||
ret = m_wmove_active;
|
||||
break;
|
||||
case TOPCAT_REG_VERT_RETRACE_INTRQ:
|
||||
ret = m_vert_retrace_intrq;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_INTRQ:
|
||||
ret = m_wmove_intrq;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
|
||||
ret = m_display_enable_planes;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
|
||||
ret = m_write_enable_plane;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
|
||||
ret = m_read_enable_plane;
|
||||
break;
|
||||
case TOPCAT_REG_FB_WRITE_ENABLE:
|
||||
ret = m_fb_write_enable;
|
||||
break;
|
||||
case TOPCAT_REG_START_WMOVE:
|
||||
ret = 0;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_BLINK_PLANES:
|
||||
ret = m_enable_blink_planes;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_ALT_FRAME:
|
||||
ret = m_enable_alt_frame;
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_CNTL:
|
||||
ret = m_cursor_ctrl;
|
||||
break;
|
||||
case TOPCAT_REG_PIXEL_REPLACE_RULE:
|
||||
ret = m_pixel_replacement_rule;
|
||||
break;
|
||||
case TOPCAT_REG_MOVE_REPLACE_RULE:
|
||||
ret = m_move_replacement_rule;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_X_PIXEL:
|
||||
ret = m_source_x_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_Y_PIXEL:
|
||||
ret = m_source_y_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_DST_X_PIXEL:
|
||||
ret = m_dst_x_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_DST_Y_PIXEL:
|
||||
ret = m_dst_y_pixel;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
|
||||
ret = m_block_mover_pixel_width;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
|
||||
ret = m_block_mover_pixel_height;
|
||||
break;
|
||||
default:
|
||||
logerror("unknown register read %02x\n", offset);
|
||||
return space.unmap();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(topcat_device::ctrl_w)
|
||||
{
|
||||
if (mem_mask == 0xff00)
|
||||
data >>= 8;
|
||||
|
||||
if (mem_mask == 0x00ff) {
|
||||
logerror("%s: write ignored\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(offset) {
|
||||
case TOPCAT_REG_VBLANK:
|
||||
m_vblank = data & 0xff;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_ACTIVE:
|
||||
break;
|
||||
case TOPCAT_REG_VERT_RETRACE_INTRQ:
|
||||
m_vert_retrace_intrq = data;
|
||||
break;
|
||||
case TOPCAT_REG_WMOVE_INTRQ:
|
||||
m_wmove_intrq = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
|
||||
m_display_enable_planes = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
|
||||
m_write_enable_plane = data;
|
||||
break;
|
||||
case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
|
||||
m_read_enable_plane = data;
|
||||
break;
|
||||
case TOPCAT_REG_FB_WRITE_ENABLE:
|
||||
m_fb_write_enable = data;
|
||||
break;
|
||||
case TOPCAT_REG_START_WMOVE:
|
||||
window_move();
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_BLINK_PLANES:
|
||||
logerror("ENABLE_BLINK_PLANES: %04x\n", data);
|
||||
m_enable_blink_planes = data;
|
||||
break;
|
||||
case TOPCAT_REG_ENABLE_ALT_FRAME:
|
||||
logerror("ENABLE_ALT_PLANE: %04x\n", data);
|
||||
m_enable_alt_frame = data;
|
||||
break;
|
||||
case TOPCAT_REG_PIXEL_REPLACE_RULE:
|
||||
logerror("PIXEL RR: data %04X mask %04X\n", data, mem_mask);
|
||||
m_pixel_replacement_rule = data;
|
||||
break;
|
||||
case TOPCAT_REG_MOVE_REPLACE_RULE:
|
||||
logerror("MOVE RR: data %04X mask %04X\n", data, mem_mask);
|
||||
m_move_replacement_rule = data;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_X_PIXEL:
|
||||
m_source_x_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_SOURCE_Y_PIXEL:
|
||||
m_source_y_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_DST_X_PIXEL:
|
||||
m_dst_x_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_DST_Y_PIXEL:
|
||||
m_dst_y_pixel = data;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
|
||||
m_block_mover_pixel_width = data;
|
||||
break;
|
||||
case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
|
||||
m_block_mover_pixel_height = data;
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_CNTL:
|
||||
update_cursor(m_cursor_x_pos, m_cursor_y_pos, data, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_X_POS:
|
||||
update_cursor(data, m_cursor_y_pos, m_cursor_ctrl, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_Y_POS:
|
||||
update_cursor(m_cursor_x_pos, data, m_cursor_ctrl, m_cursor_width);
|
||||
break;
|
||||
case TOPCAT_REG_CURSOR_WIDTH:
|
||||
update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_ctrl, data);
|
||||
break;
|
||||
default:
|
||||
logerror("unknown register: %02X = %04x\n", offset, data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t topcat_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint32_t *scanline;
|
||||
int x, y;
|
||||
uint32_t pixels;
|
||||
|
||||
for (y = 0; y < 768; y++)
|
||||
{
|
||||
scanline = &bitmap.pix32(y);
|
||||
for (x = 0; x < 1024/2; x++)
|
||||
{
|
||||
pixels = m_vram[(y * 512) + x];
|
||||
|
||||
*scanline++ = m_palette[(pixels>>8) & 1];
|
||||
*scanline++ = m_palette[(pixels & 1)];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
126
src/devices/video/topcat.h
Normal file
126
src/devices/video/topcat.h
Normal file
@ -0,0 +1,126 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sven Schnelle
|
||||
#ifndef MAME_VIDEO_TOPCAT_H_
|
||||
#define MAME_VIDEO_TOPCAT_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MCFG_TOPCAT_FB_WIDTH(_pixels) \
|
||||
downcast<topcat_device &>(*device).set_fb_width(_pixels);
|
||||
|
||||
#define MCFG_TOPCAT_FB_HEIGHT(_pixels) \
|
||||
downcast<topcat_device &>(*device).set_fb_height(_pixels);
|
||||
|
||||
#define MCFG_TOPCAT_PLANES(_planes) \
|
||||
downcast<topcat_device &>(*device).set_planes(_planes);
|
||||
|
||||
class topcat_device : public device_t
|
||||
{
|
||||
public:
|
||||
topcat_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_fb_width(int _pixels) { m_fb_width = _pixels; }
|
||||
void set_fb_height(int _pixels) { m_fb_height = _pixels; }
|
||||
void set_planes(int _planes) { m_planes = _planes; }
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cursor_callback);
|
||||
|
||||
DECLARE_READ16_MEMBER(vram_r);
|
||||
DECLARE_WRITE16_MEMBER(vram_w);
|
||||
DECLARE_READ16_MEMBER(ctrl_r);
|
||||
DECLARE_WRITE16_MEMBER(ctrl_w);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
protected:
|
||||
topcat_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
|
||||
typedef enum {
|
||||
TOPCAT_REPLACE_RULE_CLEAR, /* 0 */
|
||||
TOPCAT_REPLACE_RULE_SRC_AND_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_AND_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_AND_DST,
|
||||
TOPCAT_REPLACE_RULE_NOP,
|
||||
TOPCAT_REPLACE_RULE_SRC_XOR_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_OR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_AND_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_XOR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SRC_OR_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_OR_DST,
|
||||
TOPCAT_REPLACE_RULE_NOT_SRC_OR_NOT_DST,
|
||||
TOPCAT_REPLACE_RULE_SET,
|
||||
} replacement_rule_t;
|
||||
|
||||
enum topcat_reg {
|
||||
TOPCAT_REG_VBLANK=0x20,
|
||||
TOPCAT_REG_WMOVE_ACTIVE=0x22,
|
||||
TOPCAT_REG_VERT_RETRACE_INTRQ=0x24,
|
||||
TOPCAT_REG_WMOVE_INTRQ=0x26,
|
||||
TOPCAT_REG_DISPLAY_PLANE_ENABLE=0x40,
|
||||
TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE=0x44,
|
||||
TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE=0x46,
|
||||
TOPCAT_REG_FB_WRITE_ENABLE=0x48,
|
||||
TOPCAT_REG_START_WMOVE=0x4e,
|
||||
TOPCAT_REG_ENABLE_BLINK_PLANES=0x50,
|
||||
TOPCAT_REG_ENABLE_ALT_FRAME=0x54,
|
||||
TOPCAT_REG_CURSOR_CNTL=0x56,
|
||||
TOPCAT_REG_PIXEL_REPLACE_RULE=0x75,
|
||||
TOPCAT_REG_MOVE_REPLACE_RULE=0x77,
|
||||
TOPCAT_REG_SOURCE_X_PIXEL=0x79,
|
||||
TOPCAT_REG_SOURCE_Y_PIXEL=0x7b,
|
||||
TOPCAT_REG_DST_X_PIXEL=0x7d,
|
||||
TOPCAT_REG_DST_Y_PIXEL=0x7f,
|
||||
TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH=0x81,
|
||||
TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT=0x83,
|
||||
TOPCAT_REG_CURSOR_X_POS=0x85,
|
||||
TOPCAT_REG_CURSOR_Y_POS=0x87,
|
||||
TOPCAT_REG_CURSOR_WIDTH=0x89,
|
||||
};
|
||||
|
||||
void window_move(void);
|
||||
void execute_rule(uint16_t src, replacement_rule_t rule, uint16_t *dst);
|
||||
|
||||
void update_cursor(int x, int y, uint8_t ctrl, uint8_t width);
|
||||
std::vector<uint16_t> m_vram;
|
||||
uint32_t m_palette[2];
|
||||
|
||||
uint8_t m_vblank;
|
||||
uint8_t m_wmove_active;
|
||||
uint8_t m_vert_retrace_intrq;
|
||||
uint8_t m_wmove_intrq;
|
||||
uint8_t m_display_enable_planes;
|
||||
uint8_t m_write_enable_plane;
|
||||
uint8_t m_read_enable_plane;
|
||||
uint8_t m_fb_write_enable;
|
||||
uint8_t m_enable_blink_planes;
|
||||
uint8_t m_enable_alt_frame;
|
||||
uint8_t m_cursor_ctrl;
|
||||
uint8_t m_move_replacement_rule;
|
||||
uint8_t m_pixel_replacement_rule;
|
||||
uint16_t m_source_x_pixel;
|
||||
uint16_t m_source_y_pixel;
|
||||
uint16_t m_dst_x_pixel;
|
||||
uint16_t m_dst_y_pixel;
|
||||
uint16_t m_block_mover_pixel_width;
|
||||
uint16_t m_block_mover_pixel_height;
|
||||
|
||||
emu_timer *m_cursor_timer;
|
||||
bool m_cursor_state;
|
||||
uint16_t m_cursor_x_pos;
|
||||
uint16_t m_cursor_y_pos;
|
||||
uint16_t m_cursor_width;
|
||||
|
||||
int m_fb_width;
|
||||
int m_fb_height;
|
||||
int m_planes;
|
||||
int m_plane_mask;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(TOPCAT, topcat_device)
|
||||
#endif // MAME_VIDEO_TOPCAT_H_
|
@ -301,6 +301,7 @@ const double XTAL::known_xtals[] = {
|
||||
33'868'800, /* 33.8688_MHz_XTAL Usually used to drive 90's Yamaha OPL/FM chips with /2 divider */
|
||||
34'000'000, /* 34_MHz_XTAL Gaelco PCBs */
|
||||
34'291'712, /* 34.291712_MHz_XTAL Fairlight CMI master card */
|
||||
35'904'000, /* 35.904_MHz_XTAL Used on HP98543 graphics board */
|
||||
36'000'000, /* 36_MHz_XTAL Sega Model 1 video board */
|
||||
38'769'220, /* 38.76922_MHz_XTAL Namco System 21 video board */
|
||||
39'321'600, /* 39.3216_MHz_XTAL Sun 2/120 */
|
||||
|
Loading…
Reference in New Issue
Block a user