mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
video/pc_vga_matrox.cpp: add screen extension bit hook ups
video/mga2064w.cpp: translate alias space to 32-bits
This commit is contained in:
parent
0268ef195e
commit
2dccaba3b4
@ -22,7 +22,7 @@ mga2064w_device::mga2064w_device(const machine_config &mconfig, const char *tag,
|
||||
, m_vga_rom(*this, "vga_rom")
|
||||
{
|
||||
set_ids(0x102b0519, 0x01, 0x030000, 0x00000000);
|
||||
m_mgabase1_real_space_config = address_space_config("mgabase1_regs", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(mga2064w_device::mgabase1_map), this));
|
||||
m_mgabase1_real_space_config = address_space_config("mgabase1_regs", ENDIANNESS_LITTLE, 32, 14, 0, address_map_constructor(FUNC(mga2064w_device::mgabase1_map), this));
|
||||
}
|
||||
|
||||
ROM_START( mga2064w )
|
||||
@ -128,8 +128,8 @@ void mga2064w_device::mgabase1_map(address_map &map)
|
||||
// map(0x1cc0, 0x1cff) DR0-DR15 (DR1-5-9-13 <reserved>)
|
||||
|
||||
// map(0x1e00, 0x1eff) HSTREG Host registers
|
||||
// map(0x1e10, 0x1e13) FIFOSTATUS (r/o)
|
||||
// map(0x1e14, 0x1e17) Status (r/o)
|
||||
map(0x1e10, 0x1e13).r(FUNC(mga2064w_device::fifo_status_r));
|
||||
map(0x1e14, 0x1e17).r(FUNC(mga2064w_device::status_r));
|
||||
// map(0x1e18, 0x1e1b) ICLEAR
|
||||
// map(0x1e1c, 0x1e1f) IEN
|
||||
// map(0x1e20, 0x1e23) VCOUNT (r/o)
|
||||
@ -146,6 +146,32 @@ void mga2064w_device::mgabase2_map(address_map &map)
|
||||
map(0x000000, 0x7fffff).rw(m_svga, FUNC(matrox_vga_device::mem_linear_r), FUNC(matrox_vga_device::mem_linear_w));
|
||||
}
|
||||
|
||||
/*
|
||||
* MGABASE1 + 1e10h FIFO Status (r/o)
|
||||
*
|
||||
* ---- -x-- ---- ---- BEMPTY Bus FIFO empty
|
||||
* ---- --x- ---- ---- BFULL Bus FIFO full
|
||||
* ---- ---- ---x xxxx FIFOCOUNT free locations in FIFO (max: 32)
|
||||
*/
|
||||
u32 mga2064w_device::fifo_status_r()
|
||||
{
|
||||
return (1 << 9) | 32;
|
||||
}
|
||||
|
||||
/*
|
||||
* MGABASE1 + 1e14h Status (r/o)
|
||||
*
|
||||
* ---- ---- ---- ---x ---- ---- ---- ---- DWGENGSTS
|
||||
* ---- ---- ---- ---- ---- ---- -x-- ---- EXTPEN
|
||||
* ---- ---- ---- ---- ---- ---- --x- ---- VLINEPEN
|
||||
* ---- ---- ---- ---- ---- ---- ---x ---- VSYNCPEN
|
||||
* ---- ---- ---- ---- ---- ---- ---- x--- VSYNCSTS
|
||||
* ---- ---- ---- ---- ---- ---- ---- -x-- PICKPEN
|
||||
*/
|
||||
u32 mga2064w_device::status_r()
|
||||
{
|
||||
return m_svga->vsync_status() << 3;
|
||||
}
|
||||
|
||||
// TODO: this should really be a subclass of VGA
|
||||
void mga2064w_device::legacy_memory_map(address_map &map)
|
||||
@ -153,7 +179,6 @@ void mga2064w_device::legacy_memory_map(address_map &map)
|
||||
map(0xa0000, 0xbffff).rw(FUNC(mga2064w_device::vram_r), FUNC(mga2064w_device::vram_w));
|
||||
}
|
||||
|
||||
// TODO: card may not even support MDA access
|
||||
void mga2064w_device::legacy_io_map(address_map &map)
|
||||
{
|
||||
map(0, 0x02f).m(m_svga, FUNC(matrox_vga_device::io_map));
|
||||
@ -201,12 +226,12 @@ void mga2064w_device::mga_index_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
m_mgabase1_real_index &= 0x3ffc;
|
||||
}
|
||||
|
||||
u8 mga2064w_device::mga_data_r(offs_t offset)
|
||||
u32 mga2064w_device::mga_data_r(offs_t offset, u32 mem_mask)
|
||||
{
|
||||
return space(AS_IO).read_byte(offset + m_mgabase1_real_index);
|
||||
return space(AS_IO).read_dword(m_mgabase1_real_index, mem_mask);
|
||||
}
|
||||
|
||||
void mga2064w_device::mga_data_w(offs_t offset, u8 data)
|
||||
void mga2064w_device::mga_data_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
space(AS_IO).write_byte(offset + m_mgabase1_real_index, data);
|
||||
space(AS_IO).write_dword(m_mgabase1_real_index, data, mem_mask);
|
||||
}
|
||||
|
@ -40,10 +40,12 @@ private:
|
||||
address_space_config m_mgabase1_real_space_config;
|
||||
u32 mga_index_r();
|
||||
void mga_index_w(offs_t offset, u32 data, u32 mem_mask = ~0);
|
||||
u8 mga_data_r(offs_t offset);
|
||||
void mga_data_w(offs_t offset, u8 data);
|
||||
|
||||
u32 mga_data_r(offs_t offset, u32 mem_mask = ~0);
|
||||
void mga_data_w(offs_t offset, u32 data, u32 mem_mask = ~0);
|
||||
u32 m_mgabase1_real_index = 0;
|
||||
|
||||
u32 status_r();
|
||||
u32 fifo_status_r();
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(MGA2064W, mga2064w_device);
|
||||
|
@ -1327,7 +1327,8 @@ void vga_device::vga_vh_ega(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: I'm guessing that in 256 colors mode every pixel actually outputs two pixels. Is it right? */
|
||||
// In mode 13h (256 colors) every pixel actually double height/width
|
||||
// i.e. a 320x200 is really 640x400
|
||||
void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1);
|
||||
@ -1335,6 +1336,7 @@ void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
int addrmask = vga.crtc.no_wrap ? -1 : 0xffff;
|
||||
|
||||
/* line compare is screen sensitive */
|
||||
// FIXME: some clients extends line compare with bit 10
|
||||
uint16_t mask_comp = 0x3ff; //| (LINES & 0x300);
|
||||
|
||||
// popmessage("%02x %02x",vga.attribute.pel_shift,vga.sequencer.data[4] & 0x08);
|
||||
@ -1806,7 +1808,8 @@ void svga_device::svga_vh_rgb8(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1);
|
||||
|
||||
/* line compare is screen sensitive */
|
||||
uint16_t mask_comp = 0x3ff;
|
||||
// FIXME: some clients extends line compare with bit 10
|
||||
uint16_t mask_comp = 0x3ff;
|
||||
int curr_addr = 0;
|
||||
// uint16_t line_length;
|
||||
// if(vga.crtc.dw)
|
||||
|
@ -31,7 +31,9 @@ void matrox_vga_device::device_reset()
|
||||
|
||||
m_crtcext_index = 0;
|
||||
m_crtcext_misc = 0;
|
||||
m_crtcext_horz_counter = 0;
|
||||
m_mgamode = false;
|
||||
m_interlace_mode = false;
|
||||
m_truecolor_ctrl = 0x80;
|
||||
m_multiplex_ctrl = 0x98;
|
||||
}
|
||||
@ -60,11 +62,11 @@ void matrox_vga_device::io_3bx_3dx_map(address_map &map)
|
||||
// "CRTCEXT*"
|
||||
void matrox_vga_device::crtcext_map(address_map &map)
|
||||
{
|
||||
// map(0x00, 0x00) Address Generator Extensions
|
||||
// map(0x01, 0x01) Horizontal Counter Extensions
|
||||
// map(0x02, 0x02) Vertical Counter Extensions
|
||||
map(0x00, 0x00).rw(FUNC(matrox_vga_device::crtcext0_address_gen_r), FUNC(matrox_vga_device::crtcext0_address_gen_w));
|
||||
map(0x01, 0x01).rw(FUNC(matrox_vga_device::crtcext1_horizontal_counter_r), FUNC(matrox_vga_device::crtcext1_horizontal_counter_w));
|
||||
map(0x02, 0x02).rw(FUNC(matrox_vga_device::crtcext2_vertical_counter_r), FUNC(matrox_vga_device::crtcext2_vertical_counter_w));
|
||||
map(0x03, 0x03).rw(FUNC(matrox_vga_device::crtcext3_misc_r), FUNC(matrox_vga_device::crtcext3_misc_w));
|
||||
// CRTCEXT4 Memory Page register
|
||||
// CRTCEXT4 Memory Page register
|
||||
map(0x04, 0x04).lrw8(
|
||||
NAME([this] (offs_t offset) { return svga.bank_w & 0x7f; }),
|
||||
NAME([this] (offs_t offset, u8 data) { svga.bank_w = data & 0x7f; })
|
||||
@ -75,6 +77,87 @@ void matrox_vga_device::crtcext_map(address_map &map)
|
||||
// seems to disable SVGA drawing -> diagnostic check?
|
||||
}
|
||||
|
||||
/*
|
||||
* CRTCEXT0 Address Generator extensions
|
||||
*
|
||||
* x--- ---- Interlace mode
|
||||
* --xx ---- Offset bits 9-8
|
||||
* ---- xxxx Start Address bits 19-16
|
||||
*/
|
||||
u8 matrox_vga_device::crtcext0_address_gen_r()
|
||||
{
|
||||
u8 res = ((vga.crtc.start_addr >> 16) & 0xf);
|
||||
res |= ((vga.crtc.offset >> 8) & 3) << 4;
|
||||
res |= (m_interlace_mode) << 7;
|
||||
return res;
|
||||
}
|
||||
|
||||
void matrox_vga_device::crtcext0_address_gen_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_interlace_mode = bool(BIT(data, 7));
|
||||
vga.crtc.offset = (vga.crtc.offset & 0xff) | ((data & 0x30) << 4);
|
||||
vga.crtc.start_addr = (vga.crtc.start_addr & 0xffff) | ((data & 0xf) << 16);
|
||||
if (m_interlace_mode)
|
||||
popmessage("MGA2064W: interlace mode enable");
|
||||
// recompute_params();
|
||||
}
|
||||
|
||||
/*
|
||||
* CRTCEXT1 Horizontal Counter Extensions
|
||||
*
|
||||
* x--- ---- VRSTEN Vertical reset enable
|
||||
* -x-- ---- HBLKEND Horizontal end blank bit 6 (MGA mode only)
|
||||
* --x- ---- VSYNCOFF
|
||||
* ---x ---- HSYNCOFF
|
||||
* ---- x--- HRSTEN Horizontal reset enable
|
||||
* ---- -x-- HSYNCSTR horizontal retrace start bit 8
|
||||
* ---- --x- HBLKSTR horizontal blanking start bit 8
|
||||
* ---- ---x HTOTAL bit 8
|
||||
*/
|
||||
u8 matrox_vga_device::crtcext1_horizontal_counter_r()
|
||||
{
|
||||
return m_crtcext_horz_counter;
|
||||
}
|
||||
|
||||
void matrox_vga_device::crtcext1_horizontal_counter_w(offs_t offset, u8 data)
|
||||
{
|
||||
// TODO: honor CRTC protect enable
|
||||
m_crtcext_horz_counter = data;
|
||||
vga.crtc.horz_total = (vga.crtc.horz_total & 0xff) | (BIT(data, 0) << 8);
|
||||
vga.crtc.horz_blank_start = (vga.crtc.horz_blank_start & 0xff) | (BIT(data, 1) << 8);
|
||||
vga.crtc.horz_retrace_start = (vga.crtc.horz_retrace_start & 0xff) | (BIT(data, 2) << 8);
|
||||
vga.crtc.horz_blank_end = (vga.crtc.horz_blank_end & 0x3f) | (BIT(data, 6) << 6);
|
||||
|
||||
logerror("MGA2064W: CRTCEXT1 reset enable %02x syncoff %02x\n",data & 0x88, data & 0x30);
|
||||
recompute_params();
|
||||
}
|
||||
|
||||
/*
|
||||
* CRTCEXT1 Vertical Counter Extensions
|
||||
*
|
||||
* x--- ---- LINECOMP Line compare bit 10
|
||||
* -xx- ---- VSYNCSTR Vertical retrace start bits 11-10
|
||||
* ---x x--- VBLKSTR Vertical blank start bits 11-10
|
||||
* ---- -x-- VDISPEND Vertical display end bit 10
|
||||
* ---- --xx VTOTAL bits 11-10
|
||||
*/
|
||||
u8 matrox_vga_device::crtcext2_vertical_counter_r()
|
||||
{
|
||||
return m_crtcext_vert_counter;
|
||||
}
|
||||
|
||||
void matrox_vga_device::crtcext2_vertical_counter_w(offs_t offset, u8 data)
|
||||
{
|
||||
// TODO: honor CRTC protect enable
|
||||
m_crtcext_vert_counter = data;
|
||||
vga.crtc.vert_total = (vga.crtc.vert_total & 0x3ff) | ((data & 3) << 10);
|
||||
vga.crtc.vert_disp_end = (vga.crtc.vert_disp_end & 0x3ff) | (BIT(data, 2) << 10);
|
||||
vga.crtc.vert_blank_start = (vga.crtc.vert_blank_start & 0x3ff) | ((data & 0x18) << (10-3));
|
||||
vga.crtc.vert_retrace_start = (vga.crtc.vert_retrace_start & 0x3ff) | ((data & 0x60) << (10-5));
|
||||
vga.crtc.line_compare = (vga.crtc.line_compare & 0x3ff) | (BIT(data, 7) << 10);
|
||||
recompute_params();
|
||||
}
|
||||
|
||||
/*
|
||||
* CRTCEXT3 Miscellaneous
|
||||
*
|
||||
@ -107,15 +190,19 @@ void matrox_vga_device::crtcext3_misc_w(offs_t offset, u8 data)
|
||||
m_mgamode = bool(BIT(data, 7));
|
||||
}
|
||||
|
||||
// RAMDAC
|
||||
// - paired with a Texas Instruments TVP3026 here -> a superset of INMOS IMSG176/IMSG178
|
||||
// - integrated with a superset in G400 at least
|
||||
/*
|
||||
* RAMDAC
|
||||
* - paired with a Texas Instruments TVP3026 here -> a superset of INMOS IMSG176/IMSG178
|
||||
* - integrated and customized with supersets in the next iteration (Mystique MGA-1064SG) and onward
|
||||
*/
|
||||
void matrox_vga_device::ramdac_ext_map(address_map &map)
|
||||
{
|
||||
// map(0x00, 0x00).rw(FUNC(matrox_vga_device::ramdac_write_index_r), FUNC(matrox_vga_device::ramdac_write_index_w));
|
||||
// map(0x01, 0x01).rw(FUNC(matrox_vga_device::ramdac_data_r), FUNC(matrox_vga_device::ramdac_data_w));
|
||||
// map(0x02, 0x02).rw(FUNC(matrox_vga_device::ramdac_mask_r), FUNC(matrox_vga_device::ramdac_mask_w));
|
||||
// map(0x03, 0x03).rw(FUNC(matrox_vga_device::ramdac_read_index_r), FUNC(matrox_vga_device::ramdac_read_index_w));
|
||||
map(0x00, 0x00).rw(FUNC(matrox_vga_device::ramdac_write_index_r), FUNC(matrox_vga_device::ramdac_write_index_w));
|
||||
map(0x01, 0x01).rw(FUNC(matrox_vga_device::ramdac_data_r), FUNC(matrox_vga_device::ramdac_data_w));
|
||||
map(0x02, 0x02).rw(FUNC(matrox_vga_device::ramdac_mask_r), FUNC(matrox_vga_device::ramdac_mask_w));
|
||||
map(0x03, 0x03).lr8(
|
||||
NAME([this] (offs_t offset) { return vga.dac.read_index; })
|
||||
).w(FUNC(matrox_vga_device::ramdac_read_index_w));
|
||||
// map(0x04, 0x04) Cursor/Overscan Color Write Index
|
||||
// map(0x05, 0x05) Cursor/Overscan Color data
|
||||
// map(0x07, 0x07) Cursor/Overscan Color Read Index
|
||||
@ -255,6 +342,8 @@ void matrox_vga_device::flush_true_color_mode()
|
||||
popmessage("TVP3026: Unemulated RGB%c 4-4-4-4 mode", m_truecolor_ctrl & 0x40 ? "X" : "O");
|
||||
break;
|
||||
}
|
||||
|
||||
recompute_params();
|
||||
}
|
||||
|
||||
uint8_t matrox_vga_device::mem_r(offs_t offset)
|
||||
@ -274,10 +363,29 @@ void matrox_vga_device::mem_w(offs_t offset, uint8_t data)
|
||||
svga_device::mem_w(offset, data);
|
||||
}
|
||||
|
||||
void matrox_vga_device::recompute_params()
|
||||
{
|
||||
u8 xtal_select = (vga.miscellaneous_output & 0x0c) >> 2;
|
||||
int xtal;
|
||||
|
||||
switch(xtal_select & 3)
|
||||
{
|
||||
case 0: xtal = XTAL(25'174'800).value(); break;
|
||||
case 1: xtal = XTAL(28'636'363).value(); break;
|
||||
// TODO: stub, derives from RAMDAC PLLs
|
||||
case 2:
|
||||
default:
|
||||
xtal = XTAL(50'000'000).value();
|
||||
break;
|
||||
}
|
||||
|
||||
recompute_params_clock(1, xtal);
|
||||
}
|
||||
|
||||
uint16_t matrox_vga_device::offset()
|
||||
{
|
||||
// TODO: shifts depending on RAMDAC mode + CRTCEXT0 bits 5-4
|
||||
if (svga.rgb16_en)
|
||||
return (vga.crtc.offset << 5);
|
||||
return (vga.crtc.offset << 4);
|
||||
return svga_device::offset();
|
||||
}
|
||||
|
@ -19,12 +19,17 @@ public:
|
||||
|
||||
virtual uint8_t mem_r(offs_t offset) override;
|
||||
virtual void mem_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
// TODO: polarity
|
||||
bool vsync_status() { return vga_vblank(); }
|
||||
|
||||
protected:
|
||||
virtual void io_3bx_3dx_map(address_map &map) override;
|
||||
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual uint16_t offset() override;
|
||||
virtual void recompute_params() override;
|
||||
|
||||
void crtcext_map(address_map &map);
|
||||
void ramdac_indexed_map(address_map &map);
|
||||
@ -36,12 +41,21 @@ private:
|
||||
address_space_config m_ramdac_indexed_space_config;
|
||||
|
||||
// CRTC
|
||||
u8 crtcext0_address_gen_r();
|
||||
void crtcext0_address_gen_w(offs_t offset, u8 data);
|
||||
u8 crtcext1_horizontal_counter_r();
|
||||
void crtcext1_horizontal_counter_w(offs_t offset, u8 data);
|
||||
u8 crtcext2_vertical_counter_r();
|
||||
void crtcext2_vertical_counter_w(offs_t offset, u8 data);
|
||||
u8 crtcext3_misc_r();
|
||||
void crtcext3_misc_w(offs_t offset, u8 data);
|
||||
u8 m_crtcext_index = 0;
|
||||
|
||||
u8 m_crtcext_misc = 0;
|
||||
u8 m_crtcext_horz_counter = 0;
|
||||
u8 m_crtcext_vert_counter = 0;
|
||||
bool m_mgamode = false;
|
||||
bool m_interlace_mode = false;
|
||||
|
||||
// RAMDAC
|
||||
u8 ramdac_ext_indexed_r();
|
||||
|
Loading…
Reference in New Issue
Block a user