trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
uaecptr memp = md[0].params[0];
ri->AMemory = memp;
- ri->Memory = get_real_address (memp);
ri->BytesPerRow = md[1].params[0];
ri->RGBFormat = (RGBFTYPE)md[2].params[0];
// Can't really validate this better at this point, no height.
- if (trap_valid_address(ctx, memp, ri->BytesPerRow))
+ if (trap_valid_address(ctx, memp, ri->BytesPerRow)) {
+ ri->Memory = get_real_address(memp);
return 1;
+ }
}
write_log (_T("ERROR - Invalid RenderInfo memory area...\n"));
return 0;
};
trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
uaecptr memp = md[0].params[0];
- if (trap_is_indirect())
- pattern->Memory = NULL;
- else
- pattern->Memory = get_real_address(memp);
pattern->AMemory = memp;
pattern->XOffset = md[1].params[0];
pattern->YOffset = md[2].params[0];
pattern->BgPen = md[4].params[0];
pattern->Size = md[5].params[0];
pattern->DrawMode = md[6].params[0];
- if (trap_valid_address(ctx, memp, 2))
+ if (trap_valid_address(ctx, memp, 2)) {
+ if (trap_is_indirect())
+ pattern->Memory = NULL;
+ else
+ pattern->Memory = get_real_address(memp);
return 1;
+ }
}
write_log (_T("ERROR - Invalid Pattern memory area...\n"));
return 0;
trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
uaecptr memp = md[0].params[0];
- if (trap_is_indirect())
+ if (trap_is_indirect()) {
tmpl->Memory = NULL;
- else
+ } else {
+ if (!trap_valid_address(ctx, memp, 1)) {
+ write_log(_T("ERROR - Invalid Template memory region %08x...\n"), memp);
+ return 0;
+ }
tmpl->Memory = get_real_address(memp);
+ }
tmpl->AMemory = memp;
tmpl->BytesPerRow = md[1].params[0];
tmpl->XOffset = md[2].params[0];
ct = cursorrgbn;
}
datasize = h * ((w + 15) / 16) * 4;
+ if (!valid_address(src, datasize)) {
+ goto exit;
+ }
realsrc = get_real_address (src);
if (w > 64 || h > 64)
flags |= BIF_VIDEOWINDOW;
#endif
flags |= BIF_VGASCREENSPLIT;
+ flags |= BIF_PALETTESWITCH;
trap_put_long(ctx, ABI + PSSO_BoardInfo_Flags, flags);
if (debug_rtg_blitter != 3)
write_log (_T("P96: Blitter mode = %x!\n"), debug_rtg_blitter);
static void resetpalette(struct picasso96_state_struct *state)
{
- for (int i = 0; i < 256 * 2; i++)
+ for (int i = 0; i < 256 * 2; i++) {
state->CLUT[i].Pad = 0xff;
+ }
}
/*
* per cannon your board has. So you might have to shift the colors
* before writing them to the hardware.
*/
-static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count)
+static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count, int offset)
{
bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size;
int monid = currprefs.rtgboards[0].monitor_id;
clut += start * 3;
trap_get_bytes(ctx, clutbuf + start * 3, clut, count * 3);
for (i = start; i < start + count; i++) {
+ int coffset = i + offset;
int r = clutbuf[i * 3 + 0];
int g = clutbuf[i * 3 + 1];
int b = clutbuf[i * 3 + 2];
//write_log(_T("%d: %02x%02x%02x\n"), i, r, g, b);
- changed |= state->CLUT[i].Red != r
- || state->CLUT[i].Green != g
- || state->CLUT[i].Blue != b;
- if (state->CLUT[i].Pad) {
+ changed |= state->CLUT[coffset].Red != r
+ || state->CLUT[coffset].Green != g
+ || state->CLUT[coffset].Blue != b;
+ if (state->CLUT[coffset].Pad) {
changed = 1;
- state->CLUT[i].Pad = 0;
+ state->CLUT[coffset].Pad = 0;
}
- state->CLUT[i].Red = r;
- state->CLUT[i].Green = g;
- state->CLUT[i].Blue = b;
- state->CLUT[i + 256].Red = r;
- state->CLUT[i + 256].Green = g;
- state->CLUT[i + 256].Blue = b;
+ state->CLUT[coffset].Red = r;
+ state->CLUT[coffset].Green = g;
+ state->CLUT[coffset].Blue = b;
+ }
+ if (offset) {
+ state->dualclut = true;
}
-
changed |= picasso_palette(state->CLUT, vidinfo->clut);
return changed;
}
uae_u16 count = trap_get_dreg (ctx, 1);
uaecptr boardinfo = trap_get_areg (ctx, 0);
uaecptr clut = boardinfo + PSSO_BoardInfo_CLUT;
- if (start > 256 || count > 256 || start + count > 256)
+ int offset = 0;
+ if (start > 512 || count > 512 || start + count > 512)
return 0;
+ if (start >= 256) {
+ clut = boardinfo + PSSO_BoardInfo_SecondaryCLUT;
+ start -= 256;
+ offset = 256;
+ }
lockrtg();
- if (updateclut(ctx, clut, start, count))
+ if (updateclut(ctx, clut, start, count, offset))
vidinfo->full_refresh = 1;
unlockrtg();
P96TRACE_SETUP((_T("SetColorArray(%d,%d)\n"), start, count));
lockrtg();
int monid = currprefs.rtgboards[0].monitor_id;
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
+ uaecptr bi = trap_get_areg(ctx, 0);
- uae_s16 pos = trap_get_dreg(ctx, 0) - 1;
+ uae_s16 pos = trap_get_dreg(ctx, 0);
+ trap_put_word(ctx, bi + PSSO_BoardInfo_YSplit, pos);
+ pos--;
if (pos != vidinfo->splitypos) {
vidinfo->splitypos = pos;
vidinfo->full_refresh = 1;
{
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
struct picasso96_state_struct *state = &picasso96_state[monid];
- int y, yy, slx, sly;
+ int y, slx, sly;
int dst_height, dst_width, pitch;
dst_height = state->Height;
static void copyrow (int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dx, int dy, int dstbytesperrow, int dstpixbytes, bool direct, int convert_mode, uae_u32 *p96_rgbx16p)
{
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
+ struct picasso96_state_struct *state = &picasso96_state[monid];
int endx = x + width, endx4;
int dstpix = dstpixbytes;
int srcpix = srcpixbytes;
if (y >= vidinfo->splitypos && vidinfo->splitypos >= 0) {
src = gfxmem_banks[monid]->start + natmem_offset;
- clut += 256;
+ if (state->dualclut) {
+ clut += 256;
+ }
y -= vidinfo->splitypos;
}
{
int monid = currprefs.rtgboards[index].monitor_id;
struct picasso96_state_struct *state = &picasso96_state[monid];
- uae_u8 *src_start;
- uae_u8 *src_end;
+ uae_u8 *src_start[2];
+ uae_u8 *src_end[2];
uae_u8 *dst = NULL;
ULONG_PTR gwwcnt;
int pwidth = state->Width > state->VirtualWidth ? state->VirtualWidth : state->Width;
if (pheight > vidinfo->height)
pheight = vidinfo->height;
- src_start = src + (off & ~gwwpagemask[index]);
- src_end = src + ((off + state->BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]);
+ src_start[0] = src + (off & ~gwwpagemask[index]);
+ src_end[0] = src + ((off + state->BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]);
+ if (vidinfo->splitypos >= 0) {
+ src_end[0] = src + ((off + state->BytesPerRow * vidinfo->splitypos + gwwpagesize[index] - 1) & ~gwwpagemask[index]);
+ src_start[1] = src;
+ src_end[1] = src + ((state->BytesPerRow * (pheight - vidinfo->splitypos) + gwwpagesize[index] - 1) & ~gwwpagemask[index]);
+ } else {
+ src_start[1] = src_end[1] = 0;
+ }
#if 0
write_log(_T("%dx%d %dx%d %dx%d (%dx%d)\n"), state->Width, state->Width,
state->VirtualWidth, state->VirtualHeight,
picasso_vidinfo.width, picasso_vidinfo.height,
pwidth, pheight);
#endif
- if (!vidinfo->extra_mem || !gwwbuf[index] || src_start >= src_end) {
+ if (!vidinfo->extra_mem || !gwwbuf[index] || (src_start[0] >= src_end[0] && src_start[1] >= src_end[1])) {
return;
}
overlay_updated = gwwcnt > 0;
}
- if (vidinfo->full_refresh < 0 || overlay_updated) {
- gwwcnt = (src_end - src_start) / gwwpagesize[index] + 1;
- vidinfo->full_refresh = 1;
- for (int i = 0; i < gwwcnt; i++)
- gwwbuf[index][i] = src_start + i * gwwpagesize[index];
- } else {
- ULONG ps;
- gwwcnt = gwwbufsize[index];
- if (mman_GetWriteWatch(src_start, src_end - src_start, gwwbuf[index], &gwwcnt, &ps))
- break;
- }
-
- matchcount += gwwcnt;
- if (gwwcnt == 0)
- break;
+ for (int split = 0; split < 2; split++) {
+ uae_u32 regionsize = src_end[split] - src_start[split];
+ if (src_start[split] == 0 && src_end[split] == 0) {
+ break;
+ }
- dofull = gwwcnt >= ((src_end - src_start) / gwwpagesize[index]) * 80 / 100;
+ if (vidinfo->full_refresh < 0 || overlay_updated) {
+ gwwcnt = regionsize / gwwpagesize[index] + 1;
+ vidinfo->full_refresh = 1;
+ for (int i = 0; i < gwwcnt; i++)
+ gwwbuf[index][i] = src_start[split] + i * gwwpagesize[index];
+ } else {
+ ULONG ps;
+ gwwcnt = gwwbufsize[index];
+ if (mman_GetWriteWatch(src_start[split], regionsize, gwwbuf[index], &gwwcnt, &ps))
+ continue;
+ }
- dst = gfx_lock_picasso(monid, dofull, vidinfo->rtg_clear_flag != 0);
- if (vidinfo->rtg_clear_flag)
- vidinfo->rtg_clear_flag--;
- if (dst == NULL)
- break;
- dst += vidinfo->offset;
+ matchcount += gwwcnt;
- if (doskip() && p96skipmode == 2) {
- break;
- }
+ if (gwwcnt == 0) {
+ continue;
+ }
- if (dofull) {
- if (flashscreen != 0)
- copyallinvert(monid, src + off, dst, pwidth, pheight,
- state->BytesPerRow, state->BytesPerPixel,
- vidinfo->rowbytes, vidinfo->pixbytes,
- state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert);
- else
- copyall(monid, src + off, dst, pwidth, pheight,
- state->BytesPerRow, state->BytesPerPixel,
- vidinfo->rowbytes, vidinfo->pixbytes,
- state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert);
-
- miny = 0;
- maxy = pheight;
- flushlines = -1;
- break;
- }
+ dofull = gwwcnt >= (regionsize / gwwpagesize[index]) * 80 / 100;
- for (int i = 0; i < gwwcnt; i++) {
- uae_u8 *p = (uae_u8*)gwwbuf[index][i];
+ dst = gfx_lock_picasso(monid, dofull, vidinfo->rtg_clear_flag != 0);
+ if (vidinfo->rtg_clear_flag)
+ vidinfo->rtg_clear_flag--;
+ if (dst == NULL) {
+ continue;
+ }
+ dst += vidinfo->offset;
- if (p >= src_start && p < src_end) {
- int y, x, realoffset;
+ if (doskip() && p96skipmode == 2) {
+ continue;
+ }
- if (p >= src + off) {
- realoffset = p - (src + off);
+ if (dofull) {
+ if (flashscreen != 0) {
+ copyallinvert(monid, src + off, dst, pwidth, pheight,
+ state->BytesPerRow, state->BytesPerPixel,
+ vidinfo->rowbytes, vidinfo->pixbytes,
+ state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert);
} else {
- realoffset = 0;
+ copyall(monid, src + off, dst, pwidth, pheight,
+ state->BytesPerRow, state->BytesPerPixel,
+ vidinfo->rowbytes, vidinfo->pixbytes,
+ state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert);
}
+ miny = 0;
+ maxy = pheight;
+ flushlines = -1;
+ break;
+ }
+
+ if (split) {
+ off = 0;
+ }
+
+ for (int i = 0; i < gwwcnt; i++) {
+ uae_u8 *p = (uae_u8 *)gwwbuf[index][i];
- y = realoffset / state->BytesPerRow;
- if (y < pheight) {
- int w = (gwwpagesize[index] + state->BytesPerPixel - 1) / state->BytesPerPixel;
- x = (realoffset % state->BytesPerRow) / state->BytesPerPixel;
- if (x < pwidth) {
- copyrow(monid, src + off, dst, x, y, pwidth - x,
- state->BytesPerRow, state->BytesPerPixel,
- x, y, vidinfo->rowbytes, vidinfo->pixbytes,
- state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert, p96_rgbx16);
- flushlines++;
+ if (p >= src_start[split] && p < src_end[split]) {
+ int y, x, realoffset;
+
+ if (p >= src + off) {
+ realoffset = p - (src + off);
+ } else {
+ realoffset = 0;
}
- w = (gwwpagesize[index] - (state->BytesPerRow - x * state->BytesPerPixel) + state->BytesPerPixel - 1) / state->BytesPerPixel;
- if (y < miny)
- miny = y;
- y++;
- while (y < pheight && w > 0) {
- int maxw = w > pwidth ? pwidth : w;
- copyrow(monid, src + off, dst, 0, y, maxw,
- state->BytesPerRow, state->BytesPerPixel,
- 0, y, vidinfo->rowbytes, vidinfo->pixbytes,
- state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert, p96_rgbx16);
- w -= maxw;
+
+ y = realoffset / state->BytesPerRow;
+ if (split) {
+ y += vidinfo->splitypos;
+ }
+ if (y < pheight) {
+ int w = (gwwpagesize[index] + state->BytesPerPixel - 1) / state->BytesPerPixel;
+ x = (realoffset % state->BytesPerRow) / state->BytesPerPixel;
+ if (x < pwidth) {
+ copyrow(monid, src + off, dst, x, y, pwidth - x,
+ state->BytesPerRow, state->BytesPerPixel,
+ x, y, vidinfo->rowbytes, vidinfo->pixbytes,
+ state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert, p96_rgbx16);
+ flushlines++;
+ }
+ w = (gwwpagesize[index] - (state->BytesPerRow - x * state->BytesPerPixel) + state->BytesPerPixel - 1) / state->BytesPerPixel;
+ if (y < miny) {
+ miny = y;
+ }
y++;
- flushlines++;
+ while (y < pheight && w > 0) {
+ int maxw = w > pwidth ? pwidth : w;
+ copyrow(monid, src + off, dst, 0, y, maxw,
+ state->BytesPerRow, state->BytesPerPixel,
+ 0, y, vidinfo->rowbytes, vidinfo->pixbytes,
+ state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert, p96_rgbx16);
+ w -= maxw;
+ y++;
+ flushlines++;
+ }
+ if (y > maxy) {
+ maxy = y;
+ }
}
- if (y > maxy)
- maxy = y;
+
}
}
-
}
break;
}
interrupt_enabled = 0;
reserved_gfxmem = 0;
resetpalette(state);
+ state->dualclut = false;
InitPicasso96(monid);
}
#define PSSO_BoardInfo_Depth PSSO_BoardInfo_YOffset + 2
#define PSSO_BoardInfo_ClearMask PSSO_BoardInfo_Depth + 1
#define PSSO_BoardInfo_Border PSSO_BoardInfo_ClearMask + 1
-#define PSSO_BoardInfo_Mask PSSO_BoardInfo_Border + 2 /* BOOL type is only 2-bytes! */
-#define PSSO_BoardInfo_CLUT PSSO_BoardInfo_Mask + 4
+#define PSSO_BoardInfo_Mask PSSO_BoardInfo_Border + 2 /* BOOL type is only 2-bytes! */
+#define PSSO_BoardInfo_CLUT PSSO_BoardInfo_Mask + 4
#define PSSO_BoardInfo_ViewPort PSSO_BoardInfo_CLUT + 3*256
-#define PSSO_BoardInfo_VisibleBitMap PSSO_BoardInfo_ViewPort + 4
+#define PSSO_BoardInfo_VisibleBitMap PSSO_BoardInfo_ViewPort + 4
#define PSSO_BoardInfo_BitMapExtra PSSO_BoardInfo_VisibleBitMap + 4
#define PSSO_BoardInfo_BitMapList PSSO_BoardInfo_BitMapExtra + 4
#define PSSO_BoardInfo_MemList PSSO_BoardInfo_BitMapList + 12 /* BitMapList is 12-bytes */
#define PSSO_BoardInfo_MousePens PSSO_BoardInfo_MouseImage + 4
#define PSSO_BoardInfo_MouseRect PSSO_BoardInfo_MousePens + 4
#define PSSO_BoardInfo_MouseChunky PSSO_BoardInfo_MouseRect + 8 /* MouseRect is 8-bytes */
-#define PSSO_BoardInfo_MouseRendered PSSO_BoardInfo_MouseChunky + 4
-#define PSSO_BoardInfo_MouseSaveBuffer PSSO_BoardInfo_MouseRendered + 4
+#define PSSO_BoardInfo_MouseRendered PSSO_BoardInfo_MouseChunky + 4
+#define PSSO_BoardInfo_MouseSaveBuffer PSSO_BoardInfo_MouseRendered + 4
#define PSSO_BoardInfo_ChipData PSSO_BoardInfo_MouseSaveBuffer + 4
#define PSSO_BoardInfo_CardData PSSO_BoardInfo_ChipData + 16 * 4
-#define PSSO_BoardInfo_MemorySpaceBase PSSO_BoardInfo_CardData + 16 * 4
-#define PSSO_BoardInfo_MemorySpaceSize PSSO_BoardInfo_MemorySpaceBase + 4
-#define PSSO_BoardInfo_DoubleBufferList PSSO_BoardInfo_MemorySpaceSize + 4
+#define PSSO_BoardInfo_MemorySpaceBase PSSO_BoardInfo_CardData + 16 * 4
+#define PSSO_BoardInfo_MemorySpaceSize PSSO_BoardInfo_MemorySpaceBase + 4
+#define PSSO_BoardInfo_DoubleBufferList PSSO_BoardInfo_MemorySpaceSize + 4
#define PSSO_BoardInfo_SyncTime PSSO_BoardInfo_DoubleBufferList + 4
-#define PSSO_BoardInfo_SyncPeriod PSSO_BoardInfo_SyncTime + 4
-#define PSSO_BoardInfo_SoftVBlankPort PSSO_BoardInfo_SyncPeriod + 8
-#define PSSO_BoardInfo_SizeOf PSSO_BoardInfo_SoftVBlankPort + 34
+#define PSSO_BoardInfo_SyncPeriod PSSO_BoardInfo_SyncTime + 8
+#define PSSO_BoardInfo_SoftVBlankPort PSSO_BoardInfo_SyncPeriod + 4
+#define PSSO_BoardInfo_WaitQ PSSO_BoardInfo_SoftVBlankPort + 34
+#define PSSO_BoardInfo_EssentialFormats PSSO_BoardInfo_WaitQ + 3 * 4
+#define PSSO_BoardInfo_MouseImageBuffer PSSO_BoardInfo_EssentialFormats + 4
+#define PSSO_BoardInfo_BackViewPort PSSO_BoardInfo_MouseImageBuffer + 4
+#define PSSO_BoardInfo_BackBitMap PSSO_BoardInfo_BackViewPort + 4
+#define PSSO_BoardInfo_BackBitMapExtra PSSO_BoardInfo_BackBitMap + 4
+#define PSSO_BoardInfo_YSplit PSSO_BoardInfo_BackBitMapExtra + 4
+#define PSSO_BoardInfo_MaxPlanarMemory PSSO_BoardInfo_YSplit + 2
+#define PSSO_BoardInfo_MaxBMWidth PSSO_BoardInfo_MaxPlanarMemory + 4
+#define PSSO_BoardInfo_MaxBMHeight PSSO_BoardInfo_MaxBMWidth + 4
+#define PSSO_BoardInfo_SecondaryCLUT PSSO_BoardInfo_MaxBMHeight + 4
+#define PSSO_BoardInfo_SizeOf PSSO_BoardInfo_SecondaryCLUT + 3 * 256
/* BoardInfo flags */
/* 0-15: hardware flags */
#define BIB_NOBLITTER 24 /* disable all blitter functions */
#define BIB_SYSTEM2SCREENBLITS 25 /* allow data to be written to screen memory for cpu as blitter source */
#define BIB_GRANTDIRECTACCESS 26 /* all data on the board can be accessed at any time without bi->SetMemoryMode() */
+#define BIB_PALETTESWITCH 27
#define BIB_OVERCLOCK 31 /* enable overclocking for some boards */
#define BIB_IGNOREMASK BIB_NOMASKBLITS
#define BIF_NOBLITTER (1 << BIB_NOBLITTER)
#define BIF_SYSTEM2SCREENBLITS (1 << BIB_SYSTEM2SCREENBLITS)
#define BIF_GRANTDIRECTACCESS (1 << BIB_GRANTDIRECTACCESS)
+#define BIF_PALETTESWITCH (1 << BIB_PALETTESWITCH)
#define BIF_OVERCLOCK (1 << BIB_OVERCLOCK)
#define BIF_IGNOREMASK BIF_NOMASKBLITS
// every time windows can remove your surface from card so the mainrender place
// must be in memory
long XYOffset;
+ bool dualclut;
};
extern void InitPicasso96(int monid);