32x, add support for h32 mode rendering
authorkub <derkub@gmail.com>
Mon, 22 Nov 2021 18:18:12 +0000 (19:18 +0100)
committerkub <derkub@gmail.com>
Mon, 22 Nov 2021 18:18:49 +0000 (19:18 +0100)
pico/32x/32x.c
pico/32x/draw.c
pico/32x/draw_arm.S
pico/draw.c
pico/draw_arm.S
pico/pico.h

index a34e807..a674fb6 100644 (file)
@@ -230,7 +230,6 @@ static void p32x_start_blank(void)
 
     // XXX: no proper handling of 32col mode..
     if ((Pico32x.vdp_regs[0] & P32XV_Mx) != 0 && // 32x not blanking
-        (Pico.video.reg[12] & 1) && // 40col mode
         (!(Pico.video.debug_p & PVD_KILL_32X)))
     {
       int md_bg = Pico.video.reg[7] & 0x3f;
@@ -238,7 +237,7 @@ static void p32x_start_blank(void)
       // we draw full layer (not line-by-line)
       PicoDraw32xLayer(offs, lines, md_bg);
     }
-    else if (Pico32xDrawMode != PDM32X_32X_ONLY)
+    else if (Pico32xDrawMode == PDM32X_BOTH)
       PicoDraw32xLayerMdOnly(offs, lines);
 
     pprof_end(draw);
index 5143af8..adc5165 100644 (file)
@@ -8,6 +8,14 @@
  */
 #include "../pico_int.h"
 
+// NB: 32X officially doesn't support H32 mode. However, it does work since the
+// cartridge slot carries the EDCLK signal which is always H40 clock and is used
+// as video clock by the 32X. The H32 MD image is overlayed with the 320 px 32X
+// image which has the same on-screen width. How the /YS signal on the cartridge
+// slot (signalling the display of background color) is processed in this case
+// is however unclear and might lead to glitches due to race conditions by the
+// different video clocks for H32 and H40.
+
 // BGR555 to native conversion
 #if defined(USE_BGR555)
 #define PXCONV(t)   ((t)&(mr|mg|mb|mp))
@@ -122,8 +130,6 @@ void FinalizeLine32xRGB555(int sh, int line, struct PicoEState *est)
   FinalizeLine555(sh, line, est);
 
   if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 0 || // 32x blanking
-      // XXX: how is 32col mode handled by real hardware?
-      !(Pico.video.reg[12] & 1) || // 32col mode
       (Pico.video.debug_p & PVD_KILL_32X))
   {
     return;
@@ -310,14 +316,6 @@ void PicoDraw32xLayerMdOnly(int offs, int lines)
   int poffs = 0, plen = 320;
   int l, p;
 
-  if (!(Pico.video.reg[12] & 1)) {
-    // 32col mode. for some render modes MD pixel data carries an offset
-    if (!(PicoIn.opt & POPT_DIS_32C_BORDER))
-      pmd += 32;
-    poffs = 32;
-    plen = 256;
-  }
-
   PicoDrawUpdateHighPal();
 
   dst += poffs;
@@ -350,6 +348,8 @@ void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode)
     PicoDrawSetInternalBuf(NULL, 0);
     PicoDrawSetOutBufMD(Pico.est.Draw2FB, 328);
   }
+  // always need upscaling for H32, before mixing in 32X layer
+  PicoIn.opt |= POPT_EN_SOFTSCALE;
 
   if (use_32x_line_mode)
     // we'll draw via FinalizeLine32xRGB555 (rare)
