--- hatari/src/convert/macros.h 2019/04/01 07:12:50 1.1 +++ hatari/src/convert/macros.h 2019/04/09 08:57:09 1.1.1.8 @@ -3,23 +3,17 @@ Lookup tables and macros for screen conversion routines. - This file is distributed under the GNU Public License, version 2 or at your - option any later version. Read the file gpl.txt for details. + This file is distributed under the GNU General Public License, version 2 + or at your option any later version. Read the file gpl.txt for details. */ #ifndef HATARI_CONVERTMACROS_H #define HATARI_CONVERTMACROS_H -/* For palette we don't go from colour '0' as the whole background - * would change, so go from this value - */ -#define BASECOLOUR 0x0A -#define BASECOLOUR_LONG 0x0A0A0A0A - /* Remap tables to convert from plane format to byte-per-pixel * (Upper is for 4-Planes so if shifted by 2) */ -static Uint32 Remap_2_Planes[256] = { +static const Uint32 Remap_2_Planes[256] = { 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x02000000, 0x03000000, 0x02010000, 0x03010000, 0x02000100, 0x03000100, 0x02010100, 0x03010100, @@ -54,7 +48,7 @@ static Uint32 Remap_2_Planes[256] = { 0x02020203, 0x03020203, 0x02030203, 0x03030203, 0x02020303, 0x03020303, 0x02030303, 0x03030303, }; -static Uint32 Remap_2_Planes_Upper[256] = { +static const Uint32 Remap_2_Planes_Upper[256] = { 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x08000000, 0x0C000000, 0x08040000, 0x0C040000, 0x08000400, 0x0C000400, 0x08040400, 0x0C040400, @@ -89,11 +83,14 @@ static Uint32 Remap_2_Planes_Upper[256] 0x0808080C, 0x0C08080C, 0x080C080C, 0x0C0C080C, 0x08080C0C, 0x0C080C0C, 0x080C0C0C, 0x0C0C0C0C, }; -static Uint32 Remap_1_Plane[16] = { - 0x00000000+BASECOLOUR_LONG, 0x01000000+BASECOLOUR_LONG, 0x00010000+BASECOLOUR_LONG, 0x01010000+BASECOLOUR_LONG, 0x00000100+BASECOLOUR_LONG, 0x01000100+BASECOLOUR_LONG, 0x00010100+BASECOLOUR_LONG, 0x01010100+BASECOLOUR_LONG, - 0x00000001+BASECOLOUR_LONG, 0x01000001+BASECOLOUR_LONG, 0x00010001+BASECOLOUR_LONG, 0x01010001+BASECOLOUR_LONG, 0x00000101+BASECOLOUR_LONG, 0x01000101+BASECOLOUR_LONG, 0x00010101+BASECOLOUR_LONG, 0x01010101+BASECOLOUR_LONG, -}; +/*----------------------------------------------------------------------*/ +/* Macros to convert from Atari's planar mode to chunky mode + * (1 byte per pixel). Convert by blocks of 4 pixels. + * 16 low res pixels -> 4 planes of 16 bits + * 16 med res pixels -> 2 planes of 16 bits + * 16 hi res pixels -> 1 plane of 16 bits + */ #define LOW_BUILD_PIXELS_0 \ { \ @@ -153,63 +150,175 @@ static Uint32 Remap_1_Plane[16] = { } -/* Routines to create 'ecx' pixels - MUST be called in this order */ -#define HIGH_BUILD_PIXELS_0 \ +/*----------------------------------------------------------------------*/ +/* Macros to plot Atari's pixels in the emulator's buffer + * (the buffer can be 32, 16 or 8 bits per pixel) + */ + +/* + * 32 bit screen format + */ + +/* Plot Low Resolution (320xH) 32-Bit pixels */ +#define PLOT_LOW_320_32BIT(offset) \ +{ \ + esi[offset] = (Uint32)STRGBPalette[ecx & 0x00ff]; \ + esi[offset+1] = (Uint32)STRGBPalette[(ecx >> 8) & 0x00ff]; \ + esi[offset+2] = (Uint32)STRGBPalette[(ecx >> 16) & 0x00ff]; \ + esi[offset+3] = (Uint32)STRGBPalette[(ecx >> 24) & 0x00ff]; \ +} + +/* Plot Low Resolution (640xH) 32-Bit pixels */ +#define PLOT_LOW_640_32BIT(offset) \ +{ \ + esi[offset+0] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+2] = esi[offset+3] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+4] = esi[offset+5] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+6] = esi[offset+7] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ +} + +/* Plot Low Resolution (640xH) 16-Bit pixels (Double on Y) */ +#define PLOT_LOW_640_32BIT_DOUBLE_Y(offset) \ { \ - eax = (ebx & 0x0000000f); \ + ebx = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+0] = esi[offset+1] = esi[offset+Screen4BytesPerLine+0] \ + = esi[offset+Screen4BytesPerLine+1] = ebx; \ + ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2] = esi[offset+3] = esi[offset+Screen4BytesPerLine+2] \ + = esi[offset+Screen4BytesPerLine+3] = ebx; \ + ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+4] = esi[offset+5] = esi[offset+Screen4BytesPerLine+4] \ + = esi[offset+Screen4BytesPerLine+5] = ebx; \ + ebx = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ + esi[offset+6] = esi[offset+7] = esi[offset+Screen4BytesPerLine+6] \ + = esi[offset+Screen4BytesPerLine+7] = ebx; \ } -#define HIGH_BUILD_PIXELS_1 \ +/* Plot Medium Resolution(640xH) 32-Bit pixels */ +#define PLOT_MED_640_32BIT(offset) \ { \ - eax = (ebx >> 4) & 0x0000000f;\ + esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ } -#define HIGH_BUILD_PIXELS_2 \ +/* Plot Medium Resolution(640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - eax = (ebx >> 8) & 0x0000000f;\ + esi[offset+0+Screen4BytesPerLine] = \ + esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1+Screen4BytesPerLine] = \ + esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = \ + esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+3+Screen4BytesPerLine] = \ + esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ } -#define HIGH_BUILD_PIXELS_3 \ + +/* Plot Spectrum512 Resolution (320xH) 32-Bit pixels */ +#define PLOT_SPEC512_LEFT_LOW_320_32BIT(offset) \ { \ - eax = (ebx >> 12) & 0x0000000f;\ + esi[offset] = STRGBPalette[ecx & 0x000000ff]; \ } +/* Plot Spectrum512 Resolution (320xH) 32-Bit pixels */ +#define PLOT_SPEC512_MID_320_32BIT PLOT_LOW_320_32BIT -/* Plot Low Resolution (320xH) 16-Bit pixels */ -#define PLOT_LOW_320_16BIT(offset) \ +/* Plot Spectrum512 Resolution(320xH) 32-Bit pixels */ +#define PLOT_SPEC512_END_LOW_320_32BIT(offset) \ { \ - esi[offset] = (Uint16)STRGBPalette[ecx & 0x00ff]; \ - esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x00ff]; \ - esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x00ff]; \ - esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x00ff]; \ + esi[offset] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ } -/* Plot Low Resolution (320xH) 8-Bit pixels */ -#define PLOT_LOW_320_8BIT(offset) \ + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */ +#define PLOT_SPEC512_LEFT_LOW_640_32BIT(offset) \ +{ \ + esi[offset] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \ +} + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */ +#define PLOT_SPEC512_MID_640_32BIT PLOT_LOW_640_32BIT + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels */ +#define PLOT_SPEC512_END_LOW_640_32BIT(offset) \ +{ \ + esi[offset+0] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+2] = esi[offset+3] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+4] = esi[offset+5] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ +} + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_LEFT_LOW_640_32BIT_DOUBLE_Y(offset) \ +{ \ + esi[offset+Screen4BytesPerLine] = esi[offset+Screen4BytesPerLine+1] = \ + esi[offset] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \ +} + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_MID_640_32BIT_DOUBLE_Y PLOT_LOW_640_32BIT_DOUBLE_Y + +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_END_LOW_640_32BIT_DOUBLE_Y(offset) \ +{ \ + ebx = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+Screen4BytesPerLine] = esi[offset+Screen4BytesPerLine+1] \ + = esi[offset] = esi[offset+1] = ebx; \ + ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = esi[offset+3+Screen4BytesPerLine] \ + = esi[offset+2] = esi[offset+3] = ebx; \ + ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+4+Screen4BytesPerLine] = esi[offset+5+Screen4BytesPerLine] \ + = esi[offset+4] = esi[offset+5] = ebx; \ +} + + +/* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels */ +#define PLOT_SPEC512_LEFT_MED_640_32BIT PLOT_SPEC512_LEFT_LOW_320_32BIT + +#define PLOT_SPEC512_MID_MED_640_32BIT PLOT_SPEC512_MID_320_32BIT + +#define PLOT_SPEC512_END_MED_640_32BIT PLOT_SPEC512_END_LOW_320_32BIT + + +/* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ + esi[offset+Screen4BytesPerLine] = esi[offset] = STRGBPalette[ecx & 0x000000ff]; \ } -/* Plot Low Resolution (640xH) 8-Bit pixels */ -#define PLOT_LOW_640_8BIT(offset) \ +#define PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - ebpp = ecx + BASECOLOUR_LONG; \ - ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \ - esi[offset] = SDL_SwapLE32((ecx << 8) | ecx); \ - ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \ - esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \ + esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+3+Screen4BytesPerLine] = esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ } -/* Plot Low Resolution (640xH) 8-Bit pixels (double on Y) */ -#define PLOT_LOW_640_8BIT_DOUBLE_Y(offset) \ +#define PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - ebpp = ecx + BASECOLOUR_LONG; \ - ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \ - esi[offset+PCScreenBytesPerLine/4] = \ - esi[offset] = SDL_SwapLE32((ecx << 8) | ecx); \ - ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \ - esi[offset+1+PCScreenBytesPerLine/4] = \ - esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \ + esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ +} + + + +/* + * 16 bit screen format + */ + +/* Plot Low Resolution (320xH) 16-Bit pixels */ +#define PLOT_LOW_320_16BIT(offset) \ +{ \ + esi[offset] = (Uint16)STRGBPalette[ecx & 0x00ff]; \ + esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x00ff]; \ + esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x00ff]; \ + esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x00ff]; \ } /* Plot Low Resolution (640xH) 16-Bit pixels */ @@ -225,29 +334,16 @@ static Uint32 Remap_1_Plane[16] = { #define PLOT_LOW_640_16BIT_DOUBLE_Y(offset) \ { \ ebx = STRGBPalette[ecx & 0x000000ff]; \ - esi[offset] = esi[offset+PCScreenBytesPerLine/4] = ebx; \ + esi[offset] = esi[offset+Screen4BytesPerLine] = ebx; \ ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ - esi[offset+1] = esi[offset+1+PCScreenBytesPerLine/4] = ebx; \ + esi[offset+1] = esi[offset+1+Screen4BytesPerLine] = ebx; \ ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ - esi[offset+2] = esi[offset+2+PCScreenBytesPerLine/4] = ebx; \ + esi[offset+2] = esi[offset+2+Screen4BytesPerLine] = ebx; \ ebx = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ - esi[offset+3] = esi[offset+3+PCScreenBytesPerLine/4] = ebx; \ + esi[offset+3] = esi[offset+3+Screen4BytesPerLine] = ebx; \ } -/* Plot Medium Resolution (640xH) 8-Bit pixels */ -#define PLOT_MED_640_8BIT(offset) \ -{ \ - esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ -} - -/* Plot Medium Resolution (640xH) 8-Bit pixels (Double on Y) */ -#define PLOT_MED_640_8BIT_DOUBLE_Y(offset) \ -{ \ - esi[offset] = esi[offset+PCScreenBytesPerLine/4] =\ - SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ -} - /* Plot Medium Resolution(640xH) 16-Bit pixels */ #define PLOT_MED_640_16BIT(offset) \ { \ @@ -260,24 +356,17 @@ static Uint32 Remap_1_Plane[16] = { /* Plot Medium Resolution(640xH) 16-Bit pixels (Double on Y) */ #define PLOT_MED_640_16BIT_DOUBLE_Y(offset) \ { \ - esi[offset+PCScreenBytesPerLine/2] =\ + esi[offset+Screen2BytesPerLine] =\ esi[offset] = (Uint16)STRGBPalette[ecx & 0x000000ff]; \ - esi[offset+1+PCScreenBytesPerLine/2] =\ + esi[offset+1+Screen2BytesPerLine] =\ esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x000000ff]; \ - esi[offset+2+PCScreenBytesPerLine/2] =\ + esi[offset+2+Screen2BytesPerLine] =\ esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x000000ff]; \ - esi[offset+3+PCScreenBytesPerLine/2] =\ + esi[offset+3+Screen2BytesPerLine] =\ esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x000000ff]; \ } -/* Plot High Resolution (640xH) 8-Bit pixels */ -#define PLOT_HIGH_640_8BIT(offset) \ -{ \ - esi[offset] = SDL_SwapLE32(Remap_1_Plane[eax]); \ -} - - /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ #define PLOT_SPEC512_LEFT_LOW_320_16BIT(offset) \ { \ @@ -285,7 +374,7 @@ static Uint32 Remap_1_Plane[16] = { } /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ -#define PLOT_SPEC512_MID_320_16BIT PLOT_MED_640_16BIT +#define PLOT_SPEC512_MID_320_16BIT PLOT_LOW_640_16BIT /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ #define PLOT_SPEC512_END_LOW_320_16BIT(offset) \ @@ -316,7 +405,7 @@ static Uint32 Remap_1_Plane[16] = { /* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */ #define PLOT_SPEC512_LEFT_LOW_640_16BIT_DOUBLE_Y(offset) \ { \ - esi[offset+PCScreenBytesPerLine/4] = \ + esi[offset+Screen4BytesPerLine] = \ esi[offset] = STRGBPalette[ecx & 0x000000ff]; \ } @@ -327,11 +416,51 @@ static Uint32 Remap_1_Plane[16] = { #define PLOT_SPEC512_END_LOW_640_16BIT_DOUBLE_Y(offset) \ { \ ebx = STRGBPalette[ecx & 0x000000ff]; \ - esi[offset] = esi[offset+PCScreenBytesPerLine/4] = ebx; \ + esi[offset] = esi[offset+Screen4BytesPerLine] = ebx; \ ebx = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ - esi[offset+1] = esi[offset+1+PCScreenBytesPerLine/4] = ebx; \ + esi[offset+1] = esi[offset+1+Screen4BytesPerLine] = ebx; \ ebx = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ - esi[offset+2] = esi[offset+2+PCScreenBytesPerLine/4] = ebx; \ + esi[offset+2] = esi[offset+2+Screen4BytesPerLine] = ebx; \ } + +/* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels */ +#define PLOT_SPEC512_LEFT_MED_640_16BIT PLOT_SPEC512_LEFT_LOW_320_16BIT + +#define PLOT_SPEC512_MID_MED_640_16BIT PLOT_SPEC512_MID_320_16BIT + +#define PLOT_SPEC512_END_MED_640_16BIT PLOT_SPEC512_END_LOW_320_16BIT + + +/* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_LEFT_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y + +#define PLOT_SPEC512_MID_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y + +#define PLOT_SPEC512_END_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y + + + +/* Get Spec512 pixels which are offset by 1 pixel */ +#if defined(__i386__) // Unaligned direct access is only supported on i86 platforms + +/* on AMD XP, first one is 1/3 faster than aligned access, and + * final pixels access ~15% faster than aligned operation below + */ +# define GET_SPEC512_OFFSET_PIXELS(pixels, x) \ + (*(Uint32 *)(((Uint8 *)pixels) + x)) +# define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels) \ + (*(Uint32 *)(((Uint8 *)pixels) + 13)) + +#else + +# define GET_SPEC512_OFFSET_PIXELS(pixels, x) \ + (((*(Uint32 *)(((Uint8 *)pixels) + x-1)) >> 8) \ + | ((*(Uint32 *)(((Uint8 *)pixels) + x+3)) << 24)) +# define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels) \ + ((*(Uint32 *)(((Uint8 *)pixels) + 12)) >> 8) + +#endif /* __i386__ */ + + #endif /* HATARI_CONVERTMACROS_H */