📄 dsp1.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and * Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and * Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#include "snes9x.h"#include "dsp1.h"#include "missing.h"#include "memmap.h"#include <math.h>#ifndef M_PI#define M_PI 3.14159265359#endif#define CLIPU8(v) if(v < 0) v = 0; else if(v > 255) v = 255#define CLIP8(v) if(v < -128) v = -128; else if(v > 127) v = 127#define CLIP16(v) if(v < -32768) v = -32768; else if(v > 32767) v = 32767#define DEG(d) (M_PI * 2 * d / 360.0)int CosTable2[256]={65536,65516,65457,65358,65220,65043,64826,64571,64276,63943,63571,63161,62713,62227,61704,61144,60546,59912,59243,58537,57796,57020,56210,55367,54489,53579,52637,51663,50658,49622,48556,47461,46338,45187,44008,42803,41572,40316,39036,37732,36406,35057,33688,32298,30889,29461,28015,26553,25074,23581,22073,20552,19018,17473,15918,14353,12779,11198,9610,8016,6417,4814,3209,1601,-6,-1615,-3222,-4828,-6430,-8029,-9623,-11211,-12792,-14366,-15931,-17486,-19031,-20565,-22086,-23593,-25087,-26565,-28028,-29473,-30901,-32310,-33700,-35069,-36417,-37743,-39047,-40327,-41583,-42813,-44018,-45197,-46348,-47471,-48565,-49631,-50666,-51671,-52645,-53587,-54497,-55374,-56217,-57027,-57802,-58543,-59248,-59918,-60551,-61148,-61709,-62232,-62717,-63165,-63575,-63946,-64279,-64573,-64828,-65044,-65221,-65359,-65457,-65516,-65535,-65515,-65456,-65357,-65219,-65041,-64824,-64568,-64273,-63940,-63568,-63158,-62709,-62223,-61699,-61139,-60541,-59907,-59237,-58531,-57790,-57014,-56203,-55359,-54482,-53571,-52629,-51654,-50649,-49613,-48547,-47452,-46328,-45177,-43998,-42793,-41562,-40306,-39025,-37721,-36395,-35046,-33676,-32286,-30877,-29449,-28003,-26540,-25062,-23568,-22060,-20539,-19005,-17460,-15905,-14340,-12766,-11184,-9596,-8002,-6403,-4801,-3195,-1588,20,1628,3236,4841,6444,8043,9636,11224,12806,14379,15944,17500,19044,20578,22099,23606,25099,26578,28040,29485,30913,32322,33711,35080,36428,37754,39058,40338,41593,42824,44028,45206,46357,47480,48575,49640,50675,51680,52653,53595,54504,55381,56224,57034,57809,58549,59254,59923,60557,61153,61713,62236,62721,63168,63578,63949,64281,64575,64830,65046,65223,65360,65458,65516};int SinTable2[256]={0,1608,3215,4821,6424,8022,9616,11204,12786,14359,15924,17480,19025,20558,22079,23587,25081,26559,28021,29467,30895,32304,33694,35063,36411,37738,39041,40322,41577,42808,44013,45192,46343,47466,48561,49626,50662,51667,52641,53583,54493,55370,56214,57024,57799,58540,59245,59915,60549,61146,61706,62229,62715,63163,63573,63944,64277,64572,64827,65043,65221,65358,65457,65516,65535,65516,65456,65357,65219,65042,64825,64569,64275,63941,63570,63159,62711,62225,61702,61141,60544,59910,59240,58534,57793,57017,56207,55363,54486,53575,52633,51659,50653,49617,48552,47457,46333,45182,44003,42798,41567,40311,39031,37727,36400,35052,33682,32292,30883,29455,28009,26547,25068,23574,22067,20545,19012,17467,15911,14346,12772,11191,9603,8009,6410,4807,3202,1594,-13,-1622,-3229,-4834,-6437,-8036,-9630,-11218,-12799,-14373,-15938,-17493,-19038,-20571,-22092,-23600,-25093,-26571,-28034,-29479,-30907,-32316,-33705,-35075,-36423,-37749,-39052,-40332,-41588,-42818,-44023,-45201,-46352,-47476,-48570,-49635,-50671,-51675,-52649,-53591,-54501,-55377,-56221,-57030,-57806,-58546,-59251,-59921,-60554,-61151,-61711,-62234,-62719,-63167,-63576,-63947,-64280,-64574,-64829,-65045,-65222,-65359,-65458,-65516,-65535,-65515,-65456,-65356,-65218,-65040,-64823,-64567,-64272,-63938,-63566,-63156,-62707,-62221,-61697,-61136,-60538,-59904,-59234,-58528,-57786,-57010,-56200,-55356,-54478,-53567,-52625,-51650,-50645,-49609,-48543,-47447,-46324,-45172,-43993,-42788,-41556,-40300,-39020,-37716,-36389,-35040,-33670,-32280,-30871,-29443,-27997,-26534,-25056,-23562,-22054,-20532,-18999,-17454,-15898,-14333,-12759,-11178,-9589,-7995,-6397,-4794,-3188,-1581};int16 Op02FX = 0;int16 Op02FY = 0;int16 Op02FZ = 0;int16 Op02LFE = 0;int16 Op02LES = 0;int16 Op02AZS = 0;int16 Op02AAS = 0;int16 Op02CX = 0;int16 Op02CY = 0;int16 Op02CXF = 0;int16 Op02CYF = 0;int16 Op02VOF = 0;int16 Op02VVA = 0;int16 Op0AVS = 0;int16 Op0AA = 0;int16 Op0AB = 0;int16 Op0AC = 0;int16 Op0AD = 0;uint16 Op1CAZ = 0;uint16 Op1CAX = 0;uint16 Op1CAY = 0;int16 Op1CX = 0;int16 Op1CY = 0;int16 Op1CZ = 0;int16 Op1CX1 = 0;int16 Op1CY1 = 0;int16 Op1CZ1 = 0;int16 Op1CX2 = 0;int16 Op1CY2 = 0;int16 Op1CZ2 = 0;int16 Op1CX3 = 0;int16 Op1CY3 = 0;int16 Op1CZ3 = 0;int32 Op03F = 0;int32 Op03L = 0;int32 Op03U = 0;int16 Op03X = 0;int16 Op03Y = 0;int16 Op03Z = 0;int16 Op01m = 0;int16 Op01Zr = 0;int16 Op01Xr = 0;int16 Op01Yr = 0;int16 Op0DX = 0;int16 Op0DY = 0;int16 Op0DZ = 0;int32 Op0DF = 0;int32 Op0DL = 0;int32 Op0DU = 0;int16 Op14Zr = 0;int16 Op14Xr = 0;int16 Op14Yr = 0;int16 Op14U = 0;int16 Op14F = 0;int16 Op14L = 0;int16 Op14Zrr = 0;int16 Op14Xrr = 0;int16 Op14Yrr = 0;double matrix[4][4] = {0};double smat[4][4] = {0};double tmat[4][4] = {0};double xmat[4][4] = {0};double ymat[4][4] = {0};double zmat[4][4] = {0};double matrix0[4][4] = {0};double matrix1[4][4] = {0};double matrix2[4][4] = {0};double matrixI0[4][4] = {0};double matrixI1[4][4] = {0};double matrixI2[4][4] = {0};int16 DSPOp00 (int16 K, int16 I);void DSPOp02 ();void DSPOp0A ();void DSPOp1C ();void DSPOp14 ();void DSPOp01 ();void DSPOp11 ();void DSPOp21 ();void DSPOp0D ();void DSPOp1D ();void DSPOp2D ();void DSPOp03 ();void DSPOp13 ();void DSPOp23 ();//#define REVERSE_MATRIX_ROTATION// Screen coordinate base (number of units pr pixel)#define SCREEN_BASE_X 1.0#define SCREEN_BASE_Y 1.0//#define SCREEN_BASE_X 128.0//#define SCREEN_BASE_Y 128.0// Screen center X and Y (number of pixels)#define SCREEN_CENTER_X 0.0#define SCREEN_CENTER_Y 0.0// Screen width and height (number of pixels)#define SCREEN_WIDTH 256.0#define SCREEN_HEIGHT 224.0// Resolution of mode7 matrix// (Number of mode7 units pr pixels in mode7 layer)#define MODE7_RESOLUTION 256.0double Length(VECTOR & v){ return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);}// These are just a couple of debug macros that I use, since// I have limited debug facilities at the moment.// Please don't remove them yet.// - Lestat#if 0int debug_count = 0;#define SHOW_FUNC_START() printf("%04d - Start: %s(%d):%s\n",++debug_count,__FILE__,__LINE__,__FUNCTION__)#define SHOW_FUNC_END() printf("%04d - End: %s(%d):%s\n",debug_count--,__FILE__,__LINE__,__FUNCTION__)#else#define SHOW_FUNC_START()#define SHOW_FUNC_END()#endifvoid S9xResetDSP1 (){ SHOW_FUNC_START(); DSP1.waiting4command = TRUE; DSP1.in_count = 0; DSP1.out_count = 0; DSP1.in_index = 0; DSP1.out_index = 0; DSP1.first_parameter = TRUE; SHOW_FUNC_END();}uint8 S9xGetDSP (uint16 address){ uint8 t;#ifdef DEBUGGER if (Settings.TraceDSP) { sprintf (String, "DSP read: 0x%04X", address); S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); }#endif if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000)) { if (DSP1.out_count) { if ((address & 1) == 0) t = (uint8) DSP1.output [DSP1.out_index]; else { t = (uint8) (DSP1.output [DSP1.out_index] >> 8); DSP1.out_index++; if (--DSP1.out_count == 0) { if (DSP1.command == 0x1a || DSP1.command == 0x0a) { DSPOp0A (); DSP1.out_count = 4; DSP1.out_index = 0; DSP1.output [0] = Op0AA; DSP1.output [1] = Op0AB; DSP1.output [2] = Op0AC; DSP1.output [3] = Op0AD; } } DSP1.waiting4command = TRUE; } } else { // Top Gear 3000 requires this value.... t = 0xff; } } else t = 0x80; return (t);}void S9xSetDSP (uint8 byte, uint16 address){ SHOW_FUNC_START();#ifdef DEBUGGER missing.unknowndsp_write = address; if (Settings.TraceDSP) { sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte); S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); }#endif if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000)) { if ((address & 1) == 0) { if (DSP1.waiting4command) { DSP1.command = byte; DSP1.in_index = 0; DSP1.waiting4command = FALSE; DSP1.first_parameter = TRUE; // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a switch (byte) { case 0x00: DSP1.in_count = 2; break; case 0x10: DSP1.in_count = 2; break; case 0x04: DSP1.in_count = 2; break; case 0x08: DSP1.in_count = 3; break; case 0x18: DSP1.in_count = 4; break; case 0x28: DSP1.in_count = 3; break; case 0x0c: DSP1.in_count = 3; break; case 0x1c: DSP1.in_count = 6; break; case 0x02: DSP1.in_count = 7; break; case 0x0a: DSP1.in_count = 1; break; case 0x1a: DSP1.in_count = 1; break; case 0x06: DSP1.in_count = 3; break; case 0x0e: DSP1.in_count = 2; break; case 0x01: DSP1.in_count = 4; break; case 0x11: DSP1.in_count = 4; break; case 0x21: DSP1.in_count = 4; break; case 0x0d: DSP1.in_count = 3; break; case 0x1d: DSP1.in_count = 3; break; case 0x2d: DSP1.in_count = 3; break; case 0x03: DSP1.in_count = 3; break; case 0x13: DSP1.in_count = 3; break; case 0x23: DSP1.in_count = 3; break; case 0x0b: DSP1.in_count = 3; break; case 0x1b: DSP1.in_count = 3; break; case 0x2b: DSP1.in_count = 3; break; case 0x14: DSP1.in_count = 6; break;// case 0x80: DSP1.in_count = 2; break; default: case 0x80: DSP1.in_count = 0; DSP1.waiting4command = TRUE; DSP1.first_parameter = TRUE; break; } } else { DSP1.parameters [DSP1.in_index] = byte; DSP1.first_parameter = FALSE; } } else { if (DSP1.waiting4command || (DSP1.first_parameter && byte == 0x80)) { DSP1.waiting4command = TRUE; DSP1.first_parameter = FALSE; } else if (DSP1.first_parameter) { } else { if (DSP1.in_count) { DSP1.parameters [DSP1.in_index] |= (byte << 8); if (--DSP1.in_count == 0) { // Actually execute the command DSP1.waiting4command = TRUE; DSP1.out_index = 0; switch (DSP1.command) { case 0x00: // Multiple DSP1.output [0] = DSPOp00 ( (int16) DSP1.parameters [0], (int16) DSP1.parameters [1]); DSP1.out_count = 1; break; case 0x10: // Inverse { int16 a = (int16) DSP1.parameters [0]; int16 b = (int16) DSP1.parameters [1]; double m = ldexp (double (a) / 32768.0, b); m = 1.0 / m; int c; m = frexp (m, &c); if (m == 1.0) { c++; m = 0.5; } m *= 32768.0; DSP1.output [0] = (uint16) (int16) m; DSP1.output [1] = (uint16) (int16) c; DSP1.out_count = 2; break; } case 0x04: // Sin and Cos of angle { DSP1_Triangle triangle ((int16) DSP1.parameters [0], (int16) DSP1.parameters [1]); DSP1.out_count = 2; DSP1.output [0] = (uint16) triangle.S; DSP1.output [1] = (uint16) triangle.C; break; } case 0x08: // Radius { int32 x = (int16) DSP1.parameters [0]; int32 y = (int16) DSP1.parameters [1]; int32 z = (int16) DSP1.parameters [2]; int32 s = (x * x + y * y + z * z) * 2; DSP1.output [0] = (int16) s; DSP1.output [1] = (int16) (s >> 16); DSP1.out_count = 2; break; } case 0x18: // Range { int32 x = (int16) DSP1.parameters [0]; int32 y = (int16) DSP1.parameters [1]; int32 z = (int16) DSP1.parameters [2]; int32 r = (int16) DSP1.parameters [3]; int32 s = ((x * x + y * y + z * z - r * r) * 2) / 65536; DSP1.output [0] = (int16) s; DSP1.out_count = 1; break; } case 0x28: // Distance (vector length) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -