home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
PROGRAM
/
DJEMU106.ZIP
/
EMU387
/
E16.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-02
|
4KB
|
220 lines
#include "emu.h"
#include "rmov.h"
#include "const.h"
#include "compare.h"
void f2xm1()
{
if (empty())
return;
reg xloga, val, rv, bottom, tmp;
long i;
r_mul(CONST_LN2, st(), xloga);
r_mov(xloga, val);
r_mov(xloga, rv);
for (i=2; i<16; i++)
{
r_mov(&i, bottom);
r_mul(val, xloga, tmp);
r_div(tmp, bottom, val);
r_add(val, rv, tmp);
r_mov(tmp, rv);
}
r_mov(rv, st());
}
// logb(x) = loga(x) / loga(b)
// log2(x) = loge(x) / loge(2)
void fyl2x()
{
if (empty())
return;
reg z, x, nom, denom, xsquare, term, temp, sum, pow;
long exponent;
reg CONST_SQRT2 = { SIGN_POS, TW_V, EXP_BIAS, 0xf9de6000, 0xb504f333 };
r_mov(st(), z);
if ((z.tag != TW_V) || (z.sign != SIGN_POS)) {
return exception(EX_I); // not valid, zero or negative
}
exponent = (long)(z.exp - EXP_BIAS);
z.exp=EXP_BIAS;
if (compare(z, CONST_SQRT2) == COMP_A_GT_B) {
(z.exp)--;
exponent++;
}
r_sub(z, CONST_1, nom);
r_add(z, CONST_1, denom);
r_div(nom, denom, x);
r_mov(x, pow);
r_mov(x, sum);
r_mul(x, x, xsquare);
for (long i=3; i<25; i+=2)
{
r_mul(pow, xsquare, temp);
r_mov(temp, pow);
r_mov(&i, denom);
r_div(pow, denom, term);
r_add(term, sum, temp);
r_mov(temp, sum);
}
r_div(sum, CONST_LN2, temp);
temp.exp++;
if (exponent) {
r_mov(&exponent, term);
r_add(term, temp, sum);
} else {
r_mov(temp, sum);
}
r_mul(sum, st(1), temp);
r_mov(temp, st(1));
st().tag = TW_E;
top++;
}
void fptan()
{
extern void fsincos();
fsincos();
if (empty(1))
return;
reg tmp;
r_div(st(1), st(), tmp);
r_mov(tmp, st(1));
r_mov(CONST_1, st());
}
void fpatan()
{
if (empty(1))
return;
if (mag_same(st(), CONST_Z))
{
r_mov(CONST_PI2, st(1));
st().tag = TW_E;
top++;
return;
}
if (mag_same(st(1), CONST_Z))
{
r_mov(CONST_Z, st(1));
st().tag = TW_E;
top++;
return;
}
reg x2, sum, term, pow, temp;
int quadrant = 0;
if (st(1).sign == SIGN_NEG)
quadrant |= 1;
if (st(0).sign == SIGN_NEG)
quadrant |= 2;
st(1).sign = st().sign = SIGN_POS;
if (compare(st(1), st()) == COMP_A_GT_B)
{
quadrant |= 4;
r_mov(st(1), temp);
r_mov(st(), st(1));
r_mov(temp, st());
}
r_div(st(1), st(), sum);
r_mul(sum, sum, x2);
r_mov(sum, pow);
x2.sign ^= SIGN_POS^SIGN_NEG;
for (long i=3; i<25; i+=2)
{
r_mul(pow, x2, temp);
r_mov(temp, pow);
r_mov(&i, temp);
r_div(pow, temp, term);
r_add(sum, term, temp);
r_mov(temp, sum);
}
if (quadrant & 4)
{
r_sub(CONST_PI2, sum, temp);
r_mov(temp, sum);
}
if (quadrant & 2)
{
r_sub(CONST_PI, sum, temp);
r_mov(temp, sum);
}
if (quadrant & 1)
sum.sign ^= SIGN_POS^SIGN_NEG;
r_mov(sum, st(1));
st().tag = TW_E;
top++;
}
void fxtract()
{
if (empty())
return;
if (full())
return;
top--;
r_mov(st(1), st());
st().exp = EXP_BIAS;
long e = st(1).exp - EXP_BIAS;
r_mov(&e, st(1));
}
extern int fprem_do(reg&,reg&,int);
void fprem1()
{
if (empty(1))
return;
int q = fprem_do(st(), st(1), RC_RND);
if (q == -1)
setcc(SW_C2);
else
{
int c = 0;
if (q&4) c |= SW_C3;
if (q&2) c |= SW_C1;
if (q&1) c |= SW_C0;
setcc(c);
}
}
void fdecstp()
{
top--;
}
void fincstp()
{
top++;
}
FUNC emu_16_table[] = {
f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp
};
void emu_16()
{
if (modrm > 0277)
{
(emu_16_table[modrm&7])();
}
else
{
emu_bad();
}
}