diff options
author | mahlemiut <mahlemiut@users.noreply.github.com> | 2013-04-07 02:13:42 +0000 |
---|---|---|
committer | mahlemiut <mahlemiut@users.noreply.github.com> | 2013-04-07 02:13:42 +0000 |
commit | 38716f6a64cafd134ac61170cf6c4f6b19d38a48 (patch) | |
tree | c561f74e24d5cccb229faadaa76f3026ab8ebf6f | |
parent | 4dba2235a1f7c1d8776bd29f69b1b8778d272ed0 (diff) |
s3virge: moved to separate source file (no whatsnew)
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | src/emu/video/pc_vga.c | 630 | ||||
-rw-r--r-- | src/emu/video/pc_vga.h | 33 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 | ||||
-rw-r--r-- | src/mess/video/isa_svga_s3.c | 1 | ||||
-rw-r--r-- | src/mess/video/isa_svga_s3.h | 1 | ||||
-rw-r--r-- | src/mess/video/s3virge.c | 641 | ||||
-rw-r--r-- | src/mess/video/s3virge.h | 46 |
8 files changed, 691 insertions, 664 deletions
diff --git a/.gitattributes b/.gitattributes index 8512e72fae9..24994604f35 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7974,6 +7974,8 @@ src/mess/video/primo.c svneol=native#text/plain src/mess/video/radio86.c svneol=native#text/plain src/mess/video/rm380z.c svneol=native#text/plain src/mess/video/rmnimbus.c svneol=native#text/plain +src/mess/video/s3virge.c svneol=native#text/plain +src/mess/video/s3virge.h svneol=native#text/plain src/mess/video/samcoupe.c svneol=native#text/plain src/mess/video/sapi1.c svneol=native#text/plain src/mess/video/special.c svneol=native#text/plain diff --git a/src/emu/video/pc_vga.c b/src/emu/video/pc_vga.c index 35de3c87619..890daef3ec6 100644 --- a/src/emu/video/pc_vga.c +++ b/src/emu/video/pc_vga.c @@ -118,7 +118,6 @@ 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>; @@ -5514,632 +5513,3 @@ 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 = 0x1c; - 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 0x43: - res = s3.cr43; - 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; - double m,n; - int r; - - if((vga.miscellaneous_output & 0xc) == 0x0c) - { - // Dot clock is set via SR12 and SR13 - m = vga.sequencer.data[0x13] & 0x7f; - n = vga.sequencer.data[0x12] & 0x1f; - r = (vga.sequencer.data[0x12] & 0x60) >> 5; - xtal = (double)((m+2.0f) / ((n+2.0f)*(double)(1<<r))) * 16000000; - //printf("DCLK set to %dHz M=%f N=%f R=%i\n",xtal,m,n,r); - } - - 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 0x01: svga.rgb8_en = 1; divisor = 2; break; - 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.cr3a & 0x10) >> 4; - svga.rgb15_en = 0; - svga.rgb16_en = 0; - svga.rgb32_en = 0; - } - if(s3.cr43 & 0x80) // Horizontal clock doubling (techincally, doubles horizontal CRT parameters) - divisor *= 2; - 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); - s3_define_video_mode(); - } - 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 0x3a: - s3.cr3a = data; - break; - case 0x40: - s3.enable_s3d = data & 0x01; // enable S3D registers - break; - case 0x42: - s3.cr42 = data; // bit 5 = interlace, bits 0-3 = dot clock (seems to be undocumented) - break; - case 0x43: - s3.cr43 = data; - 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: CR%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); -} diff --git a/src/emu/video/pc_vga.h b/src/emu/video/pc_vga.h index 1bd9584815e..478dd6c84f5 100644 --- a/src/emu/video/pc_vga.h +++ b/src/emu/video/pc_vga.h @@ -585,39 +585,6 @@ 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 class gamtor_vga_device : public svga_device diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 29aa5048f8f..9865032315e 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -1526,6 +1526,7 @@ $(MESSOBJ)/pcshare.a: \ $(MESS_VIDEO)/isa_vga_ati.o \ $(MESS_VIDEO)/isa_svga_tseng.o \ $(MESS_VIDEO)/isa_svga_s3.o \ + $(MESS_VIDEO)/s3virge.o \ $(MESS_VIDEO)/isa_svga_cirrus.o \ $(MESS_MACHINE)/i82371ab.o \ $(MESS_MACHINE)/i82371sb.o \ diff --git a/src/mess/video/isa_svga_s3.c b/src/mess/video/isa_svga_s3.c index b225422fbfc..6d568ea3921 100644 --- a/src/mess/video/isa_svga_s3.c +++ b/src/mess/video/isa_svga_s3.c @@ -6,7 +6,6 @@ #include "emu.h" #include "isa_svga_s3.h" -#include "video/pc_vga.h" ROM_START( s3_764 ) ROM_REGION(0x8000,"s3_764", 0) diff --git a/src/mess/video/isa_svga_s3.h b/src/mess/video/isa_svga_s3.h index 9dc0caf701d..83bf9561451 100644 --- a/src/mess/video/isa_svga_s3.h +++ b/src/mess/video/isa_svga_s3.h @@ -6,6 +6,7 @@ #include "emu.h" #include "machine/isa.h" #include "video/pc_vga.h" +#include "video/s3virge.h" //************************************************************************** // TYPE DEFINITIONS diff --git a/src/mess/video/s3virge.c b/src/mess/video/s3virge.c new file mode 100644 index 00000000000..f1786b4efe7 --- /dev/null +++ b/src/mess/video/s3virge.c @@ -0,0 +1,641 @@ +/* + * s3virge.c + * + * Implementation of the S3 Virge series of video card + * + * Current status: + * - Working on getting VESA video modes working better - 800x600 and higher skip every other line at + * 8-bit depth, but are fine at 15/16-bit depth. + * - S3D is not implemented at all, so no 2D/3D acceleration yet. + */ + +#include "video/s3virge.h" + +#define CRTC_PORT_ADDR ((vga.miscellaneous_output&1)?0x3d0:0x3b0) +#define LOG_REG 1 + +const device_type S3VIRGE = &device_creator<s3virge_vga_device>; + +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 = 0x1c; + 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 0x43: + res = s3.cr43; + 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; + double m,n; + int r; + + if((vga.miscellaneous_output & 0xc) == 0x0c) + { + // Dot clock is set via SR12 and SR13 + m = vga.sequencer.data[0x13] & 0x7f; + n = vga.sequencer.data[0x12] & 0x1f; + r = (vga.sequencer.data[0x12] & 0x60) >> 5; + xtal = (double)((m+2.0f) / ((n+2.0f)*(double)(1<<r))) * 16000000; + //printf("DCLK set to %dHz M=%f N=%f R=%i\n",xtal,m,n,r); + } + + 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 0x01: svga.rgb8_en = 1; divisor = 2; break; + 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.cr3a & 0x10) >> 4; + svga.rgb15_en = 0; + svga.rgb16_en = 0; + svga.rgb32_en = 0; + } + if(s3.cr43 & 0x80) // Horizontal clock doubling (techincally, doubles horizontal CRT parameters) + divisor *= 2; + 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); + s3_define_video_mode(); + } + 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 0x3a: + s3.cr3a = data; + break; + case 0x40: + s3.enable_s3d = data & 0x01; // enable S3D registers + break; + case 0x42: + s3.cr42 = data; // bit 5 = interlace, bits 0-3 = dot clock (seems to be undocumented) + break; + case 0x43: + s3.cr43 = data; + 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_REG) logerror("S3: CR%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); +} diff --git a/src/mess/video/s3virge.h b/src/mess/video/s3virge.h new file mode 100644 index 00000000000..f6c66896747 --- /dev/null +++ b/src/mess/video/s3virge.h @@ -0,0 +1,46 @@ +/* + * s3virge.h + * + * S3 ViRGE 2D/3D video card + * + */ + +#ifndef S3VIRGE_H_ +#define S3VIRGE_H_ + +#include "emu.h" +#include "video/pc_vga.h" + +// ======================> 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; + +#endif /* S3VIRGE_H_ */ |