gpu_unai: add 4bpp asm sprite blitter
authornotaz <notasas@gmail.com>
Tue, 20 Dec 2011 00:38:53 +0000 (02:38 +0200)
committernotaz <notasas@gmail.com>
Tue, 20 Dec 2011 21:40:51 +0000 (23:40 +0200)
plugins/gpu_neon/Makefile
plugins/gpu_unai/Makefile
plugins/gpu_unai/gpu_arm.h [new file with mode: 0644]
plugins/gpu_unai/gpu_arm.s [new file with mode: 0644]
plugins/gpu_unai/gpu_command.h
plugins/gpu_unai/gpu_raster_sprite.h

index f227752..66a2bd5 100644 (file)
@@ -6,6 +6,9 @@ ARCH = $(shell $(CC) -v 2>&1 | grep -i 'target:' | awk '{print $$2}' | awk -F '-
 
 CFLAGS += -ggdb -Wall -fPIC -O2
 CFLAGS += -fno-strict-aliasing
+ifdef MAEMO
+CFLAGS += -DMAEMO
+endif
 
 SRC += gpu.c
 ifeq "$(ARCH)" "arm"
@@ -38,7 +41,7 @@ gpu_neon.$(EXT): SRC += psx_gpu_if.c
 gpu_neon.$(EXT): CFLAGS += -fno-strict-aliasing
 gpu_peops.$(EXT): SRC += peops_if.c
 gpu_peops.$(EXT): CFLAGS += -fno-strict-aliasing
-gpu_unai.$(EXT): SRC += unai_if.cpp
+gpu_unai.$(EXT): SRC += unai_if.cpp ../gpu_unai/gpu_arm.s
 gpu_unai.$(EXT): CC_ = $(CXX)
 
 all: $(TARGETS)
index 531c9fb..e4b6e6b 100644 (file)
@@ -16,7 +16,7 @@ CFLAGS += -mcpu=arm926ej-s -mtune=arm926ej-s
 SRC += ../../frontend/cspace.c
 endif
 
-SRC += gpu.cpp
+SRC += gpu.cpp gpu_arm.s
 
 TARGET = gpuPCSX4ALL.so
 LDFLAGS += -shared -Wl,-soname,$(TARGET)
diff --git a/plugins/gpu_unai/gpu_arm.h b/plugins/gpu_unai/gpu_arm.h
new file mode 100644 (file)
index 0000000..a0b2248
--- /dev/null
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void draw_spr16_full(u16 *d, void *s, u16 *pal, int lines);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/plugins/gpu_unai/gpu_arm.s b/plugins/gpu_unai/gpu_arm.s
new file mode 100644 (file)
index 0000000..a2fa174
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * (C) GraÅžvydas "notaz" Ignotas, 2011
+ *
+ * This work is licensed under the terms of  GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+
+.text
+.align 2
+
+@ in: r0=dst, r2=pal, r12=0x1e
+@ trashes r6-r8,lr,flags
+.macro do_4_pixels rs ibase obase
+.if \ibase - 1 < 0
+    and     r6, r12, \rs, lsl #1
+.else
+    and     r6, r12, \rs, lsr #\ibase-1
+.endif
+    and     r7, r12, \rs, lsr #\ibase+3
+    and     r8, r12, \rs, lsr #\ibase+7
+    and     lr, r12, \rs, lsr #\ibase+11
+    ldrh    r6, [r2, r6]
+    ldrh    r7, [r2, r7]
+    ldrh    r8, [r2, r8]
+    ldrh    lr, [r2, lr]
+    tst     r6, r6
+    strneh  r6, [r0, #\obase+0]
+    tst     r7, r7
+    strneh  r7, [r0, #\obase+2]
+    tst     r8, r8
+    strneh  r8, [r0, #\obase+4]
+    tst     lr, lr
+    strneh  lr, [r0, #\obase+6]
+.endm
+
+.global draw_spr16_full @ (u16 *d, void *s, u16 *pal, int lines)
+draw_spr16_full:
+    stmfd   sp!, {r4-r8,lr}
+    mov     r12, #0x1e             @ empty pixel
+
+0:
+    ldmia   r1, {r4,r5}
+    do_4_pixels r4, 0,  0
+    do_4_pixels r4, 16, 8
+    do_4_pixels r5, 0,  16
+    do_4_pixels r5, 16, 24
+    subs    r3, #1
+    add     r0, #2048
+    add     r1, #2048
+    bgt     0b
+
+    ldmfd   sp!, {r4-r8,pc}
+
+@ vim:filetype=armasm
index d380dae..049b146 100644 (file)
@@ -352,6 +352,16 @@ void gpuSendPacketFunction(const int PRIM)
                        break;
                case 0x7C:
                case 0x7D:
+#ifdef __arm__
+                       if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0)
+                       {
+                               gpuSetCLUT    (PacketBuffer.U4[2] >> 16);
+                               gpuSetTexture (GPU_GP1);
+                               gpuDrawS16();
+                               break;
+                       }
+                       // fallthrough
+#endif
                case 0x7E:
                case 0x7F:
                        if (!isSkip)
index 041fcbd..5075227 100644 (file)
@@ -84,6 +84,47 @@ void gpuDrawS(const PS gpuSpriteSpanDriver)
        }
 }
 
+#ifdef __arm__
+#include "gpu_arm.h"
+
+void gpuDrawS16(void)
+{
+       s32 x0, y0;
+       s32 u0, v0;
+       s32 xmin, xmax;
+       s32 ymin, ymax;
+       u32 h = 16;
+
+       x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0];
+       y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1];
+
+       xmin = DrawingArea[0];  xmax = DrawingArea[2];
+       ymin = DrawingArea[1];  ymax = DrawingArea[3];
+       u0 = PacketBuffer.U1[8];
+       v0 = PacketBuffer.U1[9];
+
+       if (x0 > xmax - 16 || x0 < xmin ||
+           ((u0 | v0) & 15) || !(TextureWindow[2] & TextureWindow[3] & 8)) {
+               // send corner cases to general handler
+               PacketBuffer.U4[3] = 0x00100010;
+               gpuDrawS(gpuSpriteSpanFn<0x20>);
+               return;
+       }
+
+       if (y0 >= ymax || y0 <= ymin - 16)
+               return;
+       if (y0 < ymin) {
+               h -= ymin - y0;
+               v0 += ymin - y0;
+               y0 = ymin;
+       }
+       else if (ymax - y0 < 16)
+               h = ymax - y0;
+
+       draw_spr16_full(&GPU_FrameBuffer[FRAME_OFFSET(x0, y0)], &TBA[FRAME_OFFSET(u0/4, v0)], CBA, h);
+}
+#endif // __arm__
+
 ///////////////////////////////////////////////////////////////////////////////
 void gpuDrawT(const PT gpuTileSpanDriver)
 {