Commit 6fb0c7a7 authored by Toad King's avatar Toad King
Browse files

initial pocketsnes commit

parents
This diff is collapsed.
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) 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.henderson@ntlworld.com).
*
* DOS port code contains the works of other authors. See headers in
* individual files.
*
* Snes9x homepage: http://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.
*/
#ifndef _3D_H_
#define _3D_H_
#if defined(USE_OPENGL)
#include <GL/gl.h>
#include <GL/glu.h>
#ifdef __linux__
//#include <GL/glx.h>
#endif
typedef struct
{
bool8 packed_pixels_extension_present;
bool8 draw_cube;
uint32 version;
// Texture format
GLint internal_format;
GLint format;
GLint type;
GLint max_texture_size;// 256 or 512
GLint texture_size;
uint32 num_textures; // 1 if max_texture_size == 256, 2 otherwise
GLuint textures [2];
} OpenGLData;
extern OpenGLData OpenGL;
bool8 S9xOpenGLInit ();
bool8 S9xOpenGLInit2 ();
void S9xOpenGLPutImage (int width, int height);
void S9xOpenGLDeinit ();
#endif
#ifdef USE_GLIDE
//#include <glide.h>
typedef struct
{
bool8 voodoo_present;
GrVertex sq[4];
GrTexInfo texture;
int32 texture_mem_size;
int32 texture_mem_start;
float x_offset, y_offset;
float x_scale, y_scale;
float voodoo_width;
float voodoo_height;
} GlideData;
extern GlideData Glide;
bool8 S9xGlideEnable (bool8 enable);
void S9xGlideDeinit ();
bool8 S9xGlideInit ();
bool8 S9xVoodooInitialise ();
#endif
#endif
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) 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.henderson@ntlworld.com).
*
* DOS port code contains the works of other authors. See headers in
* individual files.
*
* Snes9x homepage: http://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.
*/
#ifndef _65c816_h_
#define _65c816_h_
#define AL A.B.l
#define AH A.B.h
#define XL X.B.l
#define XH X.B.h
#define YL Y.B.l
#define YH Y.B.h
#define SL S.B.l
#define SH S.B.h
#define DL D.B.l
#define DH D.B.h
#define PL P.B.l
#define PH P.B.h
#define Carry 1
#define Zero 2
#define IRQ 4
#define Decimal 8
#define IndexFlag 16
#define MemoryFlag 32
#define Overflow 64
#define Negative 128
#define Emulation 256
#define ClearCarry() (ICPU._Carry = 0)
#define SetCarry() (ICPU._Carry = 1)
#define SetZero() (ICPU._Zero = 0)
#define ClearZero() (ICPU._Zero = 1)
#define SetIRQ() (Registers.PL |= IRQ)
#define ClearIRQ() (Registers.PL &= ~IRQ)
#define SetDecimal() (Registers.PL |= Decimal)
#define ClearDecimal() (Registers.PL &= ~Decimal)
#define SetIndex() (Registers.PL |= IndexFlag)
#define ClearIndex() (Registers.PL &= ~IndexFlag)
#define SetMemory() (Registers.PL |= MemoryFlag)
#define ClearMemory() (Registers.PL &= ~MemoryFlag)
#define SetOverflow() (ICPU._Overflow = 1)
#define ClearOverflow() (ICPU._Overflow = 0)
#define SetNegative() (ICPU._Negative = 0x80)
#define ClearNegative() (ICPU._Negative = 0)
#define CheckZero() (ICPU._Zero == 0)
#define CheckCarry() (ICPU._Carry)
#define CheckIRQ() (Registers.PL & IRQ)
#define CheckDecimal() (Registers.PL & Decimal)
#define CheckIndex() (Registers.PL & IndexFlag)
#define CheckMemory() (Registers.PL & MemoryFlag)
#define CheckOverflow() (ICPU._Overflow)
#define CheckNegative() (ICPU._Negative & 0x80)
#define CheckEmulation() (Registers.P.W & Emulation)
#define ClearFlags(f) (Registers.P.W &= ~(f))
#define SetFlags(f) (Registers.P.W |= (f))
#define CheckFlag(f) (Registers.PL & (f))
typedef union
{
#ifdef LSB_FIRST
struct { uint8 l,h; } PACKING B;
#else
struct { uint8 h,l; } PACKING B;
#endif
uint16 W;
} ALIGN_BY_ONE pair;
struct SRegisters{
uint8 PB;
uint8 DB;
pair P;
pair A;
pair D;
pair X;
pair S;
pair Y;
uint16 PC;
} PACKING;
#define Registers CPU.Regs
//EXTERN_C struct SRegisters Registers;
#endif
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) 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.henderson@ntlworld.com).
*
* DOS port code contains the works of other authors. See headers in
* individual files.
*
* Snes9x homepage: http://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>
#include "dsp1emu_gp32.c"
void S9xInitDSP1 ()
{
static bool8 init = FALSE;
if (!init)
{
InitDSP ();
init = TRUE;
}
}
void S9xResetDSP1 ()
{
S9xInitDSP1 ();
DSP1.waiting4command = TRUE;
DSP1.in_count = 0;
DSP1.out_count = 0;
DSP1.in_index = 0;
DSP1.out_index = 0;
DSP1.first_parameter = TRUE;
}
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)
{
#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
Op00Multiplicand = (int16) DSP1.parameters [0];
Op00Multiplier = (int16) DSP1.parameters [1];
DSPOp00 ();
DSP1.out_count = 1;
DSP1.output [0] = Op00Result;
break;
case 0x10: // Inverse
Op10Coefficient = (int16) DSP1.parameters [0];
Op10Exponent = (int16) DSP1.parameters [1];
DSPOp10 ();
DSP1.out_count = 2;
DSP1.output [0] = (uint16) (int16) Op10CoefficientR;
DSP1.output [1] = (uint16) (int16) Op10ExponentR;
break;
case 0x04: // Sin and Cos of angle
Op04Angle = (int16) DSP1.parameters [0];
Op04Radius = (uint16) DSP1.parameters [1];
DSPOp04 ();
DSP1.out_count = 2;
DSP1.output [0] = (uint16) Op04Sin;
DSP1.output [1] = (uint16) Op04Cos;
break;
case 0x08: // Radius
Op08X = (int16) DSP1.parameters [0];
Op08Y = (int16) DSP1.parameters [1];
Op08Z = (int16) DSP1.parameters [2];
DSPOp08 ();
DSP1.out_count = 2;
DSP1.output [0] = (int16) Op08Ll;
DSP1.output [1] = (int16) Op08Lh;
break;
case 0x18: // Range
Op18X = (int16) DSP1.parameters [0];
Op18Y = (int16) DSP1.parameters [1];
Op18Z = (int16) DSP1.parameters [2];
Op18R = (int16) DSP1.parameters [3];
DSPOp18 ();
DSP1.out_count = 1;
DSP1.output [0] = Op18D;
break;
case 0x28: // Distance (vector length)
Op28X = (int16) DSP1.parameters [0];
Op28Y = (int16) DSP1.parameters [1];
Op28Z = (int16) DSP1.parameters [2];
DSPOp28 ();
DSP1.out_count = 1;
DSP1.output [0] = (uint16) Op28R;
break;
case 0x0c: // Rotate (2D rotate)
Op0CA = (int16) DSP1.parameters [0];
Op0CX1 = (int16) DSP1.parameters [1];
Op0CY1 = (int16) DSP1.parameters [2];
DSPOp0C ();
DSP1.out_count = 2;
DSP1.output [0] = (uint16) Op0CX2;
DSP1.output [1] = (uint16) Op0CY2;
break;
case 0x1c: // Polar (3D rotate)
Op1CZ = DSP1.parameters [0];
Op1CX = DSP1.parameters [1];
Op1CY = DSP1.parameters [2];
Op1CXBR = DSP1.parameters [3];
Op1CYBR = DSP1.parameters [4];
Op1CZBR = DSP1.parameters [5];
DSPOp1C ();
DSP1.out_count = 3;
DSP1.output [0] = (uint16) Op1CXAR;
DSP1.output [1] = (uint16) Op1CYAR;
DSP1.output [2] = (uint16) Op1CZAR;
break;
case 0x02: // Parameter (Projection)
Op02FX = DSP1.parameters [0];
Op02FY = DSP1.parameters [1];
Op02FZ = DSP1.parameters [2];
Op02LFE = DSP1.parameters [3];
Op02LES = DSP1.parameters [4];
Op02AAS = DSP1.parameters [5];
Op02AZS = DSP1.parameters [6];
DSPOp02 ();
DSP1.out_count = 4;
DSP1.output [0] = Op02VOF;
DSP1.output [1] = Op02VVA;
DSP1.output [2] = Op02CX;
DSP1.output [3] = Op02CY;
break;
case 0x1a: // Raster mode 7 matrix data
case 0x0a:
Op0AVS = DSP1.parameters [0];
DSPOp0A ();
DSP1.out_count = 4;
DSP1.output [0] = Op0AA;
DSP1.output [1] = Op0AB;
DSP1.output [2] = Op0AC;
DSP1.output [3] = Op0AD;
break;
case 0x06: // Project object
Op06X = (int16) DSP1.parameters [0];
Op06Y = (int16) DSP1.parameters [1];
Op06Z = (int16) DSP1.parameters [2];
DSPOp06 ();
DSP1.out_count = 3;
DSP1.output [0] = Op06H;
DSP1.output [1] = Op06V;
DSP1.output [2] = Op06S;
break;
case 0x0e: // Target
Op0EH = (int16) DSP1.parameters [0];
Op0EV = (int16) DSP1.parameters [1];
DSPOp0E ();
DSP1.out_count = 2;
DSP1.output [0] = Op0EX;
DSP1.output [1] = Op0EY;
break;
// Extra commands used by Pilot Wings
case 0x01: // Set attitude matrix A
Op01m = (int16) DSP1.parameters [0];
Op01Zr = (int16) DSP1.parameters [1];
Op01Xr = (int16) DSP1.parameters [2];
Op01Yr = (int16) DSP1.parameters [3];
DSPOp01 ();
break;
case 0x11: // Set attitude matrix B
Op11m = (int16) DSP1.parameters [0];
Op11Zr = (int16) DSP1.parameters [1];
Op11Xr = (int16) DSP1.parameters [2];
Op11Yr = (int16) DSP1.parameters [3];
DSPOp11 ();
break;
case 0x21: // Set attitude matrix C
Op21m = (int16) DSP1.parameters [0];
Op21Zr = (int16) DSP1.parameters [1];
Op21Xr = (int16) DSP1.parameters [2];
Op21Yr = (int16) DSP1.parameters [3];
DSPOp21 ();
break;
case 0x0d: // Objective matrix A
Op0DX = (int16) DSP1.parameters [0];
Op0DY = (int16) DSP1.parameters [1];
Op0DZ = (int16) DSP1.parameters [2];
DSPOp0D ();
DSP1.out_count = 3;
DSP1.output [0] = (uint16) Op0DF;
DSP1.output [1] = (uint16) Op0DL;
DSP1.output [2] = (uint16) Op0DU;
break;
case 0x1d: // Objective matrix B