trunk/src/emu/video/pc_vga.c
r17522 | r17523 | |
219 | 219 | INT16 wait_rect_y; |
220 | 220 | UINT8 bus_size; |
221 | 221 | UINT8 multifunc_sel; |
| 222 | UINT8 write_count; |
222 | 223 | bool gpbusy; |
223 | 224 | int state; |
224 | 225 | }s3; |
r17522 | r17523 | |
2594 | 2595 | case 0x40: |
2595 | 2596 | s3.enable_8514 = data & 0x01; // enable 8514/A registers (x2e8, x6e8, xae8, xee8) |
2596 | 2597 | if(data & 0x01) |
| 2598 | { |
2597 | 2599 | s3.state = S3_IDLE; |
| 2600 | s3.gpbusy = false; |
| 2601 | s3.write_count = 0; |
| 2602 | } |
2598 | 2603 | break; |
2599 | 2604 | case 0x51: |
2600 | 2605 | vga.crtc.start_addr &= ~0xc0000; |
r17522 | r17523 | |
2864 | 2869 | if(data & 0x0100) // WAIT (for read/write of PIXEL TRANSFER (E2E8)) |
2865 | 2870 | { |
2866 | 2871 | s3.state = S3_DRAWING_RECT; |
2867 | | s3.gpbusy = true; |
| 2872 | //s3.gpbusy = true; // DirectX 5 keeps waiting for the busy bit to be clear... |
2868 | 2873 | s3.wait_rect_x = s3.curr_x; |
2869 | 2874 | s3.wait_rect_y = s3.curr_y; |
2870 | 2875 | s3.bus_size = (data & 0x0600) >> 9; |
r17522 | r17523 | |
3125 | 3130 | } |
3126 | 3131 | } |
3127 | 3132 | |
| 3133 | static void s3_wait_draw() |
| 3134 | { |
| 3135 | int x,data_size = 0; |
| 3136 | UINT32 off,xfer = 0; |
| 3137 | |
| 3138 | // the data in the pixel transfer register masks the rectangle output(?) |
| 3139 | if(s3.bus_size == 0) // 8-bit |
| 3140 | data_size = 8; |
| 3141 | if(s3.bus_size == 1) // 16-bit |
| 3142 | data_size = 16; |
| 3143 | if(s3.bus_size == 2) // 32-bit |
| 3144 | data_size = 32; |
| 3145 | off = VGA_START_ADDRESS; |
| 3146 | off += (VGA_LINE_LENGTH * s3.wait_rect_y); |
| 3147 | off += s3.wait_rect_x; |
| 3148 | for(x=0;x<data_size;x++) |
| 3149 | { |
| 3150 | if(s3.wait_rect_x >= 0 || s3.wait_rect_y >= 0) |
| 3151 | { |
| 3152 | if(s3.current_cmd & 0x1000) |
| 3153 | { |
| 3154 | xfer = ((s3.pixel_xfer & 0x000000ff) << 8) | ((s3.pixel_xfer & 0x0000ff00) >> 8) |
| 3155 | | ((s3.pixel_xfer & 0x00ff0000) << 8) | ((s3.pixel_xfer & 0xff000000) >> 8); |
| 3156 | } |
| 3157 | else |
| 3158 | xfer = s3.pixel_xfer; |
| 3159 | if((xfer & ((1<<(data_size-1))>>x)) != 0) |
| 3160 | vga.memory[off] = s3.fgcolour & 0x00ff; |
| 3161 | } |
| 3162 | off++; |
| 3163 | s3.wait_rect_x++; |
| 3164 | if(s3.wait_rect_x > s3.curr_x + s3.rect_width) |
| 3165 | { |
| 3166 | s3.wait_rect_x = s3.curr_x; |
| 3167 | s3.wait_rect_y++; |
| 3168 | if(s3.wait_rect_y > s3.curr_y + s3.rect_height) |
| 3169 | { |
| 3170 | s3.state = S3_IDLE; |
| 3171 | s3.gpbusy = false; |
| 3172 | } |
| 3173 | } |
| 3174 | } |
| 3175 | logerror("S3: Wait Draw data = %08x\n",s3.pixel_xfer); |
| 3176 | } |
| 3177 | |
3128 | 3178 | READ16_HANDLER(s3_pixel_xfer_r) |
3129 | 3179 | { |
3130 | 3180 | if(offset == 1) |
r17522 | r17523 | |
3135 | 3185 | |
3136 | 3186 | WRITE16_HANDLER(s3_pixel_xfer_w) |
3137 | 3187 | { |
3138 | | int x,data_size = 0; |
3139 | | UINT32 off,xfer = 0; |
3140 | | |
3141 | 3188 | if(offset == 1) |
3142 | 3189 | s3.pixel_xfer = (s3.pixel_xfer & 0x0000ffff) | (data << 16); |
3143 | 3190 | else |
r17522 | r17523 | |
3145 | 3192 | |
3146 | 3193 | if(s3.state == S3_DRAWING_RECT) |
3147 | 3194 | { |
3148 | | // the data in the pixel transfer register masks the rectangle output(?) |
3149 | | if(s3.bus_size == 0) // 8-bit |
3150 | | data_size = 8; |
3151 | | if(s3.bus_size == 1) // 16-bit |
3152 | | data_size = 16; |
3153 | | if(s3.bus_size == 2) // 32-bit |
3154 | | data_size = 32; |
3155 | | off = VGA_START_ADDRESS; |
3156 | | off += (VGA_LINE_LENGTH * s3.wait_rect_y); |
3157 | | off += s3.wait_rect_x; |
3158 | | for(x=0;x<data_size;x++) |
3159 | | { |
3160 | | if(s3.wait_rect_x >= 0 || s3.wait_rect_y >= 0) |
3161 | | { |
3162 | | if(s3.current_cmd & 0x1000) |
3163 | | { |
3164 | | xfer = ((s3.pixel_xfer & 0x000000ff) << 8) | ((s3.pixel_xfer & 0x0000ff00) >> 8) |
3165 | | | ((s3.pixel_xfer & 0x00ff0000) << 8) | ((s3.pixel_xfer & 0xff000000) >> 8); |
3166 | | } |
3167 | | else |
3168 | | xfer = s3.pixel_xfer; |
3169 | | if((xfer & ((1<<(data_size-1))>>x)) != 0) |
3170 | | vga.memory[off] = s3.fgcolour & 0x00ff; |
3171 | | } |
3172 | | off++; |
3173 | | s3.wait_rect_x++; |
3174 | | if(s3.wait_rect_x > s3.curr_x + s3.rect_width) |
3175 | | { |
3176 | | s3.wait_rect_x = s3.curr_x; |
3177 | | s3.wait_rect_y++; |
3178 | | if(s3.wait_rect_y > s3.curr_y + s3.rect_height) |
3179 | | { |
3180 | | s3.state = S3_IDLE; |
3181 | | s3.gpbusy = false; |
3182 | | } |
3183 | | } |
3184 | | } |
| 3195 | s3_wait_draw(); |
3185 | 3196 | } |
3186 | 3197 | |
3187 | 3198 | logerror("S3: Pixel Transfer = %08x\n",s3.pixel_xfer); |
r17522 | r17523 | |
3214 | 3225 | |
3215 | 3226 | WRITE8_HANDLER( s3_mem_w ) |
3216 | 3227 | { |
| 3228 | if(s3.state != S3_IDLE) |
| 3229 | { |
| 3230 | // pass through to the pixel transfer register (DirectX 5 wants this) |
| 3231 | if(s3.bus_size == 0) |
| 3232 | { |
| 3233 | s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data; |
| 3234 | s3_wait_draw(); |
| 3235 | } |
| 3236 | if(s3.bus_size == 1) |
| 3237 | { |
| 3238 | switch(offset & 0x0001) |
| 3239 | { |
| 3240 | case 0: |
| 3241 | default: |
| 3242 | s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data; |
| 3243 | break; |
| 3244 | case 1: |
| 3245 | s3.pixel_xfer = (s3.pixel_xfer & 0xffff00ff) | (data << 8); |
| 3246 | s3_wait_draw(); |
| 3247 | break; |
| 3248 | } |
| 3249 | } |
| 3250 | if(s3.bus_size == 2) |
| 3251 | { |
| 3252 | switch(offset & 0x0003) |
| 3253 | { |
| 3254 | case 0: |
| 3255 | default: |
| 3256 | s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data; |
| 3257 | break; |
| 3258 | case 1: |
| 3259 | s3.pixel_xfer = (s3.pixel_xfer & 0xffff00ff) | (data << 8); |
| 3260 | break; |
| 3261 | case 2: |
| 3262 | s3.pixel_xfer = (s3.pixel_xfer & 0xff00ffff) | (data << 16); |
| 3263 | break; |
| 3264 | case 3: |
| 3265 | s3.pixel_xfer = (s3.pixel_xfer & 0x00ffffff) | (data << 24); |
| 3266 | s3_wait_draw(); |
| 3267 | break; |
| 3268 | } |
| 3269 | } |
| 3270 | return; |
| 3271 | } |
| 3272 | |
3217 | 3273 | if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en) |
3218 | 3274 | { |
3219 | 3275 | //printf("%08x %02x (%02x %02x) %02X\n",offset,data,vga.sequencer.map_mask,svga.bank_w,(vga.sequencer.data[4] & 0x08)); |