mikie.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  // Mikey chip emulation class                                               //
  29  //////////////////////////////////////////////////////////////////////////////
  30  //                                                                          //
  31  // This class emulates all of the Mikey hardware with the exception of the  //
  32  // CPU and memory selector. Update() does most of the work and does screen  //
  33  // DMA and counter updates, it also schecules in which cycle the next timer //
  34  // update will occur so that the CSystem->Update() doesn't have to call it  //
  35  // every cycle, massive speedup but big complexity headache.                //
  36  //                                                                          //
  37  //    K. Wilkins                                                            //
  38  // August 1997                                                              //
  39  //                                                                          //
  40  //////////////////////////////////////////////////////////////////////////////
  41  // Revision History:                                                        //
  42  // -----------------                                                        //
  43  //                                                                          //
  44  // 01Aug1997 KW Document header added & class documented.                   //
  45  //                                                                          //
  46  //////////////////////////////////////////////////////////////////////////////
  47  
  48  //#define	TRACE_MIKIE
  49  
  50  #include <stdio.h>
  51  #include <stdlib.h>
  52  #include <string.h>
  53  #include "system.h"
  54  #include "mikie.h"
  55  #include "lynxdef.h"
  56  
  57  static inline ULONG GetLfsrNext(ULONG current)
  58  {
  59     // The table is built thus:
  60     //	Bits 0-11  LFSR					(12 Bits)
  61     //  Bits 12-20 Feedback switches	(9 Bits)
  62     //     (Order = 7,0,1,2,3,4,5,10,11)
  63     //  Order is mangled to make peek/poke easier as
  64     //  bit 7 is in a separate register
  65     //
  66     // Total 21 bits = 2MWords @ 4 Bytes/Word = 8MB !!!!!
  67     //
  68     // If the index is a combination of Current LFSR+Feedback the
  69     // table will give the next value.
  70  #if 0
  71     ULONG result = 0;
  72     if (current & (1<<12)) result ^= (current>>7)&1;
  73     if (current & (1<<13)) result ^= (current>>0)&1;
  74     if (current & (1<<14)) result ^= (current>>1)&1;
  75     if (current & (1<<15)) result ^= (current>>2)&1;
  76     if (current & (1<<16)) result ^= (current>>3)&1;
  77     if (current & (1<<17)) result ^= (current>>4)&1;
  78     if (current & (1<<18)) result ^= (current>>5)&1;
  79     if (current & (1<<19)) result ^= (current>>10)&1;
  80     if (current & (1<<20)) result ^= (current>>11)&1;
  81     return (current&0xFFFFF000) | ((current<<1)&0xFFE) | (result?0:1);
  82  #else
  83  
  84     static ULONG switches,lfsr,next,swloop,result;
  85     static const ULONG switchbits[9]={7,0,1,2,3,4,5,10,11};
  86  
  87     switches=current>>12;
  88     lfsr=current&0xfff;
  89     result=0;
  90     for(swloop=0;swloop<9;swloop++) {
  91        if((switches>>swloop)&0x001) result^=(lfsr>>switchbits[swloop])&0x001;
  92     }
  93     result=(result)?0:1;
  94     next=(switches<<12)|((lfsr<<1)&0xffe)|result;
  95     return next;
  96  #endif
  97  }
  98  
  99  
 100  CMikie::CMikie(CSystem& parent, ULONG displayformat, ULONG samplerate)
 101  :mSystem(parent)
 102  {
 103     TRACE_MIKIE0("CMikie()");
 104  
 105     mpDisplayCurrent=NULL;
 106     mpRamPointer=NULL;
 107     mDisplayFormat=displayformat;
 108     mAudioSampleRate=samplerate;
 109     mDisplayPitch=OUTPUT_SCREEN_STRIDE * sizeof(HandyPixel);
 110  
 111     mUART_CABLE_PRESENT=FALSE;
 112     mpUART_TX_CALLBACK=NULL;
 113  
 114     BuildPalette();
 115     Reset();
 116  }
 117  
 118  CMikie::~CMikie()
 119  {
 120     TRACE_MIKIE0("~CMikie()");
 121  }
 122  
 123  
 124  void CMikie::Reset(void)
 125  {
 126     TRACE_MIKIE0("Reset()");
 127  
 128     mAudioInputComparator=FALSE;	// Initialises to unknown
 129     mDisplayAddress=0x00;			// Initialises to unknown
 130     mLynxLine=0;
 131     mLynxLineDMACounter=0;
 132     mLynxAddr=0;
 133  
 134     mTimerStatusFlags=0x00;		// Initialises to ZERO, i.e No IRQ's
 135     mTimerInterruptMask=0x00;
 136  
 137     mpRamPointer=mSystem.GetRamPointer();	// Fetch pointer to system RAM
 138  
 139     mTIM_0_BKUP=0;
 140     mTIM_0_ENABLE_RELOAD=0;
 141     mTIM_0_ENABLE_COUNT=0;
 142     mTIM_0_LINKING=0;
 143     mTIM_0_CURRENT=0;
 144     mTIM_0_TIMER_DONE=0;
 145     mTIM_0_LAST_CLOCK=0;
 146     mTIM_0_BORROW_IN=0;
 147     mTIM_0_BORROW_OUT=0;
 148     mTIM_0_LAST_LINK_CARRY=0;
 149     mTIM_0_LAST_COUNT=0;
 150  
 151     mTIM_1_BKUP=0;
 152     mTIM_1_ENABLE_RELOAD=0;
 153     mTIM_1_ENABLE_COUNT=0;
 154     mTIM_1_LINKING=0;
 155     mTIM_1_CURRENT=0;
 156     mTIM_1_TIMER_DONE=0;
 157     mTIM_1_LAST_CLOCK=0;
 158     mTIM_1_BORROW_IN=0;
 159     mTIM_1_BORROW_OUT=0;
 160     mTIM_1_LAST_LINK_CARRY=0;
 161     mTIM_1_LAST_COUNT=0;
 162  
 163     mTIM_2_BKUP=0;
 164     mTIM_2_ENABLE_RELOAD=0;
 165     mTIM_2_ENABLE_COUNT=0;
 166     mTIM_2_LINKING=0;
 167     mTIM_2_CURRENT=0;
 168     mTIM_2_TIMER_DONE=0;
 169     mTIM_2_LAST_CLOCK=0;
 170     mTIM_2_BORROW_IN=0;
 171     mTIM_2_BORROW_OUT=0;
 172     mTIM_2_LAST_LINK_CARRY=0;
 173     mTIM_2_LAST_COUNT=0;
 174  
 175     mTIM_3_BKUP=0;
 176     mTIM_3_ENABLE_RELOAD=0;
 177     mTIM_3_ENABLE_COUNT=0;
 178     mTIM_3_LINKING=0;
 179     mTIM_3_CURRENT=0;
 180     mTIM_3_TIMER_DONE=0;
 181     mTIM_3_LAST_CLOCK=0;
 182     mTIM_3_BORROW_IN=0;
 183     mTIM_3_BORROW_OUT=0;
 184     mTIM_3_LAST_LINK_CARRY=0;
 185     mTIM_3_LAST_COUNT=0;
 186  
 187     mTIM_4_BKUP=0;
 188     mTIM_4_ENABLE_RELOAD=0;
 189     mTIM_4_ENABLE_COUNT=0;
 190     mTIM_4_LINKING=0;
 191     mTIM_4_CURRENT=0;
 192     mTIM_4_TIMER_DONE=0;
 193     mTIM_4_LAST_CLOCK=0;
 194     mTIM_4_BORROW_IN=0;
 195     mTIM_4_BORROW_OUT=0;
 196     mTIM_4_LAST_LINK_CARRY=0;
 197     mTIM_4_LAST_COUNT=0;
 198  
 199     mTIM_5_BKUP=0;
 200     mTIM_5_ENABLE_RELOAD=0;
 201     mTIM_5_ENABLE_COUNT=0;
 202     mTIM_5_LINKING=0;
 203     mTIM_5_CURRENT=0;
 204     mTIM_5_TIMER_DONE=0;
 205     mTIM_5_LAST_CLOCK=0;
 206     mTIM_5_BORROW_IN=0;
 207     mTIM_5_BORROW_OUT=0;
 208     mTIM_5_LAST_LINK_CARRY=0;
 209     mTIM_5_LAST_COUNT=0;
 210  
 211     mTIM_6_BKUP=0;
 212     mTIM_6_ENABLE_RELOAD=0;
 213     mTIM_6_ENABLE_COUNT=0;
 214     mTIM_6_LINKING=0;
 215     mTIM_6_CURRENT=0;
 216     mTIM_6_TIMER_DONE=0;
 217     mTIM_6_LAST_CLOCK=0;
 218     mTIM_6_BORROW_IN=0;
 219     mTIM_6_BORROW_OUT=0;
 220     mTIM_6_LAST_LINK_CARRY=0;
 221     mTIM_6_LAST_COUNT=0;
 222  
 223     mTIM_7_BKUP=0;
 224     mTIM_7_ENABLE_RELOAD=0;
 225     mTIM_7_ENABLE_COUNT=0;
 226     mTIM_7_LINKING=0;
 227     mTIM_7_CURRENT=0;
 228     mTIM_7_TIMER_DONE=0;
 229     mTIM_7_LAST_CLOCK=0;
 230     mTIM_7_BORROW_IN=0;
 231     mTIM_7_BORROW_OUT=0;
 232     mTIM_7_LAST_LINK_CARRY=0;
 233     mTIM_7_LAST_COUNT=0;
 234  
 235     mAUDIO_0_BKUP=0;
 236     mAUDIO_0_ENABLE_RELOAD=0;
 237     mAUDIO_0_ENABLE_COUNT=0;
 238     mAUDIO_0_LINKING=0;
 239     mAUDIO_0_CURRENT=0;
 240     mAUDIO_0_TIMER_DONE=0;
 241     mAUDIO_0_LAST_CLOCK=0;
 242     mAUDIO_0_BORROW_IN=0;
 243     mAUDIO_0_BORROW_OUT=0;
 244     mAUDIO_0_LAST_LINK_CARRY=0;
 245     mAUDIO_0_LAST_COUNT=0;
 246     mAUDIO_0_VOLUME=0;
 247     mAUDIO_OUTPUT[0]=0;
 248     mAUDIO_0_INTEGRATE_ENABLE=0;
 249     mAUDIO_0_WAVESHAPER=0;
 250  
 251     mAUDIO_1_BKUP=0;
 252     mAUDIO_1_ENABLE_RELOAD=0;
 253     mAUDIO_1_ENABLE_COUNT=0;
 254     mAUDIO_1_LINKING=0;
 255     mAUDIO_1_CURRENT=0;
 256     mAUDIO_1_TIMER_DONE=0;
 257     mAUDIO_1_LAST_CLOCK=0;
 258     mAUDIO_1_BORROW_IN=0;
 259     mAUDIO_1_BORROW_OUT=0;
 260     mAUDIO_1_LAST_LINK_CARRY=0;
 261     mAUDIO_1_LAST_COUNT=0;
 262     mAUDIO_1_VOLUME=0;
 263     mAUDIO_OUTPUT[1]=0;
 264     mAUDIO_1_INTEGRATE_ENABLE=0;
 265     mAUDIO_1_WAVESHAPER=0;
 266  
 267     mAUDIO_2_BKUP=0;
 268     mAUDIO_2_ENABLE_RELOAD=0;
 269     mAUDIO_2_ENABLE_COUNT=0;
 270     mAUDIO_2_LINKING=0;
 271     mAUDIO_2_CURRENT=0;
 272     mAUDIO_2_TIMER_DONE=0;
 273     mAUDIO_2_LAST_CLOCK=0;
 274     mAUDIO_2_BORROW_IN=0;
 275     mAUDIO_2_BORROW_OUT=0;
 276     mAUDIO_2_LAST_LINK_CARRY=0;
 277     mAUDIO_2_LAST_COUNT=0;
 278     mAUDIO_2_VOLUME=0;
 279     mAUDIO_OUTPUT[2]=0;
 280     mAUDIO_2_INTEGRATE_ENABLE=0;
 281     mAUDIO_2_WAVESHAPER=0;
 282  
 283     mAUDIO_3_BKUP=0;
 284     mAUDIO_3_ENABLE_RELOAD=0;
 285     mAUDIO_3_ENABLE_COUNT=0;
 286     mAUDIO_3_LINKING=0;
 287     mAUDIO_3_CURRENT=0;
 288     mAUDIO_3_TIMER_DONE=0;
 289     mAUDIO_3_LAST_CLOCK=0;
 290     mAUDIO_3_BORROW_IN=0;
 291     mAUDIO_3_BORROW_OUT=0;
 292     mAUDIO_3_LAST_LINK_CARRY=0;
 293     mAUDIO_3_LAST_COUNT=0;
 294     mAUDIO_3_VOLUME=0;
 295     mAUDIO_OUTPUT[3]=0;
 296     mAUDIO_3_INTEGRATE_ENABLE=0;
 297     mAUDIO_3_WAVESHAPER=0;
 298  
 299     mSTEREO=0x00;	// xored! All channels enabled
 300     mPAN=0x00;      // all channels panning OFF
 301     mAUDIO_ATTEN[0]=0xff; // Full volume
 302     mAUDIO_ATTEN[1]=0xff;
 303     mAUDIO_ATTEN[2]=0xff;
 304     mAUDIO_ATTEN[3]=0xff;
 305  
 306     // Start with an empty palette
 307  
 308     for(int loop=0;loop<16;loop++) {
 309        mPalette[loop].Index=loop;
 310     }
 311  
 312     // Initialise IODAT register
 313  
 314     mIODAT=0x00;
 315     mIODIR=0x00;
 316     mIODAT_REST_SIGNAL=0x00;
 317  
 318     //
 319     // Initialise display control register vars
 320     //
 321     mDISPCTL_DMAEnable=FALSE;
 322     mDISPCTL_Flip=FALSE;
 323     mDISPCTL_FourColour=0;
 324     mDISPCTL_Colour=0;
 325  
 326     //
 327     // Initialise the UART variables
 328     //
 329     mUART_RX_IRQ_ENABLE=0;
 330     mUART_TX_IRQ_ENABLE=0;
 331  
 332     mUART_TX_COUNTDOWN=UART_TX_INACTIVE;
 333     mUART_RX_COUNTDOWN=UART_RX_INACTIVE;
 334  
 335     mUART_Rx_input_ptr=0;
 336     mUART_Rx_output_ptr=0;
 337     mUART_Rx_waiting=0;
 338     mUART_Rx_framing_error=0;
 339     mUART_Rx_overun_error=0;
 340  
 341     mUART_SENDBREAK=0;
 342     mUART_TX_DATA=0;
 343     mUART_RX_DATA=0;
 344     mUART_RX_READY=0;
 345  
 346     mUART_PARITY_ENABLE=0;
 347     mUART_PARITY_EVEN=0;
 348  
 349     ResetDisplayPtr();
 350  }
 351  
 352  
 353  bool CMikie::ContextSave(LSS_FILE *fp)
 354  {
 355     TRACE_MIKIE0("ContextSave()");
 356  
 357     if(!lss_printf(fp,"CMikie::ContextSave")) return 0;
 358  
 359     if(!lss_write(&mDisplayAddress,sizeof(ULONG),1,fp)) return 0;
 360     if(!lss_write(&mAudioInputComparator,sizeof(ULONG),1,fp)) return 0;
 361     if(!lss_write(&mTimerStatusFlags,sizeof(ULONG),1,fp)) return 0;
 362     if(!lss_write(&mTimerInterruptMask,sizeof(ULONG),1,fp)) return 0;
 363  
 364     if(!lss_write(mPalette,sizeof(TPALETTE),16,fp)) return 0;
 365  
 366     if(!lss_write(&mIODAT,sizeof(ULONG),1,fp)) return 0;
 367     if(!lss_write(&mIODAT_REST_SIGNAL,sizeof(ULONG),1,fp)) return 0;
 368     if(!lss_write(&mIODIR,sizeof(ULONG),1,fp)) return 0;
 369  
 370     if(!lss_write(&mDISPCTL_DMAEnable,sizeof(ULONG),1,fp)) return 0;
 371     if(!lss_write(&mDISPCTL_Flip,sizeof(ULONG),1,fp)) return 0;
 372     if(!lss_write(&mDISPCTL_FourColour,sizeof(ULONG),1,fp)) return 0;
 373     if(!lss_write(&mDISPCTL_Colour,sizeof(ULONG),1,fp)) return 0;
 374  
 375     if(!lss_write(&mTIM_0_BKUP,sizeof(ULONG),1,fp)) return 0;
 376     if(!lss_write(&mTIM_0_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 377     if(!lss_write(&mTIM_0_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 378     if(!lss_write(&mTIM_0_LINKING,sizeof(ULONG),1,fp)) return 0;
 379     if(!lss_write(&mTIM_0_CURRENT,sizeof(ULONG),1,fp)) return 0;
 380     if(!lss_write(&mTIM_0_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 381     if(!lss_write(&mTIM_0_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 382     if(!lss_write(&mTIM_0_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 383     if(!lss_write(&mTIM_0_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 384     if(!lss_write(&mTIM_0_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 385     if(!lss_write(&mTIM_0_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 386  
 387     if(!lss_write(&mTIM_1_BKUP,sizeof(ULONG),1,fp)) return 0;
 388     if(!lss_write(&mTIM_1_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 389     if(!lss_write(&mTIM_1_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 390     if(!lss_write(&mTIM_1_LINKING,sizeof(ULONG),1,fp)) return 0;
 391     if(!lss_write(&mTIM_1_CURRENT,sizeof(ULONG),1,fp)) return 0;
 392     if(!lss_write(&mTIM_1_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 393     if(!lss_write(&mTIM_1_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 394     if(!lss_write(&mTIM_1_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 395     if(!lss_write(&mTIM_1_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 396     if(!lss_write(&mTIM_1_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 397     if(!lss_write(&mTIM_1_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 398  
 399     if(!lss_write(&mTIM_2_BKUP,sizeof(ULONG),1,fp)) return 0;
 400     if(!lss_write(&mTIM_2_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 401     if(!lss_write(&mTIM_2_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 402     if(!lss_write(&mTIM_2_LINKING,sizeof(ULONG),1,fp)) return 0;
 403     if(!lss_write(&mTIM_2_CURRENT,sizeof(ULONG),1,fp)) return 0;
 404     if(!lss_write(&mTIM_2_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 405     if(!lss_write(&mTIM_2_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 406     if(!lss_write(&mTIM_2_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 407     if(!lss_write(&mTIM_2_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 408     if(!lss_write(&mTIM_2_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 409     if(!lss_write(&mTIM_2_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 410  
 411     if(!lss_write(&mTIM_3_BKUP,sizeof(ULONG),1,fp)) return 0;
 412     if(!lss_write(&mTIM_3_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 413     if(!lss_write(&mTIM_3_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 414     if(!lss_write(&mTIM_3_LINKING,sizeof(ULONG),1,fp)) return 0;
 415     if(!lss_write(&mTIM_3_CURRENT,sizeof(ULONG),1,fp)) return 0;
 416     if(!lss_write(&mTIM_3_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 417     if(!lss_write(&mTIM_3_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 418     if(!lss_write(&mTIM_3_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 419     if(!lss_write(&mTIM_3_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 420     if(!lss_write(&mTIM_3_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 421     if(!lss_write(&mTIM_3_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 422  
 423     if(!lss_write(&mTIM_4_BKUP,sizeof(ULONG),1,fp)) return 0;
 424     if(!lss_write(&mTIM_4_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 425     if(!lss_write(&mTIM_4_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 426     if(!lss_write(&mTIM_4_LINKING,sizeof(ULONG),1,fp)) return 0;
 427     if(!lss_write(&mTIM_4_CURRENT,sizeof(ULONG),1,fp)) return 0;
 428     if(!lss_write(&mTIM_4_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 429     if(!lss_write(&mTIM_4_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 430     if(!lss_write(&mTIM_4_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 431     if(!lss_write(&mTIM_4_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 432     if(!lss_write(&mTIM_4_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 433     if(!lss_write(&mTIM_4_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 434  
 435     if(!lss_write(&mTIM_5_BKUP,sizeof(ULONG),1,fp)) return 0;
 436     if(!lss_write(&mTIM_5_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 437     if(!lss_write(&mTIM_5_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 438     if(!lss_write(&mTIM_5_LINKING,sizeof(ULONG),1,fp)) return 0;
 439     if(!lss_write(&mTIM_5_CURRENT,sizeof(ULONG),1,fp)) return 0;
 440     if(!lss_write(&mTIM_5_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 441     if(!lss_write(&mTIM_5_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 442     if(!lss_write(&mTIM_5_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 443     if(!lss_write(&mTIM_5_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 444     if(!lss_write(&mTIM_5_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 445     if(!lss_write(&mTIM_5_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 446  
 447     if(!lss_write(&mTIM_6_BKUP,sizeof(ULONG),1,fp)) return 0;
 448     if(!lss_write(&mTIM_6_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 449     if(!lss_write(&mTIM_6_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 450     if(!lss_write(&mTIM_6_LINKING,sizeof(ULONG),1,fp)) return 0;
 451     if(!lss_write(&mTIM_6_CURRENT,sizeof(ULONG),1,fp)) return 0;
 452     if(!lss_write(&mTIM_6_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 453     if(!lss_write(&mTIM_6_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 454     if(!lss_write(&mTIM_6_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 455     if(!lss_write(&mTIM_6_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 456     if(!lss_write(&mTIM_6_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 457     if(!lss_write(&mTIM_6_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 458  
 459     if(!lss_write(&mTIM_7_BKUP,sizeof(ULONG),1,fp)) return 0;
 460     if(!lss_write(&mTIM_7_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 461     if(!lss_write(&mTIM_7_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 462     if(!lss_write(&mTIM_7_LINKING,sizeof(ULONG),1,fp)) return 0;
 463     if(!lss_write(&mTIM_7_CURRENT,sizeof(ULONG),1,fp)) return 0;
 464     if(!lss_write(&mTIM_7_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 465     if(!lss_write(&mTIM_7_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 466     if(!lss_write(&mTIM_7_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 467     if(!lss_write(&mTIM_7_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 468     if(!lss_write(&mTIM_7_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 469     if(!lss_write(&mTIM_7_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 470  
 471     if(!lss_write(&mAUDIO_0_BKUP,sizeof(ULONG),1,fp)) return 0;
 472     if(!lss_write(&mAUDIO_0_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 473     if(!lss_write(&mAUDIO_0_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 474     if(!lss_write(&mAUDIO_0_LINKING,sizeof(ULONG),1,fp)) return 0;
 475     if(!lss_write(&mAUDIO_0_CURRENT,sizeof(ULONG),1,fp)) return 0;
 476     if(!lss_write(&mAUDIO_0_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 477     if(!lss_write(&mAUDIO_0_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 478     if(!lss_write(&mAUDIO_0_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 479     if(!lss_write(&mAUDIO_0_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 480     if(!lss_write(&mAUDIO_0_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 481     if(!lss_write(&mAUDIO_0_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 482     if(!lss_write(&mAUDIO_0_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 483     if(!lss_write(&mAUDIO_OUTPUT[0],sizeof(SBYTE),1,fp)) return 0;
 484     if(!lss_write(&mAUDIO_0_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 485     if(!lss_write(&mAUDIO_0_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 486  
 487     if(!lss_write(&mAUDIO_1_BKUP,sizeof(ULONG),1,fp)) return 0;
 488     if(!lss_write(&mAUDIO_1_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 489     if(!lss_write(&mAUDIO_1_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 490     if(!lss_write(&mAUDIO_1_LINKING,sizeof(ULONG),1,fp)) return 0;
 491     if(!lss_write(&mAUDIO_1_CURRENT,sizeof(ULONG),1,fp)) return 0;
 492     if(!lss_write(&mAUDIO_1_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 493     if(!lss_write(&mAUDIO_1_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 494     if(!lss_write(&mAUDIO_1_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 495     if(!lss_write(&mAUDIO_1_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 496     if(!lss_write(&mAUDIO_1_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 497     if(!lss_write(&mAUDIO_1_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 498     if(!lss_write(&mAUDIO_1_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 499     if(!lss_write(&mAUDIO_OUTPUT[1],sizeof(SBYTE),1,fp)) return 0;
 500     if(!lss_write(&mAUDIO_1_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 501     if(!lss_write(&mAUDIO_1_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 502  
 503     if(!lss_write(&mAUDIO_2_BKUP,sizeof(ULONG),1,fp)) return 0;
 504     if(!lss_write(&mAUDIO_2_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 505     if(!lss_write(&mAUDIO_2_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 506     if(!lss_write(&mAUDIO_2_LINKING,sizeof(ULONG),1,fp)) return 0;
 507     if(!lss_write(&mAUDIO_2_CURRENT,sizeof(ULONG),1,fp)) return 0;
 508     if(!lss_write(&mAUDIO_2_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 509     if(!lss_write(&mAUDIO_2_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 510     if(!lss_write(&mAUDIO_2_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 511     if(!lss_write(&mAUDIO_2_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 512     if(!lss_write(&mAUDIO_2_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 513     if(!lss_write(&mAUDIO_2_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 514     if(!lss_write(&mAUDIO_2_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 515     if(!lss_write(&mAUDIO_OUTPUT[2],sizeof(SBYTE),1,fp)) return 0;
 516     if(!lss_write(&mAUDIO_2_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 517     if(!lss_write(&mAUDIO_2_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 518  
 519     if(!lss_write(&mAUDIO_3_BKUP,sizeof(ULONG),1,fp)) return 0;
 520     if(!lss_write(&mAUDIO_3_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 521     if(!lss_write(&mAUDIO_3_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 522     if(!lss_write(&mAUDIO_3_LINKING,sizeof(ULONG),1,fp)) return 0;
 523     if(!lss_write(&mAUDIO_3_CURRENT,sizeof(ULONG),1,fp)) return 0;
 524     if(!lss_write(&mAUDIO_3_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 525     if(!lss_write(&mAUDIO_3_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 526     if(!lss_write(&mAUDIO_3_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 527     if(!lss_write(&mAUDIO_3_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 528     if(!lss_write(&mAUDIO_3_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 529     if(!lss_write(&mAUDIO_3_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 530     if(!lss_write(&mAUDIO_3_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 531     if(!lss_write(&mAUDIO_OUTPUT[3],sizeof(SBYTE),1,fp)) return 0;
 532     if(!lss_write(&mAUDIO_3_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 533     if(!lss_write(&mAUDIO_3_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 534  
 535     if(!lss_write(&mSTEREO,sizeof(ULONG),1,fp)) return 0;
 536  
 537     //
 538     // Serial related variables
 539     //
 540     if(!lss_write(&mUART_RX_IRQ_ENABLE,sizeof(ULONG),1,fp)) return 0;
 541     if(!lss_write(&mUART_TX_IRQ_ENABLE,sizeof(ULONG),1,fp)) return 0;
 542  
 543     if(!lss_write(&mUART_TX_COUNTDOWN,sizeof(ULONG),1,fp)) return 0;
 544     if(!lss_write(&mUART_RX_COUNTDOWN,sizeof(ULONG),1,fp)) return 0;
 545  
 546     if(!lss_write(&mUART_SENDBREAK,sizeof(ULONG),1,fp)) return 0;
 547     if(!lss_write(&mUART_TX_DATA,sizeof(ULONG),1,fp)) return 0;
 548     if(!lss_write(&mUART_RX_DATA,sizeof(ULONG),1,fp)) return 0;
 549     if(!lss_write(&mUART_RX_READY,sizeof(ULONG),1,fp)) return 0;
 550  
 551     if(!lss_write(&mUART_PARITY_ENABLE,sizeof(ULONG),1,fp)) return 0;
 552     if(!lss_write(&mUART_PARITY_EVEN,sizeof(ULONG),1,fp)) return 0;
 553  
 554     return 1;
 555  }
 556  
 557  bool CMikie::ContextLoad(LSS_FILE *fp)
 558  {
 559     TRACE_MIKIE0("ContextLoad()");
 560  
 561     char teststr[32]="XXXXXXXXXXXXXXXXXXX";
 562     if(!lss_read(teststr,sizeof(char),19,fp)) return 0;
 563     if(strcmp(teststr,"CMikie::ContextSave")!=0) return 0;
 564  
 565     if(!lss_read(&mDisplayAddress,sizeof(ULONG),1,fp)) return 0;
 566     if(!lss_read(&mAudioInputComparator,sizeof(ULONG),1,fp)) return 0;
 567     if(!lss_read(&mTimerStatusFlags,sizeof(ULONG),1,fp)) return 0;
 568     if(!lss_read(&mTimerInterruptMask,sizeof(ULONG),1,fp)) return 0;
 569  
 570     if(!lss_read(mPalette,sizeof(TPALETTE),16,fp)) return 0;
 571  
 572     if(!lss_read(&mIODAT,sizeof(ULONG),1,fp)) return 0;
 573     if(!lss_read(&mIODAT_REST_SIGNAL,sizeof(ULONG),1,fp)) return 0;
 574     if(!lss_read(&mIODIR,sizeof(ULONG),1,fp)) return 0;
 575  
 576     if(!lss_read(&mDISPCTL_DMAEnable,sizeof(ULONG),1,fp)) return 0;
 577     if(!lss_read(&mDISPCTL_Flip,sizeof(ULONG),1,fp)) return 0;
 578     if(!lss_read(&mDISPCTL_FourColour,sizeof(ULONG),1,fp)) return 0;
 579     if(!lss_read(&mDISPCTL_Colour,sizeof(ULONG),1,fp)) return 0;
 580  
 581     if(!lss_read(&mTIM_0_BKUP,sizeof(ULONG),1,fp)) return 0;
 582     if(!lss_read(&mTIM_0_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 583     if(!lss_read(&mTIM_0_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 584     if(!lss_read(&mTIM_0_LINKING,sizeof(ULONG),1,fp)) return 0;
 585     if(!lss_read(&mTIM_0_CURRENT,sizeof(ULONG),1,fp)) return 0;
 586     if(!lss_read(&mTIM_0_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 587     if(!lss_read(&mTIM_0_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 588     if(!lss_read(&mTIM_0_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 589     if(!lss_read(&mTIM_0_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 590     if(!lss_read(&mTIM_0_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 591     if(!lss_read(&mTIM_0_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 592  
 593     if(!lss_read(&mTIM_1_BKUP,sizeof(ULONG),1,fp)) return 0;
 594     if(!lss_read(&mTIM_1_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 595     if(!lss_read(&mTIM_1_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 596     if(!lss_read(&mTIM_1_LINKING,sizeof(ULONG),1,fp)) return 0;
 597     if(!lss_read(&mTIM_1_CURRENT,sizeof(ULONG),1,fp)) return 0;
 598     if(!lss_read(&mTIM_1_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 599     if(!lss_read(&mTIM_1_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 600     if(!lss_read(&mTIM_1_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 601     if(!lss_read(&mTIM_1_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 602     if(!lss_read(&mTIM_1_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 603     if(!lss_read(&mTIM_1_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 604  
 605     if(!lss_read(&mTIM_2_BKUP,sizeof(ULONG),1,fp)) return 0;
 606     if(!lss_read(&mTIM_2_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 607     if(!lss_read(&mTIM_2_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 608     if(!lss_read(&mTIM_2_LINKING,sizeof(ULONG),1,fp)) return 0;
 609     if(!lss_read(&mTIM_2_CURRENT,sizeof(ULONG),1,fp)) return 0;
 610     if(!lss_read(&mTIM_2_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 611     if(!lss_read(&mTIM_2_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 612     if(!lss_read(&mTIM_2_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 613     if(!lss_read(&mTIM_2_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 614     if(!lss_read(&mTIM_2_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 615     if(!lss_read(&mTIM_2_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 616  
 617     if(!lss_read(&mTIM_3_BKUP,sizeof(ULONG),1,fp)) return 0;
 618     if(!lss_read(&mTIM_3_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 619     if(!lss_read(&mTIM_3_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 620     if(!lss_read(&mTIM_3_LINKING,sizeof(ULONG),1,fp)) return 0;
 621     if(!lss_read(&mTIM_3_CURRENT,sizeof(ULONG),1,fp)) return 0;
 622     if(!lss_read(&mTIM_3_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 623     if(!lss_read(&mTIM_3_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 624     if(!lss_read(&mTIM_3_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 625     if(!lss_read(&mTIM_3_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 626     if(!lss_read(&mTIM_3_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 627     if(!lss_read(&mTIM_3_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 628  
 629     if(!lss_read(&mTIM_4_BKUP,sizeof(ULONG),1,fp)) return 0;
 630     if(!lss_read(&mTIM_4_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 631     if(!lss_read(&mTIM_4_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 632     if(!lss_read(&mTIM_4_LINKING,sizeof(ULONG),1,fp)) return 0;
 633     if(!lss_read(&mTIM_4_CURRENT,sizeof(ULONG),1,fp)) return 0;
 634     if(!lss_read(&mTIM_4_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 635     if(!lss_read(&mTIM_4_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 636     if(!lss_read(&mTIM_4_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 637     if(!lss_read(&mTIM_4_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 638     if(!lss_read(&mTIM_4_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 639     if(!lss_read(&mTIM_4_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 640  
 641     if(!lss_read(&mTIM_5_BKUP,sizeof(ULONG),1,fp)) return 0;
 642     if(!lss_read(&mTIM_5_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 643     if(!lss_read(&mTIM_5_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 644     if(!lss_read(&mTIM_5_LINKING,sizeof(ULONG),1,fp)) return 0;
 645     if(!lss_read(&mTIM_5_CURRENT,sizeof(ULONG),1,fp)) return 0;
 646     if(!lss_read(&mTIM_5_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 647     if(!lss_read(&mTIM_5_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 648     if(!lss_read(&mTIM_5_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 649     if(!lss_read(&mTIM_5_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 650     if(!lss_read(&mTIM_5_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 651     if(!lss_read(&mTIM_5_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 652  
 653     if(!lss_read(&mTIM_6_BKUP,sizeof(ULONG),1,fp)) return 0;
 654     if(!lss_read(&mTIM_6_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 655     if(!lss_read(&mTIM_6_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 656     if(!lss_read(&mTIM_6_LINKING,sizeof(ULONG),1,fp)) return 0;
 657     if(!lss_read(&mTIM_6_CURRENT,sizeof(ULONG),1,fp)) return 0;
 658     if(!lss_read(&mTIM_6_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 659     if(!lss_read(&mTIM_6_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 660     if(!lss_read(&mTIM_6_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 661     if(!lss_read(&mTIM_6_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 662     if(!lss_read(&mTIM_6_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 663     if(!lss_read(&mTIM_6_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 664  
 665     if(!lss_read(&mTIM_7_BKUP,sizeof(ULONG),1,fp)) return 0;
 666     if(!lss_read(&mTIM_7_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 667     if(!lss_read(&mTIM_7_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 668     if(!lss_read(&mTIM_7_LINKING,sizeof(ULONG),1,fp)) return 0;
 669     if(!lss_read(&mTIM_7_CURRENT,sizeof(ULONG),1,fp)) return 0;
 670     if(!lss_read(&mTIM_7_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 671     if(!lss_read(&mTIM_7_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 672     if(!lss_read(&mTIM_7_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 673     if(!lss_read(&mTIM_7_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 674     if(!lss_read(&mTIM_7_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 675     if(!lss_read(&mTIM_7_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 676  
 677     if(!lss_read(&mAUDIO_0_BKUP,sizeof(ULONG),1,fp)) return 0;
 678     if(!lss_read(&mAUDIO_0_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 679     if(!lss_read(&mAUDIO_0_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 680     if(!lss_read(&mAUDIO_0_LINKING,sizeof(ULONG),1,fp)) return 0;
 681     if(!lss_read(&mAUDIO_0_CURRENT,sizeof(ULONG),1,fp)) return 0;
 682     if(!lss_read(&mAUDIO_0_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 683     if(!lss_read(&mAUDIO_0_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 684     if(!lss_read(&mAUDIO_0_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 685     if(!lss_read(&mAUDIO_0_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 686     if(!lss_read(&mAUDIO_0_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 687     if(!lss_read(&mAUDIO_0_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 688     if(!lss_read(&mAUDIO_0_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 689     if(!lss_read(&mAUDIO_OUTPUT[0],sizeof(SBYTE),1,fp)) return 0;
 690     if(!lss_read(&mAUDIO_0_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 691     if(!lss_read(&mAUDIO_0_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 692  
 693     if(!lss_read(&mAUDIO_1_BKUP,sizeof(ULONG),1,fp)) return 0;
 694     if(!lss_read(&mAUDIO_1_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 695     if(!lss_read(&mAUDIO_1_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 696     if(!lss_read(&mAUDIO_1_LINKING,sizeof(ULONG),1,fp)) return 0;
 697     if(!lss_read(&mAUDIO_1_CURRENT,sizeof(ULONG),1,fp)) return 0;
 698     if(!lss_read(&mAUDIO_1_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 699     if(!lss_read(&mAUDIO_1_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 700     if(!lss_read(&mAUDIO_1_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 701     if(!lss_read(&mAUDIO_1_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 702     if(!lss_read(&mAUDIO_1_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 703     if(!lss_read(&mAUDIO_1_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 704     if(!lss_read(&mAUDIO_1_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 705     if(!lss_read(&mAUDIO_OUTPUT[1],sizeof(SBYTE),1,fp)) return 0;
 706     if(!lss_read(&mAUDIO_1_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 707     if(!lss_read(&mAUDIO_1_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 708  
 709     if(!lss_read(&mAUDIO_2_BKUP,sizeof(ULONG),1,fp)) return 0;
 710     if(!lss_read(&mAUDIO_2_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 711     if(!lss_read(&mAUDIO_2_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 712     if(!lss_read(&mAUDIO_2_LINKING,sizeof(ULONG),1,fp)) return 0;
 713     if(!lss_read(&mAUDIO_2_CURRENT,sizeof(ULONG),1,fp)) return 0;
 714     if(!lss_read(&mAUDIO_2_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 715     if(!lss_read(&mAUDIO_2_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 716     if(!lss_read(&mAUDIO_2_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 717     if(!lss_read(&mAUDIO_2_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 718     if(!lss_read(&mAUDIO_2_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 719     if(!lss_read(&mAUDIO_2_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 720     if(!lss_read(&mAUDIO_2_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 721     if(!lss_read(&mAUDIO_OUTPUT[2],sizeof(SBYTE),1,fp)) return 0;
 722     if(!lss_read(&mAUDIO_2_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 723     if(!lss_read(&mAUDIO_2_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 724  
 725     if(!lss_read(&mAUDIO_3_BKUP,sizeof(ULONG),1,fp)) return 0;
 726     if(!lss_read(&mAUDIO_3_ENABLE_RELOAD,sizeof(ULONG),1,fp)) return 0;
 727     if(!lss_read(&mAUDIO_3_ENABLE_COUNT,sizeof(ULONG),1,fp)) return 0;
 728     if(!lss_read(&mAUDIO_3_LINKING,sizeof(ULONG),1,fp)) return 0;
 729     if(!lss_read(&mAUDIO_3_CURRENT,sizeof(ULONG),1,fp)) return 0;
 730     if(!lss_read(&mAUDIO_3_TIMER_DONE,sizeof(ULONG),1,fp)) return 0;
 731     if(!lss_read(&mAUDIO_3_LAST_CLOCK,sizeof(ULONG),1,fp)) return 0;
 732     if(!lss_read(&mAUDIO_3_BORROW_IN,sizeof(ULONG),1,fp)) return 0;
 733     if(!lss_read(&mAUDIO_3_BORROW_OUT,sizeof(ULONG),1,fp)) return 0;
 734     if(!lss_read(&mAUDIO_3_LAST_LINK_CARRY,sizeof(ULONG),1,fp)) return 0;
 735     if(!lss_read(&mAUDIO_3_LAST_COUNT,sizeof(ULONG),1,fp)) return 0;
 736     if(!lss_read(&mAUDIO_3_VOLUME,sizeof(SBYTE),1,fp)) return 0;
 737     if(!lss_read(&mAUDIO_OUTPUT[3],sizeof(SBYTE),1,fp)) return 0;
 738     if(!lss_read(&mAUDIO_3_INTEGRATE_ENABLE,sizeof(ULONG),1,fp)) return 0;
 739     if(!lss_read(&mAUDIO_3_WAVESHAPER,sizeof(ULONG),1,fp)) return 0;
 740  
 741     if(!lss_read(&mSTEREO,sizeof(ULONG),1,fp)) return 0;
 742  
 743     //
 744     // Serial related variables
 745     //
 746     if(!lss_read(&mUART_RX_IRQ_ENABLE,sizeof(ULONG),1,fp)) return 0;
 747     if(!lss_read(&mUART_TX_IRQ_ENABLE,sizeof(ULONG),1,fp)) return 0;
 748  
 749     if(!lss_read(&mUART_TX_COUNTDOWN,sizeof(ULONG),1,fp)) return 0;
 750     if(!lss_read(&mUART_RX_COUNTDOWN,sizeof(ULONG),1,fp)) return 0;
 751  
 752     if(!lss_read(&mUART_SENDBREAK,sizeof(ULONG),1,fp)) return 0;
 753     if(!lss_read(&mUART_TX_DATA,sizeof(ULONG),1,fp)) return 0;
 754     if(!lss_read(&mUART_RX_DATA,sizeof(ULONG),1,fp)) return 0;
 755     if(!lss_read(&mUART_RX_READY,sizeof(ULONG),1,fp)) return 0;
 756  
 757     if(!lss_read(&mUART_PARITY_ENABLE,sizeof(ULONG),1,fp)) return 0;
 758     if(!lss_read(&mUART_PARITY_EVEN,sizeof(ULONG),1,fp)) return 0;
 759     return 1;
 760  }
 761  
 762  void CMikie::PresetForHomebrew(void)
 763  {
 764     TRACE_MIKIE0("PresetForHomebrew()");
 765  
 766     //
 767     // After all of that nice timer init we'll start timers running as some homebrew
 768     // i.e LR.O doesn't bother to setup the timers
 769  
 770     mTIM_0_BKUP=0x9e;
 771     mTIM_0_ENABLE_RELOAD=TRUE;
 772     mTIM_0_ENABLE_COUNT=TRUE;
 773  
 774     mTIM_2_BKUP=0x68;
 775     mTIM_2_ENABLE_RELOAD=TRUE;
 776     mTIM_2_ENABLE_COUNT=TRUE;
 777     mTIM_2_LINKING=7;
 778  
 779     mDISPCTL_DMAEnable=TRUE;
 780     mDISPCTL_Flip=FALSE;
 781     mDISPCTL_FourColour=0;
 782     mDISPCTL_Colour=TRUE;
 783  }
 784  
 785  void CMikie::ComLynxCable(int status)
 786  {
 787     mUART_CABLE_PRESENT=status;
 788  }
 789  
 790  void CMikie::ComLynxRxData(int data)
 791  {
 792     TRACE_MIKIE1("ComLynxRxData() - Received %04x",data);
 793     // Copy over the data
 794     if(mUART_Rx_waiting<UART_MAX_RX_QUEUE) {
 795        // Trigger incoming receive IF none waiting otherwise
 796        // we NEVER get to receive it!!!
 797        if(!mUART_Rx_waiting) mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD;
 798  
 799        // Receive the byte
 800        mUART_Rx_input_queue[mUART_Rx_input_ptr++]=data;
 801        mUART_Rx_input_ptr %= UART_MAX_RX_QUEUE;
 802        mUART_Rx_waiting++;
 803        TRACE_MIKIE2("ComLynxRxData() - input ptr=%02d waiting=%02d",mUART_Rx_input_ptr,mUART_Rx_waiting);
 804     } else {
 805        TRACE_MIKIE0("ComLynxRxData() - UART RX Overrun");
 806     }
 807  }
 808  
 809  void CMikie::ComLynxTxLoopback(int data)
 810  {
 811     TRACE_MIKIE1("ComLynxTxLoopback() - Received %04x",data);
 812  
 813     if(mUART_Rx_waiting<UART_MAX_RX_QUEUE) {
 814        // Trigger incoming receive IF none waiting otherwise
 815        // we NEVER get to receive it!!!
 816        if(!mUART_Rx_waiting) mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD;
 817  
 818        // Receive the byte - INSERT into front of queue
 819        mUART_Rx_output_ptr--;
 820        mUART_Rx_output_ptr %= UART_MAX_RX_QUEUE;
 821        mUART_Rx_input_queue[mUART_Rx_output_ptr]=data;
 822        mUART_Rx_waiting++;
 823        TRACE_MIKIE2("ComLynxTxLoopback() - input ptr=%02d waiting=%02d",mUART_Rx_input_ptr,mUART_Rx_waiting);
 824     } else {
 825        TRACE_MIKIE0("ComLynxTxLoopback() - UART RX Overrun");
 826     }
 827  }
 828  
 829  void CMikie::ComLynxTxCallback(void (*function)(int data,ULONG objref),ULONG objref)
 830  {
 831     mpUART_TX_CALLBACK=function;
 832     mUART_TX_CALLBACK_OBJECT=objref;
 833  }
 834  
 835  
 836  void CMikie::BuildPalette()
 837  {
 838     //
 839     // Calculate the colour lookup tabes for the relevant mode
 840     //
 841     TPALETTE Spot;
 842  
 843     for(Spot.Index=0;Spot.Index<4096;Spot.Index++) {
 844        mColourMap[Spot.Index]=((Spot.Colours.Red<<12)&0xf000) | ((Spot.Colours.Red<<8)&0x0800);
 845        mColourMap[Spot.Index]|=((Spot.Colours.Green<<7)&0x0780) | ((Spot.Colours.Green<<3)&0x0060);
 846        mColourMap[Spot.Index]|=((Spot.Colours.Blue<<1)&0x001e) | ((Spot.Colours.Blue>>3)&0x0001);
 847     }
 848  
 849     if (mDisplayFormat == MIKIE_PIXEL_FORMAT_16BPP_565_BE) {
 850        for(int i=0;i<4096;i++) {
 851           mColourMap[i] = mColourMap[i] << 8 | mColourMap[i] >> 8;
 852        }
 853     }
 854  
 855     // Reset screen related counters/vars
 856     mTIM_0_CURRENT=0;
 857     mTIM_2_CURRENT=0;
 858  
 859     // Fix lastcount so that timer update will definitely occur
 860     mTIM_0_LAST_COUNT-=(1<<(4+mTIM_0_LINKING))+1;
 861     mTIM_2_LAST_COUNT-=(1<<(4+mTIM_2_LINKING))+1;
 862  
 863     // Force immediate timer update
 864     gNextTimerEvent=gSystemCycleCount;
 865  }
 866  
 867  inline void CMikie::ResetDisplayPtr()
 868  {
 869     if (mDisplayRotate != mDisplayRotate_Pending)
 870     {
 871        mDisplayRotate = mDisplayRotate_Pending;
 872     }
 873  
 874     switch(mDisplayRotate)
 875     {
 876        case MIKIE_ROTATE_L:
 877  #ifdef DOUBLE_SCREEN
 878           mpDisplayCurrent=gPrimaryFrameBuffer+(mDisplayPitch*(HANDY_SCREEN_WIDTH-1)) + sizeof(HandyPixel)*(OUTPUT_SCREEN_WIDTH-HANDY_SCREEN_HEIGHT*2)/2;
 879  #else
 880           mpDisplayCurrent=gPrimaryFrameBuffer+(mDisplayPitch*(HANDY_SCREEN_WIDTH-1)) + sizeof(HandyPixel)*(OUTPUT_SCREEN_WIDTH-HANDY_SCREEN_HEIGHT)/2;
 881  #endif
 882           break;
 883        case MIKIE_ROTATE_R:
 884  #ifdef DOUBLE_SCREEN
 885           mpDisplayCurrent=gPrimaryFrameBuffer + sizeof(HandyPixel)*(OUTPUT_SCREEN_WIDTH -(OUTPUT_SCREEN_WIDTH-HANDY_SCREEN_HEIGHT*2)/2);
 886  #else
 887           mpDisplayCurrent=gPrimaryFrameBuffer + sizeof(HandyPixel)*(OUTPUT_SCREEN_WIDTH -(OUTPUT_SCREEN_WIDTH-HANDY_SCREEN_HEIGHT)/2);
 888  #endif
 889           break;
 890        default:
 891           mpDisplayCurrent=gPrimaryFrameBuffer;
 892           break;
 893     }
 894  }
 895  
 896  inline ULONG CMikie::DisplayRenderLine(void)
 897  {
 898     HandyPixel *bitmap_tmp=NULL;
 899     ULONG source,loop;
 900     ULONG work_done=0;
 901  
 902     if(!gPrimaryFrameBuffer) return 0;
 903     if(!mpDisplayCurrent) return 0;
 904     if(!mDISPCTL_DMAEnable) return 0;
 905  
 906     //	if(mLynxLine&0x80000000) return 0;
 907  
 908     // Set the timer interrupt flag
 909     if(mTimerInterruptMask&0x01) {
 910        TRACE_MIKIE0("Update() - TIMER0 IRQ Triggered (Line Timer)");
 911        mTimerStatusFlags|=0x01;
 912        gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
 913     }
 914  
 915     // Logic says it should be 101 but testing on an actual lynx shows the rest
 916     // period is between lines 102,101,100 with the new line being latched at
 917     // the beginning of count==99 hence the code below !!
 918  
 919     // Emulate REST signal
 920     if(mLynxLine==mTIM_2_BKUP-2 || mLynxLine==mTIM_2_BKUP-3 || mLynxLine==mTIM_2_BKUP-4) mIODAT_REST_SIGNAL=TRUE;
 921     else mIODAT_REST_SIGNAL=FALSE;
 922  
 923     if(mLynxLine==(mTIM_2_BKUP-3)) {
 924        if(mDISPCTL_Flip) {
 925           mLynxAddr=mDisplayAddress&0xfffc;
 926           mLynxAddr+=3;
 927        } else {
 928           mLynxAddr=mDisplayAddress&0xfffc;
 929        }
 930        // Trigger line rending to start
 931        mLynxLineDMACounter=102;
 932  
 933        // Reset frame buffer pointer to top of screen
 934        ResetDisplayPtr();
 935     }
 936  
 937     // Decrement line counter logic
 938     if(mLynxLine) mLynxLine--;
 939  
 940     // Do 102 lines, nothing more, less is OK.
 941     if(mLynxLineDMACounter) {
 942        //		TRACE_MIKIE1("Update() - Screen DMA, line %03d",line_count);
 943        mLynxLineDMACounter--;
 944  
 945        // Cycle hit for a 80 RAM access in rendering a line
 946        work_done+=(80+100)*DMA_RDWR_CYC;
 947  
 948        if (!gRenderFrame) return work_done;
 949  
 950        // Mikie screen DMA can only see the system RAM....
 951        // (Step through bitmap, line at a time)
 952  
 953        // Assign the temporary pointer;
 954        bitmap_tmp=(HandyPixel*)mpDisplayCurrent;
 955  
 956  #ifdef DOUBLE_SCREEN
 957        switch(mDisplayRotate)
 958        {
 959          
 960             case MIKIE_ROTATE_L:
 961                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
 962                {
 963                   source=mpRamPointer[mLynxAddr];
 964                   if(mDISPCTL_Flip)
 965                   {
 966                      mLynxAddr--;
 967                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
 968                      *(bitmap_tmp+1)=mColourMap[mPalette[source&0x0f].Index];
 969                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
 970                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
 971                      *(bitmap_tmp+1)=mColourMap[mPalette[source>>4].Index];
 972                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
 973                   }
 974                   else
 975                   {
 976                      mLynxAddr++;
 977                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
 978                      *(bitmap_tmp+1)=mColourMap[mPalette[source>>4].Index];
 979                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
 980                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
 981                      *(bitmap_tmp+1)=mColourMap[mPalette[source&0x0f].Index];
 982                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
 983                   }
 984                }
 985                mpDisplayCurrent+=2*sizeof(HandyPixel);
 986                break;
 987            case MIKIE_ROTATE_R:
 988                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
 989                {
 990                   source=mpRamPointer[mLynxAddr];
 991                   if(mDISPCTL_Flip)
 992                   {
 993                      mLynxAddr--;
 994                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
 995                      *(bitmap_tmp-1)=mColourMap[mPalette[source&0x0f].Index];
 996                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
 997                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
 998                      *(bitmap_tmp-1)=mColourMap[mPalette[source>>4].Index];
 999                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1000                   }
1001                   else
1002                   {
1003                      mLynxAddr++;
1004                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
1005                      *(bitmap_tmp-1)=mColourMap[mPalette[source>>4].Index];
1006                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1007                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
1008                      *(bitmap_tmp-1)=mColourMap[mPalette[source&0x0f].Index];
1009                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1010                   }
1011                }
1012                mpDisplayCurrent-=2*sizeof(HandyPixel);
1013                break;
1014                
1015            default:
1016                HandyPixel *bitmappt=bitmap_tmp;
1017    
1018                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
1019                {
1020                   source=mpRamPointer[mLynxAddr];
1021                   if(mDISPCTL_Flip)
1022                   {
1023                      mLynxAddr--;
1024                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1025                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];
1026                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1027                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];                 
1028                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1029                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1030                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1031                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1032                    }
1033                   else
1034                   {
1035                      mLynxAddr++;
1036                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1037                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1038                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1039                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1040                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1041                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];
1042                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1043                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];
1044                   }
1045                }
1046                mpDisplayCurrent+=mDisplayPitch*2;
1047                break;
1048          }
1049  #else
1050        switch(mDisplayRotate)
1051        {
1052          
1053             case MIKIE_ROTATE_L:
1054                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
1055                {
1056                   source=mpRamPointer[mLynxAddr];
1057                   if(mDISPCTL_Flip)
1058                   {
1059                      mLynxAddr--;
1060                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
1061                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
1062                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
1063                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
1064                   }
1065                   else
1066                   {
1067                      mLynxAddr++;
1068                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
1069                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
1070                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
1071                      bitmap_tmp-=OUTPUT_SCREEN_STRIDE;
1072                   }
1073                }
1074                mpDisplayCurrent+=sizeof(HandyPixel);
1075                break;
1076            case MIKIE_ROTATE_R:
1077                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
1078                {
1079                   source=mpRamPointer[mLynxAddr];
1080                   if(mDISPCTL_Flip)
1081                   {
1082                      mLynxAddr--;
1083                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
1084                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1085                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];
1086                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1087                   }
1088                   else
1089                   {
1090                      mLynxAddr++;
1091                      *(bitmap_tmp)=mColourMap[mPalette[source>>4].Index];;
1092                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1093                      *(bitmap_tmp)=mColourMap[mPalette[source&0x0f].Index];
1094                      bitmap_tmp+=OUTPUT_SCREEN_STRIDE;
1095                   }
1096                }
1097                mpDisplayCurrent-=sizeof(HandyPixel);
1098                break;
1099                
1100            default:
1101                HandyPixel *bitmappt=bitmap_tmp;
1102    
1103                for(loop=0;loop<HANDY_SCREEN_WIDTH/2;loop++)
1104                {
1105                   source=mpRamPointer[mLynxAddr];
1106                   if(mDISPCTL_Flip)
1107                   {
1108                      mLynxAddr--;
1109                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1110                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];                
1111                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1112                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1113                    }
1114                   else
1115                   {
1116                      mLynxAddr++;
1117                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source>>4].Index];
1118                      *(bitmappt++)=mColourMap[mPalette[source>>4].Index];
1119                      *(bitmappt+OUTPUT_SCREEN_STRIDE)=mColourMap[mPalette[source&0x0f].Index];
1120                      *(bitmappt++)=mColourMap[mPalette[source&0x0f].Index];
1121                   }
1122                }
1123                mpDisplayCurrent+=mDisplayPitch*2;
1124                break;
1125          }
1126  #endif
1127  
1128     }
1129     return work_done;
1130  }
1131  
1132  // Peek/Poke memory handlers
1133  
1134  void CMikie::Poke(ULONG addr,UBYTE data)
1135  {
1136     switch(addr&0xff) {
1137        case (TIM0BKUP&0xff):
1138           mTIM_0_BKUP=data;
1139           TRACE_MIKIE2("Poke(TIM0BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1140           break;
1141        case (TIM1BKUP&0xff):
1142           mTIM_1_BKUP=data;
1143           TRACE_MIKIE2("Poke(TIM1BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1144           break;
1145        case (TIM2BKUP&0xff):
1146           mTIM_2_BKUP=data;
1147           TRACE_MIKIE2("Poke(TIM2BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1148           break;
1149        case (TIM3BKUP&0xff):
1150           mTIM_3_BKUP=data;
1151           TRACE_MIKIE2("Poke(TIM3BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1152           break;
1153        case (TIM4BKUP&0xff):
1154           mTIM_4_BKUP=data;
1155           TRACE_MIKIE2("Poke(TIM4BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1156           break;
1157        case (TIM5BKUP&0xff):
1158           mTIM_5_BKUP=data;
1159           TRACE_MIKIE2("Poke(TIM5BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1160           break;
1161        case (TIM6BKUP&0xff):
1162           mTIM_6_BKUP=data;
1163           TRACE_MIKIE2("Poke(TIM6BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1164           break;
1165        case (TIM7BKUP&0xff):
1166           mTIM_7_BKUP=data;
1167           TRACE_MIKIE2("Poke(TIM7BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1168           break;
1169  
1170  
1171        case (TIM0CTLA&0xff):
1172           mTimerInterruptMask&=(0x01^0xff);
1173           mTimerInterruptMask|=(data&0x80)?0x01:0x00;
1174           mTIM_0_ENABLE_RELOAD=data&0x10;
1175           mTIM_0_ENABLE_COUNT=data&0x08;
1176           mTIM_0_LINKING=data&0x07;
1177           if(data&0x40) mTIM_0_TIMER_DONE=0;
1178           if(data&0x48) {
1179              mTIM_0_LAST_COUNT=gSystemCycleCount;
1180              gNextTimerEvent=gSystemCycleCount;
1181           }
1182           TRACE_MIKIE2("Poke(TIM0CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1183           break;
1184        case (TIM1CTLA&0xff):
1185           mTimerInterruptMask&=(0x02^0xff);
1186           mTimerInterruptMask|=(data&0x80)?0x02:0x00;
1187           mTIM_1_ENABLE_RELOAD=data&0x10;
1188           mTIM_1_ENABLE_COUNT=data&0x08;
1189           mTIM_1_LINKING=data&0x07;
1190           if(data&0x40) mTIM_1_TIMER_DONE=0;
1191           if(data&0x48) {
1192              mTIM_1_LAST_COUNT=gSystemCycleCount;
1193              gNextTimerEvent=gSystemCycleCount;
1194           }
1195           TRACE_MIKIE2("Poke(TIM1CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1196           break;
1197        case (TIM2CTLA&0xff):
1198           mTimerInterruptMask&=(0x04^0xff);
1199           mTimerInterruptMask|=(data&0x80)?0x04:0x00;
1200           mTIM_2_ENABLE_RELOAD=data&0x10;
1201           mTIM_2_ENABLE_COUNT=data&0x08;
1202           mTIM_2_LINKING=data&0x07;
1203           if(data&0x40) mTIM_2_TIMER_DONE=0;
1204           if(data&0x48) {
1205              mTIM_2_LAST_COUNT=gSystemCycleCount;
1206              gNextTimerEvent=gSystemCycleCount;
1207           }
1208           TRACE_MIKIE2("Poke(TIM2CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1209           break;
1210        case (TIM3CTLA&0xff):
1211           mTimerInterruptMask&=(0x08^0xff);
1212           mTimerInterruptMask|=(data&0x80)?0x08:0x00;
1213           mTIM_3_ENABLE_RELOAD=data&0x10;
1214           mTIM_3_ENABLE_COUNT=data&0x08;
1215           mTIM_3_LINKING=data&0x07;
1216           if(data&0x40) mTIM_3_TIMER_DONE=0;
1217           if(data&0x48) {
1218              mTIM_3_LAST_COUNT=gSystemCycleCount;
1219              gNextTimerEvent=gSystemCycleCount;
1220           }
1221           TRACE_MIKIE2("Poke(TIM3CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1222           break;
1223        case (TIM4CTLA&0xff):
1224           // Timer 4 can never generate interrupts as its timer output is used
1225           // to drive the UART clock generator
1226           mTIM_4_ENABLE_RELOAD=data&0x10;
1227           mTIM_4_ENABLE_COUNT=data&0x08;
1228           mTIM_4_LINKING=data&0x07;
1229           if(data&0x40) mTIM_4_TIMER_DONE=0;
1230           if(data&0x48) {
1231              mTIM_4_LAST_COUNT=gSystemCycleCount;
1232              gNextTimerEvent=gSystemCycleCount;
1233           }
1234           TRACE_MIKIE2("Poke(TIM4CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1235           break;
1236        case (TIM5CTLA&0xff):
1237           mTimerInterruptMask&=(0x20^0xff);
1238           mTimerInterruptMask|=(data&0x80)?0x20:0x00;
1239           mTIM_5_ENABLE_RELOAD=data&0x10;
1240           mTIM_5_ENABLE_COUNT=data&0x08;
1241           mTIM_5_LINKING=data&0x07;
1242           if(data&0x40) mTIM_5_TIMER_DONE=0;
1243           if(data&0x48) {
1244              mTIM_5_LAST_COUNT=gSystemCycleCount;
1245              gNextTimerEvent=gSystemCycleCount;
1246           }
1247           TRACE_MIKIE2("Poke(TIM5CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1248           break;
1249        case (TIM6CTLA&0xff):
1250           mTimerInterruptMask&=(0x40^0xff);
1251           mTimerInterruptMask|=(data&0x80)?0x40:0x00;
1252           mTIM_6_ENABLE_RELOAD=data&0x10;
1253           mTIM_6_ENABLE_COUNT=data&0x08;
1254           mTIM_6_LINKING=data&0x07;
1255           if(data&0x40) mTIM_6_TIMER_DONE=0;
1256           if(data&0x48) {
1257              mTIM_6_LAST_COUNT=gSystemCycleCount;
1258              gNextTimerEvent=gSystemCycleCount;
1259           }
1260           TRACE_MIKIE2("Poke(TIM6CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1261           break;
1262        case (TIM7CTLA&0xff):
1263           mTimerInterruptMask&=(0x80^0xff);
1264           mTimerInterruptMask|=(data&0x80)?0x80:0x00;
1265           mTIM_7_ENABLE_RELOAD=data&0x10;
1266           mTIM_7_ENABLE_COUNT=data&0x08;
1267           mTIM_7_LINKING=data&0x07;
1268           if(data&0x40) mTIM_7_TIMER_DONE=0;
1269           if(data&0x48) {
1270              mTIM_7_LAST_COUNT=gSystemCycleCount;
1271              gNextTimerEvent=gSystemCycleCount;
1272           }
1273           TRACE_MIKIE2("Poke(TIM7CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1274           break;
1275  
1276  
1277        case (TIM0CNT&0xff):
1278           mTIM_0_CURRENT=data;
1279           gNextTimerEvent=gSystemCycleCount;
1280           TRACE_MIKIE2("Poke(TIM0CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1281           break;
1282        case (TIM1CNT&0xff):
1283           mTIM_1_CURRENT=data;
1284           gNextTimerEvent=gSystemCycleCount;
1285           TRACE_MIKIE2("Poke(TIM1CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1286           break;
1287        case (TIM2CNT&0xff):
1288           mTIM_2_CURRENT=data;
1289           gNextTimerEvent=gSystemCycleCount;
1290           TRACE_MIKIE2("Poke(TIM2CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1291           break;
1292        case (TIM3CNT&0xff):
1293           mTIM_3_CURRENT=data;
1294           gNextTimerEvent=gSystemCycleCount;
1295           TRACE_MIKIE2("Poke(TIM3CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1296           break;
1297        case (TIM4CNT&0xff):
1298           mTIM_4_CURRENT=data;
1299           gNextTimerEvent=gSystemCycleCount;
1300           TRACE_MIKIE2("Poke(TIM4CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1301           break;
1302        case (TIM5CNT&0xff):
1303           mTIM_5_CURRENT=data;
1304           gNextTimerEvent=gSystemCycleCount;
1305           TRACE_MIKIE2("Poke(TIM5CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1306           break;
1307        case (TIM6CNT&0xff):
1308           mTIM_6_CURRENT=data;
1309           gNextTimerEvent=gSystemCycleCount;
1310           TRACE_MIKIE2("Poke(TIM6CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1311           break;
1312        case (TIM7CNT&0xff):
1313           mTIM_7_CURRENT=data;
1314           gNextTimerEvent=gSystemCycleCount;
1315           TRACE_MIKIE2("Poke(TIM7CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1316           break;
1317  
1318        case (TIM0CTLB&0xff):
1319           mTIM_0_TIMER_DONE=data&0x08;
1320           mTIM_0_LAST_CLOCK=data&0x04;
1321           mTIM_0_BORROW_IN=data&0x02;
1322           mTIM_0_BORROW_OUT=data&0x01;
1323           TRACE_MIKIE2("Poke(TIM0CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1324           //			BlowOut();
1325           break;
1326        case (TIM1CTLB&0xff):
1327           mTIM_1_TIMER_DONE=data&0x08;
1328           mTIM_1_LAST_CLOCK=data&0x04;
1329           mTIM_1_BORROW_IN=data&0x02;
1330           mTIM_1_BORROW_OUT=data&0x01;
1331           TRACE_MIKIE2("Poke(TIM1CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1332           //			BlowOut();
1333           break;
1334        case (TIM2CTLB&0xff):
1335           mTIM_2_TIMER_DONE=data&0x08;
1336           mTIM_2_LAST_CLOCK=data&0x04;
1337           mTIM_2_BORROW_IN=data&0x02;
1338           mTIM_2_BORROW_OUT=data&0x01;
1339           TRACE_MIKIE2("Poke(TIM2CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1340           //			BlowOut();
1341           break;
1342        case (TIM3CTLB&0xff):
1343           mTIM_3_TIMER_DONE=data&0x08;
1344           mTIM_3_LAST_CLOCK=data&0x04;
1345           mTIM_3_BORROW_IN=data&0x02;
1346           mTIM_3_BORROW_OUT=data&0x01;
1347           TRACE_MIKIE2("Poke(TIM3CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1348           //			BlowOut();
1349           break;
1350        case (TIM4CTLB&0xff):
1351           mTIM_4_TIMER_DONE=data&0x08;
1352           mTIM_4_LAST_CLOCK=data&0x04;
1353           mTIM_4_BORROW_IN=data&0x02;
1354           mTIM_4_BORROW_OUT=data&0x01;
1355           TRACE_MIKIE2("Poke(TIM4CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1356           //			BlowOut();
1357           break;
1358        case (TIM5CTLB&0xff):
1359           mTIM_5_TIMER_DONE=data&0x08;
1360           mTIM_5_LAST_CLOCK=data&0x04;
1361           mTIM_5_BORROW_IN=data&0x02;
1362           mTIM_5_BORROW_OUT=data&0x01;
1363           TRACE_MIKIE2("Poke(TIM5CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1364           //			BlowOut();
1365           break;
1366        case (TIM6CTLB&0xff):
1367           mTIM_6_TIMER_DONE=data&0x08;
1368           mTIM_6_LAST_CLOCK=data&0x04;
1369           mTIM_6_BORROW_IN=data&0x02;
1370           mTIM_6_BORROW_OUT=data&0x01;
1371           TRACE_MIKIE2("Poke(TIM6CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1372           //			BlowOut();
1373           break;
1374        case (TIM7CTLB&0xff):
1375           mTIM_7_TIMER_DONE=data&0x08;
1376           mTIM_7_LAST_CLOCK=data&0x04;
1377           mTIM_7_BORROW_IN=data&0x02;
1378           mTIM_7_BORROW_OUT=data&0x01;
1379           TRACE_MIKIE2("Poke(TIM7CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1380           //			BlowOut();
1381           break;
1382  
1383        case (AUD0VOL&0xff):
1384           mAUDIO_0_VOLUME=(SBYTE)data;
1385           TRACE_MIKIE2("Poke(AUD0VOL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1386           break;
1387        case (AUD0SHFTFB&0xff):
1388           mAUDIO_0_WAVESHAPER&=0x001fff;
1389           mAUDIO_0_WAVESHAPER|=(ULONG)data<<13;
1390           TRACE_MIKIE2("Poke(AUD0SHFTB,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1391           break;
1392        case (AUD0OUTVAL&0xff):
1393           mAUDIO_OUTPUT[0]=data;
1394           TRACE_MIKIE2("Poke(AUD0OUTVAL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1395           break;
1396        case (AUD0L8SHFT&0xff):
1397           mAUDIO_0_WAVESHAPER&=0x1fff00;
1398           mAUDIO_0_WAVESHAPER|=data;
1399           TRACE_MIKIE2("Poke(AUD0L8SHFT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1400           break;
1401        case (AUD0TBACK&0xff):
1402           // Counter is disabled when backup is zero for optimisation
1403           // due to the fact that the output frequency will be above audio
1404           // range, we must update the last use position to stop problems
1405           if(!mAUDIO_0_BKUP && data) {
1406              mAUDIO_0_LAST_COUNT=gSystemCycleCount;
1407              gNextTimerEvent=gSystemCycleCount;
1408           }
1409           mAUDIO_0_BKUP=data;
1410           TRACE_MIKIE2("Poke(AUD0TBACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1411           break;
1412        case (AUD0CTL&0xff):
1413           mAUDIO_0_ENABLE_RELOAD=data&0x10;
1414           mAUDIO_0_ENABLE_COUNT=data&0x08;
1415           mAUDIO_0_LINKING=data&0x07;
1416           mAUDIO_0_INTEGRATE_ENABLE=data&0x20;
1417           if(data&0x40) mAUDIO_0_TIMER_DONE=0;
1418           mAUDIO_0_WAVESHAPER&=0x1fefff;
1419           mAUDIO_0_WAVESHAPER|=(data&0x80)?0x001000:0x000000;
1420           if(data&0x48) {
1421              mAUDIO_0_LAST_COUNT=gSystemCycleCount;
1422              gNextTimerEvent=gSystemCycleCount;
1423           }
1424           TRACE_MIKIE2("Poke(AUD0CTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1425           break;
1426        case (AUD0COUNT&0xff):
1427           mAUDIO_0_CURRENT=data;
1428           TRACE_MIKIE2("Poke(AUD0COUNT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1429           break;
1430        case (AUD0MISC&0xff):
1431           mAUDIO_0_WAVESHAPER&=0x1ff0ff;
1432           mAUDIO_0_WAVESHAPER|=(data&0xf0)<<4;
1433           mAUDIO_0_BORROW_IN=data&0x02;
1434           mAUDIO_0_BORROW_OUT=data&0x01;
1435           mAUDIO_0_LAST_CLOCK=data&0x04;
1436           TRACE_MIKIE2("Poke(AUD0MISC,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1437           break;
1438  
1439        case (AUD1VOL&0xff):
1440           mAUDIO_1_VOLUME=(SBYTE)data;
1441           TRACE_MIKIE2("Poke(AUD1VOL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1442           break;
1443        case (AUD1SHFTFB&0xff):
1444           mAUDIO_1_WAVESHAPER&=0x001fff;
1445           mAUDIO_1_WAVESHAPER|=(ULONG)data<<13;
1446           TRACE_MIKIE2("Poke(AUD1SHFTFB,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1447           break;
1448        case (AUD1OUTVAL&0xff):
1449           mAUDIO_OUTPUT[1]=data;
1450           TRACE_MIKIE2("Poke(AUD1OUTVAL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1451           break;
1452        case (AUD1L8SHFT&0xff):
1453           mAUDIO_1_WAVESHAPER&=0x1fff00;
1454           mAUDIO_1_WAVESHAPER|=data;
1455           TRACE_MIKIE2("Poke(AUD1L8SHFT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1456           break;
1457        case (AUD1TBACK&0xff):
1458           // Counter is disabled when backup is zero for optimisation
1459           // due to the fact that the output frequency will be above audio
1460           // range, we must update the last use position to stop problems
1461           if(!mAUDIO_1_BKUP && data) {
1462              mAUDIO_1_LAST_COUNT=gSystemCycleCount;
1463              gNextTimerEvent=gSystemCycleCount;
1464           }
1465           mAUDIO_1_BKUP=data;
1466           TRACE_MIKIE2("Poke(AUD1TBACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1467           break;
1468        case (AUD1CTL&0xff):
1469           mAUDIO_1_ENABLE_RELOAD=data&0x10;
1470           mAUDIO_1_ENABLE_COUNT=data&0x08;
1471           mAUDIO_1_LINKING=data&0x07;
1472           mAUDIO_1_INTEGRATE_ENABLE=data&0x20;
1473           if(data&0x40) mAUDIO_1_TIMER_DONE=0;
1474           mAUDIO_1_WAVESHAPER&=0x1fefff;
1475           mAUDIO_1_WAVESHAPER|=(data&0x80)?0x001000:0x000000;
1476           if(data&0x48) {
1477              mAUDIO_1_LAST_COUNT=gSystemCycleCount;
1478              gNextTimerEvent=gSystemCycleCount;
1479           }
1480           TRACE_MIKIE2("Poke(AUD1CTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1481           break;
1482        case (AUD1COUNT&0xff):
1483           mAUDIO_1_CURRENT=data;
1484           TRACE_MIKIE2("Poke(AUD1COUNT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1485           break;
1486        case (AUD1MISC&0xff):
1487           mAUDIO_1_WAVESHAPER&=0x1ff0ff;
1488           mAUDIO_1_WAVESHAPER|=(data&0xf0)<<4;
1489           mAUDIO_1_BORROW_IN=data&0x02;
1490           mAUDIO_1_BORROW_OUT=data&0x01;
1491           mAUDIO_1_LAST_CLOCK=data&0x04;
1492           TRACE_MIKIE2("Poke(AUD1MISC,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1493           break;
1494  
1495        case (AUD2VOL&0xff):
1496           mAUDIO_2_VOLUME=(SBYTE)data;
1497           TRACE_MIKIE2("Poke(AUD2VOL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1498           break;
1499        case (AUD2SHFTFB&0xff):
1500           mAUDIO_2_WAVESHAPER&=0x001fff;
1501           mAUDIO_2_WAVESHAPER|=(ULONG)data<<13;
1502           TRACE_MIKIE2("Poke(AUD2VSHFTFB,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1503           break;
1504        case (AUD2OUTVAL&0xff):
1505           mAUDIO_OUTPUT[2]=data;
1506           TRACE_MIKIE2("Poke(AUD2OUTVAL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1507           break;
1508        case (AUD2L8SHFT&0xff):
1509           mAUDIO_2_WAVESHAPER&=0x1fff00;
1510           mAUDIO_2_WAVESHAPER|=data;
1511           TRACE_MIKIE2("Poke(AUD2L8SHFT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1512           break;
1513        case (AUD2TBACK&0xff):
1514           // Counter is disabled when backup is zero for optimisation
1515           // due to the fact that the output frequency will be above audio
1516           // range, we must update the last use position to stop problems
1517           if(!mAUDIO_2_BKUP && data) {
1518              mAUDIO_2_LAST_COUNT=gSystemCycleCount;
1519              gNextTimerEvent=gSystemCycleCount;
1520           }
1521           mAUDIO_2_BKUP=data;
1522           TRACE_MIKIE2("Poke(AUD2TBACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1523           break;
1524        case (AUD2CTL&0xff):
1525           mAUDIO_2_ENABLE_RELOAD=data&0x10;
1526           mAUDIO_2_ENABLE_COUNT=data&0x08;
1527           mAUDIO_2_LINKING=data&0x07;
1528           mAUDIO_2_INTEGRATE_ENABLE=data&0x20;
1529           if(data&0x40) mAUDIO_2_TIMER_DONE=0;
1530           mAUDIO_2_WAVESHAPER&=0x1fefff;
1531           mAUDIO_2_WAVESHAPER|=(data&0x80)?0x001000:0x000000;
1532           if(data&0x48) {
1533              mAUDIO_2_LAST_COUNT=gSystemCycleCount;
1534              gNextTimerEvent=gSystemCycleCount;
1535           }
1536           TRACE_MIKIE2("Poke(AUD2CTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1537           break;
1538        case (AUD2COUNT&0xff):
1539           mAUDIO_2_CURRENT=data;
1540           TRACE_MIKIE2("Poke(AUD2COUNT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1541           break;
1542        case (AUD2MISC&0xff):
1543           mAUDIO_2_WAVESHAPER&=0x1ff0ff;
1544           mAUDIO_2_WAVESHAPER|=(data&0xf0)<<4;
1545           mAUDIO_2_BORROW_IN=data&0x02;
1546           mAUDIO_2_BORROW_OUT=data&0x01;
1547           mAUDIO_2_LAST_CLOCK=data&0x04;
1548           TRACE_MIKIE2("Poke(AUD2MISC,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1549           break;
1550  
1551        case (AUD3VOL&0xff):
1552           mAUDIO_3_VOLUME=(SBYTE)data;
1553           TRACE_MIKIE2("Poke(AUD3VOL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1554           break;
1555        case (AUD3SHFTFB&0xff):
1556           mAUDIO_3_WAVESHAPER&=0x001fff;
1557           mAUDIO_3_WAVESHAPER|=(ULONG)data<<13;
1558           TRACE_MIKIE2("Poke(AUD3SHFTFB,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1559           break;
1560        case (AUD3OUTVAL&0xff):
1561           mAUDIO_OUTPUT[3]=data;
1562           TRACE_MIKIE2("Poke(AUD3OUTVAL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1563           break;
1564        case (AUD3L8SHFT&0xff):
1565           mAUDIO_3_WAVESHAPER&=0x1fff00;
1566           mAUDIO_3_WAVESHAPER|=data;
1567           TRACE_MIKIE2("Poke(AUD3L8SHFT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1568           break;
1569        case (AUD3TBACK&0xff):
1570           // Counter is disabled when backup is zero for optimisation
1571           // due to the fact that the output frequency will be above audio
1572           // range, we must update the last use position to stop problems
1573           if(!mAUDIO_3_BKUP && data) {
1574              mAUDIO_3_LAST_COUNT=gSystemCycleCount;
1575              gNextTimerEvent=gSystemCycleCount;
1576           }
1577           mAUDIO_3_BKUP=data;
1578           TRACE_MIKIE2("Poke(AUD3TBACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1579           break;
1580        case (AUD3CTL&0xff):
1581           mAUDIO_3_ENABLE_RELOAD=data&0x10;
1582           mAUDIO_3_ENABLE_COUNT=data&0x08;
1583           mAUDIO_3_LINKING=data&0x07;
1584           mAUDIO_3_INTEGRATE_ENABLE=data&0x20;
1585           if(data&0x40) mAUDIO_3_TIMER_DONE=0;
1586           mAUDIO_3_WAVESHAPER&=0x1fefff;
1587           mAUDIO_3_WAVESHAPER|=(data&0x80)?0x001000:0x000000;
1588           if(data&0x48) {
1589              mAUDIO_3_LAST_COUNT=gSystemCycleCount;
1590              gNextTimerEvent=gSystemCycleCount;
1591           }
1592           TRACE_MIKIE2("Poke(AUD3CTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1593           break;
1594        case (AUD3COUNT&0xff):
1595           mAUDIO_3_CURRENT=data;
1596           TRACE_MIKIE2("Poke(AUD3COUNT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1597           break;
1598        case (AUD3MISC&0xff):
1599           mAUDIO_3_WAVESHAPER&=0x1ff0ff;
1600           mAUDIO_3_WAVESHAPER|=(data&0xf0)<<4;
1601           mAUDIO_3_BORROW_IN=data&0x02;
1602           mAUDIO_3_BORROW_OUT=data&0x01;
1603           mAUDIO_3_LAST_CLOCK=data&0x04;
1604           TRACE_MIKIE2("Poke(AUD3MISC,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1605           break;
1606  
1607        case (ATTEN_A&0xff):
1608           mAUDIO_ATTEN[0] = data;
1609           TRACE_MIKIE2("Poke(ATTEN_A ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1610           break;
1611        case (ATTEN_B&0xff):
1612           mAUDIO_ATTEN[1] = data;
1613           TRACE_MIKIE2("Poke(ATTEN_B ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1614           break;
1615        case (ATTEN_C&0xff):
1616           mAUDIO_ATTEN[2] = data;
1617           TRACE_MIKIE2("Poke(ATTEN_C ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1618           break;
1619        case (ATTEN_D&0xff):
1620           mAUDIO_ATTEN[3] = data;
1621           TRACE_MIKIE2("Poke(ATTEN_D ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1622           break;
1623        case (MPAN&0xff):
1624           TRACE_MIKIE2("Poke(MPAN ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1625           mPAN = data;
1626           break;
1627  
1628        case (MSTEREO&0xff):
1629           TRACE_MIKIE2("Poke(MSTEREO,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1630           mSTEREO=data;
1631           //			if(!(mSTEREO&0x11) && (data&0x11))
1632           //			{
1633           //				mAUDIO_0_LAST_COUNT=gSystemCycleCount;
1634           //				gNextTimerEvent=gSystemCycleCount;
1635           //			}
1636           //			if(!(mSTEREO&0x22) && (data&0x22))
1637           //			{
1638           //				mAUDIO_1_LAST_COUNT=gSystemCycleCount;
1639           //				gNextTimerEvent=gSystemCycleCount;
1640           //			}
1641           //			if(!(mSTEREO&0x44) && (data&0x44))
1642           //			{
1643           //				mAUDIO_2_LAST_COUNT=gSystemCycleCount;
1644           //				gNextTimerEvent=gSystemCycleCount;
1645           //			}
1646           //			if(!(mSTEREO&0x88) && (data&0x88))
1647           //			{
1648           //				mAUDIO_3_LAST_COUNT=gSystemCycleCount;
1649           //				gNextTimerEvent=gSystemCycleCount;
1650           //			}
1651           break;
1652  
1653        case (INTRST&0xff):
1654           data^=0xff;
1655           mTimerStatusFlags&=data;
1656           gNextTimerEvent=gSystemCycleCount;
1657           // 22/09/06 Fix to championship rally, IRQ not getting cleared with edge triggered system
1658           gSystemIRQ=(mTimerStatusFlags&mTimerInterruptMask)?TRUE:FALSE;
1659           // 22/09/06 Fix to championship rally, IRQ not getting cleared with edge triggered system
1660           TRACE_MIKIE2("Poke(INTRST  ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1661           break;
1662  
1663        case (INTSET&0xff):
1664           TRACE_MIKIE2("Poke(INTSET  ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1665           mTimerStatusFlags|=data;
1666           // 22/09/06 Fix to championship rally, IRQ not getting cleared with edge triggered system
1667           gSystemIRQ=(mTimerStatusFlags&mTimerInterruptMask)?TRUE:FALSE;
1668           // 22/09/06 Fix to championship rally, IRQ not getting cleared with edge triggered system
1669           gNextTimerEvent=gSystemCycleCount;
1670           break;
1671  
1672        case (SYSCTL1&0xff):
1673           TRACE_MIKIE2("Poke(SYSCTL1 ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1674           if(!(data&0x02)) {
1675              C6502_REGS regs;
1676              mSystem.mCpu->GetRegs(regs);
1677              log_printf("CMikie::Poke(SYSCTL1) - Lynx power down occurred at PC=$%04x.\nResetting system.\n", regs.PC);
1678              mSystem.Reset();
1679              gSystemHalt=TRUE;
1680           }
1681           mSystem.mCart->CartAddressStrobe((data&0x01)?TRUE:FALSE);
1682           if(mSystem.mEEPROM->Available()) mSystem.mEEPROM->ProcessEepromCounter(mSystem.mCart->GetCounterValue());
1683           break;
1684  
1685        case (MIKEYSREV&0xff):
1686           TRACE_MIKIE2("Poke(MIKEYSREV,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1687           break;
1688  
1689        case (IODIR&0xff):
1690           TRACE_MIKIE2("Poke(IODIR   ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1691           mIODIR=data;
1692           if(mSystem.mEEPROM->Available()) mSystem.mEEPROM->ProcessEepromIO(mIODIR,mIODAT);
1693           break;
1694  
1695        case (IODAT&0xff):
1696           TRACE_MIKIE2("Poke(IODAT   ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1697           mIODAT=data;
1698           mSystem.mCart->CartAddressData((mIODAT&0x02)?TRUE:FALSE);
1699           // Enable cart writes to BANK1 on AUDIN if AUDIN is set to output
1700           if(mIODIR&0x10) mSystem.mCart->mWriteEnableBank1=(mIODAT&0x10)?TRUE:FALSE;// there is no reason to use AUDIN as Write Enable or latch. private patch??? TODO
1701           if(mSystem.mEEPROM->Available()) mSystem.mEEPROM->ProcessEepromIO(mIODIR,mIODAT);
1702           break;
1703  
1704        case (SERCTL&0xff):
1705           TRACE_MIKIE2("Poke(SERCTL  ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1706           mUART_TX_IRQ_ENABLE=(data&0x80)?true:false;
1707           mUART_RX_IRQ_ENABLE=(data&0x40)?true:false;
1708           mUART_PARITY_ENABLE=(data&0x10)?true:false;
1709           mUART_SENDBREAK=data&0x02;
1710           mUART_PARITY_EVEN=data&0x01;
1711  
1712           // Reset all errors if required
1713           if(data&0x08) {
1714              mUART_Rx_overun_error=0;
1715              mUART_Rx_framing_error=0;
1716           }
1717  
1718           if(mUART_SENDBREAK) {
1719              // Trigger send break, it will self sustain as long as sendbreak is set
1720              mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
1721              // Loop back what we transmitted
1722              ComLynxTxLoopback(UART_BREAK_CODE);
1723           }
1724           break;
1725  
1726        case (SERDAT&0xff):
1727           TRACE_MIKIE2("Poke(SERDAT ,%04x) at PC=%04x",data,mSystem.mCpu->GetPC());
1728           //
1729           // Fake transmission, set counter to be decremented by Timer 4
1730           //
1731           // ComLynx only has one output pin, hence Rx & Tx are shorted
1732           // therefore any transmitted data will loopback
1733           //
1734           mUART_TX_DATA=data;
1735           // Calculate Parity data
1736           if(mUART_PARITY_ENABLE) {
1737              // Calc parity value
1738              // Leave at zero !!
1739           } else {
1740              // If disabled then the PAREVEN bit is sent
1741              if(mUART_PARITY_EVEN) data|=0x0100;
1742           }
1743           // Set countdown to transmission
1744           mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
1745           // Loop back what we transmitted
1746           ComLynxTxLoopback(mUART_TX_DATA);
1747           break;
1748  
1749        case (SDONEACK&0xff):
1750           TRACE_MIKIE2("Poke(SDONEACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1751           break;
1752        case (CPUSLEEP&0xff):
1753           TRACE_MIKIE2("Poke(CPUSLEEP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1754           //
1755           // We must do "cycles_used" cycles of the system with the CPU sleeping
1756           // to compensate for the sprite painting, Mikie update will autowake the
1757           // CPU at the right time.
1758           //
1759           TRACE_MIKIE0("*********************************************************");
1760           TRACE_MIKIE0("****               CPU SLEEP STARTED                 ****");
1761           TRACE_MIKIE0("*********************************************************");
1762           gCPUWakeupTime=gSystemCycleCount+(SLONG)mSystem.mSusie->PaintSprites();
1763           gSystemCPUSleep=TRUE;
1764           TRACE_MIKIE2("Poke(CPUSLEEP,%02x) wakeup at cycle =%012d",data,gCPUWakeupTime);
1765           break;
1766  
1767        case (DISPCTL&0xff):
1768           TRACE_MIKIE2("Poke(DISPCTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1769           mDISPCTL_DMAEnable=data&0x1;
1770           mDISPCTL_Flip=data&0x2;
1771           mDISPCTL_FourColour=data&0x4;
1772           mDISPCTL_Colour=data&0x8;
1773           break;
1774        case (PBKUP&0xff):
1775           TRACE_MIKIE2("Poke(PBKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1776           break;
1777  
1778        case (DISPADRL&0xff):
1779           TRACE_MIKIE2("Poke(DISPADRL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1780           mDisplayAddress&=0xff00;
1781           mDisplayAddress+=data;
1782           break;
1783  
1784        case (DISPADRH&0xff):
1785           TRACE_MIKIE2("Poke(DISPADRH,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1786           mDisplayAddress&=0x00ff;
1787           mDisplayAddress+=(data<<8);
1788           break;
1789  
1790        case (Mtest0&0xff):
1791        case (Mtest1&0xff):
1792        case (Mtest2&0xff):
1793           // Test registers are unimplemented
1794           // lets hope no programs use them.
1795           TRACE_MIKIE2("Poke(MTEST0/1/2,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1796           break;
1797  
1798        case (0xfd97&0xff):
1799           // This code is to intercept calls to the fake ROM
1800           switch (mSystem.mCpu->GetPC()) {
1801              case 0xFE00+3: mSystem.HLE_BIOS_FE00(); break;
1802              case 0xFE19+3: mSystem.HLE_BIOS_FE19(); break;
1803              case 0xFE4A+3: mSystem.HLE_BIOS_FE4A(); break;
1804              case 0xFF80+3: mSystem.HLE_BIOS_FF80(); break;
1805              default: log_printf("BIOS: Missing function $%04X\n", mSystem.mCpu->GetPC());
1806           }
1807           break;
1808        case (GREEN0&0xff):
1809        case (GREEN1&0xff):
1810        case (GREEN2&0xff):
1811        case (GREEN3&0xff):
1812        case (GREEN4&0xff):
1813        case (GREEN5&0xff):
1814        case (GREEN6&0xff):
1815        case (GREEN7&0xff):
1816        case (GREEN8&0xff):
1817        case (GREEN9&0xff):
1818        case (GREENA&0xff):
1819        case (GREENB&0xff):
1820        case (GREENC&0xff):
1821        case (GREEND&0xff):
1822        case (GREENE&0xff):
1823        case (GREENF&0xff):
1824           TRACE_MIKIE2("Poke(GREENPAL0-F,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1825           mPalette[addr&0x0f].Colours.Green=data&0x0f;
1826           break;
1827  
1828        case (BLUERED0&0xff):
1829        case (BLUERED1&0xff):
1830        case (BLUERED2&0xff):
1831        case (BLUERED3&0xff):
1832        case (BLUERED4&0xff):
1833        case (BLUERED5&0xff):
1834        case (BLUERED6&0xff):
1835        case (BLUERED7&0xff):
1836        case (BLUERED8&0xff):
1837        case (BLUERED9&0xff):
1838        case (BLUEREDA&0xff):
1839        case (BLUEREDB&0xff):
1840        case (BLUEREDC&0xff):
1841        case (BLUEREDD&0xff):
1842        case (BLUEREDE&0xff):
1843        case (BLUEREDF&0xff):
1844           TRACE_MIKIE2("Poke(BLUEREDPAL0-F,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
1845           mPalette[addr&0x0f].Colours.Blue=(data&0xf0)>>4;
1846           mPalette[addr&0x0f].Colours.Red=data&0x0f;
1847           break;
1848  
1849           // Errors on read only register accesses
1850  
1851        case (MAGRDY0&0xff):
1852        case (MAGRDY1&0xff):
1853        case (AUDIN&0xff):
1854        case (MIKEYHREV&0xff):
1855           TRACE_MIKIE3("Poke(%04x,%02x) - Poke to read only register location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
1856           break;
1857  
1858           // Errors on illegal location accesses
1859  
1860        default:
1861           TRACE_MIKIE3("Poke(%04x,%02x) - Poke to illegal location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
1862           break;
1863     }
1864  
1865     if(addr >= AUD0VOL && addr <= MSTEREO)
1866  	  UpdateSound();
1867  }
1868  
1869  
1870  
1871  UBYTE CMikie::Peek(ULONG addr)
1872  {
1873     ULONG retval=0;
1874  
1875     switch(addr & 0xff) {
1876     // Timer control registers
1877        case (TIM0BKUP&0xff):
1878           TRACE_MIKIE2("Peek(TIM0KBUP ,%02x) at PC=%04x",mTIM_0_BKUP,mSystem.mCpu->GetPC());
1879           return (UBYTE)mTIM_0_BKUP;
1880        case (TIM1BKUP&0xff):
1881           TRACE_MIKIE2("Peek(TIM1KBUP ,%02x) at PC=%04x",mTIM_1_BKUP,mSystem.mCpu->GetPC());
1882           return (UBYTE)mTIM_1_BKUP;
1883        case (TIM2BKUP&0xff):
1884           TRACE_MIKIE2("Peek(TIM2KBUP ,%02x) at PC=%04x",mTIM_2_BKUP,mSystem.mCpu->GetPC());
1885           return (UBYTE)mTIM_2_BKUP;
1886        case (TIM3BKUP&0xff):
1887           TRACE_MIKIE2("Peek(TIM3KBUP ,%02x) at PC=%04x",mTIM_3_BKUP,mSystem.mCpu->GetPC());
1888           return (UBYTE)mTIM_3_BKUP;
1889        case (TIM4BKUP&0xff):
1890           TRACE_MIKIE2("Peek(TIM4KBUP ,%02x) at PC=%04x",mTIM_4_BKUP,mSystem.mCpu->GetPC());
1891           return (UBYTE)mTIM_4_BKUP;
1892        case (TIM5BKUP&0xff):
1893           TRACE_MIKIE2("Peek(TIM5KBUP ,%02x) at PC=%04x",mTIM_5_BKUP,mSystem.mCpu->GetPC());
1894           return (UBYTE)mTIM_5_BKUP;
1895        case (TIM6BKUP&0xff):
1896           TRACE_MIKIE2("Peek(TIM6KBUP ,%02x) at PC=%04x",mTIM_6_BKUP,mSystem.mCpu->GetPC());
1897           return (UBYTE)mTIM_6_BKUP;
1898        case (TIM7BKUP&0xff):
1899           TRACE_MIKIE2("Peek(TIM7KBUP ,%02x) at PC=%04x",mTIM_7_BKUP,mSystem.mCpu->GetPC());
1900           return (UBYTE)mTIM_7_BKUP;
1901  
1902        case (TIM0CTLA&0xff):
1903           retval|=(mTimerInterruptMask&0x01)?0x80:0x00;
1904           retval|=(mTIM_0_ENABLE_RELOAD)?0x10:0x00;
1905           retval|=(mTIM_0_ENABLE_COUNT)?0x08:0x00;
1906           retval|=mTIM_0_LINKING;
1907           TRACE_MIKIE2("Peek(TIM0CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1908           return retval;
1909  
1910        case (TIM1CTLA&0xff):
1911           retval|=(mTimerInterruptMask&0x02)?0x80:0x00;
1912           retval|=(mTIM_1_ENABLE_RELOAD)?0x10:0x00;
1913           retval|=(mTIM_1_ENABLE_COUNT)?0x08:0x00;
1914           retval|=mTIM_1_LINKING;
1915           TRACE_MIKIE2("Peek(TIM1CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1916           return retval;
1917  
1918        case (TIM2CTLA&0xff):
1919           retval|=(mTimerInterruptMask&0x04)?0x80:0x00;
1920           retval|=(mTIM_2_ENABLE_RELOAD)?0x10:0x00;
1921           retval|=(mTIM_2_ENABLE_COUNT)?0x08:0x00;
1922           retval|=mTIM_2_LINKING;
1923           TRACE_MIKIE2("Peek(TIM2CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1924           return retval;
1925  
1926        case (TIM3CTLA&0xff):
1927           retval|=(mTimerInterruptMask&0x08)?0x80:0x00;
1928           retval|=(mTIM_3_ENABLE_RELOAD)?0x10:0x00;
1929           retval|=(mTIM_3_ENABLE_COUNT)?0x08:0x00;
1930           retval|=mTIM_3_LINKING;
1931           TRACE_MIKIE2("Peek(TIM3CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1932           return retval;
1933  
1934        case (TIM4CTLA&0xff):
1935           retval|=(mTimerInterruptMask&0x10)?0x80:0x00;
1936           retval|=(mTIM_4_ENABLE_RELOAD)?0x10:0x00;
1937           retval|=(mTIM_4_ENABLE_COUNT)?0x08:0x00;
1938           retval|=mTIM_4_LINKING;
1939           TRACE_MIKIE2("Peek(TIM4CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1940           return retval;
1941  
1942        case (TIM5CTLA&0xff):
1943           retval|=(mTimerInterruptMask&0x20)?0x80:0x00;
1944           retval|=(mTIM_5_ENABLE_RELOAD)?0x10:0x00;
1945           retval|=(mTIM_5_ENABLE_COUNT)?0x08:0x00;
1946           retval|=mTIM_5_LINKING;
1947           TRACE_MIKIE2("Peek(TIM5CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1948           return retval;
1949  
1950        case (TIM6CTLA&0xff):
1951           retval|=(mTimerInterruptMask&0x40)?0x80:0x00;
1952           retval|=(mTIM_6_ENABLE_RELOAD)?0x10:0x00;
1953           retval|=(mTIM_6_ENABLE_COUNT)?0x08:0x00;
1954           retval|=mTIM_6_LINKING;
1955           TRACE_MIKIE2("Peek(TIM6CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1956           return retval;
1957  
1958        case (TIM7CTLA&0xff):
1959           retval|=(mTimerInterruptMask&0x80)?0x80:0x00;
1960           retval|=(mTIM_7_ENABLE_RELOAD)?0x10:0x00;
1961           retval|=(mTIM_7_ENABLE_COUNT)?0x08:0x00;
1962           retval|=mTIM_7_LINKING;
1963           TRACE_MIKIE2("Peek(TIM7CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
1964           return retval;
1965  
1966        case (TIM0CNT&0xff):
1967           Update();
1968           TRACE_MIKIE2("Peek(TIM0CNT  ,%02x) at PC=%04x",mTIM_0_CURRENT,mSystem.mCpu->GetPC());
1969           return (UBYTE)mTIM_0_CURRENT;
1970        case (TIM1CNT&0xff):
1971           Update();
1972           TRACE_MIKIE2("Peek(TIM1CNT  ,%02x) at PC=%04x",mTIM_1_CURRENT,mSystem.mCpu->GetPC());
1973           return (UBYTE)mTIM_1_CURRENT;
1974        case (TIM2CNT&0xff):
1975           Update();
1976           TRACE_MIKIE2("Peek(TIM2CNT  ,%02x) at PC=%04x",mTIM_2_CURRENT,mSystem.mCpu->GetPC());
1977           return (UBYTE)mTIM_2_CURRENT;
1978        case (TIM3CNT&0xff):
1979           Update();
1980           TRACE_MIKIE2("Peek(TIM3CNT  ,%02x) at PC=%04x",mTIM_3_CURRENT,mSystem.mCpu->GetPC());
1981           return (UBYTE)mTIM_3_CURRENT;
1982        case (TIM4CNT&0xff):
1983           Update();
1984           TRACE_MIKIE2("Peek(TIM4CNT  ,%02x) at PC=%04x",mTIM_4_CURRENT,mSystem.mCpu->GetPC());
1985           return (UBYTE)mTIM_4_CURRENT;
1986        case (TIM5CNT&0xff):
1987           Update();
1988           TRACE_MIKIE2("Peek(TIM5CNT  ,%02x) at PC=%04x",mTIM_5_CURRENT,mSystem.mCpu->GetPC());
1989           return (UBYTE)mTIM_5_CURRENT;
1990        case (TIM6CNT&0xff):
1991           Update();
1992           TRACE_MIKIE2("Peek(TIM6CNT  ,%02x) at PC=%04x",mTIM_6_CURRENT,mSystem.mCpu->GetPC());
1993           return (UBYTE)mTIM_6_CURRENT;
1994        case (TIM7CNT&0xff):
1995           Update();
1996           TRACE_MIKIE2("Peek(TIM7CNT  ,%02x) at PC=%04x",mTIM_7_CURRENT,mSystem.mCpu->GetPC());
1997           return (UBYTE)mTIM_7_CURRENT;
1998  
1999        case (TIM0CTLB&0xff):
2000           retval|=(mTIM_0_TIMER_DONE)?0x08:0x00;
2001           retval|=(mTIM_0_LAST_CLOCK)?0x04:0x00;
2002           retval|=(mTIM_0_BORROW_IN)?0x02:0x00;
2003           retval|=(mTIM_0_BORROW_OUT)?0x01:0x00;
2004           TRACE_MIKIE2("Peek(TIM0CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2005           return retval;
2006  
2007        case (TIM1CTLB&0xff):
2008           retval|=(mTIM_1_TIMER_DONE)?0x08:0x00;
2009           retval|=(mTIM_1_LAST_CLOCK)?0x04:0x00;
2010           retval|=(mTIM_1_BORROW_IN)?0x02:0x00;
2011           retval|=(mTIM_1_BORROW_OUT)?0x01:0x00;
2012           TRACE_MIKIE2("Peek(TIM1CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2013           return retval;
2014  
2015        case (TIM2CTLB&0xff):
2016           retval|=(mTIM_2_TIMER_DONE)?0x08:0x00;
2017           retval|=(mTIM_2_LAST_CLOCK)?0x04:0x00;
2018           retval|=(mTIM_2_BORROW_IN)?0x02:0x00;
2019           retval|=(mTIM_2_BORROW_OUT)?0x01:0x00;
2020           TRACE_MIKIE2("Peek(TIM2CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2021           return retval;
2022  
2023        case (TIM3CTLB&0xff):
2024           retval|=(mTIM_3_TIMER_DONE)?0x08:0x00;
2025           retval|=(mTIM_3_LAST_CLOCK)?0x04:0x00;
2026           retval|=(mTIM_3_BORROW_IN)?0x02:0x00;
2027           retval|=(mTIM_3_BORROW_OUT)?0x01:0x00;
2028           TRACE_MIKIE2("Peek(TIM3CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2029           return retval;
2030  
2031        case (TIM4CTLB&0xff):
2032           retval|=(mTIM_4_TIMER_DONE)?0x08:0x00;
2033           retval|=(mTIM_4_LAST_CLOCK)?0x04:0x00;
2034           retval|=(mTIM_4_BORROW_IN)?0x02:0x00;
2035           retval|=(mTIM_4_BORROW_OUT)?0x01:0x00;
2036           TRACE_MIKIE2("Peek(TIM4CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2037           return retval;
2038  
2039        case (TIM5CTLB&0xff):
2040           retval|=(mTIM_5_TIMER_DONE)?0x08:0x00;
2041           retval|=(mTIM_5_LAST_CLOCK)?0x04:0x00;
2042           retval|=(mTIM_5_BORROW_IN)?0x02:0x00;
2043           retval|=(mTIM_5_BORROW_OUT)?0x01:0x00;
2044           TRACE_MIKIE2("Peek(TIM5CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2045           return retval;
2046  
2047        case (TIM6CTLB&0xff):
2048           retval|=(mTIM_6_TIMER_DONE)?0x08:0x00;
2049           retval|=(mTIM_6_LAST_CLOCK)?0x04:0x00;
2050           retval|=(mTIM_6_BORROW_IN)?0x02:0x00;
2051           retval|=(mTIM_6_BORROW_OUT)?0x01:0x00;
2052           TRACE_MIKIE2("Peek(TIM6CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2053           return retval;
2054  
2055        case (TIM7CTLB&0xff):
2056           retval|=(mTIM_7_TIMER_DONE)?0x08:0x00;
2057           retval|=(mTIM_7_LAST_CLOCK)?0x04:0x00;
2058           retval|=(mTIM_7_BORROW_IN)?0x02:0x00;
2059           retval|=(mTIM_7_BORROW_OUT)?0x01:0x00;
2060           TRACE_MIKIE2("Peek(TIM7CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2061           return retval;
2062  
2063        // Audio control registers
2064  
2065        case (AUD0VOL&0xff):
2066           TRACE_MIKIE2("Peek(AUD0VOL,%02x) at PC=%04x",(UBYTE)mAUDIO_0_VOLUME,mSystem.mCpu->GetPC());
2067           return (UBYTE)mAUDIO_0_VOLUME;
2068        case (AUD0SHFTFB&0xff):
2069           TRACE_MIKIE2("Peek(AUD0SHFTFB,%02x) at PC=%04x",(UBYTE)(mAUDIO_0_WAVESHAPER>>13)&0xff,mSystem.mCpu->GetPC());
2070           return (UBYTE)((mAUDIO_0_WAVESHAPER>>13)&0xff);
2071        case (AUD0OUTVAL&0xff):
2072           TRACE_MIKIE2("Peek(AUD0OUTVAL,%02x) at PC=%04x",(UBYTE)mAUDIO_OUTPUT[0],mSystem.mCpu->GetPC());
2073           return (UBYTE)mAUDIO_OUTPUT[0];
2074        case (AUD0L8SHFT&0xff):
2075           TRACE_MIKIE2("Peek(AUD0L8SHFT,%02x) at PC=%04x",(UBYTE)(mAUDIO_0_WAVESHAPER&0xff),mSystem.mCpu->GetPC());
2076           return (UBYTE)(mAUDIO_0_WAVESHAPER&0xff);
2077        case (AUD0TBACK&0xff):
2078           TRACE_MIKIE2("Peek(AUD0TBACK,%02x) at PC=%04x",(UBYTE)mAUDIO_0_BKUP,mSystem.mCpu->GetPC());
2079           return (UBYTE)mAUDIO_0_BKUP;
2080        case (AUD0CTL&0xff):
2081           retval|=(mAUDIO_0_INTEGRATE_ENABLE)?0x20:0x00;
2082           retval|=(mAUDIO_0_ENABLE_RELOAD)?0x10:0x00;
2083           retval|=(mAUDIO_0_ENABLE_COUNT)?0x08:0x00;
2084           retval|=(mAUDIO_0_WAVESHAPER&0x001000)?0x80:0x00;
2085           retval|=mAUDIO_0_LINKING;
2086           TRACE_MIKIE2("Peek(AUD0CTL,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2087           return retval;
2088        case (AUD0COUNT&0xff):
2089           TRACE_MIKIE2("Peek(AUD0COUNT,%02x) at PC=%04x",(UBYTE)mAUDIO_0_CURRENT,mSystem.mCpu->GetPC());
2090           return (UBYTE)mAUDIO_0_CURRENT;
2091        case (AUD0MISC&0xff):
2092           retval|=(mAUDIO_0_BORROW_OUT)?0x01:0x00;
2093           retval|=(mAUDIO_0_BORROW_IN)?0x02:0x00;
2094           retval|=(mAUDIO_0_LAST_CLOCK)?0x08:0x00;
2095           retval|=(mAUDIO_0_WAVESHAPER>>4)&0xf0;
2096           TRACE_MIKIE2("Peek(AUD0MISC,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2097           return retval;
2098  
2099        case (AUD1VOL&0xff):
2100           TRACE_MIKIE2("Peek(AUD1VOL,%02x) at PC=%04x",(UBYTE)mAUDIO_1_VOLUME,mSystem.mCpu->GetPC());
2101           return (UBYTE)mAUDIO_1_VOLUME;
2102        case (AUD1SHFTFB&0xff):
2103           TRACE_MIKIE2("Peek(AUD1SHFTFB,%02x) at PC=%04x",(UBYTE)(mAUDIO_1_WAVESHAPER>>13)&0xff,mSystem.mCpu->GetPC());
2104           return (UBYTE)((mAUDIO_1_WAVESHAPER>>13)&0xff);
2105        case (AUD1OUTVAL&0xff):
2106           TRACE_MIKIE2("Peek(AUD1OUTVAL,%02x) at PC=%04x",(UBYTE)mAUDIO_OUTPUT[1],mSystem.mCpu->GetPC());
2107           return (UBYTE)mAUDIO_OUTPUT[1];
2108        case (AUD1L8SHFT&0xff):
2109           TRACE_MIKIE2("Peek(AUD1L8SHFT,%02x) at PC=%04x",(UBYTE)(mAUDIO_1_WAVESHAPER&0xff),mSystem.mCpu->GetPC());
2110           return (UBYTE)(mAUDIO_1_WAVESHAPER&0xff);
2111        case (AUD1TBACK&0xff):
2112           TRACE_MIKIE2("Peek(AUD1TBACK,%02x) at PC=%04x",(UBYTE)mAUDIO_1_BKUP,mSystem.mCpu->GetPC());
2113           return (UBYTE)mAUDIO_1_BKUP;
2114        case (AUD1CTL&0xff):
2115           retval|=(mAUDIO_1_INTEGRATE_ENABLE)?0x20:0x00;
2116           retval|=(mAUDIO_1_ENABLE_RELOAD)?0x10:0x00;
2117           retval|=(mAUDIO_1_ENABLE_COUNT)?0x08:0x00;
2118           retval|=(mAUDIO_1_WAVESHAPER&0x001000)?0x80:0x00;
2119           retval|=mAUDIO_1_LINKING;
2120           TRACE_MIKIE2("Peek(AUD1CTL,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2121           return retval;
2122  
2123        case (AUD1COUNT&0xff):
2124           TRACE_MIKIE2("Peek(AUD1COUNT,%02x) at PC=%04x",(UBYTE)mAUDIO_1_CURRENT,mSystem.mCpu->GetPC());
2125           return (UBYTE)mAUDIO_1_CURRENT;
2126        case (AUD1MISC&0xff):
2127           retval|=(mAUDIO_1_BORROW_OUT)?0x01:0x00;
2128           retval|=(mAUDIO_1_BORROW_IN)?0x02:0x00;
2129           retval|=(mAUDIO_1_LAST_CLOCK)?0x08:0x00;
2130           retval|=(mAUDIO_1_WAVESHAPER>>4)&0xf0;
2131           TRACE_MIKIE2("Peek(AUD1MISC,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2132           return retval;
2133  
2134        case (AUD2VOL&0xff):
2135           TRACE_MIKIE2("Peek(AUD2VOL,%02x) at PC=%04x",(UBYTE)mAUDIO_2_VOLUME,mSystem.mCpu->GetPC());
2136           return (UBYTE)mAUDIO_2_VOLUME;
2137        case (AUD2SHFTFB&0xff):
2138           TRACE_MIKIE2("Peek(AUD2SHFTFB,%02x) at PC=%04x",(UBYTE)(mAUDIO_2_WAVESHAPER>>13)&0xff,mSystem.mCpu->GetPC());
2139           return (UBYTE)((mAUDIO_2_WAVESHAPER>>13)&0xff);
2140        case (AUD2OUTVAL&0xff):
2141           TRACE_MIKIE2("Peek(AUD2OUTVAL,%02x) at PC=%04x",(UBYTE)mAUDIO_OUTPUT[2],mSystem.mCpu->GetPC());
2142           return (UBYTE)mAUDIO_OUTPUT[2];
2143        case (AUD2L8SHFT&0xff):
2144           TRACE_MIKIE2("Peek(AUD2L8SHFT,%02x) at PC=%04x",(UBYTE)(mAUDIO_2_WAVESHAPER&0xff),mSystem.mCpu->GetPC());
2145           return (UBYTE)(mAUDIO_2_WAVESHAPER&0xff);
2146        case (AUD2TBACK&0xff):
2147           TRACE_MIKIE2("Peek(AUD2TBACK,%02x) at PC=%04x",(UBYTE)mAUDIO_2_BKUP,mSystem.mCpu->GetPC());
2148           return (UBYTE)mAUDIO_2_BKUP;
2149        case (AUD2CTL&0xff):
2150           retval|=(mAUDIO_2_INTEGRATE_ENABLE)?0x20:0x00;
2151           retval|=(mAUDIO_2_ENABLE_RELOAD)?0x10:0x00;
2152           retval|=(mAUDIO_2_ENABLE_COUNT)?0x08:0x00;
2153           retval|=(mAUDIO_2_WAVESHAPER&0x001000)?0x80:0x00;
2154           retval|=mAUDIO_2_LINKING;
2155           TRACE_MIKIE2("Peek(AUD2CTL,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2156           return retval;
2157        case (AUD2COUNT&0xff):
2158           TRACE_MIKIE2("Peek(AUD2COUNT,%02x) at PC=%04x",(UBYTE)mAUDIO_2_CURRENT,mSystem.mCpu->GetPC());
2159           return (UBYTE)mAUDIO_2_CURRENT;
2160        case (AUD2MISC&0xff):
2161           retval|=(mAUDIO_2_BORROW_OUT)?0x01:0x00;
2162           retval|=(mAUDIO_2_BORROW_IN)?0x02:0x00;
2163           retval|=(mAUDIO_2_LAST_CLOCK)?0x08:0x00;
2164           retval|=(mAUDIO_2_WAVESHAPER>>4)&0xf0;
2165           TRACE_MIKIE2("Peek(AUD2MISC,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2166           return retval;
2167  
2168        case (AUD3VOL&0xff):
2169           TRACE_MIKIE2("Peek(AUD3VOL,%02x) at PC=%04x",(UBYTE)mAUDIO_3_VOLUME,mSystem.mCpu->GetPC());
2170           return (UBYTE)mAUDIO_3_VOLUME;
2171        case (AUD3SHFTFB&0xff):
2172           TRACE_MIKIE2("Peek(AUD3SHFTFB,%02x) at PC=%04x",(UBYTE)(mAUDIO_3_WAVESHAPER>>13)&0xff,mSystem.mCpu->GetPC());
2173           return (UBYTE)((mAUDIO_3_WAVESHAPER>>13)&0xff);
2174        case (AUD3OUTVAL&0xff):
2175           TRACE_MIKIE2("Peek(AUD3OUTVAL,%02x) at PC=%04x",(UBYTE)mAUDIO_OUTPUT[3],mSystem.mCpu->GetPC());
2176           return (UBYTE)mAUDIO_OUTPUT[3];
2177        case (AUD3L8SHFT&0xff):
2178           TRACE_MIKIE2("Peek(AUD3L8SHFT,%02x) at PC=%04x",(UBYTE)(mAUDIO_3_WAVESHAPER&0xff),mSystem.mCpu->GetPC());
2179           return (UBYTE)(mAUDIO_3_WAVESHAPER&0xff);
2180        case (AUD3TBACK&0xff):
2181           TRACE_MIKIE2("Peek(AUD3TBACK,%02x) at PC=%04x",(UBYTE)mAUDIO_3_BKUP,mSystem.mCpu->GetPC());
2182           return (UBYTE)mAUDIO_3_BKUP;
2183        case (AUD3CTL&0xff):
2184           retval|=(mAUDIO_3_INTEGRATE_ENABLE)?0x20:0x00;
2185           retval|=(mAUDIO_3_ENABLE_RELOAD)?0x10:0x00;
2186           retval|=(mAUDIO_3_ENABLE_COUNT)?0x08:0x00;
2187           retval|=(mAUDIO_3_WAVESHAPER&0x001000)?0x80:0x00;
2188           retval|=mAUDIO_3_LINKING;
2189           TRACE_MIKIE2("Peek(AUD3CTL,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2190           return retval;
2191        case (AUD3COUNT&0xff):
2192           TRACE_MIKIE2("Peek(AUD3COUNT,%02x) at PC=%04x",(UBYTE)mAUDIO_3_CURRENT,mSystem.mCpu->GetPC());
2193           return (UBYTE)mAUDIO_3_CURRENT;
2194        case (AUD3MISC&0xff):
2195           retval|=(mAUDIO_3_BORROW_OUT)?0x01:0x00;
2196           retval|=(mAUDIO_3_BORROW_IN)?0x02:0x00;
2197           retval|=(mAUDIO_3_LAST_CLOCK)?0x08:0x00;
2198           retval|=(mAUDIO_3_WAVESHAPER>>4)&0xf0;
2199           TRACE_MIKIE2("Peek(AUD3MISC,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2200           return retval;
2201  
2202        case (ATTEN_A&0xff):
2203           TRACE_MIKIE1("Peek(ATTEN_A) at PC=%04x",mSystem.mCpu->GetPC());
2204           return (UBYTE) mAUDIO_ATTEN[0];
2205        case (ATTEN_B&0xff):
2206           TRACE_MIKIE1("Peek(ATTEN_B) at PC=%04x",mSystem.mCpu->GetPC());
2207           return (UBYTE) mAUDIO_ATTEN[1];
2208        case (ATTEN_C&0xff):
2209           TRACE_MIKIE1("Peek(ATTEN_C) at PC=%04x",mSystem.mCpu->GetPC());
2210           return (UBYTE) mAUDIO_ATTEN[2];
2211        case (ATTEN_D&0xff):
2212           TRACE_MIKIE1("Peek(ATTEN_D) at PC=%04x",mSystem.mCpu->GetPC());
2213           return (UBYTE) mAUDIO_ATTEN[3];
2214        case (MPAN&0xff):
2215           TRACE_MIKIE1("Peek(MPAN) at PC=%04x",mSystem.mCpu->GetPC());
2216           return (UBYTE) mPAN;
2217  
2218        case (MSTEREO&0xff):
2219           TRACE_MIKIE2("Peek(MSTEREO,%02x) at PC=%04x",(UBYTE)mSTEREO^0xff,mSystem.mCpu->GetPC());
2220           return (UBYTE) mSTEREO;
2221  
2222           // Miscellaneous registers
2223  
2224        case (SERCTL&0xff):
2225           retval|=(mUART_TX_COUNTDOWN&UART_TX_INACTIVE)?0xA0:0x00;	// Indicate TxDone & TxAllDone
2226           retval|=(mUART_RX_READY)?0x40:0x00;							// Indicate Rx data ready
2227           retval|=(mUART_Rx_overun_error)?0x08:0x0;					// Framing error
2228           retval|=(mUART_Rx_framing_error)?0x04:0x00;					// Rx overrun
2229           retval|=(mUART_RX_DATA&UART_BREAK_CODE)?0x02:0x00;			// Indicate break received
2230           retval|=(mUART_RX_DATA&0x0100)?0x01:0x00;					// Add parity bit
2231           TRACE_MIKIE2("Peek(SERCTL  ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2232           return (UBYTE)retval;
2233  
2234        case (SERDAT&0xff):
2235           mUART_RX_READY=0;
2236           TRACE_MIKIE2("Peek(SERDAT  ,%02x) at PC=%04x",(UBYTE)mUART_RX_DATA,mSystem.mCpu->GetPC());
2237           return (UBYTE)(mUART_RX_DATA&0xff);
2238  
2239        case (IODAT&0xff):
2240           // IODIR  = output bit : input high (eeprom write done)
2241           if(mSystem.mEEPROM->Available()) {
2242              mSystem.mEEPROM->ProcessEepromBusy();
2243              retval|=(mIODIR&0x10)?mIODAT&0x10:(mSystem.mEEPROM->OutputBit()?0x10:0x00);
2244           } else {
2245              retval|=mIODAT&0x10;
2246           }
2247           retval|=(mIODIR&0x08)?(((mIODAT&0x08)&&mIODAT_REST_SIGNAL)?0x00:0x08):0x00;									// REST   = output bit : input low
2248           retval|=(mIODIR&0x04)?mIODAT&0x04:((mUART_CABLE_PRESENT)?0x04:0x00);	// NOEXP  = output bit : input low
2249           retval|=(mIODIR&0x02)?mIODAT&0x02:0x00;									// CARTAD = output bit : input low
2250           retval|=(mIODIR&0x01)?mIODAT&0x01:0x01;									// EXTPW  = output bit : input high (Power connected)
2251           TRACE_MIKIE2("Peek(IODAT   ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
2252           return (UBYTE)retval;
2253  
2254        case (INTRST&0xff):
2255        case (INTSET&0xff):
2256           TRACE_MIKIE2("Peek(INTSET  ,%02x) at PC=%04x",mTimerStatusFlags,mSystem.mCpu->GetPC());
2257           return (UBYTE)mTimerStatusFlags;
2258        case (MAGRDY0&0xff):
2259        case (MAGRDY1&0xff):
2260           TRACE_MIKIE2("Peek(MAGRDY0/1,%02x) at PC=%04x",0x00,mSystem.mCpu->GetPC());
2261           return 0x00;
2262        case (AUDIN&0xff):
2263           //			TRACE_MIKIE2("Peek(AUDIN,%02x) at PC=%04x",mAudioInputComparator?0x80:0x00,mSystem.mCpu->GetPC());
2264           //			if(mAudioInputComparator) return 0x80; else return 0x00;
2265           TRACE_MIKIE2("Peek(AUDIN,%02x) at PC=%04x",0x80,mSystem.mCpu->GetPC());
2266           return 0x80;
2267        case (MIKEYHREV&0xff):
2268           TRACE_MIKIE2("Peek(MIKEYHREV,%02x) at PC=%04x",0x01,mSystem.mCpu->GetPC());
2269           return 0x01;
2270  
2271        // Pallette registers
2272  
2273        case (GREEN0&0xff):
2274        case (GREEN1&0xff):
2275        case (GREEN2&0xff):
2276        case (GREEN3&0xff):
2277        case (GREEN4&0xff):
2278        case (GREEN5&0xff):
2279        case (GREEN6&0xff):
2280        case (GREEN7&0xff):
2281        case (GREEN8&0xff):
2282        case (GREEN9&0xff):
2283        case (GREENA&0xff):
2284        case (GREENB&0xff):
2285        case (GREENC&0xff):
2286        case (GREEND&0xff):
2287        case (GREENE&0xff):
2288        case (GREENF&0xff):
2289           TRACE_MIKIE2("Peek(GREENPAL0-F,%02x) at PC=%04x",mPalette[addr&0x0f].Colours.Green,mSystem.mCpu->GetPC());
2290           return mPalette[addr&0x0f].Colours.Green;
2291        case (BLUERED0&0xff):
2292        case (BLUERED1&0xff):
2293        case (BLUERED2&0xff):
2294        case (BLUERED3&0xff):
2295        case (BLUERED4&0xff):
2296        case (BLUERED5&0xff):
2297        case (BLUERED6&0xff):
2298        case (BLUERED7&0xff):
2299        case (BLUERED8&0xff):
2300        case (BLUERED9&0xff):
2301        case (BLUEREDA&0xff):
2302        case (BLUEREDB&0xff):
2303        case (BLUEREDC&0xff):
2304        case (BLUEREDD&0xff):
2305        case (BLUEREDE&0xff):
2306        case (BLUEREDF&0xff):
2307           TRACE_MIKIE2("Peek(BLUEREDPAL0-F,%02x) at PC=%04x",(mPalette[addr&0x0f].Colours.Red | (mPalette[addr&0x0f].Colours.Blue<<4)),mSystem.mCpu->GetPC());
2308           return (mPalette[addr&0x0f].Colours.Red | (mPalette[addr&0x0f].Colours.Blue<<4));
2309  
2310        // Errors on write only register accesses
2311        // For easier debugging
2312  
2313        case (DISPADRL&0xff):
2314           TRACE_MIKIE2("Peek(DISPADRL,%02x) at PC=%04x",(UBYTE)(mDisplayAddress&0xff),mSystem.mCpu->GetPC());
2315           return (UBYTE)(mDisplayAddress&0xff);
2316        case (DISPADRH&0xff):
2317           TRACE_MIKIE2("Peek(DISPADRH,%02x) at PC=%04x",(UBYTE)(mDisplayAddress>>8)&0xff,mSystem.mCpu->GetPC());
2318           return (UBYTE)(mDisplayAddress>>8)&0xff;
2319  
2320        case (DISPCTL&0xff):
2321        case (SYSCTL1&0xff):
2322        case (MIKEYSREV&0xff):
2323        case (IODIR&0xff):
2324        case (SDONEACK&0xff):
2325        case (CPUSLEEP&0xff):
2326        case (PBKUP&0xff):
2327        case (Mtest0&0xff):
2328        case (Mtest1&0xff):
2329        case (Mtest2&0xff):
2330           TRACE_MIKIE2("Peek(%04x) - Peek from write only register location at PC=$%04x",addr,mSystem.mCpu->GetPC());
2331           break;
2332  
2333        // Register to let programs know handy is running
2334  
2335        case (0xfd97&0xff):
2336           TRACE_MIKIE2("Peek(%04x) - **** HANDY DETECT ATTEMPTED **** at PC=$%04x",addr,mSystem.mCpu->GetPC());
2337           break;
2338           //return 0x42;
2339           // Errors on illegal location accesses
2340  
2341        default:
2342           TRACE_MIKIE2("Peek(%04x) - Peek from illegal location at PC=$%04x",addr,mSystem.mCpu->GetPC());
2343           break;
2344     }
2345     return 0xff;
2346  }
2347  
2348  inline void CMikie::Update(void)
2349  {
2350     SLONG divide = 0;
2351     SLONG decval = 0;
2352     ULONG tmp = 0;
2353     ULONG mikie_work_done=0;
2354  
2355     //
2356     // To stop problems with cycle count wrap we will check and then correct the
2357     // cycle counter.
2358     //
2359  
2360     //			TRACE_MIKIE0("Update()");
2361  
2362     if(gSystemCycleCount>0xf0000000) {
2363        gSystemCycleCount-=0x80000000;
2364        gThrottleNextCycleCheckpoint-=0x80000000;
2365        gAudioLastUpdateCycle-=0x80000000;
2366        mTIM_0_LAST_COUNT-=0x80000000;
2367        mTIM_1_LAST_COUNT-=0x80000000;
2368        mTIM_2_LAST_COUNT-=0x80000000;
2369        mTIM_3_LAST_COUNT-=0x80000000;
2370        mTIM_4_LAST_COUNT-=0x80000000;
2371        mTIM_5_LAST_COUNT-=0x80000000;
2372        mTIM_6_LAST_COUNT-=0x80000000;
2373        mTIM_7_LAST_COUNT-=0x80000000;
2374        mAUDIO_0_LAST_COUNT-=0x80000000;
2375        mAUDIO_1_LAST_COUNT-=0x80000000;
2376        mAUDIO_2_LAST_COUNT-=0x80000000;
2377        mAUDIO_3_LAST_COUNT-=0x80000000;
2378        // Only correct if sleep is active
2379        if(gCPUWakeupTime) {
2380           gCPUWakeupTime-=0x80000000;
2381           gIRQEntryCycle-=0x80000000;
2382        }
2383     }
2384  
2385     gNextTimerEvent=0xffffffff;
2386  
2387     //
2388     // Check if the CPU needs to be woken up from sleep mode
2389     //
2390     if(gCPUWakeupTime) {
2391        if(gSystemCycleCount>=gCPUWakeupTime) {
2392           TRACE_MIKIE0("*********************************************************");
2393           TRACE_MIKIE0("****              CPU SLEEP COMPLETED                ****");
2394           TRACE_MIKIE0("*********************************************************");
2395           gSystemCPUSleep=FALSE;
2396           gSystemCPUSleep_Saved=FALSE;
2397           gCPUWakeupTime=0;
2398        } else {
2399           if(gCPUWakeupTime>gSystemCycleCount) gNextTimerEvent=gCPUWakeupTime;
2400        }
2401     }
2402  
2403     //	Timer updates, rolled out flat in group order
2404     //
2405     //	Group A:
2406     //	Timer 0 -> Timer 2 -> Timer 4.
2407     //
2408     //	Group B:
2409     //	Timer 1 -> Timer 3 -> Timer 5 -> Timer 7 -> Audio 0 -> Audio 1-> Audio 2 -> Audio 3 -> Timer 1.
2410     //
2411  
2412     //
2413     // Within each timer code block we will predict the cycle count number of
2414     // the next timer event
2415     //
2416     // We don't need to count linked timers as the timer they are linked
2417     // from will always generate earlier events.
2418     //
2419     // As Timer 4 (UART) will generate many events we will ignore it
2420     //
2421     // We set the next event to the end of time at first and let the timers
2422     // overload it. Any writes to timer controls will force next event to
2423     // be immediate and hence a new prediction will be done. The prediction
2424     // causes overflow as opposed to zero i.e. current+1
2425     // (In reality T0 line counter should always be running.)
2426     //
2427  
2428  
2429     //
2430     // Timer 0 of Group A
2431     //
2432  
2433     //
2434     // Optimisation, assume T0 (Line timer) is never in one-shot,
2435     // never placed in link mode
2436     //
2437  
2438     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2439     //			if(mTIM_0_ENABLE_COUNT && (mTIM_0_ENABLE_RELOAD || !mTIM_0_TIMER_DONE))
2440     if(mTIM_0_ENABLE_COUNT) {
2441        // Timer 0 has no linking
2442        //				if(mTIM_0_LINKING!=0x07)
2443        {
2444           // Ordinary clocked mode as opposed to linked mode
2445           // 16MHz clock down to 1us == cyclecount >> 4
2446           divide=(4+mTIM_0_LINKING);
2447           decval=(gSystemCycleCount-mTIM_0_LAST_COUNT)>>divide;
2448  
2449           if(decval) {
2450              mTIM_0_LAST_COUNT+=decval<<divide;
2451              mTIM_0_CURRENT-=decval;
2452  
2453              if(mTIM_0_CURRENT&0x80000000) {
2454                 // Set carry out
2455                 mTIM_0_BORROW_OUT=TRUE;
2456  
2457                 //							// Reload if necessary
2458                 //							if(mTIM_0_ENABLE_RELOAD)
2459                 //							{
2460                 mTIM_0_CURRENT+=mTIM_0_BKUP+1;
2461                 //							}
2462                 //							else
2463                 //							{
2464                 //								mTIM_0_CURRENT=0;
2465                 //							}
2466  
2467                 mTIM_0_TIMER_DONE=TRUE;
2468  
2469                 // Interupt flag setting code moved into DisplayRenderLine()
2470  
2471                 // Line timer has expired, render a line, we cannot increment
2472                 // the global counter at this point as it will screw the other timers
2473                 // so we save under work done and inc at the end.
2474                 mikie_work_done+=DisplayRenderLine();
2475  
2476              } else {
2477                 mTIM_0_BORROW_OUT=FALSE;
2478              }
2479              // Set carry in as we did a count
2480              mTIM_0_BORROW_IN=TRUE;
2481           } else {
2482              // Clear carry in as we didn't count
2483              mTIM_0_BORROW_IN=FALSE;
2484              // Clear carry out
2485              mTIM_0_BORROW_OUT=FALSE;
2486           }
2487        }
2488  
2489        // Prediction for next timer event cycle number
2490  
2491        //				if(mTIM_0_LINKING!=7)
2492        {
2493           // Sometimes timeupdates can be >2x rollover in which case
2494           // then CURRENT may still be negative and we can use it to
2495           // calc the next timer value, we just want another update ASAP
2496           tmp=(mTIM_0_CURRENT&0x80000000)?1:((mTIM_0_CURRENT+1)<<divide);
2497           tmp+=gSystemCycleCount;
2498           if(tmp<gNextTimerEvent) {
2499              gNextTimerEvent=tmp;
2500              //						TRACE_MIKIE1("Update() - TIMER 0 Set NextTimerEvent = %012d",gNextTimerEvent);
2501           }
2502        }
2503        //				TRACE_MIKIE1("Update() - mTIM_0_CURRENT = %012d",mTIM_0_CURRENT);
2504        //				TRACE_MIKIE1("Update() - mTIM_0_BKUP    = %012d",mTIM_0_BKUP);
2505        //				TRACE_MIKIE1("Update() - mTIM_0_LASTCNT = %012d",mTIM_0_LAST_COUNT);
2506        //				TRACE_MIKIE1("Update() - mTIM_0_LINKING = %012d",mTIM_0_LINKING);
2507     }
2508  
2509     //
2510     // Timer 2 of Group A
2511     //
2512  
2513     //
2514     // Optimisation, assume T2 (Frame timer) is never in one-shot
2515     // always in linked mode i.e clocked by Line Timer
2516     //
2517  
2518     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2519     //			if(mTIM_2_ENABLE_COUNT && (mTIM_2_ENABLE_RELOAD || !mTIM_2_TIMER_DONE))
2520     if(mTIM_2_ENABLE_COUNT) {
2521        decval=0;
2522  
2523        //				if(mTIM_2_LINKING==0x07)
2524        {
2525           if(mTIM_0_BORROW_OUT) decval=1;
2526           mTIM_2_LAST_LINK_CARRY=mTIM_0_BORROW_OUT;
2527        }
2528        //				else
2529        //				{
2530        //					// Ordinary clocked mode as opposed to linked mode
2531        //					// 16MHz clock down to 1us == cyclecount >> 4
2532        //					divide=(4+mTIM_2_LINKING);
2533        //					decval=(gSystemCycleCount-mTIM_2_LAST_COUNT)>>divide;
2534        //				}
2535  
2536        if(decval) {
2537           //					mTIM_2_LAST_COUNT+=decval<<divide;
2538           mTIM_2_CURRENT-=decval;
2539           if(mTIM_2_CURRENT&0x80000000) {
2540              // Set carry out
2541              mTIM_2_BORROW_OUT=TRUE;
2542  
2543              //						// Reload if necessary
2544              //						if(mTIM_2_ENABLE_RELOAD)
2545              //						{
2546              mTIM_2_CURRENT+=mTIM_2_BKUP+1;
2547              //						}
2548              //						else
2549              //						{
2550              //							mTIM_2_CURRENT=0;
2551              //						}
2552              mTIM_2_TIMER_DONE=TRUE;
2553  
2554              mLynxLineDMACounter=0;
2555              mLynxLine=mTIM_2_BKUP;
2556  
2557              if(gCPUWakeupTime) {
2558                 gCPUWakeupTime = 0;
2559                 gSystemCPUSleep=FALSE;
2560                 gSystemCPUSleep_Saved=FALSE;
2561              }
2562  
2563              // Set the timer status flag
2564              if(mTimerInterruptMask&0x04) {
2565                 TRACE_MIKIE0("Update() - TIMER2 IRQ Triggered (Frame Timer)");
2566                 mTimerStatusFlags|=0x04;
2567                 gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2568              }
2569  
2570              TRACE_MIKIE0("Update() - Frame end");
2571  
2572              ResetDisplayPtr();
2573  
2574              gEndOfFrame = TRUE;
2575  
2576           } else {
2577              mTIM_2_BORROW_OUT=FALSE;
2578           }
2579           // Set carry in as we did a count
2580           mTIM_2_BORROW_IN=TRUE;
2581        } else {
2582           // Clear carry in as we didn't count
2583           mTIM_2_BORROW_IN=FALSE;
2584           // Clear carry out
2585           mTIM_2_BORROW_OUT=FALSE;
2586        }
2587  
2588        // Prediction for next timer event cycle number
2589        // We dont need to predict this as its the frame timer and will always
2590        // be beaten by the line timer on Timer 0
2591        //				if(mTIM_2_LINKING!=7)
2592        //				{
2593        //					tmp=gSystemCycleCount+((mTIM_2_CURRENT+1)<<divide);
2594        //					if(tmp<gNextTimerEvent)	gNextTimerEvent=tmp;
2595        //				}
2596        //				TRACE_MIKIE1("Update() - mTIM_2_CURRENT = %012d",mTIM_2_CURRENT);
2597        //				TRACE_MIKIE1("Update() - mTIM_2_BKUP    = %012d",mTIM_2_BKUP);
2598        //				TRACE_MIKIE1("Update() - mTIM_2_LASTCNT = %012d",mTIM_2_LAST_COUNT);
2599        //				TRACE_MIKIE1("Update() - mTIM_2_LINKING = %012d",mTIM_2_LINKING);
2600     }
2601  
2602     //
2603     // Timer 4 of Group A
2604     //
2605     // For the sake of speed it is assumed that Timer 4 (UART timer)
2606     // never uses one-shot mode, never uses linking, hence the code
2607     // is commented out. Timer 4 is at the end of a chain and seems
2608     // no reason to update its carry in-out variables
2609     //
2610  
2611     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2612     //			if(mTIM_4_ENABLE_COUNT && (mTIM_4_ENABLE_RELOAD || !mTIM_4_TIMER_DONE))
2613     if(mTIM_4_ENABLE_COUNT) {
2614        decval=0;
2615  
2616        //				if(mTIM_4_LINKING==0x07)
2617        //				{
2618        ////				if(mTIM_2_BORROW_OUT && !mTIM_4_LAST_LINK_CARRY) decval=1;
2619        //					if(mTIM_2_BORROW_OUT) decval=1;
2620        //					mTIM_4_LAST_LINK_CARRY=mTIM_2_BORROW_OUT;
2621        //				}
2622        //				else
2623        {
2624           // Ordinary clocked mode as opposed to linked mode
2625           // 16MHz clock down to 1us == cyclecount >> 4
2626           // Additional /8 (+3) for 8 clocks per bit transmit
2627           divide=4+3+mTIM_4_LINKING;
2628           decval=(gSystemCycleCount-mTIM_4_LAST_COUNT)>>divide;
2629        }
2630  
2631        if(decval) {
2632           mTIM_4_LAST_COUNT+=decval<<divide;
2633           mTIM_4_CURRENT-=decval;
2634           if(mTIM_4_CURRENT&0x80000000) {
2635              // Set carry out
2636              mTIM_4_BORROW_OUT=TRUE;
2637  
2638              //
2639              // Update the UART counter models for Rx & Tx
2640              //
2641  
2642              //
2643              // According to the docs IRQ's are level triggered and hence will always assert
2644              // what a pain in the arse
2645              //
2646              // Rx & Tx are loopedback due to comlynx structure
2647  
2648              //
2649              // Receive
2650              //
2651              if(!mUART_RX_COUNTDOWN) {
2652                 // Fetch a byte from the input queue
2653                 if(mUART_Rx_waiting>0) {
2654                    mUART_RX_DATA = mUART_Rx_input_queue[mUART_Rx_output_ptr++];
2655                    mUART_Rx_output_ptr %= UART_MAX_RX_QUEUE;
2656                    mUART_Rx_waiting--;
2657                    TRACE_MIKIE2("Update() - RX Byte output ptr=%02d waiting=%02d",mUART_Rx_output_ptr,mUART_Rx_waiting);
2658                 } else {
2659                    TRACE_MIKIE0("Update() - RX Byte but no data waiting ????");
2660                 }
2661  
2662                 // Retrigger input if more bytes waiting
2663                 if(mUART_Rx_waiting>0) {
2664                    mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD+UART_RX_NEXT_DELAY;
2665                    TRACE_MIKIE1("Update() - RX Byte retriggered, %d waiting",mUART_Rx_waiting);
2666                 } else {
2667                    mUART_RX_COUNTDOWN=UART_RX_INACTIVE;
2668                    TRACE_MIKIE0("Update() - RX Byte nothing waiting, deactivated");
2669                 }
2670  
2671                 // If RX_READY already set then we have an overrun
2672                 // as previous byte hasn't been read
2673                 if(mUART_RX_READY) mUART_Rx_overun_error=1;
2674  
2675                 // Flag byte as being recvd
2676                 mUART_RX_READY=1;
2677              } else if(!(mUART_RX_COUNTDOWN&UART_RX_INACTIVE)) {
2678                 mUART_RX_COUNTDOWN--;
2679              }
2680  
2681              if(!mUART_TX_COUNTDOWN) {
2682                 if(mUART_SENDBREAK) {
2683                    mUART_TX_DATA=UART_BREAK_CODE;
2684                    // Auto-Respawn new transmit
2685                    mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
2686                    // Loop back what we transmitted
2687                    ComLynxTxLoopback(mUART_TX_DATA);
2688                 } else {
2689                    // Serial activity finished
2690                    mUART_TX_COUNTDOWN=UART_TX_INACTIVE;
2691                 }
2692  
2693                 // If a networking object is attached then use its callback to send the data byte.
2694                 if(mpUART_TX_CALLBACK) {
2695                    TRACE_MIKIE0("Update() - UART_TX_CALLBACK");
2696                    (*mpUART_TX_CALLBACK)(mUART_TX_DATA,mUART_TX_CALLBACK_OBJECT);
2697                 }
2698  
2699              } else if(!(mUART_TX_COUNTDOWN&UART_TX_INACTIVE)) {
2700                 mUART_TX_COUNTDOWN--;
2701              }
2702  
2703              // Set the timer status flag
2704              // Timer 4 is the uart timer and doesn't generate IRQ's using this method
2705  
2706              // 16 Clocks = 1 bit transmission. Hold separate Rx & Tx counters
2707  
2708              // Reload if necessary
2709              //						if(mTIM_4_ENABLE_RELOAD)
2710              //						{
2711              mTIM_4_CURRENT+=mTIM_4_BKUP+1;
2712              // The low reload values on TIM4 coupled with a longer
2713              // timer service delay can sometimes cause
2714              // an underrun, check and fix
2715              if(mTIM_4_CURRENT&0x80000000) {
2716                 mTIM_4_CURRENT=mTIM_4_BKUP;
2717                 mTIM_4_LAST_COUNT=gSystemCycleCount;
2718              }
2719              //						}
2720              //						else
2721              //						{
2722              //							mTIM_4_CURRENT=0;
2723              //						}
2724              //						mTIM_4_TIMER_DONE=TRUE;
2725           }
2726           //					else
2727           //					{
2728           //						mTIM_4_BORROW_OUT=FALSE;
2729           //					}
2730           //					// Set carry in as we did a count
2731           //					mTIM_4_BORROW_IN=TRUE;
2732        }
2733        //				else
2734        //				{
2735        //					// Clear carry in as we didn't count
2736        //					mTIM_4_BORROW_IN=FALSE;
2737        //					// Clear carry out
2738        //					mTIM_4_BORROW_OUT=FALSE;
2739        //				}
2740        //
2741        //				// Prediction for next timer event cycle number
2742        //
2743        //				if(mTIM_4_LINKING!=7)
2744        //				{
2745        // Sometimes timeupdates can be >2x rollover in which case
2746        // then CURRENT may still be negative and we can use it to
2747        // calc the next timer value, we just want another update ASAP
2748        tmp=(mTIM_4_CURRENT&0x80000000)?1:((mTIM_4_CURRENT+1)<<divide);
2749        tmp+=gSystemCycleCount;
2750        if(tmp<gNextTimerEvent) {
2751           gNextTimerEvent=tmp;
2752           TRACE_MIKIE1("Update() - TIMER 4 Set NextTimerEvent = %012d",gNextTimerEvent);
2753        }
2754        //				}
2755        //				TRACE_MIKIE1("Update() - mTIM_4_CURRENT = %012d",mTIM_4_CURRENT);
2756        //				TRACE_MIKIE1("Update() - mTIM_4_BKUP    = %012d",mTIM_4_BKUP);
2757        //				TRACE_MIKIE1("Update() - mTIM_4_LASTCNT = %012d",mTIM_4_LAST_COUNT);
2758        //				TRACE_MIKIE1("Update() - mTIM_4_LINKING = %012d",mTIM_4_LINKING);
2759     }
2760  
2761     // Emulate the UART bug where UART IRQ is level sensitive
2762     // in that it will continue to generate interrupts as long
2763     // as they are enabled and the interrupt condition is true
2764  
2765     // If Tx is inactive i.e ready for a byte to eat and the
2766     // IRQ is enabled then generate it always
2767     if((mUART_TX_COUNTDOWN&UART_TX_INACTIVE) && mUART_TX_IRQ_ENABLE) {
2768        TRACE_MIKIE0("Update() - UART TX IRQ Triggered");
2769        mTimerStatusFlags|=0x10;
2770        gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2771     }
2772     // Is data waiting and the interrupt enabled, if so then
2773     // what are we waiting for....
2774     if(mUART_RX_READY && mUART_RX_IRQ_ENABLE) {
2775        TRACE_MIKIE0("Update() - UART RX IRQ Triggered");
2776        mTimerStatusFlags|=0x10;
2777        gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2778     }
2779  
2780     //
2781     // Timer 1 of Group B
2782     //
2783     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2784     if(mTIM_1_ENABLE_COUNT && (mTIM_1_ENABLE_RELOAD || !mTIM_1_TIMER_DONE)) {
2785        if(mTIM_1_LINKING!=0x07) {
2786           // Ordinary clocked mode as opposed to linked mode
2787           // 16MHz clock down to 1us == cyclecount >> 4
2788           divide=(4+mTIM_1_LINKING);
2789           decval=(gSystemCycleCount-mTIM_1_LAST_COUNT)>>divide;
2790  
2791           if(decval) {
2792              mTIM_1_LAST_COUNT+=decval<<divide;
2793              mTIM_1_CURRENT-=decval;
2794              if(mTIM_1_CURRENT&0x80000000) {
2795                 // Set carry out
2796                 mTIM_1_BORROW_OUT=TRUE;
2797  
2798                 // Set the timer status flag
2799                 if(mTimerInterruptMask&0x02) {
2800                    TRACE_MIKIE0("Update() - TIMER1 IRQ Triggered");
2801                    mTimerStatusFlags|=0x02;
2802                    gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2803                 }
2804  
2805                 // Reload if necessary
2806                 if(mTIM_1_ENABLE_RELOAD) {
2807                    mTIM_1_CURRENT+=mTIM_1_BKUP+1;
2808                 } else {
2809                    mTIM_1_CURRENT=0;
2810                 }
2811                 mTIM_1_TIMER_DONE=TRUE;
2812              } else {
2813                 mTIM_1_BORROW_OUT=FALSE;
2814              }
2815              // Set carry in as we did a count
2816              mTIM_1_BORROW_IN=TRUE;
2817           } else {
2818              // Clear carry in as we didn't count
2819              mTIM_1_BORROW_IN=FALSE;
2820              // Clear carry out
2821              mTIM_1_BORROW_OUT=FALSE;
2822           }
2823        }
2824  
2825        // Prediction for next timer event cycle number
2826  
2827        if(mTIM_1_LINKING!=7) {
2828           // Sometimes timeupdates can be >2x rollover in which case
2829           // then CURRENT may still be negative and we can use it to
2830           // calc the next timer value, we just want another update ASAP
2831           tmp=(mTIM_1_CURRENT&0x80000000)?1:((mTIM_1_CURRENT+1)<<divide);
2832           tmp+=gSystemCycleCount;
2833           if(tmp<gNextTimerEvent) {
2834              gNextTimerEvent=tmp;
2835              TRACE_MIKIE1("Update() - TIMER 1 Set NextTimerEvent = %012d",gNextTimerEvent);
2836           }
2837        }
2838        //				TRACE_MIKIE1("Update() - mTIM_1_CURRENT = %012d",mTIM_1_CURRENT);
2839        //				TRACE_MIKIE1("Update() - mTIM_1_BKUP    = %012d",mTIM_1_BKUP);
2840        //				TRACE_MIKIE1("Update() - mTIM_1_LASTCNT = %012d",mTIM_1_LAST_COUNT);
2841        //				TRACE_MIKIE1("Update() - mTIM_1_LINKING = %012d",mTIM_1_LINKING);
2842     }
2843  
2844     //
2845     // Timer 3 of Group A
2846     //
2847     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2848     if(mTIM_3_ENABLE_COUNT && (mTIM_3_ENABLE_RELOAD || !mTIM_3_TIMER_DONE)) {
2849        decval=0;
2850  
2851        if(mTIM_3_LINKING==0x07) {
2852           if(mTIM_1_BORROW_OUT) decval=1;
2853              mTIM_3_LAST_LINK_CARRY=mTIM_1_BORROW_OUT;
2854        } else {
2855           // Ordinary clocked mode as opposed to linked mode
2856           // 16MHz clock down to 1us == cyclecount >> 4
2857           divide=(4+mTIM_3_LINKING);
2858           decval=(gSystemCycleCount-mTIM_3_LAST_COUNT)>>divide;
2859        }
2860  
2861        if(decval) {
2862           mTIM_3_LAST_COUNT+=decval<<divide;
2863           mTIM_3_CURRENT-=decval;
2864           if(mTIM_3_CURRENT&0x80000000) {
2865              // Set carry out
2866              mTIM_3_BORROW_OUT=TRUE;
2867  
2868              // Set the timer status flag
2869              if(mTimerInterruptMask&0x08) {
2870                 TRACE_MIKIE0("Update() - TIMER3 IRQ Triggered");
2871                 mTimerStatusFlags|=0x08;
2872                 gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2873              }
2874  
2875              // Reload if necessary
2876              if(mTIM_3_ENABLE_RELOAD) {
2877                 mTIM_3_CURRENT+=mTIM_3_BKUP+1;
2878              } else {
2879                 mTIM_3_CURRENT=0;
2880              }
2881              mTIM_3_TIMER_DONE=TRUE;
2882           } else {
2883              mTIM_3_BORROW_OUT=FALSE;
2884           }
2885           // Set carry in as we did a count
2886           mTIM_3_BORROW_IN=TRUE;
2887        } else {
2888           // Clear carry in as we didn't count
2889           mTIM_3_BORROW_IN=FALSE;
2890           // Clear carry out
2891           mTIM_3_BORROW_OUT=FALSE;
2892        }
2893  
2894        // Prediction for next timer event cycle number
2895  
2896        if(mTIM_3_LINKING!=7) {
2897           // Sometimes timeupdates can be >2x rollover in which case
2898           // then CURRENT may still be negative and we can use it to
2899           // calc the next timer value, we just want another update ASAP
2900           tmp=(mTIM_3_CURRENT&0x80000000)?1:((mTIM_3_CURRENT+1)<<divide);
2901           tmp+=gSystemCycleCount;
2902           if(tmp<gNextTimerEvent) {
2903              gNextTimerEvent=tmp;
2904              TRACE_MIKIE1("Update() - TIMER 3 Set NextTimerEvent = %012d",gNextTimerEvent);
2905           }
2906        }
2907        //				TRACE_MIKIE1("Update() - mTIM_3_CURRENT = %012d",mTIM_3_CURRENT);
2908        //				TRACE_MIKIE1("Update() - mTIM_3_BKUP    = %012d",mTIM_3_BKUP);
2909        //				TRACE_MIKIE1("Update() - mTIM_3_LASTCNT = %012d",mTIM_3_LAST_COUNT);
2910        //				TRACE_MIKIE1("Update() - mTIM_3_LINKING = %012d",mTIM_3_LINKING);
2911     }
2912  
2913     //
2914     // Timer 5 of Group A
2915     //
2916     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2917     if(mTIM_5_ENABLE_COUNT && (mTIM_5_ENABLE_RELOAD || !mTIM_5_TIMER_DONE)) {
2918        decval=0;
2919  
2920        if(mTIM_5_LINKING==0x07) {
2921           if(mTIM_3_BORROW_OUT) decval=1;
2922              mTIM_5_LAST_LINK_CARRY=mTIM_3_BORROW_OUT;
2923        } else {
2924           // Ordinary clocked mode as opposed to linked mode
2925           // 16MHz clock down to 1us == cyclecount >> 4
2926           divide=(4+mTIM_5_LINKING);
2927           decval=(gSystemCycleCount-mTIM_5_LAST_COUNT)>>divide;
2928        }
2929  
2930        if(decval) {
2931           mTIM_5_LAST_COUNT+=decval<<divide;
2932           mTIM_5_CURRENT-=decval;
2933           if(mTIM_5_CURRENT&0x80000000) {
2934              // Set carry out
2935              mTIM_5_BORROW_OUT=TRUE;
2936  
2937              // Set the timer status flag
2938              if(mTimerInterruptMask&0x20) {
2939                 TRACE_MIKIE0("Update() - TIMER5 IRQ Triggered");
2940                 mTimerStatusFlags|=0x20;
2941                 gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
2942              }
2943  
2944              // Reload if necessary
2945              if(mTIM_5_ENABLE_RELOAD) {
2946                 mTIM_5_CURRENT+=mTIM_5_BKUP+1;
2947              } else {
2948                 mTIM_5_CURRENT=0;
2949              }
2950              mTIM_5_TIMER_DONE=TRUE;
2951           } else {
2952              mTIM_5_BORROW_OUT=FALSE;
2953           }
2954           // Set carry in as we did a count
2955           mTIM_5_BORROW_IN=TRUE;
2956        } else {
2957           // Clear carry in as we didn't count
2958           mTIM_5_BORROW_IN=FALSE;
2959           // Clear carry out
2960           mTIM_5_BORROW_OUT=FALSE;
2961        }
2962  
2963        // Prediction for next timer event cycle number
2964  
2965        if(mTIM_5_LINKING!=7) {
2966           // Sometimes timeupdates can be >2x rollover in which case
2967           // then CURRENT may still be negative and we can use it to
2968           // calc the next timer value, we just want another update ASAP
2969           tmp=(mTIM_5_CURRENT&0x80000000)?1:((mTIM_5_CURRENT+1)<<divide);
2970           tmp+=gSystemCycleCount;
2971           if(tmp<gNextTimerEvent) {
2972              gNextTimerEvent=tmp;
2973              TRACE_MIKIE1("Update() - TIMER 5 Set NextTimerEvent = %012d",gNextTimerEvent);
2974           }
2975        }
2976        //				TRACE_MIKIE1("Update() - mTIM_5_CURRENT = %012d",mTIM_5_CURRENT);
2977        //				TRACE_MIKIE1("Update() - mTIM_5_BKUP    = %012d",mTIM_5_BKUP);
2978        //				TRACE_MIKIE1("Update() - mTIM_5_LASTCNT = %012d",mTIM_5_LAST_COUNT);
2979        //				TRACE_MIKIE1("Update() - mTIM_5_LINKING = %012d",mTIM_5_LINKING);
2980     }
2981  
2982     //
2983     // Timer 7 of Group A
2984     //
2985     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
2986     if(mTIM_7_ENABLE_COUNT && (mTIM_7_ENABLE_RELOAD || !mTIM_7_TIMER_DONE)) {
2987        decval=0;
2988  
2989        if(mTIM_7_LINKING==0x07) {
2990           if(mTIM_5_BORROW_OUT) decval=1;
2991              mTIM_7_LAST_LINK_CARRY=mTIM_5_BORROW_OUT;
2992        } else {
2993            // Ordinary clocked mode as opposed to linked mode
2994            // 16MHz clock down to 1us == cyclecount >> 4
2995            divide=(4+mTIM_7_LINKING);
2996            decval=(gSystemCycleCount-mTIM_7_LAST_COUNT)>>divide;
2997        }
2998  
2999        if(decval) {
3000           mTIM_7_LAST_COUNT+=decval<<divide;
3001           mTIM_7_CURRENT-=decval;
3002           if(mTIM_7_CURRENT&0x80000000) {
3003              // Set carry out
3004              mTIM_7_BORROW_OUT=TRUE;
3005  
3006              // Set the timer status flag
3007              if(mTimerInterruptMask&0x80) {
3008                 TRACE_MIKIE0("Update() - TIMER7 IRQ Triggered");
3009                 mTimerStatusFlags|=0x80;
3010                 gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
3011              }
3012  
3013              // Reload if necessary
3014              if(mTIM_7_ENABLE_RELOAD) {
3015                 mTIM_7_CURRENT+=mTIM_7_BKUP+1;
3016              } else {
3017                 mTIM_7_CURRENT=0;
3018              }
3019              mTIM_7_TIMER_DONE=TRUE;
3020  
3021           } else {
3022              mTIM_7_BORROW_OUT=FALSE;
3023           }
3024           // Set carry in as we did a count
3025           mTIM_7_BORROW_IN=TRUE;
3026        } else {
3027           // Clear carry in as we didn't count
3028           mTIM_7_BORROW_IN=FALSE;
3029           // Clear carry out
3030           mTIM_7_BORROW_OUT=FALSE;
3031        }
3032  
3033        // Prediction for next timer event cycle number
3034  
3035        if(mTIM_7_LINKING!=7) {
3036           // Sometimes timeupdates can be >2x rollover in which case
3037           // then CURRENT may still be negative and we can use it to
3038           // calc the next timer value, we just want another update ASAP
3039           tmp=(mTIM_7_CURRENT&0x80000000)?1:((mTIM_7_CURRENT+1)<<divide);
3040           tmp+=gSystemCycleCount;
3041           if(tmp<gNextTimerEvent) {
3042              gNextTimerEvent=tmp;
3043              TRACE_MIKIE1("Update() - TIMER 7 Set NextTimerEvent = %012d",gNextTimerEvent);
3044           }
3045        }
3046        //				TRACE_MIKIE1("Update() - mTIM_7_CURRENT = %012d",mTIM_7_CURRENT);
3047        //				TRACE_MIKIE1("Update() - mTIM_7_BKUP    = %012d",mTIM_7_BKUP);
3048        //				TRACE_MIKIE1("Update() - mTIM_7_LASTCNT = %012d",mTIM_7_LAST_COUNT);
3049        //				TRACE_MIKIE1("Update() - mTIM_7_LINKING = %012d",mTIM_7_LINKING);
3050     }
3051  
3052     //
3053     // Timer 6 has no group
3054     //
3055     // KW bugfix 13/4/99 added (mTIM_x_ENABLE_RELOAD ||  ..)
3056     if(mTIM_6_ENABLE_COUNT && (mTIM_6_ENABLE_RELOAD || !mTIM_6_TIMER_DONE)) {
3057        //				if(mTIM_6_LINKING!=0x07)
3058        {
3059           // Ordinary clocked mode as opposed to linked mode
3060           // 16MHz clock down to 1us == cyclecount >> 4
3061           divide=(4+mTIM_6_LINKING);
3062           decval=(gSystemCycleCount-mTIM_6_LAST_COUNT)>>divide;
3063  
3064           if(decval) {
3065              mTIM_6_LAST_COUNT+=decval<<divide;
3066              mTIM_6_CURRENT-=decval;
3067              if(mTIM_6_CURRENT&0x80000000) {
3068                 // Set carry out
3069                 mTIM_6_BORROW_OUT=TRUE;
3070  
3071                 // Set the timer status flag
3072                 if(mTimerInterruptMask&0x40) {
3073                    TRACE_MIKIE0("Update() - TIMER6 IRQ Triggered");
3074                    mTimerStatusFlags|=0x40;
3075                    gSystemIRQ=TRUE;	// Added 19/09/06 fix for IRQ issue
3076                 }
3077  
3078                 // Reload if necessary
3079                 if(mTIM_6_ENABLE_RELOAD) {
3080                    mTIM_6_CURRENT+=mTIM_6_BKUP+1;
3081                 } else {
3082                    mTIM_6_CURRENT=0;
3083                 }
3084                 mTIM_6_TIMER_DONE=TRUE;
3085              } else {
3086                 mTIM_6_BORROW_OUT=FALSE;
3087              }
3088              // Set carry in as we did a count
3089              mTIM_6_BORROW_IN=TRUE;
3090           } else {
3091              // Clear carry in as we didn't count
3092              mTIM_6_BORROW_IN=FALSE;
3093              // Clear carry out
3094              mTIM_6_BORROW_OUT=FALSE;
3095           }
3096        }
3097  
3098        // Prediction for next timer event cycle number
3099        // (Timer 6 doesn't support linking)
3100  
3101        //				if(mTIM_6_LINKING!=7)
3102        {
3103           // Sometimes timeupdates can be >2x rollover in which case
3104           // then CURRENT may still be negative and we can use it to
3105           // calc the next timer value, we just want another update ASAP
3106           tmp=(mTIM_6_CURRENT&0x80000000)?1:((mTIM_6_CURRENT+1)<<divide);
3107           tmp+=gSystemCycleCount;
3108           if(tmp<gNextTimerEvent) {
3109              gNextTimerEvent=tmp;
3110              TRACE_MIKIE1("Update() - TIMER 6 Set NextTimerEvent = %012d",gNextTimerEvent);
3111           }
3112        }
3113        //				TRACE_MIKIE1("Update() - mTIM_6_CURRENT = %012d",mTIM_6_CURRENT);
3114        //				TRACE_MIKIE1("Update() - mTIM_6_BKUP    = %012d",mTIM_6_BKUP);
3115        //				TRACE_MIKIE1("Update() - mTIM_6_LASTCNT = %012d",mTIM_6_LAST_COUNT);
3116        //				TRACE_MIKIE1("Update() - mTIM_6_LINKING = %012d",mTIM_6_LINKING);
3117     }
3118  
3119     //
3120     // If sound is enabled then update the sound subsystem
3121     //
3122     if(gAudioEnabled) {
3123        UpdateCalcSound();
3124        UpdateSound();
3125     }
3126  
3127     //			TRACE_MIKIE1("Update() - NextTimerEvent = %012d",gNextTimerEvent);
3128  
3129     // Update system IRQ status as a result of timer activity
3130     gSystemIRQ=(mTimerStatusFlags)?true:false;
3131     if(gSystemIRQ && gSystemCPUSleep) {gSystemCPUSleep=gSystemCPUSleep_Saved=FALSE;/*puts("ARLARM"); */ }
3132     //else if(gSuzieDoneTime) gSystemCPUSleep=TRUE;
3133  
3134     // Now all the timer updates are done we can increment the system
3135     // counter for any work done within the Update() function, gSystemCycleCounter
3136     // cannot be updated until this point otherwise it screws up the counters.
3137     gSystemCycleCount+=mikie_work_done;
3138  }
3139  
3140  inline void CMikie::UpdateCalcSound(void)
3141  {
3142     SLONG divide = 0;
3143     SLONG decval = 0;
3144     ULONG tmp = 0;
3145     //
3146     // Audio 0
3147     //
3148     // if(mAUDIO_0_ENABLE_COUNT && (mAUDIO_0_ENABLE_RELOAD || !mAUDIO_0_TIMER_DONE))
3149     if(mAUDIO_0_ENABLE_COUNT && (mAUDIO_0_ENABLE_RELOAD || !mAUDIO_0_TIMER_DONE) && mAUDIO_0_VOLUME && mAUDIO_0_BKUP)
3150     {
3151        decval=0;
3152  
3153        if(mAUDIO_0_LINKING==0x07) {
3154           if(mTIM_7_BORROW_OUT) decval=1;
3155           mAUDIO_0_LAST_LINK_CARRY=mTIM_7_BORROW_OUT;
3156        } else {
3157           // Ordinary clocked mode as opposed to linked mode
3158           // 16MHz clock down to 1us == cyclecount >> 4
3159           divide=(4+mAUDIO_0_LINKING);
3160           decval=(gSystemCycleCount-mAUDIO_0_LAST_COUNT)>>divide;
3161        }
3162  
3163        if(decval) {
3164           mAUDIO_0_LAST_COUNT+=decval<<divide;
3165           mAUDIO_0_CURRENT-=decval;
3166           if(mAUDIO_0_CURRENT&0x80000000) {
3167              // Set carry out
3168              mAUDIO_0_BORROW_OUT=TRUE;
3169  
3170              // Reload if necessary
3171              if(mAUDIO_0_ENABLE_RELOAD) {
3172                 mAUDIO_0_CURRENT+=mAUDIO_0_BKUP+1;
3173                 if(mAUDIO_0_CURRENT&0x80000000) mAUDIO_0_CURRENT=0;
3174              } else {
3175                 // Set timer done
3176                 mAUDIO_0_TIMER_DONE=TRUE;
3177                 mAUDIO_0_CURRENT=0;
3178              }
3179  
3180              //
3181              // Update audio circuitry
3182              //
3183              mAUDIO_0_WAVESHAPER=GetLfsrNext(mAUDIO_0_WAVESHAPER);
3184  
3185              if(mAUDIO_0_INTEGRATE_ENABLE) {
3186                 SLONG temp=mAUDIO_OUTPUT[0];
3187                 if(mAUDIO_0_WAVESHAPER&0x0001) temp+=mAUDIO_0_VOLUME;
3188                 else temp-=mAUDIO_0_VOLUME;
3189                 if(temp>127) temp=127;
3190                 if(temp<-128) temp=-128;
3191                 mAUDIO_OUTPUT[0]=(SBYTE)temp;
3192              } else {
3193                 if(mAUDIO_0_WAVESHAPER&0x0001) mAUDIO_OUTPUT[0]=mAUDIO_0_VOLUME;
3194                 else mAUDIO_OUTPUT[0]=-mAUDIO_0_VOLUME;
3195              }
3196           } else {
3197              mAUDIO_0_BORROW_OUT=FALSE;
3198           }
3199           // Set carry in as we did a count
3200           mAUDIO_0_BORROW_IN=TRUE;
3201        } else {
3202           // Clear carry in as we didn't count
3203           mAUDIO_0_BORROW_IN=FALSE;
3204           // Clear carry out
3205           mAUDIO_0_BORROW_OUT=FALSE;
3206        }
3207  
3208        // Prediction for next timer event cycle number
3209  
3210        if(mAUDIO_0_LINKING!=7) {
3211           // Sometimes timeupdates can be >2x rollover in which case
3212           // then CURRENT may still be negative and we can use it to
3213           // calc the next timer value, we just want another update ASAP
3214           tmp=(mAUDIO_0_CURRENT&0x80000000)?1:((mAUDIO_0_CURRENT+1)<<divide);
3215           tmp+=gSystemCycleCount;
3216           if(tmp<gNextTimerEvent) {
3217              gNextTimerEvent=tmp;
3218              TRACE_MIKIE1("Update() - AUDIO 0 Set NextTimerEvent = %012d",gNextTimerEvent);
3219           }
3220        }
3221        //					TRACE_MIKIE1("Update() - mAUDIO_0_CURRENT = %012d",mAUDIO_0_CURRENT);
3222        //					TRACE_MIKIE1("Update() - mAUDIO_0_BKUP    = %012d",mAUDIO_0_BKUP);
3223        //					TRACE_MIKIE1("Update() - mAUDIO_0_LASTCNT = %012d",mAUDIO_0_LAST_COUNT);
3224        //					TRACE_MIKIE1("Update() - mAUDIO_0_LINKING = %012d",mAUDIO_0_LINKING);
3225     }
3226  
3227     //
3228     // Audio 1
3229     //
3230     // if(mAUDIO_1_ENABLE_COUNT && (mAUDIO_1_ENABLE_RELOAD || !mAUDIO_1_TIMER_DONE)) {
3231     if(mAUDIO_1_ENABLE_COUNT && (mAUDIO_1_ENABLE_RELOAD || !mAUDIO_1_TIMER_DONE) && mAUDIO_1_VOLUME && mAUDIO_1_BKUP)
3232     {
3233        decval=0;
3234  
3235        if(mAUDIO_1_LINKING==0x07) {
3236           if(mAUDIO_0_BORROW_OUT) decval=1;
3237           mAUDIO_1_LAST_LINK_CARRY=mAUDIO_0_BORROW_OUT;
3238        } else {
3239           // Ordinary clocked mode as opposed to linked mode
3240           // 16MHz clock down to 1us == cyclecount >> 4
3241           divide=(4+mAUDIO_1_LINKING);
3242           decval=(gSystemCycleCount-mAUDIO_1_LAST_COUNT)>>divide;
3243        }
3244  
3245        if(decval) {
3246           mAUDIO_1_LAST_COUNT+=decval<<divide;
3247           mAUDIO_1_CURRENT-=decval;
3248           if(mAUDIO_1_CURRENT&0x80000000) {
3249              // Set carry out
3250              mAUDIO_1_BORROW_OUT=TRUE;
3251  
3252              // Reload if necessary
3253              if(mAUDIO_1_ENABLE_RELOAD) {
3254                 mAUDIO_1_CURRENT+=mAUDIO_1_BKUP+1;
3255                 if(mAUDIO_1_CURRENT&0x80000000) mAUDIO_1_CURRENT=0;
3256              } else {
3257                 // Set timer done
3258                 mAUDIO_1_TIMER_DONE=TRUE;
3259                 mAUDIO_1_CURRENT=0;
3260              }
3261  
3262              //
3263              // Update audio circuitry
3264              //
3265              mAUDIO_1_WAVESHAPER=GetLfsrNext(mAUDIO_1_WAVESHAPER);
3266  
3267              if(mAUDIO_1_INTEGRATE_ENABLE) {
3268                 SLONG temp=mAUDIO_OUTPUT[1];
3269                 if(mAUDIO_1_WAVESHAPER&0x0001) temp+=mAUDIO_1_VOLUME;
3270                 else temp-=mAUDIO_1_VOLUME;
3271                 if(temp>127) temp=127;
3272                 if(temp<-128) temp=-128;
3273                 mAUDIO_OUTPUT[1]=(SBYTE)temp;
3274              } else {
3275                 if(mAUDIO_1_WAVESHAPER&0x0001) mAUDIO_OUTPUT[1]=mAUDIO_1_VOLUME;
3276                 else mAUDIO_OUTPUT[1]=-mAUDIO_1_VOLUME;
3277              }
3278           } else {
3279              mAUDIO_1_BORROW_OUT=FALSE;
3280           }
3281           // Set carry in as we did a count
3282           mAUDIO_1_BORROW_IN=TRUE;
3283        } else {
3284           // Clear carry in as we didn't count
3285           mAUDIO_1_BORROW_IN=FALSE;
3286           // Clear carry out
3287           mAUDIO_1_BORROW_OUT=FALSE;
3288        }
3289  
3290        // Prediction for next timer event cycle number
3291  
3292        if(mAUDIO_1_LINKING!=7) {
3293           // Sometimes timeupdates can be >2x rollover in which case
3294           // then CURRENT may still be negative and we can use it to
3295           // calc the next timer value, we just want another update ASAP
3296           tmp=(mAUDIO_1_CURRENT&0x80000000)?1:((mAUDIO_1_CURRENT+1)<<divide);
3297           tmp+=gSystemCycleCount;
3298           if(tmp<gNextTimerEvent) {
3299              gNextTimerEvent=tmp;
3300              TRACE_MIKIE1("Update() - AUDIO 1 Set NextTimerEvent = %012d",gNextTimerEvent);
3301           }
3302        }
3303        //					TRACE_MIKIE1("Update() - mAUDIO_1_CURRENT = %012d",mAUDIO_1_CURRENT);
3304        //					TRACE_MIKIE1("Update() - mAUDIO_1_BKUP    = %012d",mAUDIO_1_BKUP);
3305        //					TRACE_MIKIE1("Update() - mAUDIO_1_LASTCNT = %012d",mAUDIO_1_LAST_COUNT);
3306        //					TRACE_MIKIE1("Update() - mAUDIO_1_LINKING = %012d",mAUDIO_1_LINKING);
3307     }
3308  
3309     //
3310     // Audio 2
3311     //
3312     // if(mAUDIO_2_ENABLE_COUNT && (mAUDIO_2_ENABLE_RELOAD || !mAUDIO_2_TIMER_DONE))
3313     if(mAUDIO_2_ENABLE_COUNT && (mAUDIO_2_ENABLE_RELOAD || !mAUDIO_2_TIMER_DONE) && mAUDIO_2_VOLUME && mAUDIO_2_BKUP)
3314     {
3315        decval=0;
3316  
3317        if(mAUDIO_2_LINKING==0x07) {
3318           if(mAUDIO_1_BORROW_OUT) decval=1;
3319           mAUDIO_2_LAST_LINK_CARRY=mAUDIO_1_BORROW_OUT;
3320        } else {
3321           // Ordinary clocked mode as opposed to linked mode
3322           // 16MHz clock down to 1us == cyclecount >> 4
3323           divide=(4+mAUDIO_2_LINKING);
3324           decval=(gSystemCycleCount-mAUDIO_2_LAST_COUNT)>>divide;
3325        }
3326  
3327        if(decval) {
3328           mAUDIO_2_LAST_COUNT+=decval<<divide;
3329           mAUDIO_2_CURRENT-=decval;
3330           if(mAUDIO_2_CURRENT&0x80000000) {
3331              // Set carry out
3332              mAUDIO_2_BORROW_OUT=TRUE;
3333  
3334              // Reload if necessary
3335              if(mAUDIO_2_ENABLE_RELOAD) {
3336                 mAUDIO_2_CURRENT+=mAUDIO_2_BKUP+1;
3337                 if(mAUDIO_2_CURRENT&0x80000000) mAUDIO_2_CURRENT=0;
3338              } else {
3339                 // Set timer done
3340                 mAUDIO_2_TIMER_DONE=TRUE;
3341                 mAUDIO_2_CURRENT=0;
3342              }
3343  
3344              //
3345              // Update audio circuitry
3346              //
3347              mAUDIO_2_WAVESHAPER=GetLfsrNext(mAUDIO_2_WAVESHAPER);
3348  
3349              if(mAUDIO_2_INTEGRATE_ENABLE) {
3350                 SLONG temp=mAUDIO_OUTPUT[2];
3351                 if(mAUDIO_2_WAVESHAPER&0x0001) temp+=mAUDIO_2_VOLUME;
3352                 else temp-=mAUDIO_2_VOLUME;
3353                 if(temp>127) temp=127;
3354                 if(temp<-128) temp=-128;
3355                 mAUDIO_OUTPUT[2]=(SBYTE)temp;
3356              } else {
3357                 if(mAUDIO_2_WAVESHAPER&0x0001) mAUDIO_OUTPUT[2]=mAUDIO_2_VOLUME;
3358                 else mAUDIO_OUTPUT[2]=-mAUDIO_2_VOLUME;
3359              }
3360           } else {
3361              mAUDIO_2_BORROW_OUT=FALSE;
3362           }
3363           // Set carry in as we did a count
3364           mAUDIO_2_BORROW_IN=TRUE;
3365        } else {
3366           // Clear carry in as we didn't count
3367           mAUDIO_2_BORROW_IN=FALSE;
3368           // Clear carry out
3369           mAUDIO_2_BORROW_OUT=FALSE;
3370        }
3371  
3372        // Prediction for next timer event cycle number
3373  
3374        if(mAUDIO_2_LINKING!=7) {
3375           // Sometimes timeupdates can be >2x rollover in which case
3376           // then CURRENT may still be negative and we can use it to
3377           // calc the next timer value, we just want another update ASAP
3378           tmp=(mAUDIO_2_CURRENT&0x80000000)?1:((mAUDIO_2_CURRENT+1)<<divide);
3379           tmp+=gSystemCycleCount;
3380           if(tmp<gNextTimerEvent) {
3381              gNextTimerEvent=tmp;
3382              TRACE_MIKIE1("Update() - AUDIO 2 Set NextTimerEvent = %012d",gNextTimerEvent);
3383           }
3384        }
3385        //					TRACE_MIKIE1("Update() - mAUDIO_2_CURRENT = %012d",mAUDIO_2_CURRENT);
3386        //					TRACE_MIKIE1("Update() - mAUDIO_2_BKUP    = %012d",mAUDIO_2_BKUP);
3387        //					TRACE_MIKIE1("Update() - mAUDIO_2_LASTCNT = %012d",mAUDIO_2_LAST_COUNT);
3388        //					TRACE_MIKIE1("Update() - mAUDIO_2_LINKING = %012d",mAUDIO_2_LINKING);
3389     }
3390  
3391     //
3392     // Audio 3
3393     //
3394     // if(mAUDIO_3_ENABLE_COUNT && (mAUDIO_3_ENABLE_RELOAD || !mAUDIO_3_TIMER_DONE))
3395     if(mAUDIO_3_ENABLE_COUNT && (mAUDIO_3_ENABLE_RELOAD || !mAUDIO_3_TIMER_DONE) && mAUDIO_3_VOLUME && mAUDIO_3_BKUP)
3396     {
3397        decval=0;
3398  
3399        if(mAUDIO_3_LINKING==0x07) {
3400           if(mAUDIO_2_BORROW_OUT) decval=1;
3401           mAUDIO_3_LAST_LINK_CARRY=mAUDIO_2_BORROW_OUT;
3402        } else {
3403           // Ordinary clocked mode as opposed to linked mode
3404           // 16MHz clock down to 1us == cyclecount >> 4
3405           divide=(4+mAUDIO_3_LINKING);
3406           decval=(gSystemCycleCount-mAUDIO_3_LAST_COUNT)>>divide;
3407        }
3408  
3409        if(decval) {
3410           mAUDIO_3_LAST_COUNT+=decval<<divide;
3411           mAUDIO_3_CURRENT-=decval;
3412           if(mAUDIO_3_CURRENT&0x80000000) {
3413              // Set carry out
3414              mAUDIO_3_BORROW_OUT=TRUE;
3415  
3416              // Reload if necessary
3417              if(mAUDIO_3_ENABLE_RELOAD) {
3418                 mAUDIO_3_CURRENT+=mAUDIO_3_BKUP+1;
3419                 if(mAUDIO_3_CURRENT&0x80000000) mAUDIO_3_CURRENT=0;
3420              } else {
3421                 // Set timer done
3422                 mAUDIO_3_TIMER_DONE=TRUE;
3423                 mAUDIO_3_CURRENT=0;
3424              }
3425  
3426              //
3427              // Update audio circuitry
3428              //
3429              mAUDIO_3_WAVESHAPER=GetLfsrNext(mAUDIO_3_WAVESHAPER);
3430  
3431              if(mAUDIO_3_INTEGRATE_ENABLE) {
3432                 SLONG temp=mAUDIO_OUTPUT[3];
3433                 if(mAUDIO_3_WAVESHAPER&0x0001) temp+=mAUDIO_3_VOLUME;
3434                 else temp-=mAUDIO_3_VOLUME;
3435                 if(temp>127) temp=127;
3436                 if(temp<-128) temp=-128;
3437                 mAUDIO_OUTPUT[3]=(SBYTE)temp;
3438              } else {
3439                 if(mAUDIO_3_WAVESHAPER&0x0001) mAUDIO_OUTPUT[3]=mAUDIO_3_VOLUME;
3440                 else mAUDIO_OUTPUT[3]=-mAUDIO_3_VOLUME;
3441              }
3442           } else {
3443              mAUDIO_3_BORROW_OUT=FALSE;
3444           }
3445           // Set carry in as we did a count
3446           mAUDIO_3_BORROW_IN=TRUE;
3447        } else {
3448           // Clear carry in as we didn't count
3449           mAUDIO_3_BORROW_IN=FALSE;
3450           // Clear carry out
3451           mAUDIO_3_BORROW_OUT=FALSE;
3452        }
3453  
3454        // Prediction for next timer event cycle number
3455  
3456        if(mAUDIO_3_LINKING!=7) {
3457           // Sometimes timeupdates can be >2x rollover in which case
3458           // then CURRENT may still be negative and we can use it to
3459           // calc the next timer value, we just want another update ASAP
3460           tmp=(mAUDIO_3_CURRENT&0x80000000)?1:((mAUDIO_3_CURRENT+1)<<divide);
3461           tmp+=gSystemCycleCount;
3462           if(tmp<gNextTimerEvent) {
3463              gNextTimerEvent=tmp;
3464              TRACE_MIKIE1("Update() - AUDIO 3 Set NextTimerEvent = %012d",gNextTimerEvent);
3465           }
3466        }
3467        //					TRACE_MIKIE1("Update() - mAUDIO_3_CURRENT = %012d",mAUDIO_3_CURRENT);
3468        //					TRACE_MIKIE1("Update() - mAUDIO_3_BKUP    = %012d",mAUDIO_3_BKUP);
3469        //					TRACE_MIKIE1("Update() - mAUDIO_3_LASTCNT = %012d",mAUDIO_3_LAST_COUNT);
3470        //					TRACE_MIKIE1("Update() - mAUDIO_3_LINKING = %012d",mAUDIO_3_LINKING);
3471     }
3472  }
3473  
3474  inline void CMikie::UpdateSound(void)
3475  {
3476     int samples = (gSystemCycleCount-gAudioLastUpdateCycle)/HANDY_AUDIO_SAMPLE_PERIOD;
3477     if (samples == 0) return;
3478  
3479     int cur_lsample = 0;
3480     int cur_rsample = 0;
3481  
3482     for(int x = 0; x < 4; x++){
3483        /// Assumption (seems there is no documentation for the Attenuation registers)
3484        /// a) they are linear from $0 to $f - checked!
3485        /// b) an attenuation of $0 is equal to channel OFF (bits in mSTEREO not set) - checked!
3486        /// c) an attenuation of $f is NOT equal to no attenuation (bits in PAN not set), $10 would be - checked!
3487        /// These assumptions can only checked with an oscilloscope... - done
3488        /// the values stored in mSTEREO are NOT bit-inverted ...
3489        /// mSTEREO was found to be set like that already (why?), but unused
3490  
3491        if(!(mSTEREO & (0x10 << x))) {
3492           if(mPAN & (0x10 << x))
3493              cur_lsample += (mAUDIO_OUTPUT[x]*(mAUDIO_ATTEN[x]&0xF0))/(16*16); /// NOT /15*16 see remark above
3494           else
3495              cur_lsample += mAUDIO_OUTPUT[x];
3496        }
3497        if(!(mSTEREO & (0x01 << x))) {
3498           if(mPAN & (0x01 << x))
3499              cur_rsample += (mAUDIO_OUTPUT[x]*(mAUDIO_ATTEN[x]&0x0F))/16; /// NOT /15 see remark above
3500           else
3501              cur_rsample += mAUDIO_OUTPUT[x];
3502        }
3503     }
3504  
3505     SWORD sample_l = (cur_lsample << 5);
3506     SWORD sample_r = (cur_rsample << 5);
3507  
3508     for(; samples > 0; --samples)
3509     {
3510        gAudioBuffer[gAudioBufferPointer++] = (sample_l<<16)+sample_r;
3511        //gAudioBuffer[gAudioBufferPointer++] = sample_r;
3512        gAudioBufferPointer &= (AUDIO_BUFFER_LENGTH-1);
3513        gAudioLastUpdateCycle += HANDY_AUDIO_SAMPLE_PERIOD;
3514     }
3515  }