susie.cpp
   1  //
   2  // Copyright (c) 2004 K. Wilkins
   3  //
   4  // This software is provided 'as-is', without any express or implied warranty.
   5  // In no event will the authors be held liable for any damages arising from
   6  // the use of this software.
   7  //
   8  // Permission is granted to anyone to use this software for any purpose,
   9  // including commercial applications, and to alter it and redistribute it
  10  // freely, subject to the following restrictions:
  11  //
  12  // 1. The origin of this software must not be misrepresented; you must not
  13  //    claim that you wrote the original software. If you use this software
  14  //    in a product, an acknowledgment in the product documentation would be
  15  //    appreciated but is not required.
  16  //
  17  // 2. Altered source versions must be plainly marked as such, and must not
  18  //    be misrepresented as being the original software.
  19  //
  20  // 3. This notice may not be removed or altered from any source distribution.
  21  //
  22  
  23  //////////////////////////////////////////////////////////////////////////////
  24  //                       Handy - An Atari Lynx Emulator                     //
  25  //                          Copyright (c) 1996,1997                         //
  26  //                                 K. Wilkins                               //
  27  //////////////////////////////////////////////////////////////////////////////
  28  // Suzy emulation class                                                     //
  29  //////////////////////////////////////////////////////////////////////////////
  30  //                                                                          //
  31  // This class emulates the Suzy chip within the lynx. This provides math    //
  32  // and sprite painting facilities. SpritePaint() is called from within      //
  33  // the Mikey POKE functions when SPRGO is set and is called via the system  //
  34  // object to keep the interface clean.                                      //
  35  //                                                                          //
  36  //    K. Wilkins                                                            //
  37  // August 1997                                                              //
  38  //                                                                          //
  39  //////////////////////////////////////////////////////////////////////////////
  40  // Revision History:                                                        //
  41  // -----------------                                                        //
  42  //                                                                          //
  43  // 01Aug1997 KW Document header added & class documented.                   //
  44  //                                                                          //
  45  //////////////////////////////////////////////////////////////////////////////
  46  
  47  //#define TRACE_SUSIE
  48  
  49  #include <stdio.h>
  50  #include <stdlib.h>
  51  #include <string.h>
  52  #include "system.h"
  53  #include "susie.h"
  54  #include "lynxdef.h"
  55  
  56  CSusie::CSusie(CSystem& parent)
  57     :mSystem(parent)
  58  {
  59     TRACE_SUSIE0("CSusie()");
  60     Reset();
  61  }
  62  
  63  CSusie::~CSusie()
  64  {
  65     TRACE_SUSIE0("~CSusie()");
  66  }
  67  
  68  void CSusie::Reset(void)
  69  {
  70     TRACE_SUSIE0("Reset()");
  71  
  72     // Fetch pointer to system RAM, faster than object access
  73     // and seeing as Susie only ever sees RAM.
  74  
  75     mRamPointer=mSystem.GetRamPointer();
  76  
  77     // Reset ALL variables
  78  
  79     mTMPADR.Word=0;
  80     mTILTACUM.Word=0;
  81     mHOFF.Word=0;
  82     mVOFF.Word=0;
  83     mVIDBAS.Word=0;
  84     mCOLLBAS.Word=0;
  85     mVIDADR.Word=0;
  86     mCOLLADR.Word=0;
  87     mSCBNEXT.Word=0;
  88     mSPRDLINE.Word=0;
  89     mHPOSSTRT.Word=0;
  90     mVPOSSTRT.Word=0;
  91     mSPRHSIZ.Word=0;
  92     mSPRVSIZ.Word=0;
  93     mSTRETCH.Word=0;
  94     mTILT.Word=0;
  95     mSPRDOFF.Word=0;
  96     mSPRVPOS.Word=0;
  97     mCOLLOFF.Word=0;
  98     mVSIZACUM.Word=0;
  99     mHSIZACUM.Word=0;
 100     mHSIZOFF.Word=0x007f;
 101     mVSIZOFF.Word=0x007f;
 102     mSCBADR.Word=0;
 103     mPROCADR.Word=0;
 104  
 105     // Must be initialised to this due to
 106     // stun runner math initialisation bug
 107     // see whatsnew for 0.7
 108     mMATHABCD.Long=0xffffffff;
 109     mMATHEFGH.Long=0xffffffff;
 110     mMATHJKLM.Long=0xffffffff;
 111     mMATHNP.Long=0xffff;
 112  
 113     mMATHAB_sign=1;
 114     mMATHCD_sign=1;
 115     mMATHEFGH_sign=1;
 116  
 117     mSPRCTL0_Type=0;
 118     mSPRCTL0_Vflip=0;
 119     mSPRCTL0_Hflip=0;
 120     mSPRCTL0_PixelBits=0;
 121  
 122     mSPRCTL1_StartLeft=0;
 123     mSPRCTL1_StartUp=0;
 124     mSPRCTL1_SkipSprite=0;
 125     mSPRCTL1_ReloadPalette=0;
 126     mSPRCTL1_ReloadDepth=0;
 127     mSPRCTL1_Sizing=0;
 128     mSPRCTL1_Literal=0;
 129  
 130     mSPRCOLL_Number=0;
 131     mSPRCOLL_Collide=0;
 132  
 133     mSPRSYS_StopOnCurrent=0;
 134     mSPRSYS_LeftHand=0;
 135     mSPRSYS_VStretch=0;
 136     mSPRSYS_NoCollide=0;
 137     mSPRSYS_Accumulate=0;
 138     mSPRSYS_SignedMath=0;
 139     mSPRSYS_Status=0;
 140     mSPRSYS_UnsafeAccess=0;
 141     mSPRSYS_LastCarry=0;
 142     mSPRSYS_Mathbit=0;
 143     mSPRSYS_MathInProgress=0;
 144  
 145     mSUZYBUSEN=FALSE;
 146  
 147     mSPRINIT.Byte=0;
 148  
 149     mSPRGO=FALSE;
 150     mEVERON=FALSE;
 151  
 152     for(int loop=0;loop<16;loop++) mPenIndex[loop]=loop;
 153  
 154     mJOYSTICK.Byte=0;
 155     mSWITCHES.Byte=0;
 156  }
 157  
 158  bool CSusie::ContextSave(LSS_FILE *fp)
 159  {
 160     TRACE_SUSIE0("ContextSave()");
 161  
 162     if(!lss_printf(fp,"CSusie::ContextSave")) return 0;
 163  
 164     if(!lss_write(&mTMPADR,sizeof(UUWORD),1,fp)) return 0;
 165     if(!lss_write(&mTILTACUM,sizeof(UUWORD),1,fp)) return 0;
 166     if(!lss_write(&mHOFF,sizeof(UUWORD),1,fp)) return 0;
 167     if(!lss_write(&mVOFF,sizeof(UUWORD),1,fp)) return 0;
 168     if(!lss_write(&mVIDBAS,sizeof(UUWORD),1,fp)) return 0;
 169     if(!lss_write(&mCOLLBAS,sizeof(UUWORD),1,fp)) return 0;
 170     if(!lss_write(&mVIDADR,sizeof(UUWORD),1,fp)) return 0;
 171     if(!lss_write(&mCOLLADR,sizeof(UUWORD),1,fp)) return 0;
 172     if(!lss_write(&mSCBNEXT,sizeof(UUWORD),1,fp)) return 0;
 173     if(!lss_write(&mSPRDLINE,sizeof(UUWORD),1,fp)) return 0;
 174     if(!lss_write(&mHPOSSTRT,sizeof(UUWORD),1,fp)) return 0;
 175     if(!lss_write(&mVPOSSTRT,sizeof(UUWORD),1,fp)) return 0;
 176     if(!lss_write(&mSPRHSIZ,sizeof(UUWORD),1,fp)) return 0;
 177     if(!lss_write(&mSPRVSIZ,sizeof(UUWORD),1,fp)) return 0;
 178     if(!lss_write(&mSTRETCH,sizeof(UUWORD),1,fp)) return 0;
 179     if(!lss_write(&mTILT,sizeof(UUWORD),1,fp)) return 0;
 180     if(!lss_write(&mSPRDOFF,sizeof(UUWORD),1,fp)) return 0;
 181     if(!lss_write(&mSPRVPOS,sizeof(UUWORD),1,fp)) return 0;
 182     if(!lss_write(&mCOLLOFF,sizeof(UUWORD),1,fp)) return 0;
 183     if(!lss_write(&mVSIZACUM,sizeof(UUWORD),1,fp)) return 0;
 184     if(!lss_write(&mHSIZACUM,sizeof(UUWORD),1,fp)) return 0;
 185     if(!lss_write(&mHSIZOFF,sizeof(UUWORD),1,fp)) return 0;
 186     if(!lss_write(&mVSIZOFF,sizeof(UUWORD),1,fp)) return 0;
 187     if(!lss_write(&mSCBADR,sizeof(UUWORD),1,fp)) return 0;
 188     if(!lss_write(&mPROCADR,sizeof(UUWORD),1,fp)) return 0;
 189  
 190     if(!lss_write(&mMATHABCD,sizeof(TMATHABCD),1,fp)) return 0;
 191     if(!lss_write(&mMATHEFGH,sizeof(TMATHEFGH),1,fp)) return 0;
 192     if(!lss_write(&mMATHJKLM,sizeof(TMATHJKLM),1,fp)) return 0;
 193     if(!lss_write(&mMATHNP,sizeof(TMATHNP),1,fp)) return 0;
 194  
 195     if(!lss_write(&mSPRCTL0_Type,sizeof(ULONG),1,fp)) return 0;
 196     if(!lss_write(&mSPRCTL0_Vflip,sizeof(ULONG),1,fp)) return 0;
 197     if(!lss_write(&mSPRCTL0_Hflip,sizeof(ULONG),1,fp)) return 0;
 198     if(!lss_write(&mSPRCTL0_PixelBits,sizeof(ULONG),1,fp)) return 0;
 199  
 200     if(!lss_write(&mSPRCTL1_StartLeft,sizeof(ULONG),1,fp)) return 0;
 201     if(!lss_write(&mSPRCTL1_StartUp,sizeof(ULONG),1,fp)) return 0;
 202     if(!lss_write(&mSPRCTL1_SkipSprite,sizeof(ULONG),1,fp)) return 0;
 203     if(!lss_write(&mSPRCTL1_ReloadPalette,sizeof(ULONG),1,fp)) return 0;
 204     if(!lss_write(&mSPRCTL1_ReloadDepth,sizeof(ULONG),1,fp)) return 0;
 205     if(!lss_write(&mSPRCTL1_Sizing,sizeof(ULONG),1,fp)) return 0;
 206     if(!lss_write(&mSPRCTL1_Literal,sizeof(ULONG),1,fp)) return 0;
 207  
 208     if(!lss_write(&mSPRCOLL_Number,sizeof(ULONG),1,fp)) return 0;
 209     if(!lss_write(&mSPRCOLL_Collide,sizeof(ULONG),1,fp)) return 0;
 210  
 211     if(!lss_write(&mSPRSYS_StopOnCurrent,sizeof(ULONG),1,fp)) return 0;
 212     if(!lss_write(&mSPRSYS_LeftHand,sizeof(ULONG),1,fp)) return 0;
 213     if(!lss_write(&mSPRSYS_VStretch,sizeof(ULONG),1,fp)) return 0;
 214     if(!lss_write(&mSPRSYS_NoCollide,sizeof(ULONG),1,fp)) return 0;
 215     if(!lss_write(&mSPRSYS_Accumulate,sizeof(ULONG),1,fp)) return 0;
 216     if(!lss_write(&mSPRSYS_SignedMath,sizeof(ULONG),1,fp)) return 0;
 217     if(!lss_write(&mSPRSYS_Status,sizeof(ULONG),1,fp)) return 0;
 218     if(!lss_write(&mSPRSYS_UnsafeAccess,sizeof(ULONG),1,fp)) return 0;
 219     if(!lss_write(&mSPRSYS_LastCarry,sizeof(ULONG),1,fp)) return 0;
 220     if(!lss_write(&mSPRSYS_Mathbit,sizeof(ULONG),1,fp)) return 0;
 221     if(!lss_write(&mSPRSYS_MathInProgress,sizeof(ULONG),1,fp)) return 0;
 222  
 223     if(!lss_write(&mSUZYBUSEN,sizeof(ULONG),1,fp)) return 0;
 224  
 225     if(!lss_write(&mSPRINIT,sizeof(TSPRINIT),1,fp)) return 0;
 226  
 227     if(!lss_write(&mSPRGO,sizeof(ULONG),1,fp)) return 0;
 228     if(!lss_write(&mEVERON,sizeof(ULONG),1,fp)) return 0;
 229  
 230     if(!lss_write(mPenIndex,sizeof(UBYTE),16,fp)) return 0;
 231  
 232     if(!lss_write(&mLineType,sizeof(ULONG),1,fp)) return 0;
 233     if(!lss_write(&mLineShiftRegCount,sizeof(ULONG),1,fp)) return 0;
 234     if(!lss_write(&mLineShiftReg,sizeof(ULONG),1,fp)) return 0;
 235     if(!lss_write(&mLineRepeatCount,sizeof(ULONG),1,fp)) return 0;
 236     if(!lss_write(&mLinePixel,sizeof(ULONG),1,fp)) return 0;
 237     if(!lss_write(&mLinePacketBitsLeft,sizeof(ULONG),1,fp)) return 0;
 238  
 239     if(!lss_write(&mCollision,sizeof(ULONG),1,fp)) return 0;
 240  
 241     if(!lss_write(&mLineBaseAddress,sizeof(ULONG),1,fp)) return 0;
 242     if(!lss_write(&mLineCollisionAddress,sizeof(ULONG),1,fp)) return 0;
 243  
 244     if(!lss_write(&mJOYSTICK,sizeof(TJOYSTICK),1,fp)) return 0;
 245     if(!lss_write(&mSWITCHES,sizeof(TSWITCHES),1,fp)) return 0;
 246  
 247     return 1;
 248  }
 249  
 250  bool CSusie::ContextLoad(LSS_FILE *fp)
 251  {
 252     TRACE_SUSIE0("ContextLoad()");
 253  
 254     char teststr[32]="XXXXXXXXXXXXXXXXXXX";
 255     if(!lss_read(teststr,sizeof(char),19,fp)) return 0;
 256     if(strcmp(teststr,"CSusie::ContextSave")!=0) return 0;
 257  
 258     if(!lss_read(&mTMPADR,sizeof(UUWORD),1,fp)) return 0;
 259     if(!lss_read(&mTILTACUM,sizeof(UUWORD),1,fp)) return 0;
 260     if(!lss_read(&mHOFF,sizeof(UUWORD),1,fp)) return 0;
 261     if(!lss_read(&mVOFF,sizeof(UUWORD),1,fp)) return 0;
 262     if(!lss_read(&mVIDBAS,sizeof(UUWORD),1,fp)) return 0;
 263     if(!lss_read(&mCOLLBAS,sizeof(UUWORD),1,fp)) return 0;
 264     if(!lss_read(&mVIDADR,sizeof(UUWORD),1,fp)) return 0;
 265     if(!lss_read(&mCOLLADR,sizeof(UUWORD),1,fp)) return 0;
 266     if(!lss_read(&mSCBNEXT,sizeof(UUWORD),1,fp)) return 0;
 267     if(!lss_read(&mSPRDLINE,sizeof(UUWORD),1,fp)) return 0;
 268     if(!lss_read(&mHPOSSTRT,sizeof(UUWORD),1,fp)) return 0;
 269     if(!lss_read(&mVPOSSTRT,sizeof(UUWORD),1,fp)) return 0;
 270     if(!lss_read(&mSPRHSIZ,sizeof(UUWORD),1,fp)) return 0;
 271     if(!lss_read(&mSPRVSIZ,sizeof(UUWORD),1,fp)) return 0;
 272     if(!lss_read(&mSTRETCH,sizeof(UUWORD),1,fp)) return 0;
 273     if(!lss_read(&mTILT,sizeof(UUWORD),1,fp)) return 0;
 274     if(!lss_read(&mSPRDOFF,sizeof(UUWORD),1,fp)) return 0;
 275     if(!lss_read(&mSPRVPOS,sizeof(UUWORD),1,fp)) return 0;
 276     if(!lss_read(&mCOLLOFF,sizeof(UUWORD),1,fp)) return 0;
 277     if(!lss_read(&mVSIZACUM,sizeof(UUWORD),1,fp)) return 0;
 278     if(!lss_read(&mHSIZACUM,sizeof(UUWORD),1,fp)) return 0;
 279     if(!lss_read(&mHSIZOFF,sizeof(UUWORD),1,fp)) return 0;
 280     if(!lss_read(&mVSIZOFF,sizeof(UUWORD),1,fp)) return 0;
 281     if(!lss_read(&mSCBADR,sizeof(UUWORD),1,fp)) return 0;
 282     if(!lss_read(&mPROCADR,sizeof(UUWORD),1,fp)) return 0;
 283  
 284     if(!lss_read(&mMATHABCD,sizeof(TMATHABCD),1,fp)) return 0;
 285     if(!lss_read(&mMATHEFGH,sizeof(TMATHEFGH),1,fp)) return 0;
 286     if(!lss_read(&mMATHJKLM,sizeof(TMATHJKLM),1,fp)) return 0;
 287     if(!lss_read(&mMATHNP,sizeof(TMATHNP),1,fp)) return 0;
 288  
 289     if(!lss_read(&mSPRCTL0_Type,sizeof(ULONG),1,fp)) return 0;
 290     if(!lss_read(&mSPRCTL0_Vflip,sizeof(ULONG),1,fp)) return 0;
 291     if(!lss_read(&mSPRCTL0_Hflip,sizeof(ULONG),1,fp)) return 0;
 292     if(!lss_read(&mSPRCTL0_PixelBits,sizeof(ULONG),1,fp)) return 0;
 293  
 294     if(!lss_read(&mSPRCTL1_StartLeft,sizeof(ULONG),1,fp)) return 0;
 295     if(!lss_read(&mSPRCTL1_StartUp,sizeof(ULONG),1,fp)) return 0;
 296     if(!lss_read(&mSPRCTL1_SkipSprite,sizeof(ULONG),1,fp)) return 0;
 297     if(!lss_read(&mSPRCTL1_ReloadPalette,sizeof(ULONG),1,fp)) return 0;
 298     if(!lss_read(&mSPRCTL1_ReloadDepth,sizeof(ULONG),1,fp)) return 0;
 299     if(!lss_read(&mSPRCTL1_Sizing,sizeof(ULONG),1,fp)) return 0;
 300     if(!lss_read(&mSPRCTL1_Literal,sizeof(ULONG),1,fp)) return 0;
 301  
 302     if(!lss_read(&mSPRCOLL_Number,sizeof(ULONG),1,fp)) return 0;
 303     if(!lss_read(&mSPRCOLL_Collide,sizeof(ULONG),1,fp)) return 0;
 304  
 305     if(!lss_read(&mSPRSYS_StopOnCurrent,sizeof(ULONG),1,fp)) return 0;
 306     if(!lss_read(&mSPRSYS_LeftHand,sizeof(ULONG),1,fp)) return 0;
 307     if(!lss_read(&mSPRSYS_VStretch,sizeof(ULONG),1,fp)) return 0;
 308     if(!lss_read(&mSPRSYS_NoCollide,sizeof(ULONG),1,fp)) return 0;
 309     if(!lss_read(&mSPRSYS_Accumulate,sizeof(ULONG),1,fp)) return 0;
 310     if(!lss_read(&mSPRSYS_SignedMath,sizeof(ULONG),1,fp)) return 0;
 311     if(!lss_read(&mSPRSYS_Status,sizeof(ULONG),1,fp)) return 0;
 312     if(!lss_read(&mSPRSYS_UnsafeAccess,sizeof(ULONG),1,fp)) return 0;
 313     if(!lss_read(&mSPRSYS_LastCarry,sizeof(ULONG),1,fp)) return 0;
 314     if(!lss_read(&mSPRSYS_Mathbit,sizeof(ULONG),1,fp)) return 0;
 315     if(!lss_read(&mSPRSYS_MathInProgress,sizeof(ULONG),1,fp)) return 0;
 316  
 317     if(!lss_read(&mSUZYBUSEN,sizeof(ULONG),1,fp)) return 0;
 318  
 319     if(!lss_read(&mSPRINIT,sizeof(TSPRINIT),1,fp)) return 0;
 320  
 321     if(!lss_read(&mSPRGO,sizeof(ULONG),1,fp)) return 0;
 322     if(!lss_read(&mEVERON,sizeof(ULONG),1,fp)) return 0;
 323  
 324     if(!lss_read(mPenIndex,sizeof(UBYTE),16,fp)) return 0;
 325  
 326     if(!lss_read(&mLineType,sizeof(ULONG),1,fp)) return 0;
 327     if(!lss_read(&mLineShiftRegCount,sizeof(ULONG),1,fp)) return 0;
 328     if(!lss_read(&mLineShiftReg,sizeof(ULONG),1,fp)) return 0;
 329     if(!lss_read(&mLineRepeatCount,sizeof(ULONG),1,fp)) return 0;
 330     if(!lss_read(&mLinePixel,sizeof(ULONG),1,fp)) return 0;
 331     if(!lss_read(&mLinePacketBitsLeft,sizeof(ULONG),1,fp)) return 0;
 332  
 333     if(!lss_read(&mCollision,sizeof(ULONG),1,fp)) return 0;
 334  
 335     if(!lss_read(&mLineBaseAddress,sizeof(ULONG),1,fp)) return 0;
 336     if(!lss_read(&mLineCollisionAddress,sizeof(ULONG),1,fp)) return 0;
 337  
 338     if(!lss_read(&mJOYSTICK,sizeof(TJOYSTICK),1,fp)) return 0;
 339     if(!lss_read(&mSWITCHES,sizeof(TSWITCHES),1,fp)) return 0;
 340  
 341     return 1;
 342  }
 343  
 344  ULONG CSusie::PaintSprites(void)
 345  {
 346     int	sprcount=0;
 347     int data=0;
 348     int everonscreen=0;
 349  
 350     TRACE_SUSIE0("                                                              ");
 351     TRACE_SUSIE0("                                                              ");
 352     TRACE_SUSIE0("                                                              ");
 353     TRACE_SUSIE0("**************************************************************");
 354     TRACE_SUSIE0("********************** PaintSprites **************************");
 355     TRACE_SUSIE0("**************************************************************");
 356     TRACE_SUSIE0("                                                              ");
 357  
 358     TRACE_SUSIE1("PaintSprites() VIDBAS  $%04x",mVIDBAS.Word);
 359     TRACE_SUSIE1("PaintSprites() COLLBAS $%04x",mCOLLBAS.Word);
 360     TRACE_SUSIE1("PaintSprites() SPRSYS  $%02x",Peek(SPRSYS));
 361  
 362     if(!mSUZYBUSEN || !mSPRGO) {
 363        TRACE_SUSIE0("PaintSprites() Returned !mSUZYBUSEN || !mSPRGO");
 364        return 0;
 365     }
 366  
 367     //ULONG       mPenIndex[16];
 368     mCycles=0;
 369  
 370     while (1)
 371     {
 372        TRACE_SUSIE1("PaintSprites() ************ Rendering Sprite %03d ************",sprcount);
 373  
 374        everonscreen=0;// everon has to be reset for every sprite, thus line was moved inside this loop
 375  
 376        // Step 1 load up the SCB params into Susie
 377  
 378        // And thus it is documented that only the top byte of SCBNEXT is used.
 379        // Its mentioned under the bits that are broke section in the bluebook
 380        if(!(mSCBNEXT.Word&0xff00)) {
 381           TRACE_SUSIE0("PaintSprites() mSCBNEXT==0 - FINISHED");
 382           mSPRSYS_Status=0;	// Engine has finished
 383           mSPRGO=FALSE;
 384           break;
 385        } else {
 386           mSPRSYS_Status=1;
 387        }
 388  
 389        mTMPADR.Word=mSCBNEXT.Word;	// Copy SCB pointer
 390        mSCBADR.Word=mSCBNEXT.Word;	// Copy SCB pointer
 391        TRACE_SUSIE1("PaintSprites() SCBADDR $%04x",mSCBADR.Word);
 392  
 393        data=RAM_PEEK(mTMPADR.Word);			// Fetch control 0
 394        TRACE_SUSIE1("PaintSprites() SPRCTL0 $%02x",data);
 395        mSPRCTL0_Type=data&0x0007;
 396        mSPRCTL0_Vflip=data&0x0010;
 397        mSPRCTL0_Hflip=data&0x0020;
 398        mSPRCTL0_PixelBits=((data&0x00c0)>>6)+1;
 399        mTMPADR.Word+=1;
 400  
 401        data=RAM_PEEK(mTMPADR.Word);			// Fetch control 1
 402        TRACE_SUSIE1("PaintSprites() SPRCTL1 $%02x",data);
 403        mSPRCTL1_StartLeft=data&0x0001;
 404        mSPRCTL1_StartUp=data&0x0002;
 405        mSPRCTL1_SkipSprite=data&0x0004;
 406        mSPRCTL1_ReloadPalette=data&0x0008;
 407        mSPRCTL1_ReloadDepth=(data&0x0030)>>4;
 408        mSPRCTL1_Sizing=data&0x0040;
 409        mSPRCTL1_Literal=data&0x0080;
 410        mTMPADR.Word+=1;
 411  
 412        data=RAM_PEEK(mTMPADR.Word);			// Collision num
 413        TRACE_SUSIE1("PaintSprites() SPRCOLL $%02x",data);
 414        mSPRCOLL_Number=data&0x000f;
 415        mSPRCOLL_Collide=data&0x0020;
 416        mTMPADR.Word+=1;
 417  
 418        mSCBNEXT.Word=RAM_PEEKW(mTMPADR.Word);	// Next SCB
 419        TRACE_SUSIE1("PaintSprites() SCBNEXT $%04x",mSCBNEXT.Word);
 420        mTMPADR.Word+=2;
 421  
 422        mCycles+=5*SPR_RDWR_CYC;
 423  
 424        // Initialise the collision depositary
 425  
 426        // Although Tom Schenck says this is correct, it doesnt appear to be
 427        //		if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide)
 428        //		{
 429        //			mCollision=RAM_PEEK((mSCBADR.Word+mCOLLOFF.Word)&0xffff);
 430        //			mCollision&=0x0f;
 431        //		}
 432        mCollision=0;
 433  
 434        // Check if this is a skip sprite
 435  
 436        if(!mSPRCTL1_SkipSprite) {
 437           mSPRDLINE.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite pack data
 438           TRACE_SUSIE1("PaintSprites() SPRDLINE $%04x",mSPRDLINE.Word);
 439           mTMPADR.Word+=2;
 440  
 441           mHPOSSTRT.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite horizontal start position
 442           TRACE_SUSIE1("PaintSprites() HPOSSTRT $%04x",mHPOSSTRT.Word);
 443           mTMPADR.Word+=2;
 444  
 445           mVPOSSTRT.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite vertical start position
 446           TRACE_SUSIE1("PaintSprites() VPOSSTRT $%04x",mVPOSSTRT.Word);
 447           mTMPADR.Word+=2;
 448  
 449           mCycles+=6*SPR_RDWR_CYC;
 450  
 451           // bool enable_sizing  = FALSE;
 452           bool enable_stretch = FALSE;
 453           bool enable_tilt    = FALSE;
 454  
 455           // Optional section defined by reload type in Control 1
 456  
 457           TRACE_SUSIE1("PaintSprites() mSPRCTL1.Bits.ReloadDepth=%d",mSPRCTL1_ReloadDepth);
 458           switch(mSPRCTL1_ReloadDepth) {
 459              case 1:
 460                 TRACE_SUSIE0("PaintSprites() Sizing Enabled");
 461                 // enable_sizing=TRUE;
 462  
 463                 mSPRHSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Horizontal size
 464                 mTMPADR.Word+=2;
 465  
 466                 mSPRVSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Verticalal size
 467                 mTMPADR.Word+=2;
 468  
 469                 mCycles+=4*SPR_RDWR_CYC;
 470                 break;
 471  
 472              case 2:
 473                 TRACE_SUSIE0("PaintSprites() Sizing Enabled");
 474                 TRACE_SUSIE0("PaintSprites() Stretch Enabled");
 475                 // enable_sizing=TRUE;
 476                 enable_stretch=TRUE;
 477  
 478                 mSPRHSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Horizontal size
 479                 mTMPADR.Word+=2;
 480  
 481                 mSPRVSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Verticalal size
 482                 mTMPADR.Word+=2;
 483  
 484                 mSTRETCH.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite stretch
 485                 mTMPADR.Word+=2;
 486  
 487                 mCycles+=6*SPR_RDWR_CYC;
 488                 break;
 489  
 490              case 3:
 491                 TRACE_SUSIE0("PaintSprites() Sizing Enabled");
 492                 TRACE_SUSIE0("PaintSprites() Stretch Enabled");
 493                 TRACE_SUSIE0("PaintSprites() Tilt Enabled");
 494                 // enable_sizing=TRUE;
 495                 enable_stretch=TRUE;
 496                 enable_tilt=TRUE;
 497  
 498                 mSPRHSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Horizontal size
 499                 mTMPADR.Word+=2;
 500  
 501                 mSPRVSIZ.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite Verticalal size
 502                 mTMPADR.Word+=2;
 503  
 504                 mSTRETCH.Word=RAM_PEEKW(mTMPADR.Word);	// Sprite stretch
 505                 mTMPADR.Word+=2;
 506  
 507                 mTILT.Word=RAM_PEEKW(mTMPADR.Word);		// Sprite tilt
 508                 mTMPADR.Word+=2;
 509  
 510                 mCycles+=8*SPR_RDWR_CYC;
 511                 break;
 512  
 513              default:
 514                 break;
 515           }
 516  
 517           TRACE_SUSIE1("PaintSprites() SPRHSIZ $%04x",mSPRHSIZ.Word);
 518           TRACE_SUSIE1("PaintSprites() SPRVSIZ $%04x",mSPRVSIZ.Word);
 519           TRACE_SUSIE1("PaintSprites() STRETCH $%04x",mSTRETCH.Word);
 520           TRACE_SUSIE1("PaintSprites() TILT    $%04x",mTILT.Word);
 521  
 522  
 523           // Optional Palette reload
 524  
 525           if(!mSPRCTL1_ReloadPalette) {
 526              TRACE_SUSIE0("PaintSprites() Palette reloaded");
 527              for(int loop=0;loop<8;loop++) {
 528                 UBYTE data_tmp=RAM_PEEK(mTMPADR.Word++);
 529                 mPenIndex[loop*2]=(data_tmp>>4)&0x0f;
 530                 mPenIndex[(loop*2)+1]=data_tmp&0x0f;
 531              }
 532              // Increment cycle count for the reads
 533              mCycles+=8*SPR_RDWR_CYC;
 534           }
 535  
 536           // Now we can start painting
 537  
 538           // Quadrant drawing order is: SE,NE,NW,SW
 539           // start quadrant is given by sprite_control1:0 & 1
 540  
 541           // Setup screen start end variables
 542  
 543           int screen_h_start=(SWORD)mHOFF.Word;
 544           int screen_h_end=(SWORD)mHOFF.Word+HANDY_SCREEN_WIDTH;
 545           int screen_v_start=(SWORD)mVOFF.Word;
 546           int screen_v_end=(SWORD)mVOFF.Word+HANDY_SCREEN_HEIGHT;
 547  
 548           int world_h_mid=screen_h_start+0x8000+(HANDY_SCREEN_WIDTH/2);
 549           int world_v_mid=screen_v_start+0x8000+(HANDY_SCREEN_HEIGHT/2);
 550  
 551           TRACE_SUSIE2("PaintSprites() screen_h_start $%04x screen_h_end $%04x",screen_h_start,screen_h_end);
 552           TRACE_SUSIE2("PaintSprites() screen_v_start $%04x screen_v_end $%04x",screen_v_start,screen_v_end);
 553           TRACE_SUSIE2("PaintSprites() world_h_mid    $%04x world_v_mid  $%04x",world_h_mid,world_v_mid);
 554  
 555           bool superclip=FALSE;
 556           int quadrant=0;
 557           int hsign,vsign;
 558  
 559           if(mSPRCTL1_StartLeft) {
 560              if(mSPRCTL1_StartUp) quadrant=2; else quadrant=3;
 561           } else {
 562              if(mSPRCTL1_StartUp) quadrant=1; else quadrant=0;
 563           }
 564           TRACE_SUSIE1("PaintSprites() Quadrant=%d",quadrant);
 565  
 566           // Check ref is inside screen area
 567  
 568           if((SWORD)mHPOSSTRT.Word<screen_h_start || (SWORD)mHPOSSTRT.Word>=screen_h_end ||
 569              (SWORD)mVPOSSTRT.Word<screen_v_start || (SWORD)mVPOSSTRT.Word>=screen_v_end) superclip=TRUE;
 570  
 571           TRACE_SUSIE1("PaintSprites() Superclip=%d",superclip);
 572  
 573  
 574           // Quadrant mapping is:	SE	NE	NW	SW
 575           //						0	1	2	3
 576           // hsign				+1	+1	-1	-1
 577           // vsign				+1	-1	-1	+1
 578           //
 579           //
 580           //		2 | 1
 581           //     -------
 582           //      3 | 0
 583           //
 584  
 585           // Loop for 4 quadrants
 586  
 587           for(int loop=0;loop<4;loop++) {
 588              TRACE_SUSIE1("PaintSprites() -------- Rendering Quadrant %03d --------",quadrant);
 589  
 590              int sprite_v=mVPOSSTRT.Word;
 591              int sprite_h=mHPOSSTRT.Word;
 592  
 593              bool render=FALSE;
 594  
 595              // Set quadrand multipliers
 596              hsign=(quadrant==0 || quadrant==1)?1:-1;
 597              vsign=(quadrant==0 || quadrant==3)?1:-1;
 598  
 599              // Preflip		TRACE_SUSIE2("PaintSprites() hsign=%d vsign=%d",hsign,vsign);
 600  
 601              //Use h/v flip to invert v/hsign
 602  
 603              if(mSPRCTL0_Vflip) vsign=-vsign;
 604              if(mSPRCTL0_Hflip) hsign=-hsign;
 605  
 606              TRACE_SUSIE2("PaintSprites() Hflip=%d Vflip=%d",mSPRCTL0_Hflip,mSPRCTL0_Vflip);
 607              TRACE_SUSIE2("PaintSprites() Hsign=%d   Vsign=%d",hsign,vsign);
 608              TRACE_SUSIE2("PaintSprites() Hpos =%04x Vpos =%04x",mHPOSSTRT.Word,mVPOSSTRT.Word);
 609              TRACE_SUSIE2("PaintSprites() Hsizoff =%04x Vsizoff =%04x",mHSIZOFF.Word,mVSIZOFF.Word);
 610  
 611              // Two different rendering algorithms used, on-screen & superclip
 612              // when on screen we draw in x until off screen then skip to next
 613              // line, BUT on superclip we draw all the way to the end of any
 614              // given line checking each pixel is on screen.
 615  
 616              if(superclip) {
 617                 // Check on the basis of each quad, we only render the quad
 618                 // IF the screen is in the quad, relative to the centre of
 619                 // the screen which is calculated below.
 620  
 621                 // Quadrant mapping is:	SE	NE	NW	SW
 622                 //						0	1	2	3
 623                 // hsign				+1	+1	-1	-1
 624                 // vsign				+1	-1	-1	+1
 625                 //
 626                 //
 627                 //		2 | 1
 628                 //     -------
 629                 //      3 | 0
 630                 //
 631                 // Quadrant mapping for superclipping must also take into account
 632                 // the hflip, vflip bits & negative tilt to be able to work correctly
 633                 //
 634                 int	modquad=quadrant;
 635                 static int vquadflip[4]={1,0,3,2};
 636                 static int hquadflip[4]={3,2,1,0};
 637  
 638                 if(mSPRCTL0_Vflip) modquad=vquadflip[modquad];
 639                 if(mSPRCTL0_Hflip) modquad=hquadflip[modquad];
 640  
 641                 // This is causing Eurosoccer to fail!!
 642                 //					if(enable_tilt && mTILT.Word&0x8000) modquad=hquadflip[modquad];
 643  
 644                 switch(modquad) {
 645                    case 3:
 646                       if((sprite_h>=screen_h_start || sprite_h<world_h_mid) && (sprite_v<screen_v_end   || sprite_v>world_v_mid)) render=TRUE;
 647                       break;
 648                    case 2:
 649                       if((sprite_h>=screen_h_start || sprite_h<world_h_mid) && (sprite_v>=screen_v_start || sprite_v<world_v_mid)) render=TRUE;
 650                       break;
 651                    case 1:
 652                       if((sprite_h<screen_h_end   || sprite_h>world_h_mid) && (sprite_v>=screen_v_start || sprite_v<world_v_mid)) render=TRUE;
 653                       break;
 654                    default:
 655                       if((sprite_h<screen_h_end   || sprite_h>world_h_mid) && (sprite_v<screen_v_end   || sprite_v>world_v_mid)) render=TRUE;
 656                       break;
 657                 }
 658              } else {
 659                 render=TRUE;
 660              }
 661  
 662              // Is this quad to be rendered ??
 663  
 664              TRACE_SUSIE1("PaintSprites() Render status %d",render);
 665  
 666              int pixel_height=0;
 667              int pixel_width=0;
 668              // static int pixel=0;
 669              int hoff=0,voff=0;
 670              // int hloop=0;
 671              int vloop=0;
 672              bool onscreen=0;
 673              static int vquadoff=0;
 674              static int hquadoff=0;
 675  
 676              if(render) { //  && gRenderFrame
 677                 // Set the vertical position & offset
 678                 voff=(SWORD)mVPOSSTRT.Word-screen_v_start;
 679  
 680                 // Zero the stretch,tilt & acum values
 681                 mTILTACUM.Word=0;
 682  
 683                 // Perform the SIZOFF
 684                 if(vsign==1) mVSIZACUM.Word=mVSIZOFF.Word;
 685                 else mVSIZACUM.Word=0;
 686  
 687                 // Take the sign of the first quad (0) as the basic
 688                 // sign, all other quads drawing in the other direction
 689                 // get offset by 1 pixel in the other direction, this
 690                 // fixes the squashed look on the multi-quad sprites.
 691                 //					if(vsign==-1 && loop>0) voff+=vsign;
 692                 if(loop==0)	vquadoff=vsign;
 693                 if(vsign!=vquadoff) voff+=vsign;
 694  
 695                 for(;;) {
 696                    // Vertical scaling is done here
 697                    mVSIZACUM.Word+=mSPRVSIZ.Word;
 698                    pixel_height=mVSIZACUM.Byte.High;
 699                    mVSIZACUM.Byte.High=0;
 700  
 701                    // Update the next data line pointer and initialise our line
 702                    mSPRDOFF.Word=(UWORD)LineInit(0);
 703  
 704                    // If 1 == next quad, ==0 end of sprite, anyways its END OF LINE
 705                    if(mSPRDOFF.Word==1) {		// End of quad
 706                       mSPRDLINE.Word+=mSPRDOFF.Word;
 707                       break;
 708                    }
 709  
 710                    if(mSPRDOFF.Word==0) {		// End of sprite
 711                       loop=4;		// Halt the quad loop
 712                       break;
 713                    }
 714  
 715                    // Draw one horizontal line of the sprite
 716                    for(vloop=0;vloop<pixel_height;vloop++) {
 717                       // Early bailout if the sprite has moved off screen, terminate quad
 718                       if(vsign==1 && voff>=HANDY_SCREEN_HEIGHT)	break;
 719                       if(vsign==-1 && voff<0)	break;
 720  
 721                       // Only allow the draw to take place if the line is visible
 722                       if(voff>=0 && voff<HANDY_SCREEN_HEIGHT) {
 723                          // Work out the horizontal pixel start position, start + tilt
 724                          mHPOSSTRT.Word+=((SWORD)mTILTACUM.Word>>8);
 725                          mTILTACUM.Byte.High=0;
 726                          hoff=(int)((SWORD)mHPOSSTRT.Word)-screen_h_start;
 727  
 728                          // Zero/Force the horizontal scaling accumulator
 729                          if(hsign==1) mHSIZACUM.Word=mHSIZOFF.Word;
 730                          else mHSIZACUM.Word=0;
 731  
 732                          // Take the sign of the first quad (0) as the basic
 733                          // sign, all other quads drawing in the other direction
 734                          // get offset by 1 pixel in the other direction, this
 735                          // fixes the squashed look on the multi-quad sprites.
 736                          //								if(hsign==-1 && loop>0) hoff+=hsign;
 737                          if(loop==0)	hquadoff=hsign;
 738                          if(hsign!=hquadoff) hoff+=hsign;
 739  
 740                          // Initialise our line
 741                          LineInit(voff);
 742                          onscreen=FALSE;
 743  
 744                          ULONG pixel = mLinePixel; // Much faster
 745                          switch(mSPRCTL0_Type)
 746                          {
 747                                case sprite_background_shadow:
 748                                   #undef PROCESS_PIXEL
 749                                   #define PROCESS_PIXEL \
 750                                   WritePixel(hoff,pixel); \
 751                                   if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide && pixel!=0x0e) \
 752                                   { \
 753                                      WriteCollision(hoff,mSPRCOLL_Number); \
 754                                   }
 755  
 756                                   #undef EndWhile
 757                                   #undef LoopContinue
 758                                   #define EndWhile EndWhile01b
 759                                   #define LoopContinue LoopContinue01b
 760                                   #include "susie_pixel_loop.h"
 761                                   break;
 762                                case sprite_background_noncollide:
 763                                   #undef PROCESS_PIXEL
 764                                   #define PROCESS_PIXEL WritePixel(hoff,pixel);
 765  
 766                                   #undef EndWhile
 767                                   #undef LoopContinue
 768                                   #define EndWhile EndWhile02b
 769                                   #define LoopContinue LoopContinue02b
 770                                   #include "susie_pixel_loop.h"
 771                                   break;
 772                                case sprite_noncollide:
 773                                   #undef PROCESS_PIXEL
 774                                   #define PROCESS_PIXEL if(pixel!=0x00) WritePixel(hoff,pixel);
 775  
 776                                   #undef EndWhile
 777                                   #undef LoopContinue
 778                                   #define EndWhile EndWhile03b
 779                                   #define LoopContinue LoopContinue03b
 780                                   #include "susie_pixel_loop.h"
 781                                   break;
 782                                case sprite_boundary:
 783                                   #undef PROCESS_PIXEL
 784                                   #define PROCESS_PIXEL \
 785                                   if(pixel!=0x00 && pixel!=0x0f) \
 786                                   { \
 787                                      WritePixel(hoff,pixel); \
 788                                   } \
 789                                   if(pixel!=0x00) \
 790                                   { \
 791                                      if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide) \
 792                                      { \
 793                                         ULONG collision=ReadCollision(hoff); \
 794                                         if(collision>mCollision) \
 795                                         { \
 796                                            mCollision=collision; \
 797                                         } \
 798                                         { \
 799                                            WriteCollision(hoff,mSPRCOLL_Number); \
 800                                         } \
 801                                      } \
 802                                   }
 803  
 804                                   #undef EndWhile
 805                                   #undef LoopContinue
 806                                   #define EndWhile EndWhile04b
 807                                   #define LoopContinue LoopContinue04b
 808                                   #include "susie_pixel_loop.h"
 809                                   break;
 810                                case sprite_normal:
 811                                   #undef PROCESS_PIXEL
 812                                   #define PROCESS_PIXEL \
 813                                   if(pixel!=0x00) \
 814                                   { \
 815                                      WritePixel(hoff,pixel); \
 816                                      if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide) \
 817                                      { \
 818                                         ULONG collision=ReadCollision(hoff); \
 819                                         if(collision>mCollision) \
 820                                         { \
 821                                            mCollision=collision; \
 822                                         } \
 823                                         { \
 824                                            WriteCollision(hoff,mSPRCOLL_Number); \
 825                                         } \
 826                                      } \
 827                                   }
 828  
 829                                   #undef EndWhile
 830                                   #undef LoopContinue
 831                                   #define EndWhile EndWhile05b
 832                                   #define LoopContinue LoopContinue05b
 833                                   #include "susie_pixel_loop.h"
 834                                   break;
 835                                case sprite_boundary_shadow:
 836                                   #undef PROCESS_PIXEL
 837                                   #define PROCESS_PIXEL \
 838                                   if(pixel!=0x00 && pixel!=0x0e && pixel!=0x0f) \
 839                                   { \
 840                                      WritePixel(hoff,pixel); \
 841                                   } \
 842                                   if(pixel!=0x00 && pixel!=0x0e) \
 843                                   { \
 844                                      if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide) \
 845                                      { \
 846                                         ULONG collision=ReadCollision(hoff); \
 847                                         if(collision>mCollision) \
 848                                         { \
 849                                            mCollision=collision; \
 850                                         } \
 851                                         { \
 852                                            WriteCollision(hoff,mSPRCOLL_Number); \
 853                                         } \
 854                                      } \
 855                                   }
 856  
 857                                   #undef EndWhile
 858                                   #undef LoopContinue
 859                                   #define EndWhile EndWhile06b
 860                                   #define LoopContinue LoopContinue06b
 861                                   #include "susie_pixel_loop.h"
 862                                   break;
 863                                case sprite_shadow:
 864                                   #undef PROCESS_PIXEL
 865                                   #define PROCESS_PIXEL \
 866                                   if(pixel!=0x00) \
 867                                   { \
 868                                      WritePixel(hoff,pixel); \
 869                                   } \
 870                                   if(pixel!=0x00 && pixel!=0x0e) \
 871                                   { \
 872                                      if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide) \
 873                                      { \
 874                                         ULONG collision=ReadCollision(hoff); \
 875                                         if(collision>mCollision) \
 876                                         { \
 877                                            mCollision=collision; \
 878                                         } \
 879                                         { \
 880                                            WriteCollision(hoff,mSPRCOLL_Number); \
 881                                         } \
 882                                      } \
 883                                   }
 884  
 885                                   #undef EndWhile
 886                                   #undef LoopContinue
 887                                   #define EndWhile EndWhile07b
 888                                   #define LoopContinue LoopContinue07b
 889                                   #include "susie_pixel_loop.h"
 890                                   break;
 891                                case sprite_xor_shadow:
 892                                   #undef PROCESS_PIXEL
 893                                   #define PROCESS_PIXEL \
 894                                   if(pixel!=0x00) \
 895                                   { \
 896                                      WritePixel(hoff,ReadPixel(hoff)^pixel); \
 897                                   } \
 898                                   if(pixel!=0x00 && pixel!=0x0e) \
 899                                   { \
 900                                      if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide && pixel!=0x0e) \
 901                                      { \
 902                                         ULONG collision=ReadCollision(hoff); \
 903                                         if(collision>mCollision) \
 904                                         { \
 905                                            mCollision=collision; \
 906                                         } \
 907                                         { \
 908                                            WriteCollision(hoff,mSPRCOLL_Number); \
 909                                         } \
 910                                      } \
 911                                   }
 912  
 913                                   #undef EndWhile
 914                                   #undef LoopContinue
 915                                   #define EndWhile EndWhile08b
 916                                   #define LoopContinue LoopContinue08b
 917                                   #include "susie_pixel_loop.h"
 918                                   break;
 919                                default:
 920                                   #undef PROCESS_PIXEL
 921                                   #define PROCESS_PIXEL
 922  
 923                                   #undef EndWhile
 924                                   #undef LoopContinue
 925                                   #define EndWhile EndWhile09b
 926                                   #define LoopContinue LoopContinue09b
 927                                   #include "susie_pixel_loop.h"
 928                                   break;
 929                          }
 930                       }
 931                       voff+=vsign;
 932  
 933                       // For every destination line we can modify SPRHSIZ & SPRVSIZ & TILTACUM
 934                       if(enable_stretch) {
 935                          mSPRHSIZ.Word+=mSTRETCH.Word;
 936                          //								if(mSPRSYS_VStretch) mSPRVSIZ.Word+=mSTRETCH.Word;
 937                       }
 938                       if(enable_tilt) {
 939                          // Manipulate the tilt stuff
 940                          mTILTACUM.Word+=mTILT.Word;
 941                       }
 942                    }
 943                    // According to the docs this increments per dest line
 944                    // but only gets set when the source line is read
 945                    if(mSPRSYS_VStretch) mSPRVSIZ.Word+=mSTRETCH.Word*pixel_height;
 946  
 947                    // Update the line start for our next run thru the loop
 948                    mSPRDLINE.Word+=mSPRDOFF.Word;
 949                 }
 950              } else {
 951                 // Skip thru data to next quad
 952                 for(;;) {
 953                    // Read the start of line offset
 954  
 955                    mSPRDOFF.Word=(UWORD)LineInit(0);
 956  
 957                    // We dont want to process data so mSPRDLINE is useless to us
 958                    mSPRDLINE.Word+=mSPRDOFF.Word;
 959  
 960                    // If 1 == next quad, ==0 end of sprite, anyways its END OF LINE
 961  
 962                    if(mSPRDOFF.Word==1) break;	// End of quad
 963                    if(mSPRDOFF.Word==0) {		// End of sprite
 964                       loop=4;		// Halt the quad loop
 965                       break;
 966                    }
 967  
 968                 }
 969              }
 970  
 971              // Increment quadrant and mask to 2 bit value (0-3)
 972              quadrant++;
 973              quadrant&=0x03;
 974           }
 975  
 976           // Write the collision depositary if required
 977  
 978           if(!mSPRCOLL_Collide && !mSPRSYS_NoCollide) {
 979              switch(mSPRCTL0_Type) {
 980                 case sprite_xor_shadow:
 981                 case sprite_boundary:
 982                 case sprite_normal:
 983                 case sprite_boundary_shadow:
 984                 case sprite_shadow: {
 985                       UWORD coldep=mSCBADR.Word+mCOLLOFF.Word;
 986                       RAM_POKE(coldep,(UBYTE)mCollision);
 987                       TRACE_SUSIE2("PaintSprites() COLLOFF=$%04x SCBADR=$%04x",mCOLLOFF.Word,mSCBADR.Word);
 988                       TRACE_SUSIE2("PaintSprites() Wrote $%02x to SCB collision depositary at $%04x",(UBYTE)mCollision,coldep);
 989                    }
 990                    break;
 991                 default:
 992                    break;
 993              }
 994           }
 995  
 996           if(mEVERON) {
 997              UWORD coldep=mSCBADR.Word+mCOLLOFF.Word;
 998              UBYTE coldat=RAM_PEEK(coldep);
 999              if(!everonscreen) coldat|=0x80;
1000              else coldat&=0x7f;
1001              RAM_POKE(coldep,coldat);
1002              TRACE_SUSIE0("PaintSprites() EVERON IS ACTIVE");
1003              TRACE_SUSIE2("PaintSprites() Wrote $%02x to SCB collision depositary at $%04x",coldat,coldep);
1004           }
1005  
1006           // Perform Sprite debugging if required, single step on sprite draw
1007           if(gSingleStepModeSprites) {
1008              // char message[256];
1009              //log_printf("CSusie:PaintSprites() - Rendered Sprite %03d\n",sprcount);
1010              //SingleStepModeSprites=0;
1011           }
1012        } else {
1013           TRACE_SUSIE0("PaintSprites() mSPRCTL1.Bits.SkipSprite==TRUE");
1014        }
1015  
1016        // Increase sprite number
1017        sprcount++;
1018  
1019        // Check if we abort after 1st sprite is complete
1020  
1021        //		if(mSPRSYS.Read.StopOnCurrent)
1022        //		{
1023        //			mSPRSYS.Read.Status=0;	// Engine has finished
1024        //			mSPRGO=FALSE;
1025        //			break;
1026        //		}
1027  
1028        // Check sprcount for looping SCB, random large number chosen
1029        if(sprcount>4096) {
1030           // Stop the system, otherwise we may just come straight back in.....
1031           gSystemHalt=TRUE;
1032           // Display warning message
1033           log_printf("CSusie:PaintSprites(): Single draw sprite limit exceeded (>4096). The SCB is most likely looped back on itself. Reset/Exit is recommended\n");
1034           // Signal error to the caller
1035           return 0;
1036        }
1037     }
1038     // Fudge factor to fix many flickering issues, also the keypress
1039     // problem with Hard Drivin and the strange pause in Dirty Larry.
1040     //   mCycles>>=2;
1041     return mCycles;
1042  }
1043  
1044  void CSusie::Poke(ULONG addr,UBYTE data)
1045  {
1046     switch(addr&0xff) {
1047        case (TMPADRL&0xff):
1048           mTMPADR.Byte.Low=data;
1049           mTMPADR.Byte.High=0;
1050           TRACE_SUSIE2("Poke(TMPADRL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1051           break;
1052        case (TMPADRH&0xff):
1053           mTMPADR.Byte.High=data;
1054           TRACE_SUSIE2("Poke(TMPADRH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1055           break;
1056        case (TILTACUML&0xff):
1057           mTILTACUM.Byte.Low=data;
1058           mTILTACUM.Byte.High=0;
1059           TRACE_SUSIE2("Poke(TILTACUML,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1060           break;
1061        case (TILTACUMH&0xff):
1062           mTILTACUM.Byte.High=data;
1063           TRACE_SUSIE2("Poke(TILTACUMH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1064           break;
1065        case (HOFFL&0xff):
1066           mHOFF.Byte.Low=data;
1067           mHOFF.Byte.High=0;
1068           TRACE_SUSIE2("Poke(HOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1069           break;
1070        case (HOFFH&0xff):
1071           mHOFF.Byte.High=data;
1072           TRACE_SUSIE2("Poke(HOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1073           break;
1074        case (VOFFL&0xff):
1075           mVOFF.Byte.Low=data;
1076           mVOFF.Byte.High=0;
1077           TRACE_SUSIE2("Poke(VOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1078           break;
1079        case (VOFFH&0xff):
1080           mVOFF.Byte.High=data;
1081           TRACE_SUSIE2("Poke(VOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1082           break;
1083        case (VIDBASL&0xff):
1084           mVIDBAS.Byte.Low=data;
1085           mVIDBAS.Byte.High=0;
1086           TRACE_SUSIE2("Poke(VIDBASL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1087           break;
1088        case (VIDBASH&0xff):
1089           mVIDBAS.Byte.High=data;
1090           TRACE_SUSIE2("Poke(VIDBASH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1091           break;
1092        case (COLLBASL&0xff):
1093           mCOLLBAS.Byte.Low=data;
1094           mCOLLBAS.Byte.High=0;
1095           TRACE_SUSIE2("Poke(COLLBASL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1096           break;
1097        case (COLLBASH&0xff):
1098           mCOLLBAS.Byte.High=data;
1099           TRACE_SUSIE2("Poke(COLLBASH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1100           break;
1101        case (VIDADRL&0xff):
1102           mVIDADR.Byte.Low=data;
1103           mVIDADR.Byte.High=0;
1104           TRACE_SUSIE2("Poke(VIDADRL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1105           break;
1106        case (VIDADRH&0xff):
1107           mVIDADR.Byte.High=data;
1108           TRACE_SUSIE2("Poke(VIDADRH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1109           break;
1110        case (COLLADRL&0xff):
1111           mCOLLADR.Byte.Low=data;
1112           mCOLLADR.Byte.High=0;
1113           TRACE_SUSIE2("Poke(COLLADRL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1114           break;
1115        case (COLLADRH&0xff):
1116           mCOLLADR.Byte.High=data;
1117           TRACE_SUSIE2("Poke(COLLADRH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1118           break;
1119        case (SCBNEXTL&0xff):
1120           mSCBNEXT.Byte.Low=data;
1121           mSCBNEXT.Byte.High=0;
1122           TRACE_SUSIE2("Poke(SCBNEXTL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1123           break;
1124        case (SCBNEXTH&0xff):
1125           mSCBNEXT.Byte.High=data;
1126           TRACE_SUSIE2("Poke(SCBNEXTH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1127           break;
1128        case (SPRDLINEL&0xff):
1129           mSPRDLINE.Byte.Low=data;
1130           mSPRDLINE.Byte.High=0;
1131           TRACE_SUSIE2("Poke(SPRDLINEL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1132           break;
1133        case (SPRDLINEH&0xff):
1134           mSPRDLINE.Byte.High=data;
1135           TRACE_SUSIE2("Poke(SPRDLINEH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1136           break;
1137        case (HPOSSTRTL&0xff):
1138           mHPOSSTRT.Byte.Low=data;
1139           mHPOSSTRT.Byte.High=0;
1140           TRACE_SUSIE2("Poke(HPOSSTRTL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1141           break;
1142        case (HPOSSTRTH&0xff):
1143           mHPOSSTRT.Byte.High=data;
1144           TRACE_SUSIE2("Poke(HPOSSTRTH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1145           break;
1146        case (VPOSSTRTL&0xff):
1147           mVPOSSTRT.Byte.Low=data;
1148           mVPOSSTRT.Byte.High=0;
1149           TRACE_SUSIE2("Poke(VPOSSTRTL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1150           break;
1151        case (VPOSSTRTH&0xff):
1152           mVPOSSTRT.Byte.High=data;
1153           TRACE_SUSIE2("Poke(VPOSSTRTH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1154           break;
1155        case (SPRHSIZL&0xff):
1156           mSPRHSIZ.Byte.Low=data;
1157           mSPRHSIZ.Byte.High=0;
1158           TRACE_SUSIE2("Poke(SPRHSIZL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1159           break;
1160        case (SPRHSIZH&0xff):
1161           mSPRHSIZ.Byte.High=data;
1162           TRACE_SUSIE2("Poke(SPRHSIZH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1163           break;
1164        case (SPRVSIZL&0xff):
1165           mSPRVSIZ.Byte.Low=data;
1166           mSPRVSIZ.Byte.High=0;
1167           TRACE_SUSIE2("Poke(SPRVSIZL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1168           break;
1169        case (SPRVSIZH&0xff):
1170           mSPRVSIZ.Byte.High=data;
1171           TRACE_SUSIE2("Poke(SPRVSIZH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1172           break;
1173        case (STRETCHL&0xff):
1174           mSTRETCH.Byte.Low=data;
1175           mSTRETCH.Byte.High=0;
1176           TRACE_SUSIE2("Poke(STRETCHL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1177           break;
1178        case (STRETCHH&0xff):
1179           TRACE_SUSIE2("Poke(STRETCHH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1180           mSTRETCH.Byte.High=data;
1181           break;
1182        case (TILTL&0xff):
1183           mTILT.Byte.Low=data;
1184           mTILT.Byte.High=0;
1185           TRACE_SUSIE2("Poke(TILTL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1186           break;
1187        case (TILTH&0xff):
1188           mTILT.Byte.High=data;
1189           TRACE_SUSIE2("Poke(TILTH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1190           break;
1191        case (SPRDOFFL&0xff):
1192           TRACE_SUSIE2("Poke(SPRDOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1193           mSPRDOFF.Byte.Low=data;
1194           mSPRDOFF.Byte.High=0;
1195           break;
1196        case (SPRDOFFH&0xff):
1197           TRACE_SUSIE2("Poke(SPRDOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1198           mSPRDOFF.Byte.High=data;
1199           break;
1200        case (SPRVPOSL&0xff):
1201           TRACE_SUSIE2("Poke(SPRVPOSL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1202           mSPRVPOS.Byte.Low=data;
1203           mSPRVPOS.Byte.High=0;
1204           break;
1205        case (SPRVPOSH&0xff):
1206           mSPRVPOS.Byte.High=data;
1207           TRACE_SUSIE2("Poke(SPRVPOSH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1208           break;
1209        case (COLLOFFL&0xff):
1210           mCOLLOFF.Byte.Low=data;
1211           mCOLLOFF.Byte.High=0;
1212           TRACE_SUSIE2("Poke(COLLOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1213           break;
1214        case (COLLOFFH&0xff):
1215           mCOLLOFF.Byte.High=data;
1216           TRACE_SUSIE2("Poke(COLLOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1217           break;
1218        case (VSIZACUML&0xff):
1219           mVSIZACUM.Byte.Low=data;
1220           mVSIZACUM.Byte.High=0;
1221           TRACE_SUSIE2("Poke(VSIZACUML,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1222           break;
1223        case (VSIZACUMH&0xff):
1224           mVSIZACUM.Byte.High=data;
1225           TRACE_SUSIE2("Poke(VSIZACUMH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1226           break;
1227        case (HSIZOFFL&0xff):
1228           mHSIZOFF.Byte.Low=data;
1229           mHSIZOFF.Byte.High=0;
1230           TRACE_SUSIE2("Poke(HSIZOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1231           break;
1232        case (HSIZOFFH&0xff):
1233           mHSIZOFF.Byte.High=data;
1234           TRACE_SUSIE2("Poke(HSIZOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1235           break;
1236        case (VSIZOFFL&0xff):
1237           mVSIZOFF.Byte.Low=data;
1238           mVSIZOFF.Byte.High=0;
1239           TRACE_SUSIE2("Poke(VSIZOFFL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1240           break;
1241        case (VSIZOFFH&0xff):
1242           mVSIZOFF.Byte.High=data;
1243           TRACE_SUSIE2("Poke(VSIZOFFH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1244           break;
1245        case (SCBADRL&0xff):
1246           mSCBADR.Byte.Low=data;
1247           mSCBADR.Byte.High=0;
1248           TRACE_SUSIE2("Poke(SCBADRL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1249           break;
1250        case (SCBADRH&0xff):
1251           mSCBADR.Byte.High=data;
1252           TRACE_SUSIE2("Poke(SCBADRH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1253           break;
1254        case (PROCADRL&0xff):
1255           mPROCADR.Byte.Low=data;
1256           mPROCADR.Byte.High=0;
1257           TRACE_SUSIE2("Poke(PROCADRL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1258           break;
1259        case (PROCADRH&0xff):
1260           mPROCADR.Byte.High=data;
1261           TRACE_SUSIE2("Poke(PROCADRH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1262           break;
1263  
1264        case (MATHD&0xff):
1265           TRACE_SUSIE2("Poke(MATHD,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1266           mMATHABCD.Bytes.D=data;
1267           //			mMATHABCD.Bytes.C=0;
1268           // The hardware manual says that the sign shouldnt change
1269           // but if I dont do this then stun runner will hang as it
1270           // does the init in the wrong order and if the previous
1271           // calc left a zero there then we'll get a sign error
1272           Poke(MATHC,0);
1273           break;
1274        case (MATHC&0xff):
1275           TRACE_SUSIE2("Poke(MATHC,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1276           mMATHABCD.Bytes.C=data;
1277           // Perform sign conversion if required
1278           if(mSPRSYS_SignedMath) {
1279              // Account for the math bug that 0x8000 is +ve & 0x0000 is -ve by subracting 1
1280              if((mMATHABCD.Words.CD-1)&0x8000) {
1281                 UWORD conv;
1282                 conv=mMATHABCD.Words.CD^0xffff;
1283                 conv++;
1284                 mMATHCD_sign=-1;
1285                 TRACE_SUSIE2("MATH CD signed conversion complete %04x to %04x",mMATHABCD.Words.CD,conv);
1286                 mMATHABCD.Words.CD=conv;
1287              } else {
1288                 mMATHCD_sign=1;
1289              }
1290           }
1291           break;
1292        case (MATHB&0xff):
1293           TRACE_SUSIE2("Poke(MATHB,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1294           mMATHABCD.Bytes.B=data;
1295           mMATHABCD.Bytes.A=0;
1296           break;
1297        case (MATHA&0xff):
1298           TRACE_SUSIE2("Poke(MATHA,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1299           mMATHABCD.Bytes.A=data;
1300           // Perform sign conversion if required
1301           if(mSPRSYS_SignedMath) {
1302              // Account for the math bug that 0x8000 is +ve & 0x0000 is -ve by subracting 1
1303              if((mMATHABCD.Words.AB-1)&0x8000) {
1304                 UWORD conv;
1305                 conv=mMATHABCD.Words.AB^0xffff;
1306                 conv++;
1307                 mMATHAB_sign=-1;
1308                 TRACE_SUSIE2("MATH AB signed conversion complete %04x to %04x",mMATHABCD.Words.AB,conv);
1309                 mMATHABCD.Words.AB=conv;
1310              } else {
1311                 mMATHAB_sign=1;
1312              }
1313           }
1314  
1315           TRACE_SUSIE2("DoMathMultiply() AB=$%04x * CD=$%04x",mMATHABCD.Words.AB,mMATHABCD.Words.CD);
1316  
1317           mSPRSYS_Mathbit=FALSE;
1318  
1319           // Multiplies with out sign or accumulate take 44 ticks to complete.
1320           // Multiplies with sign and accumulate take 54 ticks to complete.
1321           //
1322           //    AB                                    EFGH
1323           //  * CD                                  /   NP
1324           // -------                            -----------
1325           //  EFGH                                    ABCD
1326           // Accumulate in JKLM         Remainder in (JK)LM
1327           //
1328  
1329           // Basic multiply is ALWAYS unsigned, sign conversion is done later
1330           mMATHEFGH.Long=(ULONG)mMATHABCD.Words.AB*(ULONG)mMATHABCD.Words.CD;
1331  
1332           if(mSPRSYS_SignedMath) {
1333              // Add the sign bits, only >0 is +ve result
1334              mMATHEFGH_sign=mMATHAB_sign+mMATHCD_sign;
1335              if(!mMATHEFGH_sign) {
1336                 mMATHEFGH.Long^=0xffffffff;
1337                 mMATHEFGH.Long++;
1338              }
1339           }
1340  
1341           // Check overflow, if B31 has changed from 1->0 then its overflow time
1342           if(mSPRSYS_Accumulate) {
1343              TRACE_SUSIE0("DoMathMultiply() - ACCUMULATED JKLM+=EFGH");
1344              ULONG tmp=mMATHJKLM.Long+mMATHEFGH.Long;
1345              // Let sign change indicate overflow
1346              if((tmp&0x80000000)!=(mMATHJKLM.Long&0x80000000)) {
1347                 TRACE_SUSIE0("DoMathMultiply() - OVERFLOW DETECTED");
1348                 // mSPRSYS_Mathbit=TRUE;
1349              }
1350              // Save accumulated result
1351              mMATHJKLM.Long=tmp;
1352           }
1353           TRACE_SUSIE1("DoMathMultiply() Results (Multi) EFGH=$%08x",mMATHEFGH.Long);
1354           TRACE_SUSIE1("DoMathMultiply() Results (Accum) JKLM=$%08x",mMATHJKLM.Long);
1355           break;
1356  
1357        case (MATHP&0xff):
1358           mMATHNP.Bytes.P=data;
1359           mMATHNP.Bytes.N=0;
1360           TRACE_SUSIE2("Poke(MATHP,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1361           break;
1362        case (MATHN&0xff):
1363           mMATHNP.Bytes.N=data;
1364           TRACE_SUSIE2("Poke(MATHN,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1365           break;
1366  
1367        case (MATHH&0xff):
1368           mMATHEFGH.Bytes.H=data;
1369           mMATHEFGH.Bytes.G=0;
1370           TRACE_SUSIE2("Poke(MATHH,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1371           break;
1372        case (MATHG&0xff):
1373           mMATHEFGH.Bytes.G=data;
1374           TRACE_SUSIE2("Poke(MATHG,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1375           break;
1376        case (MATHF&0xff):
1377           mMATHEFGH.Bytes.F=data;
1378           mMATHEFGH.Bytes.E=0;
1379           TRACE_SUSIE2("Poke(MATHF,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1380           break;
1381        case (MATHE&0xff):
1382           mMATHEFGH.Bytes.E=data;
1383           TRACE_SUSIE2("Poke(MATHE,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1384           mSPRSYS_Mathbit=FALSE;
1385  
1386           //
1387           // Divides take 176 + 14*N ticks
1388           // (N is the number of most significant zeros in the divisor.)
1389           //
1390           //    AB                                    EFGH
1391           //  * CD                                  /   NP
1392           // -------                            -----------
1393           //  EFGH                                    ABCD
1394           // Accumulate in JKLM         Remainder in (JK)LM
1395           //
1396  
1397           // Divide is ALWAYS unsigned arithmetic...
1398           if(mMATHNP.Long) {
1399              TRACE_SUSIE0("DoMathDivide() - UNSIGNED");
1400              mMATHABCD.Long=mMATHEFGH.Long/mMATHNP.Long;
1401              mMATHJKLM.Long=mMATHEFGH.Long%mMATHNP.Long;
1402              // mSPRSYS_Mathbit=FALSE;
1403           } else {
1404              TRACE_SUSIE0("DoMathDivide() - DIVIDE BY ZERO ERROR");
1405              mMATHABCD.Long=0xffffffff;
1406              mMATHJKLM.Long=0;
1407              mSPRSYS_Mathbit=TRUE;
1408           }
1409           break;
1410  
1411        case (MATHM&0xff):
1412           mMATHJKLM.Bytes.M=data;
1413           mMATHJKLM.Bytes.L=0;
1414           mSPRSYS_Mathbit=FALSE;
1415           TRACE_SUSIE2("Poke(MATHM,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1416           break;
1417        case (MATHL&0xff):
1418           mMATHJKLM.Bytes.L=data;
1419           TRACE_SUSIE2("Poke(MATHL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1420           break;
1421        case (MATHK&0xff):
1422           mMATHJKLM.Bytes.K=data;
1423           mMATHJKLM.Bytes.J=0;
1424           TRACE_SUSIE2("Poke(MATHK,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1425           break;
1426        case (MATHJ&0xff):
1427           mMATHJKLM.Bytes.J=data;
1428           TRACE_SUSIE2("Poke(MATHJ,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1429           break;
1430  
1431        case (SPRCTL0&0xff):
1432           // mSPRCTL0_Type=data&0x0007;
1433           mSPRCTL0_Vflip=data&0x0010;
1434           mSPRCTL0_Hflip=data&0x0020;
1435           mSPRCTL0_PixelBits=((data&0x00c0)>>6)+1;
1436           TRACE_SUSIE2("Poke(SPRCTL0,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1437           break;
1438        case (SPRCTL1&0xff):
1439           mSPRCTL1_StartLeft=data&0x0001;
1440           mSPRCTL1_StartUp=data&0x0002;
1441           mSPRCTL1_SkipSprite=data&0x0004;
1442           mSPRCTL1_ReloadPalette=data&0x0008;
1443           mSPRCTL1_ReloadDepth=(data&0x0030)>>4;
1444           mSPRCTL1_Sizing=data&0x0040;
1445           mSPRCTL1_Literal=data&0x0080;
1446           TRACE_SUSIE2("Poke(SPRCTL1,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1447           break;
1448        case (SPRCOLL&0xff):
1449           mSPRCOLL_Number=data&0x000f;
1450           mSPRCOLL_Collide=data&0x0020;
1451           TRACE_SUSIE2("Poke(SPRCOLL,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1452           break;
1453        case (SPRINIT&0xff):
1454           mSPRINIT.Byte=data;
1455           TRACE_SUSIE2("Poke(SPRINIT,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1456           break;
1457        case (SUZYBUSEN&0xff):
1458           mSUZYBUSEN=data&0x01;
1459           TRACE_SUSIE2("Poke(SUZYBUSEN,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1460           break;
1461        case (SPRGO&0xff):
1462           mSPRGO=data&0x01;
1463           mEVERON=data&0x04;
1464           TRACE_SUSIE2("Poke(SPRGO,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1465           break;
1466        case (SPRSYS&0xff):
1467           mSPRSYS_StopOnCurrent=data&0x0002;
1468           if(data&0x0004) mSPRSYS_UnsafeAccess=0;
1469           mSPRSYS_LeftHand=data&0x0008;
1470           mSPRSYS_VStretch=data&0x0010;
1471           mSPRSYS_NoCollide=data&0x0020;
1472           mSPRSYS_Accumulate=data&0x0040;
1473           mSPRSYS_SignedMath=data&0x0080;
1474           TRACE_SUSIE2("Poke(SPRSYS,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1475           break;
1476  
1477           // Cartridge writing ports
1478  
1479        case (RCART0&0xff):
1480           if(mSystem.mCart->CartGetAudin() && mSystem.mMikie->SwitchAudInValue()){
1481             mSystem.mCart->Poke0A(data);
1482           }else{
1483             mSystem.mCart->Poke0(data);
1484           }
1485           mSystem.mEEPROM->ProcessEepromCounter(mSystem.mCart->GetCounterValue());
1486           TRACE_SUSIE2("Poke(RCART0,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1487           break;
1488        case (RCART1&0xff):
1489          if(mSystem.mCart->CartGetAudin() && mSystem.mMikie->SwitchAudInValue()){
1490             mSystem.mCart->Poke1A(data);
1491          }else{
1492             mSystem.mCart->Poke1(data);
1493           }
1494           mSystem.mEEPROM->ProcessEepromCounter(mSystem.mCart->GetCounterValue());
1495           TRACE_SUSIE2("Poke(RCART1,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1496           break;
1497  
1498           // These are not so important, so lets ignore them for the moment
1499  
1500        case (LEDS&0xff):
1501        case (PPORTSTAT&0xff):
1502        case (PPORTDATA&0xff):
1503        case (HOWIE&0xff):
1504           TRACE_SUSIE2("Poke(LEDS/PPORTSTST/PPORTDATA/HOWIE,%02x) at PC=$%04x",data,mSystem.mCpu->GetPC());
1505           break;
1506  
1507           // Errors on read only register accesses
1508  
1509        case (SUZYHREV&0xff):
1510        case (JOYSTICK&0xff):
1511        case (SWITCHES&0xff):
1512           TRACE_SUSIE3("Poke(%04x,%02x) - Poke to read only register location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
1513           break;
1514  
1515           // Errors on illegal location accesses
1516  
1517        default:
1518           TRACE_SUSIE3("Poke(%04x,%02x) - Poke to illegal location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
1519           break;
1520     }
1521  }
1522  
1523  UBYTE CSusie::Peek(ULONG addr)
1524  {
1525     UBYTE	retval=0;
1526     switch(addr&0xff) {
1527        case (TMPADRL&0xff):
1528           retval=mTMPADR.Byte.Low;
1529           TRACE_SUSIE2("Peek(TMPADRL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1530           return retval;
1531        case (TMPADRH&0xff):
1532           retval=mTMPADR.Byte.High;
1533           TRACE_SUSIE2("Peek(TMPADRH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1534           return retval;
1535        case (TILTACUML&0xff):
1536           retval=mTILTACUM.Byte.Low;
1537           TRACE_SUSIE2("Peek(TILTACUML)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1538           return retval;
1539        case (TILTACUMH&0xff):
1540           retval=mTILTACUM.Byte.High;
1541           TRACE_SUSIE2("Peek(TILTACUMH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1542           return retval;
1543        case (HOFFL&0xff):
1544           retval=mHOFF.Byte.Low;
1545           TRACE_SUSIE2("Peek(HOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1546           return retval;
1547        case (HOFFH&0xff):
1548           retval=mHOFF.Byte.High;
1549           TRACE_SUSIE2("Peek(HOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1550           return retval;
1551        case (VOFFL&0xff):
1552           retval=mVOFF.Byte.Low;
1553           TRACE_SUSIE2("Peek(VOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1554           return retval;
1555        case (VOFFH&0xff):
1556           retval=mVOFF.Byte.High;
1557           TRACE_SUSIE2("Peek(VOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1558           return retval;
1559        case (VIDBASL&0xff):
1560           retval=mVIDBAS.Byte.Low;
1561           TRACE_SUSIE2("Peek(VIDBASL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1562           return retval;
1563        case (VIDBASH&0xff):
1564           retval=mVIDBAS.Byte.High;
1565           TRACE_SUSIE2("Peek(VIDBASH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1566           return retval;
1567        case (COLLBASL&0xff):
1568           retval=mCOLLBAS.Byte.Low;
1569           TRACE_SUSIE2("Peek(COLLBASL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1570           return retval;
1571        case (COLLBASH&0xff):
1572           retval=mCOLLBAS.Byte.High;
1573           TRACE_SUSIE2("Peek(COLLBASH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1574           return retval;
1575        case (VIDADRL&0xff):
1576           retval=mVIDADR.Byte.Low;
1577           TRACE_SUSIE2("Peek(VIDADRL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1578           return retval;
1579        case (VIDADRH&0xff):
1580           retval=mVIDADR.Byte.High;
1581           TRACE_SUSIE2("Peek(VIDADRH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1582           return retval;
1583        case (COLLADRL&0xff):
1584           retval=mCOLLADR.Byte.Low;
1585           TRACE_SUSIE2("Peek(COLLADRL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1586           return retval;
1587        case (COLLADRH&0xff):
1588           retval=mCOLLADR.Byte.High;
1589           TRACE_SUSIE2("Peek(COLLADRH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1590           return retval;
1591        case (SCBNEXTL&0xff):
1592           retval=mSCBNEXT.Byte.Low;
1593           TRACE_SUSIE2("Peek(SCBNEXTL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1594           return retval;
1595        case (SCBNEXTH&0xff):
1596           retval=mSCBNEXT.Byte.High;
1597           TRACE_SUSIE2("Peek(SCBNEXTH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1598           return retval;
1599        case (SPRDLINEL&0xff):
1600           retval=mSPRDLINE.Byte.Low;
1601           TRACE_SUSIE2("Peek(SPRDLINEL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1602           return retval;
1603        case (SPRDLINEH&0xff):
1604           retval=mSPRDLINE.Byte.High;
1605           TRACE_SUSIE2("Peek(SPRDLINEH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1606           return retval;
1607        case (HPOSSTRTL&0xff):
1608           retval=mHPOSSTRT.Byte.Low;
1609           TRACE_SUSIE2("Peek(HPOSSTRTL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1610           return retval;
1611        case (HPOSSTRTH&0xff):
1612           retval=mHPOSSTRT.Byte.High;
1613           TRACE_SUSIE2("Peek(HPOSSTRTH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1614           return retval;
1615        case (VPOSSTRTL&0xff):
1616           retval=mVPOSSTRT.Byte.Low;
1617           TRACE_SUSIE2("Peek(VPOSSTRTL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1618           return retval;
1619        case (VPOSSTRTH&0xff):
1620           retval=mVPOSSTRT.Byte.High;
1621           TRACE_SUSIE2("Peek(VPOSSTRTH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1622           return retval;
1623        case (SPRHSIZL&0xff):
1624           retval=mSPRHSIZ.Byte.Low;
1625           TRACE_SUSIE2("Peek(SPRHSIZL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1626           return retval;
1627        case (SPRHSIZH&0xff):
1628           retval=mSPRHSIZ.Byte.High;
1629           TRACE_SUSIE2("Peek(SPRHSIZH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1630           return retval;
1631        case (SPRVSIZL&0xff):
1632           retval=mSPRVSIZ.Byte.Low;
1633           TRACE_SUSIE2("Peek(SPRVSIZL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1634           return retval;
1635        case (SPRVSIZH&0xff):
1636           retval=mSPRVSIZ.Byte.High;
1637           TRACE_SUSIE2("Peek(SPRVSIZH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1638           return retval;
1639        case (STRETCHL&0xff):
1640           retval=mSTRETCH.Byte.Low;
1641           TRACE_SUSIE2("Peek(STRETCHL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1642           return retval;
1643        case (STRETCHH&0xff):
1644           retval=mSTRETCH.Byte.High;
1645           TRACE_SUSIE2("Peek(STRETCHH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1646           return retval;
1647        case (TILTL&0xff):
1648           retval=mTILT.Byte.Low;
1649           TRACE_SUSIE2("Peek(TILTL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1650           return retval;
1651        case (TILTH&0xff):
1652           retval=mTILT.Byte.High;
1653           TRACE_SUSIE2("Peek(TILTH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1654           return retval;
1655        case (SPRDOFFL&0xff):
1656           retval=mSPRDOFF.Byte.Low;
1657           TRACE_SUSIE2("Peek(SPRDOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1658           return retval;
1659        case (SPRDOFFH&0xff):
1660           retval=mSPRDOFF.Byte.High;
1661           TRACE_SUSIE2("Peek(SPRDOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1662           return retval;
1663        case (SPRVPOSL&0xff):
1664           retval=mSPRVPOS.Byte.Low;
1665           TRACE_SUSIE2("Peek(SPRVPOSL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1666           return retval;
1667        case (SPRVPOSH&0xff):
1668           retval=mSPRVPOS.Byte.High;
1669           TRACE_SUSIE2("Peek(SPRVPOSH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1670           return retval;
1671        case (COLLOFFL&0xff):
1672           retval=mCOLLOFF.Byte.Low;
1673           TRACE_SUSIE2("Peek(COLLOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1674           return retval;
1675        case (COLLOFFH&0xff):
1676           retval=mCOLLOFF.Byte.High;
1677           TRACE_SUSIE2("Peek(COLLOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1678           return retval;
1679        case (VSIZACUML&0xff):
1680           retval=mVSIZACUM.Byte.Low;
1681           TRACE_SUSIE2("Peek(VSIZACUML)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1682           return retval;
1683        case (VSIZACUMH&0xff):
1684           retval=mVSIZACUM.Byte.High;
1685           TRACE_SUSIE2("Peek(VSIZACUMH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1686           return retval;
1687        case (HSIZOFFL&0xff):
1688           retval=mHSIZOFF.Byte.Low;
1689           TRACE_SUSIE2("Peek(HSIZOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1690           return retval;
1691        case (HSIZOFFH&0xff):
1692           retval=mHSIZOFF.Byte.High;
1693           TRACE_SUSIE2("Peek(HSIZOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1694           return retval;
1695        case (VSIZOFFL&0xff):
1696           retval=mVSIZOFF.Byte.Low;
1697           TRACE_SUSIE2("Peek(VSIZOFFL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1698           return retval;
1699        case (VSIZOFFH&0xff):
1700           retval=mVSIZOFF.Byte.High;
1701           TRACE_SUSIE2("Peek(VSIZOFFH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1702           return retval;
1703        case (SCBADRL&0xff):
1704           retval=mSCBADR.Byte.Low;
1705           TRACE_SUSIE2("Peek(SCBADRL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1706           return retval;
1707        case (SCBADRH&0xff):
1708           retval=mSCBADR.Byte.High;
1709           TRACE_SUSIE2("Peek(SCBADRH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1710           return retval;
1711        case (PROCADRL&0xff):
1712           retval=mPROCADR.Byte.Low;
1713           TRACE_SUSIE2("Peek(PROCADRL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1714           return retval;
1715        case (PROCADRH&0xff):
1716           retval=mPROCADR.Byte.High;
1717           TRACE_SUSIE2("Peek(PROCADRH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1718           return retval;
1719        case (MATHD&0xff):
1720           retval=mMATHABCD.Bytes.D;
1721           TRACE_SUSIE2("Peek(MATHD)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1722           return retval;
1723        case (MATHC&0xff):
1724           retval=mMATHABCD.Bytes.C;
1725           TRACE_SUSIE2("Peek(MATHC)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1726           return retval;
1727        case (MATHB&0xff):
1728           retval=mMATHABCD.Bytes.B;
1729           TRACE_SUSIE2("Peek(MATHB)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1730           return retval;
1731        case (MATHA&0xff):
1732           retval=mMATHABCD.Bytes.A;
1733           TRACE_SUSIE2("Peek(MATHA)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1734           return retval;
1735  
1736        case (MATHP&0xff):
1737           retval=mMATHNP.Bytes.P;
1738           TRACE_SUSIE2("Peek(MATHP)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1739           return retval;
1740        case (MATHN&0xff):
1741           retval=mMATHNP.Bytes.N;
1742           TRACE_SUSIE2("Peek(MATHN)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1743           return retval;
1744  
1745        case (MATHH&0xff):
1746           retval=mMATHEFGH.Bytes.H;
1747           TRACE_SUSIE2("Peek(MATHH)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1748           return retval;
1749        case (MATHG&0xff):
1750           retval=mMATHEFGH.Bytes.G;
1751           TRACE_SUSIE2("Peek(MATHG)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1752           return retval;
1753        case (MATHF&0xff):
1754           retval=mMATHEFGH.Bytes.F;
1755           TRACE_SUSIE2("Peek(MATHF)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1756           return retval;
1757        case (MATHE&0xff):
1758           retval=mMATHEFGH.Bytes.E;
1759           TRACE_SUSIE2("Peek(MATHE)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1760           return retval;
1761        case (MATHM&0xff):
1762           retval=mMATHJKLM.Bytes.M;
1763           TRACE_SUSIE2("Peek(MATHM)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1764           return retval;
1765        case (MATHL&0xff):
1766           retval=mMATHJKLM.Bytes.L;
1767           TRACE_SUSIE2("Peek(MATHL)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1768           return retval;
1769        case (MATHK&0xff):
1770           retval=mMATHJKLM.Bytes.K;
1771           TRACE_SUSIE2("Peek(MATHK)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1772           return retval;
1773        case (MATHJ&0xff):
1774           retval=mMATHJKLM.Bytes.J;
1775           TRACE_SUSIE2("Peek(MATHJ)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1776           return retval;
1777        case (SUZYHREV&0xff):
1778           retval=0x01;
1779           TRACE_SUSIE2("Peek(SUZYHREV)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1780           return retval;
1781  
1782        case (SPRSYS&0xff):
1783           retval=0x0000;
1784           //	retval+=(mSPRSYS_Status)?0x0001:0x0000;
1785           // Use gSystemCPUSleep to signal the status instead, if we are asleep then
1786           // we must be rendering sprites
1787           retval+=(gSystemCPUSleep)?0x0001:0x0000;
1788           retval+=(mSPRSYS_StopOnCurrent)?0x0002:0x0000;
1789           retval+=(mSPRSYS_UnsafeAccess)?0x0004:0x0000;
1790           retval+=(mSPRSYS_LeftHand)?0x0008:0x0000;
1791           retval+=(mSPRSYS_VStretch)?0x0010:0x0000;
1792           retval+=(mSPRSYS_LastCarry)?0x0020:0x0000;
1793           retval+=(mSPRSYS_Mathbit)?0x0040:0x0000;
1794           retval+=(mSPRSYS_MathInProgress)?0x0080:0x0000;
1795           TRACE_SUSIE2("Peek(SPRSYS)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1796           return retval;
1797  
1798        case (JOYSTICK&0xff):
1799           if(mSPRSYS_LeftHand) {
1800              retval= mJOYSTICK.Byte;
1801           } else {
1802              TJOYSTICK Modified=mJOYSTICK;
1803              Modified.Bits.Left=mJOYSTICK.Bits.Right;
1804              Modified.Bits.Right=mJOYSTICK.Bits.Left;
1805              Modified.Bits.Down=mJOYSTICK.Bits.Up;
1806              Modified.Bits.Up=mJOYSTICK.Bits.Down;
1807              retval= Modified.Byte;
1808           }
1809           //			TRACE_SUSIE2("Peek(JOYSTICK)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1810           return retval;
1811  
1812        case (SWITCHES&0xff):
1813           retval=mSWITCHES.Byte;
1814           //			TRACE_SUSIE2("Peek(SWITCHES)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1815           return retval;
1816  
1817           // Cartridge reading ports
1818  
1819        case (RCART0&0xff):
1820           if(mSystem.mCart->CartGetAudin() && mSystem.mMikie->SwitchAudInValue()){
1821              retval=mSystem.mCart->Peek0A();
1822           }else{
1823              retval=mSystem.mCart->Peek0();
1824           }
1825           mSystem.mEEPROM->ProcessEepromCounter(mSystem.mCart->GetCounterValue());
1826           //			TRACE_SUSIE2("Peek(RCART0)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1827           return retval;
1828        case (RCART1&0xff):
1829           if(mSystem.mCart->CartGetAudin() && mSystem.mMikie->SwitchAudInValue()){
1830              retval=mSystem.mCart->Peek1A();
1831           }else{
1832             retval=mSystem.mCart->Peek1();
1833           }
1834           mSystem.mEEPROM->ProcessEepromCounter(mSystem.mCart->GetCounterValue());
1835           //			TRACE_SUSIE2("Peek(RCART1)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC());
1836           return retval;
1837  
1838           // These are no so important so lets ignore them for the moment
1839  
1840        case (LEDS&0xff):
1841        case (PPORTSTAT&0xff):
1842        case (PPORTDATA&0xff):
1843        case (HOWIE&0xff):
1844           TRACE_SUSIE1("Peek(LEDS/PPORTSTAT/PPORTDATA) at PC=$%04x",mSystem.mCpu->GetPC());
1845           break;
1846  
1847           // Errors on write only register accesses
1848  
1849        case (SPRCTL0&0xff):
1850        case (SPRCTL1&0xff):
1851        case (SPRCOLL&0xff):
1852        case (SPRINIT&0xff):
1853        case (SUZYBUSEN&0xff):
1854        case (SPRGO&0xff):
1855           TRACE_SUSIE2("Peek(%04x) - Peek from write only register location at PC=$%04x",addr,mSystem.mCpu->GetPC());
1856           break;
1857  
1858           // Errors on illegal location accesses
1859  
1860        default:
1861           TRACE_SUSIE2("Peek(%04x) - Peek from illegal location at PC=$%04x",addr,mSystem.mCpu->GetPC());
1862           break;
1863     }
1864  
1865     return 0xff;
1866  }