more blitter, doukutsu fully playable on pnd
authornotaz <notaz@pixelinis>
Fri, 9 Apr 2010 23:02:37 +0000 (02:02 +0300)
committernotaz <notaz@pixelinis>
Wed, 28 Jul 2010 13:01:40 +0000 (16:01 +0300)
loader/Makefile
loader/emu.c
loader/patches.c

index 5055ac7..225012f 100644 (file)
@@ -1,9 +1,15 @@
+ARCH ?= arm
+CROSS_COMPILE ?= arm-linux-
 CC = $(CROSS_COMPILE)gcc
 AS = $(CROSS_COMPILE)as
 CFLAGS += -Wall -ggdb
 LDFLAGS += -static -ggdb
+ifndef DEBUG
+CFLAGS += -O2 -fno-strict-aliasing
+LDFLAGS += -s -O2
+endif
 
-ifndef ARCH
+ifeq "$(ARCH)" "ia32"
 ARCH = ia32
 CFLAGS += -m32
 LDFLAGS += -m32
index 97649ff..b425308 100644 (file)
@@ -16,6 +16,8 @@
 
 //#define iolog printf
 #define iolog(...)
+//#define segvlog printf
+#define segvlog(...)
 
 typedef unsigned int   u32;
 typedef unsigned short u16;
@@ -49,6 +51,10 @@ static struct {
   u32 srcfifo;
 } blitter;
 
