Bochs/bochs/patches/patch.svga_cirrus
2004-08-13 15:13:14 +00:00

4867 lines
156 KiB
Plaintext

Patch name: patch.svga_cirrus
Author: m_suzu_abc@yahoo.co.jp
Date: 2 Jan. 2004
Status: Proposed
Detailed description:
An implementation of PCI/ISA SVGA card.
You can run XFree86-SVGA 3.3.6 at least
the following 3 lines are defined in XF86Config.
Option "no_mmio"
Option "nolinear"
Option "noaccel"
To enable SVGA support, configure with --enable-clgd54xx
This patch includes following.
config.h.in:
Added BX_SUPPORT_CLGD54XX and BX_SUPPORT_CLGD54XX_PCI.
configure.in:
Added option, --enabled-clgd54xx
gui/gui.h:
Prototypes for new graphics API
gui/sdl.cc:
Implementation of new graphics API for SDL
gui/x.cc:
Implementation of new graphics API for X11
iodev/Makefile.in:
Added svga_cirrus.o.
iodev/svga_cirrus.h, iodev/svga_cirrus.cc:
The implementation of SVGA CLGD54xx.
iodev/vga.cc:
modified to avoid confliction.
iodev/vga.h:
modified to avoid confliction.
modified access rights from private to protected.
Changes by vruppert (Aug 1st 2004)
- updated for current CVS
- PCI host bridge is now a core plugin and initialized earlier
- plugin version works now (CLGD54xx included in the vga plugin)
- fixed possible floating point exception in vga mem_write()
- detect device conflicts in config.h
- return device ID (CRTC reg 0x27)
- fixed sequencer register 0x06 (WHATVGA.EXE detects Cirrus VGA)
- fixed some compile problems
- PCI memory/mmio PnP support
- some vga register now support 16-bit reads
- a bunch of updates sent by suzu295@melu.jp
- ported write mode 4 + 5 and some bufixes from cirrus vga in qemu
Changes by komadori (Aug 4th 2004)
- implemented new graphics API
- implemented hardware cursor using new API
- added configure option for cirrus emulation
Changes by vruppert (Aug 10th 2004)
- wx now uses the new graphics API
- partial implementation of transparent bitblt
- partial support for bitblt write mask
Changes by vruppert (Aug 11th 2004)
- rfb now uses the new graphics API
- redrawing after bitblt operations optimized
- some bitblt fixes
Changes by komadori (Aug 11th 2004)
- redrawing after framebuffer writes optimized
- fixed error reporting for indexed host displays
Changes by vruppert (Aug 13th 2004)
- new graphics API should work now all with display libraries
(common functions in gui.cc for guis without specific support)
Patch was created with:
diff -urN
Apply patch to what version:
cvs snapshot on Aug 13th 2004
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
diff -urNX /home/volker/exclude-diff /home/volker/bochs/config.h.in ./config.h.in
--- /home/volker/bochs/config.h.in 2004-08-06 17:48:19.000000000 +0200
+++ ./config.h.in 2004-08-06 18:31:07.000000000 +0200
@@ -266,6 +266,7 @@
#define BX_USE_NE2K_SMF 1 // NE2K
#define BX_USE_EFI_SMF 1 // External FPU IRQ
#define BX_USE_GAME_SMF 1 // Gameport
+#define BX_USE_CIRRUS_SMF 1 // SVGA Cirrus
#define BX_PLUGINS 0
#define BX_HAVE_DLFCN_H 0
@@ -279,7 +280,7 @@
|| !BX_USE_P2I_SMF || !BX_USE_PCIVGA_SMF || !BX_USE_PCIUSB_SMF \
|| !BX_USE_PCIPNIC_SMF || !BX_USE_PIDE_SMF \
|| !BX_USE_NE2K_SMF || !BX_USE_EFI_SMF || !BX_USE_GAME_SMF \
- || !BX_USE_PCIDEV_SMF)
+ || !BX_USE_PCIDEV_SMF || !BX_USE_CIRRUS_SMF)
#error You must use SMF to have plugins
#endif
@@ -679,8 +680,6 @@
#define BX_PROVIDE_CPU_MEMORY 1
#define BX_PROVIDE_DEVICE_MODELS 1
-#define BX_SUPPORT_VBE 0
-
#define BX_PROVIDE_MAIN 1
#define BX_INSTRUMENTATION 0
@@ -696,8 +695,19 @@
// limited i440FX PCI support
#define BX_SUPPORT_PCI 0
+// Bochs VBE display interface
+#define BX_SUPPORT_VBE 0
+
+// CLGD54XX emulation
+#define BX_SUPPORT_CLGD54XX 0
+
+// CLGD54XX PCI emulation
+#define BX_SUPPORT_CLGD54XX_PCI 1
+
// Experimental VGA on PCI
+#if !(BX_SUPPORT_CLGD54XX && BX_SUPPORT_CLGD54XX_PCI)
#define BX_SUPPORT_PCIVGA 1
+#endif
// Experimental host PCI device mapping
#define BX_SUPPORT_PCIDEV 0
diff -urNX /home/volker/exclude-diff /home/volker/bochs/configure.in ./configure.in
--- /home/volker/bochs/configure.in 2004-08-11 13:05:10.000000000 +0200
+++ ./configure.in 2004-08-11 13:23:32.000000000 +0200
@@ -1484,16 +1484,42 @@
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SUPPORT_VBE, 1)
+ bx_support_vbe=1
else
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_VBE, 0)
+ bx_support_vbe=0
fi],
[
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_VBE, 0)
+ bx_support_vbe=0
]
)
+AC_MSG_CHECKING(for CLGD54XX emulation)
+AC_ARG_ENABLE(clgd54xx,
+ [ --enable-clgd54xx enable CLGD54XX emulation],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_CLGD54XX, 1)
+ bx_support_clgd54xx=1
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_CLGD54XX, 0)
+ bx_support_clgd54xx=0
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_CLGD54XX, 0)
+ bx_support_clgd54xx=0
+ ]
+ )
+
+if test "$bx_support_vbe" = 1 && test "$bx_suppot_clgd54xx" = 1; then
+ AC_MSG_ERROR([[--enable-vbe and --enable-clgd54xx are mutually exclusive]])
+fi
+
support_fpu=1
AC_MSG_CHECKING(for FPU emulation)
FPU_VAR=''
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/carbon.cc ./gui/carbon.cc
--- /home/volker/bochs/gui/carbon.cc 2004-06-20 07:58:08.000000000 +0200
+++ ./gui/carbon.cc 2004-08-13 16:43:16.000000000 +0200
@@ -1458,6 +1458,10 @@
}
windowUpdatesPending = true;
+
+ host_xres = x;
+ host_yres = y;
+ host_bpp = bpp;
}
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/gui.cc ./gui/gui.cc
--- /home/volker/bochs/gui/gui.cc 2004-07-06 21:59:10.000000000 +0200
+++ ./gui/gui.cc 2004-08-13 13:54:27.000000000 +0200
@@ -53,15 +53,24 @@
put("GUI"); // Init in specific_init
settype(GUILOG);
statusitem_count = 0;
+ framebuffer = NULL;
}
bx_gui_c::~bx_gui_c()
{
+ if (framebuffer != NULL) {
+ delete [] framebuffer;
+ }
}
void
bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
{
+ BX_GUI_THIS new_gfx_api = 0;
+ BX_GUI_THIS host_xres = 640;
+ BX_GUI_THIS host_yres = 480;
+ BX_GUI_THIS host_bpp = 8;
+
specific_init(argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);
// Define some bitmaps to use in the headerbar
@@ -169,6 +178,9 @@
BX_GUI_THIS charmap_updated = 0;
+ if (!BX_GUI_THIS new_gfx_api) {
+ BX_GUI_THIS framebuffer = new Bit8u[BX_MAX_XRES * BX_MAX_YRES * 4];
+ }
show_headerbar();
}
@@ -618,3 +630,111 @@
*yres = 768;
*bpp = 32;
}
+
+ bx_svga_tileinfo_t *
+bx_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
+{
+ if (!info) {
+ info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
+ if (!info) {
+ return NULL;
+ }
+ }
+
+ BX_GUI_THIS host_pitch = BX_GUI_THIS host_xres * ((BX_GUI_THIS host_bpp + 1) >> 3);
+
+ info->bpp = BX_GUI_THIS host_bpp;
+ info->pitch = BX_GUI_THIS host_pitch;
+ switch (info->bpp) {
+ case 15:
+ info->red_shift = 15;
+ info->green_shift = 10;
+ info->blue_shift = 5;
+ info->red_mask = 0x7c00;
+ info->green_mask = 0x03e0;
+ info->blue_mask = 0x001f;
+ break;
+ case 16:
+ info->red_shift = 16;
+ info->green_shift = 11;
+ info->blue_shift = 5;
+ info->red_mask = 0xf800;
+ info->green_mask = 0x07e0;
+ info->blue_mask = 0x001f;
+ break;
+ case 24:
+ case 32:
+ info->red_shift = 24;
+ info->green_shift = 16;
+ info->blue_shift = 8;
+ info->red_mask = 0xff0000;
+ info->green_mask = 0x00ff00;
+ info->blue_mask = 0x0000ff;
+ break;
+ }
+ info->is_indexed = (BX_GUI_THIS host_bpp == 8);
+#ifdef BX_LITTLE_ENDIAN
+ info->is_little_endian = 1;
+#else
+ info->is_little_endian = 0;
+#endif
+
+ return info;
+}
+
+ Bit8u *
+bx_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
+ unsigned *w, unsigned *h)
+{
+ if (x0+X_TILESIZE > BX_GUI_THIS host_xres) {
+ *w = BX_GUI_THIS host_xres - x0;
+ }
+ else {
+ *w = X_TILESIZE;
+ }
+
+ if (y0+Y_TILESIZE > BX_GUI_THIS host_yres) {
+ *h = BX_GUI_THIS host_yres - y0;
+ }
+ else {
+ *h = Y_TILESIZE;
+ }
+
+ return (Bit8u *)framebuffer + y0 * BX_GUI_THIS host_pitch +
+ x0 * ((BX_GUI_THIS host_bpp + 1) >> 3);
+}
+
+ void
+bx_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
+ unsigned w, unsigned h)
+{
+ Bit8u tile[X_TILESIZE * Y_TILESIZE * 4];
+ Bit8u *tile_ptr, *fb_ptr;
+ Bit16u xc, yc, fb_pitch, tile_pitch;
+ Bit8u r, diffx, diffy;
+
+ diffx = (x0 % X_TILESIZE);
+ diffy = (y0 % Y_TILESIZE);
+ if (diffx > 0) {
+ x0 -= diffx;
+ w += diffx;
+ }
+ if (diffy > 0) {
+ y0 -= diffy;
+ h += diffy;
+ }
+ fb_pitch = BX_GUI_THIS host_pitch;
+ tile_pitch = X_TILESIZE * ((BX_GUI_THIS host_bpp + 1) >> 3);
+ for (yc=y0; yc<(y0+h); yc+=Y_TILESIZE) {
+ for (xc=x0; xc<(x0+w); xc+=X_TILESIZE) {
+ fb_ptr = BX_GUI_THIS framebuffer + (yc * fb_pitch + xc * ((BX_GUI_THIS host_bpp + 1) >> 3));
+ tile_ptr = &tile[0];
+ for (r=0; r<h; r++) {
+ memcpy(tile_ptr, fb_ptr, tile_pitch);
+ fb_ptr += fb_pitch;
+ tile_ptr += tile_pitch;
+ }
+ BX_GUI_THIS graphics_tile_update(tile, xc, yc);
+ }
+ }
+}
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/gui.h ./gui/gui.h
--- /home/volker/bochs/gui/gui.h 2004-04-09 17:04:53.000000000 +0200
+++ ./gui/gui.h 2004-08-13 11:50:29.000000000 +0200
@@ -38,6 +38,13 @@
bx_bool split_hpanning;
} bx_vga_tminfo_t;
+typedef struct {
+ Bit16u bpp, pitch;
+ Bit8u red_shift, green_shift, blue_shift;
+ Bit8u is_indexed, is_little_endian;
+ unsigned long red_mask, green_mask, blue_mask;
+} bx_svga_tileinfo_t;
+
BOCHSAPI extern class bx_gui_c *bx_gui;
@@ -56,6 +63,9 @@
unsigned long cursor_x, unsigned long cursor_y,
bx_vga_tminfo_t tm_info, unsigned rows) = 0;
virtual void graphics_tile_update(Bit8u *snapshot, unsigned x, unsigned y) = 0;
+ virtual bx_svga_tileinfo_t *graphics_tile_info(bx_svga_tileinfo_t *info);
+ virtual Bit8u *graphics_tile_get(unsigned x, unsigned y, unsigned *w, unsigned *h);
+ virtual void graphics_tile_update_in_place(unsigned x, unsigned y, unsigned w, unsigned h);
virtual void handle_events(void) = 0;
virtual void flush(void) = 0;
virtual void clear_screen(void) = 0;
@@ -143,6 +153,12 @@
unsigned statusitem_count;
char statusitem_text[BX_MAX_STATUSITEMS][8];
disp_mode_t disp_mode;
+ bx_bool new_gfx_api;
+ Bit16u host_xres;
+ Bit16u host_yres;
+ Bit16u host_pitch;
+ Bit8u host_bpp;
+ Bit8u *framebuffer;
};
@@ -155,13 +171,13 @@
// DECLARE_GUI_VIRTUAL_METHODS()
// };
// Then, each method must be defined later in the file.
-#define DECLARE_GUI_VIRTUAL_METHODS() \
+#define DECLARE_GUI_VIRTUAL_METHODS() \
virtual void specific_init(int argc, char **argv, \
- unsigned x_tilesize, unsigned y_tilesize, \
- unsigned header_bar_y); \
+ unsigned x_tilesize, unsigned y_tilesize, \
+ unsigned header_bar_y); \
virtual void text_update(Bit8u *old_text, Bit8u *new_text, \
- unsigned long cursor_x, unsigned long cursor_y, \
- bx_vga_tminfo_t tm_info, unsigned rows); \
+ unsigned long cursor_x, unsigned long cursor_y, \
+ bx_vga_tminfo_t tm_info, unsigned rows); \
virtual void graphics_tile_update(Bit8u *snapshot, unsigned x, unsigned y); \
virtual void handle_events(void); \
virtual void flush(void); \
@@ -169,7 +185,7 @@
virtual bx_bool palette_change(unsigned index, \
unsigned red, unsigned green, unsigned blue); \
virtual void dimension_update(unsigned x, unsigned y, unsigned fheight=0, \
- unsigned fwidth=0, unsigned bpp=8); \
+ unsigned fwidth=0, unsigned bpp=8); \
virtual unsigned create_bitmap(const unsigned char *bmap, \
unsigned xdim, unsigned ydim); \
virtual unsigned headerbar_bitmap(unsigned bmap_id, unsigned alignment, \
@@ -182,6 +198,14 @@
virtual void exit(void); \
/* end of DECLARE_GUI_VIRTUAL_METHODS */
+#define DECLARE_GUI_NEW_VIRTUAL_METHODS() \
+virtual bx_svga_tileinfo_t *graphics_tile_info(bx_svga_tileinfo_t *info); \
+virtual Bit8u *graphics_tile_get(unsigned x, unsigned y, \
+ unsigned *w, unsigned *h); \
+virtual void graphics_tile_update_in_place(unsigned x, unsigned y, \
+ unsigned w, unsigned h);
+/* end of DECLARE_GUI_NEW_VIRTUAL_METHODS */
+
#define BX_MAX_PIXMAPS 16
#define BX_MAX_HEADERBAR_ENTRIES 11
#define BX_HEADER_BAR_Y 32
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/macintosh.cc ./gui/macintosh.cc
--- /home/volker/bochs/gui/macintosh.cc 2004-06-20 07:58:08.000000000 +0200
+++ ./gui/macintosh.cc 2004-08-13 16:44:14.000000000 +0200
@@ -1137,6 +1137,10 @@
width = x;
height = y;
}
+
+ host_xres = x;
+ host_yres = y;
+ host_bpp = bpp;
}
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/rfb.cc ./gui/rfb.cc
--- /home/volker/bochs/gui/rfb.cc 2004-06-20 07:58:08.000000000 +0200
+++ ./gui/rfb.cc 2004-08-13 00:18:13.000000000 +0200
@@ -45,6 +45,7 @@
public:
bx_rfb_gui_c (void) {}
DECLARE_GUI_VIRTUAL_METHODS()
+ DECLARE_GUI_NEW_VIRTUAL_METHODS()
void get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp);
void statusbar_setitem(int element, bx_bool active);
};
@@ -132,7 +133,7 @@
static char *rfbScreen;
static char rfbPalette[256];
-static long rfbWindowX, rfbWindowY;
+static unsigned rfbWindowX, rfbWindowY;
static unsigned rfbDimensionX, rfbDimensionY;
static long rfbHeaderbarY;
static long rfbTileX = 0;
@@ -270,6 +271,8 @@
#endif
}
if (timeout < 0) BX_PANIC(("timeout! no client present"));
+
+ new_gfx_api = 1;
}
void rfbSetStatus(int element, bx_bool active)
@@ -793,6 +796,62 @@
}
+ bx_svga_tileinfo_t *
+bx_rfb_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
+{
+ if (!info) {
+ info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
+ if (!info) {
+ return NULL;
+ }
+ }
+
+ info->bpp = 8;
+ info->pitch = rfbWindowX;
+ info->red_shift = 3;
+ info->green_shift = 6;
+ info->blue_shift = 8;
+ info->red_mask = 0x07;
+ info->green_mask = 0x38;
+ info->blue_mask = 0xc0;
+ info->is_indexed = 0;
+ info->is_little_endian = 1;
+
+ return info;
+}
+
+ Bit8u *
+bx_rfb_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
+ unsigned *w, unsigned *h)
+{
+ if (x0+rfbTileX > rfbDimensionX) {
+ *w = rfbDimensionX - x0;
+ }
+ else {
+ *w = rfbTileX;
+ }
+
+ if (y0+rfbTileY > rfbDimensionY) {
+ *h = rfbDimensionY - y0;
+ }
+ else {
+ *h = rfbTileY;
+ }
+
+ return (Bit8u *)rfbScreen + (rfbHeaderbarY + y0) * rfbWindowX + x0;
+}
+
+ void
+bx_rfb_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
+ unsigned w, unsigned h)
+{
+ if(x0 < rfbUpdateRegion.x) rfbUpdateRegion.x = x0;
+ if((y0 + rfbHeaderbarY) < rfbUpdateRegion.y) rfbUpdateRegion.y = y0 + rfbHeaderbarY;
+ if(((y0 + rfbHeaderbarY + h) - rfbUpdateRegion.y) > rfbUpdateRegion.height) rfbUpdateRegion.height = ((y0 + rfbHeaderbarY + h) - rfbUpdateRegion.y);
+ if(((x0 + w) - rfbUpdateRegion.x) > rfbUpdateRegion.width) rfbUpdateRegion.width = ((x0 + h) - rfbUpdateRegion.x);
+ rfbUpdateRegion.updated = true;
+}
+
// ::DIMENSION_UPDATE()
//
@@ -1174,7 +1233,7 @@
char *newBits;
int i;
- if(x < 0 || y < 0 || (x + width) > rfbWindowX || (y + height) > rfbWindowY) {
+ if(x < 0 || y < 0 || (x + width) > (int)rfbWindowX || (y + height) > (int)rfbWindowY) {
BX_ERROR(("Dimensions out of bounds. x=%i y=%i w=%i h=%i", x, y, width, height));
}
if(sGlobal != INVALID_SOCKET) {
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/sdl.cc ./gui/sdl.cc
--- /home/volker/bochs/gui/sdl.cc 2004-08-06 17:49:53.000000000 +0200
+++ ./gui/sdl.cc 2004-08-13 00:18:30.000000000 +0200
@@ -47,6 +47,7 @@
public:
bx_sdl_gui_c (void);
DECLARE_GUI_VIRTUAL_METHODS()
+ DECLARE_GUI_NEW_VIRTUAL_METHODS()
virtual void set_display_mode (disp_mode_t newmode);
virtual void statusbar_setitem(int element, bx_bool active);
};
@@ -284,6 +285,8 @@
}
}
}
+
+ new_gfx_api = 1;
}
void sdl_set_status_text(int element, const char *text, bx_bool active)
@@ -704,6 +707,84 @@
}
}
+ bx_svga_tileinfo_t *
+bx_sdl_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
+{
+ if (!info) {
+ info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
+ if (!info) {
+ return NULL;
+ }
+ }
+
+ if (sdl_screen) {
+ info->bpp = sdl_screen->format->BitsPerPixel;
+ info->pitch = sdl_screen->pitch;
+ info->red_shift = sdl_screen->format->Rshift + 8 - sdl_screen->format->Rloss;
+ info->green_shift = sdl_screen->format->Gshift + 8 - sdl_screen->format->Gloss;
+ info->blue_shift = sdl_screen->format->Bshift + 8 - sdl_screen->format->Bloss;
+ info->red_mask = sdl_screen->format->Rmask;
+ info->green_mask = sdl_screen->format->Gmask;
+ info->blue_mask = sdl_screen->format->Bmask;
+ info->is_indexed = (sdl_screen->format->palette != NULL);
+ }
+ else {
+ info->bpp = sdl_fullscreen->format->BitsPerPixel;
+ info->pitch = sdl_fullscreen->pitch;
+ info->red_shift = sdl_fullscreen->format->Rshift + 8 - sdl_screen->format->Rloss;
+ info->green_shift = sdl_fullscreen->format->Gshift + 8 - sdl_screen->format->Gloss;
+ info->blue_shift = sdl_fullscreen->format->Bshift + 8 - sdl_screen->format->Bloss;
+ info->red_mask = sdl_fullscreen->format->Rmask;
+ info->green_mask = sdl_fullscreen->format->Gmask;
+ info->blue_mask = sdl_fullscreen->format->Bmask;
+ info->is_indexed = (sdl_screen->format->palette != NULL);
+ }
+
+#ifdef BX_LITTLE_ENDIAN
+ info->is_little_endian = 1;
+#else
+ info->is_little_endian = 0;
+#endif
+
+ return info;
+}
+
+ Bit8u *
+bx_sdl_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
+ unsigned *w, unsigned *h)
+{
+ if (x0+tilewidth > res_x) {
+ *w = res_x - x0;
+ }
+ else {
+ *w = tilewidth;
+ }
+
+ if (y0+tileheight > res_y) {
+ *h = res_y - y0;
+ }
+ else {
+ *h = tileheight;
+ }
+
+ if (sdl_screen) {
+ return (Bit8u *)sdl_screen->pixels +
+ sdl_screen->pitch*(headerbar_height+y0) +
+ sdl_screen->format->BytesPerPixel*x0;
+ }
+ else {
+ return (Bit8u *)sdl_fullscreen->pixels +
+ sdl_fullscreen->pitch*(headerbar_height+y0) +
+ sdl_fullscreen->format->BytesPerPixel*x0;
+ }
+}
+
+ void
+bx_sdl_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
+ unsigned w, unsigned h)
+{
+}
+
static Bit32u sdl_sym_to_bx_key (SDLKey sym)
{
switch (sym)
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/win32.cc ./gui/win32.cc
--- /home/volker/bochs/gui/win32.cc 2004-06-20 07:58:08.000000000 +0200
+++ ./gui/win32.cc 2004-08-13 11:14:38.000000000 +0200
@@ -1631,6 +1631,10 @@
MoveWindow(stInfo.simWnd, 0, bx_headerbar_y, stretched_x, stretched_y, TRUE);
BX_INFO (("dimension update x=%d y=%d fontheight=%d fontwidth=%d bpp=%d", x, y, fheight, fwidth, bpp));
+
+ host_xres = x;
+ host_yres = y;
+ host_bpp = bpp;
}
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/wx.cc ./gui/wx.cc
--- /home/volker/bochs/gui/wx.cc 2004-06-20 07:58:08.000000000 +0200
+++ ./gui/wx.cc 2004-08-13 00:19:33.000000000 +0200
@@ -66,6 +66,7 @@
public:
bx_wx_gui_c (void) {}
DECLARE_GUI_VIRTUAL_METHODS()
+ DECLARE_GUI_NEW_VIRTUAL_METHODS()
virtual void statusbar_setitem(int element, bx_bool active);
};
@@ -90,8 +91,8 @@
wxCriticalSection wxScreen_lock;
static long wxScreenX = 0;
static long wxScreenY = 0;
-static long wxTileX = 0;
-static long wxTileY = 0;
+static unsigned wxTileX = 0;
+static unsigned wxTileY = 0;
static unsigned long wxCursorX = 0;
static unsigned long wxCursorY = 0;
static unsigned long wxFontX = 0;
@@ -909,6 +910,8 @@
#else
bx_keymap.loadKeymap(NULL);
#endif
+
+ new_gfx_api = 1;
}
// ::HANDLE_EVENTS()
@@ -1408,12 +1411,62 @@
void bx_wx_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
{
IFDBG_VGA (wxLogDebug (wxT ("graphics_tile_update")));
- //static Bit32u counter = 0;
- //BX_INFO (("graphics_tile_update executed %d times", ++counter));
UpdateScreen(tile, x0, y0, wxTileX, wxTileY);
thePanel->MyRefresh ();
}
+ bx_svga_tileinfo_t *
+bx_wx_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
+{
+ if (!info) {
+ info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
+ if (!info) {
+ return NULL;
+ }
+ }
+
+ info->bpp = 24;
+ info->pitch = wxScreenX * 3;
+ info->red_shift = 8;
+ info->green_shift = 16;
+ info->blue_shift = 24;
+ info->red_mask = 0x0000ff;
+ info->green_mask = 0x00ff00;
+ info->blue_mask = 0xff0000;
+ info->is_indexed = 0;
+ info->is_little_endian = 1;
+
+ return info;
+};
+
+ Bit8u *
+bx_wx_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
+ unsigned *w, unsigned *h)
+{
+ if (x0+wxTileX > (unsigned)wxScreenX) {
+ *w = wxScreenX - x0;
+ }
+ else {
+ *w = wxTileX;
+ }
+
+ if (y0+wxTileY > (unsigned)wxScreenY) {
+ *h = wxScreenY - y0;
+ }
+ else {
+ *h = wxTileY;
+ }
+
+ return (Bit8u *)wxScreen + y0 * wxScreenX * 3 + x0 * 3;
+}
+
+ void
+bx_wx_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
+ unsigned w, unsigned h)
+{
+ thePanel->MyRefresh ();
+}
+
// ::DIMENSION_UPDATE()
//
// Called from the simulator when the VGA mode changes it's X,Y dimensions.
diff -urNX /home/volker/exclude-diff /home/volker/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/gui/x.cc 2004-06-20 07:58:09.000000000 +0200
+++ ./gui/x.cc 2004-08-13 13:57:13.000000000 +0200
@@ -59,6 +59,7 @@
public:
bx_x_gui_c (void);
DECLARE_GUI_VIRTUAL_METHODS()
+ DECLARE_GUI_NEW_VIRTUAL_METHODS()
#if BX_USE_IDLE_HACK
virtual void sim_is_idle(void);
#endif
@@ -82,6 +83,7 @@
* additional source files, they would be declared extern there. */
Display *bx_x_display;
int bx_x_screen_num;
+static Visual *default_visual;
static Colormap default_cmap;
static unsigned long white_pixel=0, black_pixel=0;
@@ -366,7 +368,6 @@
/* create GC for text and drawing */
unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
XGCValues values;
- Visual *default_visual;
int default_depth;
XEvent report;
XSetWindowAttributes win_attr;
@@ -622,7 +623,6 @@
strcpy(bx_status_info_text, "CTRL + 3rd button enables mouse");
x_init_done = true;
-
}
curr_background = 0;
@@ -639,6 +639,8 @@
if(bx_options.keyboard.OuseMapping->get()) {
bx_keymap.loadKeymap(convertStringToXKeysym);
}
+
+ new_gfx_api = 1;
}
void
@@ -1617,6 +1619,111 @@
x_tilesize, y_size);
}
+ bx_svga_tileinfo_t *
+bx_x_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
+{
+ if (!info) {
+ info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
+ if (!info) {
+ return NULL;
+ }
+ }
+
+ info->bpp = ximage->bits_per_pixel;
+ info->pitch = ximage->bytes_per_line;
+ info->red_shift = 0;
+ info->green_shift = 0;
+ info->blue_shift = 0;
+ info->red_mask = ximage->red_mask;
+ info->green_mask = ximage->green_mask;
+ info->blue_mask = ximage->blue_mask;
+
+ int i, rf, gf, bf;
+ unsigned long red, green, blue;
+
+ i = rf = gf = bf = 0;
+ red = ximage->red_mask;
+ green = ximage->green_mask;
+ blue = ximage->blue_mask;
+
+ while (red || rf || green || gf || blue || bf) {
+ if (rf) {
+ if (!(red & 1)) {
+ info->red_shift = i;
+ rf = 0;
+ }
+ }
+ else {
+ if (red & 1) {
+ rf = 1;
+ }
+ }
+
+ if (gf) {
+ if (!(green & 1)) {
+ info->green_shift = i;
+ gf = 0;
+ }
+ }
+ else {
+ if (green & 1) {
+ gf = 1;
+ }
+ }
+
+ if (bf) {
+ if (!(blue & 1)) {
+ info->blue_shift = i;
+ bf = 0;
+ }
+ }
+ else {
+ if (blue & 1) {
+ bf = 1;
+ }
+ }
+
+ i++;
+ red >>= 1;
+ green >>= 1;
+ blue >>= 1;
+ }
+
+ info->is_indexed = (default_visual->c_class != TrueColor) &&
+ (default_visual->c_class != DirectColor);
+ info->is_little_endian = (ximage->byte_order == LSBFirst);
+
+ return info;
+}
+
+ Bit8u *
+bx_x_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
+ unsigned *w, unsigned *h)
+{
+ if (x0+x_tilesize > dimension_x) {
+ *w = dimension_x - x0;
+ }
+ else {
+ *w = x_tilesize;
+ }
+
+ if (y0+y_tilesize > dimension_y) {
+ *h = dimension_y - y0;
+ }
+ else {
+ *h = y_tilesize;
+ }
+
+ return (Bit8u *)ximage->data + ximage->xoffset*ximage->bits_per_pixel/8;
+}
+
+ void
+bx_x_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
+ unsigned w, unsigned h)
+{
+ XPutImage(bx_x_display, win, gc, ximage, 0, 0,
+ x0, y0+bx_headerbar_y, w, h);
+}
bx_bool
bx_x_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
@@ -1671,7 +1778,7 @@
XResizeWindow(bx_x_display, win, x, y+bx_headerbar_y+bx_statusbar_y);
dimension_x = x;
dimension_y = y;
- }
+ }
}
diff -urNX /home/volker/exclude-diff /home/volker/bochs/iodev/Makefile.in ./iodev/Makefile.in
--- /home/volker/bochs/iodev/Makefile.in 2004-02-18 19:29:33.000000000 +0100
+++ ./iodev/Makefile.in 2004-08-06 14:17:14.000000000 +0200
@@ -95,6 +95,7 @@
OBJS_THAT_SUPPORT_OTHER_PLUGINS = \
scancodes.o \
serial_raw.o \
+ svga_cirrus.o \
vmware3.o \
$(CDROM_OBJS) \
$(SOUNDLOW_OBJS) \
@@ -148,6 +149,9 @@
libbx_serial.la: serial.lo serial_raw.lo
$(LIBTOOL) --mode=link $(CXX) -module serial.lo serial_raw.lo -o libbx_serial.la -rpath $(PLUGIN_PATH)
+libbx_vga.la: vga.lo svga_cirrus.lo
+ $(LIBTOOL) --mode=link $(CXX) -module vga.lo svga_cirrus.lo -o libbx_vga.la -rpath $(PLUGIN_PATH)
+
#### building DLLs for win32 (tested on cygwin only)
bx_%.dll: %.o
$(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
@@ -174,6 +178,9 @@
bx_serial.dll: serial.o serial_raw.o
$(CXX) $(CXXFLAGS) -shared -o bx_serial.dll serial.o serial_raw.o $(WIN32_DLL_IMPORT_LIBRARY)
+bx_vga.dll: vga.o svga_cirrus.o
+ $(CXX) $(CXXFLAGS) -shared -o bx_vga.dll vga.o svga_cirrus.o $(WIN32_DLL_IMPORT_LIBRARY)
+
##### end DLL section
clean:
@@ -810,7 +817,7 @@
../iodev/soundwin.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
../iodev/gameport.h ../instrument/stubs/instrument.h
-vga.o: vga.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
+vga.o svga_cirrus.o: vga.@CPP_SUFFIX@ svga_cirrus.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
diff -urNX /home/volker/exclude-diff /home/volker/bochs/iodev/svga_cirrus.cc ./iodev/svga_cirrus.cc
--- /home/volker/bochs/iodev/svga_cirrus.cc 1970-01-01 01:00:00.000000000 +0100
+++ ./iodev/svga_cirrus.cc 2004-08-13 13:54:45.000000000 +0200
@@ -0,0 +1,3427 @@
+//
+// limited PCI/ISA CLGD5446 support for Bochs
+//
+// Copyright (c) 2004 Makoto Suzuki (suzu)
+// Volker Ruppert (vruppert)
+// Robin Kay (komadori)
+//
+// there are still many unimplemented features:
+//
+// - 1bpp/4bpp
+// - transparent compare not complete
+// - some bitblt functions
+// - ???
+//
+// some codes are copied from vga.cc and modified.
+//
+
+#define BX_PLUGGABLE
+
+#include "iodev.h"
+
+#if BX_SUPPORT_CLGD54XX
+
+// Only reference the array if the tile numbers are within the bounds
+// of the array. If out of bounds, do nothing.
+#define SET_TILE_UPDATED(xtile,ytile,value) \
+ do { \
+ if (((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES)) \
+ BX_CIRRUS_THIS s.vga_tile_updated[(xtile)][(ytile)] = value; \
+ } while (0)
+// Only reference the array if the tile numbers are within the bounds
+// of the array. If out of bounds, return 1.
+#define GET_TILE_UPDATED(xtile,ytile) \
+ ((((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES))? \
+ BX_CIRRUS_THIS s.vga_tile_updated[(xtile)][(ytile)] \
+ : 1)
+
+// Make colour
+#define MAKE_COLOUR(red, red_shiftfrom, red_shiftto, red_mask, \
+ green, green_shiftfrom, green_shiftto, green_mask, \
+ blue, blue_shiftfrom, blue_shiftto, blue_mask) \
+( \
+ ((((red_shiftto) > (red_shiftfrom)) ? \
+ (red) << ((red_shiftto) - (red_shiftfrom)) : \
+ (red) >> ((red_shiftfrom) - (red_shiftto))) & \
+ (red_mask)) | \
+ ((((green_shiftto) > (green_shiftfrom)) ? \
+ (green) << ((green_shiftto) - (green_shiftfrom)) : \
+ (green) >> ((green_shiftfrom) - (green_shiftto))) & \
+ (green_mask)) | \
+ ((((blue_shiftto) > (blue_shiftfrom)) ? \
+ (blue) << ((blue_shiftto) - (blue_shiftfrom)) : \
+ (blue) >> ((blue_shiftfrom) - (blue_shiftto))) & \
+ (blue_mask)) \
+)
+
+#define LOG_THIS BX_CIRRUS_THIS
+
+#if BX_USE_CIRRUS_SMF
+#define VGA_READ(addr,len) bx_vga_c::read_handler(theSvga,addr,len)
+#define VGA_WRITE(addr,val,len) bx_vga_c::write_handler(theSvga,addr,val,len)
+#define SVGA_READ(addr,len) svga_read_handler(theSvga,addr,len)
+#define SVGA_WRITE(addr,val,len) svga_write_handler(theSvga,addr,val,len)
+#else
+#define VGA_READ(addr,len) bx_vga_c::read(addr,len)
+#define VGA_WRITE(addr,val,len) bx_vga_c::write(addr,val,len)
+#define SVGA_READ(addr,len) svga_read(addr,len)
+#define SVGA_WRITE(addr,val,len) svga_write(addr,val,len)
+#endif // BX_USE_CIRRUS_SMF
+
+#define ID_CLGD5428 (0x26<<2)
+#define ID_CLGD5430 (0x28<<2)
+#define ID_CLGD5434 (0x2A<<2)
+#define ID_CLGD5446 (0x2E<<2)
+
+// sequencer 0x07
+#define CIRRUS_SR7_BPP_VGA 0x00
+#define CIRRUS_SR7_BPP_SVGA 0x01
+#define CIRRUS_SR7_BPP_MASK 0x0e
+#define CIRRUS_SR7_BPP_8 0x00
+#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
+#define CIRRUS_SR7_BPP_24 0x04
+#define CIRRUS_SR7_BPP_16 0x06
+#define CIRRUS_SR7_BPP_32 0x08
+#define CIRRUS_SR7_ISAADDR_MASK 0xe0
+
+// sequencer 0x0f
+#define CIRRUS_MEMSIZE_512k 0x08
+#define CIRRUS_MEMSIZE_1M 0x10
+#define CIRRUS_MEMSIZE_2M 0x18
+#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
+
+// sequencer 0x12
+#define CIRRUS_CURSOR_SHOW 0x01
+#define CIRRUS_CURSOR_HIDDENPEL 0x02
+#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
+
+// sequencer 0x17
+#define CIRRUS_BUSTYPE_VLBFAST 0x10
+#define CIRRUS_BUSTYPE_PCI 0x20
+#define CIRRUS_BUSTYPE_VLBSLOW 0x30
+#define CIRRUS_BUSTYPE_ISA 0x38
+#define CIRRUS_MMIO_ENABLE 0x04
+#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
+#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
+
+// control 0x0b
+#define CIRRUS_BANKING_DUAL 0x01
+#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
+
+// control 0x30
+#define CIRRUS_BLTMODE_BACKWARDS 0x01
+#define CIRRUS_BLTMODE_MEMSYSDEST 0x02
+#define CIRRUS_BLTMODE_MEMSYSSRC 0x04
+#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
+#define CIRRUS_BLTMODE_PATTERNCOPY 0x40
+#define CIRRUS_BLTMODE_COLOREXPAND 0x80
+#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
+#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
+#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
+#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
+#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
+
+// control 0x31
+#define CIRRUS_BLT_BUSY 0x01
+#define CIRRUS_BLT_START 0x02
+#define CIRRUS_BLT_RESET 0x04
+#define CIRRUS_BLT_FIFOUSED 0x10
+#define CIRRUS_BLT_AUTOSTART 0x80
+
+// control 0x32
+#define CIRRUS_ROP_0 0x00
+#define CIRRUS_ROP_SRC_AND_DST 0x05
+#define CIRRUS_ROP_NOP 0x06
+#define CIRRUS_ROP_SRC_AND_NOTDST 0x09
+#define CIRRUS_ROP_NOTDST 0x0b
+#define CIRRUS_ROP_SRC 0x0d
+#define CIRRUS_ROP_1 0x0e
+#define CIRRUS_ROP_NOTSRC_AND_DST 0x50
+#define CIRRUS_ROP_SRC_XOR_DST 0x59
+#define CIRRUS_ROP_SRC_OR_DST 0x6d
+#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
+#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
+#define CIRRUS_ROP_SRC_OR_NOTDST 0xad
+#define CIRRUS_ROP_NOTSRC 0xd0
+#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
+#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
+
+// control 0x33
+#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
+#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
+#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
+
+#define CLGD543x_MMIO_BLTBGCOLOR 0x00 // dword
+#define CLGD543x_MMIO_BLTFGCOLOR 0x04 // dword
+#define CLGD543x_MMIO_BLTWIDTH 0x08 // word
+#define CLGD543x_MMIO_BLTHEIGHT 0x0a // word
+#define CLGD543x_MMIO_BLTDESTPITCH 0x0c // word
+#define CLGD543x_MMIO_BLTSRCPITCH 0x0e // word
+#define CLGD543x_MMIO_BLTDESTADDR 0x10 // dword
+#define CLGD543x_MMIO_BLTSRCADDR 0x14 // dword
+#define CLGD543x_MMIO_BLTWRITEMASK 0x17 // byte
+#define CLGD543x_MMIO_BLTMODE 0x18 // byte
+#define CLGD543x_MMIO_BLTROP 0x1a // byte
+#define CLGD543x_MMIO_BLTMODEEXT 0x1b // byte
+#define CLGD543x_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
+#define CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
+#define CLGD543x_MMIO_BLTSTATUS 0x40 // byte
+
+// PCI 0x00: vendor, 0x02: device
+#define PCI_VENDOR_CIRRUS 0x1013
+#define PCI_DEVICE_CLGD5430 0x00a0 // CLGD5430 or CLGD5440
+#define PCI_DEVICE_CLGD5434 0x00a8
+#define PCI_DEVICE_CLGD5436 0x00ac
+#define PCI_DEVICE_CLGD5446 0x00b8
+#define PCI_DEVICE_CLGD5462 0x00d0
+#define PCI_DEVICE_CLGD5465 0x00d6
+// PCI 0x04: command(word), 0x06(word): status
+#define PCI_COMMAND_IOACCESS 0x0001
+#define PCI_COMMAND_MEMACCESS 0x0002
+#define PCI_COMMAND_BUSMASTER 0x0004
+#define PCI_COMMAND_SPECIALCYCLE 0x0008
+#define PCI_COMMAND_MEMWRITEINVALID 0x0010
+#define PCI_COMMAND_PALETTESNOOPING 0x0020
+#define PCI_COMMAND_PARITYDETECTION 0x0040
+#define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
+#define PCI_COMMAND_SERR 0x0100
+#define PCI_COMMAND_BACKTOBACKTRANS 0x0200
+// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
+#define PCI_CLASS_BASE_DISPLAY 0x03
+// PCI 0x08, 0x00ff0000
+#define PCI_CLASS_SUB_VGA 0x00
+// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
+#define PCI_CLASS_HEADERTYPE_00h 0x00
+// 0x10-0x3f (headertype 00h)
+// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
+// 0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
+#define PCI_MAP_MEM 0x0
+#define PCI_MAP_IO 0x1
+#define PCI_MAP_MEM_ADDR_MASK (~0xf)
+#define PCI_MAP_IO_ADDR_MASK (~0x3)
+#define PCI_MAP_MEMFLAGS_32BIT 0x0
+#define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
+#define PCI_MAP_MEMFLAGS_64BIT 0x4
+#define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
+// PCI 0x28: cardbus CIS pointer
+// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
+// PCI 0x30: expansion ROM base address
+// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
+// PCI 0x38: reserved
+// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
+// PCI 0x40-0xff: device dependent fields
+
+// To implement the following stuffs, memory PnP is required!
+// default PnP memory address (FIXME - can't relocate!)
+#define CIRRUS_PNPMEM_BASE_ADDRESS 0xe0000000
+#define CIRRUS_PNPMEM_SIZE CIRRUS_VIDEO_MEMORY_BYTES
+// default PnP memory-mapped I/O address (FIXME - can't relocate!)
+#define CIRRUS_PNPMMIO_BASE_ADDRESS (CIRRUS_PNPMEM_BASE_ADDRESS + CIRRUS_PNPMEM_SIZE)
+#define CIRRUS_PNPMMIO_SIZE 0x1000
+
+#define BX_MAX(a,b) ((a) > (b) ? (a) : (b))
+#define BX_MIN(a,b) ((a) < (b) ? (a) : (b))
+
+static bx_svga_cirrus_c *theSvga = NULL;
+
+ int
+libvga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
+{
+ theSvga = new bx_svga_cirrus_c ();
+ libvga_set_smf_pointer(theSvga);
+ bx_devices.pluginVgaDevice = theSvga;
+ BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSvga, BX_PLUGIN_VGA);
+ return(0); // Success
+}
+
+ void
+libvga_LTX_plugin_fini(void)
+{
+}
+
+
+bx_svga_cirrus_c::bx_svga_cirrus_c(void) :
+ bx_vga_c ()
+{
+ put("CLVGA");
+ vidmem = NULL;
+ tilemem = NULL;
+}
+
+bx_svga_cirrus_c::~bx_svga_cirrus_c()
+{
+ if (vidmem != NULL) {
+ delete [] vidmem;
+ }
+ if (tilemem != NULL) {
+ delete [] tilemem;
+ }
+}
+
+ void
+bx_svga_cirrus_c::init(void)
+{
+ // initialize VGA stuffs.
+ BX_CIRRUS_THIS bx_vga_c::init();
+ BX_CIRRUS_THIS bx_vga_c::init_iohandlers(
+ svga_read_handler, svga_write_handler);
+ BX_CIRRUS_THIS bx_vga_c::init_systemtimer(
+ svga_timer_handler);
+
+ // initialize SVGA stuffs.
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ BX_CIRRUS_THIS pci_enabled = DEV_is_pci_device("cirrus");
+#endif
+ BX_CIRRUS_THIS svga_init_members();
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ if (BX_CIRRUS_THIS pci_enabled) {
+ BX_CIRRUS_THIS svga_init_pcihandlers();
+ }
+#endif
+}
+
+ void
+bx_svga_cirrus_c::svga_init_members()
+{
+ unsigned i;
+
+ // clear all registers.
+ BX_CIRRUS_THIS sequencer.index = CIRRUS_SEQENCER_MAX + 1;
+ for (i = 0; i <= CIRRUS_SEQENCER_MAX; i++)
+ BX_CIRRUS_THIS sequencer.reg[i] = 0x00;
+ BX_CIRRUS_THIS control.index = CIRRUS_CONTROL_MAX + 1;
+ for (i = 0; i <= CIRRUS_CONTROL_MAX; i++)
+ BX_CIRRUS_THIS control.reg[i] = 0x00;
+ BX_CIRRUS_THIS control.shadow_reg0 = 0x00;
+ BX_CIRRUS_THIS control.shadow_reg1 = 0x00;
+ BX_CIRRUS_THIS crtc.index = CIRRUS_CRTC_MAX + 1;
+ for (i = 0; i <= CIRRUS_CRTC_MAX; i++)
+ BX_CIRRUS_THIS crtc.reg[i] = 0x00;
+ BX_CIRRUS_THIS hidden_dac.lockindex = 0;
+ BX_CIRRUS_THIS hidden_dac.data = 0x00;
+
+ BX_CIRRUS_THIS svga_unlock_special = false;
+ BX_CIRRUS_THIS svga_needs_update_tile = true;
+ BX_CIRRUS_THIS svga_needs_update_dispentire = true;
+ BX_CIRRUS_THIS svga_needs_update_mode = false;
+
+ BX_CIRRUS_THIS svga_xres = 640;
+ BX_CIRRUS_THIS svga_yres = 480;
+ BX_CIRRUS_THIS svga_bpp = 8;
+ BX_CIRRUS_THIS svga_pitch = 640;
+ BX_CIRRUS_THIS bank_base[0] = 0;
+ BX_CIRRUS_THIS bank_base[1] = 0;
+ BX_CIRRUS_THIS bank_limit[0] = 0;
+ BX_CIRRUS_THIS bank_limit[1] = 0;
+
+ svga_reset_bitblt();
+
+ BX_CIRRUS_THIS hw_cursor.x = 0;
+ BX_CIRRUS_THIS hw_cursor.y = 0;
+ BX_CIRRUS_THIS hw_cursor.size = 0;
+
+ // memory allocation.
+ BX_CIRRUS_THIS vidmem = new Bit8u[CIRRUS_VIDEO_MEMORY_BYTES];
+ BX_CIRRUS_THIS tilemem = new Bit8u[X_TILESIZE * Y_TILESIZE * 4];
+
+ // set some registers.
+
+ BX_CIRRUS_THIS sequencer.reg[0x06] = 0x0f;
+ BX_CIRRUS_THIS sequencer.reg[0x07] = 0x00; // 0xf0:linearbase(0x00 if disabled)
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ if (BX_CIRRUS_THIS pci_enabled) {
+ BX_CIRRUS_THIS crtc.reg[0x27] = ID_CLGD5446;
+ BX_CIRRUS_THIS sequencer.reg[0x1F] = 0x2d; // MemClock
+ BX_CIRRUS_THIS control.reg[0x18] = 0x0f;
+ BX_CIRRUS_THIS sequencer.reg[0x0F] = 0x98;
+ BX_CIRRUS_THIS sequencer.reg[0x17] = CIRRUS_BUSTYPE_PCI;
+ BX_CIRRUS_THIS sequencer.reg[0x15] = 0x04; // memory size 4MB
+ BX_CIRRUS_THIS memsize = (4 << 20);
+ } else
+#endif
+ {
+ BX_CIRRUS_THIS crtc.reg[0x27] = ID_CLGD5430;
+ BX_CIRRUS_THIS sequencer.reg[0x1F] = 0x22; // MemClock
+ BX_CIRRUS_THIS sequencer.reg[0x0F] = CIRRUS_MEMSIZE_2M;
+ BX_CIRRUS_THIS sequencer.reg[0x17] = CIRRUS_BUSTYPE_ISA;
+ BX_CIRRUS_THIS sequencer.reg[0x15] = 0x03; // memory size 2MB
+ BX_CIRRUS_THIS memsize = (2 << 20);
+ }
+
+ BX_CIRRUS_THIS hidden_dac.lockindex = 5;
+ BX_CIRRUS_THIS hidden_dac.data = 0;
+
+ memset(BX_CIRRUS_THIS vidmem, 0xff, CIRRUS_VIDEO_MEMORY_BYTES);
+ BX_CIRRUS_THIS disp_ptr = BX_CIRRUS_THIS vidmem;
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ if (BX_CIRRUS_THIS pci_enabled) {
+ // This should be done by the PCI BIOS
+ WriteHostDWordToLittleEndian(
+ &BX_CIRRUS_THIS pci_conf[0x10],
+ (PCI_MAP_MEM | PCI_MAP_MEMFLAGS_32BIT | PCI_MAP_MEMFLAGS_CACHEABLE |
+ CIRRUS_PNPMEM_BASE_ADDRESS));
+ WriteHostDWordToLittleEndian(
+ &BX_CIRRUS_THIS pci_conf[0x14],
+ (PCI_MAP_MEM | PCI_MAP_MEMFLAGS_32BIT |
+ CIRRUS_PNPMMIO_BASE_ADDRESS));
+ DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
+ cirrus_mem_write_handler,
+ &BX_CIRRUS_THIS pci_memaddr,
+ &BX_CIRRUS_THIS pci_conf[0x10],
+ CIRRUS_PNPMEM_SIZE);
+ DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
+ cirrus_mem_write_handler,
+ &BX_CIRRUS_THIS pci_mmioaddr,
+ &BX_CIRRUS_THIS pci_conf[0x14],
+ CIRRUS_PNPMMIO_SIZE);
+ }
+#endif
+}
+
+ void
+bx_svga_cirrus_c::reset(unsigned type)
+{
+ // reset VGA stuffs.
+ BX_CIRRUS_THIS bx_vga_c::reset(type);
+
+ // reset SVGA stuffs.
+ BX_CIRRUS_THIS svga_init_members();
+}
+
+
+ void
+bx_svga_cirrus_c::redraw_area(unsigned x0, unsigned y0,
+ unsigned width, unsigned height)
+{
+ unsigned xi, yi, x1, y1, xmax, ymax;
+
+ if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
+ BX_CIRRUS_THIS bx_vga_c::redraw_area(x0,y0,width,height);
+ return;
+ }
+
+ if (BX_CIRRUS_THIS svga_needs_update_mode) {
+ return;
+ }
+
+ BX_CIRRUS_THIS svga_needs_update_tile = true;
+
+ x1 = x0 + width - 1;
+ y1 = y0 + height - 1;
+ xmax = BX_CIRRUS_THIS svga_xres;
+ ymax = BX_CIRRUS_THIS svga_yres;
+ for (yi=0; yi<ymax; yi+=Y_TILESIZE) {
+ for (xi=0; xi<xmax; xi+=X_TILESIZE) {
+ // is redraw rectangle outside x boundaries of this tile?
+ if (x1 < xi) continue;
+ if (x0 > (xi+X_TILESIZE-1)) continue;
+
+ // is redraw rectangle outside y boundaries of this tile?
+ if (y1 < yi) continue;
+ if (y0 > (yi+Y_TILESIZE-1)) continue;
+
+ unsigned xti = xi/X_TILESIZE;
+ unsigned yti = yi/Y_TILESIZE;
+ SET_TILE_UPDATED (xti, yti, 1);
+ }
+ }
+}
+
+ void
+bx_svga_cirrus_c::mem_write_mode4and5_8bpp(Bit8u mode, Bit32u offset, Bit8u value)
+{
+ int x;
+ Bit8u val = value;
+ Bit8u *dst;
+
+ dst = BX_CIRRUS_THIS vidmem + offset;
+ for (x = 0; x < 8; x++) {
+ if (val & 0x80) {
+ *dst++ = BX_CIRRUS_THIS control.shadow_reg1;
+ } else if (mode == 5) {
+ *dst++ = BX_CIRRUS_THIS control.shadow_reg0;
+ }
+ val <<= 1;
+ }
+}
+
+ void
+bx_svga_cirrus_c::mem_write_mode4and5_16bpp(Bit8u mode, Bit32u offset, Bit8u value)
+{
+ int x;
+ Bit8u val = value;
+ Bit8u *dst;
+
+ dst = BX_CIRRUS_THIS vidmem + offset;
+ for (x = 0; x < 8; x++) {
+ if (val & 0x80) {
+ *dst++ = BX_CIRRUS_THIS control.shadow_reg1;
+ *dst++ = BX_CIRRUS_THIS control.reg[0x11];
+ } else if (mode == 5) {
+ *dst++ = BX_CIRRUS_THIS control.shadow_reg0;
+ *dst++ = BX_CIRRUS_THIS control.reg[0x10];
+ }
+ val <<= 1;
+ }
+}
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ bx_bool
+bx_svga_cirrus_c::cirrus_mem_read_handler(unsigned long addr, unsigned long len,
+ void *data, void *param)
+{
+ Bit8u *data_ptr;
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+ for (unsigned i = 0; i < len; i++) {
+ *data_ptr = BX_CIRRUS_THIS mem_read(addr);
+ addr++;
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ }
+ return 1;
+}
+#endif
+
+ Bit8u
+bx_svga_cirrus_c::mem_read(Bit32u addr)
+{
+ if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
+ return BX_CIRRUS_THIS bx_vga_c::mem_read(addr);
+ }
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ if (BX_CIRRUS_THIS pci_enabled) {
+ if ((addr >= BX_CIRRUS_THIS pci_memaddr) &&
+ (addr < (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256))) {
+ Bit8u *ptr;
+ Bit32u offset;
+
+ // video-to-cpu BLT
+ if (BX_CIRRUS_THIS bitblt.memdst_needed != 0) {
+ ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
+ if (ptr != BX_CIRRUS_THIS bitblt.memdst_endptr) {
+ BX_CIRRUS_THIS bitblt.memdst_ptr ++;
+ return *ptr;
+ }
+ if (!svga_asyncbitblt_next()) {
+ ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
+ BX_CIRRUS_THIS bitblt.memdst_ptr ++;
+ return *ptr;
+ }
+ }
+
+ ptr = BX_CIRRUS_THIS vidmem;
+ offset = addr - BX_CIRRUS_THIS pci_memaddr;
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
+ offset <<= 4;
+ } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
+ offset <<= 3;
+ }
+ return *(ptr + offset);
+ } else if ((addr >= (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256)) &&
+ (addr < (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE))) {
+ Bit32u offset = addr - (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256);
+ return svga_mmio_blt_read(offset & 0xff);
+ } else if ((addr >= BX_CIRRUS_THIS pci_mmioaddr) &&
+ (addr < (BX_CIRRUS_THIS pci_mmioaddr + CIRRUS_PNPMMIO_SIZE))) {
+ Bit32u offset;
+
+ offset = addr - BX_CIRRUS_THIS pci_mmioaddr;
+ if (offset >= 0x100) {
+ return svga_mmio_blt_read(offset - 0x100);
+ } else {
+ return svga_mmio_vga_read(offset);
+ }
+ }
+ }
+#endif // BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+
+ if (addr >= 0xA0000 && addr <= 0xAFFFF)
+ {
+ Bit32u bank;
+ Bit32u offset;
+ Bit8u *ptr;
+
+ // video-to-cpu BLT
+ if (BX_CIRRUS_THIS bitblt.memdst_needed != 0) {
+ ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
+ if (ptr != BX_CIRRUS_THIS bitblt.memdst_endptr) {
+ BX_CIRRUS_THIS bitblt.memdst_ptr ++;
+ return *ptr;
+ }
+ if (!svga_asyncbitblt_next()) {
+ ptr = BX_CIRRUS_THIS bitblt.memdst_ptr;
+ BX_CIRRUS_THIS bitblt.memdst_ptr ++;
+ return *ptr;
+ }
+ }
+
+ offset = addr & 0xffff;
+ bank = (offset >> 15);
+ offset &= 0x7fff;
+ if (offset < bank_limit[bank]) {
+ offset += bank_base[bank];
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
+ offset <<= 4;
+ } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
+ offset <<= 3;
+ }
+ offset &= (CIRRUS_VIDEO_MEMORY_BYTES - 1);
+ return *(BX_CIRRUS_THIS vidmem + offset);
+ }
+ else {
+ return 0xff;
+ }
+ }
+ else if (addr >= 0xB8000 && addr <= 0xBFFFF) {
+ // memory-mapped I/O.
+ Bit32u offset;
+
+ offset = addr - 0xb8000;
+ if ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x04)
+ return svga_mmio_blt_read(offset);
+ }
+ else {
+ BX_ERROR(("mem_read 0x%08x",addr));
+ }
+
+ return 0xff;
+}
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ bx_bool
+bx_svga_cirrus_c::cirrus_mem_write_handler(unsigned long addr, unsigned long len,
+ void *data, void *param)
+{
+ Bit8u *data_ptr;
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+ for (unsigned i = 0; i < len; i++) {
+ BX_CIRRUS_THIS mem_write(addr, *data_ptr);
+ addr++;
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ }
+ return 1;
+}
+#endif
+
+ void
+bx_svga_cirrus_c::mem_write(Bit32u addr, Bit8u value)
+{
+ if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
+ BX_CIRRUS_THIS bx_vga_c::mem_write(addr,value);
+ return;
+ }
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ if (BX_CIRRUS_THIS pci_enabled) {
+ if ((addr >= BX_CIRRUS_THIS pci_memaddr) &&
+ (addr < (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256))) {
+ Bit32u offset;
+ Bit8u mode;
+
+ // cpu-to-video BLT
+ if (BX_CIRRUS_THIS bitblt.memsrc_needed != 0) {
+ *(BX_CIRRUS_THIS bitblt.memsrc_ptr)++ = (value);
+ if (bitblt.memsrc_ptr == BX_CIRRUS_THIS bitblt.memsrc_endptr) {
+ svga_asyncbitblt_next();
+ }
+ return;
+ }
+
+ offset = addr - BX_CIRRUS_THIS pci_memaddr;
+ // BX_DEBUG(("write offset 0x%08x,value 0x%02x",offset,value));
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
+ offset <<= 4;
+ } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
+ offset <<= 3;
+ }
+ mode = BX_CIRRUS_THIS control.reg[0x05] & 0x07;
+ if ((mode < 4) || (mode > 5) || ((BX_CIRRUS_THIS control.reg[0x0b] & 0x4) == 0)) {
+ *(BX_CIRRUS_THIS vidmem + offset) = value;
+ } else {
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) != 0x14) {
+ mem_write_mode4and5_8bpp(mode, offset, value);
+ } else {
+ mem_write_mode4and5_16bpp(mode, offset, value);
+ }
+ }
+ BX_CIRRUS_THIS svga_needs_update_tile = true;
+ SET_TILE_UPDATED(((offset % BX_CIRRUS_THIS svga_pitch) / (BX_CIRRUS_THIS svga_bpp / 8)) / X_TILESIZE,
+ (offset / BX_CIRRUS_THIS svga_pitch) / Y_TILESIZE, 1);
+ return;
+ } else if ((addr >= (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256)) &&
+ (addr < (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE))) {
+ Bit32u offset = addr - (BX_CIRRUS_THIS pci_memaddr + CIRRUS_PNPMEM_SIZE - 256);
+ svga_mmio_blt_write(offset & 0xff, value);
+ } else if ((addr >= BX_CIRRUS_THIS pci_mmioaddr) &&
+ (addr < (BX_CIRRUS_THIS pci_mmioaddr + CIRRUS_PNPMMIO_SIZE))) {
+ // memory-mapped I/O.
+ Bit32u offset;
+
+ // BX_DEBUG(("write mmio 0x%08x",addr));
+ offset = addr - BX_CIRRUS_THIS pci_mmioaddr;
+ if (offset >= 0x100) {
+ svga_mmio_blt_write(offset - 0x100, value);
+ } else {
+ svga_mmio_vga_write(offset,value);
+ }
+ return;
+ }
+ }
+#endif // BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+
+ if (addr >= 0xA0000 && addr <= 0xAFFFF) {
+ Bit32u bank, offset;
+ Bit8u mode;
+
+ // cpu-to-video BLT
+ if (BX_CIRRUS_THIS bitblt.memsrc_needed != 0) {
+ *(BX_CIRRUS_THIS bitblt.memsrc_ptr)++ = (value);
+ if (BX_CIRRUS_THIS bitblt.memsrc_ptr == BX_CIRRUS_THIS bitblt.memsrc_endptr) {
+ svga_asyncbitblt_next();
+ }
+ return;
+ }
+
+ offset = addr & 0xffff;
+ bank = (offset >> 15);
+ offset &= 0x7fff;
+ if (offset < bank_limit[bank]) {
+ offset += bank_base[bank];
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) == 0x14) {
+ offset <<= 4;
+ } else if (BX_CIRRUS_THIS control.reg[0x0b] & 0x02) {
+ offset <<= 3;
+ }
+ offset &= (CIRRUS_VIDEO_MEMORY_BYTES - 1);
+ mode = BX_CIRRUS_THIS control.reg[0x05] & 0x07;
+ if ((mode < 4) || (mode > 5) || ((BX_CIRRUS_THIS control.reg[0x0b] & 0x4) == 0)) {
+ *(BX_CIRRUS_THIS vidmem + offset) = value;
+ } else {
+ if ((BX_CIRRUS_THIS control.reg[0x0b] & 0x14) != 0x14) {
+ mem_write_mode4and5_8bpp(mode, offset, value);
+ } else {
+ mem_write_mode4and5_16bpp(mode, offset, value);
+ }
+ }
+ BX_CIRRUS_THIS svga_needs_update_tile = true;
+ SET_TILE_UPDATED(((offset % BX_CIRRUS_THIS svga_pitch) / (BX_CIRRUS_THIS svga_bpp / 8)) / X_TILESIZE,
+ (offset / BX_CIRRUS_THIS svga_pitch) / Y_TILESIZE, 1);
+ }
+ } else if (addr >= 0xB8000 && addr <= 0xBFFFF) {
+ // memory-mapped I/O.
+ Bit32u offset;
+
+ offset = addr - 0xb8000;
+ if ((BX_CIRRUS_THIS sequencer.reg[0x17] & 0x44) == 0x04) {
+ svga_mmio_blt_write(offset & 0xff, value);
+ }
+ }
+ else {
+ BX_ERROR(("mem_write 0x%08x, value 0x%02x",addr,value));
+ }
+}
+
+
+ void
+bx_svga_cirrus_c::get_text_snapshot(Bit8u **text_snapshot,
+ unsigned *txHeight, unsigned *txWidth)
+{
+ BX_CIRRUS_THIS bx_vga_c::get_text_snapshot(text_snapshot,txHeight,txWidth);
+}
+
+ void
+bx_svga_cirrus_c::trigger_timer(void *this_ptr)
+{
+ BX_CIRRUS_THIS timer_handler(this_ptr);
+}
+
+ void
+bx_svga_cirrus_c::set_update_interval (unsigned interval)
+{
+ BX_INFO (("Changing timer interval to %d", interval));
+ BX_CIRRUS_THIS svga_timer_handler (theSvga);
+ bx_pc_system.activate_timer (BX_CIRRUS_THIS timer_id, interval, 1);
+}
+
+ Bit8u
+bx_svga_cirrus_c::get_actl_palette_idx(Bit8u index)
+{
+ return BX_CIRRUS_THIS bx_vga_c::get_actl_palette_idx(index);
+}
+
+ Bit32u
+bx_svga_cirrus_c::svga_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
+{
+#if !BX_USE_CIRRUS_SMF
+ bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
+
+ return( class_ptr->svga_read(address, io_len) );
+}
+ Bit32u
+bx_svga_cirrus_c::svga_read(Bit32u address, unsigned io_len)
+{
+#else
+ UNUSED(this_ptr);
+#endif // !BX_USE_CIRRUS_SMF
+
+ if ((io_len == 2) && ((address & 1) == 0)) {
+ Bit32u value;
+ value = (Bit32u)SVGA_READ(address,1);
+ value |= (Bit32u)SVGA_READ(address+1,1) << 8;
+ return value;
+ }
+
+ if (io_len != 1) {
+ BX_PANIC(("SVGA read: io_len != 1"));
+ }
+
+ switch (address) {
+ case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
+ case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
+ return BX_CIRRUS_THIS crtc.index;
+ case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
+ case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
+ if (BX_CIRRUS_THIS is_unlocked())
+ return BX_CIRRUS_THIS svga_read_crtc(address,BX_CIRRUS_THIS crtc.index);
+ break;
+
+ case 0x03c4: /* VGA: Sequencer Index Register */
+ return BX_CIRRUS_THIS sequencer.index;
+ case 0x03c5: /* VGA: Sequencer Registers */
+ if ((BX_CIRRUS_THIS sequencer.index == 0x06) ||
+ (BX_CIRRUS_THIS is_unlocked())) {
+ return BX_CIRRUS_THIS svga_read_sequencer(address,BX_CIRRUS_THIS sequencer.index);
+ }
+ break;
+
+ case 0x03c6: /* Hidden DAC */
+ if (BX_CIRRUS_THIS is_unlocked()) {
+ if ((++BX_CIRRUS_THIS hidden_dac.lockindex) == 5) {
+ BX_CIRRUS_THIS hidden_dac.lockindex = 0;
+ return BX_CIRRUS_THIS hidden_dac.data;
+ }
+ }
+ break;
+ case 0x03c8: /* PEL write address */
+ BX_CIRRUS_THIS hidden_dac.lockindex = 0;
+ break;
+ case 0x03c9: /* PEL Data Register, hiddem pel colors 00..0F */
+ if (BX_CIRRUS_THIS sequencer.reg[0x12] & CIRRUS_CURSOR_HIDDENPEL) {
+ Bit8u index = (BX_CIRRUS_THIS s.pel.read_data_register & 0x0f) * 3 +
+ BX_CIRRUS_THIS s.pel.read_data_cycle;
+ Bit8u retval = BX_CIRRUS_THIS hidden_dac.palette[index];
+ BX_CIRRUS_THIS s.pel.read_data_cycle ++;
+ if (BX_CIRRUS_THIS s.pel.read_data_cycle >= 3) {
+ BX_CIRRUS_THIS s.pel.read_data_cycle = 0;
+ BX_CIRRUS_THIS s.pel.read_data_register++;
+ }
+ return retval;
+ }
+ break;
+ case 0x03ce: /* VGA: Graphics Controller Index Register */
+ return BX_CIRRUS_THIS control.index;
+ case 0x03cf: /* VGA: Graphics Controller Registers */
+ if (BX_CIRRUS_THIS is_unlocked())
+ return BX_CIRRUS_THIS svga_read_control(address,BX_CIRRUS_THIS control.index);
+ break;
+
+ default:
+ break;
+ }
+
+ return VGA_READ(address,io_len);
+}
+
+ void
+bx_svga_cirrus_c::svga_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
+{
+#if !BX_USE_CIRRUS_SMF
+ bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
+
+ class_ptr->svga_write(address, value, io_len);
+}
+ void
+bx_svga_cirrus_c::svga_write(Bit32u address, Bit32u value, unsigned io_len)
+{
+#else
+ UNUSED(this_ptr);
+#endif // !BX_USE_CIRRUS_SMF
+
+ if ((io_len == 2) && ((address & 1) == 0)) {
+ SVGA_WRITE(address,value & 0xff,1);
+ SVGA_WRITE(address+1,value >> 8,1);
+ return;
+ }
+
+ if (io_len != 1) {
+ BX_PANIC(("SVGA write: io_len != 1"));
+ }
+
+ switch (address) {
+ case 0x03b4: /* VGA: CRTC Index Register (monochrome emulation modes) */
+ case 0x03d4: /* VGA: CRTC Index Register (color emulation modes) */
+ BX_CIRRUS_THIS crtc.index = value & 0x7f;
+ break;
+ case 0x03b5: /* VGA: CRTC Registers (monochrome emulation modes) */
+ case 0x03d5: /* VGA: CRTC Registers (color emulation modes) */
+ if (BX_CIRRUS_THIS is_unlocked()) {
+ BX_CIRRUS_THIS svga_write_crtc(address,BX_CIRRUS_THIS crtc.index,value);
+ return;
+ }
+ break;
+
+ case 0x03c4: /* VGA: Sequencer Index Register */
+ BX_CIRRUS_THIS sequencer.index = value;
+ break;
+ case 0x03c5: /* VGA: Sequencer Registers */
+ if ((BX_CIRRUS_THIS sequencer.index == 0x06) ||
+ (BX_CIRRUS_THIS is_unlocked())) {
+ BX_CIRRUS_THIS svga_write_sequencer(address,BX_CIRRUS_THIS sequencer.index,value);
+ return;
+ }
+ break;
+ case 0x03c6: /* Hidden DAC */
+ if (BX_CIRRUS_THIS is_unlocked()) {
+ if (BX_CIRRUS_THIS hidden_dac.lockindex == 4) {
+ BX_CIRRUS_THIS hidden_dac.data = value;
+ }
+ BX_CIRRUS_THIS hidden_dac.lockindex = 0;
+ return;
+ }
+ break;
+ case 0x03c9: /* PEL Data Register, hidden pel colors 00..0F */
+ BX_CIRRUS_THIS svga_needs_update_dispentire = true;
+
+ if (BX_CIRRUS_THIS sequencer.reg[0x12] & CIRRUS_CURSOR_HIDDENPEL) {
+ Bit8u index = (BX_CIRRUS_THIS s.pel.write_data_register & 0x0f) * 3 +
+ BX_CIRRUS_THIS s.pel.write_data_cycle;
+ BX_CIRRUS_THIS hidden_dac.palette[index] = value;
+ BX_CIRRUS_THIS s.pel.write_data_cycle ++;
+ if (BX_CIRRUS_THIS s.pel.write_data_cycle >= 3) {
+ BX_CIRRUS_THIS s.pel.write_data_cycle = 0;
+ BX_CIRRUS_THIS s.pel.write_data_register++;
+ }
+ return;
+ }
+ break;
+ case 0x03ce: /* VGA: Graphics Controller Index Register */
+ BX_CIRRUS_THIS control.index = value;
+ break;
+ case 0x03cf: /* VGA: Graphics Controller Registers */
+ if (BX_CIRRUS_THIS is_unlocked()) {
+ BX_CIRRUS_THIS svga_write_control(address,BX_CIRRUS_THIS control.index,value);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ VGA_WRITE(address,value,io_len);
+}
+
+ void
+bx_svga_cirrus_c::svga_timer_handler(void *this_ptr)
+{
+#if !BX_USE_CIRRUS_SMF
+ bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
+
+ class_ptr->svga_timer();
+}
+
+ void
+bx_svga_cirrus_c::svga_timer(void)
+{
+#else // !BX_USE_CIRRUS_SMF
+ UNUSED(this_ptr);
+#endif // !BX_USE_CIRRUS_SMF
+
+ BX_CIRRUS_THIS svga_update();
+ bx_gui->flush();
+}
+
+ void
+bx_svga_cirrus_c::svga_modeupdate(void)
+{
+ Bit32u iTopOffset, iHeight;
+ int width, iBpp, iDispBpp;
+
+ iTopOffset = (BX_CIRRUS_THIS crtc.reg[0x0c] << 8)
+ + BX_CIRRUS_THIS crtc.reg[0x0d]
+ + ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x01) << 16)
+ + ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x0c) << 15)
+ + ((BX_CIRRUS_THIS crtc.reg[0x1d] & 0x80) << 12);
+ iTopOffset <<= 2;
+
+ iHeight = 1 + BX_CIRRUS_THIS crtc.reg[0x12]
+ + ((BX_CIRRUS_THIS crtc.reg[0x07] & 0x02) << 7)
+ + ((BX_CIRRUS_THIS crtc.reg[0x07] & 0x40) << 3);
+ if ((BX_CIRRUS_THIS crtc.reg[0x1a] & 0x01) > 0) {
+ iHeight <<= 1;
+ }
+ width = (BX_CIRRUS_THIS crtc.reg[0x01] + 1) * 8;
+ iBpp = 8;
+ iDispBpp = 4;
+ if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x1) == CIRRUS_SR7_BPP_SVGA) {
+ switch (BX_CIRRUS_THIS sequencer.reg[0x07] & CIRRUS_SR7_BPP_MASK) {
+ case CIRRUS_SR7_BPP_8:
+ iBpp = 8;
+ iDispBpp = 8;
+ break;
+ case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
+ case CIRRUS_SR7_BPP_16:
+ iBpp = 16;
+ iDispBpp = (BX_CIRRUS_THIS hidden_dac.data & 0x1) ? 16 : 15;
+ break;
+ case CIRRUS_SR7_BPP_24:
+ iBpp = 24;
+ iDispBpp = 24;
+ break;
+ case CIRRUS_SR7_BPP_32:
+ iBpp = 32;
+ iDispBpp = 32;
+ break;
+ default:
+ BX_PANIC(("unknown bpp - seqencer.reg[0x07] = %02x",BX_CIRRUS_THIS sequencer.reg[0x07]));
+ break;
+ }
+ }
+ BX_INFO(("switched to %u x %u x %u",width,iHeight,iDispBpp));
+
+ BX_CIRRUS_THIS svga_xres = width;
+ BX_CIRRUS_THIS svga_yres = iHeight;
+ BX_CIRRUS_THIS svga_bpp = iBpp;
+ BX_CIRRUS_THIS svga_dispbpp = iDispBpp;
+ BX_CIRRUS_THIS disp_ptr = BX_CIRRUS_THIS vidmem + iTopOffset;
+}
+
+ void
+bx_svga_cirrus_c::draw_hardware_cursor(unsigned xc, unsigned yc, bx_svga_tileinfo_t *info)
+{
+ if (BX_CIRRUS_THIS hw_cursor.size &&
+ (xc < BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size) &&
+ (xc+X_TILESIZE > BX_CIRRUS_THIS hw_cursor.x) &&
+ (yc < BX_CIRRUS_THIS hw_cursor.y+BX_CIRRUS_THIS hw_cursor.size) &&
+ (yc+Y_TILESIZE > BX_CIRRUS_THIS hw_cursor.y)) {
+ int i;
+ unsigned w, h, pitch, cx, cy, cx0, cy0, cx1, cy1;
+
+ Bit8u * tile_ptr, * tile_ptr2;
+ Bit8u * plane0_ptr, *plane0_ptr2;
+ Bit8u * plane1_ptr, *plane1_ptr2;
+ unsigned long fgcol, bgcol;
+ Bit64u plane0, plane1;
+
+ cx0 = BX_CIRRUS_THIS hw_cursor.x > xc ? BX_CIRRUS_THIS hw_cursor.x : xc;
+ cy0 = BX_CIRRUS_THIS hw_cursor.y > yc ? BX_CIRRUS_THIS hw_cursor.y : yc;
+ cx1 = 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;
+ cy1 = 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;
+
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h) +
+ info->pitch * (cy0 - yc) + (info->bpp / 8) * (cx0 - xc);
+ plane0_ptr = BX_CIRRUS_THIS vidmem + BX_CIRRUS_THIS memsize - 16384;
+
+ switch (BX_CIRRUS_THIS hw_cursor.size) {
+ case 32:
+ plane0_ptr += (BX_CIRRUS_THIS sequencer.reg[0x13] & 0x3f) * 256;
+ plane1_ptr = plane0_ptr + 128;
+ pitch = 4;
+ break;
+
+ case 64:
+ plane0_ptr += (BX_CIRRUS_THIS sequencer.reg[0x13] & 0x3c) * 256;
+ plane1_ptr = plane0_ptr + 8;
+ pitch = 16;
+ break;
+
+ default:
+ BX_ERROR(("unsupported hardware cursor size"));
+ return;
+ break;
+ }
+
+ fgcol = MAKE_COLOUR(
+ BX_CIRRUS_THIS hidden_dac.palette[45], 6, info->red_shift, info->red_mask,
+ BX_CIRRUS_THIS hidden_dac.palette[46], 6, info->green_shift, info->green_mask,
+ BX_CIRRUS_THIS hidden_dac.palette[47], 6, info->blue_shift, info->blue_mask);
+ bgcol = MAKE_COLOUR(
+ BX_CIRRUS_THIS hidden_dac.palette[0], 6, info->red_shift, info->red_mask,
+ BX_CIRRUS_THIS hidden_dac.palette[1], 6, info->green_shift, info->green_mask,
+ BX_CIRRUS_THIS hidden_dac.palette[2], 6, info->blue_shift, info->blue_mask);
+
+ plane0_ptr += pitch * (cy0 - BX_CIRRUS_THIS hw_cursor.y);
+ plane1_ptr += pitch * (cy0 - BX_CIRRUS_THIS hw_cursor.y);
+ for (cy=cy0; cy<cy1; cy++) {
+ tile_ptr2 = tile_ptr + (info->bpp/8) * (cx1 - cx0) - 1;
+ plane0_ptr2 = plane0_ptr;
+ plane1_ptr2 = plane1_ptr;
+ plane0 = plane1 = 0;
+ for (i=0; i<BX_CIRRUS_THIS hw_cursor.size; i+=8) {
+ plane0 = (plane0 << 8) | *(plane0_ptr2++);
+ plane1 = (plane1 << 8) | *(plane1_ptr2++);
+ }
+ plane0 >>= BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size - cx1;
+ plane1 >>= BX_CIRRUS_THIS hw_cursor.x+BX_CIRRUS_THIS hw_cursor.size - cx1;
+ for (cx=cx0; cx<cx1; cx++) {
+ if (plane0 & 1) {
+ if (plane1 & 1) {
+ if (info->is_little_endian) {
+ for (i=info->bpp-8; i>-8; i-=8) {
+ *(tile_ptr2--) = fgcol >> i;
+ }
+ }
+ else {
+ for (i=0; i<info->bpp; i+=8) {
+ *(tile_ptr2--) = fgcol >> i;
+ }
+ }
+ }
+ else {
+ for (i=0; i<info->bpp; i+=8) {
+ *(tile_ptr2--) ^= 0xff;
+ }
+ }
+ }
+ else {
+ if (plane1 & 1) {
+ if (info->is_little_endian) {
+ for (i=info->bpp-8; i>-8; i-=8) {
+ *(tile_ptr2--) = bgcol >> i;
+ }
+ }
+ else {
+ for (i=0; i<info->bpp; i+=8) {
+ *(tile_ptr2--) = bgcol >> i;
+ }
+ }
+ }
+ else {
+ tile_ptr2 -= (info->bpp/8);
+ }
+ }
+ plane0 >>= 1;
+ plane1 >>= 1;
+ }
+ tile_ptr += info->pitch;
+ plane0_ptr += pitch;
+ plane1_ptr += pitch;
+ }
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_update(void)
+{
+ unsigned width, height, pitch;
+
+ /* skip screen update when the sequencer is in reset mode or video is disabled */
+ if (! BX_CIRRUS_THIS s.sequencer.reset1 ||
+ ! BX_CIRRUS_THIS s.sequencer.reset2 ||
+ ! BX_CIRRUS_THIS s.attribute_ctrl.video_enabled) {
+ return;
+ }
+
+ if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
+ if (BX_CIRRUS_THIS svga_needs_update_mode) {
+ BX_CIRRUS_THIS s.vga_mem_updated = 1;
+ BX_CIRRUS_THIS svga_needs_update_mode = false;
+ }
+ BX_CIRRUS_THIS bx_vga_c::update();
+ return;
+ }
+ else {
+ if (BX_CIRRUS_THIS svga_needs_update_mode) {
+ svga_modeupdate();
+ }
+ }
+
+ width = BX_CIRRUS_THIS svga_xres;
+ height = BX_CIRRUS_THIS svga_yres;
+ pitch = BX_CIRRUS_THIS svga_pitch;
+
+ if (BX_CIRRUS_THIS svga_needs_update_mode) {
+ width = BX_CIRRUS_THIS svga_xres;
+ height = BX_CIRRUS_THIS svga_yres;
+ bx_gui->dimension_update(width, height, 0, 0, BX_CIRRUS_THIS svga_dispbpp);
+ BX_CIRRUS_THIS svga_needs_update_mode = false;
+ BX_CIRRUS_THIS svga_needs_update_dispentire = true;
+ }
+
+ if (BX_CIRRUS_THIS svga_needs_update_dispentire) {
+ BX_CIRRUS_THIS redraw_area(0,0,width,height);
+ BX_CIRRUS_THIS svga_needs_update_dispentire = false;
+ }
+
+ if (!BX_CIRRUS_THIS svga_needs_update_tile) {
+ return;
+ }
+ BX_CIRRUS_THIS svga_needs_update_tile = false;
+
+ unsigned xc, yc, xti, yti;
+ unsigned r, c, w, h;
+ int i;
+ unsigned long red, green, blue, colour;
+ Bit8u * vid_ptr, * vid_ptr2;
+ Bit8u * tile_ptr, * tile_ptr2;
+ bx_svga_tileinfo_t info;
+
+ if (bx_gui->graphics_tile_info(&info)) {
+ if (info.is_indexed) {
+ switch (BX_CIRRUS_THIS svga_dispbpp) {
+ case 4:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays"));
+ break;
+ case 8:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + xc);
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ colour = 0;
+ for (i=0; i<(int)BX_CIRRUS_THIS svga_bpp; i+=8) {
+ colour |= *(vid_ptr2++) << i;
+ }
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ // FIXME? hardware cursor unsupported
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ }
+ }
+ else {
+ switch (BX_CIRRUS_THIS svga_dispbpp) {
+ case 4:
+ BX_ERROR(("cannot draw 4bpp SVGA"));
+ break;
+ case 8:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + xc);
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ colour = *(vid_ptr2++);
+ colour = MAKE_COLOUR(
+ BX_CIRRUS_THIS s.pel.data[colour].red, 6, info.red_shift, info.red_mask,
+ BX_CIRRUS_THIS s.pel.data[colour].green, 6, info.green_shift, info.green_mask,
+ BX_CIRRUS_THIS s.pel.data[colour].blue, 6, info.blue_shift, info.blue_mask);
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ draw_hardware_cursor(xc, yc, &info);
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 15:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<1));
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ colour = *(vid_ptr2++);
+ colour |= *(vid_ptr2++) << 8;
+ colour = MAKE_COLOUR(
+ colour & 0x001f, 5, info.blue_shift, info.blue_mask,
+ colour & 0x03e0, 10, info.green_shift, info.green_mask,
+ colour & 0x7c00, 15, info.red_shift, info.red_mask);
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ draw_hardware_cursor(xc, yc, &info);
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 16:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<1));
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ colour = *(vid_ptr2++);
+ colour |= *(vid_ptr2++) << 8;
+ colour = MAKE_COLOUR(
+ colour & 0x001f, 5, info.blue_shift, info.blue_mask,
+ colour & 0x07e0, 11, info.green_shift, info.green_mask,
+ colour & 0xf800, 16, info.red_shift, info.red_mask);
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ draw_hardware_cursor(xc, yc, &info);
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 24:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + 3*xc);
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ blue = *(vid_ptr2++);
+ green = *(vid_ptr2++);
+ red = *(vid_ptr2++);
+ colour = MAKE_COLOUR(
+ red, 8, info.red_shift, info.red_mask,
+ green, 8, info.green_shift, info.green_mask,
+ blue, 8, info.blue_shift, info.blue_mask);
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ draw_hardware_cursor(xc, yc, &info);
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 32:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++) {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++) {
+ if (GET_TILE_UPDATED (xti, yti)) {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc<<2));
+ tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
+ for (r=0; r<h; r++) {
+ vid_ptr2 = vid_ptr;
+ tile_ptr2 = tile_ptr;
+ for (c=0; c<w; c++) {
+ blue = *(vid_ptr2++);
+ green = *(vid_ptr2++);
+ red = *(vid_ptr2++);
+ vid_ptr2++;
+ colour = MAKE_COLOUR(
+ red, 8, info.red_shift, info.red_mask,
+ green, 8, info.green_shift, info.green_mask,
+ blue, 8, info.blue_shift, info.blue_mask);
+ if (info.is_little_endian) {
+ for (i=0; i<info.bpp; i+=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ else {
+ for (i=info.bpp-8; i>-8; i-=8) {
+ *(tile_ptr2++) = colour >> i;
+ }
+ }
+ }
+ vid_ptr += pitch;
+ tile_ptr += info.pitch;
+ }
+ draw_hardware_cursor(xc, yc, &info);
+ bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ else {
+ switch (BX_CIRRUS_THIS svga_bpp) {
+ case 4:
+ BX_ERROR(("cannot draw 4bpp SVGA"));
+ break;
+ case 8:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++)
+ {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++)
+ {
+ if (GET_TILE_UPDATED (xti, yti))
+ {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + xc);
+ tile_ptr = BX_CIRRUS_THIS tilemem;
+ for (r=0; r<Y_TILESIZE; r++)
+ {
+ memcpy(tile_ptr,vid_ptr,X_TILESIZE);
+ vid_ptr += pitch;
+ tile_ptr += X_TILESIZE;
+ }
+ bx_gui->graphics_tile_update(BX_CIRRUS_THIS tilemem, xc, yc);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 16:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++)
+ {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++)
+ {
+ if (GET_TILE_UPDATED (xti, yti))
+ {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc << 1));
+ tile_ptr = BX_CIRRUS_THIS tilemem;
+ for (r=0; r<Y_TILESIZE; r++)
+ {
+ memcpy(tile_ptr,vid_ptr,X_TILESIZE<<1);
+ vid_ptr += pitch;
+ tile_ptr += X_TILESIZE << 1;
+ }
+ bx_gui->graphics_tile_update(BX_CIRRUS_THIS tilemem, xc, yc);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 24:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++)
+ {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++)
+ {
+ if (GET_TILE_UPDATED (xti, yti))
+ {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc * 3));
+ tile_ptr = BX_CIRRUS_THIS tilemem;
+ for (r=0; r<Y_TILESIZE; r++)
+ {
+ memcpy(tile_ptr,vid_ptr,X_TILESIZE*3);
+ vid_ptr += pitch;
+ tile_ptr += X_TILESIZE * 3;
+ }
+ bx_gui->graphics_tile_update(BX_CIRRUS_THIS tilemem, xc, yc);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ case 32:
+ for (yc=0, yti = 0; yc<height; yc+=Y_TILESIZE, yti++)
+ {
+ for (xc=0, xti = 0; xc<width; xc+=X_TILESIZE, xti++)
+ {
+ if (GET_TILE_UPDATED (xti, yti))
+ {
+ vid_ptr = BX_CIRRUS_THIS disp_ptr + (yc * pitch + (xc << 2));
+ tile_ptr = BX_CIRRUS_THIS tilemem;
+ for (r=0; r<Y_TILESIZE; r++)
+ {
+ memcpy(tile_ptr,vid_ptr,X_TILESIZE<<2);
+ vid_ptr += pitch;
+ tile_ptr += X_TILESIZE << 2;
+ }
+ bx_gui->graphics_tile_update(BX_CIRRUS_THIS tilemem, xc, yc);
+ SET_TILE_UPDATED (xti, yti, 0);
+ }
+ }
+ }
+ break;
+ default:
+ BX_PANIC(("unknown bpp %u",(unsigned)BX_CIRRUS_THIS svga_bpp));
+ break;
+ }
+ }
+}
+
+ void
+bx_svga_cirrus_c::update_bank_ptr(Bit8u bank_index)
+{
+ unsigned offset;
+ unsigned limit;
+
+ if (BX_CIRRUS_THIS banking_is_dual())
+ offset = BX_CIRRUS_THIS control.reg[0x09 + bank_index];
+ else
+ offset = BX_CIRRUS_THIS control.reg[0x09];
+
+ if (BX_CIRRUS_THIS banking_granularity_is_16k())
+ offset <<= 14;
+ else
+ offset <<= 12;
+
+ if (CIRRUS_VIDEO_MEMORY_BYTES <= offset) {
+ limit = 0;
+ BX_ERROR(("bank offset %08x is invalid",offset));
+ } else {
+ limit = CIRRUS_VIDEO_MEMORY_BYTES - offset;
+ }
+
+ if (!BX_CIRRUS_THIS banking_is_dual() && (bank_index != 0)) {
+ if (limit > 0x8000) {
+ offset += 0x8000;
+ limit -= 0x8000;
+ } else {
+ limit = 0;
+ }
+ }
+
+ if (limit > 0) {
+ BX_CIRRUS_THIS bank_base[bank_index] = offset;
+ BX_CIRRUS_THIS bank_limit[bank_index] = limit;
+ } else {
+ BX_CIRRUS_THIS bank_base[bank_index] = 0;
+ BX_CIRRUS_THIS bank_limit[bank_index] = 0;
+ }
+}
+
+ Bit8u
+bx_svga_cirrus_c::svga_read_crtc(Bit32u address, unsigned index)
+{
+ switch (index) {
+ case 0x00: // VGA
+ case 0x01: // VGA
+ case 0x02: // VGA
+ case 0x03: // VGA
+ case 0x04: // VGA
+ case 0x05: // VGA
+ case 0x06: // VGA
+ case 0x07: // VGA
+ case 0x08: // VGA
+ case 0x09: // VGA
+ case 0x0a: // VGA
+ case 0x0b: // VGA
+ case 0x0c: // VGA
+ case 0x0d: // VGA
+ case 0x0e: // VGA
+ case 0x0f: // VGA
+ case 0x10: // VGA
+ case 0x11: // VGA
+ case 0x12: // VGA
+ case 0x13: // VGA
+ case 0x14: // VGA
+ case 0x15: // VGA
+ case 0x16: // VGA
+ case 0x17: // VGA
+ case 0x18: // VGA
+ break;
+ case 0x19:
+ case 0x1A:
+ case 0x1B:
+ case 0x1C:
+ case 0x1D:
+ case 0x22:
+ case 0x24:
+ case 0x25:
+ case 0x27:
+ break;
+ case 0x26:
+ return (BX_CIRRUS_THIS s.attribute_ctrl.address & 0x3f);
+ default:
+ BX_ERROR(("CRTC index 0x%02x is unknown(read)", index));
+ break;
+ }
+
+ if (index <= VGA_CRTC_MAX) {
+ return VGA_READ(address,1);
+ }
+
+ if (index <= CIRRUS_CRTC_MAX) {
+ return BX_CIRRUS_THIS crtc.reg[index];
+ }
+
+ return 0xff;
+}
+
+ void
+bx_svga_cirrus_c::svga_write_crtc(Bit32u address, unsigned index, Bit8u value)
+{
+ BX_DEBUG(("crtc: index 0x%02x write 0x%02x", index, (unsigned)value));
+
+ switch (index) {
+ case 0x00: // VGA
+ case 0x02: // VGA
+ case 0x03: // VGA
+ case 0x04: // VGA
+ case 0x05: // VGA
+ case 0x06: // VGA
+ case 0x08: // VGA
+ case 0x0a: // VGA
+ case 0x0b: // VGA
+ case 0x0e: // VGA
+ case 0x0f: // VGA
+ case 0x10: // VGA
+ case 0x11: // VGA
+ case 0x14: // VGA
+ case 0x15: // VGA
+ case 0x16: // VGA
+ case 0x17: // VGA
+ case 0x18: // VGA
+ break;
+
+ case 0x01: // VGA
+ case 0x07: // VGA
+ case 0x09: // VGA
+ case 0x0c: // VGA (display offset 0x00ff00)
+ case 0x0d: // VGA (display offset 0x0000ff)
+ case 0x12: // VGA
+ case 0x1A: // 0x01: interlaced video mode
+ case 0x1D: // 0x80: offset 0x080000 (>=CLGD5434)
+ BX_CIRRUS_THIS svga_needs_update_mode = true;
+ break;
+
+ case 0x13: // VGA
+ case 0x1B: // 0x01: offset 0x010000, 0x0c: offset 0x060000
+ BX_CIRRUS_THIS svga_pitch = (BX_CIRRUS_THIS crtc.reg[0x13] << 3) | ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x10) << 7);
+ BX_CIRRUS_THIS svga_needs_update_mode = true;
+ break;
+
+ case 0x19:
+ case 0x1C:
+ break;
+
+ default:
+ BX_ERROR(("CRTC index 0x%02x is unknown(write 0x%02x)", index, (unsigned)value));
+ return;
+ }
+
+ if (index <= CIRRUS_CRTC_MAX) {
+ BX_CIRRUS_THIS crtc.reg[index] = value;
+ }
+ if (index <= VGA_CRTC_MAX) {
+ VGA_WRITE(address,value,1);
+ }
+}
+
+ Bit8u
+bx_svga_cirrus_c::svga_read_sequencer(Bit32u address, unsigned index)
+{
+ switch (index) {
+ case 0x00: // VGA
+ case 0x01: // VGA
+ case 0x02: // VGA
+ case 0x03: // VGA
+ case 0x04: // VGA
+ break;
+ case 0x6: // cirrus unlock extensions
+ case 0x7: // cirrus extended sequencer mode
+ case 0xf: // cirrus dram control
+ case 0x12: // graphics cursor attribute
+ case 0x13: // graphics cursor pattern address offset
+ case 0x17: // configuration readback & extended control
+ break;
+ case 0x10: // cursor xpos << 5 (index & 0x3f)
+ case 0x30:
+ case 0x50:
+ case 0x70:
+ case 0x90:
+ case 0xb0:
+ case 0xd0:
+ case 0xf0:
+ return BX_CIRRUS_THIS sequencer.reg[0x10];
+ case 0x11: // cursor ypos << 5 (index & 0x3f)
+ case 0x31:
+ case 0x51:
+ case 0x71:
+ case 0x91:
+ case 0xb1:
+ case 0xd1:
+ case 0xf1:
+ return BX_CIRRUS_THIS sequencer.reg[0x11];
+ default:
+ BX_INFO (("sequencer index 0x%02x is unknown(read)", index));
+ break;
+ }
+
+ if (index <= VGA_SEQENCER_MAX) {
+ return VGA_READ(address,1);
+ }
+
+ if (index <= CIRRUS_SEQENCER_MAX) {
+ return BX_CIRRUS_THIS sequencer.reg[index];
+ }
+
+ return 0xff;
+}
+
+ void
+bx_svga_cirrus_c::svga_write_sequencer(Bit32u address, unsigned index, Bit8u value)
+{
+ BX_DEBUG(("sequencer: index 0x%02x write 0x%02x", index, (unsigned)value));
+
+ bx_bool update_cursor = 0;
+ Bit16u x, y, size;
+
+ x = BX_CIRRUS_THIS hw_cursor.x;
+ y = BX_CIRRUS_THIS hw_cursor.y;
+ size = BX_CIRRUS_THIS hw_cursor.size;
+
+ switch (index) {
+ case 0x00: // VGA
+ case 0x02: // VGA
+ case 0x03: // VGA
+ break;
+ case 0x01: // VGA
+ case 0x04: // VGA
+ BX_CIRRUS_THIS svga_needs_update_mode = true;
+ break;
+ case 0x6: // cirrus unlock extensions
+ value &= 0x17;
+ if (value == 0x12) {
+ BX_CIRRUS_THIS svga_unlock_special = true;
+ BX_CIRRUS_THIS sequencer.reg[0x6] = 0x12;
+ }
+ else {
+ BX_CIRRUS_THIS svga_unlock_special = false;
+ BX_CIRRUS_THIS sequencer.reg[0x6] = 0x0f;
+ }
+ return;
+ case 0x7: // cirrus extended sequencer mode
+ if (value != BX_CIRRUS_THIS sequencer.reg[0x7]) {
+ BX_CIRRUS_THIS svga_needs_update_mode = true;
+ }
+ break;
+ case 0x08:
+ case 0x09:
+ case 0x0a: // cirrus scratch reg 1
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x1b:
+ case 0x1c:
+ case 0x1d:
+ case 0x1e:
+ break;
+ case 0x0f:
+ return;
+ case 0x10: // cursor xpos << 5 (index & 0x3f)
+ case 0x30:
+ case 0x50:
+ case 0x70:
+ case 0x90:
+ case 0xb0:
+ case 0xd0:
+ case 0xf0:
+ BX_CIRRUS_THIS sequencer.reg[0x10] = value;
+ x = BX_CIRRUS_THIS hw_cursor.x;
+ BX_CIRRUS_THIS hw_cursor.x = (value << 3) | (index >> 5);
+ update_cursor = 1;
+ break;
+ case 0x11: // cursor ypos << 5 (index & 0x3f)
+ case 0x31:
+ case 0x51:
+ case 0x71:
+ case 0x91:
+ case 0xb1:
+ case 0xd1:
+ case 0xf1:
+ BX_CIRRUS_THIS sequencer.reg[0x11] = value;
+ y = BX_CIRRUS_THIS hw_cursor.y;
+ BX_CIRRUS_THIS hw_cursor.y = (value << 3) | (index >> 5);
+ update_cursor = 1;
+ break;
+ case 0x12:
+ size = BX_CIRRUS_THIS hw_cursor.size;
+ if (value & CIRRUS_CURSOR_SHOW) {
+ if (value & CIRRUS_CURSOR_LARGE) {
+ BX_CIRRUS_THIS hw_cursor.size = 64;
+ }
+ else {
+ BX_CIRRUS_THIS hw_cursor.size = 32;
+ }
+ }
+ else {
+ BX_CIRRUS_THIS hw_cursor.size = 0;
+ }
+ update_cursor = 1;
+ break;
+ case 0x13:
+ update_cursor = 1;
+ break;
+ case 0x17:
+ value = (BX_CIRRUS_THIS sequencer.reg[0x17] & 0x38) | (value & 0xc7);
+ break;
+ default:
+ BX_INFO (("sequencer index 0x%02x is unknown(write 0x%02x)", index, (unsigned)value));
+ break;
+ }
+
+ if (update_cursor) {
+ BX_CIRRUS_THIS redraw_area(x, y, size, size);
+ 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);
+ }
+
+ if (index <= CIRRUS_SEQENCER_MAX) {
+ BX_CIRRUS_THIS sequencer.reg[index] = value;
+ }
+ if (index <= VGA_SEQENCER_MAX) {
+ VGA_WRITE(address,value,1);
+ }
+}
+
+ Bit8u
+bx_svga_cirrus_c::svga_read_control(Bit32u address, unsigned index)
+{
+ switch (index) {
+ case 0x00: // VGA
+ return BX_CIRRUS_THIS control.shadow_reg0;
+ case 0x01: // VGA
+ return BX_CIRRUS_THIS control.shadow_reg1;
+ case 0x05: // VGA
+ return BX_CIRRUS_THIS control.reg[index];
+ case 0x02: // VGA
+ case 0x03: // VGA
+ case 0x04: // VGA
+ case 0x06: // VGA
+ case 0x07: // VGA
+ case 0x08: // VGA
+ break;
+ case 0x09: // bank offset #0
+ case 0x0A: // bank offset #1
+ case 0x0B:
+ break;
+
+ case 0x10: // BGCOLOR 0x0000ff00
+ case 0x11: // FGCOLOR 0x0000ff00
+ case 0x12: // BGCOLOR 0x00ff0000
+ case 0x13: // FGCOLOR 0x00ff0000
+ case 0x14: // BGCOLOR 0xff000000
+ case 0x15: // FGCOLOR 0xff000000
+ break;
+
+ case 0x20: // BLT WIDTH 0x0000ff
+ case 0x21: // BLT WIDTH 0x001f00
+ case 0x22: // BLT HEIGHT 0x0000ff
+ case 0x23: // BLT HEIGHT 0x001f00
+ case 0x24: // BLT DEST PITCH 0x0000ff
+ case 0x25: // BLT DEST PITCH 0x001f00
+ case 0x26: // BLT SRC PITCH 0x0000ff
+ case 0x27: // BLT SRC PITCH 0x001f00
+ case 0x28: // BLT DEST ADDR 0x0000ff
+ case 0x29: // BLT DEST ADDR 0x00ff00
+ case 0x2a: // BLT DEST ADDR 0x3f0000
+ case 0x2c: // BLT SRC ADDR 0x0000ff
+ case 0x2d: // BLT SRC ADDR 0x00ff00
+ case 0x2e: // BLT SRC ADDR 0x3f0000
+ case 0x2f: // BLT WRITE MASK
+ case 0x30: // BLT MODE
+ case 0x31: // BLT STATUS
+ case 0x32: // RASTER OP
+ case 0x34: // BLT TRANSPARENT COLOR 0x00ff
+ case 0x35: // BLT TRANSPARENT COLOR 0xff00
+ case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
+ case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
+ break;
+
+ default:
+ BX_INFO (("control index 0x%02x is unknown(read)", index));
+ break;
+ }
+
+ if (index <= VGA_CONTROL_MAX) {
+ return VGA_READ(address,1);
+ }
+
+ if (index <= CIRRUS_CONTROL_MAX) {
+ return BX_CIRRUS_THIS control.reg[index];
+ }
+
+ return 0xff;
+}
+
+ void
+bx_svga_cirrus_c::svga_write_control(Bit32u address, unsigned index, Bit8u value)
+{
+ Bit8u old_value;
+
+ BX_DEBUG(("control: index 0x%02x write 0x%02x", index, (unsigned)value));
+
+ switch (index) {
+ case 0x00: // VGA
+ BX_CIRRUS_THIS control.shadow_reg0 = value;
+ break;
+ case 0x01: // VGA
+ BX_CIRRUS_THIS control.shadow_reg1 = value;
+ break;
+ case 0x02: // VGA
+ case 0x03: // VGA
+ case 0x04: // VGA
+ case 0x07: // VGA
+ case 0x08: // VGA
+ break;
+ case 0x05: // VGA
+ case 0x06: // VGA
+ BX_CIRRUS_THIS svga_needs_update_mode = true;
+ break;
+ case 0x09: // bank offset #0
+ case 0x0A: // bank offset #1
+ case 0x0B:
+ BX_CIRRUS_THIS control.reg[index] = value;
+ update_bank_ptr(0);
+ update_bank_ptr(1);
+ break;
+
+ case 0x10: // BGCOLOR 0x0000ff00
+ case 0x11: // FGCOLOR 0x0000ff00
+ case 0x12: // BGCOLOR 0x00ff0000
+ case 0x13: // FGCOLOR 0x00ff0000
+ case 0x14: // BGCOLOR 0xff000000
+ case 0x15: // FGCOLOR 0xff000000
+ break;
+
+ case 0x20: // BLT WIDTH 0x0000ff
+ break;
+ case 0x21: // BLT WIDTH 0x001f00
+ value &= 0x1f;
+ break;
+ case 0x22: // BLT HEIGHT 0x0000ff
+ break;
+ case 0x23: // BLT HEIGHT 0x001f00
+ value &= 0x1f;
+ break;
+ case 0x24: // BLT DEST PITCH 0x0000ff
+ break;
+ case 0x25: // BLT DEST PITCH 0x001f00
+ value &= 0x1f;
+ break;
+ case 0x26: // BLT SRC PITCH 0x0000ff
+ break;
+ case 0x27: // BLT SRC PITCH 0x001f00
+ value &= 0x1f;
+ break;
+ case 0x28: // BLT DEST ADDR 0x0000ff
+ break;
+ case 0x29: // BLT DEST ADDR 0x00ff00
+ break;
+ case 0x2a: // BLT DEST ADDR 0x3f0000
+ BX_CIRRUS_THIS control.reg[index] = value & 0x3f;
+ if (BX_CIRRUS_THIS control.reg[0x31] & CIRRUS_BLT_AUTOSTART) {
+ svga_bitblt();
+ }
+ return;
+ case 0x2c: // BLT SRC ADDR 0x0000ff
+ break;
+ case 0x2d: // BLT SRC ADDR 0x00ff00
+ break;
+ case 0x2e: // BLT SRC ADDR 0x3f0000
+ value &= 0x3f;
+ break;
+ case 0x2f: // BLT WRITE MASK
+ if (value & 0x80) {
+ BX_ERROR(("BLT WRITE MASK support is not complete (value = 0x%02x)", value));
+ }
+ break;
+ case 0x30: // BLT MODE
+ break;
+ case 0x31: // BLT STATUS/START
+ old_value = BX_CIRRUS_THIS control.reg[0x31];
+ BX_CIRRUS_THIS control.reg[0x31] = value;
+ if (((old_value & CIRRUS_BLT_RESET) != 0) &&
+ ((value & CIRRUS_BLT_RESET) == 0)) {
+ svga_reset_bitblt();
+ }
+ else if (((old_value & CIRRUS_BLT_START) == 0) &&
+ ((value & CIRRUS_BLT_START) != 0)) {
+ BX_CIRRUS_THIS control.reg[0x31] |= CIRRUS_BLT_BUSY;
+ svga_bitblt();
+ }
+ return;
+ case 0x32: // RASTER OP
+ break;
+ case 0x34: // BLT TRANSPARENT COLOR 0x00ff
+ case 0x35: // BLT TRANSPARENT COLOR 0xff00
+ case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
+ case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
+ default:
+ BX_INFO (("control index 0x%02x is unknown(write 0x%02x)", index, (unsigned)value));
+ break;
+ }
+
+ if (index <= CIRRUS_CONTROL_MAX) {
+ BX_CIRRUS_THIS control.reg[index] = value;
+ }
+ if (index <= VGA_CONTROL_MAX) {
+ VGA_WRITE(address,value,1);
+ }
+}
+
+ Bit8u
+bx_svga_cirrus_c::svga_mmio_vga_read(Bit32u address)
+{
+ Bit8u value = 0xff;
+// bx_bool svga_unlock_special_old = BX_CIRRUS_THIS svga_unlock_special;
+
+ BX_DEBUG(("MMIO vga read - address 0x%04x, value 0x%02x",address,value));
+
+// BX_CIRRUS_THIS svga_unlock_special = true;
+
+#if BX_USE_CIRRUS_SMF
+ value = (Bit8u)svga_read_handler(theSvga,0x3c0+address,1);
+#else // BX_USE_CIRRUS_SMF
+ value = (Bit8u)svga_read(0x3c0+address,1);
+#endif // BX_USE_CIRRUS_SMF
+
+// BX_CIRRUS_THIS svga_unlock_special = svga_unlock_special_old;
+ return value;
+}
+
+ void
+bx_svga_cirrus_c::svga_mmio_vga_write(Bit32u address,Bit8u value)
+{
+// bx_bool svga_unlock_special_old = BX_CIRRUS_THIS svga_unlock_special;
+
+ BX_DEBUG(("MMIO vga write - address 0x%04x, value 0x%02x",address,value));
+
+// BX_CIRRUS_THIS svga_unlock_special = true;
+
+#if BX_USE_CIRRUS_SMF
+ svga_write_handler(theSvga,0x3c0+address,value,1);
+#else // BX_USE_CIRRUS_SMF
+ svga_write(0x3c0+address,value,1);
+#endif // BX_USE_CIRRUS_SMF
+
+/* switch (BX_CIRRUS_THIS sequencer.reg[0x06]) {
+ case 0x0f:
+ svga_unlock_special_old = false;
+ break;
+ case 0x12:
+ svga_unlock_special_old = true;
+ break;
+ }
+
+ BX_CIRRUS_THIS svga_unlock_special = svga_unlock_special_old;*/
+}
+
+ Bit8u
+bx_svga_cirrus_c::svga_mmio_blt_read(Bit32u address)
+{
+ Bit8u value = 0xff;
+
+ switch (address) {
+ case (CLGD543x_MMIO_BLTBGCOLOR+0):
+ value = BX_CIRRUS_THIS control.shadow_reg0;
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+1):
+ value = svga_read_control(0x3cf,0x10);
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+2):
+ value = svga_read_control(0x3cf,0x12);
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+3):
+ value = svga_read_control(0x3cf,0x14);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+0):
+ value = BX_CIRRUS_THIS control.shadow_reg1;
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+1):
+ value = svga_read_control(0x3cf,0x11);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+2):
+ value = svga_read_control(0x3cf,0x13);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+3):
+ value = svga_read_control(0x3cf,0x15);
+ break;
+ case (CLGD543x_MMIO_BLTWIDTH+0):
+ value = svga_read_control(0x3cf,0x20);
+ break;
+ case (CLGD543x_MMIO_BLTWIDTH+1):
+ value = svga_read_control(0x3cf,0x21);
+ break;
+ case (CLGD543x_MMIO_BLTHEIGHT+0):
+ value = svga_read_control(0x3cf,0x22);
+ break;
+ case (CLGD543x_MMIO_BLTHEIGHT+1):
+ value = svga_read_control(0x3cf,0x23);
+ break;
+ case (CLGD543x_MMIO_BLTDESTPITCH+0):
+ value = svga_read_control(0x3cf,0x24);
+ break;
+ case (CLGD543x_MMIO_BLTDESTPITCH+1):
+ value = svga_read_control(0x3cf,0x25);
+ break;
+ case (CLGD543x_MMIO_BLTSRCPITCH+0):
+ value = svga_read_control(0x3cf,0x26);
+ break;
+ case (CLGD543x_MMIO_BLTSRCPITCH+1):
+ value = svga_read_control(0x3cf,0x27);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+0):
+ value = svga_read_control(0x3cf,0x28);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+1):
+ value = svga_read_control(0x3cf,0x29);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+2):
+ value = svga_read_control(0x3cf,0x2a);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+0):
+ value = svga_read_control(0x3cf,0x2c);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+1):
+ value = svga_read_control(0x3cf,0x2d);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+2):
+ value = svga_read_control(0x3cf,0x2e);
+ break;
+ case CLGD543x_MMIO_BLTWRITEMASK:
+ value = svga_read_control(0x3cf,0x2f);
+ break;
+ case CLGD543x_MMIO_BLTMODE:
+ value = svga_read_control(0x3cf,0x30);
+ break;
+ case CLGD543x_MMIO_BLTROP:
+ value = svga_read_control(0x3cf,0x32);
+ break;
+ case CLGD543x_MMIO_BLTMODEEXT:
+ value = svga_read_control(0x3cf,0x33);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+0):
+ value = svga_read_control(0x3cf,0x34);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+1):
+ value = svga_read_control(0x3cf,0x35);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+2):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+3):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+0):
+ value = svga_read_control(0x3cf,0x38);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+1):
+ value = svga_read_control(0x3cf,0x39);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+2):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+3):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
+ break;
+ case CLGD543x_MMIO_BLTSTATUS:
+ value = svga_read_control(0x3cf,0x31);
+ break;
+ default:
+ BX_ERROR(("MMIO blt read - address 0x%04x",address));
+ break;
+ }
+
+ BX_DEBUG(("MMIO blt read - address 0x%04x, value 0x%02x",address,value));
+
+ return value;
+}
+
+ void
+bx_svga_cirrus_c::svga_mmio_blt_write(Bit32u address,Bit8u value)
+{
+ BX_DEBUG(("MMIO blt write - address 0x%04x, value 0x%02x",address,value));
+
+ switch (address) {
+ case (CLGD543x_MMIO_BLTBGCOLOR+0):
+ BX_CIRRUS_THIS control.shadow_reg0 = value;
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+1):
+ svga_write_control(0x3cf,0x10,value);
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+2):
+ svga_write_control(0x3cf,0x12,value);
+ break;
+ case (CLGD543x_MMIO_BLTBGCOLOR+3):
+ svga_write_control(0x3cf,0x14,value);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+0):
+ BX_CIRRUS_THIS control.shadow_reg1 = value;
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+1):
+ svga_write_control(0x3cf,0x11,value);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+2):
+ svga_write_control(0x3cf,0x13,value);
+ break;
+ case (CLGD543x_MMIO_BLTFGCOLOR+3):
+ svga_write_control(0x3cf,0x15,value);
+ break;
+ case (CLGD543x_MMIO_BLTWIDTH+0):
+ svga_write_control(0x3cf,0x20,value);
+ break;
+ case (CLGD543x_MMIO_BLTWIDTH+1):
+ svga_write_control(0x3cf,0x21,value);
+ break;
+ case (CLGD543x_MMIO_BLTHEIGHT+0):
+ svga_write_control(0x3cf,0x22,value);
+ break;
+ case (CLGD543x_MMIO_BLTHEIGHT+1):
+ svga_write_control(0x3cf,0x23,value);
+ break;
+ case (CLGD543x_MMIO_BLTDESTPITCH+0):
+ svga_write_control(0x3cf,0x24,value);
+ break;
+ case (CLGD543x_MMIO_BLTDESTPITCH+1):
+ svga_write_control(0x3cf,0x25,value);
+ break;
+ case (CLGD543x_MMIO_BLTSRCPITCH+0):
+ svga_write_control(0x3cf,0x26,value);
+ break;
+ case (CLGD543x_MMIO_BLTSRCPITCH+1):
+ svga_write_control(0x3cf,0x27,value);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+0):
+ svga_write_control(0x3cf,0x28,value);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+1):
+ svga_write_control(0x3cf,0x29,value);
+ break;
+ case (CLGD543x_MMIO_BLTDESTADDR+2):
+ svga_write_control(0x3cf,0x2a,value);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+0):
+ svga_write_control(0x3cf,0x2c,value);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+1):
+ svga_write_control(0x3cf,0x2d,value);
+ break;
+ case (CLGD543x_MMIO_BLTSRCADDR+2):
+ svga_write_control(0x3cf,0x2e,value);
+ break;
+ case CLGD543x_MMIO_BLTWRITEMASK:
+ svga_write_control(0x3cf,0x2f,value);
+ break;
+ case CLGD543x_MMIO_BLTMODE:
+ svga_write_control(0x3cf,0x30,value);
+ break;
+ case CLGD543x_MMIO_BLTROP:
+ svga_write_control(0x3cf,0x32,value);
+ break;
+ case CLGD543x_MMIO_BLTMODEEXT:
+ svga_write_control(0x3cf,0x33,value);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+0):
+ svga_write_control(0x3cf,0x34,value);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+1):
+ svga_write_control(0x3cf,0x35,value);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+2):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLOR+3):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLOR"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+0):
+ svga_write_control(0x3cf,0x38,value);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+1):
+ svga_write_control(0x3cf,0x39,value);
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+2):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
+ break;
+ case (CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK+3):
+ BX_ERROR(("CLGD543x_MMIO_BLTTRANSPARENTCOLORMASK"));
+ break;
+ case CLGD543x_MMIO_BLTSTATUS:
+ svga_write_control(0x3cf,0x31,value);
+ break;
+ default:
+ BX_ERROR(("MMIO blt write - address 0x%04x, value 0x%02x",address,value));
+ break;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+// PCI support
+//
+/////////////////////////////////////////////////////////////////////////
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+
+ void
+bx_svga_cirrus_c::svga_init_pcihandlers(void)
+{
+ int i;
+
+ // addresses
+ BX_CIRRUS_THIS pci_memaddr = CIRRUS_PNPMEM_BASE_ADDRESS;
+ BX_CIRRUS_THIS pci_mmioaddr = CIRRUS_PNPMMIO_BASE_ADDRESS;
+ Bit8u devfunc = 0x00;
+ DEV_register_pci_handlers(BX_CIRRUS_THIS_PTR,
+ pci_read_handler, pci_write_handler,
+ &devfunc, "cirrus", "PCI SVGA Cirrus");
+
+ for (i=0; i<256; i++) {
+ BX_CIRRUS_THIS pci_conf[i] = 0x0;
+ }
+
+ WriteHostWordToLittleEndian(
+ &BX_CIRRUS_THIS pci_conf[0x00], PCI_VENDOR_CIRRUS);
+ WriteHostWordToLittleEndian(
+ &BX_CIRRUS_THIS pci_conf[0x02], PCI_DEVICE_CLGD5446);
+ WriteHostWordToLittleEndian(
+ &BX_CIRRUS_THIS pci_conf[0x04],
+ (PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS));
+ BX_CIRRUS_THIS pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
+ BX_CIRRUS_THIS pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
+ BX_CIRRUS_THIS pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
+}
+
+ Bit32u
+bx_svga_cirrus_c::pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len)
+{
+#if !BX_USE_CIRRUS_SMF
+ return ((bx_svga_cirrus_c *)this_ptr)->pci_read(address,io_len);
+}
+
+ Bit32u
+bx_svga_cirrus_c::pci_read(Bit8u address, unsigned io_len)
+{
+#endif // !BX_USE_CIRRUS_SMF
+ unsigned i;
+ Bit32u ret;
+
+ if (io_len > 4) {
+ BX_PANIC(("pci_read: io_len > 4!"));
+ return 0xffffffff;
+ }
+ if (((unsigned)address + io_len) > 256) {
+ BX_PANIC(("pci_read: (address + io_len) > 256!"));
+ return 0xffffffff;
+ }
+
+ ret = 0;
+ for (i = 0; i < io_len; i++) {
+ ret |= (Bit32u)(BX_CIRRUS_THIS pci_conf[address + i]) << (i*8);
+ }
+
+ BX_DEBUG(("pci_read: address 0x%02x, io_len 0x%02x, value 0x%x",
+ (unsigned)address, (unsigned)io_len, (unsigned)ret));
+
+ return ret;
+}
+
+ void
+bx_svga_cirrus_c::pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len)
+{
+#if !BX_USE_CIRRUS_SMF
+ ((bx_svga_cirrus_c *)this_ptr)->pci_write(address,value,io_len);
+}
+
+ void
+bx_svga_cirrus_c::pci_write(Bit8u address, Bit32u value, unsigned io_len)
+{
+#endif // !BX_USE_CIRRUS_SMF
+ unsigned i;
+ unsigned write_addr;
+ Bit8u new_value, old_value;
+ bx_bool baseaddr0_change = 0;
+ bx_bool baseaddr1_change = 0;
+
+ BX_DEBUG(("pci_write: address 0x%02x, io_len 0x%02x, value 0x%x",
+ (unsigned)address, (unsigned)io_len, (unsigned)value));
+
+ if ((address > 0x17) && (address < 0x34))
+ return;
+ if (io_len <= 4) {
+ for (i = 0; i < io_len; i++) {
+ write_addr = address + i;
+ old_value = BX_CIRRUS_THIS pci_conf[write_addr];
+ new_value = (Bit8u)(value & 0xff);
+ switch (write_addr) {
+ case 0x04: // command bit0-7
+ new_value &= PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
+ new_value |= old_value & ~(PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS);
+ break;
+ case 0x05: // command bit8-15
+ new_value = old_value;
+ break;
+ case 0x06: // status bit0-7
+ new_value = old_value & (~new_value);
+ break;
+ case 0x07: // status bit8-15
+ new_value = old_value & (~new_value);
+ break;
+
+ case 0x10: case 0x11: case 0x12: case 0x13: // base address #0
+ baseaddr0_change = (old_value != new_value);
+ break;
+ case 0x14: case 0x15: case 0x16: case 0x17: // base address #1
+ baseaddr1_change = (old_value != new_value);
+ break;
+
+ // read-only.
+ case 0x00: case 0x01: // vendor
+ case 0x02: case 0x03: // device
+ case 0x08: // revision
+ case 0x09: case 0x0a: case 0x0b: // class
+ case 0x0e: // header type
+ case 0x0f: // built-in self test(unimplemented)
+ new_value = old_value;
+ break;
+ default:
+ break;
+ }
+ BX_CIRRUS_THIS pci_conf[write_addr] = new_value;
+ value >>= 8;
+ }
+ if (baseaddr0_change) {
+ DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
+ cirrus_mem_write_handler,
+ &BX_CIRRUS_THIS pci_memaddr,
+ &BX_CIRRUS_THIS pci_conf[0x10],
+ CIRRUS_PNPMEM_SIZE);
+ BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_memaddr));
+ }
+ if (baseaddr1_change) {
+ DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
+ cirrus_mem_write_handler,
+ &BX_CIRRUS_THIS pci_mmioaddr,
+ &BX_CIRRUS_THIS pci_conf[0x14],
+ CIRRUS_PNPMMIO_SIZE);
+ BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_mmioaddr));
+ }
+ }
+}
+
+#endif // BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Bitblt.
+//
+/////////////////////////////////////////////////////////////////////////
+
+ void
+bx_svga_cirrus_c::svga_reset_bitblt(void)
+{
+ BX_CIRRUS_THIS control.reg[0x31] &= ~(CIRRUS_BLT_START|CIRRUS_BLT_BUSY|CIRRUS_BLT_FIFOUSED);
+ BX_CIRRUS_THIS bitblt.rop_handler = NULL;
+ BX_CIRRUS_THIS bitblt.src = NULL;
+ BX_CIRRUS_THIS bitblt.dst = NULL;
+ BX_CIRRUS_THIS bitblt.memsrc_ptr = NULL;
+ BX_CIRRUS_THIS bitblt.memsrc_endptr = NULL;
+ BX_CIRRUS_THIS bitblt.memsrc_needed = 0;
+ BX_CIRRUS_THIS bitblt.memdst_ptr = NULL;
+ BX_CIRRUS_THIS bitblt.memdst_endptr = NULL;
+ BX_CIRRUS_THIS bitblt.memdst_needed = 0;
+}
+
+ void
+bx_svga_cirrus_c::svga_bitblt()
+{
+ Bit16u tmp16;
+ Bit32u tmp32;
+ Bit32u dstaddr;
+ Bit32u srcaddr;
+ Bit32u offset;
+
+ ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x20],tmp16);
+ BX_CIRRUS_THIS bitblt.bltwidth = ((int)tmp16 & (int)0x1fff) + 1;
+ ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x22],tmp16);
+ BX_CIRRUS_THIS bitblt.bltheight = ((int)tmp16 & (int)0x1fff) + 1;
+ ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x24],tmp16);
+ BX_CIRRUS_THIS bitblt.dstpitch = (int)tmp16 & (int)0x1fff;
+ ReadHostWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x26],tmp16);
+ BX_CIRRUS_THIS bitblt.srcpitch = (int)tmp16 & (int)0x1fff;
+ ReadHostDWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x28],tmp32);
+ dstaddr = tmp32 & (Bit32u)0x003fffff;
+ ReadHostDWordFromLittleEndian(&BX_CIRRUS_THIS control.reg[0x2c],tmp32);
+ srcaddr = tmp32 & (Bit32u)0x003fffff;
+ BX_CIRRUS_THIS bitblt.bltmode = BX_CIRRUS_THIS control.reg[0x30];
+ BX_CIRRUS_THIS bitblt.bltmodeext = BX_CIRRUS_THIS control.reg[0x33];
+ BX_CIRRUS_THIS bitblt.bltrop = BX_CIRRUS_THIS control.reg[0x32];
+ BX_CIRRUS_THIS bitblt.async_xbytes = 0;
+ BX_CIRRUS_THIS bitblt.async_y = 0;
+ offset = dstaddr - (BX_CIRRUS_THIS disp_ptr - BX_CIRRUS_THIS vidmem);
+ BX_CIRRUS_THIS bitblt.pos_x = (offset % BX_CIRRUS_THIS bitblt.dstpitch) / (BX_CIRRUS_THIS svga_bpp >> 3);
+ BX_CIRRUS_THIS bitblt.pos_y = offset / BX_CIRRUS_THIS bitblt.dstpitch;
+
+ BX_INFO(("BLT: src:0x%08x,dst 0x%08x,block %ux%u,mode 0x%02x,ROP 0x%02x",
+ (unsigned)srcaddr,(unsigned)dstaddr,
+ (unsigned)BX_CIRRUS_THIS bitblt.bltwidth,(unsigned)BX_CIRRUS_THIS bitblt.bltheight,
+ (unsigned)BX_CIRRUS_THIS bitblt.bltmode,(unsigned)BX_CIRRUS_THIS bitblt.bltrop));
+ BX_INFO(("BLT: srcpitch:0x%08x,dstpitch 0x%08x,modeext 0x%02x",
+ (unsigned)BX_CIRRUS_THIS bitblt.srcpitch,
+ (unsigned)BX_CIRRUS_THIS bitblt.dstpitch,
+ (unsigned)BX_CIRRUS_THIS bitblt.bltmodeext));
+ BX_INFO(("BLT: dst x = %d, dst y = %d", BX_CIRRUS_THIS bitblt.pos_x, BX_CIRRUS_THIS bitblt.pos_y));
+
+ switch (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
+ case CIRRUS_BLTMODE_PIXELWIDTH8:
+ BX_CIRRUS_THIS bitblt.pixelwidth = 1;
+ break;
+ case CIRRUS_BLTMODE_PIXELWIDTH16:
+ BX_CIRRUS_THIS bitblt.pixelwidth = 2;
+ break;
+ case CIRRUS_BLTMODE_PIXELWIDTH24:
+ BX_CIRRUS_THIS bitblt.pixelwidth = 3;
+ break;
+ case CIRRUS_BLTMODE_PIXELWIDTH32:
+ BX_CIRRUS_THIS bitblt.pixelwidth = 4;
+ break;
+ default:
+ BX_PANIC(("unknown pixel width"));
+ goto ignoreblt;
+ }
+ BX_CIRRUS_THIS bitblt.bltwidth /= BX_CIRRUS_THIS bitblt.pixelwidth;
+ BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
+
+ if ((BX_CIRRUS_THIS bitblt.bltmode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_MEMSYSDEST))
+ == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_MEMSYSDEST)) {
+ BX_ERROR(("BLT: memory-to-memory copy is requested, ROP %02x",
+ (unsigned)BX_CIRRUS_THIS bitblt.bltrop));
+ goto ignoreblt;
+ }
+
+ if ((BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
+ (BX_CIRRUS_THIS bitblt.bltmode & (CIRRUS_BLTMODE_MEMSYSDEST |
+ CIRRUS_BLTMODE_TRANSPARENTCOMP |
+ CIRRUS_BLTMODE_PATTERNCOPY |
+ CIRRUS_BLTMODE_COLOREXPAND)) ==
+ (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
+ BX_PANIC(("SOLIDFILL is not implemented"));
+ } else {
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_BACKWARDS) {
+ BX_CIRRUS_THIS bitblt.dstpitch = -BX_CIRRUS_THIS bitblt.dstpitch;
+ BX_CIRRUS_THIS bitblt.srcpitch = -BX_CIRRUS_THIS bitblt.srcpitch;
+ BX_CIRRUS_THIS bitblt.rop_handler = svga_get_bkwd_rop_handler(BX_CIRRUS_THIS bitblt.bltrop);
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.rop_handler = svga_get_fwd_rop_handler(BX_CIRRUS_THIS bitblt.bltrop);
+ }
+
+ // setup bitblt engine.
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_MEMSYSSRC) {
+ svga_setup_bitblt_cputovideo(dstaddr,srcaddr);
+ }
+ else if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_MEMSYSDEST) {
+ svga_setup_bitblt_videotocpu(dstaddr,srcaddr);
+ }
+ else {
+ svga_setup_bitblt_videotovideo(dstaddr,srcaddr);
+ }
+ return;
+ }
+
+ignoreblt:
+ svga_reset_bitblt();
+ return;
+}
+
+ void
+bx_svga_cirrus_c::svga_setup_bitblt_cputovideo(Bit32u dstaddr,Bit32u srcaddr)
+{
+ BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
+
+ BX_CIRRUS_THIS bitblt.dst = BX_CIRRUS_THIS vidmem + dstaddr;
+ BX_CIRRUS_THIS bitblt.src = NULL;
+
+ BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
+ BX_CIRRUS_THIS bitblt.memsrc_endptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ BX_CIRRUS_THIS bitblt.memsrc_needed = 8;
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.memsrc_needed = 8 * 8 * BX_CIRRUS_THIS bitblt.pixelwidth;
+ }
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
+ BX_ERROR(("BLT: patterncopy: TRANSPARENTCOMP is not implemented"));
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_memsrc_static;
+ }
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.memdst_bytesperline =
+ BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.pixelwidth;
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ BX_CIRRUS_THIS bitblt.memsrc_bytesperline =
+ (BX_CIRRUS_THIS bitblt.bltwidth + 7) / 8;
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.memsrc_bytesperline = BX_CIRRUS_THIS bitblt.memdst_bytesperline;
+ }
+ BX_CIRRUS_THIS bitblt.memsrc_needed =
+ BX_CIRRUS_THIS bitblt.memsrc_bytesperline * BX_CIRRUS_THIS bitblt.bltheight;
+ BX_CIRRUS_THIS bitblt.memsrc_needed = (BX_CIRRUS_THIS bitblt.memsrc_needed + 3) & (~3);
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_transp_memsrc_static;
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_memsrc_static;
+ }
+ }
+
+ svga_asyncbitblt_next();
+}
+
+ void
+bx_svga_cirrus_c::svga_setup_bitblt_videotocpu(Bit32u dstaddr,Bit32u srcaddr)
+{
+ BX_ERROR(("BLT: MEMSYSDEST is not implemented"));
+
+ BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_MEMSYSDEST;
+
+#if 0
+ BX_CIRRUS_THIS bitblt.dst = NULL;
+ BX_CIRRUS_THIS bitblt.src = BX_CIRRUS_THIS vidmem + srcaddr;
+
+ BX_CIRRUS_THIS bitblt.memdst_ptr = &BX_CIRRUS_THIS bitblt.memdst[0];
+ BX_CIRRUS_THIS bitblt.memdst_endptr = &BX_CIRRUS_THIS bitblt.memdst[0];
+
+ BX_CIRRUS_THIS bitblt.memdst_needed =
+ BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.pixelwidth * BX_CIRRUS_THIS bitblt.bltheight;
+ BX_CIRRUS_THIS bitblt.memdst_needed = (BX_CIRRUS_THIS bitblt.memdst_needed + 3) & (~3);
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_memdst_static;
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_memdst_static;
+ }
+
+ svga_asyncbitblt_next();
+#endif
+}
+
+ void
+bx_svga_cirrus_c::svga_setup_bitblt_videotovideo(Bit32u dstaddr,Bit32u srcaddr)
+{
+ BX_CIRRUS_THIS bitblt.dst = BX_CIRRUS_THIS vidmem + dstaddr;
+ BX_CIRRUS_THIS bitblt.src = BX_CIRRUS_THIS vidmem + srcaddr;
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_PATTERNCOPY) {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_patterncopy_static;
+ }
+ else {
+ BX_CIRRUS_THIS bitblt.bitblt_ptr = svga_simplebitblt_static;
+ }
+
+ (*BX_CIRRUS_THIS bitblt.bitblt_ptr)();
+ svga_reset_bitblt();
+ BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS bitblt.pos_x, BX_CIRRUS_THIS bitblt.pos_y,
+ BX_CIRRUS_THIS bitblt.bltwidth, BX_CIRRUS_THIS bitblt.bltheight);
+}
+
+
+ void
+bx_svga_cirrus_c::svga_colorexpand(Bit8u *dst,const Bit8u *src,int count,int pixelwidth)
+{
+ BX_DEBUG(("svga_cirrus: COLOR EXPAND"));
+
+ switch (pixelwidth) {
+ case 1:
+ svga_colorexpand_8(dst,src,count);
+ break;
+ case 2:
+ svga_colorexpand_16(dst,src,count);
+ break;
+ case 3:
+ svga_colorexpand_24(dst,src,count);
+ break;
+ case 4:
+ svga_colorexpand_32(dst,src,count);
+ break;
+ default:
+ BX_PANIC(("COLOREXPAND: unknown pixelwidth %u",(unsigned)pixelwidth));
+ break;
+ }
+}
+
+#if !BX_USE_CIRRUS_SMF
+ void
+bx_svga_cirrus_c::svga_colorexpand_8_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_8(dst,src,count);
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_16_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_16(dst,src,count);
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_24_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_24(dst,src,count);
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_32_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_colorexpand_32(dst,src,count);
+}
+
+#endif // BX_USE_CIRRUS_SMF
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_8(Bit8u *dst,const Bit8u *src,int count)
+{
+ int x;
+ Bit8u colors[2];
+ unsigned bits;
+ unsigned bitmask;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ colors[0] = BX_CIRRUS_THIS control.shadow_reg0;
+ colors[1] = BX_CIRRUS_THIS control.shadow_reg1;
+
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ for (x = 0; x < count; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ *dst++ = colors[!!(bits & bitmask)];
+ bitmask >>= 1;
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_16(Bit8u *dst,const Bit8u *src,int count)
+{
+ int x;
+ Bit8u colors[2][2];
+ unsigned bits;
+ unsigned bitmask;
+ unsigned index;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
+ colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
+ colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
+ colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
+
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ for (x = 0; x < count; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ index = !!(bits & bitmask);
+ *dst++ = colors[index][0];
+ *dst++ = colors[index][1];
+ bitmask >>= 1;
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_24(Bit8u *dst,const Bit8u *src,int count)
+{
+ int x;
+ Bit8u colors[2][3];
+ unsigned bits;
+ unsigned bitmask;
+ unsigned index;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
+ colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
+ colors[0][2] = BX_CIRRUS_THIS control.reg[0x12];
+ colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
+ colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
+ colors[1][2] = BX_CIRRUS_THIS control.reg[0x13];
+
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ for (x = 0; x < count; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ index = !!(bits & bitmask);
+ *dst++ = colors[index][0];
+ *dst++ = colors[index][1];
+ *dst++ = colors[index][2];
+ bitmask >>= 1;
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_colorexpand_32(Bit8u *dst,const Bit8u *src,int count)
+{
+ int x;
+ Bit8u colors[2][4];
+ unsigned bits;
+ unsigned bitmask;
+ unsigned index;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ colors[0][0] = BX_CIRRUS_THIS control.shadow_reg0;
+ colors[0][1] = BX_CIRRUS_THIS control.reg[0x10];
+ colors[0][2] = BX_CIRRUS_THIS control.reg[0x12];
+ colors[0][3] = BX_CIRRUS_THIS control.reg[0x14];
+ colors[1][0] = BX_CIRRUS_THIS control.shadow_reg1;
+ colors[1][1] = BX_CIRRUS_THIS control.reg[0x11];
+ colors[1][2] = BX_CIRRUS_THIS control.reg[0x13];
+ colors[1][3] = BX_CIRRUS_THIS control.reg[0x15];
+
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ for (x = 0; x < count; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ index = !!(bits & bitmask);
+ *dst++ = colors[index][0];
+ *dst++ = colors[index][1];
+ *dst++ = colors[index][2];
+ *dst++ = colors[index][3];
+ bitmask >>= 1;
+ }
+}
+
+#if !BX_USE_CIRRUS_SMF
+ void
+bx_svga_cirrus_c::svga_patterncopy_static(void *this_ptr)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_patterncopy();
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt_static(void *this_ptr)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_simplebitblt();
+}
+
+ void
+bx_svga_cirrus_c::svga_patterncopy_memsrc_static(void *this_ptr)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_patterncopy_memsrc();
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt_memsrc_static(void *this_ptr)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_simplebitblt_memsrc();
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt_transp_memsrc_static(void *this_ptr)
+{
+ ((bx_svga_cirrus_c *)this_ptr)->svga_simplebitblt_transp_memsrc();
+}
+
+#endif // !BX_USE_CIRRUS_SMF
+
+ void
+bx_svga_cirrus_c::svga_patterncopy()
+{
+ Bit8u work_colorexp[256];
+ Bit8u *dst;
+ Bit8u *dstc;
+ int x,y;
+ int tilewidth,tileheight;
+ int patternbytes = 8 * BX_CIRRUS_THIS bitblt.pixelwidth;
+ int bltbytes = BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.pixelwidth;
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ svga_colorexpand(work_colorexp,BX_CIRRUS_THIS bitblt.src,8*8,BX_CIRRUS_THIS bitblt.pixelwidth);
+ BX_CIRRUS_THIS bitblt.src = work_colorexp;
+ BX_CIRRUS_THIS bitblt.bltmode &= ~CIRRUS_BLTMODE_COLOREXPAND;
+ }
+ if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_PATTERNCOPY) {
+ BX_ERROR(("PATTERNCOPY: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
+ return;
+ }
+
+ BX_DEBUG(("svga_cirrus: PATTERN COPY"));
+ dst = BX_CIRRUS_THIS bitblt.dst;
+ for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y += 8) {
+ dstc = dst + y * BX_CIRRUS_THIS bitblt.dstpitch;
+ tileheight = BX_MIN(8,BX_CIRRUS_THIS bitblt.bltheight - y);
+ for (x = 0; x < bltbytes; x += patternbytes) {
+ tilewidth = BX_MIN(patternbytes,bltbytes - x);
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ dstc, BX_CIRRUS_THIS bitblt.src,
+ BX_CIRRUS_THIS bitblt.dstpitch, patternbytes,
+ tilewidth, tileheight);
+ dstc += patternbytes;
+ }
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt()
+{
+ Bit8u color[4];
+ Bit8u work_colorexp[2048];
+ int x, y;
+ Bit8u *dst;
+ unsigned bits, bitmask;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
+ color[0] = BX_CIRRUS_THIS control.shadow_reg1;
+ color[1] = BX_CIRRUS_THIS control.reg[0x11];
+ color[2] = BX_CIRRUS_THIS control.reg[0x13];
+ color[3] = BX_CIRRUS_THIS control.reg[0x15];
+
+ for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
+ dst = BX_CIRRUS_THIS bitblt.dst;
+ bitmask = 0x80 >> srcskipleft;
+ bits = *BX_CIRRUS_THIS bitblt.src++;
+ for (x = 0; x < BX_CIRRUS_THIS bitblt.bltwidth; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *BX_CIRRUS_THIS bitblt.src++;
+ }
+ if (bits & bitmask) {
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
+ }
+ dst += BX_CIRRUS_THIS bitblt.pixelwidth;
+ bitmask >>= 1;
+ }
+ BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
+ }
+ return;
+ } else {
+ for (y = 0; y < BX_CIRRUS_THIS bitblt.bltheight; y++) {
+ svga_colorexpand(work_colorexp,BX_CIRRUS_THIS bitblt.src,BX_CIRRUS_THIS bitblt.bltwidth,
+ BX_CIRRUS_THIS bitblt.pixelwidth);
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ BX_CIRRUS_THIS bitblt.dst, work_colorexp, 0, 0,
+ BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.pixelwidth, 1);
+ BX_CIRRUS_THIS bitblt.src += ((BX_CIRRUS_THIS bitblt.bltwidth + 7) / 8);
+ BX_CIRRUS_THIS bitblt.dst += BX_CIRRUS_THIS bitblt.dstpitch;
+ }
+ return;
+ }
+ }
+ if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_BACKWARDS) {
+ BX_ERROR(("SIMPLE BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
+ return;
+ }
+
+ BX_DEBUG(("svga_cirrus: BITBLT"));
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ BX_CIRRUS_THIS bitblt.dst, BX_CIRRUS_THIS bitblt.src,
+ BX_CIRRUS_THIS bitblt.dstpitch, BX_CIRRUS_THIS bitblt.srcpitch,
+ BX_CIRRUS_THIS bitblt.bltwidth * BX_CIRRUS_THIS bitblt.pixelwidth, BX_CIRRUS_THIS bitblt.bltheight
+ );
+}
+
+ void
+bx_svga_cirrus_c::svga_patterncopy_memsrc()
+{
+ int srcavail = BX_CIRRUS_THIS bitblt.memsrc_ptr - &BX_CIRRUS_THIS bitblt.memsrc[0];
+
+ if (srcavail > 0) {
+ if (srcavail != BX_CIRRUS_THIS bitblt.memsrc_needed) {
+ BX_PANIC(("CIRRUS_BLT_CACHESIZE is too small"));
+ BX_CIRRUS_THIS bitblt.memsrc_needed = 0;
+ return;
+ }
+ BX_INFO(("svga_patterncopy_memsrc() - not tested"));
+
+ BX_CIRRUS_THIS bitblt.src = &BX_CIRRUS_THIS bitblt.memsrc[0];
+ svga_patterncopy();
+ BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS bitblt.pos_x, BX_CIRRUS_THIS bitblt.pos_y,
+ BX_CIRRUS_THIS bitblt.bltwidth, BX_CIRRUS_THIS bitblt.bltheight);
+ }
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt_memsrc()
+{
+ Bit8u work_colorexp[256];
+ int srcavail = BX_CIRRUS_THIS bitblt.memsrc_ptr - &BX_CIRRUS_THIS bitblt.memsrc[0];
+ int bytesavail;
+ int bytesprocessed;
+ int total;
+ Bit8u *srcptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
+ Bit8u *srccurptr;
+ int srccuravail;
+
+ BX_DEBUG(("svga_cirrus: BLT, cpu-to-video"));
+ total = 0;
+ while (1) {
+ bytesavail = BX_CIRRUS_THIS bitblt.memsrc_bytesperline - BX_CIRRUS_THIS bitblt.async_xbytes;
+ bytesavail = BX_MIN(bytesavail,srcavail);
+ if (bytesavail <= 0)
+ break;
+
+ bytesprocessed = bytesavail;
+ srccurptr = srcptr;
+ srccuravail = bytesavail;
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ if (BX_CIRRUS_THIS bitblt.bltmode & ~CIRRUS_BLTMODE_COLOREXPAND) {
+ BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
+ return;
+ }
+
+ bytesprocessed = BX_MIN(256/32,bytesavail);
+ svga_colorexpand(work_colorexp,srcptr,bytesprocessed * 8,BX_CIRRUS_THIS bitblt.pixelwidth);
+ srccurptr = work_colorexp;
+ srccuravail = BX_MIN(
+ bytesprocessed * 8 * BX_CIRRUS_THIS bitblt.pixelwidth,
+ BX_CIRRUS_THIS bitblt.memdst_bytesperline - BX_CIRRUS_THIS bitblt.async_xbytes * 8 * BX_CIRRUS_THIS bitblt.pixelwidth);
+ }
+ else {
+ if (BX_CIRRUS_THIS bitblt.bltmode != 0) {
+ BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
+ return;
+ }
+ }
+
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ BX_CIRRUS_THIS bitblt.dst, srccurptr, 0, 0, srccuravail, 1);
+
+ BX_CIRRUS_THIS bitblt.dst += srccuravail;
+ total += bytesprocessed;
+ srcptr += ((bytesprocessed + 3) & ~3);
+ srcavail -= bytesprocessed;
+ BX_CIRRUS_THIS bitblt.async_xbytes += bytesprocessed;
+ if (BX_CIRRUS_THIS bitblt.async_xbytes >= BX_CIRRUS_THIS bitblt.memsrc_bytesperline) {
+ BX_CIRRUS_THIS bitblt.dst +=
+ BX_CIRRUS_THIS bitblt.dstpitch - BX_CIRRUS_THIS bitblt.memdst_bytesperline;
+ BX_CIRRUS_THIS bitblt.async_y ++;
+ BX_CIRRUS_THIS bitblt.async_xbytes = 0;
+ if (BX_CIRRUS_THIS bitblt.async_y >= BX_CIRRUS_THIS bitblt.bltheight) {
+ total += srcavail;
+ srcavail = 0;
+ break;
+ }
+ }
+ }
+
+ BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[total];
+ BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS bitblt.pos_x, BX_CIRRUS_THIS bitblt.pos_y,
+ BX_CIRRUS_THIS bitblt.bltwidth, BX_CIRRUS_THIS bitblt.bltheight);
+}
+
+ void
+bx_svga_cirrus_c::svga_simplebitblt_transp_memsrc()
+{
+ Bit8u color[4];
+ int srcavail = BX_CIRRUS_THIS bitblt.memsrc_ptr - &BX_CIRRUS_THIS bitblt.memsrc[0];
+ int bytesavail;
+ int bytesprocessed;
+ int x, total;
+ Bit8u *srcptr = &BX_CIRRUS_THIS bitblt.memsrc[0];
+ Bit8u *dst, *src;
+ int srccuravail;
+ unsigned bits, bitmask;
+ int srcskipleft = BX_CIRRUS_THIS control.reg[0x2f] & 0x07;
+
+ BX_DEBUG(("BLT, cpu-to-video, transparent"));
+
+ color[0] = BX_CIRRUS_THIS control.shadow_reg1;
+ color[1] = BX_CIRRUS_THIS control.reg[0x11];
+ color[2] = BX_CIRRUS_THIS control.reg[0x13];
+ color[3] = BX_CIRRUS_THIS control.reg[0x15];
+
+ total = 0;
+ while (1) {
+ bytesavail = BX_CIRRUS_THIS bitblt.memsrc_bytesperline - BX_CIRRUS_THIS bitblt.async_xbytes;
+ bytesavail = BX_MIN(bytesavail,srcavail);
+ if (bytesavail <= 0)
+ break;
+
+ bytesprocessed = bytesavail;
+ if (BX_CIRRUS_THIS bitblt.bltmode & CIRRUS_BLTMODE_COLOREXPAND) {
+ bytesprocessed = BX_MIN(256/32,bytesavail);
+ srccuravail = BX_MIN(
+ bytesprocessed * 8 * BX_CIRRUS_THIS bitblt.pixelwidth,
+ BX_CIRRUS_THIS bitblt.memdst_bytesperline - BX_CIRRUS_THIS bitblt.async_xbytes * 8 * BX_CIRRUS_THIS bitblt.pixelwidth);
+ src = srcptr;
+ dst = BX_CIRRUS_THIS bitblt.dst;
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ for (x = 0; x < bytesprocessed * 8; x++) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ if (bits & bitmask) {
+ (*BX_CIRRUS_THIS bitblt.rop_handler)(
+ dst, &color[0], 0, 0, BX_CIRRUS_THIS bitblt.pixelwidth, 1);
+ }
+ dst += BX_CIRRUS_THIS bitblt.pixelwidth;
+ bitmask >>= 1;
+ }
+ } else {
+ BX_ERROR(("cpu-to-video BLT: unknown bltmode %02x",BX_CIRRUS_THIS bitblt.bltmode));
+ return;
+ }
+
+ BX_CIRRUS_THIS bitblt.dst += srccuravail;
+ total += bytesprocessed;
+ srcptr += bytesprocessed;
+ srcavail -= bytesprocessed;
+ BX_CIRRUS_THIS bitblt.async_xbytes += bytesprocessed;
+ if (BX_CIRRUS_THIS bitblt.async_xbytes >= BX_CIRRUS_THIS bitblt.memsrc_bytesperline) {
+ BX_CIRRUS_THIS bitblt.dst +=
+ BX_CIRRUS_THIS bitblt.dstpitch - BX_CIRRUS_THIS bitblt.memdst_bytesperline;
+ BX_CIRRUS_THIS bitblt.async_y ++;
+ BX_CIRRUS_THIS bitblt.async_xbytes = 0;
+ if (BX_CIRRUS_THIS bitblt.async_y >= BX_CIRRUS_THIS bitblt.bltheight) {
+ total += srcavail;
+ srcavail = 0;
+ break;
+ }
+ }
+ }
+
+ BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[total];
+ BX_CIRRUS_THIS redraw_area(BX_CIRRUS_THIS bitblt.pos_x, BX_CIRRUS_THIS bitblt.pos_y,
+ BX_CIRRUS_THIS bitblt.bltwidth, BX_CIRRUS_THIS bitblt.bltheight);
+}
+
+ bx_bool // true if finished, false otherwise
+bx_svga_cirrus_c::svga_asyncbitblt_next()
+{
+ int count;
+ int avail;
+
+ if (BX_CIRRUS_THIS bitblt.bitblt_ptr == NULL) {
+ BX_PANIC(("svga_asyncbitblt_next: unexpected call"));
+ goto cleanup;
+ }
+
+ if (BX_CIRRUS_THIS bitblt.memdst_needed > 0) {
+ BX_CIRRUS_THIS bitblt.memdst_needed -= BX_CIRRUS_THIS bitblt.memdst_ptr - &BX_CIRRUS_THIS bitblt.memdst[0];
+ avail = BX_MIN(CIRRUS_BLT_CACHESIZE, BX_CIRRUS_THIS bitblt.memdst_needed);
+ BX_CIRRUS_THIS bitblt.memdst_ptr = &BX_CIRRUS_THIS bitblt.memdst[0];
+ BX_CIRRUS_THIS bitblt.memdst_endptr = &BX_CIRRUS_THIS bitblt.memdst[avail];
+
+ if (BX_CIRRUS_THIS bitblt.memsrc_needed <= 0 &&
+ BX_CIRRUS_THIS bitblt.memdst_needed <= 0) {
+ goto cleanup;
+ }
+ }
+
+ (*BX_CIRRUS_THIS bitblt.bitblt_ptr)();
+
+ if (BX_CIRRUS_THIS bitblt.memsrc_needed > 0) {
+ BX_CIRRUS_THIS bitblt.memsrc_needed -= BX_CIRRUS_THIS bitblt.memsrc_ptr - &BX_CIRRUS_THIS bitblt.memsrc[0];
+ count = BX_CIRRUS_THIS bitblt.memsrc_endptr - BX_CIRRUS_THIS bitblt.memsrc_ptr;
+ memmove(&BX_CIRRUS_THIS bitblt.memsrc[0], BX_CIRRUS_THIS bitblt.memsrc_ptr, count);
+ avail = BX_MIN(CIRRUS_BLT_CACHESIZE, BX_CIRRUS_THIS bitblt.memsrc_needed);
+ BX_CIRRUS_THIS bitblt.memsrc_ptr = &BX_CIRRUS_THIS bitblt.memsrc[count];
+ BX_CIRRUS_THIS bitblt.memsrc_endptr = &BX_CIRRUS_THIS bitblt.memsrc[avail];
+
+ if (BX_CIRRUS_THIS bitblt.memsrc_needed <= 0 &&
+ BX_CIRRUS_THIS bitblt.memdst_needed <= 0) {
+ goto cleanup;
+ }
+ }
+
+ return false;
+
+cleanup:
+ svga_reset_bitblt();
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Raster operations.
+//
+/////////////////////////////////////////////////////////////////////////
+
+#define IMPLEMENT_FORWARD_BITBLT(name,opline) \
+ static void \
+ bitblt_rop_fwd_##name( \
+ Bit8u *dst,const Bit8u *src, \
+ int dstpitch,int srcpitch, \
+ int bltwidth,int bltheight) \
+ { \
+ int x,y; \
+ dstpitch -= bltwidth; \
+ srcpitch -= bltwidth; \
+ for (y = 0; y < bltheight; y++) { \
+ for (x = 0; x < bltwidth; x++) { \
+ opline; \
+ dst++; \
+ src++; \
+ } \
+ dst += dstpitch; \
+ src += srcpitch; \
+ } \
+ }
+
+#define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
+ static void \
+ bitblt_rop_bkwd_##name( \
+ Bit8u *dst,const Bit8u *src, \
+ int dstpitch,int srcpitch, \
+ int bltwidth,int bltheight) \
+ { \
+ int x,y; \
+ dstpitch += bltwidth; \
+ srcpitch += bltwidth; \
+ for (y = 0; y < bltheight; y++) { \
+ for (x = 0; x < bltwidth; x++) { \
+ opline; \
+ dst--; \
+ src--; \
+ } \
+ dst += dstpitch; \
+ src += srcpitch; \
+ } \
+ }
+
+IMPLEMENT_FORWARD_BITBLT(0, *dst = 0)
+IMPLEMENT_FORWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
+IMPLEMENT_FORWARD_BITBLT(nop, (void)0)
+IMPLEMENT_FORWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
+IMPLEMENT_FORWARD_BITBLT(notdst, *dst = ~(*dst))
+IMPLEMENT_FORWARD_BITBLT(src, *dst = *src)
+IMPLEMENT_FORWARD_BITBLT(1, *dst = 0xff)
+IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
+IMPLEMENT_FORWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
+IMPLEMENT_FORWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
+IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
+IMPLEMENT_FORWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
+IMPLEMENT_FORWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
+IMPLEMENT_FORWARD_BITBLT(notsrc, *dst = (~(*src)))
+IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
+IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
+
+IMPLEMENT_BACKWARD_BITBLT(0, *dst = 0)
+IMPLEMENT_BACKWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
+IMPLEMENT_BACKWARD_BITBLT(nop, (void)0)
+IMPLEMENT_BACKWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
+IMPLEMENT_BACKWARD_BITBLT(notdst, *dst = ~(*dst))
+IMPLEMENT_BACKWARD_BITBLT(src, *dst = *src)
+IMPLEMENT_BACKWARD_BITBLT(1, *dst = 0xff)
+IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
+IMPLEMENT_BACKWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
+IMPLEMENT_BACKWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
+IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
+IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
+IMPLEMENT_BACKWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
+IMPLEMENT_BACKWARD_BITBLT(notsrc, *dst = (~(*src)))
+IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
+IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
+
+
+ bx_cirrus_bitblt_rop_t
+bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop)
+{
+ bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_fwd_nop;
+
+ switch (rop)
+ {
+ case CIRRUS_ROP_0:
+ rop_handler = bitblt_rop_fwd_0;
+ break;
+ case CIRRUS_ROP_SRC_AND_DST:
+ rop_handler = bitblt_rop_fwd_src_and_dst;
+ break;
+ case CIRRUS_ROP_NOP:
+ rop_handler = bitblt_rop_fwd_nop;
+ break;
+ case CIRRUS_ROP_SRC_AND_NOTDST:
+ rop_handler = bitblt_rop_fwd_src_and_notdst;
+ break;
+ case CIRRUS_ROP_NOTDST:
+ rop_handler = bitblt_rop_fwd_notdst;
+ break;
+ case CIRRUS_ROP_SRC:
+ rop_handler = bitblt_rop_fwd_src;
+ break;
+ case CIRRUS_ROP_1:
+ rop_handler = bitblt_rop_fwd_1;
+ break;
+ case CIRRUS_ROP_NOTSRC_AND_DST:
+ rop_handler = bitblt_rop_fwd_notsrc_and_dst;
+ break;
+ case CIRRUS_ROP_SRC_XOR_DST:
+ rop_handler = bitblt_rop_fwd_src_xor_dst;
+ break;
+ case CIRRUS_ROP_SRC_OR_DST:
+ rop_handler = bitblt_rop_fwd_src_or_dst;
+ break;
+ case CIRRUS_ROP_NOTSRC_OR_NOTDST:
+ rop_handler = bitblt_rop_fwd_notsrc_or_notdst;
+ break;
+ case CIRRUS_ROP_SRC_NOTXOR_DST:
+ rop_handler = bitblt_rop_fwd_src_notxor_dst;
+ break;
+ case CIRRUS_ROP_SRC_OR_NOTDST:
+ rop_handler = bitblt_rop_fwd_src_or_notdst;
+ break;
+ case CIRRUS_ROP_NOTSRC:
+ rop_handler = bitblt_rop_fwd_notsrc;
+ break;
+ case CIRRUS_ROP_NOTSRC_OR_DST:
+ rop_handler = bitblt_rop_fwd_notsrc_or_dst;
+ break;
+ case CIRRUS_ROP_NOTSRC_AND_NOTDST:
+ rop_handler = bitblt_rop_fwd_notsrc_and_notdst;
+ break;
+ default:
+ BX_ERROR(("unknown ROP %02x",rop));
+ break;
+ }
+
+ return rop_handler;
+}
+
+ bx_cirrus_bitblt_rop_t
+bx_svga_cirrus_c::svga_get_bkwd_rop_handler(Bit8u rop)
+{
+ bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_bkwd_nop;
+
+ switch (rop)
+ {
+ case CIRRUS_ROP_0:
+ rop_handler = bitblt_rop_bkwd_0;
+ break;
+ case CIRRUS_ROP_SRC_AND_DST:
+ rop_handler = bitblt_rop_bkwd_src_and_dst;
+ break;
+ case CIRRUS_ROP_NOP:
+ rop_handler = bitblt_rop_bkwd_nop;
+ break;
+ case CIRRUS_ROP_SRC_AND_NOTDST:
+ rop_handler = bitblt_rop_bkwd_src_and_notdst;
+ break;
+ case CIRRUS_ROP_NOTDST:
+ rop_handler = bitblt_rop_bkwd_notdst;
+ break;
+ case CIRRUS_ROP_SRC:
+ rop_handler = bitblt_rop_bkwd_src;
+ break;
+ case CIRRUS_ROP_1:
+ rop_handler = bitblt_rop_bkwd_1;
+ break;
+ case CIRRUS_ROP_NOTSRC_AND_DST:
+ rop_handler = bitblt_rop_bkwd_notsrc_and_dst;
+ break;
+ case CIRRUS_ROP_SRC_XOR_DST:
+ rop_handler = bitblt_rop_bkwd_src_xor_dst;
+ break;
+ case CIRRUS_ROP_SRC_OR_DST:
+ rop_handler = bitblt_rop_bkwd_src_or_dst;
+ break;
+ case CIRRUS_ROP_NOTSRC_OR_NOTDST:
+ rop_handler = bitblt_rop_bkwd_notsrc_or_notdst;
+ break;
+ case CIRRUS_ROP_SRC_NOTXOR_DST:
+ rop_handler = bitblt_rop_bkwd_src_notxor_dst;
+ break;
+ case CIRRUS_ROP_SRC_OR_NOTDST:
+ rop_handler = bitblt_rop_bkwd_src_or_notdst;
+ break;
+ case CIRRUS_ROP_NOTSRC:
+ rop_handler = bitblt_rop_bkwd_notsrc;
+ break;
+ case CIRRUS_ROP_NOTSRC_OR_DST:
+ rop_handler = bitblt_rop_bkwd_notsrc_or_dst;
+ break;
+ case CIRRUS_ROP_NOTSRC_AND_NOTDST:
+ rop_handler = bitblt_rop_bkwd_notsrc_and_notdst;
+ break;
+ default:
+ BX_ERROR(("unknown ROP %02x",rop));
+ break;
+ }
+
+ return rop_handler;
+}
+
+
+#endif // BX_SUPPORT_CLGD54XX
diff -urNX /home/volker/exclude-diff /home/volker/bochs/iodev/svga_cirrus.h ./iodev/svga_cirrus.h
--- /home/volker/bochs/iodev/svga_cirrus.h 1970-01-01 01:00:00.000000000 +0100
+++ ./iodev/svga_cirrus.h 2004-08-12 11:53:01.000000000 +0200
@@ -0,0 +1,240 @@
+#if BX_SUPPORT_CLGD54XX
+
+#if BX_USE_CIRRUS_SMF
+# define BX_CIRRUS_SMF static
+# define BX_CIRRUS_THIS theSvga->
+# define BX_CIRRUS_THIS_PTR theSvga
+#else
+# define BX_CIRRUS_SMF
+# define BX_CIRRUS_THIS this->
+# define BX_CIRRUS_THIS_PTR this
+#endif // BX_USE_CIRRUS_SMF
+
+// 0x3b4,0x3d4
+#define VGA_CRTC_MAX 0x18
+#define CIRRUS_CRTC_MAX 0x27
+// 0x3c4
+#define VGA_SEQENCER_MAX 0x04
+#define CIRRUS_SEQENCER_MAX 0x1f
+// 0x3ce
+#define VGA_CONTROL_MAX 0x08
+#define CIRRUS_CONTROL_MAX 0x39
+
+// Size of internal cache memory for bitblt. (must be >= 256 and 4-byte aligned)
+#define CIRRUS_BLT_CACHESIZE (2048 * 4)
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+#define CIRRUS_VIDEO_MEMORY_MB 4
+#else
+#define CIRRUS_VIDEO_MEMORY_MB 2
+#endif
+#define CIRRUS_VIDEO_MEMORY_KB (CIRRUS_VIDEO_MEMORY_MB * 1024)
+#define CIRRUS_VIDEO_MEMORY_BYTES (CIRRUS_VIDEO_MEMORY_KB * 1024)
+
+typedef void (*bx_cirrus_bitblt_rop_t)(
+ Bit8u *dst,const Bit8u *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight);
+
+class bx_svga_cirrus_c : public bx_vga_c {
+public:
+ bx_svga_cirrus_c(void);
+ ~bx_svga_cirrus_c();
+
+ virtual void init(void);
+ virtual void reset(unsigned type);
+ virtual void redraw_area(unsigned x0, unsigned y0,
+ unsigned width, unsigned height);
+ virtual Bit8u mem_read(Bit32u addr);
+ virtual void mem_write(Bit32u addr, Bit8u value);
+ virtual void mem_write_mode4and5_8bpp(Bit8u mode, Bit32u offset, Bit8u value);
+ virtual void mem_write_mode4and5_16bpp(Bit8u mode, Bit32u offset, Bit8u value);
+ virtual void get_text_snapshot(Bit8u **text_snapshot,
+ unsigned *txHeight, unsigned *txWidth);
+ virtual void trigger_timer(void *this_ptr);
+ virtual void set_update_interval (unsigned interval);
+ virtual Bit8u get_actl_palette_idx(Bit8u index);
+
+private:
+ static Bit32u svga_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
+ static void svga_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
+#if !BX_USE_CIRRUS_SMF
+ Bit32u svga_read(Bit32u address, unsigned io_len);
+ void svga_write(Bit32u address, Bit32u value, unsigned io_len);
+#endif // !BX_USE_CIRRUS_SMF
+
+ static void svga_timer_handler(void *);
+ BX_CIRRUS_SMF void svga_timer(void);
+ BX_CIRRUS_SMF void svga_modeupdate(void);
+ BX_CIRRUS_SMF void svga_update(void);
+
+ BX_CIRRUS_SMF void svga_init_members();
+
+ BX_CIRRUS_SMF void draw_hardware_cursor(unsigned, unsigned, bx_svga_tileinfo_t *);
+
+ // bank memory
+ BX_CIRRUS_SMF void update_bank_ptr(Bit8u bank_index);
+ // 0x3b4-0x3b5,0x3d4-0x3d5
+ BX_CIRRUS_SMF Bit8u svga_read_crtc(Bit32u address, unsigned index);
+ BX_CIRRUS_SMF void svga_write_crtc(Bit32u address, unsigned index, Bit8u value);
+ // 0x3c4-0x3c5
+ BX_CIRRUS_SMF Bit8u svga_read_sequencer(Bit32u address, unsigned index);
+ BX_CIRRUS_SMF void svga_write_sequencer(Bit32u address, unsigned index, Bit8u value);
+ // 0x3ce-0x3cf
+ BX_CIRRUS_SMF Bit8u svga_read_control(Bit32u address, unsigned index);
+ BX_CIRRUS_SMF void svga_write_control(Bit32u address, unsigned index, Bit8u value);
+ // memory-mapped I/O
+ BX_CIRRUS_SMF Bit8u svga_mmio_vga_read(Bit32u address);
+ BX_CIRRUS_SMF void svga_mmio_vga_write(Bit32u address,Bit8u value);
+ BX_CIRRUS_SMF Bit8u svga_mmio_blt_read(Bit32u address);
+ BX_CIRRUS_SMF void svga_mmio_blt_write(Bit32u address,Bit8u value);
+
+ BX_CIRRUS_SMF void svga_reset_bitblt(void);
+ BX_CIRRUS_SMF void svga_bitblt();
+
+ BX_CIRRUS_SMF void svga_colorexpand(Bit8u *dst,const Bit8u *src,int count,int pixelwidth);
+#if BX_USE_CIRRUS_SMF
+ #define svga_colorexpand_8_static svga_colorexpand_8
+ #define svga_colorexpand_16_static svga_colorexpand_16
+ #define svga_colorexpand_24_static svga_colorexpand_24
+ #define svga_colorexpand_32_static svga_colorexpand_32
+#else // BX_USE_CIRRUS_SMF
+ static void svga_colorexpand_8_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count);
+ static void svga_colorexpand_16_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count);
+ static void svga_colorexpand_24_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count);
+ static void svga_colorexpand_32_static(void *this_ptr,Bit8u *dst,const Bit8u *src,int count);
+#endif // BX_USE_CIRRUS_SMF
+ BX_CIRRUS_SMF void svga_colorexpand_8(Bit8u *dst,const Bit8u *src,int count);
+ BX_CIRRUS_SMF void svga_colorexpand_16(Bit8u *dst,const Bit8u *src,int count);
+ BX_CIRRUS_SMF void svga_colorexpand_24(Bit8u *dst,const Bit8u *src,int count);
+ BX_CIRRUS_SMF void svga_colorexpand_32(Bit8u *dst,const Bit8u *src,int count);
+
+ BX_CIRRUS_SMF void svga_setup_bitblt_cputovideo(Bit32u dstaddr,Bit32u srcaddr);
+ BX_CIRRUS_SMF void svga_setup_bitblt_videotocpu(Bit32u dstaddr,Bit32u srcaddr);
+ BX_CIRRUS_SMF void svga_setup_bitblt_videotovideo(Bit32u dstaddr,Bit32u srcaddr);
+
+#if !BX_USE_CIRRUS_SMF
+ static void svga_patterncopy_static(void *this_ptr);
+ static void svga_simplebitblt_static(void *this_ptr);
+ static void svga_patterncopy_memsrc_static(void *this_ptr);
+ static void svga_simplebitblt_memsrc_static(void *this_ptr);
+ static void svga_simplebitblt_transp_memsrc_static(void *this_ptr);
+#else
+ #define svga_patterncopy_static svga_patterncopy
+ #define svga_simplebitblt_static svga_simplebitblt
+ #define svga_patterncopy_memsrc_static svga_patterncopy_memsrc
+ #define svga_simplebitblt_memsrc_static svga_simplebitblt_memsrc
+ #define svga_simplebitblt_transp_memsrc_static svga_simplebitblt_transp_memsrc
+#endif // !BX_USE_CIRRUS_SMF
+ BX_CIRRUS_SMF void svga_patterncopy();
+ BX_CIRRUS_SMF void svga_simplebitblt();
+ BX_CIRRUS_SMF void svga_patterncopy_memsrc();
+ BX_CIRRUS_SMF void svga_simplebitblt_memsrc();
+ BX_CIRRUS_SMF void svga_simplebitblt_transp_memsrc();
+
+ BX_CIRRUS_SMF bx_bool svga_asyncbitblt_next();
+ BX_CIRRUS_SMF bx_cirrus_bitblt_rop_t svga_get_fwd_rop_handler(Bit8u rop);
+ BX_CIRRUS_SMF bx_cirrus_bitblt_rop_t svga_get_bkwd_rop_handler(Bit8u rop);
+
+ struct {
+ Bit8u index;
+ Bit8u reg[CIRRUS_CRTC_MAX+1];
+ } crtc; // 0x3b4-5/0x3d4-5
+ struct {
+ Bit8u index;
+ Bit8u reg[CIRRUS_SEQENCER_MAX+1];
+ } sequencer; // 0x3c4-5
+ struct {
+ Bit8u index;
+ Bit8u reg[CIRRUS_CONTROL_MAX+1];
+ Bit8u shadow_reg0;
+ Bit8u shadow_reg1;
+ } control; // 0x3ce-f
+ struct {
+ unsigned lockindex;
+ Bit8u data;
+ Bit8u palette[48];
+ } hidden_dac; // 0x3c6
+
+ bx_bool svga_unlock_special;
+ bx_bool svga_needs_update_tile;
+ bx_bool svga_needs_update_dispentire;
+ bx_bool svga_needs_update_mode;
+
+ unsigned svga_xres;
+ unsigned svga_yres;
+ unsigned svga_pitch;
+ unsigned svga_bpp;
+ unsigned svga_dispbpp;
+
+ Bit8u *vidmem;
+ Bit8u *tilemem;
+ Bit32u bank_base[2];
+ Bit32u bank_limit[2];
+ Bit32u memsize;
+ Bit8u *disp_ptr;
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ bx_bool pci_enabled;
+#endif
+
+ struct {
+ bx_cirrus_bitblt_rop_t rop_handler;
+ int pixelwidth;
+ int bltwidth;
+ int bltheight;
+ int dstpitch;
+ int srcpitch;
+ Bit8u bltmode;
+ Bit8u bltmodeext;
+ Bit8u bltrop;
+ Bit8u *dst;
+ const Bit8u *src;
+#if BX_USE_CIRRUS_SMF
+ void (*bitblt_ptr)();
+#else
+ void (*bitblt_ptr)(void *this_ptr);
+#endif // BX_USE_CIRRUS_SMF
+ int async_xbytes;
+ int async_y;
+ Bit8u *memsrc_ptr; // CPU -> video
+ Bit8u *memsrc_endptr;
+ int memsrc_bytesperline;
+ int memsrc_needed;
+ Bit8u *memdst_ptr; // video -> CPU
+ Bit8u *memdst_endptr;
+ int memdst_bytesperline;
+ int memdst_needed;
+ Bit8u memsrc[CIRRUS_BLT_CACHESIZE];
+ Bit8u memdst[CIRRUS_BLT_CACHESIZE];
+ Bit16u pos_x;
+ Bit16u pos_y;
+ } bitblt;
+
+ struct {
+ Bit16u x, y, size;
+ } hw_cursor;
+
+ bx_bool is_unlocked() { return svga_unlock_special; }
+
+ bx_bool banking_granularity_is_16k() { return !!(control.reg[0x0B] & 0x20); }
+ bx_bool banking_is_dual() { return !!(control.reg[0x0B] & 0x01); }
+
+#if BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+ BX_CIRRUS_SMF void svga_init_pcihandlers(void);
+
+ static Bit32u pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len);
+ static void pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len);
+
+ BX_CIRRUS_SMF bx_bool cirrus_mem_read_handler(unsigned long addr, unsigned long len, void *data, void *param);
+ BX_CIRRUS_SMF bx_bool cirrus_mem_write_handler(unsigned long addr, unsigned long len, void *data, void *param);
+#if !BX_USE_CIRRUS_SMF
+ Bit32u pci_read(Bit8u address, unsigned io_len);
+ void pci_write(Bit8u address, Bit32u value, unsigned io_len);
+#endif // !BX_USE_CIRRUS_SMF
+ Bit8u pci_conf[256];
+ Bit32u pci_memaddr;
+ Bit32u pci_mmioaddr;
+#endif // BX_SUPPORT_PCI && BX_SUPPORT_CLGD54XX_PCI
+};
+
+#endif // BX_SUPPORT_CLGD54XX
diff -urNX /home/volker/exclude-diff /home/volker/bochs/iodev/vga.cc ./iodev/vga.cc
--- /home/volker/bochs/iodev/vga.cc 2004-08-06 17:49:55.000000000 +0200
+++ ./iodev/vga.cc 2004-08-07 09:07:14.000000000 +0200
@@ -80,6 +80,13 @@
unsigned old_iHeight = 0, old_iWidth = 0, old_MSL = 0, old_BPP = 0;
+#if BX_SUPPORT_CLGD54XX
+ void
+libvga_set_smf_pointer(bx_vga_c *theVga_ptr)
+{
+ theVga = theVga_ptr;
+}
+#else // BX_SUPPORT_CLGD54XX
int
libvga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
@@ -93,6 +100,7 @@
libvga_LTX_plugin_fini(void)
{
}
+#endif // BX_SUPPORT_CLGD54XX
bx_vga_c::bx_vga_c(void)
{
@@ -122,35 +130,13 @@
char *argv[16];
char *ptr;
char string[512];
- Bit8u io_mask[16] = {3, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1};
-
+#if BX_SUPPORT_VBE
unsigned addr;
- for (addr=0x03B4; addr<=0x03B5; addr++) {
- DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
- DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
- }
-
- for (addr=0x03BA; addr<=0x03BA; addr++) {
- DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
- DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
- }
-
- i = 0;
- for (addr=0x03C0; addr<=0x03CF; addr++) {
- DEV_register_ioread_handler(this, read_handler, addr, "vga video", io_mask[i++]);
- DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
- }
-
- for (addr=0x03D4; addr<=0x03D5; addr++) {
- DEV_register_ioread_handler(this, read_handler, addr, "vga video", 3);
- DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
- }
-
- for (addr=0x03DA; addr<=0x03DA; addr++) {
- DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
- DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
- }
+#endif
+#if !BX_SUPPORT_CLGD54XX
+ BX_VGA_THIS init_iohandlers(read_handler,write_handler);
+#endif // !BX_SUPPORT_CLGD54XX
DEV_register_memory_handlers(mem_read_handler, theVga, mem_write_handler,
theVga, 0xa0000, 0xbffff);
@@ -274,11 +260,9 @@
}
}
- BX_INFO(("interval=%u", bx_options.Ovga_update_interval->get ()));
- if (BX_VGA_THIS timer_id == BX_NULL_TIMER_HANDLE) {
- BX_VGA_THIS timer_id = bx_pc_system.register_timer(this, timer_handler,
- bx_options.Ovga_update_interval->get (), 1, 1, "vga");
- }
+#if !BX_SUPPORT_CLGD54XX
+ BX_VGA_THIS init_systemtimer(timer_handler);
+#endif // !BX_SUPPORT_CLGD54XX
/* video card with BIOS ROM */
DEV_cmos_set_reg(0x14, (DEV_cmos_get_reg(0x14) & 0xcf) | 0x00);
@@ -342,6 +326,49 @@
}
void
+bx_vga_c::init_iohandlers(bx_read_handler_t f_read, bx_write_handler_t f_write)
+{
+ unsigned addr, i;
+ Bit8u io_mask[16] = {3, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1};
+ for (addr=0x03B4; addr<=0x03B5; addr++) {
+ DEV_register_ioread_handler(this, f_read, addr, "vga video", 1);
+ DEV_register_iowrite_handler(this, f_write, addr, "vga video", 3);
+ }
+
+ for (addr=0x03BA; addr<=0x03BA; addr++) {
+ DEV_register_ioread_handler(this, f_read, addr, "vga video", 1);
+ DEV_register_iowrite_handler(this, f_write, addr, "vga video", 3);
+ }
+
+ i = 0;
+ for (addr=0x03C0; addr<=0x03CF; addr++) {
+ DEV_register_ioread_handler(this, f_read, addr, "vga video", io_mask[i++]);
+ DEV_register_iowrite_handler(this, f_write, addr, "vga video", 3);
+ }
+
+ for (addr=0x03D4; addr<=0x03D5; addr++) {
+ DEV_register_ioread_handler(this, f_read, addr, "vga video", 3);
+ DEV_register_iowrite_handler(this, f_write, addr, "vga video", 3);
+ }
+
+ for (addr=0x03DA; addr<=0x03DA; addr++) {
+ DEV_register_ioread_handler(this, f_read, addr, "vga video", 1);
+ DEV_register_iowrite_handler(this, f_write, addr, "vga video", 3);
+ }
+
+}
+
+ void
+bx_vga_c::init_systemtimer(bx_timer_handler_t f_timer)
+{
+ BX_INFO(("interval=%u", bx_options.Ovga_update_interval->get ()));
+ if (BX_VGA_THIS timer_id == BX_NULL_TIMER_HANDLE) {
+ BX_VGA_THIS timer_id = bx_pc_system.register_timer(this, f_timer,
+ bx_options.Ovga_update_interval->get (), 1, 1, "vga");
+ }
+}
+
+ void
bx_vga_c::reset(unsigned type)
{
}
@@ -1014,7 +1041,7 @@
BX_DEBUG(("io write 0x3c5=0x%02x: clocking mode reg: ignoring",
(unsigned) value));
#endif
- BX_VGA_THIS s.sequencer.reg1 = value & 0x3f;
+ BX_VGA_THIS s.sequencer.reg1 = value & 0x3d;
BX_VGA_THIS s.x_dotclockdiv2 = ((value & 0x08) > 0);
break;
case 2: /* sequencer: map mask register */
@@ -1023,7 +1050,7 @@
BX_VGA_THIS s.sequencer.map_mask_bit[i] = (value >> i) & 0x01;
break;
case 3: /* sequencer: character map select register */
- BX_VGA_THIS s.sequencer.char_map_select = value;
+ BX_VGA_THIS s.sequencer.char_map_select = value & 0x3f;
charmap1 = value & 0x13;
if (charmap1 > 3) charmap1 = (charmap1 & 3) + 4;
charmap2 = (value & 0x2C) >> 2;
@@ -1150,8 +1177,7 @@
break;
case 3: /* Data Rotate */
BX_VGA_THIS s.graphics_ctrl.data_rotate = value & 0x07;
- /* ??? is this bits 3..4 or 4..5 */
- BX_VGA_THIS s.graphics_ctrl.raster_op = (value >> 3) & 0x03; /* ??? */
+ BX_VGA_THIS s.graphics_ctrl.raster_op = (value >> 3) & 0x03;
break;
case 4: /* Read Map Select */
BX_VGA_THIS s.graphics_ctrl.read_map_select = value & 0x03;
@@ -2191,19 +2217,20 @@
// 320 x 200 256 color mode: chained pixel representation
BX_VGA_THIS s.vga_memory[(offset & ~0x03) + (offset % 4)*65536] = value;
- offset -= start_addr;
- x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE/2);
- if (BX_VGA_THIS s.y_doublescan) {
- y_tileno = (offset / BX_VGA_THIS s.line_offset) / (Y_TILESIZE/2);
- } else {
- y_tileno = (offset / BX_VGA_THIS s.line_offset) / Y_TILESIZE;
+ if (BX_VGA_THIS s.line_offset > 0) {
+ offset -= start_addr;
+ x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE/2);
+ if (BX_VGA_THIS s.y_doublescan) {
+ y_tileno = (offset / BX_VGA_THIS s.line_offset) / (Y_TILESIZE/2);
+ } else {
+ y_tileno = (offset / BX_VGA_THIS s.line_offset) / Y_TILESIZE;
+ }
+ BX_VGA_THIS s.vga_mem_updated = 1;
+ SET_TILE_UPDATED (x_tileno, y_tileno, 1);
}
- BX_VGA_THIS s.vga_mem_updated = 1;
- SET_TILE_UPDATED (x_tileno, y_tileno, 1);
return;
- }
-
}
+ }
/* addr between 0xA0000 and 0xAFFFF */
diff -urNX /home/volker/exclude-diff /home/volker/bochs/iodev/vga.h ./iodev/vga.h
--- /home/volker/bochs/iodev/vga.h 2004-07-21 22:39:54.000000000 +0200
+++ ./iodev/vga.h 2004-08-06 14:17:14.000000000 +0200
@@ -79,6 +79,11 @@
#define BX_MAX_XRES VBE_DISPI_MAX_XRES
#define BX_MAX_YRES VBE_DISPI_MAX_YRES
+#elif BX_SUPPORT_CLGD54XX
+
+#define BX_MAX_XRES 1280
+#define BX_MAX_YRES 1024
+
#else
#define BX_MAX_XRES 800
@@ -130,7 +135,9 @@
unsigned *txWidth);
virtual Bit8u get_actl_palette_idx(Bit8u index);
-private:
+protected:
+ void init_iohandlers(bx_read_handler_t f_read, bx_write_handler_t f_write);
+ void init_systemtimer(bx_timer_handler_t f_timer);
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
@@ -300,9 +307,15 @@
static void timer_handler(void *);
BX_VGA_SMF void timer(void);
- private:
+ protected:
BX_VGA_SMF void update(void);
BX_VGA_SMF void dump_status(void);
BX_VGA_SMF void determine_screen_dimensions(unsigned *piHeight,
unsigned *piWidth);
};
+
+#if BX_SUPPORT_CLGD54XX
+ void
+libvga_set_smf_pointer(bx_vga_c *theVga_ptr);
+#include "iodev/svga_cirrus.h"
+#endif // BX_SUPPORT_CLGD54XX