1 /** 2 * @ingroup lib_emu68 3 * @file emu68/inst68.h 4 * @brief 68k instructions header. 5 * @author Benjamin Gerard 6 * @date 1999/03/13 7 */ 8 9 /* Copyright (c) 1998-2015 Benjamin Gerard */ 10 11 #ifndef EMU68_INST68_H 12 #define EMU68_INST68_H 13 14 #include "emu68_api.h" 15 #include "type68.h" 16 17 /** 18 * @defgroup lib_emu68_inst 68k Instructions 19 * @ingroup lib_emu68_core 20 * @{ 21 */ 22 23 /** 24 * @name Arithmetical instruction functions 25 * 26 * The integer arithmetic operations include four basic operations: 27 * ADD, SUB, MUL, and DIV. They also include CMP, CMPM, CMP2, CLR, 28 * and NEG. The instruction set includes ADD, CMP, and SUB 29 * instructions for both address and data operations with all 30 * operand sizes valid for data operations. Address operands consist 31 * of 16 or 32 bits. The CLR and NEG instructions apply to all sizes 32 * of data operands. Signed and unsigned MUL and DIV instructions 33 * include: 34 * - Word multiply to produce a long product. 35 * - Long divided by a word divisor (word quotient, word remainder). 36 * 37 * @{ 38 */ 39 40 EMU68_EXTERN 41 /** 42 * 68K ADD/X instruction. 43 * 44 * The add68() function performs addition and updates SR flags 45 * accordingly. 46 * 47 * @param emu68 68k emulator instance. 48 * @param s normalized source operand 49 * @param d normalized destination operand 50 * @param c normalized carry 51 * @return normalized result 52 * @retval d + s + c 53 */ 54 int68_t add68(emu68_t * const emu68, const int68_t s, int68_t d, int68_t c); 55 56 EMU68_EXTERN 57 /** 58 * 68K SUB/X instruction. 59 * 60 * The sub68() function performs substraction and updates SR flags 61 * accordingly. 62 * 63 * @param emu68 68k emulator instance. 64 * @param s normalized source operand 65 * @param d normalized destination operand 66 * @param c normalized carry 67 * @return normalized result 68 * @retval d - s - c 69 */ 70 int68_t sub68(emu68_t * const emu68, const int68_t s, int68_t d, int68_t c); 71 72 EMU68_EXTERN 73 /** 74 * 68K CMP instruction. 75 * 76 * The cmp68() function performs substraction d minus s and updates 77 * SR flags accordingly. 78 * 79 * @param emu68 68k emulator instance. 80 * @param s normalized source operand 81 * @param d normalized destination operand 82 */ 83 void cmp68(emu68_t * const emu68, const int68_t s, int68_t d); 84 85 EMU68_EXTERN 86 /** 87 * 68k NEG/X instruction. 88 * 89 * The neg68() function performs 2nd complement and updates SR flags 90 * accordingly. 91 * 92 * @param emu68 68k emulator instance. 93 * @param d normalized destination operand 94 * @param c normalized carry 95 * @return normalized result 96 * @retval -d - c 97 */ 98 int68_t neg68(emu68_t * const emu68, int68_t d, int68_t c); 99 100 EMU68_EXTERN 101 /** 102 * 68K MULS instruction. 103 * 104 * The muls68() function performs signed multiplication and updates 105 * SR flags accordingly. 106 * 107 * @param emu68 68k emulator instance. 108 * @param s normalized word source operand 109 * @param d normalized word destination operand 110 * @return normalized long result 111 * @retval d * s 112 */ 113 int68_t muls68(emu68_t * const emu68, const int68_t s, int68_t d); 114 115 EMU68_EXTERN 116 /** 117 * 68K MULU instruction. 118 * 119 * The mulu68() function performs unsigned multiplication and updates 120 * SR flags accordingly. 121 * 122 * @param emu68 68k emulator instance. 123 * @param s normalized word source operand 124 * @param d normalized word destination operand 125 * @return normalized long result 126 * @retval d * s 127 */ 128 int68_t mulu68(emu68_t * const emu68, const uint68_t s, uint68_t d); 129 130 EMU68_EXTERN 131 /** 132 * 68K DIVS instruction. 133 * 134 * The divs68() function performs signed division and updates SR 135 * flags accordingly. In case of divide by zero the corresponding 136 * exception is triggered. In case of overflow the result is the 137 * destination unchanged; additionnally V SR flag is set. 138 * 139 * @param emu68 68k emulator instance. 140 * @param s normalized word source operand 141 * @param d normalized long destination operand 142 * @return result 143 * @retval MSW:d%s LSW:d/s 144 * @retval unchanged d in case of overflow 145 */ 146 int68_t divs68(emu68_t * const emu68, const int68_t s, int68_t d); 147 148 EMU68_EXTERN 149 /** 150 * 68K DIVU instruction. 151 * 152 * The divu68() function performs unsigned division and updates SR 153 * flags accordingly. In case of divide by zero the corresponding 154 * exception is triggered. In case of overflow the result is the 155 * destination unchanged; additionnally V SR flag is set. 156 * 157 * @param emu68 68k emulator instance. 158 * @param s normalized word source operand 159 * @param d normalized long destination operand 160 * @return result 161 * @retval MSW:d%s LSW:d/s 162 * @retval unchanged d in case of overflow 163 */ 164 int68_t divu68(emu68_t * const emu68, const uint68_t s, uint68_t d); 165 166 EMU68_EXTERN 167 /** 168 * 68K CLR instruction. 169 * 170 * The clr68() function clears and updates SR flags accordingly. 171 * 172 * @param emu68 68k emulator instance. 173 * @retval 0 174 */ 175 int68_t clr68(emu68_t * const emu68); 176 177 /** 178 * @} 179 */ 180 181 /** 182 * @name Logical instruction functions 183 * 184 * The logical operation instructions (AND, OR, EOR, and NOT) perform 185 * logical operations with all sizes of integer data operands. 186 * 187 * @{ 188 */ 189 190 EMU68_EXTERN 191 /** 192 * 68K AND instruction. 193 * 194 * The and68() function performs bitwise AND and updates SR flags 195 * accordingly. 196 * 197 * @param emu68 68k emulator instance. 198 * @param s normalized source operand 199 * @param d normalized destination operand 200 * @return normalized result 201 * @retval d & s 202 */ 203 int68_t and68(emu68_t * const emu68, const int68_t s, int68_t d); 204 205 EMU68_EXTERN 206 /** 207 * 68K OR instruction. 208 * 209 * The orr68() function performs bitwise OR and updates SR flags 210 * accordingly. 211 * 212 * @param emu68 68k emulator instance. 213 * @param s normalized source operand 214 * @param d normalized destination operand 215 * @return normalized result 216 * @retval d | s 217 */ 218 int68_t orr68(emu68_t * const emu68, const int68_t s, int68_t d); 219 220 EMU68_EXTERN 221 /** 222 * 68K EOR instruction. 223 * 224 * The eor68() function performs bitwise OR and updates SR flags 225 * accordingly. 226 * 227 * @param emu68 68k emulator instance. 228 * @param s normalized source operand 229 * @param d normalized destination operand 230 * @return normalized result 231 * @retval d ^ s 232 */ 233 int68_t eor68(emu68_t * const emu68, const int68_t s, int68_t d); 234 235 EMU68_EXTERN 236 /** 237 * 68K NOT instruction. 238 * 239 * The not68() function performs bitwise NOT (aka 1st complement) and 240 * updates SR flags accordingly. 241 * 242 * @param emu68 68k emulator instance 243 * @param d normalized destination operand 244 * @return normalized result 245 * @retval ~d 246 */ 247 int68_t not68(emu68_t * const emu68, int68_t d); 248 249 /** 250 * @} 251 */ 252 253 254 /** 255 * @name Bit manipulation functions 256 * 257 * BTST, BSET, BCLR, and BCHG are bit manipulation instructions. All 258 * bit manipulation operations can be performed on either registers 259 * or memory. The bit number is specified either as immediate data or 260 * in the contents of a data register. Register operands are 32 bits 261 * long, and memory operands are 8 bits long. Table 3-6 summarizes 262 * bit manipulation operations; Z refers to the zero bit of the CCR. 263 * 264 * @{ 265 */ 266 267 EMU68_EXTERN 268 /** 269 * 68K BTST instruction (Bit TeST). 270 * 271 * The btst68() function performs a bit test and updates SR flags 272 * accordingly. 273 * 274 * @param emu68 68k emulator instance 275 * @param val value to test 276 * @param bit bit number 277 */ 278 void btst68(emu68_t * const emu68, const int68_t val, const int bit); 279 280 EMU68_EXTERN 281 /** 282 * 68K BSET instruction (Bit SET). 283 * 284 * The bset68() function performs a bit test and set and updates SR 285 * flags accordingly. 286 * 287 * @param emu68 68k emulator instance 288 * @param val value to test 289 * @param bit bit number 290 * @return result 291 * @retval val | (1<<bit) 292 */ 293 int68_t bset68(emu68_t * const emu68, const int68_t val, const int bit); 294 295 EMU68_EXTERN 296 /** 297 * 68K BCLR instruction (Bit CLeaR). 298 * 299 * The bclr68() function performs a bit test and clear and updates SR 300 * flags accordingly. 301 * 302 * @param emu68 68k emulator instance 303 * @param val value to test 304 * @param bit bit number 305 * @return result 306 * @retval val & ~(1<<bit) 307 */ 308 int68_t bclr68(emu68_t * const emu68, const int68_t val, const int bit); 309 310 EMU68_EXTERN 311 /** 312 * 68K BCHG instruction (Bit CHanGe). 313 * 314 * The bchg68() function performs a bit test and change and updates SR 315 * flags accordingly. 316 * 317 * @param emu68 68k emulator instance 318 * @param val value to test 319 * @param bit bit number 320 * @return result 321 * @retval val ^ (1<<bit) 322 */ 323 int68_t bchg68(emu68_t * const emu68, const int68_t val, const int bit); 324 325 /** 326 * @} 327 */ 328 329 330 /** 331 * @name Program control instructions 332 * 333 * A set of subroutine call and return instructions and conditional 334 * and unconditional branch instructions perform program control 335 * operations. Also included are test operand instructions (TST and 336 * FTST), which set the integer or floating-point condition codes for 337 * use by other program and system control instructions. NOP forces 338 * synchronization of the internal pipelines. Table 3-9 summarizes 339 * these instructions. 340 * 341 * @{ 342 */ 343 344 EMU68_EXTERN 345 void rts68(emu68_t * const emu68); 346 347 EMU68_EXTERN 348 void rte68(emu68_t * const emu68); 349 350 EMU68_EXTERN 351 void rtr68(emu68_t * const emu68); 352 353 EMU68_EXTERN 354 void bsr68(emu68_t * const emu68, const addr68_t addr); 355 356 EMU68_EXTERN 357 void (* const bcc68[])(emu68_t * const, const addr68_t); 358 359 EMU68_EXTERN 360 void jmp68(emu68_t * const emu68, const addr68_t addr); 361 362 EMU68_EXTERN 363 void jsr68(emu68_t * const emu68, const addr68_t addr); 364 365 EMU68_EXTERN 366 void nop68(emu68_t * const emu68); 367 368 EMU68_EXTERN 369 void tst68(emu68_t * const emu68, const int68_t a); 370 371 EMU68_EXTERN 372 int68_t tas68(emu68_t * const emu68, const int68_t a); 373 374 EMU68_EXTERN 375 void (* const dbcc68[])(emu68_t * const emu68, const int dn); 376 377 EMU68_EXTERN 378 int (* const scc68[])(emu68_t * const emu68); 379 380 381 /** 382 * @} 383 */ 384 385 386 /** 387 * @name Data move instructions 388 * 389 * The MOVE instructions with their associated addressing modes are 390 * the basic means of transferring and storing addresses and 391 * data. MOVE instructions transfer byte, word, and long-word 392 * operands from memory to memory, memory to register, register to 393 * memory, and register to register. MOVE instructions transfer word 394 * and long-word operands and ensure that only valid address 395 * manipulations are executed. 396 * 397 * Data move and associated instructions are MOVEM, MOVEP, MOVEQ, 398 * EXG, LEA, PEA, LINK, and UNLK. 399 * 400 * @{ 401 */ 402 403 EMU68_EXTERN 404 /** 405 * 68K LEA instruction (load effective address). 406 * 407 * The lea68() function returns effective address. 408 * 409 * @param emu68 68k emulator instance 410 * @param mode addressing mode [0..7] 411 * @param reg address register [0..7] 412 * @return effective address 413 */ 414 addr68_t lea68(emu68_t * const emu68, const int mode, const int reg); 415 416 EMU68_EXTERN 417 /** 418 * 68K PEA instruction (push effective address). 419 * 420 * The pea68() function pushs effective address into the stack. 421 * 422 * @param emu68 68k emulator instance 423 * @param mode addressing mode [0..7] 424 * @param reg address register [0..7] 425 * @return effective address 426 */ 427 addr68_t pea68(emu68_t * const emu68, const int mode, const int reg); 428 429 EMU68_EXTERN 430 void exg68(emu68_t * const emu68, const int reg0, const int reg9); 431 432 EMU68_EXTERN 433 void link68(emu68_t * const emu68, const int reg); 434 435 EMU68_EXTERN 436 void unlk68(emu68_t * const emu68, const int reg); 437 438 /* EMU68_EXTERN */ 439 /* void movem68(emu68_t * const emu68, const int reg0, const int reg9); */ 440 441 /* EMU68_EXTERN */ 442 /* void movep68(emu68_t * const emu68, const int reg0, const int reg9); */ 443 444 /** 445 * @} 446 */ 447 448 449 /** 450 * @name Shifting instructions 451 * 452 * The ASR, ASL, LSR, and LSL instructions provide shift operations 453 * in both directions. The ROR, ROL, ROXR, and ROXL instructions 454 * perform rotate (circular shift) operations, with and without the 455 * CCR extend bit (X-bit). All shift and rotate operations can be 456 * performed on either registers or memory. Register shift and 457 * rotate operations shift all operand sizes. The shift count can be 458 * specified in the instruction operation word (to shift from 1 – 8 459 * places) or in a register (modulo 64 shift count). Memory shift 460 * and rotate operations shift word operands one bit position 461 * only. The SWAP instruction exchanges the 16-bit halves of a 462 * register. Fast byte swapping is possible by using the ROR and ROL 463 * instructions with a shift count of eight, enhancing the 464 * performance of the shift/rotate instructions. Table 3-5 is a 465 * summary of the shift and rotate operations. In Table 3-5, C and X 466 * refer to the C-bit and X- bit in the CCR. 467 * 468 * @{ 469 */ 470 471 EMU68_EXTERN 472 /** 473 * SWAP high and low words. 474 * 475 * The swap68() function performs a MSW LSW swapping and updates SR 476 * flags accordingly. 477 * 478 * @param emu68 68k emulator instance 479 * @param d unnormalized destination operand 480 * @return result 481 */ 482 void swap68(emu68_t * const emu68, const int d); 483 484 EMU68_EXTERN 485 /** 486 * Logical Shift Left. 487 * 488 * The lsl68() function performs logical (unsigned) shift left and 489 * updates SR flags accordingly. 490 * 491 * @param emu68 68k emulator instance 492 * @param d normalized destination operand 493 * @param s source operand (shift count) 494 * @param l word length in bit minus one (7, 15 or 31) 495 * @return normalized result 496 * @retval d << s 497 */ 498 int68_t lsl68(emu68_t * const emu68, uint68_t d, int s, const int l); 499 500 EMU68_EXTERN 501 /** 502 * Logical Shift Right. 503 * 504 * The lsr68() function performs logical (unsigned) shift right and 505 * updates SR flags accordingly 506 * 507 * @param emu68 68k emulator instance 508 * @param d normalized destination operand 509 * @param s source operand (shift count) 510 * @param l word length in bit minus one (7, 15 or 31) 511 * @return normalized result 512 * @retval d >> s 513 */ 514 int68_t lsr68(emu68_t * const emu68, uint68_t d, int s, const int l); 515 516 EMU68_EXTERN 517 /** 518 * Arithmetic Shift Left. 519 * 520 * The asl68() function performs arithmetic (signed) shift left and 521 * updates SR flags accordingly 522 * 523 * @param emu68 68k emulator instance 524 * @param d normalized destination operand 525 * @param s source operand (shift count) 526 * @param l word length in bit minus one (7, 15 or 31) 527 * @return normalized result 528 * @retval d << s 529 */ 530 int68_t asl68(emu68_t * const emu68, int68_t d, int s, const int l); 531 532 EMU68_EXTERN 533 /** 534 * Arithmetic Shift Right. 535 * 536 * The asr68() function performs arithmetic (signed) shift right and 537 * updates SR flags accordingly 538 * 539 * @param emu68 68k emulator instance 540 * @param d normalized destination operand 541 * @param s source operand (shift count) 542 * @param l word length in bit minus one (7, 15 or 31) 543 * @return normalized result 544 * @retval d >> s 545 */ 546 int68_t asr68(emu68_t * const emu68, int68_t d, int s, const int l); 547 548 EMU68_EXTERN 549 /** 550 * ROtation Left. 551 * 552 * The rol68() function performs bit rotation to the left and updates 553 * SR flags accordingly 554 * 555 * @param emu68 68k emulator instance 556 * @param d normalized destination operand 557 * @param s source operand (shift count) 558 * @param l word length in bit minus one (7, 15 or 31) 559 * @return normalized result 560 */ 561 int68_t rol68(emu68_t * const emu68, uint68_t d, int s, const int l); 562 563 EMU68_EXTERN 564 /** 565 * ROtation Right. 566 * 567 * The ror68() function performs bit rotation to the right and 568 * updates SR flags accordingly 569 * 570 * @param emu68 68k emulator instance 571 * @param d normalized destination operand 572 * @param s source operand (shift count) 573 * @param l word length in bit minus one (7, 15 or 31) 574 * @return normalized result 575 */ 576 int68_t ror68(emu68_t * const emu68, uint68_t d, int s, const int l); 577 578 EMU68_EXTERN 579 /** 580 * ROtation eXtended Left. 581 * 582 * The roxl68() function performs extended bit rotation to the left 583 * and updates SR flags accordingly 584 * 585 * @param emu68 68k emulator instance 586 * @param d normalized destination operand 587 * @param s source operand (shift count) 588 * @param l word length in bit minus one (7, 15 or 31) 589 * @return normalized result 590 */ 591 int68_t roxl68(emu68_t * const emu68, uint68_t d, int s, const int l); 592 593 EMU68_EXTERN 594 /** 595 * ROtation eXtended Right. 596 * 597 * The roxr68() function performs extended bit rotation to the right 598 * and updates SR flags accordingly 599 * 600 * @param emu68 68k emulator instance 601 * @param d normalized destination operand 602 * @param s source operand (shift count) 603 * @param l word length in bit minus one (7, 15 or 31) 604 * @return normalized result 605 */ 606 int68_t roxr68(emu68_t * const emu68, uint68_t d, int s, const int l); 607 608 /** 609 * @} 610 */ 611 612 613 /** 614 * @name Binary Coded Decimal (BCD) instructions 615 * 616 * Three instructions support operations on binary-coded decimal 617 * (BCD) numbers. The arithmetic operations on packed BCD numbers are 618 * ABCD, SBCD, and NBCD. 619 * 620 * @{ 621 */ 622 623 EMU68_EXTERN 624 /** 625 * Negate Binary Coded Decimal with extend. 626 * 627 * The nbcd68() function performs BCD negating with extend and 628 * updates SR flags accordingly 629 * 630 * @param emu68 68k emulator instance. 631 * @param d destination operand 632 * @return result 633 * @retval 0 - d,10 - X 634 */ 635 int68_t nbcd68(emu68_t * const emu68, int68_t d); 636 637 EMU68_EXTERN 638 /** 639 * Addition Binary Coded Decimal with extend. 640 * 641 * The abcd68() function performs BCD addition with extend and 642 * updates SR flags accordingly 643 * 644 * @param emu68 68k emulator instance. 645 * @param d destination operand 646 * @return result 647 * @retval s,10 + d,10 + X 648 */ 649 int68_t abcd68(emu68_t * const emu68, const int68_t s, int68_t d); 650 651 EMU68_EXTERN 652 /** 653 * Substract Binary Coded Decimal with extend. 654 * 655 * The sbcd68() function performs BCD substraction with extend and 656 * updates SR flags accordingly 657 * 658 * @param emu68 68k emulator instance. 659 * @param d destination operand 660 * @param s source operand 661 * @return result 662 * @retval d,10 - s,10 - X 663 */ 664 int68_t sbcd68(emu68_t * const emu68, const int68_t s, int68_t d); 665 666 /** 667 * @} 668 */ 669 670 671 /** 672 * @name Exception functions 673 * @{ 674 */ 675 676 EMU68_EXTERN 677 void buserror68(emu68_t * const emu68, const int addr, const int mode); 678 679 EMU68_EXTERN 680 void exception68(emu68_t * const emu68, const int vector, const int level); 681 682 /** 683 * @} 684 */ 685 686 687 /** 688 * @name System Control Instructions 689 * 690 * Privileged and trapping instructions as well as instructions that 691 * use or modify the CCR provide system control operations. FSAVE and 692 * FRESTORE save and restore the nonuser visible portion of the FPU 693 * during context switches in a virtual memory or multitasking 694 * system. The conditional trap instructions, which use the same 695 * conditional tests as their corresponding program control 696 * instructions, allow an optional 16- or 32-bit immediate operand to 697 * be included as part of the instruction for passing parameters to 698 * the operating system. These instructions cause the processor to 699 * flush the instruction pipe. Table 3-10 summarizes these 700 * instructions. See 3.2 Integer Unit Condition Code Computation for 701 * more details on condition codes. 702 * 703 * @{ 704 */ 705 706 EMU68_EXTERN 707 void chk68(emu68_t * const emu68, const int68_t a, const int68_t b); 708 709 EMU68_EXTERN 710 void illegal68(emu68_t * const emu68); 711 712 EMU68_EXTERN 713 void linea68(emu68_t * const emu68); 714 715 EMU68_EXTERN 716 void linef68(emu68_t * const emu68); 717 718 EMU68_EXTERN 719 void trap68(emu68_t * const emu68, const int n); 720 721 EMU68_EXTERN 722 void trapv68(emu68_t * const emu68); 723 724 EMU68_EXTERN 725 void andtosr68(emu68_t * const emu68, int68_t v); 726 727 EMU68_EXTERN 728 void orrtosr68(emu68_t * const emu68, int68_t v); 729 730 EMU68_EXTERN 731 void eortosr68(emu68_t * const emu68, int68_t v); 732 733 EMU68_EXTERN 734 void reset68(emu68_t * const emu68); 735 736 EMU68_EXTERN 737 void stop68(emu68_t * const emu68); 738 739 /** 740 * @} 741 */ 742 743 744 /** 745 * @} 746 */ 747 748 #endif 749