--- uae/src/picasso96.c 2018/04/24 16:42:09 1.1.1.2 +++ uae/src/picasso96.c 2018/04/24 17:16:38 1.1.1.17 @@ -26,24 +26,31 @@ * * TODO: * - add panning capability + * - we want to add a manual switch to override SetSwitch for hardware banging + * programs started from a Picasso workbench. */ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" -#include "threaddep/penguin.h" +#include "threaddep/thread.h" #include "uae.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" #include "newcpu.h" #include "xwin.h" #include "picasso96.h" #ifdef PICASSO96 +#define P96TRACING_ENABLED 0 +#if P96TRACING_ENABLED +#define P96TRACE(x) do { write_log x; } while(0) +#else +#define P96TRACE(x) +#endif + static uae_u32 gfxmem_lget (uaecptr) REGPARAM; static uae_u32 gfxmem_wget (uaecptr) REGPARAM; static uae_u32 gfxmem_bget (uaecptr) REGPARAM; @@ -57,7 +64,7 @@ static void write_gfx_long (uaecptr addr static void write_gfx_word (uaecptr addr, uae_u16 value); static void write_gfx_byte (uaecptr addr, uae_u8 value); -static uae_u8 all_ones_bitmap, all_zeros_bitmap; /* yuk */ +static uae_u8 all_ones_bitmap, all_zeros_bitmap; struct picasso96_state_struct picasso96_state; struct picasso_vidbuf_description picasso_vidinfo; @@ -70,7 +77,7 @@ struct ScreenResolution planar = { 320, struct ScreenResolution chunky = { 640, 480 }; struct ScreenResolution hicolour = { 640, 480 }; struct ScreenResolution truecolour = { 640, 480 }; -struct ScreenResolution alphacolour = { 460, 480 }; +struct ScreenResolution alphacolour = { 640, 480 }; uae_u16 picasso96_pixel_format = RGBFF_CHUNKY; @@ -78,6 +85,12 @@ struct PicassoResolution DisplayModes[MA static int mode_count = 0; +static int set_gc_called = 0; +static int set_panning_called = 0; +/* Address of the screen in the Amiga frame buffer at the time of the last + SetPanning call. */ +static uaecptr oldscr; + static uae_u32 p2ctab[256][2]; /* @@ -117,8 +130,8 @@ static void DumpLibResolutionStructure ( { int i; uaecptr amigamodeinfoptr; - struct LibResolution *uaememptr = (struct LibResolution *)get_mem_bank(amigalibresptr).xlateaddr(amigalibresptr); - + struct LibResolution *uaememptr = (struct LibResolution *) get_mem_bank (amigalibresptr).xlateaddr (amigalibresptr); + return; write_log ("LibResolution Structure Dump:\n"); @@ -132,7 +145,7 @@ static void DumpLibResolutionStructure ( write_log (" Height = %d\n", get_word (amigalibresptr + PSSO_LibResolution_Height)); write_log (" Flags = %d\n", get_word (amigalibresptr + PSSO_LibResolution_Flags)); for (i = 0; i < MAXMODES; i++) { - amigamodeinfoptr = get_long (amigalibresptr + PSSO_LibResolution_Modes + i*4); + amigamodeinfoptr = get_long (amigalibresptr + PSSO_LibResolution_Modes + i * 4); write_log (" ModeInfo[%d] = 0x%x\n", i, amigamodeinfoptr); if (amigamodeinfoptr) DumpModeInfoStructure (amigamodeinfoptr); @@ -141,7 +154,7 @@ static void DumpLibResolutionStructure ( } } -static char binary_byte[8]; +static char binary_byte[9]; static char *BuildBinaryString (uae_u8 value) { @@ -149,6 +162,7 @@ static char *BuildBinaryString (uae_u8 v for (i = 0; i < 8; i++) { binary_byte[i] = (value & (1 << (7 - i))) ? '#' : '.'; } + binary_byte[8] = '\0'; return binary_byte; } @@ -180,10 +194,15 @@ static void DumpTemplate (struct Templat } } +int picasso_nr_resolutions (void) +{ + return mode_count; +} + static void ShowSupportedResolutions (void) { int i; - + return; for (i = 0; i < mode_count; i++) @@ -193,27 +212,27 @@ static void ShowSupportedResolutions (vo static uae_u8 GetBytesPerPixel (uae_u32 RGBfmt) { switch (RGBfmt) { - case RGBFB_CLUT: + case RGBFB_CLUT: return 1; - case RGBFB_A8R8G8B8: - case RGBFB_A8B8G8R8: - case RGBFB_R8G8B8A8: - case RGBFB_B8G8R8A8: + case RGBFB_A8R8G8B8: + case RGBFB_A8B8G8R8: + case RGBFB_R8G8B8A8: + case RGBFB_B8G8R8A8: return 4; - case RGBFB_B8G8R8: - case RGBFB_R8G8B8: + case RGBFB_B8G8R8: + case RGBFB_R8G8B8: return 3; - case RGBFB_R5G5B5: - case RGBFB_R5G6B5: - case RGBFB_R5G6B5PC: - case RGBFB_R5G5B5PC: - case RGBFB_B5G6R5PC: - case RGBFB_B5G5R5PC: + case RGBFB_R5G5B5: + case RGBFB_R5G6B5: + case RGBFB_R5G6B5PC: + case RGBFB_R5G5B5PC: + case RGBFB_B5G6R5PC: + case RGBFB_B5G5R5PC: return 2; - default: + default: write_log ("ERROR - GetBytesPerPixel() was unsuccessful with 0x%x?!\n", RGBfmt); return 0; } @@ -227,7 +246,7 @@ static int CopyRenderInfoStructureA2U (u { uaecptr memp = get_long (amigamemptr + PSSO_RenderInfo_Memory); - if (valid_address (memp, 1 /* FIXME */)) { + if (valid_address (memp, PSSO_RenderInfo_sizeof)) { ri->Memory = get_real_address (memp); ri->BytesPerRow = get_word (amigamemptr + PSSO_RenderInfo_BytesPerRow); ri->RGBFormat = get_long (amigamemptr + PSSO_RenderInfo_RGBFormat); @@ -240,7 +259,7 @@ static int CopyRenderInfoStructureA2U (u static int CopyPatternStructureA2U (uaecptr amigamemptr, struct Pattern *pattern) { uaecptr memp = get_long (amigamemptr + PSSO_Pattern_Memory); - if (valid_address (memp, 1 /* FIXME */)) { + if (valid_address (memp, PSSO_Pattern_sizeof)) { pattern->Memory = get_real_address (memp); pattern->XOffset = get_word (amigamemptr + PSSO_Pattern_XOffset); pattern->YOffset = get_word (amigamemptr + PSSO_Pattern_YOffset); @@ -272,15 +291,15 @@ static int CopyBitMapStructureA2U (uaecp bm->Depth = get_byte (amigamemptr + PSSO_BitMap_Depth); for (i = 0; i < bm->Depth; i++) { - uaecptr plane = get_long (amigamemptr + PSSO_BitMap_Planes + i*4); + uaecptr plane = get_long (amigamemptr + PSSO_BitMap_Planes + i * 4); switch (plane) { - case 0: + case 0: bm->Planes[i] = &all_zeros_bitmap; break; - case 0xFFFFFFFF: + case 0xFFFFFFFF: bm->Planes[i] = &all_ones_bitmap; break; - default: + default: if (valid_address (plane, bm->BytesPerRow * bm->Rows)) bm->Planes[i] = get_real_address (plane); else @@ -295,7 +314,7 @@ static int CopyTemplateStructureA2U (uae { uaecptr memp = get_long (amigamemptr + PSSO_Template_Memory); - if (valid_address (memp, 1 /* FIXME */)) { + if (valid_address (memp, 1 /* FIXME */ )) { tmpl->Memory = get_real_address (memp); tmpl->BytesPerRow = get_word (amigamemptr + PSSO_Template_BytesPerRow); tmpl->XOffset = get_byte (amigamemptr + PSSO_Template_XOffset); @@ -313,15 +332,15 @@ static void CopyLibResolutionStructureU2 char *uaememptr = 0; int i; - uaememptr = gfxmem_xlate(amigamemptr); /* I know that amigamemptr is inside my gfxmem chunk, so I can just do the xlate() */ - memset(uaememptr, 0, PSSO_LibResolution_sizeof); /* zero out our LibResolution structure */ - strcpy(uaememptr + PSSO_LibResolution_P96ID, libres->P96ID); + uaememptr = gfxmem_xlate (amigamemptr); /* I know that amigamemptr is inside my gfxmem chunk, so I can just do the xlate() */ + memset (uaememptr, 0, PSSO_LibResolution_sizeof); /* zero out our LibResolution structure */ + strcpy (uaememptr + PSSO_LibResolution_P96ID, libres->P96ID); put_long (amigamemptr + PSSO_LibResolution_DisplayID, libres->DisplayID); put_word (amigamemptr + PSSO_LibResolution_Width, libres->Width); put_word (amigamemptr + PSSO_LibResolution_Height, libres->Height); put_word (amigamemptr + PSSO_LibResolution_Flags, libres->Flags); for (i = 0; i < MAXMODES; i++) - put_long (amigamemptr + PSSO_LibResolution_Modes + i*4, libres->Modes[i]); + put_long (amigamemptr + PSSO_LibResolution_Modes + i * 4, libres->Modes[i]); #if 0 put_long (amigamemptr, libres->Node.ln_Succ); put_long (amigamemptr + 4, libres->Node.ln_Pred); @@ -340,24 +359,24 @@ static void AmigaListAddTail (uaecptr li if (get_long (list + 8) == list) { /* Empty list - set it up */ - put_long (list, node); /* point the lh_Head to our new node */ - put_long (list + 4, 0); /* set the lh_Tail to NULL */ - put_long (list + 8, node); /* point the lh_TailPred to our new node */ + put_long (list, node); /* point the lh_Head to our new node */ + put_long (list + 4, 0); /* set the lh_Tail to NULL */ + put_long (list + 8, node); /* point the lh_TailPred to our new node */ /* Adjust the new node - don't rely on it being zeroed out */ - put_long (node, 0); /* ln_Succ */ - put_long (node + 4, 0); /* ln_Pred */ + put_long (node, 0); /* ln_Succ */ + put_long (node + 4, 0); /* ln_Pred */ } else { - amigamemptr = get_long (list + 8); /* get the lh_TailPred contents */ + amigamemptr = get_long (list + 8); /* get the lh_TailPred contents */ - put_long (list + 8, node); /* point the lh_TailPred to our new node */ + put_long (list + 8, node); /* point the lh_TailPred to our new node */ /* Adjust the previous lh_TailPred node */ - put_long (amigamemptr, node); /* point the ln_Succ to our new node */ + put_long (amigamemptr, node); /* point the ln_Succ to our new node */ /* Adjust the new node - don't rely on it being zeroed out */ - put_long (node, 0); /* ln_Succ */ - put_long (node + 4, amigamemptr); /* ln_Pred */ + put_long (node, 0); /* ln_Succ */ + put_long (node + 4, amigamemptr); /* ln_Pred */ } } @@ -371,13 +390,34 @@ static void AmigaListAddTail (uaecptr li * there is no OS specific function to fill the rectangle. */ -static void do_fillrect (uae_u8 *src, int x, int y, int width, int height) +static void do_fillrect (uae_u8 * src, int x, int y, int width, int height, + uae_u32 pen, int Bpp, RGBFTYPE rgbtype) { uae_u8 *dst; + + /* Clipping. */ + x -= picasso96_state.XOffset; + y -= picasso96_state.YOffset; + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } + if (x + width > picasso96_state.Width) + width = picasso96_state.Width - x; + if (y + height > picasso96_state.Height) + height = picasso96_state.Height - y; + + if (width <= 0 || height <= 0) + return; + /* Try OS specific fillrect function here; and return if successful. */ DX_Invalidate (y, y + height - 1); - if (! picasso_vidinfo.extra_mem) + if (!picasso_vidinfo.extra_mem) return; width *= picasso96_state.BytesPerPixel; @@ -385,11 +425,18 @@ static void do_fillrect (uae_u8 *src, in if (!dst) goto out; - dst += y*picasso_vidinfo.rowbytes + x*picasso_vidinfo.pixbytes; + dst += y * picasso_vidinfo.rowbytes + x * picasso_vidinfo.pixbytes; if (picasso_vidinfo.rgbformat == picasso96_state.RGBFormat) { - while (height-- > 0) { - memcpy (dst, src, width); - dst += picasso_vidinfo.rowbytes; + if (Bpp == 1) { + while (height-- > 0) { + memset (dst, pen, width); + dst += picasso_vidinfo.rowbytes; + } + } else { + while (height-- > 0) { + memcpy (dst, src, width); + dst += picasso_vidinfo.rowbytes; + } } } else { int psiz = GetBytesPerPixel (picasso_vidinfo.rgbformat); @@ -399,21 +446,21 @@ static void do_fillrect (uae_u8 *src, in while (height-- > 0) { int i; switch (psiz) { - case 2: + case 2: for (i = 0; i < width; i++) - *((uae_u16 *)dst + i) = picasso_vidinfo.clut[src[i]]; + *((uae_u16 *) dst + i) = picasso_vidinfo.clut[src[i]]; break; - case 4: + case 4: for (i = 0; i < width; i++) - *((uae_u32 *)dst + i) = picasso_vidinfo.clut[src[i]]; + *((uae_u32 *) dst + i) = picasso_vidinfo.clut[src[i]]; break; - default: - abort (); + default: + abort (); } dst += picasso_vidinfo.rowbytes; } } - out: + out: gfx_unlock_picasso (); } @@ -425,11 +472,40 @@ static void do_fillrect (uae_u8 *src, in * srcp. */ -static void do_blit (uae_u8 *srcp, unsigned long src_rowbytes, - int srcx, int srcy, int dstx, int dsty, - int width, int height, int can_do_blit) -{ - uae_u8 *dstp; +static void do_blit (struct RenderInfo *ri, int Bpp, int srcx, int srcy, + int dstx, int dsty, int width, int height, + BLIT_OPCODE opcode, int can_do_blit) +{ + int xoff = picasso96_state.XOffset; + int yoff = picasso96_state.YOffset; + uae_u8 *srcp, *dstp; + + /* Clipping. */ + dstx -= xoff; + dsty -= yoff; + if (srcy < yoff || srcx < xoff + || srcx - xoff + width > picasso96_state.Width + || srcy - yoff + height > picasso96_state.Height) + { + can_do_blit = 0; + } + if (dstx < 0) { + srcx -= dstx; + width += dstx; + dstx = 0; + } + if (dsty < 0) { + srcy -= dsty; + height += dsty; + dsty = 0; + } + if (dstx + width > picasso96_state.Width) + width = picasso96_state.Width - dstx; + if (dsty + height > picasso96_state.Height) + height = picasso96_state.Height - dsty; + if (width <= 0 || height <= 0) + return; + /* If this RenderInfo points at something else than the currently visible * screen, we must ignore the blit. */ if (can_do_blit) { @@ -439,23 +515,26 @@ static void do_blit (uae_u8 *srcp, unsig */ } + /* If no OS blit available, we do a copy from the P96 framebuffer in Amiga + memory to the host's frame buffer. */ DX_Invalidate (dsty, dsty + height - 1); - if (! picasso_vidinfo.extra_mem) + if (!picasso_vidinfo.extra_mem) return; dstp = gfx_lock_picasso (); if (dstp == 0) goto out; - - /* The areas can't overlap: the source is always in the Picasso frame buffer, - * and the destination is a different buffer owned by the graphics code. */ - dstp += dsty * picasso_vidinfo.rowbytes + dstx * picasso_vidinfo.pixbytes; + P96TRACE(("do_blit with srcp 0x%x, dstp 0x%x, dst_rowbytes %d, srcx %d, srcy %d, dstx %d, dsty %d, w %d, h %d, dst_pixbytes %d\n", + srcp, dstp, picasso_vidinfo.rowbytes, srcx, srcy, dstx, dsty, width, height, picasso_vidinfo.pixbytes)); + P96TRACE(("gfxmem is at 0x%x\n",gfxmemory)); + + srcp = ri->Memory + srcx * Bpp + srcy * ri->BytesPerRow; if (picasso_vidinfo.rgbformat == picasso96_state.RGBFormat) { - width *= picasso96_state.BytesPerPixel; + width *= Bpp; while (height-- > 0) { memcpy (dstp, srcp, width); - srcp += src_rowbytes; + srcp += ri->BytesPerRow; dstp += picasso_vidinfo.rowbytes; } } else { @@ -466,103 +545,140 @@ static void do_blit (uae_u8 *srcp, unsig while (height-- > 0) { int i; switch (psiz) { - case 2: + case 2: for (i = 0; i < width; i++) - *((uae_u16 *)dstp + i) = picasso_vidinfo.clut[srcp[i]]; + *((uae_u16 *) dstp + i) = picasso_vidinfo.clut[srcp[i]]; break; - case 4: + case 4: for (i = 0; i < width; i++) - *((uae_u32 *)dstp + i) = picasso_vidinfo.clut[srcp[i]]; + *((uae_u32 *) dstp + i) = picasso_vidinfo.clut[srcp[i]]; break; - default: - abort (); + default: + abort (); } - srcp += src_rowbytes; + srcp += ri->BytesPerRow; dstp += picasso_vidinfo.rowbytes; } } - out: + out: gfx_unlock_picasso (); } /* - * Invert a rectangle on the screen. src and src_rowbytes describe the - * inverted rectangle in the frame buffer, so that do_blit can be used if - * there is no OS specific function to fill the rectangle. + * Invert a rectangle on the screen. */ -static void do_invertrect (uae_u8 *src, unsigned long src_rowbytes, - int x, int y, int width, int height) +static void do_invertrect (struct RenderInfo *ri, int Bpp, int x, int y, int width, int height) { +#if 0 + /* Clipping. */ + x -= picasso96_state.XOffset; + y -= picasso96_state.YOffset; + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } + if (x + width > picasso96_state.Width) + width = picasso96_state.Width - x; + if (y + height > picasso96_state.Height) + height = picasso96_state.Height - y; + + if (width <= 0 || height <= 0) + return; + +#endif /* TODO: Try OS specific invertrect function here; and return if successful. */ - do_blit (src, src_rowbytes, 0, 0, x, y, width, height, 0); + do_blit (ri, Bpp, x, y, x, y, width, height, BLIT_SRC, 0); } static uaecptr wgfx_linestart; static uaecptr wgfx_lineend; static uaecptr wgfx_min, wgfx_max; -static unsigned long wgfx_y; +static long wgfx_y; static void wgfx_do_flushline (void) { + int src_y = wgfx_y; + long x0, x1, width; uae_u8 *src, *dstp; + int Bpp = GetBytesPerPixel (picasso_vidinfo.rgbformat); + int fb_bpp = picasso96_state.BytesPerPixel; + + wgfx_y -= picasso96_state.YOffset; + if (wgfx_y < 0 || wgfx_y >= picasso96_state.Height) + goto out1; DX_Invalidate (wgfx_y, wgfx_y); - if (! picasso_vidinfo.extra_mem) - goto out; + if (!picasso_vidinfo.extra_mem) + goto out1; + + x0 = wgfx_min - wgfx_linestart; + width = wgfx_max - wgfx_min; + x0 -= picasso96_state.XOffset * fb_bpp; + if (x0 < 0) { + width += x0; + wgfx_min += x0; + x0 = 0; + } + if (x0 + width > picasso96_state.Width * fb_bpp) + width = picasso96_state.Width * fb_bpp - x0; dstp = gfx_lock_picasso (); if (dstp == 0) goto out; - /*printf("flushing %d (%x %x %x)\n", wgfx_y, wgfx_linestart, wgfx_min, wgfx_max); */ + + // P96TRACE(("flushing %d\n", wgfx_y)); src = gfxmemory + wgfx_min; if (picasso_vidinfo.rgbformat == picasso96_state.RGBFormat) { - dstp += wgfx_y * picasso_vidinfo.rowbytes + wgfx_min - wgfx_linestart; - memcpy (dstp, src, wgfx_max - wgfx_min); + dstp += wgfx_y * picasso_vidinfo.rowbytes + x0; + memcpy (dstp, src, width); } else { - int width = wgfx_max - wgfx_min; int i; - int psiz = GetBytesPerPixel (picasso_vidinfo.rgbformat); if (picasso96_state.RGBFormat != RGBFB_CHUNKY) abort (); - dstp += wgfx_y * picasso_vidinfo.rowbytes + (wgfx_min - wgfx_linestart) * psiz; - switch (psiz) { - case 2: + dstp += wgfx_y * picasso_vidinfo.rowbytes + x0 * Bpp; + switch (Bpp) { + case 2: for (i = 0; i < width; i++) - *((uae_u16 *)dstp + i) = picasso_vidinfo.clut[src[i]]; + *((uae_u16 *) dstp + i) = picasso_vidinfo.clut[src[i]]; break; - case 4: + case 4: for (i = 0; i < width; i++) - *((uae_u32 *)dstp + i) = picasso_vidinfo.clut[src[i]]; + *((uae_u32 *) dstp + i) = picasso_vidinfo.clut[src[i]]; break; - default: - abort (); + default: + abort (); } } - out: + out: gfx_unlock_picasso (); + out1: wgfx_linestart = 0xFFFFFFFF; } -static __inline__ void wgfx_flushline (void) +STATIC_INLINE void wgfx_flushline (void) { - if (wgfx_linestart == 0xFFFFFFFF || ! picasso_on) + if (wgfx_linestart == 0xFFFFFFFF || !picasso_on) return; wgfx_do_flushline (); } static int renderinfo_is_current_screen (struct RenderInfo *ri) { - if (! picasso_on) + if (!picasso_on) return 0; - if (ri->Memory != gfxmemory + (picasso96_state.Address - gfxmem_start)) { + if (ri->Memory != gfxmemory + (picasso96_state.Address - gfxmem_start)) return 0; - } + return 1; } @@ -576,19 +692,27 @@ void picasso_refresh (void) { struct RenderInfo ri; - if (! picasso_on) + if (!picasso_on) return; /* Make sure that the first time we show a Picasso video mode, we don't blit any crap. * We can do this by checking if we have an Address yet. */ if (picasso96_state.Address) { + unsigned int width, height; /* blit the stuff from our static frame-buffer to the gfx-card */ - uae_u8 *ptr = gfxmemory + (picasso96_state.Address - gfxmem_start); + ri.Memory = gfxmemory + (picasso96_state.Address - gfxmem_start); ri.BytesPerRow = picasso96_state.BytesPerRow; ri.RGBFormat = picasso96_state.RGBFormat; - do_blit (ptr, picasso96_state.BytesPerRow, 0, 0, 0, 0, - picasso96_state.Width, picasso96_state.Height, 0); - write_log ("picasso_refresh() successful.\n"); + + if (set_panning_called) { + width = picasso96_state.VirtualWidth; + height = picasso96_state.VirtualHeight; + } else { + width = picasso96_state.Width; + height = picasso96_state.Height; + } + + do_blit (&ri, picasso96_state.BytesPerPixel, 0, 0, 0, 0, width, height, BLIT_SRC, 0); } else write_log ("ERROR - picasso_refresh() can't refresh!\n"); } @@ -619,7 +743,7 @@ uae_u32 picasso_FindCard (void) /* size of memory, minus a 32K chunk: 16K for pattern bitmaps, 16K for resolution list */ put_long (AmigaBoardInfo + PSSO_BoardInfo_MemorySize, allocated_gfxmem - 32768); - picasso96_state.CardFound = 1; /* mark our "card" as being found */ + picasso96_state.CardFound = 1; /* mark our "card" as being found */ return -1; } else return 0; @@ -642,8 +766,8 @@ static void FillBoardInfo (uaecptr amiga res->Modes[TRUEALPHA] = amigamemptr; break; } - uaememptr = gfxmem_xlate(amigamemptr); /* I know that amigamemptr is inside my gfxmem chunk, so I can just do the xlate() */ - memset(uaememptr, 0, PSSO_ModeInfo_sizeof); /* zero out our ModeInfo struct */ + uaememptr = gfxmem_xlate (amigamemptr); /* I know that amigamemptr is inside my gfxmem chunk, so I can just do the xlate() */ + memset (uaememptr, 0, PSSO_ModeInfo_sizeof); /* zero out our ModeInfo struct */ put_word (amigamemptr + PSSO_ModeInfo_Width, dm->res.width); put_word (amigamemptr + PSSO_ModeInfo_Height, dm->res.height); @@ -667,6 +791,30 @@ static void FillBoardInfo (uaecptr amiga put_long (amigamemptr + PSSO_ModeInfo_PixelClock, dm->res.width * dm->res.height * dm->refresh); } +static uae_u32 AssignModeID (int i, int count) +{ + if (DisplayModes[i].res.width == 320 && DisplayModes[i].res.height == 200) + return 0x50001000; + else if (DisplayModes[i].res.width == 320 && DisplayModes[i].res.height == 240) + return 0x50011000; + else if (DisplayModes[i].res.width == 640 && DisplayModes[i].res.height == 400) + return 0x50021000; + else if (DisplayModes[i].res.width == 640 && DisplayModes[i].res.height == 480) + return 0x50031000; + else if (DisplayModes[i].res.width == 800 && DisplayModes[i].res.height == 600) + return 0x50041000; + else if (DisplayModes[i].res.width == 1024 && DisplayModes[i].res.height == 768) + return 0x50051000; + else if (DisplayModes[i].res.width == 1152 && DisplayModes[i].res.height == 864) + return 0x50061000; + else if (DisplayModes[i].res.width == 1280 && DisplayModes[i].res.height == 1024) + return 0x50071000; + else if (DisplayModes[i].res.width == 1600 && DisplayModes[i].res.height == 1280) + return 0x50081000; + + return 0x50091000 + count * 0x10000; +} + /**************************************** * InitCard() * @@ -690,9 +838,10 @@ uae_u32 picasso_InitCard (void) int ModeInfoStructureCount = 1, LibResolutionStructureCount = 0; uaecptr amigamemptr = 0; uaecptr AmigaBoardInfo = m68k_areg (regs, 2); - put_word (AmigaBoardInfo + PSSO_BoardInfo_BitsPerCannon, DX_BitsPerCannon()); + put_word (AmigaBoardInfo + PSSO_BoardInfo_BitsPerCannon, DX_BitsPerCannon ()); put_word (AmigaBoardInfo + PSSO_BoardInfo_RGBFormats, picasso96_pixel_format); put_word (AmigaBoardInfo + PSSO_BoardInfo_SoftSpriteFlags, picasso96_pixel_format); + put_long (AmigaBoardInfo + PSSO_BoardInfo_BoardType, BT_uaegfx); put_word (AmigaBoardInfo + PSSO_BoardInfo_MaxHorResolution + 0, planar.width); put_word (AmigaBoardInfo + PSSO_BoardInfo_MaxHorResolution + 2, chunky.width); put_word (AmigaBoardInfo + PSSO_BoardInfo_MaxHorResolution + 4, hicolour.width); @@ -707,7 +856,7 @@ uae_u32 picasso_InitCard (void) for (i = 0; i < mode_count;) { int j = i; /* Add a LibResolution structure to the ResolutionsList MinList in our BoardInfo */ - res.DisplayID = 0x50001000 + LibResolutionStructureCount * 0x10000; + res.DisplayID = AssignModeID (i, LibResolutionStructureCount); res.BoardInfo = AmigaBoardInfo; res.Width = DisplayModes[i].res.width; res.Height = DisplayModes[i].res.height; @@ -719,7 +868,7 @@ uae_u32 picasso_InitCard (void) res.P96ID[4] = '0'; res.P96ID[5] = ':'; strcpy (res.Name, "uaegfx:"); - strncat (res.Name, DisplayModes[i].name, strchr(DisplayModes[i].name, ',') - DisplayModes[i].name); + strncat (res.Name, DisplayModes[i].name, strchr (DisplayModes[i].name, ',') - DisplayModes[i].name); res.Modes[PLANAR] = 0; res.Modes[CHUNKY] = 0; res.Modes[HICOLOR] = 0; @@ -728,8 +877,12 @@ uae_u32 picasso_InitCard (void) do { /* Handle this display mode's depth */ - amigamemptr = gfxmem_start + allocated_gfxmem - (PSSO_ModeInfo_sizeof * ModeInfoStructureCount++); - FillBoardInfo(amigamemptr, &res, &DisplayModes[i]); + /* Only add the modes when there is enough P96 RTG memory to hold the bitmap */ + long required = DisplayModes[i].res.width * DisplayModes[i].res.height * DisplayModes[i].depth; + if (allocated_gfxmem - 32768 > required) { + amigamemptr = gfxmem_start + allocated_gfxmem - (PSSO_ModeInfo_sizeof * ModeInfoStructureCount++); + FillBoardInfo (amigamemptr, &res, &DisplayModes[i]); + } i++; } while (i < mode_count && DisplayModes[i].res.width == DisplayModes[j].res.width @@ -737,7 +890,7 @@ uae_u32 picasso_InitCard (void) amigamemptr = gfxmem_start + allocated_gfxmem - 16384 + (PSSO_LibResolution_sizeof * LibResolutionStructureCount++); CopyLibResolutionStructureU2A (&res, amigamemptr); - DumpLibResolutionStructure( amigamemptr); + DumpLibResolutionStructure (amigamemptr); AmigaListAddTail (AmigaBoardInfo + PSSO_BoardInfo_ResolutionsList, amigamemptr); } @@ -766,8 +919,9 @@ uae_u32 picasso_SetSwitch (void) * desired state, and wait for custom.c to call picasso_enablescreen * whenever it is ready to change the screen state. */ picasso_requested_on = !!flag; - write_log ("SetSwitch() - trying to show %s screen\n", flag ? "picasso96":"amiga"); - +#if 1 + write_log ("SetSwitch() - trying to show %s screen\n", flag ? "picasso96" : "amiga"); +#endif /* Put old switch-state in D0 */ return !flag; } @@ -776,7 +930,39 @@ void picasso_enablescreen (int on) { wgfx_linestart = 0xFFFFFFFF; picasso_refresh (); - write_log ("SetSwitch() - showing %s screen\n", on ? "picasso96": "amiga"); +#if 1 + write_log ("SetSwitch() - showing %s screen\n", on ? "picasso96" : "amiga"); +#endif +} + +static int first_color_changed = 256; +static int last_color_changed = -1; + +void picasso_handle_vsync (void) +{ + if (first_color_changed < last_color_changed) { + DX_SetPalette (first_color_changed, last_color_changed - first_color_changed); + /* If we're emulating a CLUT mode, we need to redraw the entire screen. */ + if (picasso_vidinfo.rgbformat != picasso96_state.RGBFormat) + picasso_refresh (); + } + + first_color_changed = 256; + last_color_changed = -1; +} + +void picasso_clip_mouse (int *px, int *py) +{ + int xoff = picasso96_state.XOffset; + int yoff = picasso96_state.YOffset; + if (*px < -xoff) + *px = -xoff; + if (*px + xoff > picasso_vidinfo.width) + *px = picasso_vidinfo.width - xoff; + if (*py < -yoff) + *py = -yoff; + if (*py + yoff > picasso_vidinfo.height) + *py = picasso_vidinfo.height - yoff; } /* @@ -807,20 +993,21 @@ uae_u32 picasso_SetColorArray (void) int g = get_byte (clut + 1); int b = get_byte (clut + 2); - changed |= (picasso96_state.CLUT[i].Red != r - || picasso96_state.CLUT[i].Green != g - || picasso96_state.CLUT[i].Blue != b); - - picasso96_state.CLUT[i].Red = r; + changed |= (picasso96_state.CLUT[i].Red != r || picasso96_state.CLUT[i].Green != g || picasso96_state.CLUT[i].Blue != b); + + picasso96_state.CLUT[i].Red = r; picasso96_state.CLUT[i].Green = g; picasso96_state.CLUT[i].Blue = b; clut += 3; } if (changed) { - DX_SetPalette (start, count); + if (start < first_color_changed) + first_color_changed = start; + if (start + count > last_color_changed) + last_color_changed = start + count; } /*write_log ("SetColorArray(%d,%d)\n", start, count); */ - return m68k_dreg (regs, 0); + return 1; } /* @@ -837,7 +1024,32 @@ uae_u32 picasso_SetDAC (void) * Lets us keep track of what pixel format the Amiga is thinking about in our frame-buffer */ write_log ("SetDAC()\n"); - return m68k_dreg (regs, 0); + return 1; +} + +static void init_picasso_screen (void) +{ + int width = picasso96_state.Width; + int height = picasso96_state.Height; + int vwidth = picasso96_state.VirtualWidth; + int vheight = picasso96_state.VirtualHeight; + int xoff = 0; + int yoff = 0; + + if (!set_gc_called) + return; + + if (set_panning_called) { + picasso96_state.Extent = picasso96_state.Address + (picasso96_state.BytesPerRow * vheight); + xoff = picasso96_state.XOffset; + yoff = picasso96_state.YOffset; + } + + gfx_set_picasso_modeinfo (width, height, picasso96_state.GC_Depth, picasso96_state.RGBFormat); + DX_SetPalette (0, 256); + + wgfx_linestart = 0xFFFFFFFF; + picasso_refresh (); } /* @@ -857,7 +1069,7 @@ uae_u32 picasso_SetGC (void) uaecptr modeinfo = m68k_areg (regs, 1); picasso96_state.Width = get_word (modeinfo + PSSO_ModeInfo_Width); - picasso96_state.VirtualWidth = picasso96_state.Width; /* in case SetPanning doesn't get called */ + picasso96_state.VirtualWidth = picasso96_state.Width; /* in case SetPanning doesn't get called */ picasso96_state.Height = get_word (modeinfo + PSSO_ModeInfo_Height); picasso96_state.VirtualHeight = picasso96_state.Height; @@ -865,14 +1077,11 @@ uae_u32 picasso_SetGC (void) picasso96_state.GC_Depth = get_byte (modeinfo + PSSO_ModeInfo_Depth); picasso96_state.GC_Flags = get_byte (modeinfo + PSSO_ModeInfo_Flags); - write_log ("SetGC(%d,%d,%d)\n", picasso96_state.Width, picasso96_state.Height, picasso96_state.GC_Depth); + P96TRACE (("SetGC(%d,%d,%d)\n", picasso96_state.Width, picasso96_state.Height, picasso96_state.GC_Depth)); - gfx_set_picasso_modeinfo (picasso96_state.Width, picasso96_state.Height, - picasso96_state.GC_Depth, picasso96_state.RGBFormat); - wgfx_linestart = 0xFFFFFFFF; - picasso_refresh (); - - return m68k_dreg (regs, 0); + set_gc_called = 1; /* @@@ when do we need to reset this? */ + init_picasso_screen (); + return 1; } /* @@ -901,36 +1110,44 @@ uae_u32 picasso_SetPanning (void) { uae_u16 Width = m68k_dreg (regs, 0); uaecptr start_of_screen = m68k_areg (regs, 1); + uaecptr bi = m68k_areg (regs, 0); + uaecptr bmeptr = get_long (bi + PSSO_BoardInfo_BitMapExtra); /* Get our BoardInfo ptr's BitMapExtra ptr */ + int oldxoff = picasso96_state.XOffset; + int oldyoff = picasso96_state.YOffset; +#if 0 + /* @@@ This is in WinUAE, but it breaks things. */ + if (oldscr == 0) { + oldscr = start_of_screen; + } + if ((oldscr != start_of_screen)) { + set_gc_called = 0; + oldscr = start_of_screen; + } +#endif - picasso96_state.Address = start_of_screen; /* Amiga-side address */ - picasso96_state.XOffset = (uae_s16)m68k_dreg (regs, 1); - picasso96_state.YOffset = (uae_s16)m68k_dreg (regs, 2); - picasso96_state.VirtualWidth = Width; + picasso96_state.Address = start_of_screen; /* Amiga-side address */ + picasso96_state.XOffset = (uae_s16) m68k_dreg (regs, 1); + picasso96_state.YOffset = (uae_s16) m68k_dreg (regs, 2); + picasso96_state.VirtualWidth = get_word (bmeptr + PSSO_BitMapExtra_Width); + picasso96_state.VirtualHeight = get_word (bmeptr + PSSO_BitMapExtra_Height); picasso96_state.RGBFormat = m68k_dreg (regs, 7); picasso96_state.BytesPerPixel = GetBytesPerPixel (picasso96_state.RGBFormat); picasso96_state.BytesPerRow = Width * picasso96_state.BytesPerPixel; - /* I assume SetGC() has been called, so I can calculate the Extent */ - picasso96_state.Extent = picasso96_state.Address + (picasso96_state.BytesPerRow * picasso96_state.Height); + set_panning_called = 1; + P96TRACE (("SetPanning(%d, %d, %d) Start 0x%x, BPR %d\n", + Width, picasso96_state.XOffset, picasso96_state.YOffset, start_of_screen, picasso96_state.BytesPerRow)); - write_log ("SetPanning(%d, %d, %d) Start 0x%x, BPR %d\n", - Width, picasso96_state.XOffset, picasso96_state.YOffset, - start_of_screen, picasso96_state.BytesPerRow); - gfx_set_picasso_modeinfo (picasso96_state.Width, picasso96_state.Height, - picasso96_state.GC_Depth, picasso96_state.RGBFormat); - DX_SetPalette (0, 256); + init_picasso_screen (); - wgfx_linestart = 0xFFFFFFFF; - picasso_refresh (); - - return m68k_dreg (regs, 0); + return 1; } -static void do_xor8 (uae_u8 *ptr, long len, uae_u32 val) +static void do_xor8 (uae_u8 * ptr, long len, uae_u32 val) { int i; #if 0 && defined ALIGN_POINTER_TO32 - int align_adjust = ALIGN_POINTER_TO32(ptr); + int align_adjust = ALIGN_POINTER_TO32 (ptr); int len2; len -= align_adjust; @@ -942,7 +1159,7 @@ static void do_xor8 (uae_u8 *ptr, long l len2 = len >> 2; len -= len2 << 2; for (i = 0; i < len2; i++, ptr += 4) { - *(uae_u32 *)ptr ^= val; + *(uae_u32 *) ptr ^= val; } while (len) { *ptr ^= val; @@ -958,7 +1175,7 @@ static void do_xor8 (uae_u8 *ptr, long l /* * InvertRect: - * + * * Inputs: * a0:struct BoardInfo *bi * a1:struct RenderInfo *ri @@ -968,36 +1185,37 @@ static void do_xor8 (uae_u8 *ptr, long l * d3.w:Height * d4.l:Mask * d7.l:RGBFormat - * + * * This function is used to invert a rectangular area on the board. It is called by BltBitMap, * BltPattern and BltTemplate. */ uae_u32 picasso_InvertRect (void) { uaecptr renderinfo = m68k_areg (regs, 1); - long X = (uae_u16)m68k_dreg (regs, 0); - long Y = (uae_u16)m68k_dreg (regs, 1); - long Width = (uae_u16)m68k_dreg (regs, 2); - long Height = (uae_u16)m68k_dreg (regs, 3); + unsigned long X = (uae_u16) m68k_dreg (regs, 0); + unsigned long Y = (uae_u16) m68k_dreg (regs, 1); + unsigned long Width = (uae_u16) m68k_dreg (regs, 2); + unsigned long Height = (uae_u16) m68k_dreg (regs, 3); uae_u32 mask = m68k_dreg (regs, 4); int Bpp = GetBytesPerPixel (m68k_dreg (regs, 7)); uae_u32 xorval; - int lines; + unsigned int lines; struct RenderInfo ri; - uae_u8 *uae_mem, *rectstart; - long width_in_bytes; + uae_u8 *uae_mem; + unsigned long width_in_bytes; wgfx_flushline (); - if (! CopyRenderInfoStructureA2U (renderinfo, &ri)) + if (!CopyRenderInfoStructureA2U (renderinfo, &ri)) return 0; - /*write_log ("InvertRect %d %lx\n", Bpp, (long)mask);*/ + P96TRACE (("InvertRect: X %d Y %d Width %d Height %d\n", X, Y, Width, Height)); + /*write_log ("InvertRect %d %lx\n", Bpp, (long)mask); */ /* ??? Brian? mask used to be 32 bit, but it appears that only 8 bit * values are passed to this function. This code here seems to work * much better... */ - if (mask != 0xFF && Bpp > 8) { + if (mask != 0xFF && Bpp > 1) { write_log ("InvertRect: not obeying mask 0x%x properly with Bpp %d.\n", mask, Bpp); mask = 0xFF; } @@ -1006,21 +1224,71 @@ uae_u32 picasso_InvertRect (void) } xorval = 0x01010101 * (mask & 0xFF); width_in_bytes = Bpp * Width; - rectstart = uae_mem = ri.Memory + Y*ri.BytesPerRow + X*Bpp; + uae_mem = ri.Memory + Y * ri.BytesPerRow + X * Bpp; for (lines = 0; lines < Height; lines++, uae_mem += ri.BytesPerRow) do_xor8 (uae_mem, width_in_bytes, xorval); if (renderinfo_is_current_screen (&ri)) { if (mask == 0xFF) - do_invertrect (rectstart, ri.BytesPerRow, X, Y, Width, Height); + do_invertrect (&ri, Bpp, X, Y, Width, Height); else - do_blit (rectstart, ri.BytesPerRow, 0, 0, X, Y, Width, Height, 0); + do_blit (&ri, Bpp, X, Y, X, Y, Width, Height, BLIT_SRC, 0); } - return 1; /* 1 if supported, 0 otherwise */ + return 1; /* 1 if supported, 0 otherwise */ } +/* Fill a rectangle in the Amiga-memory frame buffer. */ + +STATIC_INLINE void do_fillrect_frame_buffer (struct RenderInfo *ri, int X, int Y, + int Width, int Height, uae_u32 Pen, int Bpp, + RGBFTYPE RGBFormat) +{ + uae_u8 *start, *oldstart, *dst; + long lines, cols; + + /* Do our virtual frame-buffer memory. First, we do a single line fill by hand */ + oldstart = start = ri->Memory + Y * ri->BytesPerRow + X * Bpp; + switch (Bpp) { + case 1: + memset (start, Pen, Width); + break; + case 2: + for (cols = 0; cols < Width; cols++) { + do_put_mem_word ((uae_u16 *) start, Pen); + start += 2; + } + break; + case 3: + for (cols = 0; cols < Width; cols++) { + do_put_mem_byte (start, Pen & 0x000000FF); + start++; + *(uae_u16 *) (start) = (Pen & 0x00FFFF00) >> 8; + start += 2; + } + break; + case 4: + for (cols = 0; cols < Width; cols++) { + /**start = Pen; */ + do_put_mem_long ((uae_u32 *) start, Pen); + start += 4; + } + break; + } + + dst = oldstart + ri->BytesPerRow; + /* next, we do the remaining line fills via memcpy() for > 1 BPP, otherwise some more memset() calls */ + if (Bpp > 1) { + for (lines = 0; lines < (Height - 1); lines++, dst += ri->BytesPerRow) + memcpy (dst, oldstart, Width * Bpp); + } else { + for (lines = 0; lines < (Height - 1); lines++, dst += ri->BytesPerRow) + memset (dst, Pen, Width); + } +} + + /*********************************************************** FillRect: *********************************************************** @@ -1037,70 +1305,39 @@ FillRect: uae_u32 picasso_FillRect (void) { uaecptr renderinfo = m68k_areg (regs, 1); - unsigned long X = (uae_u16)m68k_dreg (regs, 0); - unsigned long Y = (uae_u16)m68k_dreg (regs, 1); - unsigned long Width = (uae_u16)m68k_dreg (regs, 2); - unsigned long Height = (uae_u16)m68k_dreg (regs, 3); + unsigned long X = (uae_u16) m68k_dreg (regs, 0); + unsigned long Y = (uae_u16) m68k_dreg (regs, 1); + unsigned long Width = (uae_u16) m68k_dreg (regs, 2); + unsigned long Height = (uae_u16) m68k_dreg (regs, 3); uae_u32 Pen = m68k_dreg (regs, 4); - uae_u8 Mask = (uae_u8)m68k_dreg (regs, 5); + uae_u8 Mask = (uae_u8) m68k_dreg (regs, 5); uae_u32 RGBFormat = m68k_dreg (regs, 7); - uae_u8 *src, *dst; - uae_u8 *start, *oldstart; - unsigned long lines, cols; int Bpp; struct RenderInfo ri; wgfx_flushline (); - if (! CopyRenderInfoStructureA2U (renderinfo, &ri) || Y == 0xFFFF) + if (!CopyRenderInfoStructureA2U (renderinfo, &ri) || Y == 0xFFFF) return 0; + P96TRACE(("FillRect(%d, %d, %d, %d) Pen 0x%x BPP %d BPR %d Mask 0x%x\n", + X, Y, Width, Height, Pen, Bpp, ri.BytesPerRow, Mask)); + if (ri.RGBFormat != RGBFormat) write_log ("Weird Stuff!\n"); Bpp = GetBytesPerPixel (RGBFormat); - /*write_log ("FillRect(%d, %d, %d, %d) Pen 0x%x BPP %d BPR %d Mask 0x%x\n", - X, Y, Width, Height, Pen, Bpp, ri.BytesPerRow, Mask); */ + /* write_log ("FillRect(%d, %d, %d, %d) Pen 0x%x BPP %d BPR %d Mask 0x%x\n", + X, Y, Width, Height, Pen, Bpp, ri.BytesPerRow, Mask); */ if (Mask == 0xFF) { - /* Do our virtual frame-buffer memory. First, we do a single line fill by hand */ - oldstart = start = ri.Memory + Y*ri.BytesPerRow + X*Bpp; - switch (Bpp) { - case 1: - memset (start, Pen, Width); - break; - case 2: - for (cols = 0; cols < Width; cols++) { - do_put_mem_word ((uae_u16 *)start, Pen); - start += 2; - } - break; - case 3: - for (cols = 0; cols < Width; cols++) { - do_put_mem_byte (start, Pen & 0x000000FF); - start++; - *(uae_u16 *)(start) = (Pen & 0x00FFFF00) >> 8; - start+=2; - } - break; - case 4: - for (cols = 0; cols < Width; cols++) { - /**start = Pen; */ - do_put_mem_long ((uae_u32 *)start, Pen); - start += 4; - } - break; - } - src = oldstart; - dst = src + ri.BytesPerRow; - /* next, we do the remaining line fills via memcpy() */ - for (lines = 0; lines < (Height - 1); lines++, dst += ri.BytesPerRow) - memcpy (dst, src, Width * Bpp); + do_fillrect_frame_buffer (&ri, X, Y, Width, Height, Pen, Bpp, RGBFormat); if (renderinfo_is_current_screen (&ri)) - do_fillrect (src, X, Y, Width, Height); + do_fillrect (ri.Memory + Y * ri.BytesPerRow + X * Bpp, X, Y, + Width, Height, Pen, Bpp, RGBFormat); return 1; } @@ -1113,17 +1350,21 @@ uae_u32 picasso_FillRect (void) Pen &= Mask; Mask = ~Mask; - oldstart = start = ri.Memory + Y*ri.BytesPerRow + X*Bpp; - for (lines = 0; lines < Height; lines++, start += ri.BytesPerRow) { - uae_u8 *p = start; - for (cols = 0; cols < Width; cols++) { - uae_u32 tmpval = do_get_mem_byte (p) & Mask; - do_put_mem_byte (p, Pen | tmpval); - p++; + { + uae_u8 *start = ri.Memory + Y * ri.BytesPerRow + X * Bpp; + uae_u8 *end = start + Height * ri.BytesPerRow; + for (; start != end; start += ri.BytesPerRow) { + uae_u8 *p = start; + unsigned long cols; + for (cols = 0; cols < Width; cols++) { + uae_u32 tmpval = do_get_mem_byte (p + cols) & Mask; + do_put_mem_byte (p + cols, Pen | tmpval); + } } } + if (renderinfo_is_current_screen (&ri)) - do_blit (oldstart, ri.BytesPerRow, 0, 0, X, Y, Width, Height, 0); + do_blit (&ri, Bpp, X, Y, X, Y, Width, Height, BLIT_SRC, 0); return 1; } @@ -1133,12 +1374,12 @@ uae_u32 picasso_FillRect (void) * NOTE: If dstri is NULL, then we're only dealing with one RenderInfo area, and called from picasso_BlitRect() */ static void BlitRect (struct RenderInfo *ri, struct RenderInfo *dstri, - uae_u16 srcx, uae_u16 srcy, uae_u16 dstx, uae_u16 dsty, - uae_u16 width, uae_u16 height, uae_u8 mask) + unsigned long srcx, unsigned long srcy, unsigned long dstx, unsigned long dsty, + unsigned long width, unsigned long height, uae_u8 mask, BLIT_OPCODE opcode) { uae_u8 *src, *dst, *tmp, *tmp2, *tmp3; - int lines; - uae_u8 Bpp = GetBytesPerPixel(ri->RGBFormat); + unsigned long lines; + uae_u8 Bpp = GetBytesPerPixel (ri->RGBFormat); uae_u8 *blitsrc; unsigned long total_width = width * Bpp; unsigned long linewidth = (total_width + 15) & ~15; @@ -1158,8 +1399,8 @@ static void BlitRect (struct RenderInfo } /* Do our virtual frame-buffer memory first */ - src = ri->Memory + srcx*Bpp + srcy*ri->BytesPerRow; - dst = dstri->Memory + dstx*Bpp + dsty*dstri->BytesPerRow; + src = ri->Memory + srcx * Bpp + srcy * ri->BytesPerRow; + dst = dstri->Memory + dstx * Bpp + dsty * dstri->BytesPerRow; blitsrc = dst; if (mask != 0xFF && Bpp > 1) write_log ("ERROR - not obeying BlitRect() mask 0x%x properly with Bpp %d.\n", mask, Bpp); @@ -1167,27 +1408,28 @@ static void BlitRect (struct RenderInfo if (mask == 0xFF || Bpp > 1) { /* handle normal case efficiently */ if (ri->Memory == dstri->Memory && dsty == srcy) { - int i; + unsigned long i; for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow) memmove (dst, src, total_width); } else if (dsty < srcy) { - int i; + unsigned long i; for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow) memcpy (dst, src, total_width); } else { - int i; - src += (height-1) * ri->BytesPerRow; - dst += (height-1) * dstri->BytesPerRow; + unsigned long i; + src += (height - 1) * ri->BytesPerRow; + dst += (height - 1) * dstri->BytesPerRow; for (i = 0; i < height; i++, src -= ri->BytesPerRow, dst -= dstri->BytesPerRow) memcpy (dst, src, total_width); } + if (cant_blit) + srcx = dstx, srcy = dsty; if (renderinfo_is_current_screen (dstri)) - do_blit (blitsrc, dstri->BytesPerRow, srcx, srcy, dstx, dsty, - width, height, ! cant_blit); + do_blit (dstri, Bpp, srcx, srcy, dstx, dsty, width, height, opcode, !cant_blit); return; } - tmp3 = tmp2 = tmp = xmalloc (linewidth * height); /* allocate enough memory for the src-rect */ + tmp3 = tmp2 = tmp = xmalloc (linewidth * height); /* allocate enough memory for the src-rect */ if (!tmp) return; @@ -1198,15 +1440,15 @@ static void BlitRect (struct RenderInfo /* copy the temporary buffer to the destination */ for (lines = 0; lines < height; lines++, dst += dstri->BytesPerRow, tmp += linewidth) { - int cols; + unsigned long cols; for (cols = 0; cols < width; cols++) { dst[cols] &= ~mask; dst[cols] |= tmp[cols] & mask; } } if (renderinfo_is_current_screen (dstri)) - do_blit (blitsrc, dstri->BytesPerRow, srcx, srcy, dstx, dsty, - width, height, 0); + do_blit (dstri, Bpp, dstx, dsty, dstx, dsty, width, height, opcode, 0); + /* free the temp-buf */ free (tmp3); @@ -1229,22 +1471,23 @@ BlitRect: uae_u32 picasso_BlitRect (void) { uaecptr renderinfo = m68k_areg (regs, 1); - uae_u16 srcx = (uae_u16)m68k_dreg (regs, 0); - uae_u16 srcy = (uae_u16)m68k_dreg (regs, 1); - uae_u16 dstx = (uae_u16)m68k_dreg (regs, 2); - uae_u16 dsty = (uae_u16)m68k_dreg (regs, 3); - uae_u16 width = (uae_u16)m68k_dreg (regs, 4); - uae_u16 height = (uae_u16)m68k_dreg (regs, 5); - uae_u8 Mask = (uae_u8)m68k_dreg (regs, 6); + unsigned long srcx = (uae_u16) m68k_dreg (regs, 0); + unsigned long srcy = (uae_u16) m68k_dreg (regs, 1); + unsigned long dstx = (uae_u16) m68k_dreg (regs, 2); + unsigned long dsty = (uae_u16) m68k_dreg (regs, 3); + unsigned long width = (uae_u16) m68k_dreg (regs, 4); + unsigned long height = (uae_u16) m68k_dreg (regs, 5); + uae_u8 Mask = (uae_u8) m68k_dreg (regs, 6); struct RenderInfo ri; wgfx_flushline (); - if (! CopyRenderInfoStructureA2U (renderinfo, &ri)) + if (!CopyRenderInfoStructureA2U (renderinfo, &ri)) return 0; - BlitRect(&ri, NULL, srcx, srcy, dstx, dsty, width, height, Mask); + P96TRACE(("BlitRect(%d, %d, %d, %d, %d, %d, 0x%x)\n", srcx, srcy, dstx, dsty, width, height, Mask)); + BlitRect (&ri, NULL, srcx, srcy, dstx, dsty, width, height, Mask, BLIT_SRC); /*write_log ("BlitRect(%d, %d, %d, %d, %d, %d, 0x%x)\n", srcx, srcy, dstx, dsty, width, height, Mask); */ return 1; @@ -1272,63 +1515,61 @@ uae_u32 picasso_BlitRectNoMaskComplete ( { uaecptr srcri = m68k_areg (regs, 1); uaecptr dstri = m68k_areg (regs, 2); - uae_u16 srcx = m68k_dreg (regs, 0); - uae_u16 srcy = m68k_dreg (regs, 1); - uae_u16 dstx = m68k_dreg (regs, 2); - uae_u16 dsty = m68k_dreg (regs, 3); - uae_u16 width = m68k_dreg (regs, 4); - uae_u16 height = m68k_dreg (regs, 5); + unsigned long srcx = (uae_u16) m68k_dreg (regs, 0); + unsigned long srcy = (uae_u16) m68k_dreg (regs, 1); + unsigned long dstx = (uae_u16) m68k_dreg (regs, 2); + unsigned long dsty = (uae_u16) m68k_dreg (regs, 3); + unsigned long width = (uae_u16) m68k_dreg (regs, 4); + unsigned long height = (uae_u16) m68k_dreg (regs, 5); uae_u8 OpCode = m68k_dreg (regs, 6); uae_u32 RGBFmt = m68k_dreg (regs, 7); struct RenderInfo src_ri, dst_ri; wgfx_flushline (); - if (! CopyRenderInfoStructureA2U (srcri, &src_ri) - || ! CopyRenderInfoStructureA2U (dstri, &dst_ri)) + if (!CopyRenderInfoStructureA2U (srcri, &src_ri) + || !CopyRenderInfoStructureA2U (dstri, &dst_ri)) return 0; - /*write_log ("BlitRectNoMaskComplete() op 0x%2x, Bpp %d, xy(%4d,%4d) --> xy(%4d,%4d), wh(%4d,%4d)\n", - OpCode, Bpp, srcx, srcy, dstx, dsty, width, height); */ - /*write_log ("-- src mem 0x%x BPR %d, dst mem 0x%x BPR %d, screen-mem 0x%x - 0x%x\n", - src_ri.Memory, src_ri.BytesPerRow, dst_ri.Memory, dst_ri.BytesPerRow, picasso96_state.Address, picasso96_state.Extent); */ + P96TRACE(("BlitRectNoMaskComplete() op 0x%2x, xy(%4d,%4d) --> xy(%4d,%4d), wh(%4d,%4d)\n", + OpCode, srcx, srcy, dstx, dsty, width, height)); switch (OpCode) { - case 0x0C: - BlitRect (&src_ri, &dst_ri, srcx, srcy, dstx, dsty, width, height, 0xFF); + case 0x0C: + BlitRect (&src_ri, &dst_ri, srcx, srcy, dstx, dsty, width, height, 0xFF, OpCode); return 1; - default: + default: /* FOR NOW! */ return 0; } } /* This utility function is used both by BlitTemplate() and BlitPattern() */ -static __inline__ void PixelWrite1(uae_u8 *mem, int bits, uae_u32 fgpen, uae_u32 mask) +STATIC_INLINE void PixelWrite1 (uae_u8 * mem, int bits, uae_u32 fgpen, uae_u32 mask) { if (mask != 0xFF) fgpen = (fgpen & mask) | (do_get_mem_byte (mem + bits) & ~mask); do_put_mem_byte (mem + bits, fgpen); } -static __inline__ void PixelWrite2(uae_u8 *mem, int bits, uae_u32 fgpen) +STATIC_INLINE void PixelWrite2 (uae_u8 * mem, int bits, uae_u32 fgpen) { - do_put_mem_word (((uae_u16 *)mem) + bits, fgpen); + do_put_mem_word (((uae_u16 *) mem) + bits, fgpen); } -static __inline__ void PixelWrite3(uae_u8 *mem, int bits, uae_u32 fgpen) +STATIC_INLINE void PixelWrite3 (uae_u8 * mem, int bits, uae_u32 fgpen) { - do_put_mem_byte (mem + bits*3, fgpen & 0x000000FF); - *(uae_u16 *)(mem + bits*3+1) = (fgpen & 0x00FFFF00) >> 8; + do_put_mem_byte (mem + bits * 3, fgpen & 0x000000FF); + *(uae_u16 *) (mem + bits * 3 + 1) = (fgpen & 0x00FFFF00) >> 8; } -static __inline__ void PixelWrite4(uae_u8 *mem, int bits, uae_u32 fgpen) +STATIC_INLINE void PixelWrite4 (uae_u8 * mem, int bits, uae_u32 fgpen) { - do_put_mem_long (((uae_u32 *)mem) + bits, fgpen); + do_put_mem_long (((uae_u32 *) mem) + bits, fgpen); } -static __inline__ void PixelWrite(uae_u8 *mem, int bits, uae_u32 fgpen, uae_u8 Bpp, uae_u32 mask) +STATIC_INLINE void PixelWrite (uae_u8 * mem, int bits, uae_u32 fgpen, uae_u8 Bpp, uae_u32 mask) { switch (Bpp) { case 1: @@ -1337,21 +1578,21 @@ static __inline__ void PixelWrite(uae_u8 do_put_mem_byte (mem + bits, fgpen); break; case 2: - do_put_mem_word (((uae_u16 *)mem) + bits, fgpen); + do_put_mem_word (((uae_u16 *) mem) + bits, fgpen); break; case 3: - do_put_mem_byte (mem + bits*3, fgpen & 0x000000FF); - *(uae_u16 *)(mem + bits*3+1) = (fgpen & 0x00FFFF00) >> 8; + do_put_mem_byte (mem + bits * 3, fgpen & 0x000000FF); + *(uae_u16 *) (mem + bits * 3 + 1) = (fgpen & 0x00FFFF00) >> 8; break; case 4: - do_put_mem_long (((uae_u32 *)mem) + bits, fgpen); + do_put_mem_long (((uae_u32 *) mem) + bits, fgpen); break; } } /* * BlitPattern: - * + * * Synopsis:BlitPattern(bi, ri, pattern, X, Y, Width, Height, Mask, RGBFormat); * Inputs: * a0:struct BoardInfo *bi @@ -1363,7 +1604,7 @@ static __inline__ void PixelWrite(uae_u8 * d3.w:Height * d4.w:Mask * d7.l:RGBFormat - * + * * This function is used to paint a pattern on the board memory using the blitter. It is called by * BltPattern, if a AreaPtrn is used with positive AreaPtSz. The pattern consists of a b/w image * using a single plane of image data which will be expanded repeatedly to the destination RGBFormat @@ -1375,31 +1616,31 @@ uae_u32 picasso_BlitPattern (void) { uaecptr rinf = m68k_areg (regs, 1); uaecptr pinf = m68k_areg (regs, 2); - long X = (uae_u16)m68k_dreg (regs, 0); - long Y = (uae_u16)m68k_dreg (regs, 1); - long W = (uae_u16)m68k_dreg (regs, 2); - long H = (uae_u16)m68k_dreg (regs, 3); - uae_u8 Mask = (uae_u8)m68k_dreg (regs, 4); + unsigned long X = (uae_u16) m68k_dreg (regs, 0); + unsigned long Y = (uae_u16) m68k_dreg (regs, 1); + unsigned long W = (uae_u16) m68k_dreg (regs, 2); + unsigned long H = (uae_u16) m68k_dreg (regs, 3); + uae_u8 Mask = (uae_u8) m68k_dreg (regs, 4); uae_u32 RGBFmt = m68k_dreg (regs, 7); - uae_u8 Bpp = GetBytesPerPixel(RGBFmt); + uae_u8 Bpp = GetBytesPerPixel (RGBFmt); int inversion = 0; struct RenderInfo ri; struct Pattern pattern; - uae_u16 rows; + unsigned long rows; uae_u32 fgpen; - uae_u8 *uae_mem, *frame_buffer_UAM; + uae_u8 *uae_mem; int xshift; unsigned long ysize_mask; wgfx_flushline (); if (! CopyRenderInfoStructureA2U (rinf, &ri) - || ! CopyPatternStructureA2U (pinf, &pattern)) + || !CopyPatternStructureA2U (pinf, &pattern)) return 0; - Bpp = GetBytesPerPixel(ri.RGBFormat); - uae_mem = ri.Memory + Y*ri.BytesPerRow + X*Bpp; /* offset with address */ + Bpp = GetBytesPerPixel (ri.RGBFormat); + uae_mem = ri.Memory + Y * ri.BytesPerRow + X * Bpp; /* offset with address */ if (pattern.DrawMode & INVERS) inversion = 1; @@ -1414,19 +1655,19 @@ uae_u32 picasso_BlitPattern (void) } } - /* write_log ("BlitPattern() xy(%d,%d), wh(%d,%d) draw 0x%x, off(%d,%d), ph %d\n", - X, Y, W, H, pattern.DrawMode, pattern.XOffset, pattern.YOffset, 1 << pattern.Size); */ + P96TRACE (("BlitPattern() xy(%d,%d), wh(%d,%d) draw 0x%x, off(%d,%d), ph %d\n", + X, Y, W, H, pattern.DrawMode, pattern.XOffset, pattern.YOffset, 1 << pattern.Size)); #ifdef _DEBUG - DumpPattern(&pattern); + DumpPattern (&pattern); #endif ysize_mask = (1 << pattern.Size) - 1; xshift = pattern.XOffset & 15; for (rows = 0; rows < H; rows++, uae_mem += ri.BytesPerRow) { - int prow = (rows + pattern.YOffset) & ysize_mask; - unsigned int d = do_get_mem_word (((uae_u16 *)pattern.Memory) + prow); + unsigned long prow = (rows + pattern.YOffset) & ysize_mask; + unsigned int d = do_get_mem_word (((uae_u16 *) pattern.Memory) + prow); uae_u8 *uae_mem2 = uae_mem; - long cols; + unsigned long cols; if (xshift != 0) d = (d << xshift) | (d >> (16 - xshift)); @@ -1438,18 +1679,18 @@ uae_u32 picasso_BlitPattern (void) if (max > 16) max = 16; - + for (bits = 0; bits < max; bits++) { int bit_set = data & 0x8000; data <<= 1; switch (pattern.DrawMode) { - case JAM1: + case JAM1: if (inversion) bit_set = !bit_set; if (bit_set) PixelWrite (uae_mem2, bits, pattern.FgPen, Bpp, Mask); break; - case JAM2: + case JAM2: if (inversion) bit_set = !bit_set; if (bit_set) @@ -1457,32 +1698,32 @@ uae_u32 picasso_BlitPattern (void) else PixelWrite (uae_mem2, bits, pattern.BgPen, Bpp, Mask); break; - case COMP: + case COMP: if (bit_set) { fgpen = pattern.FgPen; switch (Bpp) { - case 1: + case 1: { uae_u8 *addr = uae_mem2 + bits; do_put_mem_byte (addr, do_get_mem_byte (addr) ^ fgpen); } break; - case 2: + case 2: { - uae_u16 *addr = ((uae_u16 *)uae_mem2) + bits; + uae_u16 *addr = ((uae_u16 *) uae_mem2) + bits; do_put_mem_word (addr, do_get_mem_word (addr) ^ fgpen); } break; - case 3: + case 3: { - uae_u32 *addr = (uae_u32 *)(uae_mem2 + bits * 3); + uae_u32 *addr = (uae_u32 *) (uae_mem2 + bits * 3); do_put_mem_long (addr, do_get_mem_long (addr) ^ (fgpen & 0x00FFFFFF)); } break; - case 4: + case 4: { - uae_u32 *addr = ((uae_u32 *)uae_mem2) + bits; + uae_u32 *addr = ((uae_u32 *) uae_mem2) + bits; do_put_mem_long (addr, do_get_mem_long (addr) ^ fgpen); } break; @@ -1494,9 +1735,8 @@ uae_u32 picasso_BlitPattern (void) } } - frame_buffer_UAM = ri.Memory + X*picasso96_state.BytesPerPixel + Y*ri.BytesPerRow; if (renderinfo_is_current_screen (&ri)) - do_blit (frame_buffer_UAM, ri.BytesPerRow, 0, 0, X, Y, W, H, 0); + do_blit (&ri, Bpp, X, Y, X, Y, W, H, BLIT_SRC, 0); return 1; } @@ -1525,27 +1765,27 @@ uae_u32 picasso_BlitTemplate (void) uae_u8 inversion = 0; uaecptr rinf = m68k_areg (regs, 1); uaecptr tmpl = m68k_areg (regs, 2); - uae_u16 X = m68k_dreg (regs, 0); - uae_u16 Y = m68k_dreg (regs, 1); - uae_u16 W = m68k_dreg (regs, 2); - uae_u16 H = m68k_dreg (regs, 3); - uae_u16 Mask = m68k_dreg (regs, 4); + unsigned long X = (uae_u16) m68k_dreg (regs, 0); + unsigned long Y = (uae_u16) m68k_dreg (regs, 1); + unsigned long W = (uae_u16) m68k_dreg (regs, 2); + unsigned long H = (uae_u16) m68k_dreg (regs, 3); + uae_u16 Mask = (uae_u16) m68k_dreg (regs, 4); struct Template tmp; struct RenderInfo ri; - long rows; + unsigned long rows; int bitoffset; uae_u32 fgpen; - uae_u8 *uae_mem, Bpp, *frame_buffer_UAM; + uae_u8 *uae_mem, Bpp; uae_u8 *tmpl_base; wgfx_flushline (); - if (! CopyRenderInfoStructureA2U (rinf, &ri) - || ! CopyTemplateStructureA2U (tmpl, &tmp)) + if (!CopyRenderInfoStructureA2U (rinf, &ri) + || !CopyTemplateStructureA2U (tmpl, &tmp)) return 0; - Bpp = GetBytesPerPixel(ri.RGBFormat); - uae_mem = ri.Memory + Y*ri.BytesPerRow + X*Bpp; /* offset into address */ + Bpp = GetBytesPerPixel (ri.RGBFormat); + uae_mem = ri.Memory + Y * ri.BytesPerRow + X * Bpp; /* offset into address */ if (tmp.DrawMode & INVERS) inversion = 1; @@ -1560,19 +1800,19 @@ uae_u32 picasso_BlitTemplate (void) } } - /*write_log ("BlitTemplate() xy(%d,%d), wh(%d,%d) draw 0x%x fg 0x%x bg 0x%x \n", - X, Y, W, H, tmp.DrawMode, tmp.FgPen, tmp.BgPen); */ + P96TRACE (("BlitTemplate() xy(%d,%d), wh(%d,%d) draw 0x%x fg 0x%x bg 0x%x \n", + X, Y, W, H, tmp.DrawMode, tmp.FgPen, tmp.BgPen)); bitoffset = tmp.XOffset % 8; #ifdef _DEBUG - DumpTemplate(&tmp, W, H); + DumpTemplate (&tmp, W, H); #endif - tmpl_base = tmp.Memory + tmp.XOffset/8; + tmpl_base = tmp.Memory + tmp.XOffset / 8; for (rows = 0; rows < H; rows++, uae_mem += ri.BytesPerRow, tmpl_base += tmp.BytesPerRow) { - long cols; + unsigned long cols; uae_u8 *tmpl_mem = tmpl_base; uae_u8 *uae_mem2 = uae_mem; unsigned int data = *tmpl_mem; @@ -1594,49 +1834,49 @@ uae_u32 picasso_BlitTemplate (void) int bit_set = (byte & 0x80); byte <<= 1; switch (tmp.DrawMode) { - case JAM1: + case JAM1: if (inversion) bit_set = !bit_set; if (bit_set) { fgpen = tmp.FgPen; - PixelWrite(uae_mem2, bits, fgpen, Bpp, Mask); + PixelWrite (uae_mem2, bits, fgpen, Bpp, Mask); } break; - case JAM2: + case JAM2: if (inversion) bit_set = !bit_set; fgpen = tmp.BgPen; if (bit_set) fgpen = tmp.FgPen; - PixelWrite(uae_mem2, bits, fgpen, Bpp, Mask); + PixelWrite (uae_mem2, bits, fgpen, Bpp, Mask); break; - case COMP: + case COMP: if (bit_set) { fgpen = tmp.FgPen; switch (Bpp) { - case 1: + case 1: { uae_u8 *addr = uae_mem2 + bits; do_put_mem_byte (addr, do_get_mem_byte (addr) ^ fgpen); } break; - case 2: + case 2: { - uae_u16 *addr = ((uae_u16 *)uae_mem2) + bits; + uae_u16 *addr = ((uae_u16 *) uae_mem2) + bits; do_put_mem_word (addr, do_get_mem_word (addr) ^ fgpen); } break; - case 3: + case 3: { - uae_u32 *addr = (uae_u32 *)(uae_mem2 + bits * 3); + uae_u32 *addr = (uae_u32 *) (uae_mem2 + bits * 3); do_put_mem_long (addr, do_get_mem_long (addr) ^ (fgpen & 0x00FFFFFF)); } break; - case 4: + case 4: { - uae_u32 *addr = ((uae_u32 *)uae_mem2) + bits; + uae_u32 *addr = ((uae_u32 *) uae_mem2) + bits; do_put_mem_long (addr, do_get_mem_long (addr) ^ fgpen); } break; @@ -1648,9 +1888,8 @@ uae_u32 picasso_BlitTemplate (void) } } - frame_buffer_UAM = ri.Memory + X*picasso96_state.BytesPerPixel + Y*ri.BytesPerRow; if (renderinfo_is_current_screen (&ri)) - do_blit (frame_buffer_UAM, ri.BytesPerRow, 0, 0, X, Y, W, H, 0); + do_blit (&ri, Bpp, X, Y, X, Y, W, H, BLIT_SRC, 0); return 1; } @@ -1668,8 +1907,8 @@ uae_u32 picasso_CalculateBytesPerRow (vo uae_u16 width = m68k_dreg (regs, 0); uae_u32 type = m68k_dreg (regs, 7); - width = GetBytesPerPixel(type)*width; - /*write_log ("CalculateBytesPerRow() = %d\n",width); */ + width = GetBytesPerPixel (type) * width; + P96TRACE (("CalculateBytesPerRow() = %d\n", width)); return width; } @@ -1679,13 +1918,13 @@ uae_u32 picasso_CalculateBytesPerRow (vo * a0: struct BoardInfo * d0: BOOL state * This function enables and disables the video display. - * + * * NOTE: return the opposite of the state */ uae_u32 picasso_SetDisplay (void) { uae_u32 state = m68k_dreg (regs, 0); - write_log ("SetDisplay(%d)\n", state); + P96TRACE (("SetDisplay(%d)\n", state)); return !state; } @@ -1696,36 +1935,37 @@ uae_u32 picasso_SetDisplay (void) */ uae_u32 picasso_WaitVerticalSync (void) { - /*write_log ("WaitVerticalSync()\n");*/ + /*write_log ("WaitVerticalSync()\n"); */ return 1; } /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ -static void PlanarToChunky(struct RenderInfo *ri, struct BitMap *bm, long srcx, long srcy, - long dstx, long dsty, long width, long height, uae_u8 mask) +static void PlanarToChunky (struct RenderInfo *ri, struct BitMap *bm, + unsigned long srcx, unsigned long srcy, + unsigned long dstx, unsigned long dsty, unsigned long width, unsigned long height, uae_u8 mask) { int j; - uae_u8 *PLANAR[8], *image = ri->Memory + dstx * GetBytesPerPixel (ri->RGBFormat) + dsty*ri->BytesPerRow; + uae_u8 *PLANAR[8], *image = ri->Memory + dstx * GetBytesPerPixel (ri->RGBFormat) + dsty * ri->BytesPerRow; int Depth = bm->Depth; - uae_u16 rows, bitoffset = srcx & 7; + unsigned long rows, bitoffset = srcx & 7; long eol_offset; - /* if (mask != 0xFF) - write_log ("P2C - pixel-width = %d, bit-offset = %d\n", width, bitoffset); */ - + /* if (mask != 0xFF) + write_log ("P2C - pixel-width = %d, bit-offset = %d\n", width, bitoffset); */ + /* Set up our bm->Planes[] pointers to the right horizontal offset */ for (j = 0; j < Depth; j++) { uae_u8 *p = bm->Planes[j]; if (p != &all_zeros_bitmap && p != &all_ones_bitmap) - p += srcx/8 + srcy*bm->BytesPerRow; + p += srcx / 8 + srcy * bm->BytesPerRow; PLANAR[j] = p; if ((mask & (1 << j)) == 0) PLANAR[j] = &all_zeros_bitmap; } - eol_offset = (long)bm->BytesPerRow - ((width + 7) >> 3); + eol_offset = (long) bm->BytesPerRow - (long) ((width + 7) >> 3); for (rows = 0; rows < height; rows++, image += ri->BytesPerRow) { - long cols; + unsigned long cols; for (cols = 0; cols < width; cols += 8) { int k; @@ -1734,11 +1974,11 @@ static void PlanarToChunky(struct Render long tmp = cols + 8 - width; if (tmp > 0) { msk <<= tmp; - b = do_get_mem_long ((uae_u32 *)(image + cols + 4)); + b = do_get_mem_long ((uae_u32 *) (image + cols + 4)); if (tmp < 4) b &= 0xFFFFFFFF >> (32 - tmp * 8); else if (tmp > 4) { - a = do_get_mem_long ((uae_u32 *)(image + cols)); + a = do_get_mem_long ((uae_u32 *) (image + cols)); a &= 0xFFFFFFFF >> (64 - tmp * 8); } } @@ -1749,15 +1989,15 @@ static void PlanarToChunky(struct Render else if (PLANAR[k] == &all_ones_bitmap) data = 0xFF; else { - data = (uae_u8)(do_get_mem_word ((uae_u16 *)PLANAR[k]) >> (8 - bitoffset)); + data = (uae_u8) (do_get_mem_word ((uae_u16 *) PLANAR[k]) >> (8 - bitoffset)); PLANAR[k]++; } data &= msk; a |= p2ctab[data][0] << k; b |= p2ctab[data][1] << k; } - do_put_mem_long ((uae_u32 *)(image + cols), a); - do_put_mem_long ((uae_u32 *)(image + cols + 4), b); + do_put_mem_long ((uae_u32 *) (image + cols), a); + do_put_mem_long ((uae_u32 *) (image + cols + 4), b); } for (j = 0; j < Depth; j++) { if (PLANAR[j] != &all_zeros_bitmap && PLANAR[j] != &all_ones_bitmap) { @@ -1789,12 +2029,12 @@ uae_u32 picasso_BlitPlanar2Chunky (void) { uaecptr bm = m68k_areg (regs, 1); uaecptr ri = m68k_areg (regs, 2); - uae_u16 srcx = m68k_dreg (regs, 0) & 0xFFFF; - uae_u16 srcy = m68k_dreg (regs, 1) & 0xFFFF; - uae_u16 dstx = m68k_dreg (regs, 2) & 0xFFFF; - uae_u16 dsty = m68k_dreg (regs, 3) & 0xFFFF; - uae_u16 width = m68k_dreg (regs, 4) & 0xFFFF; - uae_u16 height = m68k_dreg (regs, 5) & 0xFFFF; + unsigned long srcx = (uae_u16) m68k_dreg (regs, 0); + unsigned long srcy = (uae_u16) m68k_dreg (regs, 1); + unsigned long dstx = (uae_u16) m68k_dreg (regs, 2); + unsigned long dsty = (uae_u16) m68k_dreg (regs, 3); + unsigned long width = (uae_u16) m68k_dreg (regs, 4); + unsigned long height = (uae_u16) m68k_dreg (regs, 5); uae_u8 minterm = m68k_dreg (regs, 6) & 0xFF; uae_u8 mask = m68k_dreg (regs, 7) & 0xFF; struct RenderInfo local_ri; @@ -1803,58 +2043,54 @@ uae_u32 picasso_BlitPlanar2Chunky (void) wgfx_flushline (); if (minterm != 0x0C) { - write_log ("ERROR - BlitPlanar2Chunky() has minterm 0x%x, which I don't handle. Using fall-back routine.\n", - minterm); + write_log ("ERROR - BlitPlanar2Chunky() has minterm 0x%x, which I don't handle. Using fall-back routine.\n", minterm); return 0; } - if (! CopyRenderInfoStructureA2U (ri, &local_ri) - || ! CopyBitMapStructureA2U (bm, &local_bm)) + if (!CopyRenderInfoStructureA2U (ri, &local_ri) + || !CopyBitMapStructureA2U (bm, &local_bm)) return 0; - /*write_log ("BlitPlanar2Chunky(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n", - srcx, srcy, dstx, dsty, width, height, minterm, mask, local_bm.Depth); - write_log ("P2C - BitMap has %d BPR, %d rows\n", local_bm.BytesPerRow, local_bm.Rows); */ + P96TRACE (("BlitPlanar2Chunky(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n", + srcx, srcy, dstx, dsty, width, height, minterm, mask, local_bm.Depth)); + P96TRACE (("P2C - BitMap has %d BPR, %d rows\n", local_bm.BytesPerRow, local_bm.Rows)); PlanarToChunky (&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, mask); if (renderinfo_is_current_screen (&local_ri)) - do_blit (local_ri.Memory + dstx * GetBytesPerPixel (local_ri.RGBFormat) + dsty * local_ri.BytesPerRow, - local_ri.BytesPerRow, - 0, 0, dstx, dsty, width, height, 0); + do_blit (&local_ri, GetBytesPerPixel (local_ri.RGBFormat), dstx, dsty, dstx, dsty, width, height, BLIT_SRC, 0); - return m68k_dreg (regs, 0); + return 1; } -/* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ -static void PlanarToDirect(struct RenderInfo *ri, struct BitMap *bm, - long srcx, long srcy, long dstx, long dsty, - long width, long height, uae_u8 mask, - struct ColorIndexMapping *cim) +static void PlanarToDirect (struct RenderInfo *ri, struct BitMap *bm, + unsigned long srcx, unsigned long srcy, + unsigned long dstx, unsigned long dsty, + unsigned long width, unsigned long height, uae_u8 mask, struct ColorIndexMapping *cim) { int j; - int bpp = GetBytesPerPixel(ri->RGBFormat); + int bpp = GetBytesPerPixel (ri->RGBFormat); uae_u8 *PLANAR[8]; uae_u8 *image = ri->Memory + dstx * bpp + dsty * ri->BytesPerRow; int Depth = bm->Depth; - long rows; + unsigned long rows; long eol_offset; /* Set up our bm->Planes[] pointers to the right horizontal offset */ for (j = 0; j < Depth; j++) { uae_u8 *p = bm->Planes[j]; if (p != &all_zeros_bitmap && p != &all_ones_bitmap) - p += srcx/8 + srcy*bm->BytesPerRow; + p += srcx / 8 + srcy * bm->BytesPerRow; PLANAR[j] = p; if ((mask & (1 << j)) == 0) PLANAR[j] = &all_zeros_bitmap; } - eol_offset = (long)bm->BytesPerRow - ((width + (srcx & 7)) >> 3); + eol_offset = (long) bm->BytesPerRow - (long) ((width + (srcx & 7)) >> 3); for (rows = 0; rows < height; rows++, image += ri->BytesPerRow) { - long cols; + unsigned long cols; uae_u8 *image2 = image; unsigned int bitoffs = 7 - (srcx & 7); int i; - for (cols = 0; cols < width; cols ++) { + for (cols = 0; cols < width; cols++) { int v = 0, k; for (k = 0; k < Depth; k++) { if (PLANAR[k] == &all_ones_bitmap) @@ -1865,17 +2101,17 @@ static void PlanarToDirect(struct Render } switch (bpp) { - case 2: - do_put_mem_word ((uae_u16 *)image2, cim->Colors[v]); + case 2: + do_put_mem_word ((uae_u16 *) image2, cim->Colors[v]); image2 += 2; break; - case 3: + case 3: do_put_mem_byte (image2++, cim->Colors[v] & 0x000000FF); - do_put_mem_word ((uae_u16 *)image2, (cim->Colors[v] & 0x00FFFF00) >> 8); + do_put_mem_word ((uae_u16 *) image2, (cim->Colors[v] & 0x00FFFF00) >> 8); image2 += 2; break; - case 4: - do_put_mem_long ((uae_u32 *)image2, cim->Colors[v]); + case 4: + do_put_mem_long ((uae_u32 *) image2, cim->Colors[v]); image2 += 4; break; } @@ -1900,8 +2136,8 @@ static void PlanarToDirect(struct Render } /* - * BlitPlanar2Direct: - * + * BlitPlanar2Direct: + * * Synopsis: * BlitPlanar2Direct(bi, bm, ri, cim, SrcX, SrcY, DstX, DstY, SizeX, SizeY, MinTerm, Mask); * Inputs: @@ -1917,26 +2153,26 @@ static void PlanarToDirect(struct Render * d5.w:SizeY * d6.b:MinTerm * d7.b:Mask - * + * * This function is currently used to blit from planar bitmaps within system memory to direct color * bitmaps (15, 16, 24 or 32 bit) on the board. Watch out for plane pointers that are 0x00000000 (represents * a plane with all bits "0") or 0xffffffff (represents a plane with all bits "1"). The ColorIndexMapping is * used to map the color index of each pixel formed by the bits in the bitmap's planes to a direct color value * which is written to the destination RenderInfo. The color mask and all colors within the mapping are words, * triple bytes or longwords respectively similar to the color values used in FillRect(), BlitPattern() or - * BlitTemplate(). + * BlitTemplate(). */ uae_u32 picasso_BlitPlanar2Direct (void) { uaecptr bm = m68k_areg (regs, 1); uaecptr ri = m68k_areg (regs, 2); uaecptr cim = m68k_areg (regs, 3); - uae_u16 srcx = m68k_dreg (regs, 0); - uae_u16 srcy = m68k_dreg (regs, 1); - uae_u16 dstx = m68k_dreg (regs, 2); - uae_u16 dsty = m68k_dreg (regs, 3); - uae_u16 width = m68k_dreg (regs, 4); - uae_u16 height = m68k_dreg (regs, 5); + unsigned long srcx = (uae_u16) m68k_dreg (regs, 0); + unsigned long srcy = (uae_u16) m68k_dreg (regs, 1); + unsigned long dstx = (uae_u16) m68k_dreg (regs, 2); + unsigned long dsty = (uae_u16) m68k_dreg (regs, 3); + unsigned long width = (uae_u16) m68k_dreg (regs, 4); + unsigned long height = (uae_u16) m68k_dreg (regs, 5); uae_u8 minterm = m68k_dreg (regs, 6); uae_u8 Mask = m68k_dreg (regs, 7); struct RenderInfo local_ri; @@ -1946,26 +2182,23 @@ uae_u32 picasso_BlitPlanar2Direct (void) wgfx_flushline (); if (minterm != 0x0C) { - write_log ("ERROR - BlitPlanar2Direct() has op-code 0x%x, which I don't handle. Using fall-back routine.\n", - minterm); + write_log ("ERROR - BlitPlanar2Direct() has op-code 0x%x, which I don't handle. Using fall-back routine.\n", minterm); return 0; } if (Mask != 0xFF) { write_log ("ERROR - Unsupported Mask value 0x%x in BlitPlanar2Direct(), using fallback method.\n", Mask); return 0; } - if (! CopyRenderInfoStructureA2U (ri, &local_ri) - || ! CopyBitMapStructureA2U (bm, &local_bm)) + if (!CopyRenderInfoStructureA2U (ri, &local_ri) + || !CopyBitMapStructureA2U (bm, &local_bm)) return 0; CopyColorIndexMappingA2U (cim, &local_cim); - /* write_log ("BlitPlanar2Direct(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n", - srcx, srcy, dstx, dsty, width, height, minterm, Mask, local_bm.Depth); */ + P96TRACE (("BlitPlanar2Direct(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n", + srcx, srcy, dstx, dsty, width, height, minterm, Mask, local_bm.Depth)); PlanarToDirect (&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, Mask, &local_cim); if (renderinfo_is_current_screen (&local_ri)) - do_blit (local_ri.Memory + dstx * GetBytesPerPixel (local_ri.RGBFormat) + dsty * local_ri.BytesPerRow, - local_ri.BytesPerRow, - 0, 0, dstx, dsty, width, height, 0); + do_blit (&local_ri, GetBytesPerPixel (local_ri.RGBFormat), dstx, dsty, dstx, dsty, width, height, BLIT_SRC, 0); return 1; } @@ -2008,30 +2241,13 @@ static void write_gfx_long (uaecptr addr addr -= picasso96_state.Address; y = addr / picasso96_state.BytesPerRow; -#if 0 - DX_Invalidate (y, y); - if (! picasso_vidinfo.extra_mem) - return; - - xbytes = addr - y * picasso96_state.BytesPerRow; - x = xbytes / picasso96_state.BytesPerPixel; - - if (x < picasso96_state.Width && y < picasso96_state.Height) { - dst = gfx_lock_picasso (); - if (dst) { - do_put_mem_long ((uae_u32 *)(dst + y * picasso_vidinfo.rowbytes + xbytes), value); - gfx_unlock_picasso (); - } - } -#else - if (y >= picasso96_state.Height) + if (y >= picasso96_state.VirtualHeight) return; wgfx_linestart = picasso96_state.Address - gfxmem_start + y * picasso96_state.BytesPerRow; wgfx_lineend = wgfx_linestart + picasso96_state.BytesPerRow; wgfx_y = y; wgfx_min = oldaddr; wgfx_max = oldaddr + 4; -#endif } static void write_gfx_word (uaecptr addr, uae_u16 value) @@ -2064,30 +2280,13 @@ static void write_gfx_word (uaecptr addr addr -= picasso96_state.Address; y = addr / picasso96_state.BytesPerRow; -#if 0 - DX_Invalidate (y, y); - if (! picasso_vidinfo.extra_mem) - return; - - xbytes = addr - y * picasso96_state.BytesPerRow; - x = xbytes / picasso96_state.BytesPerPixel; - - if (x < picasso96_state.Width && y < picasso96_state.Height) { - dst = gfx_lock_picasso (); - if (dst) { - do_put_mem_word ((uae_u16 *)(dst + y * picasso_vidinfo.rowbytes + xbytes), value); - gfx_unlock_picasso (); - } - } -#else - if (y >= picasso96_state.Height) + if (y >= picasso96_state.VirtualHeight) return; wgfx_linestart = picasso96_state.Address - gfxmem_start + y * picasso96_state.BytesPerRow; wgfx_lineend = wgfx_linestart + picasso96_state.BytesPerRow; wgfx_y = y; wgfx_min = oldaddr; wgfx_max = oldaddr + 2; -#endif } static void write_gfx_byte (uaecptr addr, uae_u8 value) @@ -2120,30 +2319,13 @@ static void write_gfx_byte (uaecptr addr addr -= picasso96_state.Address; y = addr / picasso96_state.BytesPerRow; -#if 0 - DX_Invalidate (y, y); - if (! picasso_vidinfo.extra_mem) - return; - - xbytes = addr - y * picasso96_state.BytesPerRow; - x = xbytes / picasso96_state.BytesPerPixel; - - if (x < picasso96_state.Width && y < picasso96_state.Height) { - dst = gfx_lock_picasso (); - if (dst) { - *(uae_u8 *)(dst + y * picasso_vidinfo.rowbytes + xbytes) = value; - gfx_unlock_picasso (); - } - } -#else - if (y >= picasso96_state.Height) + if (y >= picasso96_state.VirtualHeight) return; wgfx_linestart = picasso96_state.Address - gfxmem_start + y * picasso96_state.BytesPerRow; wgfx_lineend = wgfx_linestart + picasso96_state.BytesPerRow; wgfx_y = y; wgfx_min = oldaddr; wgfx_max = oldaddr + 1; -#endif } static uae_u32 REGPARAM2 gfxmem_lget (uaecptr addr) @@ -2151,8 +2333,8 @@ static uae_u32 REGPARAM2 gfxmem_lget (ua uae_u32 *m; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; - m = (uae_u32 *)(gfxmemory + addr); - return do_get_mem_long(m); + m = (uae_u32 *) (gfxmemory + addr); + return do_get_mem_long (m); } static uae_u32 REGPARAM2 gfxmem_wget (uaecptr addr) @@ -2160,8 +2342,8 @@ static uae_u32 REGPARAM2 gfxmem_wget (ua uae_u16 *m; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; - m = (uae_u16 *)(gfxmemory + addr); - return do_get_mem_word(m); + m = (uae_u16 *) (gfxmemory + addr); + return do_get_mem_word (m); } static uae_u32 REGPARAM2 gfxmem_bget (uaecptr addr) @@ -2176,11 +2358,11 @@ static void REGPARAM2 gfxmem_lput (uaecp uae_u32 *m; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; - m = (uae_u32 *)(gfxmemory + addr); - do_put_mem_long(m, l); + m = (uae_u32 *) (gfxmemory + addr); + do_put_mem_long (m, l); /* write the long-word to our displayable memory */ - write_gfx_long(addr, l); + write_gfx_long (addr, l); } static void REGPARAM2 gfxmem_wput (uaecptr addr, uae_u32 w) @@ -2188,11 +2370,11 @@ static void REGPARAM2 gfxmem_wput (uaecp uae_u16 *m; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; - m = (uae_u16 *)(gfxmemory + addr); - do_put_mem_word(m, (uae_u16)w); + m = (uae_u16 *) (gfxmemory + addr); + do_put_mem_word (m, (uae_u16) w); /* write the word to our displayable memory */ - write_gfx_word(addr, (uae_u16)w); + write_gfx_word (addr, (uae_u16) w); } static void REGPARAM2 gfxmem_bput (uaecptr addr, uae_u32 b) @@ -2202,7 +2384,7 @@ static void REGPARAM2 gfxmem_bput (uaecp gfxmemory[addr] = b; /* write the byte to our displayable memory */ - write_gfx_byte(addr, (uae_u8)b); + write_gfx_byte (addr, (uae_u8) b); } static int REGPARAM2 gfxmem_check (uaecptr addr, uae_u32 size) @@ -2222,13 +2404,27 @@ static uae_u8 REGPARAM2 *gfxmem_xlate (u addrbank gfxmem_bank = { gfxmem_lget, gfxmem_wget, gfxmem_bget, gfxmem_lput, gfxmem_wput, gfxmem_bput, - gfxmem_xlate, gfxmem_check + gfxmem_xlate, gfxmem_check, NULL }; +int picasso_display_mode_index (uae_u32 x, uae_u32 y, uae_u32 d) +{ + int i; + for (i = 0; i < mode_count; i++) { + if (DisplayModes[i].res.width == x + && DisplayModes[i].res.height == y + && DisplayModes[i].depth == d) + break; + } + if (i == mode_count) + i = -1; + return i; +} + static int resolution_compare (const void *a, const void *b) { - struct PicassoResolution *ma = (struct PicassoResolution *)a; - struct PicassoResolution *mb = (struct PicassoResolution *)b; + struct PicassoResolution *ma = (struct PicassoResolution *) a; + struct PicassoResolution *mb = (struct PicassoResolution *) b; if (ma->res.width > mb->res.width) return -1; if (ma->res.width < mb->res.width) @@ -2239,6 +2435,7 @@ static int resolution_compare (const voi return 1; return ma->depth - mb->depth; } + /* Call this function first, near the beginning of code flow * NOTE: Don't stuff it in InitGraphics() which seems reasonable... * Instead, put it in customreset() for safe-keeping. */ @@ -2246,7 +2443,7 @@ void InitPicasso96 (void) { static int first_time = 1; - memset (&picasso96_state, 0, sizeof(struct picasso96_state_struct)); + memset (&picasso96_state, 0, sizeof (struct picasso96_state_struct)); if (first_time) { int i; @@ -2262,33 +2459,31 @@ void InitPicasso96 (void) | ((i & 1) ? 0x01 : 0)); } mode_count = DX_FillResolutions (&picasso96_pixel_format); - qsort (DisplayModes, mode_count, sizeof (struct PicassoResolution), - resolution_compare); + qsort (DisplayModes, mode_count, sizeof (struct PicassoResolution), resolution_compare); for (i = 0; i < mode_count; i++) { - sprintf(DisplayModes[i].name, "%dx%d, %d-bit, %d Hz", - DisplayModes[i].res.width, DisplayModes[i].res.height, - DisplayModes[i].depth * 8, DisplayModes[i].refresh); + sprintf (DisplayModes[i].name, "%dx%d, %d-bit, %d Hz", + DisplayModes[i].res.width, DisplayModes[i].res.height, DisplayModes[i].depth * 8, DisplayModes[i].refresh); switch (DisplayModes[i].depth) { - case 1: + case 1: if (DisplayModes[i].res.width > chunky.width) chunky.width = DisplayModes[i].res.width; if (DisplayModes[i].res.height > chunky.height) chunky.height = DisplayModes[i].res.height; break; - case 2: + case 2: if (DisplayModes[i].res.width > hicolour.width) hicolour.width = DisplayModes[i].res.width; if (DisplayModes[i].res.height > hicolour.height) hicolour.height = DisplayModes[i].res.height; break; - case 3: + case 3: if (DisplayModes[i].res.width > truecolour.width) truecolour.width = DisplayModes[i].res.width; if (DisplayModes[i].res.height > truecolour.height) truecolour.height = DisplayModes[i].res.height; break; - case 4: + case 4: if (DisplayModes[i].res.width > alphacolour.width) alphacolour.width = DisplayModes[i].res.width; if (DisplayModes[i].res.height > alphacolour.height)