mirror of
https://github.com/holub/mame
synced 2025-10-07 01:16:22 +03:00
isa/pgc: accelerated VRAM writes + cleanups (#3385)
* isa/pgc: use logmacro.h (nw) * isa/pgc: implement accelerated VRAM writes * isa/pgc: code style cleanup (nw)
This commit is contained in:
parent
a8d254d416
commit
ecb3c47796
@ -3,7 +3,7 @@
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
IBM Professional Graphics Controller (PGC), skeleton driver.
|
||||
IBM Professional Graphics Controller (PGC).
|
||||
|
||||
Designed for IBM by Vermont Microsystems. References:
|
||||
|
||||
@ -16,13 +16,13 @@
|
||||
http://www.seasip.info/VintagePC/pgc.html
|
||||
|
||||
To do:
|
||||
- decode memory map
|
||||
- various VRAM write modes
|
||||
- pass IBM diagnostics (currently fail with code 3905)
|
||||
- CGA emulator
|
||||
- what's up with irq 3 (= vblank irq)? (causes soft reset)
|
||||
- "test pin of the microprocessor samples the hsync pulse"
|
||||
- CGA emulator
|
||||
- bus state handling?
|
||||
- VRAM address translator ROM?
|
||||
- clones/compatibles? CompuShow apparently was tested with a clone and sends opcode E6, writes 2 to C630C
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -32,17 +32,18 @@
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
#define VERBOSE_PGC 1
|
||||
//#define LOG_GENERAL (1U << 0) //defined in logmacro.h already
|
||||
#define LOG_VRAM (1U << 1)
|
||||
#define LOG_CMD (1U << 2)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL | LOG_VRAM)
|
||||
//#define LOG_OUTPUT_STREAM std::cout
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGV(...) LOGMASKED(LOG_VRAM, __VA_ARGS__)
|
||||
#define LOGCMD(...) LOGMASKED(LOG_CMD, __VA_ARGS__)
|
||||
|
||||
#define DBG_LOG(N,M,A) \
|
||||
do { \
|
||||
if(VERBOSE_PGC>=N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f at %s: %-24s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PGC_SCREEN_NAME "pgc_screen"
|
||||
|
||||
@ -111,18 +112,16 @@ void isa8_pgc_device::pgc_map(address_map &map)
|
||||
map(0x00000, 0x07fff).rom();
|
||||
map(0x08000, 0x0ffff).rom().region("maincpu", 0x8000);
|
||||
map(0x10000, 0x1001f).rw(this, FUNC(isa8_pgc_device::stateparam_r), FUNC(isa8_pgc_device::stateparam_w));
|
||||
// AM_RANGE(0x18000, 0x18fff) AM_RAM // ??
|
||||
// map(0x18000, 0x18fff).ram(); // ??
|
||||
map(0x28000, 0x287ff).ram().region("commarea", 0).mirror(0x800);
|
||||
map(0x32001, 0x32001).nopw();
|
||||
map(0x32020, 0x3203f).w(this, FUNC(isa8_pgc_device::accel_w));
|
||||
map(0x3c000, 0x3c001).r(this, FUNC(isa8_pgc_device::init_r));
|
||||
// AM_RANGE(0x3e000, 0x3efff) AM_RAM // ??
|
||||
// map(0x3e000, 0x3efff).ram(); // ??
|
||||
map(0x80000, 0xf7fff).rw(this, FUNC(isa8_pgc_device::vram_r), FUNC(isa8_pgc_device::vram_w));
|
||||
map(0xf8000, 0xfffff).rom().region("maincpu", 0x8000);
|
||||
}
|
||||
|
||||
void isa8_pgc_device::pgc_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
}
|
||||
|
||||
static const gfx_layout pgc_charlayout =
|
||||
{
|
||||
8, 16, /* 8x16 pixels */
|
||||
@ -155,7 +154,6 @@ DEFINE_DEVICE_TYPE(ISA8_PGC, isa8_pgc_device, "isa_ibm_pgc", "IBM Professional G
|
||||
MACHINE_CONFIG_START(isa8_pgc_device::device_add_mconfig)
|
||||
MCFG_CPU_ADD("maincpu", I8088, XTAL(24'000'000)/3)
|
||||
MCFG_CPU_PROGRAM_MAP(pgc_map)
|
||||
MCFG_CPU_IO_MAP(pgc_io)
|
||||
#if 0
|
||||
MCFG_CPU_VBLANK_INT_DRIVER(PGC_SCREEN_NAME, isa8_pgc_device, vblank_irq)
|
||||
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(isa8_pgc_device, irq_callback)
|
||||
@ -182,7 +180,7 @@ MACHINE_CONFIG_END
|
||||
|
||||
const tiny_rom_entry *isa8_pgc_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( pgc );
|
||||
return ROM_NAME(pgc);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -191,7 +189,7 @@ const tiny_rom_entry *isa8_pgc_device::device_rom_region() const
|
||||
|
||||
ioport_constructor isa8_pgc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( pgc );
|
||||
return INPUT_PORTS_NAME(pgc);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -219,7 +217,6 @@ isa8_pgc_device::isa8_pgc_device(const machine_config &mconfig, device_type type
|
||||
|
||||
void isa8_pgc_device::device_start()
|
||||
{
|
||||
address_space &space = m_cpu->space( AS_PROGRAM );
|
||||
int width = PGC_DISP_HORZ;
|
||||
int height = PGC_DISP_VERT;
|
||||
|
||||
@ -228,18 +225,15 @@ void isa8_pgc_device::device_start()
|
||||
|
||||
set_isa_device();
|
||||
|
||||
for (int i = 0; i < 256; i++ )
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
m_palette->set_pen_color( i, 0, 0, 0 );
|
||||
m_palette->set_pen_color(i, 0, 0, 0);
|
||||
}
|
||||
|
||||
m_bitmap = std::make_unique<bitmap_ind16>(width, height);
|
||||
m_bitmap->fill(0);
|
||||
|
||||
m_vram = std::make_unique<uint8_t[]>(0x78000);
|
||||
space.install_readwrite_bank(0x80000, 0xf7fff, "vram");
|
||||
membank("vram")->set_base(m_vram.get());
|
||||
|
||||
m_eram = std::make_unique<uint8_t[]>(0x8000);
|
||||
|
||||
machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&isa8_pgc_device::reset_common, this));
|
||||
@ -247,7 +241,7 @@ void isa8_pgc_device::device_start()
|
||||
|
||||
void isa8_pgc_device::reset_common()
|
||||
{
|
||||
address_space &space = m_cpu->space( AS_PROGRAM );
|
||||
address_space &space = m_cpu->space(AS_PROGRAM);
|
||||
|
||||
space.unmap_readwrite(0xf8000, 0xfffff);
|
||||
space.install_rom(0xf8000, 0xfffff, memregion("maincpu")->base() + 0x8000);
|
||||
@ -257,6 +251,7 @@ void isa8_pgc_device::device_reset()
|
||||
{
|
||||
memset(m_stateparam, 0, sizeof(m_stateparam));
|
||||
memset(m_lut, 0, sizeof(m_lut));
|
||||
m_accel = 0;
|
||||
|
||||
m_commarea = memregion("commarea")->base();
|
||||
if (BIT(ioport("DSW")->read(), 1))
|
||||
@ -269,61 +264,135 @@ void isa8_pgc_device::device_reset()
|
||||
|
||||
INTERRUPT_GEN_MEMBER(isa8_pgc_device::vblank_irq)
|
||||
{
|
||||
DBG_LOG(2,"irq",("vblank_irq\n"));
|
||||
LOGCMD("vblank_irq\n");
|
||||
m_cpu->set_input_line(0, ASSERT_LINE);
|
||||
}
|
||||
|
||||
IRQ_CALLBACK_MEMBER(isa8_pgc_device::irq_callback)
|
||||
{
|
||||
DBG_LOG(2,"irq",("irq_callback\n"));
|
||||
LOGCMD("irq_callback\n");
|
||||
m_cpu->set_input_line(0, CLEAR_LINE);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// memory handlers
|
||||
|
||||
READ8_MEMBER( isa8_pgc_device::stateparam_r ) {
|
||||
READ8_MEMBER(isa8_pgc_device::vram_r)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = m_vram[offset];
|
||||
LOGV("vram R @ %02x == %02x\n", offset, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* accel modes (decimal)
|
||||
*
|
||||
* 0 - none
|
||||
* 1 - write 4 pixels, starting at offset
|
||||
* 2 - write up to 4 pixels, ending at offset
|
||||
* 3 - write up to 4 pixels, starting at offset
|
||||
* 5 - write 20 pixels, starting at offset
|
||||
* 9 - write up to 5 pixel groups, ending at offset. offset may be in the middle of pixel group.
|
||||
* 13 - write up to 5 pixel groups, starting at offset.
|
||||
*/
|
||||
WRITE8_MEMBER(isa8_pgc_device::vram_w)
|
||||
{
|
||||
bool handled = true;
|
||||
|
||||
switch (m_accel)
|
||||
{
|
||||
case 0:
|
||||
m_vram[offset] = data;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
std::fill(&m_vram[offset], &m_vram[offset + 4], data);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
std::fill(&m_vram[offset & ~3], &m_vram[offset + 1], data);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
std::fill(&m_vram[offset], &m_vram[(offset + 4) & ~3], data);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
std::fill(&m_vram[offset], &m_vram[offset + 20], data);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
std::fill(&m_vram[offset - ((offset % 1024) % 20)], &m_vram[(offset + 4) & ~3], data);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
std::fill(&m_vram[offset], &m_vram[(offset + 20) - ((offset % 1024) + 20) % 20], data);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_vram[offset] = data;
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
LOGV("vram W @ %02x <- %02x (accel %d)%s\n", offset, data, m_accel,
|
||||
handled ? "" : " (unsupported)");
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(isa8_pgc_device::accel_w)
|
||||
{
|
||||
m_accel = offset >> 1;
|
||||
LOGV("accel @ %05x <- %02x (%d)\n", 0x32020 + offset, data, m_accel);
|
||||
}
|
||||
|
||||
READ8_MEMBER(isa8_pgc_device::stateparam_r)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = m_stateparam[offset >> 1];
|
||||
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
|
||||
{
|
||||
DBG_LOG(1,"stateparam",("R @ %02x == %02x\n", offset, ret));
|
||||
LOG("stateparam R @ %02x == %02x\n", offset, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( isa8_pgc_device::stateparam_w ) {
|
||||
WRITE8_MEMBER(isa8_pgc_device::stateparam_w)
|
||||
{
|
||||
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
|
||||
{
|
||||
DBG_LOG(1,"stateparam",("W @ %02x <- %02x\n", offset, data));
|
||||
LOG("stateparam W @ %02x <- %02x\n", offset, data);
|
||||
}
|
||||
m_stateparam[offset >> 1] = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( isa8_pgc_device::lut_w ) {
|
||||
WRITE8_MEMBER(isa8_pgc_device::lut_w)
|
||||
{
|
||||
uint8_t o = (offset >> 1) * 3;
|
||||
|
||||
if (offset & 1) {
|
||||
if (offset & 1)
|
||||
{
|
||||
m_lut[o + 2] = (data & 15) << 4;
|
||||
m_palette->set_pen_color( offset >> 1, m_lut[o], m_lut[o + 1], m_lut[o + 2] );
|
||||
DBG_LOG(1,"lut",("W @ %02X <- %d %d %d\n",
|
||||
offset >> 1, m_lut[o], m_lut[o + 1], m_lut[o + 2] ));
|
||||
LOG("lut W @ %02X <- %d %d %d\n",
|
||||
offset >> 1, m_lut[o], m_lut[o + 1], m_lut[o + 2] );
|
||||
} else {
|
||||
m_lut[o ] = data & 0xf0;
|
||||
m_lut[o + 1] = (data & 15) << 4;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( isa8_pgc_device::init_r ) {
|
||||
DBG_LOG(1,"INIT",("unmapping ROM\n"));
|
||||
READ8_MEMBER(isa8_pgc_device::init_r)
|
||||
{
|
||||
LOG("INIT: unmapping ROM\n");
|
||||
space.unmap_read(0xf8000, 0xfffff);
|
||||
|
||||
DBG_LOG(1,"INIT",("mapping emulator RAM\n"));
|
||||
LOG("INIT: mapping emulator RAM\n");
|
||||
space.install_readwrite_bank(0xf8000, 0xfffff, "eram");
|
||||
membank("eram")->set_base(m_eram.get());
|
||||
|
||||
DBG_LOG(1,"INIT",("mapping LUT\n"));
|
||||
LOG("INIT: mapping LUT\n");
|
||||
space.install_write_handler(0xf8400, 0xf85ff,
|
||||
write8_delegate(FUNC(isa8_pgc_device::lut_w), this));
|
||||
|
||||
@ -337,9 +406,8 @@ TIMER_DEVICE_CALLBACK_MEMBER(isa8_pgc_device::scanline_callback)
|
||||
uint8_t *v;
|
||||
|
||||
// XXX hpos shifts every frame -- fix
|
||||
if (y == 0) DBG_LOG(2,"scanline_cb",
|
||||
("frame %d x %.4d y %.3d\n",
|
||||
(int) m_screen->frame_number(), m_screen->hpos(), y));
|
||||
if (y == 0) LOGCMD("scanline_cb frame %d x %.4d y %.3d\n",
|
||||
(int) m_screen->frame_number(), m_screen->hpos(), y);
|
||||
|
||||
if (y < PGC_VERT_START) return;
|
||||
y -= PGC_VERT_START;
|
||||
@ -349,7 +417,8 @@ TIMER_DEVICE_CALLBACK_MEMBER(isa8_pgc_device::scanline_callback)
|
||||
v = &m_vram[y * 1024];
|
||||
p = &m_bitmap->pix16(y, 0);
|
||||
|
||||
for (x = 0; x < PGC_DISP_HORZ; x++) {
|
||||
for (x = 0; x < PGC_DISP_HORZ; x++)
|
||||
{
|
||||
*p++ = *v++;
|
||||
}
|
||||
}
|
||||
|
@ -40,15 +40,18 @@ protected:
|
||||
private:
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER( scanline_callback );
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback);
|
||||
|
||||
INTERRUPT_GEN_MEMBER(vblank_irq);
|
||||
IRQ_CALLBACK_MEMBER(irq_callback);
|
||||
|
||||
DECLARE_WRITE8_MEMBER( stateparam_w );
|
||||
DECLARE_READ8_MEMBER( stateparam_r );
|
||||
DECLARE_WRITE8_MEMBER( lut_w );
|
||||
DECLARE_READ8_MEMBER( init_r );
|
||||
DECLARE_WRITE8_MEMBER(vram_w);
|
||||
DECLARE_READ8_MEMBER(vram_r);
|
||||
DECLARE_WRITE8_MEMBER(stateparam_w);
|
||||
DECLARE_READ8_MEMBER(stateparam_r);
|
||||
DECLARE_WRITE8_MEMBER(lut_w);
|
||||
DECLARE_READ8_MEMBER(init_r);
|
||||
DECLARE_WRITE8_MEMBER(accel_w);
|
||||
|
||||
void reset_common();
|
||||
|
||||
@ -63,8 +66,9 @@ private:
|
||||
std::unique_ptr<uint8_t[]> m_vram;
|
||||
std::unique_ptr<uint8_t[]> m_eram;
|
||||
uint8_t m_stateparam[16];
|
||||
uint8_t m_lut[256*3];
|
||||
uint8_t m_lut[256 * 3];
|
||||
std::unique_ptr<bitmap_ind16> m_bitmap;
|
||||
int m_accel;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user