1 /*
2   Hatari - macros.h
3 
4   Lookup tables and macros for screen conversion routines.
5 
6   This file is distributed under the GNU General Public License, version 2
7   or at your option any later version. Read the file gpl.txt for details.
8 */
9 
10 #ifndef HATARI_CONVERTMACROS_H
11 #define HATARI_CONVERTMACROS_H
12 
13 /* For palette we don't go from colour '0' as the whole background
14  * would change, so go from this value
15  */
16 #define  BASECOLOUR       0x0A
17 #define  BASECOLOUR_LONG  0x0A0A0A0A
18 
19 /* Remap tables to convert from plane format to byte-per-pixel
20  * (Upper is for 4-Planes so if shifted by 2)
21  */
22 static const Uint32 Remap_2_Planes[256] = {
23   0x00000000,  0x01000000,  0x00010000,  0x01010000,  0x00000100,  0x01000100,  0x00010100,  0x01010100,
24   0x00000001,  0x01000001,  0x00010001,  0x01010001,  0x00000101,  0x01000101,  0x00010101,  0x01010101,
25   0x02000000,  0x03000000,  0x02010000,  0x03010000,  0x02000100,  0x03000100,  0x02010100,  0x03010100,
26   0x02000001,  0x03000001,  0x02010001,  0x03010001,  0x02000101,  0x03000101,  0x02010101,  0x03010101,
27   0x00020000,  0x01020000,  0x00030000,  0x01030000,  0x00020100,  0x01020100,  0x00030100,  0x01030100,
28   0x00020001,  0x01020001,  0x00030001,  0x01030001,  0x00020101,  0x01020101,  0x00030101,  0x01030101,
29   0x02020000,  0x03020000,  0x02030000,  0x03030000,  0x02020100,  0x03020100,  0x02030100,  0x03030100,
30   0x02020001,  0x03020001,  0x02030001,  0x03030001,  0x02020101,  0x03020101,  0x02030101,  0x03030101,
31   0x00000200,  0x01000200,  0x00010200,  0x01010200,  0x00000300,  0x01000300,  0x00010300,  0x01010300,
32   0x00000201,  0x01000201,  0x00010201,  0x01010201,  0x00000301,  0x01000301,  0x00010301,  0x01010301,
33   0x02000200,  0x03000200,  0x02010200,  0x03010200,  0x02000300,  0x03000300,  0x02010300,  0x03010300,
34   0x02000201,  0x03000201,  0x02010201,  0x03010201,  0x02000301,  0x03000301,  0x02010301,  0x03010301,
35   0x00020200,  0x01020200,  0x00030200,  0x01030200,  0x00020300,  0x01020300,  0x00030300,  0x01030300,
36   0x00020201,  0x01020201,  0x00030201,  0x01030201,  0x00020301,  0x01020301,  0x00030301,  0x01030301,
37   0x02020200,  0x03020200,  0x02030200,  0x03030200,  0x02020300,  0x03020300,  0x02030300,  0x03030300,
38   0x02020201,  0x03020201,  0x02030201,  0x03030201,  0x02020301,  0x03020301,  0x02030301,  0x03030301,
39   0x00000002,  0x01000002,  0x00010002,  0x01010002,  0x00000102,  0x01000102,  0x00010102,  0x01010102,
40   0x00000003,  0x01000003,  0x00010003,  0x01010003,  0x00000103,  0x01000103,  0x00010103,  0x01010103,
41   0x02000002,  0x03000002,  0x02010002,  0x03010002,  0x02000102,  0x03000102,  0x02010102,  0x03010102,
42   0x02000003,  0x03000003,  0x02010003,  0x03010003,  0x02000103,  0x03000103,  0x02010103,  0x03010103,
43   0x00020002,  0x01020002,  0x00030002,  0x01030002,  0x00020102,  0x01020102,  0x00030102,  0x01030102,
44   0x00020003,  0x01020003,  0x00030003,  0x01030003,  0x00020103,  0x01020103,  0x00030103,  0x01030103,
45   0x02020002,  0x03020002,  0x02030002,  0x03030002,  0x02020102,  0x03020102,  0x02030102,  0x03030102,
46   0x02020003,  0x03020003,  0x02030003,  0x03030003,  0x02020103,  0x03020103,  0x02030103,  0x03030103,
47   0x00000202,  0x01000202,  0x00010202,  0x01010202,  0x00000302,  0x01000302,  0x00010302,  0x01010302,
48   0x00000203,  0x01000203,  0x00010203,  0x01010203,  0x00000303,  0x01000303,  0x00010303,  0x01010303,
49   0x02000202,  0x03000202,  0x02010202,  0x03010202,  0x02000302,  0x03000302,  0x02010302,  0x03010302,
50   0x02000203,  0x03000203,  0x02010203,  0x03010203,  0x02000303,  0x03000303,  0x02010303,  0x03010303,
51   0x00020202,  0x01020202,  0x00030202,  0x01030202,  0x00020302,  0x01020302,  0x00030302,  0x01030302,
52   0x00020203,  0x01020203,  0x00030203,  0x01030203,  0x00020303,  0x01020303,  0x00030303,  0x01030303,
53   0x02020202,  0x03020202,  0x02030202,  0x03030202,  0x02020302,  0x03020302,  0x02030302,  0x03030302,
54   0x02020203,  0x03020203,  0x02030203,  0x03030203,  0x02020303,  0x03020303,  0x02030303,  0x03030303,
55 };
56 
57 static const Uint32 Remap_2_Planes_Upper[256] = {
58   0x00000000,  0x04000000,  0x00040000,  0x04040000,  0x00000400,  0x04000400,  0x00040400,  0x04040400,
59   0x00000004,  0x04000004,  0x00040004,  0x04040004,  0x00000404,  0x04000404,  0x00040404,  0x04040404,
60   0x08000000,  0x0C000000,  0x08040000,  0x0C040000,  0x08000400,  0x0C000400,  0x08040400,  0x0C040400,
61   0x08000004,  0x0C000004,  0x08040004,  0x0C040004,  0x08000404,  0x0C000404,  0x08040404,  0x0C040404,
62   0x00080000,  0x04080000,  0x000C0000,  0x040C0000,  0x00080400,  0x04080400,  0x000C0400,  0x040C0400,
63   0x00080004,  0x04080004,  0x000C0004,  0x040C0004,  0x00080404,  0x04080404,  0x000C0404,  0x040C0404,
64   0x08080000,  0x0C080000,  0x080C0000,  0x0C0C0000,  0x08080400,  0x0C080400,  0x080C0400,  0x0C0C0400,
65   0x08080004,  0x0C080004,  0x080C0004,  0x0C0C0004,  0x08080404,  0x0C080404,  0x080C0404,  0x0C0C0404,
66   0x00000800,  0x04000800,  0x00040800,  0x04040800,  0x00000C00,  0x04000C00,  0x00040C00,  0x04040C00,
67   0x00000804,  0x04000804,  0x00040804,  0x04040804,  0x00000C04,  0x04000C04,  0x00040C04,  0x04040C04,
68   0x08000800,  0x0C000800,  0x08040800,  0x0C040800,  0x08000C00,  0x0C000C00,  0x08040C00,  0x0C040C00,
69   0x08000804,  0x0C000804,  0x08040804,  0x0C040804,  0x08000C04,  0x0C000C04,  0x08040C04,  0x0C040C04,
70   0x00080800,  0x04080800,  0x000C0800,  0x040C0800,  0x00080C00,  0x04080C00,  0x000C0C00,  0x040C0C00,
71   0x00080804,  0x04080804,  0x000C0804,  0x040C0804,  0x00080C04,  0x04080C04,  0x000C0C04,  0x040C0C04,
72   0x08080800,  0x0C080800,  0x080C0800,  0x0C0C0800,  0x08080C00,  0x0C080C00,  0x080C0C00,  0x0C0C0C00,
73   0x08080804,  0x0C080804,  0x080C0804,  0x0C0C0804,  0x08080C04,  0x0C080C04,  0x080C0C04,  0x0C0C0C04,
74   0x00000008,  0x04000008,  0x00040008,  0x04040008,  0x00000408,  0x04000408,  0x00040408,  0x04040408,
75   0x0000000C,  0x0400000C,  0x0004000C,  0x0404000C,  0x0000040C,  0x0400040C,  0x0004040C,  0x0404040C,
76   0x08000008,  0x0C000008,  0x08040008,  0x0C040008,  0x08000408,  0x0C000408,  0x08040408,  0x0C040408,
77   0x0800000C,  0x0C00000C,  0x0804000C,  0x0C04000C,  0x0800040C,  0x0C00040C,  0x0804040C,  0x0C04040C,
78   0x00080008,  0x04080008,  0x000C0008,  0x040C0008,  0x00080408,  0x04080408,  0x000C0408,  0x040C0408,
79   0x0008000C,  0x0408000C,  0x000C000C,  0x040C000C,  0x0008040C,  0x0408040C,  0x000C040C,  0x040C040C,
80   0x08080008,  0x0C080008,  0x080C0008,  0x0C0C0008,  0x08080408,  0x0C080408,  0x080C0408,  0x0C0C0408,
81   0x0808000C,  0x0C08000C,  0x080C000C,  0x0C0C000C,  0x0808040C,  0x0C08040C,  0x080C040C,  0x0C0C040C,
82   0x00000808,  0x04000808,  0x00040808,  0x04040808,  0x00000C08,  0x04000C08,  0x00040C08,  0x04040C08,
83   0x0000080C,  0x0400080C,  0x0004080C,  0x0404080C,  0x00000C0C,  0x04000C0C,  0x00040C0C,  0x04040C0C,
84   0x08000808,  0x0C000808,  0x08040808,  0x0C040808,  0x08000C08,  0x0C000C08,  0x08040C08,  0x0C040C08,
85   0x0800080C,  0x0C00080C,  0x0804080C,  0x0C04080C,  0x08000C0C,  0x0C000C0C,  0x08040C0C,  0x0C040C0C,
86   0x00080808,  0x04080808,  0x000C0808,  0x040C0808,  0x00080C08,  0x04080C08,  0x000C0C08,  0x040C0C08,
87   0x0008080C,  0x0408080C,  0x000C080C,  0x040C080C,  0x00080C0C,  0x04080C0C,  0x000C0C0C,  0x040C0C0C,
88   0x08080808,  0x0C080808,  0x080C0808,  0x0C0C0808,  0x08080C08,  0x0C080C08,  0x080C0C08,  0x0C0C0C08,
89   0x0808080C,  0x0C08080C,  0x080C080C,  0x0C0C080C,  0x08080C0C,  0x0C080C0C,  0x080C0C0C,  0x0C0C0C0C,
90 };
91 
92 static const Uint32 Remap_1_Plane[16] = {
93   0x00000000+BASECOLOUR_LONG,  0x01000000+BASECOLOUR_LONG,  0x00010000+BASECOLOUR_LONG,  0x01010000+BASECOLOUR_LONG,  0x00000100+BASECOLOUR_LONG,  0x01000100+BASECOLOUR_LONG,  0x00010100+BASECOLOUR_LONG,  0x01010100+BASECOLOUR_LONG,
94   0x00000001+BASECOLOUR_LONG,  0x01000001+BASECOLOUR_LONG,  0x00010001+BASECOLOUR_LONG,  0x01010001+BASECOLOUR_LONG,  0x00000101+BASECOLOUR_LONG,  0x01000101+BASECOLOUR_LONG,  0x00010101+BASECOLOUR_LONG,  0x01010101+BASECOLOUR_LONG,
95 };
96 
97 
98 
99 /*----------------------------------------------------------------------*/
100 /* Macros to convert from Atari's planar mode to chunky mode
101  * (1 byte per pixel). Convert by blocks of 4 pixels.
102  * 16 low res pixels -> 4 planes of 16 bits
103  * 16 med res pixels -> 2 planes of 16 bits
104  * 16 hi  res pixels -> 1 plane of 16 bits
105  */
106 
107 #define LOW_BUILD_PIXELS_0 \
108 { \
109  ebx &= 0x0f0f0f0f; \
110  ecx &= 0x0f0f0f0f; \
111  eax = (ebx >> 12) | ebx; \
112  edx = (ecx >> 12) | ecx; \
113  ecx = Remap_2_Planes_Upper[edx & 0x00ff]; \
114  ecx +=      Remap_2_Planes[eax & 0x00ff]; \
115 }
116 
117 #define LOW_BUILD_PIXELS_1 \
118 { \
119  ecx = Remap_2_Planes_Upper[(edx >> 8) & 0x00ff]; \
120  ecx +=      Remap_2_Planes[(eax >> 8) & 0x00ff]; \
121 }
122 
123 #define LOW_BUILD_PIXELS_2 \
124 { \
125  ebx = (*edi     & 0xf0f0f0f0) >> 4; \
126  ecx = (*(edi+1) & 0xf0f0f0f0) >> 4; \
127  eax = (ebx >> 12) | ebx; \
128  edx = (ecx >> 12) | ecx; \
129  ecx = Remap_2_Planes_Upper[edx & 0x00ff]; \
130  ecx +=      Remap_2_Planes[eax & 0x00ff]; \
131 }
132 
133 #define LOW_BUILD_PIXELS_3 \
134 { \
135  ecx = Remap_2_Planes_Upper[(edx >> 8) & 0x00ff]; \
136  ecx +=      Remap_2_Planes[(eax >> 8) & 0x00ff]; \
137 }
138 
139 
140 #define MED_BUILD_PIXELS_0 \
141 { \
142  ebx &= 0x0f0f0f0f; \
143  eax = (ebx >> 12) | ebx; \
144  ecx = Remap_2_Planes[eax & 0x000000ff]; \
145 }
146 
147 #define MED_BUILD_PIXELS_1 \
148 { \
149  ecx = Remap_2_Planes[(eax >> 8) & 0x000000ff]; \
150 }
151 
152 #define MED_BUILD_PIXELS_2 \
153 { \
154  ebx = (*edi & 0xf0f0f0f0) >> 4; \
155  eax = (ebx >> 12) | ebx; \
156  ecx = Remap_2_Planes[eax & 0x000000ff]; \
157 }
158 
159 #define MED_BUILD_PIXELS_3 \
160 { \
161  ecx = Remap_2_Planes[(eax >> 8) & 0x000000ff]; \
162 }
163 
164 
165 /* Routines to create 'ecx' pixels - MUST be called in this order */
166 #define HIGH_BUILD_PIXELS_0 \
167 { \
168  eax = (ebx & 0x0000000f); \
169 }
170 
171 #define HIGH_BUILD_PIXELS_1 \
172 { \
173  eax = (ebx >> 4) & 0x0000000f;\
174 }
175 
176 #define HIGH_BUILD_PIXELS_2 \
177 { \
178  eax = (ebx >> 8) & 0x0000000f;\
179 }
180 
181 #define HIGH_BUILD_PIXELS_3 \
182 { \
183  eax = (ebx >> 12) & 0x0000000f;\
184 }
185 
186 
187 
188 /*----------------------------------------------------------------------*/
189 /* Macros to plot Atari's pixels in the emulator's buffer
190  * (the buffer can be 32, 16 or 8 bits per pixel)
191  */
192 
193 /*
194  * 32 bit screen format
195  */
196 
197 /* Plot Low Resolution (320xH) 32-Bit pixels */
198 #define PLOT_LOW_320_32BIT(offset)  \
199 { \
200 	esi[offset]   = (Uint32)STRGBPalette[ecx & 0x00ff]; \
201 	esi[offset+1] = (Uint32)STRGBPalette[(ecx >> 8) & 0x00ff]; \
202 	esi[offset+2] = (Uint32)STRGBPalette[(ecx >> 16) & 0x00ff]; \
203 	esi[offset+3] = (Uint32)STRGBPalette[(ecx >> 24) & 0x00ff]; \
204 }
205 
206 /* Plot Low Resolution (640xH) 32-Bit pixels */
207 #define PLOT_LOW_640_32BIT(offset) \
208 { \
209 	esi[offset+0] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \
210 	esi[offset+2] = esi[offset+3] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
211 	esi[offset+4] = esi[offset+5] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
212 	esi[offset+6] = esi[offset+7] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
213 }
214 
215 /* Plot Low Resolution (640xH) 16-Bit pixels (Double on Y) */
216 #define PLOT_LOW_640_32BIT_DOUBLE_Y(offset) \
217 { \
218 	ebx = STRGBPalette[ecx & 0x000000ff]; \
219 	esi[offset+0] = esi[offset+1] = esi[offset+Screen4BytesPerLine+0] \
220 	   = esi[offset+Screen4BytesPerLine+1] = ebx; \
221 	ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
222 	esi[offset+2] = esi[offset+3] = esi[offset+Screen4BytesPerLine+2] \
223 	   = esi[offset+Screen4BytesPerLine+3] = ebx; \
224 	ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
225 	esi[offset+4] = esi[offset+5] = esi[offset+Screen4BytesPerLine+4] \
226 	   = esi[offset+Screen4BytesPerLine+5] = ebx; \
227 	ebx = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
228 	esi[offset+6] = esi[offset+7] = esi[offset+Screen4BytesPerLine+6] \
229 	   = esi[offset+Screen4BytesPerLine+7] = ebx; \
230 }
231 
232 /* Plot Medium Resolution(640xH) 32-Bit pixels */
233 #define PLOT_MED_640_32BIT(offset) \
234 { \
235 	esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \
236 	esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
237 	esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
238 	esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
239 }
240 
241 /* Plot Medium Resolution(640xH) 32-Bit pixels (Double on Y) */
242 #define PLOT_MED_640_32BIT_DOUBLE_Y(offset) \
243 { \
244 	esi[offset+0+Screen4BytesPerLine]   = \
245 	esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \
246 	esi[offset+1+Screen4BytesPerLine] = \
247 	esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
248 	esi[offset+2+Screen4BytesPerLine] = \
249 	esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
250 	esi[offset+3+Screen4BytesPerLine] = \
251 	esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
252 }
253 
254 
255 /* Plot Spectrum512 Resolution (320xH) 32-Bit pixels */
256 #define PLOT_SPEC512_LEFT_LOW_320_32BIT(offset)	\
257 { \
258 	esi[offset] = STRGBPalette[ecx & 0x000000ff]; \
259 }
260 
261 /* Plot Spectrum512 Resolution (320xH) 32-Bit pixels */
262 #define PLOT_SPEC512_MID_320_32BIT PLOT_LOW_320_32BIT
263 
264 /* Plot Spectrum512 Resolution(320xH) 32-Bit pixels */
265 #define PLOT_SPEC512_END_LOW_320_32BIT(offset) \
266 { \
267 	esi[offset]   = STRGBPalette[ecx & 0x000000ff]; \
268 	esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
269 	esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
270 }
271 
272 
273 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */
274 #define PLOT_SPEC512_LEFT_LOW_640_32BIT(offset)	\
275 { \
276 	esi[offset] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \
277 }
278 
279 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */
280 #define PLOT_SPEC512_MID_640_32BIT PLOT_LOW_640_32BIT
281 
282 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */
283 #define PLOT_SPEC512_END_LOW_640_32BIT(offset)	\
284 { \
285 	esi[offset+0] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \
286 	esi[offset+2] = esi[offset+3] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
287 	esi[offset+4] = esi[offset+5] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
288 }
289 
290 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */
291 #define PLOT_SPEC512_LEFT_LOW_640_32BIT_DOUBLE_Y(offset)	\
292 { \
293 	esi[offset+Screen4BytesPerLine] = esi[offset+Screen4BytesPerLine+1] = \
294 	esi[offset] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \
295 }
296 
297 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */
298 #define PLOT_SPEC512_MID_640_32BIT_DOUBLE_Y PLOT_LOW_640_32BIT_DOUBLE_Y
299 
300 /* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */
301 #define PLOT_SPEC512_END_LOW_640_32BIT_DOUBLE_Y(offset)	\
302 { \
303 	ebx = STRGBPalette[ecx & 0x000000ff]; \
304 	esi[offset+Screen4BytesPerLine] = esi[offset+Screen4BytesPerLine+1] \
305 	    = esi[offset] = esi[offset+1] = ebx; \
306 	ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
307 	esi[offset+2+Screen4BytesPerLine] = esi[offset+3+Screen4BytesPerLine] \
308 	    = esi[offset+2] = esi[offset+3] = ebx; \
309 	ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
310 	esi[offset+4+Screen4BytesPerLine] = esi[offset+5+Screen4BytesPerLine] \
311 	    = esi[offset+4] = esi[offset+5] = ebx; \
312 }
313 
314 
315 /* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels */
316 #define PLOT_SPEC512_LEFT_MED_640_32BIT	PLOT_SPEC512_LEFT_LOW_320_32BIT
317 
318 #define PLOT_SPEC512_MID_MED_640_32BIT PLOT_SPEC512_MID_320_32BIT
319 
320 #define PLOT_SPEC512_END_MED_640_32BIT PLOT_SPEC512_END_LOW_320_32BIT
321 
322 
323 /* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels (Double on Y) */
324 #define PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y(offset) \
325 { \
326 	esi[offset+Screen4BytesPerLine] = esi[offset] = STRGBPalette[ecx & 0x000000ff]; \
327 }
328 
329 #define PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y(offset) \
330 { \
331 	esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \
332 	esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
333 	esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
334 	esi[offset+3+Screen4BytesPerLine] = esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
335 }
336 
337 #define PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y(offset) \
338 { \
339 	esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \
340 	esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
341 	esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
342 }
343 
344 
345 
346 /*
347  * 16 bit screen format
348  */
349 
350 /* Plot Low Resolution (320xH) 16-Bit pixels */
351 #define PLOT_LOW_320_16BIT(offset)  \
352 { \
353  esi[offset]   = (Uint16)STRGBPalette[ecx & 0x00ff]; \
354  esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x00ff]; \
355  esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x00ff]; \
356  esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x00ff]; \
357 }
358 
359 /* Plot Low Resolution (320xH) 8-Bit pixels */
360 #define PLOT_LOW_320_8BIT(offset) \
361 { \
362   esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \
363 }
364 
365 /* Plot Low Resolution (640xH) 8-Bit pixels */
366 #define PLOT_LOW_640_8BIT(offset) \
367 { \
368   ebpp = ecx + BASECOLOUR_LONG; \
369   ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \
370   esi[offset]   = SDL_SwapLE32((ecx << 8) | ecx); \
371   ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \
372   esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \
373 }
374 
375 /* Plot Low Resolution (640xH) 8-Bit pixels (double on Y) */
376 #define PLOT_LOW_640_8BIT_DOUBLE_Y(offset)	\
377 { \
378   ebpp = ecx + BASECOLOUR_LONG; \
379   ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \
380   esi[offset+Screen4BytesPerLine] = \
381   esi[offset]   = SDL_SwapLE32((ecx << 8) | ecx); \
382   ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \
383   esi[offset+1+Screen4BytesPerLine] = \
384   esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \
385 }
386 
387 /* Plot Low Resolution (640xH) 16-Bit pixels */
388 #define PLOT_LOW_640_16BIT(offset) \
389 { \
390  esi[offset]   = STRGBPalette[ecx & 0x000000ff]; \
391  esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
392  esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
393  esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
394 }
395 
396 /* Plot Low Resolution (640xH) 16-Bit pixels (Double on Y) */
397 #define PLOT_LOW_640_16BIT_DOUBLE_Y(offset) \
398 { \
399  ebx = STRGBPalette[ecx & 0x000000ff]; \
400  esi[offset]   = esi[offset+Screen4BytesPerLine]   = ebx; \
401  ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
402  esi[offset+1] = esi[offset+1+Screen4BytesPerLine] = ebx; \
403  ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
404  esi[offset+2] = esi[offset+2+Screen4BytesPerLine] = ebx; \
405  ebx = STRGBPalette[(ecx >> 24) & 0x000000ff]; \
406  esi[offset+3] = esi[offset+3+Screen4BytesPerLine] = ebx; \
407 }
408 
409 
410 /* Plot Medium Resolution (640xH) 8-Bit pixels */
411 #define PLOT_MED_640_8BIT(offset) \
412 { \
413   esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \
414 }
415 
416 /* Plot Medium Resolution (640xH) 8-Bit pixels (Double on Y) */
417 #define PLOT_MED_640_8BIT_DOUBLE_Y(offset) \
418 { \
419   esi[offset] = esi[offset+Screen4BytesPerLine] =\
420   SDL_SwapLE32(ecx + BASECOLOUR_LONG); \
421 }
422 
423 /* Plot Medium Resolution(640xH) 16-Bit pixels */
424 #define PLOT_MED_640_16BIT(offset) \
425 { \
426  esi[offset]   = (Uint16)STRGBPalette[ecx & 0x000000ff]; \
427  esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x000000ff]; \
428  esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x000000ff]; \
429  esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x000000ff]; \
430 }
431 
432 /* Plot Medium Resolution(640xH) 16-Bit pixels (Double on Y) */
433 #define PLOT_MED_640_16BIT_DOUBLE_Y(offset) \
434 { \
435  esi[offset+Screen2BytesPerLine]   =\
436  esi[offset]   = (Uint16)STRGBPalette[ecx & 0x000000ff]; \
437  esi[offset+1+Screen2BytesPerLine] =\
438  esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x000000ff]; \
439  esi[offset+2+Screen2BytesPerLine] =\
440  esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x000000ff]; \
441  esi[offset+3+Screen2BytesPerLine] =\
442  esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x000000ff]; \
443 }
444 
445 
446 /* Plot High Resolution (640xH) 8-Bit pixels */
447 #define PLOT_HIGH_640_8BIT(offset) \
448 { \
449  esi[offset] = SDL_SwapLE32(Remap_1_Plane[eax]); \
450 }
451 
452 
453 /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */
454 #define PLOT_SPEC512_LEFT_LOW_320_16BIT(offset)	\
455 { \
456  esi[offset] = (Uint16)STRGBPalette[ecx & 0x000000ff]; \
457 }
458 
459 /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */
460 #define PLOT_SPEC512_MID_320_16BIT PLOT_LOW_640_16BIT
461 
462 /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */
463 #define PLOT_SPEC512_END_LOW_320_16BIT(offset) \
464 { \
465  esi[offset]   = (Uint16)STRGBPalette[ecx & 0x000000ff]; \
466  esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x000000ff]; \
467  esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x000000ff]; \
468 }
469 
470 
471 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels */
472 #define PLOT_SPEC512_LEFT_LOW_640_16BIT(offset)	\
473 { \
474   esi[offset] = STRGBPalette[ecx & 0x000000ff]; \
475 }
476 
477 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels */
478 #define PLOT_SPEC512_MID_640_16BIT PLOT_LOW_640_16BIT
479 
480 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels */
481 #define PLOT_SPEC512_END_LOW_640_16BIT(offset)	\
482 { \
483   esi[offset]   = STRGBPalette[ecx & 0x000000ff]; \
484   esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
485   esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
486 }
487 
488 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */
489 #define PLOT_SPEC512_LEFT_LOW_640_16BIT_DOUBLE_Y(offset)	\
490 { \
491   esi[offset+Screen4BytesPerLine] = \
492   esi[offset] = STRGBPalette[ecx & 0x000000ff]; \
493 }
494 
495 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */
496 #define PLOT_SPEC512_MID_640_16BIT_DOUBLE_Y PLOT_LOW_640_16BIT_DOUBLE_Y
497 
498 /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */
499 #define PLOT_SPEC512_END_LOW_640_16BIT_DOUBLE_Y(offset)	\
500 { \
501   ebx = STRGBPalette[ecx & 0x000000ff]; \
502   esi[offset]   = esi[offset+Screen4BytesPerLine]   = ebx; \
503   ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \
504   esi[offset+1] = esi[offset+1+Screen4BytesPerLine] = ebx; \
505   ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \
506   esi[offset+2] = esi[offset+2+Screen4BytesPerLine] = ebx; \
507 }
508 
509 
510 /* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels */
511 #define PLOT_SPEC512_LEFT_MED_640_16BIT	PLOT_SPEC512_LEFT_LOW_320_16BIT
512 
513 #define PLOT_SPEC512_MID_MED_640_16BIT PLOT_SPEC512_MID_320_16BIT
514 
515 #define PLOT_SPEC512_END_MED_640_16BIT PLOT_SPEC512_END_LOW_320_16BIT
516 
517 
518 /* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels (Double on Y) */
519 #define PLOT_SPEC512_LEFT_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y
520 
521 #define PLOT_SPEC512_MID_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y
522 
523 #define PLOT_SPEC512_END_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y
524 
525 
526 
527 /* Get Spec512 pixels which are offset by 1 pixel */
528 #if defined(__i386__)    // Unaligned direct access is only supported on i86 platforms
529 
530 /* on AMD XP, first one is 1/3 faster than aligned access, and
531  * final pixels access ~15% faster than aligned operation below
532  */
533 # define GET_SPEC512_OFFSET_PIXELS(pixels, x)  \
534             (*(Uint32 *)(((Uint8 *)pixels) + x))
535 # define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels) \
536             (*(Uint32 *)(((Uint8 *)pixels) + 13))
537 
538 #else
539 
540 # define GET_SPEC512_OFFSET_PIXELS(pixels, x)  \
541             (((*(Uint32 *)(((Uint8 *)pixels) + x-1)) >> 8) \
542 	     | ((*(Uint32 *)(((Uint8 *)pixels) + x+3)) << 24))
543 # define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels)  \
544             ((*(Uint32 *)(((Uint8 *)pixels) + 12)) >> 8)
545 
546 #endif /* __i386__ */
547 
548 
549 #endif /* HATARI_CONVERTMACROS_H */
550