- Graphics processor mode standard screen modes supported (8/15/16/24/32 bits). Other weird modes are not supported.
- VRAM aperture byte swapping and RAMDAC red/blue swapping modes. (Used at least by Picasso96 driver)
- Hardware cursor.
-- Most of 2D blitter operations. Amiga Picasso96 and CGX4 drivers work. NOTE: Trapezoid primitive is simply assumed to be Rectangle.
+- Most of 2D blitter operations. Amiga Picasso96 and CGX4 drivers work.
Not emulated and Someone Else's Problem:
#define BLIT_LOG 0
+#define FRACT_ONE (1 << 16)
+
#define REG_STARTXDOM 0x0000
#define REG_DXDOM 0x0008
#define REG_STARTXSUB 0x0010
uint32_t gp_regs[0x2000 / 4];
int gp_pitch;
int gp_bpp;
+ int gp_bytesperline;
int gp_type;
bool gp_astipple, gp_texena, gp_fogena, gp_fastfill;
bool gp_synconbitmask, gp_reusebitmask, gp_colordda;
int gp_incx, gp_incy;
+ int gp_dxsub, gp_dxdom;
bool gp_readsrc, gp_readdst, gp_writedst;
bool gp_doswmask, gp_dohwmask;
bool gp_ropena, gp_constfbdata;
return out;
}
-static void do_stipple(permedia2_t *permedia2, uint32_t *cp, int *pxmode)
+static void do_stipple(permedia2_t *permedia2, int x, int y, uint32_t *cp, int *pxmode)
{
- int offx = (permedia2->gp_asxoffset + permedia2->gp_x) & 7;
- int offy = (permedia2->gp_asyoffset + permedia2->gp_y) & 7;
+ int offx = (permedia2->gp_asxoffset + x) & 7;
+ int offy = (permedia2->gp_asyoffset + y) & 7;
if (permedia2->gp_asmirrorx) {
offx = 7 - offx;
}
}
if (permedia2->gp_fastfill) {
+
while (permedia2->gp_y >= permedia2->gp_y1 && permedia2->gp_y < permedia2->gp_y2) {
- uint32_t d = permedia2->gp_dst + permedia2->gp_y * permedia2->gp_pitch * permedia2->gp_bpp + permedia2->gp_x * permedia2->gp_bpp;
- if (!permedia2->gp_scissor_user || (permedia2->gp_y >= permedia2->gp_scissor_min_y && permedia2->gp_y < permedia2->gp_scissor_max_y)) {
+ int y = FTOINT(permedia2->gp_y);
+ if (!permedia2->gp_scissor_user || (y >= permedia2->gp_scissor_min_y && y < permedia2->gp_scissor_max_y)) {
+ uint32_t dp = permedia2->gp_dst + y * permedia2->gp_bytesperline;
while (permedia2->gp_x >= permedia2->gp_x1 && permedia2->gp_x < permedia2->gp_x2) {
+ int x = FTOINT(permedia2->gp_x);
+ uint32_t ddp = dp + x * permedia2->gp_bpp;
// TODO: FBBlockColorL and FBBlockColorU
uint32_t c = permedia2->gp_regs[REG_FBBLOCKCOLOR >> 3];
int pxmode = 0;
if (permedia2->gp_asena) {
- do_stipple(permedia2, &c, &pxmode);
+ do_stipple(permedia2, x, y, &c, &pxmode);
}
if (permedia2->gp_bitmaskena) {
if (!do_bitmask_check(permedia2)) {
}
}
if (pxmode >= 0) {
- if (!permedia2->gp_scissor_user || (permedia2->gp_x >= permedia2->gp_scissor_min_x && permedia2->gp_x < permedia2->gp_scissor_max_x)) {
+ if (!permedia2->gp_scissor_user || (x >= permedia2->gp_scissor_min_x && x < permedia2->gp_scissor_max_x)) {
if (permedia2->gp_dohwmask) {
- uint32_t cd = readfb(permedia2, d, permedia2->gp_bpp);
+ uint32_t cd = readfb(permedia2, ddp, permedia2->gp_bpp);
c = (c & permedia2->gp_regs[REG_FBHARDWRITEMASK >> 3]) | (cd & ~permedia2->gp_regs[REG_FBHARDWRITEMASK >> 3]);
}
- writefb(permedia2, d, c, permedia2->gp_bpp);
+ writefb(permedia2, ddp, c, permedia2->gp_bpp);
}
}
- d += permedia2->gp_dx;
permedia2->gp_x += permedia2->gp_incx;
}
}
- permedia2->gp_x = permedia2->gp_incx > 0 ? permedia2->gp_x1 : permedia2->gp_x2 - 1;
- permedia2->gp_y += permedia2->gp_incy;
+ permedia2->gp_x1 += permedia2->gp_dxdom;
+ permedia2->gp_x2 += permedia2->gp_dxsub;
+ permedia2->gp_x = permedia2->gp_incx > 0 ? permedia2->gp_x1 : permedia2->gp_x2 - FRACT_ONE;
+ permedia2->gp_y += permedia2->gp_dy;
if (permedia2->gp_bitmaskena) {
if (!next_bitmask(permedia2)) {
return;
}
}
}
+
} else {
+
while (permedia2->gp_y >= permedia2->gp_y1 && permedia2->gp_y < permedia2->gp_y2) {
- if (!permedia2->gp_scissor_user || (permedia2->gp_y >= permedia2->gp_scissor_min_y && permedia2->gp_y < permedia2->gp_scissor_max_y)) {
- uint32_t d = permedia2->gp_dst + permedia2->gp_y * permedia2->gp_pitch * permedia2->gp_bpp + permedia2->gp_x * permedia2->gp_bpp;
- uint32_t s = permedia2->gp_src + permedia2->gp_y * permedia2->gp_pitch * permedia2->gp_bpp + permedia2->gp_x * permedia2->gp_bpp;
+ int y = FTOINT(permedia2->gp_y);
+ if (!permedia2->gp_scissor_user || (y >= permedia2->gp_scissor_min_y && y < permedia2->gp_scissor_max_y)) {
+ uint32_t dp = permedia2->gp_dst + y * permedia2->gp_bytesperline;
+ uint32_t sp = permedia2->gp_src + y * permedia2->gp_bytesperline;
while (permedia2->gp_x >= permedia2->gp_x1 && permedia2->gp_x < permedia2->gp_x2) {
+ int x = FTOINT(permedia2->gp_x);
+ uint32_t ddp = dp + x * permedia2->gp_bpp;
+ uint32_t ssp = sp + x * permedia2->gp_bpp;
uint32_t c = permedia2->gp_color, cd = permedia2->gp_color;
int pxmode = 0;
if (permedia2->gp_asena) {
- do_stipple(permedia2, &c, &pxmode);
+ do_stipple(permedia2, x, y, &c, &pxmode);
}
if (permedia2->gp_bitmaskena) {
if (!do_bitmask_check(permedia2)) {
do_bitmask_do(permedia2, &c, &pxmode);
}
}
- if (permedia2->gp_x >= permedia2->gp_packedlimitxstart && permedia2->gp_x < permedia2->gp_packedlimitxend) {
+ if (x >= permedia2->gp_packedlimitxstart && x < permedia2->gp_packedlimitxend) {
if (permedia2->gp_readsrc && !pxmode) {
- c = readfb(permedia2, s, permedia2->gp_bpp);
+ c = readfb(permedia2, ssp, permedia2->gp_bpp);
}
if (pxmode >=0) {
if (permedia2->gp_readdst) {
- cd = readfb(permedia2, d, permedia2->gp_bpp);
+ cd = readfb(permedia2, ddp, permedia2->gp_bpp);
}
if (permedia2->gp_ropena) {
c = dorop(permedia2->gp_rop, c, cd);
c = permedia2->gp_regs[REG_FBWRITEDATA >> 3];
}
if (permedia2->gp_writedst) {
- if (!permedia2->gp_scissor_user || (permedia2->gp_x >= permedia2->gp_scissor_min_x && permedia2->gp_x < permedia2->gp_scissor_max_x)) {
+ if (!permedia2->gp_scissor_user || (x >= permedia2->gp_scissor_min_x && x < permedia2->gp_scissor_max_x)) {
if (permedia2->gp_doswmask) {
c = (c & permedia2->gp_regs[REG_FBSOFTWRITEMASK >> 3]) | (cd & ~permedia2->gp_regs[REG_FBSOFTWRITEMASK >> 3]);
}
if (permedia2->gp_dohwmask) {
- cd = readfb(permedia2, d, permedia2->gp_bpp);
+ cd = readfb(permedia2, ddp, permedia2->gp_bpp);
c = (c & permedia2->gp_regs[REG_FBHARDWRITEMASK >> 3]) | (cd & ~permedia2->gp_regs[REG_FBHARDWRITEMASK >> 3]);
}
- writefb(permedia2, d, c, permedia2->gp_bpp);
+ writefb(permedia2, ddp, c, permedia2->gp_bpp);
}
}
}
}
permedia2->gp_x += permedia2->gp_incx;
- d += permedia2->gp_dx;
- s += permedia2->gp_sx;
}
}
- permedia2->gp_x = permedia2->gp_incx > 0 ? permedia2->gp_x1 : permedia2->gp_x2 - 1;
- permedia2->gp_y += permedia2->gp_incy;
+ permedia2->gp_x1 += permedia2->gp_dxdom;
+ permedia2->gp_x2 += permedia2->gp_dxsub;
+ permedia2->gp_x = permedia2->gp_incx > 0 ? permedia2->gp_x1 : permedia2->gp_x2 - FRACT_ONE;
+ permedia2->gp_y += permedia2->gp_dy;
if (permedia2->gp_bitmaskena) {
if (!next_bitmask(permedia2)) {
return;
int x = FTOINT(permedia2->gp_x1);
int y = FTOINT(permedia2->gp_y1);
- uint32_t d = permedia2->gp_dst + y * permedia2->gp_pitch * permedia2->gp_bpp + x * permedia2->gp_bpp;
- uint32_t s = permedia2->gp_src + y * permedia2->gp_pitch * permedia2->gp_bpp + x * permedia2->gp_bpp;
+ uint32_t d = permedia2->gp_dst + y * permedia2->gp_bytesperline + x * permedia2->gp_bpp;
+ uint32_t s = permedia2->gp_src + y * permedia2->gp_bytesperline + x * permedia2->gp_bpp;
if (!permedia2->gp_scissor_user || (y >= permedia2->gp_scissor_min_y && y < permedia2->gp_scissor_max_y)) {
uint32_t c = permedia2->gp_color, cd = permedia2->gp_color;
int pxmode = 0;
if (permedia2->gp_asena) {
- do_stipple(permedia2, &c, &pxmode);
+ do_stipple(permedia2, x, y, &c, &pxmode);
}
// is this allowed in line mode?
if (permedia2->gp_bitmaskena) {
permedia2->gp_astipple = (cmd >> 0) & 1;
permedia2->gp_texena = (cmd >> 13) & 1;
permedia2->gp_fogena = (cmd >> 14) & 1;
- permedia2->gp_incx = ((cmd >> 21) & 1) ? 1 : -1;
- permedia2->gp_incy = ((cmd >> 22) & 1) ? 1 : -1;
permedia2->gp_fastfill = (cmd >> 3) & 1;
permedia2->gp_synconbitmask = (cmd >> 11) & 1;
permedia2->gp_reusebitmask = (cmd >> 17) & 1;
#if BLIT_LOG
- pclog("Permedia2 render %08x as=%d ff=%d incx=%d incy=%d type=%d te=%d fe=%d\n",
- cmd, permedia2->gp_astipple, permedia2->gp_fastfill, permedia2->gp_incx, permedia2->gp_incy,
+ pclog("Permedia2 render %08x as=%d ff=%d type=%d te=%d fe=%d\n",
+ cmd, permedia2->gp_astipple, permedia2->gp_fastfill,
permedia2->gp_type, permedia2->gp_texena, permedia2->gp_fogena);
#endif
int readpixel = (permedia2->gp_regs[REG_FBREADPIXEL >> 3] & 7);
permedia2->gp_dst = (permedia2->gp_regs[REG_FBWINDOWBASE >> 3] + gp_pixeloffset) * permedia2->gp_bpp;
permedia2->gp_src = (permedia2->gp_regs[REG_FBSOURCEBASE >> 3] + gp_pixeloffset + gp_srcoffset - gp_packedlimitrel) * permedia2->gp_bpp;
+ permedia2->gp_bytesperline = permedia2->gp_pitch * permedia2->gp_bpp;
permedia2->gp_color = permedia2->gp_colordda ? permedia2->gp_regs[REG_CONSTANTCOLOR >> 3] : permedia2->gp_regs[REG_FBSOURCEDATA >> 3];
if (permedia2->gp_type == 0) {
} else if (permedia2->gp_type == 1) {
- // TRAPEZOID. FIXME: Currently assumes RECTANGLE!
+ // TRAPEZOID
permedia2->gp_x1 = TOFRACT1215(permedia2->gp_regs[REG_STARTXDOM >> 3]);
permedia2->gp_y1 = TOFRACT1215(permedia2->gp_regs[REG_STARTY >> 3]);
permedia2->gp_x2 = TOFRACT1215(permedia2->gp_regs[REG_STARTXSUB >> 3]);
- int dxsub = TOFRACT1215(permedia2->gp_regs[REG_DXSUB >> 3]);
- int dxdom = TOFRACT1215(permedia2->gp_regs[REG_DXDOM >> 3]);
- int dy = TOFRACT1114(permedia2->gp_regs[REG_DY >> 3]);
- if (dxsub || dxdom || (dy != 0x10000 && dy != 0xffff0000)) {
- pclog("Not yet supported: trapezoid not rectangle!\n");
- }
+ permedia2->gp_dxdom = TOFRACT1215(permedia2->gp_regs[REG_DXDOM >> 3]);
+ permedia2->gp_dxsub = TOFRACT1215(permedia2->gp_regs[REG_DXSUB >> 3]);
+ permedia2->gp_dy = TOFRACT1114(permedia2->gp_regs[REG_DY >> 3]);
permedia2->gp_len = permedia2->gp_regs[REG_COUNT >> 3] & 0xfff;
if (permedia2->gp_x2 >= permedia2->gp_x1) {
- permedia2->gp_incx = 1;
+ permedia2->gp_incx = FRACT_ONE;
} else {
- permedia2->gp_incx = -1;
+ permedia2->gp_incx = -FRACT_ONE;
}
- permedia2->gp_incy = dy < 0 ? - 1 : 1;
+ permedia2->gp_incy = permedia2->gp_dy < 0 ? -FRACT_ONE : FRACT_ONE;
+ permedia2->gp_y2 = permedia2->gp_y1 + (permedia2->gp_len * FRACT_ONE);
+ permedia2->gp_x = permedia2->gp_x1;
+ permedia2->gp_y = permedia2->gp_y1;
+
permedia2->gp_type = 3;
-
- permedia2->gp_x1 = permedia2->gp_x1 >> 16;
- permedia2->gp_x2 = permedia2->gp_x2 >> 16;
- permedia2->gp_y1 = permedia2->gp_y1 >> 16;
- permedia2->gp_y2 = permedia2->gp_y1 + permedia2->gp_len;
} else {
permedia2->gp_x2 = permedia2->gp_x1 + w;
permedia2->gp_y2 = permedia2->gp_y1 + h;
- }
- permedia2->gp_dx = permedia2->gp_bpp;
- permedia2->gp_sx = permedia2->gp_bpp;
+ permedia2->gp_x1 <<= 16;
+ permedia2->gp_x2 <<= 16;
+ permedia2->gp_y1 <<= 16;
+ permedia2->gp_y2 <<= 16;
- permedia2->gp_x = permedia2->gp_x1;
- if (permedia2->gp_incx < 0) {
- permedia2->gp_x = permedia2->gp_x2 - 1;
- permedia2->gp_dx = -permedia2->gp_dx;
- permedia2->gp_sx = -permedia2->gp_sx;
- }
- permedia2->gp_y = permedia2->gp_y1;
- if (permedia2->gp_incy < 0) {
- permedia2->gp_y = permedia2->gp_y2 - 1;
+ permedia2->gp_incx = ((cmd >> 21) & 1) ? FRACT_ONE : -FRACT_ONE;
+ permedia2->gp_incy = ((cmd >> 22) & 1) ? FRACT_ONE : -FRACT_ONE;
+
+ permedia2->gp_x = permedia2->gp_x1;
+ if (permedia2->gp_incx < 0) {
+ permedia2->gp_x = permedia2->gp_x2 - FRACT_ONE;
+ }
+ permedia2->gp_y = permedia2->gp_y1;
+ permedia2->gp_dy = FRACT_ONE;
+ if (permedia2->gp_incy < 0) {
+ permedia2->gp_y = permedia2->gp_y2 - FRACT_ONE;
+ permedia2->gp_dy = -FRACT_ONE;
+ }
+
+ permedia2->gp_dxdom = 0;
+ permedia2->gp_dxsub = 0;
}
+
if (permedia2->gp_bitmaskrelative) {
- permedia2->gp_bitmaskoffset = permedia2->gp_x & 31;
+ permedia2->gp_bitmaskoffset = (permedia2->gp_x >> 16) & 31;
}
#if BLIT_LOG
//pclog("PM2 MMIO Write %08x = %08x\n", addr, val);
if (reg >= 0x8000 && reg < 0xa000) {
- //pclog("PM2 GP MMIO Write %08x = %08x\n", addr, val);
+#if BLIT_LOG > 1
+ pclog("PM2 GP MMIO Write %08x = %08x\n", addr, val);
+#endif
reg &= 0x7fff;
int tag = reg >> 3;
permedia2->gp_regs[tag] = val;
} else if (reg == REG_BITMASKPATTERN) {
permedia2->gp_bitmaskpattern = val;
uint32_t rasterizer = permedia2->gp_regs[REG_RASTERIZERMODE >> 3];
- //pclog("REG_BITMASKPATTERN %08x %d\n", permedia2->gp_bitmaskpattern, permedia2->gp_bitmaskpatterncnt++);
+#if BLIT_LOG > 1
+ pclog("REG_BITMASKPATTERN %08x %d\n", permedia2->gp_bitmaskpattern, permedia2->gp_bitmaskpatterncnt++);
+#endif
if ((rasterizer >> 1) & 1) {
permedia2->gp_bitmaskpattern ^= 0xffffffff;
}