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 }