49 static Uint8 _apu_stack[16];
51 static Uint8 _apu_status;
55 #define _APU_F_CARRY 1
56 #define _APU_F_OVERFLOW 2
57 #define _APU_F_UNDERFLOW 4
58 #define _APU_F_NEGARG 8
59 #define _APU_F_ZERODIV 16
60 #define _APU_F_LARGE 24
61 #define _APU_F_ZERO 32
62 #define _APU_F_SIGN 64
70 memset(_apu_stack, 0,
sizeof _apu_stack);
80 static void _apu_move(
int n)
82 _apu_tos = (_apu_tos + n) & 0xF;
86 static Uint8 _apu_look8(
int depth)
88 return _apu_stack[(_apu_tos - depth) & 0xF];
92 static Uint8 _apu_pop8()
95 return _apu_look8(-1);
109 _apu_stack[_apu_tos] =
data;
119 static int _apu_pop_fix16(
void) {
120 int data = _apu_pop8() << 8;
127 static void _apu_push_fix16(
int data) {
135 _apu_push8(
data >> 8);
138 static Sint64 _apu_pop_fix32(
void) {
139 Sint64
data = _apu_pop8() << 24;
140 data |= _apu_pop8() << 16;
141 data |= _apu_pop8() << 8;
147 static void _apu_push_fix32(Sint64
data) {
155 _apu_push8(
data >> 8);
156 _apu_push8(
data >> 16);
157 _apu_push8(
data >> 24);
167 static double _apu_pop_float(
void)
169 int exp = _apu_pop8();
170 int data = _apu_pop8() << 16;
172 data |= _apu_pop8() << 8;
174 if (!(
data & 0x800000))
return 0.0;
176 if (exp & 64) exp = (exp & 63) - 64;
else exp &= 63;
177 fdata = pow(2, exp) * ((double)
data / 16777216.0);
183 static void _apu_push_float(
double data)
186 if (!isfinite(
data)) {
206 i = (
data * 16777216.0);
218 }
else if (exp < -64) {
220 exp = ((64 + exp) & 63) | 64;
222 }
else if (exp < 0) {
223 exp = ((64 + exp) & 63) | 64;
241 static void _apu_sz_fix16(
void) {
242 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
243 if (_apu_look8(0) + _apu_look8(1) == 0) _apu_status |=
_APU_F_ZERO;
245 static void _apu_sz_fix32(
void) {
246 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
247 if (_apu_look8(0) + _apu_look8(1) + _apu_look8(2) + _apu_look8(3) == 0) _apu_status |=
_APU_F_ZERO;
249 static void _apu_sz_float(
void) {
250 if (_apu_look8(0) & 128) _apu_status |=
_APU_F_SIGN;
251 if ((_apu_look8(1) & 128) == 0) _apu_status |=
_APU_F_ZERO;
255 static void _apu_xchg(
int d1,
int d2) {
256 Uint8 n = _apu_look8(d1);
257 _apu_stack[(_apu_tos - d1) & 0xF] = _apu_look8(d2);
258 _apu_stack[(_apu_tos - d2) & 0xF] = n;
260 static void _apu_copy(
int from,
int to) {
261 _apu_stack[(_apu_tos - to) & 0xF] = _apu_look8(from);
272 static void _apu_carry ( Sint64 val, Sint64 limit )
274 if (val >= limit * 2 || val < -limit * 2) {
278 }
else if (val >= limit || val < -limit) {
298 switch (cmd & 0x7F) {
303 i = _apu_pop_fix16() + _apu_pop_fix16();
305 _apu_carry(i, 0x8000);
309 i = _apu_pop_fix16();
310 i = _apu_pop_fix16() - i;
312 _apu_carry(i, 0x8000);
316 i = _apu_pop_fix16() * _apu_pop_fix16();
321 i = _apu_pop_fix16() * _apu_pop_fix16();
322 _apu_push_fix16(i >> 16);
326 i = _apu_pop_fix16();
328 _apu_push_fix16(_apu_pop_fix16() / i);
340 l = _apu_pop_fix32() + _apu_pop_fix32();
342 _apu_carry(l, 0x80000000L);
346 l = _apu_pop_fix32();
347 l = _apu_pop_fix32() - l;
349 _apu_carry(l, 0x80000000L);
353 l = _apu_pop_fix32() * _apu_pop_fix32();
358 l = _apu_pop_fix32() * _apu_pop_fix32();
359 _apu_push_fix32(l >> 32);
363 l = _apu_pop_fix32();
365 _apu_push_fix32(_apu_pop_fix32() / l);
377 f = _apu_pop_float();
378 _apu_push_float(_apu_pop_float() + f);
379 clocks = (f ? 200 : 24);
382 f = _apu_pop_float();
383 _apu_push_float(_apu_pop_float() - f);
384 clocks = (f ? 200 : 26);
387 _apu_push_float(_apu_pop_float() * _apu_pop_float());
391 f = _apu_pop_float();
393 _apu_push_float(_apu_pop_float() / f);
405 f = _apu_pop_float();
406 _apu_push_float(sqrt(fabs(f)));
411 _apu_push_float(sin(_apu_pop_float()));
415 _apu_push_float(cos(_apu_pop_float()));
419 _apu_push_float(tan(_apu_pop_float()));
423 _apu_push_float(asin(_apu_pop_float()));
427 _apu_push_float(acos(_apu_pop_float()));
431 _apu_push_float(atan(_apu_pop_float()));
435 f = _apu_pop_float();
437 _apu_push_float(log10(f));
446 f = _apu_pop_float();
448 _apu_push_float(log(f));
457 f = _apu_pop_float();
458 _apu_push_float(pow(M_E, f));
459 clocks = (f > 32 ? 34 : 4000);
462 f = _apu_pop_float();
463 _apu_push_float(pow(_apu_pop_float(), f));
474 _apu_push_fix16(_apu_pop_float());
478 _apu_push_fix32(_apu_pop_float());
482 _apu_push_float(_apu_pop_fix16());
486 _apu_push_float(_apu_pop_fix32());
491 _apu_push_fix16(-_apu_pop_fix16());
495 _apu_push_fix32(-_apu_pop_fix32());
499 if (_apu_look8(1) & 128) {
500 _apu_stack[_apu_tos] ^= 128;
501 if (_apu_stack[_apu_tos] & 128) _apu_status |=
_APU_F_SIGN;
581 DEBUG(
"APU: not implemented/unknown Am9511 command: %02Xh" NL, cmd);