+#define SRCCTRL_INVIDEO         (1 << 8)
+#define SRCCTRL_SRCENB          (1 << 7)
+#define CTRL_TRANSPARENCYENB    (1 << 11)
+
 static struct {
   union {
     u32 mlc_stl_eadr;
@@ -63,6 +69,49 @@ static u16 *host_screen;
 static int host_stride;
 
 
+static void memset16(void *dst, u32 pattern, int count)
+{
+  u32 *dl;
+  u16 *d;
+  
+  d = (u16 *)((long)dst & ~1);
+  if ((long)d & 2) {
+    *d++ = pattern;
+    count--;
+  }
+  dl = (void *)d;
+  pattern |= pattern << 16;
+
+  while (count >= 2) {
+    *dl++ = pattern;
+    count -= 2;
+  }
+  if (count)
+    *(u16 *)dl = pattern;
+}
+
+static void blt_tr(void *dst, void *src, u32 trc, int w)
+{
+  u16 *d = (u16 *)((long)dst & ~1);
+  u16 *s = (u16 *)((long)src & ~1);
+
+  // XXX: optimize
+  for (; w > 0; d++, s++, w--)
+    if (*s != trc)
+      *d = *s;
+}
+
+#define dump_blitter() \
+{ \
+  u32 *r = &blitter.dstctrl; \
+  int i; \
+  for (i = 0; i < 4*4; i++, r++) { \
+    printf("%08x ", *r); \
+    if ((i & 3) == 3) \
+      printf("\n"); \
+  } \
+}
+
 static void *upper_lookup(u32 addr, u8 **mem_end, int *stride_override)
 {
   struct uppermem_block *ub;
@@ -87,24 +136,36 @@ static void *upper_lookup(u32 addr, u8 **mem_end, int *stride_override)
 
 static void blitter_do(void)
 {
-  u8 *dst, *dste, *src, *srce;
+  u8 *dst, *dste, *src = NULL, *srce = NULL;
   int w, h, sstrd, dstrd;
-
-  if (blitter.srcaddr == blitter.dstaddr)
-    return; // dummy blit?
+  u32 addr;
 
   w = blitter.size & 0x7ff;
   h = (blitter.size >> 16) & 0x7ff;
   sstrd = blitter.srcstride;
   dstrd = blitter.dststride;
 
-  dst = upper_lookup(blitter.dstaddr, &dste, &dstrd);
-  src = upper_lookup(blitter.srcaddr, &srce, &sstrd);
-
-  if (dst == NULL || src == NULL) {
-    printf("blit %08x->%08x %dx%d translated to %p->%p\n",
-      blitter.srcaddr, blitter.dstaddr, w, h, src, dst);
-    return;
+  // XXX: need to confirm this..
+  addr = (blitter.dstaddr & ~3) | ((blitter.dstctrl & 0x1f) >> 3);
+  dst = upper_lookup(addr, &dste, &dstrd);
+  if (dst == NULL)
+    goto bad_blit;
+
+  // XXX: assume fill if no SRCENB, but it could be pattern blit..
+  if (blitter.srcctrl & SRCCTRL_SRCENB) {
+    if (!(blitter.srcctrl & SRCCTRL_INVIDEO))
+      goto bad_blit;
+
+    addr = (blitter.srcaddr & ~3) | ((blitter.srcctrl & 0x1f) >> 3);
+    src = upper_lookup(addr, &srce, &sstrd);
+    if (src == NULL)
+      goto bad_blit;
+
+    if (src + sstrd * h > srce) {
+      printf("blit %08x->%08x %dx%d did not fit src\n",
+        blitter.srcaddr, blitter.dstaddr, w, h);
+      h = (srce - src) / sstrd;
+    }
   }
 
   if (dst + dstrd * h > dste) {
@@ -113,14 +174,30 @@ static void blitter_do(void)
     h = (dste - dst) / dstrd;
   }
 
-  if (src + sstrd * h > srce) {
-    printf("blit %08x->%08x %dx%d did not fit src\n",
-      blitter.srcaddr, blitter.dstaddr, w, h);
-    h = (srce - src) / sstrd;
+  if (src != NULL) {
+    // copy
+    if (blitter.ctrl & CTRL_TRANSPARENCYENB) {
+      u32 trc = blitter.ctrl >> 16;
+      for (; h > 0; h--, dst += dstrd, src += sstrd)
+        blt_tr(dst, src, trc, w);
+    }
+    else {
+      for (; h > 0; h--, dst += dstrd, src += sstrd)
+        memcpy(dst, src, w * 2);
+    }
   }
+  else {
+    // fill. Assume the pattern is cleared and bg color is used
+    u32 bgc = blitter.patbackcolor & 0xffff;
+    for (; h > 0; h--, dst += dstrd)
+      memset16(dst, bgc, w);
+  }
+  return;
 
-  for (; h > 0; h--, dst += dstrd, src += sstrd)
-    memcpy(dst, src, w * 2);
+bad_blit:
+  printf("blit %08x->%08x %dx%d translated to %p->%p\n",
+    blitter.srcaddr, blitter.dstaddr, w, h, src, dst);
+  dump_blitter();
 }
 
 static u32 xread8(u32 a)
@@ -165,7 +242,7 @@ static void xwrite16(u32 a, u32 d)
       case 0x2912: mmsp2.mlc_stl_eadrl = d; break;
       case 0x2914: mmsp2.mlc_stl_eadrh = d; break;
     }
-    printf("w16 %08x %08x\n", a, d);
+    //printf("w16 %08x %08x\n", a, d);
   }
 }
 
@@ -353,7 +430,7 @@ static void segv_sigaction(int num, siginfo_t *info, void *ctx)
     signal(num, SIG_DFL);
     raise(num);
   }
-  printf("segv %d %p @ %08x\n", info->si_code, info->si_addr, regs[15]);
+  segvlog("segv %d %p @ %08x\n", info->si_code, info->si_addr, regs[15]);
 
   // spit PC and op
   pc_ptr = g_code_ptr++;
@@ -383,7 +460,7 @@ static void segv_sigaction(int num, siginfo_t *info, void *ctx)
   sys_cacheflush(g_linkpage, g_code_ptr);
 
   lp_size = (char *)g_code_ptr - (char *)g_linkpage;
-  printf("code #%d %d/%d\n", g_linkpage_count, lp_size, LINKPAGE_SIZE);
+  segvlog("code #%d %d/%d\n", g_linkpage_count, lp_size, LINKPAGE_SIZE);
 
   if (lp_size + 13*4 > LINKPAGE_SIZE) {
     g_linkpage_count++;
index dc9edf8..ccbaadf 100644 (file)
@@ -10,6 +10,8 @@
 #include "header.h"
 #include "sys_cacheflush.h"
 
+#define strace(...)
+
 static const unsigned int sig_open[] = {
   0xe59cc000, 0xe33c0000, 0x1a000003, 0xef900005
 };
@@ -40,7 +42,7 @@ static int w_open(const char *pathname, int flags, mode_t mode)
   else
     ret = open(pathname, flags, mode);
 
-  printf("open(%s) = %d\n", pathname, ret);
+  strace("open(%s) = %d\n", pathname, ret);
   return ret;
 }
 
@@ -52,7 +54,7 @@ static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_
   else
     ret = emu_mmap_dev(length, prot, flags, offset);
 
-  printf("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
+  strace("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
   return ret;
 }
 #define w_mmap_ w_mmap