vdp renderer, partial sync 8bit fast ARM asm with C code
authorkub <derkub@gmail.com>
Thu, 21 Jan 2021 18:09:17 +0000 (19:09 +0100)
committerkub <derkub@gmail.com>
Thu, 21 Jan 2021 18:09:17 +0000 (19:09 +0100)
pico/draw2.c
pico/draw2_arm.S
pico/pico_int.h
tools/mkoffsets.sh

index 9d65ea5..1e27af3 100644 (file)
@@ -34,7 +34,7 @@ void (*PicoPrepareCram)()=0;            // prepares PicoCramHigh for renderer to
 \r
 // stuff available in asm:\r
 #ifdef _ASM_DRAW_C\r
-void BackFillFull(void *dst, int reg7);\r
+void BackFillFull(void *dst, int reg7, int lwidth);\r
 void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,\r
                    struct PicoEState *est);\r
 void DrawTilesFromCacheF(u32 *hc, struct PicoEState *est);\r
@@ -183,7 +183,7 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
        nametab += nametab_step*(start-scrstart);\r
 \r
        // check priority\r
-       code=PicoMem.vram[nametab+tile_start];\r
+       code=est->PicoMem_vram[nametab+tile_start];\r
        if ((code>>15) != prio) return; // hack: just assume that whole window uses same priority\r
 \r
        scrpos+=8*est->Draw2Width+8;\r
@@ -197,7 +197,7 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
 //                     unsigned short *pal=NULL;\r
                        unsigned char pal;\r
 \r
-                       code=PicoMem.vram[nametab+tilex];\r
+                       code=est->PicoMem_vram[nametab+tilex];\r
                        if (code==blank) continue;\r
 \r
                        // Get tile address/2:\r
@@ -250,7 +250,7 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
 \r
        if(!(pvid->reg[11]&3)) { // full screen scroll\r
                // Get horizontal scroll value\r
-               hscroll=PicoMem.vram[htab&0x7fff];\r
+               hscroll=est->PicoMem_vram[htab&0x7fff];\r
                htab = 0; // this marks that we don't have to update scroll value\r
        }\r
 \r
@@ -297,7 +297,7 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
                if(htab) {\r
                        int htaddr=htab+(trow<<4);\r
                        if(trow) htaddr-=(vscroll&7)<<1;\r
-                       hscroll=PicoMem.vram[htaddr&0x7fff];\r
+                       hscroll=est->PicoMem_vram[htaddr&0x7fff];\r
                }\r
 \r
                // Draw tiles across screen:\r
@@ -323,7 +323,7 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
 #endif\r
                        vsidx++;\r
 \r
-                       code=PicoMem.vram[nametab_row+(tilex&xmask)];\r
+                       code=est->PicoMem_vram[nametab_row+(tilex&xmask)];\r
                        if (code==blank) continue;\r
 \r
                        if (code>>15) { // high priority tile\r
@@ -442,18 +442,19 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        pal=(unsigned char)((code>>9)&0x30);\r
 \r
        // goto first vertically visible tile\r
-       while(sy <= scrstart*8) { sy+=8; tile+=tdeltay; height--; }\r
+       sy -= scrstart*8;\r
+       while(sy <= 0) { sy+=8; tile+=tdeltay; height--; }\r
 \r
        scrpos = est->Draw2FB;\r
        if (est->rendstatus&PDRAW_BORDER_32)\r
                scrpos += 32;\r
-       scrpos+=(sy-scrstart*8)*est->Draw2Width;\r
+       scrpos+=sy*est->Draw2Width;\r
 \r
        for (; height > 0; height--, sy+=8, tile+=tdeltay)\r
        {\r
                int w = width, x=sx, t=tile, s;\r
 \r
-               if((sy-scrstart*8) >= END_ROW*8+8) return; // offscreen\r
+               if(sy >= END_ROW*8+8) return; // offscreen\r
 \r
                for (; w; w--,x+=8,t+=tdeltax)\r
                {\r
@@ -502,7 +503,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth, struct PicoEState *est)
                unsigned int *sprite=NULL;\r
                int code, code2, sx, sy, height;\r
 \r
-               sprite=(u32 *)(PicoMem.vram+((table+(link<<2))&0x7ffc)); // Find sprite\r
+               sprite=(u32 *)(est->PicoMem_vram+((table+(link<<2))&0x7ffc)); // Find sprite\r
 \r
                // get sprite info\r
                code = sprite[0];\r
@@ -559,16 +560,18 @@ static void DrawAllSpritesFull(int prio, int maxwidth, struct PicoEState *est)
 }\r
 \r
 #ifndef _ASM_DRAW_C\r
-static void BackFillFull(void *dst, int reg7)\r
+static void BackFillFull(unsigned char *dst, int reg7, int lwidth)\r
 {\r
        unsigned int back;\r
+       int i;\r
 \r
        // Start with a background color:\r
        back=reg7&0x3f;\r
        back|=back<<8;\r
        back|=back<<16;\r
 \r
-       memset32(dst, back, Pico.est.Draw2Width*(8+(END_ROW-START_ROW)*8)/4);\r
+       for (i = 0, dst += 8*lwidth; i < (END_ROW-START_ROW)*8; i++, dst += lwidth)\r
+               memset32(dst+8, back, 320/4);\r
 }\r
 #endif\r
 \r
@@ -589,19 +592,19 @@ static void DrawDisplayFull(void)
        }\r
        if(est->rendstatus & PDRAW_30_ROWS) {\r
                // In 240 line mode, the top and bottom 8 lines are omitted\r
-               // since this renderer always renderers 224 lines\r
+               // since this renderer always renders 224 lines\r
                scrstart ++, scrend ++;\r
        }\r
        est->Draw2Start = scrstart;\r
 \r
