1 /////////////////////////////////////////////////////////////////////////
2 // $Id: svga_cirrus.cc,v 1.45 2008/09/18 20:16:27 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2004 Makoto Suzuki (suzu)
6 // Volker Ruppert (vruppert)
7 // Robin Kay (komadori)
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2 of the License, or (at your option) any later version.
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /////////////////////////////////////////////////////////////////////////
25 // limited PCI/ISA CLGD5446 support for Bochs
27 // there are still many unimplemented features:
29 // - destination write mask support is not complete (bit 5..7)
33 // some codes are copied from vga.cc and modified.
34 // some codes are ported from the cirrus emulation in qemu
35 // (http://savannah.nongnu.org/projects/qemu).
41 #if BX_SUPPORT_CLGD54XX
43 // Only reference the array if the tile numbers are within the bounds
44 // of the array. If out of bounds, do nothing.
45 #define SET_TILE_UPDATED(xtile,ytile,value) \
47 if (((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES)) \
48 BX_CIRRUS_THIS s.vga_tile_updated[(xtile)][(ytile)] = value; \
50 // Only reference the array if the tile numbers are within the bounds
51 // of the array. If out of bounds, return 1.
52 #define GET_TILE_UPDATED(xtile,ytile) \
53 ((((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES))? \
54 BX_CIRRUS_THIS s.vga_tile_updated[(xtile)][(ytile)] \
57 #define LOG_THIS BX_CIRRUS_THIS
60 #define VGA_READ(addr,len) bx_vga_c::read_handler(theSvga,addr,len)
61 #define VGA_WRITE(addr,val,len) bx_vga_c::write_handler(theSvga,addr,val,len)
62 #define SVGA_READ(addr,len) svga_read_handler(theSvga,addr,len)
63 #define SVGA_WRITE(addr,val,len) svga_write_handler(theSvga,addr,val,len)
65 #define VGA_READ(addr,len) bx_vga_c::read(addr,len)
66 #define VGA_WRITE(addr,val,len) bx_vga_c::write(addr,val,len)
67 #define SVGA_READ(addr,len) svga_read(addr,len)
68 #define SVGA_WRITE(addr,val,len) svga_write(addr,val,len)
69 #endif // BX_USE_CIRRUS_SMF
71 #define ID_CLGD5428 (0x26<<2)
72 #define ID_CLGD5430 (0x28<<2)
73 #define ID_CLGD5434 (0x2A<<2)
74 #define ID_CLGD5446 (0x2E<<2)
77 #define CIRRUS_SR7_BPP_VGA 0x00
78 #define CIRRUS_SR7_BPP_SVGA 0x01
79 #define CIRRUS_SR7_BPP_MASK 0x0e
80 #define CIRRUS_SR7_BPP_8 0x00
81 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
82 #define CIRRUS_SR7_BPP_24 0x04
83 #define CIRRUS_SR7_BPP_16 0x06
84 #define CIRRUS_SR7_BPP_32 0x08
85 #define CIRRUS_SR7_ISAADDR_MASK 0xe0
88 #define CIRRUS_MEMSIZE_512k 0x08
89 #define CIRRUS_MEMSIZE_1M 0x10
90 #define CIRRUS_MEMSIZE_2M 0x18
91 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
94 #define CIRRUS_CURSOR_SHOW 0x01
95 #define CIRRUS_CURSOR_HIDDENPEL 0x02
96 #define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
99 #define CIRRUS_BUSTYPE_VLBFAST 0x10
100 #define CIRRUS_BUSTYPE_PCI 0x20
101 #define CIRRUS_BUSTYPE_VLBSLOW 0x30
102 #define CIRRUS_BUSTYPE_ISA 0x38
103 #define CIRRUS_MMIO_ENABLE 0x04
104 #define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
105 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
108 #define CIRRUS_BANKING_DUAL 0x01
109 #define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
112 #define CIRRUS_BLTMODE_BACKWARDS 0x01
113 #define CIRRUS_BLTMODE_MEMSYSDEST 0x02
114 #define CIRRUS_BLTMODE_MEMSYSSRC 0x04
115 #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
116 #define CIRRUS_BLTMODE_PATTERNCOPY 0x40
117 #define CIRRUS_BLTMODE_COLOREXPAND 0x80
118 #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
119 #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
120 #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
121 #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
122 #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
125 #define CIRRUS_BLT_BUSY 0x01
126 #define CIRRUS_BLT_START 0x02
127 #define CIRRUS_BLT_RESET 0x04
128 #define CIRRUS_BLT_FIFOUSED 0x10
129 #define CIRRUS_BLT_AUTOSTART 0x80
132 #define CIRRUS_ROP_0 0x00
133 #define CIRRUS_ROP_SRC_AND_DST 0x05
134 #define CIRRUS_ROP_NOP 0x06
135 #define CIRRUS_ROP_SRC_AND_NOTDST 0x09
136 #define CIRRUS_ROP_NOTDST 0x0b
137 #define CIRRUS_ROP_SRC 0x0d
138 #define CIRRUS_ROP_1 0x0e
139 #define CIRRUS_ROP_NOTSRC_AND_DST 0x50
140 #define CIRRUS_ROP_SRC_XOR_DST 0x59
141 #define CIRRUS_ROP_SRC_OR_DST 0x6d
142 #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
143 #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
144 #define CIRRUS_ROP_SRC_OR_NOTDST 0xad
145 #define CIRRUS_ROP_NOTSRC 0xd0
146 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
147 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
150 #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
151 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
152 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
154 #define CLGD543x_MMIO_BLTBGCOLOR 0x00 // dword
155 #define CLGD543x_MMIO_BLTFGCOLOR 0x04 // dword
156 #define CLGD543x_MMIO_BLTWIDTH 0x08 // word
157 #define CLGD543x_MMIO_BLTHEIGHT 0x0a // word
158 #define CLGD543x_MMIO_BLTDESTPITCH 0x0c // word
159 #define CLGD543x_MMIO_BLTSRCPITCH 0x0e // word
160 #define CLGD543x_MMIO_BLTDESTADDR 0x10 // dword
161 #define CLGD543x_MMIO_BLTSRCADDR 0x14 // dword
162 #define CLGD543x_MMIO_BLTWRITEMASK 0x17 // byte
163 #define CLGD543x_MMIO_BLTMODE 0x18 // byte
164 #define CLGD543x_MMIO_BLTROP 0x1a // byte
165 #define CLGD543x_MMIO_BLTMODEEXT 0x1b // byte
166 #define CLGD543x_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
167 #define CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
168 #define CLGD543x_MMIO_BLTSTATUS 0x40 // byte
170 // PCI 0x00: vendor, 0x02: device
171 #define PCI_VENDOR_CIRRUS 0x1013
172 #define PCI_DEVICE_CLGD5430 0x00a0 // CLGD5430 or CLGD5440
173 #define PCI_DEVICE_CLGD5434 0x00a8
174 #define PCI_DEVICE_CLGD5436 0x00ac
175 #define PCI_DEVICE_CLGD5446 0x00b8
176 #define PCI_DEVICE_CLGD5462 0x00d0
177 #define PCI_DEVICE_CLGD5465 0x00d6
178 // PCI 0x04: command(word), 0x06(word): status
179 #define PCI_COMMAND_IOACCESS 0x0001
180 #define PCI_COMMAND_MEMACCESS 0x0002
181 #define PCI_COMMAND_BUSMASTER 0x0004
182 #define PCI_COMMAND_SPECIALCYCLE 0x0008
183 #define PCI_COMMAND_MEMWRITEINVALID 0x0010
184 #define PCI_COMMAND_PALETTESNOOPING 0x0020
185 #define PCI_COMMAND_PARITYDETECTION 0x0040
186 #define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
187 #define PCI_COMMAND_SERR 0x0100
188 #define PCI_COMMAND_BACKTOBACKTRANS 0x0200
189 // PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
190 #define PCI_CLASS_BASE_DISPLAY 0x03
191 // PCI 0x08, 0x00ff0000
192 #define PCI_CLASS_SUB_VGA 0x00
193 // PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
194 #define PCI_CLASS_HEADERTYPE_00h 0x00
195 // 0x10-0x3f (headertype 00h)
196 // PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
197 // 0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
198 #define PCI_MAP_MEM 0x0
199 #define PCI_MAP_IO 0x1
200 #define PCI_MAP_MEM_ADDR_MASK (~0xf)
201 #define PCI_MAP_IO_ADDR_MASK (~0x3)
202 #define PCI_MAP_MEMFLAGS_32BIT 0x0
203 #define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
204 #define PCI_MAP_MEMFLAGS_64BIT 0x4
205 #define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
206 // PCI 0x28: cardbus CIS pointer
207 // PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
208 // PCI 0x30: expansion ROM base address
209 // PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
210 // PCI 0x38: reserved
211 // PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
212 // PCI 0x40-0xff: device dependent fields
214 // default PnP memory and memory-mapped I/O sizes
215 #define CIRRUS_PNPMEM_SIZE CIRRUS_VIDEO_MEMORY_BYTES
216 #define CIRRUS_PNPMMIO_SIZE 0x1000
218 #define BX_MAX(a,b) ((a) > (b) ? (a) : (b))
219 #define BX_MIN(a,b) ((a) < (b) ? (a) : (b))
221 static bx_svga_cirrus_c
*theSvga
= NULL
;
223 int libvga_LTX_plugin_init(plugin_t
*plugin
, plugintype_t type
, int argc
, char *argv
[])
225 theSvga
= new bx_svga_cirrus_c();
226 libvga_set_smf_pointer(theSvga
);
227 bx_devices
.pluginVgaDevice
= theSvga
;
228 BX_REGISTER_DEVICE_DEVMODEL(plugin
, type
, theSvga
, BX_PLUGIN_VGA
);
229 return(0); // Success
232 void libvga_LTX_plugin_fini(void)
237 bx_svga_cirrus_c::bx_svga_cirrus_c() : bx_vga_c ()
242 bx_svga_cirrus_c::~bx_svga_cirrus_c()
247 void bx_svga_cirrus_c::init(void)
249 // initialize VGA stuffs.
250 BX_CIRRUS_THIS
bx_vga_c::init();
251 if (!strcmp(SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr(), "cirrus")) {
252 // initialize SVGA stuffs.
253 BX_CIRRUS_THIS
bx_vga_c::init_iohandlers(
254 svga_read_handler
, svga_write_handler
);
255 BX_CIRRUS_THIS
bx_vga_c::init_systemtimer(
256 svga_timer_handler
, svga_param_handler
);
258 BX_CIRRUS_THIS pci_enabled
= DEV_is_pci_device("cirrus");
260 BX_CIRRUS_THIS
svga_init_members();
262 if (BX_CIRRUS_THIS pci_enabled
)
264 BX_CIRRUS_THIS
svga_init_pcihandlers();
265 BX_INFO(("CL-GD5446 PCI initialized"));
270 BX_INFO(("CL-GD5430 ISA initialized"));
272 BX_CIRRUS_THIS extension_init
= 1;
274 BX_CIRRUS_THIS sequencer
.reg
[0x07] = 0x00; // Cirrus extension disabled
275 // initialize VGA read/write handlers and timer
276 BX_CIRRUS_THIS
bx_vga_c::init_iohandlers(
277 bx_vga_c::read_handler
, bx_vga_c::write_handler
);
278 BX_CIRRUS_THIS
bx_vga_c::init_systemtimer(
279 bx_vga_c::timer_handler
, bx_vga_c::vga_param_handler
);
283 void bx_svga_cirrus_c::svga_init_members()
287 // clear all registers.
288 BX_CIRRUS_THIS sequencer
.index
= CIRRUS_SEQENCER_MAX
+ 1;
289 for (i
= 0; i
<= CIRRUS_SEQENCER_MAX
; i
++)
290 BX_CIRRUS_THIS sequencer
.reg
[i
] = 0x00;
291 BX_CIRRUS_THIS control
.index
= CIRRUS_CONTROL_MAX
+ 1;
292 for (i
= 0; i
<= CIRRUS_CONTROL_MAX
; i
++)
293 BX_CIRRUS_THIS control
.reg
[i
] = 0x00;
294 BX_CIRRUS_THIS control
.shadow_reg0
= 0x00;
295 BX_CIRRUS_THIS control
.shadow_reg1
= 0x00;
296 BX_CIRRUS_THIS crtc
.index
= CIRRUS_CRTC_MAX
+ 1;
297 for (i
= 0; i
<= CIRRUS_CRTC_MAX
; i
++)
298 BX_CIRRUS_THIS crtc
.reg
[i
] = 0x00;
299 BX_CIRRUS_THIS hidden_dac
.lockindex
= 0;
300 BX_CIRRUS_THIS hidden_dac
.data
= 0x00;
302 BX_CIRRUS_THIS svga_unlock_special
= false;
303 BX_CIRRUS_THIS svga_needs_update_tile
= true;
304 BX_CIRRUS_THIS svga_needs_update_dispentire
= true;
305 BX_CIRRUS_THIS svga_needs_update_mode
= false;
307 BX_CIRRUS_THIS svga_xres
= 640;
308 BX_CIRRUS_THIS svga_yres
= 480;
309 BX_CIRRUS_THIS svga_bpp
= 8;
310 BX_CIRRUS_THIS svga_pitch
= 640;
311 BX_CIRRUS_THIS bank_base
[0] = 0;
312 BX_CIRRUS_THIS bank_base
[1] = 0;
313 BX_CIRRUS_THIS bank_limit
[0] = 0;
314 BX_CIRRUS_THIS bank_limit
[1] = 0;
318 BX_CIRRUS_THIS hw_cursor
.x
= 0;
319 BX_CIRRUS_THIS hw_cursor
.y
= 0;
320 BX_CIRRUS_THIS hw_cursor
.size
= 0;
322 // memory allocation.
323 if (BX_CIRRUS_THIS s
.memory
== NULL
)
324 BX_CIRRUS_THIS s
.memory
= new Bit8u
[CIRRUS_VIDEO_MEMORY_BYTES
];
326 // set some registers.
328 BX_CIRRUS_THIS sequencer
.reg
[0x06] = 0x0f;
329 BX_CIRRUS_THIS sequencer
.reg
[0x07] = 0x00; // 0xf0:linearbase(0x00 if disabled)
331 if (BX_CIRRUS_THIS pci_enabled
) {
332 BX_CIRRUS_THIS crtc
.reg
[0x27] = ID_CLGD5446
;
333 BX_CIRRUS_THIS sequencer
.reg
[0x1F] = 0x2d; // MemClock
334 BX_CIRRUS_THIS control
.reg
[0x18] = 0x0f;
335 BX_CIRRUS_THIS sequencer
.reg
[0x0F] = 0x98;
336 BX_CIRRUS_THIS sequencer
.reg
[0x17] = CIRRUS_BUSTYPE_PCI
;
337 BX_CIRRUS_THIS sequencer
.reg
[0x15] = 0x04; // memory size 4MB
338 BX_CIRRUS_THIS s
.memsize
= (4 << 20);
342 BX_CIRRUS_THIS crtc
.reg
[0x27] = ID_CLGD5430
;
343 BX_CIRRUS_THIS sequencer
.reg
[0x1F] = 0x22; // MemClock
344 BX_CIRRUS_THIS sequencer
.reg
[0x0F] = CIRRUS_MEMSIZE_2M
;
345 BX_CIRRUS_THIS sequencer
.reg
[0x17] = CIRRUS_BUSTYPE_ISA
;
346 BX_CIRRUS_THIS sequencer
.reg
[0x15] = 0x03; // memory size 2MB
347 BX_CIRRUS_THIS s
.memsize
= (2 << 20);
350 BX_CIRRUS_THIS hidden_dac
.lockindex
= 5;
351 BX_CIRRUS_THIS hidden_dac
.data
= 0;
353 memset(BX_CIRRUS_THIS s
.memory
, 0xff, CIRRUS_VIDEO_MEMORY_BYTES
);
354 BX_CIRRUS_THIS disp_ptr
= BX_CIRRUS_THIS s
.memory
;
357 void bx_svga_cirrus_c::reset(unsigned type
)
360 BX_CIRRUS_THIS
bx_vga_c::reset(type
);
362 if (!strcmp(SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr(), "cirrus")) {
363 // reset SVGA stuffs.
364 BX_CIRRUS_THIS
svga_init_members();
368 void bx_svga_cirrus_c::register_state(void)
374 if (!strcmp(SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr(), "cirrus")) {
375 bx_list_c
*list
= new bx_list_c(SIM
->get_bochs_root(), "svga_cirrus", "Cirrus SVGA State", 18);
376 bx_list_c
*crtc
= new bx_list_c(list
, "crtc", 2);
377 new bx_shadow_num_c(crtc
, "index", &BX_CIRRUS_THIS crtc
.index
, BASE_HEX
);
378 reg
= new bx_list_c(crtc
, "reg", CIRRUS_CRTC_MAX
+1);
379 for (i
=0; i
<=CIRRUS_CRTC_MAX
; i
++) {
380 sprintf(name
, "0x%02x", i
);
381 new bx_shadow_num_c(reg
, name
, &BX_CIRRUS_THIS crtc
.reg
[i
], BASE_HEX
);
383 bx_list_c
*sequ
= new bx_list_c(list
, "sequencer", 2);
384 new bx_shadow_num_c(sequ
, "index", &BX_CIRRUS_THIS sequencer
.index
, BASE_HEX
);
385 reg
= new bx_list_c(sequ
, "reg", CIRRUS_SEQENCER_MAX
+1);
386 for (i
=0; i
<=CIRRUS_SEQENCER_MAX
; i
++) {
387 sprintf(name
, "0x%02x", i
);
388 new bx_shadow_num_c(reg
, name
, &BX_CIRRUS_THIS sequencer
.reg
[i
], BASE_HEX
);
390 bx_list_c
*ctrl
= new bx_list_c(list
, "control", 4);
391 new bx_shadow_num_c(ctrl
, "index", &BX_CIRRUS_THIS control
.index
, BASE_HEX
);
392 reg
= new bx_list_c(ctrl
, "reg", CIRRUS_CONTROL_MAX
+1);
393 for (i
=0; i
<=CIRRUS_CONTROL_MAX
; i
++) {
394 sprintf(name
, "0x%02x", i
);
395 new bx_shadow_num_c(reg
, name
, &BX_CIRRUS_THIS control
.reg
[i
], BASE_HEX
);
397 new bx_shadow_num_c(ctrl
, "shadow_reg0", &BX_CIRRUS_THIS control
.shadow_reg0
, BASE_HEX
);
398 new bx_shadow_num_c(ctrl
, "shadow_reg1", &BX_CIRRUS_THIS control
.shadow_reg1
, BASE_HEX
);
399 bx_list_c
*hdac
= new bx_list_c(list
, "hidden_dac", 3);
400 new bx_shadow_num_c(hdac
, "lockindex", &BX_CIRRUS_THIS hidden_dac
.lockindex
, BASE_HEX
);
401 new bx_shadow_num_c(hdac
, "data", &BX_CIRRUS_THIS hidden_dac
.data
, BASE_HEX
);
402 reg
= new bx_list_c(hdac
, "palette", 48);
403 for (i
=0; i
<48; i
++) {
404 sprintf(name
, "0x%02x", i
);
405 new bx_shadow_num_c(reg
, name
, &BX_CIRRUS_THIS hidden_dac
.palette
[i
], BASE_HEX
);
407 new bx_shadow_bool_c(list
, "svga_unlock_special", &BX_CIRRUS_THIS svga_unlock_special
);
408 new bx_shadow_num_c(list
, "svga_xres", &BX_CIRRUS_THIS svga_xres
);
409 new bx_shadow_num_c(list
, "svga_yres", &BX_CIRRUS_THIS svga_yres
);
410 new bx_shadow_num_c(list
, "svga_pitch", &BX_CIRRUS_THIS svga_pitch
);
411 new bx_shadow_num_c(list
, "svga_bpp", &BX_CIRRUS_THIS svga_bpp
);
412 new bx_shadow_num_c(list
, "svga_dispbpp", &BX_CIRRUS_THIS svga_dispbpp
);
413 new bx_shadow_num_c(list
, "bank_base0", &BX_CIRRUS_THIS bank_base
[0], BASE_HEX
);
414 new bx_shadow_num_c(list
, "bank_base1", &BX_CIRRUS_THIS bank_base
[1], BASE_HEX
);
415 new bx_shadow_num_c(list
, "bank_limit0", &BX_CIRRUS_THIS bank_limit
[0], BASE_HEX
);
416 new bx_shadow_num_c(list
, "bank_limit1", &BX_CIRRUS_THIS bank_limit
[1], BASE_HEX
);
417 bx_list_c
*cursor
= new bx_list_c(list
, "hw_cursor", 3);
418 new bx_shadow_num_c(cursor
, "x", &BX_CIRRUS_THIS hw_cursor
.x
, BASE_HEX
);
419 new bx_shadow_num_c(cursor
, "y", &BX_CIRRUS_THIS hw_cursor
.y
, BASE_HEX
);
420 new bx_shadow_num_c(cursor
, "size", &BX_CIRRUS_THIS hw_cursor
.size
, BASE_HEX
);
422 if (BX_CIRRUS_THIS pci_enabled
) {
423 register_pci_state(list
, BX_CIRRUS_THIS pci_conf
);
427 bx_vga_c::register_state();
430 void bx_svga_cirrus_c::after_restore_state(void)
432 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA
) {
433 BX_CIRRUS_THIS
bx_vga_c::after_restore_state();
436 if (BX_CIRRUS_THIS pci_enabled
) {
437 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR
, cirrus_mem_read_handler
,
438 cirrus_mem_write_handler
,
439 &BX_CIRRUS_THIS pci_memaddr
,
440 &BX_CIRRUS_THIS pci_conf
[0x10],
442 BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_memaddr
));
444 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR
, cirrus_mem_read_handler
,
445 cirrus_mem_write_handler
,
446 &BX_CIRRUS_THIS pci_mmioaddr
,
447 &BX_CIRRUS_THIS pci_conf
[0x14],
448 CIRRUS_PNPMMIO_SIZE
)) {
449 BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_mmioaddr
));
453 for (unsigned i
=0; i
<256; i
++) {
454 bx_gui
->palette_change(i
, BX_CIRRUS_THIS s
.pel
.data
[i
].red
<<2,
455 BX_CIRRUS_THIS s
.pel
.data
[i
].green
<<2,
456 BX_CIRRUS_THIS s
.pel
.data
[i
].blue
<<2);
458 BX_CIRRUS_THIS svga_needs_update_mode
= 1;
459 BX_CIRRUS_THIS
svga_update();
463 void bx_svga_cirrus_c::redraw_area(unsigned x0
, unsigned y0
,
464 unsigned width
, unsigned height
)
466 unsigned xti
, yti
, xt0
, xt1
, yt0
, yt1
;
468 if ((width
== 0) || (height
== 0)) {
472 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA
) {
473 BX_CIRRUS_THIS
bx_vga_c::redraw_area(x0
,y0
,width
,height
);
477 if (BX_CIRRUS_THIS svga_needs_update_mode
) {
481 BX_CIRRUS_THIS svga_needs_update_tile
= true;
483 xt0
= x0
/ X_TILESIZE
;
484 yt0
= y0
/ Y_TILESIZE
;
485 if (x0
< BX_CIRRUS_THIS svga_xres
) {
486 xt1
= (x0
+ width
- 1) / X_TILESIZE
;
488 xt1
= (BX_CIRRUS_THIS svga_xres
- 1) / X_TILESIZE
;
490 if (y0
< BX_CIRRUS_THIS svga_yres
) {
491 yt1
= (y0
+ height
- 1) / Y_TILESIZE
;
493 yt1
= (BX_CIRRUS_THIS svga_yres
- 1) / Y_TILESIZE
;
495 for (yti
=yt0
; yti
<=yt1
; yti
++) {
496 for (xti
=xt0
; xti
<=xt1
; xti
++) {
497 SET_TILE_UPDATED (xti
, yti
, 1);
502 void bx_svga_cirrus_c::mem_write_mode4and5_8bpp(Bit8u mode
, Bit32u offset
, Bit8u value
)
507 dst
= BX_CIRRUS_THIS s
.memory
+ offset
;
508 for (int x
= 0; x
< 8; x
++) {
510 *dst
= BX_CIRRUS_THIS control
.shadow_reg1
;
511 } else if (mode
== 5) {
512 *dst
= BX_CIRRUS_THIS control
.shadow_reg0
;
519 void bx_svga_cirrus_c::mem_write_mode4and5_16bpp(Bit8u mode
, Bit32u offset
, Bit8u value
)
524 dst
= BX_CIRRUS_THIS s
.memory
+ offset
;
525 for (int x
= 0; x
< 8; x
++) {
527 *dst
= BX_CIRRUS_THIS control
.shadow_reg1
;
528 *(dst
+ 1) = BX_CIRRUS_THIS control
.reg
[0x11];
529 } else if (mode
== 5) {
530 *dst
= BX_CIRRUS_THIS control
.shadow_reg0
;
531 *(dst
+ 1) = BX_CIRRUS_THIS control
.reg
[0x10];
539 bx_bool
bx_svga_cirrus_c::cirrus_mem_read_handler(bx_phy_address addr
, unsigned len
,
540 void *data
, void *param
)
543 #ifdef BX_LITTLE_ENDIAN
544 data_ptr
= (Bit8u
*) data
;
545 #else // BX_BIG_ENDIAN
546 data_ptr
= (Bit8u
*) data
+ (len
- 1);
548 for (unsigned i
= 0; i
< len
; i
++) {
549 *data_ptr
= BX_CIRRUS_THIS
mem_read(addr
);
551 #ifdef BX_LITTLE_ENDIAN
553 #else // BX_BIG_ENDIAN
561 Bit8u
bx_svga_cirrus_c::mem_read(bx_phy_address addr
)
563 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA
) {
564 return BX_CIRRUS_THIS
bx_vga_c::mem_read(addr
);
568 if (BX_CIRRUS_THIS pci_enabled
) {
569 if ((addr
>= BX_CIRRUS_THIS pci_memaddr
) &&
570 (addr
< (BX_CIRRUS_THIS pci_memaddr
+ CIRRUS_PNPMEM_SIZE
))) {
573 Bit32u offset
= addr
& (BX_CIRRUS_THIS s
.memsize
- 1);
574 if ((offset
>= (BX_CIRRUS_THIS s
.memsize
- 256)) &&
575 ((BX_CIRRUS_THIS sequencer
.reg
[0x17] & 0x44) == 0x44)) {
576 return svga_mmio_blt_read(offset
& 0xff);
580 if (BX_CIRRUS_THIS bitblt
.memdst_needed
!= 0) {
581 ptr
= BX_CIRRUS_THIS bitblt
.memdst_ptr
;
582 if (ptr
!= BX_CIRRUS_THIS bitblt
.memdst_endptr
) {
583 BX_CIRRUS_THIS bitblt
.memdst_ptr
++;
586 if (!svga_asyncbitblt_next()) {
587 ptr
= BX_CIRRUS_THIS bitblt
.memdst_ptr
;
588 BX_CIRRUS_THIS bitblt
.memdst_ptr
++;
593 ptr
= BX_CIRRUS_THIS s
.memory
;
594 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) == 0x14) {
596 } else if (BX_CIRRUS_THIS control
.reg
[0x0b] & 0x02) {
599 offset
&= (BX_CIRRUS_THIS s
.memsize
- 1);
600 return *(ptr
+ offset
);
601 } else if ((addr
>= BX_CIRRUS_THIS pci_mmioaddr
) &&
602 (addr
< (BX_CIRRUS_THIS pci_mmioaddr
+ CIRRUS_PNPMMIO_SIZE
))) {
604 Bit32u offset
= addr
& (CIRRUS_PNPMMIO_SIZE
- 1);
605 if (offset
>= 0x100) {
606 return svga_mmio_blt_read(offset
- 0x100);
608 return svga_mmio_vga_read(offset
);
612 #endif // BX_SUPPORT_PCI
614 if (addr
>= 0xA0000 && addr
<= 0xAFFFF)
621 if (BX_CIRRUS_THIS bitblt
.memdst_needed
!= 0) {
622 ptr
= BX_CIRRUS_THIS bitblt
.memdst_ptr
;
623 if (ptr
!= BX_CIRRUS_THIS bitblt
.memdst_endptr
) {
624 BX_CIRRUS_THIS bitblt
.memdst_ptr
++;
627 if (!svga_asyncbitblt_next()) {
628 ptr
= BX_CIRRUS_THIS bitblt
.memdst_ptr
;
629 BX_CIRRUS_THIS bitblt
.memdst_ptr
++;
634 offset
= addr
& 0xffff;
635 bank
= (offset
>> 15);
637 if (offset
< bank_limit
[bank
]) {
638 offset
+= bank_base
[bank
];
639 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) == 0x14) {
641 } else if (BX_CIRRUS_THIS control
.reg
[0x0b] & 0x02) {
644 offset
&= (BX_CIRRUS_THIS s
.memsize
- 1);
645 return *(BX_CIRRUS_THIS s
.memory
+ offset
);
651 else if (addr
>= 0xB8000 && addr
<= 0xB8100) {
652 // memory-mapped I/O.
655 offset
= addr
- 0xb8000;
656 if ((BX_CIRRUS_THIS sequencer
.reg
[0x17] & 0x44) == 0x04)
657 return svga_mmio_blt_read(offset
);
660 BX_DEBUG(("mem_read 0x%08x",addr
));
667 bx_bool
bx_svga_cirrus_c::cirrus_mem_write_handler(bx_phy_address addr
, unsigned len
,
668 void *data
, void *param
)
671 #ifdef BX_LITTLE_ENDIAN
672 data_ptr
= (Bit8u
*) data
;
673 #else // BX_BIG_ENDIAN
674 data_ptr
= (Bit8u
*) data
+ (len
- 1);
676 for (unsigned i
= 0; i
< len
; i
++) {
677 BX_CIRRUS_THIS
mem_write(addr
, *data_ptr
);
679 #ifdef BX_LITTLE_ENDIAN
681 #else // BX_BIG_ENDIAN
689 void bx_svga_cirrus_c::mem_write(bx_phy_address addr
, Bit8u value
)
691 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA
) {
692 BX_CIRRUS_THIS
bx_vga_c::mem_write(addr
,value
);
697 if (BX_CIRRUS_THIS pci_enabled
) {
698 if ((addr
>= BX_CIRRUS_THIS pci_memaddr
) &&
699 (addr
< (BX_CIRRUS_THIS pci_memaddr
+ CIRRUS_PNPMEM_SIZE
))) {
701 Bit32u offset
= addr
& (BX_CIRRUS_THIS s
.memsize
- 1);
702 if ((offset
>= (BX_CIRRUS_THIS s
.memsize
- 256)) &&
703 ((BX_CIRRUS_THIS sequencer
.reg
[0x17] & 0x44) == 0x44)) {
704 svga_mmio_blt_write(addr
& 0xff, value
);
709 if (BX_CIRRUS_THIS bitblt
.memsrc_needed
> 0) {
710 *(BX_CIRRUS_THIS bitblt
.memsrc_ptr
)++ = (value
);
711 if (BX_CIRRUS_THIS bitblt
.memsrc_ptr
>= BX_CIRRUS_THIS bitblt
.memsrc_endptr
) {
712 svga_asyncbitblt_next();
717 // BX_DEBUG(("write offset 0x%08x,value 0x%02x",offset,value));
718 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) == 0x14) {
720 } else if (BX_CIRRUS_THIS control
.reg
[0x0b] & 0x02) {
723 offset
&= (BX_CIRRUS_THIS s
.memsize
- 1);
724 Bit8u mode
= BX_CIRRUS_THIS control
.reg
[0x05] & 0x07;
725 if ((mode
< 4) || (mode
> 5) || ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x4) == 0)) {
726 *(BX_CIRRUS_THIS s
.memory
+ offset
) = value
;
728 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) != 0x14) {
729 mem_write_mode4and5_8bpp(mode
, offset
, value
);
731 mem_write_mode4and5_16bpp(mode
, offset
, value
);
734 BX_CIRRUS_THIS svga_needs_update_tile
= true;
735 SET_TILE_UPDATED(((offset
% BX_CIRRUS_THIS svga_pitch
) / (BX_CIRRUS_THIS svga_bpp
/ 8)) / X_TILESIZE
,
736 (offset
/ BX_CIRRUS_THIS svga_pitch
) / Y_TILESIZE
, 1);
738 } else if ((addr
>= BX_CIRRUS_THIS pci_mmioaddr
) &&
739 (addr
< (BX_CIRRUS_THIS pci_mmioaddr
+ CIRRUS_PNPMMIO_SIZE
))) {
740 // memory-mapped I/O.
742 // BX_DEBUG(("write mmio 0x%08x",addr));
743 Bit32u offset
= addr
& (CIRRUS_PNPMMIO_SIZE
- 1);
744 if (offset
>= 0x100) {
745 svga_mmio_blt_write(offset
- 0x100, value
);
747 svga_mmio_vga_write(offset
,value
);
752 #endif // BX_SUPPORT_PCI
754 if (addr
>= 0xA0000 && addr
<= 0xAFFFF) {
759 if (BX_CIRRUS_THIS bitblt
.memsrc_needed
> 0) {
760 *(BX_CIRRUS_THIS bitblt
.memsrc_ptr
)++ = (value
);
761 if (BX_CIRRUS_THIS bitblt
.memsrc_ptr
>= BX_CIRRUS_THIS bitblt
.memsrc_endptr
) {
762 svga_asyncbitblt_next();
767 offset
= addr
& 0xffff;
768 bank
= (offset
>> 15);
770 if (offset
< bank_limit
[bank
]) {
771 offset
+= bank_base
[bank
];
772 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) == 0x14) {
774 } else if (BX_CIRRUS_THIS control
.reg
[0x0b] & 0x02) {
777 offset
&= (BX_CIRRUS_THIS s
.memsize
- 1);
778 mode
= BX_CIRRUS_THIS control
.reg
[0x05] & 0x07;
779 if ((mode
< 4) || (mode
> 5) || ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x4) == 0)) {
780 *(BX_CIRRUS_THIS s
.memory
+ offset
) = value
;
782 if ((BX_CIRRUS_THIS control
.reg
[0x0b] & 0x14) != 0x14) {
783 mem_write_mode4and5_8bpp(mode
, offset
, value
);
785 mem_write_mode4and5_16bpp(mode
, offset
, value
);
788 BX_CIRRUS_THIS svga_needs_update_tile
= true;
789 SET_TILE_UPDATED(((offset
% BX_CIRRUS_THIS svga_pitch
) / (BX_CIRRUS_THIS svga_bpp
/ 8)) / X_TILESIZE
,
790 (offset
/ BX_CIRRUS_THIS svga_pitch
) / Y_TILESIZE
, 1);
792 } else if (addr
>= 0xB8000 && addr
< 0xB8100) {
793 // memory-mapped I/O.
796 offset
= addr
- 0xb8000;
797 if ((BX_CIRRUS_THIS sequencer
.reg
[0x17] & 0x44) == 0x04) {
798 svga_mmio_blt_write(offset
& 0xff, value
);
802 BX_DEBUG(("mem_write 0x%08x, value 0x%02x",addr
,value
));
806 void bx_svga_cirrus_c::get_text_snapshot(Bit8u
**text_snapshot
,
807 unsigned *txHeight
, unsigned *txWidth
)
809 BX_CIRRUS_THIS
bx_vga_c::get_text_snapshot(text_snapshot
,txHeight
,txWidth
);
812 void bx_svga_cirrus_c::trigger_timer(void *this_ptr
)
814 BX_CIRRUS_THIS
timer_handler(this_ptr
);
817 Bit64s
bx_svga_cirrus_c::svga_param_handler(bx_param_c
*param
, int set
, Bit64s val
)
820 BX_INFO (("Changing timer interval to %d", (Bit32u
)val
));
821 BX_CIRRUS_THIS
svga_timer_handler (theSvga
);
822 bx_pc_system
.activate_timer (BX_CIRRUS_THIS timer_id
, (Bit32u
)val
, 1);
827 Bit8u
bx_svga_cirrus_c::get_actl_palette_idx(Bit8u index
)
829 return BX_CIRRUS_THIS
bx_vga_c::get_actl_palette_idx(index
);
832 Bit32u
bx_svga_cirrus_c::svga_read_handler(void *this_ptr
, Bit32u address
, unsigned io_len
)
834 #if !BX_USE_CIRRUS_SMF
835 bx_svga_cirrus_c
*class_ptr
= (bx_svga_cirrus_c
*) this_ptr
;
837 return class_ptr
->svga_read(address
, io_len
);
840 Bit32u
bx_svga_cirrus_c::svga_read(Bit32u address
, unsigned io_len
)
844 #endif // !BX_USE_CIRRUS_SMF
846 if ((io_len
== 2) && ((address
& 1) == 0)) {
848 value
= (Bit32u
)SVGA_READ(address
,1);
849 value
|= (Bit32u
)SVGA_READ(address
+1,1) << 8;
854 BX_PANIC(("SVGA read: io_len != 1"));
858 case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
859 case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
860 return BX_CIRRUS_THIS crtc
.index
;
861 case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
862 case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
863 if (BX_CIRRUS_THIS
is_unlocked())
864 return BX_CIRRUS_THIS
svga_read_crtc(address
,BX_CIRRUS_THIS crtc
.index
);
867 case 0x03c4: /* VGA: Sequencer Index Register */
868 if (BX_CIRRUS_THIS
is_unlocked()) {
869 Bit32u value
= BX_CIRRUS_THIS sequencer
.index
;
870 if ((value
& 0x1e) == 0x10) { /* SR10-F0, SR11-F1 */
872 value
= ((BX_CIRRUS_THIS hw_cursor
.y
& 7) << 5) | 0x11;
874 value
= ((BX_CIRRUS_THIS hw_cursor
.x
& 7) << 5) | 0x10;
878 return BX_CIRRUS_THIS sequencer
.index
;
879 case 0x03c5: /* VGA: Sequencer Registers */
880 if ((BX_CIRRUS_THIS sequencer
.index
== 0x06) ||
881 (BX_CIRRUS_THIS
is_unlocked())) {
882 return BX_CIRRUS_THIS
svga_read_sequencer(address
,BX_CIRRUS_THIS sequencer
.index
);
886 case 0x03c6: /* Hidden DAC */
887 if (BX_CIRRUS_THIS
is_unlocked()) {
888 if ((++BX_CIRRUS_THIS hidden_dac
.lockindex
) == 5) {
889 BX_CIRRUS_THIS hidden_dac
.lockindex
= 0;
890 return BX_CIRRUS_THIS hidden_dac
.data
;
894 case 0x03c8: /* PEL write address */
895 BX_CIRRUS_THIS hidden_dac
.lockindex
= 0;
897 case 0x03c9: /* PEL Data Register, hiddem pel colors 00..0F */
898 if (BX_CIRRUS_THIS sequencer
.reg
[0x12] & CIRRUS_CURSOR_HIDDENPEL
) {
899 Bit8u index
= (BX_CIRRUS_THIS s
.pel
.read_data_register
& 0x0f) * 3 +
900 BX_CIRRUS_THIS s
.pel
.read_data_cycle
;
901 Bit8u retval
= BX_CIRRUS_THIS hidden_dac
.palette
[index
];
902 BX_CIRRUS_THIS s
.pel
.read_data_cycle
++;
903 if (BX_CIRRUS_THIS s
.pel
.read_data_cycle
>= 3) {
904 BX_CIRRUS_THIS s
.pel
.read_data_cycle
= 0;
905 BX_CIRRUS_THIS s
.pel
.read_data_register
++;
910 case 0x03ce: /* VGA: Graphics Controller Index Register */
911 return BX_CIRRUS_THIS control
.index
;
912 case 0x03cf: /* VGA: Graphics Controller Registers */
913 if (BX_CIRRUS_THIS
is_unlocked())
914 return BX_CIRRUS_THIS
svga_read_control(address
,BX_CIRRUS_THIS control
.index
);
921 return VGA_READ(address
,io_len
);
924 void bx_svga_cirrus_c::svga_write_handler(void *this_ptr
, Bit32u address
, Bit32u value
, unsigned io_len
)
926 #if !BX_USE_CIRRUS_SMF
927 bx_svga_cirrus_c
*class_ptr
= (bx_svga_cirrus_c
*) this_ptr
;
928 class_ptr
->svga_write(address
, value
, io_len
);
931 void bx_svga_cirrus_c::svga_write(Bit32u address
, Bit32u value
, unsigned io_len
)
935 #endif // !BX_USE_CIRRUS_SMF
937 if ((io_len
== 2) && ((address
& 1) == 0)) {
938 SVGA_WRITE(address
,value
& 0xff,1);
939 SVGA_WRITE(address
+1,value
>> 8,1);
944 BX_PANIC(("SVGA write: io_len != 1"));
948 case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
949 case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
950 BX_CIRRUS_THIS crtc
.index
= value
& 0x7f;
952 case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
953 case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
954 if (BX_CIRRUS_THIS
is_unlocked()) {
955 BX_CIRRUS_THIS
svga_write_crtc(address
,BX_CIRRUS_THIS crtc
.index
,value
);
960 case 0x03c4: /* VGA: Sequencer Index Register */
961 BX_CIRRUS_THIS sequencer
.index
= value
;
963 case 0x03c5: /* VGA: Sequencer Registers */
964 if ((BX_CIRRUS_THIS sequencer
.index
== 0x06) ||
965 (BX_CIRRUS_THIS
is_unlocked())) {
966 BX_CIRRUS_THIS
svga_write_sequencer(address
,BX_CIRRUS_THIS sequencer
.index
,value
);
970 case 0x03c6: /* Hidden DAC */
971 if (BX_CIRRUS_THIS
is_unlocked()) {
972 if (BX_CIRRUS_THIS hidden_dac
.lockindex
== 4) {
973 BX_CIRRUS_THIS hidden_dac
.data
= value
;
975 BX_CIRRUS_THIS hidden_dac
.lockindex
= 0;
979 case 0x03c9: /* PEL Data Register, hidden pel colors 00..0F */
980 BX_CIRRUS_THIS svga_needs_update_dispentire
= true;
982 if (BX_CIRRUS_THIS sequencer
.reg
[0x12] & CIRRUS_CURSOR_HIDDENPEL
) {
983 Bit8u index
= (BX_CIRRUS_THIS s
.pel
.write_data_register
& 0x0f) * 3 +
984 BX_CIRRUS_THIS s
.pel
.write_data_cycle
;
985 BX_CIRRUS_THIS hidden_dac
.palette
[index
] = value
;
986 BX_CIRRUS_THIS s
.pel
.write_data_cycle
++;
987 if (BX_CIRRUS_THIS s
.pel
.write_data_cycle
>= 3) {
988 BX_CIRRUS_THIS s
.pel
.write_data_cycle
= 0;
989 BX_CIRRUS_THIS s
.pel
.write_data_register
++;
994 case 0x03ce: /* VGA: Graphics Controller Index Register */
995 BX_CIRRUS_THIS control
.index
= value
;
997 case 0x03cf: /* VGA: Graphics Controller Registers */
998 if (BX_CIRRUS_THIS
is_unlocked()) {
999 BX_CIRRUS_THIS
svga_write_control(address
,BX_CIRRUS_THIS control
.index
,value
);
1007 VGA_WRITE(address
,value
,io_len
);
1010 void bx_svga_cirrus_c::svga_timer_handler(void *this_ptr
)
1012 #if !BX_USE_CIRRUS_SMF
1013 bx_svga_cirrus_c
*class_ptr
= (bx_svga_cirrus_c
*) this_ptr
;
1014 class_ptr
->svga_timer();
1017 void bx_svga_cirrus_c::svga_timer(void)
1019 #else // !BX_USE_CIRRUS_SMF
1021 #endif // !BX_USE_CIRRUS_SMF
1023 BX_CIRRUS_THIS
svga_update();
1027 void bx_svga_cirrus_c::svga_modeupdate(void)
1029 Bit32u iTopOffset
, iWidth
, iHeight
;
1030 Bit8u iBpp
, iDispBpp
;
1032 iTopOffset
= (BX_CIRRUS_THIS crtc
.reg
[0x0c] << 8)
1033 + BX_CIRRUS_THIS crtc
.reg
[0x0d]
1034 + ((BX_CIRRUS_THIS crtc
.reg
[0x1b] & 0x01) << 16)
1035 + ((BX_CIRRUS_THIS crtc
.reg
[0x1b] & 0x0c) << 15)
1036 + ((BX_CIRRUS_THIS crtc
.reg
[0x1d] & 0x80) << 12);
1039 iHeight
= 1 + BX_CIRRUS_THIS crtc
.reg
[0x12]
1040 + ((BX_CIRRUS_THIS crtc
.reg
[0x07] & 0x02) << 7)
1041 + ((BX_CIRRUS_THIS crtc
.reg
[0x07] & 0x40) << 3);
1042 if ((BX_CIRRUS_THIS crtc
.reg
[0x1a] & 0x01) > 0) {
1045 iWidth
= (BX_CIRRUS_THIS crtc
.reg
[0x01] + 1) * 8;
1048 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x1) == CIRRUS_SR7_BPP_SVGA
) {
1049 switch (BX_CIRRUS_THIS sequencer
.reg
[0x07] & CIRRUS_SR7_BPP_MASK
) {
1050 case CIRRUS_SR7_BPP_8
:
1054 case CIRRUS_SR7_BPP_16_DOUBLEVCLK
:
1055 case CIRRUS_SR7_BPP_16
:
1057 iDispBpp
= (BX_CIRRUS_THIS hidden_dac
.data
& 0x1) ? 16 : 15;
1059 case CIRRUS_SR7_BPP_24
:
1063 case CIRRUS_SR7_BPP_32
:
1068 BX_PANIC(("unknown bpp - seqencer.reg[0x07] = %02x",BX_CIRRUS_THIS sequencer
.reg
[0x07]));
1072 if ((iWidth
!= BX_CIRRUS_THIS svga_xres
) || (iHeight
!= BX_CIRRUS_THIS svga_yres
)
1073 || (iDispBpp
!= BX_CIRRUS_THIS svga_dispbpp
)) {
1074 BX_INFO(("switched to %u x %u x %u", iWidth
, iHeight
, iDispBpp
));
1076 BX_CIRRUS_THIS svga_xres
= iWidth
;
1077 BX_CIRRUS_THIS svga_yres
= iHeight
;
1078 BX_CIRRUS_THIS svga_bpp
= iBpp
;
1079 BX_CIRRUS_THIS svga_dispbpp
= iDispBpp
;
1080 BX_CIRRUS_THIS disp_ptr
= BX_CIRRUS_THIS s
.memory
+ iTopOffset
;
1083 void bx_svga_cirrus_c::draw_hardware_cursor(unsigned xc
, unsigned yc
, bx_svga_tileinfo_t
*info
)
1085 if (BX_CIRRUS_THIS hw_cursor
.size
&&
1086 (xc
< (unsigned)(BX_CIRRUS_THIS hw_cursor
.x
+BX_CIRRUS_THIS hw_cursor
.size
)) &&
1087 (xc
+X_TILESIZE
> BX_CIRRUS_THIS hw_cursor
.x
) &&
1088 (yc
< (unsigned)(BX_CIRRUS_THIS hw_cursor
.y
+BX_CIRRUS_THIS hw_cursor
.size
)) &&
1089 (yc
+Y_TILESIZE
> BX_CIRRUS_THIS hw_cursor
.y
)) {
1091 unsigned w
, h
, pitch
, cx
, cy
, cx0
, cy0
, cx1
, cy1
;
1093 Bit8u
* tile_ptr
, * tile_ptr2
;
1094 Bit8u
* plane0_ptr
, *plane0_ptr2
;
1095 Bit8u
* plane1_ptr
, *plane1_ptr2
;
1096 unsigned long fgcol
, bgcol
;
1097 Bit64u plane0
, plane1
;
1099 cx0
= BX_CIRRUS_THIS hw_cursor
.x
> xc
? BX_CIRRUS_THIS hw_cursor
.x
: xc
;
1100 cy0
= BX_CIRRUS_THIS hw_cursor
.y
> yc
? BX_CIRRUS_THIS hw_cursor
.y
: yc
;
1101 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
;
1102 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
;
1104 if (info
->bpp
== 15) info
->bpp
= 16;
1105 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
) +
1106 info
->pitch
* (cy0
- yc
) + (info
->bpp
/ 8) * (cx0
- xc
);
1107 plane0_ptr
= BX_CIRRUS_THIS s
.memory
+ BX_CIRRUS_THIS s
.memsize
- 16384;
1109 switch (BX_CIRRUS_THIS hw_cursor
.size
) {
1111 plane0_ptr
+= (BX_CIRRUS_THIS sequencer
.reg
[0x13] & 0x3f) * 256;
1112 plane1_ptr
= plane0_ptr
+ 128;
1117 plane0_ptr
+= (BX_CIRRUS_THIS sequencer
.reg
[0x13] & 0x3c) * 256;
1118 plane1_ptr
= plane0_ptr
+ 8;
1123 BX_ERROR(("unsupported hardware cursor size"));
1128 if (!info
->is_indexed
) {
1129 fgcol
= MAKE_COLOUR(
1130 BX_CIRRUS_THIS hidden_dac
.palette
[45], 6, info
->red_shift
, info
->red_mask
,
1131 BX_CIRRUS_THIS hidden_dac
.palette
[46], 6, info
->green_shift
, info
->green_mask
,
1132 BX_CIRRUS_THIS hidden_dac
.palette
[47], 6, info
->blue_shift
, info
->blue_mask
);
1133 bgcol
= MAKE_COLOUR(
1134 BX_CIRRUS_THIS hidden_dac
.palette
[0], 6, info
->red_shift
, info
->red_mask
,
1135 BX_CIRRUS_THIS hidden_dac
.palette
[1], 6, info
->green_shift
, info
->green_mask
,
1136 BX_CIRRUS_THIS hidden_dac
.palette
[2], 6, info
->blue_shift
, info
->blue_mask
);
1138 // FIXME: this is a hack that works in Windows guests
1139 // TODO: compare hidden DAC entries with DAC entries to find nearest match
1144 plane0_ptr
+= pitch
* (cy0
- BX_CIRRUS_THIS hw_cursor
.y
);
1145 plane1_ptr
+= pitch
* (cy0
- BX_CIRRUS_THIS hw_cursor
.y
);
1146 for (cy
=cy0
; cy
<cy1
; cy
++) {
1147 tile_ptr2
= tile_ptr
+ (info
->bpp
/8) * (cx1
- cx0
) - 1;
1148 plane0_ptr2
= plane0_ptr
;
1149 plane1_ptr2
= plane1_ptr
;
1150 plane0
= plane1
= 0;
1151 for (i
=0; i
<BX_CIRRUS_THIS hw_cursor
.size
; i
+=8) {
1152 plane0
= (plane0
<< 8) | *(plane0_ptr2
++);
1153 plane1
= (plane1
<< 8) | *(plane1_ptr2
++);
1155 plane0
>>= BX_CIRRUS_THIS hw_cursor
.x
+BX_CIRRUS_THIS hw_cursor
.size
- cx1
;
1156 plane1
>>= BX_CIRRUS_THIS hw_cursor
.x
+BX_CIRRUS_THIS hw_cursor
.size
- cx1
;
1157 for (cx
=cx0
; cx
<cx1
; cx
++) {
1160 if (info
->is_little_endian
) {
1161 for (i
=info
->bpp
-8; i
>-8; i
-=8) {
1162 *(tile_ptr2
--) = (Bit8u
)(fgcol
>> i
);
1166 for (i
=0; i
<info
->bpp
; i
+=8) {
1167 *(tile_ptr2
--) = (Bit8u
)(fgcol
>> i
);
1172 for (i
=0; i
<info
->bpp
; i
+=8) {
1173 *(tile_ptr2
--) ^= 0xff;
1179 if (info
->is_little_endian
) {
1180 for (i
=info
->bpp
-8; i
>-8; i
-=8) {
1181 *(tile_ptr2
--) = (Bit8u
)(bgcol
>> i
);
1185 for (i
=0; i
<info
->bpp
; i
+=8) {
1186 *(tile_ptr2
--) = (Bit8u
)(bgcol
>> i
);
1191 tile_ptr2
-= (info
->bpp
/8);
1197 tile_ptr
+= info
->pitch
;
1198 plane0_ptr
+= pitch
;
1199 plane1_ptr
+= pitch
;
1204 void bx_svga_cirrus_c::svga_update(void)
1206 unsigned width
, height
, pitch
;
1208 /* skip screen update when the sequencer is in reset mode or video is disabled */
1209 if (! BX_CIRRUS_THIS s
.sequencer
.reset1
||
1210 ! BX_CIRRUS_THIS s
.sequencer
.reset2
||
1211 ! BX_CIRRUS_THIS s
.attribute_ctrl
.video_enabled
) {
1215 if ((BX_CIRRUS_THIS sequencer
.reg
[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA
) {
1216 if (BX_CIRRUS_THIS svga_needs_update_mode
) {
1217 BX_CIRRUS_THIS s
.vga_mem_updated
= 1;
1218 BX_CIRRUS_THIS svga_needs_update_mode
= false;
1220 BX_CIRRUS_THIS
bx_vga_c::update();
1224 if (BX_CIRRUS_THIS svga_needs_update_mode
) {
1229 width
= BX_CIRRUS_THIS svga_xres
;
1230 height
= BX_CIRRUS_THIS svga_yres
;
1231 pitch
= BX_CIRRUS_THIS svga_pitch
;
1233 if (BX_CIRRUS_THIS svga_needs_update_mode
) {
1234 width
= BX_CIRRUS_THIS svga_xres
;
1235 height
= BX_CIRRUS_THIS svga_yres
;
1236 bx_gui
->dimension_update(width
, height
, 0, 0, BX_CIRRUS_THIS svga_dispbpp
);
1237 BX_CIRRUS_THIS s
.last_bpp
= BX_CIRRUS_THIS svga_dispbpp
;
1238 BX_CIRRUS_THIS svga_needs_update_mode
= false;
1239 BX_CIRRUS_THIS svga_needs_update_dispentire
= true;
1242 if (BX_CIRRUS_THIS svga_needs_update_dispentire
) {
1243 BX_CIRRUS_THIS
redraw_area(0,0,width
,height
);
1244 BX_CIRRUS_THIS svga_needs_update_dispentire
= false;
1247 if (!BX_CIRRUS_THIS svga_needs_update_tile
) {
1250 BX_CIRRUS_THIS svga_needs_update_tile
= false;
1252 unsigned xc
, yc
, xti
, yti
;
1253 unsigned r
, c
, w
, h
;
1255 Bit8u red
, green
, blue
;
1257 Bit8u
* vid_ptr
, * vid_ptr2
;
1258 Bit8u
* tile_ptr
, * tile_ptr2
;
1259 bx_svga_tileinfo_t info
;
1261 if (bx_gui
->graphics_tile_info(&info
)) {
1262 if (info
.is_indexed
) {
1263 switch (BX_CIRRUS_THIS svga_dispbpp
) {
1269 BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays, svga_dispbpp=%d",
1270 BX_CIRRUS_THIS svga_dispbpp
));
1273 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1274 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1275 if (GET_TILE_UPDATED (xti
, yti
)) {
1276 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ xc
);
1277 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1278 for (r
=0; r
<h
; r
++) {
1280 tile_ptr2
= tile_ptr
;
1281 for (c
=0; c
<w
; c
++) {
1283 for (i
=0; i
<(int)BX_CIRRUS_THIS svga_bpp
; i
+=8) {
1284 colour
|= *(vid_ptr2
++) << i
;
1286 if (info
.is_little_endian
) {
1287 for (i
=0; i
<info
.bpp
; i
+=8) {
1288 *(tile_ptr2
++) = colour
>> i
;
1292 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1293 *(tile_ptr2
++) = colour
>> i
;
1298 tile_ptr
+= info
.pitch
;
1300 draw_hardware_cursor(xc
, yc
, &info
);
1301 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1302 SET_TILE_UPDATED (xti
, yti
, 0);
1310 switch (BX_CIRRUS_THIS svga_dispbpp
) {
1312 BX_ERROR(("cannot draw 4bpp SVGA"));
1315 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1316 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1317 if (GET_TILE_UPDATED (xti
, yti
)) {
1318 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ xc
);
1319 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1320 for (r
=0; r
<h
; r
++) {
1322 tile_ptr2
= tile_ptr
;
1323 for (c
=0; c
<w
; c
++) {
1324 colour
= *(vid_ptr2
++);
1325 colour
= MAKE_COLOUR(
1326 BX_CIRRUS_THIS s
.pel
.data
[colour
].red
, 6, info
.red_shift
, info
.red_mask
,
1327 BX_CIRRUS_THIS s
.pel
.data
[colour
].green
, 6, info
.green_shift
, info
.green_mask
,
1328 BX_CIRRUS_THIS s
.pel
.data
[colour
].blue
, 6, info
.blue_shift
, info
.blue_mask
);
1329 if (info
.is_little_endian
) {
1330 for (i
=0; i
<info
.bpp
; i
+=8) {
1331 *(tile_ptr2
++) = colour
>> i
;
1335 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1336 *(tile_ptr2
++) = colour
>> i
;
1341 tile_ptr
+= info
.pitch
;
1343 draw_hardware_cursor(xc
, yc
, &info
);
1344 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1345 SET_TILE_UPDATED (xti
, yti
, 0);
1351 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1352 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1353 if (GET_TILE_UPDATED (xti
, yti
)) {
1354 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ (xc
<<1));
1355 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1356 for (r
=0; r
<h
; r
++) {
1358 tile_ptr2
= tile_ptr
;
1359 for (c
=0; c
<w
; c
++) {
1360 colour
= *(vid_ptr2
++);
1361 colour
|= *(vid_ptr2
++) << 8;
1362 colour
= MAKE_COLOUR(
1363 colour
& 0x001f, 5, info
.blue_shift
, info
.blue_mask
,
1364 colour
& 0x03e0, 10, info
.green_shift
, info
.green_mask
,
1365 colour
& 0x7c00, 15, info
.red_shift
, info
.red_mask
);
1366 if (info
.is_little_endian
) {
1367 for (i
=0; i
<info
.bpp
; i
+=8) {
1368 *(tile_ptr2
++) = colour
>> i
;
1372 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1373 *(tile_ptr2
++) = colour
>> i
;
1378 tile_ptr
+= info
.pitch
;
1380 draw_hardware_cursor(xc
, yc
, &info
);
1381 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1382 SET_TILE_UPDATED (xti
, yti
, 0);
1388 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1389 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1390 if (GET_TILE_UPDATED (xti
, yti
)) {
1391 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ (xc
<<1));
1392 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1393 for (r
=0; r
<h
; r
++) {
1395 tile_ptr2
= tile_ptr
;
1396 for (c
=0; c
<w
; c
++) {
1397 colour
= *(vid_ptr2
++);
1398 colour
|= *(vid_ptr2
++) << 8;
1399 colour
= MAKE_COLOUR(
1400 colour
& 0x001f, 5, info
.blue_shift
, info
.blue_mask
,
1401 colour
& 0x07e0, 11, info
.green_shift
, info
.green_mask
,
1402 colour
& 0xf800, 16, info
.red_shift
, info
.red_mask
);
1403 if (info
.is_little_endian
) {
1404 for (i
=0; i
<info
.bpp
; i
+=8) {
1405 *(tile_ptr2
++) = colour
>> i
;
1409 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1410 *(tile_ptr2
++) = colour
>> i
;
1415 tile_ptr
+= info
.pitch
;
1417 draw_hardware_cursor(xc
, yc
, &info
);
1418 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1419 SET_TILE_UPDATED (xti
, yti
, 0);
1425 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1426 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1427 if (GET_TILE_UPDATED (xti
, yti
)) {
1428 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ 3*xc
);
1429 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1430 for (r
=0; r
<h
; r
++) {
1432 tile_ptr2
= tile_ptr
;
1433 for (c
=0; c
<w
; c
++) {
1434 blue
= *(vid_ptr2
++);
1435 green
= *(vid_ptr2
++);
1436 red
= *(vid_ptr2
++);
1437 colour
= MAKE_COLOUR(
1438 red
, 8, info
.red_shift
, info
.red_mask
,
1439 green
, 8, info
.green_shift
, info
.green_mask
,
1440 blue
, 8, info
.blue_shift
, info
.blue_mask
);
1441 if (info
.is_little_endian
) {
1442 for (i
=0; i
<info
.bpp
; i
+=8) {
1443 *(tile_ptr2
++) = colour
>> i
;
1447 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1448 *(tile_ptr2
++) = colour
>> i
;
1453 tile_ptr
+= info
.pitch
;
1455 draw_hardware_cursor(xc
, yc
, &info
);
1456 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1457 SET_TILE_UPDATED (xti
, yti
, 0);
1463 for (yc
=0, yti
= 0; yc
<height
; yc
+=Y_TILESIZE
, yti
++) {
1464 for (xc
=0, xti
= 0; xc
<width
; xc
+=X_TILESIZE
, xti
++) {
1465 if (GET_TILE_UPDATED (xti
, yti
)) {
1466 vid_ptr
= BX_CIRRUS_THIS disp_ptr
+ (yc
* pitch
+ (xc
<<2));
1467 tile_ptr
= bx_gui
->graphics_tile_get(xc
, yc
, &w
, &h
);
1468 for (r
=0; r
<h
; r
++) {
1470 tile_ptr2
= tile_ptr
;
1471 for (c
=0; c
<w
; c
++) {
1472 blue
= *(vid_ptr2
++);
1473 green
= *(vid_ptr2
++);
1474 red
= *(vid_ptr2
++);
1476 colour
= MAKE_COLOUR(
1477 red
, 8, info
.red_shift
, info
.red_mask
,
1478 green
, 8, info
.green_shift
, info
.green_mask
,
1479 blue
, 8, info
.blue_shift
, info
.blue_mask
);
1480 if (info
.is_little_endian
) {
1481 for (i
=0; i
<info
.bpp
; i
+=8) {
1482 *(tile_ptr2
++) = colour
>> i
;
1486 for (i
=info
.bpp
-8; i
>-8; i
-=8) {
1487 *(tile_ptr2
++) = colour
>> i
;
1492 tile_ptr
+= info
.pitch
;
1494 draw_hardware_cursor(xc
, yc
, &info
);
1495 bx_gui
->graphics_tile_update_in_place(xc
, yc
, w
, h
);
1496 SET_TILE_UPDATED (xti
, yti
, 0);
1505 BX_PANIC(("cannot get svga tile info"));
1509 void bx_svga_cirrus_c::update_bank_ptr(Bit8u bank_index
)
1514 if (BX_CIRRUS_THIS
banking_is_dual())
1515 offset
= BX_CIRRUS_THIS control
.reg
[0x09 + bank_index
];
1517 offset
= BX_CIRRUS_THIS control
.reg
[0x09];
1519 if (BX_CIRRUS_THIS
banking_granularity_is_16k())
1524 if (BX_CIRRUS_THIS s
.memsize
<= offset
) {
1526 BX_ERROR(("bank offset %08x is invalid",offset
));
1528 limit
= BX_CIRRUS_THIS s
.memsize
- offset
;
1531 if (!BX_CIRRUS_THIS
banking_is_dual() && (bank_index
!= 0)) {
1532 if (limit
> 0x8000) {
1541 BX_CIRRUS_THIS bank_base
[bank_index
] = offset
;
1542 BX_CIRRUS_THIS bank_limit
[bank_index
] = limit
;
1544 BX_CIRRUS_THIS bank_base
[bank_index
] = 0;
1545 BX_CIRRUS_THIS bank_limit
[bank_index
] = 0;
1549 Bit8u
bx_svga_cirrus_c::svga_read_crtc(Bit32u address
, unsigned index
)
1589 return (BX_CIRRUS_THIS s
.attribute_ctrl
.address
& 0x3f);
1591 BX_DEBUG(("CRTC index 0x%02x is unknown(read)", index
));
1595 if (index
<= VGA_CRTC_MAX
) {
1596 return VGA_READ(address
,1);
1599 if (index
<= CIRRUS_CRTC_MAX
) {
1600 return BX_CIRRUS_THIS crtc
.reg
[index
];
1606 void bx_svga_cirrus_c::svga_write_crtc(Bit32u address
, unsigned index
, Bit8u value
)
1608 BX_DEBUG(("crtc: index 0x%02x write 0x%02x", index
, (unsigned)value
));
1610 bx_bool update_pitch
= 0;
1636 case 0x0c: // VGA (display offset 0x00ff00)
1637 case 0x0d: // VGA (display offset 0x0000ff)
1639 case 0x1A: // 0x01: interlaced video mode
1640 case 0x1D: // 0x80: offset 0x080000 (>=CLGD5434)
1641 BX_CIRRUS_THIS svga_needs_update_mode
= true;
1645 case 0x1B: // 0x01: offset 0x010000, 0x0c: offset 0x060000
1654 BX_DEBUG(("CRTC index 0x%02x is unknown(write 0x%02x)", index
, (unsigned)value
));
1658 if (index
<= CIRRUS_CRTC_MAX
) {
1659 BX_CIRRUS_THIS crtc
.reg
[index
] = value
;
1661 if (index
<= VGA_CRTC_MAX
) {
1662 VGA_WRITE(address
,value
,1);
1666 BX_CIRRUS_THIS svga_pitch
= (BX_CIRRUS_THIS crtc
.reg
[0x13] << 3) | ((BX_CIRRUS_THIS crtc
.reg
[0x1b] & 0x10) << 7);
1667 BX_CIRRUS_THIS svga_needs_update_mode
= true;
1671 Bit8u
bx_svga_cirrus_c::svga_read_sequencer(Bit32u address
, unsigned index
)
1680 case 0x6: // cirrus unlock extensions
1681 case 0x7: // cirrus extended sequencer mode
1682 case 0xf: // cirrus dram control
1683 case 0x12: // graphics cursor attribute
1684 case 0x13: // graphics cursor pattern address offset
1685 case 0x17: // configuration readback & extended control
1687 case 0x10: // cursor xpos << 5 (index & 0x3f)
1695 return BX_CIRRUS_THIS sequencer
.reg
[0x10];
1696 case 0x11: // cursor ypos << 5 (index & 0x3f)
1704 return BX_CIRRUS_THIS sequencer
.reg
[0x11];
1706 BX_DEBUG(("sequencer index 0x%02x is unknown(read)", index
));
1710 if (index
<= VGA_SEQENCER_MAX
) {
1711 return VGA_READ(address
,1);
1714 if (index
<= CIRRUS_SEQENCER_MAX
) {
1715 return BX_CIRRUS_THIS sequencer
.reg
[index
];
1721 void bx_svga_cirrus_c::svga_write_sequencer(Bit32u address
, unsigned index
, Bit8u value
)
1723 BX_DEBUG(("sequencer: index 0x%02x write 0x%02x", index
, (unsigned)value
));
1725 bx_bool update_cursor
= 0;
1728 x
= BX_CIRRUS_THIS hw_cursor
.x
;
1729 y
= BX_CIRRUS_THIS hw_cursor
.y
;
1730 size
= BX_CIRRUS_THIS hw_cursor
.size
;
1739 BX_CIRRUS_THIS svga_needs_update_mode
= true;
1741 case 0x6: // cirrus unlock extensions
1743 if (value
== 0x12) {
1744 BX_CIRRUS_THIS svga_unlock_special
= true;
1745 BX_CIRRUS_THIS sequencer
.reg
[0x6] = 0x12;
1748 BX_CIRRUS_THIS svga_unlock_special
= false;
1749 BX_CIRRUS_THIS sequencer
.reg
[0x6] = 0x0f;
1752 case 0x7: // cirrus extended sequencer mode
1753 if (value
!= BX_CIRRUS_THIS sequencer
.reg
[0x7]) {
1754 BX_CIRRUS_THIS svga_needs_update_mode
= true;
1759 case 0x0a: // cirrus scratch reg 1
1771 case 0x10: // cursor xpos << 5 (index & 0x3f)
1779 BX_CIRRUS_THIS sequencer
.reg
[0x10] = value
;
1780 x
= BX_CIRRUS_THIS hw_cursor
.x
;
1781 BX_CIRRUS_THIS hw_cursor
.x
= (value
<< 3) | (index
>> 5);
1784 case 0x11: // cursor ypos << 5 (index & 0x3f)
1792 BX_CIRRUS_THIS sequencer
.reg
[0x11] = value
;
1793 y
= BX_CIRRUS_THIS hw_cursor
.y
;
1794 BX_CIRRUS_THIS hw_cursor
.y
= (value
<< 3) | (index
>> 5);
1798 size
= BX_CIRRUS_THIS hw_cursor
.size
;
1799 if (value
& CIRRUS_CURSOR_SHOW
) {
1800 if (value
& CIRRUS_CURSOR_LARGE
) {
1801 BX_CIRRUS_THIS hw_cursor
.size
= 64;
1804 BX_CIRRUS_THIS hw_cursor
.size
= 32;
1808 BX_CIRRUS_THIS hw_cursor
.size
= 0;
1816 value
= (BX_CIRRUS_THIS sequencer
.reg
[0x17] & 0x38) | (value
& 0xc7);
1819 BX_DEBUG(("sequencer index 0x%02x is unknown(write 0x%02x)", index
, (unsigned)value
));
1823 if (update_cursor
) {
1824 BX_CIRRUS_THIS
redraw_area(x
, y
, size
, size
);
1825 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
);
1828 if (index
<= CIRRUS_SEQENCER_MAX
) {
1829 BX_CIRRUS_THIS sequencer
.reg
[index
] = value
;
1831 if (index
<= VGA_SEQENCER_MAX
) {
1832 VGA_WRITE(address
,value
,1);
1836 Bit8u
bx_svga_cirrus_c::svga_read_control(Bit32u address
, unsigned index
)
1840 return BX_CIRRUS_THIS control
.shadow_reg0
;
1842 return BX_CIRRUS_THIS control
.shadow_reg1
;
1844 return BX_CIRRUS_THIS control
.reg
[index
];
1852 case 0x09: // bank offset #0
1853 case 0x0A: // bank offset #1
1857 case 0x10: // BGCOLOR 0x0000ff00
1858 case 0x11: // FGCOLOR 0x0000ff00
1859 case 0x12: // BGCOLOR 0x00ff0000
1860 case 0x13: // FGCOLOR 0x00ff0000
1861 case 0x14: // BGCOLOR 0xff000000
1862 case 0x15: // FGCOLOR 0xff000000
1865 case 0x20: // BLT WIDTH 0x0000ff
1866 case 0x21: // BLT WIDTH 0x001f00
1867 case 0x22: // BLT HEIGHT 0x0000ff
1868 case 0x23: // BLT HEIGHT 0x001f00
1869 case 0x24: // BLT DEST PITCH 0x0000ff
1870 case 0x25: // BLT DEST PITCH 0x001f00
1871 case 0x26: // BLT SRC PITCH 0x0000ff
1872 case 0x27: // BLT SRC PITCH 0x001f00
1873 case 0x28: // BLT DEST ADDR 0x0000ff
1874 case 0x29: // BLT DEST ADDR 0x00ff00
1875 case 0x2a: // BLT DEST ADDR 0x3f0000
1876 case 0x2c: // BLT SRC ADDR 0x0000ff
1877 case 0x2d: // BLT SRC ADDR 0x00ff00
1878 case 0x2e: // BLT SRC ADDR 0x3f0000
1879 case 0x2f: // BLT WRITE MASK
1880 case 0x30: // BLT MODE
1881 case 0x31: // BLT STATUS
1882 case 0x32: // RASTER OP
1883 case 0x33: // BLT MODE EXTENSION
1884 case 0x34: // BLT TRANSPARENT COLOR 0x00ff
1885 case 0x35: // BLT TRANSPARENT COLOR 0xff00
1886 case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
1887 case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
1891 BX_DEBUG(("control index 0x%02x is unknown(read)", index
));
1895 if (index
<= VGA_CONTROL_MAX
) {
1896 return VGA_READ(address
,1);
1899 if (index
<= CIRRUS_CONTROL_MAX
) {
1900 return BX_CIRRUS_THIS control
.reg
[index
];
1906 void bx_svga_cirrus_c::svga_write_control(Bit32u address
, unsigned index
, Bit8u value
)
1910 BX_DEBUG(("control: index 0x%02x write 0x%02x", index
, (unsigned)value
));
1914 BX_CIRRUS_THIS control
.shadow_reg0
= value
;
1917 BX_CIRRUS_THIS control
.shadow_reg1
= value
;
1927 BX_CIRRUS_THIS svga_needs_update_mode
= true;
1929 case 0x09: // bank offset #0
1930 case 0x0A: // bank offset #1
1932 BX_CIRRUS_THIS control
.reg
[index
] = value
;
1937 case 0x10: // BGCOLOR 0x0000ff00
1938 case 0x11: // FGCOLOR 0x0000ff00
1939 case 0x12: // BGCOLOR 0x00ff0000
1940 case 0x13: // FGCOLOR 0x00ff0000
1941 case 0x14: // BGCOLOR 0xff000000
1942 case 0x15: // FGCOLOR 0xff000000
1945 case 0x20: // BLT WIDTH 0x0000ff
1947 case 0x21: // BLT WIDTH 0x001f00
1950 case 0x22: // BLT HEIGHT 0x0000ff
1952 case 0x23: // BLT HEIGHT 0x001f00
1955 case 0x24: // BLT DEST PITCH 0x0000ff
1957 case 0x25: // BLT DEST PITCH 0x001f00
1960 case 0x26: // BLT SRC PITCH 0x0000ff
1962 case 0x27: // BLT SRC PITCH 0x001f00
1965 case 0x28: // BLT DEST ADDR 0x0000ff
1967 case 0x29: // BLT DEST ADDR 0x00ff00
1969 case 0x2a: // BLT DEST ADDR 0x3f0000
1970 BX_CIRRUS_THIS control
.reg
[index
] = value
& 0x3f;
1971 if (BX_CIRRUS_THIS control
.reg
[0x31] & CIRRUS_BLT_AUTOSTART
) {
1975 case 0x2b: // BLT DEST ADDR (unused bits)
1977 case 0x2c: // BLT SRC ADDR 0x0000ff
1979 case 0x2d: // BLT SRC ADDR 0x00ff00
1981 case 0x2e: // BLT SRC ADDR 0x3f0000
1984 case 0x2f: // BLT WRITE MASK
1985 if (value
& ~0x1f) {
1986 BX_ERROR(("BLT WRITE MASK support is not complete (value = 0x%02x)", value
));
1989 case 0x30: // BLT MODE
1991 case 0x31: // BLT STATUS/START
1992 old_value
= BX_CIRRUS_THIS control
.reg
[0x31];
1993 BX_CIRRUS_THIS control
.reg
[0x31] = value
;
1994 if (((old_value
& CIRRUS_BLT_RESET
) != 0) &&
1995 ((value
& CIRRUS_BLT_RESET
) == 0)) {
1996 svga_reset_bitblt();
1998 else if (((old_value
& CIRRUS_BLT_START
) == 0) &&
1999 ((value
& CIRRUS_BLT_START
) != 0)) {
2000 BX_CIRRUS_THIS control
.reg
[0x31] |= CIRRUS_BLT_BUSY
;
2004 case 0x32: // RASTER OP
2005 case 0x33: // BLT MODE EXTENSION
2007 case 0x34: // BLT TRANSPARENT COLOR 0x00ff
2008 case 0x35: // BLT TRANSPARENT COLOR 0xff00
2009 case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
2010 case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
2012 BX_DEBUG(("control index 0x%02x is unknown(write 0x%02x)", index
, (unsigned)value
));
2016 if (index
<= CIRRUS_CONTROL_MAX
) {
2017 BX_CIRRUS_THIS control
.reg
[index
] = value
;
2019 if (index
<= VGA_CONTROL_MAX
) {
2020 VGA_WRITE(address
,value
,1);
2024 Bit8u
bx_svga_cirrus_c::svga_mmio_vga_read(Bit32u address
)
2027 // bx_bool svga_unlock_special_old = BX_CIRRUS_THIS svga_unlock_special;
2029 BX_DEBUG(("MMIO vga read - address 0x%04x, value 0x%02x",address
,value
));
2031 // BX_CIRRUS_THIS svga_unlock_special = true;
2033 #if BX_USE_CIRRUS_SMF
2034 value
= (Bit8u
)svga_read_handler(theSvga
,0x3c0+address
,1);
2035 #else // BX_USE_CIRRUS_SMF
2036 value
= (Bit8u
)svga_read(0x3c0+address
,1);
2037 #endif // BX_USE_CIRRUS_SMF
2039 // BX_CIRRUS_THIS svga_unlock_special = svga_unlock_special_old;
2043 void bx_svga_cirrus_c::svga_mmio_vga_write(Bit32u address
,Bit8u value
)
2045 // bx_bool svga_unlock_special_old = BX_CIRRUS_THIS svga_unlock_special;
2047 BX_DEBUG(("MMIO vga write - address 0x%04x, value 0x%02x",address
,value
));
2049 // BX_CIRRUS_THIS svga_unlock_special = true;
2051 #if BX_USE_CIRRUS_SMF
2052 svga_write_handler(theSvga
,0x3c0+address
,value
,1);
2053 #else // BX_USE_CIRRUS_SMF
2054 svga_write(0x3c0+address
,value
,1);
2055 #endif // BX_USE_CIRRUS_SMF
2057 /* switch (BX_CIRRUS_THIS sequencer.reg[0x06]) {
2059 svga_unlock_special_old = false;
2062 svga_unlock_special_old = true;
2066 BX_CIRRUS_THIS svga_unlock_special = svga_unlock_special_old;*/
2069 Bit8u
bx_svga_cirrus_c::svga_mmio_blt_read(Bit32u address
)
2074 case (CLGD543x_MMIO_BLTBGCOLOR
+0):
2075 value
= BX_CIRRUS_THIS control
.shadow_reg0
;
2077 case (CLGD543x_MMIO_BLTBGCOLOR
+1):
2078 value
= svga_read_control(0x3cf,0x10);
2080 case (CLGD543x_MMIO_BLTBGCOLOR
+2):
2081 value
= svga_read_control(0x3cf,0x12);
2083 case (CLGD543x_MMIO_BLTBGCOLOR
+3):
2084 value
= svga_read_control(0x3cf,0x14);
2086 case (CLGD543x_MMIO_BLTFGCOLOR
+0):
2087 value
= BX_CIRRUS_THIS control
.shadow_reg1
;
2089 case (CLGD543x_MMIO_BLTFGCOLOR
+1):
2090 value
= svga_read_control(0x3cf,0x11);
2092 case (CLGD543x_MMIO_BLTFGCOLOR
+2):
2093 value
= svga_read_control(0x3cf,0x13);
2095 case (CLGD543x_MMIO_BLTFGCOLOR
+3):
2096 value
= svga_read_control(0x3cf,0x15);
2098 case (CLGD543x_MMIO_BLTWIDTH
+0):
2099 value
= svga_read_control(0x3cf,0x20);
2101 case (CLGD543x_MMIO_BLTWIDTH
+1):
2102 value
= svga_read_control(0x3cf,0x21);
2104 case (CLGD543x_MMIO_BLTHEIGHT
+0):
2105 value
= svga_read_control(0x3cf,0x22);
2107 case (CLGD543x_MMIO_BLTHEIGHT
+1):
2108 value
= svga_read_control(0x3cf,0x23);
2110 case (CLGD543x_MMIO_BLTDESTPITCH
+0):
2111 value
= svga_read_control(0x3cf,0x24);
2113 case (CLGD543x_MMIO_BLTDESTPITCH
+1):
2114 value
= svga_read_control(0x3cf,0x25);
2116 case (CLGD543x_MMIO_BLTSRCPITCH
+0):
2117 value
= svga_read_control(0x3cf,0x26);
2119 case (CLGD543x_MMIO_BLTSRCPITCH
+1):
2120 value
= svga_read_control(0x3cf,0x27);
2122 case (CLGD543x_MMIO_BLTDESTADDR
+0):
2123 value
= svga_read_control(0x3cf,0x28);
2125 case (CLGD543x_MMIO_BLTDESTADDR
+1):
2126 value
= svga_read_control(0x3cf,0x29);
2128 case (CLGD543x_MMIO_BLTDESTADDR
+2):
2129 value
= svga_read_control(0x3cf,0x2a);
2131 case (CLGD543x_MMIO_BLTDESTADDR
+3):
2132 value
= svga_read_control(0x3cf,0x2b);
2134 case (CLGD543x_MMIO_BLTSRCADDR
+0):
2135 value
= svga_read_control(0x3cf,0x2c);
2137 case (CLGD543x_MMIO_BLTSRCADDR
+1):
2138 value
= svga_read_control(0x3cf,0x2d);
2140 case (CLGD543x_MMIO_BLTSRCADDR
+2):
2141 value
= svga_read_control(0x3cf,0x2e);
2143 case CLGD543x_MMIO_BLTWRITEMASK
:
2144 value
= svga_read_control(0x3cf,0x2f);
2146 case CLGD543x_MMIO_BLTMODE
:
2147 value
= svga_read_control(0x3cf,0x30);
2149 case CLGD543x_MMIO_BLTROP
:
2150 value
= svga_read_control(0x3cf,0x32);
2152 case CLGD543x_MMIO_BLTMODEEXT
:
2153 value
= svga_read_control(0x3cf,0x33);
2155 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+0):
2156 value
= svga_read_control(0x3cf,0x34);
2158 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+1):
2159 value
= svga_read_control(0x3cf,0x35);
2161 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+2):
2162 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2164 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+3):
2165 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2167 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+0):
2168 value
= svga_read_control(0x3cf,0x38);
2170 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+1):
2171 value
= svga_read_control(0x3cf,0x39);
2173 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+2):
2174 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2176 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+3):
2177 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2179 case CLGD543x_MMIO_BLTSTATUS
:
2180 value
= svga_read_control(0x3cf,0x31);
2183 BX_ERROR(("MMIO blt read - address 0x%04x",address
));
2187 BX_DEBUG(("MMIO blt read - address 0x%04x, value 0x%02x",address
,value
));
2192 void bx_svga_cirrus_c::svga_mmio_blt_write(Bit32u address
,Bit8u value
)
2194 BX_DEBUG(("MMIO blt write - address 0x%04x, value 0x%02x",address
,value
));
2197 case (CLGD543x_MMIO_BLTBGCOLOR
+0):
2198 BX_CIRRUS_THIS control
.shadow_reg0
= value
;
2200 case (CLGD543x_MMIO_BLTBGCOLOR
+1):
2201 svga_write_control(0x3cf,0x10,value
);
2203 case (CLGD543x_MMIO_BLTBGCOLOR
+2):
2204 svga_write_control(0x3cf,0x12,value
);
2206 case (CLGD543x_MMIO_BLTBGCOLOR
+3):
2207 svga_write_control(0x3cf,0x14,value
);
2209 case (CLGD543x_MMIO_BLTFGCOLOR
+0):
2210 BX_CIRRUS_THIS control
.shadow_reg1
= value
;
2212 case (CLGD543x_MMIO_BLTFGCOLOR
+1):
2213 svga_write_control(0x3cf,0x11,value
);
2215 case (CLGD543x_MMIO_BLTFGCOLOR
+2):
2216 svga_write_control(0x3cf,0x13,value
);
2218 case (CLGD543x_MMIO_BLTFGCOLOR
+3):
2219 svga_write_control(0x3cf,0x15,value
);
2221 case (CLGD543x_MMIO_BLTWIDTH
+0):
2222 svga_write_control(0x3cf,0x20,value
);
2224 case (CLGD543x_MMIO_BLTWIDTH
+1):
2225 svga_write_control(0x3cf,0x21,value
);
2227 case (CLGD543x_MMIO_BLTHEIGHT
+0):
2228 svga_write_control(0x3cf,0x22,value
);
2230 case (CLGD543x_MMIO_BLTHEIGHT
+1):
2231 svga_write_control(0x3cf,0x23,value
);
2233 case (CLGD543x_MMIO_BLTDESTPITCH
+0):
2234 svga_write_control(0x3cf,0x24,value
);
2236 case (CLGD543x_MMIO_BLTDESTPITCH
+1):
2237 svga_write_control(0x3cf,0x25,value
);
2239 case (CLGD543x_MMIO_BLTSRCPITCH
+0):
2240 svga_write_control(0x3cf,0x26,value
);
2242 case (CLGD543x_MMIO_BLTSRCPITCH
+1):
2243 svga_write_control(0x3cf,0x27,value
);
2245 case (CLGD543x_MMIO_BLTDESTADDR
+0):
2246 svga_write_control(0x3cf,0x28,value
);
2248 case (CLGD543x_MMIO_BLTDESTADDR
+1):
2249 svga_write_control(0x3cf,0x29,value
);
2251 case (CLGD543x_MMIO_BLTDESTADDR
+2):
2252 svga_write_control(0x3cf,0x2a,value
);
2254 case (CLGD543x_MMIO_BLTDESTADDR
+3):
2255 svga_write_control(0x3cf,0x2b,value
);
2257 case (CLGD543x_MMIO_BLTSRCADDR
+0):
2258 svga_write_control(0x3cf,0x2c,value
);
2260 case (CLGD543x_MMIO_BLTSRCADDR
+1):
2261 svga_write_control(0x3cf,0x2d,value
);
2263 case (CLGD543x_MMIO_BLTSRCADDR
+2):
2264 svga_write_control(0x3cf,0x2e,value
);
2266 case CLGD543x_MMIO_BLTWRITEMASK
:
2267 svga_write_control(0x3cf,0x2f,value
);
2269 case CLGD543x_MMIO_BLTMODE
:
2270 svga_write_control(0x3cf,0x30,value
);
2272 case CLGD543x_MMIO_BLTMODE
+1:
2273 // unused ??? - ignored for now
2275 case CLGD543x_MMIO_BLTROP
:
2276 svga_write_control(0x3cf,0x32,value
);
2278 case CLGD543x_MMIO_BLTMODEEXT
:
2279 svga_write_control(0x3cf,0x33,value
);
2281 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+0):
2282 svga_write_control(0x3cf,0x34,value
);
2284 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+1):
2285 svga_write_control(0x3cf,0x35,value
);
2287 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+2):
2288 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2290 case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR
+3):
2291 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
2293 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+0):
2294 svga_write_control(0x3cf,0x38,value
);
2296 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+1):
2297 svga_write_control(0x3cf,0x39,value
);
2299 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+2):
2300 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2302 case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK
+3):
2303 BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
2305 case CLGD543x_MMIO_BLTSTATUS
:
2306 svga_write_control(0x3cf,0x31,value
);
2309 BX_ERROR(("MMIO blt write - address 0x%04x, value 0x%02x",address
,value
));
2315 /////////////////////////////////////////////////////////////////////////
2319 /////////////////////////////////////////////////////////////////////////
2323 void bx_svga_cirrus_c::svga_init_pcihandlers(void)
2327 Bit8u devfunc
= 0x00;
2328 DEV_register_pci_handlers(BX_CIRRUS_THIS_PTR
,
2329 &devfunc
, "cirrus", "SVGA Cirrus PCI");
2331 for (i
=0; i
<256; i
++) {
2332 BX_CIRRUS_THIS pci_conf
[i
] = 0x0;
2335 WriteHostWordToLittleEndian(
2336 &BX_CIRRUS_THIS pci_conf
[0x00], PCI_VENDOR_CIRRUS
);
2337 WriteHostWordToLittleEndian(
2338 &BX_CIRRUS_THIS pci_conf
[0x02], PCI_DEVICE_CLGD5446
);
2339 WriteHostWordToLittleEndian(
2340 &BX_CIRRUS_THIS pci_conf
[0x04],
2341 (PCI_COMMAND_IOACCESS
| PCI_COMMAND_MEMACCESS
));
2342 WriteHostDWordToLittleEndian(
2343 &BX_CIRRUS_THIS pci_conf
[0x10],
2344 (PCI_MAP_MEM
| PCI_MAP_MEMFLAGS_32BIT
| PCI_MAP_MEMFLAGS_CACHEABLE
));
2345 WriteHostDWordToLittleEndian(
2346 &BX_CIRRUS_THIS pci_conf
[0x14],
2347 (PCI_MAP_MEM
| PCI_MAP_MEMFLAGS_32BIT
));
2348 BX_CIRRUS_THIS pci_conf
[0x0a] = PCI_CLASS_SUB_VGA
;
2349 BX_CIRRUS_THIS pci_conf
[0x0b] = PCI_CLASS_BASE_DISPLAY
;
2350 BX_CIRRUS_THIS pci_conf
[0x0e] = PCI_CLASS_HEADERTYPE_00h
;
2352 BX_CIRRUS_THIS pci_memaddr
= 0;
2353 BX_CIRRUS_THIS pci_mmioaddr
= 0;
2356 Bit32u
bx_svga_cirrus_c::pci_read_handler(Bit8u address
, unsigned io_len
)
2359 BX_PANIC(("pci_read: io_len > 4!"));
2362 if (((unsigned)address
+ io_len
) > 256) {
2363 BX_PANIC(("pci_read: (address + io_len) > 256!"));
2368 for (unsigned i
= 0; i
< io_len
; i
++) {
2369 ret
|= (Bit32u
)(BX_CIRRUS_THIS pci_conf
[address
+ i
]) << (i
*8);
2372 BX_DEBUG(("pci_read: address 0x%02x, io_len 0x%02x, value 0x%x",
2373 (unsigned)address
, (unsigned)io_len
, (unsigned)ret
));
2378 void bx_svga_cirrus_c::pci_write_handler(Bit8u address
, Bit32u value
, unsigned io_len
)
2381 unsigned write_addr
;
2382 Bit8u new_value
, old_value
;
2383 bx_bool baseaddr0_change
= 0;
2384 bx_bool baseaddr1_change
= 0;
2386 BX_DEBUG(("pci_write: address 0x%02x, io_len 0x%02x, value 0x%x",
2387 (unsigned)address
, (unsigned)io_len
, (unsigned)value
));
2389 if ((address
> 0x17) && (address
< 0x34))
2392 for (i
= 0; i
< io_len
; i
++) {
2393 write_addr
= address
+ i
;
2394 old_value
= BX_CIRRUS_THIS pci_conf
[write_addr
];
2395 new_value
= (Bit8u
)(value
& 0xff);
2396 switch (write_addr
) {
2397 case 0x04: // command bit0-7
2398 new_value
&= PCI_COMMAND_IOACCESS
| PCI_COMMAND_MEMACCESS
;
2399 new_value
|= old_value
& ~(PCI_COMMAND_IOACCESS
| PCI_COMMAND_MEMACCESS
);
2401 case 0x05: // command bit8-15
2402 new_value
= old_value
;
2404 case 0x06: // status bit0-7
2405 new_value
= old_value
& (~new_value
);
2407 case 0x07: // status bit8-15
2408 new_value
= old_value
& (~new_value
);
2411 case 0x10: // base address #0
2412 new_value
= (new_value
& 0xf0) | (old_value
& 0x0f);
2413 case 0x11: case 0x12: case 0x13:
2414 baseaddr0_change
|= (old_value
!= new_value
);
2416 case 0x14: // base address #1
2417 new_value
= (new_value
& 0xf0) | (old_value
& 0x0f);
2418 case 0x15: case 0x16: case 0x17:
2419 baseaddr1_change
|= (old_value
!= new_value
);
2423 case 0x00: case 0x01: // vendor
2424 case 0x02: case 0x03: // device
2425 case 0x08: // revision
2426 case 0x09: case 0x0a: case 0x0b: // class
2427 case 0x0e: // header type
2428 case 0x0f: // built-in self test(unimplemented)
2429 new_value
= old_value
;
2434 BX_CIRRUS_THIS pci_conf
[write_addr
] = new_value
;
2437 if (baseaddr0_change
) {
2438 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR
, cirrus_mem_read_handler
,
2439 cirrus_mem_write_handler
,
2440 &BX_CIRRUS_THIS pci_memaddr
,
2441 &BX_CIRRUS_THIS pci_conf
[0x10],
2443 BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_memaddr
));
2446 if (baseaddr1_change
) {
2447 if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR
, cirrus_mem_read_handler
,
2448 cirrus_mem_write_handler
,
2449 &BX_CIRRUS_THIS pci_mmioaddr
,
2450 &BX_CIRRUS_THIS pci_conf
[0x14],
2451 CIRRUS_PNPMMIO_SIZE
)) {
2452 BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_mmioaddr
));
2458 #endif // BX_SUPPORT_PCI
2460 /////////////////////////////////////////////////////////////////////////
2464 /////////////////////////////////////////////////////////////////////////
2466 void bx_svga_cirrus_c::svga_reset_bitblt(void)
2468 BX_CIRRUS_THIS control
.reg
[0x31] &= ~(CIRRUS_BLT_START
|CIRRUS_BLT_BUSY
|CIRRUS_BLT_FIFOUSED
);
2469 BX_CIRRUS_THIS bitblt
.rop_handler
= NULL
;
2470 BX_CIRRUS_THIS bitblt
.src
= NULL
;
2471 BX_CIRRUS_THIS bitblt
.dst
= NULL
;
2472 BX_CIRRUS_THIS bitblt
.memsrc_ptr
= NULL
;
2473 BX_CIRRUS_THIS bitblt
.memsrc_endptr
= NULL
;
2474 BX_CIRRUS_THIS bitblt
.memsrc_needed
= 0;
2475 BX_CIRRUS_THIS bitblt
.memdst_ptr
= NULL
;
2476 BX_CIRRUS_THIS bitblt
.memdst_endptr
= NULL
;
2477 BX_CIRRUS_THIS bitblt
.memdst_needed
= 0;
2480 void bx_svga_cirrus_c::svga_bitblt()
2488 ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x20],tmp16
);
2489 BX_CIRRUS_THIS bitblt
.bltwidth
= ((int)tmp16
& (int)0x1fff) + 1;
2490 ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x22],tmp16
);
2491 BX_CIRRUS_THIS bitblt
.bltheight
= ((int)tmp16
& (int)0x1fff) + 1;
2492 ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x24],tmp16
);
2493 BX_CIRRUS_THIS bitblt
.dstpitch
= (int)tmp16
& (int)0x1fff;
2494 ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x26],tmp16
);
2495 BX_CIRRUS_THIS bitblt
.srcpitch
= (int)tmp16
& (int)0x1fff;
2496 ReadHostDWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x28],tmp32
);
2497 dstaddr
= tmp32
& (BX_CIRRUS_THIS s
.memsize
- 1);
2498 ReadHostDWordFromLittleEndian(&BX_CIRRUS_THIS control
.reg
[0x2c],tmp32
);
2499 srcaddr
= tmp32
& (BX_CIRRUS_THIS s
.memsize
- 1);
2500 BX_CIRRUS_THIS bitblt
.srcaddr
= srcaddr
;
2501 BX_CIRRUS_THIS bitblt
.bltmode
= BX_CIRRUS_THIS control
.reg
[0x30];
2502 BX_CIRRUS_THIS bitblt
.bltmodeext
= BX_CIRRUS_THIS control
.reg
[0x33];
2503 BX_CIRRUS_THIS bitblt
.bltrop
= BX_CIRRUS_THIS control
.reg
[0x32];
2504 offset
= dstaddr
- (BX_CIRRUS_THIS disp_ptr
- BX_CIRRUS_THIS s
.memory
);
2505 BX_CIRRUS_THIS redraw
.x
= (offset
% BX_CIRRUS_THIS bitblt
.dstpitch
) / (BX_CIRRUS_THIS svga_bpp
>> 3);
2506 BX_CIRRUS_THIS redraw
.y
= offset
/ BX_CIRRUS_THIS bitblt
.dstpitch
;
2507 BX_CIRRUS_THIS redraw
.w
= BX_CIRRUS_THIS bitblt
.bltwidth
/ (BX_CIRRUS_THIS svga_bpp
>> 3);
2508 BX_CIRRUS_THIS redraw
.h
= BX_CIRRUS_THIS bitblt
.bltheight
;
2510 BX_DEBUG(("BLT: src:0x%08x,dst 0x%08x,block %ux%u,mode 0x%02x,ROP 0x%02x",
2511 (unsigned)srcaddr
,(unsigned)dstaddr
,
2512 (unsigned)BX_CIRRUS_THIS bitblt
.bltwidth
,(unsigned)BX_CIRRUS_THIS bitblt
.bltheight
,
2513 (unsigned)BX_CIRRUS_THIS bitblt
.bltmode
,(unsigned)BX_CIRRUS_THIS bitblt
.bltrop
));
2514 BX_DEBUG(("BLT: srcpitch:0x%08x,dstpitch 0x%08x,modeext 0x%02x,writemask 0x%02x",
2515 (unsigned)BX_CIRRUS_THIS bitblt
.srcpitch
,
2516 (unsigned)BX_CIRRUS_THIS bitblt
.dstpitch
,
2517 (unsigned)BX_CIRRUS_THIS bitblt
.bltmodeext
,
2518 BX_CIRRUS_THIS control
.reg
[0x2f]));
2520 switch (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_PIXELWIDTHMASK
) {
2521 case CIRRUS_BLTMODE_PIXELWIDTH8
:
2522 BX_CIRRUS_THIS bitblt
.pixelwidth
= 1;
2524 case CIRRUS_BLTMODE_PIXELWIDTH16
:
2525 BX_CIRRUS_THIS bitblt
.pixelwidth
= 2;
2527 case CIRRUS_BLTMODE_PIXELWIDTH24
:
2528 BX_CIRRUS_THIS bitblt
.pixelwidth
= 3;
2530 case CIRRUS_BLTMODE_PIXELWIDTH32
:
2531 BX_CIRRUS_THIS bitblt
.pixelwidth
= 4;
2534 BX_PANIC(("unknown pixel width"));
2538 BX_CIRRUS_THIS bitblt
.bltmode
&= ~CIRRUS_BLTMODE_PIXELWIDTHMASK
;
2540 if ((BX_CIRRUS_THIS bitblt
.bltmode
& (CIRRUS_BLTMODE_MEMSYSSRC
|CIRRUS_BLTMODE_MEMSYSDEST
))
2541 == (CIRRUS_BLTMODE_MEMSYSSRC
|CIRRUS_BLTMODE_MEMSYSDEST
)) {
2542 BX_ERROR(("BLT: memory-to-memory copy is requested, ROP %02x",
2543 (unsigned)BX_CIRRUS_THIS bitblt
.bltrop
));
2547 if ((BX_CIRRUS_THIS bitblt
.bltmodeext
& CIRRUS_BLTMODEEXT_SOLIDFILL
) &&
2548 (BX_CIRRUS_THIS bitblt
.bltmode
& (CIRRUS_BLTMODE_MEMSYSDEST
|
2549 CIRRUS_BLTMODE_TRANSPARENTCOMP
|
2550 CIRRUS_BLTMODE_PATTERNCOPY
|
2551 CIRRUS_BLTMODE_COLOREXPAND
)) ==
2552 (CIRRUS_BLTMODE_PATTERNCOPY
| CIRRUS_BLTMODE_COLOREXPAND
)) {
2553 BX_CIRRUS_THIS bitblt
.rop_handler
= svga_get_fwd_rop_handler(BX_CIRRUS_THIS bitblt
.bltrop
);
2554 BX_CIRRUS_THIS bitblt
.dst
= BX_CIRRUS_THIS s
.memory
+ dstaddr
;
2558 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_BACKWARDS
) {
2559 BX_CIRRUS_THIS bitblt
.dstpitch
= -BX_CIRRUS_THIS bitblt
.dstpitch
;
2560 BX_CIRRUS_THIS bitblt
.srcpitch
= -BX_CIRRUS_THIS bitblt
.srcpitch
;
2561 BX_CIRRUS_THIS bitblt
.rop_handler
= svga_get_bkwd_rop_handler(BX_CIRRUS_THIS bitblt
.bltrop
);
2562 BX_CIRRUS_THIS redraw
.x
-= BX_CIRRUS_THIS redraw
.w
;
2563 BX_CIRRUS_THIS redraw
.y
-= BX_CIRRUS_THIS redraw
.h
;
2565 BX_CIRRUS_THIS bitblt
.rop_handler
= svga_get_fwd_rop_handler(BX_CIRRUS_THIS bitblt
.bltrop
);
2568 BX_DEBUG(("BLT redraw: x = %d, y = %d, w = %d, h = %d", BX_CIRRUS_THIS redraw
.x
,
2569 BX_CIRRUS_THIS redraw
.y
, BX_CIRRUS_THIS redraw
.w
, BX_CIRRUS_THIS redraw
.h
));
2571 // setup bitblt engine.
2572 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_MEMSYSSRC
) {
2573 svga_setup_bitblt_cputovideo(dstaddr
,srcaddr
);
2575 else if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_MEMSYSDEST
) {
2576 svga_setup_bitblt_videotocpu(dstaddr
,srcaddr
);
2579 svga_setup_bitblt_videotovideo(dstaddr
,srcaddr
);
2585 svga_reset_bitblt();
2588 void bx_svga_cirrus_c::svga_setup_bitblt_cputovideo(Bit32u dstaddr
,Bit32u srcaddr
)
2592 BX_CIRRUS_THIS bitblt
.bltmode
&= ~CIRRUS_BLTMODE_MEMSYSSRC
;
2594 BX_CIRRUS_THIS bitblt
.dst
= BX_CIRRUS_THIS s
.memory
+ dstaddr
;
2595 BX_CIRRUS_THIS bitblt
.src
= NULL
;
2597 BX_CIRRUS_THIS bitblt
.memsrc_ptr
= &BX_CIRRUS_THIS bitblt
.memsrc
[0];
2598 BX_CIRRUS_THIS bitblt
.memsrc_endptr
= &BX_CIRRUS_THIS bitblt
.memsrc
[0];
2600 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_PATTERNCOPY
) {
2601 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_COLOREXPAND
) {
2602 BX_CIRRUS_THIS bitblt
.srcpitch
= 8;
2604 BX_CIRRUS_THIS bitblt
.srcpitch
= 8 * 8 * BX_CIRRUS_THIS bitblt
.pixelwidth
;
2606 BX_CIRRUS_THIS bitblt
.memsrc_needed
= BX_CIRRUS_THIS bitblt
.srcpitch
;
2607 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_patterncopy_memsrc_static
;
2609 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_COLOREXPAND
) {
2610 w
= BX_CIRRUS_THIS bitblt
.bltwidth
/ BX_CIRRUS_THIS bitblt
.pixelwidth
;
2611 if (BX_CIRRUS_THIS bitblt
.bltmodeext
& CIRRUS_BLTMODEEXT_DWORDGRANULARITY
) {
2612 BX_CIRRUS_THIS bitblt
.srcpitch
= (w
+ 31) >> 5;
2614 BX_CIRRUS_THIS bitblt
.srcpitch
= (w
+ 7) >> 3;
2616 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_TRANSPARENTCOMP
) {
2617 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_colorexpand_transp_memsrc_static
;
2619 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_simplebitblt_memsrc_static
;
2622 BX_CIRRUS_THIS bitblt
.srcpitch
= (BX_CIRRUS_THIS bitblt
.bltwidth
+ 3) & (~3);
2623 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_simplebitblt_memsrc_static
;
2625 BX_CIRRUS_THIS bitblt
.memsrc_needed
=
2626 BX_CIRRUS_THIS bitblt
.srcpitch
* BX_CIRRUS_THIS bitblt
.bltheight
;
2628 BX_CIRRUS_THIS bitblt
.memsrc_endptr
+= BX_CIRRUS_THIS bitblt
.srcpitch
;
2631 void bx_svga_cirrus_c::svga_setup_bitblt_videotocpu(Bit32u dstaddr
,Bit32u srcaddr
)
2633 BX_ERROR(("BLT: MEMSYSDEST is not implemented"));
2635 BX_CIRRUS_THIS bitblt
.bltmode
&= ~CIRRUS_BLTMODE_MEMSYSDEST
;
2638 BX_CIRRUS_THIS bitblt
.dst
= NULL
;
2639 BX_CIRRUS_THIS bitblt
.src
= BX_CIRRUS_THIS s
.memory
+ srcaddr
;
2641 BX_CIRRUS_THIS bitblt
.memdst_ptr
= &BX_CIRRUS_THIS bitblt
.memdst
[0];
2642 BX_CIRRUS_THIS bitblt
.memdst_endptr
= &BX_CIRRUS_THIS bitblt
.memdst
[0];
2644 BX_CIRRUS_THIS bitblt
.memdst_needed
=
2645 BX_CIRRUS_THIS bitblt
.bltwidth
* BX_CIRRUS_THIS bitblt
.bltheight
;
2646 BX_CIRRUS_THIS bitblt
.memdst_needed
= (BX_CIRRUS_THIS bitblt
.memdst_needed
+ 3) & (~3);
2648 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_PATTERNCOPY
) {
2649 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_patterncopy_memdst_static
;
2652 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_simplebitblt_memdst_static
;
2657 void bx_svga_cirrus_c::svga_setup_bitblt_videotovideo(Bit32u dstaddr
,Bit32u srcaddr
)
2659 BX_CIRRUS_THIS bitblt
.dst
= BX_CIRRUS_THIS s
.memory
+ dstaddr
;
2661 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_PATTERNCOPY
) {
2662 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_patterncopy_static
;
2663 BX_CIRRUS_THIS bitblt
.src
= BX_CIRRUS_THIS s
.memory
+ (srcaddr
& ~0x07);
2665 BX_CIRRUS_THIS bitblt
.bitblt_ptr
= svga_simplebitblt_static
;
2666 BX_CIRRUS_THIS bitblt
.src
= BX_CIRRUS_THIS s
.memory
+ srcaddr
;
2669 (*BX_CIRRUS_THIS bitblt
.bitblt_ptr
)();
2670 svga_reset_bitblt();
2671 BX_CIRRUS_THIS
redraw_area(BX_CIRRUS_THIS redraw
.x
, BX_CIRRUS_THIS redraw
.y
,
2672 BX_CIRRUS_THIS redraw
.w
, BX_CIRRUS_THIS redraw
.h
);
2675 void bx_svga_cirrus_c::svga_colorexpand(Bit8u
*dst
,const Bit8u
*src
,int count
,int pixelwidth
)
2677 BX_DEBUG(("svga_cirrus: COLOR EXPAND"));
2679 switch (pixelwidth
) {
2681 svga_colorexpand_8(dst
,src
,count
);
2684 svga_colorexpand_16(dst
,src
,count
);
2687 svga_colorexpand_24(dst
,src
,count
);
2690 svga_colorexpand_32(dst
,src
,count
);
2693 BX_PANIC(("COLOREXPAND: unknown pixelwidth %u",(unsigned)pixelwidth
));
2698 #if !BX_USE_CIRRUS_SMF
2699 void bx_svga_cirrus_c::svga_colorexpand_8_static(void *this_ptr
,Bit8u
*dst
,const Bit8u
*src
,int count
)
2701 ((bx_svga_cirrus_c
*)this_ptr
)->svga_colorexpand_8(dst
,src
,count
);
2704 void bx_svga_cirrus_c::svga_colorexpand_16_static(void *this_ptr
,Bit8u
*dst
,const Bit8u
*src
,int count
)
2706 ((bx_svga_cirrus_c
*)this_ptr
)->svga_colorexpand_16(dst
,src
,count
);
2709 void bx_svga_cirrus_c::svga_colorexpand_24_static(void *this_ptr
,Bit8u
*dst
,const Bit8u
*src
,int count
)
2711 ((bx_svga_cirrus_c
*)this_ptr
)->svga_colorexpand_24(dst
,src
,count
);
2714 void bx_svga_cirrus_c::svga_colorexpand_32_static(void *this_ptr
,Bit8u
*dst
,const Bit8u
*src
,int count
)
2716 ((bx_svga_cirrus_c
*)this_ptr
)->svga_colorexpand_32(dst
,src
,count
);
2719 #endif // BX_USE_CIRRUS_SMF
2721 void bx_svga_cirrus_c::svga_colorexpand_8(Bit8u
*dst
,const Bit8u
*src
,int count
)
2727 colors
[0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2728 colors
[1] = BX_CIRRUS_THIS control
.shadow_reg1
;
2732 for (int x
= 0; x
< count
; x
++) {
2733 if ((bitmask
& 0xff) == 0) {
2737 *dst
++ = colors
[!!(bits
& bitmask
)];
2742 void bx_svga_cirrus_c::svga_colorexpand_16(Bit8u
*dst
,const Bit8u
*src
,int count
)
2749 colors
[0][0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2750 colors
[0][1] = BX_CIRRUS_THIS control
.reg
[0x10];
2751 colors
[1][0] = BX_CIRRUS_THIS control
.shadow_reg1
;
2752 colors
[1][1] = BX_CIRRUS_THIS control
.reg
[0x11];
2756 for (int x
= 0; x
< count
; x
++) {
2757 if ((bitmask
& 0xff) == 0) {
2761 index
= !!(bits
& bitmask
);
2762 *dst
++ = colors
[index
][0];
2763 *dst
++ = colors
[index
][1];
2768 void bx_svga_cirrus_c::svga_colorexpand_24(Bit8u
*dst
,const Bit8u
*src
,int count
)
2775 colors
[0][0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2776 colors
[0][1] = BX_CIRRUS_THIS control
.reg
[0x10];
2777 colors
[0][2] = BX_CIRRUS_THIS control
.reg
[0x12];
2778 colors
[1][0] = BX_CIRRUS_THIS control
.shadow_reg1
;
2779 colors
[1][1] = BX_CIRRUS_THIS control
.reg
[0x11];
2780 colors
[1][2] = BX_CIRRUS_THIS control
.reg
[0x13];
2784 for (int x
= 0; x
< count
; x
++) {
2785 if ((bitmask
& 0xff) == 0) {
2789 index
= !!(bits
& bitmask
);
2790 *dst
++ = colors
[index
][0];
2791 *dst
++ = colors
[index
][1];
2792 *dst
++ = colors
[index
][2];
2797 void bx_svga_cirrus_c::svga_colorexpand_32(Bit8u
*dst
,const Bit8u
*src
,int count
)
2804 colors
[0][0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2805 colors
[0][1] = BX_CIRRUS_THIS control
.reg
[0x10];
2806 colors
[0][2] = BX_CIRRUS_THIS control
.reg
[0x12];
2807 colors
[0][3] = BX_CIRRUS_THIS control
.reg
[0x14];
2808 colors
[1][0] = BX_CIRRUS_THIS control
.shadow_reg1
;
2809 colors
[1][1] = BX_CIRRUS_THIS control
.reg
[0x11];
2810 colors
[1][2] = BX_CIRRUS_THIS control
.reg
[0x13];
2811 colors
[1][3] = BX_CIRRUS_THIS control
.reg
[0x15];
2815 for (int x
= 0; x
< count
; x
++) {
2816 if ((bitmask
& 0xff) == 0) {
2820 index
= !!(bits
& bitmask
);
2821 *dst
++ = colors
[index
][0];
2822 *dst
++ = colors
[index
][1];
2823 *dst
++ = colors
[index
][2];
2824 *dst
++ = colors
[index
][3];
2829 #if !BX_USE_CIRRUS_SMF
2830 void bx_svga_cirrus_c::svga_patterncopy_static(void *this_ptr
)
2832 ((bx_svga_cirrus_c
*)this_ptr
)->svga_patterncopy();
2835 void bx_svga_cirrus_c::svga_simplebitblt_static(void *this_ptr
)
2837 ((bx_svga_cirrus_c
*)this_ptr
)->svga_simplebitblt();
2840 void bx_svga_cirrus_c::svga_solidfill_static(void *this_ptr
)
2842 ((bx_svga_cirrus_c
*)this_ptr
)->svga_solidfill();
2845 void bx_svga_cirrus_c::svga_patterncopy_memsrc_static(void *this_ptr
)
2847 ((bx_svga_cirrus_c
*)this_ptr
)->svga_patterncopy_memsrc();
2850 void bx_svga_cirrus_c::svga_simplebitblt_memsrc_static(void *this_ptr
)
2852 ((bx_svga_cirrus_c
*)this_ptr
)->svga_simplebitblt_memsrc();
2855 void bx_svga_cirrus_c::svga_colorexpand_transp_memsrc_static(void *this_ptr
)
2857 ((bx_svga_cirrus_c
*)this_ptr
)->svga_colorexpand_transp_memsrc();
2860 #endif // !BX_USE_CIRRUS_SMF
2862 void bx_svga_cirrus_c::svga_patterncopy()
2865 Bit8u work_colorexp
[256];
2867 Bit8u
*dstc
, *srcc
, *src2
;
2868 int x
, y
, pattern_x
, pattern_y
, srcskipleft
;
2869 int patternbytes
= 8 * BX_CIRRUS_THIS bitblt
.pixelwidth
;
2870 int pattern_pitch
= patternbytes
;
2871 int bltbytes
= BX_CIRRUS_THIS bitblt
.bltwidth
;
2872 unsigned bits
, bits_xor
, bitmask
;
2874 if (BX_CIRRUS_THIS bitblt
.pixelwidth
== 3) {
2875 pattern_x
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x1f;
2876 srcskipleft
= pattern_x
/ 3;
2878 srcskipleft
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x07;
2879 pattern_x
= srcskipleft
* BX_CIRRUS_THIS bitblt
.pixelwidth
;
2881 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_COLOREXPAND
) {
2882 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_TRANSPARENTCOMP
) {
2883 if (BX_CIRRUS_THIS bitblt
.bltmodeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
2884 color
[0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2885 color
[1] = BX_CIRRUS_THIS control
.reg
[0x10];
2886 color
[2] = BX_CIRRUS_THIS control
.reg
[0x12];
2887 color
[3] = BX_CIRRUS_THIS control
.reg
[0x14];
2890 color
[0] = BX_CIRRUS_THIS control
.shadow_reg1
;
2891 color
[1] = BX_CIRRUS_THIS control
.reg
[0x11];
2892 color
[2] = BX_CIRRUS_THIS control
.reg
[0x13];
2893 color
[3] = BX_CIRRUS_THIS control
.reg
[0x15];
2897 pattern_y
= BX_CIRRUS_THIS bitblt
.srcaddr
& 0x07;
2898 for (y
= 0; y
< BX_CIRRUS_THIS bitblt
.bltheight
; y
++) {
2899 dst
= BX_CIRRUS_THIS bitblt
.dst
+ pattern_x
;
2900 bitmask
= 0x80 >> srcskipleft
;
2901 bits
= BX_CIRRUS_THIS bitblt
.src
[pattern_y
] ^ bits_xor
;
2902 for (x
= pattern_x
; x
< BX_CIRRUS_THIS bitblt
.bltwidth
; x
+=BX_CIRRUS_THIS bitblt
.pixelwidth
) {
2903 if ((bitmask
& 0xff) == 0) {
2905 bits
= BX_CIRRUS_THIS bitblt
.src
[pattern_y
] ^ bits_xor
;
2907 if (bits
& bitmask
) {
2908 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
2909 dst
, &color
[0], 0, 0, BX_CIRRUS_THIS bitblt
.pixelwidth
, 1);
2911 dst
+= BX_CIRRUS_THIS bitblt
.pixelwidth
;
2914 pattern_y
= (pattern_y
+ 1) & 7;
2915 BX_CIRRUS_THIS bitblt
.dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
2919 svga_colorexpand(work_colorexp
,BX_CIRRUS_THIS bitblt
.src
,8*8,BX_CIRRUS_THIS bitblt
.pixelwidth
);
2920 BX_CIRRUS_THIS bitblt
.src
= work_colorexp
;
2921 BX_CIRRUS_THIS bitblt
.bltmode
&= ~CIRRUS_BLTMODE_COLOREXPAND
;
2924 if (BX_CIRRUS_THIS bitblt
.pixelwidth
== 3) {
2928 if (BX_CIRRUS_THIS bitblt
.bltmode
& ~CIRRUS_BLTMODE_PATTERNCOPY
) {
2929 BX_ERROR(("PATTERNCOPY: unknown bltmode %02x",BX_CIRRUS_THIS bitblt
.bltmode
));
2933 BX_DEBUG(("svga_cirrus: PATTERN COPY"));
2934 dst
= BX_CIRRUS_THIS bitblt
.dst
;
2935 pattern_y
= BX_CIRRUS_THIS bitblt
.srcaddr
& 0x07;
2936 src
= (Bit8u
*)BX_CIRRUS_THIS bitblt
.src
;
2937 for (y
= 0; y
< BX_CIRRUS_THIS bitblt
.bltheight
; y
++) {
2938 srcc
= src
+ pattern_y
* pattern_pitch
;
2939 dstc
= dst
+ pattern_x
;
2940 for (x
= pattern_x
; x
< bltbytes
; x
+= BX_CIRRUS_THIS bitblt
.pixelwidth
) {
2941 src2
= srcc
+ (x
% patternbytes
);
2942 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
2943 dstc
, src2
, 0, 0, BX_CIRRUS_THIS bitblt
.pixelwidth
, 1);
2944 dstc
+= BX_CIRRUS_THIS bitblt
.pixelwidth
;
2946 pattern_y
= (pattern_y
+ 1) & 7;
2947 dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
2951 void bx_svga_cirrus_c::svga_simplebitblt()
2954 Bit8u work_colorexp
[2048];
2957 unsigned bits
, bits_xor
, bitmask
;
2958 int pattern_x
, srcskipleft
;
2960 if (BX_CIRRUS_THIS bitblt
.pixelwidth
== 3) {
2961 pattern_x
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x1f;
2962 srcskipleft
= pattern_x
/ 3;
2964 srcskipleft
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x07;
2965 pattern_x
= srcskipleft
* BX_CIRRUS_THIS bitblt
.pixelwidth
;
2967 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_COLOREXPAND
) {
2968 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_TRANSPARENTCOMP
) {
2969 if (BX_CIRRUS_THIS bitblt
.bltmodeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
2970 color
[0] = BX_CIRRUS_THIS control
.shadow_reg0
;
2971 color
[1] = BX_CIRRUS_THIS control
.reg
[0x10];
2972 color
[2] = BX_CIRRUS_THIS control
.reg
[0x12];
2973 color
[3] = BX_CIRRUS_THIS control
.reg
[0x14];
2976 color
[0] = BX_CIRRUS_THIS control
.shadow_reg1
;
2977 color
[1] = BX_CIRRUS_THIS control
.reg
[0x11];
2978 color
[2] = BX_CIRRUS_THIS control
.reg
[0x13];
2979 color
[3] = BX_CIRRUS_THIS control
.reg
[0x15];
2983 for (y
= 0; y
< BX_CIRRUS_THIS bitblt
.bltheight
; y
++) {
2984 dst
= BX_CIRRUS_THIS bitblt
.dst
+ pattern_x
;
2985 bitmask
= 0x80 >> srcskipleft
;
2986 bits
= *BX_CIRRUS_THIS bitblt
.src
++ ^ bits_xor
;
2987 for (x
= pattern_x
; x
< BX_CIRRUS_THIS bitblt
.bltwidth
; x
+=BX_CIRRUS_THIS bitblt
.pixelwidth
) {
2988 if ((bitmask
& 0xff) == 0) {
2990 bits
= *BX_CIRRUS_THIS bitblt
.src
++ ^ bits_xor
;
2992 if (bits
& bitmask
) {
2993 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
2994 dst
, &color
[0], 0, 0, BX_CIRRUS_THIS bitblt
.pixelwidth
, 1);
2996 dst
+= BX_CIRRUS_THIS bitblt
.pixelwidth
;
2999 BX_CIRRUS_THIS bitblt
.dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
3003 w
= BX_CIRRUS_THIS bitblt
.bltwidth
/ BX_CIRRUS_THIS bitblt
.pixelwidth
;
3004 for (y
= 0; y
< BX_CIRRUS_THIS bitblt
.bltheight
; y
++) {
3005 svga_colorexpand(work_colorexp
,BX_CIRRUS_THIS bitblt
.src
, w
,
3006 BX_CIRRUS_THIS bitblt
.pixelwidth
);
3007 dst
= BX_CIRRUS_THIS bitblt
.dst
+ pattern_x
;
3008 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3009 dst
, work_colorexp
+ pattern_x
, 0, 0,
3010 BX_CIRRUS_THIS bitblt
.bltwidth
- pattern_x
, 1);
3011 BX_CIRRUS_THIS bitblt
.src
+= ((w
+ 7) >> 3);
3012 BX_CIRRUS_THIS bitblt
.dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
3017 if (BX_CIRRUS_THIS bitblt
.bltmode
& ~CIRRUS_BLTMODE_BACKWARDS
) {
3018 BX_ERROR(("SIMPLE BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt
.bltmode
));
3022 BX_DEBUG(("svga_cirrus: BITBLT"));
3023 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3024 BX_CIRRUS_THIS bitblt
.dst
, BX_CIRRUS_THIS bitblt
.src
,
3025 BX_CIRRUS_THIS bitblt
.dstpitch
, BX_CIRRUS_THIS bitblt
.srcpitch
,
3026 BX_CIRRUS_THIS bitblt
.bltwidth
, BX_CIRRUS_THIS bitblt
.bltheight
);
3029 void bx_svga_cirrus_c::svga_solidfill()
3035 BX_DEBUG(("BLT: SOLIDFILL"));
3037 color
[0] = BX_CIRRUS_THIS control
.shadow_reg1
;
3038 color
[1] = BX_CIRRUS_THIS control
.reg
[0x11];
3039 color
[2] = BX_CIRRUS_THIS control
.reg
[0x13];
3040 color
[3] = BX_CIRRUS_THIS control
.reg
[0x15];
3042 for (y
= 0; y
< BX_CIRRUS_THIS bitblt
.bltheight
; y
++) {
3043 dst
= BX_CIRRUS_THIS bitblt
.dst
;
3044 for (x
= 0; x
< BX_CIRRUS_THIS bitblt
.bltwidth
; x
+=BX_CIRRUS_THIS bitblt
.pixelwidth
) {
3045 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3046 dst
, &color
[0], 0, 0, BX_CIRRUS_THIS bitblt
.pixelwidth
, 1);
3047 dst
+= BX_CIRRUS_THIS bitblt
.pixelwidth
;
3049 BX_CIRRUS_THIS bitblt
.dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
3051 BX_CIRRUS_THIS
redraw_area(BX_CIRRUS_THIS redraw
.x
, BX_CIRRUS_THIS redraw
.y
,
3052 BX_CIRRUS_THIS redraw
.w
, BX_CIRRUS_THIS redraw
.h
);
3055 void bx_svga_cirrus_c::svga_patterncopy_memsrc()
3057 BX_INFO(("svga_patterncopy_memsrc() - not tested"));
3059 BX_CIRRUS_THIS bitblt
.src
= &BX_CIRRUS_THIS bitblt
.memsrc
[0];
3061 BX_CIRRUS_THIS bitblt
.memsrc_needed
= 0;
3062 BX_CIRRUS_THIS
redraw_area(BX_CIRRUS_THIS redraw
.x
, BX_CIRRUS_THIS redraw
.y
,
3063 BX_CIRRUS_THIS redraw
.w
, BX_CIRRUS_THIS redraw
.h
);
3066 void bx_svga_cirrus_c::svga_simplebitblt_memsrc()
3068 Bit8u
*srcptr
= &BX_CIRRUS_THIS bitblt
.memsrc
[0];
3069 Bit8u work_colorexp
[2048];
3073 BX_DEBUG(("svga_cirrus: BLT, cpu-to-video"));
3075 if (BX_CIRRUS_THIS bitblt
.pixelwidth
== 3) {
3076 pattern_x
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x1f;
3078 pattern_x
= (BX_CIRRUS_THIS control
.reg
[0x2f] & 0x07) * BX_CIRRUS_THIS bitblt
.pixelwidth
;
3080 if (BX_CIRRUS_THIS bitblt
.bltmode
& CIRRUS_BLTMODE_COLOREXPAND
) {
3081 if (BX_CIRRUS_THIS bitblt
.bltmode
& ~CIRRUS_BLTMODE_COLOREXPAND
) {
3082 BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt
.bltmode
));
3086 w
= BX_CIRRUS_THIS bitblt
.bltwidth
/ BX_CIRRUS_THIS bitblt
.pixelwidth
;
3087 svga_colorexpand(work_colorexp
,srcptr
,w
,BX_CIRRUS_THIS bitblt
.pixelwidth
);
3088 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3089 BX_CIRRUS_THIS bitblt
.dst
+ pattern_x
, work_colorexp
+ pattern_x
, 0, 0,
3090 BX_CIRRUS_THIS bitblt
.bltwidth
- pattern_x
, 1);
3092 if (BX_CIRRUS_THIS bitblt
.bltmode
!= 0) {
3093 BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt
.bltmode
));
3096 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3097 BX_CIRRUS_THIS bitblt
.dst
, srcptr
, 0, 0,
3098 BX_CIRRUS_THIS bitblt
.bltwidth
, 1);
3102 void bx_svga_cirrus_c::svga_colorexpand_transp_memsrc()
3104 Bit8u
*src
= &BX_CIRRUS_THIS bitblt
.memsrc
[0];
3106 int x
, pattern_x
, srcskipleft
;
3108 unsigned bits
, bits_xor
, bitmask
;
3110 BX_DEBUG(("BLT, cpu-to-video, transparent"));
3112 if (BX_CIRRUS_THIS bitblt
.pixelwidth
== 3) {
3113 pattern_x
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x1f;
3114 srcskipleft
= pattern_x
/ 3;
3116 srcskipleft
= BX_CIRRUS_THIS control
.reg
[0x2f] & 0x07;
3117 pattern_x
= srcskipleft
* BX_CIRRUS_THIS bitblt
.pixelwidth
;
3119 if (BX_CIRRUS_THIS bitblt
.bltmodeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
3120 color
[0] = BX_CIRRUS_THIS control
.shadow_reg0
;
3121 color
[1] = BX_CIRRUS_THIS control
.reg
[0x10];
3122 color
[2] = BX_CIRRUS_THIS control
.reg
[0x12];
3123 color
[3] = BX_CIRRUS_THIS control
.reg
[0x14];
3126 color
[0] = BX_CIRRUS_THIS control
.shadow_reg1
;
3127 color
[1] = BX_CIRRUS_THIS control
.reg
[0x11];
3128 color
[2] = BX_CIRRUS_THIS control
.reg
[0x13];
3129 color
[3] = BX_CIRRUS_THIS control
.reg
[0x15];
3133 dst
= BX_CIRRUS_THIS bitblt
.dst
+ pattern_x
;
3134 bitmask
= 0x80 >> srcskipleft
;
3136 for (x
= pattern_x
; x
< BX_CIRRUS_THIS bitblt
.bltwidth
; x
+=BX_CIRRUS_THIS bitblt
.pixelwidth
) {
3137 if ((bitmask
& 0xff) == 0) {
3139 bits
= *src
++ ^ bits_xor
;
3141 if (bits
& bitmask
) {
3142 (*BX_CIRRUS_THIS bitblt
.rop_handler
)(
3143 dst
, &color
[0], 0, 0, BX_CIRRUS_THIS bitblt
.pixelwidth
, 1);
3145 dst
+= BX_CIRRUS_THIS bitblt
.pixelwidth
;
3150 bx_bool
// true if finished, false otherwise
3151 bx_svga_cirrus_c::svga_asyncbitblt_next()
3156 if (BX_CIRRUS_THIS bitblt
.bitblt_ptr
== NULL
) {
3157 BX_PANIC(("svga_asyncbitblt_next: unexpected call"));
3161 if (BX_CIRRUS_THIS bitblt
.memdst_needed
> 0) {
3162 BX_CIRRUS_THIS bitblt
.memdst_needed
-= BX_CIRRUS_THIS bitblt
.memdst_ptr
- &BX_CIRRUS_THIS bitblt
.memdst
[0];
3163 avail
= BX_MIN(CIRRUS_BLT_CACHESIZE
, BX_CIRRUS_THIS bitblt
.memdst_needed
);
3164 BX_CIRRUS_THIS bitblt
.memdst_ptr
= &BX_CIRRUS_THIS bitblt
.memdst
[0];
3165 BX_CIRRUS_THIS bitblt
.memdst_endptr
= &BX_CIRRUS_THIS bitblt
.memdst
[avail
];
3167 if (BX_CIRRUS_THIS bitblt
.memsrc_needed
<= 0 &&
3168 BX_CIRRUS_THIS bitblt
.memdst_needed
<= 0) {
3173 (*BX_CIRRUS_THIS bitblt
.bitblt_ptr
)();
3175 if (BX_CIRRUS_THIS bitblt
.memsrc_needed
> 0) {
3176 BX_CIRRUS_THIS bitblt
.dst
+= BX_CIRRUS_THIS bitblt
.dstpitch
;
3177 BX_CIRRUS_THIS bitblt
.memsrc_needed
-= BX_CIRRUS_THIS bitblt
.srcpitch
;
3178 if (BX_CIRRUS_THIS bitblt
.memsrc_needed
<= 0) {
3179 BX_CIRRUS_THIS
redraw_area(BX_CIRRUS_THIS redraw
.x
, BX_CIRRUS_THIS redraw
.y
,
3180 BX_CIRRUS_THIS redraw
.w
, BX_CIRRUS_THIS redraw
.h
);
3181 if (BX_CIRRUS_THIS bitblt
.memdst_needed
<= 0) {
3185 count
= BX_CIRRUS_THIS bitblt
.memsrc_endptr
- BX_CIRRUS_THIS bitblt
.memsrc_ptr
;
3186 memmove(&BX_CIRRUS_THIS bitblt
.memsrc
[0], BX_CIRRUS_THIS bitblt
.memsrc_ptr
, count
);
3187 BX_CIRRUS_THIS bitblt
.memsrc_ptr
= &BX_CIRRUS_THIS bitblt
.memsrc
[count
];
3194 svga_reset_bitblt();
3198 /////////////////////////////////////////////////////////////////////////
3200 // Raster operations.
3202 /////////////////////////////////////////////////////////////////////////
3204 #define IMPLEMENT_FORWARD_BITBLT(name,opline) \
3205 static void bitblt_rop_fwd_##name( \
3206 Bit8u *dst,const Bit8u *src, \
3207 int dstpitch,int srcpitch, \
3208 int bltwidth,int bltheight) \
3211 dstpitch -= bltwidth; \
3212 srcpitch -= bltwidth; \
3213 for (y = 0; y < bltheight; y++) { \
3214 for (x = 0; x < bltwidth; x++) { \
3224 #define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
3225 static void bitblt_rop_bkwd_##name( \
3226 Bit8u *dst,const Bit8u *src, \
3227 int dstpitch,int srcpitch, \
3228 int bltwidth,int bltheight) \
3231 dstpitch += bltwidth; \
3232 srcpitch += bltwidth; \
3233 for (y = 0; y < bltheight; y++) { \
3234 for (x = 0; x < bltwidth; x++) { \
3244 IMPLEMENT_FORWARD_BITBLT(0, *dst
= 0)
3245 IMPLEMENT_FORWARD_BITBLT(src_and_dst
, *dst
= (*src
) & (*dst
))
3246 IMPLEMENT_FORWARD_BITBLT(nop
, (void)0)
3247 IMPLEMENT_FORWARD_BITBLT(src_and_notdst
, *dst
= (*src
) & (~(*dst
)))
3248 IMPLEMENT_FORWARD_BITBLT(notdst
, *dst
= ~(*dst
))
3249 IMPLEMENT_FORWARD_BITBLT(src
, *dst
= *src
)
3250 IMPLEMENT_FORWARD_BITBLT(1, *dst
= 0xff)
3251 IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst
, *dst
= (~(*src
)) & (*dst
))
3252 IMPLEMENT_FORWARD_BITBLT(src_xor_dst
, *dst
= (*src
) ^ (*dst
))
3253 IMPLEMENT_FORWARD_BITBLT(src_or_dst
, *dst
= (*src
) | (*dst
))
3254 IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst
, *dst
= (~(*src
)) | (~(*dst
)))
3255 IMPLEMENT_FORWARD_BITBLT(src_notxor_dst
, *dst
= ~((*src
) ^ (*dst
)))
3256 IMPLEMENT_FORWARD_BITBLT(src_or_notdst
, *dst
= (*src
) | (~(*dst
)))
3257 IMPLEMENT_FORWARD_BITBLT(notsrc
, *dst
= (~(*src
)))
3258 IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst
, *dst
= (~(*src
)) | (*dst
))
3259 IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst
, *dst
= (~(*src
)) & (~(*dst
)))
3261 IMPLEMENT_BACKWARD_BITBLT(0, *dst
= 0)
3262 IMPLEMENT_BACKWARD_BITBLT(src_and_dst
, *dst
= (*src
) & (*dst
))
3263 IMPLEMENT_BACKWARD_BITBLT(nop
, (void)0)
3264 IMPLEMENT_BACKWARD_BITBLT(src_and_notdst
, *dst
= (*src
) & (~(*dst
)))
3265 IMPLEMENT_BACKWARD_BITBLT(notdst
, *dst
= ~(*dst
))
3266 IMPLEMENT_BACKWARD_BITBLT(src
, *dst
= *src
)
3267 IMPLEMENT_BACKWARD_BITBLT(1, *dst
= 0xff)
3268 IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst
, *dst
= (~(*src
)) & (*dst
))
3269 IMPLEMENT_BACKWARD_BITBLT(src_xor_dst
, *dst
= (*src
) ^ (*dst
))
3270 IMPLEMENT_BACKWARD_BITBLT(src_or_dst
, *dst
= (*src
) | (*dst
))
3271 IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst
, *dst
= (~(*src
)) | (~(*dst
)))
3272 IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst
, *dst
= ~((*src
) ^ (*dst
)))
3273 IMPLEMENT_BACKWARD_BITBLT(src_or_notdst
, *dst
= (*src
) | (~(*dst
)))
3274 IMPLEMENT_BACKWARD_BITBLT(notsrc
, *dst
= (~(*src
)))
3275 IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst
, *dst
= (~(*src
)) | (*dst
))
3276 IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst
, *dst
= (~(*src
)) & (~(*dst
)))
3278 bx_cirrus_bitblt_rop_t
bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop
)
3280 bx_cirrus_bitblt_rop_t rop_handler
= bitblt_rop_fwd_nop
;
3285 rop_handler
= bitblt_rop_fwd_0
;
3287 case CIRRUS_ROP_SRC_AND_DST
:
3288 rop_handler
= bitblt_rop_fwd_src_and_dst
;
3290 case CIRRUS_ROP_NOP
:
3291 rop_handler
= bitblt_rop_fwd_nop
;
3293 case CIRRUS_ROP_SRC_AND_NOTDST
:
3294 rop_handler
= bitblt_rop_fwd_src_and_notdst
;
3296 case CIRRUS_ROP_NOTDST
:
3297 rop_handler
= bitblt_rop_fwd_notdst
;
3299 case CIRRUS_ROP_SRC
:
3300 rop_handler
= bitblt_rop_fwd_src
;
3303 rop_handler
= bitblt_rop_fwd_1
;
3305 case CIRRUS_ROP_NOTSRC_AND_DST
:
3306 rop_handler
= bitblt_rop_fwd_notsrc_and_dst
;
3308 case CIRRUS_ROP_SRC_XOR_DST
:
3309 rop_handler
= bitblt_rop_fwd_src_xor_dst
;
3311 case CIRRUS_ROP_SRC_OR_DST
:
3312 rop_handler
= bitblt_rop_fwd_src_or_dst
;
3314 case CIRRUS_ROP_NOTSRC_OR_NOTDST
:
3315 rop_handler
= bitblt_rop_fwd_notsrc_or_notdst
;
3317 case CIRRUS_ROP_SRC_NOTXOR_DST
:
3318 rop_handler
= bitblt_rop_fwd_src_notxor_dst
;
3320 case CIRRUS_ROP_SRC_OR_NOTDST
:
3321 rop_handler
= bitblt_rop_fwd_src_or_notdst
;
3323 case CIRRUS_ROP_NOTSRC
:
3324 rop_handler
= bitblt_rop_fwd_notsrc
;
3326 case CIRRUS_ROP_NOTSRC_OR_DST
:
3327 rop_handler
= bitblt_rop_fwd_notsrc_or_dst
;
3329 case CIRRUS_ROP_NOTSRC_AND_NOTDST
:
3330 rop_handler
= bitblt_rop_fwd_notsrc_and_notdst
;
3333 BX_ERROR(("unknown ROP %02x",rop
));
3340 bx_cirrus_bitblt_rop_t
bx_svga_cirrus_c::svga_get_bkwd_rop_handler(Bit8u rop
)
3342 bx_cirrus_bitblt_rop_t rop_handler
= bitblt_rop_bkwd_nop
;
3347 rop_handler
= bitblt_rop_bkwd_0
;
3349 case CIRRUS_ROP_SRC_AND_DST
:
3350 rop_handler
= bitblt_rop_bkwd_src_and_dst
;
3352 case CIRRUS_ROP_NOP
:
3353 rop_handler
= bitblt_rop_bkwd_nop
;
3355 case CIRRUS_ROP_SRC_AND_NOTDST
:
3356 rop_handler
= bitblt_rop_bkwd_src_and_notdst
;
3358 case CIRRUS_ROP_NOTDST
:
3359 rop_handler
= bitblt_rop_bkwd_notdst
;
3361 case CIRRUS_ROP_SRC
:
3362 rop_handler
= bitblt_rop_bkwd_src
;
3365 rop_handler
= bitblt_rop_bkwd_1
;
3367 case CIRRUS_ROP_NOTSRC_AND_DST
:
3368 rop_handler
= bitblt_rop_bkwd_notsrc_and_dst
;
3370 case CIRRUS_ROP_SRC_XOR_DST
:
3371 rop_handler
= bitblt_rop_bkwd_src_xor_dst
;
3373 case CIRRUS_ROP_SRC_OR_DST
:
3374 rop_handler
= bitblt_rop_bkwd_src_or_dst
;
3376 case CIRRUS_ROP_NOTSRC_OR_NOTDST
:
3377 rop_handler
= bitblt_rop_bkwd_notsrc_or_notdst
;
3379 case CIRRUS_ROP_SRC_NOTXOR_DST
:
3380 rop_handler
= bitblt_rop_bkwd_src_notxor_dst
;
3382 case CIRRUS_ROP_SRC_OR_NOTDST
:
3383 rop_handler
= bitblt_rop_bkwd_src_or_notdst
;
3385 case CIRRUS_ROP_NOTSRC
:
3386 rop_handler
= bitblt_rop_bkwd_notsrc
;
3388 case CIRRUS_ROP_NOTSRC_OR_DST
:
3389 rop_handler
= bitblt_rop_bkwd_notsrc_or_dst
;
3391 case CIRRUS_ROP_NOTSRC_AND_NOTDST
:
3392 rop_handler
= bitblt_rop_bkwd_notsrc_and_notdst
;
3395 BX_ERROR(("unknown ROP %02x",rop
));
3402 #endif // BX_SUPPORT_CLGD54XX