Version:
~
[ SVN-2014-01-05 ] ~
[ 2.6.2 ] ~
** Warning: Cannot open xref database.
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: svga_cirrus.cc 12097 2014-01-04 15:42:17Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (c) 2004 Makoto Suzuki (suzu)
6 // Volker Ruppert (vruppert)
7 // Robin Kay (komadori)
8 // Copyright (C) 2004-2014 The Bochs Project
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 /////////////////////////////////////////////////////////////////////////
25
26 // limited PCI/ISA CLGD5446 support for Bochs
27 //
28 // there are still many unimplemented features:
29 //
30 // - destination write mask support is not complete (bit 5..6)
31 // - BLT mode extension support is not complete (bit 3..4)
32 // - 4bpp modes
33 //
34 // some codes are copied from vga.cc and modified.
35 // some codes are ported from the cirrus emulation in qemu
36 // (http://savannah.nongnu.org/projects/qemu).
37
38 #define BX_PLUGGABLE
39
40 #include "iodev.h"
41 #include "vgacore.h"
42 #include "svga_cirrus.h"
43 #include "virt_timer.h"
44
45 #if BX_SUPPORT_CLGD54XX
46
47 // Only reference the array if the tile numbers are within the bounds
48 // of the array. If out of bounds, do nothing.
49 #define SET_TILE_UPDATED(xtile, ytile, value) \
50 do { \
51 if (((xtile) < BX_CIRRUS_THIS s.num_x_tiles) && ((ytile) < BX_CIRRUS_THIS s.num_y_tiles)) \
52 BX_CIRRUS_THIS s.vga_tile_updated[(xtile)+(ytile)*BX_CIRRUS_THIS s.num_x_tiles] = value; \
53 } while (0)
54
55 // Only reference the array if the tile numbers are within the bounds
56 // of the array. If out of bounds, return 0.
57 #define GET_TILE_UPDATED(xtile,ytile) \
58 ((((xtile) < BX_CIRRUS_THIS s.num_x_tiles) && ((ytile) < BX_CIRRUS_THIS s.num_y_tiles))? \
59 BX_CIRRUS_THIS s.vga_tile_updated[(xtile)+(ytile)*BX_CIRRUS_THIS s.num_x_tiles] \
60 : 0)
61
62 #define LOG_THIS BX_CIRRUS_THIS
63
64 #if BX_USE_CIRRUS_SMF
65 #define VGA_READ(addr,len) bx_vgacore_c::read_handler(theSvga,addr,len)
66 #define VGA_WRITE(addr,val,len) bx_vgacore_c::write_handler(theSvga,addr,val,len)
67 #define SVGA_READ(addr,len) svga_read_handler(theSvga,addr,len)
68 #define SVGA_WRITE(addr,val,len) svga_write_handler(theSvga,addr,val,len)
69 #else
70 #define VGA_READ(addr,len) bx_vgacore_c::read(addr,len)
71 #define VGA_WRITE(addr,val,len) bx_vgacore_c::write(addr,val,len)
72 #define SVGA_READ(addr,len) svga_read(addr,len)
73 #define SVGA_WRITE(addr,val,len) svga_write(addr,val,len)
74 #endif // BX_USE_CIRRUS_SMF
75
76 #define ID_CLGD5428 (0x26<<2)
77 #define ID_CLGD5430 (0x28<<2)
78 #define ID_CLGD5434 (0x2A<<2)
79 #define ID_CLGD5446 (0x2E<<2)
80
81 // sequencer 0x07
82 #define CIRRUS_SR7_BPP_VGA 0x00
83 #define CIRRUS_SR7_BPP_SVGA 0x01
84 #define CIRRUS_SR7_BPP_MASK 0x0e
85 #define CIRRUS_SR7_BPP_8 0x00
86 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
87 #define CIRRUS_SR7_BPP_24 0x04
88 #define CIRRUS_SR7_BPP_16 0x06
89 #define CIRRUS_SR7_BPP_32 0x08
90 #define CIRRUS_SR7_ISAADDR_MASK 0xe0
91
92 // sequencer 0x0f
93 #define CIRRUS_MEMSIZE_512k 0x08
94 #define CIRRUS_MEMSIZE_1M 0x10
95 #define CIRRUS_MEMSIZE_2M 0x18
96 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
97
98 // sequencer 0x12
99 #define CIRRUS_CURSOR_SHOW 0x01
100 #define CIRRUS_CURSOR_HIDDENPEL 0x02
101 #define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
102
103 // sequencer 0x17
104 #define CIRRUS_BUSTYPE_VLBFAST 0x10
105 #define CIRRUS_BUSTYPE_PCI 0x20
106 #define CIRRUS_BUSTYPE_VLBSLOW 0x30
107 #define CIRRUS_BUSTYPE_ISA 0x38
108 #define CIRRUS_MMIO_ENABLE 0x04
109 #define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
110 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
111
112 // control 0x0b
113 #define CIRRUS_BANKING_DUAL 0x01
114 #define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
115
116 // control 0x30
117 #define CIRRUS_BLTMODE_BACKWARDS 0x01
118 #define CIRRUS_BLTMODE_MEMSYSDEST 0x02
119 #define CIRRUS_BLTMODE_MEMSYSSRC 0x04
120 #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
121 #define CIRRUS_BLTMODE_PATTERNCOPY 0x40
122 #define CIRRUS_BLTMODE_COLOREXPAND 0x80
123 #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
124 #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
125 #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
126 #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
127 #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
128
129 // control 0x31
130 #define CIRRUS_BLT_BUSY 0x01
131 #define CIRRUS_BLT_START 0x02
132 #define CIRRUS_BLT_RESET 0x04
133 #define CIRRUS_BLT_FIFOUSED 0x10
134 #define CIRRUS_BLT_AUTOSTART 0x80
135
136 // control 0x32
137 #define CIRRUS_ROP_0 0x00
138 #define CIRRUS_ROP_SRC_AND_DST 0x05
139 #define CIRRUS_ROP_NOP 0x06
140 #define CIRRUS_ROP_SRC_AND_NOTDST 0x09
141 #define CIRRUS_ROP_NOTDST 0x0b
142 #define CIRRUS_ROP_SRC 0x0d
143 #define CIRRUS_ROP_1 0x0e
144 #define CIRRUS_ROP_NOTSRC_AND_DST 0x50
145 #define CIRRUS_ROP_SRC_XOR_DST 0x59
146 #define CIRRUS_ROP_SRC_OR_DST 0x6d
147 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0x90
148 #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
149 #define CIRRUS_ROP_SRC_OR_NOTDST 0xad
150 #define CIRRUS_ROP_NOTSRC 0xd0
151 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
152 #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0xda
153
154 // control 0x33
155 #define CIRRUS_BLTMODEEXT_SYNCDISPSWITCH 0x10 // unimplemented
156 #define CIRRUS_BLTMODEEXT_BKGNDONLYCLIP 0x08 // unimplemented
157 #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
158 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
159 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
160
161 #define CLGD543x_MMIO_BLTBGCOLOR 0x00 // dword
162 #define CLGD543x_MMIO_BLTFGCOLOR 0x04 // dword
163 #define CLGD543x_MMIO_BLTWIDTH 0x08 // word
164 #define CLGD543x_MMIO_BLTHEIGHT 0x0a // word
165 #define CLGD543x_MMIO_BLTDESTPITCH 0x0c // word
166 #define CLGD543x_MMIO_BLTSRCPITCH 0x0e // word
167 #define CLGD543x_MMIO_BLTDESTADDR 0x10 // dword
168 #define CLGD543x_MMIO_BLTSRCADDR 0x14 // dword
169 #define CLGD543x_MMIO_BLTWRITEMASK 0x17 // byte
170 #define CLGD543x_MMIO_BLTMODE 0x18 // byte
171 #define CLGD543x_MMIO_BLTROP 0x1a // byte
172 #define CLGD543x_MMIO_BLTMODEEXT 0x1b // byte
173 #define CLGD543x_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
174 #define CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
175 #define CLGD543x_MMIO_BLTSTATUS 0x40 // byte
176
177 // PCI 0x00: vendor, 0x02: device
178 #define PCI_VENDOR_CIRRUS 0x1013
179 #define PCI_DEVICE_CLGD5430 0x00a0 // CLGD5430 or CLGD5440
180 #define PCI_DEVICE_CLGD5434 0x00a8
181 #define PCI_DEVICE_CLGD5436 0x00ac
182 #define PCI_DEVICE_CLGD5446 0x00b8
183 #define PCI_DEVICE_CLGD5462 0x00d0
184 #define PCI_DEVICE_CLGD5465 0x00d6
185 // PCI 0x04: command(word), 0x06(word): status
186 #define PCI_COMMAND_IOACCESS 0x0001
187 #define PCI_COMMAND_MEMACCESS 0x0002
188 #define PCI_COMMAND_BUSMASTER 0x0004
189 #define PCI_COMMAND_SPECIALCYCLE 0x0008
190 #define PCI_COMMAND_MEMWRITEINVALID 0x0010
191 #define PCI_COMMAND_PALETTESNOOPING 0x0020
192 #define PCI_COMMAND_PARITYDETECTION 0x0040
193 #define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
194 #define PCI_COMMAND_SERR 0x0100
195 #define PCI_COMMAND_BACKTOBACKTRANS 0x0200
196 // PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
197 #define PCI_CLASS_BASE_DISPLAY 0x03
198 // PCI 0x08, 0x00ff0000
199 #define PCI_CLASS_SUB_VGA 0x00
200 // PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
201 #define PCI_CLASS_HEADERTYPE_00h 0x00
202 // 0x10-0x3f (headertype 00h)
203 // PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
204 // 0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
205 #define PCI_MAP_MEM 0x0
206 #define PCI_MAP_IO 0x1
207 #define PCI_MAP_MEM_ADDR_MASK (~0xf)
208 #define PCI_MAP_IO_ADDR_MASK (~0x3)
209 #define PCI_MAP_MEMFLAGS_32BIT 0x0
210 #define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
211 #define PCI_MAP_MEMFLAGS_64BIT 0x4
212 #define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
213 // PCI 0x28: cardbus CIS pointer
214 // PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
215 // PCI 0x30: expansion ROM base address
216 // PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
217 // PCI 0x38: reserved
218 // PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
219 // PCI 0x40-0xff: device dependent fields
220
221 // default PnP memory and memory-mapped I/O sizes
222 #define CIRRUS_PNPMEM_SIZE CIRRUS_VIDEO_MEMORY_BYTES
223 #define CIRRUS_PNPMMIO_SIZE 0x1000
224
225 static bx_svga_cirrus_c *theSvga = NULL;
226
227 int libsvga_cirrus_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
228 {
229 if (type == PLUGTYPE_CORE) {
230 theSvga = new bx_svga_cirrus_c();
231 bx_devices.pluginVgaDevice = theSvga;
232 BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSvga, BX_PLUGIN_CIRRUS);
233 return 0; // Success
234 } else {
235 return -1;
236 }
237 }
238
239 void libsvga_cirrus_LTX_plugin_fini(void)
240 {
241 delete theSvga;
242 }
243
244 bx_svga_cirrus_c::bx_svga_cirrus_c() : bx_vgacore_c()
245 {
246 // nothing else to do
247 }
248
249 bx_svga_cirrus_c::~bx_svga_cirrus_c()
250 {
251 SIM->get_bochs_root()->remove("svga_cirrus");
252 BX_DEBUG(("Exit"));
253 }
254
255 void bx_svga_cirrus_c::init_vga_extension(void)
256 {
257 if (!strcmp(SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), "cirrus")) {
258 BX_CIRRUS_THIS put("CIRRUS");
259 // initialize SVGA stuffs.
260 BX_CIRRUS_THIS bx_vgacore_c::init_iohandlers(svga_read_handler, svga_write_handler);
261 BX_CIRRUS_THIS bx_vgacore_c::init_systemtimer(svga_timer_handler, svga_param_handler);
262 BX_CIRRUS_THIS pci_enabled = SIM->is_pci_device("cirrus");
263 BX_CIRRUS_THIS svga_init_members();
264 #if BX_SUPPORT_PCI
265 if (BX_CIRRUS_THIS pci_enabled)
266 {
267 BX_CIRRUS_THIS svga_init_pcihandlers();
268 BX_INFO(("CL-GD5446 PCI initialized"));
269 }
270 else
271 #endif
272 {
273 BX_INFO(("CL-GD5430 ISA initialized"));
274 }
275 BX_CIRRUS_THIS s.max_xres = 1600;
276 BX_CIRRUS_THIS s.max_yres = 1200;
277 BX_CIRRUS_THIS extension_init = 1;
278 } else {
279 BX_CIRRUS_THIS sequencer.reg[0x07] = 0x00; // Cirrus extension disabled
280 // initialize VGA extension, read/write handlers and timer
281 BX_CIRRUS_THIS bx_vgacore_c::init_vga_extension();
282 }
283 #if BX_DEBUGGER
284 // register device for the 'info device' command (calls debug_dump())
285 bx_dbg_register_debug_info("cirrus", this);
286 #endif
287 }
288
289 void bx_svga_cirrus_c::svga_init_members()
290 {
291 unsigned i;
292
293 // clear all registers.
294 BX_CIRRUS_THIS sequencer.index = CIRRUS_SEQENCER_MAX + 1;
295 for (i = 0; i <= CIRRUS_SEQENCER_MAX; i++)
296 BX_CIRRUS_THIS sequencer.reg[i] = 0x00;
297 BX_CIRRUS_THIS control.index = CIRRUS_CONTROL_MAX + 1;
298 for (i = 0; i <= CIRRUS_CONTROL_MAX; i++)
299 BX_CIRRUS_THIS control.reg[i] = 0x00;
300 BX_CIRRUS_THIS control.shadow_reg0 = 0x00;
301 BX_CIRRUS_THIS control.shadow_reg1 = 0x00;
302 BX_CIRRUS_THIS crtc.index = CIRRUS_CRTC_MAX + 1;
303 for (i = 0; i <= CIRRUS_CRTC_MAX; i++)
304 BX_CIRRUS_THIS crtc.reg[i] = 0x00;
305 BX_CIRRUS_THIS hidden_dac.lockindex = 0;
306 BX_CIRRUS_THIS hidden_dac.data = 0x00;
307
308 BX_CIRRUS_THIS svga_unlock_special = 0;
309 BX_CIRRUS_THIS svga_needs_update_tile = 1;
310 BX_CIRRUS_THIS svga_needs_update_dispentire = 1;
311 BX_CIRRUS_THIS svga_needs_update_mode = 0;
312
313 BX_CIRRUS_THIS svga_xres = 640;
314 BX_CIRRUS_THIS svga_yres = 480;
315 BX_CIRRUS_THIS svga_bpp = 8;
316 BX_CIRRUS_THIS svga_pitch = 640;
317 BX_CIRRUS_THIS bank_base[0] = 0;
318 BX_CIRRUS_THIS bank_base[1] = 0;
319 BX_CIRRUS_THIS bank_limit[0] = 0;
320 BX_CIRRUS_THIS bank_limit[1] = 0;
321
322 svga_reset_bitblt();
323
324 BX_CIRRUS_THIS hw_cursor.x = 0;
325 BX_CIRRUS_THIS hw_cursor.y = 0;
326 BX_CIRRUS_THIS hw_cursor.size = 0;
327
328 // memory allocation.
329 if (BX_CIRRUS_THIS s.memory == NULL)
330 BX_CIRRUS_THIS s.memory = new Bit8u[CIRRUS_VIDEO_MEMORY_BYTES];
331
332 // set some registers.
333
334 BX_CIRRUS_THIS sequencer.reg[0x06] = 0x0f;
335 BX_CIRRUS_THIS sequencer.reg[0x07] = 0x00; // 0xf0:linearbase(0x00 if disabled)
336 #if BX_SUPPORT_PCI
337 if (BX_CIRRUS_THIS pci_enabled) {
338 BX_CIRRUS_THIS svga_unlock_special = 1;
339 BX_CIRRUS_THIS crtc.reg[0x27] = ID_CLGD5446;
340 BX_CIRRUS_THIS sequencer.reg[0x1F] = 0x2d; // MemClock
341 BX_CIRRUS_THIS control.reg[0x18] = 0x0f;
342 BX_CIRRUS_THIS sequencer.reg[0x0F] = 0x98;
343 BX_CIRRUS_THIS sequencer.reg[0x17] = CIRRUS_BUSTYPE_PCI;
344 BX_CIRRUS_THIS sequencer.reg[0x15] = 0x04; // memory size 4MB
345 BX_CIRRUS_THIS s.memsize = (4 << 20);
346 } else
347 #endif
348 {
349 BX_CIRRUS_THIS crtc.reg[0x27] = ID_CLGD5430;
350 BX_CIRRUS_THIS sequencer.reg[0x1F] = 0x22; // MemClock
351 BX_CIRRUS_THIS sequencer.reg[0x0F] = CIRRUS_MEMSIZE_2M;
352 BX_CIRRUS_THIS sequencer.reg[0x17] = CIRRUS_BUSTYPE_ISA;
353 BX_CIRRUS_THIS sequencer.reg[0x15] = 0x03; // memory size 2MB
354 BX_CIRRUS_THIS s.memsize = (2 << 20);
355 }
356
357 BX_CIRRUS_THIS hidden_dac.lockindex = 5;
358 BX_CIRRUS_THIS hidden_dac.data = 0;
359
360 memset(BX_CIRRUS_THIS s.memory, 0xff, CIRRUS_VIDEO_MEMORY_BYTES);
361 BX_CIRRUS_THIS disp_ptr = BX_CIRRUS_THIS s.memory;
362 BX_CIRRUS_THIS memsize_mask = BX_CIRRUS_THIS s.memsize - 1;
363 }
364
365 void bx_svga_cirrus_c::reset(unsigned type)
366 {
367 // reset VGA stuffs.
368 BX_CIRRUS_THIS bx_vgacore_c::reset(type);
369
370 if (!strcmp(SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), "cirrus")) {
371 // reset SVGA stuffs.
372 BX_CIRRUS_THIS svga_init_members();
373 }
374 }
375
376 void bx_svga_cirrus_c::register_state(void)
377 {
378 unsigned i;
379 char name[6];
380 bx_list_c *reg;
381
382 if (!strcmp(SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), "cirrus")) {
383 bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "svga_cirrus", "Cirrus SVGA State");
384 bx_vgacore_c::register_state(list);
385 bx_list_c *crtc = new bx_list_c(list, "crtc");
386 new bx_shadow_num_c(crtc, "index", &BX_CIRRUS_THIS crtc.index, BASE_HEX);
387 reg = new bx_list_c(crtc, "reg");
388 for (i=0; i<=CIRRUS_CRTC_MAX; i++) {
389 sprintf(name, "0x%02x", i);
390 new bx_shadow_num_c(reg, name, &BX_CIRRUS_THIS crtc.reg[i], BASE_HEX);
391 }
392 bx_list_c *sequ = new bx_list_c(list, "sequencer");
393 new bx_shadow_num_c(sequ, "index", &BX_CIRRUS_THIS sequencer.index, BASE_HEX);
394 reg = new bx_list_c(sequ, "reg");
395 for (i=0; i<=CIRRUS_SEQENCER_MAX; i++) {
396 sprintf(name, "0x%02x", i);
397 new bx_shadow_num_c(reg, name, &BX_CIRRUS_THIS sequencer.reg[i], BASE_HEX);
398 }
399 bx_list_c *ctrl = new bx_list_c(list, "control");
400 new bx_shadow_num_c(ctrl, "index", &BX_CIRRUS_THIS control.index, BASE_HEX);
401 reg = new bx_list_c(ctrl, "reg");
402 for (i=0; i<=CIRRUS_CONTROL_MAX; i++) {
403 sprintf(name, "0x%02x", i);
404 new bx_shadow_num_c(reg, name, &BX_CIRRUS_THIS control.reg[i], BASE_HEX);
405 }
406 new bx_shadow_num_c(ctrl, "shadow_reg0", &BX_CIRRUS_THIS control.shadow_reg0, BASE_HEX);
407 new bx_shadow_num_c(ctrl, "shadow_reg1", &BX_CIRRUS_THIS control.shadow_reg1, BASE_HEX);
408 bx_list_c *hdac = new bx_list_c(list, "hidden_dac");
409 new bx_shadow_num_c(hdac, "lockindex", &BX_CIRRUS_THIS hidden_dac.lockindex, BASE_HEX);
410 new bx_shadow_num_c(hdac, "data", &BX_CIRRUS_THIS hidden_dac.data, BASE_HEX);
411 reg = new bx_list_c(hdac, "palette");
412 for (i=0; i<48; i++) {
413 sprintf(name, "0x%02x", i);
414 new bx_shadow_num_c(reg, name, &BX_CIRRUS_THIS hidden_dac.palette[i], BASE_HEX);
415 }
416 new bx_shadow_bool_c(list, "svga_unlock_special", &BX_CIRRUS_THIS svga_unlock_special);
417 new bx_shadow_num_c(list, "svga_xres", &BX_CIRRUS_THIS svga_xres);
418 new bx_shadow_num_c(list, "svga_yres", &BX_CIRRUS_THIS svga_yres);
419 new bx_shadow_num_c(list, "svga_pitch", &BX_CIRRUS_THIS svga_pitch);
420 new bx_shadow_num_c(list, "svga_bpp", &BX_CIRRUS_THIS svga_bpp);
421 new bx_shadow_num_c(list, "svga_dispbpp", &BX_CIRRUS_THIS svga_dispbpp);
422 new bx_shadow_num_c(list, "bank_base0", &BX_CIRRUS_THIS bank_base[0], BASE_HEX);
423 new bx_shadow_num_c(list, "bank_base1", &BX_CIRRUS_THIS bank_base[1], BASE_HEX);
424 new bx_shadow_num_c(list, "bank_limit0", &BX_CIRRUS_THIS bank_limit[0], BASE_HEX);
425 new bx_shadow_num_c(list, "bank_limit1", &BX_CIRRUS_THIS bank_limit[1], BASE_HEX);
426 bx_list_c *cursor = new bx_list_c(list, "hw_cursor");
427 new bx_shadow_num_c(cursor, "x", &BX_CIRRUS_THIS hw_cursor.x, BASE_HEX);
428 new bx_shadow_num_c(cursor, "y", &BX_CIRRUS_THIS hw_cursor.y, BASE_HEX);
429 new bx_shadow_num_c(cursor, "size", &BX_CIRRUS_THIS hw_cursor.size, BASE_HEX);
430 #if BX_SUPPORT_PCI
431 if (BX_CIRRUS_THIS pci_enabled) {
432 register_pci_state(list);
433 }
434 #endif
435 }
436 }
437
438 void bx_svga_cirrus_c::after_restore_state(void)
439 {
440 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
441 BX_CIRRUS_THIS bx_vgacore_c::after_restore_state();
442 } else {
443 #if BX_SUPPORT_PCI
444 if (BX_CIRRUS_THIS pci_enabled) {
445 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
446 cirrus_mem_write_handler,
447 &BX_CIRRUS_THIS pci_base_address[0],
448 &BX_CIRRUS_THIS pci_conf[0x10],
449 0x2000000)) {
450 BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_base_address[0]));
451 }
452 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
453 cirrus_mem_write_handler,
454 &BX_CIRRUS_THIS pci_base_address[1],
455 &BX_CIRRUS_THIS pci_conf[0x14],
456 CIRRUS_PNPMMIO_SIZE)) {
457 BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_base_address[1]));
458 }
459 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
460 cirrus_mem_write_handler,
461 &BX_CIRRUS_THIS pci_rom_address,
462 &BX_CIRRUS_THIS pci_conf[0x30],
463 BX_CIRRUS_THIS pci_rom_size)) {
464 BX_INFO(("new ROM address: 0x%08x", BX_CIRRUS_THIS pci_rom_address));
465 }
466 }
467 #endif
468 for (unsigned i=0; i<256; i++) {
469 bx_gui->palette_change_common(i, BX_CIRRUS_THIS s.pel.data[i].red<<2,
470 BX_CIRRUS_THIS s.pel.data[i].green<<2,
471 BX_CIRRUS_THIS s.pel.data[i].blue<<2);
472 }
473 BX_CIRRUS_THIS svga_needs_update_mode = 1;
474 BX_CIRRUS_THIS svga_update();
475 }
476 }
477
478 void bx_svga_cirrus_c::redraw_area(unsigned x0, unsigned y0,
479 unsigned width, unsigned height)
480 {
481 unsigned xti, yti, xt0, xt1, yt0, yt1;
482
483 if ((width == 0) || (height == 0)) {
484 return;
485 }
486 if (BX_CIRRUS_THIS s.vga_override && (BX_CIRRUS_THIS s.nvgadev != NULL)) {
487 BX_CIRRUS_THIS s.nvgadev->redraw_area(x0, y0, width, height);
488 return;
489 }
490
491 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
492 BX_CIRRUS_THIS bx_vgacore_c::redraw_area(x0,y0,width,height);
493 return;
494 }
495
496 if (BX_CIRRUS_THIS svga_needs_update_mode) {
497 return;
498 }
499
500 BX_CIRRUS_THIS svga_needs_update_tile = 1;
501
502 xt0 = x0 / X_TILESIZE;
503 yt0 = y0 / Y_TILESIZE;
504 if (x0 < BX_CIRRUS_THIS svga_xres) {
505 xt1 = (x0 + width - 1) / X_TILESIZE;
506 } else {
507 xt1 = (BX_CIRRUS_THIS svga_xres - 1) / X_TILESIZE;
508 }
509 if (y0 < BX_CIRRUS_THIS svga_yres) {
510 yt1 = (y0 + height - 1) / Y_TILESIZE;
511 } else {
512 yt1 = (BX_CIRRUS_THIS svga_yres - 1) / Y_TILESIZE;
513 }
514 for (yti=yt0; yti<=yt1; yti++) {
515 for (xti=xt0; xti<=xt1; xti++) {
516 SET_TILE_UPDATED (xti, yti, 1);
517 }
518 }
519 }
520
521 void bx_svga_cirrus_c::mem_write_mode4and5_8bpp(Bit8u mode, Bit32u offset, Bit8u value)
522 {
523 Bit8u val = value;
524 Bit8u *dst;
525
526 dst = BX_CIRRUS_THIS s.memory + offset;
527 for (int x = 0; x < 8; x++) {
528 if (val & 0x80) {
529 *dst = BX_CIRRUS_THIS control.shadow_reg1;
530 } else if (mode == 5) {
531 *dst = BX_CIRRUS_THIS control.shadow_reg0;
532 }
533 val <<= 1;
534 dst++;
535 }
536 }
537
538 void bx_svga_cirrus_c::mem_write_mode4and5_16bpp(Bit8u mode, Bit32u offset, Bit8u value)
539 {
540 Bit8u val = value;
541 Bit8u *dst;
542
543 dst = BX_CIRRUS_THIS s.memory + offset;
544 for (int x = 0; x < 8; x++) {
545 if (val & 0x80) {
546 *dst = BX_CIRRUS_THIS control.shadow_reg1;
547 *(dst + 1) = BX_CIRRUS_THIS control.reg[0x11];
548 } else if (mode == 5) {
549 *dst = BX_CIRRUS_THIS control.shadow_reg0;
550 *(dst + 1) = BX_CIRRUS_THIS control.reg[0x10];
551 }
552 val <<= 1;
553 dst += 2;
554 }
555 }
556
557 #if BX_SUPPORT_PCI
558 bx_bool bx_svga_cirrus_c::cirrus_mem_read_handler(bx_phy_address addr, unsigned len,
559 void *data, void *param)
560 {
561 Bit8u *data_ptr;
562 #ifdef BX_LITTLE_ENDIAN
563 data_ptr = (Bit8u *) data;
564 #else // BX_BIG_ENDIAN
565 data_ptr = (Bit8u *) data + (len - 1);
566 #endif
567 for (unsigned i = 0; i < len; i++) {
568 *data_ptr = BX_CIRRUS_THIS mem_read(addr);
569 addr++;
570 #ifdef BX_LITTLE_ENDIAN
571 data_ptr++;
572 #else // BX_BIG_ENDIAN
573 data_ptr--;
574 #endif
575 }
576 return 1;
577 }
578 #endif
579
580 Bit8u bx_svga_cirrus_c::mem_read(bx_phy_address addr)
581 {
582 #if BX_SUPPORT_PCI
583 if ((BX_CIRRUS_THIS pci_enabled) && (BX_CIRRUS_THIS pci_rom_size > 0)) {
584 Bit32u mask = (BX_CIRRUS_THIS pci_rom_size - 1);
585 if ((addr & ~mask) == BX_CIRRUS_THIS pci_rom_address) {
586 if (BX_CIRRUS_THIS pci_conf[0x30] & 0x01) {
587 return BX_CIRRUS_THIS pci_rom[addr & mask];
588 } else {
589 return 0xff;
590 }
591 }
592 }
593 #endif
594
595 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
596 return BX_CIRRUS_THIS bx_vgacore_c::mem_read(addr);
597 }
598
599 #if BX_SUPPORT_PCI
600 if (BX_CIRRUS_THIS pci_enabled) {
601 if ((addr >= BX_CIRRUS_THIS pci_base_address[0]) &&
602 (addr < (BX_CIRRUS_THIS pci_base_address[0] + CIRRUS_PNPMEM_SIZE))) {
603 Bit8u *ptr;
604
605 Bit32u offset = addr & BX_CIRRUS_THIS memsize_mask;
606 if ((offset >= (BX_CIRRUS_THIS s.memsize - 256)) &&
607 ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x44)) {
608 return svga_mmio_blt_read(offset & 0xff);
609 }
610
611 // video-to-cpu BLT
612 if (BX_CIRRUS_THIS bitblt.memdst_needed != 0) {
613 ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
614 if (ptr != BX_CIRRUS_THIS bitblt.memdst_endptr) {
615 BX_CIRRUS_THIS bitblt.memdst_ptr ++;
616 return *ptr;
617 }
618 if (!svga_asyncbitblt_next()) {
619 ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
620 BX_CIRRUS_THIS bitblt.memdst_ptr ++;
621 return *ptr;
622 }
623 }
624
625 ptr = BX_CIRRUS_THIS s.memory;
626 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
627 offset <<= 4;
628 } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
629 offset <<= 3;
630 }
631 offset &= BX_CIRRUS_THIS memsize_mask;
632 return *(ptr + offset);
633 } else if ((addr >= BX_CIRRUS_THIS pci_base_address[1]) &&
634 (addr < (BX_CIRRUS_THIS pci_base_address[1] + CIRRUS_PNPMMIO_SIZE))) {
635
636 Bit32u offset = addr & (CIRRUS_PNPMMIO_SIZE - 1);
637 if (offset >= 0x100) {
638 return svga_mmio_blt_read(offset - 0x100);
639 } else {
640 return svga_mmio_vga_read(offset);
641 }
642 }
643 }
644 #endif // BX_SUPPORT_PCI
645
646 if (addr >= 0xA0000 && addr <= 0xAFFFF)
647 {
648 Bit32u bank;
649 Bit32u offset;
650 Bit8u *ptr;
651
652 // video-to-cpu BLT
653 if (BX_CIRRUS_THIS bitblt.memdst_needed != 0) {
654 ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
655 if (ptr != BX_CIRRUS_THIS bitblt.memdst_endptr) {
656 BX_CIRRUS_THIS bitblt.memdst_ptr ++;
657 return *ptr;
658 }
659 if (!svga_asyncbitblt_next()) {
660 ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
661 BX_CIRRUS_THIS bitblt.memdst_ptr ++;
662 return *ptr;
663 }
664 }
665
666 offset = addr & 0xffff;
667 bank = (offset >> 15);
668 offset &= 0x7fff;
669 if (offset < bank_limit[bank]) {
670 offset += bank_base[bank];
671 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
672 offset <<= 4;
673 } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
674 offset <<= 3;
675 }
676 offset &= BX_CIRRUS_THIS memsize_mask;
677 return *(BX_CIRRUS_THIS s.memory + offset);
678 }
679 else {
680 return 0xff;
681 }
682 }
683 else if (addr >= 0xB8000 && addr <= 0xB8100) {
684 // memory-mapped I/O.
685 Bit32u offset = (Bit32u) (addr - 0xb8000);
686 if ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x04)
687 return svga_mmio_blt_read(offset);
688 }
689 else {
690 BX_DEBUG(("mem_read 0x%08x", (Bit32u)addr));
691 }
692
693 return 0xff;
694 }
695
696 #if BX_SUPPORT_PCI
697 bx_bool bx_svga_cirrus_c::cirrus_mem_write_handler(bx_phy_address addr, unsigned len,
698 void *data, void *param)
699 {
700 Bit8u *data_ptr;
701 #ifdef BX_LITTLE_ENDIAN
702 data_ptr = (Bit8u *) data;
703 #else // BX_BIG_ENDIAN
704 data_ptr = (Bit8u *) data + (len - 1);
705 #endif
706 for (unsigned i = 0; i < len; i++) {
707 BX_CIRRUS_THIS mem_write(addr, *data_ptr);
708 addr++;
709 #ifdef BX_LITTLE_ENDIAN
710 data_ptr++;
711 #else // BX_BIG_ENDIAN
712 data_ptr--;
713 #endif
714 }
715 return 1;
716 }
717 #endif
718
719 void bx_svga_cirrus_c::mem_write(bx_phy_address addr, Bit8u value)
720 {
721 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
722 BX_CIRRUS_THIS bx_vgacore_c::mem_write(addr,value);
723 return;
724 }
725
726 #if BX_SUPPORT_PCI
727 if (BX_CIRRUS_THIS pci_enabled) {
728 if ((addr >= BX_CIRRUS_THIS pci_base_address[0]) &&
729 (addr < (BX_CIRRUS_THIS pci_base_address[0] + CIRRUS_PNPMEM_SIZE))) {
730
731 Bit32u offset = addr & BX_CIRRUS_THIS memsize_mask;
732 if ((offset >= (BX_CIRRUS_THIS s.memsize - 256)) &&
733 ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x44)) {
734 svga_mmio_blt_write(addr & 0xff, value);
735 return;
736 }
737
738 // cpu-to-video BLT
739 if (BX_CIRRUS_THIS bitblt.memsrc_needed > 0) {
740 *(BX_CIRRUS_THIS bitblt.memsrc_ptr)++ = (value);
741 if (BX_CIRRUS_THIS bitblt.memsrc_ptr >= BX_CIRRUS_THIS bitblt.memsrc_endptr) {
742 svga_asyncbitblt_next();
743 }
744 return;
745 }
746
747 // BX_DEBUG(("write offset 0x%08x,value 0x%02x",offset,value));
748 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
749 offset <<= 4;
750 } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
751 offset <<= 3;
752 }
753 offset &= BX_CIRRUS_THIS memsize_mask;
754 Bit8u mode = BX_CIRRUS_THIS control.reg[0x05] & 0x07;
755 if ((mode < 4) || (mode > 5) || ((BX_CIRRUS_THIS control.reg[0x0b] & 0x4) == 0)) {
756 *(BX_CIRRUS_THIS s.memory + offset) = value;
757 } else {
758 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) != 0x14) {
759 mem_write_mode4and5_8bpp(mode, offset, value);
760 } else {
761 mem_write_mode4and5_16bpp(mode, offset, value);
762 }
763 }
764 BX_CIRRUS_THIS svga_needs_update_tile = 1;
765 SET_TILE_UPDATED(((offset % BX_CIRRUS_THIS svga_pitch) / (BX_CIRRUS_THIS svga_bpp / 8)) / X_TILESIZE,
766 (offset / BX_CIRRUS_THIS svga_pitch) / Y_TILESIZE, 1);
767 return;
768 } else if ((addr >= BX_CIRRUS_THIS pci_base_address[1]) &&
769 (addr < (BX_CIRRUS_THIS pci_base_address[1] + CIRRUS_PNPMMIO_SIZE))) {
770 // memory-mapped I/O.
771
772 // BX_DEBUG(("write mmio 0x%08x",addr));
773 Bit32u offset = addr & (CIRRUS_PNPMMIO_SIZE - 1);
774 if (offset >= 0x100) {
775 svga_mmio_blt_write(offset - 0x100, value);
776 } else {
777 svga_mmio_vga_write(offset,value);
778 }
779 return;
780 }
781 }
782 #endif // BX_SUPPORT_PCI
783
784 if (addr >= 0xA0000 && addr <= 0xAFFFF) {
785 Bit32u bank, offset;
786 Bit8u mode;
787
788 // cpu-to-video BLT
789 if (BX_CIRRUS_THIS bitblt.memsrc_needed > 0) {
790 *(BX_CIRRUS_THIS bitblt.memsrc_ptr)++ = (value);
791 if (BX_CIRRUS_THIS bitblt.memsrc_ptr >= BX_CIRRUS_THIS bitblt.memsrc_endptr) {
792 svga_asyncbitblt_next();
793 }
794 return;
795 }
796
797 offset = addr & 0xffff;
798 bank = (offset >> 15);
799 offset &= 0x7fff;
800 if (offset < bank_limit[bank]) {
801 offset += bank_base[bank];
802 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
803 offset <<= 4;
804 } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
805 offset <<= 3;
806 }
807 offset &= BX_CIRRUS_THIS memsize_mask;
808 mode = BX_CIRRUS_THIS control.reg[0x05] & 0x07;
809 if ((mode < 4) || (mode > 5) || ((BX_CIRRUS_THIS control.reg[0x0b] & 0x4) == 0)) {
810 *(BX_CIRRUS_THIS s.memory + offset) = value;
811 } else {
812 if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) != 0x14) {
813 mem_write_mode4and5_8bpp(mode, offset, value);
814 } else {
815 mem_write_mode4and5_16bpp(mode, offset, value);
816 }
817 }
818 BX_CIRRUS_THIS svga_needs_update_tile = 1;
819 SET_TILE_UPDATED(((offset % BX_CIRRUS_THIS svga_pitch) / (BX_CIRRUS_THIS svga_bpp / 8)) / X_TILESIZE,
820 (offset / BX_CIRRUS_THIS svga_pitch) / Y_TILESIZE, 1);
821 }
822 } else if (addr >= 0xB8000 && addr < 0xB8100) {
823 // memory-mapped I/O.
824 Bit32u offset = (Bit32u) (addr - 0xb8000);
825 if ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x04) {
826 svga_mmio_blt_write(offset & 0xff, value);
827 }
828 }
829 else {
830 BX_DEBUG(("mem_write 0x%08x, value 0x%02x", (Bit32u)addr, value));
831 }
832 }
833
834 void bx_svga_cirrus_c::get_text_snapshot(Bit8u **text_snapshot,
835 unsigned *txHeight, unsigned *txWidth)
836 {
837 BX_CIRRUS_THIS bx_vgacore_c::get_text_snapshot(text_snapshot,txHeight,txWidth);
838 }
839
840 Bit64s bx_svga_cirrus_c::svga_param_handler(bx_param_c *param, int set, Bit64s val)
841 {
842 if (set) {
843 BX_CIRRUS_THIS update_interval = (Bit32u)(1000000 / val);
844 BX_INFO(("Changing timer interval to %d", BX_CIRRUS_THIS update_interval));
845 BX_CIRRUS_THIS svga_timer_handler(theSvga);
846 bx_virt_timer.activate_timer(BX_CIRRUS_THIS timer_id, BX_CIRRUS_THIS update_interval, 1);
847 if (BX_CIRRUS_THIS update_interval < 300000) {
848 BX_CIRRUS_THIS s.blink_counter = 300000 / (unsigned)BX_CIRRUS_THIS update_interval;
849 } else {
850 BX_CIRRUS_THIS s.blink_counter = 1;
851 }
852 }
853 return val;
854 }
855
856 Bit32u bx_svga_cirrus_c::svga_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
857 {
858 #if !BX_USE_CIRRUS_SMF
859 bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
860
861 return class_ptr->svga_read(address, io_len);
862 }
863
864 Bit32u bx_svga_cirrus_c::svga_read(Bit32u address, unsigned io_len)
865 {
866 #else
867 UNUSED(this_ptr);
868 #endif // !BX_USE_CIRRUS_SMF
869
870 if ((io_len == 2) && ((address & 1) == 0)) {
871 Bit32u value;
872 value = (Bit32u)SVGA_READ(address,1);
873 value |= (Bit32u)SVGA_READ(address+1,1) << 8;
874 return value;
875 }
876
877 if (io_len != 1) {
878 BX_PANIC(("SVGA read: io_len != 1"));
879 }
880
881 switch (address) {
882 case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
883 case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
884 return BX_CIRRUS_THIS crtc.index;
885 case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
886 case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
887 if (BX_CIRRUS_THIS is_unlocked())
888 return BX_CIRRUS_THIS svga_read_crtc(address,BX_CIRRUS_THIS crtc.index);
889 break;
890
891 case 0x03c4: /* VGA: Sequencer Index Register */
892 if (BX_CIRRUS_THIS is_unlocked()) {
893 Bit32u value = BX_CIRRUS_THIS sequencer.index;
894 if ((value & 0x1e) == 0x10) { /* SR10-F0, SR11-F1 */
895 if (value & 1)
896 value = ((BX_CIRRUS_THIS hw_cursor.y & 7) << 5) | 0x11;
897 else
898 value = ((BX_CIRRUS_THIS hw_cursor.x & 7) << 5) | 0x10;
899 }
900 return value;
901 }
902 return BX_CIRRUS_THIS sequencer.index;
903 case 0x03c5: /* VGA: Sequencer Registers */
904 if ((BX_CIRRUS_THIS sequencer.index == 0x06) ||
905 (BX_CIRRUS_THIS is_unlocked())) {
906 return BX_CIRRUS_THIS svga_read_sequencer(address,BX_CIRRUS_THIS sequencer.index);
907 }
908 break;
909
910 case 0x03c6: /* Hidden DAC */
911 if (BX_CIRRUS_THIS is_unlocked()) {
912 if ((++BX_CIRRUS_THIS hidden_dac.lockindex) == 5) {
913 BX_CIRRUS_THIS hidden_dac.lockindex = 0;
914 return BX_CIRRUS_THIS hidden_dac.data;
915 }
916 }
917 break;
918 case 0x03c8: /* PEL write address */
919 BX_CIRRUS_THIS hidden_dac.lockindex = 0;
920 break;
921 case 0x03c9: /* PEL Data Register, hiddem pel colors 00..0F */
922 if (BX_CIRRUS_THIS sequencer.reg[0x12] & CIRRUS_CURSOR_HIDDENPEL) {
923 Bit8u index = (BX_CIRRUS_THIS s.pel.read_data_register & 0x0f) * 3 +
924 BX_CIRRUS_THIS s.pel.read_data_cycle;
925 Bit8u retval = BX_CIRRUS_THIS hidden_dac.palette[index];
926 BX_CIRRUS_THIS s.pel.read_data_cycle ++;
927 if (BX_CIRRUS_THIS s.pel.read_data_cycle >= 3) {
928 BX_CIRRUS_THIS s.pel.read_data_cycle = 0;
929 BX_CIRRUS_THIS s.pel.read_data_register++;
930 }
931 return retval;
932 }
933 break;
934 case 0x03ce: /* VGA: Graphics Controller Index Register */
935 return BX_CIRRUS_THIS control.index;
936 case 0x03cf: /* VGA: Graphics Controller Registers */
937 if (BX_CIRRUS_THIS is_unlocked())
938 return BX_CIRRUS_THIS svga_read_control(address,BX_CIRRUS_THIS control.index);
939 break;
940
941 default:
942 break;
943 }
944
945 return VGA_READ(address,io_len);
946 }
947
948 void bx_svga_cirrus_c::svga_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
949 {
950 #if !BX_USE_CIRRUS_SMF
951 bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
952 class_ptr->svga_write(address, value, io_len);
953 }
954
955 void bx_svga_cirrus_c::svga_write(Bit32u address, Bit32u value, unsigned io_len)
956 {
957 #else
958 UNUSED(this_ptr);
959 #endif // !BX_USE_CIRRUS_SMF
960
961 if ((io_len == 2) && ((address & 1) == 0)) {
962 SVGA_WRITE(address,value & 0xff,1);
963 SVGA_WRITE(address+1,value >> 8,1);
964 return;
965 }
966
967 if (io_len != 1) {
968 BX_PANIC(("SVGA write: io_len != 1"));
969 }
970
971 switch (address) {
972 case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
973 case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
974 BX_CIRRUS_THIS crtc.index = value & 0x7f;
975 break;
976 case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
977 case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
978 if (BX_CIRRUS_THIS is_unlocked()) {
979 BX_CIRRUS_THIS svga_write_crtc(address,BX_CIRRUS_THIS crtc.index,value);
980 return;
981 }
982 break;
983
984 case 0x03c4: /* VGA: Sequencer Index Register */
985 BX_CIRRUS_THIS sequencer.index = value;
986 break;
987 case 0x03c5: /* VGA: Sequencer Registers */
988 if ((BX_CIRRUS_THIS sequencer.index == 0x06) ||
989 (BX_CIRRUS_THIS is_unlocked())) {
990 BX_CIRRUS_THIS svga_write_sequencer(address,BX_CIRRUS_THIS sequencer.index,value);
991 return;
992 }
993 break;
994 case 0x03c6: /* Hidden DAC */
995 if (BX_CIRRUS_THIS is_unlocked()) {
996 if (BX_CIRRUS_THIS hidden_dac.lockindex == 4) {
997 BX_CIRRUS_THIS hidden_dac.data = value;
998 }
999 BX_CIRRUS_THIS hidden_dac.lockindex = 0;
1000 return;
1001 }
1002 break;
1003 case 0x03c9: /* PEL Data Register, hidden pel colors 00..0F */
1004 BX_CIRRUS_THIS svga_needs_update_dispentire = 1;
1005
1006 if (BX_CIRRUS_THIS sequencer.reg[0x12] & CIRRUS_CURSOR_HIDDENPEL) {
1007 Bit8u index = (BX_CIRRUS_THIS s.pel.write_data_register & 0x0f) * 3 +
1008 BX_CIRRUS_THIS s.pel.write_data_cycle;
1009 BX_CIRRUS_THIS hidden_dac.palette[index] = value;
1010 BX_CIRRUS_THIS s.pel.write_data_cycle ++;
1011 if (BX_CIRRUS_THIS s.pel.write_data_cycle >= 3) {
1012 BX_CIRRUS_THIS s.pel.write_data_cycle = 0;
1013 BX_CIRRUS_THIS s.pel.write_data_register++;
1014 }
1015 return;
1016 }
1017 break;
1018 case 0x03ce: /* VGA: Graphics Controller Index Register */
1019 BX_CIRRUS_THIS control.index = value;
1020 break;
1021 case 0x03cf: /* VGA: Graphics Controller Registers */
1022 if (BX_CIRRUS_THIS is_unlocked()) {
1023 BX_CIRRUS_THIS svga_write_control(address,BX_CIRRUS_THIS control.index,value);
1024 return;
1025 }
1026 break;
1027 default:
1028 break;
1029 }
1030
1031 VGA_WRITE(address,value,io_len);
1032 }
1033
1034 void bx_svga_cirrus_c::refresh_display(void *this_ptr, bx_bool redraw)
1035 {
1036 if (BX_CIRRUS_THIS s.vga_override && (BX_CIRRUS_THIS s.nvgadev != NULL)) {
1037 BX_CIRRUS_THIS s.nvgadev->refresh_display(BX_CIRRUS_THIS s.nvgadev, redraw);
1038 } else {
1039 if (redraw) {
1040 redraw_area(0, 0, BX_CIRRUS_THIS s.last_xres, BX_CIRRUS_THIS s.last_yres);
1041 }
1042 svga_timer_handler(this_ptr);
1043 }
1044 }
1045
1046 void bx_svga_cirrus_c::svga_timer_handler(void *this_ptr)
1047 {
1048 #if !BX_USE_CIRRUS_SMF
1049 bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
1050 class_ptr->svga_timer();
1051 }
1052
1053 void bx_svga_cirrus_c::svga_timer(void)
1054 {
1055 #else // !BX_USE_CIRRUS_SMF
1056 UNUSED(this_ptr);
1057 #endif // !BX_USE_CIRRUS_SMF
1058
1059 BX_CIRRUS_THIS svga_update();
1060 bx_gui->flush();
1061 }
1062
1063 void bx_svga_cirrus_c::svga_modeupdate(void)
1064 {
1065 Bit32u iTopOffset, iWidth, iHeight;
1066 Bit8u iBpp, iDispBpp;
1067
1068 iTopOffset = (BX_CIRRUS_THIS crtc.reg[0x0c] << 8)
1069 + BX_CIRRUS_THIS crtc.reg[0x0d]
1070 + ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x01) << 16)
1071 + ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x0c) << 15)
1072 + ((BX_CIRRUS_THIS crtc.reg[0x1d] & 0x80) << 12);
1073 iTopOffset <<= 2;
1074
1075 iHeight = 1 + BX_CIRRUS_THIS crtc.reg[0x12]
1076 + ((BX_CIRRUS_THIS crtc.reg[0x07] & 0x02) << 7)
1077 + ((BX_CIRRUS_THIS crtc.reg[0x07] & 0x40) << 3);
1078 if ((BX_CIRRUS_THIS crtc.reg[0x1a] & 0x01) > 0) {
1079 iHeight <<= 1;
1080 }
1081 iWidth = (BX_CIRRUS_THIS crtc.reg[0x01] + 1) * 8;
1082 iBpp = 8;
1083 iDispBpp = 4;
1084 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x1) == CIRRUS_SR7_BPP_SVGA) {
1085 switch (BX_CIRRUS_THIS sequencer.reg[0x07] & CIRRUS_SR7_BPP_MASK) {
1086 case CIRRUS_SR7_BPP_8:
1087 iBpp = 8;
1088 iDispBpp = 8;
1089 break;
1090 case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
1091 case CIRRUS_SR7_BPP_16:
1092 iBpp = 16;
1093 iDispBpp = (BX_CIRRUS_THIS hidden_dac.data & 0x1) ? 16 : 15;
1094 break;
1095 case CIRRUS_SR7_BPP_24:
1096 iBpp = 24;
1097 iDispBpp = 24;
1098 break;
1099 case CIRRUS_SR7_BPP_32:
1100 iBpp = 32;
1101 iDispBpp = 32;
1102 break;
1103 default:
1104 BX_PANIC(("unknown bpp - seqencer.reg[0x07] = %02x",BX_CIRRUS_THIS sequencer.reg[0x07]));
1105 break;
1106 }
1107 }
1108 if ((iWidth != BX_CIRRUS_THIS svga_xres) || (iHeight != BX_CIRRUS_THIS svga_yres)
1109 || (iDispBpp != BX_CIRRUS_THIS svga_dispbpp)) {
1110 BX_INFO(("switched to %u x %u x %u", iWidth, iHeight, iDispBpp));
1111 }
1112 BX_CIRRUS_THIS svga_xres = iWidth;
1113 BX_CIRRUS_THIS svga_yres = iHeight;
1114 BX_CIRRUS_THIS svga_bpp = iBpp;
1115 BX_CIRRUS_THIS svga_dispbpp = iDispBpp;
1116 BX_CIRRUS_THIS disp_ptr = BX_CIRRUS_THIS s.memory + iTopOffset;
1117 // compatibilty settings for VGA core
1118 BX_CIRRUS_THIS s.last_xres = iWidth;
1119 BX_CIRRUS_THIS s.last_yres = iHeight;
1120 BX_CIRRUS_THIS s.last_bpp = iDispBpp;
1121 }
1122
1123 void bx_svga_cirrus_c::draw_hardware_cursor(unsigned xc, unsigned yc, bx_svga_tileinfo_t *info)
1124 {
1125 if (BX_CIRRUS_THIS hw_cursor.size &&
1126 (xc < (unsigned)(BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size)) &&
1127 (xc+X_TILESIZE > BX_CIRRUS_THIS hw_cursor.x) &&
1128 (yc < (unsigned)(BX_CIRRUS_THIS hw_cursor.y+BX_CIRRUS_THIS hw_cursor.size)) &&
1129 (yc+Y_TILESIZE > BX_CIRRUS_THIS hw_cursor.y)) {
1130 int i;
1131 unsigned w, h, pitch, cx, cy, cx0, cy0, cx1, cy1;
1132
1133 Bit8u * tile_ptr, * tile_ptr2;
1134 Bit8u * plane0_ptr, *plane0_ptr2;
1135 Bit8u * plane1_ptr, *plane1_ptr2;
1136 unsigned long fgcol, bgcol;
1137 Bit64u plane0, plane1;
1138
1139 cx0 = BX_CIRRUS_THIS hw_cursor.x > xc ? BX_CIRRUS_THIS hw_cursor.x : xc;
1140 cy0 = BX_CIRRUS_THIS hw_cursor.y > yc ? BX_CIRRUS_THIS hw_cursor.y : yc;
1141 cx1 = (unsigned)(BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size) < xc+X_TILESIZE ? BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size : xc+X_TILESIZE;
1142 cy1 = (unsigned)(BX_CIRRUS_THIS hw_cursor.y+BX_CIRRUS_THIS hw_cursor.size) < yc+Y_TILESIZE ? BX_CIRRUS_THIS hw_cursor.y+BX_CIRRUS_THIS hw_cursor.size : yc+Y_TILESIZE;
1143
1144 if (info->bpp == 15) info->bpp = 16;
1145 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h) +
1146 info->pitch * (cy0 - yc) + (info->bpp / 8) * (cx0 - xc);
1147 plane0_ptr = BX_CIRRUS_THIS s.memory + BX_CIRRUS_THIS s.memsize - 16384;
1148
1149 switch (BX_CIRRUS_THIS hw_cursor.size) {
1150 case 32:
1151 plane0_ptr += (BX_CIRRUS_THIS sequencer.reg[0x13] & 0x3f) * 256;
1152 plane1_ptr = plane0_ptr + 128;
1153 pitch = 4;
1154 break;
1155
1156 case 64:
1157 plane0_ptr += (BX_CIRRUS_THIS sequencer.reg[0x13] & 0x3c) * 256;
1158 plane1_ptr = plane0_ptr + 8;
1159 pitch = 16;
1160 break;
1161
1162 default:
1163 BX_ERROR(("unsupported hardware cursor size"));
1164 return;
1165 break;
1166 }
1167
1168 if (!info->is_indexed) {
1169 fgcol = MAKE_COLOUR(
1170 BX_CIRRUS_THIS hidden_dac.palette[45], 6, info->red_shift, info->red_mask,
1171 BX_CIRRUS_THIS hidden_dac.palette[46], 6, info->green_shift, info->green_mask,
1172 BX_CIRRUS_THIS hidden_dac.palette[47], 6, info->blue_shift, info->blue_mask);
1173 bgcol = MAKE_COLOUR(
1174 BX_CIRRUS_THIS hidden_dac.palette[0], 6, info->red_shift, info->red_mask,
1175 BX_CIRRUS_THIS hidden_dac.palette[1], 6, info->green_shift, info->green_mask,
1176 BX_CIRRUS_THIS hidden_dac.palette[2], 6, info->blue_shift, info->blue_mask);
1177 } else {
1178 // FIXME: this is a hack that works in Windows guests
1179 // TODO: compare hidden DAC entries with DAC entries to find nearest match
1180 fgcol = 0xff;
1181 bgcol = 0x00;
1182 }
1183
1184 plane0_ptr += pitch * (cy0 - BX_CIRRUS_THIS hw_cursor.y);
1185 plane1_ptr += pitch * (cy0 - BX_CIRRUS_THIS hw_cursor.y);
1186 for (cy=cy0; cy<cy1; cy++) {
1187 tile_ptr2 = tile_ptr + (info->bpp/8) * (cx1 - cx0) - 1;
1188 plane0_ptr2 = plane0_ptr;
1189 plane1_ptr2 = plane1_ptr;
1190 plane0 = plane1 = 0;
1191 for (i=0; i<BX_CIRRUS_THIS hw_cursor.size; i+=8) {
1192 plane0 = (plane0 << 8) | *(plane0_ptr2++);
1193 plane1 = (plane1 << 8) | *(plane1_ptr2++);
1194 }
1195 plane0 >>= BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size - cx1;
1196 plane1 >>= BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size - cx1;
1197 for (cx=cx0; cx<cx1; cx++) {
1198 if (plane0 & 1) {
1199 if (plane1 & 1) {
1200 if (info->is_little_endian) {
1201 for (i=info->bpp-8; i>-8; i-=8) {
1202 *(tile_ptr2--) = (Bit8u)(fgcol >> i);
1203 }
1204 }
1205 else {
1206 for (i=0; i<info->bpp; i+=8) {
1207 *(tile_ptr2--) = (Bit8u)(fgcol >> i);
1208 }
1209 }
1210 }
1211 else {
1212 for (i=0; i<info->bpp; i+=8) {
1213 *(tile_ptr2--) ^= 0xff;
1214 }
1215 }
1216 }
1217 else {
1218 if (plane1 & 1) {
1219 if (info->is_little_endian) {
1220 for (i=info->bpp-8; i>-8; i-=8) {
1221 *(tile_ptr2--) = (Bit8u)(bgcol >> i);
1222 }
1223 }
1224 else {
1225 for (i=0; i<info->bpp; i+=8) {
1226 *(tile_ptr2--) = (Bit8u)(bgcol >> i);
1227 }
1228 }
1229 }
1230 else {
1231 tile_ptr2 -= (info->bpp/8);
1232 }
1233 }
1234 plane0 >>= 1;
1235 plane1 >>= 1;
1236 }
1237 tile_ptr += info->pitch;
1238 plane0_ptr += pitch;
1239 plane1_ptr += pitch;
1240 }
1241 }
1242 }
1243
1244 void bx_svga_cirrus_c::svga_update(void)
1245 {
1246 unsigned width, height, pitch;
1247
1248 /* skip screen update when the sequencer is in reset mode or video is disabled */
1249 if (! BX_CIRRUS_THIS s.sequencer.reset1 ||
1250 ! BX_CIRRUS_THIS s.sequencer.reset2 ||
1251 ! BX_CIRRUS_THIS s.attribute_ctrl.video_enabled) {
1252 return;
1253 }
1254
1255 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
1256 if (BX_CIRRUS_THIS svga_needs_update_mode) {
1257 BX_CIRRUS_THIS s.vga_mem_updated = 1;
1258 BX_CIRRUS_THIS svga_needs_update_mode = 0;
1259 }
1260 BX_CIRRUS_THIS bx_vgacore_c::update();
1261 return;
1262 }
1263 else {
1264 if (BX_CIRRUS_THIS svga_needs_update_mode) {
1265 svga_modeupdate();
1266 }
1267 }
1268
1269 width = BX_CIRRUS_THIS svga_xres;
1270 height = BX_CIRRUS_THIS svga_yres;
1271 pitch = BX_CIRRUS_THIS svga_pitch;
1272
1273 if (BX_CIRRUS_THIS svga_needs_update_mode) {
1274 width = BX_CIRRUS_THIS svga_xres;
1275 height = BX_CIRRUS_THIS svga_yres;
1276 bx_gui->dimension_update(width, height, 0, 0, BX_CIRRUS_THIS svga_dispbpp);
1277 BX_CIRRUS_THIS s.last_bpp = BX_CIRRUS_THIS svga_dispbpp;
1278 BX_CIRRUS_THIS svga_needs_update_mode = 0;
1279 BX_CIRRUS_THIS svga_needs_update_dispentire = 1;
1280 }
1281
1282 if (BX_CIRRUS_THIS svga_needs_update_dispentire) {
1283 BX_CIRRUS_THIS redraw_area(0,0,width,height);
1284 BX_CIRRUS_THIS svga_needs_update_dispentire = 0;
1285 }
1286
1287 if (!BX_CIRRUS_THIS svga_needs_update_tile) {
1288 return;
1289 }
1290 BX_CIRRUS_THIS svga_needs_update_tile = 0;
1291
1292 unsigned xc, yc, xti, yti;
1293 unsigned r, c, w, h;
1294 int i;
1295 Bit8u red, green, blue;
1296 Bit32u colour;
1297 Bit8u * vid_ptr, * vid_ptr2;
1298 Bit8u * tile_ptr, * tile_ptr2;
1299 bx_svga_tileinfo_t info;
1300
1301 if (bx_gui->graphics_tile_info_common(&info)) {
1302 if (info.snapshot_mode) {
1303 vid_ptr = BX_CIRRUS_THIS disp_ptr;
1304 tile_ptr = bx_gui->get_snapshot_buffer();
1305 if (tile_ptr != NULL) {
1306 for (yc = 0; yc < height; yc++) {
1307 memcpy(tile_ptr, vid_ptr, info.pitch);
1308 vid_ptr += pitch;
1309 tile_ptr += info.pitch;
1310 }
1311 }
1312 } else if (info.is_indexed) {
1313 switch (BX_CIRRUS_THIS svga_dispbpp) {
1314 case 4:
1315 case 15:
1316 case 16:
1317 case 24:
1318 case 32:
1319 BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays, svga_dispbpp=%d",
1320 BX_CIRRUS_THIS svga_dispbpp));
1321 break;
1322 case 8:
1323 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1324 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1325 if (GET_TILE_UPDATED (xti, yti)) {
1326 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + xc);
1327 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1328 for (r=0; r<h; r++) {
1329 vid_ptr2 = vid_ptr;
1330 tile_ptr2 = tile_ptr;
1331 for (c=0; c<w; c++) {
1332 colour = 0;
1333 for (i=0; i<(int)BX_CIRRUS_THIS svga_bpp; i+=8) {
1334 colour |= *(vid_ptr2++) << i;
1335 }
1336 if (info.is_little_endian) {
1337 for (i=0; i<info.bpp; i+=8) {
1338 *(tile_ptr2++) = colour >> i;
1339 }
1340 }
1341 else {
1342 for (i=info.bpp-8; i>-8; i-=8) {
1343 *(tile_ptr2++) = colour >> i;
1344 }
1345 }
1346 }
1347 vid_ptr += pitch;
1348 tile_ptr += info.pitch;
1349 }
1350 draw_hardware_cursor(xc, yc, &info);
1351 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1352 SET_TILE_UPDATED (xti, yti, 0);
1353 }
1354 }
1355 }
1356 break;
1357 }
1358 }
1359 else {
1360 switch (BX_CIRRUS_THIS svga_dispbpp) {
1361 case 4:
1362 BX_ERROR(("cannot draw 4bpp SVGA"));
1363 break;
1364 case 8:
1365 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1366 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1367 if (GET_TILE_UPDATED (xti, yti)) {
1368 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + xc);
1369 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1370 for (r=0; r<h; r++) {
1371 vid_ptr2 = vid_ptr;
1372 tile_ptr2 = tile_ptr;
1373 for (c=0; c<w; c++) {
1374 colour = *(vid_ptr2++);
1375 colour = MAKE_COLOUR(
1376 BX_CIRRUS_THIS s.pel.data[colour].red, 6, info.red_shift, info.red_mask,
1377 BX_CIRRUS_THIS s.pel.data[colour].green, 6, info.green_shift, info.green_mask,
1378 BX_CIRRUS_THIS s.pel.data[colour].blue, 6, info.blue_shift, info.blue_mask);
1379 if (info.is_little_endian) {
1380 for (i=0; i<info.bpp; i+=8) {
1381 *(tile_ptr2++) = colour >> i;
1382 }
1383 }
1384 else {
1385 for (i=info.bpp-8; i>-8; i-=8) {
1386 *(tile_ptr2++) = colour >> i;
1387 }
1388 }
1389 }
1390 vid_ptr += pitch;
1391 tile_ptr += info.pitch;
1392 }
1393 draw_hardware_cursor(xc, yc, &info);
1394 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1395 SET_TILE_UPDATED (xti, yti, 0);
1396 }
1397 }
1398 }
1399 break;
1400 case 15:
1401 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1402 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1403 if (GET_TILE_UPDATED (xti, yti)) {
1404 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<1));
1405 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1406 for (r=0; r<h; r++) {
1407 vid_ptr2 = vid_ptr;
1408 tile_ptr2 = tile_ptr;
1409 for (c=0; c<w; c++) {
1410 colour = *(vid_ptr2++);
1411 colour |= *(vid_ptr2++) << 8;
1412 colour = MAKE_COLOUR(
1413 colour & 0x001f, 5, info.blue_shift, info.blue_mask,
1414 colour & 0x03e0, 10, info.green_shift, info.green_mask,
1415 colour & 0x7c00, 15, info.red_shift, info.red_mask);
1416 if (info.is_little_endian) {
1417 for (i=0; i<info.bpp; i+=8) {
1418 *(tile_ptr2++) = colour >> i;
1419 }
1420 }
1421 else {
1422 for (i=info.bpp-8; i>-8; i-=8) {
1423 *(tile_ptr2++) = colour >> i;
1424 }
1425 }
1426 }
1427 vid_ptr += pitch;
1428 tile_ptr += info.pitch;
1429 }
1430 draw_hardware_cursor(xc, yc, &info);
1431 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1432 SET_TILE_UPDATED (xti, yti, 0);
1433 }
1434 }
1435 }
1436 break;
1437 case 16:
1438 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1439 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1440 if (GET_TILE_UPDATED (xti, yti)) {
1441 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<1));
1442 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1443 for (r=0; r<h; r++) {
1444 vid_ptr2 = vid_ptr;
1445 tile_ptr2 = tile_ptr;
1446 for (c=0; c<w; c++) {
1447 colour = *(vid_ptr2++);
1448 colour |= *(vid_ptr2++) << 8;
1449 colour = MAKE_COLOUR(
1450 colour & 0x001f, 5, info.blue_shift, info.blue_mask,
1451 colour & 0x07e0, 11, info.green_shift, info.green_mask,
1452 colour & 0xf800, 16, info.red_shift, info.red_mask);
1453 if (info.is_little_endian) {
1454 for (i=0; i<info.bpp; i+=8) {
1455 *(tile_ptr2++) = colour >> i;
1456 }
1457 }
1458 else {
1459 for (i=info.bpp-8; i>-8; i-=8) {
1460 *(tile_ptr2++) = colour >> i;
1461 }
1462 }
1463 }
1464 vid_ptr += pitch;
1465 tile_ptr += info.pitch;
1466 }
1467 draw_hardware_cursor(xc, yc, &info);
1468 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1469 SET_TILE_UPDATED (xti, yti, 0);
1470 }
1471 }
1472 }
1473 break;
1474 case 24:
1475 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1476 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1477 if (GET_TILE_UPDATED (xti, yti)) {
1478 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + 3*xc);
1479 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1480 for (r=0; r<h; r++) {
1481 vid_ptr2 = vid_ptr;
1482 tile_ptr2 = tile_ptr;
1483 for (c=0; c<w; c++) {
1484 blue = *(vid_ptr2++);
1485 green = *(vid_ptr2++);
1486 red = *(vid_ptr2++);
1487 colour = MAKE_COLOUR(
1488 red, 8, info.red_shift, info.red_mask,
1489 green, 8, info.green_shift, info.green_mask,
1490 blue, 8, info.blue_shift, info.blue_mask);
1491 if (info.is_little_endian) {
1492 for (i=0; i<info.bpp; i+=8) {
1493 *(tile_ptr2++) = colour >> i;
1494 }
1495 }
1496 else {
1497 for (i=info.bpp-8; i>-8; i-=8) {
1498 *(tile_ptr2++) = colour >> i;
1499 }
1500 }
1501 }
1502 vid_ptr += pitch;
1503 tile_ptr += info.pitch;
1504 }
1505 draw_hardware_cursor(xc, yc, &info);
1506 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1507 SET_TILE_UPDATED (xti, yti, 0);
1508 }
1509 }
1510 }
1511 break;
1512 case 32:
1513 for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
1514 for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
1515 if (GET_TILE_UPDATED (xti, yti)) {
1516 vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<2));
1517 tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
1518 for (r=0; r<h; r++) {
1519 vid_ptr2 = vid_ptr;
1520 tile_ptr2 = tile_ptr;
1521 for (c=0; c<w; c++) {
1522 blue = *(vid_ptr2++);
1523 green = *(vid_ptr2++);
1524 red = *(vid_ptr2++);
1525 vid_ptr2++;
1526 colour = MAKE_COLOUR(
1527 red, 8, info.red_shift, info.red_mask,
1528 green, 8, info.green_shift, info.green_mask,
1529 blue, 8, info.blue_shift, info.blue_mask);
1530 if (info.is_little_endian) {
1531 for (i=0; i<info.bpp; i+=8) {
1532 *(tile_ptr2++) = colour >> i;
1533 }
1534 }
1535 else {
1536 for (i=info.bpp-8; i>-8; i-=8) {
1537 *(tile_ptr2++) = colour >> i;
1538 }
1539 }
1540 }
1541 vid_ptr += pitch;
1542 tile_ptr += info.pitch;
1543 }
1544 draw_hardware_cursor(xc, yc, &info);
1545 bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
1546 SET_TILE_UPDATED (xti, yti, 0);
1547 }
1548 }
1549 }
1550 break;
1551 }
1552 }
1553 }
1554 else {
1555 BX_PANIC(("cannot get svga tile info"));
1556 }
1557 }
1558
1559 void bx_svga_cirrus_c::update_bank_ptr(Bit8u bank_index)
1560 {
1561 unsigned offset;
1562 unsigned limit;
1563
1564 if (BX_CIRRUS_THIS banking_is_dual())
1565 offset = BX_CIRRUS_THIS control.reg[0x09 + bank_index];
1566 else
1567 offset = BX_CIRRUS_THIS control.reg[0x09];
1568
1569 if (BX_CIRRUS_THIS banking_granularity_is_16k())
1570 offset <<= 14;
1571 else
1572 offset <<= 12;
1573
1574 if (BX_CIRRUS_THIS s.memsize <= offset) {
1575 limit = 0;
1576 BX_ERROR(("bank offset %08x is invalid",offset));
1577 } else {
1578 limit = BX_CIRRUS_THIS s.memsize - offset;
1579 }
1580
1581 if (!BX_CIRRUS_THIS banking_is_dual() && (bank_index != 0)) {
1582 if (limit > 0x8000) {
1583 offset += 0x8000;
1584 limit -= 0x8000;
1585 } else {
1586 limit = 0;
1587 }
1588 }
1589
1590 if (limit > 0) {
1591 BX_CIRRUS_THIS bank_base[bank_index] = offset;
1592 BX_CIRRUS_THIS bank_limit[bank_index] = limit;
1593 } else {
1594 BX_CIRRUS_THIS bank_base[bank_index] = 0;
1595 BX_CIRRUS_THIS bank_limit[bank_index] = 0;
1596 }
1597 }
1598
1599 Bit8u bx_svga_cirrus_c::svga_read_crtc(Bit32u address, unsigned index)
1600 {
1601 switch (index) {
1602 case 0x00: // VGA
1603 case 0x01: // VGA
1604 case 0x02: // VGA
1605 case 0x03: // VGA
1606 case 0x04: // VGA
1607 case 0x05: // VGA
1608 case 0x06: // VGA
1609 case 0x07: // VGA
1610 case 0x08: // VGA
1611 case 0x09: // VGA
1612 case 0x0a: // VGA
1613 case 0x0b: // VGA
1614 case 0x0c: // VGA
1615 case 0x0d: // VGA
1616 case 0x0e: // VGA
1617 case 0x0f: // VGA
1618 case 0x10: // VGA
1619 case 0x11: // VGA
1620 case 0x12: // VGA
1621 case 0x13: // VGA
1622 case 0x14: // VGA
1623 case 0x15: // VGA
1624 case 0x16: // VGA
1625 case 0x17: // VGA
1626 case 0x18: // VGA
1627 break;
1628 case 0x19:
1629 case 0x1A:
1630 case 0x1B:
1631 case 0x1C:
1632 case 0x1D:
1633 case 0x22:
1634 case 0x24:
1635 case 0x25:
1636 case 0x27:
1637 break;
1638 case 0x26:
1639 return (BX_CIRRUS_THIS s.attribute_ctrl.address & 0x3f);
1640 default:
1641 BX_DEBUG(("CRTC index 0x%02x is unknown(read)", index));
1642 break;
1643 }
1644
1645 if (index <= VGA_CRTC_MAX) {
1646 return VGA_READ(address,1);
1647 }
1648
1649 if (index <= CIRRUS_CRTC_MAX) {
1650 return BX_CIRRUS_THIS crtc.reg[index];
1651 }
1652
1653 return 0xff;
1654 }
1655
1656 void bx_svga_cirrus_c::svga_write_crtc(Bit32u address, unsigned index, Bit8u value)
1657 {
1658 BX_DEBUG(("crtc: index 0x%02x write 0x%02x", index, (unsigned)value));
1659
1660 bx_bool update_pitch = 0;
1661
1662 switch (index) {
1663 case 0x00: // VGA
1664 case 0x02: // VGA
1665 case 0x03: // VGA
1666 case 0x04: // VGA
1667 case 0x05: // VGA
1668 case 0x06: // VGA
1669 case 0x08: // VGA
1670 case 0x0a: // VGA
1671 case 0x0b: // VGA
1672 case 0x0e: // VGA
1673 case 0x0f: // VGA
1674 case 0x10: // VGA
1675 case 0x11: // VGA
1676 case 0x14: // VGA
1677 case 0x15: // VGA
1678 case 0x16: // VGA
1679 case 0x17: // VGA
1680 case 0x18: // VGA
1681 break;
1682
1683 case 0x01: // VGA
1684 case 0x07: // VGA
1685 case 0x09: // VGA
1686 case 0x0c: // VGA (display offset 0x00ff00)
1687 case 0x0d: // VGA (display offset 0x0000ff)
1688 case 0x12: // VGA
1689 case 0x1A: // 0x01: interlaced video mode
1690 case 0x1D: // 0x80: offset 0x080000 (>=CLGD5434)
1691 BX_CIRRUS_THIS svga_needs_update_mode = 1;
1692 break;
1693
1694 case 0x13: // VGA
1695 case 0x1B: // 0x01: offset 0x010000, 0x0c: offset 0x060000
1696 update_pitch = 1;
1697 break;
1698
1699 case 0x19:
1700 case 0x1C:
1701 break;
1702
1703 default:
1704 BX_DEBUG(("CRTC index 0x%02x is unknown(write 0x%02x)", index, (unsigned)value));
1705 return;
1706 }
1707
1708 if (index <= CIRRUS_CRTC_MAX) {
1709 BX_CIRRUS_THIS crtc.reg[index] = value;
1710 }
1711 if (index <= VGA_CRTC_MAX) {
1712 VGA_WRITE(address,value,1);
1713 }
1714
1715 if (update_pitch) {
1716 BX_CIRRUS_THIS svga_pitch = (BX_CIRRUS_THIS crtc.reg[0x13] << 3) | ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x10) << 7);
1717 BX_CIRRUS_THIS svga_needs_update_mode = 1;
1718 }
1719 }
1720
1721 Bit8u bx_svga_cirrus_c::svga_read_sequencer(Bit32u address, unsigned index)
1722 {
1723 switch (index) {
1724 case 0x00: // VGA
1725 case 0x01: // VGA
1726 case 0x02: // VGA
1727 case 0x03: // VGA
1728 case 0x04: // VGA
1729 break;
1730 case 0x6: // cirrus unlock extensions
1731 case 0x7: // cirrus extended sequencer mode
1732 case 0xf: // cirrus dram control
1733 case 0x12: // graphics cursor attribute
1734 case 0x13: // graphics cursor pattern address offset
1735 case 0x17: // configuration readback & extended control
1736 break;
1737 case 0x10: // cursor xpos << 5 (index & 0x3f)
1738 case 0x30:
1739 case 0x50:
1740 case 0x70:
1741 case 0x90:
1742 case 0xb0:
1743 case 0xd0:
1744 case 0xf0:
1745 return BX_CIRRUS_THIS sequencer.reg[0x10];
1746 case 0x11: // cursor ypos << 5 (index & 0x3f)
1747 case 0x31:
1748 case 0x51:
1749 case 0x71:
1750 case 0x91:
1751 case 0xb1:
1752 case 0xd1:
1753 case 0xf1:
1754 return BX_CIRRUS_THIS sequencer.reg[0x11];
1755 default:
1756 BX_DEBUG(("sequencer index 0x%02x is unknown(read)", index));
1757 break;
1758 }
1759
1760 if (index <= VGA_SEQENCER_MAX) {
1761 return VGA_READ(address,1);
1762 }
1763
1764 if (index <= CIRRUS_SEQENCER_MAX) {
1765 return BX_CIRRUS_THIS sequencer.reg[index];
1766 }
1767
1768 return 0xff;
1769 }
1770
1771 void bx_svga_cirrus_c::svga_write_sequencer(Bit32u address, unsigned index, Bit8u value)
1772 {
1773 BX_DEBUG(("sequencer: index 0x%02x write 0x%02x", index, (unsigned)value));
1774
1775 bx_bool update_cursor = 0;
1776 Bit16u x, y, size;
1777
1778 x = BX_CIRRUS_THIS hw_cursor.x;
1779 y = BX_CIRRUS_THIS hw_cursor.y;
1780 size = BX_CIRRUS_THIS hw_cursor.size;
1781
1782 switch (index) {
1783 case 0x00: // VGA
1784 case 0x02: // VGA
1785 case 0x03: // VGA
1786 break;
1787 case 0x01: // VGA
1788 case 0x04: // VGA
1789 BX_CIRRUS_THIS svga_needs_update_mode = 1;
1790 break;
1791 case 0x6: // cirrus unlock extensions
1792 value &= 0x17;
1793 if (value == 0x12) {
1794 BX_CIRRUS_THIS svga_unlock_special = 1;
1795 BX_CIRRUS_THIS sequencer.reg[0x6] = 0x12;
1796 } else {
1797 #if BX_SUPPORT_PCI
1798 BX_CIRRUS_THIS svga_unlock_special = 0;
1799 #else
1800 if (!BX_CIRRUS_THIS pci_enabled) {
1801 BX_CIRRUS_THIS svga_unlock_special = 0;
1802 }
1803 #endif
1804 BX_CIRRUS_THIS sequencer.reg[0x6] = 0x0f;
1805 }
1806 return;
1807 case 0x7: // cirrus extended sequencer mode
1808 if (value != BX_CIRRUS_THIS sequencer.reg[0x7]) {
1809 BX_CIRRUS_THIS svga_needs_update_mode = 1;
1810 }
1811 break;
1812 case 0x08:
1813 case 0x09:
1814 case 0x0a: // cirrus scratch reg 1
1815 case 0x0b:
1816 case 0x0c:
1817 case 0x0d:
1818 case 0x0e:
1819 case 0x1b:
1820 case 0x1c:
1821 case 0x1d:
1822 case 0x1e:
1823 break;
1824 case 0x0f:
1825 return;
1826 case 0x10: // cursor xpos << 5 (index & 0x3f)
1827 case 0x30:
1828 case 0x50:
1829 case 0x70:
1830 case 0x90:
1831 case 0xb0:
1832 case 0xd0:
1833 case 0xf0:
1834 BX_CIRRUS_THIS sequencer.reg[0x10] = value;
1835 x = BX_CIRRUS_THIS hw_cursor.x;
1836 BX_CIRRUS_THIS hw_cursor.x = (value << 3) | (index >> 5);
1837 update_cursor = 1;
1838 break;
1839 case 0x11: // cursor ypos << 5 (index & 0x3f)
1840 case 0x31:
1841 case 0x51:
1842 case 0x71:
1843 case 0x91:
1844 case 0xb1:
1845 case 0xd1:
1846 case 0xf1:
1847 BX_CIRRUS_THIS sequencer.reg[0x11] = value;
1848 y = BX_CIRRUS_THIS hw_cursor.y;
1849 BX_CIRRUS_THIS hw_cursor.y = (value << 3) | (index >> 5);
1850 update_cursor = 1;
1851 break;
1852 case 0x12:
1853 size = BX_CIRRUS_THIS hw_cursor.size;
1854 if (value & CIRRUS_CURSOR_SHOW) {
1855 if (value & CIRRUS_CURSOR_LARGE) {
1856 BX_CIRRUS_THIS hw_cursor.size = 64;
1857 }
1858 else {
1859 BX_CIRRUS_THIS hw_cursor.size = 32;
1860 }
1861 }
1862 else {
1863 BX_CIRRUS_THIS hw_cursor.size = 0;
1864 }
1865 update_cursor = 1;
1866 break;
1867 case 0x13:
1868 update_cursor = 1;
1869 break;
1870 case 0x17:
1871 value = (BX_CIRRUS_THIS sequencer.reg[0x17] & 0x38) | (value & 0xc7);
1872 break;
1873 default:
1874 BX_DEBUG(("sequencer index 0x%02x is unknown(write 0x%02x)", index, (unsigned)value));
1875 break;
1876 }
1877
1878 if (update_cursor) {
1879 BX_CIRRUS_THIS redraw_area(x, y, size, size);
1880 BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS hw_cursor.x, BX_CIRRUS_THIS hw_cursor.y, BX_CIRRUS_THIS hw_cursor.size, BX_CIRRUS_THIS hw_cursor.size);
1881 }
1882
1883 if (index <= CIRRUS_SEQENCER_MAX) {
1884 BX_CIRRUS_THIS sequencer.reg[index] = value;
1885 }
1886 if (index <= VGA_SEQENCER_MAX) {
1887 VGA_WRITE(address,value,1);
1888 }
1889 }
1890
1891 Bit8u bx_svga_cirrus_c::svga_read_control(Bit32u address, unsigned index)
1892 {
1893 switch (index) {
1894 case 0x00: // VGA
1895 return BX_CIRRUS_THIS control.shadow_reg0;
1896 case 0x01: // VGA
1897 return BX_CIRRUS_THIS control.shadow_reg1;
1898 case 0x05: // VGA
1899 return BX_CIRRUS_THIS control.reg[index];
1900 case 0x02: // VGA
1901 case 0x03: // VGA
1902 case 0x04: // VGA
1903 case 0x06: // VGA
1904 case 0x07: // VGA
1905 case 0x08: // VGA
1906 break;
1907 case 0x09: // bank offset #0
1908 case 0x0A: // bank offset #1
1909 case 0x0B:
1910 break;
1911
1912 case 0x10: // BGCOLOR 0x0000ff00
1913 case 0x11: // FGCOLOR 0x0000ff00
1914 case 0x12: // BGCOLOR 0x00ff0000
1915 case 0x13: // FGCOLOR 0x00ff0000
1916 case 0x14: // BGCOLOR 0xff000000
1917 case 0x15: // FGCOLOR 0xff000000
1918 break;
1919
1920 case 0x20: // BLT WIDTH 0x0000ff
1921 case 0x21: // BLT WIDTH 0x001f00
1922 case 0x22: // BLT HEIGHT 0x0000ff
1923 case 0x23: // BLT HEIGHT 0x001f00
1924 case 0x24: // BLT DEST PITCH 0x0000ff
1925 case 0x25: // BLT DEST PITCH 0x001f00
1926 case 0x26: // BLT SRC PITCH 0x0000ff
1927 case 0x27: // BLT SRC PITCH 0x001f00
1928 case 0x28: // BLT DEST ADDR 0x0000ff
1929 case 0x29: // BLT DEST ADDR 0x00ff00
1930 case 0x2a: // BLT DEST ADDR 0x3f0000
1931 case 0x2c: // BLT SRC ADDR 0x0000ff
1932 case 0x2d: // BLT SRC ADDR 0x00ff00
1933 case 0x2e: // BLT SRC ADDR 0x3f0000
1934 case 0x2f: // BLT WRITE MASK
1935 case 0x30: // BLT MODE
1936 case 0x31: // BLT STATUS
1937 case 0x32: // RASTER OP
1938 case 0x33: // BLT MODE EXTENSION
1939 case 0x34: // BLT TRANSPARENT COLOR 0x00ff
1940 case 0x35: // BLT TRANSPARENT COLOR 0xff00
1941 case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
1942 case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
1943 break;
1944
1945 default:
1946 BX_DEBUG(("control index 0x%02x is unknown(read)", index));
1947 break;
1948 }
1949
1950 if (index <= VGA_CONTROL_MAX) {
1951 return VGA_READ(address,1);
1952 }
1953
1954 if (index <= CIRRUS_CONTROL_MAX) {
1955 return BX_CIRRUS_THIS control.reg[index];
1956 }
1957
1958 return 0xff;
1959 }
1960
1961 void bx_svga_cirrus_c::svga_write_control(Bit32u address, unsigned index, Bit8u value)
1962 {
1963 Bit8u old_value = BX_CIRRUS_THIS control.reg[index];
1964
1965 BX_DEBUG(("control: index 0x%02x write 0x%02x", index, (unsigned)value));
1966
1967 switch (index) {
1968 case 0x00: // VGA
1969 BX_CIRRUS_THIS control.shadow_reg0 = value;
1970 break;
1971 case 0x01: // VGA
1972 BX_CIRRUS_THIS control.shadow_reg1 = value;
1973 break;
1974 case 0x02: // VGA
1975 case 0x03: // VGA
1976 case 0x04: // VGA
1977 case 0x07: // VGA
1978 case 0x08: // VGA
1979 break;
1980 case 0x05: // VGA
1981 case 0x06: // VGA
1982 BX_CIRRUS_THIS svga_needs_update_mode = 1;
1983 break;
1984 case 0x09: // bank offset #0
1985 case 0x0A: // bank offset #1
1986 case 0x0B:
1987 BX_CIRRUS_THIS control.reg[index] = value;
1988 update_bank_ptr(0);
1989 update_bank_ptr(1);
1990 break;
1991
1992 case 0x10: // BGCOLOR 0x0000ff00
1993 case 0x11: // FGCOLOR 0x0000ff00
1994 case 0x12: // BGCOLOR 0x00ff0000
1995 case 0x13: // FGCOLOR 0x00ff0000
1996 case 0x14: // BGCOLOR 0xff000000
1997 case 0x15: // FGCOLOR 0xff000000
1998 break;
1999
2000 case 0x20: // BLT WIDTH 0x0000ff
2001 break;
2002 case 0x21: // BLT WIDTH 0x001f00
2003 value &= 0x1f;
2004 break;
2005 case 0x22: // BLT HEIGHT 0x0000ff
2006 break;
2007 case 0x23: // BLT HEIGHT 0x001f00
2008 value &= 0x1f;
2009 break;
2010 case 0x24: // BLT DEST PITCH 0x0000ff
2011 break;
2012 case 0x25: // BLT DEST PITCH 0x001f00
2013 value &= 0x1f;
2014 break;
2015 case 0x26: // BLT SRC PITCH 0x0000ff
2016 break;
2017 case 0x27: // BLT SRC PITCH 0x001f00
2018 value &= 0x1f;
2019 break;
2020 case 0x28: // BLT DEST ADDR 0x0000ff
2021 break;
2022 case 0x29: // BLT DEST ADDR 0x00ff00
2023 break;
2024 case 0x2a: // BLT DEST ADDR 0x3f0000
2025 BX_CIRRUS_THIS control.reg[index] = value & 0x3f;
2026 if (BX_CIRRUS_THIS control.reg[0x31] & CIRRUS_BLT_AUTOSTART) {
2027 svga_bitblt();
2028 }
2029 return;
2030 case 0x2b: // BLT DEST ADDR (unused bits)
2031 break;
2032 case 0x2c: // BLT SRC ADDR 0x0000ff
2033 break;
2034 case 0x2d: // BLT SRC ADDR 0x00ff00
2035 break;
2036 case 0x2e: // BLT SRC ADDR 0x3f0000
2037 value &= 0x3f;
2038 break;
2039 case 0x2f: // BLT WRITE MASK
2040 if (((value ^ old_value) & 0x60) && (value & 0x60)) {
2041 BX_ERROR(("BLT WRITE MASK support is not complete (value = 0x%02x)", value));
2042 }
2043 break;
2044 case 0x30: // BLT MODE
2045 break;
2046 case 0x31: // BLT STATUS/START
2047 BX_CIRRUS_THIS control.reg[0x31] = value;
2048 if (((old_value & CIRRUS_BLT_RESET) != 0) &&
2049 ((value & CIRRUS_BLT_RESET) == 0)) {
2050 svga_reset_bitblt();
2051 }
2052 else if (((old_value & CIRRUS_BLT_START) == 0) &&
2053 ((value & CIRRUS_BLT_START) != 0)) {
2054 BX_CIRRUS_THIS control.reg[0x31] |= CIRRUS_BLT_BUSY;
2055 svga_bitblt();
2056 }
2057 return;
2058 case 0x32: // RASTER OP
2059 break;
2060 case 0x33: // BLT MODE EXTENSION
2061 #if BX_SUPPORT_PCI
2062 if (BX_CIRRUS_THIS pci_enabled) {
2063 if (((value ^ old_value) & 0x18) && (value & 0x18)) {
2064 BX_ERROR(("BLT MODE EXTENSION support is not complete (value = 0x%02x)", value & 0x18));
2065 }
2066 }
2067 else
2068 #endif
2069 {
2070 BX_DEBUG(("BLT MODE EXTENSION not available"));
2071 return;
2072 }
2073 break;
2074 case 0x34: // BLT TRANSPARENT COLOR 0x00ff
2075 case 0x35: // BLT TRANSPARENT COLOR 0xff00
2076 case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
2077 case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
2078 default:
2079 BX_DEBUG(("control index 0x%02x is unknown (write 0x%02x)", index, (unsigned)value));
2080 break;
2081 }
2082
2083 if (index <= CIRRUS_CONTROL_MAX) {
2084 BX_CIRRUS_THIS control.reg[index] = value;
2085 }
2086 if (index <= VGA_CONTROL_MAX) {
2087 VGA_WRITE(address,value,1);
2088 }
2089 }
2090
2091 Bit8u bx_svga_cirrus_c::svga_mmio_vga_read(Bit32u address)
2092 {
2093 Bit8u value = 0xff;
2094
2095 BX_DEBUG(("MMIO vga read - address 0x%04x, value 0x%02x",address,value));
2096
2097 #if BX_USE_CIRRUS_SMF
2098 value = (Bit8u)svga_read_handler(theSvga,0x3c0+address,1);
2099 #else // BX_USE_CIRRUS_SMF
2100 value = (Bit8u)svga_read(0x3c0+address,1);
2101 #endif // BX_USE_CIRRUS_SMF
2102
2103 return value;
2104 }
2105
2106 void bx_svga_cirrus_c::svga_mmio_vga_write(Bit32u address,Bit8u value)
2107 {
2108
2109 BX_DEBUG(("MMIO vga write - address 0x%04x, value 0x%02x",address,value));
2110
2111 #if BX_USE_CIRRUS_SMF
2112 svga_write_handler(theSvga,0x3c0+address,value,1);
2113 #else // BX_USE_CIRRUS_SMF
2114 svga_write(0x3c0+address,value,1);
2115 #endif // BX_USE_CIRRUS_SMF
2116
2117 }
2118
2119 Bit8u bx_svga_cirrus_c::svga_mmio_blt_read(Bit32u address)
2120 {
2121 Bit8u value = 0xff;
2122
2123 switch (address) {
2124 case (CLGD543x_MMIO_BLTBGCOLOR+0):
2125 value = BX_CIRRUS_THIS control.shadow_reg0;
2126 break;
2127 case (CLGD543x_MMIO_BLTBGCOLOR+1):
2128 value = svga_read_control(0x3cf,0x10);
2129 break;
2130 case (CLGD543x_MMIO_BLTBGCOLOR+2):
2131 value = svga_read_control(0x3cf,0x12);
2132 break;
2133 case (CLGD543x_MMIO_BLTBGCOLOR+3):
2134 value = svga_read_control(0x3cf,0x14);
2135 break;
2136 case (CLGD543x_MMIO_BLTFGCOLOR+0):
2137 value = BX_CIRRUS_THIS control.shadow_reg1;
2138 break;
2139 case (CLGD543x_MMIO_BLTFGCOLOR+1):
2140 value = svga_read_control(0x3cf,0x11);
2141 break;
2142 case (CLGD543x_MMIO_BLTFGCOLOR+2):
2143 value = svga_read_control(0x3cf,0x13);
2144 break;
2145 case (CLGD543x_MMIO_BLTFGCOLOR+3):
2146 value = svga_read_control(0x3cf,0x15);
2147 break;
2148 case (CLGD543x_MMIO_BLTWIDTH+0):
2149 value = svga_read_control(0x3cf,0x20);
2150 break;
2151 case (CLGD543x_MMIO_BLTWIDTH+1):
2152 value = svga_read_control(0x3cf,0x21);
2153 break;
2154 case (CLGD543x_MMIO_BLTHEIGHT+0):
2155 value = svga_read_control(0x3cf,0x22);
2156 break;
2157 case (CLGD543x_MMIO_BLTHEIGHT+1):
2158 value = svga_read_control(0x3cf,0x23);
2159 break;
2160 case (CLGD543x_MMIO_BLTDESTPITCH+0):
2161 value = svga_read_control(0x3cf,0x24);
2162 break;
2163 case (CLGD543x_MMIO_BLTDESTPITCH+1):
2164 value = svga_read_control(0x3cf,0x25);
2165 break;
2166 case (CLGD543x_MMIO_BLTSRCPITCH+0):
2167 value = svga_read_control(0x3cf,0x26);
2168 break;
2169 case (CLGD543x_MMIO_BLTSRCPITCH+1):
2170 value = svga_read_control(0x3cf,0x27);
2171 break;
2172 case (CLGD543x_MMIO_BLTDESTADDR+0):
2173 value = svga_read_control(0x3cf,0x28);
2174 break;
2175 case (CLGD543x_MMIO_BLTDESTADDR+1):
2176 value = svga_read_control(0x3cf,0x29);
2177 break;
2178 case (CLGD543x_MMIO_BLTDESTADDR+2):
2179 value = svga_read_control(0x3cf,0x2a);
2180 break;
2181 case (CLGD543x_MMIO_BLTDESTADDR+3):
2182 value = svga_read_control(0x3cf,0x2b);
2183 break;
2184 case (CLGD543x_MMIO_BLTSRCADDR+0):
2185 value = svga_read_control(0x3cf,0x2c);
2186 break;
2187 case (CLGD543x_MMIO_BLTSRCADDR+1):
2188 value = svga_read_control(0x3cf,0x2d);
2189 break;
2190 case (CLGD543x_MMIO_BLTSRCADDR+2):
2191 value = svga_read_control(0x3cf,0x2e);
2192 break;
2193 case CLGD543x_MMIO_BLTWRITEMASK:
2194 value = svga_read_control(0x3cf,0x2f);
2195 break;
2196 case CLGD543x_MMIO_BLTMODE:
2197 value = svga_read_control(0x3cf,0x30);
2198 break;
2199 case CLGD543x_MMIO_BLTROP:
2200 value = svga_read_control(0x3cf,0x32);
2201 break;
2202 case CLGD543x_MMIO_BLTMODEEXT:
2203 value = svga_read_control(0x3cf,0x33);
2204 break;
2205 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+0):
2206 value = svga_read_control(0x3cf,0x34);
2207 break;
2208 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+1):
2209 value = svga_read_control(0x3cf,0x35);
2210 break;
2211 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+2):
2212 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2213 break;
2214 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+3):
2215 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2216 break;
2217 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+0):
2218 value = svga_read_control(0x3cf,0x38);
2219 break;
2220 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+1):
2221 value = svga_read_control(0x3cf,0x39);
2222 break;
2223 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+2):
2224 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2225 break;
2226 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+3):
2227 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2228 break;
2229 case CLGD543x_MMIO_BLTSTATUS:
2230 value = svga_read_control(0x3cf,0x31);
2231 break;
2232 default:
2233 BX_ERROR(("MMIO blt read - address 0x%04x",address));
2234 break;
2235 }
2236
2237 BX_DEBUG(("MMIO blt read - address 0x%04x, value 0x%02x",address,value));
2238
2239 return value;
2240 }
2241
2242 void bx_svga_cirrus_c::svga_mmio_blt_write(Bit32u address,Bit8u value)
2243 {
2244 BX_DEBUG(("MMIO blt write - address 0x%04x, value 0x%02x",address,value));
2245
2246 switch (address) {
2247 case (CLGD543x_MMIO_BLTBGCOLOR+0):
2248 BX_CIRRUS_THIS control.shadow_reg0 = value;
2249 break;
2250 case (CLGD543x_MMIO_BLTBGCOLOR+1):
2251 svga_write_control(0x3cf,0x10,value);
2252 break;
2253 case (CLGD543x_MMIO_BLTBGCOLOR+2):
2254 svga_write_control(0x3cf,0x12,value);
2255 break;
2256 case (CLGD543x_MMIO_BLTBGCOLOR+3):
2257 svga_write_control(0x3cf,0x14,value);
2258 break;
2259 case (CLGD543x_MMIO_BLTFGCOLOR+0):
2260 BX_CIRRUS_THIS control.shadow_reg1 = value;
2261 break;
2262 case (CLGD543x_MMIO_BLTFGCOLOR+1):
2263 svga_write_control(0x3cf,0x11,value);
2264 break;
2265 case (CLGD543x_MMIO_BLTFGCOLOR+2):
2266 svga_write_control(0x3cf,0x13,value);
2267 break;
2268 case (CLGD543x_MMIO_BLTFGCOLOR+3):
2269 svga_write_control(0x3cf,0x15,value);
2270 break;
2271 case (CLGD543x_MMIO_BLTWIDTH+0):
2272 svga_write_control(0x3cf,0x20,value);
2273 break;
2274 case (CLGD543x_MMIO_BLTWIDTH+1):
2275 svga_write_control(0x3cf,0x21,value);
2276 break;
2277 case (CLGD543x_MMIO_BLTHEIGHT+0):
2278 svga_write_control(0x3cf,0x22,value);
2279 break;
2280 case (CLGD543x_MMIO_BLTHEIGHT+1):
2281 svga_write_control(0x3cf,0x23,value);
2282 break;
2283 case (CLGD543x_MMIO_BLTDESTPITCH+0):
2284 svga_write_control(0x3cf,0x24,value);
2285 break;
2286 case (CLGD543x_MMIO_BLTDESTPITCH+1):
2287 svga_write_control(0x3cf,0x25,value);
2288 break;
2289 case (CLGD543x_MMIO_BLTSRCPITCH+0):
2290 svga_write_control(0x3cf,0x26,value);
2291 break;
2292 case (CLGD543x_MMIO_BLTSRCPITCH+1):
2293 svga_write_control(0x3cf,0x27,value);
2294 break;
2295 case (CLGD543x_MMIO_BLTDESTADDR+0):
2296 svga_write_control(0x3cf,0x28,value);
2297 break;
2298 case (CLGD543x_MMIO_BLTDESTADDR+1):
2299 svga_write_control(0x3cf,0x29,value);
2300 break;
2301 case (CLGD543x_MMIO_BLTDESTADDR+2):
2302 svga_write_control(0x3cf,0x2a,value);
2303 break;
2304 case (CLGD543x_MMIO_BLTDESTADDR+3):
2305 svga_write_control(0x3cf,0x2b,value);
2306 break;
2307 case (CLGD543x_MMIO_BLTSRCADDR+0):
2308 svga_write_control(0x3cf,0x2c,value);
2309 break;
2310 case (CLGD543x_MMIO_BLTSRCADDR+1):
2311 svga_write_control(0x3cf,0x2d,value);
2312 break;
2313 case (CLGD543x_MMIO_BLTSRCADDR+2):
2314 svga_write_control(0x3cf,0x2e,value);
2315 break;
2316 case CLGD543x_MMIO_BLTWRITEMASK:
2317 svga_write_control(0x3cf,0x2f,value);
2318 break;
2319 case CLGD543x_MMIO_BLTMODE:
2320 svga_write_control(0x3cf,0x30,value);
2321 break;
2322 case CLGD543x_MMIO_BLTMODE+1:
2323 // unused ??? - ignored for now
2324 break;
2325 case CLGD543x_MMIO_BLTROP:
2326 svga_write_control(0x3cf,0x32,value);
2327 break;
2328 case CLGD543x_MMIO_BLTMODEEXT:
2329 svga_write_control(0x3cf,0x33,value);
2330 break;
2331 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+0):
2332 svga_write_control(0x3cf,0x34,value);
2333 break;
2334 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+1):
2335 svga_write_control(0x3cf,0x35,value);
2336 break;
2337 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+2):
2338 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2339 break;
2340 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+3):
2341 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2342 break;
2343 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+0):
2344 svga_write_control(0x3cf,0x38,value);
2345 break;
2346 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+1):
2347 svga_write_control(0x3cf,0x39,value);
2348 break;
2349 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+2):
2350 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2351 break;
2352 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+3):
2353 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2354 break;
2355 case CLGD543x_MMIO_BLTSTATUS:
2356 svga_write_control(0x3cf,0x31,value);
2357 break;
2358 default:
2359 BX_ERROR(("MMIO blt write - address 0x%04x, value 0x%02x",address,value));
2360 break;
2361 }
2362 }
2363
2364
2365 /////////////////////////////////////////////////////////////////////////
2366 //
2367 // PCI support
2368 //
2369 /////////////////////////////////////////////////////////////////////////
2370
2371 #if BX_SUPPORT_PCI
2372
2373 void bx_svga_cirrus_c::svga_init_pcihandlers(void)
2374 {
2375 Bit8u devfunc = 0x00;
2376 DEV_register_pci_handlers(BX_CIRRUS_THIS_PTR,
2377 &devfunc, "cirrus", "SVGA Cirrus PCI");
2378
2379 // initialize readonly registers
2380 BX_CIRRUS_THIS init_pci_conf(PCI_VENDOR_CIRRUS, PCI_DEVICE_CLGD5446, 0x00,
2381 (PCI_CLASS_BASE_DISPLAY << 16) | (PCI_CLASS_SUB_VGA << 8),
2382 PCI_CLASS_HEADERTYPE_00h);
2383 BX_CIRRUS_THIS pci_conf[0x04] = (PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS);
2384
2385 BX_CIRRUS_THIS pci_conf[0x10] =
2386 (PCI_MAP_MEM | PCI_MAP_MEMFLAGS_32BIT | PCI_MAP_MEMFLAGS_CACHEABLE);
2387 BX_CIRRUS_THIS pci_conf[0x14] =
2388 (PCI_MAP_MEM | PCI_MAP_MEMFLAGS_32BIT);
2389
2390 BX_CIRRUS_THIS pci_base_address[0] = 0;
2391 BX_CIRRUS_THIS pci_base_address[1] = 0;
2392 BX_CIRRUS_THIS pci_rom_address = 0;
2393 BX_CIRRUS_THIS load_pci_rom(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr());
2394 }
2395
2396 Bit32u bx_svga_cirrus_c::pci_read_handler(Bit8u address, unsigned io_len)
2397 {
2398 Bit32u ret = 0;
2399 for (unsigned i = 0; i < io_len; i++) {
2400 ret |= (Bit32u)(BX_CIRRUS_THIS pci_conf[address + i]) << (i*8);
2401 }
2402
2403 BX_DEBUG(("pci_read: address 0x%02x, io_len 0x%02x, value 0x%x",
2404 (unsigned)address, (unsigned)io_len, (unsigned)ret));
2405
2406 return ret;
2407 }
2408
2409 void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
2410 {
2411 unsigned i;
2412 unsigned write_addr;
2413 Bit8u new_value, old_value;
2414 bx_bool baseaddr0_change = 0;
2415 bx_bool baseaddr1_change = 0;
2416 bx_bool romaddr_change = 0;
2417
2418 BX_DEBUG(("pci_write: address 0x%02x, io_len 0x%02x, value 0x%x",
2419 (unsigned)address, (unsigned)io_len, (unsigned)value));
2420
2421 if ((address > 0x17) && (address < 0x30))
2422 return;
2423
2424 if (address == 0x30) {
2425 value = value & 0xfffffc01;
2426 romaddr_change = 1;
2427 }
2428
2429 for (i = 0; i < io_len; i++) {
2430 write_addr = address + i;
2431 old_value = BX_CIRRUS_THIS pci_conf[write_addr];
2432 new_value = (Bit8u)(value & 0xff);
2433 switch (write_addr) {
2434 case 0x04: // command bit0-7
2435 new_value &= PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
2436 new_value |= old_value & ~(PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS);
2437 break;
2438 case 0x05: // command bit8-15
2439 new_value = old_value;
2440 break;
2441 case 0x06: // status bit0-7
2442 new_value = old_value & (~new_value);
2443 break;
2444 case 0x07: // status bit8-15
2445 new_value = old_value & (~new_value);
2446 break;
2447 case 0x10: // base address #0
2448 new_value = (new_value & 0xf0) | (old_value & 0x0f);
2449 case 0x11: case 0x12: case 0x13:
2450 baseaddr0_change |= (old_value != new_value);
2451 break;
2452 case 0x14: // base address #1
2453 new_value = (new_value & 0xf0) | (old_value & 0x0f);
2454 case 0x15: case 0x16: case 0x17:
2455 baseaddr1_change |= (old_value != new_value);
2456 break;
2457
2458 // read-only.
2459 case 0x00: case 0x01: // vendor
2460 case 0x02: case 0x03: // device
2461 case 0x08: // revision
2462 case 0x09: case 0x0a: case 0x0b: // class
2463 case 0x0e: // header type
2464 case 0x0f: // built-in self test(unimplemented)
2465 new_value = old_value;
2466 break;
2467 default:
2468 break;
2469 }
2470 BX_CIRRUS_THIS pci_conf[write_addr] = new_value;
2471 value >>= 8;
2472 }
2473 if (baseaddr0_change) {
2474 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
2475 cirrus_mem_write_handler,
2476 &BX_CIRRUS_THIS pci_base_address[0],
2477 &BX_CIRRUS_THIS pci_conf[0x10],
2478 0x2000000)) {
2479 BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_base_address[0]));
2480 }
2481 }
2482 if (baseaddr1_change) {
2483 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
2484 cirrus_mem_write_handler,
2485 &BX_CIRRUS_THIS pci_base_address[1],
2486 &BX_CIRRUS_THIS pci_conf[0x14],
2487 CIRRUS_PNPMMIO_SIZE)) {
2488 BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_base_address[1]));
2489 }
2490 }
2491 if (romaddr_change) {
2492 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
2493 cirrus_mem_write_handler,
2494 &BX_CIRRUS_THIS pci_rom_address,
2495 &BX_CIRRUS_THIS pci_conf[0x30],
2496 BX_CIRRUS_THIS pci_rom_size)) {
2497 BX_INFO(("new ROM address: 0x%08x", BX_CIRRUS_THIS pci_rom_address));
2498 }
2499 }
2500 }
2501
2502 #endif // BX_SUPPORT_PCI
2503
2504 /////////////////////////////////////////////////////////////////////////
2505 //
2506 // Bitblt.
2507 //
2508 /////////////////////////////////////////////////////////////////////////
2509
2510 void bx_svga_cirrus_c::svga_reset_bitblt(void)
2511 {
2512 BX_CIRRUS_THIS control.reg[0x31] &= ~(CIRRUS_BLT_START|CIRRUS_BLT_BUSY|CIRRUS_BLT_FIFOUSED);
2513 BX_CIRRUS_THIS bitblt.rop_handler = NULL;
2514 BX_CIRRUS_THIS bitblt.src = NULL;
2515 BX_CIRRUS_THIS bitblt.dst = NULL;
2516 BX_CIRRUS_THIS bitblt.memsrc_ptr = NULL;
2517 BX_CIRRUS_THIS bitblt.memsrc_endptr = NULL;
2518 BX_CIRRUS_THIS bitblt.memsrc_needed = 0;
2519 BX_CIRRUS_THIS bitblt.memdst_ptr = NULL;
2520 BX_CIRRUS_THIS bitblt.memdst_endptr = NULL;
2521 BX_CIRRUS_THIS bitblt.memdst_needed = 0;
2522 }
2523
2524 void bx_svga_cirrus_c::svga_bitblt()
2525 {
2526 Bit16u tmp16;
2527 Bit32u tmp32;
2528 Bit32u dstaddr;
2529 Bit32u srcaddr;
2530 Bit32u offset;
2531 Bit8u *cregs = BX_CIRRUS_THIS control.reg;
2532
2533 ReadHostWordFromLittleEndian(&cregs[0x20], tmp16);
2534 BX_CIRRUS_THIS bitblt.bltwidth = ((int)(tmp16 & 0x1fff)) + 1;
2535 ReadHostWordFromLittleEndian(&cregs[0x22], tmp16);
2536 BX_CIRRUS_THIS bitblt.bltheight = ((int)(tmp16 & 0x07ff)) + 1;
2537 ReadHostWordFromLittleEndian(&cregs[0x24], tmp16);
2538 BX_CIRRUS_THIS bitblt.dstpitch = (int)(tmp16 & 0x1fff);
2539 ReadHostWordFromLittleEndian(&cregs[0x26], tmp16);
2540 BX_CIRRUS_THIS bitblt.srcpitch = (int)(tmp16 & 0x1fff);
2541 ReadHostDWordFromLittleEndian(&cregs[0x28], tmp32);
2542 dstaddr = tmp32 & BX_CIRRUS_THIS memsize_mask;
2543 ReadHostDWordFromLittleEndian(&cregs[0x2c], tmp32);
2544 srcaddr = tmp32 & BX_CIRRUS_THIS memsize_mask;
2545 BX_CIRRUS_THIS bitblt.srcaddr = srcaddr;
2546 BX_CIRRUS_THIS bitblt.bltmode = BX_CIRRUS_THIS control.reg[0x30];
2547 BX_CIRRUS_THIS bitblt.bltmodeext = BX_CIRRUS_THIS control.reg[0x33];
2548 BX_CIRRUS_THIS bitblt.bltrop = BX_CIRRUS_THIS control.reg[0x32];
2549 offset = dstaddr - (BX_CIRRUS_THIS disp_ptr - BX_CIRRUS_THIS s.memory);
2550 BX_CIRRUS_THIS redraw.x = (offset % BX_CIRRUS_THIS bitblt.dstpitch) / (BX_CIRRUS_THIS svga_bpp >> 3);
2551 BX_CIRRUS_THIS redraw.y = offset / BX_CIRRUS_THIS bitblt.dstpitch;
2552 BX_CIRRUS_THIS redraw.w = BX_CIRRUS_THIS bitblt.bltwidth / (BX_CIRRUS_THIS svga_bpp >> 3);
2553 BX_CIRRUS_THIS redraw.h = BX_CIRRUS_THIS bitblt.bltheight;
2554
2555 BX_DEBUG(("BLT: src:0x%08x,dst 0x%08x,block %ux%u,mode 0x%02x,ROP 0x%02x",
2556 (unsigned)srcaddr,(unsigned)dstaddr,
2557 (unsigned)BX_CIRRUS_THIS bitblt.bltwidth,(unsigned)BX_CIRRUS_THIS bitblt.bltheight,
2558 (unsigned)BX_CIRRUS_THIS bitblt.bltmode,(unsigned)BX_CIRRUS_THIS bitblt.bltrop));
2559 BX_DEBUG(("BLT: srcpitch:0x%08x,dstpitch 0x%08x,modeext 0x%02x,writemask 0x%02x",
2560 (unsigned)BX_CIRRUS_THIS bitblt.srcpitch,
2561 (unsigned)BX_CIRRUS_THIS bitblt.dstpitch,
2562 (unsigned)BX_CIRRUS_THIS bitblt.bltmodeext,
2563 BX_CIRRUS_THIS control.reg[0x2f]));
2564
2565 switch (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
2566 case CIRRUS_BLTMODE_PIXELWIDTH8:
2567 BX_CIRRUS_THIS bitblt.pixelwidth = 1;
2568 break;
2569 case CIRRUS_BLTMODE_PIXELWIDTH16:
2570 BX_CIRRUS_THIS bitblt.pixelwidth = 2;
2571 break;
2572 case CIRRUS_BLTMODE_PIXELWIDTH24:
2573 BX_CIRRUS_THIS bitblt.pixelwidth = 3;
2574 break;
2575 case CIRRUS_BLTMODE_PIXELWIDTH32:
2576 BX_CIRRUS_THIS bitblt.pixelwidth = 4;
2577 break;
2578 default:
2579 BX_PANIC(("unknown pixel width"));
2580 goto ignoreblt;
2581 }
2582
2583 BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
2584
2585 if ((BX_CIRRUS_THIS bitblt.bltmode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_MEMSYSDEST))
2586 == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_MEMSYSDEST)) {
2587 BX_ERROR(("BLT: memory-to-memory copy is requested, ROP %02x",
2588 (unsigned)BX_CIRRUS_THIS bitblt.bltrop));
2589 goto ignoreblt;
2590 }
2591
2592 if ((BX_CIRRUS_THIS bitblt.bltmodeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
2593 (BX_CIRRUS_THIS bitblt.bltmode & (CIRRUS_BLTMODE_MEMSYSDEST |
2594 CIRRUS_BLTMODE_TRANSPARENTCOMP |
2595 CIRRUS_BLTMODE_PATTERNCOPY |
2596 CIRRUS_BLTMODE_COLOREXPAND)) ==
2597 (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
2598 BX_CIRRUS_THIS bitblt.rop_handler = svga_get_fwd_rop_handler(BX_CIRRUS_THIS bitblt.bltrop);
2599 BX_CIRRUS_THIS bitblt.dst = BX_CIRRUS_THIS s.memory + dstaddr;
2600 svga_solidfill();
2601 } else {
2602
2603 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_BACKWARDS) {
2604 BX_CIRRUS_THIS bitblt.dstpitch = -BX_CIRRUS_THIS bitblt.dstpitch;
2605 BX_CIRRUS_THIS bitblt.srcpitch = -BX_CIRRUS_THIS bitblt.srcpitch;
2606 BX_CIRRUS_THIS bitblt.rop_handler = svga_get_bkwd_rop_handler(BX_CIRRUS_THIS bitblt.bltrop);
2607 BX_CIRRUS_THIS redraw.x -= BX_CIRRUS_THIS redraw.w;
2608 BX_CIRRUS_THIS redraw.y -= BX_CIRRUS_THIS redraw.h;
2609 } else {
2610 BX_CIRRUS_THIS bitblt.rop_handler = svga_get_fwd_rop_handler(BX_CIRRUS_THIS bitblt.bltrop);
2611 }
2612
2613 BX_DEBUG(("BLT redraw: x = %d, y = %d, w = %d, h = %d", BX_CIRRUS_THIS redraw.x,
2614 BX_CIRRUS_THIS redraw.y, BX_CIRRUS_THIS redraw.w, BX_CIRRUS_THIS redraw.h));
2615
2616 // setup bitblt engine.
2617 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_MEMSYSSRC) {
2618 svga_setup_bitblt_cputovideo(dstaddr,srcaddr);
2619 }
2620 else if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_MEMSYSDEST) {
2621 svga_setup_bitblt_videotocpu(dstaddr,srcaddr);
2622 }
2623 else {
2624 svga_setup_bitblt_videotovideo(dstaddr,srcaddr);
2625 }
2626 return;
2627 }
2628
2629 ignoreblt:
2630 svga_reset_bitblt();
2631 }
2632
2633 void bx_svga_cirrus_c::svga_setup_bitblt_cputovideo(Bit32u dstaddr,Bit32u srcaddr)
2634 {
2635 Bit16u w;
2636
2637 BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
2638
2639 BX_CIRRUS_THIS bitblt.dst = BX_CIRRUS_THIS s.memory + dstaddr;
2640 BX_CIRRUS_THIS bitblt.src = NULL;
2641
2642 BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
2643 BX_CIRRUS_THIS bitblt.memsrc_endptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
2644
2645 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
2646 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
2647 BX_CIRRUS_THIS bitblt.srcpitch = 8;
2648 } else {
2649 BX_CIRRUS_THIS bitblt.srcpitch = 8 * 8 * BX_CIRRUS_THIS bitblt.pixelwidth;
2650 }
2651 BX_CIRRUS_THIS bitblt.memsrc_needed = BX_CIRRUS_THIS bitblt.srcpitch;
2652 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_memsrc_static;
2653 } else {
2654 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
2655 w = BX_CIRRUS_THIS bitblt.bltwidth / BX_CIRRUS_THIS bitblt.pixelwidth;
2656 if (BX_CIRRUS_THIS bitblt.bltmodeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) {
2657 BX_CIRRUS_THIS bitblt.srcpitch = (w + 31) >> 5;
2658 } else {
2659 BX_CIRRUS_THIS bitblt.srcpitch = (w + 7) >> 3;
2660 }
2661 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
2662 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_colorexpand_transp_memsrc_static;
2663 } else {
2664 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_memsrc_static;
2665 }
2666 } else {
2667 BX_CIRRUS_THIS bitblt.srcpitch = (BX_CIRRUS_THIS bitblt.bltwidth + 3) & (~3);
2668 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_memsrc_static;
2669 }
2670 BX_CIRRUS_THIS bitblt.memsrc_needed =
2671 BX_CIRRUS_THIS bitblt.srcpitch * BX_CIRRUS_THIS bitblt.bltheight;
2672 }
2673 BX_CIRRUS_THIS bitblt.memsrc_endptr += BX_CIRRUS_THIS bitblt.srcpitch;
2674 }
2675
2676 void bx_svga_cirrus_c::svga_setup_bitblt_videotocpu(Bit32u dstaddr,Bit32u srcaddr)
2677 {
2678 BX_ERROR(("BLT: MEMSYSDEST is not implemented"));
2679
2680 BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_MEMSYSDEST;
2681
2682 #if 0
2683 BX_CIRRUS_THIS bitblt.dst = NULL;
2684 BX_CIRRUS_THIS bitblt.src = BX_CIRRUS_THIS s.memory + srcaddr;
2685
2686 BX_CIRRUS_THIS bitblt.memdst_ptr = &BX_CIRRUS_THIS bitblt.memdst[0];
2687 BX_CIRRUS_THIS bitblt.memdst_endptr = &BX_CIRRUS_THIS bitblt.memdst[0];
2688
2689 BX_CIRRUS_THIS bitblt.memdst_needed =
2690 BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.bltheight;
2691 BX_CIRRUS_THIS bitblt.memdst_needed = (BX_CIRRUS_THIS bitblt.memdst_needed + 3) & (~3);
2692
2693 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
2694 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_memdst_static;
2695 }
2696 else {
2697 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_memdst_static;
2698 }
2699 #endif
2700 }
2701
2702 void bx_svga_cirrus_c::svga_setup_bitblt_videotovideo(Bit32u dstaddr,Bit32u srcaddr)
2703 {
2704 BX_CIRRUS_THIS bitblt.dst = BX_CIRRUS_THIS s.memory + dstaddr;
2705
2706 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
2707 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_static;
2708 BX_CIRRUS_THIS bitblt.src = BX_CIRRUS_THIS s.memory + (srcaddr & ~0x07);
2709 } else {
2710 BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_static;
2711 BX_CIRRUS_THIS bitblt.src = BX_CIRRUS_THIS s.memory + srcaddr;
2712 }
2713
2714 (*BX_CIRRUS_THIS bitblt.bitblt_ptr)();
2715 svga_reset_bitblt();
2716 BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS redraw.x, BX_CIRRUS_THIS redraw.y,
2717 BX_CIRRUS_THIS redraw.w, BX_CIRRUS_THIS redraw.h);
2718 }
2719
2720 void bx_svga_cirrus_c::svga_colorexpand(Bit8u *dst,const Bit8u *src,int count,int pixelwidth)
2721 {
2722 BX_DEBUG(("svga_cirrus: COLOR EXPAND"));
2723
2724 switch (pixelwidth) {
2725 case 1:
2726 svga_colorexpand_8(dst,src,count);
2727 break;
2728 case 2:
2729 svga_colorexpand_16(dst,src,count);
2730 break;
2731 case 3:
2732 svga_colorexpand_24(dst,src,count);
2733 break;
2734 case 4:
2735 svga_colorexpand_32(dst,src,count);
2736 break;
2737 default:
2738 BX_PANIC(("COLOREXPAND: unknown pixelwidth %u",(unsigned)pixelwidth));
2739 break;
2740 }
2741 }
2742
2743 #if !BX_USE_CIRRUS_SMF
2744 void bx_svga_cirrus_c::svga_colorexpand_8_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
2745 {
2746 ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_8(dst,src,count);
2747 }
2748
2749 void bx_svga_cirrus_c::svga_colorexpand_16_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
2750 {
2751 ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_16(dst,src,count);
2752 }
2753
2754 void bx_svga_cirrus_c::svga_colorexpand_24_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
2755 {
2756 ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_24(dst,src,count);
2757 }
2758
2759 void bx_svga_cirrus_c::svga_colorexpand_32_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
2760 {
2761 ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_32(dst,src,count);
2762 }
2763
2764 #endif // BX_USE_CIRRUS_SMF
2765
2766 void bx_svga_cirrus_c::svga_colorexpand_8(Bit8u *dst,const Bit8u *src,int count)
2767 {
2768 Bit8u colors[2];
2769 unsigned bits;
2770 unsigned bitmask;
2771
2772 colors[0] = BX_CIRRUS_THIS control.shadow_reg0;
2773 colors[1] = BX_CIRRUS_THIS control.shadow_reg1;
2774
2775 bitmask = 0x80;
2776 bits = *src++;
2777 for (int x = 0; x < count; x++) {
2778 if ((bitmask & 0xff) == 0) {
2779 bitmask = 0x80;
2780 bits = *src++;
2781 }
2782 *dst++ = colors[!!(bits & bitmask)];
2783 bitmask >>= 1;
2784 }
2785 }
2786
2787 void bx_svga_cirrus_c::svga_colorexpand_16(Bit8u *dst,const Bit8u *src,int count)
2788 {
2789 Bit8u colors[2][2];
2790 unsigned bits;
2791 unsigned bitmask;
2792 unsigned index;
2793
2794 colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
2795 colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
2796 colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
2797 colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
2798
2799 bitmask = 0x80;
2800 bits = *src++;
2801 for (int x = 0; x < count; x++) {
2802 if ((bitmask & 0xff) == 0) {
2803 bitmask = 0x80;
2804 bits = *src++;
2805 }
2806 index = !!(bits & bitmask);
2807 *dst++ = colors[index][0];
2808 *dst++ = colors[index][1];
2809 bitmask >>= 1;
2810 }
2811 }
2812
2813 void bx_svga_cirrus_c::svga_colorexpand_24(Bit8u *dst,const Bit8u *src,int count)
2814 {
2815 Bit8u colors[2][3];
2816 unsigned bits;
2817 unsigned bitmask;
2818 unsigned index;
2819
2820 colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
2821 colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
2822 colors[0][2] = BX_CIRRUS_THIS control.reg[0x12];
2823 colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
2824 colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
2825 colors[1][2] = BX_CIRRUS_THIS control.reg[0x13];
2826
2827 bitmask = 0x80;
2828 bits = *src++;
2829 for (int x = 0; x < count; x++) {
2830 if ((bitmask & 0xff) == 0) {
2831 bitmask = 0x80;
2832 bits = *src++;
2833 }
2834 index = !!(bits & bitmask);
2835 *dst++ = colors[index][0];
2836 *dst++ = colors[index][1];
2837 *dst++ = colors[index][2];
2838 bitmask >>= 1;
2839 }
2840 }
2841
2842 void bx_svga_cirrus_c::svga_colorexpand_32(Bit8u *dst,const Bit8u *src,int count)
2843 {
2844 Bit8u colors[2][4];
2845 unsigned bits;
2846 unsigned bitmask;
2847 unsigned index;
2848
2849 colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
2850 colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
2851 colors[0][2] = BX_CIRRUS_THIS control.reg[0x12];
2852 colors[0][3] = BX_CIRRUS_THIS control.reg[0x14];
2853 colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
2854 colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
2855 colors[1][2] = BX_CIRRUS_THIS control.reg[0x13];
2856 colors[1][3] = BX_CIRRUS_THIS control.reg[0x15];
2857
2858 bitmask = 0x80;
2859 bits = *src++;
2860 for (int x = 0; x < count; x++) {
2861 if ((bitmask & 0xff) == 0) {
2862 bitmask = 0x80;
2863 bits = *src++;
2864 }
2865 index = !!(bits & bitmask);
2866 *dst++ = colors[index][0];
2867 *dst++ = colors[index][1];
2868 *dst++ = colors[index][2];
2869 *dst++ = colors[index][3];
2870 bitmask >>= 1;
2871 }
2872 }
2873
2874 #if !BX_USE_CIRRUS_SMF
2875 void bx_svga_cirrus_c::svga_patterncopy_static(void *this_ptr)
2876 {
2877 ((bx_svga_cirrus_c *)this_ptr)->svga_patterncopy();
2878 }
2879
2880 void bx_svga_cirrus_c::svga_simplebitblt_static(void *this_ptr)
2881 {
2882 ((bx_svga_cirrus_c *)this_ptr)->svga_simplebitblt();
2883 }
2884
2885 void bx_svga_cirrus_c::svga_solidfill_static(void *this_ptr)
2886 {
2887 ((bx_svga_cirrus_c *)this_ptr)->svga_solidfill();
2888 }
2889
2890 void bx_svga_cirrus_c::svga_patterncopy_memsrc_static(void *this_ptr)
2891 {
2892 ((bx_svga_cirrus_c *)this_ptr)->svga_patterncopy_memsrc();
2893 }
2894
2895 void bx_svga_cirrus_c::svga_simplebitblt_memsrc_static(void *this_ptr)
2896 {
2897 ((bx_svga_cirrus_c *)this_ptr)->svga_simplebitblt_memsrc();
2898 }
2899
2900 void bx_svga_cirrus_c::svga_colorexpand_transp_memsrc_static(void *this_ptr)
2901 {
2902 ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_transp_memsrc();
2903 }
2904
2905 #endif // !BX_USE_CIRRUS_SMF
2906
2907 void bx_svga_cirrus_c::svga_patterncopy()
2908 {
2909 Bit8u color[4];
2910 Bit8u work_colorexp[256];
2911 Bit8u *src, *dst;
2912 Bit8u *dstc, *srcc, *src2;
2913 int x, y, pattern_x, pattern_y, srcskipleft;
2914 int patternbytes = 8 * BX_CIRRUS_THIS bitblt.pixelwidth;
2915 int pattern_pitch = patternbytes;
2916 int bltbytes = BX_CIRRUS_THIS bitblt.bltwidth;
2917 unsigned bits, bits_xor, bitmask;
2918
2919 if (BX_CIRRUS_THIS bitblt.pixelwidth == 3) {
2920 pattern_x = BX_CIRRUS_THIS control.reg[0x2f] & 0x1f;
2921 srcskipleft = pattern_x / 3;
2922 } else {
2923 srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
2924 pattern_x = srcskipleft * BX_CIRRUS_THIS bitblt.pixelwidth;
2925 }
2926 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
2927 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
2928 color[0] = BX_CIRRUS_THIS control.shadow_reg1;
2929 color[1] = BX_CIRRUS_THIS control.reg[0x11];
2930 color[2] = BX_CIRRUS_THIS control.reg[0x13];
2931 color[3] = BX_CIRRUS_THIS control.reg[0x15];
2932 if (BX_CIRRUS_THIS bitblt.bltmodeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
2933 bits_xor = 0xff;
2934 } else {
2935 bits_xor = 0x00;
2936 }
2937
2938 pattern_y = BX_CIRRUS_THIS bitblt.srcaddr & 0x07;
2939 for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
2940 dst = BX_CIRRUS_THIS bitblt.dst + pattern_x;
2941 bitmask = 0x80 >> srcskipleft;
2942 bits = BX_CIRRUS_THIS bitblt.src[pattern_y] ^ bits_xor;
2943 for (x = pattern_x; x < BX_CIRRUS_THIS bitblt.bltwidth; x+=BX_CIRRUS_THIS bitblt.pixelwidth) {
2944 if ((bitmask & 0xff) == 0) {
2945 bitmask = 0x80;
2946 bits = BX_CIRRUS_THIS bitblt.src[pattern_y] ^ bits_xor;
2947 }
2948 if (bits & bitmask) {
2949 (*BX_CIRRUS_THIS bitblt.rop_handler)(
2950 dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
2951 }
2952 dst += BX_CIRRUS_THIS bitblt.pixelwidth;
2953 bitmask >>= 1;
2954 }
2955 pattern_y = (pattern_y + 1) & 7;
2956 BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
2957 }
2958 return;
2959 } else {
2960 svga_colorexpand(work_colorexp,BX_CIRRUS_THIS bitblt.src,8*8,BX_CIRRUS_THIS bitblt.pixelwidth);
2961 BX_CIRRUS_THIS bitblt.src = work_colorexp;
2962 BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_COLOREXPAND;
2963 }
2964 } else {
2965 if (BX_CIRRUS_THIS bitblt.pixelwidth == 3) {
2966 pattern_pitch = 32;
2967 }
2968 }
2969 if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_PATTERNCOPY) {
2970 BX_ERROR(("PATTERNCOPY: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
2971 return;
2972 }
2973
2974 BX_DEBUG(("svga_cirrus: PATTERN COPY"));
2975 dst = BX_CIRRUS_THIS bitblt.dst;
2976 pattern_y = BX_CIRRUS_THIS bitblt.srcaddr & 0x07;
2977 src = (Bit8u *)BX_CIRRUS_THIS bitblt.src;
2978 for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
2979 srcc = src + pattern_y * pattern_pitch;
2980 dstc = dst + pattern_x;
2981 for (x = pattern_x; x < bltbytes; x += BX_CIRRUS_THIS bitblt.pixelwidth) {
2982 src2 = srcc + (x % patternbytes);
2983 (*BX_CIRRUS_THIS bitblt.rop_handler)(
2984 dstc, src2, 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
2985 dstc += BX_CIRRUS_THIS bitblt.pixelwidth;
2986 }
2987 pattern_y = (pattern_y + 1) & 7;
2988 dst += BX_CIRRUS_THIS bitblt.dstpitch;
2989 }
2990 }
2991
2992 void bx_svga_cirrus_c::svga_simplebitblt()
2993 {
2994 Bit8u color[4];
2995 Bit8u work_colorexp[2048];
2996 Bit16u w, x, y;
2997 Bit8u *dst;
2998 unsigned bits, bits_xor, bitmask;
2999 int pattern_x, srcskipleft;
3000
3001 if (BX_CIRRUS_THIS bitblt.pixelwidth == 3) {
3002 pattern_x = BX_CIRRUS_THIS control.reg[0x2f] & 0x1f;
3003 srcskipleft = pattern_x / 3;
3004 } else {
3005 srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
3006 pattern_x = srcskipleft * BX_CIRRUS_THIS bitblt.pixelwidth;
3007 }
3008 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
3009 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
3010 color[0] = BX_CIRRUS_THIS control.shadow_reg1;
3011 color[1] = BX_CIRRUS_THIS control.reg[0x11];
3012 color[2] = BX_CIRRUS_THIS control.reg[0x13];
3013 color[3] = BX_CIRRUS_THIS control.reg[0x15];
3014 if (BX_CIRRUS_THIS bitblt.bltmodeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
3015 bits_xor = 0xff;
3016 } else {
3017 bits_xor = 0x00;
3018 }
3019
3020 for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
3021 dst = BX_CIRRUS_THIS bitblt.dst + pattern_x;
3022 bitmask = 0x80 >> srcskipleft;
3023 bits = *BX_CIRRUS_THIS bitblt.src++ ^ bits_xor;
3024 for (x = pattern_x; x < BX_CIRRUS_THIS bitblt.bltwidth; x+=BX_CIRRUS_THIS bitblt.pixelwidth) {
3025 if ((bitmask & 0xff) == 0) {
3026 bitmask = 0x80;
3027 bits = *BX_CIRRUS_THIS bitblt.src++ ^ bits_xor;
3028 }
3029 if (bits & bitmask) {
3030 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3031 dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
3032 }
3033 dst += BX_CIRRUS_THIS bitblt.pixelwidth;
3034 bitmask >>= 1;
3035 }
3036 BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
3037 }
3038 return;
3039 } else {
3040 w = BX_CIRRUS_THIS bitblt.bltwidth / BX_CIRRUS_THIS bitblt.pixelwidth;
3041 for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
3042 svga_colorexpand(work_colorexp,BX_CIRRUS_THIS bitblt.src, w,
3043 BX_CIRRUS_THIS bitblt.pixelwidth);
3044 dst = BX_CIRRUS_THIS bitblt.dst + pattern_x;
3045 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3046 dst, work_colorexp + pattern_x, 0, 0,
3047 BX_CIRRUS_THIS bitblt.bltwidth - pattern_x, 1);
3048 BX_CIRRUS_THIS bitblt.src += ((w + 7) >> 3);
3049 BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
3050 }
3051 return;
3052 }
3053 }
3054 if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_BACKWARDS) {
3055 BX_ERROR(("SIMPLE BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
3056 return;
3057 }
3058
3059 BX_DEBUG(("svga_cirrus: BITBLT"));
3060 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3061 BX_CIRRUS_THIS bitblt.dst, BX_CIRRUS_THIS bitblt.src,
3062 BX_CIRRUS_THIS bitblt.dstpitch, BX_CIRRUS_THIS bitblt.srcpitch,
3063 BX_CIRRUS_THIS bitblt.bltwidth, BX_CIRRUS_THIS bitblt.bltheight);
3064 }
3065
3066 void bx_svga_cirrus_c::svga_solidfill()
3067 {
3068 Bit8u color[4];
3069 int x, y;
3070 Bit8u *dst;
3071
3072 BX_DEBUG(("BLT: SOLIDFILL"));
3073
3074 color[0] = BX_CIRRUS_THIS control.shadow_reg1;
3075 color[1] = BX_CIRRUS_THIS control.reg[0x11];
3076 color[2] = BX_CIRRUS_THIS control.reg[0x13];
3077 color[3] = BX_CIRRUS_THIS control.reg[0x15];
3078
3079 for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
3080 dst = BX_CIRRUS_THIS bitblt.dst;
3081 for (x = 0; x < BX_CIRRUS_THIS bitblt.bltwidth; x+=BX_CIRRUS_THIS bitblt.pixelwidth) {
3082 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3083 dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
3084 dst += BX_CIRRUS_THIS bitblt.pixelwidth;
3085 }
3086 BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
3087 }
3088 BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS redraw.x, BX_CIRRUS_THIS redraw.y,
3089 BX_CIRRUS_THIS redraw.w, BX_CIRRUS_THIS redraw.h);
3090 }
3091
3092 void bx_svga_cirrus_c::svga_patterncopy_memsrc()
3093 {
3094 BX_INFO(("svga_patterncopy_memsrc() - not tested"));
3095
3096 BX_CIRRUS_THIS bitblt.src = &BX_CIRRUS_THIS bitblt.memsrc[0];
3097 svga_patterncopy();
3098 BX_CIRRUS_THIS bitblt.memsrc_needed = 0;
3099 BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS redraw.x, BX_CIRRUS_THIS redraw.y,
3100 BX_CIRRUS_THIS redraw.w, BX_CIRRUS_THIS redraw.h);
3101 }
3102
3103 void bx_svga_cirrus_c::svga_simplebitblt_memsrc()
3104 {
3105 Bit8u *srcptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
3106 Bit8u work_colorexp[2048];
3107 Bit16u w;
3108 int pattern_x;
3109
3110 BX_DEBUG(("svga_cirrus: BLT, cpu-to-video"));
3111
3112 if (BX_CIRRUS_THIS bitblt.pixelwidth == 3) {
3113 pattern_x = BX_CIRRUS_THIS control.reg[0x2f] & 0x1f;
3114 } else {
3115 pattern_x = (BX_CIRRUS_THIS control.reg[0x2f] & 0x07) * BX_CIRRUS_THIS bitblt.pixelwidth;
3116 }
3117 if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
3118 if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_COLOREXPAND) {
3119 BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
3120 return;
3121 }
3122
3123 w = BX_CIRRUS_THIS bitblt.bltwidth / BX_CIRRUS_THIS bitblt.pixelwidth;
3124 svga_colorexpand(work_colorexp,srcptr,w,BX_CIRRUS_THIS bitblt.pixelwidth);
3125 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3126 BX_CIRRUS_THIS bitblt.dst + pattern_x, work_colorexp + pattern_x, 0, 0,
3127 BX_CIRRUS_THIS bitblt.bltwidth - pattern_x, 1);
3128 } else {
3129 if (BX_CIRRUS_THIS bitblt.bltmode != 0) {
3130 BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
3131 return;
3132 }
3133 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3134 BX_CIRRUS_THIS bitblt.dst, srcptr, 0, 0,
3135 BX_CIRRUS_THIS bitblt.bltwidth, 1);
3136 }
3137 }
3138
3139 void bx_svga_cirrus_c::svga_colorexpand_transp_memsrc()
3140 {
3141 Bit8u *src = &BX_CIRRUS_THIS bitblt.memsrc[0];
3142 Bit8u color[4];
3143 int x, pattern_x, srcskipleft;
3144 Bit8u *dst;
3145 unsigned bits, bits_xor, bitmask;
3146
3147 BX_DEBUG(("BLT, cpu-to-video, transparent"));
3148
3149 if (BX_CIRRUS_THIS bitblt.pixelwidth == 3) {
3150 pattern_x = BX_CIRRUS_THIS control.reg[0x2f] & 0x1f;
3151 srcskipleft = pattern_x / 3;
3152 } else {
3153 srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
3154 pattern_x = srcskipleft * BX_CIRRUS_THIS bitblt.pixelwidth;
3155 }
3156 color[0] = BX_CIRRUS_THIS control.shadow_reg1;
3157 color[1] = BX_CIRRUS_THIS control.reg[0x11];
3158 color[2] = BX_CIRRUS_THIS control.reg[0x13];
3159 color[3] = BX_CIRRUS_THIS control.reg[0x15];
3160 if (BX_CIRRUS_THIS bitblt.bltmodeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
3161 bits_xor = 0xff;
3162 } else {
3163 bits_xor = 0x00;
3164 }
3165
3166 dst = BX_CIRRUS_THIS bitblt.dst + pattern_x;
3167 bitmask = 0x80 >> srcskipleft;
3168 bits = *src++ ^ bits_xor;
3169 for (x = pattern_x; x < BX_CIRRUS_THIS bitblt.bltwidth; x+=BX_CIRRUS_THIS bitblt.pixelwidth) {
3170 if ((bitmask & 0xff) == 0) {
3171 bitmask = 0x80;
3172 bits = *src++ ^ bits_xor;
3173 }
3174 if (bits & bitmask) {
3175 (*BX_CIRRUS_THIS bitblt.rop_handler)(
3176 dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
3177 }
3178 dst += BX_CIRRUS_THIS bitblt.pixelwidth;
3179 bitmask >>= 1;
3180 }
3181 }
3182
3183 bx_bool // 1 if finished, 0 otherwise
3184 bx_svga_cirrus_c::svga_asyncbitblt_next()
3185 {
3186 int count;
3187 int avail;
3188
3189 if (BX_CIRRUS_THIS bitblt.bitblt_ptr == NULL) {
3190 BX_PANIC(("svga_asyncbitblt_next: unexpected call"));
3191 goto cleanup;
3192 }
3193
3194 if (BX_CIRRUS_THIS bitblt.memdst_needed > 0) {
3195 BX_CIRRUS_THIS bitblt.memdst_needed -= BX_CIRRUS_THIS bitblt.memdst_ptr - &BX_CIRRUS_THIS bitblt.memdst[0];
3196 avail = BX_MIN(CIRRUS_BLT_CACHESIZE, BX_CIRRUS_THIS bitblt.memdst_needed);
3197 BX_CIRRUS_THIS bitblt.memdst_ptr = &BX_CIRRUS_THIS bitblt.memdst[0];
3198 BX_CIRRUS_THIS bitblt.memdst_endptr = &BX_CIRRUS_THIS bitblt.memdst[avail];
3199
3200 if (BX_CIRRUS_THIS bitblt.memsrc_needed <= 0 &&
3201 BX_CIRRUS_THIS bitblt.memdst_needed <= 0) {
3202 goto cleanup;
3203 }
3204 }
3205
3206 (*BX_CIRRUS_THIS bitblt.bitblt_ptr)();
3207
3208 if (BX_CIRRUS_THIS bitblt.memsrc_needed > 0) {
3209 BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
3210 BX_CIRRUS_THIS bitblt.memsrc_needed -= BX_CIRRUS_THIS bitblt.srcpitch;
3211 if (BX_CIRRUS_THIS bitblt.memsrc_needed <= 0) {
3212 BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS redraw.x, BX_CIRRUS_THIS redraw.y,
3213 BX_CIRRUS_THIS redraw.w, BX_CIRRUS_THIS redraw.h);
3214 if (BX_CIRRUS_THIS bitblt.memdst_needed <= 0) {
3215 goto cleanup;
3216 }
3217 } else {
3218 count = BX_CIRRUS_THIS bitblt.memsrc_endptr - BX_CIRRUS_THIS bitblt.memsrc_ptr;
3219 memmove(&BX_CIRRUS_THIS bitblt.memsrc[0], BX_CIRRUS_THIS bitblt.memsrc_ptr, count);
3220 BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[count];
3221 }
3222 }
3223
3224 return 0;
3225
3226 cleanup:
3227 svga_reset_bitblt();
3228 return 1;
3229 }
3230
3231 /////////////////////////////////////////////////////////////////////////
3232 //
3233 // Raster operations.
3234 //
3235 /////////////////////////////////////////////////////////////////////////
3236
3237 #define IMPLEMENT_FORWARD_BITBLT(name,opline) \
3238 static void bitblt_rop_fwd_##name( \
3239 Bit8u *dst,const Bit8u *src, \
3240 int dstpitch,int srcpitch, \
3241 int bltwidth,int bltheight) \
3242 { \
3243 int x,y; \
3244 dstpitch -= bltwidth; \
3245 srcpitch -= bltwidth; \
3246 for (y = 0; y < bltheight; y++) { \
3247 for (x = 0; x < bltwidth; x++) { \
3248 opline; \
3249 dst++; \
3250 src++; \
3251 } \
3252 dst += dstpitch; \
3253 src += srcpitch; \
3254 } \
3255 }
3256
3257 #define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
3258 static void bitblt_rop_bkwd_##name( \
3259 Bit8u *dst,const Bit8u *src, \
3260 int dstpitch,int srcpitch, \
3261 int bltwidth,int bltheight) \
3262 { \
3263 int x,y; \
3264 dstpitch += bltwidth; \
3265 srcpitch += bltwidth; \
3266 for (y = 0; y < bltheight; y++) { \
3267 for (x = 0; x < bltwidth; x++) { \
3268 opline; \
3269 dst--; \
3270 src--; \
3271 } \
3272 dst += dstpitch; \
3273 src += srcpitch; \
3274 } \
3275 }
3276
3277 IMPLEMENT_FORWARD_BITBLT(0, *dst = 0)
3278 IMPLEMENT_FORWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
3279 IMPLEMENT_FORWARD_BITBLT(nop, (void)0)
3280 IMPLEMENT_FORWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
3281 IMPLEMENT_FORWARD_BITBLT(notdst, *dst = ~(*dst))
3282 IMPLEMENT_FORWARD_BITBLT(src, *dst = *src)
3283 IMPLEMENT_FORWARD_BITBLT(1, *dst = 0xff)
3284 IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
3285 IMPLEMENT_FORWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
3286 IMPLEMENT_FORWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
3287 IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
3288 IMPLEMENT_FORWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
3289 IMPLEMENT_FORWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
3290 IMPLEMENT_FORWARD_BITBLT(notsrc, *dst = (~(*src)))
3291 IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
3292 IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
3293
3294 IMPLEMENT_BACKWARD_BITBLT(0, *dst = 0)
3295 IMPLEMENT_BACKWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
3296 IMPLEMENT_BACKWARD_BITBLT(nop, (void)0)
3297 IMPLEMENT_BACKWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
3298 IMPLEMENT_BACKWARD_BITBLT(notdst, *dst = ~(*dst))
3299 IMPLEMENT_BACKWARD_BITBLT(src, *dst = *src)
3300 IMPLEMENT_BACKWARD_BITBLT(1, *dst = 0xff)
3301 IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
3302 IMPLEMENT_BACKWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
3303 IMPLEMENT_BACKWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
3304 IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
3305 IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
3306 IMPLEMENT_BACKWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
3307 IMPLEMENT_BACKWARD_BITBLT(notsrc, *dst = (~(*src)))
3308 IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
3309 IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
3310
3311 bx_cirrus_bitblt_rop_t bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop)
3312 {
3313 bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_fwd_nop;
3314
3315 switch (rop)
3316 {
3317 case CIRRUS_ROP_0:
3318 rop_handler = bitblt_rop_fwd_0;
3319 break;
3320 case CIRRUS_ROP_SRC_AND_DST:
3321 rop_handler = bitblt_rop_fwd_src_and_dst;
3322 break;
3323 case CIRRUS_ROP_NOP:
3324 rop_handler = bitblt_rop_fwd_nop;
3325 break;
3326 case CIRRUS_ROP_SRC_AND_NOTDST:
3327 rop_handler = bitblt_rop_fwd_src_and_notdst;
3328 break;
3329 case CIRRUS_ROP_NOTDST:
3330 rop_handler = bitblt_rop_fwd_notdst;
3331 break;
3332 case CIRRUS_ROP_SRC:
3333 rop_handler = bitblt_rop_fwd_src;
3334 break;
3335 case CIRRUS_ROP_1:
3336 rop_handler = bitblt_rop_fwd_1;
3337 break;
3338 case CIRRUS_ROP_NOTSRC_AND_DST:
3339 rop_handler = bitblt_rop_fwd_notsrc_and_dst;
3340 break;
3341 case CIRRUS_ROP_SRC_XOR_DST:
3342 rop_handler = bitblt_rop_fwd_src_xor_dst;
3343 break;
3344 case CIRRUS_ROP_SRC_OR_DST:
3345 rop_handler = bitblt_rop_fwd_src_or_dst;
3346 break;
3347 case CIRRUS_ROP_NOTSRC_OR_NOTDST:
3348 rop_handler = bitblt_rop_fwd_notsrc_or_notdst;
3349 break;
3350 case CIRRUS_ROP_SRC_NOTXOR_DST:
3351 rop_handler = bitblt_rop_fwd_src_notxor_dst;
3352 break;
3353 case CIRRUS_ROP_SRC_OR_NOTDST:
3354 rop_handler = bitblt_rop_fwd_src_or_notdst;
3355 break;
3356 case CIRRUS_ROP_NOTSRC:
3357 rop_handler = bitblt_rop_fwd_notsrc;
3358 break;
3359 case CIRRUS_ROP_NOTSRC_OR_DST:
3360 rop_handler = bitblt_rop_fwd_notsrc_or_dst;
3361 break;
3362 case CIRRUS_ROP_NOTSRC_AND_NOTDST:
3363 rop_handler = bitblt_rop_fwd_notsrc_and_notdst;
3364 break;
3365 default:
3366 BX_ERROR(("unknown ROP %02x",rop));
3367 break;
3368 }
3369
3370 return rop_handler;
3371 }
3372
3373 bx_cirrus_bitblt_rop_t bx_svga_cirrus_c::svga_get_bkwd_rop_handler(Bit8u rop)
3374 {
3375 bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_bkwd_nop;
3376
3377 switch (rop)
3378 {
3379 case CIRRUS_ROP_0:
3380 rop_handler = bitblt_rop_bkwd_0;
3381 break;
3382 case CIRRUS_ROP_SRC_AND_DST:
3383 rop_handler = bitblt_rop_bkwd_src_and_dst;
3384 break;
3385 case CIRRUS_ROP_NOP:
3386 rop_handler = bitblt_rop_bkwd_nop;
3387 break;
3388 case CIRRUS_ROP_SRC_AND_NOTDST:
3389 rop_handler = bitblt_rop_bkwd_src_and_notdst;
3390 break;
3391 case CIRRUS_ROP_NOTDST:
3392 rop_handler = bitblt_rop_bkwd_notdst;
3393 break;
3394 case CIRRUS_ROP_SRC:
3395 rop_handler = bitblt_rop_bkwd_src;
3396 break;
3397 case CIRRUS_ROP_1:
3398 rop_handler = bitblt_rop_bkwd_1;
3399 break;
3400 case CIRRUS_ROP_NOTSRC_AND_DST:
3401 rop_handler = bitblt_rop_bkwd_notsrc_and_dst;
3402 break;
3403 case CIRRUS_ROP_SRC_XOR_DST:
3404 rop_handler = bitblt_rop_bkwd_src_xor_dst;
3405 break;
3406 case CIRRUS_ROP_SRC_OR_DST:
3407 rop_handler = bitblt_rop_bkwd_src_or_dst;
3408 break;
3409 case CIRRUS_ROP_NOTSRC_OR_NOTDST:
3410 rop_handler = bitblt_rop_bkwd_notsrc_or_notdst;
3411 break;
3412 case CIRRUS_ROP_SRC_NOTXOR_DST:
3413 rop_handler = bitblt_rop_bkwd_src_notxor_dst;
3414 break;
3415 case CIRRUS_ROP_SRC_OR_NOTDST:
3416 rop_handler = bitblt_rop_bkwd_src_or_notdst;
3417 break;
3418 case CIRRUS_ROP_NOTSRC:
3419 rop_handler = bitblt_rop_bkwd_notsrc;
3420 break;
3421 case CIRRUS_ROP_NOTSRC_OR_DST:
3422 rop_handler = bitblt_rop_bkwd_notsrc_or_dst;
3423 break;
3424 case CIRRUS_ROP_NOTSRC_AND_NOTDST:
3425 rop_handler = bitblt_rop_bkwd_notsrc_and_notdst;
3426 break;
3427 default:
3428 BX_ERROR(("unknown ROP %02x",rop));
3429 break;
3430 }
3431
3432 return rop_handler;
3433 }
3434
3435 #if BX_DEBUGGER
3436 void bx_svga_cirrus_c::debug_dump(int argc, char **argv)
3437 {
3438 if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_SVGA) {
3439 #if BX_SUPPORT_PCI
3440 if (BX_CIRRUS_THIS pci_enabled)
3441 {
3442 dbg_printf("CL-GD5446 PCI\n\n");
3443 }
3444 else
3445 #endif
3446 {
3447 dbg_printf("CL-GD5430 ISA\n\n");
3448 }
3449 dbg_printf("current mode: %u x %u x %u\n", BX_CIRRUS_THIS svga_xres,
3450 BX_CIRRUS_THIS svga_yres, BX_CIRRUS_THIS svga_dispbpp);
3451 } else {
3452 bx_vgacore_c::debug_dump();
3453 }
3454 if (argc > 0) {
3455 dbg_printf("\nAdditional options not supported\n");
3456 }
3457 }
3458 #endif
3459
3460 #endif // BX_SUPPORT_CLGD54XX
3461
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.