trunk/src/emu/video/pc_vga.c
| r17831 | r17832 | |
| 43 | 43 | |
| 44 | 44 | #include "emu.h" |
| 45 | 45 | #include "pc_vga.h" |
| 46 | #include "video/isa_vga_ati.h" |
| 47 | #include "machine/eeprom.h" |
| 46 | 48 | #include "debugger.h" |
| 47 | 49 | |
| 48 | 50 | /*************************************************************************** |
| r17831 | r17832 | |
| 188 | 190 | |
| 189 | 191 | enum |
| 190 | 192 | { |
| 191 | | S3_IDLE = 0, |
| 192 | | S3_DRAWING_RECT, |
| 193 | | S3_DRAWING_LINE, |
| 194 | | S3_DRAWING_BITBLT, |
| 195 | | S3_DRAWING_PATTERN |
| 193 | IBM8514_IDLE = 0, |
| 194 | IBM8514_DRAWING_RECT, |
| 195 | IBM8514_DRAWING_LINE, |
| 196 | IBM8514_DRAWING_BITBLT, |
| 197 | IBM8514_DRAWING_PATTERN, |
| 198 | IBM8514_DRAWING_SSV_1, |
| 199 | IBM8514_DRAWING_SSV_2 |
| 196 | 200 | }; |
| 197 | 201 | |
| 198 | 202 | static struct |
| r17831 | r17832 | |
| 248 | 252 | UINT8 cursor_fg_ptr; |
| 249 | 253 | UINT8 cursor_bg_ptr; |
| 250 | 254 | UINT8 extended_dac_ctrl; |
| 255 | } s3; |
| 251 | 256 | |
| 257 | static struct |
| 258 | { |
| 259 | UINT8 ext_reg[64]; |
| 260 | UINT8 ext_reg_select; |
| 261 | UINT16 scratch0; |
| 262 | UINT16 scratch1; |
| 263 | UINT16 linedraw; |
| 264 | } ati; |
| 265 | |
| 266 | static struct |
| 267 | { |
| 268 | UINT16 htotal; // Horizontal total (9 bits) |
| 269 | UINT16 vtotal; // Vertical total adjust (3 bits), Vertical total base (9 bit) |
| 270 | UINT16 vdisp; |
| 271 | UINT16 vsync; |
| 272 | UINT16 subctrl; |
| 273 | UINT16 substatus; |
| 274 | UINT16 ssv; |
| 275 | UINT16 ec0; |
| 276 | UINT16 ec1; |
| 277 | UINT16 ec2; |
| 278 | UINT16 ec3; |
| 252 | 279 | bool gpbusy; |
| 280 | bool data_avail; |
| 253 | 281 | int state; |
| 254 | | }s3; |
| 255 | 282 | |
| 283 | UINT8 wait_vector_len; |
| 284 | UINT8 wait_vector_dir; |
| 285 | bool wait_vector_draw; |
| 286 | UINT8 wait_vector_count; |
| 287 | |
| 288 | } ibm8514; |
| 289 | |
| 256 | 290 | #define CRTC_PORT_ADDR ((vga.miscellaneous_output&1)?0x3d0:0x3b0) |
| 257 | 291 | |
| 258 | 292 | //#define TEXT_LINES (LINES_HELPER) |
| r17831 | r17832 | |
| 2070 | 2104 | return vga.svga_intf.vram_size; |
| 2071 | 2105 | } |
| 2072 | 2106 | |
| 2107 | static struct eeprom_interface ati_eeprom_interface = |
| 2108 | { |
| 2109 | 6, /* address bits */ |
| 2110 | 16, /* data bits */ |
| 2111 | "*110", /* read command */ |
| 2112 | "*101", /* write command */ |
| 2113 | "*111", /* erase command */ |
| 2114 | "*10000xxxx", // lock 1 00 00xxxx |
| 2115 | "*10011xxxx" // unlock 1 00 11xxxx |
| 2116 | }; |
| 2117 | |
| 2073 | 2118 | MACHINE_CONFIG_FRAGMENT( pcvideo_vga ) |
| 2074 | 2119 | MCFG_SCREEN_ADD("screen", RASTER) |
| 2075 | 2120 | MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480) |
| r17831 | r17832 | |
| 2097 | 2142 | MCFG_PALETTE_LENGTH(0x100) |
| 2098 | 2143 | MACHINE_CONFIG_END |
| 2099 | 2144 | |
| 2145 | MACHINE_CONFIG_FRAGMENT( pcvideo_ati_isa ) |
| 2146 | MCFG_SCREEN_ADD("screen", RASTER) |
| 2147 | MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480) |
| 2148 | MCFG_SCREEN_UPDATE_STATIC(pc_video) |
| 2149 | |
| 2150 | MCFG_PALETTE_LENGTH(0x100) |
| 2151 | |
| 2152 | MCFG_EEPROM_ADD("ati_eeprom",ati_eeprom_interface) |
| 2153 | MACHINE_CONFIG_END |
| 2154 | |
| 2100 | 2155 | /****************************************** |
| 2101 | 2156 | |
| 2102 | 2157 | Tseng ET4000k implementation |
| r17831 | r17832 | |
| 2631 | 2686 | { |
| 2632 | 2687 | switch(index) |
| 2633 | 2688 | { |
| 2634 | | // case 0x2e: |
| 2635 | | // res = 0x11; // Trio64 |
| 2636 | | // break; |
| 2637 | | // case 0x2f: |
| 2638 | | // res = 0x00; |
| 2639 | | // break; |
| 2689 | case 0x2d: |
| 2690 | res = 0x88; // always? |
| 2691 | break; |
| 2692 | case 0x2e: |
| 2693 | res = 0x11; // Trio64 |
| 2694 | break; |
| 2695 | case 0x2f: |
| 2696 | res = 0x00; |
| 2697 | break; |
| 2640 | 2698 | case 0x30: // CR30 Chip ID/REV register |
| 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 |
| 2699 | //res = 0xe1; // 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 |
| 2700 | res = 0xc0; // But win95 wants this... |
| 2642 | 2701 | break; |
| 2643 | 2702 | case 0x31: |
| 2644 | 2703 | res = s3.memory_config; |
| r17831 | r17832 | |
| 2768 | 2827 | s3.enable_8514 = data & 0x01; // enable 8514/A registers (x2e8, x6e8, xae8, xee8) |
| 2769 | 2828 | if(data & 0x01) |
| 2770 | 2829 | { |
| 2771 | | s3.state = S3_IDLE; |
| 2772 | | s3.gpbusy = false; |
| 2830 | ibm8514.state = IBM8514_IDLE; |
| 2831 | ibm8514.gpbusy = false; |
| 2773 | 2832 | s3.write_count = 0; |
| 2774 | 2833 | } |
| 2775 | 2834 | break; |
| r17831 | r17832 | |
| 3306 | 3365 | available, Fh for 9 words, 7 for 10 words, 3 for 11 words, 1 for |
| 3307 | 3366 | 12 words and 0 for 13 words available. |
| 3308 | 3367 | */ |
| 3368 | READ16_HANDLER(ibm8514_gpstatus_r) |
| 3369 | { |
| 3370 | UINT16 ret = 0x0000; |
| 3371 | |
| 3372 | //logerror("S3: 9AE8 read\n"); |
| 3373 | if(ibm8514.gpbusy == true) |
| 3374 | ret |= 0x0200; |
| 3375 | if(ibm8514.data_avail == true) |
| 3376 | ret |= 0x0100; |
| 3377 | return ret; |
| 3378 | } |
| 3379 | |
| 3380 | static void ibm8514_draw_vector(UINT8 len, UINT8 dir, bool draw) |
| 3381 | { |
| 3382 | UINT32 offset; |
| 3383 | int x = 0; |
| 3384 | |
| 3385 | while(x <= len) |
| 3386 | { |
| 3387 | offset = (s3.curr_y * VGA_LINE_LENGTH) + s3.curr_x; |
| 3388 | if(draw) |
| 3389 | s3_write(offset,offset); |
| 3390 | switch(dir) |
| 3391 | { |
| 3392 | case 0: // 0 degrees |
| 3393 | s3.curr_x++; |
| 3394 | break; |
| 3395 | case 1: // 45 degrees |
| 3396 | s3.curr_x++; |
| 3397 | s3.curr_y--; |
| 3398 | break; |
| 3399 | case 2: // 90 degrees |
| 3400 | s3.curr_y--; |
| 3401 | break; |
| 3402 | case 3: // 135 degrees |
| 3403 | s3.curr_y--; |
| 3404 | s3.curr_x--; |
| 3405 | break; |
| 3406 | case 4: // 180 degrees |
| 3407 | s3.curr_x--; |
| 3408 | break; |
| 3409 | case 5: // 225 degrees |
| 3410 | s3.curr_x--; |
| 3411 | s3.curr_y++; |
| 3412 | break; |
| 3413 | case 6: // 270 degrees |
| 3414 | s3.curr_y++; |
| 3415 | break; |
| 3416 | case 7: // 315 degrees |
| 3417 | s3.curr_y++; |
| 3418 | s3.curr_x++; |
| 3419 | break; |
| 3420 | } |
| 3421 | x++; |
| 3422 | } |
| 3423 | } |
| 3424 | |
| 3309 | 3425 | READ16_HANDLER(s3_gpstatus_r) |
| 3310 | 3426 | { |
| 3311 | 3427 | UINT16 ret = 0x0000; |
| 3312 | 3428 | |
| 3313 | | logerror("S3: 9AE8 read\n"); |
| 3429 | //logerror("S3: 9AE8 read\n"); |
| 3314 | 3430 | if(s3.enable_8514 != 0) |
| 3315 | 3431 | { |
| 3316 | | if(s3.gpbusy == true) |
| 3432 | if(ibm8514.gpbusy == true) |
| 3317 | 3433 | ret |= 0x0200; |
| 3434 | if(ibm8514.data_avail == true) |
| 3435 | ret |= 0x0100; |
| 3318 | 3436 | return ret; |
| 3319 | 3437 | } |
| 3320 | 3438 | else |
| r17831 | r17832 | |
| 3404 | 3522 | rectangle, which is copied repeatably to the destination |
| 3405 | 3523 | rectangle. |
| 3406 | 3524 | */ |
| 3407 | | WRITE16_HANDLER(s3_cmd_w) |
| 3525 | WRITE16_HANDLER(ibm8514_cmd_w) |
| 3408 | 3526 | { |
| 3409 | | if(s3.enable_8514 != 0) |
| 3527 | int x,y; |
| 3528 | int pattern_x,pattern_y; |
| 3529 | UINT32 off,src; |
| 3530 | |
| 3531 | s3.current_cmd = data; |
| 3532 | s3.src_x = 0; |
| 3533 | s3.src_y = 0; |
| 3534 | s3.bus_size = (data & 0x0600) >> 9; |
| 3535 | switch(data & 0xe000) |
| 3410 | 3536 | { |
| 3411 | | int x,y; |
| 3412 | | int pattern_x,pattern_y; |
| 3413 | | UINT32 offset,src; |
| 3414 | | |
| 3415 | | s3.current_cmd = data; |
| 3416 | | s3.src_x = 0; |
| 3417 | | s3.src_y = 0; |
| 3418 | | switch(data & 0xe000) |
| 3537 | case 0x0000: // NOP (for "Short Stroke Vectors") |
| 3538 | ibm8514.state = IBM8514_IDLE; |
| 3539 | ibm8514.gpbusy = false; |
| 3540 | logerror("S3: Command (%04x) - NOP (Short Stroke Vector)\n",s3.current_cmd); |
| 3541 | break; |
| 3542 | case 0x2000: // Line |
| 3543 | ibm8514.state = IBM8514_IDLE; |
| 3544 | ibm8514.gpbusy = false; |
| 3545 | if(data & 0x0008) |
| 3419 | 3546 | { |
| 3420 | | case 0x0000: // NOP (for "Short Stroke Vectors") |
| 3421 | | s3.state = S3_IDLE; |
| 3422 | | s3.gpbusy = false; |
| 3423 | | logerror("S3: Command (%04x) - NOP\n",s3.current_cmd); |
| 3424 | | break; |
| 3425 | | case 0x2000: // Line |
| 3426 | | s3.state = S3_IDLE; |
| 3427 | | s3.gpbusy = false; |
| 3428 | | if(data & 0x0008) |
| 3547 | if(data & 0x0100) |
| 3429 | 3548 | { |
| 3430 | | // TODO |
| 3431 | | logerror("S3: Command (%04x) - Line (Vector) - %i,%i \n",s3.current_cmd,s3.curr_x,s3.curr_y); |
| 3549 | ibm8514.state = IBM8514_DRAWING_LINE; |
| 3550 | ibm8514.data_avail = true; |
| 3551 | logerror("S3: Command (%04x) - Vector Line (WAIT) %i,%i \n",s3.current_cmd,s3.curr_x,s3.curr_y); |
| 3432 | 3552 | } |
| 3433 | 3553 | else |
| 3434 | 3554 | { |
| 3435 | | // Not perfect, but will do for now. |
| 3436 | | INT16 dx = s3.rect_width; |
| 3437 | | INT16 dy = s3.line_axial_step >> 1; |
| 3438 | | INT16 err = s3.line_errorterm; |
| 3439 | | int sx = (data & 0x0020) ? 1 : -1; |
| 3440 | | int sy = (data & 0x0080) ? 1 : -1; |
| 3441 | | int count = 0; |
| 3442 | | INT16 temp; |
| 3555 | ibm8514_draw_vector(s3.rect_width,(data & 0x00e0) >> 5,(data & 0010) ? true : false); |
| 3556 | logerror("S3: Command (%04x) - Vector Line - %i,%i \n",s3.current_cmd,s3.curr_x,s3.curr_y); |
| 3557 | } |
| 3558 | } |
| 3559 | else |
| 3560 | { |
| 3561 | // Not perfect, but will do for now. |
| 3562 | INT16 dx = s3.rect_width; |
| 3563 | INT16 dy = s3.line_axial_step >> 1; |
| 3564 | INT16 err = s3.line_errorterm; |
| 3565 | int sx = (data & 0x0020) ? 1 : -1; |
| 3566 | int sy = (data & 0x0080) ? 1 : -1; |
| 3567 | int count = 0; |
| 3568 | INT16 temp; |
| 3443 | 3569 | |
| 3444 | | logerror("S3: Command (%04x) - Line (Bresenham) - %i,%i Axial %i, Diagonal %i, Error %i, Major Axis %i, Minor Axis %i\n",s3.current_cmd, |
| 3445 | | s3.curr_x,s3.curr_y,s3.line_axial_step,s3.line_diagonal_step,s3.line_errorterm,s3.rect_width,s3.rect_height); |
| 3570 | logerror("S3: Command (%04x) - Line (Bresenham) - %i,%i Axial %i, Diagonal %i, Error %i, Major Axis %i, Minor Axis %i\n",s3.current_cmd, |
| 3571 | s3.curr_x,s3.curr_y,s3.line_axial_step,s3.line_diagonal_step,s3.line_errorterm,s3.rect_width,s3.rect_height); |
| 3446 | 3572 | |
| 3447 | | if((data & 0x0040)) |
| 3573 | if((data & 0x0040)) |
| 3574 | { |
| 3575 | temp = dx; dx = dy; dy = temp; |
| 3576 | } |
| 3577 | for(;;) |
| 3578 | { |
| 3579 | s3_write(s3.curr_x + (s3.curr_y * VGA_LINE_LENGTH),s3.curr_x + (s3.curr_y * VGA_LINE_LENGTH)); |
| 3580 | if (count > s3.rect_width) break; |
| 3581 | count++; |
| 3582 | if((err*2) > -dy) |
| 3448 | 3583 | { |
| 3449 | | temp = dx; dx = dy; dy = temp; |
| 3584 | err -= dy; |
| 3585 | s3.curr_x += sx; |
| 3450 | 3586 | } |
| 3451 | | for(;;) |
| 3587 | if((err*2) < dx) |
| 3452 | 3588 | { |
| 3453 | | s3_write(s3.curr_x + (s3.curr_y * VGA_LINE_LENGTH),s3.curr_x + (s3.curr_y * VGA_LINE_LENGTH)); |
| 3454 | | if (count > s3.rect_width) break; |
| 3455 | | count++; |
| 3456 | | if((err*2) > -dy) |
| 3457 | | { |
| 3458 | | err -= dy; |
| 3459 | | s3.curr_x += sx; |
| 3460 | | } |
| 3461 | | if((err*2) < dx) |
| 3462 | | { |
| 3463 | | err += dx; |
| 3464 | | s3.curr_y += sy; |
| 3465 | | } |
| 3589 | err += dx; |
| 3590 | s3.curr_y += sy; |
| 3466 | 3591 | } |
| 3467 | 3592 | } |
| 3593 | } |
| 3594 | break; |
| 3595 | case 0x4000: // Rectangle Fill |
| 3596 | if(data & 0x0100) // WAIT (for read/write of PIXEL TRANSFER (E2E8)) |
| 3597 | { |
| 3598 | ibm8514.state = IBM8514_DRAWING_RECT; |
| 3599 | //ibm8514.gpbusy = true; // DirectX 5 keeps waiting for the busy bit to be clear... |
| 3600 | s3.bus_size = (data & 0x0600) >> 9; |
| 3601 | ibm8514.data_avail = true; |
| 3602 | logerror("S3: Command (%04x) - Rectangle Fill (WAIT) %i,%i Width: %i Height: %i Colour: %08x\n",s3.current_cmd,s3.curr_x, |
| 3603 | s3.curr_y,s3.rect_width,s3.rect_height,s3.fgcolour); |
| 3468 | 3604 | break; |
| 3469 | | case 0x4000: // Rectangle Fill |
| 3470 | | if(data & 0x0100) // WAIT (for read/write of PIXEL TRANSFER (E2E8)) |
| 3605 | } |
| 3606 | logerror("S3: Command (%04x) - Rectangle Fill %i,%i Width: %i Height: %i Colour: %08x\n",s3.current_cmd,s3.curr_x, |
| 3607 | s3.curr_y,s3.rect_width,s3.rect_height,s3.fgcolour); |
| 3608 | off = 0; |
| 3609 | off += (VGA_LINE_LENGTH * s3.curr_y); |
| 3610 | off += s3.curr_x; |
| 3611 | for(y=0;y<=s3.rect_height;y++) |
| 3612 | { |
| 3613 | for(x=0;x<=s3.rect_width;x++) |
| 3471 | 3614 | { |
| 3472 | | s3.state = S3_DRAWING_RECT; |
| 3473 | | //s3.gpbusy = true; // DirectX 5 keeps waiting for the busy bit to be clear... |
| 3474 | | s3.bus_size = (data & 0x0600) >> 9; |
| 3475 | | logerror("S3: Command (%04x) - Rectangle Fill (WAIT) %i,%i Width: %i Height: %i Colour: %08x\n",s3.current_cmd,s3.curr_x, |
| 3476 | | s3.curr_y,s3.rect_width,s3.rect_height,s3.fgcolour); |
| 3477 | | break; |
| 3478 | | } |
| 3479 | | logerror("S3: Command (%04x) - Rectangle Fill %i,%i Width: %i Height: %i Colour: %08x\n",s3.current_cmd,s3.curr_x, |
| 3480 | | s3.curr_y,s3.rect_width,s3.rect_height,s3.fgcolour); |
| 3481 | | offset = 0; |
| 3482 | | offset += (VGA_LINE_LENGTH * s3.curr_y); |
| 3483 | | offset += s3.curr_x; |
| 3484 | | for(y=0;y<=s3.rect_height;y++) |
| 3485 | | { |
| 3486 | | for(x=0;x<=s3.rect_width;x++) |
| 3615 | if(data & 0x0020) // source pattern is always based on current X/Y? |
| 3616 | s3_write((off+x) % vga.svga_intf.vram_size,(off+x) % vga.svga_intf.vram_size); |
| 3617 | else |
| 3618 | s3_write((off-x) % vga.svga_intf.vram_size,(off-x) % vga.svga_intf.vram_size); |
| 3619 | if(s3.current_cmd & 0x0020) |
| 3487 | 3620 | { |
| 3488 | | if(data & 0x0020) // source pattern is always based on current X/Y? |
| 3489 | | s3_write((offset+x) % vga.svga_intf.vram_size,(offset+x) % vga.svga_intf.vram_size); |
| 3490 | | else |
| 3491 | | s3_write((offset-x) % vga.svga_intf.vram_size,(offset-x) % vga.svga_intf.vram_size); |
| 3492 | | if(s3.current_cmd & 0x0020) |
| 3621 | s3.curr_x++; |
| 3622 | if(s3.curr_x > s3.prev_x + s3.rect_width) |
| 3493 | 3623 | { |
| 3494 | | s3.curr_x++; |
| 3495 | | if(s3.curr_x > s3.prev_x + s3.rect_width) |
| 3496 | | { |
| 3497 | | s3.curr_x = s3.prev_x; |
| 3498 | | s3.src_x = 0; |
| 3499 | | if(s3.current_cmd & 0x0080) |
| 3500 | | s3.curr_y++; |
| 3501 | | else |
| 3502 | | s3.curr_y--; |
| 3503 | | } |
| 3624 | s3.curr_x = s3.prev_x; |
| 3625 | s3.src_x = 0; |
| 3626 | if(s3.current_cmd & 0x0080) |
| 3627 | s3.curr_y++; |
| 3628 | else |
| 3629 | s3.curr_y--; |
| 3504 | 3630 | } |
| 3505 | | else |
| 3631 | } |
| 3632 | else |
| 3633 | { |
| 3634 | s3.curr_x--; |
| 3635 | if(s3.curr_x < s3.prev_x - s3.rect_width) |
| 3506 | 3636 | { |
| 3507 | | s3.curr_x--; |
| 3508 | | if(s3.curr_x < s3.prev_x - s3.rect_width) |
| 3509 | | { |
| 3510 | | s3.curr_x = s3.prev_x; |
| 3511 | | s3.src_x = 0; |
| 3512 | | if(s3.current_cmd & 0x0080) |
| 3513 | | s3.curr_y++; |
| 3514 | | else |
| 3515 | | s3.curr_y--; |
| 3516 | | } |
| 3637 | s3.curr_x = s3.prev_x; |
| 3638 | s3.src_x = 0; |
| 3639 | if(s3.current_cmd & 0x0080) |
| 3640 | s3.curr_y++; |
| 3641 | else |
| 3642 | s3.curr_y--; |
| 3517 | 3643 | } |
| 3518 | 3644 | } |
| 3519 | | if(data & 0x0080) |
| 3520 | | offset += VGA_LINE_LENGTH; |
| 3521 | | else |
| 3522 | | offset -= VGA_LINE_LENGTH; |
| 3523 | 3645 | } |
| 3524 | | s3.state = S3_IDLE; |
| 3525 | | s3.gpbusy = false; |
| 3526 | | break; |
| 3527 | | case 0xc000: // BitBLT |
| 3528 | | logerror("S3: Command (%04x) - BitBLT from %i,%i to %i,%i Width: %i Height: %i\n",s3.current_cmd, |
| 3529 | | s3.curr_x,s3.curr_y,s3.dest_x,s3.dest_y,s3.rect_width,s3.rect_height); |
| 3530 | | offset = 0; |
| 3531 | | offset += (VGA_LINE_LENGTH * s3.dest_y); |
| 3532 | | offset += s3.dest_x; |
| 3533 | | src = 0; |
| 3534 | | src += (VGA_LINE_LENGTH * s3.curr_y); |
| 3535 | | src += s3.curr_x; |
| 3536 | | for(y=0;y<=s3.rect_height;y++) |
| 3646 | if(data & 0x0080) |
| 3647 | off += VGA_LINE_LENGTH; |
| 3648 | else |
| 3649 | off -= VGA_LINE_LENGTH; |
| 3650 | } |
| 3651 | ibm8514.state = IBM8514_IDLE; |
| 3652 | ibm8514.gpbusy = false; |
| 3653 | break; |
| 3654 | case 0xc000: // BitBLT |
| 3655 | logerror("S3: Command (%04x) - BitBLT from %i,%i to %i,%i Width: %i Height: %i\n",s3.current_cmd, |
| 3656 | s3.curr_x,s3.curr_y,s3.dest_x,s3.dest_y,s3.rect_width,s3.rect_height); |
| 3657 | off = 0; |
| 3658 | off += (VGA_LINE_LENGTH * s3.dest_y); |
| 3659 | off += s3.dest_x; |
| 3660 | src = 0; |
| 3661 | src += (VGA_LINE_LENGTH * s3.curr_y); |
| 3662 | src += s3.curr_x; |
| 3663 | for(y=0;y<=s3.rect_height;y++) |
| 3664 | { |
| 3665 | for(x=0;x<=s3.rect_width;x++) |
| 3537 | 3666 | { |
| 3538 | | for(x=0;x<=s3.rect_width;x++) |
| 3667 | if(data & 0x0020) |
| 3668 | vga.memory[(off+x) % vga.svga_intf.vram_size] = vga.memory[(src+x) % vga.svga_intf.vram_size]; |
| 3669 | else |
| 3670 | vga.memory[(off-x) % vga.svga_intf.vram_size] = vga.memory[(src-x) % vga.svga_intf.vram_size]; |
| 3671 | if(s3.current_cmd & 0x0020) |
| 3539 | 3672 | { |
| 3540 | | if(data & 0x0020) |
| 3541 | | vga.memory[(offset+x) % vga.svga_intf.vram_size] = vga.memory[(src+x) % vga.svga_intf.vram_size]; |
| 3542 | | else |
| 3543 | | vga.memory[(offset-x) % vga.svga_intf.vram_size] = vga.memory[(src-x) % vga.svga_intf.vram_size]; |
| 3544 | | if(s3.current_cmd & 0x0020) |
| 3673 | s3.curr_x++; |
| 3674 | if(s3.curr_x > s3.prev_x + s3.rect_width) |
| 3545 | 3675 | { |
| 3546 | | s3.curr_x++; |
| 3547 | | if(s3.curr_x > s3.prev_x + s3.rect_width) |
| 3548 | | { |
| 3549 | | s3.curr_x = s3.prev_x; |
| 3550 | | s3.src_x = 0; |
| 3551 | | if(s3.current_cmd & 0x0080) |
| 3552 | | s3.curr_y++; |
| 3553 | | else |
| 3554 | | s3.curr_y--; |
| 3555 | | } |
| 3676 | s3.curr_x = s3.prev_x; |
| 3677 | s3.src_x = 0; |
| 3678 | if(s3.current_cmd & 0x0080) |
| 3679 | s3.curr_y++; |
| 3680 | else |
| 3681 | s3.curr_y--; |
| 3556 | 3682 | } |
| 3557 | | else |
| 3683 | } |
| 3684 | else |
| 3685 | { |
| 3686 | s3.curr_x--; |
| 3687 | if(s3.curr_x < s3.prev_x - s3.rect_width) |
| 3558 | 3688 | { |
| 3559 | | s3.curr_x--; |
| 3560 | | if(s3.curr_x < s3.prev_x - s3.rect_width) |
| 3561 | | { |
| 3562 | | s3.curr_x = s3.prev_x; |
| 3563 | | s3.src_x = 0; |
| 3564 | | if(s3.current_cmd & 0x0080) |
| 3565 | | s3.curr_y++; |
| 3566 | | else |
| 3567 | | s3.curr_y--; |
| 3568 | | } |
| 3689 | s3.curr_x = s3.prev_x; |
| 3690 | s3.src_x = 0; |
| 3691 | if(s3.current_cmd & 0x0080) |
| 3692 | s3.curr_y++; |
| 3693 | else |
| 3694 | s3.curr_y--; |
| 3569 | 3695 | } |
| 3570 | 3696 | } |
| 3571 | | if(data & 0x0080) |
| 3697 | } |
| 3698 | if(data & 0x0080) |
| 3699 | { |
| 3700 | src += VGA_LINE_LENGTH; |
| 3701 | off += VGA_LINE_LENGTH; |
| 3702 | } |
| 3703 | else |
| 3704 | { |
| 3705 | src -= VGA_LINE_LENGTH; |
| 3706 | off -= VGA_LINE_LENGTH; |
| 3707 | } |
| 3708 | } |
| 3709 | ibm8514.state = IBM8514_IDLE; |
| 3710 | ibm8514.gpbusy = false; |
| 3711 | break; |
| 3712 | case 0xe000: // Pattern Fill |
| 3713 | logerror("S3: Command (%04x) - Pattern Fill - source %i,%i dest %i,%i Width: %i Height: %i\n",s3.current_cmd, |
| 3714 | s3.curr_x,s3.curr_y,s3.dest_x,s3.dest_y,s3.rect_width,s3.rect_height); |
| 3715 | off = 0; |
| 3716 | off += (VGA_LINE_LENGTH * s3.dest_y); |
| 3717 | off += s3.dest_x; |
| 3718 | src = 0; |
| 3719 | src += (VGA_LINE_LENGTH * s3.curr_y); |
| 3720 | src += s3.curr_x; |
| 3721 | if(data & 0x0020) |
| 3722 | pattern_x = 0; |
| 3723 | else |
| 3724 | pattern_x = 7; |
| 3725 | if(data & 0x0080) |
| 3726 | pattern_y = 0; |
| 3727 | else |
| 3728 | pattern_y = 7; |
| 3729 | |
| 3730 | for(y=0;y<=s3.rect_height;y++) |
| 3731 | { |
| 3732 | for(x=0;x<=s3.rect_width;x++) |
| 3733 | { |
| 3734 | if(data & 0x0020) |
| 3572 | 3735 | { |
| 3573 | | src += VGA_LINE_LENGTH; |
| 3574 | | offset += VGA_LINE_LENGTH; |
| 3736 | s3_write(off+x,src+pattern_x); |
| 3737 | pattern_x++; |
| 3738 | if(pattern_x >= 8) |
| 3739 | pattern_x = 0; |
| 3575 | 3740 | } |
| 3576 | 3741 | else |
| 3577 | 3742 | { |
| 3578 | | src -= VGA_LINE_LENGTH; |
| 3579 | | offset -= VGA_LINE_LENGTH; |
| 3743 | s3_write(off-x,src-pattern_x); |
| 3744 | pattern_x--; |
| 3745 | if(pattern_x < 0) |
| 3746 | pattern_x = 7; |
| 3580 | 3747 | } |
| 3581 | 3748 | } |
| 3582 | | s3.state = S3_IDLE; |
| 3583 | | s3.gpbusy = false; |
| 3584 | | break; |
| 3585 | | case 0xe000: // Pattern Fill |
| 3586 | | logerror("S3: Command (%04x) - Pattern Fill - source %i,%i dest %i,%i Width: %i Height: %i\n",s3.current_cmd, |
| 3587 | | s3.curr_x,s3.curr_y,s3.dest_x,s3.dest_y,s3.rect_width,s3.rect_height); |
| 3588 | | offset = 0; |
| 3589 | | offset += (VGA_LINE_LENGTH * s3.dest_y); |
| 3590 | | offset += s3.dest_x; |
| 3591 | | src = 0; |
| 3592 | | src += (VGA_LINE_LENGTH * s3.curr_y); |
| 3593 | | src += s3.curr_x; |
| 3749 | |
| 3750 | // for now, presume that INC_X and INC_Y affect both src and dest, at is would for a bitblt. |
| 3594 | 3751 | if(data & 0x0020) |
| 3595 | 3752 | pattern_x = 0; |
| 3596 | 3753 | else |
| 3597 | 3754 | pattern_x = 7; |
| 3598 | 3755 | if(data & 0x0080) |
| 3599 | | pattern_y = 0; |
| 3600 | | else |
| 3601 | | pattern_y = 7; |
| 3602 | | |
| 3603 | | for(y=0;y<=s3.rect_height;y++) |
| 3604 | 3756 | { |
| 3605 | | for(x=0;x<=s3.rect_width;x++) |
| 3757 | pattern_y++; |
| 3758 | src += VGA_LINE_LENGTH; |
| 3759 | if(pattern_y >= 8) |
| 3606 | 3760 | { |
| 3607 | | if(data & 0x0020) |
| 3608 | | { |
| 3609 | | s3_write(offset+x,src+pattern_x); |
| 3610 | | pattern_x++; |
| 3611 | | if(pattern_x >= 8) |
| 3612 | | pattern_x = 0; |
| 3613 | | } |
| 3614 | | else |
| 3615 | | { |
| 3616 | | s3_write(offset-x,src-pattern_x); |
| 3617 | | pattern_x--; |
| 3618 | | if(pattern_x < 0) |
| 3619 | | pattern_x = 7; |
| 3620 | | } |
| 3761 | pattern_y = 0; |
| 3762 | src -= (VGA_LINE_LENGTH * 8); // move src pointer back to top of pattern |
| 3621 | 3763 | } |
| 3622 | | |
| 3623 | | // for now, presume that INC_X and INC_Y affect both src and dest, at is would for a bitblt. |
| 3624 | | if(data & 0x0020) |
| 3625 | | pattern_x = 0; |
| 3626 | | else |
| 3627 | | pattern_x = 7; |
| 3628 | | if(data & 0x0080) |
| 3764 | off += VGA_LINE_LENGTH; |
| 3765 | } |
| 3766 | else |
| 3767 | { |
| 3768 | pattern_y--; |
| 3769 | src -= VGA_LINE_LENGTH; |
| 3770 | if(pattern_y < 0) |
| 3629 | 3771 | { |
| 3630 | | pattern_y++; |
| 3631 | | src += VGA_LINE_LENGTH; |
| 3632 | | if(pattern_y >= 8) |
| 3633 | | { |
| 3634 | | pattern_y = 0; |
| 3635 | | src -= (VGA_LINE_LENGTH * 8); // move src pointer back to top of pattern |
| 3636 | | } |
| 3637 | | offset += VGA_LINE_LENGTH; |
| 3772 | pattern_y = 7; |
| 3773 | src += (VGA_LINE_LENGTH * 8); // move src pointer back to bottom of pattern |
| 3638 | 3774 | } |
| 3639 | | else |
| 3640 | | { |
| 3641 | | pattern_y--; |
| 3642 | | src -= VGA_LINE_LENGTH; |
| 3643 | | if(pattern_y < 0) |
| 3644 | | { |
| 3645 | | pattern_y = 7; |
| 3646 | | src += (VGA_LINE_LENGTH * 8); // move src pointer back to bottom of pattern |
| 3647 | | } |
| 3648 | | offset -= VGA_LINE_LENGTH; |
| 3649 | | } |
| 3775 | off -= VGA_LINE_LENGTH; |
| 3650 | 3776 | } |
| 3651 | | s3.state = S3_IDLE; |
| 3652 | | s3.gpbusy = false; |
| 3653 | | break; |
| 3654 | | default: |
| 3655 | | s3.state = S3_IDLE; |
| 3656 | | s3.gpbusy = false; |
| 3657 | | logerror("S3: Unknown command: %04x\n",data); |
| 3658 | 3777 | } |
| 3778 | ibm8514.state = IBM8514_IDLE; |
| 3779 | ibm8514.gpbusy = false; |
| 3780 | break; |
| 3781 | default: |
| 3782 | ibm8514.state = IBM8514_IDLE; |
| 3783 | ibm8514.gpbusy = false; |
| 3784 | logerror("S3: Unknown command: %04x\n",data); |
| 3659 | 3785 | } |
| 3660 | | else |
| 3661 | | logerror("S3: Write to 8514/A port 9ae8 while disabled.\n"); |
| 3662 | 3786 | } |
| 3663 | 3787 | |
| 3788 | WRITE16_HANDLER(s3_cmd_w) |
| 3789 | { |
| 3790 | if(s3.enable_8514 != 0) |
| 3791 | ibm8514_cmd_w(space,offset,data,mem_mask); |
| 3792 | } |
| 3664 | 3793 | /* |
| 3665 | 3794 | 8AE8h W(R/W): Destination Y Position & Axial Step Constant Register |
| 3666 | 3795 | (DESTY_AXSTP) |
| r17831 | r17832 | |
| 3711 | 3840 | } |
| 3712 | 3841 | |
| 3713 | 3842 | /* |
| 3843 | 9EE8h W(R/W): Short Stroke Vector Transfer Register (SHORT_STROKE) |
| 3844 | bit 0-3 Length of vector projected onto the major axis. |
| 3845 | This is also the number of pixels drawn. |
| 3846 | 4 Must be set for pixels to be written. |
| 3847 | 5-7 VECDIR. The angle measured counter-clockwise from horizontal |
| 3848 | right) at which the line is drawn, |
| 3849 | 0 = 000 degrees |
| 3850 | 1 = 045 degrees |
| 3851 | 2 = 090 degrees |
| 3852 | 3 = 135 degrees |
| 3853 | 4 = 180 degrees |
| 3854 | 5 = 225 degrees |
| 3855 | 6 = 270 degrees |
| 3856 | 7 = 315 degrees |
| 3857 | 8-15 The lower 8 bits are duplicated in the upper 8 bits so two |
| 3858 | short stroke vectors can be drawn with one command. |
| 3859 | Note: The upper byte must be written for the SSV command to be executed. |
| 3860 | Thus if a byte is written to 9EE8h another byte must be written to |
| 3861 | 9EE9h before execution starts. A single 16bit write will do. |
| 3862 | If only one SSV is desired the other byte can be set to 0. |
| 3863 | */ |
| 3864 | static void ibm8514_wait_draw_ssv() |
| 3865 | { |
| 3866 | UINT8 len = ibm8514.wait_vector_len; |
| 3867 | UINT8 dir = ibm8514.wait_vector_dir; |
| 3868 | bool draw = ibm8514.wait_vector_draw; |
| 3869 | UINT8 count = ibm8514.wait_vector_count; |
| 3870 | UINT32 offset; |
| 3871 | int x; |
| 3872 | int data_size; |
| 3873 | |
| 3874 | switch(s3.bus_size) |
| 3875 | { |
| 3876 | case 0: |
| 3877 | data_size = 8; |
| 3878 | break; |
| 3879 | case 1: |
| 3880 | data_size = 16; |
| 3881 | break; |
| 3882 | case 2: |
| 3883 | data_size = 32; |
| 3884 | break; |
| 3885 | default: |
| 3886 | data_size = 8; |
| 3887 | break; |
| 3888 | } |
| 3889 | |
| 3890 | for(x=0;x<data_size;x++) |
| 3891 | { |
| 3892 | if(len > count) |
| 3893 | { |
| 3894 | if(ibm8514.state == IBM8514_DRAWING_SSV_1) |
| 3895 | { |
| 3896 | ibm8514.state = IBM8514_DRAWING_SSV_2; |
| 3897 | ibm8514.wait_vector_len = (ibm8514.ssv & 0x0f00) >> 8; |
| 3898 | ibm8514.wait_vector_dir = (ibm8514.ssv & 0xe000) >> 13; |
| 3899 | ibm8514.wait_vector_draw = (ibm8514.ssv & 0x1000) ? true : false; |
| 3900 | ibm8514.wait_vector_count = 0; |
| 3901 | return; |
| 3902 | } |
| 3903 | else if(ibm8514.state == IBM8514_DRAWING_SSV_2) |
| 3904 | { |
| 3905 | ibm8514.state = IBM8514_IDLE; |
| 3906 | ibm8514.gpbusy = false; |
| 3907 | ibm8514.data_avail = false; |
| 3908 | return; |
| 3909 | } |
| 3910 | } |
| 3911 | |
| 3912 | if(ibm8514.state == IBM8514_DRAWING_SSV_1 || ibm8514.state == IBM8514_DRAWING_SSV_2) |
| 3913 | { |
| 3914 | offset = (s3.curr_y * VGA_LINE_LENGTH) + s3.curr_x; |
| 3915 | if(draw) |
| 3916 | s3_write(offset,offset); |
| 3917 | switch(dir) |
| 3918 | { |
| 3919 | case 0: // 0 degrees |
| 3920 | s3.curr_x++; |
| 3921 | break; |
| 3922 | case 1: // 45 degrees |
| 3923 | s3.curr_x++; |
| 3924 | s3.curr_y--; |
| 3925 | break; |
| 3926 | case 2: // 90 degrees |
| 3927 | s3.curr_y--; |
| 3928 | break; |
| 3929 | case 3: // 135 degrees |
| 3930 | s3.curr_y--; |
| 3931 | s3.curr_x--; |
| 3932 | break; |
| 3933 | case 4: // 180 degrees |
| 3934 | s3.curr_x--; |
| 3935 | break; |
| 3936 | case 5: // 225 degrees |
| 3937 | s3.curr_x--; |
| 3938 | s3.curr_y++; |
| 3939 | break; |
| 3940 | case 6: // 270 degrees |
| 3941 | s3.curr_y++; |
| 3942 | break; |
| 3943 | case 7: // 315 degrees |
| 3944 | s3.curr_y++; |
| 3945 | s3.curr_x++; |
| 3946 | break; |
| 3947 | } |
| 3948 | } |
| 3949 | } |
| 3950 | } |
| 3951 | |
| 3952 | static void ibm8514_draw_ssv(UINT8 data) |
| 3953 | { |
| 3954 | UINT8 len = data & 0x0f; |
| 3955 | UINT8 dir = (data & 0xe0) >> 5; |
| 3956 | bool draw = (data & 0x10) ? true : false; |
| 3957 | |
| 3958 | ibm8514_draw_vector(len,dir,draw); |
| 3959 | } |
| 3960 | |
| 3961 | READ16_HANDLER(ibm8514_ssv_r) |
| 3962 | { |
| 3963 | return ibm8514.ssv; |
| 3964 | } |
| 3965 | |
| 3966 | WRITE16_HANDLER(ibm8514_ssv_w) |
| 3967 | { |
| 3968 | ibm8514.ssv = data; |
| 3969 | |
| 3970 | if(s3.current_cmd & 0x0100) |
| 3971 | { |
| 3972 | ibm8514.state = IBM8514_DRAWING_SSV_1; |
| 3973 | ibm8514.data_avail = true; |
| 3974 | ibm8514.wait_vector_len = ibm8514.ssv & 0x0f; |
| 3975 | ibm8514.wait_vector_dir = (ibm8514.ssv & 0xe0) >> 5; |
| 3976 | ibm8514.wait_vector_draw = (ibm8514.ssv & 0x10) ? true : false; |
| 3977 | ibm8514.wait_vector_count = 0; |
| 3978 | return; |
| 3979 | } |
| 3980 | |
| 3981 | if(s3.current_cmd & 0x1000) // byte sequence |
| 3982 | { |
| 3983 | ibm8514_draw_ssv(data & 0xff); |
| 3984 | ibm8514_draw_ssv(data >> 8); |
| 3985 | } |
| 3986 | else |
| 3987 | { |
| 3988 | ibm8514_draw_ssv(data >> 8); |
| 3989 | ibm8514_draw_ssv(data & 0xff); |
| 3990 | } |
| 3991 | logerror("8514/A: Short Stroke Vector write %04x\n",data); |
| 3992 | } |
| 3993 | |
| 3994 | static void ibm8514_wait_draw_vector() |
| 3995 | { |
| 3996 | UINT8 len = ibm8514.wait_vector_len; |
| 3997 | UINT8 dir = ibm8514.wait_vector_dir; |
| 3998 | bool draw = ibm8514.wait_vector_draw; |
| 3999 | UINT8 count = ibm8514.wait_vector_count; |
| 4000 | UINT32 offset; |
| 4001 | UINT8 data_size; |
| 4002 | int x; |
| 4003 | |
| 4004 | if(s3.bus_size == 0) // 8-bit |
| 4005 | data_size = 8; |
| 4006 | if(s3.bus_size == 1) // 16-bit |
| 4007 | data_size = 16; |
| 4008 | if(s3.bus_size == 2) // 32-bit |
| 4009 | data_size = 32; |
| 4010 | |
| 4011 | for(x=0;x<data_size;x++) |
| 4012 | { |
| 4013 | if(len > count) |
| 4014 | { |
| 4015 | if(ibm8514.state == IBM8514_DRAWING_LINE) |
| 4016 | { |
| 4017 | ibm8514.state = IBM8514_IDLE; |
| 4018 | ibm8514.gpbusy = false; |
| 4019 | ibm8514.data_avail = false; |
| 4020 | return; |
| 4021 | } |
| 4022 | } |
| 4023 | |
| 4024 | if(ibm8514.state == IBM8514_DRAWING_LINE) |
| 4025 | { |
| 4026 | offset = (s3.curr_y * VGA_LINE_LENGTH) + s3.curr_x; |
| 4027 | if(draw) |
| 4028 | s3_write(offset,offset); |
| 4029 | switch(dir) |
| 4030 | { |
| 4031 | case 0: // 0 degrees |
| 4032 | s3.curr_x++; |
| 4033 | break; |
| 4034 | case 1: // 45 degrees |
| 4035 | s3.curr_x++; |
| 4036 | s3.curr_y--; |
| 4037 | break; |
| 4038 | case 2: // 90 degrees |
| 4039 | s3.curr_y--; |
| 4040 | break; |
| 4041 | case 3: // 135 degrees |
| 4042 | s3.curr_y--; |
| 4043 | s3.curr_x--; |
| 4044 | break; |
| 4045 | case 4: // 180 degrees |
| 4046 | s3.curr_x--; |
| 4047 | break; |
| 4048 | case 5: // 225 degrees |
| 4049 | s3.curr_x--; |
| 4050 | s3.curr_y++; |
| 4051 | break; |
| 4052 | case 6: // 270 degrees |
| 4053 | s3.curr_y++; |
| 4054 | break; |
| 4055 | case 7: // 315 degrees |
| 4056 | s3.curr_y++; |
| 4057 | s3.curr_x++; |
| 4058 | break; |
| 4059 | } |
| 4060 | } |
| 4061 | } |
| 4062 | } |
| 4063 | |
| 4064 | /* |
| 3714 | 4065 | 96E8h W(R/W): Major Axis Pixel Count/Rectangle Width Register (MAJ_AXIS_PCNT) |
| 3715 | 4066 | bit 0-10 (911/924) RECTANGLE WIDTH/LINE PARAMETER MAX. For BITBLT and |
| 3716 | 4067 | rectangle commands this is the width of the area. For Line Drawing |
| r17831 | r17832 | |
| 3726 | 4077 | |
| 3727 | 4078 | WRITE16_HANDLER( s3_width_w ) |
| 3728 | 4079 | { |
| 3729 | | s3.rect_width = data & 0x0fff; |
| 4080 | s3.rect_width = data & 0x1fff; |
| 3730 | 4081 | logerror("S3: Major Axis Pixel Count / Rectangle Width write %04x\n",data); |
| 3731 | 4082 | } |
| 3732 | 4083 | |
| r17831 | r17832 | |
| 3921 | 4272 | s3.curr_y++; |
| 3922 | 4273 | if(s3.curr_y > s3.prev_y + s3.rect_height) |
| 3923 | 4274 | { |
| 3924 | | s3.state = S3_IDLE; |
| 3925 | | s3.gpbusy = false; |
| 4275 | ibm8514.state = IBM8514_IDLE; |
| 4276 | ibm8514.data_avail = false; |
| 4277 | ibm8514.gpbusy = false; |
| 3926 | 4278 | } |
| 3927 | 4279 | } |
| 3928 | 4280 | else |
| r17831 | r17832 | |
| 3930 | 4282 | s3.curr_y--; |
| 3931 | 4283 | if(s3.curr_y < s3.prev_y - s3.rect_height) |
| 3932 | 4284 | { |
| 3933 | | s3.state = S3_IDLE; |
| 3934 | | s3.gpbusy = false; |
| 4285 | ibm8514.state = IBM8514_IDLE; |
| 4286 | ibm8514.data_avail = false; |
| 4287 | ibm8514.gpbusy = false; |
| 3935 | 4288 | } |
| 3936 | 4289 | } |
| 3937 | 4290 | return; |
| r17831 | r17832 | |
| 3950 | 4303 | s3.curr_y++; |
| 3951 | 4304 | if(s3.curr_y > s3.prev_y + s3.rect_height) |
| 3952 | 4305 | { |
| 3953 | | s3.state = S3_IDLE; |
| 3954 | | s3.gpbusy = false; |
| 4306 | ibm8514.state = IBM8514_IDLE; |
| 4307 | ibm8514.gpbusy = false; |
| 4308 | ibm8514.data_avail = false; |
| 3955 | 4309 | } |
| 3956 | 4310 | } |
| 3957 | 4311 | else |
| r17831 | r17832 | |
| 3959 | 4313 | s3.curr_y--; |
| 3960 | 4314 | if(s3.curr_y < s3.prev_y - s3.rect_height) |
| 3961 | 4315 | { |
| 3962 | | s3.state = S3_IDLE; |
| 3963 | | s3.gpbusy = false; |
| 4316 | ibm8514.state = IBM8514_IDLE; |
| 4317 | ibm8514.gpbusy = false; |
| 4318 | ibm8514.data_avail = false; |
| 3964 | 4319 | } |
| 3965 | 4320 | } |
| 3966 | 4321 | return; |
| r17831 | r17832 | |
| 3988 | 4343 | s3.curr_y++; |
| 3989 | 4344 | if(s3.curr_y > s3.prev_y + s3.rect_height) |
| 3990 | 4345 | { |
| 3991 | | s3.state = S3_IDLE; |
| 3992 | | s3.gpbusy = false; |
| 4346 | ibm8514.state = IBM8514_IDLE; |
| 4347 | ibm8514.gpbusy = false; |
| 4348 | ibm8514.data_avail = false; |
| 3993 | 4349 | } |
| 3994 | 4350 | } |
| 3995 | 4351 | else |
| r17831 | r17832 | |
| 3997 | 4353 | s3.curr_y--; |
| 3998 | 4354 | if(s3.curr_y < s3.prev_y - s3.rect_height) |
| 3999 | 4355 | { |
| 4000 | | s3.state = S3_IDLE; |
| 4001 | | s3.gpbusy = false; |
| 4356 | ibm8514.state = IBM8514_IDLE; |
| 4357 | ibm8514.gpbusy = false; |
| 4358 | ibm8514.data_avail = false; |
| 4002 | 4359 | } |
| 4003 | 4360 | } |
| 4004 | 4361 | return; |
| r17831 | r17832 | |
| 4017 | 4374 | s3.curr_y++; |
| 4018 | 4375 | if(s3.curr_y > s3.prev_y + s3.rect_height) |
| 4019 | 4376 | { |
| 4020 | | s3.state = S3_IDLE; |
| 4021 | | s3.gpbusy = false; |
| 4377 | ibm8514.state = IBM8514_IDLE; |
| 4378 | ibm8514.gpbusy = false; |
| 4379 | ibm8514.data_avail = false; |
| 4022 | 4380 | } |
| 4023 | 4381 | } |
| 4024 | 4382 | else |
| r17831 | r17832 | |
| 4026 | 4384 | s3.curr_y--; |
| 4027 | 4385 | if(s3.curr_y < s3.prev_y - s3.rect_height) |
| 4028 | 4386 | { |
| 4029 | | s3.state = S3_IDLE; |
| 4030 | | s3.gpbusy = false; |
| 4387 | ibm8514.state = IBM8514_IDLE; |
| 4388 | ibm8514.gpbusy = false; |
| 4389 | ibm8514.data_avail = false; |
| 4031 | 4390 | } |
| 4032 | 4391 | } |
| 4033 | 4392 | return; |
| r17831 | r17832 | |
| 4101 | 4460 | else |
| 4102 | 4461 | s3.pixel_xfer = (s3.pixel_xfer & 0xffff0000) | data; |
| 4103 | 4462 | |
| 4104 | | if(s3.state == S3_DRAWING_RECT) |
| 4105 | | { |
| 4463 | if(ibm8514.state == IBM8514_DRAWING_RECT) |
| 4106 | 4464 | s3_wait_draw(); |
| 4107 | | } |
| 4108 | 4465 | |
| 4466 | if(ibm8514.state == IBM8514_DRAWING_SSV_1 || ibm8514.state == IBM8514_DRAWING_SSV_2) |
| 4467 | ibm8514_wait_draw_ssv(); |
| 4468 | |
| 4469 | if(ibm8514.state == IBM8514_DRAWING_LINE) |
| 4470 | ibm8514_wait_draw_vector(); |
| 4471 | |
| 4109 | 4472 | logerror("S3: Pixel Transfer = %08x\n",s3.pixel_xfer); |
| 4110 | 4473 | } |
| 4111 | 4474 | |
| r17831 | r17832 | |
| 4314 | 4677 | break; |
| 4315 | 4678 | case 0x8150: |
| 4316 | 4679 | s3.pixel_xfer = (s3.pixel_xfer & 0xffffff00) | data; |
| 4317 | | if(s3.state == S3_DRAWING_RECT) |
| 4680 | if(ibm8514.state == IBM8514_DRAWING_RECT) |
| 4318 | 4681 | s3_wait_draw(); |
| 4319 | 4682 | break; |
| 4320 | 4683 | case 0x8151: |
| 4321 | 4684 | s3.pixel_xfer = (s3.pixel_xfer & 0xffff00ff) | (data << 8); |
| 4322 | | if(s3.state == S3_DRAWING_RECT) |
| 4685 | if(ibm8514.state == IBM8514_DRAWING_RECT) |
| 4323 | 4686 | s3_wait_draw(); |
| 4324 | 4687 | break; |
| 4325 | 4688 | case 0x8152: |
| 4326 | 4689 | s3.pixel_xfer = (s3.pixel_xfer & 0xff00ffff) | (data << 16); |
| 4327 | | if(s3.state == S3_DRAWING_RECT) |
| 4690 | if(ibm8514.state == IBM8514_DRAWING_RECT) |
| 4328 | 4691 | s3_wait_draw(); |
| 4329 | 4692 | break; |
| 4330 | 4693 | case 0x8153: |
| 4331 | 4694 | s3.pixel_xfer = (s3.pixel_xfer & 0x00ffffff) | (data << 24); |
| 4332 | | if(s3.state == S3_DRAWING_RECT) |
| 4695 | if(ibm8514.state == IBM8514_DRAWING_RECT) |
| 4333 | 4696 | s3_wait_draw(); |
| 4334 | 4697 | break; |
| 4335 | 4698 | case 0xbee8: |
| r17831 | r17832 | |
| 4491 | 4854 | mem_space->install_legacy_readwrite_handler(mem_offset + 0x00000, mem_offset + 0x1ffff, FUNC(vga_gamtor_mem_r), FUNC(vga_gamtor_mem_w), mask); |
| 4492 | 4855 | } |
| 4493 | 4856 | |
| 4857 | static void ati_define_video_mode(running_machine &machine) |
| 4858 | { |
| 4859 | int clock; |
| 4860 | UINT8 clock_type; |
| 4861 | int div = ((ati.ext_reg[0x38] & 0xc0) >> 6) + 1; |
| 4862 | |
| 4863 | svga.rgb8_en = 0; |
| 4864 | svga.rgb15_en = 0; |
| 4865 | svga.rgb16_en = 0; |
| 4866 | svga.rgb32_en = 0; |
| 4867 | |
| 4868 | if(ati.ext_reg[0x30] & 0x20) |
| 4869 | svga.rgb8_en = 1; |
| 4870 | |
| 4871 | clock_type = ((ati.ext_reg[0x3e] & 0x10)>>1) | ((ati.ext_reg[0x39] & 0x02)<<1) | ((vga.miscellaneous_output & 0x0c)>>2); |
| 4872 | switch(clock_type) |
| 4873 | { |
| 4874 | case 0: |
| 4875 | clock = XTAL_42_9545MHz; |
| 4876 | break; |
| 4877 | case 1: |
| 4878 | clock = 48771000; |
| 4879 | break; |
| 4880 | case 2: |
| 4881 | clock = 16657000; |
| 4882 | break; |
| 4883 | case 3: |
| 4884 | clock = XTAL_36MHz; |
| 4885 | break; |
| 4886 | case 4: |
| 4887 | clock = 50350000; |
| 4888 | break; |
| 4889 | case 5: |
| 4890 | clock = 56640000; |
| 4891 | break; |
| 4892 | case 6: |
| 4893 | clock = 28322000; |
| 4894 | break; |
| 4895 | case 7: |
| 4896 | clock = 44900000; |
| 4897 | break; |
| 4898 | case 8: |
| 4899 | clock = 30240000; |
| 4900 | break; |
| 4901 | case 9: |
| 4902 | clock = XTAL_32MHz; |
| 4903 | break; |
| 4904 | case 10: |
| 4905 | clock = 37500000; |
| 4906 | break; |
| 4907 | case 11: |
| 4908 | clock = 39000000; |
| 4909 | break; |
| 4910 | case 12: |
| 4911 | clock = XTAL_40MHz; |
| 4912 | break; |
| 4913 | case 13: |
| 4914 | clock = 56644000; |
| 4915 | break; |
| 4916 | case 14: |
| 4917 | clock = 75000000; |
| 4918 | break; |
| 4919 | case 15: |
| 4920 | clock = 65000000; |
| 4921 | break; |
| 4922 | default: |
| 4923 | clock = XTAL_42_9545MHz; |
| 4924 | logerror("Invalid dot clock %i selected.\n",clock_type); |
| 4925 | } |
| 4926 | |
| 4927 | recompute_params_clock(machine,1,clock / div); |
| 4928 | } |
| 4929 | |
| 4930 | READ8_HANDLER( ati_mem_r ) |
| 4931 | { |
| 4932 | if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) |
| 4933 | { |
| 4934 | offset &= 0xffff; |
| 4935 | return vga.memory[(offset+svga.bank_r*0x10000)]; |
| 4936 | } |
| 4937 | |
| 4938 | return vga_mem_r(space,offset); |
| 4939 | } |
| 4940 | |
| 4941 | WRITE8_HANDLER( ati_mem_w ) |
| 4942 | { |
| 4943 | if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) |
| 4944 | { |
| 4945 | offset &= 0xffff; |
| 4946 | vga.memory[(offset+svga.bank_w*0x10000)] = data; |
| 4947 | } |
| 4948 | else |
| 4949 | vga_mem_w(space,offset,data); |
| 4950 | } |
| 4951 | |
| 4952 | |
| 4953 | READ8_DEVICE_HANDLER(ati_port_ext_r) |
| 4954 | { |
| 4955 | UINT8 ret = 0xff; |
| 4956 | |
| 4957 | switch(offset) |
| 4958 | { |
| 4959 | case 0: |
| 4960 | break; |
| 4961 | case 1: |
| 4962 | switch(ati.ext_reg_select) |
| 4963 | { |
| 4964 | case 0x20: |
| 4965 | ret = 0x10; // 512kB memory |
| 4966 | break; |
| 4967 | case 0x2a: |
| 4968 | ret = 0x06; // Chip revision (6 for the 28800-6, 5 for the 28800-5) |
| 4969 | break; |
| 4970 | case 0x37: |
| 4971 | { |
| 4972 | eeprom_device* eep = device->subdevice<eeprom_device>("ati_eeprom"); |
| 4973 | ret = 0x00; |
| 4974 | ret |= eep->read_bit() << 3; |
| 4975 | } |
| 4976 | break; |
| 4977 | default: |
| 4978 | ret = ati.ext_reg[ati.ext_reg_select]; |
| 4979 | } |
| 4980 | break; |
| 4981 | } |
| 4982 | |
| 4983 | return ret; |
| 4984 | } |
| 4985 | |
| 4986 | WRITE8_DEVICE_HANDLER(ati_port_ext_w) |
| 4987 | { |
| 4988 | switch(offset) |
| 4989 | { |
| 4990 | case 0: |
| 4991 | ati.ext_reg_select = data & 0x3f; |
| 4992 | break; |
| 4993 | case 1: |
| 4994 | ati.ext_reg[ati.ext_reg_select] = data; |
| 4995 | switch(ati.ext_reg_select) |
| 4996 | { |
| 4997 | case 0x2d: |
| 4998 | if(data & 0x08) |
| 4999 | { |
| 5000 | vga.crtc.horz_total = (vga.crtc.horz_total & 0x00ff) | (data & 0x01) << 8; |
| 5001 | // bit 1 = bit 8 of horizontal blank start |
| 5002 | // bit 2 = bit 8 of horizontal retrace start |
| 5003 | logerror("ATI: ATI2D (extensions) write %02x\n",data); |
| 5004 | } |
| 5005 | break; |
| 5006 | case 0x32: // memory page select |
| 5007 | svga.bank_r = ((data & 0x01) << 3) | ((data & 0xe0) >> 5); |
| 5008 | svga.bank_w = ((data & 0x1e) >> 1); |
| 5009 | //logerror("ATI: Memory Page Select write %02x\n",data); |
| 5010 | break; |
| 5011 | case 0x33: // EEPROM |
| 5012 | if(data & 0x04) |
| 5013 | { |
| 5014 | eeprom_device* eep = device->subdevice<eeprom_device>("ati_eeprom"); |
| 5015 | if(eep != NULL) |
| 5016 | { |
| 5017 | eep->write_bit((data & 0x01) ? ASSERT_LINE : CLEAR_LINE); |
| 5018 | eep->set_clock_line((data & 0x02) ? ASSERT_LINE : CLEAR_LINE); |
| 5019 | eep->set_cs_line((data & 0x08) ? CLEAR_LINE : ASSERT_LINE); |
| 5020 | } |
| 5021 | } |
| 5022 | break; |
| 5023 | default: |
| 5024 | logerror("ATI: Extended VGA register 0x01CE index %02x write %02x\n",ati.ext_reg_select,data); |
| 5025 | } |
| 5026 | break; |
| 5027 | } |
| 5028 | ati_define_video_mode(device->machine()); |
| 5029 | } |
| 5030 | |
| 5031 | /* |
| 5032 | 02E8h W(R): Display Status Register |
| 5033 | bit 0 SENSE is the result of a wired-OR of 3 comparators, one |
| 5034 | for each of the RGB video signal. |
| 5035 | By programming the RAMDAC for various values |
| 5036 | and patterns and then reading the SENSE, the monitor type |
| 5037 | (color, monochrome or none) can be determined. |
| 5038 | 1 VBLANK. Vertical Blank State |
| 5039 | If Vertical Blank is active this bit is set. |
| 5040 | 2 HORTOG. Horizontal Toggle |
| 5041 | This bit toggles every time a HSYNC pulse starts |
| 5042 | 3-15 Reserved(0) |
| 5043 | */ |
| 5044 | READ16_HANDLER(mach8_status_r) |
| 5045 | { |
| 5046 | return vga_vblank(space->machine()) << 1; |
| 5047 | } |
| 5048 | |
| 5049 | WRITE16_HANDLER(mach8_htotal_w) |
| 5050 | { |
| 5051 | ibm8514.htotal = data & 0x01ff; |
| 5052 | //vga.crtc.horz_total = data & 0x01ff; |
| 5053 | logerror("8514/A: Horizontal total write %04x\n",data); |
| 5054 | } |
| 5055 | |
| 5056 | /* |
| 5057 | 42E8h W(R): Subsystem Status Register (SUBSYS_STAT) |
| 5058 | bit 0-3 Interrupt requests. These bits show the state of internal interrupt |
| 5059 | requests. An interrupt will only occur if the corresponding bit(s) |
| 5060 | in SUBSYS_CNTL is set. Interrupts can only be reset by writing a 1 |
| 5061 | to the corresponding Interrupt Clear bit in SUBSYS_CNTL. |
| 5062 | Bit 0: VBLNKFLG |
| 5063 | 1: PICKFLAG |
| 5064 | 2: INVALIDIO |
| 5065 | 3: GPIDLE |
| 5066 | 4-6 MONITORID. |
| 5067 | 1: IBM 8507 (1024x768) Monochrome |
| 5068 | 2: IBM 8514 (1024x768) Color |
| 5069 | 5: IBM 8503 (640x480) Monochrome |
| 5070 | 6: IBM 8512/13 (640x480) Color |
| 5071 | 7 8PLANE. |
| 5072 | (CT82c480) This bit is latched on reset from pin P4D7. |
| 5073 | 8-11 CHIP_REV. Chip revision number. |
| 5074 | 12-15 (CT82c480) CHIP_ID. 0=CT 82c480. |
| 5075 | */ |
| 5076 | READ16_HANDLER(mach8_substatus_r) |
| 5077 | { |
| 5078 | // TODO: |
| 5079 | if(vga_vblank(space->machine()) != 0) // not correct, but will do for now |
| 5080 | ibm8514.substatus |= 0x01; |
| 5081 | return ibm8514.substatus; |
| 5082 | } |
| 5083 | |
| 5084 | /* |
| 5085 | 42E8h W(W): Subsystem Control Register (SUBSYS_CNTL) |
| 5086 | bit 0-3 Interrupt Reset. Write 1 to a bit to reset the interrupt. |
| 5087 | Bit 0 RVBLNKFLG Write 1 to reset Vertical Blank interrupt. |
| 5088 | 1 RPICKFLAG Write 1 to reset PICK interrupt. |
| 5089 | 2 RINVALIDIO Write 1 to reset Queue Overflow/Data |
| 5090 | Underflow interrupt. |
| 5091 | 3 RGPIDLE Write 1 to reset GPIDLE interrupt. |
| 5092 | 4-7 Reserved(0) |
| 5093 | 8 IBLNKFLG. If set Vertical Blank Interrupts are enabled. |
| 5094 | 9 IPICKFLAG. If set PICK Interrupts are enabled. |
| 5095 | 10 IINVALIDIO. If set Queue Overflow/Data Underflow Interrupts are |
| 5096 | enabled. |
| 5097 | 11 IGPIDLE. If set Graphics Engine Idle Interrupts are enabled. |
| 5098 | 12-13 CHPTEST. Used for chip testing. |
| 5099 | 14-15 Graphics Processor Control (GPCTRL). |
| 5100 | */ |
| 5101 | WRITE16_HANDLER(mach8_subcontrol_w) |
| 5102 | { |
| 5103 | ibm8514.subctrl = data; |
| 5104 | ibm8514.substatus &= ~(data & 0x0f); // reset interrupts |
| 5105 | // logerror("8514/A: Subsystem control write %04x\n",data); |
| 5106 | } |
| 5107 | |
| 5108 | READ16_HANDLER(mach8_subcontrol_r) |
| 5109 | { |
| 5110 | return ibm8514.subctrl; |
| 5111 | } |
| 5112 | |
| 5113 | READ16_HANDLER(mach8_htotal_r) |
| 5114 | { |
| 5115 | return ibm8514.htotal; |
| 5116 | } |
| 5117 | |
| 5118 | READ16_HANDLER(mach8_vtotal_r) |
| 5119 | { |
| 5120 | return ibm8514.vtotal; |
| 5121 | } |
| 5122 | |
| 5123 | WRITE16_HANDLER(mach8_vtotal_w) |
| 5124 | { |
| 5125 | ibm8514.vtotal = data; |
| 5126 | // vga.crtc.vert_total = data; |
| 5127 | logerror("8514/A: Vertical total write %04x\n",data); |
| 5128 | } |
| 5129 | |
| 5130 | READ16_HANDLER(mach8_vdisp_r) |
| 5131 | { |
| 5132 | return ibm8514.vdisp; |
| 5133 | } |
| 5134 | |
| 5135 | WRITE16_HANDLER(mach8_vdisp_w) |
| 5136 | { |
| 5137 | ibm8514.vdisp = data; |
| 5138 | // vga.crtc.vert_disp_end = data >> 3; |
| 5139 | logerror("8514/A: Vertical Displayed write %04x\n",data); |
| 5140 | } |
| 5141 | |
| 5142 | READ16_HANDLER(mach8_vsync_r) |
| 5143 | { |
| 5144 | return ibm8514.vsync; |
| 5145 | } |
| 5146 | |
| 5147 | WRITE16_HANDLER(mach8_vsync_w) |
| 5148 | { |
| 5149 | ibm8514.vsync = data; |
| 5150 | logerror("8514/A: Vertical Sync write %04x\n",data); |
| 5151 | } |
| 5152 | |
| 5153 | READ16_HANDLER(mach8_ec0_r) |
| 5154 | { |
| 5155 | return ibm8514.ec0; |
| 5156 | } |
| 5157 | |
| 5158 | WRITE16_HANDLER(mach8_ec0_w) |
| 5159 | { |
| 5160 | ibm8514.ec0 = data; |
| 5161 | logerror("8514/A: Extended configuration 0 write %04x\n",data); |
| 5162 | } |
| 5163 | |
| 5164 | READ16_HANDLER(mach8_ec1_r) |
| 5165 | { |
| 5166 | return ibm8514.ec1; |
| 5167 | } |
| 5168 | |
| 5169 | WRITE16_HANDLER(mach8_ec1_w) |
| 5170 | { |
| 5171 | ibm8514.ec1 = data; |
| 5172 | logerror("8514/A: Extended configuration 1 write %04x\n",data); |
| 5173 | } |
| 5174 | |
| 5175 | READ16_HANDLER(mach8_ec2_r) |
| 5176 | { |
| 5177 | return ibm8514.ec2; |
| 5178 | } |
| 5179 | |
| 5180 | WRITE16_HANDLER(mach8_ec2_w) |
| 5181 | { |
| 5182 | ibm8514.ec2 = data; |
| 5183 | logerror("8514/A: Extended configuration 2 write %04x\n",data); |
| 5184 | } |
| 5185 | |
| 5186 | READ16_HANDLER(mach8_ec3_r) |
| 5187 | { |
| 5188 | return ibm8514.ec3; |
| 5189 | } |
| 5190 | |
| 5191 | WRITE16_HANDLER(mach8_ec3_w) |
| 5192 | { |
| 5193 | ibm8514.ec3 = data; |
| 5194 | logerror("8514/A: Extended configuration 3 write %04x\n",data); |
| 5195 | } |
| 5196 | |
| 5197 | READ16_HANDLER(mach8_ext_fifo_r) |
| 5198 | { |
| 5199 | return 0x00; // for now, report all FIFO slots at free |
| 5200 | } |
| 5201 | |
| 5202 | WRITE16_HANDLER(mach8_linedraw_index_w) |
| 5203 | { |
| 5204 | ati.linedraw = data & 0x07; |
| 5205 | logerror("Mach8: Line Draw Index write %04x\n",data); |
| 5206 | } |
| 5207 | |
| 5208 | READ16_HANDLER(mach8_bresenham_count_r) |
| 5209 | { |
| 5210 | return s3.rect_width & 0x1fff; |
| 5211 | } |
| 5212 | |
| 5213 | WRITE16_HANDLER(mach8_bresenham_count_w) |
| 5214 | { |
| 5215 | s3.rect_width = data & 0x1fff; |
| 5216 | logerror("Mach8: Bresenham count write %04x\n",data); |
| 5217 | } |
| 5218 | |
| 5219 | READ16_HANDLER(mach8_scratch0_r) |
| 5220 | { |
| 5221 | return ati.scratch0; |
| 5222 | } |
| 5223 | |
| 5224 | WRITE16_HANDLER(mach8_scratch0_w) |
| 5225 | { |
| 5226 | ati.scratch0 = data; |
| 5227 | logerror("Mach8: Scratch Pad 0 write %04x\n",data); |
| 5228 | } |
| 5229 | |
| 5230 | READ16_HANDLER(mach8_scratch1_r) |
| 5231 | { |
| 5232 | return ati.scratch1; |
| 5233 | } |
| 5234 | |
| 5235 | WRITE16_HANDLER(mach8_scratch1_w) |
| 5236 | { |
| 5237 | ati.scratch1 = data; |
| 5238 | logerror("Mach8: Scratch Pad 1 write %04x\n",data); |
| 5239 | } |
| 5240 | |
| 5241 | /* |
| 5242 | 12EEh W(R): Configuration Status 1 Register (Mach8) |
| 5243 | bit 0 CLK_MODE. Set to use clock chip, clear to use crystals. |
| 5244 | 1 BUS_16. Set for 16bit bus, clear for 8bit bus |
| 5245 | 2 MC_BUS. Set for MicroChannel bus, clear for ISA/EISA bus |
| 5246 | 3 EEPROM_ENA. EEPROM enabled if set |
| 5247 | 4 DRAM_ENA. Set for DRAM, clear for VRAM. |
| 5248 | 5-6 MEM_INSTALLED. Video memory. 0: 512K, 1: 1024K |
| 5249 | 7 ROM_ENA. Set is ROM is enabled |
| 5250 | 8 ROM_PAGE_ENA. Set if ROM paging enabled |
| 5251 | 9-15 ROM_LOCATION. If bit 2 and 3 are 0 the ROM will be at this location: |
| 5252 | 0: C000h, 1: C080h, 2: C100h, .. 127: FF80h (unlikely) |
| 5253 | */ |
| 5254 | READ16_HANDLER(mach8_config1_r) |
| 5255 | { |
| 5256 | return 0x0082; |
| 5257 | } |
| 5258 | |
| 5259 | /* |
| 5260 | 16EEh (R): Configuration Status 2 Register (Mach8) |
| 5261 | bit 0 SHARE_CLOCK. If set the Mach8 shares clock with the VGA |
| 5262 | 1 HIRES_BOOT. Boot in hi-res mode if set |
| 5263 | 2 EPROM_16_ENA. Adapter configured for 16bit ROM if set |
| 5264 | 3 WRITE_PER_BIT. Write masked VRAM operations supported if set |
| 5265 | 4 FLASH_ENA. Flash page writes supported if set |
| 5266 | */ |
| 5267 | READ16_HANDLER(mach8_config2_r) |
| 5268 | { |
| 5269 | return 0x0002; |
| 5270 | } |
| 5271 | |
trunk/src/mess/video/isa_vga_ati.c
| r0 | r17832 | |
| 1 | /* |
| 2 | * isa_vga_ati.c |
| 3 | * |
| 4 | * Implementation of the ATi Graphics Ultra ISA Video card |
| 5 | * - Uses ATi 28800-6 (VGA Wonder) and ATi 38800-1 (Mach8, 8514/A clone) |
| 6 | * |
| 7 | * Created on: 9/09/2012 |
| 8 | */ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "isa_vga_ati.h" |
| 12 | #include "video/pc_vga.h" |
| 13 | |
| 14 | ROM_START( gfxultra ) |
| 15 | ROM_REGION(0x8000,"gfxultra", 0) |
| 16 | ROM_LOAD("113-11504-002.bin", 0x00000, 0x8000, CRC(f498b36a) SHA1(117cfc972ce4645538ba7262222d8ff38bc2c58c) ) |
| 17 | ROM_IGNORE( 0x8000 ) |
| 18 | ROM_END |
| 19 | |
| 20 | //************************************************************************** |
| 21 | // GLOBAL VARIABLES |
| 22 | //************************************************************************** |
| 23 | |
| 24 | const device_type ISA16_VGA_GFXULTRA = &device_creator<isa16_vga_gfxultra_device>; |
| 25 | |
| 26 | |
| 27 | //------------------------------------------------- |
| 28 | // machine_config_additions - device-specific |
| 29 | // machine configurations |
| 30 | //------------------------------------------------- |
| 31 | |
| 32 | machine_config_constructor isa16_vga_gfxultra_device::device_mconfig_additions() const |
| 33 | { |
| 34 | return MACHINE_CONFIG_NAME( pcvideo_ati_isa ); |
| 35 | } |
| 36 | |
| 37 | //------------------------------------------------- |
| 38 | // rom_region - device-specific ROM region |
| 39 | //------------------------------------------------- |
| 40 | |
| 41 | const rom_entry *isa16_vga_gfxultra_device::device_rom_region() const |
| 42 | { |
| 43 | return ROM_NAME( gfxultra ); |
| 44 | } |
| 45 | |
| 46 | //************************************************************************** |
| 47 | // LIVE DEVICE |
| 48 | //************************************************************************** |
| 49 | |
| 50 | //------------------------------------------------- |
| 51 | // isa8_vga_device - constructor |
| 52 | //------------------------------------------------- |
| 53 | |
| 54 | isa16_vga_gfxultra_device::isa16_vga_gfxultra_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 55 | device_t(mconfig, ISA16_VGA_GFXULTRA, "ATi Graphics Ultra Graphics Card", tag, owner, clock), |
| 56 | device_isa16_card_interface(mconfig, *this) |
| 57 | { |
| 58 | m_shortname = "gfxultra"; |
| 59 | } |
| 60 | |
| 61 | //------------------------------------------------- |
| 62 | // device_start - device-specific startup |
| 63 | //------------------------------------------------- |
| 64 | static READ8_HANDLER( input_port_0_r ) { return 0xff; } //return space->machine().root_device().ioport("IN0")->read(); } |
| 65 | |
| 66 | void isa16_vga_gfxultra_device::device_start() |
| 67 | { |
| 68 | set_isa_device(); |
| 69 | |
| 70 | video_start_vga( machine() ); |
| 71 | |
| 72 | pc_vga_init(machine(), input_port_0_r, NULL); |
| 73 | |
| 74 | int i; |
| 75 | for (i = 0; i < 0x100; i++) |
| 76 | palette_set_color_rgb(machine(), i, 0, 0, 0); |
| 77 | pc_video_start(machine()); |
| 78 | |
| 79 | m_isa->install_rom(this, 0xc0000, 0xc7fff, 0, 0, "vga", "gfxultra"); |
| 80 | |
| 81 | m_isa->install_device(this, 0x1ce, 0x1cf, 0, 0, FUNC(ati_port_ext_r), FUNC(ati_port_ext_w)); |
| 82 | m_isa->install16_device(0x2e8, 0x2eb, 0, 0, FUNC(mach8_status_r), FUNC(mach8_htotal_w)); |
| 83 | m_isa->install_device(0x3b0, 0x3bf, 0, 0, FUNC(vga_port_03b0_r), FUNC(vga_port_03b0_w)); |
| 84 | m_isa->install_device(0x3c0, 0x3cf, 0, 0, FUNC(vga_port_03c0_r), FUNC(vga_port_03c0_w)); |
| 85 | m_isa->install_device(0x3d0, 0x3df, 0, 0, FUNC(vga_port_03d0_r), FUNC(vga_port_03d0_w)); |
| 86 | m_isa->install16_device(0x12e8, 0x12eb, 0, 0, FUNC(mach8_vtotal_r),FUNC(mach8_vtotal_w)); |
| 87 | m_isa->install16_device(0x12ec, 0x12ef, 0, 0, FUNC(mach8_config1_r),NULL,NULL); |
| 88 | m_isa->install16_device(0x16e8, 0x16eb, 0, 0, FUNC(mach8_vdisp_r),FUNC(mach8_vdisp_w)); |
| 89 | m_isa->install16_device(0x16ec, 0x16ef, 0, 0, FUNC(mach8_config2_r),NULL,NULL); |
| 90 | m_isa->install16_device(0x1ae8, 0x1aeb, 0, 0, FUNC(mach8_vsync_r),FUNC(mach8_vsync_w)); |
| 91 | m_isa->install16_device(0x26e8, 0x26eb, 0, 0, FUNC(mach8_htotal_r),NULL,NULL); |
| 92 | m_isa->install16_device(0x2ee8, 0x2eeb, 0, 0, FUNC(mach8_subcontrol_r),NULL,NULL); |
| 93 | m_isa->install16_device(0x42e8, 0x42eb, 0, 0, FUNC(mach8_substatus_r), FUNC(mach8_subcontrol_w)); |
| 94 | m_isa->install16_device(0x52e8, 0x52eb, 0, 0, FUNC(mach8_ec0_r), FUNC(mach8_ec0_w)); |
| 95 | m_isa->install16_device(0x52ec, 0x52ef, 0, 0, FUNC(mach8_scratch0_r), FUNC(mach8_scratch0_w)); |
| 96 | m_isa->install16_device(0x56e8, 0x56eb, 0, 0, FUNC(mach8_ec1_r), FUNC(mach8_ec1_w)); |
| 97 | m_isa->install16_device(0x56ec, 0x56ef, 0, 0, FUNC(mach8_scratch0_r), FUNC(mach8_scratch0_w)); |
| 98 | m_isa->install16_device(0x5ae8, 0x5aeb, 0, 0, FUNC(mach8_ec2_r), FUNC(mach8_ec2_w)); |
| 99 | m_isa->install16_device(0x5ee8, 0x5eeb, 0, 0, FUNC(mach8_ec3_r), FUNC(mach8_ec3_w)); |
| 100 | m_isa->install16_device(0x82e8, 0x82eb, 0, 0, FUNC(s3_currenty_r), FUNC(s3_currenty_w)); |
| 101 | m_isa->install16_device(0x86e8, 0x86eb, 0, 0, FUNC(s3_currentx_r), FUNC(s3_currentx_w)); |
| 102 | m_isa->install16_device(0x8ae8, 0x8aeb, 0, 0, FUNC(s3_8ae8_r), FUNC(s3_8ae8_w)); |
| 103 | m_isa->install16_device(0x8ee8, 0x8eeb, 0, 0, FUNC(s3_8ee8_r), FUNC(s3_8ee8_w)); |
| 104 | m_isa->install16_device(0x92e8, 0x92eb, 0, 0, FUNC(s3_line_error_r), FUNC(s3_line_error_w)); |
| 105 | m_isa->install16_device(0x96e8, 0x96eb, 0, 0, FUNC(s3_width_r), FUNC(s3_width_w)); |
| 106 | m_isa->install16_device(0x96ec, 0x96ef, 0, 0, FUNC(mach8_bresenham_count_r), FUNC(mach8_bresenham_count_w)); |
| 107 | m_isa->install16_device(0x9ae8, 0x9aeb, 0, 0, FUNC(ibm8514_gpstatus_r), FUNC(ibm8514_cmd_w)); |
| 108 | m_isa->install16_device(0x9aec, 0x9aef, 0, 0, FUNC(mach8_ext_fifo_r), FUNC(mach8_linedraw_index_w)); |
| 109 | m_isa->install16_device(0x9ee8, 0x9eeb, 0, 0, FUNC(ibm8514_ssv_r), FUNC(ibm8514_ssv_w)); |
| 110 | m_isa->install16_device(0xa2e8, 0xa2eb, 0, 0, FUNC(s3_bgcolour_r), FUNC(s3_bgcolour_w)); |
| 111 | m_isa->install16_device(0xa6e8, 0xa6eb, 0, 0, FUNC(s3_fgcolour_r), FUNC(s3_fgcolour_w)); |
| 112 | m_isa->install16_device(0xb6e8, 0xb6eb, 0, 0, FUNC(s3_backmix_r), FUNC(s3_backmix_w)); |
| 113 | m_isa->install16_device(0xbae8, 0xbaeb, 0, 0, FUNC(s3_foremix_r), FUNC(s3_foremix_w)); |
| 114 | m_isa->install16_device(0xbee8, 0xbeeb, 0, 0, FUNC(s3_multifunc_r), FUNC(s3_multifunc_w)); |
| 115 | m_isa->install16_device(0xe2e8, 0xe2eb, 0, 0, FUNC(s3_pixel_xfer_r), FUNC(s3_pixel_xfer_w)); |
| 116 | |
| 117 | m_isa->install_memory(0xa0000, 0xbffff, 0, 0, FUNC(ati_mem_r), FUNC(ati_mem_w)); |
| 118 | } |
| 119 | |
| 120 | //------------------------------------------------- |
| 121 | // device_reset - device-specific reset |
| 122 | //------------------------------------------------- |
| 123 | |
| 124 | void isa16_vga_gfxultra_device::device_reset() |
| 125 | { |
| 126 | pc_vga_reset(machine()); |
| 127 | } |