trunk/src/emu/video/pc_vga.c
| r245604 | r245605 | |
| 276 | 276 | vga.svga_intf.seq_regcount = 0x1f; |
| 277 | 277 | vga.svga_intf.crtc_regcount = 0x2d; |
| 278 | 278 | vga.svga_intf.vram_size = 0x200000; |
| 279 | | gc_locked = true; |
| 280 | 279 | |
| 281 | 280 | vga.memory.resize_and_clear(vga.svga_intf.vram_size); |
| 282 | 281 | save_item(NAME(vga.memory)); |
| r245604 | r245605 | |
| 1144 | 1143 | return 0; |
| 1145 | 1144 | } |
| 1146 | 1145 | |
| 1146 | UINT32 cirrus_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 1147 | { |
| 1148 | UINT8 cur_mode = 0; |
| 1149 | int x,y,bit; |
| 1150 | UINT32 ptr = (vga.svga_intf.vram_size - 0x4000); // cursor patterns are stored in the last 16kB of VRAM |
| 1151 | svga_device::screen_update(screen, bitmap, cliprect); |
| 1152 | |
| 1153 | cur_mode = pc_vga_choosevideomode(); |
| 1154 | |
| 1155 | if(m_cursor_attr & 0x01) // hardware cursor enabled |
| 1156 | { |
| 1157 | // draw hardware graphics cursor |
| 1158 | if(m_cursor_attr & 0x04) // 64x64 |
| 1159 | { |
| 1160 | ptr += ((m_cursor_addr & 0x3c) * 256); |
| 1161 | for(y=0;y<64;y++) |
| 1162 | { |
| 1163 | for(x=0;x<64;x+=8) |
| 1164 | { |
| 1165 | for(bit=0;bit<8;bit++) |
| 1166 | { |
| 1167 | UINT8 pixel1 = vga.memory[ptr] >> (7-bit); |
| 1168 | UINT8 pixel2 = vga.memory[ptr+256] >> (7-bit); |
| 1169 | UINT8 output = ((pixel1 & 0x01) << 1) | (pixel2 & 0x01); |
| 1170 | switch(output) |
| 1171 | { |
| 1172 | case 0: // transparent - do nothing |
| 1173 | break; |
| 1174 | case 1: // background |
| 1175 | bitmap.pix32(y,x+bit) = (m_ext_palette[0].red << 16) | (m_ext_palette[0].green << 8) | (m_ext_palette[0].blue); |
| 1176 | break; |
| 1177 | case 2: // XOR |
| 1178 | bitmap.pix32(y,x+bit) = ~bitmap.pix32(y,x+bit); |
| 1179 | break; |
| 1180 | case 3: // foreground |
| 1181 | bitmap.pix32(y,x+bit) = (m_ext_palette[15].red << 16) | (m_ext_palette[15].green << 8) | (m_ext_palette[15].blue); |
| 1182 | break; |
| 1183 | } |
| 1184 | } |
| 1185 | } |
| 1186 | } |
| 1187 | } |
| 1188 | else |
| 1189 | { |
| 1190 | ptr += ((m_cursor_addr & 0x3f) * 256); |
| 1191 | for(y=0;y<32;y++) |
| 1192 | { |
| 1193 | for(x=0;x<32;x+=8) |
| 1194 | { |
| 1195 | for(bit=0;bit<8;bit++) |
| 1196 | { |
| 1197 | UINT8 pixel1 = vga.memory[ptr] >> (7-bit); |
| 1198 | UINT8 pixel2 = vga.memory[ptr+128] >> (7-bit); |
| 1199 | UINT8 output = ((pixel1 & 0x01) << 1) | (pixel2 & 0x01); |
| 1200 | switch(output) |
| 1201 | { |
| 1202 | case 0: // transparent - do nothing |
| 1203 | break; |
| 1204 | case 1: // background |
| 1205 | bitmap.pix32(y,x+bit) = (m_ext_palette[0].red << 16) | (m_ext_palette[0].green << 8) | (m_ext_palette[0].blue); |
| 1206 | break; |
| 1207 | case 2: // XOR |
| 1208 | bitmap.pix32(y,x+bit) = ~bitmap.pix32(y,x+bit); |
| 1209 | break; |
| 1210 | case 3: // foreground |
| 1211 | bitmap.pix32(y,x+bit) = (m_ext_palette[15].red << 16) | (m_ext_palette[15].green << 8) | (m_ext_palette[15].blue); |
| 1212 | break; |
| 1213 | } |
| 1214 | } |
| 1215 | ptr++; |
| 1216 | } |
| 1217 | } |
| 1218 | } |
| 1219 | } |
| 1220 | return 0; |
| 1221 | } |
| 1222 | |
| 1147 | 1223 | /***************************************************************************/ |
| 1148 | 1224 | |
| 1149 | 1225 | inline UINT8 vga_device::rotate_right(UINT8 val) |
| r245604 | r245605 | |
| 2025 | 2101 | s3.sr11 = 0x41; |
| 2026 | 2102 | } |
| 2027 | 2103 | |
| 2104 | void cirrus_vga_device::device_reset() |
| 2105 | { |
| 2106 | vga_device::device_reset(); |
| 2107 | gc_locked = true; |
| 2108 | gc_mode_ext = 0; |
| 2109 | gc_bank_0 = gc_bank_1 = 0; |
| 2110 | gc_blt_status = 0; |
| 2111 | m_cursor_attr = 0x00; // disable hardware cursor and extra palette |
| 2112 | m_cursor_x = m_cursor_y = 0; |
| 2113 | m_cursor_addr = 0; |
| 2114 | m_scratchpad1 = m_scratchpad2 = m_scratchpad3 = 0; |
| 2115 | m_cr19 = m_cr1a = m_cr1b = 0; |
| 2116 | memset(m_ext_palette, 0, sizeof(m_ext_palette)); |
| 2117 | } |
| 2118 | |
| 2028 | 2119 | READ8_MEMBER(vga_device::mem_r) |
| 2029 | 2120 | { |
| 2030 | 2121 | /* TODO: check me */ |
| r245604 | r245605 | |
| 5684 | 5775 | if(gc_locked) |
| 5685 | 5776 | return 0x0f; |
| 5686 | 5777 | else |
| 5687 | | return 0x00; |
| 5778 | return m_lock_reg; |
| 5688 | 5779 | break; |
| 5689 | | case 0x07: |
| 5690 | 5780 | case 0x09: |
| 5691 | | case 0x0a: |
| 5692 | 5781 | //printf("%02x\n",index); |
| 5693 | 5782 | res = vga.sequencer.data[index]; |
| 5694 | 5783 | break; |
| 5784 | case 0x0a: |
| 5785 | res = m_scratchpad1; |
| 5786 | break; |
| 5787 | case 0x14: |
| 5788 | res = m_scratchpad2; |
| 5789 | break; |
| 5790 | case 0x15: |
| 5791 | res = m_scratchpad3; |
| 5792 | break; |
| 5695 | 5793 | default: |
| 5696 | 5794 | res = vga.sequencer.data[index]; |
| 5697 | 5795 | } |
| r245604 | r245605 | |
| 5712 | 5810 | case 0x06: |
| 5713 | 5811 | // Note: extensions are always enabled on the GD5429 |
| 5714 | 5812 | if((data & 0x17) == 0x12) // bits 3,5,6,7 ignored |
| 5813 | { |
| 5715 | 5814 | gc_locked = false; |
| 5815 | logerror("Cirrus register extensions unlocked\n"); |
| 5816 | } |
| 5716 | 5817 | else |
| 5818 | { |
| 5717 | 5819 | gc_locked = true; |
| 5718 | | case 0x09: |
| 5719 | | case 0x0a: |
| 5720 | | //printf("%02x %02x\n",index,data); |
| 5721 | | vga.sequencer.data[vga.sequencer.index] = data; |
| 5820 | logerror("Cirrus register extensions locked\n"); |
| 5821 | } |
| 5822 | m_lock_reg = data & 0x17; |
| 5722 | 5823 | break; |
| 5723 | 5824 | case 0x07: |
| 5724 | 5825 | if((data & 0xf0) != 0) |
| 5725 | | popmessage("1MB framebuffer window enabled at %iMB",data >> 4); |
| 5826 | popmessage("1MB framebuffer window enabled at %iMB (%02x)",data >> 4,data); |
| 5726 | 5827 | vga.sequencer.data[vga.sequencer.index] = data; |
| 5727 | 5828 | break; |
| 5829 | case 0x09: |
| 5830 | //printf("%02x %02x\n",index,data); |
| 5831 | vga.sequencer.data[vga.sequencer.index] = data; |
| 5832 | break; |
| 5833 | case 0x0a: |
| 5834 | m_scratchpad1 = data; // GD5402/GD542x BIOS writes VRAM size here. |
| 5835 | break; |
| 5836 | case 0x10: |
| 5837 | case 0x30: |
| 5838 | case 0x50: |
| 5839 | case 0x70: |
| 5840 | case 0x90: |
| 5841 | case 0xb0: |
| 5842 | case 0xd0: |
| 5843 | case 0xf0: // bits 5-7 of the register index are the low bits of the X co-ordinate |
| 5844 | m_cursor_x = (data << 3) | ((index & 0xe0) >> 5); |
| 5845 | break; |
| 5846 | case 0x11: |
| 5847 | case 0x31: |
| 5848 | case 0x51: |
| 5849 | case 0x71: |
| 5850 | case 0x91: |
| 5851 | case 0xb1: |
| 5852 | case 0xd1: |
| 5853 | case 0xf1: // bits 5-7 of the register index are the low bits of the Y co-ordinate |
| 5854 | m_cursor_y = (data << 3) | ((index & 0xe0) >> 5); |
| 5855 | break; |
| 5856 | case 0x12: |
| 5857 | // bit 0 - enable cursor |
| 5858 | // bit 1 - enable extra palette (cursor colours are there) |
| 5859 | // bit 2 - 64x64 cursor (32x32 if clear, GD5422+) |
| 5860 | // bit 7 - overscan colour protect - if set, use colour 2 in the extra palette for the border (GD5424+) |
| 5861 | m_cursor_attr = data; |
| 5862 | break; |
| 5863 | case 0x13: |
| 5864 | m_cursor_addr = data; // bits 0 and 1 are ignored if using 64x64 cursor |
| 5865 | break; |
| 5866 | case 0x14: |
| 5867 | m_scratchpad2 = data; |
| 5868 | break; |
| 5869 | case 0x15: |
| 5870 | m_scratchpad3 = data; // GD543x BIOS writes VRAM size here |
| 5871 | break; |
| 5728 | 5872 | default: |
| 5729 | 5873 | vga.sequencer.data[vga.sequencer.index] = data; |
| 5730 | 5874 | seq_reg_write(vga.sequencer.index,data); |
| r245604 | r245605 | |
| 5830 | 5974 | |
| 5831 | 5975 | READ8_MEMBER(cirrus_vga_device::port_03c0_r) |
| 5832 | 5976 | { |
| 5833 | | UINT8 res; |
| 5977 | UINT8 res = 0xff; |
| 5834 | 5978 | |
| 5835 | 5979 | switch(offset) |
| 5836 | 5980 | { |
| 5837 | 5981 | case 0x05: |
| 5838 | 5982 | res = cirrus_seq_reg_read(vga.sequencer.index); |
| 5839 | 5983 | break; |
| 5984 | case 0x09: |
| 5985 | if(!(m_cursor_attr & 0x02)) |
| 5986 | res = vga_device::port_03c0_r(space,offset,mem_mask); |
| 5987 | else |
| 5988 | { |
| 5989 | if (vga.dac.read) |
| 5990 | { |
| 5991 | switch (vga.dac.state++) |
| 5992 | { |
| 5993 | case 0: |
| 5994 | res = m_ext_palette[vga.dac.read_index & 0x0f].red; |
| 5995 | break; |
| 5996 | case 1: |
| 5997 | res = m_ext_palette[vga.dac.read_index & 0x0f].green; |
| 5998 | break; |
| 5999 | case 2: |
| 6000 | res = m_ext_palette[vga.dac.read_index & 0x0f].blue; |
| 6001 | break; |
| 6002 | } |
| 6003 | |
| 6004 | if (vga.dac.state==3) |
| 6005 | { |
| 6006 | vga.dac.state = 0; |
| 6007 | vga.dac.read_index++; |
| 6008 | } |
| 6009 | } |
| 6010 | } |
| 6011 | break; |
| 5840 | 6012 | case 0x0f: |
| 5841 | 6013 | res = cirrus_gc_reg_read(vga.gc.index); |
| 5842 | 6014 | break; |
| r245604 | r245605 | |
| 5855 | 6027 | case 0x05: |
| 5856 | 6028 | cirrus_seq_reg_write(vga.sequencer.index,data); |
| 5857 | 6029 | break; |
| 6030 | case 0x09: |
| 6031 | if(!(m_cursor_attr & 0x02)) |
| 6032 | vga_device::port_03c0_w(space,offset,data,mem_mask); |
| 6033 | else |
| 6034 | { |
| 6035 | if (!vga.dac.read) |
| 6036 | { |
| 6037 | switch (vga.dac.state++) { |
| 6038 | case 0: |
| 6039 | m_ext_palette[vga.dac.write_index & 0x0f].red=data; |
| 6040 | break; |
| 6041 | case 1: |
| 6042 | m_ext_palette[vga.dac.write_index & 0x0f].green=data; |
| 6043 | break; |
| 6044 | case 2: |
| 6045 | m_ext_palette[vga.dac.write_index & 0x0f].blue=data; |
| 6046 | break; |
| 6047 | } |
| 6048 | vga.dac.dirty=1; |
| 6049 | if (vga.dac.state==3) { |
| 6050 | vga.dac.state=0; vga.dac.write_index++; |
| 6051 | } |
| 6052 | } |
| 6053 | } |
| 6054 | break; |
| 5858 | 6055 | case 0x0f: |
| 5859 | 6056 | cirrus_gc_reg_write(vga.gc.index,data); |
| 5860 | 6057 | break; |
| r245604 | r245605 | |
| 5948 | 6145 | |
| 5949 | 6146 | switch(index) |
| 5950 | 6147 | { |
| 6148 | case 0x19: |
| 6149 | res = m_cr19; |
| 6150 | break; |
| 6151 | case 0x1a: |
| 6152 | res = m_cr1a; |
| 6153 | break; |
| 6154 | case 0x1b: |
| 6155 | res = m_cr1b; |
| 6156 | break; |
| 5951 | 6157 | case 0x27: |
| 5952 | | res = 0xa0; |
| 6158 | res = 0xa0; // Chip ID - GD5430 rev 0 |
| 5953 | 6159 | break; |
| 5954 | 6160 | default: |
| 5955 | 6161 | logerror("CL: Unhandled extended CRTC register CR%02x read\n",index); |
| r245604 | r245605 | |
| 5967 | 6173 | } |
| 5968 | 6174 | switch(index) |
| 5969 | 6175 | { |
| 6176 | case 0x19: |
| 6177 | m_cr19 = data; |
| 6178 | break; |
| 6179 | case 0x1a: |
| 6180 | m_cr1a = data; |
| 6181 | break; |
| 6182 | case 0x1b: |
| 6183 | m_cr1b = data; |
| 6184 | break; |
| 5970 | 6185 | case 0x27: |
| 5971 | 6186 | // Do nothing, read only |
| 5972 | 6187 | break; |
| r245604 | r245605 | |
| 5980 | 6195 | { |
| 5981 | 6196 | UINT32 addr; |
| 5982 | 6197 | UINT8 bank; |
| 6198 | UINT8 cur_mode = pc_vga_choosevideomode(); |
| 5983 | 6199 | |
| 5984 | | if(gc_locked) |
| 6200 | if(gc_locked || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) |
| 5985 | 6201 | return vga_device::mem_r(space,offset,mem_mask); |
| 5986 | 6202 | |
| 5987 | 6203 | if(offset >= 0x8000 && offset < 0x10000 && (gc_mode_ext & 0x01)) // if accessing bank 1 (if enabled) |
| r245604 | r245605 | |
| 5993 | 6209 | addr = bank * 0x4000; |
| 5994 | 6210 | else // 4kB bank granularity |
| 5995 | 6211 | addr = bank * 0x1000; |
| 5996 | | // Win 3.1 GD5426/8 drivers use this in 16-colour mode also |
| 6212 | |
| 5997 | 6213 | if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) |
| 5998 | 6214 | { |
| 5999 | 6215 | if(gc_mode_ext & 0x01) |
| r245604 | r245605 | |
| 6080 | 6296 | { |
| 6081 | 6297 | UINT32 addr; |
| 6082 | 6298 | UINT8 bank; |
| 6299 | UINT8 cur_mode = pc_vga_choosevideomode(); |
| 6083 | 6300 | |
| 6084 | | if(gc_locked) |
| 6301 | if(gc_locked || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) |
| 6085 | 6302 | { |
| 6086 | 6303 | vga_device::mem_w(space,offset,data,mem_mask); |
| 6087 | 6304 | return; |