1091 lines
26 KiB
C
1091 lines
26 KiB
C
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||
|
// See the included license file "BUILDLIC.TXT" for license info.
|
||
|
// This file has been modified from Ken Silverman's original release
|
||
|
|
||
|
/* DDOI - This file is an attempt to reimplement a_nasm.asm in C */
|
||
|
|
||
|
#include "platform.h"
|
||
|
#include "build.h"
|
||
|
|
||
|
#define shrd(a,b,c) (((b)<<(32-(c))) | ((a)>>(c)))
|
||
|
#define shld(a,b,c) (((b)>>(32-(c))) | ((a)<<(c)))
|
||
|
|
||
|
extern long asm1;
|
||
|
extern long asm2;
|
||
|
extern long asm3;
|
||
|
extern long asm4;
|
||
|
|
||
|
long is_vmware_running(void)
|
||
|
{
|
||
|
return 0;
|
||
|
} /* is_vmware_running */
|
||
|
|
||
|
/* #pragma aux mmxoverlay modify [eax ebx ecx edx] */
|
||
|
long mmxoverlay(void)
|
||
|
{
|
||
|
return 0;
|
||
|
} /* mmxoverlay */
|
||
|
|
||
|
/* #pragma aux sethlinesizes parm [eax][ebx][ecx] */
|
||
|
static unsigned char machxbits_al;
|
||
|
static unsigned char machxbits_bl;
|
||
|
static long machxbits_ecx;
|
||
|
void sethlinesizes(long i1, long i2, long i3)
|
||
|
{
|
||
|
machxbits_al = i1;
|
||
|
machxbits_bl = i2;
|
||
|
machxbits_ecx = i3;
|
||
|
} /* sethlinesizes */
|
||
|
|
||
|
static unsigned char* pal_eax;
|
||
|
void setuphlineasm4(long i1, long i2) { }
|
||
|
void setpalookupaddress(unsigned char *i1) { pal_eax = i1; }
|
||
|
|
||
|
void hlineasm4(long _count, unsigned long unused_source, long _shade, unsigned long _i4, unsigned long _i5, long i6)
|
||
|
{
|
||
|
/* force into registers (probably only useful on PowerPC)... */
|
||
|
register unsigned char *dest = (unsigned char *) i6;
|
||
|
register unsigned long i4 = _i4;
|
||
|
register unsigned long i5 = _i5;
|
||
|
register int shifter = ((256-machxbits_al) & 0x1f);
|
||
|
register unsigned long source;
|
||
|
register long shade = _shade & 0xffffff00;
|
||
|
register long count = _count + 1;
|
||
|
register unsigned char bits = machxbits_bl;
|
||
|
register unsigned char *lookup = (unsigned char *) machxbits_ecx;
|
||
|
register unsigned char *pal = (unsigned char *) pal_eax;
|
||
|
register long _asm1 = asm1;
|
||
|
register long _asm2 = asm2;
|
||
|
|
||
|
while (count) {
|
||
|
source = i5 >> shifter;
|
||
|
source = shld(source,i4,bits);
|
||
|
source = lookup[source];
|
||
|
*dest = pal[shade|source];
|
||
|
dest--;
|
||
|
i5 -= _asm1;
|
||
|
i4 -= _asm2;
|
||
|
count--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static long rmach_eax;
|
||
|
static long rmach_ebx;
|
||
|
static long rmach_ecx;
|
||
|
static long rmach_edx;
|
||
|
static long rmach_esi;
|
||
|
void setuprhlineasm4(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
rmach_eax = i1;
|
||
|
rmach_ebx = i2;
|
||
|
rmach_ecx = i3;
|
||
|
rmach_edx = i4;
|
||
|
rmach_esi = i5;
|
||
|
} /* setuprhlineasm4 */
|
||
|
|
||
|
void rhlineasm4(long i1, long i2, long i3, unsigned long i4, unsigned long i5, long i6)
|
||
|
{
|
||
|
unsigned long ebp = i6 - i1;
|
||
|
unsigned long rmach6b = ebp-1;
|
||
|
|
||
|
if (i1 <= 0) return;
|
||
|
|
||
|
i6 = i1;
|
||
|
do {
|
||
|
i3 = ((i3&0xffffff00)|(*((unsigned char *)i2)));
|
||
|
i4 -= rmach_eax;
|
||
|
ebp = (((i4+rmach_eax) < i4) ? -1 : 0);
|
||
|
i5 -= rmach_ebx;
|
||
|
if ((i5 + rmach_ebx) < i5) i2 -= (rmach_ecx+1);
|
||
|
else i2 -= rmach_ecx;
|
||
|
ebp &= rmach_esi;
|
||
|
i1 = ((i1&0xffffff00)|(((unsigned char *)i3)[rmach_edx]));
|
||
|
((unsigned char *)rmach6b)[i6] = (i1&0xff);
|
||
|
i2 -= ebp;
|
||
|
i6--;
|
||
|
} while (i6);
|
||
|
} /* rhlineasm4 */
|
||
|
|
||
|
static long rmmach_eax;
|
||
|
static long rmmach_ebx;
|
||
|
static long rmmach_ecx;
|
||
|
static long rmmach_edx;
|
||
|
static long rmmach_esi;
|
||
|
void setuprmhlineasm4(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
rmmach_eax = i1;
|
||
|
rmmach_ebx = i2;
|
||
|
rmmach_ecx = i3;
|
||
|
rmmach_edx = i4;
|
||
|
rmmach_esi = i5;
|
||
|
} /* setuprmhlineasm4 */
|
||
|
|
||
|
/* #pragma aux rmhlineasm4 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void rmhlineasm4(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned long ebp = i6 - i1;
|
||
|
unsigned long rmach6b = ebp-1;
|
||
|
|
||
|
if (i1 <= 0) return;
|
||
|
|
||
|
i6 = i1;
|
||
|
do {
|
||
|
i3 = ((i3&0xffffff00)|(*((unsigned char *)i2)));
|
||
|
i4 -= rmmach_eax;
|
||
|
ebp = (((i4+rmmach_eax) < i4) ? -1 : 0);
|
||
|
i5 -= rmmach_ebx;
|
||
|
if ((i5 + rmmach_ebx) < i5) i2 -= (rmmach_ecx+1);
|
||
|
else i2 -= rmmach_ecx;
|
||
|
ebp &= rmmach_esi;
|
||
|
if ((i3&0xff) != 255) {
|
||
|
i1 = ((i1&0xffffff00)|(((unsigned char *)i3)[rmmach_edx]));
|
||
|
((unsigned char *)rmach6b)[i6] = (i1&0xff);
|
||
|
}
|
||
|
i2 -= ebp;
|
||
|
i6--;
|
||
|
} while (i6);
|
||
|
} /* rmhlineasm4 */
|
||
|
|
||
|
|
||
|
/* #pragma aux setupqrhlineasm4 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void setupqrhlineasm4(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
setuprhlineasm4(i1,i2,i3,i4,i5,i6);
|
||
|
} /* setupqrhlineasm4 */
|
||
|
|
||
|
|
||
|
/* #pragma aux qrhlineasm4 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void qrhlineasm4(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
rhlineasm4(i1,i2,i3,i4,i5,i6);
|
||
|
} /* qrhlineasm4 */
|
||
|
|
||
|
/* #pragma aux setvlinebpl parm [eax] */
|
||
|
static long fixchain;
|
||
|
void setvlinebpl(long i1)
|
||
|
{
|
||
|
fixchain = i1;
|
||
|
} /* setvlinebpl */
|
||
|
|
||
|
/* #pragma aux fixtransluscence parm [eax] */
|
||
|
static long tmach;
|
||
|
void fixtransluscence(long i1)
|
||
|
{
|
||
|
tmach = i1;
|
||
|
} /* fixtransluscence */
|
||
|
|
||
|
long vlineasm1(long i1, long i2, long i3, long i4, long i5, long i6);
|
||
|
|
||
|
/* #pragma aux prevlineasm1 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static unsigned char mach3_al;
|
||
|
long prevlineasm1(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned char *source = (unsigned char *)i5;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
if (i3 == 0)
|
||
|
{
|
||
|
i1 += i4;
|
||
|
i4 = (long) (((unsigned long)i4) >> mach3_al);
|
||
|
i4 = (i4&0xffffff00) | (source[i4]&0xff);
|
||
|
*dest = ((unsigned char*)i2)[i4];
|
||
|
return i1;
|
||
|
} else {
|
||
|
return vlineasm1(i1,i2,i3,i4,i5,i6);
|
||
|
}
|
||
|
} /* prevlineasm1 */
|
||
|
|
||
|
/* #pragma aux vlineasm1 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
long vlineasm1(long vince, long palookupoffse, long i3, long vplce, long bufplce, long i6)
|
||
|
{
|
||
|
unsigned long temp;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
|
||
|
i3++;
|
||
|
while (i3)
|
||
|
{
|
||
|
temp = ((unsigned)vplce) >> mach3_al;
|
||
|
temp = ((unsigned char *)bufplce)[temp];
|
||
|
*dest = ((unsigned char*)palookupoffse)[temp];
|
||
|
vplce += vince;
|
||
|
dest += fixchain;
|
||
|
i3--;
|
||
|
}
|
||
|
return vplce;
|
||
|
} /* vlineasm1 */
|
||
|
|
||
|
/* #pragma aux setuptvlineasm parm [eax] */
|
||
|
static unsigned char transmach3_al = 32;
|
||
|
void setuptvlineasm(long i1)
|
||
|
{
|
||
|
transmach3_al = (i1 & 0x1f);
|
||
|
} /* setuptvlineasm */
|
||
|
|
||
|
/* #pragma aux tvlineasm1 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static int transrev = 0;
|
||
|
long tvlineasm1(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned char *source = (unsigned char *)i5;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
|
||
|
i3++;
|
||
|
while (i3)
|
||
|
{
|
||
|
unsigned long temp = i4;
|
||
|
temp >>= transmach3_al;
|
||
|
temp = source[temp];
|
||
|
if (temp != 255)
|
||
|
{
|
||
|
unsigned short val;
|
||
|
val = ((unsigned char *)i2)[temp];
|
||
|
val |= ((*dest)<<8);
|
||
|
if (transrev) val = ((val>>8)|(val<<8));
|
||
|
*dest = ((unsigned char *)tmach)[val];
|
||
|
}
|
||
|
i4 += i1;
|
||
|
dest += fixchain;
|
||
|
i3--;
|
||
|
}
|
||
|
return i4;
|
||
|
} /* tvlineasm1 */
|
||
|
|
||
|
/* #pragma aux setuptvlineasm2 parm [eax][ebx][ecx] */
|
||
|
static unsigned char tran2shr;
|
||
|
static unsigned long tran2pal_ebx;
|
||
|
static unsigned long tran2pal_ecx;
|
||
|
void setuptvlineasm2(long i1, long i2, long i3)
|
||
|
{
|
||
|
tran2shr = (i1&0x1f);
|
||
|
tran2pal_ebx = i2;
|
||
|
tran2pal_ecx = i3;
|
||
|
} /* */
|
||
|
|
||
|
/* #pragma aux tvlineasm2 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void tvlineasm2(unsigned long i1, unsigned long i2, unsigned long i3, unsigned long i4, unsigned long i5, unsigned long i6)
|
||
|
{
|
||
|
unsigned long ebp = i1;
|
||
|
unsigned long tran2inca = i2;
|
||
|
unsigned long tran2incb = asm1;
|
||
|
unsigned long tran2bufa = i3;
|
||
|
unsigned long tran2bufb = i4;
|
||
|
unsigned long tran2edi = asm2;
|
||
|
unsigned long tran2edi1 = asm2 + 1;
|
||
|
|
||
|
i6 -= asm2;
|
||
|
|
||
|
do {
|
||
|
i1 = i5 >> tran2shr;
|
||
|
i2 = ebp >> tran2shr;
|
||
|
i5 += tran2inca;
|
||
|
ebp += tran2incb;
|
||
|
i3 = ((unsigned char *)tran2bufa)[i1];
|
||
|
i4 = ((unsigned char *)tran2bufb)[i2];
|
||
|
if (i3 == 255) { // skipdraw1
|
||
|
if (i4 != 255) { // skipdraw3
|
||
|
unsigned short val;
|
||
|
val = ((unsigned char *)tran2pal_ecx)[i4];
|
||
|
val |= (((unsigned char *)i6)[tran2edi1]<<8);
|
||
|
if (transrev) val = ((val>>8)|(val<<8));
|
||
|
((unsigned char *)i6)[tran2edi1] =
|
||
|
((unsigned char *)tmach)[val];
|
||
|
}
|
||
|
} else if (i4 == 255) { // skipdraw2
|
||
|
unsigned short val;
|
||
|
val = ((unsigned char *)tran2pal_ebx)[i3];
|
||
|
val |= (((unsigned char *)i6)[tran2edi]<<8);
|
||
|
if (transrev) val = ((val>>8)|(val<<8));
|
||
|
((unsigned char *)i6)[tran2edi] =
|
||
|
((unsigned char *)tmach)[val];
|
||
|
} else {
|
||
|
unsigned short l = ((unsigned char *)i6)[tran2edi]<<8;
|
||
|
unsigned short r = ((unsigned char *)i6)[tran2edi1]<<8;
|
||
|
l |= ((unsigned char *)tran2pal_ebx)[i3];
|
||
|
r |= ((unsigned char *)tran2pal_ecx)[i4];
|
||
|
if (transrev) {
|
||
|
l = ((l>>8)|(l<<8));
|
||
|
r = ((r>>8)|(r<<8));
|
||
|
}
|
||
|
((unsigned char *)i6)[tran2edi] =
|
||
|
((unsigned char *)tmach)[l];
|
||
|
((unsigned char *)i6)[tran2edi1] =
|
||
|
((unsigned char *)tmach)[r];
|
||
|
}
|
||
|
i6 += fixchain;
|
||
|
} while (i6 > i6 - fixchain);
|
||
|
asm1 = i5;
|
||
|
asm2 = ebp;
|
||
|
} /* tvlineasm2 */
|
||
|
|
||
|
|
||
|
/* #pragma aux mvlineasm1 parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static unsigned char machmv;
|
||
|
long mvlineasm1(long vince, long palookupoffse, long i3, long vplce, long bufplce, long i6)
|
||
|
{
|
||
|
unsigned long temp;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
|
||
|
while (i3)
|
||
|
{
|
||
|
temp = ((unsigned)vplce) >> machmv;
|
||
|
temp = ((unsigned char *)bufplce)[temp];
|
||
|
if (temp != 255) *dest = ((unsigned char*)palookupoffse)[temp];
|
||
|
vplce += vince;
|
||
|
dest += fixchain;
|
||
|
i3--;
|
||
|
}
|
||
|
return vplce;
|
||
|
} /* mvlineasm1 */
|
||
|
|
||
|
/* #pragma aux setupvlineasm parm [eax] */
|
||
|
void setupvlineasm(long i1)
|
||
|
{
|
||
|
mach3_al = (i1&0x1f);
|
||
|
} /* setupvlineasm */
|
||
|
|
||
|
extern long vplce[4], vince[4], palookupoffse[4], bufplce[4];
|
||
|
|
||
|
#if HAVE_POWERPC
|
||
|
/* About 25% faster than the scalar version on my 12" Powerbook. --ryan. */
|
||
|
static void vlineasm4_altivec(long i1, long i2)
|
||
|
{
|
||
|
unsigned int mach_array[4] = { (unsigned int) mach3_al,
|
||
|
(unsigned int) mach3_al,
|
||
|
(unsigned int) mach3_al,
|
||
|
(unsigned int) mach3_al };
|
||
|
|
||
|
unsigned int temp[4];
|
||
|
unsigned long index = (i2 + ylookup[i1]);
|
||
|
unsigned char *dest = (unsigned char*)(-ylookup[i1]);
|
||
|
|
||
|
register vector unsigned int vec_temp;
|
||
|
register vector signed int vec_vplce;
|
||
|
register vector signed int vec_vince;
|
||
|
register vector signed int vec_bufplce;
|
||
|
register vector unsigned int vec_shifter;
|
||
|
|
||
|
register unsigned char *pal0 = (unsigned char *) palookupoffse[0];
|
||
|
register unsigned char *pal1 = (unsigned char *) palookupoffse[1];
|
||
|
register unsigned char *pal2 = (unsigned char *) palookupoffse[2];
|
||
|
register unsigned char *pal3 = (unsigned char *) palookupoffse[3];
|
||
|
|
||
|
vec_shifter = vec_ld(0, mach_array);
|
||
|
vec_vplce = vec_ld(0, vplce);
|
||
|
vec_vince = vec_ld(0, vince);
|
||
|
vec_bufplce = vec_ld(0, bufplce);
|
||
|
|
||
|
do {
|
||
|
vec_temp = (vector unsigned int) vec_sr(vec_vplce, vec_shifter);
|
||
|
vec_temp = (vector unsigned int) vec_add(vec_bufplce, (vector signed int) vec_temp);
|
||
|
vec_st(vec_temp, 0x00, temp);
|
||
|
vec_vplce = vec_add(vec_vplce, vec_vince);
|
||
|
dest[index] = pal0[*((unsigned char *) temp[0])];
|
||
|
dest[index+1] = pal1[*((unsigned char *) temp[1])];
|
||
|
dest[index+2] = pal2[*((unsigned char *) temp[2])];
|
||
|
dest[index+3] = pal3[*((unsigned char *) temp[3])];
|
||
|
dest += fixchain;
|
||
|
} while (((unsigned)dest - fixchain) < ((unsigned)dest));
|
||
|
|
||
|
vec_st(vec_vplce, 0, vplce);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* #pragma aux vlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi] */
|
||
|
void vlineasm4(long i1, long i2)
|
||
|
{
|
||
|
#if HAVE_POWERPC
|
||
|
if (has_altivec)
|
||
|
vlineasm4_altivec(i1, i2);
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
int i;
|
||
|
unsigned long temp;
|
||
|
unsigned long index = (i2 + ylookup[i1]);
|
||
|
unsigned char *dest = (unsigned char*)(-ylookup[i1]);
|
||
|
do {
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
temp = ((unsigned)vplce[i]) >> mach3_al;
|
||
|
temp = (((unsigned char*)(bufplce[i]))[temp]);
|
||
|
dest[index+i] = ((unsigned char*)(palookupoffse[i]))[temp];
|
||
|
vplce[i] += vince[i];
|
||
|
}
|
||
|
dest += fixchain;
|
||
|
} while (((unsigned)dest - fixchain) < ((unsigned)dest));
|
||
|
}
|
||
|
} /* vlineasm4 */
|
||
|
|
||
|
/* #pragma aux setupmvlineasm parm [eax] */
|
||
|
void setupmvlineasm(long i1)
|
||
|
{
|
||
|
machmv = (i1&0x1f);
|
||
|
} /* setupmvlineasm */
|
||
|
|
||
|
/* #pragma aux mvlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi] */
|
||
|
void mvlineasm4(long i1, long i2)
|
||
|
{
|
||
|
int i;
|
||
|
unsigned long temp;
|
||
|
unsigned long index = (i2 + ylookup[i1]);
|
||
|
unsigned char *dest = (unsigned char*)(-ylookup[i1]);
|
||
|
do {
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
temp = ((unsigned)vplce[i]) >> machmv;
|
||
|
temp = (((unsigned char*)(bufplce[i]))[temp]);
|
||
|
if (temp != 255)
|
||
|
dest[index+i] = ((unsigned char*)(palookupoffse[i]))[temp];
|
||
|
vplce[i] += vince[i];
|
||
|
}
|
||
|
dest += fixchain;
|
||
|
} while (((unsigned)dest - fixchain) < ((unsigned)dest));
|
||
|
} /* mvlineasm4 */
|
||
|
|
||
|
/* #pragma aux setupspritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static long spal_eax;
|
||
|
static long smach_eax;
|
||
|
static long smach2_eax;
|
||
|
static long smach5_eax;
|
||
|
static long smach_ecx;
|
||
|
void setupspritevline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
spal_eax = i1;
|
||
|
smach_eax = (i5<<16);
|
||
|
smach2_eax = (i5>>16)+i2;
|
||
|
smach5_eax = smach2_eax + i4;
|
||
|
smach_ecx = i3;
|
||
|
} /* setupspritevline */
|
||
|
|
||
|
/* #pragma aux spritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void spritevline(long i1, unsigned long i2, long i3, unsigned long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned char *source = (unsigned char *)i5;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
|
||
|
dumblabel1:
|
||
|
i2 += smach_eax;
|
||
|
i1 = (i1&0xffffff00) | (*source&0xff);
|
||
|
if ((i2 - smach_eax) > i2) source += smach2_eax + 1;
|
||
|
else source += smach2_eax;
|
||
|
dumblabel2:
|
||
|
i1 = (i1&0xffffff00) | (((unsigned char *)spal_eax)[i1]&0xff);
|
||
|
*dest = i1;
|
||
|
dest += fixchain;
|
||
|
|
||
|
i4 += smach_ecx;
|
||
|
i4--;
|
||
|
if (!((i4 - smach_ecx) > i4) && i4 != 0)
|
||
|
goto dumblabel1;
|
||
|
if (i4 == 0) return;
|
||
|
i2 += smach_eax;
|
||
|
i1 = (i1&0xffffff00) | (*source&0xff);
|
||
|
if ((i2 - smach_eax) > i2) source += smach5_eax + 1;
|
||
|
else source += smach5_eax;
|
||
|
goto dumblabel2;
|
||
|
} /* spritevline */
|
||
|
|
||
|
/* #pragma aux msetupspritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static long mspal_eax;
|
||
|
static long msmach_eax;
|
||
|
static long msmach2_eax;
|
||
|
static long msmach5_eax;
|
||
|
static long msmach_ecx;
|
||
|
void msetupspritevline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
mspal_eax = i1;
|
||
|
msmach_eax = (i5<<16);
|
||
|
msmach2_eax = (i5>>16)+i2;
|
||
|
msmach5_eax = smach2_eax + i4;
|
||
|
msmach_ecx = i3;
|
||
|
} /* msetupspritevline */
|
||
|
|
||
|
/* #pragma aux mspritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void mspritevline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned char *source = (unsigned char *)i5;
|
||
|
unsigned char *dest = (unsigned char *)i6;
|
||
|
|
||
|
msdumblabel1:
|
||
|
i2 += smach_eax;
|
||
|
i1 = (i1&0xffffff00) | (*source&0xff);
|
||
|
if ((i2 - smach_eax) > i2) source += smach2_eax + 1;
|
||
|
else source += smach2_eax;
|
||
|
msdumblabel2:
|
||
|
if ((i1&0xff) != 255)
|
||
|
{
|
||
|
i1 = (i1&0xffffff00) | (((unsigned char *)spal_eax)[i1]&0xff);
|
||
|
*dest = i1;
|
||
|
}
|
||
|
dest += fixchain;
|
||
|
|
||
|
i4 += smach_ecx;
|
||
|
i4--;
|
||
|
if (!((i4 - smach_ecx) > i4) && i4 != 0)
|
||
|
goto msdumblabel1;
|
||
|
if (i4 == 0) return;
|
||
|
i2 += smach_eax;
|
||
|
i1 = (i1&0xffffff00) | (*source&0xff);
|
||
|
if ((i2 - smach_eax) > i2) source += smach5_eax + 1;
|
||
|
else source += smach5_eax;
|
||
|
goto msdumblabel2;
|
||
|
} /* mspritevline */
|
||
|
|
||
|
/* #pragma aux tsetupspritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
unsigned long tspal;
|
||
|
unsigned long tsmach_eax1;
|
||
|
unsigned long tsmach_eax2;
|
||
|
unsigned long tsmach_eax3;
|
||
|
unsigned long tsmach_ecx;
|
||
|
void tsetupspritevline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
tspal = i1;
|
||
|
tsmach_eax1 = i5 << 16;
|
||
|
tsmach_eax2 = (i5 >> 16) + i2;
|
||
|
tsmach_eax3 = tsmach_eax2 + i4;
|
||
|
tsmach_ecx = i3;
|
||
|
} /* tsetupspritevline */
|
||
|
|
||
|
/* #pragma aux tspritevline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void tspritevline(long i1, long i2, long i3, unsigned long i4, long i5, long i6)
|
||
|
{
|
||
|
while (i3)
|
||
|
{
|
||
|
i3--;
|
||
|
if (i3 != 0)
|
||
|
{
|
||
|
unsigned long adder = tsmach_eax2;
|
||
|
i4 += tsmach_ecx;
|
||
|
if (i4 < (i4 - tsmach_ecx)) adder = tsmach_eax3;
|
||
|
i1 = *((unsigned char *)i5);
|
||
|
i2 += tsmach_eax1;
|
||
|
if (i2 < (i2 - tsmach_eax1)) i5++;
|
||
|
i5 += adder;
|
||
|
// tstartsvline
|
||
|
if (i1 != 0xff)
|
||
|
{
|
||
|
unsigned short val;
|
||
|
val = ((unsigned char*)tspal)[i1];
|
||
|
val |= ((*((unsigned char *)i6))<<8);
|
||
|
if (transrev) val = ((val>>8)|(val<<8));
|
||
|
i1 = ((unsigned char *)tmach)[val];
|
||
|
*((unsigned char *)i6) = (i1&0xff);
|
||
|
}
|
||
|
i6 += fixchain;
|
||
|
}
|
||
|
}
|
||
|
} /* tspritevline */
|
||
|
|
||
|
/* #pragma aux mhline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static long mmach_eax;
|
||
|
static long mmach_asm3;
|
||
|
static long mmach_asm1;
|
||
|
static long mmach_asm2;
|
||
|
void mhlineskipmodify(long i1, unsigned long i2, unsigned long i3, long i4, long i5, long i6);
|
||
|
void mhline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
mmach_eax = i1;
|
||
|
mmach_asm3 = asm3;
|
||
|
mmach_asm1 = asm1;
|
||
|
mmach_asm2 = asm2;
|
||
|
mhlineskipmodify(asm2,i2,i3,i4,i5,i6);
|
||
|
} /* mhline */
|
||
|
|
||
|
/* #pragma aux mhlineskipmodify parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static unsigned char mshift_al = 26;
|
||
|
static unsigned char mshift_bl = 6;
|
||
|
void mhlineskipmodify(long i1, unsigned long i2, unsigned long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned long ebx;
|
||
|
int counter = (i3>>16);
|
||
|
while (counter >= 0)
|
||
|
{
|
||
|
ebx = i2 >> mshift_al;
|
||
|
ebx = shld (ebx, (unsigned)i5, mshift_bl);
|
||
|
i1 = ((unsigned char *)mmach_eax)[ebx];
|
||
|
if ((i1&0xff) != 0xff)
|
||
|
*((unsigned char *)i6) = (((unsigned char*)mmach_asm3)[i1]);
|
||
|
|
||
|
i2 += mmach_asm1;
|
||
|
i5 += mmach_asm2;
|
||
|
i6++;
|
||
|
counter--;
|
||
|
}
|
||
|
} /* mhlineskipmodify */
|
||
|
|
||
|
/* #pragma aux msethlineshift parm [eax][ebx] */
|
||
|
void msethlineshift(long i1, long i2)
|
||
|
{
|
||
|
i1 = 256-i1;
|
||
|
mshift_al = (i1&0x1f);
|
||
|
mshift_bl = (i2&0x1f);
|
||
|
} /* msethlineshift */
|
||
|
|
||
|
/* #pragma aux thline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static long tmach_eax;
|
||
|
static long tmach_asm3;
|
||
|
static long tmach_asm1;
|
||
|
static long tmach_asm2;
|
||
|
void thlineskipmodify(long i1, unsigned long i2, unsigned long i3, long i4, long i5, long i6);
|
||
|
void thline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
tmach_eax = i1;
|
||
|
tmach_asm3 = asm3;
|
||
|
tmach_asm1 = asm1;
|
||
|
tmach_asm2 = asm2;
|
||
|
thlineskipmodify(asm2,i2,i3,i4,i5,i6);
|
||
|
} /* thline */
|
||
|
|
||
|
/* #pragma aux thlineskipmodify parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
static unsigned char tshift_al = 26;
|
||
|
static unsigned char tshift_bl = 6;
|
||
|
void thlineskipmodify(long i1, unsigned long i2, unsigned long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
unsigned long ebx;
|
||
|
int counter = (i3>>16);
|
||
|
while (counter >= 0)
|
||
|
{
|
||
|
ebx = i2 >> tshift_al;
|
||
|
ebx = shld (ebx, (unsigned)i5, tshift_bl);
|
||
|
i1 = ((unsigned char *)tmach_eax)[ebx];
|
||
|
if ((i1&0xff) != 0xff)
|
||
|
{
|
||
|
unsigned short val = (((unsigned char*)tmach_asm3)[i1]);
|
||
|
val |= (*((unsigned char *)i6)<<8);
|
||
|
if (transrev) val = ((val>>8)|(val<<8));
|
||
|
*((unsigned char *)i6) = (((unsigned char*)tmach)[val]);
|
||
|
}
|
||
|
|
||
|
i2 += tmach_asm1;
|
||
|
i5 += tmach_asm2;
|
||
|
i6++;
|
||
|
counter--;
|
||
|
}
|
||
|
} /* thlineskipmodify */
|
||
|
|
||
|
/* #pragma aux tsethlineshift parm [eax][ebx] */
|
||
|
void tsethlineshift(long i1, long i2)
|
||
|
{
|
||
|
i1 = 256-i1;
|
||
|
tshift_al = (i1&0x1f);
|
||
|
tshift_bl = (i2&0x1f);
|
||
|
} /* tsethlineshift */
|
||
|
|
||
|
/* #pragma aux setupslopevlin parm [eax][ebx][ecx] modify [edx] */
|
||
|
static long slopemach_ebx;
|
||
|
static long slopemach_ecx;
|
||
|
static long slopemach_edx;
|
||
|
static unsigned char slopemach_ah1;
|
||
|
static unsigned char slopemach_ah2;
|
||
|
static float asm2_f;
|
||
|
typedef union { unsigned int i; float f; } bitwisef2i;
|
||
|
void setupslopevlin(long i1, long i2, long i3)
|
||
|
{
|
||
|
bitwisef2i c;
|
||
|
slopemach_ebx = i2;
|
||
|
slopemach_ecx = i3;
|
||
|
slopemach_edx = (1<<(i1&0x1f)) - 1;
|
||
|
slopemach_edx <<= ((i1&0x1f00)>>8);
|
||
|
slopemach_ah1 = 32-((i1&0x1f00)>>8);
|
||
|
slopemach_ah2 = (slopemach_ah1 - (i1&0x1f)) & 0x1f;
|
||
|
c.f = asm2_f = (float)asm1;
|
||
|
asm2 = c.i;
|
||
|
} /* setupslopevlin */
|
||
|
|
||
|
extern long reciptable[2048];
|
||
|
extern long globalx3, globaly3;
|
||
|
extern long fpuasm;
|
||
|
#define low32(a) ((a&0xffffffff))
|
||
|
#define high32(a) ((int)(((__int64)a&(__int64)0xffffffff00000000)>>32))
|
||
|
|
||
|
/* #pragma aux slopevlin parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
void slopevlin(long i1, unsigned long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
bitwisef2i c;
|
||
|
unsigned long ecx,eax,ebx,edx,esi,edi;
|
||
|
float a = (float) asm3 + asm2_f;
|
||
|
i1 -= slopemach_ecx;
|
||
|
esi = i5 + low32((__int64)globalx3 * (__int64)(i2<<3));
|
||
|
edi = i6 + low32((__int64)globaly3 * (__int64)(i2<<3));
|
||
|
ebx = i4;
|
||
|
do {
|
||
|
// -------------
|
||
|
// All this is calculating a fixed point approx. of 1/a
|
||
|
c.f = a;
|
||
|
fpuasm = eax = c.i;
|
||
|
edx = (((long)eax) < 0) ? 0xffffffff : 0;
|
||
|
eax = eax << 1;
|
||
|
ecx = (eax>>24); // exponent
|
||
|
eax = ((eax&0xffe000)>>11);
|
||
|
ecx = ((ecx&0xffffff00)|((ecx-2)&0xff));
|
||
|
eax = reciptable[eax/4];
|
||
|
eax >>= (ecx&0x1f);
|
||
|
eax ^= edx;
|
||
|
// -------------
|
||
|
edx = i2;
|
||
|
i2 = eax;
|
||
|
eax -= edx;
|
||
|
ecx = low32((__int64)globalx3 * (__int64)eax);
|
||
|
eax = low32((__int64)globaly3 * (__int64)eax);
|
||
|
a += asm2_f;
|
||
|
|
||
|
asm4 = ebx;
|
||
|
ecx = ((ecx&0xffffff00)|(ebx&0xff));
|
||
|
if (ebx >= 8) ecx = ((ecx&0xffffff00)|8);
|
||
|
|
||
|
ebx = esi;
|
||
|
edx = edi;
|
||
|
while ((ecx&0xff))
|
||
|
{
|
||
|
ebx >>= slopemach_ah2;
|
||
|
esi += ecx;
|
||
|
edx >>= slopemach_ah1;
|
||
|
ebx &= slopemach_edx;
|
||
|
edi += eax;
|
||
|
i1 += slopemach_ecx;
|
||
|
edx = ((edx&0xffffff00)|((((unsigned char *)(ebx+edx))[slopemach_ebx])));
|
||
|
ebx = *((unsigned long*)i3); // register trickery
|
||
|
i3 -= 4;
|
||
|
eax = ((eax&0xffffff00)|(*((unsigned char *)(ebx+edx))));
|
||
|
ebx = esi;
|
||
|
*((unsigned char *)i1) = (eax&0xff);
|
||
|
edx = edi;
|
||
|
ecx = ((ecx&0xffffff00)|((ecx-1)&0xff));
|
||
|
}
|
||
|
ebx = asm4;
|
||
|
ebx -= 8; // BITSOFPRECISIONPOW
|
||
|
} while ((long)ebx > 0);
|
||
|
} /* slopevlin */
|
||
|
|
||
|
/* #pragma aux settransnormal parm */
|
||
|
void settransnormal(void)
|
||
|
{
|
||
|
transrev = 0;
|
||
|
} /* settransnormal */
|
||
|
|
||
|
/* #pragma aux settransreverse parm */
|
||
|
void settransreverse(void)
|
||
|
{
|
||
|
transrev = 1;
|
||
|
} /* settransreverse */
|
||
|
|
||
|
/* #pragma aux setupdrawslab parm [eax][ebx] */
|
||
|
long setupdrawslab(long i1, long i2)
|
||
|
{
|
||
|
long retval = 0;
|
||
|
/*
|
||
|
__asm__ __volatile__ (
|
||
|
"call _asm_setupdrawslab \n\t"
|
||
|
: "=a" (retval)
|
||
|
: "a" (i1), "b" (i2)
|
||
|
: "cc", "memory");
|
||
|
*/
|
||
|
return(retval);
|
||
|
/*
|
||
|
_asm_setupdrawslab:
|
||
|
mov dword [voxbpl1+2], eax
|
||
|
mov dword [voxbpl2+2], eax
|
||
|
mov dword [voxbpl3+2], eax
|
||
|
mov dword [voxbpl4+2], eax
|
||
|
mov dword [voxbpl5+2], eax
|
||
|
mov dword [voxbpl6+2], eax
|
||
|
mov dword [voxbpl7+2], eax
|
||
|
mov dword [voxbpl8+2], eax
|
||
|
|
||
|
mov dword [voxpal1+2], ebx
|
||
|
mov dword [voxpal2+2], ebx
|
||
|
mov dword [voxpal3+2], ebx
|
||
|
mov dword [voxpal4+2], ebx
|
||
|
mov dword [voxpal5+2], ebx
|
||
|
mov dword [voxpal6+2], ebx
|
||
|
mov dword [voxpal7+2], ebx
|
||
|
mov dword [voxpal8+2], ebx
|
||
|
ret
|
||
|
*/
|
||
|
} /* setupdrawslab */
|
||
|
|
||
|
/* #pragma aux drawslab parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
long drawslab(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
long retval = 0;
|
||
|
/*
|
||
|
__asm__ __volatile__ (
|
||
|
"call _asm_drawslab \n\t"
|
||
|
: "=a" (retval)
|
||
|
: "a" (i1), "b" (i2), "c" (i3), "d" (i4), "S" (i5), "D" (i6)
|
||
|
: "cc", "memory");
|
||
|
*/
|
||
|
return(retval);
|
||
|
/*
|
||
|
_asm_drawslab:
|
||
|
push ebp
|
||
|
cmp eax, 2
|
||
|
je voxbegdraw2
|
||
|
ja voxskip2
|
||
|
xor eax, eax
|
||
|
voxbegdraw1:
|
||
|
mov ebp, ebx
|
||
|
shr ebp, 16
|
||
|
add ebx, edx
|
||
|
dec ecx
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal1: mov al, byte [eax+88888888h]
|
||
|
mov byte [edi], al
|
||
|
voxbpl1: lea edi, [edi+88888888h]
|
||
|
jnz voxbegdraw1
|
||
|
pop ebp
|
||
|
ret
|
||
|
|
||
|
voxbegdraw2:
|
||
|
mov ebp, ebx
|
||
|
shr ebp, 16
|
||
|
add ebx, edx
|
||
|
xor eax, eax
|
||
|
dec ecx
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal2: mov al, byte [eax+88888888h]
|
||
|
mov ah, al
|
||
|
mov word [edi], ax
|
||
|
voxbpl2: lea edi, [edi+88888888h]
|
||
|
jnz voxbegdraw2
|
||
|
pop ebp
|
||
|
ret
|
||
|
|
||
|
voxskip2:
|
||
|
cmp eax, 4
|
||
|
jne voxskip4
|
||
|
xor eax, eax
|
||
|
voxbegdraw4:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal3: mov al, byte [eax+88888888h]
|
||
|
mov ah, al
|
||
|
shl eax, 8
|
||
|
mov al, ah
|
||
|
shl eax, 8
|
||
|
mov al, ah
|
||
|
mov dword [edi], eax
|
||
|
voxbpl3: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegdraw4
|
||
|
pop ebp
|
||
|
ret
|
||
|
|
||
|
voxskip4:
|
||
|
add eax, edi
|
||
|
|
||
|
test edi, 1
|
||
|
jz voxskipslab1
|
||
|
cmp edi, eax
|
||
|
je voxskipslab1
|
||
|
|
||
|
push eax
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edi
|
||
|
voxbegslab1:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal4: mov al, byte [eax+88888888h]
|
||
|
mov byte [edi], al
|
||
|
voxbpl4: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegslab1
|
||
|
pop edi
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
pop eax
|
||
|
inc edi
|
||
|
|
||
|
voxskipslab1:
|
||
|
push eax
|
||
|
test edi, 2
|
||
|
jz voxskipslab2
|
||
|
dec eax
|
||
|
cmp edi, eax
|
||
|
jge voxskipslab2
|
||
|
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edi
|
||
|
voxbegslab2:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal5: mov al, byte [eax+88888888h]
|
||
|
mov ah, al
|
||
|
mov word [edi], ax
|
||
|
voxbpl5: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegslab2
|
||
|
pop edi
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
add edi, 2
|
||
|
|
||
|
voxskipslab2:
|
||
|
mov eax, [esp]
|
||
|
|
||
|
sub eax, 3
|
||
|
cmp edi, eax
|
||
|
jge voxskipslab3
|
||
|
|
||
|
voxprebegslab3:
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edi
|
||
|
voxbegslab3:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal6: mov al, byte [eax+88888888h]
|
||
|
mov ah, al
|
||
|
shl eax, 8
|
||
|
mov al, ah
|
||
|
shl eax, 8
|
||
|
mov al, ah
|
||
|
mov dword [edi], eax
|
||
|
voxbpl6: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegslab3
|
||
|
pop edi
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
add edi, 4
|
||
|
|
||
|
mov eax, [esp]
|
||
|
|
||
|
sub eax, 3
|
||
|
cmp edi, eax
|
||
|
jl voxprebegslab3
|
||
|
|
||
|
voxskipslab3:
|
||
|
mov eax, [esp]
|
||
|
|
||
|
dec eax
|
||
|
cmp edi, eax
|
||
|
jge voxskipslab4
|
||
|
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edi
|
||
|
voxbegslab4:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal7: mov al, byte [eax+88888888h]
|
||
|
mov ah, al
|
||
|
mov word [edi], ax
|
||
|
voxbpl7: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegslab4
|
||
|
pop edi
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
add edi, 2
|
||
|
|
||
|
voxskipslab4:
|
||
|
pop eax
|
||
|
|
||
|
cmp edi, eax
|
||
|
je voxskipslab5
|
||
|
|
||
|
voxbegslab5:
|
||
|
mov ebp, ebx
|
||
|
add ebx, edx
|
||
|
shr ebp, 16
|
||
|
xor eax, eax
|
||
|
mov al, byte [esi+ebp]
|
||
|
voxpal8: mov al, byte [eax+88888888h]
|
||
|
mov byte [edi], al
|
||
|
voxbpl8: add edi, 88888888h
|
||
|
dec ecx
|
||
|
jnz voxbegslab5
|
||
|
|
||
|
voxskipslab5:
|
||
|
pop ebp
|
||
|
ret
|
||
|
*/
|
||
|
} /* drawslab */
|
||
|
|
||
|
/* #pragma aux stretchhline parm [eax][ebx][ecx][edx][esi][edi] */
|
||
|
long stretchhline(long i1, long i2, long i3, long i4, long i5, long i6)
|
||
|
{
|
||
|
long retval = 0;
|
||
|
/*
|
||
|
__asm__ __volatile__ (
|
||
|
"call _asm_stretchhline \n\t"
|
||
|
: "=a" (retval)
|
||
|
: "a" (i1), "b" (i2), "c" (i3), "d" (i4), "S" (i5), "D" (i6)
|
||
|
: "cc", "memory");
|
||
|
*/
|
||
|
return(retval);
|
||
|
/*
|
||
|
_asm_stretchhline:
|
||
|
push ebp
|
||
|
|
||
|
mov eax, ebx
|
||
|
shl ebx, 16
|
||
|
sar eax, 16
|
||
|
and ecx, 0000ffffh
|
||
|
or ecx, ebx
|
||
|
|
||
|
add esi, eax
|
||
|
mov eax, edx
|
||
|
mov edx, esi
|
||
|
|
||
|
mov ebp, eax
|
||
|
shl eax, 16
|
||
|
sar ebp, 16
|
||
|
|
||
|
add ecx, eax
|
||
|
adc esi, ebp
|
||
|
|
||
|
add eax, eax
|
||
|
adc ebp, ebp
|
||
|
mov dword [loinc1+2], eax
|
||
|
mov dword [loinc2+2], eax
|
||
|
mov dword [loinc3+2], eax
|
||
|
mov dword [loinc4+2], eax
|
||
|
|
||
|
inc ch
|
||
|
|
||
|
jmp begloop
|
||
|
|
||
|
begloop:
|
||
|
mov al, [edx]
|
||
|
loinc1: sub ebx, 88888888h
|
||
|
sbb edx, ebp
|
||
|
mov ah, [esi]
|
||
|
loinc2: sub ecx, 88888888h
|
||
|
sbb esi, ebp
|
||
|
sub edi, 4
|
||
|
shl eax, 16
|
||
|
loinc3: sub ebx, 88888888h
|
||
|
mov al, [edx]
|
||
|
sbb edx, ebp
|
||
|
mov ah, [esi]
|
||
|
loinc4: sub ecx, 88888888h
|
||
|
sbb esi, ebp
|
||
|
mov [edi], eax
|
||
|
dec cl
|
||
|
jnz begloop
|
||
|
dec ch
|
||
|
jnz begloop
|
||
|
|
||
|
pop ebp
|
||
|
ret
|
||
|
*/
|
||
|
} /* stretchhline */
|