index e226d2a..5c19329 100644 (file)
@@ -57,7 +57,7 @@
     add     r0, r0, r4
     mov     lr, pc
     ldr     pc, [sp, #(4+1)*4]
-    ldr     r1, [sp, #(3+2)*4] @ &Pico.est
+    ldr     r1, [sp, #(4+2)*4] @ &Pico.est
     ldr     r0, [r1, #OFS_EST_DrawLineDest]
     ldr     r2, [r1, #OFS_EST_DrawLineDestIncr]
     add     r0, r0, r2
index 6dce27c..bf4ef38 100644 (file)
@@ -1652,14 +1652,18 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
   else                                  len = 256;\r
 \r
   if ((*est->PicoOpt & POPT_EN_SOFTSCALE) && len < 320) {\r
-    if (len == 256)\r
+    if (len == 256) {\r
       switch (PicoIn.filter) {\r
       case 3: h_upscale_bl4_4_5(pd, 320, ps, 256, len, f_pal); break;\r
       case 2: h_upscale_bl2_4_5(pd, 320, ps, 256, len, f_pal); break;\r
       case 1: h_upscale_snn_4_5(pd, 320, ps, 256, len, f_pal); break;\r
       default: h_upscale_nn_4_5(pd, 320, ps, 256, len, f_pal); break;\r
       }\r
-    else if (len == 160)\r
+      if (est->rendstatus & PDRAW_32X_SCALE) { // 32X needs scaled CLUT data\r
+        unsigned char *psc = ps - 256, *pdc = psc;\r
+        rh_upscale_nn_4_5(pdc, 320, psc, 256, 256, f_nop);\r
+      }\r
+    } else if (len == 160)\r
       switch (PicoIn.filter) {\r
       case 3:\r
       case 2: h_upscale_bl2_1_2(pd, 320, ps, 160, len, f_pal); break;\r
@@ -1886,6 +1890,8 @@ PICO_INTERNAL void PicoFrameStart(void)
     Pico.est.rendstatus |= PDRAW_SKIP_FRAME;\r
   if (sprep | skipped)\r
     Pico.est.rendstatus |= PDRAW_PARSE_SPRITES;\r
+  if (PicoIn.AHW & PAHW_32X)\r
+    Pico.est.rendstatus |= PDRAW_32X_SCALE;\r
 \r
   Pico.est.HighCol = HighColBase + loffs * HighColIncrement;\r
   Pico.est.DrawLineDest = (char *)DrawLineDestBase + loffs * DrawLineDestIncrement;\r
index a991563..11d0171 100644 (file)
@@ -21,6 +21,7 @@
 .equ PDRAW_DIRTY_SPRITES, (1<<4)\r
 .equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
 .equ PDRAW_SHHI_DONE,     (1<<7)\r
+.equ PDRAW_32X_SCALE,     (1<<12)\r
 \r
 @ helpers\r
 .macro add_c24 d s c\r
@@ -1633,20 +1634,20 @@ PicoDoHighPal555_end:
 .global FinalizeLine555\r
 \r
 FinalizeLine555:\r
-    stmfd   sp!, {r4-r10,lr}\r
-    mov     r10,r2               @ est\r
-    ldr     r8, [r10, #OFS_EST_Pico]\r
+    stmfd   sp!, {r4-r11,lr}\r
+    mov     r11,r2               @ est\r
+    ldr     r8, [r11, #OFS_EST_Pico]\r
 \r
     bl      PicoDrawUpdateHighPal\r
 \r
-    add     r3, r10, #OFS_EST_HighPal\r
+    add     r3, r11, #OFS_EST_HighPal\r
 \r
     mov     lr, #0xff\r
     mov     lr, lr, lsl #1\r
 \r
-    ldr     r5, [r10, #OFS_EST_PicoOpt]\r
-    ldr     r1, [r10, #OFS_EST_HighCol]\r
-    ldr     r0, [r10, #OFS_EST_DrawLineDest]\r
+    ldr     r5, [r11, #OFS_EST_PicoOpt]\r
+    ldr     r1, [r11, #OFS_EST_HighCol]\r
+    ldr     r0, [r11, #OFS_EST_DrawLineDest]\r
     ldr     r4, [r5]\r
     ldr     r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]\r
     ldrb    r12,[r8, #OFS_Pico_video_reg+12]\r
@@ -1716,7 +1717,7 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r8,r12}\r
     bne     .fl_loopRGB555\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    ldmfd   sp!, {r4-r11,pc}\r
 \r
 \r
 .fl_32scale_RGB555:\r
@@ -1773,7 +1774,7 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r6,r8,r10}\r
     bne     .fl_32scale_nn\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    b       .fl_32scale_8bit\r
 \r
 .fl_32scale_snn:\r
     ldr     r12, [r1], #4\r
@@ -1822,7 +1823,7 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r6,r8,r10}\r
     bne     .fl_32scale_snn\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    b       .fl_32scale_8bit\r
 \r
 .fl_32scale_bl2:\r
     ldr     r12, [r1], #4\r
@@ -1878,7 +1879,7 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r6,r8,r10}\r
     bne     .fl_32scale_bl2\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    b       .fl_32scale_8bit\r
 \r
 .fl_32scale_bl4:\r
     // TODO this should reflect the bl4 C algorithm, but it doesn't, it's bln.\r
@@ -1946,7 +1947,48 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r6,r8,r10}\r
     bne     .fl_32loop_bl4\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+.fl_32scale_8bit:\r
+    ldr     r4, [r11, #OFS_EST_rendstatus]\r
+    add     r0, r1, #320-256\r
+    mov     r2, #256/8\r
+    tst     r4, #PDRAW_32X_SCALE\r
+    ldmeqfd sp!, {r4-r11,pc}\r
+    mov     lr, #0xff\r
+\r
+.fl_32scale_8bit_nn:\r
+    ldr     r7,  [r1, #-4]!\r
+    ldr     r12, [r1, #-4]!\r
+\r
+    and     r4, lr, r12, lsl #0\r
+    and     r5, lr, r12, lsr #8\r
+    and     r6, lr, r12, lsr #16\r
+    and     r10,lr, r12, lsr #24\r
+    \r
+    orr     r4, r4, r5, lsl #8\r
+    orr     r5, r6, r6, lsl #8\r
+\r
+    and     r6, lr, r7, lsl #0\r
+    and     r8, lr, r7, lsr #8\r
+    and     r12,lr, r7, lsr #16\r
+    and     r7, lr, r7, lsr #24\r
+\r
+    orr     r6, r10,r6, lsl  #8\r
+    orr     r8, r8,r12, lsl #8\r
+\r
+    subs    r2, r2, #1\r
+\r
+    orr     r10,r12,r7, lsl #8\r
+\r
+    strh    r10, [r0, #-2]!\r
+    strh    r8, [r0, #-2]!\r
+    strh    r6, [r0, #-2]!\r
+    strh    r5, [r0, #-2]!\r
+    strh    r4, [r0, #-2]!\r
+\r
+    bne     .fl_32scale_8bit_nn\r
+\r
+    ldmfd   sp!, {r4-r11,pc}\r
+\r
 \r
 .fl_20scale_RGB555:\r
     ldr     r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]\r
@@ -2002,7 +2044,7 @@ FinalizeLine555:
     subs    r2, r2, #1\r
     bne     .fl_20scale_nn\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    ldmfd   sp!, {r4-r11,pc}\r
 \r
 \r
 .fl_20scale_bl2:\r
@@ -2082,7 +2124,7 @@ FinalizeLine555:
     stmia   r0!, {r4,r5,r6,r8}\r
     bne     .fl_20loop_bl2\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    ldmfd   sp!, {r4-r11,pc}\r
 \r
 \r
 #ifdef UNALIGNED_DRAWLINEDEST\r
@@ -2128,7 +2170,7 @@ FinalizeLine555:
 \r
     strh    r8, [r0], #2\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    ldmfd   sp!, {r4-r11,pc}\r
 \r
 \r
 .fl_32scale_RGB555u:\r
@@ -2193,7 +2235,7 @@ FinalizeLine555:
 \r
     strh    r4, [r0], #2\r
 \r
-    ldmfd   sp!, {r4-r10,pc}\r
+    ldmfd   sp!, {r4-r11,pc}\r
 \r
 #endif /* UNALIGNED_DRAWLINEDEST */\r
 \r
index 5102107..b35ce2f 100644 (file)
@@ -223,6 +223,7 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
 #define PDRAW_BORDER_32     (1<<9) // center H32 in buffer (32 px border)\r
 #define PDRAW_SKIP_FRAME   (1<<10) // frame is skipped\r
 #define PDRAW_30_ROWS      (1<<11) // 30 rows mode (240 lines)\r
+#define PDRAW_32X_SCALE    (1<<12) // scale CLUT layer for 32X\r
 extern int rendstatus_old;\r
 extern int rendlines;\r
 \r