mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
isa_ibm_pgc: new skeleton driver
This commit is contained in:
parent
00a276f7d1
commit
b7f4c082e6
@ -779,6 +779,8 @@ if (BUSES["ISA"]~=null) then
|
||||
MAME_DIR .. "src/emu/bus/isa/svga_cirrus.h",
|
||||
MAME_DIR .. "src/emu/bus/isa/ega.c",
|
||||
MAME_DIR .. "src/emu/bus/isa/ega.h",
|
||||
MAME_DIR .. "src/emu/bus/isa/pgc.c",
|
||||
MAME_DIR .. "src/emu/bus/isa/pgc.h",
|
||||
MAME_DIR .. "src/emu/bus/isa/vga.c",
|
||||
MAME_DIR .. "src/emu/bus/isa/vga.h",
|
||||
MAME_DIR .. "src/emu/bus/isa/vga_ati.c",
|
||||
|
@ -18,6 +18,7 @@ SLOT_INTERFACE_START( pc_isa8_cards )
|
||||
SLOT_INTERFACE("aga", ISA8_AGA)
|
||||
SLOT_INTERFACE("aga_pc200", ISA8_AGA_PC200)
|
||||
SLOT_INTERFACE("ega", ISA8_EGA)
|
||||
SLOT_INTERFACE("pgc", ISA8_PGC)
|
||||
SLOT_INTERFACE("svga_et4k", ISA8_SVGA_ET4K)
|
||||
SLOT_INTERFACE("num9rev",ISA8_NUM_9_REV)
|
||||
SLOT_INTERFACE("com", ISA8_COM)
|
||||
@ -55,6 +56,7 @@ SLOT_INTERFACE_START( pc_isa16_cards )
|
||||
SLOT_INTERFACE("cga", ISA8_CGA)
|
||||
SLOT_INTERFACE("wyse700", ISA8_WYSE700)
|
||||
SLOT_INTERFACE("ega", ISA8_EGA)
|
||||
SLOT_INTERFACE("pgc", ISA8_PGC)
|
||||
SLOT_INTERFACE("vga", ISA8_VGA)
|
||||
SLOT_INTERFACE("svga_et4k", ISA8_SVGA_ET4K)
|
||||
SLOT_INTERFACE("num9rev",ISA8_NUM_9_REV)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "cga.h"
|
||||
#include "aga.h"
|
||||
#include "ega.h"
|
||||
#include "pgc.h"
|
||||
#include "vga.h"
|
||||
#include "vga_ati.h"
|
||||
#include "svga_cirrus.h"
|
||||
|
372
src/emu/bus/isa/pgc.c
Normal file
372
src/emu/bus/isa/pgc.c
Normal file
@ -0,0 +1,372 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
IBM Professional Graphics Controller (PGC), skeleton driver.
|
||||
|
||||
Designed for IBM by Vermont Microsystems. References:
|
||||
|
||||
IBM Options and Adapters manual
|
||||
http://www.minuszerodegrees.net/oa/OA%20-%20IBM%20Professional%20Graphics%20Controller.pdf
|
||||
http://bitsavers.org/pdf/ibm/pc/cards/Technical_Reference_Options_and_Adapters_Volume_3.pdf
|
||||
IBM Systems Journal white paper
|
||||
http://wayback.archive.org/web/20061015235146/http://www.research.ibm.com/journal/sj/241/ibmsj2401D.pdf
|
||||
John Elliott's page
|
||||
http://www.seasip.info/VintagePC/pgc.html
|
||||
|
||||
To do:
|
||||
- memory map (restore ROM mapping on reset, ...)
|
||||
- various VRAM write modes
|
||||
- what's up with irq 3 (= vblank irq)?
|
||||
- "test pin of the microprocessor samples the hsync pulse"
|
||||
- CGA emulator
|
||||
- bus state handling?
|
||||
- VRAM address translator ROM?
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
//nclude "machine/ram.h"
|
||||
|
||||
#include "pgc.h"
|
||||
|
||||
#define VERBOSE_PGC 1
|
||||
|
||||
#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"
|
||||
|
||||
#define PGC_TOTAL_HORZ 820
|
||||
#define PGC_DISP_HORZ 640
|
||||
#define PGC_HORZ_START 80
|
||||
|
||||
#define PGC_TOTAL_VERT 508
|
||||
#define PGC_DISP_VERT 480
|
||||
#define PGC_VERT_START 10
|
||||
|
||||
/*
|
||||
Prototypes
|
||||
*/
|
||||
|
||||
ROM_START( pgc )
|
||||
ROM_REGION(0x100000, "maincpu", 0)
|
||||
ROM_DEFAULT_BIOS("1985")
|
||||
|
||||
ROM_SYSTEM_BIOS(0, "1984", "1984 firmware, P/N 6137322/3")
|
||||
ROMX_LOAD("ibm_6137323_pgc_card_27256.bin", 0x00000, 0x8000, CRC(f564f342) SHA1(c5ef17fd1569043cb59f61faf828ea8b0ee95526), ROM_BIOS(1))
|
||||
ROMX_LOAD("ibm_6137322_pgc_card_27256.bin", 0x08000, 0x8000, CRC(5e6cc82f) SHA1(45b3ffb5a9c51986862f8d47b3e03dcaaf4073d5), ROM_BIOS(1))
|
||||
|
||||
ROM_SYSTEM_BIOS(1, "1985", "1985 firmware, P/N 59X7354/5")
|
||||
ROMX_LOAD("pgc_u44.bin", 0x00000, 0x8000, CRC(71280241) SHA1(7042ccd4ebd03f576a256a433b8aa38d1b4fefa8), ROM_BIOS(2))
|
||||
ROMX_LOAD("pgc_u43.bin", 0x08000, 0x8000, CRC(923f5ea3) SHA1(2b2a55d64b20d3a613b00c51443105aa03eca5d6), ROM_BIOS(2))
|
||||
|
||||
ROM_REGION(0x800, "commarea", ROMREGION_ERASE00)
|
||||
|
||||
ROM_REGION(0x1000, "chargen", 0)
|
||||
ROM_LOAD("pgc_u27.bin", 0x0000, 0x1000, CRC(6be256cc) SHA1(deb1195886268dcddce10459911e020f7a9f74f7))
|
||||
ROM_END
|
||||
|
||||
static INPUT_PORTS_START( pgc )
|
||||
PORT_START("DSW")
|
||||
/*
|
||||
PORT_DIPNAME( 0x01, 0x00, "CGA emulator")
|
||||
PORT_DIPSETTING( 0x00, DEF_STR(No) )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR(Yes) )
|
||||
*/
|
||||
PORT_DIPNAME( 0x02, 0x00, "Communication area")
|
||||
PORT_DIPSETTING( 0x00, "C6000" )
|
||||
PORT_DIPSETTING( 0x02, "C6400" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/*
|
||||
write only
|
||||
30000 LUT WR O L
|
||||
30001 LUT WR I L
|
||||
32000 MODE WT L
|
||||
32001 NIBBLE WT L
|
||||
3200A ??
|
||||
34000 FUNCTION WT L
|
||||
34001 STARTADD WT L
|
||||
36001 CURSOR WT L
|
||||
|
||||
read only
|
||||
38000 LUT RD O L
|
||||
38001 LUT RD I L
|
||||
3C001 INIT L/INIT H
|
||||
*/
|
||||
|
||||
static ADDRESS_MAP_START( pgc_map, AS_PROGRAM, 8, isa8_pgc_device )
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x00000, 0x07fff) AM_ROM
|
||||
AM_RANGE(0x08000, 0x0ffff) AM_ROM AM_REGION("maincpu", 0x8000)
|
||||
AM_RANGE(0x10000, 0x1001f) AM_READWRITE(stateparam_r, stateparam_w)
|
||||
// AM_RANGE(0x18000, 0x18fff) AM_RAM // ??
|
||||
AM_RANGE(0x28000, 0x287ff) AM_RAM AM_REGION("commarea", 0) AM_MIRROR(0x800)
|
||||
AM_RANGE(0x3c000, 0x3c001) AM_READ(init_r)
|
||||
// AM_RANGE(0x3e000, 0x3efff) AM_RAM // ??
|
||||
AM_RANGE(0xf8000, 0xfffff) AM_ROM AM_REGION("maincpu", 0x8000)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( pgc_io, AS_IO, 8, isa8_pgc_device )
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static const gfx_layout pgc_charlayout =
|
||||
{
|
||||
8, 16, /* 8x16 pixels */
|
||||
256, /* 256 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
/* y offsets */
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
|
||||
8*16 /* every char takes 10 bytes */
|
||||
};
|
||||
|
||||
static GFXDECODE_START( pgc )
|
||||
GFXDECODE_REVERSEBITS("chargen", 0, pgc_charlayout, 0, 1)
|
||||
GFXDECODE_END
|
||||
|
||||
MACHINE_CONFIG_FRAGMENT( pcvideo_pgc )
|
||||
MCFG_CPU_ADD("maincpu", I8088, XTAL_24MHz/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)
|
||||
#endif
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("scantimer", isa8_pgc_device, scanline_callback,
|
||||
attotime::from_hz(60*PGC_TOTAL_VERT))
|
||||
MCFG_TIMER_START_DELAY(attotime::from_hz(XTAL_50MHz/(2*PGC_HORZ_START)))
|
||||
|
||||
MCFG_SCREEN_ADD(PGC_SCREEN_NAME, RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS(XTAL_50MHz/2,
|
||||
PGC_TOTAL_HORZ, PGC_HORZ_START, PGC_HORZ_START+PGC_DISP_HORZ,
|
||||
PGC_TOTAL_VERT, PGC_VERT_START, PGC_VERT_START+PGC_DISP_VERT)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(isa8_pgc_device, screen_update)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", pgc)
|
||||
MCFG_PALETTE_ADD( "palette", 256 )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type ISA8_PGC = &device_creator<isa8_pgc_device>;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor isa8_pgc_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( pcvideo_pgc );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
const rom_entry *isa8_pgc_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( pgc );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
ioport_constructor isa8_pgc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( pgc );
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// isa8_pgc_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
isa8_pgc_device::isa8_pgc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, ISA8_PGC, "IBM Professional Graphics Controller", tag, owner, clock, "isa_ibm_pgc", __FILE__),
|
||||
device_isa8_card_interface(mconfig, *this),
|
||||
m_cpu(*this, "maincpu"),
|
||||
m_screen(*this, PGC_SCREEN_NAME),
|
||||
m_palette(*this, "palette")
|
||||
{
|
||||
}
|
||||
|
||||
isa8_pgc_device::isa8_pgc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
|
||||
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_isa8_card_interface(mconfig, *this),
|
||||
m_cpu(*this, "maincpu"),
|
||||
m_screen(*this, PGC_SCREEN_NAME),
|
||||
m_palette(*this, "palette")
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void isa8_pgc_device::device_start()
|
||||
{
|
||||
address_space &space = m_cpu->space( AS_PROGRAM );
|
||||
int width = PGC_DISP_HORZ;
|
||||
int height = PGC_DISP_VERT;
|
||||
|
||||
if (m_palette != NULL && !m_palette->started())
|
||||
throw device_missing_dependencies();
|
||||
|
||||
set_isa_device();
|
||||
|
||||
for (int i = 0; i < 256; i++ )
|
||||
{
|
||||
m_palette->set_pen_color( i, 0, 0, 0 );
|
||||
}
|
||||
|
||||
m_bitmap = auto_bitmap_ind16_alloc(machine(), width, height);
|
||||
m_bitmap->fill(0);
|
||||
|
||||
m_vram = auto_alloc_array(machine(), UINT8, 0x78000);
|
||||
space.install_readwrite_bank(0x80000, 0xf7fff, "vram");
|
||||
membank("vram")->set_base(m_vram);
|
||||
|
||||
m_eram = auto_alloc_array(machine(), UINT8, 0x8000);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void isa8_pgc_device::device_reset()
|
||||
{
|
||||
address_space &space = m_cpu->space( AS_PROGRAM );
|
||||
|
||||
memset(m_stateparam, 0, sizeof(m_stateparam));
|
||||
memset(m_lut, 0, sizeof(m_lut));
|
||||
|
||||
m_commarea = memregion("commarea")->base();
|
||||
if (BIT(ioport("DSW")->read(), 1))
|
||||
m_isa->install_bank(0xc6400, 0xc67ff, 0, 0, "commarea", m_commarea);
|
||||
else
|
||||
m_isa->install_bank(0xc6000, 0xc63ff, 0, 0, "commarea", m_commarea);
|
||||
#if 0
|
||||
space.unmap_readwrite(0xf8000, 0xfffff);
|
||||
space.install_rom(0xf8000, 0xfffff,
|
||||
space.machine().root_device().memregion("maincpu")->base() + 0x8000);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
INTERRUPT_GEN_MEMBER(isa8_pgc_device::vblank_irq)
|
||||
{
|
||||
DBG_LOG(2,"irq",("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"));
|
||||
m_cpu->set_input_line(0, CLEAR_LINE);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// memory handlers
|
||||
|
||||
READ8_MEMBER( isa8_pgc_device::stateparam_r ) {
|
||||
UINT8 ret;
|
||||
|
||||
ret = m_stateparam[offset >> 1];
|
||||
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
|
||||
{
|
||||
DBG_LOG(1,"stateparam",("R @ %02x == %02x\n", offset, ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
m_stateparam[offset >> 1] = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( isa8_pgc_device::lut_w ) {
|
||||
UINT8 o = (offset >> 1) * 3;
|
||||
|
||||
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] ));
|
||||
} 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"));
|
||||
space.unmap_read(0xf8000, 0xfffff);
|
||||
|
||||
DBG_LOG(1,"INIT",("mapping emulator RAM\n"));
|
||||
space.install_readwrite_bank(0xf8000, 0xfffff, "eram");
|
||||
membank("eram")->set_base(m_eram);
|
||||
|
||||
DBG_LOG(1,"INIT",("mapping LUT\n"));
|
||||
space.install_write_handler(0xf8400, 0xf85ff,
|
||||
write8_delegate(FUNC(isa8_pgc_device::lut_w), this));
|
||||
|
||||
return 0; // XXX ignored
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(isa8_pgc_device::scanline_callback)
|
||||
{
|
||||
UINT16 x, y = m_screen->vpos();
|
||||
UINT16 *p;
|
||||
UINT8 *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 < PGC_VERT_START) return;
|
||||
y -= PGC_VERT_START;
|
||||
if (y >= PGC_DISP_VERT) return;
|
||||
|
||||
// XXX address translation happens in hardware
|
||||
v = &m_vram[y * 1024];
|
||||
p = &m_bitmap->pix16(y, 0);
|
||||
|
||||
for (x = 0; x < PGC_DISP_HORZ; x++) {
|
||||
*p++ = *v++;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 isa8_pgc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, *m_bitmap, 0, 0, PGC_HORZ_START, PGC_VERT_START, cliprect);
|
||||
return 0;
|
||||
}
|
67
src/emu/bus/isa/pgc.h
Normal file
67
src/emu/bus/isa/pgc.h
Normal file
@ -0,0 +1,67 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ISA_PGC_H__
|
||||
#define __ISA_PGC_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "isa.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> isa8_pgc_device
|
||||
|
||||
class isa8_pgc_device :
|
||||
public device_t,
|
||||
public device_isa8_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
isa8_pgc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
isa8_pgc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
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 );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
private:
|
||||
required_device<i8088_cpu_device> m_cpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
UINT8 *m_commarea;
|
||||
UINT8 *m_vram;
|
||||
UINT8 *m_eram;
|
||||
UINT8 m_stateparam[16];
|
||||
UINT8 m_lut[256*3];
|
||||
bitmap_ind16 *m_bitmap;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type ISA8_PGC;
|
||||
|
||||
#endif /* __ISA_PGC_H__ */
|
Loading…
Reference in New Issue
Block a user