trunk/src/emu/video/pc_vga.c
r22817 | r22818 | |
80 | 80 | #define VGA_START_ADDRESS (vga.crtc.start_addr) |
81 | 81 | #define VGA_LINE_LENGTH (vga.crtc.offset<<3) |
82 | 82 | |
83 | | #define IBM8514_LINE_LENGTH (m_vga->vga.crtc.offset << 3) |
| 83 | #define IBM8514_LINE_LENGTH (m_vga->offset()) |
84 | 84 | |
85 | 85 | #define CHAR_WIDTH ((vga.sequencer.data[1]&1)?8:9) |
86 | 86 | |
r22817 | r22818 | |
254 | 254 | |
255 | 255 | // copy over interfaces |
256 | 256 | vga.read_dipswitch = read8_delegate(); //read_dipswitch; |
257 | | vga.svga_intf.seq_regcount = 0x08; |
258 | | vga.svga_intf.crtc_regcount = 0x19; |
| 257 | vga.svga_intf.seq_regcount = 0x1f; |
| 258 | vga.svga_intf.crtc_regcount = 0x2d; |
259 | 259 | vga.svga_intf.vram_size = 0x200000; |
260 | 260 | |
261 | 261 | vga.memory = auto_alloc_array_clear(machine(), UINT8, vga.svga_intf.vram_size); |
r22817 | r22818 | |
289 | 289 | // set device ID |
290 | 290 | s3.id_high = 0x88; // CR2D |
291 | 291 | s3.id_low = 0x11; // CR2E |
292 | | s3.revision = 0x00; // CR2F |
293 | | s3.id_cr30 = 0xc0; // CR30 |
| 292 | s3.revision = 0x40; // CR2F |
| 293 | s3.id_cr30 = 0xe0; // CR30 |
294 | 294 | } |
295 | 295 | |
296 | 296 | void tseng_vga_device::device_start() |
r22817 | r22818 | |
320 | 320 | memset(&mach8, 0, sizeof(mach8)); |
321 | 321 | } |
322 | 322 | |
| 323 | UINT16 vga_device::offset() |
| 324 | { |
| 325 | // popmessage("Offset: %04x %s %s **",vga.crtc.offset,vga.crtc.dw?"DW":"--",vga.crtc.word_mode?"BYTE":"WORD"); |
| 326 | if(vga.crtc.dw) |
| 327 | return vga.crtc.offset << 3; |
| 328 | if(vga.crtc.word_mode) |
| 329 | return vga.crtc.offset << 1; |
| 330 | else |
| 331 | return vga.crtc.offset << 2; |
| 332 | } |
| 333 | |
323 | 334 | void vga_device::vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect) |
324 | 335 | { |
325 | 336 | UINT8 ch, attr; |
r22817 | r22818 | |
337 | 348 | vga.cursor.visible = 0; |
338 | 349 | |
339 | 350 | for (addr = vga.crtc.start_addr, line = -vga.crtc.preset_row_scan; line < TEXT_LINES; |
340 | | line += height, addr += TEXT_LINE_LENGTH) |
| 351 | line += height, addr += (offset()>>1)) |
341 | 352 | { |
342 | 353 | for (pos = addr, column=0; column<TEXT_COLUMNS; column++, pos++) |
343 | 354 | { |
r22817 | r22818 | |
408 | 419 | |
409 | 420 | /**/ |
410 | 421 | for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES; |
411 | | line += height, addr += EGA_LINE_LENGTH) |
| 422 | line += height, addr += offset()) |
412 | 423 | { |
413 | 424 | for(yi=0;yi<height;yi++) |
414 | 425 | { |
r22817 | r22818 | |
460 | 471 | curr_addr = 0; |
461 | 472 | if(!(vga.sequencer.data[4] & 0x08)) |
462 | 473 | { |
463 | | for (addr = VGA_START_ADDRESS, line=0; line<LINES; line+=height, addr+=VGA_LINE_LENGTH/4, curr_addr+=VGA_LINE_LENGTH/4) |
| 474 | for (addr = VGA_START_ADDRESS, line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) |
464 | 475 | { |
465 | 476 | for(yi = 0;yi < height; yi++) |
466 | 477 | { |
r22817 | r22818 | |
486 | 497 | } |
487 | 498 | else |
488 | 499 | { |
489 | | for (addr = VGA_START_ADDRESS, line=0; line<LINES; line+=height, addr+=VGA_LINE_LENGTH, curr_addr+=VGA_LINE_LENGTH) |
| 500 | for (addr = VGA_START_ADDRESS, line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) |
490 | 501 | { |
491 | 502 | for(yi = 0;yi < height; yi++) |
492 | 503 | { |
r22817 | r22818 | |
592 | 603 | int yi; |
593 | 604 | int xi; |
594 | 605 | UINT8 start_shift; |
595 | | UINT16 line_length; |
| 606 | // UINT16 line_length; |
596 | 607 | |
597 | 608 | /* line compare is screen sensitive */ |
598 | 609 | mask_comp = 0x3ff; |
599 | 610 | curr_addr = 0; |
600 | 611 | |
601 | | if(vga.crtc.dw) |
602 | | line_length = vga.crtc.offset << 3; // doubleword mode |
603 | | else |
604 | | { |
605 | | line_length = vga.crtc.offset << 4; |
606 | | } |
| 612 | // if(vga.crtc.dw) |
| 613 | // line_length = vga.crtc.offset << 3; // doubleword mode |
| 614 | // else |
| 615 | // { |
| 616 | // line_length = vga.crtc.offset << 4; |
| 617 | // } |
607 | 618 | |
608 | 619 | start_shift = (!(vga.sequencer.data[4] & 0x08)) ? 2 : 0; |
609 | 620 | |
610 | 621 | { |
611 | | for (addr = VGA_START_ADDRESS << start_shift, line=0; line<LINES; line+=height, addr+=line_length, curr_addr+=line_length) |
| 622 | for (addr = VGA_START_ADDRESS << start_shift, line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) |
612 | 623 | { |
613 | 624 | for(yi = 0;yi < height; yi++) |
614 | 625 | { |
r22817 | r22818 | |
652 | 663 | // mask_comp = 0xff | (TLINES & 0x300); |
653 | 664 | curr_addr = 0; |
654 | 665 | yi=0; |
655 | | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=TGA_LINE_LENGTH, curr_addr+=TGA_LINE_LENGTH) |
| 666 | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) |
656 | 667 | { |
657 | 668 | bitmapline = &bitmap.pix32(line); |
658 | 669 | addr %= vga.svga_intf.vram_size; |
r22817 | r22818 | |
696 | 707 | // mask_comp = 0xff | (TLINES & 0x300); |
697 | 708 | curr_addr = 0; |
698 | 709 | yi=0; |
699 | | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=TGA_LINE_LENGTH, curr_addr+=TGA_LINE_LENGTH) |
| 710 | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) |
700 | 711 | { |
701 | 712 | bitmapline = &bitmap.pix32(line); |
702 | 713 | addr %= vga.svga_intf.vram_size; |
r22817 | r22818 | |
740 | 751 | // mask_comp = 0xff | (TLINES & 0x300); |
741 | 752 | curr_addr = 0; |
742 | 753 | yi=0; |
743 | | for (addr = TGA_START_ADDRESS<<1, line=0; line<TLINES; line+=height, addr+=TGA_LINE_LENGTH, curr_addr+=TGA_LINE_LENGTH) |
| 754 | for (addr = TGA_START_ADDRESS<<1, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) |
744 | 755 | { |
745 | 756 | bitmapline = &bitmap.pix32(line); |
746 | 757 | addr %= vga.svga_intf.vram_size; |
r22817 | r22818 | |
781 | 792 | // mask_comp = 0xff | (TLINES & 0x300); |
782 | 793 | curr_addr = 0; |
783 | 794 | yi=0; |
784 | | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=(vga.crtc.offset * 4), curr_addr+=(vga.crtc.offset * 4)) |
| 795 | for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=(offset()), curr_addr+=(offset())) |
785 | 796 | { |
786 | 797 | bitmapline = &bitmap.pix32(line); |
787 | 798 | addr %= vga.svga_intf.vram_size; |
r22817 | r22818 | |
2659 | 2670 | |
2660 | 2671 | ******************************************/ |
2661 | 2672 | |
| 2673 | UINT16 s3_vga_device::offset() |
| 2674 | { |
| 2675 | //popmessage("Offset: %04x %s %s %s",vga.crtc.offset,vga.crtc.dw?"DW":"--",vga.crtc.word_mode?"BYTE":"WORD",(s3.memory_config & 0x08)?"31":"--"); |
| 2676 | if(s3.memory_config & 0x08) |
| 2677 | return vga.crtc.offset << 3; |
| 2678 | return vga_device::offset(); |
| 2679 | } |
| 2680 | |
2662 | 2681 | UINT8 s3_vga_device::s3_crtc_reg_read(UINT8 index) |
2663 | 2682 | { |
2664 | 2683 | UINT8 res; |
r22817 | r22818 | |
2737 | 2756 | case 0x51: |
2738 | 2757 | res = (vga.crtc.start_addr_latch & 0x0c0000) >> 18; |
2739 | 2758 | res |= ((svga.bank_w & 0x30) >> 2); |
| 2759 | res |= ((vga.crtc.offset & 0x0300) >> 4); |
2740 | 2760 | break; |
2741 | 2761 | case 0x55: |
2742 | 2762 | res = s3.extended_dac_ctrl; |
r22817 | r22818 | |
5050 | 5070 | } |
5051 | 5071 | } |
5052 | 5072 | |
| 5073 | UINT16 ati_vga_device::offset() |
| 5074 | { |
| 5075 | //popmessage("Offset: %04x %s %s %s %s",vga.crtc.offset,vga.crtc.dw?"DW":"--",vga.crtc.word_mode?"BYTE":"WORD",(ati.ext_reg[0x33] & 0x40) ? "PEL" : "---",(ati.ext_reg[0x30] & 0x20) ? "256" : "---"); |
| 5076 | if(ati.ext_reg[0x30] & 0x20) // likely wrong, gets 640x400/480 SVGA and tweaked 256 colour modes displaying correctly in Fractint. |
| 5077 | return vga_device::offset() << 3; |
| 5078 | if(ati.ext_reg[0x33] & 0x40) |
| 5079 | return vga_device::offset() << 2; |
| 5080 | return vga_device::offset(); |
| 5081 | } |
5053 | 5082 | |
| 5083 | |
5054 | 5084 | void ati_vga_device::ati_define_video_mode() |
5055 | 5085 | { |
5056 | 5086 | int clock; |
r22817 | r22818 | |
5224 | 5254 | //logerror("ATI: Memory Page Select write %02x (read: %i write %i)\n",data,svga.bank_r,svga.bank_w); |
5225 | 5255 | break; |
5226 | 5256 | case 0x33: // EEPROM |
| 5257 | |
5227 | 5258 | if(data & 0x04) |
5228 | 5259 | { |
5229 | 5260 | eeprom_device* eep = subdevice<eeprom_device>("ati_eeprom"); |
r22817 | r22818 | |
5576 | 5607 | } |
5577 | 5608 | } |
5578 | 5609 | |
| 5610 | UINT16 cirrus_vga_device::offset() |
| 5611 | { |
| 5612 | //popmessage("Offset: %04x %s %s **",vga.crtc.offset,vga.crtc.dw?"DW":"--",vga.crtc.word_mode?"BYTE":"WORD"); |
| 5613 | if(gc_mode_ext & 0x10) |
| 5614 | return vga.crtc.offset << 3; |
| 5615 | return vga_device::offset(); |
| 5616 | } |
| 5617 | |
5579 | 5618 | UINT8 cirrus_vga_device::cirrus_seq_reg_read(UINT8 index) |
5580 | 5619 | { |
5581 | 5620 | UINT8 res; |
r22817 | r22818 | |
5590 | 5629 | { |
5591 | 5630 | case 0x06: |
5592 | 5631 | case 0x07: |
| 5632 | case 0x09: |
| 5633 | case 0x0a: |
5593 | 5634 | //printf("%02x\n",index); |
5594 | 5635 | res = vga.sequencer.data[index]; |
5595 | 5636 | break; |
r22817 | r22818 | |
5612 | 5653 | { |
5613 | 5654 | case 0x06: |
5614 | 5655 | case 0x07: |
| 5656 | case 0x09: |
| 5657 | case 0x0a: |
5615 | 5658 | //printf("%02x %02x\n",index,data); |
5616 | 5659 | vga.sequencer.data[vga.sequencer.index] = data; |
5617 | 5660 | break; |
5618 | 5661 | } |
5619 | 5662 | } |
5620 | 5663 | } |
| 5664 | |
| 5665 | UINT8 cirrus_vga_device::cirrus_gc_reg_read(UINT8 index) |
| 5666 | { |
| 5667 | UINT8 res = 0xff; |
| 5668 | |
| 5669 | switch(index) |
| 5670 | { |
| 5671 | case 0x00: |
| 5672 | break; |
| 5673 | case 0x01: |
| 5674 | break; |
| 5675 | case 0x09: // Offset register 0 |
| 5676 | res = gc_bank_0; |
| 5677 | break; |
| 5678 | case 0x0a: // Offset register 1 |
| 5679 | res = gc_bank_1; |
| 5680 | break; |
| 5681 | case 0x0b: // Graphics controller mode extensions |
| 5682 | res = gc_mode_ext; |
| 5683 | break; |
| 5684 | case 0x0c: // Colour Key |
| 5685 | break; |
| 5686 | case 0x0d: // Colour Key Mask |
| 5687 | break; |
| 5688 | case 0x0e: // Miscellaneous Control |
| 5689 | break; |
| 5690 | case 0x10: // Foreground Colour Byte 1 |
| 5691 | break; |
| 5692 | case 0x11: // Background Colour Byte 1 |
| 5693 | break; |
| 5694 | // later registers are related to the BitBLT hardware |
| 5695 | default: |
| 5696 | res = gc_reg_read(index); |
| 5697 | } |
| 5698 | |
| 5699 | return res; |
| 5700 | } |
| 5701 | |
| 5702 | void cirrus_vga_device::cirrus_gc_reg_write(UINT8 index, UINT8 data) |
| 5703 | { |
| 5704 | logerror("CL: GC write %02x to GR%02x\n",data,index); |
| 5705 | switch(index) |
| 5706 | { |
| 5707 | case 0x00: |
| 5708 | case 0x01: // if extended writes are enabled (bit 2 of index 0bh), then index 0 and 1 are extended to 8 bits |
| 5709 | if(gc_mode_ext & 0x02) |
| 5710 | gc_reg_write(index,data); |
| 5711 | else |
| 5712 | gc_reg_write(index,data & 0x0f); |
| 5713 | break; |
| 5714 | case 0x09: // Offset register 0 |
| 5715 | gc_bank_0 = data; |
| 5716 | logerror("CL: Offset register 0 set to %i\n",data); |
| 5717 | break; |
| 5718 | case 0x0a: // Offset register 1 |
| 5719 | gc_bank_1 = data; |
| 5720 | logerror("CL: Offset register 1 set to %i\n",data); |
| 5721 | break; |
| 5722 | case 0x0b: // Graphics controller mode extensions |
| 5723 | gc_mode_ext = data; |
| 5724 | break; |
| 5725 | case 0x0c: // Colour Key |
| 5726 | break; |
| 5727 | case 0x0d: // Colour Key Mask |
| 5728 | break; |
| 5729 | case 0x0e: // Miscellaneous Control |
| 5730 | break; |
| 5731 | case 0x10: // Foreground Colour Byte 1 |
| 5732 | break; |
| 5733 | case 0x11: // Background Colour Byte 1 |
| 5734 | break; |
| 5735 | // later registers are related to the BitBLT hardware |
| 5736 | default: |
| 5737 | gc_reg_write(index,data); |
| 5738 | } |
| 5739 | } |
| 5740 | |
5621 | 5741 | READ8_MEMBER(cirrus_vga_device::port_03c0_r) |
5622 | 5742 | { |
5623 | 5743 | UINT8 res; |
r22817 | r22818 | |
5627 | 5747 | case 0x05: |
5628 | 5748 | res = cirrus_seq_reg_read(vga.sequencer.index); |
5629 | 5749 | break; |
| 5750 | case 0x0f: |
| 5751 | res = cirrus_gc_reg_read(vga.gc.index); |
| 5752 | break; |
5630 | 5753 | default: |
5631 | 5754 | res = vga_device::port_03c0_r(space,offset,mem_mask); |
5632 | 5755 | break; |
r22817 | r22818 | |
5642 | 5765 | case 0x05: |
5643 | 5766 | cirrus_seq_reg_write(vga.sequencer.index,data); |
5644 | 5767 | break; |
| 5768 | case 0x0f: |
| 5769 | cirrus_gc_reg_write(vga.gc.index,data); |
| 5770 | break; |
5645 | 5771 | default: |
5646 | 5772 | vga_device::port_03c0_w(space,offset,data,mem_mask); |
5647 | 5773 | break; |
5648 | 5774 | } |
5649 | 5775 | cirrus_define_video_mode(); |
5650 | 5776 | } |
| 5777 | |
| 5778 | READ8_MEMBER(cirrus_vga_device::port_03b0_r) |
| 5779 | { |
| 5780 | UINT8 res = 0xff; |
| 5781 | |
| 5782 | if (CRTC_PORT_ADDR == 0x3b0) |
| 5783 | { |
| 5784 | switch(offset) |
| 5785 | { |
| 5786 | case 5: |
| 5787 | res = cirrus_crtc_reg_read(vga.crtc.index); |
| 5788 | break; |
| 5789 | default: |
| 5790 | res = vga_device::port_03b0_r(space,offset,mem_mask); |
| 5791 | break; |
| 5792 | } |
| 5793 | } |
| 5794 | |
| 5795 | return res; |
| 5796 | } |
| 5797 | |
| 5798 | READ8_MEMBER(cirrus_vga_device::port_03d0_r) |
| 5799 | { |
| 5800 | UINT8 res = 0xff; |
| 5801 | |
| 5802 | if (CRTC_PORT_ADDR == 0x3d0) |
| 5803 | { |
| 5804 | switch(offset) |
| 5805 | { |
| 5806 | case 5: |
| 5807 | res = cirrus_crtc_reg_read(vga.crtc.index); |
| 5808 | break; |
| 5809 | default: |
| 5810 | res = vga_device::port_03d0_r(space,offset,mem_mask); |
| 5811 | break; |
| 5812 | } |
| 5813 | } |
| 5814 | |
| 5815 | return res; |
| 5816 | } |
| 5817 | |
| 5818 | WRITE8_MEMBER(cirrus_vga_device::port_03b0_w) |
| 5819 | { |
| 5820 | if (CRTC_PORT_ADDR == 0x3b0) |
| 5821 | { |
| 5822 | switch(offset) |
| 5823 | { |
| 5824 | case 5: |
| 5825 | vga.crtc.data[vga.crtc.index] = data; |
| 5826 | cirrus_crtc_reg_write(vga.crtc.index,data); |
| 5827 | break; |
| 5828 | default: |
| 5829 | vga_device::port_03b0_w(space,offset,data,mem_mask); |
| 5830 | break; |
| 5831 | } |
| 5832 | } |
| 5833 | } |
| 5834 | |
| 5835 | WRITE8_MEMBER(cirrus_vga_device::port_03d0_w) |
| 5836 | { |
| 5837 | if (CRTC_PORT_ADDR == 0x3d0) |
| 5838 | { |
| 5839 | switch(offset) |
| 5840 | { |
| 5841 | case 5: |
| 5842 | vga.crtc.data[vga.crtc.index] = data; |
| 5843 | cirrus_crtc_reg_write(vga.crtc.index,data); |
| 5844 | break; |
| 5845 | default: |
| 5846 | vga_device::port_03d0_w(space,offset,data,mem_mask); |
| 5847 | break; |
| 5848 | } |
| 5849 | } |
| 5850 | } |
| 5851 | |
| 5852 | UINT8 cirrus_vga_device::cirrus_crtc_reg_read(UINT8 index) |
| 5853 | { |
| 5854 | UINT8 res = 0xff; |
| 5855 | |
| 5856 | if(index <= 0x18) |
| 5857 | return crtc_reg_read(index); |
| 5858 | |
| 5859 | switch(index) |
| 5860 | { |
| 5861 | case 0x27: |
| 5862 | res = 0xa0; |
| 5863 | break; |
| 5864 | default: |
| 5865 | logerror("CL: Unhandled extended CRTC register CR%02x read\n",index); |
| 5866 | } |
| 5867 | |
| 5868 | return res; |
| 5869 | } |
| 5870 | |
| 5871 | void cirrus_vga_device::cirrus_crtc_reg_write(UINT8 index, UINT8 data) |
| 5872 | { |
| 5873 | if(index <= 0x18) |
| 5874 | { |
| 5875 | crtc_reg_write(index,data); |
| 5876 | return; |
| 5877 | } |
| 5878 | switch(index) |
| 5879 | { |
| 5880 | case 0x27: |
| 5881 | // Do nothing, read only |
| 5882 | break; |
| 5883 | default: |
| 5884 | logerror("CL: Unhandled extended CRTC register CR%02x write %02x\n",index,data); |
| 5885 | } |
| 5886 | |
| 5887 | } |
| 5888 | |
| 5889 | READ8_MEMBER(cirrus_vga_device::mem_r) |
| 5890 | { |
| 5891 | if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) |
| 5892 | { |
| 5893 | offset &= 0xffff; |
| 5894 | if(gc_mode_ext & 0x20) |
| 5895 | return vga.memory[(offset+gc_bank_0*0x4000)]; |
| 5896 | else |
| 5897 | return vga.memory[(offset+gc_bank_0*0x1000)]; |
| 5898 | } |
| 5899 | |
| 5900 | return vga_device::mem_r(space,offset,mem_mask); |
| 5901 | } |
| 5902 | |
| 5903 | WRITE8_MEMBER(cirrus_vga_device::mem_w) |
| 5904 | { |
| 5905 | if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) |
| 5906 | { |
| 5907 | offset &= 0xffff; |
| 5908 | if(gc_mode_ext & 0x20) |
| 5909 | vga.memory[(offset+gc_bank_0*0x4000)] = data; |
| 5910 | else |
| 5911 | vga.memory[(offset+gc_bank_0*0x1000)] = data; |
| 5912 | } |
| 5913 | else |
| 5914 | vga_device::mem_w(space,offset,data,mem_mask); |
| 5915 | } |