trunk/src/emu/video/pc_vga.c
| r18208 | r18209 | |
| 55 | 55 | static struct |
| 56 | 56 | { |
| 57 | 57 | read8_delegate read_dipswitch; |
| 58 | | struct pc_svga_interface svga_intf; |
| 58 | struct |
| 59 | { |
| 60 | size_t vram_size; |
| 61 | int seq_regcount; |
| 62 | int crtc_regcount; |
| 63 | } svga_intf; |
| 59 | 64 | |
| 60 | 65 | UINT8 *memory; |
| 61 | 66 | UINT32 pens[16]; /* the current 16 pens */ |
| r18208 | r18209 | |
| 888 | 893 | } |
| 889 | 894 | } |
| 890 | 895 | |
| 891 | | if (vga.svga_intf.choosevideomode) // TODO: remove this hack |
| 896 | if (svga.rgb32_en) |
| 892 | 897 | { |
| 893 | | return SVGA_HACK; |
| 894 | | } |
| 895 | | else if (svga.rgb32_en) |
| 896 | | { |
| 897 | 898 | return RGB32_MODE; |
| 898 | 899 | } |
| 899 | 900 | else if (svga.rgb24_en) |
| r18208 | r18209 | |
| 951 | 952 | |
| 952 | 953 | SCREEN_UPDATE_RGB32( pc_video ) |
| 953 | 954 | { |
| 954 | | UINT8 cur_mode = 0; |
| 955 | | int w = 0, h = 0; |
| 955 | UINT8 cur_mode = pc_vga_choosevideomode(screen.machine()); |
| 956 | 956 | |
| 957 | | cur_mode = pc_vga_choosevideomode(screen.machine()); |
| 958 | | |
| 959 | 957 | //popmessage("%02x %02x",cur_mode,vga.attribute.data[0x13]); |
| 960 | 958 | //popmessage("%d",vga.attribute.pel_shift); |
| 961 | 959 | //popmessage("%d %d %d",vga.crtc.vert_blank_start,vga.crtc.vert_blank_end,vga.crtc.vert_total); |
| r18208 | r18209 | |
| 973 | 971 | case RGB16_MODE: svga_vh_rgb16(screen.machine(), bitmap, cliprect); break; |
| 974 | 972 | case RGB24_MODE: svga_vh_rgb24(screen.machine(), bitmap, cliprect); break; |
| 975 | 973 | case RGB32_MODE: svga_vh_rgb32(screen.machine(), bitmap, cliprect); break; |
| 976 | | case SVGA_HACK: vga.svga_intf.choosevideomode(screen.machine(), bitmap, cliprect, vga.sequencer.data, vga.crtc.data, &w, &h); break; |
| 977 | 974 | } |
| 978 | 975 | |
| 979 | 976 | return 0; |
| r18208 | r18209 | |
| 2019 | 2016 | } |
| 2020 | 2017 | } |
| 2021 | 2018 | |
| 2022 | | void pc_vga_init(running_machine &machine, read8_delegate read_dipswitch, const struct pc_svga_interface *svga_intf) |
| 2019 | void pc_vga_init(running_machine &machine, read8_delegate read_dipswitch) |
| 2023 | 2020 | { |
| 2024 | 2021 | memset(&vga, 0, sizeof(vga)); |
| 2025 | 2022 | |
| 2026 | 2023 | /* copy over interfaces */ |
| 2024 | vga.read_dipswitch = read_dipswitch; |
| 2025 | vga.svga_intf.vram_size = 0x100000; |
| 2026 | vga.svga_intf.seq_regcount = 0x05; |
| 2027 | vga.svga_intf.crtc_regcount = 0x19; |
| 2028 | |
| 2029 | vga.memory = auto_alloc_array(machine, UINT8, vga.svga_intf.vram_size); |
| 2030 | vga.sequencer.data = auto_alloc_array(machine, UINT8, vga.svga_intf.seq_regcount); |
| 2031 | vga.crtc.data = auto_alloc_array(machine, UINT8, 0x100); |
| 2032 | memset(vga.memory, '\0', vga.svga_intf.vram_size); |
| 2033 | memset(vga.sequencer.data, '\0', vga.svga_intf.seq_regcount); |
| 2034 | memset(vga.crtc.data, '\0', 0x100); |
| 2035 | |
| 2036 | pc_vga_reset(machine); |
| 2037 | |
| 2038 | } |
| 2039 | |
| 2040 | void pc_vga_cirrus_init(running_machine &machine, read8_delegate read_dipswitch) |
| 2041 | { |
| 2042 | memset(&vga, 0, sizeof(vga)); |
| 2043 | |
| 2044 | /* copy over interfaces */ |
| 2027 | 2045 | vga.read_dipswitch = read_dipswitch; |
| 2028 | | if (svga_intf) |
| 2029 | | { |
| 2030 | | vga.svga_intf = *svga_intf; |
| 2046 | vga.svga_intf.vram_size = 0x200000; |
| 2047 | vga.svga_intf.seq_regcount = 0x08; |
| 2048 | vga.svga_intf.crtc_regcount = 0x19; |
| 2031 | 2049 | |
| 2032 | | if (vga.svga_intf.seq_regcount < 0x05) |
| 2033 | | fatalerror("Invalid SVGA sequencer register count\n"); |
| 2034 | | if (vga.svga_intf.crtc_regcount < 0x19) |
| 2035 | | fatalerror("Invalid SVGA CRTC register count\n"); |
| 2036 | | } |
| 2037 | | else |
| 2038 | | { |
| 2039 | | vga.svga_intf.vram_size = 0x100000; |
| 2040 | | vga.svga_intf.seq_regcount = 0x05; |
| 2041 | | vga.svga_intf.crtc_regcount = 0x19; |
| 2042 | | } |
| 2043 | | |
| 2044 | 2050 | vga.memory = auto_alloc_array(machine, UINT8, vga.svga_intf.vram_size); |
| 2045 | 2051 | vga.sequencer.data = auto_alloc_array(machine, UINT8, vga.svga_intf.seq_regcount); |
| 2046 | 2052 | vga.crtc.data = auto_alloc_array(machine, UINT8, 0x100); |
| r18208 | r18209 | |
| 5360 | 5366 | return 0x0002; |
| 5361 | 5367 | } |
| 5362 | 5368 | |
| 5369 | /****************************************** |
| 5370 | |
| 5371 | Cirrus SVGA card implementation |
| 5372 | |
| 5373 | ******************************************/ |
| 5374 | |
| 5375 | static void cirrus_define_video_mode(running_machine &machine) |
| 5376 | { |
| 5377 | svga.rgb8_en = 0; |
| 5378 | svga.rgb15_en = 0; |
| 5379 | svga.rgb16_en = 0; |
| 5380 | svga.rgb24_en = 0; |
| 5381 | svga.rgb32_en = 0; |
| 5382 | if ((vga.sequencer.data[0x06] == 0x12) && (vga.sequencer.data[0x07] & 0x01)) |
| 5383 | { |
| 5384 | switch(vga.sequencer.data[0x07] & 0x0E) |
| 5385 | { |
| 5386 | case 0x00: svga.rgb8_en = 1; break; |
| 5387 | case 0x02: svga.rgb16_en = 1; break; //double VCLK |
| 5388 | case 0x04: svga.rgb24_en = 1; break; |
| 5389 | case 0x06: svga.rgb16_en = 1; break; |
| 5390 | case 0x08: svga.rgb32_en = 1; break; |
| 5391 | } |
| 5392 | } |
| 5393 | } |
| 5394 | |
| 5395 | static UINT8 cirrus_seq_reg_read(running_machine &machine, UINT8 index) |
| 5396 | { |
| 5397 | UINT8 res; |
| 5398 | |
| 5399 | res = 0xff; |
| 5400 | |
| 5401 | if(index <= 0x04) |
| 5402 | res = vga.sequencer.data[index]; |
| 5403 | else |
| 5404 | { |
| 5405 | switch(index) |
| 5406 | { |
| 5407 | case 0x06: |
| 5408 | case 0x07: |
| 5409 | //printf("%02x\n",index); |
| 5410 | res = vga.sequencer.data[index]; |
| 5411 | break; |
| 5412 | } |
| 5413 | } |
| 5414 | |
| 5415 | return res; |
| 5416 | } |
| 5417 | |
| 5418 | static void cirrus_seq_reg_write(running_machine &machine, UINT8 index, UINT8 data) |
| 5419 | { |
| 5420 | if(index <= 0x04) |
| 5421 | { |
| 5422 | vga.sequencer.data[vga.sequencer.index] = data; |
| 5423 | seq_reg_write(machine,vga.sequencer.index,data); |
| 5424 | } |
| 5425 | else |
| 5426 | { |
| 5427 | switch(index) |
| 5428 | { |
| 5429 | case 0x06: |
| 5430 | case 0x07: |
| 5431 | //printf("%02x %02x\n",index,data); |
| 5432 | vga.sequencer.data[vga.sequencer.index] = data; |
| 5433 | break; |
| 5434 | } |
| 5435 | } |
| 5436 | } |
| 5437 | READ8_HANDLER(cirrus_03c0_r) |
| 5438 | { |
| 5439 | UINT8 res; |
| 5440 | |
| 5441 | switch(offset) |
| 5442 | { |
| 5443 | case 0x05: |
| 5444 | res = cirrus_seq_reg_read(space.machine(),vga.sequencer.index); |
| 5445 | break; |
| 5446 | default: |
| 5447 | res = vga_port_03c0_r(space,offset); |
| 5448 | break; |
| 5449 | } |
| 5450 | |
| 5451 | return res; |
| 5452 | } |
| 5453 | |
| 5454 | WRITE8_HANDLER(cirrus_03c0_w) |
| 5455 | { |
| 5456 | switch(offset) |
| 5457 | { |
| 5458 | case 0x05: |
| 5459 | cirrus_seq_reg_write(space.machine(),vga.sequencer.index,data); |
| 5460 | break; |
| 5461 | default: |
| 5462 | vga_port_03c0_w(space,offset,data); |
| 5463 | break; |
| 5464 | } |
| 5465 | cirrus_define_video_mode(space.machine()); |
| 5466 | } |
| 5467 | |
| 5468 | void pc_svga_cirrus_io_init(running_machine &machine, address_space &mem_space, offs_t mem_offset, address_space &io_space, offs_t port_offset) |
| 5469 | { |
| 5470 | int buswidth; |
| 5471 | UINT64 mask = 0; |
| 5472 | |
| 5473 | buswidth = machine.firstcpu->space_config(AS_PROGRAM)->m_databus_width; |
| 5474 | switch(buswidth) |
| 5475 | { |
| 5476 | case 8: |
| 5477 | mask = 0; |
| 5478 | break; |
| 5479 | |
| 5480 | case 16: |
| 5481 | mask = 0xffff; |
| 5482 | break; |
| 5483 | |
| 5484 | case 32: |
| 5485 | mask = 0xffffffff; |
| 5486 | break; |
| 5487 | |
| 5488 | case 64: |
| 5489 | mask = -1; |
| 5490 | break; |
| 5491 | |
| 5492 | default: |
| 5493 | fatalerror("VGA: Bus width %d not supported\n", buswidth); |
| 5494 | break; |
| 5495 | } |
| 5496 | io_space.install_legacy_readwrite_handler(port_offset + 0x3b0, port_offset + 0x3bf, FUNC(vga_port_03b0_r), FUNC(vga_port_03b0_w), mask); |
| 5497 | io_space.install_legacy_readwrite_handler(port_offset + 0x3c0, port_offset + 0x3cf, FUNC(cirrus_03c0_r), FUNC(cirrus_03c0_w), mask); |
| 5498 | io_space.install_legacy_readwrite_handler(port_offset + 0x3d0, port_offset + 0x3df, FUNC(vga_port_03d0_r), FUNC(vga_port_03d0_w), mask); |
| 5499 | |
| 5500 | mem_space.install_legacy_readwrite_handler(mem_offset + 0x00000, mem_offset + 0x1ffff, FUNC(vga_mem_r), FUNC(vga_mem_w), mask); |
| 5501 | } |
trunk/src/emu/video/pc_vga.h
| r18208 | r18209 | |
| 15 | 15 | MACHINE_CONFIG_EXTERN( pcvideo_ati_isa ); |
| 16 | 16 | |
| 17 | 17 | VIDEO_START( vga ); |
| 18 | | |
| 19 | | struct pc_svga_interface |
| 20 | | { |
| 21 | | size_t vram_size; |
| 22 | | int seq_regcount; |
| 23 | | int gc_regcount; |
| 24 | | int crtc_regcount; |
| 25 | | void (*choosevideomode)(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, const UINT8 *sequencer, const UINT8 *crtc, int *width, int *height); |
| 26 | | }; |
| 27 | | |
| 28 | | void pc_vga_init(running_machine &machine, read8_delegate read_dipswitch, const struct pc_svga_interface *svga_intf); |
| 18 | void pc_vga_init(running_machine &machine, read8_delegate read_dipswitch); |
| 19 | void pc_vga_cirrus_init(running_machine &machine, read8_delegate read_dipswitch); |
| 29 | 20 | void pc_vga_io_init(running_machine &machine, address_space &mem_space, offs_t mem_offset, address_space &io_space, offs_t port_offset); |
| 30 | 21 | void pc_vga_gamtor_io_init(running_machine &machine, address_space &mem_space, offs_t mem_offset, address_space &io_space, offs_t port_offset); |
| 31 | 22 | void pc_svga_trident_io_init(running_machine &machine, address_space &mem_space, offs_t mem_offset, address_space &io_space, offs_t port_offset); |
| 23 | void pc_svga_cirrus_io_init(running_machine &machine, address_space &mem_space, offs_t mem_offset, address_space &io_space, offs_t port_offset); |
| 32 | 24 | void pc_vga_reset(running_machine &machine); |
| 33 | 25 | void *pc_vga_memory(void); |
| 34 | 26 | size_t pc_vga_memory_size(void); |
trunk/src/mess/video/cirrus.c
| r18208 | r18209 | |
| 67 | 67 | |
| 68 | 68 | #define LOG_PCIACCESS 0 |
| 69 | 69 | |
| 70 | | static void cirrus_update_8bpp(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 71 | | { |
| 72 | | UINT32 *line; |
| 73 | | const UINT8 *vram; |
| 74 | | int y, x; |
| 75 | | |
| 76 | | vram = (const UINT8 *) pc_vga_memory(); |
| 77 | | |
| 78 | | for (y = 0; y < 480; y++) |
| 79 | | { |
| 80 | | line = &bitmap.pix32(y); |
| 81 | | |
| 82 | | for (x = 0; x < 640; x++) |
| 83 | | *line++ = machine.pens[*vram++]; |
| 84 | | } |
| 85 | | } |
| 86 | | |
| 87 | | |
| 88 | | |
| 89 | | static void cirrus_update_16bpp(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 90 | | { |
| 91 | | fatalerror("NYI\n"); |
| 92 | | } |
| 93 | | |
| 94 | | |
| 95 | | |
| 96 | | static void cirrus_update_24bpp(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 97 | | { |
| 98 | | fatalerror("NYI\n"); |
| 99 | | } |
| 100 | | |
| 101 | | |
| 102 | | |
| 103 | | static void cirrus_update_32bpp(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 104 | | { |
| 105 | | fatalerror("NYI\n"); |
| 106 | | } |
| 107 | | |
| 108 | | |
| 109 | | |
| 110 | | static void cirrus_choosevideomode(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, const UINT8 *sequencer, |
| 111 | | const UINT8 *crtc, int *width, int *height) |
| 112 | | { |
| 113 | | if ((sequencer[0x06] == 0x12) && (sequencer[0x07] & 0x01)) |
| 114 | | { |
| 115 | | *width = 640; |
| 116 | | *height = 480; |
| 117 | | |
| 118 | | switch(sequencer[0x07] & 0x0E) |
| 119 | | { |
| 120 | | case 0x00: cirrus_update_8bpp(machine, bitmap, cliprect); break; |
| 121 | | case 0x02: cirrus_update_16bpp(machine, bitmap, cliprect); break; |
| 122 | | case 0x04: cirrus_update_24bpp(machine, bitmap, cliprect); break; |
| 123 | | case 0x06: cirrus_update_16bpp(machine, bitmap, cliprect); break; |
| 124 | | case 0x08: cirrus_update_32bpp(machine, bitmap, cliprect); break; |
| 125 | | } |
| 126 | | } |
| 127 | | } |
| 128 | | |
| 129 | 70 | //************************************************************************** |
| 130 | 71 | // DEVICE DEFINITIONS |
| 131 | 72 | //************************************************************************** |
| r18208 | r18209 | |
| 146 | 87 | { |
| 147 | 88 | } |
| 148 | 89 | |
| 149 | | const struct pc_svga_interface cirrus_svga_interface = |
| 150 | | { |
| 151 | | 2 * 1024 * 1024, /* 2 megs vram */ |
| 152 | | 8, /* 8 sequencer registers */ |
| 153 | | 10, /* 10 gc registers */ |
| 154 | | 25, /* 25 crtc registers */ |
| 155 | | cirrus_choosevideomode |
| 156 | | }; |
| 157 | | |
| 158 | | |
| 159 | 90 | //------------------------------------------------- |
| 160 | 91 | // device_start - device-specific startup |
| 161 | 92 | //------------------------------------------------- |
| 162 | 93 | |
| 163 | 94 | void cirrus_device::device_start() |
| 164 | 95 | { |
| 165 | | pc_vga_init(machine(), read8_delegate(), &cirrus_svga_interface); |
| 166 | | pc_vga_io_init(machine(), machine().device("ppc1")->memory().space(AS_PROGRAM), 0xC00A0000, machine().device("ppc1")->memory().space(AS_PROGRAM), 0x80000000); |
| 96 | pc_vga_cirrus_init(machine(), read8_delegate()); |
| 97 | pc_svga_cirrus_io_init(machine(), machine().device("ppc1")->memory().space(AS_PROGRAM), 0xC00A0000, machine().device("ppc1")->memory().space(AS_PROGRAM), 0x80000000); |
| 167 | 98 | } |
| 168 | 99 | |
| 169 | 100 | //------------------------------------------------- |