--- hatari/src/convert/high640x8.c 2019/04/01 07:09:16 1.1 +++ hatari/src/convert/high640x8.c 2019/04/01 07:10:07 1.1.1.3 @@ -1,103 +1,100 @@ -// Screen Conversion, High Res to 640x8Bit +/* Screen Conversion, High Res to 640x8Bit */ -void ConvertHighRes_640x8Bit_YLoop(void); -void Line_ConvertHighRes_640x8Bit(void); void ConvertHighRes_640x8Bit(void) { -//fprintf(stderr,"FIXME: Screen Conversion, High Res to 640x8Bit\n"); - unsigned char *src=pSTScreen; - unsigned char *dst=pPCScreenDest; - int i; - for(i=0; i<640*400/8; i++, src++) - { - if( *src & 128 ) *dst++ = 0; else *dst++ = 1; - if( *src & 64 ) *dst++ = 0; else *dst++ = 1; - if( *src & 32 ) *dst++ = 0; else *dst++ = 1; - if( *src & 16 ) *dst++ = 0; else *dst++ = 1; - if( *src & 8 ) *dst++ = 0; else *dst++ = 1; - if( *src & 4 ) *dst++ = 0; else *dst++ = 1; - if( *src & 2 ) *dst++ = 0; else *dst++ = 1; - if( *src & 1 ) *dst++ = 0; else *dst++ = 1; - } - bScreenContentsChanged = TRUE; -/* FIXME */ + Uint16 *edi, *ebp; + Uint32 *esi; + register Uint16 eax, ebx; + /* - __asm { - push ebp - push edi - push esi - push ebx - - mov edi,[pSTScreen] // ST format screen 4-plane 16 colours - mov ebp,[pSTScreenCopy] // Previous ST format screen - mov esi,[pPCScreenDest] // PC format screen, byte per pixel 256 colours - xor edx,edx // Clear index for loop - - mov eax,[STScreenStartHorizLine] - mov [ScrY],eax // 200 lines - jmp ConvertHighRes_640x8Bit_YLoop - } + // This is the method that I first used in Hatari... + // ...but I now rewrote the old WinSTon method, too. + // Don't know what is faster, so I didn't removed my + // first method here completely... + Uint8 *src=pSTScreen; + Uint8 *osrc=pSTScreenCopy; + Uint8 *dst=pPCScreenDest; + int i; + for(i=0; i<640*400/8; i++, src++, osrc++) + { + if( *osrc==*src ) + dst+=8; + else + { + if( *src & 128 ) *dst++ = 1; else *dst++ = 0; + if( *src & 64 ) *dst++ = 1; else *dst++ = 0; + if( *src & 32 ) *dst++ = 1; else *dst++ = 0; + if( *src & 16 ) *dst++ = 1; else *dst++ = 0; + if( *src & 8 ) *dst++ = 1; else *dst++ = 0; + if( *src & 4 ) *dst++ = 1; else *dst++ = 0; + if( *src & 2 ) *dst++ = 1; else *dst++ = 0; + if( *src & 1 ) *dst++ = 1; else *dst++ = 0; + } + } + bScreenContentsChanged = TRUE; + return; */ -} -/* -NAKED void ConvertHighRes_640x8Bit_YLoop(void) -{ - __asm { - // NOTE 'ScrUpdateFlag' is already set(to full update or check, no palettes) - jmp Line_ConvertHighRes_640x8Bit // 0 palette same, can do check tests - } -} -NAKED void Line_ConvertHighRes_640x8Bit(void) -{ - __asm { - mov [ScrX],40 -x_loop: - // Do 16 pixels at one time - mov bx,[edi] - // Full update? or just test changes? - test [ScrUpdateFlag],0xe0000000 - jne copy_word // Force - // Does differ? - cmp bx,[ebp] - je next_word // Pixels are same as last frame, so ignore - -copy_word: - mov [bScreenContentsChanged],TRUE - - // Plot in 'wrong-order', as ebx is 68000 endian - HIGH_BUILD_PIXELS_0 // Generate 'ecx' as pixels [4,5,6,7] - PLOT_HIGH_640_8BIT(4) - HIGH_BUILD_PIXELS_1 // Generate 'ecx' as pixels [0,1,2,3] - PLOT_HIGH_640_8BIT(0) - HIGH_BUILD_PIXELS_2 // Generate 'ecx' as pixels [12,13,14,15] - PLOT_HIGH_640_8BIT(12) - HIGH_BUILD_PIXELS_3 // Generate 'ecx' as pixels [8,9,10,11] - PLOT_HIGH_640_8BIT(8) - -next_word: - add esi,16 // Next PC pixels - add edi,2 // Next ST pixels - add ebp,2 // Next ST copy pixels - - dec [ScrX] - jne x_loop // Loop on X - - sub esi,(40*16) // Back to start of line - add esi,[PCScreenBytesPerLine] // Offset to next line - - inc [ScrY] - mov eax,[STScreenEndHorizLine] - cmp [ScrY],eax - jne ConvertHighRes_640x8Bit_YLoop // And on Y - - pop ebx - pop esi - pop edi - pop ebp + /* Here's now the rewrite of the original WinSTon method: */ + + edi = (Uint16 *)pSTScreen; /* ST format screen */ + ebp = (Uint16 *)pSTScreenCopy; /* Previous ST format screen */ + esi = (Uint32 *)pPCScreenDest; /* PC format screen */ + + ScrY = STScreenStartHorizLine; + + /* NOTE 'ScrUpdateFlag' is already set (to full update or check, no palettes) */ + + do /* Y-loop */ + { + + ScrX = 40; + + do /* X-loop */ + { + + /* Do 16 pixels at one time */ + ebx = *edi; + + if( (ScrUpdateFlag&0xe0000000) || ebx!=*ebp ) /* Does differ? */ + { + bScreenContentsChanged = TRUE; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + /* Plot in 'right-order' on big endian systems */ + HIGH_BUILD_PIXELS_0 ; /* Generate pixels [4,5,6,7] */ + PLOT_HIGH_640_8BIT(3) ; + HIGH_BUILD_PIXELS_1 ; /* Generate pixels [0,1,2,3] */ + PLOT_HIGH_640_8BIT(2) ; + HIGH_BUILD_PIXELS_2 ; /* Generate pixels [12,13,14,15] */ + PLOT_HIGH_640_8BIT(1) ; + HIGH_BUILD_PIXELS_3 ; /* Generate pixels [8,9,10,11] */ + PLOT_HIGH_640_8BIT(0) ; +#else + /* Plot in 'wrong-order', as ebx is 68000 endian */ + HIGH_BUILD_PIXELS_0 ; /* Generate pixels [4,5,6,7] */ + PLOT_HIGH_640_8BIT(1) ; + HIGH_BUILD_PIXELS_1 ; /* Generate pixels [0,1,2,3] */ + PLOT_HIGH_640_8BIT(0) ; + HIGH_BUILD_PIXELS_2 ; /* Generate pixels [12,13,14,15] */ + PLOT_HIGH_640_8BIT(3) ; + HIGH_BUILD_PIXELS_3 ; /* Generate pixels [8,9,10,11] */ + PLOT_HIGH_640_8BIT(2) ; +#endif + } + + esi += 4; /* Next PC pixels */ + edi += 1; /* Next ST pixels */ + ebp += 1; /* Next ST copy pixels */ + } + while( --ScrX ); /* Loop on X */ + +/*?? esi = esi -40*8 +PCScreenBytesPerLine/2;*/ /* Back to start of line + Offset to next line */ - ret + ScrY += 1; } + while( ScrY < STScreenEndHorizLine ); /* Loop on Y */ + } -*/ +