trunk/src/emu/video/pc_vga.c
| r17685 | r17686 | |
| 236 | 236 | UINT16 mmio_9ae8; |
| 237 | 237 | UINT16 mmio_bee8; |
| 238 | 238 | |
| 239 | // hardware graphics cursor |
| 240 | UINT8 cursor_mode; |
| 241 | UINT16 cursor_x; |
| 242 | UINT16 cursor_y; |
| 243 | UINT16 cursor_start_addr; |
| 244 | UINT8 cursor_pattern_x; // cursor pattern origin |
| 245 | UINT8 cursor_pattern_y; |
| 246 | UINT8 cursor_fg[4]; |
| 247 | UINT8 cursor_bg[4]; |
| 248 | UINT8 cursor_fg_ptr; |
| 249 | UINT8 cursor_bg_ptr; |
| 250 | UINT8 extended_dac_ctrl; |
| 251 | |
| 239 | 252 | bool gpbusy; |
| 240 | 253 | int state; |
| 241 | 254 | }s3; |
| r17685 | r17686 | |
| 296 | 309 | vga.crtc.maximum_scan_line = 1; |
| 297 | 310 | } |
| 298 | 311 | |
| 312 | void s3_video_start(running_machine &machine) |
| 313 | { |
| 314 | int x; |
| 315 | // Avoid an infinite loop when displaying. 0 is not possible anyway. |
| 316 | vga.crtc.maximum_scan_line = 1; |
| 317 | // Initialise hardware graphics cursor colours, Windows 95 doesn't touch the registers for some reason |
| 318 | for(x=0;x<4;x++) |
| 319 | { |
| 320 | s3.cursor_fg[x] = 0xff; |
| 321 | s3.cursor_bg[x] = 0x00; |
| 322 | } |
| 323 | } |
| 324 | |
| 299 | 325 | static void vga_vh_text(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 300 | 326 | { |
| 301 | 327 | UINT8 ch, attr; |
| r17685 | r17686 | |
| 909 | 935 | |
| 910 | 936 | return 0; |
| 911 | 937 | } |
| 938 | |
| 939 | SCREEN_UPDATE_RGB32( pc_video_s3 ) |
| 940 | { |
| 941 | UINT8 cur_mode = 0; |
| 942 | |
| 943 | SCREEN_UPDATE32_CALL( pc_video ); |
| 944 | |
| 945 | cur_mode = pc_vga_choosevideomode(screen.machine()); |
| 946 | |
| 947 | // draw hardware graphics cursor |
| 948 | // TODO: support 16 bit and greater video modes |
| 949 | if(s3.cursor_mode & 0x01) // if cursor is enabled |
| 950 | { |
| 951 | UINT32 src; |
| 952 | UINT32* dst; |
| 953 | UINT8 val; |
| 954 | int x,y; |
| 955 | UINT16 cx = s3.cursor_x & 0x07ff; |
| 956 | UINT16 cy = s3.cursor_y & 0x07ff; |
| 957 | |
| 958 | if(cur_mode == SCREEN_OFF || cur_mode == TEXT_MODE || cur_mode == MONO_MODE || cur_mode == CGA_MODE || cur_mode == EGA_MODE) |
| 959 | return 0; // cursor only works in VGA or SVGA modes |
| 960 | |
| 961 | src = s3.cursor_start_addr * 1024; // start address is in units of 1024 bytes |
| 962 | // for(x=0;x<64;x++) |
| 963 | // 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]); |
| 964 | for(y=0;y<64;y++) |
| 965 | { |
| 966 | dst = &bitmap.pix32(cy + y, cx); |
| 967 | for(x=0;x<64;x++) |
| 968 | { |
| 969 | UINT16 bita = (vga.memory[(src+1) % vga.svga_intf.vram_size] | ((vga.memory[(src+0) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16)); |
| 970 | UINT16 bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16)); |
| 971 | val = ((bita & 0x01) << 1) | (bitb & 0x01); |
| 972 | if(s3.extended_dac_ctrl & 0x10) |
| 973 | { // X11 mode |
| 974 | switch(val) |
| 975 | { |
| 976 | case 0x00: |
| 977 | // no change |
| 978 | break; |
| 979 | case 0x01: |
| 980 | // no change |
| 981 | break; |
| 982 | case 0x02: |
| 983 | dst[x] = screen.machine().pens[s3.cursor_bg[0]]; |
| 984 | break; |
| 985 | case 0x03: |
| 986 | dst[x] = screen.machine().pens[s3.cursor_fg[0]]; |
| 987 | break; |
| 988 | } |
| 989 | } |
| 990 | else |
| 991 | { // Windows mode |
| 992 | switch(val) |
| 993 | { |
| 994 | case 0x00: |
| 995 | dst[x] = screen.machine().pens[s3.cursor_bg[0]]; |
| 996 | break; |
| 997 | case 0x01: |
| 998 | dst[x] = screen.machine().pens[s3.cursor_fg[0]]; |
| 999 | break; |
| 1000 | case 0x02: // screen data |
| 1001 | // no change |
| 1002 | break; |
| 1003 | case 0x03: // inverted screen data |
| 1004 | dst[x] = ~(dst[x]); |
| 1005 | break; |
| 1006 | } |
| 1007 | } |
| 1008 | if(x % 16 == 15) |
| 1009 | src+=4; |
| 1010 | } |
| 1011 | } |
| 1012 | } |
| 1013 | return 0; |
| 1014 | } |
| 1015 | |
| 912 | 1016 | /***************************************************************************/ |
| 913 | 1017 | |
| 914 | 1018 | INLINE UINT8 rotate_right(UINT8 val) |
| r17685 | r17686 | |
| 1985 | 2089 | MCFG_PALETTE_LENGTH(0x100) |
| 1986 | 2090 | MACHINE_CONFIG_END |
| 1987 | 2091 | |
| 2092 | MACHINE_CONFIG_FRAGMENT( pcvideo_s3_isa ) |
| 2093 | MCFG_SCREEN_ADD("screen", RASTER) |
| 2094 | MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480) |
| 2095 | MCFG_SCREEN_UPDATE_STATIC(pc_video_s3) |
| 2096 | |
| 2097 | MCFG_PALETTE_LENGTH(0x100) |
| 2098 | MACHINE_CONFIG_END |
| 2099 | |
| 1988 | 2100 | /****************************************** |
| 1989 | 2101 | |
| 1990 | 2102 | Tseng ET4000k implementation |
| r17685 | r17686 | |
| 2526 | 2638 | // res = 0x00; |
| 2527 | 2639 | // break; |
| 2528 | 2640 | case 0x30: // CR30 Chip ID/REV register |
| 2529 | | res = 0xc0; // BIOS is from a card with the 764 chipset (Trio64) |
| 2641 | 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 |
| 2530 | 2642 | break; |
| 2531 | 2643 | case 0x31: |
| 2532 | 2644 | res = s3.memory_config; |
| r17685 | r17686 | |
| 2543 | 2655 | case 0x42: // CR42 Mode Control |
| 2544 | 2656 | res = 0x0d; // hardcode to non-interlace |
| 2545 | 2657 | break; |
| 2658 | case 0x45: |
| 2659 | res = s3.cursor_mode; |
| 2660 | break; |
| 2661 | case 0x46: |
| 2662 | res = (s3.cursor_x & 0xff00) >> 8; |
| 2663 | break; |
| 2664 | case 0x47: |
| 2665 | res = s3.cursor_x & 0x00ff; |
| 2666 | break; |
| 2667 | case 0x48: |
| 2668 | res = (s3.cursor_y & 0xff00) >> 8; |
| 2669 | break; |
| 2670 | case 0x49: |
| 2671 | res = s3.cursor_y & 0x00ff; |
| 2672 | break; |
| 2673 | case 0x4a: |
| 2674 | res = s3.cursor_fg[s3.cursor_fg_ptr]; |
| 2675 | s3.cursor_fg_ptr = 0; |
| 2676 | break; |
| 2677 | case 0x4b: |
| 2678 | res = s3.cursor_bg[s3.cursor_bg_ptr]; |
| 2679 | s3.cursor_bg_ptr = 0; |
| 2680 | break; |
| 2681 | case 0x4c: |
| 2682 | res = (s3.cursor_start_addr & 0xff00) >> 8; |
| 2683 | break; |
| 2684 | case 0x4d: |
| 2685 | res = s3.cursor_start_addr & 0x00ff; |
| 2686 | break; |
| 2687 | case 0x4e: |
| 2688 | res = s3.cursor_pattern_x; |
| 2689 | break; |
| 2690 | case 0x4f: |
| 2691 | res = s3.cursor_pattern_y; |
| 2692 | break; |
| 2693 | case 0x55: |
| 2694 | res = s3.extended_dac_ctrl; |
| 2695 | break; |
| 2546 | 2696 | case 0x67: |
| 2547 | 2697 | res = s3.ext_misc_ctrl_2; |
| 2548 | 2698 | break; |
| r17685 | r17686 | |
| 2623 | 2773 | s3.write_count = 0; |
| 2624 | 2774 | } |
| 2625 | 2775 | break; |
| 2776 | /* |
| 2777 | 3d4h index 45h (R/W): CR45 Hardware Graphics Cursor Mode |
| 2778 | bit 0 HWGC ENB. Hardware Graphics Cursor Enable. Set to enable the |
| 2779 | HardWare Cursor in VGA and enhanced modes. |
| 2780 | 1 (911/24) Delay Timing for Pattern Data Fetch |
| 2781 | 2 (801/5,928) Hardware Cursor Horizontal Stretch 2. If set the cursor |
| 2782 | pixels are stretched horizontally to two bytes and items 0 and 1 of |
| 2783 | the fore/background stacks in 3d4h index 4Ah/4Bh are used. |
| 2784 | 3 (801/5,928) Hardware Cursor Horizontal Stretch 3. If set the cursor |
| 2785 | pixels are stretched horizontally to three bytes and items 0,1 and |
| 2786 | 2 of the fore/background stacks in 3d4h index 4Ah/4Bh are used. |
| 2787 | 2-3 (805i,864/964) HWC-CSEL. Hardware Cursor Color Select. |
| 2788 | 0: 4/8bit, 1: 15/16bt, 2: 24bit, 3: 32bit |
| 2789 | Note: So far I've had better luck with: 0: 8/15/16bit, 1: 32bit?? |
| 2790 | 4 (80x +) Hardware Cursor Right Storage. If set the cursor data is |
| 2791 | stored in the last 256 bytes of 4 1Kyte lines (4bits/pixel) or the |
| 2792 | last 512 bytes of 2 2Kbyte lines (8bits/pixel). Intended for |
| 2793 | 1280x1024 modes where there are no free lines at the bottom. |
| 2794 | 5 (928) Cursor Control Enable for Brooktree Bt485 DAC. If set and 3d4h |
| 2795 | index 55h bit 5 is set the HC1 output becomes the ODF and the HC0 |
| 2796 | output becomes the CDE |
| 2797 | (964) BT485 ODF Selection for Bt485A RAMDAC. If set pin 185 (RS3 |
| 2798 | /ODF) is the ODF output to a Bt485A compatible RamDAC (low for even |
| 2799 | fields and high for odd fields), if clear pin185 is the RS3 output. |
| 2800 | */ |
| 2801 | case 0x45: |
| 2802 | s3.cursor_mode = data; |
| 2803 | break; |
| 2804 | /* |
| 2805 | 3d4h index 46h M(R/W): CR46/7 Hardware Graphics Cursor Origin-X |
| 2806 | bit 0-10 The HardWare Cursor X position. For 64k modes this value should be |
| 2807 | twice the actual X co-ordinate. |
| 2808 | */ |
| 2809 | case 0x46: |
| 2810 | s3.cursor_x = (s3.cursor_x & 0x00ff) | (data << 8); |
| 2811 | break; |
| 2812 | case 0x47: |
| 2813 | s3.cursor_x = (s3.cursor_x & 0xff00) | data; |
| 2814 | break; |
| 2815 | /* |
| 2816 | 3d4h index 48h M(R/W): CR48/9 Hardware Graphics Cursor Origin-Y |
| 2817 | bit 0-9 (911/24) The HardWare Cursor Y position. |
| 2818 | 0-10 (80x +) The HardWare Cursor Y position. |
| 2819 | Note: The position is activated when the high byte of the Y coordinate (index |
| 2820 | 48h) is written, so this byte should be written last (not 911/924 ?) |
| 2821 | */ |
| 2822 | case 0x48: |
| 2823 | s3.cursor_y = (s3.cursor_y & 0x00ff) | (data << 8); |
| 2824 | break; |
| 2825 | case 0x49: |
| 2826 | s3.cursor_y = (s3.cursor_y & 0xff00) | data; |
| 2827 | break; |
| 2828 | |
| 2829 | /* |
| 2830 | 3d4h index 4Ah (R/W): Hardware Graphics Cursor Foreground Stack (80x +) |
| 2831 | bit 0-7 The Foreground Cursor color. Three bytes (4 for the 864/964) are |
| 2832 | stacked here. When the Cursor Mode register (3d4h index 45h) is read |
| 2833 | the stackpointer is reset. When a byte is written the byte is |
| 2834 | written into the current top of stack and the stackpointer is |
| 2835 | increased. The first byte written (item 0) is allways used, the |
| 2836 | other two(3) only when Hardware Cursor Horizontal Stretch (3d4h |
| 2837 | index 45h bit 2-3) is enabled. |
| 2838 | */ |
| 2839 | case 0x4a: |
| 2840 | s3.cursor_fg[s3.cursor_fg_ptr++] = data; |
| 2841 | s3.cursor_fg_ptr %= 4; |
| 2842 | break; |
| 2843 | /* |
| 2844 | 3d4h index 4Bh (R/W): Hardware Graphics Cursor Background Stack (80x +) |
| 2845 | bit 0-7 The Background Cursor color. Three bytes (4 for the 864/964) are |
| 2846 | stacked here. When the Cursor Mode register (3d4h index 45h) is read |
| 2847 | the stackpointer is reset. When a byte is written the byte is |
| 2848 | written into the current top of stack and the stackpointer is |
| 2849 | increased. The first byte written (item 0) is allways used, the |
| 2850 | other two(3) only when Hardware Cursor Horizontal Stretch (3d4h |
| 2851 | index 45h bit 2-3) is enabled. |
| 2852 | */ |
| 2853 | case 0x4b: |
| 2854 | s3.cursor_bg[s3.cursor_bg_ptr++] = data; |
| 2855 | s3.cursor_bg_ptr %= 4; |
| 2856 | break; |
| 2857 | /* |
| 2858 | 3d4h index 4Ch M(R/W): CR4C/D Hardware Graphics Cursor Storage Start Address |
| 2859 | bit 0-9 (911,924) HCS_STADR. Hardware Graphics Cursor Storage Start Address |
| 2860 | 0-11 (80x,928) HWGC_STA. Hardware Graphics Cursor Storage Start Address |
| 2861 | 0-12 (864,964) HWGC_STA. Hardware Graphics Cursor Storage Start Address |
| 2862 | Address of the HardWare Cursor Map in units of 1024 bytes (256 bytes |
| 2863 | for planar modes). The cursor map is a 64x64 bitmap with 2 bits (A |
| 2864 | and B) per pixel. The map is stored as one word (16 bits) of bit A, |
| 2865 | followed by one word with the corresponding 16 B bits. |
| 2866 | The bits are interpreted as: |
| 2867 | A B MS-Windows: X-11: |
| 2868 | 0 0 Background Screen data |
| 2869 | 0 1 Foreground Screen data |
| 2870 | 1 0 Screen data Background |
| 2871 | 1 1 Inverted screen Foreground |
| 2872 | The Windows/X11 switch is only available for the 80x +. |
| 2873 | (911/24) For 64k color modes the cursor is stored as one byte (8 |
| 2874 | bits) of A bits, followed by the 8 B-bits, and each bit in the |
| 2875 | cursor should be doubled to provide a consistent cursor image. |
| 2876 | (801/5,928) For Hi/True color modes use the Horizontal Stretch bits |
| 2877 | (3d4h index 45h bits 2 and 3). |
| 2878 | */ |
| 2879 | case 0x4c: |
| 2880 | s3.cursor_start_addr = (s3.cursor_start_addr & 0x00ff) | (data << 8); |
| 2881 | break; |
| 2882 | case 0x4d: |
| 2883 | s3.cursor_start_addr = (s3.cursor_start_addr & 0xff00) | data; |
| 2884 | break; |
| 2885 | /* |
| 2886 | 3d4h index 4Eh (R/W): CR4E HGC Pattern Disp Start X-Pixel Position |
| 2887 | bit 0-5 Pattern Display Start X-Pixel Position. |
| 2888 | */ |
| 2889 | case 0x4e: |
| 2890 | s3.cursor_pattern_x = data; |
| 2891 | break; |
| 2892 | /* |
| 2893 | 3d4h index 4Fh (R/W): CR4F HGC Pattern Disp Start Y-Pixel Position |
| 2894 | bit 0-5 Pattern Display Start Y-Pixel Position. |
| 2895 | */ |
| 2896 | case 0x4f: |
| 2897 | s3.cursor_pattern_y = data; |
| 2898 | break; |
| 2626 | 2899 | case 0x51: |
| 2627 | 2900 | vga.crtc.start_addr &= ~0xc0000; |
| 2628 | 2901 | vga.crtc.start_addr |= ((data & 0x3) << 18); |
| r17685 | r17686 | |
| 2630 | 2903 | case 0x53: |
| 2631 | 2904 | s3.cr53 = data; |
| 2632 | 2905 | break; |
| 2906 | /* |
| 2907 | 3d4h index 55h (R/W): Extended Video DAC Control Register (80x +) |
| 2908 | bit 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the |
| 2909 | RAMDAC, allowing access to all 8 or 16 registers on advanced RAMDACs. |
| 2910 | If this field is 0, 3d4h index 43h bit 1 is active. |
| 2911 | 2 Enable General Input Port Read. If set DAC reads are disabled and the |
| 2912 | STRD strobe for reading the General Input Port is enabled for reading |
| 2913 | while DACRD is active, if clear DAC reads are enabled. |
| 2914 | 3 (928) Enable External SID Operation if set. If set video data is |
| 2915 | passed directly from the VRAMs to the DAC rather than through the |
| 2916 | VGA chip |
| 2917 | 4 Hardware Cursor MS/X11 Mode. If set the Hardware Cursor is in X11 |
| 2918 | mode, if clear in MS-Windows mode |
| 2919 | 5 (80x,928) Hardware Cursor External Operation Mode. If set the two |
| 2920 | bits of cursor data ,is output on the HC[0-1] pins for the video DAC |
| 2921 | The SENS pin becomes HC1 and the MID2 pin becomes HC0. |
| 2922 | 6 ?? |
| 2923 | 7 (80x,928) Disable PA Output. If set PA[0-7] and VCLK are tristated. |
| 2924 | (864/964) TOFF VCLK. Tri-State Off VCLK Output. VCLK output tri |
| 2925 | -stated if set |
| 2926 | */ |
| 2927 | case 0x55: |
| 2928 | s3.extended_dac_ctrl = data; |
| 2929 | break; |
| 2633 | 2930 | case 0x67: |
| 2634 | 2931 | s3.ext_misc_ctrl_2 = data; |
| 2635 | 2932 | s3_define_video_mode(); |
| r17685 | r17686 | |
| 3966 | 4263 | case 0xbae8: |
| 3967 | 4264 | s3.fgmix = (s3.fgmix & 0xff00) | data; |
| 3968 | 4265 | break; |
| 4266 | case 0x8137: |
| 3969 | 4267 | case 0xbae9: |
| 3970 | | case 0x8137: |
| 3971 | 4268 | s3.fgmix = (s3.fgmix & 0x00ff) | (data << 8); |
| 3972 | 4269 | break; |
| 3973 | 4270 | case 0x8138: |
| r17685 | r17686 | |
| 4015 | 4312 | case 0x814b: |
| 4016 | 4313 | s3.rect_width = (s3.rect_width & 0x00ff) | (data << 8); |
| 4017 | 4314 | break; |
| 4315 | case 0x8150: |
| 4316 | s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data; |
| 4317 | if(s3.state == S3_DRAWING_RECT) |
| 4318 | s3_wait_draw(); |
| 4319 | break; |
| 4320 | case 0x8151: |
| 4321 | s3.pixel_xfer = (s3.pixel_xfer & 0xffff00ff) | (data << 8); |
| 4322 | if(s3.state == S3_DRAWING_RECT) |
| 4323 | s3_wait_draw(); |
| 4324 | break; |
| 4325 | case 0x8152: |
| 4326 | s3.pixel_xfer = (s3.pixel_xfer & 0xff00ffff) | (data << 16); |
| 4327 | if(s3.state == S3_DRAWING_RECT) |
| 4328 | s3_wait_draw(); |
| 4329 | break; |
| 4330 | case 0x8153: |
| 4331 | s3.pixel_xfer = (s3.pixel_xfer & 0x00ffffff) | (data << 24); |
| 4332 | if(s3.state == S3_DRAWING_RECT) |
| 4333 | s3_wait_draw(); |
| 4334 | break; |
| 4018 | 4335 | case 0xbee8: |
| 4019 | 4336 | s3.mmio_bee8 = (s3.mmio_bee8 & 0xff00) | data; |
| 4020 | 4337 | break; |