summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author mahlemiut <mahlemiut@users.noreply.github.com>2012-09-06 22:58:12 +0000
committer mahlemiut <mahlemiut@users.noreply.github.com>2012-09-06 22:58:12 +0000
commit21c9ba5b97400abe3099205f07dd4838d5beab0e (patch)
treea8bb64d62c0ab509fffd921db1901d8ea531b43a /src/emu
parentdbe595e54c0b6f3b31fa21ee51d997184eb5f1d8 (diff)
(MESS) svga_s3: Added Hardware Graphics Cursor. Works fine under Windows 95, allowing hardware acceleration to be set to full, but doesn't work right under Windows 3.1.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/video/pc_vga.c321
-rw-r--r--src/emu/video/pc_vga.h2
2 files changed, 321 insertions, 2 deletions
diff --git a/src/emu/video/pc_vga.c b/src/emu/video/pc_vga.c
index ea8f32363ce..ec0d2408361 100644
--- a/src/emu/video/pc_vga.c
+++ b/src/emu/video/pc_vga.c
@@ -236,6 +236,19 @@ static struct
UINT16 mmio_9ae8;
UINT16 mmio_bee8;
+ // hardware graphics cursor
+ UINT8 cursor_mode;
+ UINT16 cursor_x;
+ UINT16 cursor_y;
+ UINT16 cursor_start_addr;
+ UINT8 cursor_pattern_x; // cursor pattern origin
+ UINT8 cursor_pattern_y;
+ UINT8 cursor_fg[4];
+ UINT8 cursor_bg[4];
+ UINT8 cursor_fg_ptr;
+ UINT8 cursor_bg_ptr;
+ UINT8 extended_dac_ctrl;
+
bool gpbusy;
int state;
}s3;
@@ -296,6 +309,19 @@ void pc_video_start(running_machine &machine)
vga.crtc.maximum_scan_line = 1;
}
+void s3_video_start(running_machine &machine)
+{
+ int x;
+ // Avoid an infinite loop when displaying. 0 is not possible anyway.
+ vga.crtc.maximum_scan_line = 1;
+ // 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;
+ }
+}
+
static void vga_vh_text(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
UINT8 ch, attr;
@@ -909,6 +935,84 @@ SCREEN_UPDATE_RGB32( pc_video )
return 0;
}
+
+SCREEN_UPDATE_RGB32( pc_video_s3 )
+{
+ UINT8 cur_mode = 0;
+
+ SCREEN_UPDATE32_CALL( pc_video );
+
+ cur_mode = pc_vga_choosevideomode(screen.machine());
+
+ // draw hardware graphics cursor
+ // TODO: support 16 bit and greater video modes
+ if(s3.cursor_mode & 0x01) // if cursor is enabled
+ {
+ UINT32 src;
+ UINT32* dst;
+ UINT8 val;
+ int x,y;
+ UINT16 cx = s3.cursor_x & 0x07ff;
+ UINT16 cy = s3.cursor_y & 0x07ff;
+
+ if(cur_mode == SCREEN_OFF || cur_mode == TEXT_MODE || cur_mode == MONO_MODE || cur_mode == CGA_MODE || cur_mode == EGA_MODE)
+ return 0; // cursor only works in VGA or SVGA modes
+
+ src = s3.cursor_start_addr * 1024; // start address is in units of 1024 bytes
+// for(x=0;x<64;x++)
+// printf("%08x: %02x %02x %02x %02x\n",src+x*4,vga.memory[src+x*4],vga.memory[src+x*4+1],vga.memory[src+x*4+2],vga.memory[src+x*4+3]);
+ for(y=0;y<64;y++)
+ {
+ dst = &bitmap.pix32(cy + y, cx);
+ for(x=0;x<64;x++)
+ {
+ UINT16 bita = (vga.memory[(src+1) % vga.svga_intf.vram_size] | ((vga.memory[(src+0) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
+ UINT16 bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
+ val = ((bita & 0x01) << 1) | (bitb & 0x01);
+ if(s3.extended_dac_ctrl & 0x10)
+ { // X11 mode
+ switch(val)
+ {
+ case 0x00:
+ // no change
+ break;
+ case 0x01:
+ // no change
+ break;
+ case 0x02:
+ dst[x] = screen.machine().pens[s3.cursor_bg[0]];
+ break;
+ case 0x03:
+ dst[x] = screen.machine().pens[s3.cursor_fg[0]];
+ break;
+ }
+ }
+ else
+ { // Windows mode
+ switch(val)
+ {
+ case 0x00:
+ dst[x] = screen.machine().pens[s3.cursor_bg[0]];
+ break;
+ case 0x01:
+ dst[x] = screen.machine().pens[s3.cursor_fg[0]];
+ break;
+ case 0x02: // screen data
+ // no change
+ break;
+ case 0x03: // inverted screen data
+ dst[x] = ~(dst[x]);
+ break;
+ }
+ }
+ if(x % 16 == 15)
+ src+=4;
+ }
+ }
+ }
+ return 0;
+}
+
/***************************************************************************/
INLINE UINT8 rotate_right(UINT8 val)
@@ -1985,6 +2089,14 @@ MACHINE_CONFIG_FRAGMENT( pcvideo_vga_isa )
MCFG_PALETTE_LENGTH(0x100)
MACHINE_CONFIG_END
+MACHINE_CONFIG_FRAGMENT( pcvideo_s3_isa )
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480)
+ MCFG_SCREEN_UPDATE_STATIC(pc_video_s3)
+
+ MCFG_PALETTE_LENGTH(0x100)
+MACHINE_CONFIG_END
+
/******************************************
Tseng ET4000k implementation
@@ -2526,7 +2638,7 @@ static UINT8 s3_crtc_reg_read(running_machine &machine, UINT8 index)
// res = 0x00;
// break;
case 0x30: // CR30 Chip ID/REV register
- res = 0xc0; // BIOS is from a card with the 764 chipset (Trio64)
+ res = 0xc0; // BIOS is from a card with the 764 chipset (Trio64), should be 0xe0 or 0xe1, but the Vision 330 driver in win95 doesn't like that
break;
case 0x31:
res = s3.memory_config;
@@ -2543,6 +2655,44 @@ static UINT8 s3_crtc_reg_read(running_machine &machine, UINT8 index)
case 0x42: // CR42 Mode Control
res = 0x0d; // hardcode to non-interlace
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 0x55:
+ res = s3.extended_dac_ctrl;
+ break;
case 0x67:
res = s3.ext_misc_ctrl_2;
break;
@@ -2623,6 +2773,129 @@ static void s3_crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data)
s3.write_count = 0;
}
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 &= ~0xc0000;
vga.crtc.start_addr |= ((data & 0x3) << 18);
@@ -2630,6 +2903,30 @@ static void s3_crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data)
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;
case 0x67:
s3.ext_misc_ctrl_2 = data;
s3_define_video_mode();
@@ -3966,8 +4263,8 @@ WRITE8_HANDLER( s3_mem_w )
case 0xbae8:
s3.fgmix = (s3.fgmix & 0xff00) | data;
break;
- case 0xbae9:
case 0x8137:
+ case 0xbae9:
s3.fgmix = (s3.fgmix & 0x00ff) | (data << 8);
break;
case 0x8138:
@@ -4015,6 +4312,26 @@ WRITE8_HANDLER( s3_mem_w )
case 0x814b:
s3.rect_width = (s3.rect_width & 0x00ff) | (data << 8);
break;
+ case 0x8150:
+ s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data;
+ if(s3.state == S3_DRAWING_RECT)
+ s3_wait_draw();
+ break;
+ case 0x8151:
+ s3.pixel_xfer = (s3.pixel_xfer & 0xffff00ff) | (data << 8);
+ if(s3.state == S3_DRAWING_RECT)
+ s3_wait_draw();
+ break;
+ case 0x8152:
+ s3.pixel_xfer = (s3.pixel_xfer & 0xff00ffff) | (data << 16);
+ if(s3.state == S3_DRAWING_RECT)
+ s3_wait_draw();
+ break;
+ case 0x8153:
+ s3.pixel_xfer = (s3.pixel_xfer & 0x00ffffff) | (data << 24);
+ if(s3.state == S3_DRAWING_RECT)
+ s3_wait_draw();
+ break;
case 0xbee8:
s3.mmio_bee8 = (s3.mmio_bee8 & 0xff00) | data;
break;
diff --git a/src/emu/video/pc_vga.h b/src/emu/video/pc_vga.h
index 3b05b4cdeb2..a001297f7b9 100644
--- a/src/emu/video/pc_vga.h
+++ b/src/emu/video/pc_vga.h
@@ -11,6 +11,7 @@
MACHINE_CONFIG_EXTERN( pcvideo_vga );
MACHINE_CONFIG_EXTERN( pcvideo_vga_isa );
+MACHINE_CONFIG_EXTERN( pcvideo_s3_isa );
VIDEO_START( vga );
@@ -31,6 +32,7 @@ void pc_vga_reset(running_machine &machine);
void *pc_vga_memory(void);
size_t pc_vga_memory_size(void);
void pc_video_start(running_machine &machine);
+void s3_video_start(running_machine &machine);
READ8_HANDLER(vga_port_03b0_r);
READ8_HANDLER(vga_port_03c0_r);