-       planestart = scrstart, planeend = scrend;\r
-       winstart = scrstart, winend = scrend;\r
-\r
        // 32C border for centering? (for asm)\r
        est->rendstatus &= ~PDRAW_BORDER_32;\r
        if ((est->rendstatus&PDRAW_32_COLS) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
                est->rendstatus |= PDRAW_BORDER_32;\r
 \r
+       planestart = scrstart, planeend = scrend;\r
+       winstart = scrstart, winend = scrend;\r
+\r
        // horizontal window?\r
        if ((win=pvid->reg[0x12]))\r
        {\r
@@ -716,7 +719,7 @@ PICO_INTERNAL void PicoFrameFull()
        if (PicoPrepareCram) PicoPrepareCram();\r
 \r
        // Draw screen:\r
-       BackFillFull(Pico.est.Draw2FB, Pico.video.reg[7]);\r
+       BackFillFull(Pico.est.Draw2FB, Pico.video.reg[7], Pico.est.Draw2Width);\r
        if (Pico.video.reg[1] & 0x40)\r
                DrawDisplayFull();\r
 \r
index ded0d5a..3101a82 100644 (file)
@@ -6,10 +6,17 @@
  * See COPYING file in the top-level directory.\r
  *\r
  * this is highly specialized, be careful if changing related C code!\r
+ *\r
+ * NB: this only deals with buffers having line width at 328\r
  */\r
 \r
 #include "pico_int_offs.h"\r
 \r
+.equ PDRAW_INTERLACE,  (1<<3)\r
+.equ PDRAW_32_COLS,    (1<<8)\r
+.equ PDRAW_BORDER_32,  (1<<9)\r
+.equ PDRAW_30_ROWS,    (1<<11)\r
+\r
 @ define these constants in your include file:\r
 @ .equiv START_ROW,            1\r
 @ .equiv END_ROW,              27\r
 .text\r
 .align 2\r
 \r
-@ void BackFillFull(void *dst, int reg7)\r
+@ void BackFillFull(unsigned char *dst, int reg7, int lwidth)\r
 \r
 .global BackFillFull\r
 \r
 BackFillFull:\r
-    stmfd   sp!, {r4-r9,lr}\r
+    stmfd   sp!, {r4-r10,lr}\r
+\r
+    sub     r10,r2, #320 @ unused bytes in a line\r
+    add     lr, r0, #8  @ 8 px overlap area at start of line\r
+    add     lr, lr, r2, lsl #3 @ 8 lines overlap area at top\r
 \r
-    add     lr, r0, #328*8\r
     mov     r0, r1, lsl #26\r
     mov     r0, r0, lsr #26\r
 \r
@@ -52,7 +62,6 @@ BackFillFull:
 \r
     @ go go go!\r
 .bff_loop:\r
-    add     lr, lr, #8\r
     subs    r12, r12, #1\r
 \r
     stmia   lr!, {r0-r9} @ 10*4*8\r
@@ -64,9 +73,10 @@ BackFillFull:
     stmia   lr!, {r0-r9}\r
     stmia   lr!, {r0-r9}\r
 \r
+    add     lr, lr, r10 @ skip unused rest of line\r
     bne     .bff_loop\r
 \r
-    ldmfd   sp!, {r4-r9,lr}\r
+    ldmfd   sp!, {r4-r10,lr}\r
     bx      lr\r
 \r
 .pool\r
@@ -413,14 +423,15 @@ DrawLayerFull:
     orr     lr, lr, r4, lsl #13   @ lr|=nametab_bits{3}<<13\r
 \r
     ldr     r11,[sp, #9*4]        @ est\r
-    sub     r4, r9, #(START_ROW<<24)\r
+    ldr     r4, [r11, #OFS_EST_Draw2Start]\r
     ldr     r7, [r11, #OFS_EST_rendstatus]\r
     ldr     r11, [r11, #OFS_EST_Draw2FB]\r
-    tst     r7, #0x100            @ H32 border mode?\r
+    sub     r4, r9, r4, lsl #24\r
+    tst     r7, #PDRAW_BORDER_32  @ H32 border mode?\r
     addne   r11, r11, #32\r
     mov     r4, r4, asr #24\r
     mov     r7, #328*8\r
-    mla     r11, r4, r7, r11      @ scrpos+=8*328*(planestart-START_ROW);\r
+    mla     r11, r4, r7, r11      @ scrpos+=8*328*(planestart-Draw2Start);\r
 \r
     @ Get vertical scroll value:\r
     add_c24 r7, r10, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
@@ -588,15 +599,16 @@ DrawLayerFull:
 .global DrawTilesFromCacheF\r
 \r
 DrawTilesFromCacheF:\r
-    stmfd   sp!, {r4-r10,lr}\r
+    stmfd   sp!, {r4-r11,lr}\r
 \r
     mov     r9, #0xff000000 @ r9=prevcode=-1\r
     mvn     r6, #0          @ r6=prevy=-1\r
 \r
     ldr     r7, [r1, #OFS_EST_rendstatus]\r
     ldr     r4, [r1, #OFS_EST_Draw2FB]\r
+    ldr     r11,[r1, #OFS_EST_Draw2Start]\r
     ldr     r2, [r0], #4    @ read y offset\r
-    tst     r7, #0x100      @ H32 border mode?\r
+    tst     r7, #PDRAW_BORDER_32 @ H32 border mode?\r
     addne   r4, r4, #32\r
     mov     r7, #328\r
     mla     r2, r7, r2, r4\r
@@ -612,13 +624,14 @@ DrawTilesFromCacheF:
 .dtfcf_loop:\r
     ldr     r7, [r8], #4    @ read code\r
     movs    r1, r7, lsr #16 @ r1=dx;\r
-    ldmeqfd sp!, {r4-r10,pc} @ dx is never zero, this must be a terminator, return\r
+    ldmeqfd sp!, {r4-r11,pc} @ dx is never zero, this must be a terminator, return\r
 \r
     @ row changed?\r
     cmp     r6, r7, lsr #27\r
     movne   r6, r7, lsr #27\r
+    subne   r6, r6, r11\r
     movne   r4, #328*8\r
-    mlane   r5, r4, r6, r12 @ r5=pd = scrpos + prevy*328*8\r
+    mlane   r5, r4, r6, r12 @ r5=pd = scrpos + (prevy-Draw2Start)*328*8\r
 \r
     bic     r1, r1, #0xf800\r
     add     r1, r5, r1      @ r1=pdest (halfwords)\r
@@ -695,6 +708,7 @@ DrawWindowFull:
     ldr     r4, [r11, #OFS_Pico_video_reg+12]\r
     mov     r5, #1                @ nametab_step\r
     ldr     r11, [r3, #OFS_EST_Draw2FB]\r
+    ldr     r6, [r3, #OFS_EST_Draw2Start]\r
     tst     r4, #1                @ 40 cell mode?\r
     andne   r12, r12, #0xf000     @ 0x3c<<10\r
     movne   r5, r5, lsl #7\r
@@ -702,11 +716,12 @@ DrawWindowFull:
     ldr     r7, [r3, #OFS_EST_rendstatus]\r
     and     r12, r12, #0xf800\r
     mov     r5, r5, lsl #6        @ nametab_step\r
-    tst     r7, #0x100\r
+    tst     r7, #PDRAW_BORDER_32\r
     addne   r11, r11, #32         @ center screen in H32 mode\r
 \r
 0:  and     r4, r0, #0xff\r
-    mla     r12, r5, r4, r12      @ nametab += nametab_step*start;\r
+    sub     r4, r4, r6\r
+    mla     r12, r5, r4, r12      @ nametab += nametab_step*(start-Draw2Start];\r
 \r
     ldr     r10, [r3, #OFS_EST_PicoMem_vram]\r
     mov     r4, r0, lsr #16       @ r4=start_cell_h\r
@@ -728,11 +743,11 @@ DrawWindowFull:
 \r
     and     r4, r0, #0xff\r
     add     r11, r11, #328*8\r
-    sub     r4, r4, #START_ROW\r
+    sub     r4, r4, r6\r
     add     r11, r11, #8\r
 \r
     mov     r7, #328*8\r
-    mla     r11, r7, r4, r11      @ scrpos+=8*328*(start-START_ROW);\r
+    mla     r11, r7, r4, r11      @ scrpos+=8*328*(start-Draw2Start);\r
     mov     r0, #0xf\r
 \r
 .dwfloop_outer:\r
@@ -927,12 +942,13 @@ DrawSpriteFull:
 \r
     ldr     r0, [r1,  #OFS_EST_rendstatus]\r
     ldr     r11, [r1, #OFS_EST_Draw2FB]\r
+    ldr     r2, [r1,  #OFS_EST_Draw2Start]\r
     ldr     r10, [r1, #OFS_EST_PicoMem_vram]\r
-    tst     r0, #0x100      @ H32 border mode?\r
+    tst     r0, #PDRAW_BORDER_32  @ H32 border mode?\r
     addne   r11, r11, #32\r
-    sub     r1, r12, #(START_ROW*8)\r
+    sub     r12, r12, r2, lsl #3\r
     mov     r0, #328\r
-    mla     r11, r1, r0, r11      @ scrpos+=(sy-START_ROW*8)*328;\r
+    mla     r11, r12, r0, r11     @ scrpos+=(sy-Draw2Start*8)*328;\r
 \r
     orr     r5, r5, r5, lsl #16   @\r
     orr     r5, r6, r5, lsl #8    @ r5=width|(height<<8)|(height<<24)\r
index d66b67e..26fb60a 100644 (file)
@@ -355,8 +355,8 @@ struct PicoEState
   unsigned char *HighCol;\r
   u32 *HighPreSpr;\r
   struct Pico *Pico;\r
-  void *PicoMem_vram;\r
-  void *PicoMem_cram;\r
+  unsigned short *PicoMem_vram;\r
+  unsigned short *PicoMem_cram;\r
   unsigned int  *PicoOpt;\r
   unsigned char *Draw2FB;\r
   int Draw2Width;\r
index c347587..e45567f 100755 (executable)
@@ -144,6 +144,8 @@ get_define OFS_EST_ PicoEState PicoMem_vram ; echo "$line" >>$fn
 get_define OFS_EST_ PicoEState PicoMem_cram    ; echo "$line" >>$fn
 get_define OFS_EST_ PicoEState PicoOpt         ; echo "$line" >>$fn
 get_define OFS_EST_ PicoEState Draw2FB         ; echo "$line" >>$fn
+get_define OFS_EST_ PicoEState Draw2Width      ; echo "$line" >>$fn
+get_define OFS_EST_ PicoEState Draw2Start      ; echo "$line" >>$fn
 get_define OFS_EST_ PicoEState HighPal         ; echo "$line" >>$fn
 
 get_define OFS_PMEM_ PicoMem vram              ; echo "$line" >>$fn