1 /**************************************************** 2 *Part of SPC2IT, read readme.md for more information* 3 ****************************************************/ 4 5 /* 6 7 SNEeSe, an Open Source Super NES emulator. 8 9 10 Copyright (c) 1998-2006, Charles Bilyue'. 11 Portions copyright (c) 1998-2003, Brad Martin. 12 Portions copyright (c) 2003-2004, Daniel Horchner. 13 Portions copyright (c) 2004-2005, Nach. ( http://nsrt.edgeemu.com/ ) 14 Unzip Technology, copyright (c) 1998 Gilles Vollant. 15 zlib Technology ( www.gzip.org/zlib/ ), Copyright (c) 1995-2003, 16 Jean-loup Gailly ( jloup* *at* *gzip.org ) and Mark Adler 17 ( madler* *at* *alumni.caltech.edu ). 18 JMA Technology, copyright (c) 2004-2005 NSRT Team. ( http://nsrt.edgeemu.com/ ) 19 LZMA Technology, copyright (c) 2001-4 Igor Pavlov. ( http://www.7-zip.org ) 20 Portions copyright (c) 2002 Andrea Mazzoleni. ( http://advancemame.sf.net ) 21 22 This is free software. See './doc/LICENSE_SNEESE' for details. 23 You must read and accept the license prior to use. 24 25 */ 26 27 #define SNEeSe_apu_spc700_c 28 29 #include "sneese_spc.h" 30 31 SPC700_CONTEXT primary_context; 32 33 SPC700_CONTEXT *active_context = &primary_context; 34 35 /* 36 SNEeSe SPC700 CPU emulation core 37 Originally written by Lee Hammerton in AT&T assembly 38 Maintained/rewritten/ported to NASM by Charles Bilyue' 39 Maintained/ported to C by Charles Bilyue' 40 41 This file contains: 42 CPU core info 43 Reset 44 Execution Loop 45 Invalid Opcode Handler or Dispatcher 46 Variable definitions (registers, cycle counters, etc.) 47 CPU opcode emulation handlers 48 CPU opcode handler table 49 CPU opcode timing table 50 51 CPU core info: 52 A register - active_context->YA.b.A 53 Y register - active_context->YA.b.Y 54 YA register pair - active_context->YA.w 55 X register - active_context->X 56 Stack pointer - active_context->SP 57 Program Counter - active_context->PC 58 Processor status word - active_context->PSW 59 Individual flags - N_flag, V_flag, P_flag, B_flag, 60 H_flag, I_flag, Z_flag, C_flag 61 62 63 SPC timers 64 SPC700 timing is not directly related to 65c816 timing, but for 65 simplicity in emulation we act as if it is. SPC700 gets 5632 66 cycles for every 118125 (21.47727..MHz) 5A22 cycles. Since the 67 timers run at ~8KHz and ~64KHz and the CPU core runs at 68 1.024Mhz, the timers are clocked as follows: 69 1.024MHz / 8KHz = 128 cycles (Timers 0 and 1) 70 1.024MHz / 64KHz = 16 cycles (Timer 2) 71 */ 72 73 /* lots of #define's! */ 74 75 /* These are the bits for flag set/clr operations */ 76 #define SPC_FLAG_C 1 /* Carry */ 77 #define SPC_FLAG_Z 2 /* Zero result */ 78 #define SPC_FLAG_I 4 /* Interrupt Disable */ 79 #define SPC_FLAG_H 8 /* Half-carry */ 80 #define SPC_FLAG_B 0x10 /* Break */ 81 #define SPC_FLAG_P 0x20 /* Page (direct page) */ 82 #define SPC_FLAG_V 0x40 /* Overflow */ 83 #define SPC_FLAG_N 0x80 /* Negative result */ 84 85 #define SPC_FLAG_NZ (SPC_FLAG_N | SPC_FLAG_Z) 86 #define SPC_FLAG_NZC (SPC_FLAG_NZ | SPC_FLAG_C) 87 #define SPC_FLAG_NHZC (SPC_FLAG_NZC | SPC_FLAG_H) 88 89 #define _Cycles (active_context->Cycles) 90 #define _last_cycles (active_context->last_cycles) 91 #define _TotalCycles (active_context->TotalCycles) 92 #define _WorkCycles (active_context->WorkCycles) 93 94 #define _PORT_R (active_context->PORT_R) 95 #define _PORT0R (_PORT_R[0]) 96 #define _PORT1R (_PORT_R[1]) 97 #define _PORT2R (_PORT_R[2]) 98 #define _PORT3R (_PORT_R[3]) 99 100 #define _PORT_W (active_context->PORT_W) 101 #define _PORT0W (_PORT_W[0]) 102 #define _PORT1W (_PORT_W[1]) 103 #define _PORT2W (_PORT_W[2]) 104 #define _PORT3W (_PORT_W[3]) 105 106 #define _FFC0_Address (active_context->FFC0_Address) 107 108 #define _PC (active_context->PC.w) 109 #define _PCL (active_context->PC.b.l) 110 #define _PCH (active_context->PC.b.h) 111 #define _YA (active_context->YA.w) 112 #define _A (active_context->YA.b.l) 113 #define _Y (active_context->YA.b.h) 114 #define _dp (active_context->direct_page.w) 115 #define _direct_page (active_context->direct_page.b.h) 116 #define _SP (active_context->SP) 117 #define _X (active_context->X) 118 #define _PSW (active_context->PSW) 119 120 #define _cycle (active_context->cycle) 121 #define _opcode (active_context->opcode) 122 #define _data (active_context->data) 123 #define _data2 (active_context->data2) 124 #define _data16 (active_context->data16.w) 125 #define _offset (active_context->offset) 126 #define _address (active_context->address.w) 127 #define _address_l (active_context->address.b.l) 128 #define _address_h (active_context->address.b.h) 129 #define _address2 (active_context->address2.w) 130 #define _address2_l (active_context->address2.b.l) 131 #define _address2_h (active_context->address2.b.h) 132 133 #define _N_flag (active_context->N_flag) 134 #define _V_flag (active_context->V_flag) 135 #define _P_flag (active_context->P_flag) 136 #define _B_flag (active_context->B_flag) 137 #define _H_flag (active_context->H_flag) 138 #define _I_flag (active_context->I_flag) 139 #define _Z_flag (active_context->Z_flag) 140 #define _C_flag (active_context->C_flag) 141 142 #define _timers (active_context->timers) 143 144 /* bits used all over the core */ 145 void set_flag_spc(u8 flag) 146 { 147 if (flag & SPC_FLAG_N) 148 { 149 _N_flag = 0x80; 150 } 151 if (flag & SPC_FLAG_V) 152 { 153 _V_flag = 1; 154 } 155 if (flag & SPC_FLAG_P) 156 { 157 _P_flag = 1; 158 _direct_page = 0x01; 159 } 160 if (flag & SPC_FLAG_B) 161 { 162 _B_flag = 1; 163 } 164 if (flag & SPC_FLAG_H) 165 { 166 _H_flag = 1; 167 } 168 if (flag & SPC_FLAG_I) 169 { 170 _I_flag = 1; 171 } 172 if (flag & SPC_FLAG_Z) 173 { 174 _Z_flag = 0; 175 } 176 if (flag & SPC_FLAG_C) 177 { 178 _C_flag = 1; 179 } 180 } 181 182 void clr_flag_spc(u8 flag) 183 { 184 if (flag & SPC_FLAG_N) 185 { 186 _N_flag = 0; 187 } 188 if (flag & SPC_FLAG_V) 189 { 190 _V_flag = 0; 191 } 192 if (flag & SPC_FLAG_P) 193 { 194 _P_flag = 0; 195 _direct_page = 0x00; 196 } 197 if (flag & SPC_FLAG_B) 198 { 199 _B_flag = 0; 200 } 201 if (flag & SPC_FLAG_H) 202 { 203 _H_flag = 0; 204 } 205 if (flag & SPC_FLAG_I) 206 { 207 _I_flag = 0; 208 } 209 if (flag & SPC_FLAG_Z) 210 { 211 _Z_flag = 1; 212 } 213 if (flag & SPC_FLAG_C) 214 { 215 _C_flag = 0; 216 } 217 } 218 219 void complement_carry_spc(void) 220 { 221 _C_flag = !_C_flag; 222 } 223 224 u8 flag_state_spc(u8 flag) 225 { 226 if (flag == SPC_FLAG_N) 227 { 228 return _N_flag & 0x80; 229 } 230 else if (flag == SPC_FLAG_V) 231 { 232 return _V_flag; 233 } 234 else if (flag == SPC_FLAG_P) 235 { 236 return _P_flag; 237 } 238 else if (flag == SPC_FLAG_B) 239 { 240 return _B_flag; 241 } 242 else if (flag == SPC_FLAG_H) 243 { 244 return _H_flag; 245 } 246 else if (flag == SPC_FLAG_I) 247 { 248 return _I_flag; 249 } 250 else if (flag == SPC_FLAG_Z) 251 { 252 return !_Z_flag; 253 } 254 else if (flag == SPC_FLAG_C) 255 { 256 return _C_flag; 257 } 258 259 return 0; 260 } 261 262 void load_cycles_spc(void) 263 { 264 _WorkCycles = _TotalCycles - _Cycles; 265 } 266 267 u32 get_cycles_spc(void) 268 { 269 return _WorkCycles + _Cycles; 270 } 271 272 void save_cycles_spc(void) 273 { 274 _TotalCycles = _WorkCycles + _Cycles; 275 } 276 277 /* Set up the flags from our flag format to SPC flag format */ 278 void spc_setup_flags(s32 B_flag) 279 { 280 u8 PSW = 0; 281 282 PSW += _N_flag & 0x80; 283 PSW += _V_flag ? 0x40 : 0; 284 PSW += _P_flag ? 0x20 : 0; 285 PSW += B_flag ? 0x10 : 0; 286 PSW += _H_flag ? 0x08 : 0; 287 PSW += _I_flag ? 0x04 : 0; 288 PSW += !_Z_flag ? 0x02 : 0; 289 PSW += _C_flag ? 0x01 : 0; 290 291 _PSW = PSW; 292 } 293 294 /* Restore the flags from SPC flag format to our flag format */ 295 void spc_restore_flags(void) 296 { 297 u8 PSW = _PSW; 298 299 _N_flag = PSW; 300 _V_flag = PSW & SPC_FLAG_V; 301 302 if (PSW & SPC_FLAG_P) 303 set_flag_spc(SPC_FLAG_P); 304 else 305 clr_flag_spc(SPC_FLAG_P); 306 307 _B_flag = PSW & SPC_FLAG_B; 308 _H_flag = PSW & SPC_FLAG_H; 309 _I_flag = PSW & SPC_FLAG_I; 310 _Z_flag = ~PSW & SPC_FLAG_Z; 311 _C_flag = PSW & SPC_FLAG_C; 312 } 313 314 void store_flag_n(u8 value) 315 { 316 _N_flag = value; 317 } 318 319 void store_flag_v(u8 value) 320 { 321 _V_flag = value; 322 } 323 324 void store_flag_p(u8 value) 325 { 326 _P_flag = value; 327 _direct_page = value ? 0x01 : 0x00; 328 } 329 330 void store_flag_h(u8 value) 331 { 332 _H_flag = value; 333 } 334 335 void store_flag_i(u8 value) 336 { 337 _I_flag = value; 338 } 339 340 void store_flag_z(u8 value) 341 { 342 _Z_flag = value; 343 } 344 345 void store_flag_c(u8 value) 346 { 347 _C_flag = value; 348 } 349 350 void store_flags_nz(u8 value) 351 { 352 store_flag_n(value); 353 store_flag_z(value); 354 } 355 356 void store_flags_nzc(u8 nz, u8 c) 357 { 358 store_flag_n(nz); 359 store_flag_z(nz); 360 store_flag_c(c); 361 } 362 363 /* bits for external access by the 5A22 core */ 364 u8 SPC_READ_PORT_W(u16 address) 365 { 366 return _PORT_W[address & 3]; 367 } 368 369 void SPC_WRITE_PORT_R(u16 address, u8 data) 370 { 371 _PORT_R[address & 3] = data; 372 } 373 374 /* bits for handling cycle counter overflows */ 375 void Wrap_SPC_Cyclecounter() 376 { 377 _TotalCycles -= 0xF0000000; 378 _Cycles -= 0xF0000000; 379 _timers[0].cycle_latch -= 0xF0000000; 380 _timers[1].cycle_latch -= 0xF0000000; 381 _timers[2].cycle_latch -= 0xF0000000; 382 383 Wrap_SDSP_Cyclecounter(); 384 } 385 386 /* This code should be mapped into the top of the address space */ 387 static u8 SPC_ROM_CODE[64] = {0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 388 0xBB, 0xF5, 0x78, 0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4, 0xD0, 0xFC, 389 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5, 0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 390 0xAB, 0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA, 0xF6, 0xDA, 0x00, 0xBA, 391 0xF4, 0xC4, 0xF4, 0xDD, 0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF}; 392 393 static u8 SPC_READ_INVALID(u16 address) 394 { 395 #ifdef TRAP_INVALID_READ 396 #ifdef DEBUG 397 /* Set up address so message works */ 398 Map_Address = address; 399 Map_Byte = 0; 400 401 InvalidSPCHWRead(); /* Display read from invalid HW warning */ 402 #endif 403 #endif 404 return 0; 405 } 406 407 static u8 SPC_READ_RAM(u16 address) 408 { 409 return SPCRAM[address]; 410 } 411 412 static u8 SPC_READ_DSP_DATA(u16 address) 413 { 414 SPC_READ_DSP(); 415 416 /* read from DSP register */ 417 /* DSP address bit 7 ignored during reads only! */ 418 return SPC_DSP[SPC_DSP_ADDR & 0x7F]; 419 } 420 421 u8 SPC_READ_PORT_R(u16 address) 422 { 423 return _PORT_R[address & 3]; 424 } 425 426 /* timer registers are write-only, actual timer clock is internal and */ 427 /* not accessible! */ 428 /* counters are 4-bit, upon read/write they reset to 0 */ 429 430 void Update_SPC_Timer(s32 timer) 431 { 432 u32 shift, mask, cycles, position; 433 434 if (timer != 2) 435 { 436 shift = 7; 437 } 438 else 439 { 440 shift = 4; 441 } 442 mask = -BIT(shift); 443 444 cycles = _TotalCycles - _timers[timer].cycle_latch; 445 _timers[timer].cycle_latch += cycles & mask; 446 447 /* nothing to do if timer turned off */ 448 if (!(SPC_CTRL & BIT(timer))) 449 return; 450 451 position = _timers[timer].position + (cycles >> shift); 452 _timers[timer].position = position; 453 if (position < _timers[timer].target) 454 { 455 return; 456 } 457 458 _timers[timer].counter += position / _timers[timer].target; 459 /* 4-bit counter without saturation */ 460 _timers[timer].counter &= 0x0F; 461 462 _timers[timer].position = position % _timers[timer].target; 463 } 464 465 static u8 SPC_READ_COUNTER(u16 address) 466 { 467 /* 0xFD = read address for first timer's counter */ 468 s32 timer = address - 0xFD; 469 u8 counter; 470 471 Update_SPC_Timer(timer); 472 counter = _timers[timer].counter; 473 _timers[timer].counter = 0; 474 475 return counter; 476 } 477 478 /* 479 | ROMEN | ----- | PC32 | PC10 | ----- | ST2 | ST1 | ST0 | 480 481 ROMEN - enable mask ROM in top 64-bytes of address space for CPU read 482 PC32 - clear SPC read ports 2 & 3 483 PC10 - clear SPC read ports 0 & 1 484 ST2 - start timer 2 (64kHz) 485 ST1 - start timer 1 (8kHz) 486 ST0 - start timer 0 (8kHz) 487 */ 488 489 void spc_start_timer(s32 timer) 490 { 491 u32 shift, mask; 492 493 if (timer != 2) 494 { 495 shift = 7; 496 } 497 else 498 { 499 shift = 4; 500 } 501 mask = -BIT(shift); 502 503 _timers[timer].cycle_latch = _TotalCycles & mask; 504 _timers[timer].position = 0; 505 _timers[timer].counter = 0; 506 } 507 508 static void SPC_WRITE_INVALID(u16 address, u8 data) 509 { 510 #ifdef TRAP_INVALID_WRITE 511 #ifdef DEBUG 512 /* Set up address so message works */ 513 Map_Address = address; 514 Map_Byte = data; 515 516 InvalidSPCHWWrite(); /* Display write to invalid HW warning */ 517 #endif 518 #endif 519 } 520 521 static void SPC_WRITE_CTRL(u16 address, u8 data) 522 { 523 /* IPL ROM enable */ 524 _FFC0_Address = data & 0x80 ? SPC_ROM_CODE - 0xFFC0 : SPCRAM; 525 526 /* read ports 0/1 reset */ 527 if (data & 0x10) 528 { 529 _PORT_R[0] = 0; 530 _PORT_R[1] = 0; 531 } 532 533 /* read ports 2/3 reset */ 534 if (data & 0x20) 535 { 536 _PORT_R[2] = 0; 537 _PORT_R[3] = 0; 538 } 539 540 /* timer 0 control */ 541 if (!(SPCRAM[address] & 1) && (data & 1)) 542 { 543 spc_start_timer(0); 544 } 545 546 /* timer 0 control */ 547 if (!(SPCRAM[address] & 2) && (data & 2)) 548 { 549 spc_start_timer(1); 550 } 551 552 /* timer 2 control */ 553 if (!(SPCRAM[address] & 4) && (data & 4)) 554 { 555 spc_start_timer(2); 556 } 557 558 SPC_CTRL = data; 559 } 560 561 static void SPC_WRITE_RAM(u16 address, u8 data) 562 { 563 SPCRAM[address] = data; 564 } 565 566 static void SPC_WRITE_DSP_DATA(u16 address, u8 data) 567 { 568 SPC_DSP_DATA = data; 569 570 /* write to DSP register */ 571 SPC_WRITE_DSP(); 572 } 573 574 void SPC_WRITE_PORT_W(u16 address, u8 data) 575 { 576 _PORT_W[address & 3] = data; 577 } 578 579 static void SPC_WRITE_TIMER(u16 address, u8 data) 580 { 581 /* 0xFA = write address for first timer's target */ 582 s32 timer = address - 0xFA; 583 s32 target; 584 585 if ((_timers[timer].target & 0xFF) == data) 586 { 587 return; 588 } 589 590 target = data ? data : 256; 591 592 /* Timer must catch up before changing target */ 593 Update_SPC_Timer(timer); 594 595 _timers[timer].target = target; 596 597 /* does setting target for current position raise counter? assuming not */ 598 if (target <= _timers[timer].position) 599 /* handle 'delay' where new target is set below position */ 600 { 601 _timers[timer].position -= 256; 602 } 603 } 604 605 /* Mappings for SPC Registers */ 606 static u8 (*Read_Func_Map[16])(u16 address) = {SPC_READ_INVALID, SPC_READ_INVALID, SPC_READ_RAM, SPC_READ_DSP_DATA, 607 SPC_READ_PORT_R, SPC_READ_PORT_R, SPC_READ_PORT_R, SPC_READ_PORT_R, 608 SPC_READ_RAM, SPC_READ_RAM, SPC_READ_INVALID, SPC_READ_INVALID, 609 SPC_READ_INVALID, SPC_READ_COUNTER, SPC_READ_COUNTER, SPC_READ_COUNTER}; 610 611 static void (*Write_Func_Map[16])(u16 address, u8 data) = { 612 SPC_WRITE_INVALID, SPC_WRITE_CTRL, SPC_WRITE_RAM, SPC_WRITE_DSP_DATA, SPC_WRITE_PORT_W, SPC_WRITE_PORT_W, 613 SPC_WRITE_PORT_W, SPC_WRITE_PORT_W, SPC_WRITE_RAM, SPC_WRITE_RAM, SPC_WRITE_TIMER, SPC_WRITE_TIMER, 614 SPC_WRITE_TIMER, SPC_WRITE_RAM, SPC_WRITE_RAM, SPC_WRITE_RAM}; 615 616 static u8 offset_to_bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 617 618 static u8 offset_to_not[8] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; 619 620 u8 get_byte_spc(u16 address) 621 { 622 /* Note: need to update sound if echo write enabled and accessing echo */ 623 /* region */ 624 if (address >= 0x0100) 625 /* not zero page */ 626 { 627 if (address >= 0xFFC0) 628 /* return ROM if it's mapped in, else RAM */ 629 { 630 return ((u8 *)_FFC0_Address)[address]; 631 } 632 /* return RAM */ 633 return SPCRAM[address]; 634 } 635 636 /* zero page */ 637 if (address < 0xF0) 638 /* RAM */ 639 { 640 return SPCRAM[address]; 641 } 642 643 save_cycles_spc(); /* Set cycle counter */ 644 return Read_Func_Map[address - 0xF0](address); 645 } 646 647 /* -------- */ 648 649 void set_byte_spc(u16 address, u8 data) 650 { 651 /* Note: need to update sound always, since all (?) writes affect RAM */ 652 if (address >= 0x0100 || address < 0xF0) 653 /* write to RAM */ 654 { 655 save_cycles_spc(); /* Set cycle counter */ 656 update_sound(); 657 SPCRAM[address] = data; 658 } 659 else 660 { 661 save_cycles_spc(); /* Set cycle counter */ 662 Write_Func_Map[address - 0xF0](address, data); 663 } 664 } 665 666 void Reset_SPC(void) 667 { 668 s32 i; 669 670 /* Get ROM reset vector and setup Program Counter */ 671 _PC = SPC_ROM_CODE[0xFFFE - 0xFFC0] + (SPC_ROM_CODE[0xFFFF - 0xFFC0] << 8); 672 673 /* Reset cycle counts */ 674 _TotalCycles = 6; /* 5-7 cycles before execution begins */ 675 676 _Cycles = 0; 677 _last_cycles = 0; 678 679 _cycle = 0; 680 681 /* Reset SSMP registers */ 682 _dp = 0; /* Used to save P flag check for dp addressing */ 683 _SP = 0xEF; 684 _YA = 0; 685 _X = 0; 686 /* Clear flags register */ 687 _PSW = 0; 688 clr_flag_spc(SPC_FLAG_N); 689 clr_flag_spc(SPC_FLAG_V); 690 clr_flag_spc(SPC_FLAG_P); 691 clr_flag_spc(SPC_FLAG_B); 692 clr_flag_spc(SPC_FLAG_H); 693 clr_flag_spc(SPC_FLAG_I); 694 clr_flag_spc(SPC_FLAG_Z); 695 clr_flag_spc(SPC_FLAG_C); 696 697 SPC_CTRL = 0x80; 698 _FFC0_Address = SPC_ROM_CODE - 0xFFC0; 699 700 /* Reset timers */ 701 for (i = 0; i < 3; i++) 702 { 703 _timers[i].cycle_latch = 0; 704 _timers[i].position = 0; 705 _timers[i].target = 256; 706 _timers[i].counter = 0; 707 } 708 709 sound_cycle_latch = 0; 710 711 /* Reset SPC700 input ports */ 712 _PORT_R[0] = 0; 713 _PORT_R[1] = 0; 714 _PORT_R[2] = 0; 715 _PORT_R[3] = 0; 716 717 /* Reset SPC700 output ports */ 718 _PORT_W[0] = 0; 719 _PORT_W[1] = 0; 720 _PORT_W[2] = 0; 721 _PORT_W[3] = 0; 722 723 /* Reset sound DSP port address */ 724 SPC_DSP_ADDR = 0; 725 SPC_DSP_DATA = 0; 726 } 727 728 void SPC_SHOW_REGISTERS(void) 729 { 730 DisplaySPC(); 731 } 732 733 u8 get_SPC_PSW(void) 734 { 735 spc_setup_flags(_B_flag); 736 737 return _PSW; 738 } 739 740 #ifdef OPCODE_TRACE_LOG 741 #define SS_WAIT_FOR_KEY /*if ((readkey() & 0xFF) == 'g') { s32 i = 0; while (i++ < 49) simulate_keypress(' ' + \ 742 (KEY_SPACE << 8)); }*/ 743 744 #else 745 #define SS_WAIT_FOR_KEY 746 747 void dummy_fprintf() 748 { 749 } 750 #define fprintf dummy_fprintf 751 752 #endif 753 754 #ifdef OPCODE_TRACE_LOG 755 /* cycle #, PC, TotalCycles */ 756 #define SINGLE_STEP_START(c) \ 757 if (dump_flag && debug_log_file) \ 758 { \ 759 fprintf(debug_log_file, "START_CYCLE(%u) PC:%04X %u\n", c, _PC & 0xFFFF, get_cycles_spc()); \ 760 if ((c == 1) && (_PC == 0x02C4)) \ 761 exit(0); \ 762 } 763 764 void single_step_end(void) 765 { 766 if (!dump_flag || !debug_log_file) 767 return; 768 fprintf(debug_log_file, "NVPBHIZC R:%02X %02X %02X %02X X:%02X Y:%02X A:%02X SP:%02X dp:%02X Op:%02X\n", 769 _PORT0R & 0xFF, _PORT1R & 0xFF, _PORT2R & 0xFF, _PORT3R & 0xFF, _X & 0xFF, _Y & 0xFF, _A & 0xFF, _SP & 0xFF, 770 _direct_page & 0xFF, _opcode & 0xFF); 771 fprintf(debug_log_file, "%c%c%c%c%c%c%c%c W:%02X %02X %02X %02X Ad%04X %04X Off%02X D%02X %02X D16 %04X", 772 flag_state_spc(SPC_FLAG_N) ? '1' : '0', flag_state_spc(SPC_FLAG_V) ? '1' : '0', 773 flag_state_spc(SPC_FLAG_P) ? '1' : '0', flag_state_spc(SPC_FLAG_B) ? '1' : '0', 774 flag_state_spc(SPC_FLAG_H) ? '1' : '0', flag_state_spc(SPC_FLAG_I) ? '1' : '0', 775 flag_state_spc(SPC_FLAG_Z) ? '1' : '0', flag_state_spc(SPC_FLAG_C) ? '1' : '0', _PORT0W & 0xFF, 776 _PORT1W & 0xFF, _PORT2W & 0xFF, _PORT3W & 0xFF, _address & 0xFFFF, _address2 & 0xFFFF, _offset & 0xFF, 777 _data & 0xFF, _data2 & 0xFF, _data16 & 0xFFFF); 778 if (_cycle == 0) 779 fprintf(debug_log_file, " %s\n", SPC_OpID[_opcode]); 780 else 781 fprintf(debug_log_file, "\n"); 782 } 783 784 /* op, R ports, W ports, X Y A */ 785 /* address1 address2 offset data1 data2 data16 */ 786 #define SINGLE_STEP_END single_step_end(); 787 788 #else 789 #define SINGLE_STEP_START(c) 790 #define SINGLE_STEP_END 791 #endif 792 793 #define START_CYCLE(c) \ 794 if (_cycle <= ((c)-1)) \ 795 { \ 796 SINGLE_STEP_START(c) 797 798 #define END_FETCH_CYCLE() \ 799 _WorkCycles++; \ 800 SINGLE_STEP_END if (_WorkCycles >= 0) \ 801 { \ 802 _cycle = 1; \ 803 opcode_done = 0; \ 804 break; \ 805 } \ 806 } 807 808 #define END_CYCLE(c, n) \ 809 _WorkCycles += n; \ 810 SINGLE_STEP_END if (_WorkCycles >= 0) \ 811 { \ 812 _cycle = c; \ 813 opcode_done = 0; \ 814 break; \ 815 } \ 816 } 817 818 #define EXIT_OPCODE(n) \ 819 { \ 820 _WorkCycles += n; \ 821 SINGLE_STEP_END break; \ 822 } 823 824 #define END_OPCODE(n) \ 825 EXIT_OPCODE(n) \ 826 } 827 828 #define END_BRANCH_OPCODE(cycle, TEST) \ 829 TEST END_CYCLE((cycle), 1) \ 830 \ 831 /* sign extend offset and add to PC */ \ 832 START_CYCLE((cycle)+1) _address = _PC + (((s32)_offset ^ 0x80) - 0x80); \ 833 END_CYCLE((cycle)+1, 1) \ 834 \ 835 START_CYCLE((cycle)+2) \ 836 _PC = _address; \ 837 END_OPCODE(1) 838 839 #define REL_TEST_BRA ; 840 #define REL_TEST_BPL \ 841 if (flag_state_spc(SPC_FLAG_N)) \ 842 EXIT_OPCODE(1) 843 #define REL_TEST_BMI \ 844 if (!flag_state_spc(SPC_FLAG_N)) \ 845 EXIT_OPCODE(1) 846 #define REL_TEST_BVC \ 847 if (flag_state_spc(SPC_FLAG_V)) \ 848 EXIT_OPCODE(1) 849 #define REL_TEST_BVS \ 850 if (!flag_state_spc(SPC_FLAG_V)) \ 851 EXIT_OPCODE(1) 852 #define REL_TEST_BCC \ 853 if (flag_state_spc(SPC_FLAG_C)) \ 854 EXIT_OPCODE(1) 855 #define REL_TEST_BCS \ 856 if (!flag_state_spc(SPC_FLAG_C)) \ 857 EXIT_OPCODE(1) 858 #define REL_TEST_BNE \ 859 if (flag_state_spc(SPC_FLAG_Z)) \ 860 EXIT_OPCODE(1) 861 #define REL_TEST_BEQ \ 862 if (!flag_state_spc(SPC_FLAG_Z)) \ 863 EXIT_OPCODE(1) 864 865 #define OP_TCALL(vector) \ 866 /* 8 cycles - opcode, new PCL, new PCH, stack address load, PCH */ \ 867 /* write, PCL write, dummy cycle (PSW write in BRK?) */ \ 868 /* SP decrement */ \ 869 /* fetch address for PC */ \ 870 START_CYCLE(2) \ 871 _address = 0xFFC0 + ((15 - (vector)) * 2); \ 872 _address2 = get_byte_spc(_address); \ 873 END_CYCLE(2, 1) \ 874 \ 875 START_CYCLE(3) \ 876 _address2 += (get_byte_spc(_address + 1) << 8); \ 877 END_CYCLE(3, 1) \ 878 \ 879 START_CYCLE(4) \ 880 _address = 0x0100 + _SP; \ 881 END_CYCLE(4, 1) \ 882 \ 883 START_CYCLE(5) \ 884 set_byte_spc(_address, _PC >> 8); \ 885 _SP--; \ 886 _address = 0x0100 + _SP; \ 887 END_CYCLE(5, 1) \ 888 \ 889 START_CYCLE(6) \ 890 set_byte_spc(_address, _PC); \ 891 _SP--; \ 892 _address = 0x0100 + _SP; \ 893 END_CYCLE(6, 1) \ 894 \ 895 START_CYCLE(7) \ 896 /* should we write PSW to stack here? */ \ 897 END_CYCLE(7, 1) \ 898 \ 899 START_CYCLE(8) \ 900 _PC = _address2; \ 901 END_OPCODE(1) 902 903 #define COND_REL(TEST) \ 904 /* 2 cycles - opcode, branch logic + offset; */ \ 905 /* +2 cycles (taken branch) add PC to offset, reload PC */ \ 906 \ 907 START_CYCLE(2) \ 908 _offset = get_byte_spc(_PC); \ 909 _PC++; \ 910 END_BRANCH_OPCODE(2, TEST) 911 912 #define DP_REL_TEST_BBS \ 913 if (!(_data & offset_to_bit[_opcode >> 5])) \ 914 EXIT_OPCODE(1) 915 916 #define DP_REL_TEST_BBC \ 917 if ((_data & offset_to_bit[_opcode >> 5])) \ 918 EXIT_OPCODE(1) 919 920 #define TEST_CBNE \ 921 if (_data == _A) \ 922 EXIT_OPCODE(1) 923 924 #define DP_REL_TEST_DBNZ \ 925 --_data; \ 926 set_byte_spc(_address, _data); \ 927 if (!_data) \ 928 EXIT_OPCODE(1) 929 930 #define COND_DP_REL(TEST) \ 931 /* 5 cycles - opcode, address, branch offset, data read, branch logic */ \ 932 /* and data write (DBNZ only); +2 cycles (taken branch) add PC to */ \ 933 /* offset, reload PC */ \ 934 START_CYCLE(2) \ 935 _address = _dp + get_byte_spc(_PC); \ 936 _PC++; \ 937 END_CYCLE(2, 1) \ 938 \ 939 START_CYCLE(3) \ 940 _offset = get_byte_spc(_PC); \ 941 _PC++; \ 942 END_CYCLE(3, 1) \ 943 \ 944 START_CYCLE(4) \ 945 _data = get_byte_spc(_address); \ 946 END_CYCLE(4, 1) \ 947 \ 948 START_CYCLE(5) \ 949 END_BRANCH_OPCODE(5, TEST) 950 951 #define OP_READ_DP(OP, dest) \ 952 /* 3 cycles - opcode, address, data read + op */ \ 953 START_CYCLE(2) \ 954 _address = _dp + get_byte_spc(_PC); \ 955 _PC++; \ 956 END_CYCLE(2, 1) \ 957 \ 958 START_CYCLE(3) \ 959 _data = get_byte_spc(_address); \ 960 OP_##OP((dest), _data) END_OPCODE(1) 961 962 /* xxx00100 */ 963 #define OP_READ_DP_A(OP) OP_READ_DP(OP, _A) 964 965 #define OP_READ_ABS(OP, dest) \ 966 /* 4 cycles - opcode, address low, address high, data read + op */ \ 967 START_CYCLE(2) \ 968 _address = get_byte_spc(_PC); \ 969 _PC++; \ 970 END_CYCLE(2, 1) \ 971 \ 972 START_CYCLE(3) \ 973 _address += get_byte_spc(_PC) << 8; \ 974 _PC++; \ 975 END_CYCLE(3, 1) \ 976 \ 977 START_CYCLE(4) \ 978 _data = get_byte_spc(_address); \ 979 OP_##OP((dest), _data) END_OPCODE(1) 980 981 /* xxx00101 */ 982 #define OP_READ_ABS_A(OP) OP_READ_ABS(OP, _A) 983 984 #define OP_READ_INDIRECT(OP, dest) \ 985 /* 3 cycles - opcode, address calc, data read + op */ \ 986 START_CYCLE(2) \ 987 _address = _dp + _X; \ 988 END_CYCLE(2, 1) \ 989 \ 990 START_CYCLE(3) \ 991 _data = get_byte_spc(_address); \ 992 OP_##OP(_A, _data) END_OPCODE(1) 993 994 #define OP_RMW_INDIRECT(OP, NEED_OLD_DATA) \ 995 /* 4 cycles - opcode, address calc, data read, data write */ \ 996 START_CYCLE(2) \ 997 _address = _dp + _X; \ 998 END_CYCLE(2, 1) \ 999 \ 1000 START_CYCLE(3) \ 1001 if (NEED_OLD_DATA) \ 1002 _data = get_byte_spc(_address); \ 1003 else \ 1004 get_byte_spc(_address); \ 1005 END_CYCLE(3, 1) \ 1006 \ 1007 START_CYCLE(4) \ 1008 OP END_OPCODE(1) 1009 1010 /* xxx00110 */ 1011 #define OP_READ_INDIRECT_A(OP) OP_READ_INDIRECT(OP, _A) 1012 1013 #define OP_READ_INDEXED_INDIRECT(OP, dest) \ 1014 /* 6 cycles - opcode, offset, address calc, address low, */ \ 1015 /* address high, data read + op */ \ 1016 START_CYCLE(2) \ 1017 _address2 = get_byte_spc(_PC); \ 1018 _PC++; \ 1019 END_CYCLE(2, 1) \ 1020 \ 1021 START_CYCLE(3) \ 1022 _address2 = _dp + ((_address2 + _X) & 0xFF); \ 1023 END_CYCLE(3, 1) \ 1024 \ 1025 START_CYCLE(4) \ 1026 _address = get_byte_spc(_address2); \ 1027 END_CYCLE(4, 1) \ 1028 \ 1029 START_CYCLE(5) \ 1030 _address += get_byte_spc(_address2 + 1) << 8; \ 1031 END_CYCLE(5, 1) \ 1032 \ 1033 START_CYCLE(6) \ 1034 _data = get_byte_spc(_address); \ 1035 OP_##OP((dest), _data) END_OPCODE(1) 1036 1037 #define OP_RMW_INDEXED_INDIRECT(OP, NEED_OLD_DATA) \ 1038 /* 7 cycles - opcode, offset, address calc, address low, */ \ 1039 /* address high, data read, data read + op */ \ 1040 START_CYCLE(2) \ 1041 _address2 = get_byte_spc(_PC); \ 1042 _PC++; \ 1043 END_CYCLE(2, 1) \ 1044 \ 1045 START_CYCLE(3) \ 1046 _address2 = _dp + ((_address2 + _X) & 0xFF); \ 1047 END_CYCLE(3, 1) \ 1048 \ 1049 START_CYCLE(4) \ 1050 _address = get_byte_spc(_address2); \ 1051 END_CYCLE(4, 1) \ 1052 \ 1053 START_CYCLE(5) \ 1054 _address += get_byte_spc(_address2 + 1) << 8; \ 1055 END_CYCLE(5, 1) \ 1056 \ 1057 START_CYCLE(6) \ 1058 if (NEED_OLD_DATA) \ 1059 _data = get_byte_spc(_address); \ 1060 else \ 1061 get_byte_spc(_address); \ 1062 END_CYCLE(6, 1) \ 1063 \ 1064 START_CYCLE(7) \ 1065 OP END_OPCODE(1) 1066 1067 /* xxx00111 */ 1068 #define OP_READ_INDEXED_INDIRECT_A(OP) OP_READ_INDEXED_INDIRECT(OP, _A) 1069 1070 #define OP_READ_IMM(OP, dest) \ 1071 /* 2 cycles - opcode, data read + op */ \ 1072 START_CYCLE(2) \ 1073 _data = get_byte_spc(_PC); \ 1074 _PC++; \ 1075 OP_##OP((dest), _data) END_OPCODE(1) 1076 1077 /* xxx01000 */ 1078 #define OP_READ_IMM_A(OP) OP_READ_IMM(OP, _A) 1079 1080 #define OP_OR(dest, src) \ 1081 { \ 1082 (dest) |= (src); \ 1083 store_flags_nz(dest); \ 1084 } 1085 1086 #define OP_AND(dest, src) \ 1087 { \ 1088 (dest) &= (src); \ 1089 store_flags_nz(dest); \ 1090 } 1091 1092 #define OP_EOR(dest, src) \ 1093 { \ 1094 (dest) ^= (src); \ 1095 store_flags_nz(dest); \ 1096 } 1097 1098 #define OP_CMP(dest, src) \ 1099 { \ 1100 u32 temp = (dest) - (src); \ 1101 \ 1102 store_flag_c(temp <= 0xFF); \ 1103 store_flags_nz(temp); \ 1104 } 1105 1106 #define OP_ADC(dest, src) \ 1107 { \ 1108 u32 result = (dest) + (src) + (flag_state_spc(SPC_FLAG_C) ? 1 : 0); \ 1109 \ 1110 store_flag_h(((u32)(((dest)&0x0F) + ((src)&0x0F) + (flag_state_spc(SPC_FLAG_C) ? 1 : 0))) > 0x0F ? 1 : 0); \ 1111 store_flag_c(result > 0xFF); \ 1112 store_flag_v((~((dest) ^ (src))) & (((dest) ^ result) & 0x80)); \ 1113 store_flags_nz(result); \ 1114 (dest) = result; \ 1115 } 1116 1117 #define OP_SBC(dest, src) \ 1118 { \ 1119 u32 result = (dest) - (src) - (flag_state_spc(SPC_FLAG_C) ? 0 : 1); \ 1120 \ 1121 store_flag_h(((u32)(((dest)&0x0F) - ((src)&0x0F) - (flag_state_spc(SPC_FLAG_C) ? 0 : 1))) > 0x0F ? 0 : 1); \ 1122 store_flag_c(result <= 0xFF); \ 1123 store_flag_v(((dest) ^ (src)) & (((dest) ^ result) & 0x80)); \ 1124 store_flags_nz(result); \ 1125 (dest) = result; \ 1126 } 1127 1128 #define OP_MOV_READ_NOFLAGS(dest, src) \ 1129 { \ 1130 (dest) = (src); \ 1131 } 1132 1133 #define OP_MOV_READ(dest, src) \ 1134 { \ 1135 (dest) = (src); \ 1136 store_flags_nz(src); \ 1137 } 1138 1139 #define OP_ADDW(dest, src) \ 1140 { \ 1141 u32 temp_low, carry_low, temp_high, result; \ 1142 \ 1143 temp_low = ((dest)&0xFF) + ((src)&0xFF); \ 1144 carry_low = temp_low > 0xFF ? 1 : 0; \ 1145 \ 1146 store_flag_h(((u32)((((dest) >> 8) & 0x0F) + (((src) >> 8) & 0x0F) + carry_low)) > 0x0F ? 1 : 0); \ 1147 \ 1148 temp_high = ((dest) >> 8) + ((src) >> 8) + carry_low; \ 1149 store_flag_c(temp_high > 0xFF); \ 1150 result = ((temp_low & 0xFF) + (temp_high << 8)) & 0xFFFF; \ 1151 \ 1152 store_flag_v(((~((dest) ^ (src))) & (((dest) ^ result) & 0x8000)) >> 8); \ 1153 store_flag_n(result >> 8); \ 1154 store_flag_z(result != 0); \ 1155 (dest) = result; \ 1156 } 1157 1158 #define OP_SUBW(dest, src) \ 1159 { \ 1160 u32 temp_low, carry_low, temp_high, result; \ 1161 \ 1162 temp_low = ((dest)&0xFF) - ((src)&0xFF); \ 1163 carry_low = temp_low > 0xFF ? 1 : 0; \ 1164 \ 1165 store_flag_h(((u32)((((dest) >> 8) & 0x0F) - (((src) >> 8) & 0x0F) - carry_low)) > 0x0F ? 0 : 1); \ 1166 \ 1167 temp_high = ((dest) >> 8) - ((src) >> 8) - carry_low; \ 1168 store_flag_c(temp_high <= 0xFF); \ 1169 result = ((temp_low & 0xFF) + (temp_high << 8)) & 0xFFFF; \ 1170 \ 1171 store_flag_v((((dest) ^ (src)) & (((dest) ^ result) & 0x8000)) >> 8); \ 1172 store_flag_n(result >> 8); \ 1173 store_flag_z(result != 0); \ 1174 (dest) = result; \ 1175 } 1176 1177 #define OP_MOVW_READ(dest, src) \ 1178 { \ 1179 (dest) = (src); \ 1180 store_flag_n((dest) >> 8); \ 1181 store_flag_z((dest) != 0); \ 1182 } 1183 1184 #define OP_ASL(var) \ 1185 { \ 1186 store_flag_c((var)&0x80); \ 1187 (var) <<= 1; \ 1188 store_flags_nz(var); \ 1189 } 1190 1191 #define OP_ROL(var) \ 1192 { \ 1193 s32 c = flag_state_spc(SPC_FLAG_C) ? 1 : 0; \ 1194 \ 1195 store_flag_c((var)&0x80); \ 1196 (var) = ((var) << 1) + c; \ 1197 store_flags_nz(var); \ 1198 } 1199 1200 #define OP_LSR(var) \ 1201 { \ 1202 store_flag_c((var)&1); \ 1203 (var) >>= 1; \ 1204 store_flags_nz(var); \ 1205 } 1206 1207 #define OP_ROR(var) \ 1208 { \ 1209 s32 c = flag_state_spc(SPC_FLAG_C) ? 0x80 : 0; \ 1210 \ 1211 store_flag_c((var)&1); \ 1212 (var) = ((var) >> 1) + c; \ 1213 store_flags_nz(var); \ 1214 } 1215 1216 #define OP_DECW(var) \ 1217 { \ 1218 (var)--; \ 1219 store_flag_n(var >> 8); \ 1220 store_flag_z((var & 0xFFFF) != 0); \ 1221 } 1222 1223 #define OP_INCW(var) \ 1224 { \ 1225 (var)++; \ 1226 store_flag_n(var >> 8); \ 1227 store_flag_z((var & 0xFFFF) != 0); \ 1228 } 1229 1230 #define OP_DEC(var) \ 1231 { \ 1232 (var)--; \ 1233 store_flags_nz(var); \ 1234 } 1235 1236 #define OP_INC(var) \ 1237 { \ 1238 (var)++; \ 1239 store_flags_nz(var); \ 1240 } 1241 1242 #define OP_SET1(var) \ 1243 { \ 1244 (var) |= offset_to_bit[_opcode >> 5]; \ 1245 } 1246 #define OP_CLR1(var) \ 1247 { \ 1248 (var) &= offset_to_not[_opcode >> 5]; \ 1249 } 1250 1251 #define WRITE_OP(OP) \ 1252 OP_##OP(_data); \ 1253 set_byte_spc(_address, _data); 1254 #define WRITE_MOV(var) set_byte_spc(_address, (var)); 1255 1256 #define WRITE_ASL \ 1257 OP_ASL(_data); \ 1258 set_byte_spc(_address, _data); 1259 #define WRITE_LSR \ 1260 OP_LSR(_data); \ 1261 set_byte_spc(_address, _data); 1262 #define WRITE_ROL \ 1263 OP_ROL(_data); \ 1264 set_byte_spc(_address, _data); 1265 #define WRITE_ROR \ 1266 OP_ROR(_data); \ 1267 set_byte_spc(_address, _data); 1268 1269 #define WRITE_DEC \ 1270 OP_DEC(_data); \ 1271 set_byte_spc(_address, _data); 1272 #define WRITE_INC \ 1273 OP_INC(_data); \ 1274 set_byte_spc(_address, _data); 1275 1276 /* xxx01011 */ 1277 #define OP_RMW_DP(OP, NEED_OLD_DATA) \ 1278 /* 4 cycles - opcode, address, data read, op + data write */ \ 1279 START_CYCLE(2) \ 1280 _address = _dp + get_byte_spc(_PC); \ 1281 _PC++; \ 1282 END_CYCLE(2, 1) \ 1283 \ 1284 START_CYCLE(3) \ 1285 if (NEED_OLD_DATA) \ 1286 _data = get_byte_spc(_address); \ 1287 else \ 1288 get_byte_spc(_address); \ 1289 END_CYCLE(3, 1) \ 1290 \ 1291 START_CYCLE(4) \ 1292 OP END_OPCODE(1) 1293 1294 /* xxx01001 */ 1295 #define OP_RMW_DP_DP(OP) \ 1296 /* 6 cycles - opcode, src address, dest address, src read, */ \ 1297 /* dest read + op, dest write */ \ 1298 START_CYCLE(2) \ 1299 _address2 = _dp + get_byte_spc(_PC); \ 1300 _PC++; \ 1301 END_CYCLE(2, 1) \ 1302 \ 1303 START_CYCLE(3) \ 1304 _address = _dp + get_byte_spc(_PC); \ 1305 _PC++; \ 1306 END_CYCLE(3, 1) \ 1307 \ 1308 START_CYCLE(4) \ 1309 _data2 = get_byte_spc(_address2); \ 1310 END_CYCLE(4, 1) \ 1311 \ 1312 START_CYCLE(5) \ 1313 _data = get_byte_spc(_address); \ 1314 OP_##OP(_data, _data2) END_CYCLE(5, 1) \ 1315 \ 1316 START_CYCLE(6) set_byte_spc(_address, _data); \ 1317 END_OPCODE(1) 1318 1319 /* xxx01100 */ 1320 #define OP_RMW_ABS(OP, NEED_OLD_DATA) \ 1321 /* 5 cycles - opcode, address low, address high, data read, */ \ 1322 /* op + data write */ \ 1323 START_CYCLE(2) \ 1324 _address = get_byte_spc(_PC); \ 1325 _PC++; \ 1326 END_CYCLE(2, 1) \ 1327 \ 1328 START_CYCLE(3) \ 1329 _address += get_byte_spc(_PC) << 8; \ 1330 _PC++; \ 1331 END_CYCLE(3, 1) \ 1332 \ 1333 START_CYCLE(4) \ 1334 if (NEED_OLD_DATA) \ 1335 _data = get_byte_spc(_address); \ 1336 else \ 1337 get_byte_spc(_address); \ 1338 END_CYCLE(4, 1) \ 1339 \ 1340 START_CYCLE(5) \ 1341 OP END_OPCODE(1) 1342 1343 /* 0xx01101 */ 1344 #define OP_PUSH(src) \ 1345 { \ 1346 /* 4 cycles - opcode, address load, data write, SP decrement */ \ 1347 START_CYCLE(2) \ 1348 _address = 0x0100 + _SP; \ 1349 END_CYCLE(2, 1) \ 1350 \ 1351 START_CYCLE(3) \ 1352 set_byte_spc(_address, src); \ 1353 END_CYCLE(3, 1) \ 1354 \ 1355 START_CYCLE(4) \ 1356 _SP--; \ 1357 END_OPCODE(1) \ 1358 } 1359 1360 /* 1xx01110 */ 1361 #define OP_POP(dest) \ 1362 { \ 1363 /* 4 cycles - opcode, SP increment, address load, data read */ \ 1364 START_CYCLE(2) \ 1365 _SP++; \ 1366 END_CYCLE(2, 1) \ 1367 \ 1368 START_CYCLE(3) \ 1369 _address = 0x0100 + _SP; \ 1370 END_CYCLE(3, 1) \ 1371 \ 1372 START_CYCLE(4) \ 1373 (dest) = get_byte_spc(_address); \ 1374 END_OPCODE(1) \ 1375 } 1376 1377 #define OP_READ_DP_reg_INDEXED(OP, dest, index) \ 1378 /* 4 cycles - opcode, address, address calc, data read + op */ \ 1379 START_CYCLE(2) \ 1380 _address = get_byte_spc(_PC); \ 1381 _PC++; \ 1382 END_CYCLE(2, 1) \ 1383 \ 1384 START_CYCLE(3) \ 1385 _address = _dp + ((_address + index) & 0xFF); \ 1386 END_CYCLE(3, 1) \ 1387 \ 1388 START_CYCLE(4) \ 1389 _data = get_byte_spc(_address); \ 1390 OP_##OP((dest), _data) END_OPCODE(1) 1391 1392 #define OP_RMW_DP_reg_INDEXED(OP, NEED_OLD_DATA, index) \ 1393 /* 5 cycles - opcode, address, address calc, data read, */ \ 1394 /* data write */ \ 1395 START_CYCLE(2) \ 1396 _address = get_byte_spc(_PC); \ 1397 _PC++; \ 1398 END_CYCLE(2, 1) \ 1399 \ 1400 START_CYCLE(3) \ 1401 _address = _dp + ((_address + index) & 0xFF); \ 1402 END_CYCLE(3, 1) \ 1403 \ 1404 START_CYCLE(4) \ 1405 if (NEED_OLD_DATA) \ 1406 _data = get_byte_spc(_address); \ 1407 else \ 1408 get_byte_spc(_address); \ 1409 END_CYCLE(4, 1) \ 1410 \ 1411 START_CYCLE(5) \ 1412 OP END_OPCODE(1) 1413 1414 /* xxx10100 */ 1415 #define OP_READ_DP_X_INDEXED(OP, dest) OP_READ_DP_reg_INDEXED(OP, dest, _X) 1416 #define OP_READ_DP_X_INDEXED_A(OP) OP_READ_DP_X_INDEXED(OP, _A) 1417 /* xxx11011 */ 1418 #define OP_RMW_DP_X_INDEXED(OP, NEED_OLD_DATA) OP_RMW_DP_reg_INDEXED(OP, NEED_OLD_DATA, _X) 1419 1420 /* xxx11001 */ 1421 #define OP_READ_DP_Y_INDEXED(OP, dest) OP_READ_DP_reg_INDEXED(OP, dest, _Y) 1422 #define OP_RMW_DP_Y_INDEXED(OP, NEED_OLD_DATA) OP_RMW_DP_reg_INDEXED(OP, NEED_OLD_DATA, _Y) 1423 1424 #define OP_READ_ABS_reg_INDEXED(OP, dest, index) \ 1425 /* 5 cycles - opcode, address low, address high, address calc, */ \ 1426 /* data read + op */ \ 1427 START_CYCLE(2) \ 1428 _address = get_byte_spc(_PC); \ 1429 _PC++; \ 1430 END_CYCLE(2, 1) \ 1431 \ 1432 START_CYCLE(3) \ 1433 _address += get_byte_spc(_PC) << 8; \ 1434 _PC++; \ 1435 END_CYCLE(3, 1) \ 1436 \ 1437 START_CYCLE(4) \ 1438 _address += index; \ 1439 END_CYCLE(4, 1) \ 1440 \ 1441 START_CYCLE(5) \ 1442 _data = get_byte_spc(_address); \ 1443 OP_##OP((dest), _data) END_OPCODE(1) 1444 1445 #define OP_RMW_ABS_reg_INDEXED(OP, NEED_OLD_DATA, index) \ 1446 /* 6 cycles - opcode, address low, address high, address calc, */ \ 1447 /* data read, data write */ \ 1448 START_CYCLE(2) \ 1449 _address = get_byte_spc(_PC); \ 1450 _PC++; \ 1451 END_CYCLE(2, 1) \ 1452 \ 1453 START_CYCLE(3) \ 1454 _address += get_byte_spc(_PC) << 8; \ 1455 _PC++; \ 1456 END_CYCLE(3, 1) \ 1457 \ 1458 START_CYCLE(4) \ 1459 _address += index; \ 1460 END_CYCLE(4, 1) \ 1461 \ 1462 START_CYCLE(5) \ 1463 if (NEED_OLD_DATA) \ 1464 _data = get_byte_spc(_address); \ 1465 else \ 1466 get_byte_spc(_address); \ 1467 END_CYCLE(5, 1) \ 1468 \ 1469 START_CYCLE(6) \ 1470 OP END_OPCODE(1) 1471 1472 /* xxx10101 */ 1473 #define OP_READ_ABS_X_INDEXED_A(OP) OP_READ_ABS_reg_INDEXED(OP, _A, _X) 1474 #define OP_RMW_ABS_X_INDEXED(OP, NEED_OLD_DATA) OP_RMW_ABS_reg_INDEXED(OP, NEED_OLD_DATA, _X) 1475 1476 /* xxx10110 */ 1477 #define OP_READ_ABS_Y_INDEXED_A(OP) OP_READ_ABS_reg_INDEXED(OP, _A, _Y) 1478 #define OP_RMW_ABS_Y_INDEXED(OP, NEED_OLD_DATA) OP_RMW_ABS_reg_INDEXED(OP, NEED_OLD_DATA, _Y) 1479 1480 #define OP_READ_INDIRECT_INDEXED(OP, dest) \ 1481 /* 6 cycles - opcode, offset, address low, address high, */ \ 1482 /* address calc, data read + op */ \ 1483 START_CYCLE(2) \ 1484 _address2 = _dp + get_byte_spc(_PC); \ 1485 _PC++; \ 1486 END_CYCLE(2, 1) \ 1487 \ 1488 START_CYCLE(3) \ 1489 _address = get_byte_spc(_address2); \ 1490 END_CYCLE(3, 1) \ 1491 \ 1492 START_CYCLE(4) \ 1493 _address += get_byte_spc(_address2 + 1) << 8; \ 1494 END_CYCLE(4, 1) \ 1495 \ 1496 START_CYCLE(5) \ 1497 _address += _Y; \ 1498 END_CYCLE(5, 1) \ 1499 \ 1500 START_CYCLE(6) \ 1501 _data = get_byte_spc(_address); \ 1502 OP_##OP((dest), _data) END_OPCODE(1) 1503 1504 #define OP_RMW_INDIRECT_INDEXED(OP, NEED_OLD_DATA) \ 1505 /* 7 cycles - opcode, offset, address low, address high, */ \ 1506 /* address calc, data read + op, data write */ \ 1507 START_CYCLE(2) \ 1508 _address2 = _dp + get_byte_spc(_PC); \ 1509 _PC++; \ 1510 END_CYCLE(2, 1) \ 1511 \ 1512 START_CYCLE(3) \ 1513 _address = get_byte_spc(_address2); \ 1514 END_CYCLE(3, 1) \ 1515 \ 1516 START_CYCLE(4) \ 1517 _address += get_byte_spc(_address2 + 1) << 8; \ 1518 END_CYCLE(4, 1) \ 1519 \ 1520 START_CYCLE(5) \ 1521 _address += _Y; \ 1522 END_CYCLE(5, 1) \ 1523 \ 1524 START_CYCLE(6) \ 1525 if (NEED_OLD_DATA) \ 1526 _data = get_byte_spc(_address); \ 1527 else \ 1528 get_byte_spc(_address); \ 1529 END_CYCLE(6, 1) \ 1530 \ 1531 START_CYCLE(7) \ 1532 OP END_OPCODE(1) 1533 1534 /* xxx10111 */ 1535 #define OP_READ_INDIRECT_INDEXED_A(OP) OP_READ_INDIRECT_INDEXED(OP, _A) 1536 1537 /* xxx11000 */ 1538 #define OP_RMW_DP_IMM(OP) \ 1539 /* 5 cycles - opcode, src data, dest address, dest read + op, */ \ 1540 /* dest write */ \ 1541 START_CYCLE(2) \ 1542 _data2 = get_byte_spc(_PC); \ 1543 _PC++; \ 1544 END_CYCLE(2, 1) \ 1545 \ 1546 START_CYCLE(3) \ 1547 _address = _dp + get_byte_spc(_PC); \ 1548 _PC++; \ 1549 END_CYCLE(3, 1) \ 1550 \ 1551 START_CYCLE(4) \ 1552 _data = get_byte_spc(_address); \ 1553 OP_##OP(_data, _data2) END_CYCLE(4, 1) \ 1554 \ 1555 START_CYCLE(5) set_byte_spc(_address, _data); \ 1556 END_OPCODE(1) 1557 1558 /* xxx11001 */ 1559 #define OP_RMW_INDIRECT_INDIRECT(OP) \ 1560 /* 5 cycles - opcode, address calc, src read, dest read + op, */ \ 1561 /* dest write */ \ 1562 START_CYCLE(2) \ 1563 _address = _dp + _Y; \ 1564 END_CYCLE(2, 1) \ 1565 \ 1566 START_CYCLE(3) \ 1567 _data2 = get_byte_spc(_address); \ 1568 _address = _dp + _X; \ 1569 END_CYCLE(3, 1) \ 1570 \ 1571 START_CYCLE(4) \ 1572 _data = get_byte_spc(_address); \ 1573 OP_##OP(_data, _data2) END_CYCLE(4, 1) \ 1574 \ 1575 START_CYCLE(5) set_byte_spc(_address, _data); \ 1576 END_OPCODE(1) 1577 1578 /* note - timing on all 16-bit opcodes may be off: RMW could be instead: */ 1579 /* data low read, write, data high read, write; or data low read, */ 1580 /* data high read, data low write, data high write */ 1581 1582 /* xxx11010 */ 1583 #define OP_READ16_YA_DP(OP) \ 1584 /* 5 cycles - opcode, address, data low read, data high read + op, */ \ 1585 /* (?) */ \ 1586 START_CYCLE(2) \ 1587 _address = _dp + get_byte_spc(_PC); \ 1588 _PC++; \ 1589 END_CYCLE(2, 1) \ 1590 \ 1591 START_CYCLE(3) \ 1592 _data16 = get_byte_spc(_address); \ 1593 END_CYCLE(3, 1) \ 1594 \ 1595 START_CYCLE(4) \ 1596 _data16 += get_byte_spc(_address + 1) << 8; \ 1597 END_CYCLE(4, 1) \ 1598 \ 1599 START_CYCLE(5) \ 1600 OP_##OP(_YA, _data16) END_OPCODE(1) 1601 1602 #define OP_RMW16_DP(OP) \ 1603 /* 6 cycles - opcode, address, data low read, data high read + op, */ \ 1604 /* data low (?) write, data high write */ \ 1605 START_CYCLE(2) \ 1606 _address = _dp + get_byte_spc(_PC); \ 1607 _PC++; \ 1608 END_CYCLE(2, 1) \ 1609 \ 1610 START_CYCLE(3) \ 1611 _data16 = get_byte_spc(_address); \ 1612 END_CYCLE(3, 1) \ 1613 \ 1614 START_CYCLE(4) \ 1615 _data16 += get_byte_spc(_address + 1) << 8; \ 1616 END_CYCLE(4, 1) \ 1617 \ 1618 START_CYCLE(5) \ 1619 OP_##OP(_data16) set_byte_spc(_address, _data16); \ 1620 END_CYCLE(5, 1) \ 1621 \ 1622 START_CYCLE(6) \ 1623 set_byte_spc(_address + 1, _data16 >> 8); \ 1624 END_OPCODE(1) 1625 1626 /* xxx11100 */ 1627 #define OP_RMW_IMPLIED(OP, reg) \ 1628 /* 2 cycles - opcode, op */ \ 1629 START_CYCLE(2) \ 1630 OP_##OP(reg); \ 1631 END_OPCODE(1) 1632 1633 /* xxx11101 */ 1634 #define OP_MOV_IMPLIED(dest, src) \ 1635 /* 2 cycles - opcode, op */ \ 1636 START_CYCLE(2) \ 1637 OP_MOV_READ(dest, src) \ 1638 END_OPCODE(1) 1639 1640 #define OP_MOV_IMPLIED_NO_FLAGS(dest, src) \ 1641 /* 2 cycles - opcode, op */ \ 1642 START_CYCLE(2) \ 1643 (dest) = (src); \ 1644 END_OPCODE(1) 1645 1646 static void Execute_SPC(void) 1647 { 1648 u8 was_in_cpu = In_CPU; 1649 In_CPU = 0; 1650 1651 load_cycles_spc(); 1652 1653 while (_WorkCycles < 0) 1654 { 1655 s32 opcode_done = 1; 1656 1657 START_CYCLE(1) 1658 /* fetch opcode */ 1659 _opcode = get_byte_spc(_PC); 1660 _PC++; 1661 END_FETCH_CYCLE() 1662 1663 switch (_opcode) 1664 { 1665 /* xxx00000 */ 1666 case 0x00: /* NOP */ 1667 { 1668 START_CYCLE(2) 1669 END_OPCODE(1) 1670 } 1671 1672 case 0x20: /* CLRP */ 1673 { 1674 START_CYCLE(2) 1675 clr_flag_spc(SPC_FLAG_P); 1676 END_OPCODE(1) 1677 } 1678 1679 case 0x40: /* SETP */ 1680 { 1681 START_CYCLE(2) 1682 set_flag_spc(SPC_FLAG_P); 1683 END_OPCODE(1) 1684 } 1685 1686 case 0x60: /* CLRC */ 1687 { 1688 START_CYCLE(2) 1689 clr_flag_spc(SPC_FLAG_C); 1690 END_OPCODE(1) 1691 } 1692 1693 case 0x80: /* SETC */ 1694 { 1695 START_CYCLE(2) 1696 set_flag_spc(SPC_FLAG_C); 1697 END_OPCODE(1) 1698 } 1699 1700 case 0xA0: /* EI */ 1701 { 1702 START_CYCLE(2) 1703 set_flag_spc(SPC_FLAG_I); 1704 END_OPCODE(1) 1705 } 1706 1707 case 0xC0: /* DI */ 1708 { 1709 START_CYCLE(2) 1710 clr_flag_spc(SPC_FLAG_I); 1711 END_OPCODE(1) 1712 } 1713 1714 case 0xE0: /* CLRV */ 1715 { 1716 START_CYCLE(2) 1717 clr_flag_spc(SPC_FLAG_H | SPC_FLAG_V); 1718 END_OPCODE(1) 1719 } 1720 1721 /* xxxx0001 */ 1722 #define opcode_TCALL(vector) (((vector) << 4) + 0x01) 1723 case opcode_TCALL(0): 1724 case opcode_TCALL(1): 1725 case opcode_TCALL(2): 1726 case opcode_TCALL(3): 1727 case opcode_TCALL(4): 1728 case opcode_TCALL(5): 1729 case opcode_TCALL(6): 1730 case opcode_TCALL(7): 1731 case opcode_TCALL(8): 1732 case opcode_TCALL(9): 1733 case opcode_TCALL(10): 1734 case opcode_TCALL(11): 1735 case opcode_TCALL(12): 1736 case opcode_TCALL(13): 1737 case opcode_TCALL(14): 1738 case opcode_TCALL(15): 1739 { 1740 OP_TCALL(_opcode >> 4) 1741 } 1742 1743 /* xxx00010 */ 1744 #define opcode_SET1(bit) (((bit) << 5) + 0x02) 1745 case opcode_SET1(0): 1746 case opcode_SET1(1): 1747 case opcode_SET1(2): 1748 case opcode_SET1(3): 1749 case opcode_SET1(4): 1750 case opcode_SET1(5): 1751 case opcode_SET1(6): 1752 case opcode_SET1(7): 1753 { 1754 OP_RMW_DP(WRITE_OP(SET1), 1) 1755 } 1756 1757 /* xxx00011 */ 1758 #define opcode_BBS(bit) (((bit) << 5) + 0x03) 1759 case opcode_BBS(0): 1760 case opcode_BBS(1): 1761 case opcode_BBS(2): 1762 case opcode_BBS(3): 1763 case opcode_BBS(4): 1764 case opcode_BBS(5): 1765 case opcode_BBS(6): 1766 case opcode_BBS(7): 1767 { 1768 COND_DP_REL(DP_REL_TEST_BBS) 1769 } 1770 1771 /* xxx00100 */ 1772 case 0x04: /* OR A,dp */ 1773 { 1774 OP_READ_DP_A(OR) 1775 } 1776 1777 case 0x24: /* AND A,dp */ 1778 { 1779 OP_READ_DP_A(AND) 1780 } 1781 1782 case 0x44: /* EOR A,dp */ 1783 { 1784 OP_READ_DP_A(EOR) 1785 } 1786 1787 case 0x64: /* CMP A,dp */ 1788 { 1789 OP_READ_DP_A(CMP) 1790 } 1791 1792 case 0x84: /* ADC A,dp */ 1793 { 1794 OP_READ_DP_A(ADC) 1795 } 1796 1797 case 0xA4: /* SBC A,dp */ 1798 { 1799 OP_READ_DP_A(SBC) 1800 } 1801 1802 case 0xC4: /* MOV dp,A */ 1803 { 1804 OP_RMW_DP(WRITE_MOV(_A), 0) 1805 } 1806 1807 case 0xE4: /* MOV A,dp */ 1808 { 1809 OP_READ_DP_A(MOV_READ) 1810 } 1811 1812 /* xxx00101 */ 1813 case 0x05: /* OR A,abs */ 1814 { 1815 OP_READ_ABS_A(OR) 1816 } 1817 1818 case 0x25: /* AND A,abs */ 1819 { 1820 OP_READ_ABS_A(AND) 1821 } 1822 1823 case 0x45: /* EOR A,abs */ 1824 { 1825 OP_READ_ABS_A(EOR) 1826 } 1827 1828 case 0x65: /* CMP A,abs */ 1829 { 1830 OP_READ_ABS_A(CMP) 1831 } 1832 1833 case 0x85: /* ADC A,abs */ 1834 { 1835 OP_READ_ABS_A(ADC) 1836 } 1837 1838 case 0xA5: /* SBC A,abs */ 1839 { 1840 OP_READ_ABS_A(SBC) 1841 } 1842 1843 case 0xC5: /* MOV abs,A */ 1844 { 1845 OP_RMW_ABS(WRITE_MOV(_A), 0) 1846 } 1847 1848 case 0xE5: /* MOV A,abs */ 1849 { 1850 OP_READ_ABS_A(MOV_READ) 1851 } 1852 1853 /* xxx00110 */ 1854 case 0x06: /* OR A,(X) */ 1855 { 1856 OP_READ_INDIRECT_A(OR) 1857 } 1858 1859 case 0x26: /* AND A,(X) */ 1860 { 1861 OP_READ_INDIRECT_A(AND) 1862 } 1863 1864 case 0x46: /* EOR A,(X) */ 1865 { 1866 OP_READ_INDIRECT_A(EOR) 1867 } 1868 1869 case 0x66: /* CMP A,(X) */ 1870 { 1871 OP_READ_INDIRECT_A(CMP) 1872 } 1873 1874 case 0x86: /* ADC A,(X) */ 1875 { 1876 OP_READ_INDIRECT_A(ADC) 1877 } 1878 1879 case 0xA6: /* SBC A,(X) */ 1880 { 1881 OP_READ_INDIRECT_A(SBC) 1882 } 1883 1884 case 0xC6: /* MOV (X),A */ 1885 { 1886 OP_RMW_INDIRECT(WRITE_MOV(_A), 0) 1887 } 1888 1889 case 0xE6: /* MOV A,(X) */ 1890 { 1891 OP_READ_INDIRECT_A(MOV_READ) 1892 } 1893 1894 /* xxx00111 */ 1895 case 0x07: /* OR A,(dp+X) */ 1896 { 1897 OP_READ_INDEXED_INDIRECT_A(OR) 1898 } 1899 1900 case 0x27: /* AND A,(dp+X) */ 1901 { 1902 OP_READ_INDEXED_INDIRECT_A(AND) 1903 } 1904 1905 case 0x47: /* EOR A,(dp+X) */ 1906 { 1907 OP_READ_INDEXED_INDIRECT_A(EOR) 1908 } 1909 1910 case 0x67: /* CMP A,(dp+X) */ 1911 { 1912 OP_READ_INDEXED_INDIRECT_A(CMP) 1913 } 1914 1915 case 0x87: /* ADC A,(dp+X) */ 1916 { 1917 OP_READ_INDEXED_INDIRECT_A(ADC) 1918 } 1919 1920 case 0xA7: /* SBC A,(dp+X) */ 1921 { 1922 OP_READ_INDEXED_INDIRECT_A(SBC) 1923 } 1924 1925 case 0xC7: /* MOV (dp+X),A */ 1926 { 1927 OP_RMW_INDEXED_INDIRECT(WRITE_MOV(_A), 0) 1928 } 1929 1930 case 0xE7: /* MOV A,(dp+X) */ 1931 { 1932 OP_READ_INDEXED_INDIRECT_A(MOV_READ) 1933 } 1934 1935 /* xxx01000 */ 1936 case 0x08: /* OR A,#imm */ 1937 { 1938 OP_READ_IMM_A(OR) 1939 } 1940 1941 case 0x28: /* AND A,#imm */ 1942 { 1943 OP_READ_IMM_A(AND) 1944 } 1945 1946 case 0x48: /* EOR A,#imm */ 1947 { 1948 OP_READ_IMM_A(EOR) 1949 } 1950 1951 case 0x68: /* CMP A,#imm */ 1952 { 1953 OP_READ_IMM_A(CMP) 1954 } 1955 1956 case 0x88: /* ADC A,#imm */ 1957 { 1958 OP_READ_IMM_A(ADC) 1959 } 1960 1961 case 0xA8: /* SBC A,#imm */ 1962 { 1963 OP_READ_IMM_A(SBC) 1964 } 1965 1966 case 0xC8: /* CMP X,#imm */ 1967 { 1968 OP_READ_IMM(CMP, _X) 1969 } 1970 1971 case 0xE8: /* MOV A,#imm */ 1972 { 1973 OP_READ_IMM_A(MOV_READ) 1974 } 1975 1976 /* xxx01001 */ 1977 case 0x09: /* OR dp(d),dp(s) */ 1978 { 1979 OP_RMW_DP_DP(OR) 1980 } 1981 1982 case 0x29: /* AND dp(d),dp(s) */ 1983 { 1984 OP_RMW_DP_DP(AND) 1985 } 1986 1987 case 0x49: /* EOR dp(d),dp(s) */ 1988 { 1989 OP_RMW_DP_DP(EOR) 1990 } 1991 1992 case 0x69: /* CMP dp(d),dp(s) */ 1993 { 1994 /* 6 cycles - opcode, src address, dest address, src read, */ 1995 /* dest read + op, dummy cycle */ 1996 START_CYCLE(2) 1997 _address2 = _dp + get_byte_spc(_PC); 1998 _PC++; 1999 END_CYCLE(2, 1) 2000 2001 START_CYCLE(3) 2002 _address = _dp + get_byte_spc(_PC); 2003 _PC++; 2004 END_CYCLE(3, 1) 2005 2006 START_CYCLE(4) 2007 _data2 = get_byte_spc(_address2); 2008 END_CYCLE(4, 1) 2009 2010 START_CYCLE(5) 2011 _data = get_byte_spc(_address); 2012 OP_CMP(_data, _data2) 2013 END_OPCODE(2) 2014 } 2015 2016 case 0x89: /* ADC dp(d),dp(s) */ 2017 { 2018 OP_RMW_DP_DP(ADC) 2019 } 2020 2021 case 0xA9: /* SBC dp(d),dp(s) */ 2022 { 2023 OP_RMW_DP_DP(SBC) 2024 } 2025 2026 case 0xC9: /* MOV abs,X */ 2027 { 2028 OP_RMW_ABS(WRITE_MOV(_X), 0) 2029 } 2030 2031 case 0xE9: /* MOV X,abs */ 2032 { 2033 OP_READ_ABS(MOV_READ, _X) 2034 } 2035 2036 /* xxx01010 */ 2037 case 0x0A: /* OR1 C,mem.bit */ 2038 { 2039 /* 5 cycles - opcode, address low, address high, data read, op */ 2040 START_CYCLE(2) 2041 _address = get_byte_spc(_PC); 2042 _PC++; 2043 END_CYCLE(2, 1) 2044 2045 START_CYCLE(3) 2046 _address += get_byte_spc(_PC) << 8; 2047 /* separate bit number, address */ 2048 _offset = _address >> 13; 2049 _address &= 0x1FFF; 2050 _PC++; 2051 END_CYCLE(3, 1) 2052 2053 START_CYCLE(4) 2054 _data = get_byte_spc(_address); 2055 END_CYCLE(4, 1) 2056 2057 START_CYCLE(5) 2058 if (_data & offset_to_bit[_offset]) 2059 set_flag_spc(SPC_FLAG_C); 2060 END_OPCODE(1) 2061 } 2062 2063 case 0x2A: /* OR1 C,/mem.bit */ 2064 { 2065 /* 5 cycles - opcode, address low, address high, data read, op */ 2066 START_CYCLE(2) 2067 _address = get_byte_spc(_PC); 2068 _PC++; 2069 END_CYCLE(2, 1) 2070 2071 START_CYCLE(3) 2072 _address += get_byte_spc(_PC) << 8; 2073 /* separate bit number, address */ 2074 _offset = _address >> 13; 2075 _address &= 0x1FFF; 2076 _PC++; 2077 END_CYCLE(3, 1) 2078 2079 START_CYCLE(4) 2080 _data = get_byte_spc(_address); 2081 END_CYCLE(4, 1) 2082 2083 START_CYCLE(5) 2084 if (!(_data & offset_to_bit[_offset])) 2085 set_flag_spc(SPC_FLAG_C); 2086 END_OPCODE(1) 2087 } 2088 2089 case 0x4A: /* AND1 C,mem.bit */ 2090 { 2091 /* 4 cycles - opcode, address low, address high, data read + op */ 2092 START_CYCLE(2) 2093 _address = get_byte_spc(_PC); 2094 _PC++; 2095 END_CYCLE(2, 1) 2096 2097 START_CYCLE(3) 2098 _address += get_byte_spc(_PC) << 8; 2099 /* separate bit number, address */ 2100 _offset = _address >> 13; 2101 _address &= 0x1FFF; 2102 _PC++; 2103 END_CYCLE(3, 1) 2104 2105 START_CYCLE(4) 2106 _data = get_byte_spc(_address); 2107 if (!(_data & offset_to_bit[_offset])) 2108 clr_flag_spc(SPC_FLAG_C); 2109 END_OPCODE(1) 2110 } 2111 2112 case 0x6A: /* AND1 C,/mem.bit */ 2113 { 2114 /* 4 cycles - opcode, address low, address high, data read + op */ 2115 START_CYCLE(2) 2116 _address = get_byte_spc(_PC); 2117 _PC++; 2118 END_CYCLE(2, 1) 2119 2120 START_CYCLE(3) 2121 _address += get_byte_spc(_PC) << 8; 2122 /* separate bit number, address */ 2123 _offset = _address >> 13; 2124 _address &= 0x1FFF; 2125 _PC++; 2126 END_CYCLE(3, 1) 2127 2128 START_CYCLE(4) 2129 _data = get_byte_spc(_address); 2130 if (_data & offset_to_bit[_offset]) 2131 clr_flag_spc(SPC_FLAG_C); 2132 END_OPCODE(1) 2133 } 2134 2135 case 0x8A: /* EOR1 C,mem.bit */ 2136 { 2137 /* 5 cycles - opcode, address low, address high, data read, op */ 2138 START_CYCLE(2) 2139 _address = get_byte_spc(_PC); 2140 _PC++; 2141 END_CYCLE(2, 1) 2142 2143 START_CYCLE(3) 2144 _address += get_byte_spc(_PC) << 8; 2145 /* separate bit number, address */ 2146 _offset = _address >> 13; 2147 _address &= 0x1FFF; 2148 _PC++; 2149 END_CYCLE(3, 1) 2150 2151 START_CYCLE(4) 2152 _data = get_byte_spc(_address); 2153 END_CYCLE(4, 1) 2154 2155 START_CYCLE(5) 2156 if (_data & offset_to_bit[_offset]) 2157 complement_carry_spc(); 2158 END_OPCODE(1) 2159 } 2160 2161 case 0xAA: /* MOV1 C,mem.bit */ 2162 { 2163 /* 4 cycles - opcode, address low, address high, data read */ 2164 START_CYCLE(2) 2165 _address = get_byte_spc(_PC); 2166 _PC++; 2167 END_CYCLE(2, 1) 2168 2169 START_CYCLE(3) 2170 _address += get_byte_spc(_PC) << 8; 2171 /* separate bit number, address */ 2172 _offset = _address >> 13; 2173 _address &= 0x1FFF; 2174 _PC++; 2175 END_CYCLE(3, 1) 2176 2177 START_CYCLE(4) 2178 _data = get_byte_spc(_address); 2179 store_flag_c(_data & offset_to_bit[_offset]); 2180 END_OPCODE(1) 2181 } 2182 2183 case 0xCA: /* MOV1 mem.bit,C */ 2184 { 2185 /* 6 cycles - opcode, address low, address high, data read, op, */ 2186 /* data write */ 2187 START_CYCLE(2) 2188 _address = get_byte_spc(_PC); 2189 _PC++; 2190 END_CYCLE(2, 1) 2191 2192 START_CYCLE(3) 2193 _address += get_byte_spc(_PC) << 8; 2194 /* separate bit number, address */ 2195 _offset = _address >> 13; 2196 _address &= 0x1FFF; 2197 _PC++; 2198 END_CYCLE(3, 1) 2199 2200 START_CYCLE(4) 2201 _data = get_byte_spc(_address); 2202 END_CYCLE(4, 1) 2203 2204 START_CYCLE(5) 2205 if (flag_state_spc(SPC_FLAG_C)) 2206 _data |= offset_to_bit[_offset]; 2207 else 2208 _data &= offset_to_not[_offset]; 2209 END_CYCLE(5, 1) 2210 2211 START_CYCLE(6) 2212 set_byte_spc(_address, _data); 2213 END_OPCODE(1) 2214 } 2215 2216 case 0xEA: /* NOT1 mem.bit */ 2217 { 2218 /* 5 cycles - opcode, address low, address high, data read, */ 2219 /* op + data write */ 2220 START_CYCLE(2) 2221 _address = get_byte_spc(_PC); 2222 _PC++; 2223 END_CYCLE(2, 1) 2224 2225 START_CYCLE(3) 2226 _address += get_byte_spc(_PC) << 8; 2227 /* separate bit number, address */ 2228 _offset = _address >> 13; 2229 _address &= 0x1FFF; 2230 _PC++; 2231 END_CYCLE(3, 1) 2232 2233 START_CYCLE(4) 2234 _data = get_byte_spc(_address); 2235 END_CYCLE(4, 1) 2236 2237 START_CYCLE(5) 2238 _data ^= offset_to_bit[_offset]; 2239 set_byte_spc(_address, _data); 2240 END_OPCODE(1) 2241 } 2242 2243 /* xxx01011 */ 2244 case 0x0B: /* ASL dp */ 2245 { 2246 OP_RMW_DP(WRITE_OP(ASL), 1) 2247 } 2248 2249 case 0x2B: /* ROL dp */ 2250 { 2251 OP_RMW_DP(WRITE_OP(ROL), 1) 2252 } 2253 2254 case 0x4B: /* LSR dp */ 2255 { 2256 OP_RMW_DP(WRITE_OP(LSR), 1) 2257 } 2258 2259 case 0x6B: /* ROR dp */ 2260 { 2261 OP_RMW_DP(WRITE_OP(ROR), 1) 2262 } 2263 2264 case 0x8B: /* DEC dp */ 2265 { 2266 OP_RMW_DP(WRITE_OP(DEC), 1) 2267 } 2268 2269 case 0xAB: /* INC dp */ 2270 { 2271 OP_RMW_DP(WRITE_OP(INC), 1) 2272 } 2273 2274 case 0xCB: /* MOV dp,Y */ 2275 { 2276 OP_RMW_DP(WRITE_MOV(_Y), 0) 2277 } 2278 2279 case 0xEB: /* MOV Y,dp */ 2280 { 2281 OP_READ_DP(MOV_READ, _Y) 2282 } 2283 2284 /* xxx01100 */ 2285 case 0x0C: /* ASL abs */ 2286 { 2287 OP_RMW_ABS(WRITE_OP(ASL), 1) 2288 } 2289 2290 case 0x2C: /* ROL abs */ 2291 { 2292 OP_RMW_ABS(WRITE_OP(ROL), 1) 2293 } 2294 2295 case 0x4C: /* LSR abs */ 2296 { 2297 OP_RMW_ABS(WRITE_OP(LSR), 1) 2298 } 2299 2300 case 0x6C: /* ROR abs */ 2301 { 2302 OP_RMW_ABS(WRITE_OP(ROR), 1) 2303 } 2304 2305 case 0x8C: /* DEC abs */ 2306 { 2307 OP_RMW_ABS(WRITE_OP(DEC), 1) 2308 } 2309 2310 case 0xAC: /* INC abs */ 2311 { 2312 OP_RMW_ABS(WRITE_OP(INC), 1) 2313 } 2314 2315 case 0xCC: /* MOV abs,Y */ 2316 { 2317 OP_RMW_ABS(WRITE_MOV(_Y), 0) 2318 } 2319 2320 case 0xEC: /* MOV Y,abs */ 2321 { 2322 OP_READ_ABS(MOV_READ, _Y) 2323 } 2324 2325 /* xxx01101 */ 2326 case 0x0D: /* PUSH PSW */ 2327 { 2328 /* 4 cycles - opcode, address load, data write, SP decrement */ 2329 START_CYCLE(2) 2330 _address = 0x0100 + _SP; 2331 END_CYCLE(2, 1) 2332 2333 START_CYCLE(3) 2334 spc_setup_flags(_B_flag); 2335 set_byte_spc(_address, _PSW); 2336 END_CYCLE(3, 1) 2337 2338 START_CYCLE(4) 2339 _SP--; 2340 END_OPCODE(1) 2341 } 2342 2343 case 0x2D: /* PUSH A */ 2344 { 2345 OP_PUSH(_A) 2346 } 2347 2348 case 0x4D: /* PUSH X */ 2349 { 2350 OP_PUSH(_X) 2351 } 2352 2353 case 0x6D: /* PUSH Y */ 2354 { 2355 OP_PUSH(_Y) 2356 } 2357 2358 case 0x8D: /* MOV Y,#imm */ 2359 { 2360 OP_READ_IMM(MOV_READ, _Y) 2361 } 2362 2363 case 0xAD: /* CMP Y,#imm */ 2364 { 2365 OP_READ_IMM(CMP, _Y) 2366 } 2367 2368 case 0xCD: /* MOV X,#imm */ 2369 { 2370 OP_READ_IMM(MOV_READ, _X) 2371 } 2372 2373 case 0xED: /* NOTC */ 2374 { 2375 /* 2 cycles - opcode, op */ 2376 START_CYCLE(2) 2377 complement_carry_spc(); 2378 END_OPCODE(1) 2379 } 2380 2381 /* xxx01110 */ 2382 case 0x0E: /* TSET1 abs */ 2383 { 2384 /* 6 cycles - opcode, address low, address high, data read, */ 2385 /* test for flags, op + data write */ 2386 START_CYCLE(2) 2387 _address = get_byte_spc(_PC); 2388 _PC++; 2389 END_CYCLE(2, 1) 2390 2391 START_CYCLE(3) 2392 _address += get_byte_spc(_PC) << 8; 2393 _PC++; 2394 END_CYCLE(3, 1) 2395 2396 START_CYCLE(4) 2397 _data = get_byte_spc(_address); 2398 END_CYCLE(4, 1) 2399 2400 START_CYCLE(5) 2401 store_flags_nz(_data & _A); 2402 END_CYCLE(5, 1) 2403 2404 START_CYCLE(6) 2405 _data |= _A; 2406 set_byte_spc(_address, _data); 2407 END_OPCODE(1) 2408 } 2409 2410 case 0x2E: /* CBNE dp,rel */ 2411 { 2412 COND_DP_REL(TEST_CBNE) 2413 } 2414 2415 case 0x4E: /* TCLR1 abs */ 2416 { 2417 /* 6 cycles - opcode, address low, address high, data read, */ 2418 /* test for flags, op + data write */ 2419 START_CYCLE(2) 2420 _address = get_byte_spc(_PC); 2421 _PC++; 2422 END_CYCLE(2, 1) 2423 2424 START_CYCLE(3) 2425 _address += get_byte_spc(_PC) << 8; 2426 _PC++; 2427 END_CYCLE(3, 1) 2428 2429 START_CYCLE(4) 2430 _data = get_byte_spc(_address); 2431 END_CYCLE(4, 1) 2432 2433 START_CYCLE(5) 2434 store_flags_nz(_data & _A); 2435 END_CYCLE(5, 1) 2436 2437 START_CYCLE(6) 2438 _data &= ~_A; 2439 set_byte_spc(_address, _data); 2440 END_OPCODE(1) 2441 } 2442 2443 case 0x6E: /* DBNZ dp,rel */ 2444 { 2445 COND_DP_REL(DP_REL_TEST_DBNZ) 2446 } 2447 2448 case 0x8E: /* POP PSW */ 2449 { 2450 /* 4 cycles - opcode, SP increment, address load, data read */ 2451 START_CYCLE(2) 2452 _SP++; 2453 END_CYCLE(2, 1) 2454 2455 START_CYCLE(3) 2456 _address = 0x0100 + _SP; 2457 END_CYCLE(3, 1) 2458 2459 START_CYCLE(4) 2460 _PSW = get_byte_spc(_address); 2461 spc_restore_flags(); 2462 END_OPCODE(1) 2463 } 2464 2465 case 0xAE: /* POP A */ 2466 { 2467 OP_POP(_A) 2468 } 2469 2470 case 0xCE: /* POP X */ 2471 { 2472 OP_POP(_X) 2473 } 2474 2475 case 0xEE: /* POP Y */ 2476 { 2477 OP_POP(_Y) 2478 } 2479 2480 /* xxx01111 */ 2481 case 0x0F: /* BRK */ 2482 { 2483 /* 8 cycles - opcode, new PCL, new PCH, stack address load, */ 2484 /* PSW write, PCH write, PCL write, SP decrement */ 2485 /* fetch address for PC */ 2486 START_CYCLE(2) 2487 /* same vector as TCALL 0 */ 2488 _address = 0xFFC0 + ((15 - (0)) * 2); 2489 _address2 = get_byte_spc(_address); 2490 END_CYCLE(2, 1) 2491 2492 START_CYCLE(3) 2493 _address2 += (get_byte_spc(_address + 1) << 8); 2494 END_CYCLE(3, 1) 2495 2496 START_CYCLE(4) 2497 _address = 0x0100 + _SP; 2498 END_CYCLE(4, 1) 2499 2500 START_CYCLE(5) 2501 set_byte_spc(_address, _PC >> 8); 2502 _SP--; 2503 _address = 0x0100 + _SP; 2504 END_CYCLE(5, 1) 2505 2506 START_CYCLE(6) 2507 set_byte_spc(_address, _PC); 2508 _SP--; 2509 _address = 0x0100 + _SP; 2510 END_CYCLE(6, 1) 2511 2512 START_CYCLE(7) 2513 spc_setup_flags(_B_flag); 2514 set_byte_spc(_address, _PSW); 2515 set_flag_spc(SPC_FLAG_B); 2516 clr_flag_spc(SPC_FLAG_I); 2517 END_CYCLE(7, 1) 2518 2519 START_CYCLE(8) 2520 _PC = _address2; 2521 _SP--; 2522 END_OPCODE(1) 2523 } 2524 2525 case 0x2F: /* BRA rel */ 2526 { 2527 COND_REL(REL_TEST_BRA) 2528 } 2529 2530 case 0x4F: /* PCALL upage */ 2531 { 2532 /* 6 cycles - opcode, new PCL, stack address load, PCH write, */ 2533 /* PCL write, SP decrement */ 2534 /* fetch address for PC */ 2535 START_CYCLE(2) 2536 _address2 = 0xFF00 + get_byte_spc(_PC); 2537 _PC++; 2538 END_CYCLE(2, 1) 2539 2540 START_CYCLE(3) 2541 _address = 0x0100 + _SP; 2542 END_CYCLE(3, 1) 2543 2544 START_CYCLE(4) 2545 set_byte_spc(_address, _PC >> 8); 2546 _SP--; 2547 _address = 0x0100 + _SP; 2548 END_CYCLE(4, 1) 2549 2550 START_CYCLE(5) 2551 set_byte_spc(_address, _PC); 2552 END_CYCLE(5, 1) 2553 2554 START_CYCLE(6) 2555 _PC = _address2; 2556 _SP--; 2557 END_OPCODE(1) 2558 } 2559 2560 case 0x6F: /* RET */ 2561 { 2562 /* 5 cycles - opcode, SP increment, address load, new PCL, new PCH */ 2563 /* pop address to PC */ 2564 START_CYCLE(2) 2565 _SP++; 2566 END_CYCLE(2, 1) 2567 2568 START_CYCLE(3) 2569 _address = 0x0100 + _SP; 2570 2571 END_CYCLE(3, 1) 2572 2573 START_CYCLE(4) 2574 _address2 = get_byte_spc(_address); 2575 _SP++; 2576 _address = 0x0100 + _SP; 2577 END_CYCLE(4, 1) 2578 2579 START_CYCLE(5) 2580 _PC = (get_byte_spc(_address) << 8) + _address2; 2581 END_OPCODE(1) 2582 } 2583 2584 case 0x8F: /* MOV dp,#imm */ 2585 { 2586 OP_RMW_DP_IMM(MOV_READ_NOFLAGS) 2587 } 2588 2589 case 0xAF: /* MOV (X)+,A */ 2590 { 2591 /* 4 cycles - opcode, address load, data write, X increment */ 2592 START_CYCLE(2) 2593 _address = _dp + _X; 2594 END_CYCLE(2, 1) 2595 2596 START_CYCLE(3) 2597 set_byte_spc(_address, _A); 2598 END_CYCLE(3, 1) 2599 2600 START_CYCLE(4) 2601 _X++; 2602 END_OPCODE(1) 2603 } 2604 2605 case 0xCF: /* MUL YA */ 2606 { 2607 /* 9 cycles - opcode, 8(op) */ 2608 START_CYCLE(2) 2609 _YA = (u32)_Y * _A; 2610 store_flags_nz(_Y); 2611 END_OPCODE(8) 2612 } 2613 2614 /* xxx10000 */ 2615 case 0x10: /* BPL rel */ 2616 { 2617 COND_REL(REL_TEST_BPL) 2618 } 2619 2620 case 0x30: /* BMI rel */ 2621 { 2622 COND_REL(REL_TEST_BMI) 2623 } 2624 2625 case 0x50: /* BVC rel */ 2626 { 2627 COND_REL(REL_TEST_BVC) 2628 } 2629 2630 case 0x70: /* BVS rel */ 2631 { 2632 COND_REL(REL_TEST_BVS) 2633 } 2634 2635 case 0x90: /* BCC rel */ 2636 { 2637 COND_REL(REL_TEST_BCC) 2638 } 2639 2640 case 0xB0: /* BCS rel */ 2641 { 2642 COND_REL(REL_TEST_BCS) 2643 } 2644 2645 case 0xD0: /* BNE rel */ 2646 { 2647 COND_REL(REL_TEST_BNE) 2648 } 2649 2650 case 0xF0: /* BEQ rel */ 2651 { 2652 COND_REL(REL_TEST_BEQ) 2653 } 2654 2655 /* xxx10010 */ 2656 #define opcode_CLR1(bit) (((bit) << 5) + 0x12) 2657 case opcode_CLR1(0): 2658 case opcode_CLR1(1): 2659 case opcode_CLR1(2): 2660 case opcode_CLR1(3): 2661 case opcode_CLR1(4): 2662 case opcode_CLR1(5): 2663 case opcode_CLR1(6): 2664 case opcode_CLR1(7): 2665 { 2666 OP_RMW_DP(WRITE_OP(CLR1), 1) 2667 } 2668 2669 /* xxx10011 */ 2670 #define opcode_BBC(bit) (((bit) << 5) + 0x13) 2671 case opcode_BBC(0): 2672 case opcode_BBC(1): 2673 case opcode_BBC(2): 2674 case opcode_BBC(3): 2675 case opcode_BBC(4): 2676 case opcode_BBC(5): 2677 case opcode_BBC(6): 2678 case opcode_BBC(7): 2679 { 2680 COND_DP_REL(DP_REL_TEST_BBC) 2681 } 2682 2683 /* xxx10100 */ 2684 case 0x14: /* OR A,dp+X */ 2685 { 2686 OP_READ_DP_X_INDEXED_A(OR) 2687 } 2688 2689 case 0x34: /* AND A,dp+X */ 2690 { 2691 OP_READ_DP_X_INDEXED_A(AND) 2692 } 2693 2694 case 0x54: /* EOR A,dp+X */ 2695 { 2696 OP_READ_DP_X_INDEXED_A(EOR) 2697 } 2698 2699 case 0x74: /* CMP A,dp+X */ 2700 { 2701 OP_READ_DP_X_INDEXED_A(CMP) 2702 } 2703 2704 case 0x94: /* ADC A,dp+X */ 2705 { 2706 OP_READ_DP_X_INDEXED_A(ADC) 2707 } 2708 2709 case 0xB4: /* SBC A,dp+X */ 2710 { 2711 OP_READ_DP_X_INDEXED_A(SBC) 2712 } 2713 2714 case 0xD4: /* MOV dp+X,A */ 2715 { 2716 OP_RMW_DP_X_INDEXED(WRITE_MOV(_A), 0) 2717 } 2718 2719 case 0xF4: /* MOV A,dp+X */ 2720 { 2721 OP_READ_DP_X_INDEXED_A(MOV_READ) 2722 } 2723 2724 /* xxx10101 */ 2725 case 0x15: /* OR A,abs+X */ 2726 { 2727 OP_READ_ABS_X_INDEXED_A(OR) 2728 } 2729 2730 case 0x35: /* AND A,abs+X */ 2731 { 2732 OP_READ_ABS_X_INDEXED_A(AND) 2733 } 2734 2735 case 0x55: /* EOR A,abs+X */ 2736 { 2737 OP_READ_ABS_X_INDEXED_A(EOR) 2738 } 2739 2740 case 0x75: /* CMP A,abs+X */ 2741 { 2742 OP_READ_ABS_X_INDEXED_A(CMP) 2743 } 2744 2745 case 0x95: /* ADC A,abs+X */ 2746 { 2747 OP_READ_ABS_X_INDEXED_A(ADC) 2748 } 2749 2750 case 0xB5: /* SBC A,abs+X */ 2751 { 2752 OP_READ_ABS_X_INDEXED_A(SBC) 2753 } 2754 2755 case 0xD5: /* MOV abs+X,A */ 2756 { 2757 OP_RMW_ABS_X_INDEXED(WRITE_MOV(_A), 0) 2758 } 2759 2760 case 0xF5: /* MOV A,abs+X */ 2761 { 2762 OP_READ_ABS_X_INDEXED_A(MOV_READ) 2763 } 2764 2765 /* xxx10110 */ 2766 case 0x16: /* OR A,abs+Y */ 2767 { 2768 OP_READ_ABS_Y_INDEXED_A(OR) 2769 } 2770 2771 case 0x36: /* AND A,abs+Y */ 2772 { 2773 OP_READ_ABS_Y_INDEXED_A(AND) 2774 } 2775 2776 case 0x56: /* EOR A,abs+Y */ 2777 { 2778 OP_READ_ABS_Y_INDEXED_A(EOR) 2779 } 2780 2781 case 0x76: /* CMP A,abs+Y */ 2782 { 2783 OP_READ_ABS_Y_INDEXED_A(CMP) 2784 } 2785 2786 case 0x96: /* ADC A,abs+Y */ 2787 { 2788 OP_READ_ABS_Y_INDEXED_A(ADC) 2789 } 2790 2791 case 0xB6: /* SBC A,abs+Y */ 2792 { 2793 OP_READ_ABS_Y_INDEXED_A(SBC) 2794 } 2795 2796 case 0xD6: /* MOV abs+Y,A */ 2797 { 2798 OP_RMW_ABS_Y_INDEXED(WRITE_MOV(_A), 0) 2799 } 2800 2801 case 0xF6: /* MOV A,abs+Y */ 2802 { 2803 OP_READ_ABS_Y_INDEXED_A(MOV_READ) 2804 } 2805 2806 /* xxx10111 */ 2807 case 0x17: /* OR A,(dp)+Y */ 2808 { 2809 OP_READ_INDIRECT_INDEXED_A(OR) 2810 } 2811 2812 case 0x37: /* AND A,(dp)+Y */ 2813 { 2814 OP_READ_INDIRECT_INDEXED_A(AND) 2815 } 2816 2817 case 0x57: /* EOR A,(dp)+Y */ 2818 { 2819 OP_READ_INDIRECT_INDEXED_A(EOR) 2820 } 2821 2822 case 0x77: /* CMP A,(dp)+Y */ 2823 { 2824 OP_READ_INDIRECT_INDEXED_A(CMP) 2825 } 2826 2827 case 0x97: /* ADC A,(dp)+Y */ 2828 { 2829 OP_READ_INDIRECT_INDEXED_A(ADC) 2830 } 2831 2832 case 0xB7: /* SBC A,(dp)+Y */ 2833 { 2834 OP_READ_INDIRECT_INDEXED_A(SBC) 2835 } 2836 2837 case 0xD7: /* MOV (dp)+Y,A */ 2838 { 2839 OP_RMW_INDIRECT_INDEXED(WRITE_MOV(_A), 0) 2840 } 2841 2842 case 0xF7: /* MOV A,(dp)+Y */ 2843 { 2844 OP_READ_INDIRECT_INDEXED_A(MOV_READ) 2845 } 2846 2847 /* xxx11000 */ 2848 case 0x18: /* OR dp,#imm */ 2849 { 2850 OP_RMW_DP_IMM(OR) 2851 } 2852 2853 case 0x38: /* AND dp,#imm */ 2854 { 2855 OP_RMW_DP_IMM(AND) 2856 } 2857 2858 case 0x58: /* EOR dp,#imm */ 2859 { 2860 OP_RMW_DP_IMM(EOR) 2861 } 2862 2863 case 0x78: /* CMP dp,#imm */ 2864 { 2865 /* 5 cycles - opcode, src data, dest address, dest read + op, */ 2866 /* dummy cycle */ 2867 START_CYCLE(2) 2868 _data2 = get_byte_spc(_PC); 2869 _PC++; 2870 END_CYCLE(2, 1) 2871 2872 START_CYCLE(3) 2873 _address = _dp + get_byte_spc(_PC); 2874 _PC++; 2875 END_CYCLE(3, 1) 2876 2877 START_CYCLE(4) 2878 _data = get_byte_spc(_address); 2879 OP_CMP(_data, _data2) 2880 END_OPCODE(2) 2881 } 2882 2883 case 0x98: /* ADC dp,#imm */ 2884 { 2885 OP_RMW_DP_IMM(ADC) 2886 } 2887 2888 case 0xB8: /* SBC dp,#imm */ 2889 { 2890 OP_RMW_DP_IMM(SBC) 2891 } 2892 2893 case 0xD8: /* MOV dp,X */ 2894 { 2895 OP_RMW_DP(WRITE_MOV(_X), 0) 2896 } 2897 2898 case 0xF8: /* MOV X,dp */ 2899 { 2900 OP_READ_DP(MOV_READ, _X) 2901 } 2902 2903 /* xxx11001 */ 2904 case 0x19: /* OR (X),(Y) */ 2905 { 2906 OP_RMW_INDIRECT_INDIRECT(OR) 2907 } 2908 2909 case 0x39: /* AND (X),(Y) */ 2910 { 2911 OP_RMW_INDIRECT_INDIRECT(AND) 2912 } 2913 2914 case 0x59: /* EOR (X),(Y) */ 2915 { 2916 OP_RMW_INDIRECT_INDIRECT(EOR) 2917 } 2918 2919 case 0x79: /* CMP (X),(Y) */ 2920 { 2921 /* 5 cycles - opcode, address calc, src read, dest read + op, */ 2922 /* dummy cycle */ 2923 START_CYCLE(2) 2924 _address = _dp + _Y; 2925 END_CYCLE(2, 1) 2926 2927 START_CYCLE(3) 2928 _data2 = get_byte_spc(_address); 2929 _address = _dp + _X; 2930 END_CYCLE(3, 1) 2931 2932 START_CYCLE(4) 2933 _data = get_byte_spc(_address); 2934 OP_CMP(_data, _data2) 2935 END_OPCODE(2) 2936 } 2937 2938 case 0x99: /* ADC (X),(Y) */ 2939 { 2940 OP_RMW_INDIRECT_INDIRECT(ADC) 2941 } 2942 2943 case 0xB9: /* SBC (X),(Y) */ 2944 { 2945 OP_RMW_INDIRECT_INDIRECT(SBC) 2946 } 2947 2948 case 0xD9: /* MOV dp+Y,X */ 2949 { 2950 OP_RMW_DP_Y_INDEXED(WRITE_MOV(_X), 0) 2951 } 2952 2953 case 0xF9: /* MOV X,dp+Y */ 2954 { 2955 OP_READ_DP_Y_INDEXED(MOV_READ, _X) 2956 } 2957 2958 /* xxx11010 */ 2959 case 0x1A: /* DECW dp */ 2960 { 2961 OP_RMW16_DP(DECW) 2962 } 2963 2964 case 0x3A: /* INCW dp */ 2965 { 2966 OP_RMW16_DP(INCW) 2967 } 2968 2969 case 0x5A: /* CMPW YA,dp */ 2970 { 2971 u32 temp; 2972 2973 /* 4 cycles - opcode, address, data low read, data high read + op */ 2974 START_CYCLE(2) 2975 _address = _dp + get_byte_spc(_PC); 2976 _PC++; 2977 END_CYCLE(2, 1) 2978 2979 START_CYCLE(3) 2980 _data16 = get_byte_spc(_address); 2981 END_CYCLE(3, 1) 2982 2983 START_CYCLE(4) 2984 _data16 += get_byte_spc(_address + 1) << 8; 2985 temp = _YA - _data16; 2986 store_flag_c(temp <= 0xFFFF); 2987 store_flag_n(temp >> 8); 2988 store_flag_z(temp != 0); 2989 END_OPCODE(1) 2990 } 2991 2992 case 0x7A: /* ADDW YA,dp */ 2993 { 2994 OP_READ16_YA_DP(ADDW) 2995 } 2996 2997 case 0x9A: /* SUBW YA,dp */ 2998 { 2999 OP_READ16_YA_DP(SUBW) 3000 } 3001 3002 case 0xBA: /* MOVW YA,dp */ 3003 { 3004 OP_READ16_YA_DP(MOVW_READ) 3005 } 3006 3007 case 0xDA: /* MOVW dp,YA */ 3008 { 3009 /* 5 cycles - opcode, address, (?), data low write, data high write, */ 3010 START_CYCLE(2) 3011 _address = _dp + get_byte_spc(_PC); 3012 _PC++; 3013 END_CYCLE(2, 1) 3014 3015 START_CYCLE(3) 3016 get_byte_spc(_address); 3017 END_CYCLE(3, 1) 3018 3019 START_CYCLE(4) 3020 set_byte_spc(_address, _A); 3021 END_CYCLE(4, 1) 3022 3023 START_CYCLE(5) 3024 set_byte_spc(_address + 1, _Y); 3025 END_OPCODE(1) 3026 } 3027 3028 case 0xFA: /* MOV dp(d),dp(s) */ 3029 { 3030 /* 5 cycles - opcode, src address, dest address, src read, */ 3031 /* dest write */ 3032 START_CYCLE(2) 3033 _address2 = _dp + get_byte_spc(_PC); 3034 _PC++; 3035 END_CYCLE(2, 1) 3036 3037 START_CYCLE(3) 3038 _address = _dp + get_byte_spc(_PC); 3039 _PC++; 3040 END_CYCLE(3, 1) 3041 3042 START_CYCLE(4) 3043 _data = get_byte_spc(_address2); 3044 END_CYCLE(4, 1) 3045 3046 START_CYCLE(5) 3047 set_byte_spc(_address, _data); 3048 END_OPCODE(1) 3049 } 3050 3051 /* xxx11011 */ 3052 case 0x1B: /* ASL dp+X */ 3053 { 3054 OP_RMW_DP_X_INDEXED(WRITE_OP(ASL), 1) 3055 } 3056 3057 case 0x3B: /* ROL dp+X */ 3058 { 3059 OP_RMW_DP_X_INDEXED(WRITE_OP(ROL), 1) 3060 } 3061 3062 case 0x5B: /* LSR dp+X */ 3063 { 3064 OP_RMW_DP_X_INDEXED(WRITE_OP(LSR), 1) 3065 } 3066 3067 case 0x7B: /* ROR dp+X */ 3068 { 3069 OP_RMW_DP_X_INDEXED(WRITE_OP(ROR), 1) 3070 } 3071 3072 case 0x9B: /* DEC dp+X */ 3073 { 3074 OP_RMW_DP_X_INDEXED(WRITE_OP(DEC), 1) 3075 } 3076 3077 case 0xBB: /* INC dp+X */ 3078 { 3079 OP_RMW_DP_X_INDEXED(WRITE_OP(INC), 1) 3080 } 3081 3082 case 0xDB: /* MOV dp+X,Y */ 3083 { 3084 OP_RMW_DP_X_INDEXED(WRITE_MOV(_Y), 0) 3085 } 3086 3087 case 0xFB: /* MOV Y,dp+X */ 3088 { 3089 OP_READ_DP_X_INDEXED(MOV_READ, _Y) 3090 } 3091 3092 /* xxx11100 */ 3093 case 0x1C: /* ASL A */ 3094 { 3095 OP_RMW_IMPLIED(ASL, _A) 3096 } 3097 3098 case 0x3C: /* ROL A */ 3099 { 3100 OP_RMW_IMPLIED(ROL, _A) 3101 } 3102 3103 case 0x5C: /* LSR A */ 3104 { 3105 OP_RMW_IMPLIED(LSR, _A) 3106 } 3107 3108 case 0x7C: /* ROR A */ 3109 { 3110 OP_RMW_IMPLIED(ROR, _A) 3111 } 3112 3113 case 0x9C: /* DEC A */ 3114 { 3115 OP_RMW_IMPLIED(DEC, _A) 3116 } 3117 3118 case 0xBC: /* INC A */ 3119 { 3120 OP_RMW_IMPLIED(INC, _A) 3121 } 3122 3123 case 0xDC: /* DEC Y */ 3124 { 3125 OP_RMW_IMPLIED(DEC, _Y) 3126 } 3127 3128 case 0xFC: /* INC Y */ 3129 { 3130 OP_RMW_IMPLIED(INC, _Y) 3131 } 3132 3133 /* xxx11101 */ 3134 case 0x1D: /* DEC X */ 3135 { 3136 OP_RMW_IMPLIED(DEC, _X) 3137 } 3138 3139 case 0x3D: /* INC X */ 3140 { 3141 OP_RMW_IMPLIED(INC, _X) 3142 } 3143 3144 case 0x5D: /* MOV X,A */ 3145 { 3146 OP_MOV_IMPLIED(_X, _A) 3147 } 3148 3149 case 0x7D: /* MOV A,X */ 3150 { 3151 OP_MOV_IMPLIED(_A, _X) 3152 } 3153 3154 case 0x9D: /* MOV X,SP */ 3155 { 3156 OP_MOV_IMPLIED(_X, _SP) 3157 } 3158 3159 case 0xBD: /* MOV SP,X */ 3160 { 3161 OP_MOV_IMPLIED_NO_FLAGS(_SP, _X) 3162 } 3163 3164 case 0xDD: /* MOV A,Y */ 3165 { 3166 OP_MOV_IMPLIED(_A, _Y) 3167 } 3168 3169 case 0xFD: /* MOV Y,A */ 3170 { 3171 OP_MOV_IMPLIED(_Y, _A) 3172 } 3173 3174 /* xxx11110 */ 3175 case 0x1E: /* CMP X,abs */ 3176 { 3177 OP_READ_ABS(CMP, _X) 3178 } 3179 3180 case 0x3E: /* CMP X,dp */ 3181 { 3182 OP_READ_DP(CMP, _X) 3183 } 3184 3185 case 0x5E: /* CMP Y,abs */ 3186 { 3187 OP_READ_ABS(CMP, _Y) 3188 } 3189 3190 case 0x7E: /* CMP Y,dp */ 3191 { 3192 OP_READ_DP(CMP, _Y) 3193 } 3194 3195 case 0x9E: /* DIV YA,X */ 3196 { 3197 /* 12 cycles - opcode, 11(op) */ 3198 /* timing of operations completely wrong here, at least */ 3199 START_CYCLE(2) 3200 u32 yva, work_x, i; 3201 yva = _YA; 3202 work_x = (u32)_X << 9; 3203 3204 if ((_X & 0xF) <= (_Y & 0xF)) 3205 set_flag_spc(SPC_FLAG_H); 3206 else 3207 clr_flag_spc(SPC_FLAG_H); 3208 3209 for (i = 0; i < 9; i++) 3210 { 3211 yva <<= 1; 3212 if (yva & 0x20000) 3213 yva = (yva & 0x1FFFF) | 1; /* 17-bit ROL */ 3214 if (yva >= work_x) 3215 yva ^= 1; /* Why XOR i don't know, but it's what works */ 3216 /* and I guess this was easier than a compound if */ 3217 if (yva & 1) 3218 yva = (yva - work_x) & 0x1FFFF; /* enforce 17-bit register limit! */ 3219 } 3220 3221 if (yva & 0x100) 3222 set_flag_spc(SPC_FLAG_V); 3223 else 3224 clr_flag_spc(SPC_FLAG_V); 3225 3226 _YA = (((yva >> 9) & 0xFF) << 8) + (yva & 0xFF); 3227 store_flags_nz(_YA); 3228 END_OPCODE(11) 3229 } 3230 3231 case 0xBE: /* DAS */ 3232 { 3233 /* 3 cycles - opcode, 2(op) */ 3234 START_CYCLE(2) 3235 _data = _A; 3236 if ((_data & 0x0F) > 9 || !flag_state_spc(SPC_FLAG_H)) 3237 { 3238 _A -= 6; 3239 } 3240 END_CYCLE(2, 1) 3241 3242 START_CYCLE(3) 3243 if (_data > 0x99 || !flag_state_spc(SPC_FLAG_C)) 3244 { 3245 _A -= 0x60; 3246 clr_flag_spc(SPC_FLAG_C); 3247 } 3248 store_flags_nz(_A); 3249 END_OPCODE(1) 3250 } 3251 3252 case 0xDE: /* CBNE dp+X,rel */ 3253 { 3254 /* 6 cycles - opcode, address, branch offset, address index */ 3255 /* (add X), data read, branch logic; */ 3256 /* +2 cycles (taken branch) add PC to offset, reload PC */ 3257 START_CYCLE(2) 3258 _address = get_byte_spc(_PC); 3259 _PC++; 3260 END_CYCLE(2, 1) 3261 3262 START_CYCLE(3) 3263 _offset = get_byte_spc(_PC); 3264 _PC++; 3265 END_CYCLE(3, 1) 3266 3267 START_CYCLE(4) 3268 _address = _dp + ((_address + _X) & 0xFF); 3269 END_CYCLE(4, 1) 3270 3271 START_CYCLE(5) 3272 _data = get_byte_spc(_address); 3273 END_CYCLE(5, 1) 3274 3275 START_CYCLE(6) 3276 END_BRANCH_OPCODE(6, TEST_CBNE) 3277 } 3278 3279 case 0xFE: /* DBNZ Y,rel */ 3280 { 3281 /* 4 cycles - opcode, branch offset, decrement Y, branch logic; */ 3282 /* +2 cycles (taken branch) add PC to offset, reload PC */ 3283 3284 START_CYCLE(2) 3285 _offset = get_byte_spc(_PC); 3286 _PC++; 3287 END_CYCLE(2, 1) 3288 3289 START_CYCLE(3) 3290 _Y--; 3291 END_CYCLE(3, 1) 3292 3293 START_CYCLE(4) 3294 END_BRANCH_OPCODE(4, if (!_Y) EXIT_OPCODE(1)) 3295 } 3296 3297 /* xxx11111 */ 3298 case 0x1F: /* JMP (abs+X) */ 3299 { 3300 /* 6 cycles - opcode, address low, address high */ 3301 /* address index (add X), new PCL, new PCH */ 3302 /* fetch base adderss */ 3303 START_CYCLE(2) 3304 _address = get_byte_spc(_PC); 3305 _PC++; 3306 END_CYCLE(2, 1) 3307 3308 START_CYCLE(3) 3309 _address += get_byte_spc(_PC) << 8; 3310 END_CYCLE(3, 1) 3311 3312 START_CYCLE(4) 3313 _address += _X; 3314 END_CYCLE(4, 1) 3315 3316 START_CYCLE(5) 3317 _offset = get_byte_spc(_address); 3318 END_CYCLE(5, 1) 3319 3320 START_CYCLE(6) 3321 _PC = (get_byte_spc(_address + 1) << 8) + _offset; 3322 END_OPCODE(1) 3323 } 3324 3325 case 0x3F: /* CALL abs */ 3326 { 3327 /* 8 cycles - opcode, new PCL, new PCH, stack address load, PCH */ 3328 /* write, PCL write, dummy cycle (PSW write in BRK?) */ 3329 /* SP decrement */ 3330 /* fetch address for PC */ 3331 START_CYCLE(2) 3332 _address2 = get_byte_spc(_PC); 3333 _PC++; 3334 END_CYCLE(2, 1) 3335 3336 START_CYCLE(3) 3337 _address2 += (get_byte_spc(_PC) << 8); 3338 _PC++; 3339 END_CYCLE(3, 1) 3340 3341 START_CYCLE(4) 3342 _address = 0x0100 + _SP; 3343 END_CYCLE(4, 1) 3344 3345 START_CYCLE(5) 3346 set_byte_spc(_address, _PC >> 8); 3347 _SP--; 3348 _address = 0x0100 + _SP; 3349 END_CYCLE(5, 1) 3350 3351 START_CYCLE(6) 3352 set_byte_spc(_address, _PC); 3353 _SP--; 3354 _address = 0x0100 + _SP; 3355 END_CYCLE(6, 1) 3356 3357 START_CYCLE(7) 3358 /* should we write PSW to stack here? */ 3359 END_CYCLE(7, 1) 3360 3361 START_CYCLE(8) 3362 _PC = _address2; 3363 END_OPCODE(1) 3364 } 3365 3366 case 0x5F: /* JMP abs */ 3367 { 3368 /* 3 cycles - opcode, new PCL, new PCH */ 3369 /* fetch address to PC */ 3370 START_CYCLE(2) 3371 _address = get_byte_spc(_PC); 3372 _PC++; 3373 END_CYCLE(2, 1) 3374 3375 START_CYCLE(3) 3376 _PC = (get_byte_spc(_PC) << 8) + _address; 3377 END_OPCODE(1) 3378 } 3379 3380 case 0x7F: /* RETI */ 3381 { 3382 /* 6 cycles - opcode, SP increment, address load, new PSW, new PCL, */ 3383 /* new PCH, pop address to PC */ 3384 START_CYCLE(2) 3385 _SP++; 3386 END_CYCLE(2, 1) 3387 3388 START_CYCLE(3) 3389 _address = 0x0100 + _SP; 3390 3391 END_CYCLE(3, 1) 3392 3393 START_CYCLE(4) 3394 _PSW = get_byte_spc(_address); 3395 spc_restore_flags(); 3396 _SP++; 3397 _address = 0x0100 + _SP; 3398 END_CYCLE(4, 1) 3399 3400 START_CYCLE(5) 3401 _address2 = get_byte_spc(_address); 3402 _SP++; 3403 _address = 0x0100 + _SP; 3404 END_CYCLE(5, 1) 3405 3406 START_CYCLE(6) 3407 _PC = (get_byte_spc(_address) << 8) + _address2; 3408 END_OPCODE(1) 3409 } 3410 3411 case 0x9F: /* XCN A */ 3412 { 3413 /* 5 cycles - opcode, 4(op) */ 3414 /* timing of operations may be off here */ 3415 START_CYCLE(2) 3416 _data = _A; 3417 END_CYCLE(2, 1) 3418 3419 START_CYCLE(3) 3420 _A <<= 4; 3421 END_CYCLE(3, 1) 3422 3423 START_CYCLE(4) 3424 _data >>= 4; 3425 END_CYCLE(4, 1) 3426 3427 START_CYCLE(5) 3428 OP_OR(_A, _data); 3429 END_OPCODE(1) 3430 } 3431 3432 case 0xBF: /* MOV A,(X)+ */ 3433 { 3434 /* 4 cycles - opcode, address load, data read, X increment */ 3435 START_CYCLE(2) 3436 _address = _dp + _X; 3437 END_CYCLE(2, 1) 3438 3439 START_CYCLE(3) 3440 _data = get_byte_spc(_address); 3441 OP_MOV_READ(_A, _data) 3442 END_CYCLE(3, 1) 3443 3444 START_CYCLE(4) 3445 _X++; 3446 END_OPCODE(1) 3447 } 3448 3449 case 0xDF: /* DAA */ 3450 { 3451 /* 3 cycles - opcode, 2(op) */ 3452 START_CYCLE(2) 3453 _data = _A; 3454 if ((_data & 0x0F) > 9 || flag_state_spc(SPC_FLAG_H)) 3455 { 3456 _A += 6; 3457 if (_A < 6) 3458 set_flag_spc(SPC_FLAG_C); 3459 } 3460 END_CYCLE(2, 1) 3461 3462 START_CYCLE(3) 3463 if (_data > 0x99 || flag_state_spc(SPC_FLAG_C)) 3464 { 3465 _A += 0x60; 3466 set_flag_spc(SPC_FLAG_C); 3467 } 3468 store_flags_nz(_A); 3469 END_OPCODE(1) 3470 } 3471 3472 /* handle unhandled or invalid opcodes */ 3473 case 0xEF: /* SLEEP */ 3474 case 0xFF: /* STOP */ 3475 default: 3476 { 3477 /* set up address (PC) and opcode for display */ 3478 Map_Byte = _opcode; 3479 /* Adjust address to correct for increment */ 3480 Map_Address = (_PC - 1) & 0xFFFF; 3481 save_cycles_spc(); /* Set cycle counter */ 3482 InvalidSPCOpcode(); /* This exits.. aviods conflict with other things! */ 3483 load_cycles_spc(); 3484 break; 3485 } 3486 } 3487 if (opcode_done) 3488 _cycle = 0; 3489 } 3490 3491 save_cycles_spc(); /* Set cycle counter */ 3492 3493 #ifdef INDEPENDENT_SPC 3494 /* update SPC700 timers to prevent overflow */ 3495 Update_SPC_Timer(0); 3496 Update_SPC_Timer(1); 3497 Update_SPC_Timer(2); 3498 #endif 3499 3500 In_CPU = was_in_cpu; 3501 } 3502 3503 void SPC_START(u32 cycles) 3504 { 3505 u64 temp = cycles; 3506 temp = (temp * SPC_CPU_cycle_multiplicand) + SPC_CPU_cycles_mul; 3507 3508 /* save remainder */ 3509 SPC_CPU_cycles_mul = temp % SPC_CPU_cycle_divisor; 3510 3511 cycles = temp / SPC_CPU_cycle_divisor; 3512 SPC_CPU_cycles = 0; 3513 3514 /* Add new balance of SPC cycles */ 3515 _Cycles += cycles; 3516 if (_Cycles <= _TotalCycles) 3517 { 3518 if ((s32)_Cycles < 0) 3519 return; 3520 if ((s32)_TotalCycles >= 0) 3521 return; 3522 Wrap_SPC_Cyclecounter(); 3523 } 3524 3525 Execute_SPC(); 3526 } 3527