76 #define INTERNAL_FB_ADDR 0x300000000ULL
77 #define PVR_FB_TICK_SHIFT 18
79 #define PVR_VBLANK_HZ 60.0
83 #define VRAM_SIZE (8*1048576)
86 #define PVR_DMA_MEMLENGTH 0x100
87 #define N_PVR_DMA_REGS (PVR_DMA_MEMLENGTH / sizeof(uint32_t))
90 #define PVR_COUNT 0x04
92 #define PVR_LMMODE0 0x84
93 #define PVR_LMMODE1 0x88
136 uint32_t
ta[64 /
sizeof(uint32_t)];
158 #define REG(x) (d->reg[(x)/sizeof(uint32_t)])
159 #define DEFAULT_WRITE REG(relative_addr) = idata;
168 const int channel = 2;
173 int transmit_size = 1;
174 int src_delta = 0, dst_delta = 0;
175 int cause_interrupt = chcr &
CHCR_IE;
179 for (
int dmaChannel = 0; dmaChannel < 4; ++dmaChannel)
181 fatal(
"{# dma channel %i: sar=%08x dar=%08x count=%08x chcr=%08x #}\n",
192 fatal(
"pvr_dma_transfer: SH4 dma not enabled?\n");
210 default:
fatal(
"Unimplemented transmit size?! CHCR[%i] = 0x%08x\n",
219 default:
fatal(
"Unimplemented destination delta?! CHCR[%i] = 0x%08x\n",
228 default:
fatal(
"Unimplemented source delta?! CHCR[%i] = 0x%08x\n",
233 src_delta *= transmit_size;
234 dst_delta *= transmit_size;
240 if (dar != 0x10000000) {
243 dar = 0x04000000 | (dar & 0x007fffff);
245 dst_delta = src_delta;
247 uint8_t *buf = (uint8_t*) malloc(transmit_size);
270 unsigned char buf[
sizeof(uint32_t)];
272 size_t chunksize = transmit_size;
274 if (chunksize >
sizeof(uint32_t))
275 chunksize =
sizeof(uint32_t);
277 for (ofs = 0; ofs < transmit_size; ofs += chunksize) {
281 dev_pvr_ta_access(
cpu,
cpu->
mem, ofs, buf, chunksize,
304 fatal(
"Unimplemented SH4 RS DMAC: 0x%08x (PVR)\n",
309 if (cause_interrupt) {
310 fatal(
"TODO: pvr sh4 dmac interrupt!\n");
319 uint64_t idata = 0, odata = 0;
326 odata = d->
dma_reg[relative_addr /
sizeof(uint32_t)];
328 switch (relative_addr) {
332 debug(
"[ pvr_dma: ADDR set to 0x%08x ]\n",
339 debug(
"[ pvr_dma: COUNT set to 0x%08x ]\n",
346 debug(
"[ pvr_dma: MODE set to 0x%08x ]\n",
359 if (writeflag ==
MEM_WRITE && idata != 0x0cff0000) {
360 fatal(
"[ pvr_dma: TODO: unknown_0x%02x set to "
361 "0x%08x ]\n", (
int) relative_addr, (
int) idata);
373 if (writeflag ==
MEM_WRITE && idata != 0) {
374 fatal(
"[ pvr_dma: TODO: unknown_0x%02x set to "
375 "0x%08x ]\n", (
int) relative_addr, (
int) idata);
381 if (writeflag ==
MEM_WRITE && idata != 0) {
382 fatal(
"[ pvr_dma: TODO: LMMODE0 set to "
383 "0x%08x ]\n", (
int) idata);
389 if (writeflag ==
MEM_WRITE && idata != 0) {
390 fatal(
"[ pvr_dma: TODO: LMMODE1 set to "
391 "0x%08x ]\n", (
int) idata);
398 fatal(
"[ pvr_dma: write to 0x8c: TODO ]\n");
403 odata = 0x11 * (random() & 1);
408 if (writeflag ==
MEM_WRITE && idata != 0) {
409 fatal(
"[ pvr_dma: TODO: unknown_0x%02x set to "
410 "0x%08x ]\n", (
int) relative_addr, (
int) idata);
416 if (writeflag ==
MEM_WRITE && idata != 0x80000000) {
417 fatal(
"[ pvr_dma: TODO: unknown_0x%02x set to "
418 "0x%08x ]\n", (
int) relative_addr, (
int) idata);
425 if (writeflag ==
MEM_WRITE && idata != 0) {
426 fatal(
"[ pvr_dma: TODO: unknown_0x%02x set to "
427 "0x%08x ]\n", (
int) relative_addr, (
int) idata);
432 default:
if (writeflag ==
MEM_READ) {
433 fatal(
"[ pvr_dma: read from addr 0x%x ]\n",
436 fatal(
"[ pvr_dma: write to addr 0x%x: 0x%x ]\n",
437 (
int)relative_addr, (
int)idata);
445 d->
dma_reg[relative_addr /
sizeof(uint32_t)] = idata;
457 uint64_t idata = 0, odata = 0;
464 odata = d->
dma_more_reg[relative_addr /
sizeof(uint32_t)];
466 switch (relative_addr) {
478 if (writeflag ==
MEM_WRITE && idata != 0)
480 fatal(
"PVR other DMA mode (?):\n");
491 default:
if (writeflag ==
MEM_READ) {
492 fatal(
"[ pvr_dma_more: read from addr 0x%x ]\n",
495 fatal(
"[ pvr_dma_more: write to addr 0x%x: 0x%x ]\n",
496 (
int)relative_addr, (
int)idata);
504 d->
dma_more_reg[relative_addr /
sizeof(uint32_t)] = idata;
530 static void pvr_vblank_timer_tick(
struct timer *
t,
void *extra)
572 bool settingsChanged = d->
xsize != old_xsize ||
573 d->
ysize != old_ysize ||
576 if (!settingsChanged)
592 case 0:
debug(
"RGB0555 (16-bit)");
break;
593 case 1:
debug(
"RGB565 (16-bit)");
break;
594 case 2:
debug(
"RGB888 (24-bit)");
break;
595 case 3:
debug(
"RGB0888 (32-bit)");
break;
602 #ifdef DEBUG_RENDER_AS_WIRE_FRAME
604 static void line(
struct pvr_data *d,
int x1,
int y1,
int x2,
int y2)
608 for (i=0; i<256; i++) {
609 int px = (i * x2 + (256-i) * x1) >> 8;
610 int py = (i * y2 + (256-i) * y1) >> 8;
611 if (px > 0 && py > 0 && px < d->
xsize && py < d->
ysize) {
612 int ofs = fb_base + (px + py * d->
xsize) *
624 static void simpleline(
struct pvr_data *d,
int y,
double x1,
double x2,
625 double z1,
double z2,
double r1,
double r2,
double g1,
double g2,
626 double b1,
double b2)
628 if (y < 0 || y >= d->
ysize || (x1 < 0 && x2 < 0)
634 double tmpf = x1; x1 = x2; x2 = tmpf;
635 tmpf = z1; z1 = z2; z2 = tmpf;
636 tmpf = r1; r1 = r2; r2 = tmpf;
637 tmpf = g1; g1 = g2; g2 = tmpf;
638 tmpf = b1; b1 = b2; b2 = tmpf;
648 double dz12 = (x2 - x1 != 0) ? ( (
double)(z2 - z1) / (
double)(x2 - x1) ) : 0;
649 double dr12 = (x2 - x1 != 0) ? ( (
double)(r2 - r1) / (
double)(x2 - x1) ) : 0;
650 double dg12 = (x2 - x1 != 0) ? ( (
double)(g2 - g1) / (
double)(x2 - x1) ) : 0;
651 double db12 = (x2 - x1 != 0) ? ( (
double)(b2 - b1) / (
double)(x2 - x1) ) : 0;
652 double z = z1, r = r1, g = g1, b = b1;
653 for (
int x = x1; x <= x2; ++x) {
654 if (x > 0 && x < d->
xsize) {
655 int ofs = x + y * d->
xsize;
656 if (d->
vram_z[ofs] <= z) {
670 int ri = r, gi = g, bi = b;
676 if (ri < 0) ri = 0;
if (ri > 255) ri = 255;
677 if (gi < 0) gi = 0;
if (gi > 255) gi = 255;
678 if (bi < 0) bi = 0;
if (bi > 255) bi = 255;
679 int color = ((ri >> 3) << 11) + ((gi >> 2) << 5) + (bi >> 3);
687 z += dz12; r += dr12; g += dg12; b += db12;
691 static void texturedline(
struct pvr_data *d,
692 int texture_pixelformat,
bool twiddled,
int stride,
693 int texture,
int texture_xsize,
int texture_ysize,
694 int y,
int x1,
int x2,
double z1,
double z2,
695 double u1,
double u2,
double v1,
double v2)
697 if (y < 0 || y >= d->
ysize || (x1 < 0 && x2 < 0)
703 int tmp = x1; x1 = x2; x2 = tmp;
704 double tmpf = z1; z1 = z2; z2 = tmpf;
705 tmpf = u1; u1 = u2; u2 = tmpf;
706 tmpf = v1; v1 = v2; v2 = tmpf;
709 int bytesperpixel = 2;
711 switch (texture_pixelformat)
728 double dz12 = (x2 - x1 != 0) ? ( (
double)(z2 - z1) / (
double)(x2 - x1) ) : 0;
729 double du12 = (x2 - x1 != 0) ? ( (
double)(u2 - u1) / (
double)(x2 - x1) ) : 0;
730 double dv12 = (x2 - x1 != 0) ? ( (
double)(v2 - v1) / (
double)(x2 - x1) ) : 0;
732 double z = z1, u = u1, v = v1;
734 for (
int x = x1; x <= x2; ++x) {
735 if (x > 0 && x < d->
xsize) {
736 int ofs = x + y * d->
xsize;
737 if (d->
vram_z[ofs] <= z) {
743 int texturex = u * texture_xsize;
744 texturex &= (texture_xsize-1);
745 int texturey = v * texture_ysize;
746 texturey &= (texture_ysize-1);
751 (texturex&1)|((texturex&2)<<1)|((texturex&4)<<2)|((texturex&8)<<3)|((texturex&16)<<4)|
752 ((texturex&32)<<5)|((texturex&64)<<6)|((texturex&128)<<7)|((texturex&256)<<8)|((texturex&512)<<9);
754 (texturey&1)|((texturey&2)<<1)|((texturey&4)<<2)|((texturey&8)<<3)|((texturey&16)<<4)|
755 ((texturey&32)<<5)|((texturey&64)<<6)|((texturey&128)<<7)|((texturey&256)<<8)|((texturey&512)<<9);
756 textureofs = texturex * 2 + texturey;
759 textureofs = texturex + texturey * stride;
761 textureofs = texturex + texturey * texture_xsize;
764 textureofs *= bytesperpixel;
766 int addr = texture + textureofs;
769 int a = 255, r = 64, g = 64, b = 64;
770 switch (texture_pixelformat)
775 a = (color >> 15) & 0x1 ? 255 : 0;
776 r = (color >> 10) & 0x1f;
777 g = ((color >> 5) & 0x1f) << 1;
784 r = (color >> 11) & 0x1f;
785 g = (color >> 5) & 0x3f;
792 a = ((color >> 12) & 15) * 0x11;
793 r = ((color >> 8) & 15) << 1;
794 g = ((color >> 4) & 15) << 2;
795 b = ((color) & 15) << 1;
803 uint16_t c16 = *((uint16_t*)(
void*)base + index8bpp);
804 uint16_t c32 = *((uint32_t*)(
void*)base + index8bpp);
805 switch (palette_cfg) {
807 a = (c16 >> 15) & 0x1 ? 255 : 0;
808 r = (c16 >> 10) & 0x1f;
809 g = ((c16 >> 5) & 0x1f) << 1;
813 r = (c16 >> 11) & 0x1f;
814 g = (c16 >> 5) & 0x3f;
818 a = ((c16 >> 12) & 15) * 0x11;
819 r = ((c16 >> 8) & 15) << 1;
820 g = ((c16 >> 4) & 15) << 2;
821 b = ((c16) & 15) << 1;
824 a = (c32 >> 24) & 255;
825 r = ((c32 >> 16) & 255) >> 3;
826 g = ((c32 >> 8) & 255) >> 2;
827 b = ((c32) & 255) >> 3;
833 fatal(
"pvr: unimplemented texture_pixelformat %i\n", texture_pixelformat);
841 int color = (r << 11) + (g << 5) + (b);
847 int oldr = (oldcolor >> 11) & 0x1f;
848 int oldg = (oldcolor >> 5) & 0x3f;
849 int oldb = (oldcolor) & 0x1f;
850 r = (a * r + oldr * (255 - a)) / 255;
851 g = (a * g + oldg * (255 - a)) / 255;
852 b = (a * b + oldb * (255 - a)) / 255;
853 int color = (r << 11) + (g << 5) + (b);
868 static void pvr_render_triangle(
struct pvr_data *d,
869 int x1,
int y1,
double z1,
int r1,
int g1,
int b1,
870 int x2,
int y2,
double z2,
int r2,
int g2,
int b2,
871 int x3,
int y3,
double z3,
int r3,
int g3,
int b3)
875 int tmp = x1; x1 = x2; x2 = tmp;
876 tmp = y1; y1 = y2; y2 = tmp;
877 tmp = r1; r1 = r2; r2 = tmp;
878 tmp = g1; g1 = g2; g2 = tmp;
879 tmp = b1; b1 = b2; b2 = tmp;
880 double tmpf = z1; z1 = z2; z2 = tmpf;
884 int tmp = x1; x1 = x3; x3 = tmp;
885 tmp = y1; y1 = y3; y3 = tmp;
886 tmp = r1; r1 = r3; r3 = tmp;
887 tmp = g1; g1 = g3; g3 = tmp;
888 tmp = b1; b1 = b3; b3 = tmp;
889 double tmpf = z1; z1 = z3; z3 = tmpf;
893 int tmp = x2; x2 = x3; x3 = tmp;
894 tmp = y2; y2 = y3; y3 = tmp;
895 tmp = r2; r2 = r3; r3 = tmp;
896 tmp = g2; g2 = g3; g3 = tmp;
897 tmp = b2; b2 = b3; b3 = tmp;
898 double tmpf = z2; z2 = z3; z3 = tmpf;
901 if (y3 < 0 || y1 >= d->
ysize)
904 double dx12 = (y2-y1 != 0) ? ( (x2 - x1) / (double)(y2 - y1) ) : 0.0;
905 double dx13 = (y3-y1 != 0) ? ( (x3 - x1) / (double)(y3 - y1) ) : 0.0;
906 double dx23 = (y3-y2 != 0) ? ( (x3 - x2) / (double)(y3 - y2) ) : 0.0;
908 double dz12 = (y2-y1 != 0) ? ( (z2 - z1) / (double)(y2 - y1) ) : 0.0;
909 double dz13 = (y3-y1 != 0) ? ( (z3 - z1) / (double)(y3 - y1) ) : 0.0;
910 double dz23 = (y3-y2 != 0) ? ( (z3 - z2) / (double)(y3 - y2) ) : 0.0;
912 double dr12 = (y2-y1 != 0) ? ( (r2 - r1) / (double)(y2 - y1) ) : 0.0;
913 double dr13 = (y3-y1 != 0) ? ( (r3 - r1) / (double)(y3 - y1) ) : 0.0;
914 double dr23 = (y3-y2 != 0) ? ( (r3 - r2) / (double)(y3 - y2) ) : 0.0;
916 double dg12 = (y2-y1 != 0) ? ( (g2 - g1) / (double)(y2 - y1) ) : 0.0;
917 double dg13 = (y3-y1 != 0) ? ( (g3 - g1) / (double)(y3 - y1) ) : 0.0;
918 double dg23 = (y3-y2 != 0) ? ( (g3 - g2) / (double)(y3 - y2) ) : 0.0;
920 double db12 = (y2-y1 != 0) ? ( (b2 - b1) / (double)(y2 - y1) ) : 0.0;
921 double db13 = (y3-y1 != 0) ? ( (b3 - b1) / (double)(y3 - y1) ) : 0.0;
922 double db23 = (y3-y2 != 0) ? ( (b3 - b2) / (double)(y3 - y2) ) : 0.0;
924 double startx = x1, startz = z1, startr = r1, startg = g1, startb = b1;
925 double stopx = x1, stopz = z1, stopr = r1, stopg = g1, stopb = b1;
926 for (
int y = y1; y < y2; ++y)
928 simpleline(d, y, startx, stopx, startz, stopz, startr, stopr, startg, stopg, startb, stopb);
929 startx += dx13; startz += dz13; startr += dr13; startg += dg13; startb += db13;
930 stopx += dx12; stopz += dz12; stopr += dr12; stopg += dg12; stopb += db12;
933 stopx = x2; stopz = z2; stopr = r2; stopg = g2; stopb = b2;
934 for (
int y = y2; y < y3; ++y)
936 simpleline(d, y, startx, stopx, startz, stopz, startr, stopr, startg, stopg, startb, stopb);
937 startx += dx13; startz += dz13; startr += dr13; startg += dg13; startb += db13;
938 stopx += dx23; stopz += dz23; stopr += dr23; stopg += dg23; stopb += db23;
941 #ifdef DEBUG_RENDER_AS_WIRE_FRAME
943 line(d, x1, y1, x2, y2);
944 line(d, x1, y1, x3, y3);
945 line(d, x2, y2, x3, y3);
951 static void pvr_render_triangle_textured(
struct pvr_data *d,
952 int texture_pixelformat,
bool twiddled,
int stride,
953 int texture,
int texture_xsize,
int texture_ysize,
954 int x1,
int y1,
double z1,
double u1,
double v1,
955 int x2,
int y2,
double z2,
double u2,
double v2,
956 int x3,
int y3,
double z3,
double u3,
double v3)
960 int tmp = x1; x1 = x2; x2 = tmp;
961 tmp = y1; y1 = y2; y2 = tmp;
962 double tmpf = z1; z1 = z2; z2 = tmpf;
963 tmpf = u1; u1 = u2; u2 = tmpf;
964 tmpf = v1; v1 = v2; v2 = tmpf;
968 int tmp = x1; x1 = x3; x3 = tmp;
969 tmp = y1; y1 = y3; y3 = tmp;
970 double tmpf = z1; z1 = z3; z3 = tmpf;
971 tmpf = u1; u1 = u3; u3 = tmpf;
972 tmpf = v1; v1 = v3; v3 = tmpf;
976 int tmp = x2; x2 = x3; x3 = tmp;
977 tmp = y2; y2 = y3; y3 = tmp;
978 double tmpf = z2; z2 = z3; z3 = tmpf;
979 tmpf = u2; u2 = u3; u3 = tmpf;
980 tmpf = v2; v2 = v3; v3 = tmpf;
983 if (y3 < 0 || y1 >= d->
ysize)
986 double dx12 = (y2-y1 != 0) ? ( (x2 - x1) / (double)(y2 - y1) ) : 0.0;
987 double dx13 = (y3-y1 != 0) ? ( (x3 - x1) / (double)(y3 - y1) ) : 0.0;
988 double dx23 = (y3-y2 != 0) ? ( (x3 - x2) / (double)(y3 - y2) ) : 0.0;
990 double dz12 = (y2-y1 != 0) ? ( (z2 - z1) / (double)(y2 - y1) ) : 0.0;
991 double dz13 = (y3-y1 != 0) ? ( (z3 - z1) / (double)(y3 - y1) ) : 0.0;
992 double dz23 = (y3-y2 != 0) ? ( (z3 - z2) / (double)(y3 - y2) ) : 0.0;
994 double du12 = (y2-y1 != 0) ? ( (u2 - u1) / (double)(y2 - y1) ) : 0.0;
995 double du13 = (y3-y1 != 0) ? ( (u3 - u1) / (double)(y3 - y1) ) : 0.0;
996 double du23 = (y3-y2 != 0) ? ( (u3 - u2) / (double)(y3 - y2) ) : 0.0;
998 double dv12 = (y2-y1 != 0) ? ( (v2 - v1) / (double)(y2 - y1) ) : 0.0;
999 double dv13 = (y3-y1 != 0) ? ( (v3 - v1) / (double)(y3 - y1) ) : 0.0;
1000 double dv23 = (y3-y2 != 0) ? ( (v3 - v2) / (double)(y3 - y2) ) : 0.0;
1002 double startx = x1, startz = z1, startu = u1, startv = v1;
1003 double stopx = x1, stopz = z1, stopu = u1, stopv = v1;
1005 for (
int y = y1; y < y2; ++y)
1007 texturedline(d, texture_pixelformat, twiddled, stride, texture, texture_xsize, texture_ysize, y, startx, stopx, startz, stopz, startu, stopu, startv, stopv);
1008 startx += dx13; startz += dz13; startu += du13; startv += dv13;
1009 stopx += dx12; stopz += dz12; stopu += du12; stopv += dv12;
1012 stopx = x2; stopz = z2; stopu = u2; stopv = v2;
1013 for (
int y = y2; y < y3; ++y)
1015 texturedline(d, texture_pixelformat, twiddled, stride, texture, texture_xsize, texture_ysize, y, startx, stopx, startz, stopz, startu, stopu, startv, stopv);
1016 startx += dx13; startz += dz13; startu += du13; startv += dv13;
1017 stopx += dx23; stopz += dz23; stopu += du23; stopv += dv23;
1020 #ifdef DEBUG_RENDER_AS_WIRE_FRAME
1022 line(d, x1, y1, x2, y2);
1023 line(d, x1, y1, x3, y3);
1024 line(d, x2, y2, x3, y3);
1029 static void pvr_clear_ta_commands(
struct pvr_data* d)
1049 printf(
"pvr: only RGB565 rendering has been implemented\n");
1056 int striplength = 0;
1061 bool texture =
false;
1068 int cullingmode = 0;
1078 int texture_usize = 0, texture_vsize = 0;
1081 bool texture_mipmap =
false;
1082 bool texture_vq_compression =
false;
1083 int texture_pixelformat = 0;
1084 bool texture_twiddled =
false;
1085 bool texture_stride =
false;
1086 uint32_t textureAddr = 0;
1088 int vertex_index = 0;
1089 int wf_x[4], wf_y[4];
double wf_z[4], wf_u[4], wf_v[4];
1090 int wf_r[4], wf_g[4], wf_b[4];
1092 double baseRed = 0.0, baseGreen = 0.0, baseBlue = 0.0;
1094 debug(
"[ pvr_render: rendering to FB offset 0x%x, "
1095 "%i Tile Accelerator commands ]\n", fb_base, d->
n_ta_commands);
1114 for (
int q = 0; q < d->
xsize * d->
ysize; ++q)
1121 int cmd = (list[0] >> 29) & 7;
1141 listtype = (list[0] >> 24) & 7;
1142 striplength = (list[0] >> 18) & 3;
1143 striplength = striplength == 2 ? 4 : (
1144 striplength == 3 ? 6 : (striplength + 1));
1145 clipmode = (list[0] >> 16) & 3;
1146 modifier = (list[0] >> 7) & 1;
1147 modifier_mode = (list[0] >> 6) & 1;
1148 color_type = (list[0] >> 4) & 3;
1149 texture = list[0] & 8;
1150 specular = list[0] & 4;
1151 shading = list[0] & 2;
1152 uv_format = list[0] & 1;
1155 fatal(
"\nTA polygon listtype %i, ", listtype);
1156 fatal(
"striplength %i, ", striplength);
1157 fatal(
"clipmode %i, ", clipmode);
1158 fatal(
"modifier %i, ", modifier);
1159 fatal(
"modifier_mode %i,\n", modifier_mode);
1160 fatal(
" color_type %i, ", color_type);
1161 fatal(
"texture %s, ", texture ?
"TRUE" :
"false");
1162 fatal(
"specular %s, ", specular ?
"TRUE" :
"false");
1163 fatal(
"shading %s, ", shading ?
"TRUE" :
"false");
1164 fatal(
"uv_format %s\n", uv_format ?
"TRUE" :
"false");
1168 depthmode = (list[1] >> 29) & 7;
1169 cullingmode = (list[1] >> 27) & 3;
1170 zwrite = ! ((list[1] >> 26) & 1);
1171 texture1 = (list[1] >> 25) & 1;
1172 specular1 = (list[1] >> 24) & 1;
1173 shading1 = (list[1] >> 23) & 1;
1174 uv_format1 = (list[1] >> 22) & 1;
1175 dcalcexact = (list[1] >> 20) & 1;
1178 fatal(
" depthmode %i, ", depthmode);
1179 fatal(
"cullingmode %i, ", cullingmode);
1180 fatal(
"zwrite %s, ", zwrite ?
"TRUE" :
"false");
1181 fatal(
"texture1 %s\n", texture1 ?
"TRUE" :
"false");
1182 fatal(
" specular1 %s, ", specular1 ?
"TRUE" :
"false");
1183 fatal(
"shading1 %s, ", shading1 ?
"TRUE" :
"false");
1184 fatal(
"uv_format1 %s, ", uv_format1 ?
"TRUE" :
"false");
1185 fatal(
"dcalcexact %s\n", dcalcexact ?
"TRUE" :
"false");
1189 fatal(
"pvr: no zwrite? not implemented yet.\n");
1204 fog = (list[2] >> 22) & 3;
1213 texture_usize = 8 << ((list[2] >> 3) & 7);
1214 texture_vsize = 8 << (list[2] & 7);
1217 texture_mipmap = (list[3] >> 31) & 1;
1218 texture_vq_compression = (list[3] >> 30) & 1;
1219 texture_pixelformat = (list[3] >> 27) & 7;
1220 texture_twiddled = ! ((list[3] >> 26) & 1);
1221 texture_stride = (list[3] >> 25) & 1;
1222 textureAddr = (list[3] << 3) & 0x7fffff;
1225 fatal(
" texture: mipmap %s, ", texture_mipmap ?
"TRUE" :
"false");
1226 fatal(
"vq_compression %s, ", texture_vq_compression ?
"TRUE" :
"false");
1227 fatal(
"pixelformat %i, ", texture_pixelformat);
1228 fatal(
"twiddled %s\n", texture_twiddled ?
"TRUE" :
"false");
1229 fatal(
" stride %s, ", texture_stride ?
"TRUE" :
"false");
1230 fatal(
"textureAddr 0x%08x\n", textureAddr);
1234 fatal(
"[ pvr: fog type %i not yet implemented ]\n", fog);
1236 if (texture_vq_compression) {
1237 fatal(
"pvr: texture_vq_compression not supported yet\n");
1245 baseRed = r.
f * 255;
1246 baseGreen = g.
f * 255;
1247 baseBlue = b.
f * 255;
1258 if (listtype != 0 && listtype != 2 && listtype != 4)
1261 bool eos = (list[0] >> 28) & 1;
1267 wf_x[vertex_index] = fx.
f;
1268 wf_y[vertex_index] = fy.
f;
1269 wf_z[vertex_index] = fz.
f;
1272 fatal(
"TA vertex %f %f %f%s\n", fx.
f, fy.
f, fz.
f,
1273 eos ?
" end_of_strip" :
"");
1279 wf_u[vertex_index] = u.
f;
1280 wf_v[vertex_index] = v.
f;
1282 if (color_type == 0) {
1283 wf_r[vertex_index] = (list[6] >> 16) & 255;
1284 wf_g[vertex_index] = (list[6] >> 8) & 255;
1285 wf_b[vertex_index] = (list[6]) & 255;
1286 }
else if (color_type == 1) {
1290 wf_r[vertex_index] = v.
f * 255;
1291 wf_g[vertex_index] = extra1.
f * 255;
1292 wf_b[vertex_index] = extra2.
f * 255;
1293 }
else if (color_type == 2) {
1295 wf_r[vertex_index] = extra1.
f * baseRed;
1296 wf_g[vertex_index] = extra1.
f * baseGreen;
1297 wf_b[vertex_index] = extra1.
f * baseBlue;
1300 wf_r[vertex_index] = 255;
1301 wf_g[vertex_index] = 0;
1302 wf_b[vertex_index] = 0;
1308 if (vertex_index >= 3) {
1311 float crossProduct =
1312 ((wf_x[1] - wf_x[0])*(wf_y[2] - wf_y[0])) -
1313 ((wf_y[1] - wf_y[0])*(wf_x[2] - wf_x[0]));
1319 bool culled =
false;
1320 if (cullingmode == 2) {
1321 if (crossProduct < 0)
1324 }
else if (cullingmode == 3) {
1325 if (crossProduct > 0)
1332 pvr_render_triangle_textured(d,
1333 texture_pixelformat, texture_twiddled, texture_stride ? (32*modulo_mask) : 0,
1334 textureAddr, texture_usize, texture_vsize,
1335 wf_x[0], wf_y[0], wf_z[0], wf_u[0], wf_v[0],
1336 wf_x[1], wf_y[1], wf_z[1], wf_u[1], wf_v[1],
1337 wf_x[2], wf_y[2], wf_z[2], wf_u[2], wf_v[2]);
1339 pvr_render_triangle(d,
1340 wf_x[0], wf_y[0], wf_z[0], wf_r[0], wf_g[0], wf_b[0],
1341 wf_x[1], wf_y[1], wf_z[1], wf_r[1], wf_g[1], wf_b[1],
1342 wf_x[2], wf_y[2], wf_z[2], wf_r[2], wf_g[2], wf_b[2]);
1352 wf_x[0] = wf_x[1]; wf_y[0] = wf_y[1]; wf_z[0] = wf_z[1];
1353 wf_u[0] = wf_u[1]; wf_v[0] = wf_v[1];
1354 wf_r[0] = wf_r[1]; wf_g[0] = wf_g[1]; wf_b[0] = wf_b[1];
1356 wf_x[1] = wf_x[2]; wf_y[1] = wf_y[2]; wf_z[1] = wf_z[2];
1357 wf_u[1] = wf_u[2]; wf_v[1] = wf_v[2];
1358 wf_r[1] = wf_r[2]; wf_g[1] = wf_g[2]; wf_b[1] = wf_b[2];
1365 fatal(
"pvr_render: unimplemented list cmd %i\n",
cmd);
1370 pvr_clear_ta_commands(d);
1382 static void pvr_reset_ta(
struct pvr_data *d)
1385 pvr_clear_ta_commands(d);
1394 static void pvr_reset(
struct pvr_data *d)
1413 static void pvr_tilebuf_debugdump(
struct pvr_data *d)
1423 uint32_t *p = (uint32_t*) (d->
vram + tilebuf);
1425 fatal(
"PVR tile buffer debug dump:\n");
1427 for (
int i = 0; i < 24; ++i)
1428 fatal(
" %08x", *p++);
1436 fatal(
" Tile %i,%i:", x, y);
1437 for (
int i = 0; i < 6; ++i)
1438 fatal(
" %08x", *p++);
1454 static void pvr_ta_command(
struct cpu *
cpu,
struct pvr_data *d,
int list_ofs)
1456 uint32_t *ta = &d->
ta[list_ofs];
1463 for (i = 0; i < 8; ++i)
1464 fatal(
" %08x", (
int) ta[i]);
1493 int cmd = (ta[0] >> 29) & 7;
1508 }
else if (
cmd == 4) {
1518 uint64_t idata = 0, odata = 0;
1520 if (len !=
sizeof(uint32_t)) {
1521 fatal(
"pvr_ta access len = %i: TODO\n", (
int) len);
1527 relative_addr &= (
sizeof(d->
ta) - 1);
1532 fatal(
"[ pvr_ta: WRITE addr=%08x value=%08x ]\n",
1533 (
int)relative_addr, (
int)idata);
1537 d->
ta[relative_addr /
sizeof(uint32_t)] = idata;
1542 if (relative_addr == 0x1c)
1543 pvr_ta_command(
cpu, d, 0);
1544 if (relative_addr == 0x3c)
1545 pvr_ta_command(
cpu, d, 8);
1547 odata = d->
ta[relative_addr /
sizeof(uint32_t)];
1550 fatal(
"[ pvr_ta: READ addr=%08x value=%08x ]\n", (
int)relative_addr, (
int)odata);
1561 uint64_t idata = 0, odata = 0;
1568 odata = d->
reg[relative_addr /
sizeof(uint32_t)];
1586 switch (relative_addr) {
1602 debug(
"[ pvr: RESET ");
1616 debug(
"[ pvr: STARTRENDER ]\n");
1619 fatal(
"[ pvr: huh? read from STARTRENDER ]\n");
1626 debug(
"[ pvr: OB_ADDR set to 0x%08" PRIx32
" ]\n",
1629 fatal(
"[ pvr: OB_ADDR: Fatal error: Unknown"
1630 " bits set: 0x%08" PRIx32
" ]\n",
1641 debug(
"[ pvr: TILEBUF_ADDR set to 0x%08" PRIx32
" ]\n",
1644 fatal(
"[ pvr: TILEBUF_ADDR: Unknown"
1645 " bits set: 0x%08" PRIx32
" ]\n",
1651 pvr_tilebuf_debugdump(d);
1657 debug(
"[ pvr: SPANSORT: ");
1663 debug(
"TSP_CACHE_ENABLE ");
1671 debug(
"[ pvr: BRDCOLR set to 0x%06" PRIx32
" ]\n",
1693 debug(
"[ pvr: DIWMODE set to: ");
1695 debug(
"strip_buffer_enabled=%i, ",
1700 debug(
"pixelmode=");
1702 case 0:
debug(
"RGB0555 (16-bit)");
break;
1703 case 1:
debug(
"RGB565 (16-bit)");
break;
1704 case 2:
debug(
"RGB888 (24-bit)");
break;
1705 case 3:
debug(
"RGB0888 (32-bit)");
break;
1719 debug(
"[ pvr: DIWSIZE set to modulo=%i, "
1720 "width=%i, height=%i ]\n", (
int)
1732 debug(
"[ pvr: FB_RENDER_ADDR1 set to 0x%08" PRIx32
1733 " ]\n", (
int) idata);
1740 debug(
"[ pvr: FB_RENDER_ADDR2 set to 0x%08" PRIx32
1741 " ]\n", (
int) idata);
1748 debug(
"[ pvr: FB_CLIP_X set to min=%i, "
1760 debug(
"[ pvr: FB_CLIP_Y set to min=%i, "
1772 debug(
"[ pvr: SHADOW set to enable=%i, "
1784 debug(
"[ pvr: OBJECT_CLIP 0x%08x ]\n", (
int)idata);
1791 debug(
"[ pvr: OB_CFG 0x%08x ]\n", (
int)idata);
1798 debug(
"[ pvr: UNKNOWN_80 0x%08x ]\n", (
int)idata);
1805 debug(
"[ pvr: UNKNOWN_84 0x%08x ]\n", (
int)idata);
1812 debug(
"[ pvr: BGPLANE_Z 0x%08x ]\n", (
int)idata);
1819 debug(
"[ pvr: BGPLANE_CFG 0x%08x ]\n", (
int)idata);
1826 debug(
"[ pvr: ISP_CFG 0x%08x ]\n", (
int)idata);
1833 debug(
"[ pvr: VRAM_CFG1 set to 0x%08" PRIx32,
1836 fatal(
"{ VRAM_CFG1 = 0x%08" PRIx32
" is not "
1837 "yet implemented! }", (
int) idata);
1845 debug(
"[ pvr: VRAM_CFG2 set to 0x%08" PRIx32,
1848 fatal(
"{ VRAM_CFG2 = 0x%08" PRIx32
" is not "
1849 "yet implemented! }", (
int) idata);
1857 debug(
"[ pvr: VRAM_CFG3 set to 0x%08" PRIx32,
1860 fatal(
"{ VRAM_CFG3 = 0x%08" PRIx32
" is not "
1861 "yet implemented! }", (
int) idata);
1870 debug(
"[ pvr: FOG_TABLE_COL set to 0x%06" PRIx32
" ]\n",
1879 debug(
"[ pvr: FOG_VERTEX_COL set to 0x%06" PRIx32
" ]\n",
1888 debug(
"[ pvr: FOG_DENSITY set to 0x%08" PRIx32
" ]\n",
1897 debug(
"[ pvr: CLAMP_MAX set to 0x%06" PRIx32
" ]\n",
1906 debug(
"[ pvr: CLAMP_MIN set to 0x%06" PRIx32
" ]\n",
1914 debug(
"[ pvr: PVRREG_FB_RENDER_CFG set to 0x%08x ]\n",
1923 debug(
"[ pvr: PVRREG_FB_RENDER_MODULO set to %i ]\n",
1932 debug(
"[ pvr: DIWADDRL set to 0x%08" PRIx32
" ]\n",
1941 debug(
"[ pvr: DIWADDRS set to 0x%08" PRIx32
" ]\n",
1954 debug(
"[ pvr: RASEVTPOS pos1=%i pos2=%i ]\n",
1971 debug(
"[ pvr: SYNCCONF set to: ");
1977 default:
debug(
"*UNKNOWN*");
break;
1991 debug(
"[ pvr: BRDHORZ start=%i stop=%i ]\n",
2001 debug(
"[ pvr: SYNCSIZE v=%i h=%i ]\n",
2011 debug(
"[ pvr: BRDVERT start=%i stop=%i ]\n",
2021 debug(
"[ pvr: SYNCH_WIDTH 0x%08x ]\n", (
int)idata);
2028 debug(
"[ pvr: TSP_CFG 0x%08x ]\n", (
int)idata);
2038 fatal(
"PVRREG_DIWCONF magic not set to "
2039 "Magic value. 0x%08x\n", (
int)idata);
2043 debug(
"[ pvr: PVRREG_DIWCONF: BLANK: TODO ]\n");
2053 debug(
"[ pvr: DIWHSTRT hpos=%i (%s) ]\n",
2054 v, v == 174?
"PAL" :
2056 (v == 144?
"VGA" :
"unknown!")));
2063 debug(
"[ pvr: DIWVSTRT v2=%i v1=%i ]\n",
2073 debug(
"[ pvr: SCALER_CFG 0x%08x ]\n", (
int)idata);
2080 debug(
"[ pvr: PALETTE_CFG 0x%08x ]\n", (
int)idata);
2092 debug(
"[ pvr: MAGIC_110 set to 0x%08" PRIx32,
2095 fatal(
"{ MAGIC_110 = 0x%08" PRIx32
" is not "
2096 "yet implemented! }", (
int) idata);
2104 debug(
"[ pvr: TA_LUMINANCE set to 0x%08" PRIx32
" ]\n",
2113 fatal(
"[ pvr: UNEXPECTED bits in "
2114 "TA_OPB_START: 0x%08x ]\n", (
int)idata);
2118 debug(
"[ pvr: TA_OPB_START set to 0x%x ]\n",
2127 fatal(
"[ pvr: UNEXPECTED bits in "
2128 "TA_OB_START: 0x%08x ]\n", (
int)idata);
2132 debug(
"[ pvr: TA_OB_START set to 0x%x ]\n",
2141 debug(
"[ pvr: TA_OPB_END set to 0x%x ]\n",
2150 debug(
"[ pvr: TA_OB_END set to 0x%x ]\n",
2159 debug(
"[ pvr: TA_OPB_POS set to 0x%x ]\n",
2168 debug(
"[ pvr: TA_OB_POS set to 0x%x ]\n",
2177 debug(
"[ pvr: TA_OPL_INIT set to 0x%x ]\n",
2189 debug(
"[ pvr: TILEBUF_SIZE set to %i x %i ]\n",
2197 debug(
"[ pvr: TA_OPB_CFG set to 0x%x ]\n",
2205 debug(
"[ pvr: TA_INIT ]\n");
2211 fatal(
"{ TA_INIT = 0x%08" PRIx32
" is not "
2212 "yet implemented! }", (
int) idata);
2224 default:
if (writeflag ==
MEM_READ) {
2225 fatal(
"[ pvr: read from UNIMPLEMENTED addr 0x%x ]\n",
2226 (
int)relative_addr);
2228 fatal(
"[ pvr: write to UNIMPLEMENTED addr 0x%x: 0x%x"
2229 " ]\n", (
int)relative_addr, (
int)idata);
2253 if ((int64_t)high >= 0 && (int64_t)low <
2254 bytes_per_line * d->
ysize) {
2262 new_y1 = low / bytes_per_line;
2263 new_y2 = high / bytes_per_line + 1;
2281 uint64_t high, low = (uint64_t)(int64_t) -1;
2286 uint8_t *
vram = (uint8_t *) d->
vram;
2322 int x, y, b = rgb & 0xff, g = (rgb >> 8) & 0xff, r = rgb >> 16;
2325 for (y=0; y<d->
fb->
ysize; y++) {
2326 int xskip = y < PVR_MARGIN || y >=
2328 for (x=0; x<d->
fb->
xsize; x++) {
2346 if ((int64_t)low != -1)
2371 int fo = fb_ofs, vo = vram_ofs;
2372 for (p=0; p<pixels_to_copy; p++) {
2381 vram_ofs += bytes_per_line;
2391 int fo = fb_ofs, vo = vram_ofs;
2392 for (p=0; p<pixels_to_copy; p++) {
2401 vram_ofs += bytes_per_line;
2413 vram_ofs += bytes_per_line;
2423 int fo = fb_ofs, vo = vram_ofs;
2424 for (p=0; p<pixels_to_copy; p++) {
2431 vram_ofs += bytes_per_line;
2470 for (i=0; i<len; i++) {
2471 int addr = relative_addr + i;
2473 | ((
addr & 0x7ffff8) >> 1);
2480 if (len <
sizeof(uint16_t))
2481 fatal(
"pvr_vram_alt: write of less than 16 bits attempted?\n");
2487 for (i=0; i<len; i++) {
2488 int addr = relative_addr + i;
2509 memcpy(
data, d->
vram + relative_addr, len);
2514 if (len <
sizeof(uint16_t))
2515 fatal(
"pvr_vram: write of less than 16 bits attempted?\n");
2525 memcpy(d->
vram + relative_addr,
data, len);
2559 VRAM_SIZE, dev_pvr_vram_alt_access, (
void *)d_alt,
2564 0x10000000, 0x800000, dev_pvr_ta_access,
d,
DM_DEFAULT, NULL);
2582 24,
"Dreamcast PVR");