mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
(MESS) Added skeleton S3 ViRGE video card. [Barry Rodewald]
This commit is contained in:
parent
0ff930c1a1
commit
a6c60b425c
@ -118,6 +118,7 @@ const device_type VGA = &device_creator<vga_device>;
|
||||
const device_type TSENG_VGA = &device_creator<tseng_vga_device>;
|
||||
const device_type TRIDENT_VGA = &device_creator<trident_vga_device>;
|
||||
const device_type S3_VGA = &device_creator<s3_vga_device>;
|
||||
const device_type S3VIRGE = &device_creator<s3virge_vga_device>;
|
||||
const device_type GAMTOR_VGA = &device_creator<gamtor_vga_device>;
|
||||
const device_type ATI_VGA = &device_creator<ati_vga_device>;
|
||||
const device_type CIRRUS_VGA = &device_creator<cirrus_vga_device>;
|
||||
@ -154,6 +155,11 @@ s3_vga_device::s3_vga_device(const machine_config &mconfig, const char *tag, dev
|
||||
{
|
||||
}
|
||||
|
||||
s3_vga_device::s3_vga_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: ati_vga_device(mconfig, type, name, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
gamtor_vga_device::gamtor_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: svga_device(mconfig, GAMTOR_VGA, "GAMTOR_VGA", tag, owner, clock)
|
||||
{
|
||||
@ -216,9 +222,9 @@ void vga_device::device_start()
|
||||
|
||||
// copy over interfaces
|
||||
vga.read_dipswitch = read8_delegate(); //read_dipswitch;
|
||||
vga.svga_intf.vram_size = 0x100000;
|
||||
vga.svga_intf.seq_regcount = 0x05;
|
||||
vga.svga_intf.crtc_regcount = 0x19;
|
||||
vga.svga_intf.vram_size = 0x100000;
|
||||
|
||||
vga.memory = auto_alloc_array_clear(machine(), UINT8, vga.svga_intf.vram_size);
|
||||
|
||||
@ -245,9 +251,9 @@ void cirrus_vga_device::device_start()
|
||||
|
||||
// copy over interfaces
|
||||
vga.read_dipswitch = read8_delegate(); //read_dipswitch;
|
||||
vga.svga_intf.vram_size = 0x200000;
|
||||
vga.svga_intf.seq_regcount = 0x08;
|
||||
vga.svga_intf.crtc_regcount = 0x19;
|
||||
vga.svga_intf.vram_size = 0x200000;
|
||||
|
||||
vga.memory = auto_alloc_array_clear(machine(), UINT8, vga.svga_intf.vram_size);
|
||||
|
||||
@ -1287,7 +1293,6 @@ void vga_device::recompute_params_clock(int divisor, int xtal)
|
||||
pixel_clock = xtal / (((vga.sequencer.data[1]&8) >> 3) + 1);
|
||||
|
||||
refresh = HZ_TO_ATTOSECONDS(pixel_clock) * (hblank_period) * vblank_period;
|
||||
|
||||
machine().primary_screen->configure((hblank_period), (vblank_period), visarea, refresh );
|
||||
// popmessage("%d %d\n",vga.crtc.horz_total * 8,vga.crtc.vert_total);
|
||||
|
||||
@ -4827,14 +4832,14 @@ WRITE8_MEMBER(s3_vga_device::mem_w)
|
||||
if(offset & 0x10000)
|
||||
return;
|
||||
if(vga.sequencer.data[4] & 0x8)
|
||||
vga.memory[offset + (svga.bank_w*0x10000)] = data;
|
||||
vga.memory[(offset + (svga.bank_w*0x10000)) % vga.svga_intf.vram_size] = data;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
if(vga.sequencer.map_mask & 1 << i)
|
||||
vga.memory[offset*4+i+(svga.bank_w*0x10000)] = data;
|
||||
vga.memory[(offset*4+i+(svga.bank_w*0x10000)) % vga.svga_intf.vram_size] = data;
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -5510,3 +5515,662 @@ WRITE8_MEMBER(cirrus_vga_device::port_03c0_w)
|
||||
}
|
||||
cirrus_define_video_mode();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* S3 Virge implementation
|
||||
*/
|
||||
|
||||
s3virge_vga_device::s3virge_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: s3_vga_device(mconfig, S3VIRGE, "S3VIRGE", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void s3virge_vga_device::device_start()
|
||||
{
|
||||
memset(&vga, 0, sizeof(vga));
|
||||
memset(&svga, 0, sizeof(svga));
|
||||
|
||||
int x;
|
||||
int i;
|
||||
for (i = 0; i < 0x100; i++)
|
||||
palette_set_color_rgb(machine(), i, 0, 0, 0);
|
||||
|
||||
// Avoid an infinite loop when displaying. 0 is not possible anyway.
|
||||
vga.crtc.maximum_scan_line = 1;
|
||||
|
||||
// copy over interfaces
|
||||
vga.read_dipswitch = read8_delegate(); //read_dipswitch;
|
||||
vga.svga_intf.seq_regcount = 0x08;
|
||||
vga.svga_intf.crtc_regcount = 0x19;
|
||||
vga.svga_intf.vram_size = 0x400000;
|
||||
vga.memory = auto_alloc_array_clear(machine(), UINT8, vga.svga_intf.vram_size);
|
||||
|
||||
m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this));
|
||||
|
||||
memset(&s3, 0, sizeof(s3));
|
||||
// Initialise hardware graphics cursor colours, Windows 95 doesn't touch the registers for some reason
|
||||
for(x=0;x<4;x++)
|
||||
{
|
||||
s3.cursor_fg[x] = 0xff;
|
||||
s3.cursor_bg[x] = 0x00;
|
||||
}
|
||||
// set device ID
|
||||
s3.id_high = 0x56; // CR2D
|
||||
s3.id_low = 0x31; // CR2E
|
||||
s3.revision = 0x00; // CR2F (value unknown)
|
||||
s3.id_cr30 = 0xe1; // CR30
|
||||
}
|
||||
|
||||
UINT8 s3virge_vga_device::s3_crtc_reg_read(UINT8 index)
|
||||
{
|
||||
UINT8 res;
|
||||
|
||||
if(index <= 0x18)
|
||||
res = crtc_reg_read(index);
|
||||
else
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0x2d:
|
||||
res = s3.id_high;
|
||||
break;
|
||||
case 0x2e:
|
||||
res = s3.id_low;
|
||||
break;
|
||||
case 0x2f:
|
||||
res = s3.revision;
|
||||
break;
|
||||
case 0x30: // CR30 Chip ID/REV register
|
||||
res = s3.id_cr30;
|
||||
break;
|
||||
case 0x31:
|
||||
res = s3.memory_config;
|
||||
break;
|
||||
case 0x35:
|
||||
res = s3.crt_reg_lock;
|
||||
break;
|
||||
case 0x38:
|
||||
res = s3.reg_lock1;
|
||||
break;
|
||||
case 0x39:
|
||||
res = s3.reg_lock2;
|
||||
break;
|
||||
case 0x42: // CR42 Mode Control
|
||||
res = s3.cr42 & 0x0f; // bit 5 set if interlaced, leave it unset for now.
|
||||
break;
|
||||
case 0x45:
|
||||
res = s3.cursor_mode;
|
||||
break;
|
||||
case 0x46:
|
||||
res = (s3.cursor_x & 0xff00) >> 8;
|
||||
break;
|
||||
case 0x47:
|
||||
res = s3.cursor_x & 0x00ff;
|
||||
break;
|
||||
case 0x48:
|
||||
res = (s3.cursor_y & 0xff00) >> 8;
|
||||
break;
|
||||
case 0x49:
|
||||
res = s3.cursor_y & 0x00ff;
|
||||
break;
|
||||
case 0x4a:
|
||||
res = s3.cursor_fg[s3.cursor_fg_ptr];
|
||||
s3.cursor_fg_ptr = 0;
|
||||
break;
|
||||
case 0x4b:
|
||||
res = s3.cursor_bg[s3.cursor_bg_ptr];
|
||||
s3.cursor_bg_ptr = 0;
|
||||
break;
|
||||
case 0x4c:
|
||||
res = (s3.cursor_start_addr & 0xff00) >> 8;
|
||||
break;
|
||||
case 0x4d:
|
||||
res = s3.cursor_start_addr & 0x00ff;
|
||||
break;
|
||||
case 0x4e:
|
||||
res = s3.cursor_pattern_x;
|
||||
break;
|
||||
case 0x4f:
|
||||
res = s3.cursor_pattern_y;
|
||||
break;
|
||||
case 0x51:
|
||||
res = (vga.crtc.start_addr_latch & 0x0c0000) >> 18;
|
||||
res |= ((svga.bank_w & 0x30) >> 2);
|
||||
break;
|
||||
case 0x55:
|
||||
res = s3.extended_dac_ctrl;
|
||||
break;
|
||||
case 0x5c:
|
||||
// if VGA dot clock is set to 3 (misc reg bits 2-3), then selected dot clock is read, otherwise read VGA clock select
|
||||
if((vga.miscellaneous_output & 0xc) == 0x0c)
|
||||
res = s3.cr42 & 0x0f;
|
||||
else
|
||||
res = (vga.miscellaneous_output & 0xc) >> 2;
|
||||
break;
|
||||
case 0x67:
|
||||
res = s3.ext_misc_ctrl_2;
|
||||
break;
|
||||
case 0x69:
|
||||
res = vga.crtc.start_addr_latch >> 16;
|
||||
break;
|
||||
case 0x6a:
|
||||
res = svga.bank_r & 0x7f;
|
||||
break;
|
||||
default:
|
||||
res = vga.crtc.data[index];
|
||||
//debugger_break(machine);
|
||||
//printf("%02x\n",index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void s3virge_vga_device::s3_define_video_mode()
|
||||
{
|
||||
int divisor = 1;
|
||||
int xtal = (vga.miscellaneous_output & 0xc) ? XTAL_28_63636MHz : XTAL_25_1748MHz;
|
||||
|
||||
if((vga.miscellaneous_output & 0xc) == 0x0c)
|
||||
{
|
||||
switch(s3.cr42 & 0x0f) // TODO: confirm clock settings
|
||||
{
|
||||
case 0:
|
||||
xtal = XTAL_25_1748MHz;
|
||||
break;
|
||||
case 1:
|
||||
xtal = XTAL_28_63636MHz;
|
||||
break;
|
||||
case 2:
|
||||
xtal = 40000000;
|
||||
break;
|
||||
case 3:
|
||||
xtal = 3000000;
|
||||
break;
|
||||
case 4:
|
||||
xtal = 50000000;
|
||||
break;
|
||||
case 5:
|
||||
xtal = 77000000;
|
||||
break;
|
||||
case 6:
|
||||
xtal = 36000000;
|
||||
break;
|
||||
case 7:
|
||||
xtal = 45000000;
|
||||
break;
|
||||
case 8:
|
||||
xtal = 1000000;
|
||||
break;
|
||||
case 9:
|
||||
xtal = 1000000;
|
||||
break;
|
||||
case 10:
|
||||
xtal = 79000000;
|
||||
break;
|
||||
case 11:
|
||||
xtal = 31000000;
|
||||
break;
|
||||
case 12:
|
||||
xtal = 94000000;
|
||||
break;
|
||||
case 13:
|
||||
xtal = 65000000;
|
||||
break;
|
||||
case 14:
|
||||
xtal = 75000000;
|
||||
break;
|
||||
case 15:
|
||||
xtal = 71000000;
|
||||
break;
|
||||
default:
|
||||
xtal = 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
if((s3.ext_misc_ctrl_2) >> 4)
|
||||
{
|
||||
svga.rgb8_en = 0;
|
||||
svga.rgb15_en = 0;
|
||||
svga.rgb16_en = 0;
|
||||
svga.rgb32_en = 0;
|
||||
switch((s3.ext_misc_ctrl_2) >> 4)
|
||||
{
|
||||
case 0x03: svga.rgb15_en = 1; divisor = 2; break;
|
||||
case 0x05: svga.rgb16_en = 1; divisor = 2; break;
|
||||
case 0x0d: svga.rgb32_en = 1; divisor = 2; break;
|
||||
default: fatalerror("TODO: s3 video mode not implemented %02x\n",((s3.ext_misc_ctrl_2) >> 4)); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
svga.rgb8_en = (s3.memory_config & 8) >> 3;
|
||||
svga.rgb15_en = 0;
|
||||
svga.rgb16_en = 0;
|
||||
svga.rgb32_en = 0;
|
||||
}
|
||||
recompute_params_clock(divisor, xtal);
|
||||
}
|
||||
|
||||
void s3virge_vga_device::s3_crtc_reg_write(UINT8 index, UINT8 data)
|
||||
{
|
||||
if(index <= 0x18)
|
||||
crtc_reg_write(index,data);
|
||||
else
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0x31: // CR31 Memory Configuration Register
|
||||
s3.memory_config = data;
|
||||
vga.crtc.start_addr_latch &= ~0x30000;
|
||||
vga.crtc.start_addr_latch |= ((data & 0x30) << 12);
|
||||
s3_define_video_mode();
|
||||
break;
|
||||
case 0x35:
|
||||
if((s3.reg_lock1 & 0xc) != 8 || ((s3.reg_lock1 & 0xc0) == 0)) // lock register
|
||||
return;
|
||||
s3.crt_reg_lock = data;
|
||||
svga.bank_w = data & 0xf;
|
||||
svga.bank_r = svga.bank_w;
|
||||
break;
|
||||
case 0x38:
|
||||
s3.reg_lock1 = data;
|
||||
break;
|
||||
case 0x39:
|
||||
/* TODO: reg lock mechanism */
|
||||
s3.reg_lock2 = data;
|
||||
break;
|
||||
case 0x40:
|
||||
s3.enable_s3d = data & 0x01; // enable S3D registers at 0x100A
|
||||
break;
|
||||
case 0x42:
|
||||
s3.cr42 = data; // bit 5 = interlace, bits 0-3 = dot clock (seems to be undocumented)
|
||||
break;
|
||||
/*
|
||||
3d4h index 45h (R/W): CR45 Hardware Graphics Cursor Mode
|
||||
bit 0 HWGC ENB. Hardware Graphics Cursor Enable. Set to enable the
|
||||
HardWare Cursor in VGA and enhanced modes.
|
||||
1 (911/24) Delay Timing for Pattern Data Fetch
|
||||
2 (801/5,928) Hardware Cursor Horizontal Stretch 2. If set the cursor
|
||||
pixels are stretched horizontally to two bytes and items 0 and 1 of
|
||||
the fore/background stacks in 3d4h index 4Ah/4Bh are used.
|
||||
3 (801/5,928) Hardware Cursor Horizontal Stretch 3. If set the cursor
|
||||
pixels are stretched horizontally to three bytes and items 0,1 and
|
||||
2 of the fore/background stacks in 3d4h index 4Ah/4Bh are used.
|
||||
2-3 (805i,864/964) HWC-CSEL. Hardware Cursor Color Select.
|
||||
0: 4/8bit, 1: 15/16bt, 2: 24bit, 3: 32bit
|
||||
Note: So far I've had better luck with: 0: 8/15/16bit, 1: 32bit??
|
||||
4 (80x +) Hardware Cursor Right Storage. If set the cursor data is
|
||||
stored in the last 256 bytes of 4 1Kyte lines (4bits/pixel) or the
|
||||
last 512 bytes of 2 2Kbyte lines (8bits/pixel). Intended for
|
||||
1280x1024 modes where there are no free lines at the bottom.
|
||||
5 (928) Cursor Control Enable for Brooktree Bt485 DAC. If set and 3d4h
|
||||
index 55h bit 5 is set the HC1 output becomes the ODF and the HC0
|
||||
output becomes the CDE
|
||||
(964) BT485 ODF Selection for Bt485A RAMDAC. If set pin 185 (RS3
|
||||
/ODF) is the ODF output to a Bt485A compatible RamDAC (low for even
|
||||
fields and high for odd fields), if clear pin185 is the RS3 output.
|
||||
*/
|
||||
case 0x45:
|
||||
s3.cursor_mode = data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 46h M(R/W): CR46/7 Hardware Graphics Cursor Origin-X
|
||||
bit 0-10 The HardWare Cursor X position. For 64k modes this value should be
|
||||
twice the actual X co-ordinate.
|
||||
*/
|
||||
case 0x46:
|
||||
s3.cursor_x = (s3.cursor_x & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 0x47:
|
||||
s3.cursor_x = (s3.cursor_x & 0xff00) | data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 48h M(R/W): CR48/9 Hardware Graphics Cursor Origin-Y
|
||||
bit 0-9 (911/24) The HardWare Cursor Y position.
|
||||
0-10 (80x +) The HardWare Cursor Y position.
|
||||
Note: The position is activated when the high byte of the Y coordinate (index
|
||||
48h) is written, so this byte should be written last (not 911/924 ?)
|
||||
*/
|
||||
case 0x48:
|
||||
s3.cursor_y = (s3.cursor_y & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 0x49:
|
||||
s3.cursor_y = (s3.cursor_y & 0xff00) | data;
|
||||
break;
|
||||
|
||||
/*
|
||||
3d4h index 4Ah (R/W): Hardware Graphics Cursor Foreground Stack (80x +)
|
||||
bit 0-7 The Foreground Cursor color. Three bytes (4 for the 864/964) are
|
||||
stacked here. When the Cursor Mode register (3d4h index 45h) is read
|
||||
the stackpointer is reset. When a byte is written the byte is
|
||||
written into the current top of stack and the stackpointer is
|
||||
increased. The first byte written (item 0) is allways used, the
|
||||
other two(3) only when Hardware Cursor Horizontal Stretch (3d4h
|
||||
index 45h bit 2-3) is enabled.
|
||||
*/
|
||||
case 0x4a:
|
||||
s3.cursor_fg[s3.cursor_fg_ptr++] = data;
|
||||
s3.cursor_fg_ptr %= 4;
|
||||
break;
|
||||
/*
|
||||
3d4h index 4Bh (R/W): Hardware Graphics Cursor Background Stack (80x +)
|
||||
bit 0-7 The Background Cursor color. Three bytes (4 for the 864/964) are
|
||||
stacked here. When the Cursor Mode register (3d4h index 45h) is read
|
||||
the stackpointer is reset. When a byte is written the byte is
|
||||
written into the current top of stack and the stackpointer is
|
||||
increased. The first byte written (item 0) is allways used, the
|
||||
other two(3) only when Hardware Cursor Horizontal Stretch (3d4h
|
||||
index 45h bit 2-3) is enabled.
|
||||
*/
|
||||
case 0x4b:
|
||||
s3.cursor_bg[s3.cursor_bg_ptr++] = data;
|
||||
s3.cursor_bg_ptr %= 4;
|
||||
break;
|
||||
/*
|
||||
3d4h index 4Ch M(R/W): CR4C/D Hardware Graphics Cursor Storage Start Address
|
||||
bit 0-9 (911,924) HCS_STADR. Hardware Graphics Cursor Storage Start Address
|
||||
0-11 (80x,928) HWGC_STA. Hardware Graphics Cursor Storage Start Address
|
||||
0-12 (864,964) HWGC_STA. Hardware Graphics Cursor Storage Start Address
|
||||
Address of the HardWare Cursor Map in units of 1024 bytes (256 bytes
|
||||
for planar modes). The cursor map is a 64x64 bitmap with 2 bits (A
|
||||
and B) per pixel. The map is stored as one word (16 bits) of bit A,
|
||||
followed by one word with the corresponding 16 B bits.
|
||||
The bits are interpreted as:
|
||||
A B MS-Windows: X-11:
|
||||
0 0 Background Screen data
|
||||
0 1 Foreground Screen data
|
||||
1 0 Screen data Background
|
||||
1 1 Inverted screen Foreground
|
||||
The Windows/X11 switch is only available for the 80x +.
|
||||
(911/24) For 64k color modes the cursor is stored as one byte (8
|
||||
bits) of A bits, followed by the 8 B-bits, and each bit in the
|
||||
cursor should be doubled to provide a consistent cursor image.
|
||||
(801/5,928) For Hi/True color modes use the Horizontal Stretch bits
|
||||
(3d4h index 45h bits 2 and 3).
|
||||
*/
|
||||
case 0x4c:
|
||||
s3.cursor_start_addr = (s3.cursor_start_addr & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 0x4d:
|
||||
s3.cursor_start_addr = (s3.cursor_start_addr & 0xff00) | data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 4Eh (R/W): CR4E HGC Pattern Disp Start X-Pixel Position
|
||||
bit 0-5 Pattern Display Start X-Pixel Position.
|
||||
*/
|
||||
case 0x4e:
|
||||
s3.cursor_pattern_x = data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 4Fh (R/W): CR4F HGC Pattern Disp Start Y-Pixel Position
|
||||
bit 0-5 Pattern Display Start Y-Pixel Position.
|
||||
*/
|
||||
case 0x4f:
|
||||
s3.cursor_pattern_y = data;
|
||||
break;
|
||||
case 0x51:
|
||||
vga.crtc.start_addr_latch &= ~0xc0000;
|
||||
vga.crtc.start_addr_latch |= ((data & 0x3) << 18);
|
||||
svga.bank_w = (svga.bank_w & 0xcf) | ((data & 0x0c) << 2);
|
||||
svga.bank_r = svga.bank_w;
|
||||
s3_define_video_mode();
|
||||
break;
|
||||
case 0x53:
|
||||
s3.cr53 = data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 55h (R/W): Extended Video DAC Control Register (80x +)
|
||||
bit 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the
|
||||
RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs.
|
||||
If this field is 0, 3d4h index 43h bit 1 is active.
|
||||
2 Enable General Input Port Read. If set DAC reads are disabled and the
|
||||
STRD strobe for reading the General Input Port is enabled for reading
|
||||
while DACRD is active, if clear DAC reads are enabled.
|
||||
3 (928) Enable External SID Operation if set. If set video data is
|
||||
passed directly from the VRAMs to the DAC rather than through the
|
||||
VGA chip
|
||||
4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11
|
||||
mode, if clear in MS-Windows mode
|
||||
5 (80x,928) Hardware Cursor External Operation Mode. If set the two
|
||||
bits of cursor data ,is output on the HC[0-1] pins for the video DAC
|
||||
The SENS pin becomes HC1 and the MID2 pin becomes HC0.
|
||||
6 ??
|
||||
7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated.
|
||||
(864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri
|
||||
-stated if set
|
||||
*/
|
||||
case 0x55:
|
||||
s3.extended_dac_ctrl = data;
|
||||
break;
|
||||
/*
|
||||
3d4h index 5Dh (R/W): Extended Horizontal Overflow Register (80x +)
|
||||
bit 0 Horizontal Total bit 8. Bit 8 of the Horizontal Total register (3d4h
|
||||
index 0)
|
||||
1 Horizontal Display End bit 8. Bit 8 of the Horizontal Display End
|
||||
register (3d4h index 1)
|
||||
2 Start Horizontal Blank bit 8. Bit 8 of the Horizontal Start Blanking
|
||||
register (3d4h index 2).
|
||||
3 (864,964) EHB+64. End Horizontal Blank +64. If set the /BLANK pulse
|
||||
is extended by 64 DCLKs. Note: Is this bit 6 of 3d4h index 3 or
|
||||
does it really extend by 64 ?
|
||||
4 Start Horizontal Sync Position bit 8. Bit 8 of the Horizontal Start
|
||||
Retrace register (3d4h index 4).
|
||||
5 (864,964) EHS+32. End Horizontal Sync +32. If set the HSYNC pulse
|
||||
is extended by 32 DCLKs. Note: Is this bit 5 of 3d4h index 5 or
|
||||
does it really extend by 32 ?
|
||||
6 (928,964) Data Transfer Position bit 8. Bit 8 of the Data Transfer
|
||||
Position register (3d4h index 3Bh)
|
||||
7 (928,964) Bus-Grant Terminate Position bit 8. Bit 8 of the Bus Grant
|
||||
Termination register (3d4h index 5Fh).
|
||||
*/
|
||||
case 0x5d:
|
||||
vga.crtc.horz_total = (vga.crtc.horz_total & 0xfeff) | ((data & 0x01) << 8);
|
||||
vga.crtc.horz_disp_end = (vga.crtc.horz_disp_end & 0xfeff) | ((data & 0x02) << 7);
|
||||
vga.crtc.horz_blank_start = (vga.crtc.horz_blank_start & 0xfeff) | ((data & 0x04) << 6);
|
||||
vga.crtc.horz_blank_end = (vga.crtc.horz_blank_end & 0xffbf) | ((data & 0x08) << 3);
|
||||
vga.crtc.horz_retrace_start = (vga.crtc.horz_retrace_start & 0xfeff) | ((data & 0x10) << 4);
|
||||
vga.crtc.horz_retrace_end = (vga.crtc.horz_retrace_end & 0xffdf) | (data & 0x20);
|
||||
s3_define_video_mode();
|
||||
break;
|
||||
/*
|
||||
3d4h index 5Eh (R/W): Extended Vertical Overflow Register (80x +)
|
||||
bit 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h
|
||||
index 6). Bits 8 and 9 are in 3d4h index 7 bit 0 and 5.
|
||||
1 Vertical Display End bit 10. Bit 10 of the Vertical Display End
|
||||
register (3d4h index 12h). Bits 8 and 9 are in 3d4h index 7 bit 1
|
||||
and 6
|
||||
2 Start Vertical Blank bit 10. Bit 10 of the Vertical Start Blanking
|
||||
register (3d4h index 15h). Bit 8 is in 3d4h index 7 bit 3 and bit 9
|
||||
in 3d4h index 9 bit 5
|
||||
4 Vertical Retrace Start bit 10. Bit 10 of the Vertical Start Retrace
|
||||
register (3d4h index 10h). Bits 8 and 9 are in 3d4h index 7 bit 2
|
||||
and 7.
|
||||
6 Line Compare Position bit 10. Bit 10 of the Line Compare register
|
||||
(3d4h index 18h). Bit 8 is in 3d4h index 7 bit 4 and bit 9 in 3d4h
|
||||
index 9 bit 6.
|
||||
*/
|
||||
case 0x5e:
|
||||
vga.crtc.vert_total = (vga.crtc.vert_total & 0xfbff) | ((data & 0x01) << 10);
|
||||
vga.crtc.vert_disp_end = (vga.crtc.vert_disp_end & 0xfbff) | ((data & 0x02) << 9);
|
||||
vga.crtc.vert_blank_start = (vga.crtc.vert_blank_start & 0xfbff) | ((data & 0x04) << 8);
|
||||
vga.crtc.vert_retrace_start = (vga.crtc.vert_retrace_start & 0xfbff) | ((data & 0x10) << 6);
|
||||
vga.crtc.line_compare = (vga.crtc.line_compare & 0xfbff) | ((data & 0x40) << 4);
|
||||
s3_define_video_mode();
|
||||
break;
|
||||
case 0x67:
|
||||
s3.ext_misc_ctrl_2 = data;
|
||||
s3_define_video_mode();
|
||||
//printf("%02x X\n",data);
|
||||
break;
|
||||
case 0x69:
|
||||
vga.crtc.start_addr_latch &= ~0x1f0000;
|
||||
vga.crtc.start_addr_latch |= ((data & 0x1f) << 16);
|
||||
s3_define_video_mode();
|
||||
break;
|
||||
case 0x6a:
|
||||
svga.bank_w = data & 0x3f;
|
||||
svga.bank_r = svga.bank_w;
|
||||
break;
|
||||
default:
|
||||
if(LOG_8514) logerror("S3: 3D4 index %02x write %02x\n",index,data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(s3virge_vga_device::port_03b0_r)
|
||||
{
|
||||
UINT8 res = 0xff;
|
||||
|
||||
if (CRTC_PORT_ADDR == 0x3b0)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 5:
|
||||
res = s3_crtc_reg_read(vga.crtc.index);
|
||||
break;
|
||||
default:
|
||||
res = vga_device::port_03b0_r(space,offset,mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(s3virge_vga_device::port_03b0_w)
|
||||
{
|
||||
if (CRTC_PORT_ADDR == 0x3b0)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 5:
|
||||
vga.crtc.data[vga.crtc.index] = data;
|
||||
s3_crtc_reg_write(vga.crtc.index,data);
|
||||
break;
|
||||
default:
|
||||
vga_device::port_03b0_w(space,offset,data,mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(s3virge_vga_device::port_03c0_r)
|
||||
{
|
||||
UINT8 res;
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
default:
|
||||
res = vga_device::port_03c0_r(space,offset,mem_mask);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(s3virge_vga_device::port_03c0_w)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
default:
|
||||
vga_device::port_03c0_w(space,offset,data,mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(s3virge_vga_device::port_03d0_r)
|
||||
{
|
||||
UINT8 res = 0xff;
|
||||
|
||||
if (CRTC_PORT_ADDR == 0x3d0)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 5:
|
||||
res = s3_crtc_reg_read(vga.crtc.index);
|
||||
break;
|
||||
default:
|
||||
res = vga_device::port_03d0_r(space,offset,mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(s3virge_vga_device::port_03d0_w)
|
||||
{
|
||||
if (CRTC_PORT_ADDR == 0x3d0)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 5:
|
||||
vga.crtc.data[vga.crtc.index] = data;
|
||||
s3_crtc_reg_write(vga.crtc.index,data);
|
||||
break;
|
||||
default:
|
||||
vga_device::port_03d0_w(space,offset,data,mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(s3virge_vga_device::mem_r)
|
||||
{
|
||||
if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
|
||||
{
|
||||
int data;
|
||||
if(offset & 0x10000)
|
||||
return 0;
|
||||
data = 0;
|
||||
if(vga.sequencer.data[4] & 0x8)
|
||||
data = vga.memory[offset + (svga.bank_r*0x10000)];
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
if(vga.sequencer.map_mask & 1 << i)
|
||||
data |= vga.memory[offset*4+i+(svga.bank_r*0x10000)];
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return vga_device::mem_r(space,offset,mem_mask);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(s3virge_vga_device::mem_w)
|
||||
{
|
||||
// bit 4 of CR53 enables memory-mapped I/O
|
||||
if(s3.cr53 & 0x10)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
|
||||
{
|
||||
// printf("%08x %02x (%02x %02x) %02X\n",offset,data,vga.sequencer.map_mask,svga.bank_w,(vga.sequencer.data[4] & 0x08));
|
||||
if(offset & 0x10000)
|
||||
return;
|
||||
if(vga.sequencer.data[4] & 0x8)
|
||||
vga.memory[(offset + (svga.bank_w*0x10000)) % vga.svga_intf.vram_size] = data;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
if(vga.sequencer.map_mask & 1 << i)
|
||||
vga.memory[(offset*4+i+(svga.bank_w*0x10000)) % vga.svga_intf.vram_size] = data;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vga_device::mem_w(space,offset,data,mem_mask);
|
||||
}
|
||||
|
@ -519,6 +519,7 @@ class s3_vga_device : public ati_vga_device
|
||||
public:
|
||||
// construction/destruction
|
||||
s3_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
s3_vga_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual READ8_MEMBER(port_03b0_r);
|
||||
virtual WRITE8_MEMBER(port_03b0_w);
|
||||
@ -545,6 +546,7 @@ protected:
|
||||
UINT8 reg_lock1;
|
||||
UINT8 reg_lock2;
|
||||
UINT8 enable_8514;
|
||||
UINT8 enable_s3d;
|
||||
UINT8 cr42;
|
||||
UINT8 cr53;
|
||||
UINT8 id_high;
|
||||
@ -570,6 +572,7 @@ protected:
|
||||
UINT8 cursor_bg_ptr;
|
||||
UINT8 extended_dac_ctrl;
|
||||
} s3;
|
||||
|
||||
private:
|
||||
UINT8 s3_crtc_reg_read(UINT8 index);
|
||||
void s3_define_video_mode(void);
|
||||
@ -580,6 +583,38 @@ private:
|
||||
// device type definition
|
||||
extern const device_type S3_VGA;
|
||||
|
||||
// ======================> s3virge_vga_device
|
||||
|
||||
class s3virge_vga_device : public s3_vga_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
s3virge_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual READ8_MEMBER(port_03b0_r);
|
||||
virtual WRITE8_MEMBER(port_03b0_w);
|
||||
virtual READ8_MEMBER(port_03c0_r);
|
||||
virtual WRITE8_MEMBER(port_03c0_w);
|
||||
virtual READ8_MEMBER(port_03d0_r);
|
||||
virtual WRITE8_MEMBER(port_03d0_w);
|
||||
virtual READ8_MEMBER(mem_r);
|
||||
virtual WRITE8_MEMBER(mem_w);
|
||||
|
||||
ibm8514a_device* get_8514() { fatalerror("s3virge requested non-existant 8514/A device\n"); return NULL; }
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
private:
|
||||
UINT8 s3_crtc_reg_read(UINT8 index);
|
||||
void s3_define_video_mode(void);
|
||||
void s3_crtc_reg_write(UINT8 index, UINT8 data);
|
||||
// has no 8514/A device
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type S3VIRGE;
|
||||
|
||||
|
||||
// ======================> gamtor_vga_device
|
||||
|
||||
|
@ -59,7 +59,7 @@ const rom_entry *isa16_svga_s3_device::device_rom_region() const
|
||||
//-------------------------------------------------
|
||||
|
||||
isa16_svga_s3_device::isa16_svga_s3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, ISA16_SVGA_S3, "SVGA S3 Graphics Card", tag, owner, clock, "s3_764", __FILE__),
|
||||
device_t(mconfig, ISA16_SVGA_S3, "Number Nine 9FX Vision 330 (S3 764) Graphics Card", tag, owner, clock, "s3_764", __FILE__),
|
||||
device_isa16_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
@ -106,3 +106,92 @@ void isa16_svga_s3_device::device_start()
|
||||
void isa16_svga_s3_device::device_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* S3 Virge 2D/3D accelerator
|
||||
*/
|
||||
|
||||
ROM_START( s3virge )
|
||||
ROM_REGION(0x8000,"s3virge", 0)
|
||||
ROM_LOAD("s3virge.bin", 0x00000, 0x8000, CRC(a7983a85) SHA1(e885371816d3237f7badd57ccd602cd863c9c9f8) )
|
||||
ROM_IGNORE( 0x8000 )
|
||||
ROM_END
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type ISA16_S3VIRGE = &device_creator<isa16_s3virge_device>;
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( vga_s3virge )
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480)
|
||||
MCFG_SCREEN_UPDATE_DEVICE("vga", s3virge_vga_device, screen_update)
|
||||
|
||||
MCFG_PALETTE_LENGTH(0x100)
|
||||
|
||||
MCFG_DEVICE_ADD("vga", S3VIRGE, 0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor isa16_s3virge_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( vga_s3virge );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
const rom_entry *isa16_s3virge_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( s3virge );
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// isa16_vga_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
isa16_s3virge_device::isa16_s3virge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, ISA16_S3VIRGE, "S3 ViRGE Graphics Card", tag, owner, clock, "s3virge", __FILE__),
|
||||
device_isa16_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
READ8_MEMBER(isa16_s3virge_device::input_port_0_r ) { return 0xff; } //return space.machine().root_device().ioport("IN0")->read(); }
|
||||
|
||||
void isa16_s3virge_device::device_start()
|
||||
{
|
||||
set_isa_device();
|
||||
|
||||
m_vga = subdevice<s3virge_vga_device>("vga");
|
||||
|
||||
m_isa->install_rom(this, 0xc0000, 0xc7fff, 0, 0, "svga", "s3virge");
|
||||
|
||||
m_isa->install_device(0x03b0, 0x03bf, 0, 0, read8_delegate(FUNC(s3virge_vga_device::port_03b0_r),m_vga), write8_delegate(FUNC(s3virge_vga_device::port_03b0_w),m_vga));
|
||||
m_isa->install_device(0x03c0, 0x03cf, 0, 0, read8_delegate(FUNC(s3virge_vga_device::port_03c0_r),m_vga), write8_delegate(FUNC(s3virge_vga_device::port_03c0_w),m_vga));
|
||||
m_isa->install_device(0x03d0, 0x03df, 0, 0, read8_delegate(FUNC(s3virge_vga_device::port_03d0_r),m_vga), write8_delegate(FUNC(s3virge_vga_device::port_03d0_w),m_vga));
|
||||
|
||||
m_isa->install_memory(0xa0000, 0xbffff, 0, 0, read8_delegate(FUNC(s3virge_vga_device::mem_r),m_vga), write8_delegate(FUNC(s3virge_vga_device::mem_w),m_vga));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void isa16_s3virge_device::device_reset()
|
||||
{
|
||||
}
|
||||
|
@ -35,8 +35,30 @@ private:
|
||||
ibm8514a_device *m_8514;
|
||||
};
|
||||
|
||||
class isa16_s3virge_device :
|
||||
public device_t,
|
||||
public device_isa16_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
isa16_s3virge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
|
||||
DECLARE_READ8_MEMBER(input_port_0_r);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
private:
|
||||
s3virge_vga_device *m_vga;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type ISA16_SVGA_S3;
|
||||
extern const device_type ISA16_S3VIRGE;
|
||||
|
||||
#endif /* __ISA_VGA_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user