449 lines
9.3 KiB
C++
449 lines
9.3 KiB
C++
//
|
|
// Copyright (c) 2004 K. Wilkins
|
|
//
|
|
// This software is provided 'as-is', without any express or implied warranty.
|
|
// In no event will the authors be held liable for any damages arising from
|
|
// the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would be
|
|
// appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such, and must not
|
|
// be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
//
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Handy - An Atari Lynx Emulator //
|
|
// Copyright (c) 1996,1997 //
|
|
// K. Wilkins //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Susie object header file //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// This header file provides the interface definition for the Suzy class //
|
|
// which provides math and sprite support to the emulator //
|
|
// //
|
|
// K. Wilkins //
|
|
// August 1997 //
|
|
// //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Revision History: //
|
|
// ----------------- //
|
|
// //
|
|
// 01Aug1997 KW Document header added & class documented. //
|
|
// //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef SUSIE_H
|
|
#define SUSIE_H
|
|
|
|
#ifdef TRACE_SUSIE
|
|
|
|
#define TRACE_SUSIE0(msg) _RPT1(_CRT_WARN,"CSusie::"msg" (Time=%012d)\n",gSystemCycleCount)
|
|
#define TRACE_SUSIE1(msg,arg1) _RPT2(_CRT_WARN,"CSusie::"msg" (Time=%012d)\n",arg1,gSystemCycleCount)
|
|
#define TRACE_SUSIE2(msg,arg1,arg2) _RPT3(_CRT_WARN,"CSusie::"msg" (Time=%012d)\n",arg1,arg2,gSystemCycleCount)
|
|
#define TRACE_SUSIE3(msg,arg1,arg2,arg3) _RPT4(_CRT_WARN,"CSusie::"msg" (Time=%012d)\n",arg1,arg2,arg3,gSystemCycleCount)
|
|
|
|
#else
|
|
|
|
#define TRACE_SUSIE0(msg)
|
|
#define TRACE_SUSIE1(msg,arg1)
|
|
#define TRACE_SUSIE2(msg,arg1,arg2)
|
|
#define TRACE_SUSIE3(msg,arg1,arg2,arg3)
|
|
|
|
#endif
|
|
|
|
class CSystem;
|
|
|
|
#define SUSIE_START 0xfc00
|
|
#define SUSIE_SIZE 0x100
|
|
|
|
#define SCREEN_WIDTH 160
|
|
#define SCREEN_HEIGHT 102
|
|
|
|
#define LINE_END 0x80
|
|
|
|
//
|
|
// Define button values
|
|
//
|
|
|
|
#define BUTTON_A 0x0001
|
|
#define BUTTON_B 0x0002
|
|
#define BUTTON_OPT2 0x0004
|
|
#define BUTTON_OPT1 0x0008
|
|
#define BUTTON_LEFT 0x0010
|
|
#define BUTTON_RIGHT 0x0020
|
|
#define BUTTON_UP 0x0040
|
|
#define BUTTON_DOWN 0x0080
|
|
#define BUTTON_PAUSE 0x0100
|
|
|
|
|
|
enum {line_error=0,line_abs_literal,line_literal,line_packed};
|
|
enum {math_finished=0,math_divide,math_multiply,math_init_divide,math_init_multiply};
|
|
|
|
enum {sprite_background_shadow=0,
|
|
sprite_background_noncollide,
|
|
sprite_boundary_shadow,
|
|
sprite_boundary,
|
|
sprite_normal,
|
|
sprite_noncollide,
|
|
sprite_xor_shadow,
|
|
sprite_shadow};
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 Fc1:1;
|
|
uint8 Fc2:1;
|
|
uint8 Fc3:1;
|
|
uint8 reserved:1;
|
|
uint8 Ac1:1;
|
|
uint8 Ac2:1;
|
|
uint8 Ac3:1;
|
|
uint8 Ac4:1;
|
|
#else
|
|
uint8 Ac4:1;
|
|
uint8 Ac3:1;
|
|
uint8 Ac2:1;
|
|
uint8 Ac1:1;
|
|
uint8 reserved:1;
|
|
uint8 Fc3:1;
|
|
uint8 Fc2:1;
|
|
uint8 Fc1:1;
|
|
#endif
|
|
}Bits;
|
|
uint8 Byte;
|
|
};
|
|
}TSPRINIT;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 Up:1;
|
|
uint8 Down:1;
|
|
uint8 Left:1;
|
|
uint8 Right:1;
|
|
uint8 Option1:1;
|
|
uint8 Option2:1;
|
|
uint8 Inside:1;
|
|
uint8 Outside:1;
|
|
#else
|
|
uint8 Outside:1;
|
|
uint8 Inside:1;
|
|
uint8 Option2:1;
|
|
uint8 Option1:1;
|
|
uint8 Right:1;
|
|
uint8 Left:1;
|
|
uint8 Down:1;
|
|
uint8 Up:1;
|
|
#endif
|
|
}Bits;
|
|
uint8 Byte;
|
|
};
|
|
}TJOYSTICK;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 spare:5;
|
|
uint8 Cart1IO:1;
|
|
uint8 Cart0IO:1;
|
|
uint8 Pause:1;
|
|
#else
|
|
uint8 Pause:1;
|
|
uint8 Cart0IO:1;
|
|
uint8 Cart1IO:1;
|
|
uint8 spare:5;
|
|
#endif
|
|
}Bits;
|
|
uint8 Byte;
|
|
};
|
|
}TSWITCHES;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 A;
|
|
uint8 B;
|
|
uint8 C;
|
|
uint8 D;
|
|
#else
|
|
uint8 D;
|
|
uint8 C;
|
|
uint8 B;
|
|
uint8 A;
|
|
#endif
|
|
}Bytes;
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint16 AB;
|
|
uint16 CD;
|
|
#else
|
|
uint16 CD;
|
|
uint16 AB;
|
|
#endif
|
|
}Words;
|
|
uint32 Long;
|
|
};
|
|
}TMATHABCD;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 E;
|
|
uint8 F;
|
|
uint8 G;
|
|
uint8 H;
|
|
#else
|
|
uint8 H;
|
|
uint8 G;
|
|
uint8 F;
|
|
uint8 E;
|
|
#endif
|
|
}Bytes;
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint16 EF;
|
|
uint16 GH;
|
|
#else
|
|
uint16 GH;
|
|
uint16 EF;
|
|
#endif
|
|
}Words;
|
|
uint32 Long;
|
|
};
|
|
}TMATHEFGH;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 J;
|
|
uint8 K;
|
|
uint8 L;
|
|
uint8 M;
|
|
#else
|
|
uint8 M;
|
|
uint8 L;
|
|
uint8 K;
|
|
uint8 J;
|
|
#endif
|
|
}Bytes;
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint16 JK;
|
|
uint16 LM;
|
|
#else
|
|
uint16 LM;
|
|
uint16 JK;
|
|
#endif
|
|
}Words;
|
|
uint32 Long;
|
|
};
|
|
}TMATHJKLM;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint8 xx2;
|
|
uint8 xx1;
|
|
uint8 N;
|
|
uint8 P;
|
|
#else
|
|
uint8 P;
|
|
uint8 N;
|
|
uint8 xx1;
|
|
uint8 xx2;
|
|
#endif
|
|
}Bytes;
|
|
struct
|
|
{
|
|
#ifdef MSB_FIRST
|
|
uint16 xx1;
|
|
uint16 NP;
|
|
#else
|
|
uint16 NP;
|
|
uint16 xx1;
|
|
#endif
|
|
}Words;
|
|
uint32 Long;
|
|
};
|
|
}TMATHNP;
|
|
|
|
|
|
class CSusie : public CLynxBase
|
|
{
|
|
public:
|
|
CSusie(CSystem& parent) MDFN_COLD;
|
|
~CSusie() MDFN_COLD;
|
|
|
|
void Reset(void) MDFN_COLD;
|
|
|
|
uint8 Peek(uint32 addr);
|
|
void Poke(uint32 addr,uint8 data);
|
|
uint32 ReadCycle(void) {return 9;};
|
|
uint32 WriteCycle(void) {return 5;};
|
|
uint32 ObjectSize(void) {return SUSIE_SIZE;};
|
|
|
|
void SetButtonData(uint32 data) {mJOYSTICK.Byte=(uint8)data;mSWITCHES.Byte=(uint8)(data>>8);};
|
|
// uint32 GetButtonData(void) {return mJOYSTICK.Byte+(mSWITCHES.Byte<<8);};
|
|
|
|
uint32 PaintSprites(void);
|
|
bool lagged; // set to false whenever joystick/switches are read
|
|
|
|
template<bool isReader>void SyncState(NewState *ns);
|
|
|
|
private:
|
|
void DoMathDivide(void);
|
|
void DoMathMultiply(void);
|
|
uint32 LineInit(uint32 voff);
|
|
uint32 LineGetPixel(void);
|
|
uint32 LineGetBits(uint32 bits);
|
|
|
|
void ProcessPixel(uint32 hoff,uint32 pixel);
|
|
void WritePixel(uint32 hoff,uint32 pixel);
|
|
uint32 ReadPixel(uint32 hoff);
|
|
void WriteCollision(uint32 hoff,uint32 pixel);
|
|
uint32 ReadCollision(uint32 hoff);
|
|
|
|
private:
|
|
CSystem& mSystem;
|
|
|
|
uint32 cycles_used;
|
|
|
|
Uuint16 mTMPADR; // ENG
|
|
Uuint16 mTILTACUM; // ENG
|
|
Uuint16 mHOFF; // CPU
|
|
Uuint16 mVOFF; // CPU
|
|
Uuint16 mVIDBAS; // CPU
|
|
Uuint16 mCOLLBAS; // CPU
|
|
Uuint16 mVIDADR; // ENG
|
|
Uuint16 mCOLLADR; // ENG
|
|
Uuint16 mSCBNEXT; // SCB
|
|
Uuint16 mSPRDLINE; // SCB
|
|
Uuint16 mHPOSSTRT; // SCB
|
|
Uuint16 mVPOSSTRT; // SCB
|
|
Uuint16 mSPRHSIZ; // SCB
|
|
Uuint16 mSPRVSIZ; // SCB
|
|
Uuint16 mSTRETCH; // ENG
|
|
Uuint16 mTILT; // ENG
|
|
Uuint16 mSPRDOFF; // ENG
|
|
Uuint16 mSPRVPOS; // ENG
|
|
Uuint16 mCOLLOFF; // CPU
|
|
Uuint16 mVSIZACUM; // ENG
|
|
Uuint16 mHSIZACUM; // K.s creation
|
|
Uuint16 mHSIZOFF; // CPU
|
|
Uuint16 mVSIZOFF; // CPU
|
|
Uuint16 mSCBADR; // ENG
|
|
Uuint16 mPROCADR; // ENG
|
|
|
|
TMATHABCD mMATHABCD; // ENG
|
|
TMATHEFGH mMATHEFGH; // ENG
|
|
TMATHJKLM mMATHJKLM; // ENG
|
|
TMATHNP mMATHNP; // ENG
|
|
int mMATHAB_sign;
|
|
int mMATHCD_sign;
|
|
int mMATHEFGH_sign;
|
|
|
|
int mSPRCTL0_Type; // SCB
|
|
int mSPRCTL0_Vflip;
|
|
int mSPRCTL0_Hflip;
|
|
int mSPRCTL0_PixelBits;
|
|
|
|
int mSPRCTL1_StartLeft; // SCB
|
|
int mSPRCTL1_StartUp;
|
|
int mSPRCTL1_SkipSprite;
|
|
int mSPRCTL1_ReloadPalette;
|
|
int mSPRCTL1_ReloadDepth;
|
|
int mSPRCTL1_Sizing;
|
|
int mSPRCTL1_Literal;
|
|
|
|
int mSPRCOLL_Number; //CPU
|
|
int mSPRCOLL_Collide;
|
|
|
|
int mSPRSYS_StopOnCurrent; //CPU
|
|
int mSPRSYS_LeftHand;
|
|
int mSPRSYS_VStretch;
|
|
int mSPRSYS_NoCollide;
|
|
int mSPRSYS_Accumulate;
|
|
int mSPRSYS_SignedMath;
|
|
int mSPRSYS_Status;
|
|
int mSPRSYS_UnsafeAccess;
|
|
int mSPRSYS_LastCarry;
|
|
int mSPRSYS_Mathbit;
|
|
int mSPRSYS_MathInProgress;
|
|
|
|
uint32 mSUZYBUSEN; // CPU
|
|
|
|
TSPRINIT mSPRINIT; // CPU
|
|
|
|
uint32 mSPRGO; // CPU
|
|
int mEVERON;
|
|
|
|
uint8 mPenIndex[16]; // SCB
|
|
|
|
// Line rendering related variables
|
|
|
|
uint32 mLineType;
|
|
uint32 mLineShiftRegCount;
|
|
uint32 mLineShiftReg;
|
|
uint32 mLineRepeatCount;
|
|
uint32 mLinePixel;
|
|
uint32 mLinePacketBitsLeft;
|
|
|
|
int mCollision;
|
|
|
|
uint8 *mRamPointer;
|
|
|
|
uint32 mLineBaseAddress;
|
|
uint32 mLineCollisionAddress;
|
|
|
|
int hquadoff, vquadoff;
|
|
|
|
// Joystick switches
|
|
|
|
TJOYSTICK mJOYSTICK;
|
|
TSWITCHES mSWITCHES;
|
|
};
|
|
|
|
#endif
|
|
|