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