/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1997-98 Francis Gastellu
                    aka Lone Runner/Aegis

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

// PowerPPL Compiler - PPC Sources
//
// PPE Encryption routines, Thanks to Clark Development Company

#include <dos.h>

void crypt(char *buffer, int len);
int recrypt(char *buffer, char *buffer2, int len);
void cryptXor(char *buffer, unsigned int len);
extern int xor17;

//---------------------------------------------------------------------------
// COMPRESSION DU CODE
//---------------------------------------------------------------------------
int recrypt(char *buffer, char *buffer2, int len)
{
unsigned int bufStart, bufEnd;

if (len == 0) return len;


asm				push    ds
asm				mov 	dx, len
asm				les     di,buffer2   			// Load 32 bit ptr
asm				mov		bufStart, di
asm				lds     si,buffer    			// Load 32 bit ptr
asm				cld                             // Clear direction
asm				xor     bx,bx                   // Zero register
loc_2229:
asm				lodsb                           // String [si] to al
asm				stosb                           // Store al to es:[di]
asm				inc     bx
asm				dec     dx
asm				or      al,al                   // Zero ?
asm				jz      loc_2230                // Jump if zero
asm				or      dx,dx                   // Zero ?
asm				jz      loc_2233                // Jump if zero
asm				jmp     short loc_2229
loc_2230:
asm				xor     cx,cx                   // Zero register
loc_2231:
asm				inc     cx
asm				or      dx,dx                   // Zero ?
asm				jz      loc_2232                // Jump if zero
asm				lodsb                           // String [si] to al
asm				or      al,al                   // Zero ?
asm				jz      loc_2231                // Jump if zero
asm				dec     si
loc_2232:
asm				mov     es:[di],cl
asm				inc     di
asm				inc     bx
asm				dec     cx
asm				sub     dx,cx
asm				or      dx,dx                   // Zero ?
asm				jnz     loc_2229                // Jump if not zero
loc_2233:
asm				mov		bufEnd, di
asm				pop		ds


return bufEnd-bufStart;

}

//---------------------------------------------------------------------------
// CRYPTAGE D'UN BLOC
//---------------------------------------------------------------------------
void crypt(char *buffer, int len)
{
int wlen = len;
int parts = 1 + (int)len/2047;
int len2;
int ref;
int lastoff=0;
char lastbyte=1;
int dec=0;
int totalDec=0;
char *startpointer;
int a;

if (len == 1)
	{
	buffer[0]=0x24;
	return;
	}

for (a=0;a<parts;a++)
	{
	if (lastbyte == 0)
		{
		dec++;
		totalDec++;
		}

	ref = a * 2047;// + a/2;

	wlen += dec;

	len = wlen - ref;

	if (len > 2047)
		len = 2047;
	else
		len -= (totalDec*2);

	if (lastoff == 0)
		startpointer = buffer;
	else
		startpointer = (char *)MK_FP(FP_SEG(startpointer), lastoff+dec);

	dec=0;

	len2 = len >> 1;

asm		push    ds
asm		push	es
asm		lds     si,startpointer         // Load 32 bit ptr
asm		les     di,startpointer	        // Load 32 bit ptr
asm		cld                             // Clear direction
asm		mov     bx,0DB24h
asm		mov     dx,len2
loc_2192:
asm		or      dx,dx                   // Zero ?
asm		jz      loc_2193                // Jump if zero
asm		lodsw                           // String [si] to ax
asm		xor     ax,bx
asm		xor     ah,dl
asm		xor     al,dl
asm		mov     cl,bl
asm		add     cl,dl
asm		rol     ax,cl                   // Rotate
asm		stosw                           // Store ax to es:[di]
asm		mov     bx,ax
asm		dec     dx
asm		jmp     short loc_2192
loc_2193:
asm		test    word ptr len,1
asm		jz      loc_2194                // Jump if zero
asm		lodsb                           // String [si] to al
asm		mov 	lastbyte, al
asm		rol     al,cl                   // Rotate
asm		xor     al,bl
asm		stosb                           // Store al to es:[di]
loc_2194:
asm		mov 	lastoff, di
asm		pop		es
asm		pop     ds

if (xor17)
	cryptXor(startpointer, len);

	}


}

void cryptXor(char *buffer, unsigned int len)
{
unsigned int i;
unsigned char c;
unsigned int a;
char xor[17] = {
    0x8C,0x53,0xB8,0xA7,0x9E,0x0F,0x0A,0xCB,0x28,0x62,0x2D,0x50,0x7E,0x05,
    0x3D,0x4E,0x35};

    a = len;
    c = 0;
    for (i = 0; i<len;i++)
    	{
        if (c > 16)
        	c = 0;
        buffer[i] = buffer[i] ^ (xor[c] + (a & 0xFF));
        c++;
        a--;
        }

}
