trunk/src/emu/video/pc_vga.c
r17525 | r17526 | |
214 | 214 | UINT16 rect_height; |
215 | 215 | UINT32 fgcolour; |
216 | 216 | UINT32 bgcolour; |
| 217 | UINT16 fgmix; |
| 218 | UINT16 bgmix; |
217 | 219 | UINT32 pixel_xfer; |
218 | 220 | INT16 wait_rect_x; |
219 | 221 | INT16 wait_rect_y; |
| 222 | INT16 scissors_left; |
| 223 | INT16 scissors_right; |
| 224 | INT16 scissors_top; |
| 225 | INT16 scissors_bottom; |
220 | 226 | UINT8 bus_size; |
221 | 227 | UINT8 multifunc_sel; |
222 | 228 | UINT8 write_count; |
r17525 | r17526 | |
2724 | 2730 | } |
2725 | 2731 | |
2726 | 2732 | /* accelerated ports, TBD ... */ |
| 2733 | |
| 2734 | |
| 2735 | static void s3_write_fg(UINT32 offset) |
| 2736 | { |
| 2737 | UINT8 dst = vga.memory[offset]; |
| 2738 | UINT8 src; |
| 2739 | |
| 2740 | // determine source |
| 2741 | switch(s3.fgmix & 0x0060) |
| 2742 | { |
| 2743 | case 0x0000: |
| 2744 | src = s3.bgcolour; |
| 2745 | break; |
| 2746 | case 0x0020: |
| 2747 | src = s3.fgcolour; |
| 2748 | break; |
| 2749 | case 0x0040: |
| 2750 | src = s3.pixel_xfer; |
| 2751 | break; |
| 2752 | case 0x0060: |
| 2753 | // TODO: Bitmap data; |
| 2754 | break; |
| 2755 | } |
| 2756 | |
| 2757 | // write the data |
| 2758 | switch(s3.fgmix & 0x000f) |
| 2759 | { |
| 2760 | case 0x0000: |
| 2761 | vga.memory[offset] = !dst; |
| 2762 | break; |
| 2763 | case 0x0001: |
| 2764 | // TODO: false |
| 2765 | break; |
| 2766 | case 0x0002: |
| 2767 | // TODO: true |
| 2768 | break; |
| 2769 | case 0x0003: |
| 2770 | // change nothing, pixel is unchanged |
| 2771 | break; |
| 2772 | case 0x0004: |
| 2773 | vga.memory[offset] = !src; |
| 2774 | break; |
| 2775 | case 0x0005: |
| 2776 | vga.memory[offset] = src ^ dst; |
| 2777 | break; |
| 2778 | case 0x0006: |
| 2779 | vga.memory[offset] = !(src ^ dst); |
| 2780 | break; |
| 2781 | case 0x0007: |
| 2782 | vga.memory[offset] = src; |
| 2783 | break; |
| 2784 | case 0x0008: |
| 2785 | vga.memory[offset] = !(src & dst); |
| 2786 | break; |
| 2787 | case 0x0009: |
| 2788 | vga.memory[offset] = (!src) | dst; |
| 2789 | break; |
| 2790 | case 0x000a: |
| 2791 | vga.memory[offset] = src | (!dst); |
| 2792 | break; |
| 2793 | case 0x000b: |
| 2794 | vga.memory[offset] = src | dst; |
| 2795 | break; |
| 2796 | case 0x000c: |
| 2797 | vga.memory[offset] = src & dst; |
| 2798 | break; |
| 2799 | case 0x000d: |
| 2800 | vga.memory[offset] = src & (!dst); |
| 2801 | break; |
| 2802 | case 0x000e: |
| 2803 | vga.memory[offset] = (!src) & dst; |
| 2804 | break; |
| 2805 | case 0x000f: |
| 2806 | vga.memory[offset] = !(src | dst); |
| 2807 | break; |
| 2808 | } |
| 2809 | } |
| 2810 | |
| 2811 | static void s3_write_bg(UINT32 offset) |
| 2812 | { |
| 2813 | UINT8 dst = vga.memory[offset]; |
| 2814 | UINT8 src; |
| 2815 | // determine source |
| 2816 | switch(s3.bgmix & 0x0060) |
| 2817 | { |
| 2818 | case 0x0000: |
| 2819 | src = s3.bgcolour; |
| 2820 | break; |
| 2821 | case 0x0020: |
| 2822 | src = s3.fgcolour; |
| 2823 | break; |
| 2824 | case 0x0040: |
| 2825 | src = s3.pixel_xfer; |
| 2826 | break; |
| 2827 | case 0x0060: |
| 2828 | // TODO: Bitmap data; |
| 2829 | break; |
| 2830 | } |
| 2831 | |
| 2832 | // write the data |
| 2833 | switch(s3.bgmix & 0x000f) |
| 2834 | { |
| 2835 | case 0x0000: |
| 2836 | vga.memory[offset] = !dst; |
| 2837 | break; |
| 2838 | case 0x0001: |
| 2839 | // TODO: false |
| 2840 | break; |
| 2841 | case 0x0002: |
| 2842 | // TODO: true |
| 2843 | break; |
| 2844 | case 0x0003: |
| 2845 | // change nothing, pixel is unchanged |
| 2846 | break; |
| 2847 | case 0x0004: |
| 2848 | vga.memory[offset] = !src; |
| 2849 | break; |
| 2850 | case 0x0005: |
| 2851 | vga.memory[offset] = src ^ dst; |
| 2852 | break; |
| 2853 | case 0x0006: |
| 2854 | vga.memory[offset] = !(src ^ dst); |
| 2855 | break; |
| 2856 | case 0x0007: |
| 2857 | vga.memory[offset] = src; |
| 2858 | break; |
| 2859 | case 0x0008: |
| 2860 | vga.memory[offset] = !(src & dst); |
| 2861 | break; |
| 2862 | case 0x0009: |
| 2863 | vga.memory[offset] = (!src) | dst; |
| 2864 | break; |
| 2865 | case 0x000a: |
| 2866 | vga.memory[offset] = src | (!dst); |
| 2867 | break; |
| 2868 | case 0x000b: |
| 2869 | vga.memory[offset] = src | dst; |
| 2870 | break; |
| 2871 | case 0x000c: |
| 2872 | vga.memory[offset] = src & dst; |
| 2873 | break; |
| 2874 | case 0x000d: |
| 2875 | vga.memory[offset] = src & (!dst); |
| 2876 | break; |
| 2877 | case 0x000e: |
| 2878 | vga.memory[offset] = (!src) & dst; |
| 2879 | break; |
| 2880 | case 0x000f: |
| 2881 | vga.memory[offset] = !(src | dst); |
| 2882 | break; |
| 2883 | } |
| 2884 | } |
2727 | 2885 | /* |
2728 | 2886 | 9AE8h W(R): Graphics Processor Status Register (GP_STAT) |
2729 | 2887 | bit 0-7 Queue State. |
r17525 | r17526 | |
2881 | 3039 | offset += (VGA_LINE_LENGTH * s3.curr_y); |
2882 | 3040 | offset += s3.curr_x; |
2883 | 3041 | if(data & 0x0020) |
2884 | | dir_x = 2; |
| 3042 | dir_x = 1; |
2885 | 3043 | else |
2886 | | dir_x -= 2; |
| 3044 | dir_x -= 1; |
2887 | 3045 | for(y=0;y<=s3.rect_height;y++) |
2888 | 3046 | { |
2889 | 3047 | for(x=0;x<=s3.rect_width;x+=dir_x) |
2890 | 3048 | { |
2891 | | vga.memory[(offset+x) % vga.svga_intf.vram_size] = s3.fgcolour & 0x000000ff; |
2892 | | vga.memory[(offset+x+1) % vga.svga_intf.vram_size] = (s3.fgcolour & 0x0000ff00) >> 8; |
| 3049 | s3_write_fg((offset+x) % vga.svga_intf.vram_size); |
2893 | 3050 | } |
2894 | 3051 | if(data & 0x0080) |
2895 | 3052 | offset += VGA_LINE_LENGTH; |
r17525 | r17526 | |
3084 | 3241 | { |
3085 | 3242 | case 0: |
3086 | 3243 | return s3.rect_height; |
| 3244 | case 1: |
| 3245 | return s3.scissors_top; |
| 3246 | case 2: |
| 3247 | return s3.scissors_left; |
| 3248 | case 3: |
| 3249 | return s3.scissors_bottom; |
| 3250 | case 4: |
| 3251 | return s3.scissors_right; |
3087 | 3252 | // TODO: remaining functions |
3088 | 3253 | default: |
3089 | 3254 | logerror("S3: Unimplemented multifunction register %i selected\n",s3.multifunc_sel); |
r17525 | r17526 | |
3106 | 3271 | logerror("S3: Minor Axis Pixel Count / Rectangle Height write %04x\n",data); |
3107 | 3272 | break; |
3108 | 3273 | /* |
| 3274 | BEE8h index 01h W(R/W): Top Scissors Register (SCISSORS_T). |
| 3275 | bit 0-10 (911/924) Clipping Top Limit. Defines the upper bound of the |
| 3276 | Clipping Rectangle (Lowest Y coordinate). |
| 3277 | 0-11 (80x +) Clipping Top Limit. See above |
| 3278 | |
| 3279 | BEE8h index 02h W(R/W): Left Scissors Registers (SCISSORS_L). |
| 3280 | bit 0-10 (911,924) Clipping Left Limit. Defines the left bound of the |
| 3281 | Clipping Rectangle (Lowest X coordinate). |
| 3282 | 0-11 (80x +) Clipping Left Limit. See above. |
| 3283 | |
| 3284 | BEE8h index 03h W(R/W): Bottom Scissors Register (SCISSORS_B). |
| 3285 | bit 0-10 (911,924) Clipping Bottom Limit. Defines the bottom bound of the |
| 3286 | Clipping Rectangle (Highest Y coordinate). |
| 3287 | 0-11 (80x +) Clipping Bottom Limit. See above. |
| 3288 | |
| 3289 | BEE8h index 04h W(R/W): Right Scissors Register (SCISSORS_R). |
| 3290 | bit 0-10 (911,924) Clipping Right Limit. Defines the right bound of the |
| 3291 | Clipping Rectangle (Highest X coordinate). |
| 3292 | 0-11 (80x +) Clipping Bottom Limit. See above. |
| 3293 | */ |
| 3294 | case 0x1000: |
| 3295 | s3.scissors_top = data & 0x0fff; |
| 3296 | logerror("S3: Scissors Top write %04x\n",data); |
| 3297 | break; |
| 3298 | case 0x2000: |
| 3299 | s3.scissors_left = data & 0x0fff; |
| 3300 | logerror("S3: Scissors Left write %04x\n",data); |
| 3301 | break; |
| 3302 | case 0x3000: |
| 3303 | s3.scissors_bottom = data & 0x0fff; |
| 3304 | logerror("S3: Scissors Bottom write %04x\n",data); |
| 3305 | break; |
| 3306 | case 0x4000: |
| 3307 | s3.scissors_right = data & 0x0fff; |
| 3308 | logerror("S3: Scissors Right write %04x\n",data); |
| 3309 | break; |
| 3310 | /* |
3109 | 3311 | BEE8h index 0Fh W(W): Read Register Select Register (READ_SEL) (801/5,928) |
3110 | 3312 | bit 0-2 (911-928) READ-REG-SEL. Read Register Select. Selects the register |
3111 | 3313 | that is actually read when a read of BEE8h happens. Each read of |
r17525 | r17526 | |
3147 | 3349 | off += s3.wait_rect_x; |
3148 | 3350 | for(x=0;x<data_size;x++) |
3149 | 3351 | { |
3150 | | if(s3.wait_rect_x >= 0 || s3.wait_rect_y >= 0) |
| 3352 | if(s3.wait_rect_x >= 0 && s3.wait_rect_y >= 0) |
3151 | 3353 | { |
3152 | | if(s3.current_cmd & 0x1000) |
| 3354 | // check clipping rectangle |
| 3355 | if(s3.wait_rect_x >= s3.scissors_left && s3.wait_rect_x <= s3.scissors_right && s3.wait_rect_y >= s3.scissors_top && s3.wait_rect_y <= s3.scissors_bottom) |
3153 | 3356 | { |
3154 | | xfer = ((s3.pixel_xfer & 0x000000ff) << 8) | ((s3.pixel_xfer & 0x0000ff00) >> 8) |
3155 | | | ((s3.pixel_xfer & 0x00ff0000) << 8) | ((s3.pixel_xfer & 0xff000000) >> 8); |
| 3357 | if(s3.current_cmd & 0x1000) |
| 3358 | { |
| 3359 | xfer = ((s3.pixel_xfer & 0x000000ff) << 8) | ((s3.pixel_xfer & 0x0000ff00) >> 8) |
| 3360 | | ((s3.pixel_xfer & 0x00ff0000) << 8) | ((s3.pixel_xfer & 0xff000000) >> 8); |
| 3361 | } |
| 3362 | else |
| 3363 | xfer = s3.pixel_xfer; |
| 3364 | if((xfer & ((1<<(data_size-1))>>x)) != 0) |
| 3365 | s3_write_fg(off % vga.svga_intf.vram_size); |
| 3366 | else |
| 3367 | s3_write_bg(off % vga.svga_intf.vram_size); |
3156 | 3368 | } |
3157 | | else |
3158 | | xfer = s3.pixel_xfer; |
3159 | | if((xfer & ((1<<(data_size-1))>>x)) != 0) |
3160 | | vga.memory[off] = s3.fgcolour & 0x00ff; |
3161 | 3369 | } |
3162 | 3370 | off++; |
3163 | 3371 | s3.wait_rect_x++; |
r17525 | r17526 | |
3172 | 3380 | } |
3173 | 3381 | } |
3174 | 3382 | } |
3175 | | logerror("S3: Wait Draw data = %08x\n",s3.pixel_xfer); |
3176 | 3383 | } |
3177 | 3384 | |
| 3385 | /* |
| 3386 | B6E8h W(R/W): Background Mix Register (BKGD_MIX) |
| 3387 | bit 0-3 Background MIX (BACKMIX). |
| 3388 | 00 not DST |
| 3389 | 01 0 (false) |
| 3390 | 02 1 (true) |
| 3391 | 03 2 DST |
| 3392 | 04 not SRC |
| 3393 | 05 SRC xor DST |
| 3394 | 06 not (SRC xor DST) |
| 3395 | 07 SRC |
| 3396 | 08 not (SRC and DST) |
| 3397 | 09 (not SRC) or DST |
| 3398 | 0A SRC or (not DST) |
| 3399 | 0B SRC or DST |
| 3400 | 0C SRC and DST |
| 3401 | 0D SRC and (not DST) |
| 3402 | 0E (not SRC) and DST |
| 3403 | 0F not (SRC or DST) |
| 3404 | DST is always the destination bitmap, bit SRC has four |
| 3405 | possible sources selected by the BSS bits. |
| 3406 | 5-6 Background Source Select (BSS) |
| 3407 | 0 BSS is Background Color |
| 3408 | 1 BSS is Foreground Color |
| 3409 | 2 BSS is Pixel Data from the PIX_TRANS register (E2E8h) |
| 3410 | 3 BSS is Bitmap Data (Source data from display buffer). |
| 3411 | */ |
| 3412 | READ16_HANDLER(s3_backmix_r) |
| 3413 | { |
| 3414 | return s3.bgmix; |
| 3415 | } |
| 3416 | |
| 3417 | WRITE16_HANDLER(s3_backmix_w) |
| 3418 | { |
| 3419 | s3.bgmix = data; |
| 3420 | } |
| 3421 | |
| 3422 | READ16_HANDLER(s3_foremix_r) |
| 3423 | { |
| 3424 | return s3.fgmix; |
| 3425 | } |
| 3426 | |
| 3427 | WRITE16_HANDLER(s3_foremix_w) |
| 3428 | { |
| 3429 | s3.fgmix = data; |
| 3430 | } |
| 3431 | |
3178 | 3432 | READ16_HANDLER(s3_pixel_xfer_r) |
3179 | 3433 | { |
3180 | 3434 | if(offset == 1) |
trunk/src/mess/video/isa_svga_s3.c
r17525 | r17526 | |
86 | 86 | m_isa->install16_device(0x9ae8, 0x9aeb, 0, 0, FUNC(s3_gpstatus_r), FUNC(s3_cmd_w)); |
87 | 87 | m_isa->install16_device(0xa2e8, 0xa2eb, 0, 0, FUNC(s3_bgcolour_r), FUNC(s3_bgcolour_w)); |
88 | 88 | m_isa->install16_device(0xa6e8, 0xa6eb, 0, 0, FUNC(s3_fgcolour_r), FUNC(s3_fgcolour_w)); |
| 89 | m_isa->install16_device(0xb6e8, 0xb6eb, 0, 0, FUNC(s3_backmix_r), FUNC(s3_backmix_w)); |
| 90 | m_isa->install16_device(0xbae8, 0xbaeb, 0, 0, FUNC(s3_foremix_r), FUNC(s3_foremix_w)); |
89 | 91 | m_isa->install16_device(0xbee8, 0xbeeb, 0, 0, FUNC(s3_multifunc_r), FUNC(s3_multifunc_w)); |
90 | 92 | m_isa->install16_device(0xe2e8, 0xe2eb, 0, 0, FUNC(s3_pixel_xfer_r), FUNC(s3_pixel_xfer_w)); |
91 | 93 | |