3 static void (*FinalizeLineM4)(void);
4 static int skip_next_line;
6 #define PLANAR_PIXEL(x,p) \
7 t = pack & (0x80808080 >> p); \
9 t = ((t >> (7-p)) | (t >> (14-p)) | (t >> (21-p)) | (t >> (28-p))) & 0x0f; \
13 static int TileNormM4(int sx, int addr, int pal)
15 unsigned char *pd = HighCol + sx;
18 pack = *(unsigned int *)(Pico.vram + addr); /* Get 4 bitplanes / 8 pixels */
32 return 1; /* Tile blank */
35 static int TileFlipM4(int sx,int addr,int pal)
37 unsigned char *pd = HighCol + sx;
40 pack = *(unsigned int *)(Pico.vram + addr); /* Get 4 bitplanes / 8 pixels */
54 return 1; /* Tile blank */
59 int nametab; // Position in VRAM of name table (for this tile line)
60 int line; // Line number in pixels 0x000-0x3ff within the virtual tilemap
61 int hscroll; // Horizontal scroll value in pixels for the line
62 int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap
63 int *hc; // cache for high tile codes and their positions
64 int cells; // cells (tiles) to draw (32 col mode doesn't need to update whole 320)
67 static void DrawStrip(struct TileStrip *ts, int cellskip)
69 int tilex,dx,ty,code=0,addr=0,cells;
70 int oldcode=-1,blank=-1; // The tile we know is blank
73 // Draw tiles across screen:
74 tilex=((-ts->hscroll)>>3)+cellskip;
75 ty=(ts->line&7)<<1; // Y-Offset into tile
76 dx=((ts->hscroll-1)&7)+1;
77 cells = ts->cells - cellskip;
78 if (dx != 8) cells++; // have hscroll, need to draw 1 cell more
81 for (; cells > 0; dx+=8,tilex++,cells--)
85 code=Pico.vram[ts->nametab + (tilex & 0x1f)];
86 if (code==blank) continue;
90 // Get tile address/2:
93 if (code&0x0400) addr^=0xe; // Y-flip
98 if (code&0x0200) zero=TileFlipM4(dx,addr,pal);
99 else zero=TileNormM4(dx,addr,pal);
101 if (zero) blank=code; // We know this tile is blank now
105 static void DrawLayer(int cellskip, int maxcells)
107 struct PicoVideo *pvid=&Pico.video;
114 ts.nametab=(pvid->reg[2]&0x0e) << (10-1);
116 // Get horizontal scroll value, will be masked later
117 ts.hscroll=0;//pvid->reg[8];
118 vscroll=0;//pvid->reg[9]; // Get vertical scroll value
120 // Find the line in the name table
121 ts.line=(vscroll+DrawScanline)&0xff;
122 ts.nametab+=(ts.line>>3) << (6-1);
124 DrawStrip(&ts, cellskip);
127 static void DrawDisplayM4(void)
132 void PicoFrameStartMode4(void)
138 void PicoLineMode4(int line)
140 if (skip_next_line > 0) {
147 if (PicoScanBegin != NULL)
148 skip_next_line = PicoScanBegin(DrawScanline);
151 BackFill((Pico.video.reg[7] & 0x0f) | 0x10, 0);
152 if (Pico.video.reg[1] & 0x40)
155 if (FinalizeLineM4 != NULL)
158 if (PicoScanEnd != NULL)
159 skip_next_line = PicoScanEnd(DrawScanline);
162 void PicoDoHighPal555M4(void)
164 unsigned int *spal=(void *)Pico.cram;
165 unsigned int *dpal=(void *)HighPal;
171 /* cram is always stored as shorts, even though real hardware probably uses bytes */
172 for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
175 t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)<<10);
177 t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1);
180 t |= (t >> 4) & 0x08610861;
185 static void FinalizeLineRGB555M4(void)
187 unsigned short *pd=DrawLineDest;
188 unsigned char *ps=HighCol+8;
189 unsigned short *pal=HighPal;
193 PicoDoHighPal555M4();
195 if (!(PicoOpt & POPT_DIS_32C_BORDER))
198 for (i = 256/4; i > 0; i--) {
206 void PicoDrawSetColorFormatMode4(int which)
210 case 1: FinalizeLineM4 = FinalizeLineRGB555M4; break;
211 default:FinalizeLineM4 = NULL; break;
215 HighCol = DefHighCol;