48 static Uint8 _apu_stack[16];
50 static Uint8 _apu_status;
54 #define _APU_F_CARRY 1
55 #define _APU_F_OVERFLOW 2
56 #define _APU_F_UNDERFLOW 4
57 #define _APU_F_NEGARG 8
58 #define _APU_F_ZERODIV 16
59 #define _APU_F_LARGE 24
60 #define _APU_F_ZERO 32
61 #define _APU_F_SIGN 64
69 memset(_apu_stack, 0,
sizeof _apu_stack);
79 static void _apu_move(
int n)
81 _apu_tos = (_apu_tos + n) & 0xF;
85 static Uint8 _apu_look8(
int depth)
87 return _apu_stack[(_apu_tos - depth) & 0xF];
91 static Uint8 _apu_pop8()
94 return _apu_look8(-1);
108 _apu_stack[_apu_tos] =
data;
118 static int _apu_pop_fix16(
void) {
119 int data = _apu_pop8() << 8;
126 static void _apu_push_fix16(
int data) {
134 _apu_push8(
data >> 8);
137 static Sint64 _apu_pop_fix32(
void) {
138 Sint64
data = _apu_pop8() << 24;
139 data |= _apu_pop8() << 16;
140 data |= _apu_pop8() << 8;
146 static void _apu_push_fix32(Sint64
data) {
154 _apu_push8(
data >> 8);
155 _apu_push8(
data >> 16);
156 _apu_push8(
data >> 24);
166 static double _apu_pop_float()
168 int exp = _apu_pop8();
169 int data = _apu_pop8() << 16;
171 data |= _apu_pop8() << 8;
173 if (!(
data & 0x800000))
return 0.0;
175 if (exp & 64) exp = (exp & 63) - 64;
else exp &= 63;
176 fdata = pow(2, exp) * ((double)
data / 16777216.0);
182 static void _apu_push_float(
double data)
185 if (!isfinite(
data)) {
205 i = (
data * 16777216.0);
217 }
else if (exp < -64) {
219 exp = ((64 + exp) & 63) | 64;
221 }
else if (exp < 0) {
222 exp = ((64 + exp) & 63) | 64;
240 static void _apu_sz_fix16(
void) {
241 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
242 if (_apu_look8(0) + _apu_look8(1) == 0) _apu_status |=
_APU_F_ZERO;
244 static void _apu_sz_fix32(
void) {
245 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
246 if (_apu_look8(0) + _apu_look8(1) + _apu_look8(2) + _apu_look8(3) == 0) _apu_status |=
_APU_F_ZERO;
248 static void _apu_sz_float(
void) {
249 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
250 if ((_apu_look8(1) & 128) == 0) _apu_status |=
_APU_F_ZERO;
254 static void _apu_xchg(
int d1,
int d2) {
255 Uint8 n = _apu_look8(d1);
256 _apu_stack[(_apu_tos - d1) & 0xF] = _apu_look8(d2);
257 _apu_stack[(_apu_tos - d2) & 0xF] = n;
259 static void _apu_copy(
int from,
int to) {
260 _apu_stack[(_apu_tos - to) & 0xF] = _apu_look8(from);
271 static void _apu_carry ( Sint64 val, Sint64 limit )
273 if (val >= limit * 2 || val < -limit * 2) {
277 }
else if (val >= limit || val < -limit) {
297 switch (cmd & 0x7F) {
302 i = _apu_pop_fix16() + _apu_pop_fix16();
304 _apu_carry(i, 0x8000);
308 i = _apu_pop_fix16();
309 i = _apu_pop_fix16() - i;
311 _apu_carry(i, 0x8000);
315 i = _apu_pop_fix16() * _apu_pop_fix16();
320 i = _apu_pop_fix16() * _apu_pop_fix16();
321 _apu_push_fix16(i >> 16);
325 i = _apu_pop_fix16();
327 _apu_push_fix16(_apu_pop_fix16() / i);
339 l = _apu_pop_fix32() + _apu_pop_fix32();
341 _apu_carry(l, 0x80000000L);
345 l = _apu_pop_fix32();
346 l = _apu_pop_fix32() - l;
348 _apu_carry(l, 0x80000000L);
352 l = _apu_pop_fix32() * _apu_pop_fix32();
357 l = _apu_pop_fix32() * _apu_pop_fix32();
358 _apu_push_fix32(l >> 32);
362 l = _apu_pop_fix32();
364 _apu_push_fix32(_apu_pop_fix32() / l);
376 f = _apu_pop_float();
377 _apu_push_float(_apu_pop_float() + f);
378 clocks = (f ? 200 : 24);
381 f = _apu_pop_float();
382 _apu_push_float(_apu_pop_float() - f);
383 clocks = (f ? 200 : 26);
386 _apu_push_float(_apu_pop_float() * _apu_pop_float());
390 f = _apu_pop_float();
392 _apu_push_float(_apu_pop_float() / f);
404 f = _apu_pop_float();
405 _apu_push_float(sqrt(fabs(f)));
410 _apu_push_float(sin(_apu_pop_float()));
414 _apu_push_float(cos(_apu_pop_float()));
418 _apu_push_float(tan(_apu_pop_float()));
422 _apu_push_float(asin(_apu_pop_float()));
426 _apu_push_float(acos(_apu_pop_float()));
430 _apu_push_float(atan(_apu_pop_float()));
434 f = _apu_pop_float();
436 _apu_push_float(log10(f));
445 f = _apu_pop_float();
447 _apu_push_float(log(f));
456 f = _apu_pop_float();
457 _apu_push_float(pow(M_E, f));
458 clocks = (f > 32 ? 34 : 4000);
461 f = _apu_pop_float();
462 _apu_push_float(pow(_apu_pop_float(), f));
473 _apu_push_fix16(_apu_pop_float());
477 _apu_push_fix32(_apu_pop_float());
481 _apu_push_float(_apu_pop_fix16());
485 _apu_push_float(_apu_pop_fix32());
490 _apu_push_fix16(-_apu_pop_fix16());
494 _apu_push_fix32(-_apu_pop_fix32());
498 if (_apu_look8(1) & 128) {
499 _apu_stack[_apu_tos] ^= 128;
500 if (_apu_stack[_apu_tos] & 128) _apu_status |=
_APU_F_SIGN;
580 DEBUG(
"APU: not implemented/unknown Am9511 command: %02Xh" NL, cmd);