*/
#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))
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;
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;
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)
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
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
.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
.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
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
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
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
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
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
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
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
\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
\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