#define MIKIE_CPP
#include "system.h"
#include "mikie.h"
#include "lynxdef.h"
CMikie::CMikie(CSystem& parent)
:mSystem(parent)
{
TRACE_MIKIE0("CMikie()");
int loop;
for(loop=0;loop<16;loop++) mPalette[loop].Index=loop;
DisplaySetAttributes();
Reset();
}
CMikie::~CMikie()
{
TRACE_MIKIE0("~CMikie()");
}
void CMikie::SetCPUSleep() { mSystem.gSystemCPUSleep = true; }
void CMikie::ClearCPUSleep() { mSystem.gSystemCPUSleep = false; }
void CMikie::Reset()
{
TRACE_MIKIE0("Reset()");
mAudioInputComparator=FALSE;
mDisplayAddress=0x00;
mLynxLine=0;
mLynxLineDMACounter=0;
mLynxAddr=0;
mpDisplayCurrentLine = 0;
mTimerStatusFlags=0x00;
mTimerInterruptMask=0x00;
mpRamPointer=mSystem.GetRamPointer();
mTIM_0_BKUP=0;
mTIM_0_ENABLE_RELOAD=0;
mTIM_0_ENABLE_COUNT=0;
mTIM_0_LINKING=0;
mTIM_0_CURRENT=0;
mTIM_0_TIMER_DONE=0;
mTIM_0_LAST_CLOCK=0;
mTIM_0_BORROW_IN=0;
mTIM_0_BORROW_OUT=0;
mTIM_0_LAST_LINK_CARRY=0;
mTIM_0_LAST_COUNT=0;
mTIM_1_BKUP=0;
mTIM_1_ENABLE_RELOAD=0;
mTIM_1_ENABLE_COUNT=0;
mTIM_1_LINKING=0;
mTIM_1_CURRENT=0;
mTIM_1_TIMER_DONE=0;
mTIM_1_LAST_CLOCK=0;
mTIM_1_BORROW_IN=0;
mTIM_1_BORROW_OUT=0;
mTIM_1_LAST_LINK_CARRY=0;
mTIM_1_LAST_COUNT=0;
mTIM_2_BKUP=0;
mTIM_2_ENABLE_RELOAD=0;
mTIM_2_ENABLE_COUNT=0;
mTIM_2_LINKING=0;
mTIM_2_CURRENT=0;
mTIM_2_TIMER_DONE=0;
mTIM_2_LAST_CLOCK=0;
mTIM_2_BORROW_IN=0;
mTIM_2_BORROW_OUT=0;
mTIM_2_LAST_LINK_CARRY=0;
mTIM_2_LAST_COUNT=0;
mTIM_3_BKUP=0;
mTIM_3_ENABLE_RELOAD=0;
mTIM_3_ENABLE_COUNT=0;
mTIM_3_LINKING=0;
mTIM_3_CURRENT=0;
mTIM_3_TIMER_DONE=0;
mTIM_3_LAST_CLOCK=0;
mTIM_3_BORROW_IN=0;
mTIM_3_BORROW_OUT=0;
mTIM_3_LAST_LINK_CARRY=0;
mTIM_3_LAST_COUNT=0;
mTIM_4_BKUP=0;
mTIM_4_ENABLE_RELOAD=0;
mTIM_4_ENABLE_COUNT=0;
mTIM_4_LINKING=0;
mTIM_4_CURRENT=0;
mTIM_4_TIMER_DONE=0;
mTIM_4_LAST_CLOCK=0;
mTIM_4_BORROW_IN=0;
mTIM_4_BORROW_OUT=0;
mTIM_4_LAST_LINK_CARRY=0;
mTIM_4_LAST_COUNT=0;
mTIM_5_BKUP=0;
mTIM_5_ENABLE_RELOAD=0;
mTIM_5_ENABLE_COUNT=0;
mTIM_5_LINKING=0;
mTIM_5_CURRENT=0;
mTIM_5_TIMER_DONE=0;
mTIM_5_LAST_CLOCK=0;
mTIM_5_BORROW_IN=0;
mTIM_5_BORROW_OUT=0;
mTIM_5_LAST_LINK_CARRY=0;
mTIM_5_LAST_COUNT=0;
mTIM_6_BKUP=0;
mTIM_6_ENABLE_RELOAD=0;
mTIM_6_ENABLE_COUNT=0;
mTIM_6_LINKING=0;
mTIM_6_CURRENT=0;
mTIM_6_TIMER_DONE=0;
mTIM_6_LAST_CLOCK=0;
mTIM_6_BORROW_IN=0;
mTIM_6_BORROW_OUT=0;
mTIM_6_LAST_LINK_CARRY=0;
mTIM_6_LAST_COUNT=0;
mTIM_7_BKUP=0;
mTIM_7_ENABLE_RELOAD=0;
mTIM_7_ENABLE_COUNT=0;
mTIM_7_LINKING=0;
mTIM_7_CURRENT=0;
mTIM_7_TIMER_DONE=0;
mTIM_7_LAST_CLOCK=0;
mTIM_7_BORROW_IN=0;
mTIM_7_BORROW_OUT=0;
mTIM_7_LAST_LINK_CARRY=0;
mTIM_7_LAST_COUNT=0;
for(int y = 0; y < 4; y++)
{
mAUDIO_BKUP[y]=0;
mAUDIO_ENABLE_RELOAD[y]=0;
mAUDIO_ENABLE_COUNT[y]=0;
mAUDIO_LINKING[y]=0;
mAUDIO_CURRENT[y]=0;
mAUDIO_TIMER_DONE[y]=0;
mAUDIO_LAST_CLOCK[y]=0;
mAUDIO_BORROW_IN[y]=0;
mAUDIO_BORROW_OUT[y]=0;
mAUDIO_LAST_LINK_CARRY[y]=0;
mAUDIO_LAST_COUNT[y]=0;
mAUDIO_VOLUME[y]=0;
mAUDIO_INTEGRATE_ENABLE[y]=0;
mAUDIO_WAVESHAPER[y]=0;
mAUDIO_OUTPUT[y] = 0;
}
mSTEREO=0xff;
mPAN=0x00;
mAUDIO_ATTEN[0]=0xff;
mAUDIO_ATTEN[1]=0xff;
mAUDIO_ATTEN[2]=0xff;
mAUDIO_ATTEN[3]=0xff;
for(int loop=0;loop<16;loop++)
{
mPalette[loop].Index=loop;
}
mIODAT=0x00;
mIODIR=0x00;
mIODAT_REST_SIGNAL=0x00;
mDISPCTL_DMAEnable=FALSE;
mDISPCTL_Flip=FALSE;
mDISPCTL_FourColour=0;
mDISPCTL_Colour=0;
mUART_RX_IRQ_ENABLE=0;
mUART_TX_IRQ_ENABLE=0;
mUART_TX_COUNTDOWN=UART_TX_INACTIVE;
mUART_RX_COUNTDOWN=UART_RX_INACTIVE;
mUART_Rx_input_ptr=0;
mUART_Rx_output_ptr=0;
mUART_Rx_waiting=0;
mUART_Rx_framing_error=0;
mUART_Rx_overun_error=0;
mUART_SENDBREAK=0;
mUART_TX_DATA=0;
mUART_RX_DATA=0;
mUART_RX_READY=0;
mUART_PARITY_ENABLE=0;
mUART_PARITY_EVEN=0;
}
uint32 CMikie::GetLfsrNext(uint32 current)
{
uint32 switches,lfsr,next,swloop,result;
static const uint32 switchbits[9]={7,0,1,2,3,4,5,10,11};
switches=current>>12;
lfsr=current&0xfff;
result=0;
for(swloop=0;swloop<9;swloop++)
{
if((switches>>swloop)&0x001) result^=(lfsr>>switchbits[swloop])&0x001;
}
result=(result)?0:1;
next=(switches<<12)|((lfsr<<1)&0xffe)|result;
return next;
}
void CMikie::ComLynxCable(int status)
{
mUART_CABLE_PRESENT=status;
}
void CMikie::ComLynxRxData(int data)
{
TRACE_MIKIE1("ComLynxRxData() - Received %04x",data);
if(mUART_Rx_waiting<UART_MAX_RX_QUEUE)
{
if(!mUART_Rx_waiting) mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD;
mUART_Rx_input_queue[mUART_Rx_input_ptr]=data;
mUART_Rx_input_ptr = (mUART_Rx_input_ptr + 1) % UART_MAX_RX_QUEUE;
mUART_Rx_waiting++;
TRACE_MIKIE2("ComLynxRxData() - input ptr=%02d waiting=%02d",mUART_Rx_input_ptr,mUART_Rx_waiting);
}
else
{
TRACE_MIKIE0("ComLynxRxData() - UART RX Overun");
}
}
void CMikie::ComLynxTxLoopback(int data)
{
TRACE_MIKIE1("ComLynxTxLoopback() - Received %04x",data);
if(mUART_Rx_waiting<UART_MAX_RX_QUEUE)
{
if(!mUART_Rx_waiting) mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD;
mUART_Rx_output_ptr = (mUART_Rx_output_ptr - 1) % UART_MAX_RX_QUEUE;
mUART_Rx_input_queue[mUART_Rx_output_ptr]=data;
mUART_Rx_waiting++;
TRACE_MIKIE2("ComLynxTxLoopback() - input ptr=%02d waiting=%02d",mUART_Rx_input_ptr,mUART_Rx_waiting);
}
else
{
TRACE_MIKIE0("ComLynxTxLoopback() - UART RX Overun");
}
}
void CMikie::ComLynxTxCallback(void (*function)(int data,uint32 objref),uint32 objref)
{
mpUART_TX_CALLBACK=function;
mUART_TX_CALLBACK_OBJECT=objref;
}
void CMikie::DisplaySetAttributes()
{
TPALETTE Spot;
for(Spot.Index=0;Spot.Index<4096;Spot.Index++)
{
mColourMap[Spot.Index] =
0xff000000 |
(Spot.Colours.Red * 15 + 30) << 16 |
(Spot.Colours.Green * 15 + 30) << 8 |
(Spot.Colours.Blue * 15 + 30);
}
}
void CMikie::BlankLineSurface()
{
uint32* bitmap_tmp = framebuffer + mpDisplayCurrentLine * SCREEN_WIDTH;
for (int i = 0; i < SCREEN_WIDTH; i++)
bitmap_tmp[i] = 0xff000000;
}
void CMikie::CopyLineSurface()
{
uint32* bitmap_tmp = framebuffer + mpDisplayCurrentLine * SCREEN_WIDTH;
for (int loop = 0; loop < SCREEN_WIDTH / 2; loop++)
{
uint32 source = mpRamPointer[(uint16)mLynxAddr];
if(mDISPCTL_Flip)
{
mLynxAddr--;
*bitmap_tmp=mColourMap[mPalette[source&0x0f].Index];
bitmap_tmp++;
*bitmap_tmp=mColourMap[mPalette[source>>4].Index];
bitmap_tmp++;
}
else
{
mLynxAddr++;
*bitmap_tmp = mColourMap[mPalette[source>>4].Index];
bitmap_tmp++;
*bitmap_tmp = mColourMap[mPalette[source&0x0f].Index];
bitmap_tmp++;
}
}
}
uint32 CMikie::DisplayRenderLine()
{
uint32 work_done=0;
if(!mDISPCTL_DMAEnable) return 0;
if(mTimerInterruptMask&0x01)
{
TRACE_MIKIE0("Update() - TIMER0 IRQ Triggered (Line Timer)");
mTimerStatusFlags|=0x01;
}
if(mLynxLine==mTIM_2_BKUP-2 || mLynxLine==mTIM_2_BKUP-3 || mLynxLine==mTIM_2_BKUP-4) mIODAT_REST_SIGNAL=TRUE; else mIODAT_REST_SIGNAL=FALSE;
if(mLynxLine==(mTIM_2_BKUP-3))
{
if(mDISPCTL_Flip)
{
mLynxAddr=mDisplayAddress&0xfffc;
mLynxAddr+=3;
}
else
{
mLynxAddr=mDisplayAddress&0xfffc;
}
mLynxLineDMACounter=102;
}
if(mLynxLine) mLynxLine--;
if(mLynxLineDMACounter)
{
mLynxLineDMACounter--;
work_done+=80*DMA_RDWR_CYC;
if (mpDisplayCurrentLine < 102)
{
CopyLineSurface();
}
else
{
printf("Lynx Line Overflow: %d\n", mpDisplayCurrentLine);
}
mpDisplayCurrentLine++;
}
return work_done;
}
uint32 CMikie::DisplayEndOfFrame()
{
mLynxLineDMACounter=0;
mLynxLine=mTIM_2_BKUP;
if(mTimerInterruptMask&0x04)
{
TRACE_MIKIE0("Update() - TIMER2 IRQ Triggered (Frame Timer)");
mTimerStatusFlags|=0x04;
}
while (mpDisplayCurrentLine < 102)
{
BlankLineSurface();
mpDisplayCurrentLine++;
}
mSystem.Blit(framebuffer);
mpDisplayCurrentLine = 0;
return 0;
}
void CMikie::Poke(uint32 addr,uint8 data)
{
if(addr >= 0xFD20 && addr <= 0xFD3F)
{
int which = (addr - 0xFD20) >> 3;
switch(addr & 0x7)
{
case (AUD0VOL&0x7):
mAUDIO_VOLUME[which]=(int8)data;
TRACE_MIKIE2("Poke(AUD0VOL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0SHFTFB&0x7):
mAUDIO_WAVESHAPER[which]&=0x001fff;
mAUDIO_WAVESHAPER[which]|=(uint32)data<<13;
TRACE_MIKIE2("Poke(AUD0SHFTB,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0OUTVAL&0x7):
mAUDIO_OUTPUT[which]=data;
TRACE_MIKIE2("Poke(AUD0OUTVAL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0L8SHFT&0x7):
mAUDIO_WAVESHAPER[which]&=0x1fff00;
mAUDIO_WAVESHAPER[which]|=data;
TRACE_MIKIE2("Poke(AUD0L8SHFT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0TBACK&0x7):
mAUDIO_BKUP[which]=data;
TRACE_MIKIE2("Poke(AUD0TBACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0CTL&0x7):
mAUDIO_ENABLE_RELOAD[which]=data&0x10;
mAUDIO_ENABLE_COUNT[which]=data&0x08;
mAUDIO_LINKING[which]=data&0x07;
mAUDIO_INTEGRATE_ENABLE[which]=data&0x20;
if(data&0x40) mAUDIO_TIMER_DONE[which]=0;
mAUDIO_WAVESHAPER[which]&=0x1fefff;
mAUDIO_WAVESHAPER[which]|=(data&0x80)?0x001000:0x000000;
if(data&0x48)
{
mAUDIO_LAST_COUNT[which]=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(AUD0CTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0COUNT&0x7):
mAUDIO_CURRENT[which]=data;
TRACE_MIKIE2("Poke(AUD0COUNT,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (AUD0MISC&0x7):
mAUDIO_WAVESHAPER[which]&=0x1ff0ff;
mAUDIO_WAVESHAPER[which]|=(data&0xf0)<<4;
mAUDIO_BORROW_IN[which]=data&0x02;
mAUDIO_BORROW_OUT[which]=data&0x01;
mAUDIO_LAST_CLOCK[which]=data&0x04;
TRACE_MIKIE2("Poke(AUD0MISC,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
}
}
else switch(addr&0xff)
{
case (TIM0BKUP&0xff):
mTIM_0_BKUP=data;
TRACE_MIKIE2("Poke(TIM0BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM1BKUP&0xff):
mTIM_1_BKUP=data;
TRACE_MIKIE2("Poke(TIM1BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM2BKUP&0xff):
mTIM_2_BKUP=data;
TRACE_MIKIE2("Poke(TIM2BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM3BKUP&0xff):
mTIM_3_BKUP=data;
TRACE_MIKIE2("Poke(TIM3BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM4BKUP&0xff):
mTIM_4_BKUP=data;
TRACE_MIKIE2("Poke(TIM4BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM5BKUP&0xff):
mTIM_5_BKUP=data;
TRACE_MIKIE2("Poke(TIM5BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM6BKUP&0xff):
mTIM_6_BKUP=data;
TRACE_MIKIE2("Poke(TIM6BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM7BKUP&0xff):
mTIM_7_BKUP=data;
TRACE_MIKIE2("Poke(TIM7BKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM0CTLA&0xff):
mTimerInterruptMask&=(0x01^0xff);
mTimerInterruptMask|=(data&0x80)?0x01:0x00;
mTIM_0_ENABLE_RELOAD=data&0x10;
mTIM_0_ENABLE_COUNT=data&0x08;
mTIM_0_LINKING=data&0x07;
if(data&0x40) mTIM_0_TIMER_DONE=0;
if(data&0x48)
{
mTIM_0_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM0CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM1CTLA&0xff):
mTimerInterruptMask&=(0x02^0xff);
mTimerInterruptMask|=(data&0x80)?0x02:0x00;
mTIM_1_ENABLE_RELOAD=data&0x10;
mTIM_1_ENABLE_COUNT=data&0x08;
mTIM_1_LINKING=data&0x07;
if(data&0x40) mTIM_1_TIMER_DONE=0;
if(data&0x48)
{
mTIM_1_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM1CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM2CTLA&0xff):
mTimerInterruptMask&=(0x04^0xff);
mTimerInterruptMask|=(data&0x80)?0x04:0x00;
mTIM_2_ENABLE_RELOAD=data&0x10;
mTIM_2_ENABLE_COUNT=data&0x08;
mTIM_2_LINKING=data&0x07;
if(data&0x40) mTIM_2_TIMER_DONE=0;
if(data&0x48)
{
mTIM_2_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM2CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM3CTLA&0xff):
mTimerInterruptMask&=(0x08^0xff);
mTimerInterruptMask|=(data&0x80)?0x08:0x00;
mTIM_3_ENABLE_RELOAD=data&0x10;
mTIM_3_ENABLE_COUNT=data&0x08;
mTIM_3_LINKING=data&0x07;
if(data&0x40) mTIM_3_TIMER_DONE=0;
if(data&0x48)
{
mTIM_3_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM3CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM4CTLA&0xff):
mTIM_4_ENABLE_RELOAD=data&0x10;
mTIM_4_ENABLE_COUNT=data&0x08;
mTIM_4_LINKING=data&0x07;
if(data&0x40) mTIM_4_TIMER_DONE=0;
if(data&0x48)
{
mTIM_4_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM4CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM5CTLA&0xff):
mTimerInterruptMask&=(0x20^0xff);
mTimerInterruptMask|=(data&0x80)?0x20:0x00;
mTIM_5_ENABLE_RELOAD=data&0x10;
mTIM_5_ENABLE_COUNT=data&0x08;
mTIM_5_LINKING=data&0x07;
if(data&0x40) mTIM_5_TIMER_DONE=0;
if(data&0x48)
{
mTIM_5_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM5CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM6CTLA&0xff):
mTimerInterruptMask&=(0x40^0xff);
mTimerInterruptMask|=(data&0x80)?0x40:0x00;
mTIM_6_ENABLE_RELOAD=data&0x10;
mTIM_6_ENABLE_COUNT=data&0x08;
mTIM_6_LINKING=data&0x07;
if(data&0x40) mTIM_6_TIMER_DONE=0;
if(data&0x48)
{
mTIM_6_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM6CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM7CTLA&0xff):
mTimerInterruptMask&=(0x80^0xff);
mTimerInterruptMask|=(data&0x80)?0x80:0x00;
mTIM_7_ENABLE_RELOAD=data&0x10;
mTIM_7_ENABLE_COUNT=data&0x08;
mTIM_7_LINKING=data&0x07;
if(data&0x40) mTIM_7_TIMER_DONE=0;
if(data&0x48)
{
mTIM_7_LAST_COUNT=mSystem.gSystemCycleCount;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
}
TRACE_MIKIE2("Poke(TIM7CTLA,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM0CNT&0xff):
mTIM_0_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM0CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM1CNT&0xff):
mTIM_1_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM1CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM2CNT&0xff):
mTIM_2_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM2CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM3CNT&0xff):
mTIM_3_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM3CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM4CNT&0xff):
mTIM_4_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM4CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM5CNT&0xff):
mTIM_5_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM5CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM6CNT&0xff):
mTIM_6_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM6CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM7CNT&0xff):
mTIM_7_CURRENT=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(TIM7CNT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM0CTLB&0xff):
mTIM_0_TIMER_DONE=data&0x08;
mTIM_0_LAST_CLOCK=data&0x04;
mTIM_0_BORROW_IN=data&0x02;
mTIM_0_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM0CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM1CTLB&0xff):
mTIM_1_TIMER_DONE=data&0x08;
mTIM_1_LAST_CLOCK=data&0x04;
mTIM_1_BORROW_IN=data&0x02;
mTIM_1_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM1CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM2CTLB&0xff):
mTIM_2_TIMER_DONE=data&0x08;
mTIM_2_LAST_CLOCK=data&0x04;
mTIM_2_BORROW_IN=data&0x02;
mTIM_2_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM2CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM3CTLB&0xff):
mTIM_3_TIMER_DONE=data&0x08;
mTIM_3_LAST_CLOCK=data&0x04;
mTIM_3_BORROW_IN=data&0x02;
mTIM_3_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM3CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM4CTLB&0xff):
mTIM_4_TIMER_DONE=data&0x08;
mTIM_4_LAST_CLOCK=data&0x04;
mTIM_4_BORROW_IN=data&0x02;
mTIM_4_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM4CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM5CTLB&0xff):
mTIM_5_TIMER_DONE=data&0x08;
mTIM_5_LAST_CLOCK=data&0x04;
mTIM_5_BORROW_IN=data&0x02;
mTIM_5_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM5CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM6CTLB&0xff):
mTIM_6_TIMER_DONE=data&0x08;
mTIM_6_LAST_CLOCK=data&0x04;
mTIM_6_BORROW_IN=data&0x02;
mTIM_6_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM6CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (TIM7CTLB&0xff):
mTIM_7_TIMER_DONE=data&0x08;
mTIM_7_LAST_CLOCK=data&0x04;
mTIM_7_BORROW_IN=data&0x02;
mTIM_7_BORROW_OUT=data&0x01;
TRACE_MIKIE2("Poke(TIM7CTLB ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (ATTEN_A&0xff):
mAUDIO_ATTEN[0] = data;
TRACE_MIKIE2("Poke(ATTEN_A ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (ATTEN_B&0xff):
mAUDIO_ATTEN[1] = data;
TRACE_MIKIE2("Poke(ATTEN_B ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (ATTEN_C&0xff):
mAUDIO_ATTEN[2] = data;
TRACE_MIKIE2("Poke(ATTEN_C ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (ATTEN_D&0xff):
mAUDIO_ATTEN[3] = data;
TRACE_MIKIE2("Poke(ATTEN_D ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (MPAN&0xff):
TRACE_MIKIE2("Poke(MPAN ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mPAN = data;
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (MSTEREO&0xff):
TRACE_MIKIE2("Poke(MSTEREO ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
data^=0xff;
mSTEREO=data;
CombobulateSound(mSystem.gSystemCycleCount - startTS);
break;
case (INTRST&0xff):
data^=0xff;
mTimerStatusFlags&=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
TRACE_MIKIE2("Poke(INTRST ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (INTSET&0xff):
TRACE_MIKIE2("Poke(INTSET ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mTimerStatusFlags|=data;
mSystem.gNextTimerEvent=mSystem.gSystemCycleCount;
break;
case (SYSCTL1&0xff):
TRACE_MIKIE2("Poke(SYSCTL1 ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
if(!(data&0x02))
{
C6502_REGS regs;
mSystem.GetRegs(regs);
TRACE_MIKIE1("Runtime Alert - System Halted\nCMikie::Poke(SYSCTL1) - Lynx power down occured at PC=$%04x.\nResetting system.",regs.PC);
mSystem.gSystemHalt=TRUE;
}
mSystem.CartAddressStrobe((data&0x01)?TRUE:FALSE);
break;
case (MIKEYSREV&0xff):
TRACE_MIKIE2("Poke(MIKEYSREV,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (IODIR&0xff):
TRACE_MIKIE2("Poke(IODIR ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mIODIR=data;
break;
case (IODAT&0xff):
TRACE_MIKIE2("Poke(IODAT ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mIODAT=data;
mSystem.CartAddressData((mIODAT&0x02)?TRUE:FALSE);
if(mIODIR&0x10) mSystem.mCart->mWriteEnableBank1=(mIODAT&0x10)?true:false;
break;
case (SERCTL&0xff):
TRACE_MIKIE2("Poke(SERCTL ,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mUART_TX_IRQ_ENABLE=(data&0x80)?true:false;
mUART_RX_IRQ_ENABLE=(data&0x40)?true:false;
mUART_PARITY_ENABLE=(data&0x10)?true:false;
mUART_SENDBREAK=data&0x02;
mUART_PARITY_EVEN=data&0x01;
if(data&0x08)
{
mUART_Rx_overun_error=0;
mUART_Rx_framing_error=0;
}
if(mUART_SENDBREAK)
{
mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
ComLynxTxLoopback(UART_BREAK_CODE);
}
break;
case (SERDAT&0xff):
TRACE_MIKIE2("Poke(SERDAT ,%04x) at PC=%04x",data,mSystem.mCpu->GetPC());
mUART_TX_DATA=data;
if(mUART_PARITY_ENABLE)
{
}
else
{
if(mUART_PARITY_EVEN) data|=0x0100;
}
mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
ComLynxTxLoopback(mUART_TX_DATA);
break;
case (SDONEACK&0xff):
TRACE_MIKIE2("Poke(SDONEACK,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (CPUSLEEP&0xff):
mSystem.gSuzieDoneTime = mSystem.gSystemCycleCount+mSystem.PaintSprites();
SetCPUSleep();
break;
case (DISPCTL&0xff):
TRACE_MIKIE2("Poke(DISPCTL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
{
TDISPCTL tmp;
tmp.Byte=data;
mDISPCTL_DMAEnable=tmp.Bits.DMAEnable;
mDISPCTL_Flip=tmp.Bits.Flip;
mDISPCTL_FourColour=tmp.Bits.FourColour;
mDISPCTL_Colour=tmp.Bits.Colour;
}
break;
case (PBKUP&0xff):
TRACE_MIKIE2("Poke(PBKUP,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (DISPADRL&0xff):
TRACE_MIKIE2("Poke(DISPADRL,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mDisplayAddress&=0xff00;
mDisplayAddress+=data;
break;
case (DISPADRH&0xff):
TRACE_MIKIE2("Poke(DISPADRH,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mDisplayAddress&=0x00ff;
mDisplayAddress+=(data<<8);
break;
case (Mtest0&0xff):
case (Mtest1&0xff):
TRACE_MIKIE2("Poke(MTEST0/1,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
case (Mtest2&0xff):
TRACE_MIKIE2("Poke(MTEST2,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
break;
case (GREEN0&0xff):
case (GREEN1&0xff):
case (GREEN2&0xff):
case (GREEN3&0xff):
case (GREEN4&0xff):
case (GREEN5&0xff):
case (GREEN6&0xff):
case (GREEN7&0xff):
case (GREEN8&0xff):
case (GREEN9&0xff):
case (GREENA&0xff):
case (GREENB&0xff):
case (GREENC&0xff):
case (GREEND&0xff):
case (GREENE&0xff):
case (GREENF&0xff):
TRACE_MIKIE2("Poke(GREENPAL0-F,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mPalette[addr&0x0f].Colours.Green=data&0x0f;
break;
case (BLUERED0&0xff):
case (BLUERED1&0xff):
case (BLUERED2&0xff):
case (BLUERED3&0xff):
case (BLUERED4&0xff):
case (BLUERED5&0xff):
case (BLUERED6&0xff):
case (BLUERED7&0xff):
case (BLUERED8&0xff):
case (BLUERED9&0xff):
case (BLUEREDA&0xff):
case (BLUEREDB&0xff):
case (BLUEREDC&0xff):
case (BLUEREDD&0xff):
case (BLUEREDE&0xff):
case (BLUEREDF&0xff):
TRACE_MIKIE2("Poke(BLUEREDPAL0-F,%02x) at PC=%04x",data,mSystem.mCpu->GetPC());
mPalette[addr&0x0f].Colours.Blue=(data&0xf0)>>4;
mPalette[addr&0x0f].Colours.Red=data&0x0f;
break;
case (MAGRDY0&0xff):
case (MAGRDY1&0xff):
case (AUDIN&0xff):
case (MIKEYHREV&0xff):
TRACE_MIKIE3("Poke(%04x,%02x) - Poke to read only register location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
break;
default:
TRACE_MIKIE3("Poke(%04x,%02x) - Poke to illegal location at PC=%04x",addr,data,mSystem.mCpu->GetPC());
break;
}
}
uint8 CMikie::Peek(uint32 addr)
{
if(addr >= 0xFD20 && addr <= 0xFD3F)
{
int which = (addr - 0xFD20) >> 3;
switch(addr & 0x7)
{
case (AUD0VOL&0x7):
return (uint8)mAUDIO_VOLUME[which];
break;
case (AUD0SHFTFB&0x7):
return (uint8)((mAUDIO_WAVESHAPER[which]>>13)&0xff);
break;
case (AUD0OUTVAL&0x7):
return (uint8)mAUDIO_OUTPUT[which];
break;
case (AUD0L8SHFT&0x7):
return (uint8)(mAUDIO_WAVESHAPER[which]&0xff);
break;
case (AUD0TBACK&0x7):
return (uint8)mAUDIO_BKUP[which];
break;
case (AUD0CTL&0x7):
{
uint8 retval=0;
retval|=(mAUDIO_INTEGRATE_ENABLE[which])?0x20:0x00;
retval|=(mAUDIO_ENABLE_RELOAD[which])?0x10:0x00;
retval|=(mAUDIO_ENABLE_COUNT[which])?0x08:0x00;
retval|=(mAUDIO_WAVESHAPER[which]&0x001000)?0x80:0x00;
retval|=mAUDIO_LINKING[which];
return retval;
}
break;
case (AUD0COUNT&0x7):
return (uint8)mAUDIO_CURRENT[which];
break;
case (AUD0MISC&0x7):
{
uint8 retval=0;
retval|=(mAUDIO_BORROW_OUT[which])?0x01:0x00;
retval|=(mAUDIO_BORROW_IN[which])?0x02:0x00;
retval|=(mAUDIO_LAST_CLOCK[which])?0x08:0x00;
retval|=(mAUDIO_WAVESHAPER[which]>>4)&0xf0;
return retval;
}
break;
}
}
else switch(addr&0xff)
{
case (TIM0BKUP&0xff):
TRACE_MIKIE2("Peek(TIM0KBUP ,%02x) at PC=%04x",mTIM_0_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_0_BKUP;
break;
case (TIM1BKUP&0xff):
TRACE_MIKIE2("Peek(TIM1KBUP ,%02x) at PC=%04x",mTIM_1_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_1_BKUP;
break;
case (TIM2BKUP&0xff):
TRACE_MIKIE2("Peek(TIM2KBUP ,%02x) at PC=%04x",mTIM_2_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_2_BKUP;
break;
case (TIM3BKUP&0xff):
TRACE_MIKIE2("Peek(TIM3KBUP ,%02x) at PC=%04x",mTIM_3_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_3_BKUP;
break;
case (TIM4BKUP&0xff):
TRACE_MIKIE2("Peek(TIM4KBUP ,%02x) at PC=%04x",mTIM_4_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_4_BKUP;
break;
case (TIM5BKUP&0xff):
TRACE_MIKIE2("Peek(TIM5KBUP ,%02x) at PC=%04x",mTIM_5_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_5_BKUP;
break;
case (TIM6BKUP&0xff):
TRACE_MIKIE2("Peek(TIM6KBUP ,%02x) at PC=%04x",mTIM_6_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_6_BKUP;
break;
case (TIM7BKUP&0xff):
TRACE_MIKIE2("Peek(TIM7KBUP ,%02x) at PC=%04x",mTIM_7_BKUP,mSystem.mCpu->GetPC());
return (uint8)mTIM_7_BKUP;
break;
case (TIM0CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x01)?0x80:0x00;
retval|=(mTIM_0_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_0_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_0_LINKING;
TRACE_MIKIE2("Peek(TIM0CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM1CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x02)?0x80:0x00;
retval|=(mTIM_1_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_1_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_1_LINKING;
TRACE_MIKIE2("Peek(TIM1CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM2CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x04)?0x80:0x00;
retval|=(mTIM_2_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_2_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_2_LINKING;
TRACE_MIKIE2("Peek(TIM2CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM3CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x08)?0x80:0x00;
retval|=(mTIM_3_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_3_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_3_LINKING;
TRACE_MIKIE2("Peek(TIM3CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM4CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x10)?0x80:0x00;
retval|=(mTIM_4_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_4_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_4_LINKING;
TRACE_MIKIE2("Peek(TIM4CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM5CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x20)?0x80:0x00;
retval|=(mTIM_5_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_5_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_5_LINKING;
TRACE_MIKIE2("Peek(TIM5CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM6CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x40)?0x80:0x00;
retval|=(mTIM_6_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_6_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_6_LINKING;
TRACE_MIKIE2("Peek(TIM6CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM7CTLA&0xff):
{
uint8 retval=0;
retval|=(mTimerInterruptMask&0x80)?0x80:0x00;
retval|=(mTIM_7_ENABLE_RELOAD)?0x10:0x00;
retval|=(mTIM_7_ENABLE_COUNT)?0x08:0x00;
retval|=mTIM_7_LINKING;
TRACE_MIKIE2("Peek(TIM7CTLA ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM0CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM0CNT ,%02x) at PC=%04x",mTIM_0_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_0_CURRENT;
break;
case (TIM1CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM1CNT ,%02x) at PC=%04x",mTIM_1_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_1_CURRENT;
break;
case (TIM2CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM2CNT ,%02x) at PC=%04x",mTIM_2_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_2_CURRENT;
break;
case (TIM3CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM3CNT ,%02x) at PC=%04x",mTIM_3_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_3_CURRENT;
break;
case (TIM4CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM4CNT ,%02x) at PC=%04x",mTIM_4_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_4_CURRENT;
break;
case (TIM5CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM5CNT ,%02x) at PC=%04x",mTIM_5_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_5_CURRENT;
break;
case (TIM6CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM6CNT ,%02x) at PC=%04x",mTIM_6_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_6_CURRENT;
break;
case (TIM7CNT&0xff):
Update();
TRACE_MIKIE2("Peek(TIM7CNT ,%02x) at PC=%04x",mTIM_7_CURRENT,mSystem.mCpu->GetPC());
return (uint8)mTIM_7_CURRENT;
break;
case (TIM0CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_0_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_0_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_0_BORROW_IN)?0x02:0x00;
retval|=(mTIM_0_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM0CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM1CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_1_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_1_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_1_BORROW_IN)?0x02:0x00;
retval|=(mTIM_1_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM1CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM2CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_2_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_2_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_2_BORROW_IN)?0x02:0x00;
retval|=(mTIM_2_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM2CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM3CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_3_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_3_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_3_BORROW_IN)?0x02:0x00;
retval|=(mTIM_3_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM3CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM4CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_4_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_4_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_4_BORROW_IN)?0x02:0x00;
retval|=(mTIM_4_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM4CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM5CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_5_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_5_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_5_BORROW_IN)?0x02:0x00;
retval|=(mTIM_5_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM5CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM6CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_6_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_6_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_6_BORROW_IN)?0x02:0x00;
retval|=(mTIM_6_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM6CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (TIM7CTLB&0xff):
{
uint8 retval=0;
retval|=(mTIM_7_TIMER_DONE)?0x08:0x00;
retval|=(mTIM_7_LAST_CLOCK)?0x04:0x00;
retval|=(mTIM_7_BORROW_IN)?0x02:0x00;
retval|=(mTIM_7_BORROW_OUT)?0x01:0x00;
TRACE_MIKIE2("Peek(TIM7CTLB ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return retval;
}
break;
case (ATTEN_A&0xff):
TRACE_MIKIE1("Peek(ATTEN_A) at PC=%04x",mSystem.mCpu->GetPC());
return (uint8) mAUDIO_ATTEN[0];
break;
case (ATTEN_B&0xff):
TRACE_MIKIE1("Peek(ATTEN_B) at PC=%04x",mSystem.mCpu->GetPC());
return (uint8) mAUDIO_ATTEN[1];
break;
case (ATTEN_C&0xff):
TRACE_MIKIE1("Peek(ATTEN_C) at PC=%04x",mSystem.mCpu->GetPC());
return (uint8) mAUDIO_ATTEN[2];
break;
case (ATTEN_D&0xff):
TRACE_MIKIE1("Peek(ATTEN_D) at PC=%04x",mSystem.mCpu->GetPC());
return (uint8) mAUDIO_ATTEN[3];
break;
case (MPAN&0xff):
TRACE_MIKIE1("Peek(MPAN) at PC=%04x",mSystem.mCpu->GetPC());
return (uint8) mPAN;
break;
case (MSTEREO&0xff):
TRACE_MIKIE2("Peek(MSTEREO,%02x) at PC=%04x",(uint8)mSTEREO^0xff,mSystem.mCpu->GetPC());
return (uint8) mSTEREO^0xff;
break;
case (SERCTL&0xff):
{
uint32 retval=0;
retval|=(mUART_TX_COUNTDOWN&UART_TX_INACTIVE)?0xA0:0x00;
retval|=(mUART_RX_READY)?0x40:0x00;
retval|=(mUART_Rx_overun_error)?0x08:0x0;
retval|=(mUART_Rx_framing_error)?0x04:0x00;
retval|=(mUART_RX_DATA&UART_BREAK_CODE)?0x02:0x00;
retval|=(mUART_RX_DATA&0x0100)?0x01:0x00;
TRACE_MIKIE2("Peek(SERCTL ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return (uint8)retval;
}
break;
case (SERDAT&0xff):
mUART_RX_READY=0;
TRACE_MIKIE2("Peek(SERDAT ,%02x) at PC=%04x",(uint8)mUART_RX_DATA,mSystem.mCpu->GetPC());
return (uint8)(mUART_RX_DATA&0xff);
break;
case (IODAT&0xff):
{
uint32 retval=0;
retval|=(mIODIR&0x10)?mIODAT&0x10:0x10;
retval|=(mIODIR&0x08)?(((mIODAT&0x08)&&mIODAT_REST_SIGNAL)?0x00:0x08):0x00;
retval|=(mIODIR&0x04)?mIODAT&0x04:((mUART_CABLE_PRESENT)?0x04:0x00);
retval|=(mIODIR&0x02)?mIODAT&0x02:0x00;
retval|=(mIODIR&0x01)?mIODAT&0x01:0x01;
TRACE_MIKIE2("Peek(IODAT ,%02x) at PC=%04x",retval,mSystem.mCpu->GetPC());
return (uint8)retval;
}
break;
case (INTRST&0xff):
case (INTSET&0xff):
TRACE_MIKIE2("Peek(INTSET ,%02x) at PC=%04x",mTimerStatusFlags,mSystem.mCpu->GetPC());
return (uint8)mTimerStatusFlags;
break;
case (MAGRDY0&0xff):
case (MAGRDY1&0xff):
TRACE_MIKIE2("Peek(MAGRDY0/1,%02x) at PC=%04x",0x00,mSystem.mCpu->GetPC());
return 0x00;
break;
case (AUDIN&0xff):
TRACE_MIKIE2("Peek(AUDIN,%02x) at PC=%04x",0x80,mSystem.mCpu->GetPC());
return 0x80;
break;
case (MIKEYHREV&0xff):
TRACE_MIKIE2("Peek(MIKEYHREV,%02x) at PC=%04x",0x01,mSystem.mCpu->GetPC());
return 0x01;
break;
case (GREEN0&0xff):
case (GREEN1&0xff):
case (GREEN2&0xff):
case (GREEN3&0xff):
case (GREEN4&0xff):
case (GREEN5&0xff):
case (GREEN6&0xff):
case (GREEN7&0xff):
case (GREEN8&0xff):
case (GREEN9&0xff):
case (GREENA&0xff):
case (GREENB&0xff):
case (GREENC&0xff):
case (GREEND&0xff):
case (GREENE&0xff):
case (GREENF&0xff):
TRACE_MIKIE2("Peek(GREENPAL0-F,%02x) at PC=%04x",mPalette[addr&0x0f].Colours.Green,mSystem.mCpu->GetPC());
return mPalette[addr&0x0f].Colours.Green;
break;
case (BLUERED0&0xff):
case (BLUERED1&0xff):
case (BLUERED2&0xff):
case (BLUERED3&0xff):
case (BLUERED4&0xff):
case (BLUERED5&0xff):
case (BLUERED6&0xff):
case (BLUERED7&0xff):
case (BLUERED8&0xff):
case (BLUERED9&0xff):
case (BLUEREDA&0xff):
case (BLUEREDB&0xff):
case (BLUEREDC&0xff):
case (BLUEREDD&0xff):
case (BLUEREDE&0xff):
case (BLUEREDF&0xff):
TRACE_MIKIE2("Peek(BLUEREDPAL0-F,%02x) at PC=%04x",(mPalette[addr&0x0f].Colours.Red | (mPalette[addr&0x0f].Colours.Blue<<4)),mSystem.mCpu->GetPC());
return (mPalette[addr&0x0f].Colours.Red | (mPalette[addr&0x0f].Colours.Blue<<4));
break;
case (DISPADRL&0xff):
TRACE_MIKIE2("Peek(DISPADRL,%02x) at PC=%04x",(uint8)(mDisplayAddress&0xff),mSystem.mCpu->GetPC());
return (uint8)(mDisplayAddress&0xff);
case (DISPADRH&0xff):
TRACE_MIKIE2("Peek(DISPADRH,%02x) at PC=%04x",(uint8)(mDisplayAddress>>8)&0xff,mSystem.mCpu->GetPC());
return (uint8)(mDisplayAddress>>8)&0xff;
case (DISPCTL&0xff):
case (SYSCTL1&0xff):
case (MIKEYSREV&0xff):
case (IODIR&0xff):
case (SDONEACK&0xff):
case (CPUSLEEP&0xff):
case (PBKUP&0xff):
case (Mtest0&0xff):
case (Mtest1&0xff):
case (Mtest2&0xff):
TRACE_MIKIE2("Peek(%04x) - Peek from write only register location at PC=$%04x",addr,mSystem.mCpu->GetPC());
break;
case (0xfd97&0xff):
TRACE_MIKIE2("Peek(%04x) - **** HANDY DETECT ATTEMPTED **** at PC=$%04x",addr,mSystem.mCpu->GetPC());
return 0x42;
break;
default:
TRACE_MIKIE2("Peek(%04x) - Peek from illegal location at PC=$%04x",addr,mSystem.mCpu->GetPC());
break;
}
return 0xff;
}
void CMikie::CombobulateSound(uint32 teatime)
{
int cur_lsample = 0;
int cur_rsample = 0;
int x;
teatime >>= 2;
for(x = 0; x < 4; x++)
{
if(mSTEREO & (0x10 << x))
{
if(mPAN & (0x10 << x))
cur_lsample += (mAUDIO_OUTPUT[x]*(mAUDIO_ATTEN[x]&0xF0))/(15*16);
else
cur_lsample += mAUDIO_OUTPUT[x];
}
if(mSTEREO & (0x01 << x))
{
if(mPAN & (0x01 << x))
cur_rsample += (mAUDIO_OUTPUT[x]*(mAUDIO_ATTEN[x]&0x0F))/15;
else
cur_rsample += mAUDIO_OUTPUT[x];
}
}
if(cur_lsample != last_lsample)
{
miksynth.offset_inline(teatime, cur_lsample - last_lsample, mikbuf.left());
last_lsample = cur_lsample;
}
if(cur_rsample != last_rsample)
{
miksynth.offset_inline(teatime, cur_rsample - last_rsample, mikbuf.right());
last_rsample = cur_rsample;
}
}
void CMikie::CheckWrap()
{
#define DEC(X) do { if((X)) { (X) -= 0x80000000; } } while (0)
if(mSystem.gSystemCycleCount>0xf0000000)
{
DEC(mSystem.gSystemCycleCount);
DEC(mTIM_0_LAST_COUNT);
DEC(mTIM_1_LAST_COUNT);
DEC(mTIM_2_LAST_COUNT);
DEC(mTIM_3_LAST_COUNT);
DEC(mTIM_4_LAST_COUNT);
DEC(mTIM_5_LAST_COUNT);
DEC(mTIM_6_LAST_COUNT);
DEC(mTIM_7_LAST_COUNT);
DEC(mAUDIO_LAST_COUNT[0]);
DEC(mAUDIO_LAST_COUNT[1]);
DEC(mAUDIO_LAST_COUNT[2]);
DEC(mAUDIO_LAST_COUNT[3]);
DEC(startTS);
DEC(mSystem.gSuzieDoneTime);
DEC(mSystem.gNextTimerEvent);
}
#undef DEC
}
void CMikie::Update()
{
int32 divide;
int32 decval;
uint32 tmp;
uint32 mikie_work_done=0;
mSystem.gNextTimerEvent=0xffffffff;
if(mSystem.gSuzieDoneTime)
{
if(mSystem.gSystemCycleCount >= mSystem.gSuzieDoneTime)
{
ClearCPUSleep();
mSystem.gSuzieDoneTime = 0;
}
else if(mSystem.gSuzieDoneTime > mSystem.gSystemCycleCount) mSystem.gNextTimerEvent = mSystem.gSuzieDoneTime;
}
if(mTIM_0_ENABLE_COUNT)
{
{
divide=(4+mTIM_0_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_0_LAST_COUNT)>>divide;
if(decval)
{
mTIM_0_LAST_COUNT+=decval<<divide;
mTIM_0_CURRENT-=decval;
if(mTIM_0_CURRENT&0x80000000)
{
mTIM_0_BORROW_OUT=TRUE;
mTIM_0_CURRENT+=mTIM_0_BKUP+1;
mTIM_0_TIMER_DONE=TRUE;
mikie_work_done+=DisplayRenderLine();
}
else
{
mTIM_0_BORROW_OUT=FALSE;
}
mTIM_0_BORROW_IN=TRUE;
}
else
{
mTIM_0_BORROW_IN=FALSE;
mTIM_0_BORROW_OUT=FALSE;
}
}
{
tmp=(mTIM_0_CURRENT&0x80000000)?1:((mTIM_0_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
}
}
}
if(mTIM_2_ENABLE_COUNT)
{
decval=0;
{
if(mTIM_0_BORROW_OUT) decval=1;
mTIM_2_LAST_LINK_CARRY=mTIM_0_BORROW_OUT;
divide = 0;
}
if(decval)
{
mTIM_2_CURRENT-=decval;
if(mTIM_2_CURRENT&0x80000000)
{
mTIM_2_BORROW_OUT=TRUE;
mTIM_2_CURRENT+=mTIM_2_BKUP+1;
mTIM_2_TIMER_DONE=TRUE;
mikie_work_done+=DisplayEndOfFrame();
}
else
{
mTIM_2_BORROW_OUT=FALSE;
}
mTIM_2_BORROW_IN=TRUE;
}
else
{
mTIM_2_BORROW_IN=FALSE;
mTIM_2_BORROW_OUT=FALSE;
}
}
if(mTIM_4_ENABLE_COUNT)
{
decval=0;
{
divide=4+3+mTIM_4_LINKING;
decval=(mSystem.gSystemCycleCount-mTIM_4_LAST_COUNT)>>divide;
}
if(decval)
{
mTIM_4_LAST_COUNT+=decval<<divide;
mTIM_4_CURRENT-=decval;
if(mTIM_4_CURRENT&0x80000000)
{
mTIM_4_BORROW_OUT=TRUE;
if(!mUART_RX_COUNTDOWN)
{
if(mUART_Rx_waiting>0)
{
mUART_RX_DATA=mUART_Rx_input_queue[mUART_Rx_output_ptr];
mUART_Rx_output_ptr = (mUART_Rx_output_ptr + 1) % UART_MAX_RX_QUEUE;
mUART_Rx_waiting--;
TRACE_MIKIE2("Update() - RX Byte output ptr=%02d waiting=%02d",mUART_Rx_output_ptr,mUART_Rx_waiting);
}
else
{
TRACE_MIKIE0("Update() - RX Byte but no data waiting ????");
}
if(mUART_Rx_waiting>0)
{
mUART_RX_COUNTDOWN=UART_RX_TIME_PERIOD+UART_RX_NEXT_DELAY;
TRACE_MIKIE1("Update() - RX Byte retriggered, %d waiting",mUART_Rx_waiting);
}
else
{
mUART_RX_COUNTDOWN=UART_RX_INACTIVE;
TRACE_MIKIE0("Update() - RX Byte nothing waiting, deactivated");
}
if(mUART_RX_READY) mUART_Rx_overun_error=1;
mUART_RX_READY=1;
}
else if(!(mUART_RX_COUNTDOWN&UART_RX_INACTIVE))
{
mUART_RX_COUNTDOWN--;
}
if(!mUART_TX_COUNTDOWN)
{
if(mUART_SENDBREAK)
{
mUART_TX_DATA=UART_BREAK_CODE;
mUART_TX_COUNTDOWN=UART_TX_TIME_PERIOD;
ComLynxTxLoopback(mUART_TX_DATA);
}
else
{
mUART_TX_COUNTDOWN=UART_TX_INACTIVE;
}
if(mpUART_TX_CALLBACK)
{
TRACE_MIKIE0("Update() - UART_TX_CALLBACK");
(*mpUART_TX_CALLBACK)(mUART_TX_DATA,mUART_TX_CALLBACK_OBJECT);
}
}
else if(!(mUART_TX_COUNTDOWN&UART_TX_INACTIVE))
{
mUART_TX_COUNTDOWN--;
}
mTIM_4_CURRENT+=mTIM_4_BKUP+1;
if(mTIM_4_CURRENT&0x80000000)
{
mTIM_4_CURRENT=mTIM_4_BKUP;
mTIM_4_LAST_COUNT=mSystem.gSystemCycleCount;
}
}
}
tmp=(mTIM_4_CURRENT&0x80000000)?1:((mTIM_4_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 4 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
if((mUART_TX_COUNTDOWN&UART_TX_INACTIVE) && mUART_TX_IRQ_ENABLE)
{
TRACE_MIKIE0("Update() - UART TX IRQ Triggered");
mTimerStatusFlags|=0x10;
}
if(mUART_RX_READY && mUART_RX_IRQ_ENABLE)
{
TRACE_MIKIE0("Update() - UART RX IRQ Triggered");
mTimerStatusFlags|=0x10;
}
if(mTIM_1_ENABLE_COUNT && (mTIM_1_ENABLE_RELOAD || !mTIM_1_TIMER_DONE))
{
divide = 0;
if(mTIM_1_LINKING!=0x07)
{
divide=(4+mTIM_1_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_1_LAST_COUNT)>>divide;
if(decval)
{
mTIM_1_LAST_COUNT+=decval<<divide;
mTIM_1_CURRENT-=decval;
if(mTIM_1_CURRENT&0x80000000)
{
mTIM_1_BORROW_OUT=TRUE;
if(mTimerInterruptMask&0x02)
{
TRACE_MIKIE0("Update() - TIMER1 IRQ Triggered");
mTimerStatusFlags|=0x02;
}
if(mTIM_1_ENABLE_RELOAD)
{
mTIM_1_CURRENT+=mTIM_1_BKUP+1;
}
else
{
mTIM_1_CURRENT=0;
}
mTIM_1_TIMER_DONE=TRUE;
}
else
{
mTIM_1_BORROW_OUT=FALSE;
}
mTIM_1_BORROW_IN=TRUE;
}
else
{
mTIM_1_BORROW_IN=FALSE;
mTIM_1_BORROW_OUT=FALSE;
}
}
if(mTIM_1_LINKING!=7)
{
tmp=(mTIM_1_CURRENT&0x80000000)?1:((mTIM_1_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 1 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
if(mTIM_3_ENABLE_COUNT && (mTIM_3_ENABLE_RELOAD || !mTIM_3_TIMER_DONE))
{
decval=0;
if(mTIM_3_LINKING==0x07)
{
if(mTIM_1_BORROW_OUT) decval=1;
mTIM_3_LAST_LINK_CARRY=mTIM_1_BORROW_OUT;
divide = 0;
}
else
{
divide=(4+mTIM_3_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_3_LAST_COUNT)>>divide;
}
if(decval)
{
mTIM_3_LAST_COUNT+=decval<<divide;
mTIM_3_CURRENT-=decval;
if(mTIM_3_CURRENT&0x80000000)
{
mTIM_3_BORROW_OUT=TRUE;
if(mTimerInterruptMask&0x08)
{
TRACE_MIKIE0("Update() - TIMER3 IRQ Triggered");
mTimerStatusFlags|=0x08;
}
if(mTIM_3_ENABLE_RELOAD)
{
mTIM_3_CURRENT+=mTIM_3_BKUP+1;
}
else
{
mTIM_3_CURRENT=0;
}
mTIM_3_TIMER_DONE=TRUE;
}
else
{
mTIM_3_BORROW_OUT=FALSE;
}
mTIM_3_BORROW_IN=TRUE;
}
else
{
mTIM_3_BORROW_IN=FALSE;
mTIM_3_BORROW_OUT=FALSE;
}
if(mTIM_3_LINKING!=7)
{
tmp=(mTIM_3_CURRENT&0x80000000)?1:((mTIM_3_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 3 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
if(mTIM_5_ENABLE_COUNT && (mTIM_5_ENABLE_RELOAD || !mTIM_5_TIMER_DONE))
{
decval=0;
if(mTIM_5_LINKING==0x07)
{
if(mTIM_3_BORROW_OUT) decval=1;
mTIM_5_LAST_LINK_CARRY=mTIM_3_BORROW_OUT;
divide = 0;
}
else
{
divide=(4+mTIM_5_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_5_LAST_COUNT)>>divide;
}
if(decval)
{
mTIM_5_LAST_COUNT+=decval<<divide;
mTIM_5_CURRENT-=decval;
if(mTIM_5_CURRENT&0x80000000)
{
mTIM_5_BORROW_OUT=TRUE;
if(mTimerInterruptMask&0x20)
{
TRACE_MIKIE0("Update() - TIMER5 IRQ Triggered");
mTimerStatusFlags|=0x20;
}
if(mTIM_5_ENABLE_RELOAD)
{
mTIM_5_CURRENT+=mTIM_5_BKUP+1;
}
else
{
mTIM_5_CURRENT=0;
}
mTIM_5_TIMER_DONE=TRUE;
}
else
{
mTIM_5_BORROW_OUT=FALSE;
}
mTIM_5_BORROW_IN=TRUE;
}
else
{
mTIM_5_BORROW_IN=FALSE;
mTIM_5_BORROW_OUT=FALSE;
}
if(mTIM_5_LINKING!=7)
{
tmp=(mTIM_5_CURRENT&0x80000000)?1:((mTIM_5_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 5 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
if(mTIM_7_ENABLE_COUNT && (mTIM_7_ENABLE_RELOAD || !mTIM_7_TIMER_DONE))
{
decval=0;
if(mTIM_7_LINKING==0x07)
{
if(mTIM_5_BORROW_OUT) decval=1;
mTIM_7_LAST_LINK_CARRY=mTIM_5_BORROW_OUT;
divide = 0;
}
else
{
divide=(4+mTIM_7_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_7_LAST_COUNT)>>divide;
}
if(decval)
{
mTIM_7_LAST_COUNT+=decval<<divide;
mTIM_7_CURRENT-=decval;
if(mTIM_7_CURRENT&0x80000000)
{
mTIM_7_BORROW_OUT=TRUE;
if(mTimerInterruptMask&0x80)
{
TRACE_MIKIE0("Update() - TIMER7 IRQ Triggered");
mTimerStatusFlags|=0x80;
}
if(mTIM_7_ENABLE_RELOAD)
{
mTIM_7_CURRENT+=mTIM_7_BKUP+1;
}
else
{
mTIM_7_CURRENT=0;
}
mTIM_7_TIMER_DONE=TRUE;
}
else
{
mTIM_7_BORROW_OUT=FALSE;
}
mTIM_7_BORROW_IN=TRUE;
}
else
{
mTIM_7_BORROW_IN=FALSE;
mTIM_7_BORROW_OUT=FALSE;
}
if(mTIM_7_LINKING!=7)
{
tmp=(mTIM_7_CURRENT&0x80000000)?1:((mTIM_7_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 7 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
if(mTIM_6_ENABLE_COUNT && (mTIM_6_ENABLE_RELOAD || !mTIM_6_TIMER_DONE))
{
{
divide=(4+mTIM_6_LINKING);
decval=(mSystem.gSystemCycleCount-mTIM_6_LAST_COUNT)>>divide;
if(decval)
{
mTIM_6_LAST_COUNT+=decval<<divide;
mTIM_6_CURRENT-=decval;
if(mTIM_6_CURRENT&0x80000000)
{
mTIM_6_BORROW_OUT=TRUE;
if(mTimerInterruptMask&0x40)
{
TRACE_MIKIE0("Update() - TIMER6 IRQ Triggered");
mTimerStatusFlags|=0x40;
}
if(mTIM_6_ENABLE_RELOAD)
{
mTIM_6_CURRENT+=mTIM_6_BKUP+1;
}
else
{
mTIM_6_CURRENT=0;
}
mTIM_6_TIMER_DONE=TRUE;
}
else
{
mTIM_6_BORROW_OUT=FALSE;
}
mTIM_6_BORROW_IN=TRUE;
}
else
{
mTIM_6_BORROW_IN=FALSE;
mTIM_6_BORROW_OUT=FALSE;
}
}
{
tmp=(mTIM_6_CURRENT&0x80000000)?1:((mTIM_6_CURRENT+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - TIMER 6 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
{
int y;
for(y = 0; y < 4; y++)
{
if(mAUDIO_ENABLE_COUNT[y] && (mAUDIO_ENABLE_RELOAD[y] || !mAUDIO_TIMER_DONE[y]))
{
decval=0;
if(mAUDIO_LINKING[y]==0x07)
{
int bort;
if(y)
bort = mAUDIO_BORROW_OUT[y - 1];
else
bort = mTIM_7_BORROW_OUT;
if(bort) decval=1;
mAUDIO_LAST_LINK_CARRY[y]=bort;
divide = 0;
}
else
{
divide=(4+mAUDIO_LINKING[y]);
decval=(mSystem.gSystemCycleCount-mAUDIO_LAST_COUNT[y])>>divide;
}
if(decval)
{
mAUDIO_LAST_COUNT[y] += decval<<divide;
mAUDIO_CURRENT[y]-=decval;
if(mAUDIO_CURRENT[y]&0x80000000)
{
mAUDIO_BORROW_OUT[y]=TRUE;
if(mAUDIO_ENABLE_RELOAD[y])
{
mAUDIO_CURRENT[y]+=mAUDIO_BKUP[y]+1;
if(mAUDIO_CURRENT[y]&0x80000000) mAUDIO_CURRENT[y]=0;
}
else
{
mAUDIO_TIMER_DONE[y]=TRUE;
mAUDIO_CURRENT[y]=0;
}
if(mAUDIO_BKUP[y] || mAUDIO_LINKING[y])
mAUDIO_WAVESHAPER[y] = GetLfsrNext(mAUDIO_WAVESHAPER[y]);
if(mAUDIO_INTEGRATE_ENABLE[y])
{
int32 temp=mAUDIO_OUTPUT[y];
if(mAUDIO_WAVESHAPER[y]&0x0001) temp+=mAUDIO_VOLUME[y]; else temp-=mAUDIO_VOLUME[y];
if(temp>127) temp=127;
if(temp<-128) temp=-128;
mAUDIO_OUTPUT[y]=(int8)temp;
}
else
{
if(mAUDIO_WAVESHAPER[y]&0x0001) mAUDIO_OUTPUT[y]=mAUDIO_VOLUME[y]; else mAUDIO_OUTPUT[y]=-mAUDIO_VOLUME[y];
}
CombobulateSound(mSystem.gSystemCycleCount - startTS);
}
else
{
mAUDIO_BORROW_OUT[y]=FALSE;
}
mAUDIO_BORROW_IN[y]=TRUE;
}
else
{
mAUDIO_BORROW_IN[y]=FALSE;
mAUDIO_BORROW_OUT[y]=FALSE;
}
if(mAUDIO_LINKING[y]!=7)
{
tmp=(mAUDIO_CURRENT[y]&0x80000000)?1:((mAUDIO_CURRENT[y]+1)<<divide);
tmp+=mSystem.gSystemCycleCount;
if(tmp<mSystem.gNextTimerEvent)
{
mSystem.gNextTimerEvent=tmp;
TRACE_MIKIE1("Update() - AUDIO 0 Set NextTimerEvent = %012d",gNextTimerEvent);
}
}
}
}
}
mSystem.gSystemIRQ=(mTimerStatusFlags)?TRUE:FALSE;
if(mSystem.gSystemIRQ && mSystem.gSystemCPUSleep) { ClearCPUSleep(); }
mSystem.gSystemCycleCount+=mikie_work_done;
}
SYNCFUNC(CMikie)
{
NSS(startTS);
NSS(mpDisplayCurrentLine);
NSS(framebuffer);
NSS(last_lsample);
NSS(last_rsample);
NSS(mDisplayAddress);
NSS(mAudioInputComparator);
NSS(mTimerStatusFlags);
NSS(mTimerInterruptMask);
NSS(mPalette);
NSS(mColourMap);
NSS(mIODAT);
NSS(mIODIR);
NSS(mIODAT_REST_SIGNAL);
NSS(mDISPCTL_DMAEnable);
NSS(mDISPCTL_Flip);
NSS(mDISPCTL_FourColour);
NSS(mDISPCTL_Colour);
NSS(mTIM_0_BKUP);
NSS(mTIM_0_ENABLE_RELOAD);
NSS(mTIM_0_ENABLE_COUNT);
NSS(mTIM_0_LINKING);
NSS(mTIM_0_CURRENT);
NSS(mTIM_0_TIMER_DONE);
NSS(mTIM_0_LAST_CLOCK);
NSS(mTIM_0_BORROW_IN);
NSS(mTIM_0_BORROW_OUT);
NSS(mTIM_0_LAST_LINK_CARRY);
NSS(mTIM_0_LAST_COUNT);
NSS(mTIM_1_BKUP);
NSS(mTIM_1_ENABLE_RELOAD);
NSS(mTIM_1_ENABLE_COUNT);
NSS(mTIM_1_LINKING);
NSS(mTIM_1_CURRENT);
NSS(mTIM_1_TIMER_DONE);
NSS(mTIM_1_LAST_CLOCK);
NSS(mTIM_1_BORROW_IN);
NSS(mTIM_1_BORROW_OUT);
NSS(mTIM_1_LAST_LINK_CARRY);
NSS(mTIM_1_LAST_COUNT);
NSS(mTIM_2_BKUP);
NSS(mTIM_2_ENABLE_RELOAD);
NSS(mTIM_2_ENABLE_COUNT);
NSS(mTIM_2_LINKING);
NSS(mTIM_2_CURRENT);
NSS(mTIM_2_TIMER_DONE);
NSS(mTIM_2_LAST_CLOCK);
NSS(mTIM_2_BORROW_IN);
NSS(mTIM_2_BORROW_OUT);
NSS(mTIM_2_LAST_LINK_CARRY);
NSS(mTIM_2_LAST_COUNT);
NSS(mTIM_3_BKUP);
NSS(mTIM_3_ENABLE_RELOAD);
NSS(mTIM_3_ENABLE_COUNT);
NSS(mTIM_3_LINKING);
NSS(mTIM_3_CURRENT);
NSS(mTIM_3_TIMER_DONE);
NSS(mTIM_3_LAST_CLOCK);
NSS(mTIM_3_BORROW_IN);
NSS(mTIM_3_BORROW_OUT);
NSS(mTIM_3_LAST_LINK_CARRY);
NSS(mTIM_3_LAST_COUNT);
NSS(mTIM_4_BKUP);
NSS(mTIM_4_ENABLE_RELOAD);
NSS(mTIM_4_ENABLE_COUNT);
NSS(mTIM_4_LINKING);
NSS(mTIM_4_CURRENT);
NSS(mTIM_4_TIMER_DONE);
NSS(mTIM_4_LAST_CLOCK);
NSS(mTIM_4_BORROW_IN);
NSS(mTIM_4_BORROW_OUT);
NSS(mTIM_4_LAST_LINK_CARRY);
NSS(mTIM_4_LAST_COUNT);
NSS(mTIM_5_BKUP);
NSS(mTIM_5_ENABLE_RELOAD);
NSS(mTIM_5_ENABLE_COUNT);
NSS(mTIM_5_LINKING);
NSS(mTIM_5_CURRENT);
NSS(mTIM_5_TIMER_DONE);
NSS(mTIM_5_LAST_CLOCK);
NSS(mTIM_5_BORROW_IN);
NSS(mTIM_5_BORROW_OUT);
NSS(mTIM_5_LAST_LINK_CARRY);
NSS(mTIM_5_LAST_COUNT);
NSS(mTIM_6_BKUP);
NSS(mTIM_6_ENABLE_RELOAD);
NSS(mTIM_6_ENABLE_COUNT);
NSS(mTIM_6_LINKING);
NSS(mTIM_6_CURRENT);
NSS(mTIM_6_TIMER_DONE);
NSS(mTIM_6_LAST_CLOCK);
NSS(mTIM_6_BORROW_IN);
NSS(mTIM_6_BORROW_OUT);
NSS(mTIM_6_LAST_LINK_CARRY);
NSS(mTIM_6_LAST_COUNT);
NSS(mTIM_7_BKUP);
NSS(mTIM_7_ENABLE_RELOAD);
NSS(mTIM_7_ENABLE_COUNT);
NSS(mTIM_7_LINKING);
NSS(mTIM_7_CURRENT);
NSS(mTIM_7_TIMER_DONE);
NSS(mTIM_7_LAST_CLOCK);
NSS(mTIM_7_BORROW_IN);
NSS(mTIM_7_BORROW_OUT);
NSS(mTIM_7_LAST_LINK_CARRY);
NSS(mTIM_7_LAST_COUNT);
NSS(mAUDIO_BKUP);
NSS(mAUDIO_ENABLE_RELOAD);
NSS(mAUDIO_ENABLE_COUNT);
NSS(mAUDIO_LINKING);
NSS(mAUDIO_CURRENT);
NSS(mAUDIO_TIMER_DONE);
NSS(mAUDIO_LAST_CLOCK);
NSS(mAUDIO_BORROW_IN);
NSS(mAUDIO_BORROW_OUT);
NSS(mAUDIO_LAST_LINK_CARRY);
NSS(mAUDIO_LAST_COUNT);
NSS(mAUDIO_VOLUME);
NSS(mAUDIO_INTEGRATE_ENABLE);
NSS(mAUDIO_WAVESHAPER);
NSS(mAUDIO_OUTPUT);
NSS(mAUDIO_ATTEN);
NSS(mSTEREO);
NSS(mPAN);
NSS(mUART_RX_IRQ_ENABLE);
NSS(mUART_TX_IRQ_ENABLE);
NSS(mUART_RX_COUNTDOWN);
NSS(mUART_TX_COUNTDOWN);
NSS(mUART_SENDBREAK);
NSS(mUART_TX_DATA);
NSS(mUART_RX_DATA);
NSS(mUART_RX_READY);
NSS(mUART_PARITY_ENABLE);
NSS(mUART_PARITY_EVEN);
NSS(mUART_CABLE_PRESENT);
NSS(mUART_Rx_input_queue);
NSS(mUART_Rx_input_ptr);
NSS(mUART_Rx_output_ptr);
NSS(mUART_Rx_waiting);
NSS(mUART_Rx_framing_error);
NSS(mUART_Rx_overun_error);
NSS(mLynxLine);
NSS(mLynxLineDMACounter);
NSS(mLynxAddr);
}