From decbe5b76b1a9517e6feaec078039057848dfde8 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sat, 11 Mar 2023 13:20:50 -1000 Subject: [PATCH] Various simulators: Set line endings to CRLF for consistency, remove stray tabs Project standard source code has tabs converted to spaces and CRLF line endings. Other text files have CRLF line endings. --- 3B2/3b2_scsi.c | 2 +- AltairZ80/altairz80_sio.c | 4 +- AltairZ80/m68k/example/README.md | 626 +- AltairZ80/m68k/example/softfloat/README.txt | 156 +- AltairZ80/m68k/example/softfloat/mamesf.h | 122 +- AltairZ80/m68k/example/softfloat/milieu.h | 84 +- .../m68k/example/softfloat/softfloat-macros | 1464 +- .../example/softfloat/softfloat-specialize | 952 +- AltairZ80/m68k/example/softfloat/softfloat.c | 9880 +++---- AltairZ80/m68k/example/softfloat/softfloat.h | 920 +- AltairZ80/m68k/m68k.h | 98 +- AltairZ80/m68k/m68k_in.c | 21306 ++++++++-------- AltairZ80/m68k/m68kasm.c | 8104 +++--- AltairZ80/m68k/m68kconf.h | 2 +- AltairZ80/m68k/m68kcpu.c | 1722 +- AltairZ80/m68k/m68kcpu.h | 1662 +- AltairZ80/m68k/m68kdasm.c | 4476 ++-- AltairZ80/m68k/m68kfpu.c | 3538 +-- AltairZ80/m68k/m68kmake.c | 2816 +- AltairZ80/m68k/m68kmmu.h | 642 +- AltairZ80/m68k/softfloat/softfloat.c | 9880 +++---- AltairZ80/m68k/softfloat/softfloat.h | 248 +- AltairZ80/mmd.c | 4614 ++-- AltairZ80/s100_djhdc.c | 1728 +- AltairZ80/s100_tdd.c | 360 +- AltairZ80/wd179x.c | 12 +- BESM6/besm6_tty.c | 2 +- BESM6/expect.ini | 62 +- Intel-Systems/common/i8080.c | 8 +- NOVA/nova_pt.c | 598 +- PDP11/ddcmp_sync.md | 18 +- PDP11/pdp11_dz.c | 10 +- PDP11/pdp11_mb.c | 14 +- PDP11/pdp11_tv.c | 12 +- PDP18B/tests/test340.simh | 54 +- TX-0/tx0_defs.h | 2 +- display/iii.c | 2 +- imlac/tests/ssv.simh | 18 +- scp.c | 8 +- slirp_glue/qemu/main-loop.h | 86 +- slirp_glue/qemu/monitor/monitor.h | 16 +- slirp_glue/qemu/qemu-common.h | 108 +- slirp_glue/qemu/queue.h | 862 +- slirp_glue/qemu/sockets.h | 104 +- slirp_glue/qemu/sysemu/char.h | 42 +- slirp_glue/qemu/sysemu/os-win32.h | 224 +- slirp_glue/qemu/timer.h | 190 +- slirp_glue/qemu/typedefs.h | 22 +- swtp6800/common/m6800.c | 8 +- swtp6800/common/mp-s.c | 8 +- tt2500/tests/tt2500_test.ini | 34 +- tt2500/tt2500_dpy.c | 2 +- tt2500/tt2500_rom.c | 198 +- 53 files changed, 39065 insertions(+), 39065 deletions(-) diff --git a/3B2/3b2_scsi.c b/3B2/3b2_scsi.c index 22d4ac23..91779821 100644 --- a/3B2/3b2_scsi.c +++ b/3B2/3b2_scsi.c @@ -1183,7 +1183,7 @@ static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, int32 len, t_bool expres void ha_ctrl(uint8 tc) { volatile t_bool txn_done; - uint32 i, j; + uint32 i, j; uint32 plen, ha_ptr; uint32 in_len, out_len; uint8 lu, status; diff --git a/AltairZ80/altairz80_sio.c b/AltairZ80/altairz80_sio.c index 0763f66b..9f4646ab 100644 --- a/AltairZ80/altairz80_sio.c +++ b/AltairZ80/altairz80_sio.c @@ -1771,12 +1771,12 @@ static int32 simh_out(const int32 port, const int32 data) { if (genInterruptPos == 0) { genInterruptVec = data; genInterruptPos = 1; - sim_printf("genInterruptVec=%d genInterruptPos=%d\n", genInterruptVec, genInterruptPos); + sim_printf("genInterruptVec=%d genInterruptPos=%d\n", genInterruptVec, genInterruptPos); } else { vectorInterrupt |= (1 << genInterruptVec); dataBus[genInterruptVec] = data; genInterruptPos = lastCommand = 0; - sim_printf("genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", genInterruptVec, vectorInterrupt, data, genInterruptPos); + sim_printf("genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", genInterruptVec, vectorInterrupt, data, genInterruptPos); } break; case setFCBAddressCmd: diff --git a/AltairZ80/m68k/example/README.md b/AltairZ80/m68k/example/README.md index f5d9a3fe..92c3c488 100644 --- a/AltairZ80/m68k/example/README.md +++ b/AltairZ80/m68k/example/README.md @@ -1,313 +1,313 @@ -Example M68k Program -==================== - -As an example, I'll build an imaginary hardware platform. - -The system is fairly simple, comprising a 68000, an input device, an output -device, a non-maskable-interrupt device, and an interrupt controller. - -The input device receives input from the user and asserts its interrupt -request line until its value is read. Reading from the input device's -memory-mapped port will both clear its interrupt request and read an ASCII -representation (8 bits) of what the user entered. - -The output device reads value when it is selected through its memory-mapped -port and outputs it to a display. The value it reads will be interpreted as -an ASCII value and output to the display. The output device is fairly slow -(it can only process 1 byte per second), and so it asserts its interrupt -request line when it is ready to receive a byte. Writing to the output device -sends a byte to it. If the output device is not ready, the write is ignored. -Reading from the output device returns 0 and clears its interrupt request line -until another byte is written to it and 1 second elapses. - -The non-maskable-interrupt (NMI) device, as can be surmised from the name, -generates a non-maskable-interrupt. This is connected to some kind of external -switch that the user can push to generate a NMI. - -Since there are 3 devices interrupting the CPU, an interrupt controller is -needed. The interrupt controller takes 7 inputs and encodes the highest -priority asserted line on the 3 output pins. the input device is wired to IN2 -and the output device is wired to IN1 on the controller. The NMI device is -wired to IN7 and all the other inputs are wired low. - -The bus is also connected to a 1K ROM and a 256 byte RAM. - -Beware: This platform places ROM and RAM in the same address range and uses - the FC pins to select the correct address space! - (You didn't expect me to make it easy, did you? =) - - - -Schematic ---------- - - NMI TIED - SWITCH LOW - | | - | +-+-+-+ - | | | | | +------------------------------------------------+ - | | | | | | +------------------------------------+ | - | | | | | | | | | - +-------------+ | | - |7 6 5 4 3 2 1| | | - | | | | - | INT CONTRLR | | | - | | | | - |i i i | | | - |2 1 0 | | | - +-------------+ | | - | | | | | - | | | +--------------------------------+--+ | | - o o o | | | | | - +--------------+ +-------+ +----------+ +---------+ +----------+ - | I I I a | | | | | | r a i | | i | - | 2 1 0 23 | | | | | | e c | | | - | | | | | | | a k | | | - | | | | | | | d | | | - | | | | | | | | | | - | M68000 | | ROM | | RAM | | IN | | OUT | - | | | | | | | | | | - | a9|--|a9 |--| |--| |--| | - | a8|--|a8 |--| |--| |--| | - | a7|--|a7 |--|a7 |--| |--| | - | a6|--|a6 |--|a6 |--| |--| | - | a5|--|a5 |--|a5 |--| |--| | - | a4|--|a4 |--|a4 |--| |--| | - | a3|--|a3 |--|a3 |--| |--| | - | a2|--|a2 |--|a2 |--| |--| | - | a1|--|a1 |--|a1 |--| |--| | - | a0|--|a0 |--|a0 |--| |--| | - | | | | | | | | | | - | d15|--|d15 |--|d15 |--| |--| | - | d14|--|d14 |--|d14 |--| |--| | - | d13|--|d13 |--|d13 |--| |--| | - | d12|--|d12 |--|d12 |--| |--| | - | d11|--|d11 |--|d11 |--| |--| | - | d10|--|d10 |--|d10 |--| |--| | - | d9|--|d9 |--|d9 |--| |--| | - | d8|--|d8 |--|d8 |--| |--| | - | d7|--|d7 |--|d7 |--|d7 |--|d7 | - | d6|--|d6 |--|d6 |--|d6 |--|d6 | - | d5|--|d5 |--|d5 |--|d5 |--|d5 | - | d4|--|d4 |--|d4 |--|d4 |--|d4 | - | d3|--|d3 |--|d3 |--|d3 |--|d3 | - | d2|--|d2 |--|d2 |--|d2 |--|d2 | - | d1|--|d1 |--|d1 |--|d1 |--|d1 w | - | d0|--|d0 |--|d0 |--|d0 |--|d0 r | - | | | | | | | | | i a | - | a F F F | | | | | | | | t c | - |22 rW 2 1 0 | | cs | | cs rW | | | | e k | - +--------------+ +-------+ +----------+ +---------+ +----------+ - | | | | | | | | | | - | | | | | | | | | | - | | | | | +-------+ +-----+ | +---+ | - | | | | | | IC1 | | IC2 | | |AND| | - | | | | | |a b c d| |a b c| | +---+ | - | | | | | +-------+ +-----+ | | | | - | | | | | | | | | | | | | | +--+ - | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | - | | | | +-----)-)-+-)----)-)-+ | | | - | | | +-------)-+---)----)-+ | | | - | | +---------+-----)----+ | | | - | | | | | | - | +------------------+-----------+----------------------+ | - | | - +-----------------------------------------------------------+ - -IC1: output=1 if a=0 and b=1 and c=0 and d=0 -IC2: output=1 if a=0 and b=0 and c=1 - - - -Program Listing (program.bin) ------------------------------ - -``` - INPUT_ADDRESS equ $800000 - OUTPUT_ADDRESS equ $400000 - CIRCULAR_BUFFER equ $c0 - CAN_OUTPUT equ $d0 - STACK_AREA equ $100 - - vector_table: -00000000 0000 0100 dc.l STACK_AREA * 0: SP -00000004 0000 00c0 dc.l init * 1: PC -00000008 0000 0148 dc.l unhandled_exception * 2: bus error -0000000c 0000 0148 dc.l unhandled_exception * 3: address error -00000010 0000 0148 dc.l unhandled_exception * 4: illegal instruction -00000014 0000 0148 dc.l unhandled_exception * 5: zero divide -00000018 0000 0148 dc.l unhandled_exception * 6: chk -0000001c 0000 0148 dc.l unhandled_exception * 7: trapv -00000020 0000 0148 dc.l unhandled_exception * 8: privilege violation -00000024 0000 0148 dc.l unhandled_exception * 9: trace -00000028 0000 0148 dc.l unhandled_exception * 10: 1010 -0000002c 0000 0148 dc.l unhandled_exception * 11: 1111 -00000030 0000 0148 dc.l unhandled_exception * 12: - -00000034 0000 0148 dc.l unhandled_exception * 13: - -00000038 0000 0148 dc.l unhandled_exception * 14: - -0000003c 0000 0148 dc.l unhandled_exception * 15: uninitialized interrupt -00000040 0000 0148 dc.l unhandled_exception * 16: - -00000044 0000 0148 dc.l unhandled_exception * 17: - -00000048 0000 0148 dc.l unhandled_exception * 18: - -0000004c 0000 0148 dc.l unhandled_exception * 19: - -00000050 0000 0148 dc.l unhandled_exception * 20: - -00000054 0000 0148 dc.l unhandled_exception * 21: - -00000058 0000 0148 dc.l unhandled_exception * 22: - -0000005c 0000 0148 dc.l unhandled_exception * 23: - -00000060 0000 0148 dc.l unhandled_exception * 24: spurious interrupt -00000064 0000 0136 dc.l output_ready * 25: l1 irq -00000068 0000 010e dc.l input_ready * 26: l2 irq -0000006c 0000 0148 dc.l unhandled_exception * 27: l3 irq -00000070 0000 0148 dc.l unhandled_exception * 28: l4 irq -00000074 0000 0148 dc.l unhandled_exception * 29: l5 irq -00000078 0000 0148 dc.l unhandled_exception * 30: l6 irq -0000007c 0000 014e dc.l nmi * 31: l7 irq -00000080 0000 0148 dc.l unhandled_exception * 32: trap 0 -00000084 0000 0148 dc.l unhandled_exception * 33: trap 1 -00000088 0000 0148 dc.l unhandled_exception * 34: trap 2 -0000008c 0000 0148 dc.l unhandled_exception * 35: trap 3 -00000090 0000 0148 dc.l unhandled_exception * 36: trap 4 -00000094 0000 0148 dc.l unhandled_exception * 37: trap 5 -00000098 0000 0148 dc.l unhandled_exception * 38: trap 6 -0000009c 0000 0148 dc.l unhandled_exception * 39: trap 7 -000000a0 0000 0148 dc.l unhandled_exception * 40: trap 8 -000000a4 0000 0148 dc.l unhandled_exception * 41: trap 9 -000000a8 0000 0148 dc.l unhandled_exception * 42: trap 10 -000000ac 0000 0148 dc.l unhandled_exception * 43: trap 11 -000000b0 0000 0148 dc.l unhandled_exception * 44: trap 12 -000000b4 0000 0148 dc.l unhandled_exception * 45: trap 13 -000000b8 0000 0148 dc.l unhandled_exception * 46: trap 14 -000000bc 0000 0148 dc.l unhandled_exception * 47: trap 15 - * This is the end of the useful part of the table. - * We will now do the Capcom thing and put code starting at $c0. - - init: - * Copy the exception vector table to RAM. -000000c0 227c 0000 0000 move.l #0, a1 * a1 is RAM index -000000c6 303c 002f move.w #47, d0 * d0 is counter (48 vectors) -000000ca 41fa 0006 lea.l (copy_table,PC), a0 * a0 is scratch -000000ce 2208 move.l a0, d1 * d1 is ROM index -000000d0 4481 neg.l d1 - copy_table: -000000d2 22fb 18fe dc.l $22fb18fe * stoopid as68k generates 020 code here - * move.l (copy_table,PC,d1.l), (a1)+ -000000d6 5841 addq #4, d1 -000000d8 51c8 fff8 dbf d0, copy_table - - main_init: - * Initialize main program -000000dc 11fc 0000 00d0 move.b #0, CAN_OUTPUT -000000e2 4df8 00c0 lea.l CIRCULAR_BUFFER, a6 -000000e6 7c00 moveq #0, d6 * output buffer ptr -000000e8 7e00 moveq #0, d7 * input buffer ptr -000000ea 027c f8ff andi #$f8ff, SR * clear interrupt mask - main: - * Main program -000000ee 4a38 00d0 tst.b CAN_OUTPUT * can we output? -000000f2 67fa beq main -000000f4 be06 cmp.b d6, d7 * is there data? -000000f6 67f6 beq main -000000f8 11fc 0000 00d0 move.b #0, CAN_OUTPUT -000000fe 13f6 6000 0040 move.b (0,a6,d6.w), OUTPUT_ADDRESS * write data - 0000 -00000106 5246 addq #1, d6 -00000108 0206 000f andi.b #15, d6 * update circular buffer -0000010c 60e0 bra main - - - input_ready: -0000010e 2f00 move.l d0, -(a7) -00000110 2f01 move.l d1, -(a7) -00000112 1239 0080 0000 move.b INPUT_ADDRESS, d1 * read data -00000118 1007 move.b d7, d0 * check if buffer full -0000011a 5240 addq #1, d0 -0000011c 0200 000f andi.b #15, d0 -00000120 bc00 cmp.b d0, d6 -00000122 6700 000c beq input_ready_quit * throw away if full -00000126 1d81 7000 move.b d1, (0,a6,d7.w) * store the data -0000012a 5247 addq #1, d7 -0000012c 0207 000f andi.b #15, d7 * update circular buffer - input_ready_quit: -00000130 221f move.l (a7)+, d1 -00000132 201f move.l (a7)+, d0 -00000134 4e73 rte - - output_ready: -00000136 2f00 move.l d0, -(a7) -00000138 11fc 0001 00d0 move.b #1, CAN_OUTPUT -0000013e 1039 0040 0000 move.b OUTPUT_ADDRESS, d0 * acknowledge the interrupt -00000144 201f move.l (a7)+, d0 -00000146 4e73 rte - - unhandled_exception: -00000148 4e72 2700 stop #$2700 * wait for NMI -0000014c 60fa bra unhandled_exception * shouldn't get here - - nmi: - * perform a soft reset -0000014e 46fc 2700 move #$2700, SR * set status register -00000152 2e7a feac move.l (vector_table,PC), a7 * reset stack pointer -00000156 4e70 reset * reset peripherals -00000158 4efa feaa jmp (vector_table+4,PC) * reset program counter - - END -``` - - -Compiling the example host environment --------------------------------------- - -### DOS - -`osd_dos.c` - -This code was written a long time ago, in another era when DOS environments -were still a thing. Thus, the primary interface was designed around the DOS -console, which allowed easy control over keyboard input and console echo. If -you still have such an environment, compilers such as mingw or djgpp are -enough to compile it. - -### Linux - -`osd_linux.c` - -There's now a Linux interface but it's very **very** basic. The terminal echoes -back everything you type immediately, which makes the output look weird as the -program output mixes with the terminal echo. - -Unfortunately, I don't have enough free time to sort through the -termios/ncurses minefield to make it behave better. If you happen to know how -to do this sort of thing, please help out by submitting a PR! - -### Other Platforms - -You'll need to make an `osd_xyz.c` for your particular platform to implement -`osd_get_key()`, and update the Makefile to handle your particular environment. - -### Building and running - -You'll need a C compiler. GCC or Clang should work fine. MSVC will require you -to set up a project (use the makefile as a guide). - -- Type `make` -- Type `./sim program.bin` -- Interact with program.bin using the keyboard. - -#### Keys: - - ESC - quits the simulator - ~ - generates an NMI interrupt - Any other key - Genearate input for the input device - - -### Note - -I've cheated a bit in the emulation. There is no speed control to set the -speed the CPU runs at; it simply runs as fast as your processor can run it. - -To add speed control, you will need a high-precision timestamp function -(like the RDTSC instruction for newer Pentium CPUs) and a bit of arithmetic -to make the cycles argument for m68k_execute(). I'll leave that as an -excercise to the reader. +Example M68k Program +==================== + +As an example, I'll build an imaginary hardware platform. + +The system is fairly simple, comprising a 68000, an input device, an output +device, a non-maskable-interrupt device, and an interrupt controller. + +The input device receives input from the user and asserts its interrupt +request line until its value is read. Reading from the input device's +memory-mapped port will both clear its interrupt request and read an ASCII +representation (8 bits) of what the user entered. + +The output device reads value when it is selected through its memory-mapped +port and outputs it to a display. The value it reads will be interpreted as +an ASCII value and output to the display. The output device is fairly slow +(it can only process 1 byte per second), and so it asserts its interrupt +request line when it is ready to receive a byte. Writing to the output device +sends a byte to it. If the output device is not ready, the write is ignored. +Reading from the output device returns 0 and clears its interrupt request line +until another byte is written to it and 1 second elapses. + +The non-maskable-interrupt (NMI) device, as can be surmised from the name, +generates a non-maskable-interrupt. This is connected to some kind of external +switch that the user can push to generate a NMI. + +Since there are 3 devices interrupting the CPU, an interrupt controller is +needed. The interrupt controller takes 7 inputs and encodes the highest +priority asserted line on the 3 output pins. the input device is wired to IN2 +and the output device is wired to IN1 on the controller. The NMI device is +wired to IN7 and all the other inputs are wired low. + +The bus is also connected to a 1K ROM and a 256 byte RAM. + +Beware: This platform places ROM and RAM in the same address range and uses + the FC pins to select the correct address space! + (You didn't expect me to make it easy, did you? =) + + + +Schematic +--------- + + NMI TIED + SWITCH LOW + | | + | +-+-+-+ + | | | | | +------------------------------------------------+ + | | | | | | +------------------------------------+ | + | | | | | | | | | + +-------------+ | | + |7 6 5 4 3 2 1| | | + | | | | + | INT CONTRLR | | | + | | | | + |i i i | | | + |2 1 0 | | | + +-------------+ | | + | | | | | + | | | +--------------------------------+--+ | | + o o o | | | | | + +--------------+ +-------+ +----------+ +---------+ +----------+ + | I I I a | | | | | | r a i | | i | + | 2 1 0 23 | | | | | | e c | | | + | | | | | | | a k | | | + | | | | | | | d | | | + | | | | | | | | | | + | M68000 | | ROM | | RAM | | IN | | OUT | + | | | | | | | | | | + | a9|--|a9 |--| |--| |--| | + | a8|--|a8 |--| |--| |--| | + | a7|--|a7 |--|a7 |--| |--| | + | a6|--|a6 |--|a6 |--| |--| | + | a5|--|a5 |--|a5 |--| |--| | + | a4|--|a4 |--|a4 |--| |--| | + | a3|--|a3 |--|a3 |--| |--| | + | a2|--|a2 |--|a2 |--| |--| | + | a1|--|a1 |--|a1 |--| |--| | + | a0|--|a0 |--|a0 |--| |--| | + | | | | | | | | | | + | d15|--|d15 |--|d15 |--| |--| | + | d14|--|d14 |--|d14 |--| |--| | + | d13|--|d13 |--|d13 |--| |--| | + | d12|--|d12 |--|d12 |--| |--| | + | d11|--|d11 |--|d11 |--| |--| | + | d10|--|d10 |--|d10 |--| |--| | + | d9|--|d9 |--|d9 |--| |--| | + | d8|--|d8 |--|d8 |--| |--| | + | d7|--|d7 |--|d7 |--|d7 |--|d7 | + | d6|--|d6 |--|d6 |--|d6 |--|d6 | + | d5|--|d5 |--|d5 |--|d5 |--|d5 | + | d4|--|d4 |--|d4 |--|d4 |--|d4 | + | d3|--|d3 |--|d3 |--|d3 |--|d3 | + | d2|--|d2 |--|d2 |--|d2 |--|d2 | + | d1|--|d1 |--|d1 |--|d1 |--|d1 w | + | d0|--|d0 |--|d0 |--|d0 |--|d0 r | + | | | | | | | | | i a | + | a F F F | | | | | | | | t c | + |22 rW 2 1 0 | | cs | | cs rW | | | | e k | + +--------------+ +-------+ +----------+ +---------+ +----------+ + | | | | | | | | | | + | | | | | | | | | | + | | | | | +-------+ +-----+ | +---+ | + | | | | | | IC1 | | IC2 | | |AND| | + | | | | | |a b c d| |a b c| | +---+ | + | | | | | +-------+ +-----+ | | | | + | | | | | | | | | | | | | | +--+ + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | +-----)-)-+-)----)-)-+ | | | + | | | +-------)-+---)----)-+ | | | + | | +---------+-----)----+ | | | + | | | | | | + | +------------------+-----------+----------------------+ | + | | + +-----------------------------------------------------------+ + +IC1: output=1 if a=0 and b=1 and c=0 and d=0 +IC2: output=1 if a=0 and b=0 and c=1 + + + +Program Listing (program.bin) +----------------------------- + +``` + INPUT_ADDRESS equ $800000 + OUTPUT_ADDRESS equ $400000 + CIRCULAR_BUFFER equ $c0 + CAN_OUTPUT equ $d0 + STACK_AREA equ $100 + + vector_table: +00000000 0000 0100 dc.l STACK_AREA * 0: SP +00000004 0000 00c0 dc.l init * 1: PC +00000008 0000 0148 dc.l unhandled_exception * 2: bus error +0000000c 0000 0148 dc.l unhandled_exception * 3: address error +00000010 0000 0148 dc.l unhandled_exception * 4: illegal instruction +00000014 0000 0148 dc.l unhandled_exception * 5: zero divide +00000018 0000 0148 dc.l unhandled_exception * 6: chk +0000001c 0000 0148 dc.l unhandled_exception * 7: trapv +00000020 0000 0148 dc.l unhandled_exception * 8: privilege violation +00000024 0000 0148 dc.l unhandled_exception * 9: trace +00000028 0000 0148 dc.l unhandled_exception * 10: 1010 +0000002c 0000 0148 dc.l unhandled_exception * 11: 1111 +00000030 0000 0148 dc.l unhandled_exception * 12: - +00000034 0000 0148 dc.l unhandled_exception * 13: - +00000038 0000 0148 dc.l unhandled_exception * 14: - +0000003c 0000 0148 dc.l unhandled_exception * 15: uninitialized interrupt +00000040 0000 0148 dc.l unhandled_exception * 16: - +00000044 0000 0148 dc.l unhandled_exception * 17: - +00000048 0000 0148 dc.l unhandled_exception * 18: - +0000004c 0000 0148 dc.l unhandled_exception * 19: - +00000050 0000 0148 dc.l unhandled_exception * 20: - +00000054 0000 0148 dc.l unhandled_exception * 21: - +00000058 0000 0148 dc.l unhandled_exception * 22: - +0000005c 0000 0148 dc.l unhandled_exception * 23: - +00000060 0000 0148 dc.l unhandled_exception * 24: spurious interrupt +00000064 0000 0136 dc.l output_ready * 25: l1 irq +00000068 0000 010e dc.l input_ready * 26: l2 irq +0000006c 0000 0148 dc.l unhandled_exception * 27: l3 irq +00000070 0000 0148 dc.l unhandled_exception * 28: l4 irq +00000074 0000 0148 dc.l unhandled_exception * 29: l5 irq +00000078 0000 0148 dc.l unhandled_exception * 30: l6 irq +0000007c 0000 014e dc.l nmi * 31: l7 irq +00000080 0000 0148 dc.l unhandled_exception * 32: trap 0 +00000084 0000 0148 dc.l unhandled_exception * 33: trap 1 +00000088 0000 0148 dc.l unhandled_exception * 34: trap 2 +0000008c 0000 0148 dc.l unhandled_exception * 35: trap 3 +00000090 0000 0148 dc.l unhandled_exception * 36: trap 4 +00000094 0000 0148 dc.l unhandled_exception * 37: trap 5 +00000098 0000 0148 dc.l unhandled_exception * 38: trap 6 +0000009c 0000 0148 dc.l unhandled_exception * 39: trap 7 +000000a0 0000 0148 dc.l unhandled_exception * 40: trap 8 +000000a4 0000 0148 dc.l unhandled_exception * 41: trap 9 +000000a8 0000 0148 dc.l unhandled_exception * 42: trap 10 +000000ac 0000 0148 dc.l unhandled_exception * 43: trap 11 +000000b0 0000 0148 dc.l unhandled_exception * 44: trap 12 +000000b4 0000 0148 dc.l unhandled_exception * 45: trap 13 +000000b8 0000 0148 dc.l unhandled_exception * 46: trap 14 +000000bc 0000 0148 dc.l unhandled_exception * 47: trap 15 + * This is the end of the useful part of the table. + * We will now do the Capcom thing and put code starting at $c0. + + init: + * Copy the exception vector table to RAM. +000000c0 227c 0000 0000 move.l #0, a1 * a1 is RAM index +000000c6 303c 002f move.w #47, d0 * d0 is counter (48 vectors) +000000ca 41fa 0006 lea.l (copy_table,PC), a0 * a0 is scratch +000000ce 2208 move.l a0, d1 * d1 is ROM index +000000d0 4481 neg.l d1 + copy_table: +000000d2 22fb 18fe dc.l $22fb18fe * stoopid as68k generates 020 code here + * move.l (copy_table,PC,d1.l), (a1)+ +000000d6 5841 addq #4, d1 +000000d8 51c8 fff8 dbf d0, copy_table + + main_init: + * Initialize main program +000000dc 11fc 0000 00d0 move.b #0, CAN_OUTPUT +000000e2 4df8 00c0 lea.l CIRCULAR_BUFFER, a6 +000000e6 7c00 moveq #0, d6 * output buffer ptr +000000e8 7e00 moveq #0, d7 * input buffer ptr +000000ea 027c f8ff andi #$f8ff, SR * clear interrupt mask + main: + * Main program +000000ee 4a38 00d0 tst.b CAN_OUTPUT * can we output? +000000f2 67fa beq main +000000f4 be06 cmp.b d6, d7 * is there data? +000000f6 67f6 beq main +000000f8 11fc 0000 00d0 move.b #0, CAN_OUTPUT +000000fe 13f6 6000 0040 move.b (0,a6,d6.w), OUTPUT_ADDRESS * write data + 0000 +00000106 5246 addq #1, d6 +00000108 0206 000f andi.b #15, d6 * update circular buffer +0000010c 60e0 bra main + + + input_ready: +0000010e 2f00 move.l d0, -(a7) +00000110 2f01 move.l d1, -(a7) +00000112 1239 0080 0000 move.b INPUT_ADDRESS, d1 * read data +00000118 1007 move.b d7, d0 * check if buffer full +0000011a 5240 addq #1, d0 +0000011c 0200 000f andi.b #15, d0 +00000120 bc00 cmp.b d0, d6 +00000122 6700 000c beq input_ready_quit * throw away if full +00000126 1d81 7000 move.b d1, (0,a6,d7.w) * store the data +0000012a 5247 addq #1, d7 +0000012c 0207 000f andi.b #15, d7 * update circular buffer + input_ready_quit: +00000130 221f move.l (a7)+, d1 +00000132 201f move.l (a7)+, d0 +00000134 4e73 rte + + output_ready: +00000136 2f00 move.l d0, -(a7) +00000138 11fc 0001 00d0 move.b #1, CAN_OUTPUT +0000013e 1039 0040 0000 move.b OUTPUT_ADDRESS, d0 * acknowledge the interrupt +00000144 201f move.l (a7)+, d0 +00000146 4e73 rte + + unhandled_exception: +00000148 4e72 2700 stop #$2700 * wait for NMI +0000014c 60fa bra unhandled_exception * shouldn't get here + + nmi: + * perform a soft reset +0000014e 46fc 2700 move #$2700, SR * set status register +00000152 2e7a feac move.l (vector_table,PC), a7 * reset stack pointer +00000156 4e70 reset * reset peripherals +00000158 4efa feaa jmp (vector_table+4,PC) * reset program counter + + END +``` + + +Compiling the example host environment +-------------------------------------- + +### DOS + +`osd_dos.c` + +This code was written a long time ago, in another era when DOS environments +were still a thing. Thus, the primary interface was designed around the DOS +console, which allowed easy control over keyboard input and console echo. If +you still have such an environment, compilers such as mingw or djgpp are +enough to compile it. + +### Linux + +`osd_linux.c` + +There's now a Linux interface but it's very **very** basic. The terminal echoes +back everything you type immediately, which makes the output look weird as the +program output mixes with the terminal echo. + +Unfortunately, I don't have enough free time to sort through the +termios/ncurses minefield to make it behave better. If you happen to know how +to do this sort of thing, please help out by submitting a PR! + +### Other Platforms + +You'll need to make an `osd_xyz.c` for your particular platform to implement +`osd_get_key()`, and update the Makefile to handle your particular environment. + +### Building and running + +You'll need a C compiler. GCC or Clang should work fine. MSVC will require you +to set up a project (use the makefile as a guide). + +- Type `make` +- Type `./sim program.bin` +- Interact with program.bin using the keyboard. + +#### Keys: + + ESC - quits the simulator + ~ - generates an NMI interrupt + Any other key - Genearate input for the input device + + +### Note + +I've cheated a bit in the emulation. There is no speed control to set the +speed the CPU runs at; it simply runs as fast as your processor can run it. + +To add speed control, you will need a high-precision timestamp function +(like the RDTSC instruction for newer Pentium CPUs) and a bit of arithmetic +to make the cycles argument for m68k_execute(). I'll leave that as an +excercise to the reader. diff --git a/AltairZ80/m68k/example/softfloat/README.txt b/AltairZ80/m68k/example/softfloat/README.txt index 9500d25e..32d024c4 100644 --- a/AltairZ80/m68k/example/softfloat/README.txt +++ b/AltairZ80/m68k/example/softfloat/README.txt @@ -1,78 +1,78 @@ -MAME note: this package is derived from the following original SoftFloat -package and has been "re-packaged" to work with MAME's conventions and -build system. The source files come from bits64/ and bits64/templates -in the original distribution as MAME requires a compiler with a 64-bit -integer type. - - -Package Overview for SoftFloat Release 2b - -John R. Hauser -2002 May 27 - - ----------------------------------------------------------------------------- -Overview - -SoftFloat is a software implementation of floating-point that conforms to -the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is -distributed in the form of C source code. Compiling the SoftFloat sources -generates two things: - --- A SoftFloat object file (typically `softfloat.o') containing the complete - set of IEC/IEEE floating-point routines. - --- A `timesoftfloat' program for evaluating the speed of the SoftFloat - routines. (The SoftFloat module is linked into this program.) - -The SoftFloat package is documented in four text files: - - SoftFloat.txt Documentation for using the SoftFloat functions. - SoftFloat-source.txt Documentation for compiling SoftFloat. - SoftFloat-history.txt History of major changes to SoftFloat. - timesoftfloat.txt Documentation for using `timesoftfloat'. - -Other files in the package comprise the source code for SoftFloat. - -Please be aware that some work is involved in porting this software to other -targets. It is not just a matter of getting `make' to complete without -error messages. I would have written the code that way if I could, but -there are fundamental differences between systems that can't be hidden. -You should not attempt to compile SoftFloat without first reading both -`SoftFloat.txt' and `SoftFloat-source.txt'. - - ----------------------------------------------------------------------------- -Legal Notice - -SoftFloat was written by me, John R. Hauser. This work was made possible in -part by the International Computer Science Institute, located at Suite 600, -1947 Center Street, Berkeley, California 94704. Funding was partially -provided by the National Science Foundation under grant MIP-9311980. The -original version of this code was written as part of a project to build -a fixed-point vector processor in collaboration with the University of -California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort -has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT -TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO -PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL -LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO -FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER -SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, -COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE -SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, provided -that the minimal documentation requirements stated in the source code are -satisfied. - - ----------------------------------------------------------------------------- -Contact Information - -At the time of this writing, the most up-to-date information about -SoftFloat and the latest release can be found at the Web page `http:// -www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'. - - +MAME note: this package is derived from the following original SoftFloat +package and has been "re-packaged" to work with MAME's conventions and +build system. The source files come from bits64/ and bits64/templates +in the original distribution as MAME requires a compiler with a 64-bit +integer type. + + +Package Overview for SoftFloat Release 2b + +John R. Hauser +2002 May 27 + + +---------------------------------------------------------------------------- +Overview + +SoftFloat is a software implementation of floating-point that conforms to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is +distributed in the form of C source code. Compiling the SoftFloat sources +generates two things: + +-- A SoftFloat object file (typically `softfloat.o') containing the complete + set of IEC/IEEE floating-point routines. + +-- A `timesoftfloat' program for evaluating the speed of the SoftFloat + routines. (The SoftFloat module is linked into this program.) + +The SoftFloat package is documented in four text files: + + SoftFloat.txt Documentation for using the SoftFloat functions. + SoftFloat-source.txt Documentation for compiling SoftFloat. + SoftFloat-history.txt History of major changes to SoftFloat. + timesoftfloat.txt Documentation for using `timesoftfloat'. + +Other files in the package comprise the source code for SoftFloat. + +Please be aware that some work is involved in porting this software to other +targets. It is not just a matter of getting `make' to complete without +error messages. I would have written the code that way if I could, but +there are fundamental differences between systems that can't be hidden. +You should not attempt to compile SoftFloat without first reading both +`SoftFloat.txt' and `SoftFloat-source.txt'. + + +---------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by me, John R. Hauser. This work was made possible in +part by the International Computer Science Institute, located at Suite 600, +1947 Center Street, Berkeley, California 94704. Funding was partially +provided by the National Science Foundation under grant MIP-9311980. The +original version of this code was written as part of a project to build +a fixed-point vector processor in collaboration with the University of +California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL +LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO +FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER +SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, +COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE +SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, provided +that the minimal documentation requirements stated in the source code are +satisfied. + + +---------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about +SoftFloat and the latest release can be found at the Web page `http:// +www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'. + + diff --git a/AltairZ80/m68k/example/softfloat/mamesf.h b/AltairZ80/m68k/example/softfloat/mamesf.h index c4195039..02f1055f 100644 --- a/AltairZ80/m68k/example/softfloat/mamesf.h +++ b/AltairZ80/m68k/example/softfloat/mamesf.h @@ -1,61 +1,61 @@ -/*---------------------------------------------------------------------------- -| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. -*----------------------------------------------------------------------------*/ -#ifdef LSB_FIRST -#define LITTLEENDIAN -#else -#define BIGENDIAN -#endif - -/*---------------------------------------------------------------------------- -| The macro `BITS64' can be defined to indicate that 64-bit integer types are -| supported by the compiler. -*----------------------------------------------------------------------------*/ -#define BITS64 - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines the most convenient type that holds -| integers of at least as many bits as specified. For example, `uint8' should -| be the most convenient type that can hold unsigned integers of as many as -| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most -| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed -| to the same as `int'. -*----------------------------------------------------------------------------*/ - -typedef sint8 flag; -typedef sint8 int8; -typedef sint16 int16; -typedef sint32 int32; -typedef sint64 int64; - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines a type that holds integers -| of _exactly_ the number of bits specified. For instance, for most -| implementation of C, `bits16' and `sbits16' should be `typedef'ed to -| `unsigned short int' and `signed short int' (or `short int'), respectively. -*----------------------------------------------------------------------------*/ -typedef uint8 bits8; -typedef sint8 sbits8; -typedef uint16 bits16; -typedef sint16 sbits16; -typedef uint32 bits32; -typedef sint32 sbits32; -typedef uint64 bits64; -typedef sint64 sbits64; - -/*---------------------------------------------------------------------------- -| The `LIT64' macro takes as its argument a textual integer literal and -| if necessary ``marks'' the literal as having a 64-bit integer type. -| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be -| appended with the letters `LL' standing for `long long', which is `gcc's -| name for the 64-bit integer type. Some compilers may allow `LIT64' to be -| defined as the identity macro: `#define LIT64( a ) a'. -*----------------------------------------------------------------------------*/ -#define LIT64( a ) a##ULL - -/*---------------------------------------------------------------------------- -| The macro `INLINE' can be used before functions that should be inlined. If -| a compiler does not support explicit inlining, this macro should be defined -| to be `static'. -*----------------------------------------------------------------------------*/ -// MAME defines INLINE +/*---------------------------------------------------------------------------- +| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +*----------------------------------------------------------------------------*/ +#ifdef LSB_FIRST +#define LITTLEENDIAN +#else +#define BIGENDIAN +#endif + +/*---------------------------------------------------------------------------- +| The macro `BITS64' can be defined to indicate that 64-bit integer types are +| supported by the compiler. +*----------------------------------------------------------------------------*/ +#define BITS64 + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines the most convenient type that holds +| integers of at least as many bits as specified. For example, `uint8' should +| be the most convenient type that can hold unsigned integers of as many as +| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most +| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +| to the same as `int'. +*----------------------------------------------------------------------------*/ + +typedef sint8 flag; +typedef sint8 int8; +typedef sint16 int16; +typedef sint32 int32; +typedef sint64 int64; + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines a type that holds integers +| of _exactly_ the number of bits specified. For instance, for most +| implementation of C, `bits16' and `sbits16' should be `typedef'ed to +| `unsigned short int' and `signed short int' (or `short int'), respectively. +*----------------------------------------------------------------------------*/ +typedef uint8 bits8; +typedef sint8 sbits8; +typedef uint16 bits16; +typedef sint16 sbits16; +typedef uint32 bits32; +typedef sint32 sbits32; +typedef uint64 bits64; +typedef sint64 sbits64; + +/*---------------------------------------------------------------------------- +| The `LIT64' macro takes as its argument a textual integer literal and +| if necessary ``marks'' the literal as having a 64-bit integer type. +| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +| appended with the letters `LL' standing for `long long', which is `gcc's +| name for the 64-bit integer type. Some compilers may allow `LIT64' to be +| defined as the identity macro: `#define LIT64( a ) a'. +*----------------------------------------------------------------------------*/ +#define LIT64( a ) a##ULL + +/*---------------------------------------------------------------------------- +| The macro `INLINE' can be used before functions that should be inlined. If +| a compiler does not support explicit inlining, this macro should be defined +| to be `static'. +*----------------------------------------------------------------------------*/ +// MAME defines INLINE diff --git a/AltairZ80/m68k/example/softfloat/milieu.h b/AltairZ80/m68k/example/softfloat/milieu.h index 10687b75..f25f688e 100644 --- a/AltairZ80/m68k/example/softfloat/milieu.h +++ b/AltairZ80/m68k/example/softfloat/milieu.h @@ -1,42 +1,42 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Include common integer types and flags. -*----------------------------------------------------------------------------*/ -#include "mamesf.h" - -/*---------------------------------------------------------------------------- -| Symbolic Boolean literals. -*----------------------------------------------------------------------------*/ -#define FALSE 0 -#define TRUE 1 + +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Include common integer types and flags. +*----------------------------------------------------------------------------*/ +#include "mamesf.h" + +/*---------------------------------------------------------------------------- +| Symbolic Boolean literals. +*----------------------------------------------------------------------------*/ +#define FALSE 0 +#define TRUE 1 diff --git a/AltairZ80/m68k/example/softfloat/softfloat-macros b/AltairZ80/m68k/example/softfloat/softfloat-macros index 5de9031d..39ef1ba4 100644 --- a/AltairZ80/m68k/example/softfloat/softfloat-macros +++ b/AltairZ80/m68k/example/softfloat/softfloat-macros @@ -1,732 +1,732 @@ - -/*============================================================================ - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 32, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -| The result is stored in the location pointed to by `zPtr'. -*----------------------------------------------------------------------------*/ - -static inline void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) -{ - bits32 z; - - if ( count == 0 ) { - z = a; - } - else if ( count < 32 ) { - z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); - } - else { - z = ( a != 0 ); - } - *zPtr = z; - -} - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 64, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -| The result is stored in the location pointed to by `zPtr'. -*----------------------------------------------------------------------------*/ - -static inline void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) -{ - bits64 z; - - if ( count == 0 ) { - z = a; - } - else if ( count < 64 ) { - z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); - } - else { - z = ( a != 0 ); - } - *zPtr = z; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 -| _plus_ the number of bits given in `count'. The shifted result is at most -| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The -| bits shifted off form a second 64-bit result as follows: The _last_ bit -| shifted off is the most-significant bit of the extra result, and the other -| 63 bits of the extra result are all zero if and only if _all_but_the_last_ -| bits shifted off were all zero. This extra result is stored in the location -| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. -| (This routine makes more sense if `a0' and `a1' are considered to form -| a fixed-point value with binary point between `a0' and `a1'. This fixed- -| point value is shifted right by the number of bits given in `count', and -| the integer part of the result is returned at the location pointed to by -| `z0Ptr'. The fractional part of the result may be slightly corrupted as -| described above, and is returned at the location pointed to by `z1Ptr'.) -*----------------------------------------------------------------------------*/ - -static inline void - shift64ExtraRightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count; - } - else { - if ( count == 64 ) { - z1 = a0 | ( a1 != 0 ); - } - else { - z1 = ( ( a0 | a1 ) != 0 ); - } - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' can be arbitrarily large; in particular, if `count' is greater -| than 128, the result will be 0. The result is broken into two 64-bit pieces -| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - shift128Right( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count ); - z0 = a0>>count; - } - else { - z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. If any nonzero bits are shifted off, they -| are ``jammed'' into the least significant bit of the result by setting the -| least significant bit to 1. The value of `count' can be arbitrarily large; -| in particular, if `count' is greater than 128, the result will be either -| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or -| nonzero. The result is broken into two 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - shift128RightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count ) | ( ( a1<>count; - } - else { - if ( count == 64 ) { - z1 = a0 | ( a1 != 0 ); - } - else if ( count < 128 ) { - z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<>count ); - z0 = a0>>count; - } - else { - if ( count == 64 ) { - z2 = a1; - z1 = a0; - } - else { - a2 |= a1; - if ( count < 128 ) { - z2 = a0<>( count & 63 ); - } - else { - z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); - z1 = 0; - } - } - z0 = 0; - } - z2 |= ( a2 != 0 ); - } - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' must be less than 64. The result is broken into two 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - shortShift128Left( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - - *z1Ptr = a1<>( ( - count ) & 63 ) ); - -} - -/*---------------------------------------------------------------------------- -| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left -| by the number of bits given in `count'. Any bits shifted off are lost. -| The value of `count' must be less than 64. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - shortShift192Left( - bits64 a0, - bits64 a1, - bits64 a2, - int16 count, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - int8 negCount; - - z2 = a2<>negCount; - z0 |= a1>>negCount; - } - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit -| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so -| any carry out is lost. The result is broken into two 64-bit pieces which -| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - add128( - bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z1; - - z1 = a1 + b1; - *z1Ptr = z1; - *z0Ptr = a0 + b0 + ( z1 < a1 ); - -} - -/*---------------------------------------------------------------------------- -| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the -| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is -| modulo 2^192, so any carry out is lost. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - add192( - bits64 a0, - bits64 a1, - bits64 a2, - bits64 b0, - bits64 b1, - bits64 b2, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - uint8 carry0, carry1; - - z2 = a2 + b2; - carry1 = ( z2 < a2 ); - z1 = a1 + b1; - carry0 = ( z1 < a1 ); - z0 = a0 + b0; - z1 += carry1; - z0 += ( z1 < carry1 ); - z0 += carry0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the -| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo -| 2^128, so any borrow out (carry out) is lost. The result is broken into two -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and -| `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - sub128( - bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - - *z1Ptr = a1 - b1; - *z0Ptr = a0 - b0 - ( a1 < b1 ); - -} - -/*---------------------------------------------------------------------------- -| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' -| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. -| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The -| result is broken into three 64-bit pieces which are stored at the locations -| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - sub192( - bits64 a0, - bits64 a1, - bits64 a2, - bits64 b0, - bits64 b1, - bits64 b2, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - uint8 borrow0, borrow1; - - z2 = a2 - b2; - borrow1 = ( a2 < b2 ); - z1 = a1 - b1; - borrow0 = ( a1 < b1 ); - z0 = a0 - b0; - z0 -= ( z1 < borrow1 ); - z1 -= borrow1; - z0 -= borrow0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken -| into two 64-bit pieces which are stored at the locations pointed to by -| `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits32 aHigh, aLow, bHigh, bLow; - bits64 z0, zMiddleA, zMiddleB, z1; - - aLow = a; - aHigh = a>>32; - bLow = b; - bHigh = b>>32; - z1 = ( (bits64) aLow ) * bLow; - zMiddleA = ( (bits64) aLow ) * bHigh; - zMiddleB = ( (bits64) aHigh ) * bLow; - z0 = ( (bits64) aHigh ) * bHigh; - zMiddleA += zMiddleB; - z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); - zMiddleA <<= 32; - z1 += zMiddleA; - z0 += ( z1 < zMiddleA ); - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by -| `b' to obtain a 192-bit product. The product is broken into three 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and -| `z2Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - mul128By64To192( - bits64 a0, - bits64 a1, - bits64 b, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2, more1; - - mul64To128( a1, b, &z1, &z2 ); - mul64To128( a0, b, &z0, &more1 ); - add128( z0, more1, 0, z1, &z0, &z1 ); - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the -| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit -| product. The product is broken into four 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. -*----------------------------------------------------------------------------*/ - -static inline void - mul128To256( - bits64 a0, - bits64 a1, - bits64 b0, - bits64 b1, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr, - bits64 *z3Ptr - ) -{ - bits64 z0, z1, z2, z3; - bits64 more1, more2; - - mul64To128( a1, b1, &z2, &z3 ); - mul64To128( a1, b0, &z1, &more2 ); - add128( z1, more2, 0, z2, &z1, &z2 ); - mul64To128( a0, b0, &z0, &more1 ); - add128( z0, more1, 0, z1, &z0, &z1 ); - mul64To128( a0, b1, &more1, &more2 ); - add128( more1, more2, 0, z2, &more1, &z2 ); - add128( z0, z1, 0, more1, &z0, &z1 ); - *z3Ptr = z3; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the 64-bit integer quotient obtained by dividing -| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The -| divisor `b' must be at least 2^63. If q is the exact quotient truncated -| toward zero, the approximation returned lies between q and q + 2 inclusive. -| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit -| unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -static inline bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) -{ - bits64 b0, b1; - bits64 rem0, rem1, term0, term1; - bits64 z; - - if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); - b0 = b>>32; - z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; - mul64To128( b, z, &term0, &term1 ); - sub128( a0, a1, term0, term1, &rem0, &rem1 ); - while ( ( (sbits64) rem0 ) < 0 ) { - z -= LIT64( 0x100000000 ); - b1 = b<<32; - add128( rem0, rem1, b0, b1, &rem0, &rem1 ); - } - rem0 = ( rem0<<32 ) | ( rem1>>32 ); - z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the square root of the 32-bit significand given -| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of -| `aExp' (the least significant bit) is 1, the integer returned approximates -| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' -| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either -| case, the approximation returned lies strictly within +/-2 of the exact -| value. -*----------------------------------------------------------------------------*/ - -static inline bits32 estimateSqrt32( int16 aExp, bits32 a ) -{ - static const bits16 sqrtOddAdjustments[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; - static const bits16 sqrtEvenAdjustments[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - int8 index; - bits32 z; - - index = ( a>>27 ) & 15; - if ( aExp & 1 ) { - z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; - z = ( ( a / z )<<14 ) + ( z<<15 ); - a >>= 1; - } - else { - z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; - z = a / z + z; - z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); - if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); - } - return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. -*----------------------------------------------------------------------------*/ - -static int8 countLeadingZeros32( bits32 a ) -{ - static const int8 countLeadingZerosHigh[] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - int8 shiftCount; - - shiftCount = 0; - if ( a < 0x10000 ) { - shiftCount += 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - shiftCount += 8; - a <<= 8; - } - shiftCount += countLeadingZerosHigh[ a>>24 ]; - return shiftCount; - -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. -*----------------------------------------------------------------------------*/ - -static int8 countLeadingZeros64( bits64 a ) -{ - int8 shiftCount; - - shiftCount = 0; - if ( a < ( (bits64) 1 )<<32 ) { - shiftCount += 32; - } - else { - a >>= 32; - } - shiftCount += countLeadingZeros32( a ); - return shiftCount; - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' -| is equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -static inline flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 == b0 ) && ( a1 == b1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than or equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -static inline flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, -| returns 0. -*----------------------------------------------------------------------------*/ - -static inline flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is -| not equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -static inline flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 != b0 ) || ( a1 != b1 ); - -} - -/*----------------------------------------------------------------------------- -| Changes the sign of the extended double-precision floating-point value 'a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static inline floatx80 floatx80_chs(floatx80 reg) -{ - reg.high ^= 0x8000; - return reg; -} - + +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are ``jammed'' into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 32, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +static inline void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +{ + bits32 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are ``jammed'' into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 64, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +static inline void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) +{ + bits64 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 64 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 +| _plus_ the number of bits given in `count'. The shifted result is at most +| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The +| bits shifted off form a second 64-bit result as follows: The _last_ bit +| shifted off is the most-significant bit of the extra result, and the other +| 63 bits of the extra result are all zero if and only if _all_but_the_last_ +| bits shifted off were all zero. This extra result is stored in the location +| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. +| (This routine makes more sense if `a0' and `a1' are considered to form +| a fixed-point value with binary point between `a0' and `a1'. This fixed- +| point value is shifted right by the number of bits given in `count', and +| the integer part of the result is returned at the location pointed to by +| `z0Ptr'. The fractional part of the result may be slightly corrupted as +| described above, and is returned at the location pointed to by `z1Ptr'.) +*----------------------------------------------------------------------------*/ + +static inline void + shift64ExtraRightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else { + z1 = ( ( a0 | a1 ) != 0 ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' can be arbitrarily large; in particular, if `count' is greater +| than 128, the result will be 0. The result is broken into two 64-bit pieces +| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + shift128Right( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +| number of bits given in `count'. If any nonzero bits are shifted off, they +| are ``jammed'' into the least significant bit of the result by setting the +| least significant bit to 1. The value of `count' can be arbitrarily large; +| in particular, if `count' is greater than 128, the result will be either +| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or +| nonzero. The result is broken into two 64-bit pieces which are stored at +| the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + shift128RightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ) | ( ( a1<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else if ( count < 128 ) { + z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<>count ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 128 ) { + z2 = a0<>( count & 63 ); + } + else { + z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( a2 != 0 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' must be less than 64. The result is broken into two 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + shortShift128Left( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1<>( ( - count ) & 63 ) ); + +} + +/*---------------------------------------------------------------------------- +| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left +| by the number of bits given in `count'. Any bits shifted off are lost. +| The value of `count' must be less than 64. The result is broken into three +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', +| `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + shortShift192Left( + bits64 a0, + bits64 a1, + bits64 a2, + int16 count, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 negCount; + + z2 = a2<>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +| any carry out is lost. The result is broken into two 64-bit pieces which +| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + add128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/*---------------------------------------------------------------------------- +| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the +| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +| modulo 2^192, so any carry out is lost. The result is broken into three +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', +| `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + add192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + uint8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +| 2^128, so any borrow out (carry out) is lost. The result is broken into two +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +| `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + sub128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' +| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. +| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The +| result is broken into three 64-bit pieces which are stored at the locations +| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + sub192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + uint8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +| into two 64-bit pieces which are stored at the locations pointed to by +| `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a>>32; + bLow = b; + bHigh = b>>32; + z1 = ( (bits64) aLow ) * bLow; + zMiddleA = ( (bits64) aLow ) * bHigh; + zMiddleB = ( (bits64) aHigh ) * bLow; + z0 = ( (bits64) aHigh ) * bHigh; + zMiddleA += zMiddleB; + z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += ( z1 < zMiddleA ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by +| `b' to obtain a 192-bit product. The product is broken into three 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +| `z2Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + mul128By64To192( + bits64 a0, + bits64 a1, + bits64 b, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2, more1; + + mul64To128( a1, b, &z1, &z2 ); + mul64To128( a0, b, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the +| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit +| product. The product is broken into four 64-bit pieces which are stored at +| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +*----------------------------------------------------------------------------*/ + +static inline void + mul128To256( + bits64 a0, + bits64 a1, + bits64 b0, + bits64 b1, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr, + bits64 *z3Ptr + ) +{ + bits64 z0, z1, z2, z3; + bits64 more1, more2; + + mul64To128( a1, b1, &z2, &z3 ); + mul64To128( a1, b0, &z1, &more2 ); + add128( z1, more2, 0, z2, &z1, &z2 ); + mul64To128( a0, b0, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + mul64To128( a0, b1, &more1, &more2 ); + add128( more1, more2, 0, z2, &more1, &z2 ); + add128( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +static inline bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + + if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); + b0 = b>>32; + z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; + mul64To128( b, z, &term0, &term1 ); + sub128( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits64) rem0 ) < 0 ) { + z -= LIT64( 0x100000000 ); + b1 = b<<32; + add128( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<32 ) | ( rem1>>32 ); + z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the square root of the 32-bit significand given +| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +| `aExp' (the least significant bit) is 1, the integer returned approximates +| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +| case, the approximation returned lies strictly within +/-2 of the exact +| value. +*----------------------------------------------------------------------------*/ + +static inline bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 index; + bits32 z; + + index = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a >>= 1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; + z = a / z + z; + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 32 is returned. +*----------------------------------------------------------------------------*/ + +static int8 countLeadingZeros32( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a <<= 16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 64 is returned. +*----------------------------------------------------------------------------*/ + +static int8 countLeadingZeros64( bits64 a ) +{ + int8 shiftCount; + + shiftCount = 0; + if ( a < ( (bits64) 1 )<<32 ) { + shiftCount += 32; + } + else { + a >>= 32; + } + shiftCount += countLeadingZeros32( a ); + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' +| is equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +static inline flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +| than or equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +static inline flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, +| returns 0. +*----------------------------------------------------------------------------*/ + +static inline flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is +| not equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +static inline flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} + +/*----------------------------------------------------------------------------- +| Changes the sign of the extended double-precision floating-point value 'a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static inline floatx80 floatx80_chs(floatx80 reg) +{ + reg.high ^= 0x8000; + return reg; +} + diff --git a/AltairZ80/m68k/example/softfloat/softfloat-specialize b/AltairZ80/m68k/example/softfloat/softfloat-specialize index a3113bad..b1f9da49 100644 --- a/AltairZ80/m68k/example/softfloat/softfloat-specialize +++ b/AltairZ80/m68k/example/softfloat/softfloat-specialize @@ -1,476 +1,476 @@ - -/*============================================================================ - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -flag float32_is_nan( float32 a ); -flag float64_is_nan( float64 a ); -flag floatx80_is_nan( floatx80 a ); -floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); -flag float128_is_nan( float128 a ); - -/*---------------------------------------------------------------------------- -| Underflow tininess-detection mode, statically initialized to default value. -| (The declaration in `softfloat.h' must match the `int8' type here.) -*----------------------------------------------------------------------------*/ -int8 float_detect_tininess = float_tininess_after_rounding; - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by `flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap to -| substitute a result value. If traps are not implemented, this routine -| should be simply `float_exception_flags |= flags;'. -*----------------------------------------------------------------------------*/ - -void float_raise( int8 flags ) -{ - - float_exception_flags |= flags; - -} - -/*---------------------------------------------------------------------------- -| Internal canonical NaN format. -*----------------------------------------------------------------------------*/ -typedef struct { - flag sign; - bits64 high, low; -} commonNaNT; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -#define float32_default_nan 0xFFFFFFFF - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float32_is_nan( float32 a ) -{ - - return ( 0xFF000000 < (bits32) ( a<<1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float32_is_signaling_nan( float32 a ) -{ - - return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float32ToCommonNaN( float32 a ) -{ - commonNaNT z; - - if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a>>31; - z.low = 0; - z.high = ( (bits64) a )<<41; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float32 commonNaNToFloat32( commonNaNT a ) -{ - - return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); - -} - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float32 propagateFloat32NaN( float32 a, float32 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float32_is_nan( a ); - aIsSignalingNaN = float32_is_signaling_nan( a ); - bIsNaN = float32_is_nan( b ); - bIsSignalingNaN = float32_is_signaling_nan( b ); - a |= 0x00400000; - b |= 0x00400000; - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float64_is_nan( float64 a ) -{ - - return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float64_is_signaling_nan( float64 a ) -{ - - return - ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) - && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float64ToCommonNaN( float64 a ) -{ - commonNaNT z; - - if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a>>63; - z.low = 0; - z.high = a<<12; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float64 commonNaNToFloat64( commonNaNT a ) -{ - - return - ( ( (bits64) a.sign )<<63 ) - | LIT64( 0x7FF8000000000000 ) - | ( a.high>>12 ); - -} - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64NaN( float64 a, float64 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float64_is_nan( a ); - aIsSignalingNaN = float64_is_signaling_nan( a ); - bIsNaN = float64_is_nan( b ); - bIsSignalingNaN = float64_is_signaling_nan( b ); - a |= LIT64( 0x0008000000000000 ); - b |= LIT64( 0x0008000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. The -| `high' and `low' values hold the most- and least-significant bits, -| respectively. -*----------------------------------------------------------------------------*/ -#define floatx80_default_nan_high 0xFFFF -#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_nan( floatx80 a ) -{ - - return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_signaling_nan( floatx80 a ) -{ - bits64 aLow; - - aLow = a.low & ~ LIT64( 0x4000000000000000 ); - return - ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) - && ( a.low == aLow ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT floatx80ToCommonNaN( floatx80 a ) -{ - commonNaNT z; - - if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>15; - z.low = 0; - z.high = a.low<<1; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the extended -| double-precision floating-point format. -*----------------------------------------------------------------------------*/ - -static floatx80 commonNaNToFloatx80( commonNaNT a ) -{ - floatx80 z; - - z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); - z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two extended double-precision floating-point values `a' and `b', one -| of which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = floatx80_is_nan( a ); - aIsSignalingNaN = floatx80_is_signaling_nan( a ); - bIsNaN = floatx80_is_nan( b ); - bIsSignalingNaN = floatx80_is_signaling_nan( b ); - a.low |= LIT64( 0xC000000000000000 ); - b.low |= LIT64( 0xC000000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#define EXP_BIAS 0x3FFF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -static inline bits64 extractFloatx80Frac( floatx80 a ) -{ - - return a.low; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -static inline int32 extractFloatx80Exp( floatx80 a ) -{ - - return a.high & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the extended double-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloatx80Sign( floatx80 a ) -{ - - return a.high>>15; - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. -*----------------------------------------------------------------------------*/ -#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) -#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_nan( float128 a ) -{ - - return - ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) - && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_signaling_nan( float128 a ) -{ - - return - ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) - && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float128ToCommonNaN( float128 a ) -{ - commonNaNT z; - - if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>63; - shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the quadruple- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float128 commonNaNToFloat128( commonNaNT a ) -{ - float128 z; - - shift128Right( a.high, a.low, 16, &z.high, &z.low ); - z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float128 propagateFloat128NaN( float128 a, float128 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float128_is_nan( a ); - aIsSignalingNaN = float128_is_signaling_nan( a ); - bIsNaN = float128_is_nan( b ); - bIsSignalingNaN = float128_is_signaling_nan( b ); - a.high |= LIT64( 0x0000800000000000 ); - b.high |= LIT64( 0x0000800000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#endif - + +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +flag float32_is_nan( float32 a ); +flag float64_is_nan( float64 a ); +flag floatx80_is_nan( floatx80 a ); +floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); +flag float128_is_nan( float128 a ); + +/*---------------------------------------------------------------------------- +| Underflow tininess-detection mode, statically initialized to default value. +| (The declaration in `softfloat.h' must match the `int8' type here.) +*----------------------------------------------------------------------------*/ +int8 float_detect_tininess = float_tininess_after_rounding; + +/*---------------------------------------------------------------------------- +| Raises the exceptions specified by `flags'. Floating-point traps can be +| defined here if desired. It is currently not possible for such a trap to +| substitute a result value. If traps are not implemented, this routine +| should be simply `float_exception_flags |= flags;'. +*----------------------------------------------------------------------------*/ + +void float_raise( int8 flags ) +{ + + float_exception_flags |= flags; + +} + +/*---------------------------------------------------------------------------- +| Internal canonical NaN format. +*----------------------------------------------------------------------------*/ +typedef struct { + flag sign; + bits64 high, low; +} commonNaNT; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +#define float32_default_nan 0xFFFFFFFF + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float32_is_nan( float32 a ) +{ + + return ( 0xFF000000 < (bits32) ( a<<1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float32ToCommonNaN( float32 a ) +{ + commonNaNT z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>31; + z.low = 0; + z.high = ( (bits64) a )<<41; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the single- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float32 commonNaNToFloat32( commonNaNT a ) +{ + + return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); + +} + +/*---------------------------------------------------------------------------- +| Takes two single-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float32_is_nan( a ); + aIsSignalingNaN = float32_is_signaling_nan( a ); + bIsNaN = float32_is_nan( b ); + bIsSignalingNaN = float32_is_signaling_nan( b ); + a |= 0x00400000; + b |= 0x00400000; + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float64_is_nan( float64 a ) +{ + + return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) + && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float64ToCommonNaN( float64 a ) +{ + commonNaNT z; + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>63; + z.low = 0; + z.high = a<<12; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the double- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float64 commonNaNToFloat64( commonNaNT a ) +{ + + return + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF8000000000000 ) + | ( a.high>>12 ); + +} + +/*---------------------------------------------------------------------------- +| Takes two double-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan( a ); + aIsSignalingNaN = float64_is_signaling_nan( a ); + bIsNaN = float64_is_nan( b ); + bIsSignalingNaN = float64_is_signaling_nan( b ); + a |= LIT64( 0x0008000000000000 ); + b |= LIT64( 0x0008000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. The +| `high' and `low' values hold the most- and least-significant bits, +| respectively. +*----------------------------------------------------------------------------*/ +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is a +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag floatx80_is_nan( floatx80 a ) +{ + + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is a +| signaling NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag floatx80_is_signaling_nan( floatx80 a ) +{ + bits64 aLow; + + aLow = a.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( a.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( a.low == aLow ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the +| invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT floatx80ToCommonNaN( floatx80 a ) +{ + commonNaNT z; + + if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>15; + z.low = 0; + z.high = a.low<<1; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the extended +| double-precision floating-point format. +*----------------------------------------------------------------------------*/ + +static floatx80 commonNaNToFloatx80( commonNaNT a ) +{ + floatx80 z; + + z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes two extended double-precision floating-point values `a' and `b', one +| of which is a NaN, and returns the appropriate NaN result. If either `a' or +| `b' is a signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = floatx80_is_nan( a ); + aIsSignalingNaN = floatx80_is_signaling_nan( a ); + bIsNaN = floatx80_is_nan( b ); + bIsSignalingNaN = floatx80_is_signaling_nan( b ); + a.low |= LIT64( 0xC000000000000000 ); + b.low |= LIT64( 0xC000000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#define EXP_BIAS 0x3FFF + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the extended double-precision floating-point +| value `a'. +*----------------------------------------------------------------------------*/ + +static inline bits64 extractFloatx80Frac( floatx80 a ) +{ + + return a.low; + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the extended double-precision floating-point +| value `a'. +*----------------------------------------------------------------------------*/ + +static inline int32 extractFloatx80Exp( floatx80 a ) +{ + + return a.high & 0x7FFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the extended double-precision floating-point value +| `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloatx80Sign( floatx80 a ) +{ + + return a.high>>15; + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| The pattern for a default generated quadruple-precision NaN. The `high' and +| `low' values hold the most- and least-significant bits, respectively. +*----------------------------------------------------------------------------*/ +#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) +#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float128_is_nan( float128 a ) +{ + + return + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is a +| signaling NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float128_is_signaling_nan( float128 a ) +{ + + return + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float128ToCommonNaN( float128 a ) +{ + commonNaNT z; + + if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>63; + shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the quadruple- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float128 commonNaNToFloat128( commonNaNT a ) +{ + float128 z; + + shift128Right( a.high, a.low, 16, &z.high, &z.low ); + z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes two quadruple-precision floating-point values `a' and `b', one of +| which is a NaN, and returns the appropriate NaN result. If either `a' or +| `b' is a signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float128 propagateFloat128NaN( float128 a, float128 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float128_is_nan( a ); + aIsSignalingNaN = float128_is_signaling_nan( a ); + bIsNaN = float128_is_nan( b ); + bIsSignalingNaN = float128_is_signaling_nan( b ); + a.high |= LIT64( 0x0000800000000000 ); + b.high |= LIT64( 0x0000800000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif + diff --git a/AltairZ80/m68k/example/softfloat/softfloat.c b/AltairZ80/m68k/example/softfloat/softfloat.c index 400fd593..75c0f20e 100644 --- a/AltairZ80/m68k/example/softfloat/softfloat.c +++ b/AltairZ80/m68k/example/softfloat/softfloat.c @@ -1,4940 +1,4940 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include "../m68kcpu.h" // which includes softfloat.h after defining the basic types - -/*---------------------------------------------------------------------------- -| Floating-point rounding mode, extended double-precision rounding precision, -| and exception flags. -*----------------------------------------------------------------------------*/ -int8 float_exception_flags = 0; -#ifdef FLOATX80 -int8 floatx80_rounding_precision = 80; -#endif - -int8 float_rounding_mode = float_round_nearest_even; - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize" - -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the largest -| positive or negative integer is returned. -*----------------------------------------------------------------------------*/ - -static int32 roundAndPackInt32( flag zSign, bits64 absZ ) -{ - int8 roundingMode; - flag roundNearestEven; - int8 roundIncrement, roundBits; - int32 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - roundIncrement = 0x40; - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - roundIncrement = 0; - } - else { - roundIncrement = 0x7F; - if ( zSign ) { - if ( roundingMode == float_round_up ) roundIncrement = 0; - } - else { - if ( roundingMode == float_round_down ) roundIncrement = 0; - } - } - } - roundBits = absZ & 0x7F; - absZ = ( absZ + roundIncrement )>>7; - absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - z = absZ; - if ( zSign ) z = - z; - if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { - float_raise( float_flag_invalid ); - return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( roundBits ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest positive or negative integer is -| returned. -*----------------------------------------------------------------------------*/ - -static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) -{ - int8 roundingMode; - flag roundNearestEven, increment; - int64 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) absZ1 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && absZ1; - } - else { - increment = ( roundingMode == float_round_up ) && absZ1; - } - } - } - if ( increment ) { - ++absZ0; - if ( absZ0 == 0 ) goto overflow; - absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); - } - z = absZ0; - if ( zSign ) z = - z; - if ( z && ( ( z < 0 ) ^ zSign ) ) { - overflow: - float_raise( float_flag_invalid ); - return - zSign ? (sbits64) LIT64( 0x8000000000000000 ) - : (sbits64) LIT64( 0x7FFFFFFFFFFFFFFF ); - } - if ( absZ1 ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline bits32 extractFloat32Frac( float32 a ) -{ - return a & 0x007FFFFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline int16 extractFloat32Exp( float32 a ) -{ - return ( a>>23 ) & 0xFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat32Sign( float32 a ) -{ - return a>>31; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( aSig ) - 8; - *zSigPtr = aSig<>7; - zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float32 - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( zSig ) - 1; - return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat64Sign( float64 a ) -{ - return a>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal double-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( aSig ) - 11; - *zSigPtr = aSig<>10; - zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float64 - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( zSig ) - 1; - return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the quadruple-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat128Sign( float128 a ) -{ - return a.high>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat128Subnormal( - bits64 aSig0, - bits64 aSig1, - int32 *zExpPtr, - bits64 *zSig0Ptr, - bits64 *zSig1Ptr - ) -{ - int8 shiftCount; - - if ( aSig0 == 0 ) { - shiftCount = countLeadingZeros64( aSig1 ) - 15; - if ( shiftCount < 0 ) { - *zSig0Ptr = aSig1>>( - shiftCount ); - *zSig1Ptr = aSig1<<( shiftCount & 63 ); - } - else { - *zSig0Ptr = aSig1<>( - shiftCount ); - if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64, aSigExtra; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64( aSign, aSig64, aSigExtra ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64_round_to_zero( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64; - int64 z; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( a != 0xDF000000 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float32_to_float64( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); - return packFloat64( aSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float32_to_floatx80( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - aSig |= 0x00800000; - return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float32_to_float128( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_round_to_int( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 lastBitMask, roundBitsMask; - int8 roundingMode; - float32 z; - - aExp = extractFloat32Exp( a ); - if ( 0x96 <= aExp ) { - if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN( a, a ); - } - return a; - } - if ( aExp <= 0x7E ) { - if ( (bits32) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat32Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_down: - return aSign ? 0xBF800000 : 0; - case float_round_up: - return aSign ? 0x80000000 : 0x3F800000; - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - if ( 0 < expDiff ) { - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - zSig = 0x40000000 + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= 0x20000000; - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits32) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the single-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_add( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return addFloat32Sigs( a, b, aSign ); - } - else { - return subFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sub( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return subFloat32Sigs( a, b, aSign ); - } - else { - return addFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_mul( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig; - bits64 zSig64; - bits32 zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x7F; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); - zSig = zSig64; - if ( 0 <= (sbits32) ( zSig<<1 ) ) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the single-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_div( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x7D; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = ( ( (bits64) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the single-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_rem( float32 a, float32 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits32 aSig, bSig; - bits32 q; - bits64 aSig64, bSig64, q64; - bits32 alternateASig; - sbits32 sigMean; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); -// bSign = extractFloat32Sign( b ); - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig |= 0x00800000; - bSig |= 0x00800000; - if ( expDiff < 32 ) { - aSig <<= 8; - bSig <<= 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - if ( 0 < expDiff ) { - q = ( ( (bits64) aSig )<<32 ) / bSig; - q >>= 32 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - } - else { - if ( bSig <= aSig ) aSig -= bSig; - aSig64 = ( (bits64) aSig )<<40; - bSig64 = ( (bits64) bSig )<<40; - expDiff -= 64; - while ( 0 < expDiff ) { - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - aSig64 = - ( ( bSig * q64 )<<38 ); - expDiff -= 62; - } - expDiff += 64; - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - q = q64>>( 64 - expDiff ); - bSig <<= 6; - aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits32) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits32) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sqrt( float32 a ) -{ - flag aSign; - int16 aExp, zExp; - bits32 aSig, zSig; - bits64 rem, term; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, 0 ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; - aSig = ( aSig | 0x00800000 )<<8; - zSig = estimateSqrt32( aExp, aSig ) + 2; - if ( ( zSig & 0x7F ) <= 5 ) { - if ( zSig < 2 ) { - zSig = 0x7FFFFFFF; - goto roundAndPack; - } - aSig >>= aExp & 1; - term = ( (bits64) zSig ) * zSig; - rem = ( ( (bits64) aSig )<<32 ) - term; - while ( (sbits64) rem < 0 ) { - --zSig; - rem += ( ( (bits64) zSig )<<1 ) | 1; - } - zSig |= ( rem != 0 ); - } - shift32RightJamming( zSig, 1, &zSig ); - roundAndPack: - return roundAndPackFloat32( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq_signaling( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32_round_to_zero( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the single-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float64_to_float32( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - bits32 zSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 22, &aSig ); - zSig = aSig; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x381; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float64_to_floatx80( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - return - packFloatx80( - aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the quadruple-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float64_to_float128( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_round_to_int( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float64 z; - - aExp = extractFloat64Exp( a ); - if ( 0x433 <= aExp ) { - if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (bits64) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat64Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_down: - return aSign ? LIT64( 0xBFF0000000000000 ) : 0; - case float_round_up: - return - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if ( 0 < expDiff ) { - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= LIT64( 0x2000000000000000 ); - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits64) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |= LIT64( 0x4000000000000000 ); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |= LIT64( 0x4000000000000000 ); - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the double-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_add( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return addFloat64Sigs( a, b, aSign ); - } - else { - return subFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sub( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return subFloat64Sigs( a, b, aSign ); - } - else { - return addFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_mul( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FF; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (sbits64) ( zSig0<<1 ) ) { - zSig0 <<= 1; - --zExp; - } - return roundAndPackFloat64( zSign, zExp, zSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the double-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_div( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - bits64 rem0, rem1; - bits64 term0, term1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FD; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <= 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |= ( rem1 != 0 ); - } - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the double-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_rem( float64 a, float64 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits64 aSig, bSig; - bits64 q, alternateASig; - sbits64 sigMean; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); -// bSign = extractFloat64Sign( b ); - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - aSig = - ( ( bSig>>2 ) * q ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits64) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits64) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sqrt( float64 a ) -{ - flag aSign; - int16 aExp, zExp; - bits64 aSig, zSig, doubleZSig; - bits64 rem0, rem1, term0, term1; -// float64 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, a ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; - aSig |= LIT64( 0x0010000000000000 ); - zSig = estimateSqrt32( aExp, aSig>>21 ); - aSig <<= 9 - ( aExp & 1 ); - zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); - if ( ( zSig & 0x1FF ) <= 5 ) { - doubleZSig = zSig<<1; - mul64To128( zSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - doubleZSig -= 2; - add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); - } - zSig |= ( ( rem0 | rem1 ) != 0 ); - } - return roundAndPackFloat64( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The invalid exception is raised -| if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq_signaling( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic---which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN, the -| largest positive integer is returned. Otherwise, if the conversion -| overflows, the largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - shiftCount = 0x4037 - aExp; - if ( shiftCount <= 0 ) shiftCount = 1; - shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN, the largest positive integer is returned. -| Otherwise, if the conversion overflows, the largest integer with the same -| sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32_round_to_zero( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 floatx80_to_float32( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 33, &aSig ); - if ( aExp || aSig ) aExp -= 0x3F81; - return roundAndPackFloat32( aSign, aExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 floatx80_to_float64( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig, zSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shift64RightJamming( aSig, 1, &zSig ); - if ( aExp || aSig ) aExp -= 0x3C01; - return roundAndPackFloat64( aSign, aExp, zSig ); - -} - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the quadruple-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 floatx80_to_float128( floatx80 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); - } - shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the extended double-precision floating-point value `a' to an integer, -| and returns the result as an extended quadruple-precision floating-point -| value. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_round_to_int( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - floatx80 z; - - aExp = extractFloatx80Exp( a ); - if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FFF ) { - if ( ( aExp == 0 ) - && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { - return a; - } - float_exception_flags |= float_flag_inexact; - aSign = extractFloatx80Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) - ) { - return - packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - break; - case float_round_down: - return - aSign ? - packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) - : packFloatx80( 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloatx80( 1, 0, 0 ) - : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - return packFloatx80( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x403E - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.low += lastBitMask>>1; - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z.low += roundBitsMask; - } - } - z.low &= ~ roundBitsMask; - if ( z.low == 0 ) { - ++z.high; - z.low = LIT64( 0x8000000000000000 ); - } - if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the extended double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is -| negated before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - return a; - } - zSig1 = 0; - zSig0 = aSig + bSig; - if ( aExp == 0 ) { - normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); - goto roundAndPack; - } - zExp = aExp; - goto shiftRight1; - } - zSig0 = aSig + bSig; - if ( (sbits64) zSig0 < 0 ) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= LIT64( 0x8000000000000000 ); - ++zExp; - roundAndPack: - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the extended -| double-precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - zSig1 = 0; - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - bBigger: - sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - aBigger: - sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - return - normalizeRoundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the extended double-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_add( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return addFloatx80Sigs( a, b, aSign ); - } - else { - return subFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sub( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return subFloatx80Sigs( a, b, aSign ); - } - else { - return addFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_mul( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FFE; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - if ( 0 < (sbits64) zSig0 ) { - shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); - --zExp; - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_div( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - bits64 rem0, rem1, rem2, term0, term1, term2; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - goto invalid; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if ( bSig <= aSig ) { - shift128Right( aSig, 0, 1, &aSig, &rem1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig, rem1, bSig ); - mul64To128( bSig, zSig0, &term0, &term1 ); - sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, bSig ); - if ( (bits64) ( zSig1<<1 ) <= 8 ) { - mul64To128( bSig, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); - } - zSig1 |= ( ( rem1 | rem2 ) != 0 ); - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the extended double-precision floating-point value -| `a' with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_rem( floatx80 a, floatx80 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig; - bits64 q, term0, term1, alternateASig0, alternateASig1; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); -// bSign = extractFloatx80Sign( b ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( (bits64) ( aSig0<<1 ) == 0 ) return a; - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - bSig |= LIT64( 0x8000000000000000 ); - zSign = aSign; - expDiff = aExp - bExp; - aSig1 = 0; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); - expDiff = 0; - } - q = ( bSig <= aSig0 ); - if ( q ) aSig0 -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - mul64To128( bSig, q, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); - while ( le128( term0, term1, aSig0, aSig1 ) ) { - ++q; - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - } - } - else { - term1 = 0; - term0 = bSig; - } - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) - && ( q & 1 ) ) - ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - zSign = ! zSign; - } - return - normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sqrt( floatx80 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; - zSig0 = estimateSqrt32( aExp, aSig0>>32 ); - shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= doubleZSig0; - return - roundAndPackFloatx80( - floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than or equal to the corresponding value `b', and 0 otherwise. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is equal -| to the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq_signaling( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs -| do not cause an exception. Otherwise, the comparison is performed according -| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause -| an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; - if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); - aSig0 |= ( aSig1 != 0 ); - shiftCount = 0x4028 - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); - return roundAndPackInt32( aSign, aSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32_round_to_zero( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1, savedASig; - int32 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - aSig0 |= ( aSig1 != 0 ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig0 |= LIT64( 0x0001000000000000 ); - shiftCount = 0x402F - aExp; - savedASig = aSig0; - aSig0 >>= shiftCount; - z = aSig0; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); - if ( (bits64) ( aSig1<>( - shiftCount ); - if ( aSig1 - || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the single-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float128_to_float32( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - bits32 zSig; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat32( float128ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - aSig0 |= ( aSig1 != 0 ); - shift64RightJamming( aSig0, 18, &aSig0 ); - zSig = aSig0; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x3F81; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float128_to_float64( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat64( float128ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - aSig0 |= ( aSig1 != 0 ); - if ( aExp || aSig0 ) { - aSig0 |= LIT64( 0x4000000000000000 ); - aExp -= 0x3C01; - } - return roundAndPackFloat64( aSign, aExp, aSig0 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the extended double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float128_to_floatx80( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloatx80( float128ToCommonNaN( a ) ); - } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); - return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the quadruple-precision floating-point value `a' to an integer, and -| returns the result as a quadruple-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_round_to_int( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float128 z; - - aExp = extractFloat128Exp( a ); - if ( 0x402F <= aExp ) { - if ( 0x406F <= aExp ) { - if ( ( aExp == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) - ) { - return propagateFloat128NaN( a, a ); - } - return a; - } - lastBitMask = 1; - lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - if ( lastBitMask ) { - add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else { - if ( (sbits64) z.low < 0 ) { - ++z.high; - if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; - } - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); - } - } - z.low &= ~ roundBitsMask; - } - else { - if ( aExp < 0x3FFF ) { - if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat128Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) - && ( extractFloat128Frac0( a ) - | extractFloat128Frac1( a ) ) - ) { - return packFloat128( aSign, 0x3FFF, 0, 0 ); - } - break; - case float_round_down: - return - aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) - : packFloat128( 0, 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloat128( 1, 0, 0, 0 ) - : packFloat128( 0, 0x3FFF, 0, 0 ); - } - return packFloat128( aSign, 0, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x402F - aExp; - roundBitsMask = lastBitMask - 1; - z.low = 0; - z.high = a.high; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.high += lastBitMask>>1; - if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { - z.high &= ~ lastBitMask; - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - z.high |= ( a.low != 0 ); - z.high += roundBitsMask; - } - } - z.high &= ~ roundBitsMask; - } - if ( ( z.low != a.low ) || ( z.high != a.high ) ) { - float_exception_flags |= float_flag_inexact; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the quadruple-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - int32 expDiff; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - return a; - } - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); - zSig2 = 0; - zSig0 |= LIT64( 0x0002000000000000 ); - zExp = aExp; - goto shiftRight1; - } - aSig0 |= LIT64( 0x0001000000000000 ); - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - --zExp; - if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; - ++zExp; - shiftRight1: - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - roundAndPack: - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the quadruple- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; - int32 expDiff; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig0 < aSig0 ) goto aBigger; - if ( aSig0 < bSig0 ) goto bBigger; - if ( bSig1 < aSig1 ) goto aBigger; - if ( aSig1 < bSig1 ) goto bBigger; - return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - bSig0 |= LIT64( 0x4000000000000000 ); - bBigger: - sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); - aSig0 |= LIT64( 0x4000000000000000 ); - aBigger: - sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the quadruple-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_add( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return addFloat128Sigs( a, b, aSign ); - } - else { - return subFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sub( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return subFloat128Sigs( a, b, aSign ); - } - else { - return addFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_mul( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - zExp = aExp + bExp - 0x4000; - aSig0 |= LIT64( 0x0001000000000000 ); - shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); - mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); - add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zSig2 |= ( zSig3 != 0 ); - if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - ++zExp; - } - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the quadruple-precision floating-point value -| `a' by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_div( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - goto invalid; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0, 0, 0 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = aExp - bExp + 0x3FFD; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { - shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); - mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); - sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); - } - zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); - if ( ( zSig1 & 0x3FFF ) <= 4 ) { - mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); - sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the quadruple-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_rem( float128 a, float128 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; - bits64 allZero, alternateASig0, alternateASig1, sigMean1; - sbits64 sigMean0; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); -// bSign = extractFloat128Sign( b ); - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return a; - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - expDiff = aExp - bExp; - if ( expDiff < -1 ) return a; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), - aSig1, - 15 - ( expDiff < 0 ), - &aSig0, - &aSig1 - ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - q = le128( bSig0, bSig1, aSig0, aSig1 ); - if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); - shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); - sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); - expDiff -= 61; - } - if ( -64 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - q >>= - expDiff; - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - expDiff += 52; - if ( expDiff < 0 ) { - shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - } - else { - shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); - } - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); - } - else { - shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - } - do { - alternateASig0 = aSig0; - alternateASig1 = aSig1; - ++q; - sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <= (sbits64) aSig0 ); - add128( - aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); - if ( ( sigMean0 < 0 ) - || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - } - zSign = ( (sbits64) aSig0 < 0 ); - if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); - return - normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the quadruple-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sqrt( float128 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; - aSig0 |= LIT64( 0x0001000000000000 ); - zSig0 = estimateSqrt32( aExp, aSig0>>17 ); - shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & 0x1FFF ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq_signaling( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif + +/*============================================================================ + +This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +#include "../m68kcpu.h" // which includes softfloat.h after defining the basic types + +/*---------------------------------------------------------------------------- +| Floating-point rounding mode, extended double-precision rounding precision, +| and exception flags. +*----------------------------------------------------------------------------*/ +int8 float_exception_flags = 0; +#ifdef FLOATX80 +int8 floatx80_rounding_precision = 80; +#endif + +int8 float_rounding_mode = float_round_nearest_even; + +/*---------------------------------------------------------------------------- +| Functions and definitions to determine: (1) whether tininess for underflow +| is detected before or after rounding by default, (2) what (if anything) +| happens when exceptions are raised, (3) how signaling NaNs are distinguished +| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +| are propagated from function inputs to output. These details are target- +| specific. +*----------------------------------------------------------------------------*/ +#include "softfloat-specialize" + +/*---------------------------------------------------------------------------- +| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 +| and 7, and returns the properly rounded 32-bit integer corresponding to the +| input. If `zSign' is 1, the input is negated before being converted to an +| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input +| is simply rounded to an integer, with the inexact exception raised if the +| input cannot be represented exactly as an integer. However, if the fixed- +| point input is too large, the invalid exception is raised and the largest +| positive or negative integer is returned. +*----------------------------------------------------------------------------*/ + +static int32 roundAndPackInt32( flag zSign, bits64 absZ ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + int32 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = absZ & 0x7F; + absZ = ( absZ + roundIncrement )>>7; + absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + z = absZ; + if ( zSign ) z = - z; + if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { + float_raise( float_flag_invalid ); + return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +| `absZ1', with binary point between bits 63 and 64 (between the input words), +| and returns the properly rounded 64-bit integer corresponding to the input. +| If `zSign' is 1, the input is negated before being converted to an integer. +| Ordinarily, the fixed-point input is simply rounded to an integer, with +| the inexact exception raised if the input cannot be represented exactly as +| an integer. However, if the fixed-point input is too large, the invalid +| exception is raised and the largest positive or negative integer is +| returned. +*----------------------------------------------------------------------------*/ + +static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) +{ + int8 roundingMode; + flag roundNearestEven, increment; + int64 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) absZ1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && absZ1; + } + else { + increment = ( roundingMode == float_round_up ) && absZ1; + } + } + } + if ( increment ) { + ++absZ0; + if ( absZ0 == 0 ) goto overflow; + absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + } + z = absZ0; + if ( zSign ) z = - z; + if ( z && ( ( z < 0 ) ^ zSign ) ) { + overflow: + float_raise( float_flag_invalid ); + return + zSign ? (sbits64) LIT64( 0x8000000000000000 ) + : (sbits64) LIT64( 0x7FFFFFFFFFFFFFFF ); + } + if ( absZ1 ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline bits32 extractFloat32Frac( float32 a ) +{ + return a & 0x007FFFFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline int16 extractFloat32Exp( float32 a ) +{ + return ( a>>23 ) & 0xFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat32Sign( float32 a ) +{ + return a>>31; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal single-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper single-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat32' except that `zSig' does not have to be normalized. +| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat64Sign( float64 a ) +{ + return a>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ) - 11; + *zSigPtr = aSig<>10; + zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper double-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat64' except that `zSig' does not have to be normalized. +| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float64 + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( zSig ) - 1; + return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the quadruple-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat128Sign( float128 a ) +{ + return a.high>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal quadruple-precision floating-point value +| represented by the denormalized significand formed by the concatenation of +| `aSig0' and `aSig1'. The normalized exponent is stored at the location +| pointed to by `zExpPtr'. The most significant 49 bits of the normalized +| significand are stored at the location pointed to by `zSig0Ptr', and the +| least significant 64 bits of the normalized significand are stored at the +| location pointed to by `zSig1Ptr'. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat128Subnormal( + bits64 aSig0, + bits64 aSig1, + int32 *zExpPtr, + bits64 *zSig0Ptr, + bits64 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros64( aSig1 ) - 15; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 63 ); + } + else { + *zSig0Ptr = aSig1<>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64, aSigExtra; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = 0xBE - aExp; + if ( shiftCount < 0 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + if ( aExp ) aSig |= 0x00800000; + aSig64 = aSig; + aSig64 <<= 40; + shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); + return roundAndPackInt64( aSign, aSig64, aSigExtra ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest positive integer is returned. Otherwise, if the +| conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64; + int64 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0xBE; + if ( 0 <= shiftCount ) { + if ( a != 0xDF000000 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig64 = aSig | 0x00800000; + aSig64 <<= 40; + z = aSig64>>( - shiftCount ); + if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the extended double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float32_to_floatx80( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + aSig |= 0x00800000; + return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float32_to_float128( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the single-precision floating-point value `a' to an integer, and +| returns the result as a single-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the single-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the single- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the single-precision floating-point values `a' +| and `b'. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig; + bits64 zSig64; + bits32 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + zSig = zSig64; + if ( 0 <= (sbits32) ( zSig<<1 ) ) { + zSig <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the single-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = ( ( (bits64) aSig )<<32 ) / bSig; + if ( ( zSig & 0x3F ) == 0 ) { + zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the single-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q; + bits64 aSig64, bSig64, q64; + bits32 alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); +// bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig |= 0x00800000; + bSig |= 0x00800000; + if ( expDiff < 32 ) { + aSig <<= 8; + bSig <<= 8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + if ( 0 < expDiff ) { + q = ( ( (bits64) aSig )<<32 ) / bSig; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + } + else { + if ( bSig <= aSig ) aSig -= bSig; + aSig64 = ( (bits64) aSig )<<40; + bSig64 = ( (bits64) bSig )<<40; + expDiff -= 64; + while ( 0 < expDiff ) { + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + aSig64 = - ( ( bSig * q64 )<<38 ); + expDiff -= 62; + } + expDiff += 64; + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + q = q64>>( 64 - expDiff ); + bSig <<= 6; + aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the single-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits64 rem, term; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0x7FFFFFFF; + goto roundAndPack; + } + aSig >>= aExp & 1; + term = ( (bits64) zSig ) * zSig; + rem = ( ( (bits64) aSig )<<32 ) - term; + while ( (sbits64) rem < 0 ) { + --zSig; + rem += ( ( (bits64) zSig )<<1 ) | 1; + } + zSig |= ( rem != 0 ); + } + shift32RightJamming( zSig, 1, &zSig ); + roundAndPack: + return roundAndPackFloat32( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq( float32 a, float32 b ) +{ + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq_signaling( float32 a, float32 b ) +{ + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. +| If `a' is a NaN, the largest positive integer is returned. Otherwise, if +| the conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the single-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + bits32 zSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 22, &aSig ); + zSig = aSig; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x381; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the extended double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float64_to_floatx80( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + return + packFloatx80( + aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the quadruple-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float64_to_float128( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the double-precision floating-point value `a' to an integer, and +| returns the result as a double-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FF ) { + if ( (bits64) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { + return packFloat64( aSign, 0x3FF, 0 ); + } + break; + case float_round_down: + return aSign ? LIT64( 0xBFF0000000000000 ) : 0; + case float_round_up: + return + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); + } + return packFloat64( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x433 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the double-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 9; + bSig <<= 9; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); + zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= LIT64( 0x2000000000000000 ); + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits64) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the double- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 10; + bSig <<= 10; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + bSig |= LIT64( 0x4000000000000000 ); + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + aSig |= LIT64( 0x4000000000000000 ); + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the double-precision floating-point values `a' +| and `b'. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FF; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1; + bits64 term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0 ); + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FD; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64( aSig, 0, bSig ); + if ( ( zSig & 0x1FF ) <= 2 ) { + mul64To128( bSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the double-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, zSign; + int16 aExp, bExp, expDiff; + bits64 aSig, bSig; + bits64 q, alternateASig; + sbits64 sigMean; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); +// bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits64) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits64) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the double-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits64 aSig, zSig, doubleZSig; + bits64 rem0, rem1, term0, term1; +// float64 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig |= LIT64( 0x0010000000000000 ); + zSig = estimateSqrt32( aExp, aSig>>21 ); + aSig <<= 9 - ( aExp & 1 ); + zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); + if ( ( zSig & 0x1FF ) <= 5 ) { + doubleZSig = zSig<<1; + mul64To128( zSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + doubleZSig -= 2; + add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + return roundAndPackFloat64( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq( float64 a, float64 b ) +{ + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. The invalid exception is raised +| if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq_signaling( float64 a, float64 b ) +{ + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic---which means in particular that the conversion +| is rounded according to the current rounding mode. If `a' is a NaN, the +| largest positive integer is returned. Otherwise, if the conversion +| overflows, the largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + shiftCount = 0x4037 - aExp; + if ( shiftCount <= 0 ) shiftCount = 1; + shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic, except that the conversion is always rounded +| toward zero. If `a' is a NaN, the largest positive integer is returned. +| Otherwise, if the conversion overflows, the largest integer with the same +| sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32_round_to_zero( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + shiftCount = 0x403E - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the single-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 floatx80_to_float32( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 33, &aSig ); + if ( aExp || aSig ) aExp -= 0x3F81; + return roundAndPackFloat32( aSign, aExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the double-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 floatx80_to_float64( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig, zSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shift64RightJamming( aSig, 1, &zSig ); + if ( aExp || aSig ) aExp -= 0x3C01; + return roundAndPackFloat64( aSign, aExp, zSig ); + +} + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the quadruple-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 floatx80_to_float128( floatx80 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); + } + shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the extended double-precision floating-point value `a' to an integer, +| and returns the result as an extended quadruple-precision floating-point +| value. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_round_to_int( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + floatx80 z; + + aExp = extractFloatx80Exp( a ); + if ( 0x403E <= aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + return propagateFloatx80NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FFF ) { + if ( ( aExp == 0 ) + && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + return a; + } + float_exception_flags |= float_flag_inexact; + aSign = extractFloatx80Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + ) { + return + packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + break; + case float_round_down: + return + aSign ? + packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) + : packFloatx80( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloatx80( 1, 0, 0 ) + : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + return packFloatx80( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x403E - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.low += lastBitMask>>1; + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z.low += roundBitsMask; + } + } + z.low &= ~ roundBitsMask; + if ( z.low == 0 ) { + ++z.high; + z.low = LIT64( 0x8000000000000000 ); + } + if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the extended double- +| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is +| negated before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + return a; + } + zSig1 = 0; + zSig0 = aSig + bSig; + if ( aExp == 0 ) { + normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); + goto roundAndPack; + } + zExp = aExp; + goto shiftRight1; + } + zSig0 = aSig + bSig; + if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= LIT64( 0x8000000000000000 ); + ++zExp; + roundAndPack: + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the extended +| double-precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + zSig1 = 0; + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + bBigger: + sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + aBigger: + sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + return + normalizeRoundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the extended double-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_add( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return addFloatx80Sigs( a, b, aSign ); + } + else { + return subFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the extended double-precision floating- +| point values `a' and `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sub( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return subFloatx80Sigs( a, b, aSign ); + } + else { + return addFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the extended double-precision floating- +| point values `a' and `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_mul( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) goto invalid; + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FFE; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + if ( 0 < (sbits64) zSig0 ) { + shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); + --zExp; + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the extended double-precision floating-point +| value `a' by the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_div( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + bits64 rem0, rem1, rem2, term0, term1, term2; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + goto invalid; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FFE; + rem1 = 0; + if ( bSig <= aSig ) { + shift128Right( aSig, 0, 1, &aSig, &rem1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig, rem1, bSig ); + mul64To128( bSig, zSig0, &term0, &term1 ); + sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, bSig ); + if ( (bits64) ( zSig1<<1 ) <= 8 ) { + mul64To128( bSig, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); + } + zSig1 |= ( ( rem1 | rem2 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the extended double-precision floating-point value +| `a' with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_rem( floatx80 a, floatx80 b ) +{ + flag aSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig; + bits64 q, term0, term1, alternateASig0, alternateASig1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); +// bSign = extractFloatx80Sign( b ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + bSig |= LIT64( 0x8000000000000000 ); + zSign = aSign; + expDiff = aExp - bExp; + aSig1 = 0; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); + expDiff = 0; + } + q = ( bSig <= aSig0 ); + if ( q ) aSig0 -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul64To128( bSig, q, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); + while ( le128( term0, term1, aSig0, aSig1 ) ) { + ++q; + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + } + } + else { + term1 = 0; + term0 = bSig; + } + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) + && ( q & 1 ) ) + ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + zSign = ! zSign; + } + return + normalizeRoundAndPackFloatx80( + 80, zSign, bExp + expDiff, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the extended double-precision floating-point +| value `a'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sqrt( floatx80 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; + zSig0 = estimateSqrt32( aExp, aSig0>>32 ); + shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= doubleZSig0; + return + roundAndPackFloatx80( + floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq( floatx80 a, floatx80 b ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| less than or equal to the corresponding value `b', and 0 otherwise. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| less than the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is equal +| to the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq_signaling( floatx80 a, floatx80 b ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is less +| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs +| do not cause an exception. Otherwise, the comparison is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is less +| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause +| an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; + if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); + aSig0 |= ( aSig1 != 0 ); + shiftCount = 0x4028 - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); + return roundAndPackInt32( aSign, aSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest positive integer is returned. Otherwise, if the +| conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32_round_to_zero( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1, savedASig; + int32 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + aSig0 |= ( aSig1 != 0 ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig0 |= LIT64( 0x0001000000000000 ); + shiftCount = 0x402F - aExp; + savedASig = aSig0; + aSig0 >>= shiftCount; + z = aSig0; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); + if ( (bits64) ( aSig1<>( - shiftCount ); + if ( aSig1 + || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the single-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float128_to_float32( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + bits32 zSig; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat32( float128ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + aSig0 |= ( aSig1 != 0 ); + shift64RightJamming( aSig0, 18, &aSig0 ); + zSig = aSig0; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x3F81; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float128_to_float64( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat64( float128ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + aSig0 |= ( aSig1 != 0 ); + if ( aExp || aSig0 ) { + aSig0 |= LIT64( 0x4000000000000000 ); + aExp -= 0x3C01; + } + return roundAndPackFloat64( aSign, aExp, aSig0 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the extended double-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float128_to_floatx80( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloatx80( float128ToCommonNaN( a ) ); + } + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); + return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the quadruple-precision floating-point value `a' to an integer, and +| returns the result as a quadruple-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_round_to_int( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float128 z; + + aExp = extractFloat128Exp( a ); + if ( 0x402F <= aExp ) { + if ( 0x406F <= aExp ) { + if ( ( aExp == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) + ) { + return propagateFloat128NaN( a, a ); + } + return a; + } + lastBitMask = 1; + lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( (sbits64) z.low < 0 ) { + ++z.high; + if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp < 0x3FFF ) { + if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat128Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) + && ( extractFloat128Frac0( a ) + | extractFloat128Frac1( a ) ) + ) { + return packFloat128( aSign, 0x3FFF, 0, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) + : packFloat128( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat128( 1, 0, 0, 0 ) + : packFloat128( 0, 0x3FFF, 0, 0 ); + } + return packFloat128( aSign, 0, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x402F - aExp; + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the quadruple-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int32 expDiff; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + return a; + } + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= LIT64( 0x0002000000000000 ); + zExp = aExp; + goto shiftRight1; + } + aSig0 |= LIT64( 0x0001000000000000 ); + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; + ++zExp; + shiftRight1: + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the quadruple- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int32 expDiff; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= LIT64( 0x4000000000000000 ); + bBigger: + sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= LIT64( 0x4000000000000000 ); + aBigger: + sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the quadruple-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_add( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return addFloat128Sigs( a, b, aSign ); + } + else { + return subFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sub( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return subFloat128Sigs( a, b, aSign ); + } + else { + return addFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_mul( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x4000; + aSig0 |= LIT64( 0x0001000000000000 ); + shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); + mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( zSig3 != 0 ); + if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the quadruple-precision floating-point value +| `a' by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_div( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + goto invalid; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FFD; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { + shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); + mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FFF ) <= 4 ) { + mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the quadruple-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_rem( float128 a, float128 b ) +{ + flag aSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + bits64 allZero, alternateASig0, alternateASig1, sigMean1; + sbits64 sigMean0; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); +// bSign = extractFloat128Sign( b ); + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), + aSig1, + 15 - ( expDiff < 0 ), + &aSig0, + &aSig1 + ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + q = le128( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); + shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); + sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 61; + } + if ( -64 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + expDiff += 52; + if ( expDiff < 0 ) { + shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= (sbits64) aSig0 ); + add128( + aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits64) aSig0 < 0 ); + if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the quadruple-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sqrt( float128 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; + aSig0 |= LIT64( 0x0001000000000000 ); + zSig0 = estimateSqrt32( aExp, aSig0>>17 ); + shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & 0x1FFF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq( float128 a, float128 b ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq_signaling( float128 a, float128 b ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif diff --git a/AltairZ80/m68k/example/softfloat/softfloat.h b/AltairZ80/m68k/example/softfloat/softfloat.h index 92135e66..88b0c4fc 100644 --- a/AltairZ80/m68k/example/softfloat/softfloat.h +++ b/AltairZ80/m68k/example/softfloat/softfloat.h @@ -1,460 +1,460 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| The macro `FLOATX80' must be defined to enable the extended double-precision -| floating-point format `floatx80'. If this macro is not defined, the -| `floatx80' type will not be defined, and none of the functions that either -| input or output the `floatx80' type will be defined. The same applies to -| the `FLOAT128' macro and the quadruple-precision format `float128'. -*----------------------------------------------------------------------------*/ -#define FLOATX80 -#define FLOAT128 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ -typedef bits32 float32; -typedef bits64 float64; -#ifdef FLOATX80 -typedef struct { - bits16 high; - bits64 low; -} floatx80; -#endif -#ifdef FLOAT128 -typedef struct { - bits64 high, low; -} float128; -#endif - -/*---------------------------------------------------------------------------- -| Primitive arithmetic functions, including multi-word arithmetic, and -| division and square root approximations. (Can be specialized to target if -| desired.) -*----------------------------------------------------------------------------*/ -#include "softfloat-macros" - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -extern int8 float_detect_tininess; -enum { - float_tininess_after_rounding = 0, - float_tininess_before_rounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -extern int8 float_rounding_mode; -enum { - float_round_nearest_even = 0, - float_round_to_zero = 1, - float_round_down = 2, - float_round_up = 3 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ -extern int8 float_exception_flags; -enum { - float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, - float_flag_underflow = 0x10, float_flag_inexact = 0x20 -}; - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software IEC/IEEE floating-point -| exception flags. -*----------------------------------------------------------------------------*/ -void float_raise( int8 ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32( int32 ); -float64 int32_to_float64( int32 ); -#ifdef FLOATX80 -floatx80 int32_to_floatx80( int32 ); -#endif -#ifdef FLOAT128 -float128 int32_to_float128( int32 ); -#endif -float32 int64_to_float32( int64 ); -float64 int64_to_float64( int64 ); -#ifdef FLOATX80 -floatx80 int64_to_floatx80( int64 ); -#endif -#ifdef FLOAT128 -float128 int64_to_float128( int64 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float32_to_int32( float32 ); -int32 float32_to_int32_round_to_zero( float32 ); -int64 float32_to_int64( float32 ); -int64 float32_to_int64_round_to_zero( float32 ); -float64 float32_to_float64( float32 ); -#ifdef FLOATX80 -floatx80 float32_to_floatx80( float32 ); -#endif -#ifdef FLOAT128 -float128 float32_to_float128( float32 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int( float32 ); -float32 float32_add( float32, float32 ); -float32 float32_sub( float32, float32 ); -float32 float32_mul( float32, float32 ); -float32 float32_div( float32, float32 ); -float32 float32_rem( float32, float32 ); -float32 float32_sqrt( float32 ); -flag float32_eq( float32, float32 ); -flag float32_le( float32, float32 ); -flag float32_lt( float32, float32 ); -flag float32_eq_signaling( float32, float32 ); -flag float32_le_quiet( float32, float32 ); -flag float32_lt_quiet( float32, float32 ); -flag float32_is_signaling_nan( float32 ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float64_to_int32( float64 ); -int32 float64_to_int32_round_to_zero( float64 ); -int64 float64_to_int64( float64 ); -int64 float64_to_int64_round_to_zero( float64 ); -float32 float64_to_float32( float64 ); -#ifdef FLOATX80 -floatx80 float64_to_floatx80( float64 ); -#endif -#ifdef FLOAT128 -float128 float64_to_float128( float64 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -float64 float64_round_to_int( float64 ); -float64 float64_add( float64, float64 ); -float64 float64_sub( float64, float64 ); -float64 float64_mul( float64, float64 ); -float64 float64_div( float64, float64 ); -float64 float64_rem( float64, float64 ); -float64 float64_sqrt( float64 ); -flag float64_eq( float64, float64 ); -flag float64_le( float64, float64 ); -flag float64_lt( float64, float64 ); -flag float64_eq_signaling( float64, float64 ); -flag float64_le_quiet( float64, float64 ); -flag float64_lt_quiet( float64, float64 ); -flag float64_is_signaling_nan( float64 ); - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 floatx80_to_int32( floatx80 ); -int32 floatx80_to_int32_round_to_zero( floatx80 ); -int64 floatx80_to_int64( floatx80 ); -int64 floatx80_to_int64_round_to_zero( floatx80 ); -float32 floatx80_to_float32( floatx80 ); -float64 floatx80_to_float64( floatx80 ); -#ifdef FLOAT128 -float128 floatx80_to_float128( floatx80 ); -#endif -floatx80 floatx80_scale(floatx80 a, floatx80 b); - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an -| extended double-precision floating-point value, returning the result. -*----------------------------------------------------------------------------*/ - -static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) -{ - floatx80 z; - - z.low = zSig; - z.high = ( ( (bits16) zSign )<<15 ) + zExp; - return z; - -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision rounding precision. Valid -| values are 32, 64, and 80. -*----------------------------------------------------------------------------*/ -extern int8 floatx80_rounding_precision; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int( floatx80 ); -floatx80 floatx80_add( floatx80, floatx80 ); -floatx80 floatx80_sub( floatx80, floatx80 ); -floatx80 floatx80_mul( floatx80, floatx80 ); -floatx80 floatx80_div( floatx80, floatx80 ); -floatx80 floatx80_rem( floatx80, floatx80 ); -floatx80 floatx80_sqrt( floatx80 ); -flag floatx80_eq( floatx80, floatx80 ); -flag floatx80_le( floatx80, floatx80 ); -flag floatx80_lt( floatx80, floatx80 ); -flag floatx80_eq_signaling( floatx80, floatx80 ); -flag floatx80_le_quiet( floatx80, floatx80 ); -flag floatx80_lt_quiet( floatx80, floatx80 ); -flag floatx80_is_signaling_nan( floatx80 ); - -/* int floatx80_fsin(floatx80 &a); -int floatx80_fcos(floatx80 &a); -int floatx80_ftan(floatx80 &a); */ - -floatx80 floatx80_flognp1(floatx80 a); -floatx80 floatx80_flogn(floatx80 a); -floatx80 floatx80_flog2(floatx80 a); -floatx80 floatx80_flog10(floatx80 a); - -// roundAndPackFloatx80 used to be in softfloat-round-pack, is now in softfloat.c -floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1); - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float128_to_int32( float128 ); -int32 float128_to_int32_round_to_zero( float128 ); -int64 float128_to_int64( float128 ); -int64 float128_to_int64_round_to_zero( float128 ); -float32 float128_to_float32( float128 ); -float64 float128_to_float64( float128 ); -#ifdef FLOATX80 -floatx80 float128_to_floatx80( float128 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision operations. -*----------------------------------------------------------------------------*/ -float128 float128_round_to_int( float128 ); -float128 float128_add( float128, float128 ); -float128 float128_sub( float128, float128 ); -float128 float128_mul( float128, float128 ); -float128 float128_div( float128, float128 ); -float128 float128_rem( float128, float128 ); -float128 float128_sqrt( float128 ); -flag float128_eq( float128, float128 ); -flag float128_le( float128, float128 ); -flag float128_lt( float128, float128 ); -flag float128_eq_signaling( float128, float128 ); -flag float128_le_quiet( float128, float128 ); -flag float128_lt_quiet( float128, float128 ); -flag float128_is_signaling_nan( float128 ); - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', the exponent `zExp', and the significand formed -| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision -| floating-point value, returning the result. After being shifted into the -| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply -| added together to form the most significant 32 bits of the result. This -| means that any integer portion of `zSig0' will be added into the exponent. -| Since a properly normalized significand will have an integer portion equal -| to 1, the `zExp' input should be 1 less than the desired result exponent -| whenever `zSig0' and `zSig1' concatenated form a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -static inline float128 - packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) -{ - float128 z; - - z.low = zSig1; - z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and extended significand formed by the concatenation of `zSig0', `zSig1', -| and `zSig2', and returns the proper quadruple-precision floating-point value -| corresponding to the abstract input. Ordinarily, the abstract value is -| simply rounded and packed into the quadruple-precision format, with the -| inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal quadruple- -| precision floating-point number. -| The input significand must be normalized or smaller. If the input -| significand is not normalized, `zExp' must be 0; in that case, the result -| returned is a subnormal number, and it must not require rounding. In the -| usual case that the input significand is normalized, `zExp' must be 1 less -| than the ``true'' floating-point exponent. The handling of underflow and -| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static inline float128 - roundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) -{ - int8 roundingMode; - flag roundNearestEven, increment, isTiny; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) zSig2 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - if ( 0x7FFD <= (bits32) zExp ) { - if ( ( 0x7FFD < zExp ) - || ( ( zExp == 0x7FFD ) - && eq128( - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ), - zSig0, - zSig1 - ) - && increment - ) - ) { - float_raise( float_flag_overflow | float_flag_inexact ); - if ( ( roundingMode == float_round_to_zero ) - || ( zSign && ( roundingMode == float_round_up ) ) - || ( ! zSign && ( roundingMode == float_round_down ) ) - ) { - return - packFloat128( - zSign, - 0x7FFE, - LIT64( 0x0000FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( zExp < 0 ) { - isTiny = - ( float_detect_tininess == float_tininess_before_rounding ) - || ( zExp < -1 ) - || ! increment - || lt128( - zSig0, - zSig1, - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); - zExp = 0; - if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); - if ( roundNearestEven ) { - increment = ( (sbits64) zSig2 < 0 ); - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - } - if ( zSig2 ) float_exception_flags |= float_flag_inexact; - if ( increment ) { - add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); - zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); - } - else { - if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; - } - return packFloat128( zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand formed by the concatenation of `zSig0' and `zSig1', and -| returns the proper quadruple-precision floating-point value corresponding -| to the abstract input. This routine is just like `roundAndPackFloat128' -| except that the input significand has fewer bits and does not have to be -| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- -| point exponent. -*----------------------------------------------------------------------------*/ - -static inline float128 - normalizeRoundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) -{ - int8 shiftCount; - bits64 zSig2; - - if ( zSig0 == 0 ) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - shiftCount = countLeadingZeros64( zSig0 ) - 15; - if ( 0 <= shiftCount ) { - zSig2 = 0; - shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); - } - zExp -= shiftCount; - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} -#endif + +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| The macro `FLOATX80' must be defined to enable the extended double-precision +| floating-point format `floatx80'. If this macro is not defined, the +| `floatx80' type will not be defined, and none of the functions that either +| input or output the `floatx80' type will be defined. The same applies to +| the `FLOAT128' macro and the quadruple-precision format `float128'. +*----------------------------------------------------------------------------*/ +#define FLOATX80 +#define FLOAT128 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point types. +*----------------------------------------------------------------------------*/ +typedef bits32 float32; +typedef bits64 float64; +#ifdef FLOATX80 +typedef struct { + bits16 high; + bits64 low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + bits64 high, low; +} float128; +#endif + +/*---------------------------------------------------------------------------- +| Primitive arithmetic functions, including multi-word arithmetic, and +| division and square root approximations. (Can be specialized to target if +| desired.) +*----------------------------------------------------------------------------*/ +#include "softfloat-macros" + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point underflow tininess-detection mode. +*----------------------------------------------------------------------------*/ +extern int8 float_detect_tininess; +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point rounding mode. +*----------------------------------------------------------------------------*/ +extern int8 float_rounding_mode; +enum { + float_round_nearest_even = 0, + float_round_to_zero = 1, + float_round_down = 2, + float_round_up = 3 +}; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point exception flags. +*----------------------------------------------------------------------------*/ +extern int8 float_exception_flags; +enum { + float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, + float_flag_underflow = 0x10, float_flag_inexact = 0x20 +}; + +/*---------------------------------------------------------------------------- +| Routine to raise any or all of the software IEC/IEEE floating-point +| exception flags. +*----------------------------------------------------------------------------*/ +void float_raise( int8 ); + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE integer-to-floating-point conversion routines. +*----------------------------------------------------------------------------*/ +float32 int32_to_float32( int32 ); +float64 int32_to_float64( int32 ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int32 ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int32 ); +#endif +float32 int64_to_float32( int64 ); +float64 int64_to_float64( int64 ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( int64 ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( int64 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE single-precision conversion routines. +*----------------------------------------------------------------------------*/ +int32 float32_to_int32( float32 ); +int32 float32_to_int32_round_to_zero( float32 ); +int64 float32_to_int64( float32 ); +int64 float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE single-precision operations. +*----------------------------------------------------------------------------*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +flag float32_eq( float32, float32 ); +flag float32_le( float32, float32 ); +flag float32_lt( float32, float32 ); +flag float32_eq_signaling( float32, float32 ); +flag float32_le_quiet( float32, float32 ); +flag float32_lt_quiet( float32, float32 ); +flag float32_is_signaling_nan( float32 ); + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE double-precision conversion routines. +*----------------------------------------------------------------------------*/ +int32 float64_to_int32( float64 ); +int32 float64_to_int32_round_to_zero( float64 ); +int64 float64_to_int64( float64 ); +int64 float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE double-precision operations. +*----------------------------------------------------------------------------*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +flag float64_eq( float64, float64 ); +flag float64_le( float64, float64 ); +flag float64_lt( float64, float64 ); +flag float64_eq_signaling( float64, float64 ); +flag float64_le_quiet( float64, float64 ); +flag float64_lt_quiet( float64, float64 ); +flag float64_is_signaling_nan( float64 ); + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision conversion routines. +*----------------------------------------------------------------------------*/ +int32 floatx80_to_int32( floatx80 ); +int32 floatx80_to_int32_round_to_zero( floatx80 ); +int64 floatx80_to_int64( floatx80 ); +int64 floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif +floatx80 floatx80_scale(floatx80 a, floatx80 b); + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an +| extended double-precision floating-point value, returning the result. +*----------------------------------------------------------------------------*/ + +static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) +{ + floatx80 z; + + z.low = zSig; + z.high = ( ( (bits16) zSign )<<15 ) + zExp; + return z; + +} + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision rounding precision. Valid +| values are 32, 64, and 80. +*----------------------------------------------------------------------------*/ +extern int8 floatx80_rounding_precision; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE extended double-precision operations. +*----------------------------------------------------------------------------*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +flag floatx80_eq( floatx80, floatx80 ); +flag floatx80_le( floatx80, floatx80 ); +flag floatx80_lt( floatx80, floatx80 ); +flag floatx80_eq_signaling( floatx80, floatx80 ); +flag floatx80_le_quiet( floatx80, floatx80 ); +flag floatx80_lt_quiet( floatx80, floatx80 ); +flag floatx80_is_signaling_nan( floatx80 ); + +/* int floatx80_fsin(floatx80 &a); +int floatx80_fcos(floatx80 &a); +int floatx80_ftan(floatx80 &a); */ + +floatx80 floatx80_flognp1(floatx80 a); +floatx80 floatx80_flogn(floatx80 a); +floatx80 floatx80_flog2(floatx80 a); +floatx80 floatx80_flog10(floatx80 a); + +// roundAndPackFloatx80 used to be in softfloat-round-pack, is now in softfloat.c +floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1); + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE quadruple-precision conversion routines. +*----------------------------------------------------------------------------*/ +int32 float128_to_int32( float128 ); +int32 float128_to_int32_round_to_zero( float128 ); +int64 float128_to_int64( float128 ); +int64 float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE quadruple-precision operations. +*----------------------------------------------------------------------------*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +flag float128_eq( float128, float128 ); +flag float128_le( float128, float128 ); +flag float128_lt( float128, float128 ); +flag float128_eq_signaling( float128, float128 ); +flag float128_le_quiet( float128, float128 ); +flag float128_lt_quiet( float128, float128 ); +flag float128_is_signaling_nan( float128 ); + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', the exponent `zExp', and the significand formed +| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision +| floating-point value, returning the result. After being shifted into the +| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply +| added together to form the most significant 32 bits of the result. This +| means that any integer portion of `zSig0' will be added into the exponent. +| Since a properly normalized significand will have an integer portion equal +| to 1, the `zExp' input should be 1 less than the desired result exponent +| whenever `zSig0' and `zSig1' concatenated form a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +static inline float128 + packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) +{ + float128 z; + + z.low = zSig1; + z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and extended significand formed by the concatenation of `zSig0', `zSig1', +| and `zSig2', and returns the proper quadruple-precision floating-point value +| corresponding to the abstract input. Ordinarily, the abstract value is +| simply rounded and packed into the quadruple-precision format, with the +| inexact exception raised if the abstract input cannot be represented +| exactly. However, if the abstract value is too large, the overflow and +| inexact exceptions are raised and an infinity or maximal finite value is +| returned. If the abstract value is too small, the input value is rounded to +| a subnormal number, and the underflow and inexact exceptions are raised if +| the abstract input cannot be represented exactly as a subnormal quadruple- +| precision floating-point number. +| The input significand must be normalized or smaller. If the input +| significand is not normalized, `zExp' must be 0; in that case, the result +| returned is a subnormal number, and it must not require rounding. In the +| usual case that the input significand is normalized, `zExp' must be 1 less +| than the ``true'' floating-point exponent. The handling of underflow and +| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static inline float128 + roundAndPackFloat128( + flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) +{ + int8 roundingMode; + flag roundNearestEven, increment, isTiny; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) zSig2 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + if ( 0x7FFD <= (bits32) zExp ) { + if ( ( 0x7FFD < zExp ) + || ( ( zExp == 0x7FFD ) + && eq128( + LIT64( 0x0001FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ), + zSig0, + zSig1 + ) + && increment + ) + ) { + float_raise( float_flag_overflow | float_flag_inexact ); + if ( ( roundingMode == float_round_to_zero ) + || ( zSign && ( roundingMode == float_round_up ) ) + || ( ! zSign && ( roundingMode == float_round_down ) ) + ) { + return + packFloat128( + zSign, + 0x7FFE, + LIT64( 0x0000FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ) + ); + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ! increment + || lt128( + zSig0, + zSig1, + LIT64( 0x0001FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ) + ); + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); + zExp = 0; + if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); + if ( roundNearestEven ) { + increment = ( (sbits64) zSig2 < 0 ); + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + } + if ( zSig2 ) float_exception_flags |= float_flag_inexact; + if ( increment ) { + add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); + zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); + } + else { + if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; + } + return packFloat128( zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand formed by the concatenation of `zSig0' and `zSig1', and +| returns the proper quadruple-precision floating-point value corresponding +| to the abstract input. This routine is just like `roundAndPackFloat128' +| except that the input significand has fewer bits and does not have to be +| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- +| point exponent. +*----------------------------------------------------------------------------*/ + +static inline float128 + normalizeRoundAndPackFloat128( + flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) +{ + int8 shiftCount; + bits64 zSig2; + + if ( zSig0 == 0 ) { + zSig0 = zSig1; + zSig1 = 0; + zExp -= 64; + } + shiftCount = countLeadingZeros64( zSig0 ) - 15; + if ( 0 <= shiftCount ) { + zSig2 = 0; + shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); + } + else { + shift128ExtraRightJamming( + zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); + } + zExp -= shiftCount; + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} +#endif diff --git a/AltairZ80/m68k/m68k.h b/AltairZ80/m68k/m68k.h index 8654287a..d28a2893 100755 --- a/AltairZ80/m68k/m68k.h +++ b/AltairZ80/m68k/m68k.h @@ -93,62 +93,62 @@ extern "C" { /* CPU types for use in m68k_set_cpu_type() */ enum { - M68K_CPU_TYPE_INVALID, - M68K_CPU_TYPE_68000, - M68K_CPU_TYPE_68010, - M68K_CPU_TYPE_68EC020, - M68K_CPU_TYPE_68020, - M68K_CPU_TYPE_68EC030, - M68K_CPU_TYPE_68030, - M68K_CPU_TYPE_68EC040, - M68K_CPU_TYPE_68LC040, - M68K_CPU_TYPE_68040, - M68K_CPU_TYPE_SCC68070 + M68K_CPU_TYPE_INVALID, + M68K_CPU_TYPE_68000, + M68K_CPU_TYPE_68010, + M68K_CPU_TYPE_68EC020, + M68K_CPU_TYPE_68020, + M68K_CPU_TYPE_68EC030, + M68K_CPU_TYPE_68030, + M68K_CPU_TYPE_68EC040, + M68K_CPU_TYPE_68LC040, + M68K_CPU_TYPE_68040, + M68K_CPU_TYPE_SCC68070 }; /* Registers used by m68k_get_reg() and m68k_set_reg() */ typedef enum { - /* Real registers */ - M68K_REG_D0, /* Data registers */ - M68K_REG_D1, - M68K_REG_D2, - M68K_REG_D3, - M68K_REG_D4, - M68K_REG_D5, - M68K_REG_D6, - M68K_REG_D7, - M68K_REG_A0, /* Address registers */ - M68K_REG_A1, - M68K_REG_A2, - M68K_REG_A3, - M68K_REG_A4, - M68K_REG_A5, - M68K_REG_A6, - M68K_REG_A7, - M68K_REG_PC, /* Program Counter */ - M68K_REG_SR, /* Status Register */ - M68K_REG_SP, /* The current Stack Pointer (located in A7) */ - M68K_REG_USP, /* User Stack Pointer */ - M68K_REG_ISP, /* Interrupt Stack Pointer */ - M68K_REG_MSP, /* Master Stack Pointer */ - M68K_REG_SFC, /* Source Function Code */ - M68K_REG_DFC, /* Destination Function Code */ - M68K_REG_VBR, /* Vector Base Register */ - M68K_REG_CACR, /* Cache Control Register */ - M68K_REG_CAAR, /* Cache Address Register */ + /* Real registers */ + M68K_REG_D0, /* Data registers */ + M68K_REG_D1, + M68K_REG_D2, + M68K_REG_D3, + M68K_REG_D4, + M68K_REG_D5, + M68K_REG_D6, + M68K_REG_D7, + M68K_REG_A0, /* Address registers */ + M68K_REG_A1, + M68K_REG_A2, + M68K_REG_A3, + M68K_REG_A4, + M68K_REG_A5, + M68K_REG_A6, + M68K_REG_A7, + M68K_REG_PC, /* Program Counter */ + M68K_REG_SR, /* Status Register */ + M68K_REG_SP, /* The current Stack Pointer (located in A7) */ + M68K_REG_USP, /* User Stack Pointer */ + M68K_REG_ISP, /* Interrupt Stack Pointer */ + M68K_REG_MSP, /* Master Stack Pointer */ + M68K_REG_SFC, /* Source Function Code */ + M68K_REG_DFC, /* Destination Function Code */ + M68K_REG_VBR, /* Vector Base Register */ + M68K_REG_CACR, /* Cache Control Register */ + M68K_REG_CAAR, /* Cache Address Register */ - /* Assumed registers */ - /* These are cheat registers which emulate the 1-longword prefetch - * present in the 68000 and 68010. - */ - M68K_REG_PREF_ADDR, /* Last prefetch address */ - M68K_REG_PREF_DATA, /* Last prefetch data */ + /* Assumed registers */ + /* These are cheat registers which emulate the 1-longword prefetch + * present in the 68000 and 68010. + */ + M68K_REG_PREF_ADDR, /* Last prefetch address */ + M68K_REG_PREF_DATA, /* Last prefetch data */ - /* Convenience registers */ - M68K_REG_PPC, /* Previous value in the program counter */ - M68K_REG_IR, /* Instruction register */ - M68K_REG_CPU_TYPE /* Type of CPU being run */ + /* Convenience registers */ + M68K_REG_PPC, /* Previous value in the program counter */ + M68K_REG_IR, /* Instruction register */ + M68K_REG_CPU_TYPE /* Type of CPU being run */ } m68k_register_t; /* ======================================================================== */ diff --git a/AltairZ80/m68k/m68k_in.c b/AltairZ80/m68k/m68k_in.c index e5811b3b..53bfb72e 100644 --- a/AltairZ80/m68k/m68k_in.c +++ b/AltairZ80/m68k/m68k_in.c @@ -1,10653 +1,10653 @@ -/* -must fix: - callm - chk -*/ -/* ======================================================================== */ -/* ========================= LICENSING & COPYRIGHT ======================== */ -/* ======================================================================== */ -/* - * MUSASHI - * Version 3.32 - * - * A portable Motorola M680x0 processor emulation engine. - * Copyright Karl Stenerud. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* Special thanks to Bart Trzynadlowski for his insight into the - * undocumented features of this chip: - * - * http://dynarec.com/~bart/files/68knotes.txt - */ - - -/* Input file for m68kmake - * ----------------------- - * - * All sections begin with 80 X's in a row followed by an end-of-line - * sequence. - * After this, m68kmake will expect to find one of the following section - * identifiers: - * M68KMAKE_PROTOTYPE_HEADER - header for opcode handler prototypes - * M68KMAKE_PROTOTYPE_FOOTER - footer for opcode handler prototypes - * M68KMAKE_TABLE_HEADER - header for opcode handler jumptable - * M68KMAKE_TABLE_FOOTER - footer for opcode handler jumptable - * M68KMAKE_TABLE_BODY - the table itself - * M68KMAKE_OPCODE_HANDLER_HEADER - header for opcode handler implementation - * M68KMAKE_OPCODE_HANDLER_FOOTER - footer for opcode handler implementation - * M68KMAKE_OPCODE_HANDLER_BODY - body section for opcode handler implementation - * - * NOTE: M68KMAKE_OPCODE_HANDLER_BODY must be last in the file and - * M68KMAKE_TABLE_BODY must be second last in the file. - * - * The M68KMAKE_OPHANDLER_BODY section contains the opcode handler - * primitives themselves. Each opcode handler begins with: - * M68KMAKE_OP(A, B, C, D) - * - * where A is the opcode handler name, B is the size of the operation, - * C denotes any special processing mode, and D denotes a specific - * addressing mode. - * For C and D where nothing is specified, use "." - * - * Example: - * M68KMAKE_OP(abcd, 8, rr, .) abcd, size 8, register to register, default EA - * M68KMAKE_OP(abcd, 8, mm, ax7) abcd, size 8, memory to memory, register X is A7 - * M68KMAKE_OP(tst, 16, ., pcix) tst, size 16, PCIX addressing - * - * All opcode handler primitives end with a closing curly brace "}" at column 1 - * - * NOTE: Do not place a M68KMAKE_OP() directive inside the opcode handler, - * and do not put a closing curly brace at column 1 unless it is - * marking the end of the handler! - * - * Inside the handler, m68kmake will recognize M68KMAKE_GET_OPER_xx_xx, - * M68KMAKE_GET_EA_xx_xx, and M68KMAKE_CC directives, and create multiple - * opcode handlers to handle variations in the opcode handler. - * Note: M68KMAKE_CC will only be interpreted in condition code opcodes. - * As well, M68KMAKE_GET_EA_xx_xx and M68KMAKE_GET_OPER_xx_xx will only - * be interpreted on instructions where the corresponding table entry - * specifies multiple effective addressing modes. - * Example: - * clr 32 . . 0100001010...... A+-DXWL... U U U 12 6 4 - * - * This table entry says that the clr.l opcde has 7 variations (A+-DXWL). - * It is run in user or supervisor mode for all CPUs, and uses 12 cycles for - * 68000, 6 cycles for 68010, and 4 cycles for 68020. - */ - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_PROTOTYPE_HEADER - -#ifndef M68KOPS__HEADER -#define M68KOPS__HEADER - -/* ======================================================================== */ -/* ============================ OPCODE HANDLERS =========================== */ -/* ======================================================================== */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_PROTOTYPE_FOOTER - - -/* Build the opcode handler table */ -void m68ki_build_opcode_table(void); - -extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ -extern unsigned char m68ki_cycles[][0x10000]; - - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ - -#endif /* M68KOPS__HEADER */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_TABLE_HEADER - -/* ======================================================================== */ -/* ========================= OPCODE TABLE BUILDER ========================= */ -/* ======================================================================== */ - -#include -#include "m68kops.h" - -#define NUM_CPU_TYPES 5 - -void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ -unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */ - -/* This is used to generate the opcode handler jump table */ -typedef struct -{ - void (*opcode_handler)(void); /* handler function */ - unsigned int mask; /* mask on opcode */ - unsigned int match; /* what to match after masking */ - unsigned char cycles[NUM_CPU_TYPES]; /* cycles each cpu type takes */ -} opcode_handler_struct; - - -/* Opcode handler table */ -static const opcode_handler_struct m68k_opcode_handler_table[] = -{ -/* function mask match 000 010 020 040 */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_TABLE_FOOTER - - {0, 0, 0, {0, 0, 0, 0, 0}} -}; - - -/* Build the opcode handler jump table */ -void m68ki_build_opcode_table(void) -{ - const opcode_handler_struct *ostruct; - int cycle_cost; - int instr; - int i; - int j; - int k; - - for(i = 0; i < 0x10000; i++) - { - /* default to illegal */ - m68ki_instruction_jump_table[i] = m68k_op_illegal; - for(k=0;kmask != 0xff00) - { - for(i = 0;i < 0x10000;i++) - { - if((i & ostruct->mask) == ostruct->match) - { - m68ki_instruction_jump_table[i] = ostruct->opcode_handler; - for(k=0;kcycles[k]; - } - } - ostruct++; - } - while(ostruct->mask == 0xff00) - { - for(i = 0;i <= 0xff;i++) - { - m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; - for(k=0;kmatch | i] = ostruct->cycles[k]; - } - ostruct++; - } - while(ostruct->mask == 0xf1f8) - { - for(i = 0;i < 8;i++) - { - for(j = 0;j < 8;j++) - { - instr = ostruct->match | (i << 9) | j; - m68ki_instruction_jump_table[instr] = ostruct->opcode_handler; - for(k=0;kcycles[k]; - // For all shift operations with known shift distance (encoded in instruction word) - if((instr & 0xf000) == 0xe000 && (!(instr & 0x20))) - { - // On the 68000 and 68010 shift distance affect execution time. - // Add the cycle cost of shifting; 2 times the shift distance - cycle_cost = ((((i-1)&7)+1)<<1); - m68ki_cycles[0][instr] += cycle_cost; - m68ki_cycles[1][instr] += cycle_cost; - // On the 68020 shift distance does not affect execution time - m68ki_cycles[2][instr] += 0; - } - } - } - ostruct++; - } - while(ostruct->mask == 0xfff0) - { - for(i = 0;i <= 0x0f;i++) - { - m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; - for(k=0;kmatch | i] = ostruct->cycles[k]; - } - ostruct++; - } - while(ostruct->mask == 0xf1ff) - { - for(i = 0;i <= 0x07;i++) - { - m68ki_instruction_jump_table[ostruct->match | (i << 9)] = ostruct->opcode_handler; - for(k=0;kmatch | (i << 9)] = ostruct->cycles[k]; - } - ostruct++; - } - while(ostruct->mask == 0xfff8) - { - for(i = 0;i <= 0x07;i++) - { - m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; - for(k=0;kmatch | i] = ostruct->cycles[k]; - } - ostruct++; - } - while(ostruct->mask == 0xffff) - { - m68ki_instruction_jump_table[ostruct->match] = ostruct->opcode_handler; - for(k=0;kmatch] = ostruct->cycles[k]; - ostruct++; - } -} - - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_OPCODE_HANDLER_HEADER - -#include -#include "m68kcpu.h" -extern void m68040_fpu_op0(void); -extern void m68040_fpu_op1(void); -extern void m68881_mmu_ops(void); - -/* ======================================================================== */ -/* ========================= INSTRUCTION HANDLERS ========================= */ -/* ======================================================================== */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_OPCODE_HANDLER_FOOTER - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_TABLE_BODY - -The following table is arranged as follows: - -name: Opcode mnemonic - -size: Operation size - -spec proc: Special processing mode: - .: normal - s: static operand - r: register operand - rr: register to register - mm: memory to memory - er: effective address to register - re: register to effective address - dd: data register to data register - da: data register to address register - aa: address register to address register - cr: control register to register - rc: register to control register - toc: to condition code register - tos: to status register - tou: to user stack pointer - frc: from condition code register - frs: from status register - fru: from user stack pointer - * for move.x, the special processing mode is a specific - destination effective addressing mode. - -spec ea: Specific effective addressing mode: - .: normal - i: immediate - d: data register - a: address register - ai: address register indirect - pi: address register indirect with postincrement - pd: address register indirect with predecrement - di: address register indirect with displacement - ix: address register indirect with index - aw: absolute word address - al: absolute long address - pcdi: program counter relative with displacement - pcix: program counter relative with index - a7: register specified in instruction is A7 - ax7: register field X of instruction is A7 - ay7: register field Y of instruction is A7 - axy7: register fields X and Y of instruction are A7 - -bit pattern: Pattern to recognize this opcode. "." means don't care. - -allowed ea: List of allowed addressing modes: - .: not present - A: address register indirect - +: ARI (address register indirect) with postincrement - -: ARI with predecrement - D: ARI with displacement - X: ARI with index - W: absolute word address - L: absolute long address - d: program counter indirect with displacement - x: program counter indirect with index - I: immediate -mode: CPU operating mode for each cpu type. U = user or supervisor, - S = supervisor only, "." = opcode not present. - -cpu cycles: Base number of cycles required to execute this opcode on the - specified CPU type. - Use "." if CPU does not have this opcode. - - - - spec spec allowed ea mode cpu cycles -name size proc ea bit pattern A+-DXWLdxI 0 1 2 3 4 000 010 020 030 040 comments -====== ==== ==== ==== ================ ========== = = = = = === === === === === ============= -M68KMAKE_TABLE_START -1010 0 . . 1010............ .......... U U U U U 4 4 4 4 4 -1111 0 . . 1111............ .......... U U U U U 4 4 4 4 4 -040fpu0 32 . . 11110010........ .......... . . . . U . . . . 0 -040fpu1 32 . . 11110011........ .......... . . . . U . . . . 0 -abcd 8 rr . 1100...100000... .......... U U U U U 6 6 4 4 4 -abcd 8 mm ax7 1100111100001... .......... U U U U U 18 18 16 16 16 -abcd 8 mm ay7 1100...100001111 .......... U U U U U 18 18 16 16 16 -abcd 8 mm axy7 1100111100001111 .......... U U U U U 18 18 16 16 16 -abcd 8 mm . 1100...100001... .......... U U U U U 18 18 16 16 16 -add 8 er d 1101...000000... .......... U U U U U 4 4 2 2 2 -add 8 er . 1101...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -add 16 er d 1101...001000... .......... U U U U U 4 4 2 2 2 -add 16 er a 1101...001001... .......... U U U U U 4 4 2 2 2 -add 16 er . 1101...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -add 32 er d 1101...010000... .......... U U U U U 6 6 2 2 2 -add 32 er a 1101...010001... .......... U U U U U 6 6 2 2 2 -add 32 er . 1101...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 -add 8 re . 1101...100...... A+-DXWL... U U U U U 8 8 4 4 4 -add 16 re . 1101...101...... A+-DXWL... U U U U U 8 8 4 4 4 -add 32 re . 1101...110...... A+-DXWL... U U U U U 12 12 4 4 4 -adda 16 . d 1101...011000... .......... U U U U U 8 8 2 2 2 -adda 16 . a 1101...011001... .......... U U U U U 8 8 2 2 2 -adda 16 . . 1101...011...... A+-DXWLdxI U U U U U 8 8 2 2 2 -adda 32 . d 1101...111000... .......... U U U U U 6 6 2 2 2 -adda 32 . a 1101...111001... .......... U U U U U 6 6 2 2 2 -adda 32 . . 1101...111...... A+-DXWLdxI U U U U U 6 6 2 2 2 -addi 8 . d 0000011000000... .......... U U U U U 8 8 2 2 2 -addi 8 . . 0000011000...... A+-DXWL... U U U U U 12 12 4 4 4 -addi 16 . d 0000011001000... .......... U U U U U 8 8 2 2 2 -addi 16 . . 0000011001...... A+-DXWL... U U U U U 12 12 4 4 4 -addi 32 . d 0000011010000... .......... U U U U U 16 14 2 2 2 -addi 32 . . 0000011010...... A+-DXWL... U U U U U 20 20 4 4 4 -addq 8 . d 0101...000000... .......... U U U U U 4 4 2 2 2 -addq 8 . . 0101...000...... A+-DXWL... U U U U U 8 8 4 4 4 -addq 16 . d 0101...001000... .......... U U U U U 4 4 2 2 2 -addq 16 . a 0101...001001... .......... U U U U U 4 4 2 2 2 -addq 16 . . 0101...001...... A+-DXWL... U U U U U 8 8 4 4 4 -addq 32 . d 0101...010000... .......... U U U U U 8 8 2 2 2 -addq 32 . a 0101...010001... .......... U U U U U 8 8 2 2 2 -addq 32 . . 0101...010...... A+-DXWL... U U U U U 12 12 4 4 4 -addx 8 rr . 1101...100000... .......... U U U U U 4 4 2 2 2 -addx 16 rr . 1101...101000... .......... U U U U U 4 4 2 2 2 -addx 32 rr . 1101...110000... .......... U U U U U 8 6 2 2 2 -addx 8 mm ax7 1101111100001... .......... U U U U U 18 18 12 12 12 -addx 8 mm ay7 1101...100001111 .......... U U U U U 18 18 12 12 12 -addx 8 mm axy7 1101111100001111 .......... U U U U U 18 18 12 12 12 -addx 8 mm . 1101...100001... .......... U U U U U 18 18 12 12 12 -addx 16 mm . 1101...101001... .......... U U U U U 18 18 12 12 12 -addx 32 mm . 1101...110001... .......... U U U U U 30 30 12 12 12 -and 8 er d 1100...000000... .......... U U U U U 4 4 2 2 2 -and 8 er . 1100...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -and 16 er d 1100...001000... .......... U U U U U 4 4 2 2 2 -and 16 er . 1100...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -and 32 er d 1100...010000... .......... U U U U U 6 6 2 2 2 -and 32 er . 1100...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 -and 8 re . 1100...100...... A+-DXWL... U U U U U 8 8 4 4 4 -and 16 re . 1100...101...... A+-DXWL... U U U U U 8 8 4 4 4 -and 32 re . 1100...110...... A+-DXWL... U U U U U 12 12 4 4 4 -andi 16 toc . 0000001000111100 .......... U U U U U 20 16 12 12 12 -andi 16 tos . 0000001001111100 .......... S S S S S 20 16 12 12 12 -andi 8 . d 0000001000000... .......... U U U U U 8 8 2 2 2 -andi 8 . . 0000001000...... A+-DXWL... U U U U U 12 12 4 4 4 -andi 16 . d 0000001001000... .......... U U U U U 8 8 2 2 2 -andi 16 . . 0000001001...... A+-DXWL... U U U U U 12 12 4 4 4 -andi 32 . d 0000001010000... .......... U U U U U 14 14 2 2 2 -andi 32 . . 0000001010...... A+-DXWL... U U U U U 20 20 4 4 4 -asr 8 s . 1110...000000... .......... U U U U U 6 6 6 6 6 -asr 16 s . 1110...001000... .......... U U U U U 6 6 6 6 6 -asr 32 s . 1110...010000... .......... U U U U U 8 8 6 6 6 -asr 8 r . 1110...000100... .......... U U U U U 6 6 6 6 6 -asr 16 r . 1110...001100... .......... U U U U U 6 6 6 6 6 -asr 32 r . 1110...010100... .......... U U U U U 8 8 6 6 6 -asr 16 . . 1110000011...... A+-DXWL... U U U U U 8 8 5 5 5 -asl 8 s . 1110...100000... .......... U U U U U 6 6 8 8 8 -asl 16 s . 1110...101000... .......... U U U U U 6 6 8 8 8 -asl 32 s . 1110...110000... .......... U U U U U 8 8 8 8 8 -asl 8 r . 1110...100100... .......... U U U U U 6 6 8 8 8 -asl 16 r . 1110...101100... .......... U U U U U 6 6 8 8 8 -asl 32 r . 1110...110100... .......... U U U U U 8 8 8 8 8 -asl 16 . . 1110000111...... A+-DXWL... U U U U U 8 8 6 6 6 -bcc 8 . . 0110............ .......... U U U U U 10 10 6 6 6 -bcc 16 . . 0110....00000000 .......... U U U U U 10 10 6 6 6 -bcc 32 . . 0110....11111111 .......... U U U U U 10 10 6 6 6 -bchg 8 r . 0000...101...... A+-DXWL... U U U U U 8 8 4 4 4 -bchg 32 r d 0000...101000... .......... U U U U U 8 8 4 4 4 -bchg 8 s . 0000100001...... A+-DXWL... U U U U U 12 12 4 4 4 -bchg 32 s d 0000100001000... .......... U U U U U 12 12 4 4 4 -bclr 8 r . 0000...110...... A+-DXWL... U U U U U 8 10 4 4 4 -bclr 32 r d 0000...110000... .......... U U U U U 10 10 4 4 4 -bclr 8 s . 0000100010...... A+-DXWL... U U U U U 12 12 4 4 4 -bclr 32 s d 0000100010000... .......... U U U U U 14 14 4 4 4 -bfchg 32 . d 1110101011000... .......... . . U U U . . 12 12 12 timing not quite correct -bfchg 32 . . 1110101011...... A..DXWL... . . U U U . . 20 20 20 -bfclr 32 . d 1110110011000... .......... . . U U U . . 12 12 12 -bfclr 32 . . 1110110011...... A..DXWL... . . U U U . . 20 20 20 -bfexts 32 . d 1110101111000... .......... . . U U U . . 8 8 8 -bfexts 32 . . 1110101111...... A..DXWLdx. . . U U U . . 15 15 15 -bfextu 32 . d 1110100111000... .......... . . U U U . . 8 8 8 -bfextu 32 . . 1110100111...... A..DXWLdx. . . U U U . . 15 15 15 -bfffo 32 . d 1110110111000... .......... . . U U U . . 18 18 18 -bfffo 32 . . 1110110111...... A..DXWLdx. . . U U U . . 28 28 28 -bfins 32 . d 1110111111000... .......... . . U U U . . 10 10 10 -bfins 32 . . 1110111111...... A..DXWL... . . U U U . . 17 17 17 -bfset 32 . d 1110111011000... .......... . . U U U . . 12 12 12 -bfset 32 . . 1110111011...... A..DXWL... . . U U U . . 20 20 20 -bftst 32 . d 1110100011000... .......... . . U U U . . 6 6 6 -bftst 32 . . 1110100011...... A..DXWLdx. . . U U U . . 13 13 13 -bkpt 0 . . 0100100001001... .......... . U U U U . 10 10 10 10 -bra 8 . . 01100000........ .......... U U U U U 10 10 10 10 10 -bra 16 . . 0110000000000000 .......... U U U U U 10 10 10 10 10 -bra 32 . . 0110000011111111 .......... U U U U U 10 10 10 10 10 -bset 32 r d 0000...111000... .......... U U U U U 8 8 4 4 4 -bset 8 r . 0000...111...... A+-DXWL... U U U U U 8 8 4 4 4 -bset 8 s . 0000100011...... A+-DXWL... U U U U U 12 12 4 4 4 -bset 32 s d 0000100011000... .......... U U U U U 12 12 4 4 4 -bsr 8 . . 01100001........ .......... U U U U U 18 18 7 7 7 -bsr 16 . . 0110000100000000 .......... U U U U U 18 18 7 7 7 -bsr 32 . . 0110000111111111 .......... U U U U U 18 18 7 7 7 -btst 8 r . 0000...100...... A+-DXWLdxI U U U U U 4 4 4 4 4 -btst 32 r d 0000...100000... .......... U U U U U 6 6 4 4 4 -btst 8 s . 0000100000...... A+-DXWLdx. U U U U U 8 8 4 4 4 -btst 32 s d 0000100000000... .......... U U U U U 10 10 4 4 4 -callm 32 . . 0000011011...... A..DXWLdx. . . U U U . . 60 60 60 not properly emulated -cas 8 . . 0000101011...... A+-DXWL... . . U U U . . 12 12 12 -cas 16 . . 0000110011...... A+-DXWL... . . U U U . . 12 12 12 -cas 32 . . 0000111011...... A+-DXWL... . . U U U . . 12 12 12 -cas2 16 . . 0000110011111100 .......... . . U U U . . 12 12 12 -cas2 32 . . 0000111011111100 .......... . . U U U . . 12 12 12 -chk 16 . d 0100...110000... .......... U U U U U 10 8 8 8 8 -chk 16 . . 0100...110...... A+-DXWLdxI U U U U U 10 8 8 8 8 -chk 32 . d 0100...100000... .......... . . U U U . . 8 8 8 -chk 32 . . 0100...100...... A+-DXWLdxI . . U U U . . 8 8 8 -chk2cmp2 8 . pcdi 0000000011111010 .......... . . U U U . . 23 23 23 -chk2cmp2 8 . pcix 0000000011111011 .......... . . U U U . . 23 23 23 -chk2cmp2 8 . . 0000000011...... A..DXWL... . . U U U . . 18 18 18 -chk2cmp2 16 . pcdi 0000001011111010 .......... . . U U U . . 23 23 23 -chk2cmp2 16 . pcix 0000001011111011 .......... . . U U U . . 23 23 23 -chk2cmp2 16 . . 0000001011...... A..DXWL... . . U U U . . 18 18 18 -chk2cmp2 32 . pcdi 0000010011111010 .......... . . U U U . . 23 23 23 -chk2cmp2 32 . pcix 0000010011111011 .......... . . U U U . . 23 23 23 -chk2cmp2 32 . . 0000010011...... A..DXWL... . . U U U . . 18 18 18 -clr 8 . d 0100001000000... .......... U U U U U 4 4 2 2 2 -clr 8 . . 0100001000...... A+-DXWL... U U U U U 8 4 4 4 4 -clr 16 . d 0100001001000... .......... U U U U U 4 4 2 2 2 -clr 16 . . 0100001001...... A+-DXWL... U U U U U 8 4 4 4 4 -clr 32 . d 0100001010000... .......... U U U U U 6 6 2 2 2 -clr 32 . . 0100001010...... A+-DXWL... U U U U U 12 6 4 4 4 -cmp 8 . d 1011...000000... .......... U U U U U 4 4 2 2 2 -cmp 8 . . 1011...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -cmp 16 . d 1011...001000... .......... U U U U U 4 4 2 2 2 -cmp 16 . a 1011...001001... .......... U U U U U 4 4 2 2 2 -cmp 16 . . 1011...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -cmp 32 . d 1011...010000... .......... U U U U U 6 6 2 2 2 -cmp 32 . a 1011...010001... .......... U U U U U 6 6 2 2 2 -cmp 32 . . 1011...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 -cmpa 16 . d 1011...011000... .......... U U U U U 6 6 4 4 4 -cmpa 16 . a 1011...011001... .......... U U U U U 6 6 4 4 4 -cmpa 16 . . 1011...011...... A+-DXWLdxI U U U U U 6 6 4 4 4 -cmpa 32 . d 1011...111000... .......... U U U U U 6 6 4 4 4 -cmpa 32 . a 1011...111001... .......... U U U U U 6 6 4 4 4 -cmpa 32 . . 1011...111...... A+-DXWLdxI U U U U U 6 6 4 4 4 -cmpi 8 . d 0000110000000... .......... U U U U U 8 8 2 2 2 -cmpi 8 . . 0000110000...... A+-DXWL... U U U U U 8 8 2 2 2 -cmpi 8 . pcdi 0000110000111010 .......... . . U U U . . 7 7 7 -cmpi 8 . pcix 0000110000111011 .......... . . U U U . . 9 9 9 -cmpi 16 . d 0000110001000... .......... U U U U U 8 8 2 2 2 -cmpi 16 . . 0000110001...... A+-DXWL... U U U U U 8 8 2 2 2 -cmpi 16 . pcdi 0000110001111010 .......... . . U U U . . 7 7 7 -cmpi 16 . pcix 0000110001111011 .......... . . U U U . . 9 9 9 -cmpi 32 . d 0000110010000... .......... U U U U U 14 12 2 2 2 -cmpi 32 . . 0000110010...... A+-DXWL... U U U U U 12 12 2 2 2 -cmpi 32 . pcdi 0000110010111010 .......... . . U U U . . 7 7 7 -cmpi 32 . pcix 0000110010111011 .......... . . U U U . . 9 9 9 -cmpm 8 . ax7 1011111100001... .......... U U U U U 12 12 9 9 9 -cmpm 8 . ay7 1011...100001111 .......... U U U U U 12 12 9 9 9 -cmpm 8 . axy7 1011111100001111 .......... U U U U U 12 12 9 9 9 -cmpm 8 . . 1011...100001... .......... U U U U U 12 12 9 9 9 -cmpm 16 . . 1011...101001... .......... U U U U U 12 12 9 9 9 -cmpm 32 . . 1011...110001... .......... U U U U U 20 20 9 9 9 -cpbcc 32 . . 1111...01....... .......... . . U U . . . 4 4 . unemulated -cpdbcc 32 . . 1111...001001... .......... . . U U . . . 4 4 . unemulated -cpgen 32 . . 1111...000...... .......... . . U U . . . 4 4 . unemulated -cpscc 32 . . 1111...001...... .......... . . U U . . . 4 4 . unemulated -cptrapcc 32 . . 1111...001111... .......... . . U U . . . 4 4 . unemulated -dbt 16 . . 0101000011001... .......... U U U U U 12 12 6 6 6 -dbf 16 . . 0101000111001... .......... U U U U U 12 12 6 6 6 -dbcc 16 . . 0101....11001... .......... U U U U U 12 12 6 6 6 -divs 16 . d 1000...111000... .......... U U U U U 158 122 56 56 56 -divs 16 . . 1000...111...... A+-DXWLdxI U U U U U 158 122 56 56 56 -divu 16 . d 1000...011000... .......... U U U U U 140 108 44 44 44 -divu 16 . . 1000...011...... A+-DXWLdxI U U U U U 140 108 44 44 44 -divl 32 . d 0100110001000... .......... . . U U U . . 84 84 84 -divl 32 . . 0100110001...... A+-DXWLdxI . . U U U . . 84 84 84 -eor 8 . d 1011...100000... .......... U U U U U 4 4 2 2 2 -eor 8 . . 1011...100...... A+-DXWL... U U U U U 8 8 4 4 4 -eor 16 . d 1011...101000... .......... U U U U U 4 4 2 2 2 -eor 16 . . 1011...101...... A+-DXWL... U U U U U 8 8 4 4 4 -eor 32 . d 1011...110000... .......... U U U U U 8 6 2 2 2 -eor 32 . . 1011...110...... A+-DXWL... U U U U U 12 12 4 4 4 -eori 16 toc . 0000101000111100 .......... U U U U U 20 16 12 12 12 -eori 16 tos . 0000101001111100 .......... S S S S S 20 16 12 12 12 -eori 8 . d 0000101000000... .......... U U U U U 8 8 2 2 2 -eori 8 . . 0000101000...... A+-DXWL... U U U U U 12 12 4 4 4 -eori 16 . d 0000101001000... .......... U U U U U 8 8 2 2 2 -eori 16 . . 0000101001...... A+-DXWL... U U U U U 12 12 4 4 4 -eori 32 . d 0000101010000... .......... U U U U U 16 14 2 2 2 -eori 32 . . 0000101010...... A+-DXWL... U U U U U 20 20 4 4 4 -exg 32 dd . 1100...101000... .......... U U U U U 6 6 2 2 2 -exg 32 aa . 1100...101001... .......... U U U U U 6 6 2 2 2 -exg 32 da . 1100...110001... .......... U U U U U 6 6 2 2 2 -ext 16 . . 0100100010000... .......... U U U U U 4 4 4 4 4 -ext 32 . . 0100100011000... .......... U U U U U 4 4 4 4 4 -extb 32 . . 0100100111000... .......... . . U U U . . 4 4 4 -illegal 0 . . 0100101011111100 .......... U U U U U 4 4 4 4 4 -jmp 32 . . 0100111011...... A..DXWLdx. U U U U U 4 4 0 0 0 -jsr 32 . . 0100111010...... A..DXWLdx. U U U U U 12 12 0 0 0 -lea 32 . . 0100...111...... A..DXWLdx. U U U U U 0 0 2 2 2 -link 16 . a7 0100111001010111 .......... U U U U U 16 16 5 5 5 -link 16 . . 0100111001010... .......... U U U U U 16 16 5 5 5 -link 32 . a7 0100100000001111 .......... . . U U U . . 6 6 6 -link 32 . . 0100100000001... .......... . . U U U . . 6 6 6 -lsr 8 s . 1110...000001... .......... U U U U U 6 6 4 4 4 -lsr 16 s . 1110...001001... .......... U U U U U 6 6 4 4 4 -lsr 32 s . 1110...010001... .......... U U U U U 8 8 4 4 4 -lsr 8 r . 1110...000101... .......... U U U U U 6 6 6 6 6 -lsr 16 r . 1110...001101... .......... U U U U U 6 6 6 6 6 -lsr 32 r . 1110...010101... .......... U U U U U 8 8 6 6 6 -lsr 16 . . 1110001011...... A+-DXWL... U U U U U 8 8 5 5 5 -lsl 8 s . 1110...100001... .......... U U U U U 6 6 4 4 4 -lsl 16 s . 1110...101001... .......... U U U U U 6 6 4 4 4 -lsl 32 s . 1110...110001... .......... U U U U U 8 8 4 4 4 -lsl 8 r . 1110...100101... .......... U U U U U 6 6 6 6 6 -lsl 16 r . 1110...101101... .......... U U U U U 6 6 6 6 6 -lsl 32 r . 1110...110101... .......... U U U U U 8 8 6 6 6 -lsl 16 . . 1110001111...... A+-DXWL... U U U U U 8 8 5 5 5 -move 8 d d 0001...000000... .......... U U U U U 4 4 2 2 2 -move 8 d . 0001...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -move 8 ai d 0001...010000... .......... U U U U U 8 8 4 4 4 -move 8 ai . 0001...010...... A+-DXWLdxI U U U U U 8 8 4 4 4 -move 8 pi d 0001...011000... .......... U U U U U 8 8 4 4 4 -move 8 pi . 0001...011...... A+-DXWLdxI U U U U U 8 8 4 4 4 -move 8 pi7 d 0001111011000... .......... U U U U U 8 8 4 4 4 -move 8 pi7 . 0001111011...... A+-DXWLdxI U U U U U 8 8 4 4 4 -move 8 pd d 0001...100000... .......... U U U U U 8 8 5 5 5 -move 8 pd . 0001...100...... A+-DXWLdxI U U U U U 8 8 5 5 5 -move 8 pd7 d 0001111100000... .......... U U U U U 8 8 5 5 5 -move 8 pd7 . 0001111100...... A+-DXWLdxI U U U U U 8 8 5 5 5 -move 8 di d 0001...101000... .......... U U U U U 12 12 5 5 5 -move 8 di . 0001...101...... A+-DXWLdxI U U U U U 12 12 5 5 5 -move 8 ix d 0001...110000... .......... U U U U U 14 14 7 7 7 -move 8 ix . 0001...110...... A+-DXWLdxI U U U U U 14 14 7 7 7 -move 8 aw d 0001000111000... .......... U U U U U 12 12 4 4 4 -move 8 aw . 0001000111...... A+-DXWLdxI U U U U U 12 12 4 4 4 -move 8 al d 0001001111000... .......... U U U U U 16 16 6 6 6 -move 8 al . 0001001111...... A+-DXWLdxI U U U U U 16 16 6 6 6 -move 16 d d 0011...000000... .......... U U U U U 4 4 2 2 2 -move 16 d a 0011...000001... .......... U U U U U 4 4 2 2 2 -move 16 d . 0011...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -move 16 ai d 0011...010000... .......... U U U U U 8 8 4 4 4 -move 16 ai a 0011...010001... .......... U U U U U 8 8 4 4 4 -move 16 ai . 0011...010...... A+-DXWLdxI U U U U U 8 8 4 4 4 -move 16 pi d 0011...011000... .......... U U U U U 8 8 4 4 4 -move 16 pi a 0011...011001... .......... U U U U U 8 8 4 4 4 -move 16 pi . 0011...011...... A+-DXWLdxI U U U U U 8 8 4 4 4 -move 16 pd d 0011...100000... .......... U U U U U 8 8 5 5 5 -move 16 pd a 0011...100001... .......... U U U U U 8 8 5 5 5 -move 16 pd . 0011...100...... A+-DXWLdxI U U U U U 8 8 5 5 5 -move 16 di d 0011...101000... .......... U U U U U 12 12 5 5 5 -move 16 di a 0011...101001... .......... U U U U U 12 12 5 5 5 -move 16 di . 0011...101...... A+-DXWLdxI U U U U U 12 12 5 5 5 -move 16 ix d 0011...110000... .......... U U U U U 14 14 7 7 7 -move 16 ix a 0011...110001... .......... U U U U U 14 14 7 7 7 -move 16 ix . 0011...110...... A+-DXWLdxI U U U U U 14 14 7 7 7 -move 16 aw d 0011000111000... .......... U U U U U 12 12 4 4 4 -move 16 aw a 0011000111001... .......... U U U U U 12 12 4 4 4 -move 16 aw . 0011000111...... A+-DXWLdxI U U U U U 12 12 4 4 4 -move 16 al d 0011001111000... .......... U U U U U 16 16 6 6 6 -move 16 al a 0011001111001... .......... U U U U U 16 16 6 6 6 -move 16 al . 0011001111...... A+-DXWLdxI U U U U U 16 16 6 6 6 -move 32 d d 0010...000000... .......... U U U U U 4 4 2 2 2 -move 32 d a 0010...000001... .......... U U U U U 4 4 2 2 2 -move 32 d . 0010...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -move 32 ai d 0010...010000... .......... U U U U U 12 12 4 4 4 -move 32 ai a 0010...010001... .......... U U U U U 12 12 4 4 4 -move 32 ai . 0010...010...... A+-DXWLdxI U U U U U 12 12 4 4 4 -move 32 pi d 0010...011000... .......... U U U U U 12 12 4 4 4 -move 32 pi a 0010...011001... .......... U U U U U 12 12 4 4 4 -move 32 pi . 0010...011...... A+-DXWLdxI U U U U U 12 12 4 4 4 -move 32 pd d 0010...100000... .......... U U U U U 12 14 5 5 5 -move 32 pd a 0010...100001... .......... U U U U U 12 14 5 5 5 -move 32 pd . 0010...100...... A+-DXWLdxI U U U U U 12 14 5 5 5 -move 32 di d 0010...101000... .......... U U U U U 16 16 5 5 5 -move 32 di a 0010...101001... .......... U U U U U 16 16 5 5 5 -move 32 di . 0010...101...... A+-DXWLdxI U U U U U 16 16 5 5 5 -move 32 ix d 0010...110000... .......... U U U U U 18 18 7 7 7 -move 32 ix a 0010...110001... .......... U U U U U 18 18 7 7 7 -move 32 ix . 0010...110...... A+-DXWLdxI U U U U U 18 18 7 7 7 -move 32 aw d 0010000111000... .......... U U U U U 16 16 4 4 4 -move 32 aw a 0010000111001... .......... U U U U U 16 16 4 4 4 -move 32 aw . 0010000111...... A+-DXWLdxI U U U U U 16 16 4 4 4 -move 32 al d 0010001111000... .......... U U U U U 20 20 6 6 6 -move 32 al a 0010001111001... .......... U U U U U 20 20 6 6 6 -move 32 al . 0010001111...... A+-DXWLdxI U U U U U 20 20 6 6 6 -movea 16 . d 0011...001000... .......... U U U U U 4 4 2 2 2 -movea 16 . a 0011...001001... .......... U U U U U 4 4 2 2 2 -movea 16 . . 0011...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -movea 32 . d 0010...001000... .......... U U U U U 4 4 2 2 2 -movea 32 . a 0010...001001... .......... U U U U U 4 4 2 2 2 -movea 32 . . 0010...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -move 16 frc d 0100001011000... .......... . U U U U . 4 4 4 4 -move 16 frc . 0100001011...... A+-DXWL... . U U U U . 8 4 4 4 -move 16 toc d 0100010011000... .......... U U U U U 12 12 4 4 4 -move 16 toc . 0100010011...... A+-DXWLdxI U U U U U 12 12 4 4 4 -move 16 frs d 0100000011000... .......... U S S S S 6 4 8 8 8 U only for 000 -move 16 frs . 0100000011...... A+-DXWL... U S S S S 8 8 8 8 8 U only for 000 -move 16 tos d 0100011011000... .......... S S S S S 12 12 8 8 8 -move 16 tos . 0100011011...... A+-DXWLdxI S S S S S 12 12 8 8 8 -move 32 fru . 0100111001101... .......... S S S S S 4 6 2 2 2 -move 32 tou . 0100111001100... .......... S S S S S 4 6 2 2 2 -movec 32 cr . 0100111001111010 .......... . S S S S . 12 6 6 6 -movec 32 rc . 0100111001111011 .......... . S S S S . 10 12 12 12 -movem 16 re pd 0100100010100... .......... U U U U U 8 8 4 4 4 -movem 16 re . 0100100010...... A..DXWL... U U U U U 8 8 4 4 4 -movem 32 re pd 0100100011100... .......... U U U U U 8 8 4 4 4 -movem 32 re . 0100100011...... A..DXWL... U U U U U 8 8 4 4 4 -movem 16 er pi 0100110010011... .......... U U U U U 12 12 8 8 8 -movem 16 er pcdi 0100110010111010 .......... U U U U U 16 16 9 9 9 -movem 16 er pcix 0100110010111011 .......... U U U U U 18 18 11 11 11 -movem 16 er . 0100110010...... A..DXWL... U U U U U 12 12 8 8 8 -movem 32 er pi 0100110011011... .......... U U U U U 12 12 8 8 8 -movem 32 er pcdi 0100110011111010 .......... U U U U U 16 16 9 9 9 -movem 32 er pcix 0100110011111011 .......... U U U U U 18 18 11 11 11 -movem 32 er . 0100110011...... A..DXWL... U U U U U 12 12 8 8 8 -movep 16 er . 0000...100001... .......... U U U U U 16 16 12 12 12 -movep 32 er . 0000...101001... .......... U U U U U 24 24 18 18 18 -movep 16 re . 0000...110001... .......... U U U U U 16 16 11 11 11 -movep 32 re . 0000...111001... .......... U U U U U 24 24 17 17 17 -moveq 32 . . 0111...0........ .......... U U U U U 4 4 2 2 2 -moves 8 . . 0000111000...... A+-DXWL... . S S S S . 14 5 5 5 -moves 16 . . 0000111001...... A+-DXWL... . S S S S . 14 5 5 5 -moves 32 . . 0000111010...... A+-DXWL... . S S S S . 16 5 5 5 -move16 32 . . 1111011000100... .......... . . . . U . . . . 4 TODO: correct timing -muls 16 . d 1100...111000... .......... U U U U U 54 32 27 27 27 -muls 16 . . 1100...111...... A+-DXWLdxI U U U U U 54 32 27 27 27 -mulu 16 . d 1100...011000... .......... U U U U U 54 30 27 27 27 -mulu 16 . . 1100...011...... A+-DXWLdxI U U U U U 54 30 27 27 27 -mull 32 . d 0100110000000... .......... . . U U U . . 43 43 43 -mull 32 . . 0100110000...... A+-DXWLdxI . . U U U . . 43 43 43 -nbcd 8 . d 0100100000000... .......... U U U U U 6 6 6 6 6 -nbcd 8 . . 0100100000...... A+-DXWL... U U U U U 8 8 6 6 6 -neg 8 . d 0100010000000... .......... U U U U U 4 4 2 2 2 -neg 8 . . 0100010000...... A+-DXWL... U U U U U 8 8 4 4 4 -neg 16 . d 0100010001000... .......... U U U U U 4 4 2 2 2 -neg 16 . . 0100010001...... A+-DXWL... U U U U U 8 8 4 4 4 -neg 32 . d 0100010010000... .......... U U U U U 6 6 2 2 2 -neg 32 . . 0100010010...... A+-DXWL... U U U U U 12 12 4 4 4 -negx 8 . d 0100000000000... .......... U U U U U 4 4 2 2 2 -negx 8 . . 0100000000...... A+-DXWL... U U U U U 8 8 4 4 4 -negx 16 . d 0100000001000... .......... U U U U U 4 4 2 2 2 -negx 16 . . 0100000001...... A+-DXWL... U U U U U 8 8 4 4 4 -negx 32 . d 0100000010000... .......... U U U U U 6 6 2 2 2 -negx 32 . . 0100000010...... A+-DXWL... U U U U U 12 12 4 4 4 -nop 0 . . 0100111001110001 .......... U U U U U 4 4 2 2 2 -not 8 . d 0100011000000... .......... U U U U U 4 4 2 2 2 -not 8 . . 0100011000...... A+-DXWL... U U U U U 8 8 4 4 4 -not 16 . d 0100011001000... .......... U U U U U 4 4 2 2 2 -not 16 . . 0100011001...... A+-DXWL... U U U U U 8 8 4 4 4 -not 32 . d 0100011010000... .......... U U U U U 6 6 2 2 2 -not 32 . . 0100011010...... A+-DXWL... U U U U U 12 12 4 4 4 -or 8 er d 1000...000000... .......... U U U U U 4 4 2 2 2 -or 8 er . 1000...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -or 16 er d 1000...001000... .......... U U U U U 4 4 2 2 2 -or 16 er . 1000...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -or 32 er d 1000...010000... .......... U U U U U 6 6 2 2 2 -or 32 er . 1000...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 -or 8 re . 1000...100...... A+-DXWL... U U U U U 8 8 4 4 4 -or 16 re . 1000...101...... A+-DXWL... U U U U U 8 8 4 4 4 -or 32 re . 1000...110...... A+-DXWL... U U U U U 12 12 4 4 4 -ori 16 toc . 0000000000111100 .......... U U U U U 20 16 12 12 12 -ori 16 tos . 0000000001111100 .......... S S S S S 20 16 12 12 12 -ori 8 . d 0000000000000... .......... U U U U U 8 8 2 2 2 -ori 8 . . 0000000000...... A+-DXWL... U U U U U 12 12 4 4 4 -ori 16 . d 0000000001000... .......... U U U U U 8 8 2 2 2 -ori 16 . . 0000000001...... A+-DXWL... U U U U U 12 12 4 4 4 -ori 32 . d 0000000010000... .......... U U U U U 16 14 2 2 2 -ori 32 . . 0000000010...... A+-DXWL... U U U U U 20 20 4 4 4 -pack 16 rr . 1000...101000... .......... . . U U U . . 6 6 6 -pack 16 mm ax7 1000111101001... .......... . . U U U . . 13 13 13 -pack 16 mm ay7 1000...101001111 .......... . . U U U . . 13 13 13 -pack 16 mm axy7 1000111101001111 .......... . . U U U . . 13 13 13 -pack 16 mm . 1000...101001... .......... . . U U U . . 13 13 13 -pea 32 . . 0100100001...... A..DXWLdx. U U U U U 6 6 5 5 5 -pflush 32 . . 1111010100011000 .......... . . . . S . . . . 4 TODO: correct timing -pmmu 32 . . 1111000......... .......... . . S S S . . 8 8 8 -reset 0 . . 0100111001110000 .......... S S S S S 0 0 0 0 0 -ror 8 s . 1110...000011... .......... U U U U U 6 6 8 8 8 -ror 16 s . 1110...001011... .......... U U U U U 6 6 8 8 8 -ror 32 s . 1110...010011... .......... U U U U U 8 8 8 8 8 -ror 8 r . 1110...000111... .......... U U U U U 6 6 8 8 8 -ror 16 r . 1110...001111... .......... U U U U U 6 6 8 8 8 -ror 32 r . 1110...010111... .......... U U U U U 8 8 8 8 8 -ror 16 . . 1110011011...... A+-DXWL... U U U U U 8 8 7 7 7 -rol 8 s . 1110...100011... .......... U U U U U 6 6 8 8 8 -rol 16 s . 1110...101011... .......... U U U U U 6 6 8 8 8 -rol 32 s . 1110...110011... .......... U U U U U 8 8 8 8 8 -rol 8 r . 1110...100111... .......... U U U U U 6 6 8 8 8 -rol 16 r . 1110...101111... .......... U U U U U 6 6 8 8 8 -rol 32 r . 1110...110111... .......... U U U U U 8 8 8 8 8 -rol 16 . . 1110011111...... A+-DXWL... U U U U U 8 8 7 7 7 -roxr 8 s . 1110...000010... .......... U U U U U 6 6 12 12 12 -roxr 16 s . 1110...001010... .......... U U U U U 6 6 12 12 12 -roxr 32 s . 1110...010010... .......... U U U U U 8 8 12 12 12 -roxr 8 r . 1110...000110... .......... U U U U U 6 6 12 12 12 -roxr 16 r . 1110...001110... .......... U U U U U 6 6 12 12 12 -roxr 32 r . 1110...010110... .......... U U U U U 8 8 12 12 12 -roxr 16 . . 1110010011...... A+-DXWL... U U U U U 8 8 5 5 5 -roxl 8 s . 1110...100010... .......... U U U U U 6 6 12 12 12 -roxl 16 s . 1110...101010... .......... U U U U U 6 6 12 12 12 -roxl 32 s . 1110...110010... .......... U U U U U 8 8 12 12 12 -roxl 8 r . 1110...100110... .......... U U U U U 6 6 12 12 12 -roxl 16 r . 1110...101110... .......... U U U U U 6 6 12 12 12 -roxl 32 r . 1110...110110... .......... U U U U U 8 8 12 12 12 -roxl 16 . . 1110010111...... A+-DXWL... U U U U U 8 8 5 5 5 -rtd 32 . . 0100111001110100 .......... . U U U U . 16 10 10 10 -rte 32 . . 0100111001110011 .......... S S S S S 20 24 20 20 20 bus fault not emulated -rtm 32 . . 000001101100.... .......... . . U U U . . 19 19 19 not properly emulated -rtr 32 . . 0100111001110111 .......... U U U U U 20 20 14 14 14 -rts 32 . . 0100111001110101 .......... U U U U U 16 16 10 10 10 -sbcd 8 rr . 1000...100000... .......... U U U U U 6 6 4 4 4 -sbcd 8 mm ax7 1000111100001... .......... U U U U U 18 18 16 16 16 -sbcd 8 mm ay7 1000...100001111 .......... U U U U U 18 18 16 16 16 -sbcd 8 mm axy7 1000111100001111 .......... U U U U U 18 18 16 16 16 -sbcd 8 mm . 1000...100001... .......... U U U U U 18 18 16 16 16 -st 8 . d 0101000011000... .......... U U U U U 6 4 4 4 4 -st 8 . . 0101000011...... A+-DXWL... U U U U U 8 8 6 6 6 -sf 8 . d 0101000111000... .......... U U U U U 4 4 4 4 4 -sf 8 . . 0101000111...... A+-DXWL... U U U U U 8 8 6 6 6 -scc 8 . d 0101....11000... .......... U U U U U 4 4 4 4 4 -scc 8 . . 0101....11...... A+-DXWL... U U U U U 8 8 6 6 6 -stop 0 . . 0100111001110010 .......... S S S S S 4 4 8 8 8 -sub 8 er d 1001...000000... .......... U U U U U 4 4 2 2 2 -sub 8 er . 1001...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 -sub 16 er d 1001...001000... .......... U U U U U 4 4 2 2 2 -sub 16 er a 1001...001001... .......... U U U U U 4 4 2 2 2 -sub 16 er . 1001...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 -sub 32 er d 1001...010000... .......... U U U U U 6 6 2 2 2 -sub 32 er a 1001...010001... .......... U U U U U 6 6 2 2 2 -sub 32 er . 1001...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 -sub 8 re . 1001...100...... A+-DXWL... U U U U U 8 8 4 4 4 -sub 16 re . 1001...101...... A+-DXWL... U U U U U 8 8 4 4 4 -sub 32 re . 1001...110...... A+-DXWL... U U U U U 12 12 4 4 4 -suba 16 . d 1001...011000... .......... U U U U U 8 8 2 2 2 -suba 16 . a 1001...011001... .......... U U U U U 8 8 2 2 2 -suba 16 . . 1001...011...... A+-DXWLdxI U U U U U 8 8 2 2 2 -suba 32 . d 1001...111000... .......... U U U U U 6 6 2 2 2 -suba 32 . a 1001...111001... .......... U U U U U 6 6 2 2 2 -suba 32 . . 1001...111...... A+-DXWLdxI U U U U U 6 6 2 2 2 -subi 8 . d 0000010000000... .......... U U U U U 8 8 2 2 2 -subi 8 . . 0000010000...... A+-DXWL... U U U U U 12 12 4 4 4 -subi 16 . d 0000010001000... .......... U U U U U 8 8 2 2 2 -subi 16 . . 0000010001...... A+-DXWL... U U U U U 12 12 4 4 4 -subi 32 . d 0000010010000... .......... U U U U U 16 14 2 2 2 -subi 32 . . 0000010010...... A+-DXWL... U U U U U 20 20 4 4 4 -subq 8 . d 0101...100000... .......... U U U U U 4 4 2 2 2 -subq 8 . . 0101...100...... A+-DXWL... U U U U U 8 8 4 4 4 -subq 16 . d 0101...101000... .......... U U U U U 4 4 2 2 2 -subq 16 . a 0101...101001... .......... U U U U U 8 4 2 2 2 -subq 16 . . 0101...101...... A+-DXWL... U U U U U 8 8 4 4 4 -subq 32 . d 0101...110000... .......... U U U U U 8 8 2 2 2 -subq 32 . a 0101...110001... .......... U U U U U 8 8 2 2 2 -subq 32 . . 0101...110...... A+-DXWL... U U U U U 12 12 4 4 4 -subx 8 rr . 1001...100000... .......... U U U U U 4 4 2 2 2 -subx 16 rr . 1001...101000... .......... U U U U U 4 4 2 2 2 -subx 32 rr . 1001...110000... .......... U U U U U 8 6 2 2 2 -subx 8 mm ax7 1001111100001... .......... U U U U U 18 18 12 12 12 -subx 8 mm ay7 1001...100001111 .......... U U U U U 18 18 12 12 12 -subx 8 mm axy7 1001111100001111 .......... U U U U U 18 18 12 12 12 -subx 8 mm . 1001...100001... .......... U U U U U 18 18 12 12 12 -subx 16 mm . 1001...101001... .......... U U U U U 18 18 12 12 12 -subx 32 mm . 1001...110001... .......... U U U U U 30 30 12 12 12 -swap 32 . . 0100100001000... .......... U U U U U 4 4 4 4 4 -tas 8 . d 0100101011000... .......... U U U U U 4 4 4 4 4 -tas 8 . . 0100101011...... A+-DXWL... U U U U U 14 14 12 12 12 -trap 0 . . 010011100100.... .......... U U U U U 4 4 4 4 4 -trapt 0 . . 0101000011111100 .......... . . U U U . . 4 4 4 -trapt 16 . . 0101000011111010 .......... . . U U U . . 6 6 6 -trapt 32 . . 0101000011111011 .......... . . U U U . . 8 8 8 -trapf 0 . . 0101000111111100 .......... . . U U U . . 4 4 4 -trapf 16 . . 0101000111111010 .......... . . U U U . . 6 6 6 -trapf 32 . . 0101000111111011 .......... . . U U U . . 8 8 8 -trapcc 0 . . 0101....11111100 .......... . . U U U . . 4 4 4 -trapcc 16 . . 0101....11111010 .......... . . U U U . . 6 6 6 -trapcc 32 . . 0101....11111011 .......... . . U U U . . 8 8 8 -trapv 0 . . 0100111001110110 .......... U U U U U 4 4 4 4 4 -tst 8 . d 0100101000000... .......... U U U U U 4 4 2 2 2 -tst 8 . . 0100101000...... A+-DXWL... U U U U U 4 4 2 2 2 -tst 8 . pcdi 0100101000111010 .......... . . U U U . . 7 7 7 -tst 8 . pcix 0100101000111011 .......... . . U U U . . 9 9 9 -tst 8 . i 0100101000111100 .......... . . U U U . . 6 6 6 -tst 16 . d 0100101001000... .......... U U U U U 4 4 2 2 2 -tst 16 . a 0100101001001... .......... . . U U U . . 2 2 2 -tst 16 . . 0100101001...... A+-DXWL... U U U U U 4 4 2 2 2 -tst 16 . pcdi 0100101001111010 .......... . . U U U . . 7 7 7 -tst 16 . pcix 0100101001111011 .......... . . U U U . . 9 9 9 -tst 16 . i 0100101001111100 .......... . . U U U . . 6 6 6 -tst 32 . d 0100101010000... .......... U U U U U 4 4 2 2 2 -tst 32 . a 0100101010001... .......... . . U U U . . 2 2 2 -tst 32 . . 0100101010...... A+-DXWL... U U U U U 4 4 2 2 2 -tst 32 . pcdi 0100101010111010 .......... . . U U U . . 7 7 7 -tst 32 . pcix 0100101010111011 .......... . . U U U . . 9 9 9 -tst 32 . i 0100101010111100 .......... . . U U U . . 6 6 6 -unlk 32 . a7 0100111001011111 .......... U U U U U 12 12 6 6 6 -unlk 32 . . 0100111001011... .......... U U U U U 12 12 6 6 6 -unpk 16 rr . 1000...110000... .......... . . U U U . . 8 8 8 -unpk 16 mm ax7 1000111110001... .......... . . U U U . . 13 13 13 -unpk 16 mm ay7 1000...110001111 .......... . . U U U . . 13 13 13 -unpk 16 mm axy7 1000111110001111 .......... . . U U U . . 13 13 13 -unpk 16 mm . 1000...110001... .......... . . U U U . . 13 13 13 - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_OPCODE_HANDLER_BODY - -M68KMAKE_OP(1010, 0, ., .) -{ - m68ki_exception_1010(); -} - - -M68KMAKE_OP(1111, 0, ., .) -{ - m68ki_exception_1111(); -} - - -M68KMAKE_OP(040fpu0, 32, ., .) -{ - if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) - { - m68040_fpu_op0(); - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(040fpu1, 32, ., .) -{ - if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) - { - m68040_fpu_op1(); - return; - } - m68ki_exception_1111(); -} - - - -M68KMAKE_OP(abcd, 8, rr, .) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res += 6; - res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res -= 0xa0; - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; -} - - -M68KMAKE_OP(abcd, 8, mm, ax7) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res += 6; - res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res -= 0xa0; - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(abcd, 8, mm, ay7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res += 6; - res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res -= 0xa0; - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(abcd, 8, mm, axy7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res += 6; - res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res -= 0xa0; - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(abcd, 8, mm, .) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res += 6; - res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res -= 0xa0; - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(add, 8, er, d) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_8(DY); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(add, 8, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_8; - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(add, 16, er, d) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(DY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(add, 16, er, a) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(AY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(add, 16, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_16; - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(add, 32, er, d) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(add, 32, er, a) -{ - uint* r_dst = &DX; - uint src = AY; - uint dst = *r_dst; - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(add, 32, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_32; - uint dst = *r_dst; - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(add, 8, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = MASK_OUT_ABOVE_8(DX); - uint dst = m68ki_read_8(ea); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(add, 16, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = MASK_OUT_ABOVE_16(DX); - uint dst = m68ki_read_16(ea); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(add, 32, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint src = DX; - uint dst = m68ki_read_32(ea); - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(adda, 16, ., d) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(DY)); -} - - -M68KMAKE_OP(adda, 16, ., a) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(AY)); -} - - -M68KMAKE_OP(adda, 16, ., .) -{ - uint* r_dst = &AX; - uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); -} - - -M68KMAKE_OP(adda, 32, ., d) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + DY); -} - - -M68KMAKE_OP(adda, 32, ., a) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + AY); -} - - -M68KMAKE_OP(adda, 32, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_32; - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); -} - - -M68KMAKE_OP(addi, 8, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_8(); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(addi, 8, ., .) -{ - uint src = OPER_I_8(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(addi, 16, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_16(); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(addi, 16, ., .) -{ - uint src = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint dst = m68ki_read_16(ea); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(addi, 32, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_32(); - uint dst = *r_dst; - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(addi, 32, ., .) -{ - uint src = OPER_I_32(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint dst = m68ki_read_32(ea); - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(addq, 8, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(addq, 8, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint res = src + dst; - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(addq, 16, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(addq, 16, ., a) -{ - uint* r_dst = &AY; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); -} - - -M68KMAKE_OP(addq, 16, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_16; - uint dst = m68ki_read_16(ea); - uint res = src + dst; - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(addq, 32, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = *r_dst; - uint res = src + dst; - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(addq, 32, ., a) -{ - uint* r_dst = &AY; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); -} - - -M68KMAKE_OP(addq, 32, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_32; - uint dst = m68ki_read_32(ea); - uint res = src + dst; - - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(addx, 8, rr, .) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_8(DY); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; -} - - -M68KMAKE_OP(addx, 16, rr, .) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(DY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; -} - - -M68KMAKE_OP(addx, 32, rr, .) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - *r_dst = res; -} - - -M68KMAKE_OP(addx, 8, mm, ax7) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(addx, 8, mm, ay7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(addx, 8, mm, axy7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(addx, 8, mm, .) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_V = VFLAG_ADD_8(src, dst, res); - FLAG_X = FLAG_C = CFLAG_8(res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(addx, 16, mm, .) -{ - uint src = OPER_AY_PD_16(); - uint ea = EA_AX_PD_16(); - uint dst = m68ki_read_16(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_V = VFLAG_ADD_16(src, dst, res); - FLAG_X = FLAG_C = CFLAG_16(res); - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - m68ki_write_16(ea, res); -} - - -M68KMAKE_OP(addx, 32, mm, .) -{ - uint src = OPER_AY_PD_32(); - uint ea = EA_AX_PD_32(); - uint dst = m68ki_read_32(ea); - uint res = src + dst + XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_ADD_32(src, dst, res); - FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - m68ki_write_32(ea, res); -} - - -M68KMAKE_OP(and, 8, er, d) -{ - FLAG_Z = MASK_OUT_ABOVE_8(DX &= (DY | 0xffffff00)); - - FLAG_N = NFLAG_8(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 8, er, .) -{ - FLAG_Z = MASK_OUT_ABOVE_8(DX &= (M68KMAKE_GET_OPER_AY_8 | 0xffffff00)); - - FLAG_N = NFLAG_8(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 16, er, d) -{ - FLAG_Z = MASK_OUT_ABOVE_16(DX &= (DY | 0xffff0000)); - - FLAG_N = NFLAG_16(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 16, er, .) -{ - FLAG_Z = MASK_OUT_ABOVE_16(DX &= (M68KMAKE_GET_OPER_AY_16 | 0xffff0000)); - - FLAG_N = NFLAG_16(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 32, er, d) -{ - FLAG_Z = DX &= DY; - - FLAG_N = NFLAG_32(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 32, er, .) -{ - FLAG_Z = DX &= M68KMAKE_GET_OPER_AY_32; - - FLAG_N = NFLAG_32(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(and, 8, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = DX & m68ki_read_8(ea); - - FLAG_N = NFLAG_8(res); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_Z = MASK_OUT_ABOVE_8(res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(and, 16, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = DX & m68ki_read_16(ea); - - FLAG_N = NFLAG_16(res); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_Z = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(and, 32, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = DX & m68ki_read_32(ea); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - - m68ki_write_32(ea, res); -} - - -M68KMAKE_OP(andi, 8, ., d) -{ - FLAG_Z = MASK_OUT_ABOVE_8(DY &= (OPER_I_8() | 0xffffff00)); - - FLAG_N = NFLAG_8(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(andi, 8, ., .) -{ - uint src = OPER_I_8(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = src & m68ki_read_8(ea); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(andi, 16, ., d) -{ - FLAG_Z = MASK_OUT_ABOVE_16(DY &= (OPER_I_16() | 0xffff0000)); - - FLAG_N = NFLAG_16(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(andi, 16, ., .) -{ - uint src = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = src & m68ki_read_16(ea); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - - m68ki_write_16(ea, res); -} - - -M68KMAKE_OP(andi, 32, ., d) -{ - FLAG_Z = DY &= (OPER_I_32()); - - FLAG_N = NFLAG_32(FLAG_Z); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(andi, 32, ., .) -{ - uint src = OPER_I_32(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = src & m68ki_read_32(ea); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - - m68ki_write_32(ea, res); -} - - -M68KMAKE_OP(andi, 16, toc, .) -{ - m68ki_set_ccr(m68ki_get_ccr() & OPER_I_8()); -} - - -M68KMAKE_OP(andi, 16, tos, .) -{ - if(FLAG_S) - { - uint src = OPER_I_16(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_set_sr(m68ki_get_sr() & src); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(asr, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> (shift - 1))<<8; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - if(GET_MSB_16(src)) - { - *r_dst |= 0xffff; - FLAG_C = CFLAG_SET; - FLAG_X = XFLAG_SET; - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst &= 0xffff0000; - FLAG_C = CFLAG_CLEAR; - FLAG_X = XFLAG_CLEAR; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(asr, 32, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = *r_dst; - uint res = src >> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> (shift - 1))<<8; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - if(GET_MSB_32(src)) - { - *r_dst = 0xffffffff; - FLAG_C = CFLAG_SET; - FLAG_X = XFLAG_SET; - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst = 0; - FLAG_C = CFLAG_CLEAR; - FLAG_X = XFLAG_CLEAR; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(asr, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = src >> 1; - - if(GET_MSB_16(src)) - res |= 0x8000; - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = FLAG_X = src << 8; -} - - -M68KMAKE_OP(asl, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = MASK_OUT_ABOVE_8(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = MASK_OUT_ABOVE_16(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> (8-shift); - src &= m68ki_shift_16_table[shift + 1]; - FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; -} - - -M68KMAKE_OP(asl, 32, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> (24-shift); - src &= m68ki_shift_32_table[shift + 1]; - FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; -} - - -M68KMAKE_OP(asl, 8, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = MASK_OUT_ABOVE_8(src << shift); - - if(shift != 0) - { - USE_CYCLES(shift<> 8; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - src &= m68ki_shift_16_table[shift + 1]; - FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; - return; - } - - *r_dst &= 0xffff0000; - FLAG_X = FLAG_C = ((shift == 16 ? src & 1 : 0))<<8; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = (!(src == 0))<<7; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(asl, 32, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32(src << shift); - - if(shift != 0) - { - USE_CYCLES(shift<> (32 - shift)) << 8; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - src &= m68ki_shift_32_table[shift + 1]; - FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; - return; - } - - *r_dst = 0; - FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = (!(src == 0))<<7; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(asl, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = MASK_OUT_ABOVE_16(src << 1); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_X = FLAG_C = src >> 7; - src &= 0xc000; - FLAG_V = (!(src == 0 || src == 0xc000))<<7; -} - - -M68KMAKE_OP(bcc, 8, ., .) -{ - if(M68KMAKE_CC) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - return; - } - USE_CYCLES(CYC_BCC_NOTAKE_B); -} - - -M68KMAKE_OP(bcc, 16, ., .) -{ - if(M68KMAKE_CC) - { - uint offset = OPER_I_16(); - REG_PC -= 2; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_16(offset); - return; - } - REG_PC += 2; - USE_CYCLES(CYC_BCC_NOTAKE_W); -} - - -M68KMAKE_OP(bcc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - if(M68KMAKE_CC) - { - uint offset = OPER_I_32(); - REG_PC -= 4; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_32(offset); - return; - } - REG_PC += 4; - return; - } - else - { - if(M68KMAKE_CC) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - return; - } - USE_CYCLES(CYC_BCC_NOTAKE_B); - } -} - - -M68KMAKE_OP(bchg, 32, r, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (DX & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst ^= mask; -} - - -M68KMAKE_OP(bchg, 8, r, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - uint mask = 1 << (DX & 7); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src ^ mask); -} - - -M68KMAKE_OP(bchg, 32, s, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (OPER_I_8() & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst ^= mask; -} - - -M68KMAKE_OP(bchg, 8, s, .) -{ - uint mask = 1 << (OPER_I_8() & 7); - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src ^ mask); -} - - -M68KMAKE_OP(bclr, 32, r, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (DX & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst &= ~mask; -} - - -M68KMAKE_OP(bclr, 8, r, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - uint mask = 1 << (DX & 7); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src & ~mask); -} - - -M68KMAKE_OP(bclr, 32, s, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (OPER_I_8() & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst &= ~mask; -} - - -M68KMAKE_OP(bclr, 8, s, .) -{ - uint mask = 1 << (OPER_I_8() & 7); - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src & ~mask); -} - - -M68KMAKE_OP(bfchg, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint* data = &DY; - uint64 mask; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - offset &= 31; - width = ((width-1) & 31) + 1; - - mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask = ROR_32(mask, offset); - - FLAG_N = NFLAG_32(*data<>6)&31; - uint width = word2; - uint mask_base; - uint data_long; - uint mask_long; - uint data_byte = 0; - uint mask_byte = 0; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask_long = mask_base >> offset; - - data_long = m68ki_read_32(ea); - FLAG_N = NFLAG_32(data_long << offset); - FLAG_Z = data_long & mask_long; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - m68ki_write_32(ea, data_long ^ mask_long); - - if((width + offset) > 32) - { - mask_byte = MASK_OUT_ABOVE_8(mask_base); - data_byte = m68ki_read_8(ea+4); - FLAG_Z |= (data_byte & mask_byte); - m68ki_write_8(ea+4, data_byte ^ mask_byte); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfclr, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint* data = &DY; - uint64 mask; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - - offset &= 31; - width = ((width-1) & 31) + 1; - - - mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask = ROR_32(mask, offset); - - FLAG_N = NFLAG_32(*data<>6)&31; - uint width = word2; - uint mask_base; - uint data_long; - uint mask_long; - uint data_byte = 0; - uint mask_byte = 0; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask_long = mask_base >> offset; - - data_long = m68ki_read_32(ea); - FLAG_N = NFLAG_32(data_long << offset); - FLAG_Z = data_long & mask_long; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - m68ki_write_32(ea, data_long & ~mask_long); - - if((width + offset) > 32) - { - mask_byte = MASK_OUT_ABOVE_8(mask_base); - data_byte = m68ki_read_8(ea+4); - FLAG_Z |= (data_byte & mask_byte); - m68ki_write_8(ea+4, data_byte & ~mask_byte); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfexts, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint64 data = DY; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - offset &= 31; - width = ((width-1) & 31) + 1; - - data = ROL_32(data, offset); - FLAG_N = NFLAG_32(data); - data = MAKE_INT_32(data) >> (32 - width); - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - REG_D[(word2>>12)&7] = data; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfexts, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint offset = (word2>>6)&31; - uint width = word2; - uint data; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - data = m68ki_read_32(ea); - - data = MASK_OUT_ABOVE_32(data< 32) - data |= (m68ki_read_8(ea+4) << offset) >> 8; - - FLAG_N = NFLAG_32(data); - data = MAKE_INT_32(data) >> (32 - width); - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - REG_D[(word2 >> 12) & 7] = data; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfextu, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint64 data = DY; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - offset &= 31; - width = ((width-1) & 31) + 1; - - data = ROL_32(data, offset); - FLAG_N = NFLAG_32(data); - data >>= 32 - width; - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - REG_D[(word2>>12)&7] = data; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfextu, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint offset = (word2>>6)&31; - uint width = word2; - uint data; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - data = m68ki_read_32(ea); - data = MASK_OUT_ABOVE_32(data< 32) - data |= (m68ki_read_8(ea+4) << offset) >> 8; - - FLAG_N = NFLAG_32(data); - data >>= (32 - width); - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - REG_D[(word2 >> 12) & 7] = data; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfffo, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint64 data = DY; - uint bit; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - offset &= 31; - width = ((width-1) & 31) + 1; - - data = ROL_32(data, offset); - FLAG_N = NFLAG_32(data); - data >>= 32 - width; - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - for(bit = 1<<(width-1);bit && !(data & bit);bit>>= 1) - offset++; - - REG_D[(word2>>12)&7] = offset; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfffo, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint offset = (word2>>6)&31; - sint local_offset; - uint width = word2; - uint data; - uint bit; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - local_offset = offset % 8; - if(local_offset < 0) - { - local_offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - data = m68ki_read_32(ea); - data = MASK_OUT_ABOVE_32(data< 32) - data |= (m68ki_read_8(ea+4) << local_offset) >> 8; - - FLAG_N = NFLAG_32(data); - data >>= (32 - width); - - FLAG_Z = data; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - for(bit = 1<<(width-1);bit && !(data & bit);bit>>= 1) - offset++; - - REG_D[(word2>>12)&7] = offset; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfins, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint* data = &DY; - uint64 mask; - uint64 insert = REG_D[(word2>>12)&7]; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - - offset &= 31; - width = ((width-1) & 31) + 1; - - - mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask = ROR_32(mask, offset); - - insert = MASK_OUT_ABOVE_32(insert << (32 - width)); - FLAG_N = NFLAG_32(insert); - FLAG_Z = insert; - insert = ROR_32(insert, offset); - - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - *data &= ~mask; - *data |= insert; - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfins, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint offset = (word2>>6)&31; - uint width = word2; - uint insert_base = REG_D[(word2>>12)&7]; - uint insert_long; - uint insert_byte; - uint mask_base; - uint data_long; - uint mask_long; - uint data_byte = 0; - uint mask_byte = 0; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask_long = mask_base >> offset; - - insert_base = MASK_OUT_ABOVE_32(insert_base << (32 - width)); - FLAG_N = NFLAG_32(insert_base); - FLAG_Z = insert_base; - insert_long = insert_base >> offset; - - data_long = m68ki_read_32(ea); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - m68ki_write_32(ea, (data_long & ~mask_long) | insert_long); - - if((width + offset) > 32) - { - mask_byte = MASK_OUT_ABOVE_8(mask_base); - insert_byte = MASK_OUT_ABOVE_8(insert_base); - data_byte = m68ki_read_8(ea+4); - FLAG_Z |= (data_byte & mask_byte); - m68ki_write_8(ea+4, (data_byte & ~mask_byte) | insert_byte); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bfset, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint* data = &DY; - uint64 mask; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - - offset &= 31; - width = ((width-1) & 31) + 1; - - - mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask = ROR_32(mask, offset); - - FLAG_N = NFLAG_32(*data<>6)&31; - uint width = word2; - uint mask_base; - uint data_long; - uint mask_long; - uint data_byte = 0; - uint mask_byte = 0; - uint ea = M68KMAKE_GET_EA_AY_8; - - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - - mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask_long = mask_base >> offset; - - data_long = m68ki_read_32(ea); - FLAG_N = NFLAG_32(data_long << offset); - FLAG_Z = data_long & mask_long; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - m68ki_write_32(ea, data_long | mask_long); - - if((width + offset) > 32) - { - mask_byte = MASK_OUT_ABOVE_8(mask_base); - data_byte = m68ki_read_8(ea+4); - FLAG_Z |= (data_byte & mask_byte); - m68ki_write_8(ea+4, data_byte | mask_byte); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bftst, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint offset = (word2>>6)&31; - uint width = word2; - uint* data = &DY; - uint64 mask; - - - if(BIT_B(word2)) - offset = REG_D[offset&7]; - if(BIT_5(word2)) - width = REG_D[width&7]; - - - offset &= 31; - width = ((width-1) & 31) + 1; - - - mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask = ROR_32(mask, offset); - - FLAG_N = NFLAG_32(*data<>6)&31; - uint width = word2; - uint mask_base; - uint data_long; - uint mask_long; - uint data_byte = 0; - uint mask_byte = 0; - uint ea = M68KMAKE_GET_EA_AY_8; - - if(BIT_B(word2)) - offset = MAKE_INT_32(REG_D[offset&7]); - if(BIT_5(word2)) - width = REG_D[width&7]; - - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; - } - width = ((width-1) & 31) + 1; - - - mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); - mask_long = mask_base >> offset; - - data_long = m68ki_read_32(ea); - FLAG_N = ((data_long & (0x80000000 >> offset))<>24; - FLAG_Z = data_long & mask_long; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - if((width + offset) > 32) - { - mask_byte = MASK_OUT_ABOVE_8(mask_base); - data_byte = m68ki_read_8(ea+4); - FLAG_Z |= (data_byte & mask_byte); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bkpt, 0, ., .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - m68ki_bkpt_ack(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE) ? REG_IR & 7 : 0); /* auto-disable (see m68kcpu.h) */ - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(bra, 8, ., .) -{ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); -} - - -M68KMAKE_OP(bra, 16, ., .) -{ - uint offset = OPER_I_16(); - REG_PC -= 2; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_16(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); -} - - -M68KMAKE_OP(bra, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint offset = OPER_I_32(); - REG_PC -= 4; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_32(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); - return; - } - else - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); - } -} - - -M68KMAKE_OP(bset, 32, r, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (DX & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst |= mask; -} - - -M68KMAKE_OP(bset, 8, r, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - uint mask = 1 << (DX & 7); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src | mask); -} - - -M68KMAKE_OP(bset, 32, s, d) -{ - uint* r_dst = &DY; - uint mask = 1 << (OPER_I_8() & 0x1f); - - FLAG_Z = *r_dst & mask; - *r_dst |= mask; -} - - -M68KMAKE_OP(bset, 8, s, .) -{ - uint mask = 1 << (OPER_I_8() & 7); - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - - FLAG_Z = src & mask; - m68ki_write_8(ea, src | mask); -} - - -M68KMAKE_OP(bsr, 8, ., .) -{ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); -} - - -M68KMAKE_OP(bsr, 16, ., .) -{ - uint offset = OPER_I_16(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - REG_PC -= 2; - m68ki_branch_16(offset); -} - - -M68KMAKE_OP(bsr, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint offset = OPER_I_32(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - REG_PC -= 4; - m68ki_branch_32(offset); - return; - } - else - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - } -} - - -M68KMAKE_OP(btst, 32, r, d) -{ - FLAG_Z = DY & (1 << (DX & 0x1f)); -} - - -M68KMAKE_OP(btst, 8, r, .) -{ - FLAG_Z = M68KMAKE_GET_OPER_AY_8 & (1 << (DX & 7)); -} - - -M68KMAKE_OP(btst, 32, s, d) -{ - FLAG_Z = DY & (1 << (OPER_I_8() & 0x1f)); -} - - -M68KMAKE_OP(btst, 8, s, .) -{ - uint bit = OPER_I_8() & 7; - - FLAG_Z = M68KMAKE_GET_OPER_AY_8 & (1 << bit); -} - - -M68KMAKE_OP(callm, 32, ., .) -{ - /* note: watch out for pcrelative modes */ - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - { - uint ea = M68KMAKE_GET_EA_AY_32; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - REG_PC += 2; -(void)ea; /* just to avoid an 'unused variable' warning */ - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cas, 8, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint dest = m68ki_read_8(ea); - uint* compare = ®_D[word2 & 7]; - uint res = dest - MASK_OUT_ABOVE_8(*compare); - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(*compare, dest, res); - FLAG_C = CFLAG_8(res); - - if(COND_NE()) - *compare = MASK_OUT_BELOW_8(*compare) | dest; - else - { - USE_CYCLES(3); - m68ki_write_8(ea, MASK_OUT_ABOVE_8(REG_D[(word2 >> 6) & 7])); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cas, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint dest = m68ki_read_16(ea); - uint* compare = ®_D[word2 & 7]; - uint res = dest - MASK_OUT_ABOVE_16(*compare); - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(*compare, dest, res); - FLAG_C = CFLAG_16(res); - - if(COND_NE()) - *compare = MASK_OUT_BELOW_16(*compare) | dest; - else - { - USE_CYCLES(3); - m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_D[(word2 >> 6) & 7])); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cas, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint dest = m68ki_read_32(ea); - uint* compare = ®_D[word2 & 7]; - uint res = dest - *compare; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(*compare, dest, res); - FLAG_C = CFLAG_SUB_32(*compare, dest, res); - - if(COND_NE()) - *compare = dest; - else - { - USE_CYCLES(3); - m68ki_write_32(ea, REG_D[(word2 >> 6) & 7]); - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cas2, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_32(); - uint* compare1 = ®_D[(word2 >> 16) & 7]; - uint ea1 = REG_DA[(word2 >> 28) & 15]; - uint dest1 = m68ki_read_16(ea1); - uint res1 = dest1 - MASK_OUT_ABOVE_16(*compare1); - uint* compare2 = ®_D[word2 & 7]; - uint ea2 = REG_DA[(word2 >> 12) & 15]; - uint dest2 = m68ki_read_16(ea2); - uint res2; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_16(res1); - FLAG_Z = MASK_OUT_ABOVE_16(res1); - FLAG_V = VFLAG_SUB_16(*compare1, dest1, res1); - FLAG_C = CFLAG_16(res1); - - if(COND_EQ()) - { - res2 = dest2 - MASK_OUT_ABOVE_16(*compare2); - - FLAG_N = NFLAG_16(res2); - FLAG_Z = MASK_OUT_ABOVE_16(res2); - FLAG_V = VFLAG_SUB_16(*compare2, dest2, res2); - FLAG_C = CFLAG_16(res2); - - if(COND_EQ()) - { - USE_CYCLES(3); - m68ki_write_16(ea1, REG_D[(word2 >> 22) & 7]); - m68ki_write_16(ea2, REG_D[(word2 >> 6) & 7]); - return; - } - } - *compare1 = BIT_1F(word2) ? (uint)MAKE_INT_16(dest1) : MASK_OUT_BELOW_16(*compare1) | dest1; - *compare2 = BIT_F(word2) ? (uint)MAKE_INT_16(dest2) : MASK_OUT_BELOW_16(*compare2) | dest2; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cas2, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_32(); - uint* compare1 = ®_D[(word2 >> 16) & 7]; - uint ea1 = REG_DA[(word2 >> 28) & 15]; - uint dest1 = m68ki_read_32(ea1); - uint res1 = dest1 - *compare1; - uint* compare2 = ®_D[word2 & 7]; - uint ea2 = REG_DA[(word2 >> 12) & 15]; - uint dest2 = m68ki_read_32(ea2); - uint res2; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_32(res1); - FLAG_Z = MASK_OUT_ABOVE_32(res1); - FLAG_V = VFLAG_SUB_32(*compare1, dest1, res1); - FLAG_C = CFLAG_SUB_32(*compare1, dest1, res1); - - if(COND_EQ()) - { - res2 = dest2 - *compare2; - - FLAG_N = NFLAG_32(res2); - FLAG_Z = MASK_OUT_ABOVE_32(res2); - FLAG_V = VFLAG_SUB_32(*compare2, dest2, res2); - FLAG_C = CFLAG_SUB_32(*compare2, dest2, res2); - - if(COND_EQ()) - { - USE_CYCLES(3); - m68ki_write_32(ea1, REG_D[(word2 >> 22) & 7]); - m68ki_write_32(ea2, REG_D[(word2 >> 6) & 7]); - return; - } - } - *compare1 = dest1; - *compare2 = dest2; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk, 16, ., d) -{ - sint src = MAKE_INT_16(DX); - sint bound = MAKE_INT_16(DY); - - FLAG_Z = ZFLAG_16(src); /* Undocumented */ - FLAG_V = VFLAG_CLEAR; /* Undocumented */ - FLAG_C = CFLAG_CLEAR; /* Undocumented */ - - if(src >= 0 && src <= bound) - { - return; - } - FLAG_N = (src < 0)<<7; - m68ki_exception_trap(EXCEPTION_CHK); -} - - -M68KMAKE_OP(chk, 16, ., .) -{ - sint src = MAKE_INT_16(DX); - sint bound = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); - - FLAG_Z = ZFLAG_16(src); /* Undocumented */ - FLAG_V = VFLAG_CLEAR; /* Undocumented */ - FLAG_C = CFLAG_CLEAR; /* Undocumented */ - - if(src >= 0 && src <= bound) - { - return; - } - FLAG_N = (src < 0)<<7; - m68ki_exception_trap(EXCEPTION_CHK); -} - - -M68KMAKE_OP(chk, 32, ., d) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - sint src = MAKE_INT_32(DX); - sint bound = MAKE_INT_32(DY); - - FLAG_Z = ZFLAG_32(src); /* Undocumented */ - FLAG_V = VFLAG_CLEAR; /* Undocumented */ - FLAG_C = CFLAG_CLEAR; /* Undocumented */ - - if(src >= 0 && src <= bound) - { - return; - } - FLAG_N = (src < 0)<<7; - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - sint src = MAKE_INT_32(DX); - sint bound = MAKE_INT_32(M68KMAKE_GET_OPER_AY_32); - - FLAG_Z = ZFLAG_32(src); /* Undocumented */ - FLAG_V = VFLAG_CLEAR; /* Undocumented */ - FLAG_C = CFLAG_CLEAR; /* Undocumented */ - - if(src >= 0 && src <= bound) - { - return; - } - FLAG_N = (src < 0)<<7; - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 8, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; - uint ea = EA_PCDI_8(); - sint lower_bound = m68ki_read_pcrel_8(ea); - sint upper_bound = m68ki_read_pcrel_8(ea + 1); - - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - - - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 8, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; - uint ea = EA_PCIX_8(); - sint lower_bound = m68ki_read_pcrel_8(ea); - sint upper_bound = m68ki_read_pcrel_8(ea + 1); - - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => ||, faster operation short circuits - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 8, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; - uint ea = M68KMAKE_GET_EA_AY_8; - sint lower_bound = (int8)m68ki_read_8(ea); - sint upper_bound = (int8)m68ki_read_8(ea + 1); - - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 16, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; - uint ea = EA_PCDI_16(); - sint lower_bound = (int16)m68ki_read_pcrel_16(ea); - sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); - - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 16, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; - uint ea = EA_PCIX_16(); - sint lower_bound = (int16)m68ki_read_pcrel_16(ea); - sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); - - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; - uint ea = M68KMAKE_GET_EA_AY_16; - sint lower_bound = (int16)m68ki_read_16(ea); - sint upper_bound = (int16)m68ki_read_16(ea + 2); - - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 32, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = EA_PCDI_32(); - sint lower_bound = m68ki_read_pcrel_32(ea); - sint upper_bound = m68ki_read_pcrel_32(ea + 4); - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 32, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = EA_PCIX_32(); - sint lower_bound = m68ki_read_32(ea); - sint upper_bound = m68ki_read_32(ea + 4); - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(chk2cmp2, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - // JFF changed the logic. chk2/cmp2 uses signed values, not unsigned - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = M68KMAKE_GET_EA_AY_32; - sint lower_bound = m68ki_read_32(ea); - sint upper_bound = m68ki_read_32(ea + 4); - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || - - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - - if(COND_CS() && BIT_B(word2)) - m68ki_exception_trap(EXCEPTION_CHK); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(clr, 8, ., d) -{ - DY &= 0xffffff00; - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(clr, 8, ., .) -{ - m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0); - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(clr, 16, ., d) -{ - DY &= 0xffff0000; - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(clr, 16, ., .) -{ - m68ki_write_16(M68KMAKE_GET_EA_AY_16, 0); - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(clr, 32, ., d) -{ - DY = 0; - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(clr, 32, ., .) -{ - m68ki_write_32(M68KMAKE_GET_EA_AY_32, 0); - - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; -} - - -M68KMAKE_OP(cmp, 8, ., d) -{ - uint src = MASK_OUT_ABOVE_8(DY); - uint dst = MASK_OUT_ABOVE_8(DX); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmp, 8, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_8; - uint dst = MASK_OUT_ABOVE_8(DX); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmp, 16, ., d) -{ - uint src = MASK_OUT_ABOVE_16(DY); - uint dst = MASK_OUT_ABOVE_16(DX); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmp, 16, ., a) -{ - uint src = MASK_OUT_ABOVE_16(AY); - uint dst = MASK_OUT_ABOVE_16(DX); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmp, 16, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_16; - uint dst = MASK_OUT_ABOVE_16(DX); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmp, 32, ., d) -{ - uint src = DY; - uint dst = DX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmp, 32, ., a) -{ - uint src = AY; - uint dst = DX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmp, 32, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_32; - uint dst = DX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 16, ., d) -{ - uint src = MAKE_INT_16(DY); - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 16, ., a) -{ - uint src = MAKE_INT_16(AY); - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 16, ., .) -{ - uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 32, ., d) -{ - uint src = DY; - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 32, ., a) -{ - uint src = AY; - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpa, 32, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_32; - uint dst = AX; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpi, 8, ., d) -{ - uint src = OPER_I_8(); - uint dst = MASK_OUT_ABOVE_8(DY); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpi, 8, ., .) -{ - uint src = OPER_I_8(); - uint dst = M68KMAKE_GET_OPER_AY_8; - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpi, 8, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_8(); - uint dst = OPER_PCDI_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpi, 8, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_8(); - uint dst = OPER_PCIX_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpi, 16, ., d) -{ - uint src = OPER_I_16(); - uint dst = MASK_OUT_ABOVE_16(DY); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmpi, 16, ., .) -{ - uint src = OPER_I_16(); - uint dst = M68KMAKE_GET_OPER_AY_16; - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmpi, 16, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_16(); - uint dst = OPER_PCDI_16(); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpi, 16, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_16(); - uint dst = OPER_PCIX_16(); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpi, 32, ., d) -{ - uint src = OPER_I_32(); - uint dst = DY; - uint res = dst - src; - - m68ki_cmpild_callback(src, REG_IR & 7); /* auto-disable (see m68kcpu.h) */ - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpi, 32, ., .) -{ - uint src = OPER_I_32(); - uint dst = M68KMAKE_GET_OPER_AY_32; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cmpi, 32, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_32(); - uint dst = OPER_PCDI_32(); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpi, 32, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_I_32(); - uint dst = OPER_PCIX_32(); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(cmpm, 8, ., ax7) -{ - uint src = OPER_AY_PI_8(); - uint dst = OPER_A7_PI_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpm, 8, ., ay7) -{ - uint src = OPER_A7_PI_8(); - uint dst = OPER_AX_PI_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpm, 8, ., axy7) -{ - uint src = OPER_A7_PI_8(); - uint dst = OPER_A7_PI_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpm, 8, ., .) -{ - uint src = OPER_AY_PI_8(); - uint dst = OPER_AX_PI_8(); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_C = CFLAG_8(res); -} - - -M68KMAKE_OP(cmpm, 16, ., .) -{ - uint src = OPER_AY_PI_16(); - uint dst = OPER_AX_PI_16(); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_C = CFLAG_16(res); -} - - -M68KMAKE_OP(cmpm, 32, ., .) -{ - uint src = OPER_AY_PI_32(); - uint dst = OPER_AX_PI_32(); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_C = CFLAG_SUB_32(src, dst, res); -} - - -M68KMAKE_OP(cpbcc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(cpdbcc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(cpgen, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(cpscc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(cptrapcc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - // JFF: unsupported, but at least if the trap doesn't occur, app should still work, so at least PC increase is correct - REG_PC += 4; - return; - } - m68ki_exception_1111(); -} - - -M68KMAKE_OP(dbt, 16, ., .) -{ - REG_PC += 2; -} - - -M68KMAKE_OP(dbf, 16, ., .) -{ - uint* r_dst = &DY; - uint res = MASK_OUT_ABOVE_16(*r_dst - 1); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - if(res != 0xffff) - { - uint offset = OPER_I_16(); - REG_PC -= 2; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_16(offset); - USE_CYCLES(CYC_DBCC_F_NOEXP); - return; - } - REG_PC += 2; - USE_CYCLES(CYC_DBCC_F_EXP); -} - - -M68KMAKE_OP(dbcc, 16, ., .) -{ - if(M68KMAKE_NOT_CC) - { - uint* r_dst = &DY; - uint res = MASK_OUT_ABOVE_16(*r_dst - 1); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - if(res != 0xffff) - { - uint offset = OPER_I_16(); - REG_PC -= 2; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_16(offset); - USE_CYCLES(CYC_DBCC_F_NOEXP); - return; - } - REG_PC += 2; - USE_CYCLES(CYC_DBCC_F_EXP); - return; - } - REG_PC += 2; -} - - -M68KMAKE_OP(divs, 16, ., d) -{ - uint* r_dst = &DX; - sint src = MAKE_INT_16(DY); - sint quotient; - sint remainder; - - if(src != 0) - { - if((uint32)*r_dst == 0x80000000 && src == -1) - { - FLAG_Z = 0; - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = 0; - return; - } - - quotient = MAKE_INT_32(*r_dst) / src; - remainder = MAKE_INT_32(*r_dst) % src; - - if(quotient == MAKE_INT_16(quotient)) - { - FLAG_Z = quotient; - FLAG_N = NFLAG_16(quotient); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); - return; - } - FLAG_V = VFLAG_SET; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); -} - - -M68KMAKE_OP(divs, 16, ., .) -{ - uint* r_dst = &DX; - sint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); - sint quotient; - sint remainder; - - if(src != 0) - { - if((uint32)*r_dst == 0x80000000 && src == -1) - { - FLAG_Z = 0; - FLAG_N = NFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = 0; - return; - } - - quotient = MAKE_INT_32(*r_dst) / src; - remainder = MAKE_INT_32(*r_dst) % src; - - if(quotient == MAKE_INT_16(quotient)) - { - FLAG_Z = quotient; - FLAG_N = NFLAG_16(quotient); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); - return; - } - FLAG_V = VFLAG_SET; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); -} - - -M68KMAKE_OP(divu, 16, ., d) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(DY); - - if(src != 0) - { - uint quotient = *r_dst / src; - uint remainder = *r_dst % src; - - if(quotient < 0x10000) - { - FLAG_Z = quotient; - FLAG_N = NFLAG_16(quotient); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); - return; - } - FLAG_V = VFLAG_SET; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); -} - - -M68KMAKE_OP(divu, 16, ., .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_16; - - if(src != 0) - { - uint quotient = *r_dst / src; - uint remainder = *r_dst % src; - - if(quotient < 0x10000) - { - FLAG_Z = quotient; - FLAG_N = NFLAG_16(quotient); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); - return; - } - FLAG_V = VFLAG_SET; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); -} - - -M68KMAKE_OP(divl, 32, ., d) -{ -#if M68K_USE_64_BIT - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint64 divisor = DY; - uint64 dividend = 0; - uint64 quotient = 0; - uint64 remainder = 0; - - if(divisor != 0) - { - if(BIT_A(word2)) /* 64 bit */ - { - dividend = REG_D[word2 & 7]; - dividend <<= 32; - dividend |= REG_D[(word2 >> 12) & 7]; - - if(BIT_B(word2)) /* signed */ - { - quotient = (uint64)((sint64)dividend / (sint64)((sint32)divisor)); - remainder = (uint64)((sint64)dividend % (sint64)((sint32)divisor)); - if((sint64)quotient != (sint64)((sint32)quotient)) - { - FLAG_V = VFLAG_SET; - return; - } - } - else /* unsigned */ - { - quotient = dividend / divisor; - if(quotient > 0xffffffff) - { - FLAG_V = VFLAG_SET; - return; - } - remainder = dividend % divisor; - } - } - else /* 32 bit */ - { - dividend = REG_D[(word2 >> 12) & 7]; - if(BIT_B(word2)) /* signed */ - { - quotient = (uint64)((sint64)((sint32)dividend) / (sint64)((sint32)divisor)); - remainder = (uint64)((sint64)((sint32)dividend) % (sint64)((sint32)divisor)); - } - else /* unsigned */ - { - quotient = dividend / divisor; - remainder = dividend % divisor; - } - } - - REG_D[word2 & 7] = remainder; - REG_D[(word2 >> 12) & 7] = quotient; - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); - return; - } - m68ki_exception_illegal(); - -#else - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint divisor = DY; - uint dividend_hi = REG_D[word2 & 7]; - uint dividend_lo = REG_D[(word2 >> 12) & 7]; - uint quotient = 0; - uint remainder = 0; - uint dividend_neg = 0; - uint divisor_neg = 0; - sint i; - uint overflow; - - if(divisor != 0) - { - /* quad / long : long quotient, long remainder */ - if(BIT_A(word2)) - { - if(BIT_B(word2)) /* signed */ - { - /* special case in signed divide */ - if(dividend_hi == 0 && dividend_lo == 0x80000000 && divisor == 0xffffffff) - { - REG_D[word2 & 7] = 0; - REG_D[(word2 >> 12) & 7] = 0x80000000; - - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - if(GET_MSB_32(dividend_hi)) - { - dividend_neg = 1; - dividend_hi = (uint)MASK_OUT_ABOVE_32((-(sint)dividend_hi) - (dividend_lo != 0)); - dividend_lo = (uint)MASK_OUT_ABOVE_32(-(sint)dividend_lo); - } - if(GET_MSB_32(divisor)) - { - divisor_neg = 1; - divisor = (uint)MASK_OUT_ABOVE_32(-(sint)divisor); - - } - } - - /* if the upper long is greater than the divisor, we're overflowing. */ - if(dividend_hi >= divisor) - { - FLAG_V = VFLAG_SET; - return; - } - - for(i = 31; i >= 0; i--) - { - quotient <<= 1; - remainder = (remainder << 1) + ((dividend_hi >> i) & 1); - if(remainder >= divisor) - { - remainder -= divisor; - quotient++; - } - } - for(i = 31; i >= 0; i--) - { - quotient <<= 1; - overflow = GET_MSB_32(remainder); - remainder = (remainder << 1) + ((dividend_lo >> i) & 1); - if(remainder >= divisor || overflow) - { - remainder -= divisor; - quotient++; - } - } - - if(BIT_B(word2)) /* signed */ - { - if(quotient > 0x7fffffff) - { - FLAG_V = VFLAG_SET; - return; - } - if(dividend_neg) - { - remainder = (uint)MASK_OUT_ABOVE_32(-(sint)remainder); - quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); - } - if(divisor_neg) - quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); - } - - REG_D[word2 & 7] = remainder; - REG_D[(word2 >> 12) & 7] = quotient; - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - - /* long / long: long quotient, maybe long remainder */ - if(BIT_B(word2)) /* signed */ - { - /* Special case in divide */ - if(dividend_lo == 0x80000000 && divisor == 0xffffffff) - { - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - REG_D[(word2 >> 12) & 7] = 0x80000000; - REG_D[word2 & 7] = 0; - return; - } - REG_D[word2 & 7] = MAKE_INT_32(dividend_lo) % MAKE_INT_32(divisor); - quotient = REG_D[(word2 >> 12) & 7] = MAKE_INT_32(dividend_lo) / MAKE_INT_32(divisor); - } - else - { - REG_D[word2 & 7] = MASK_OUT_ABOVE_32(dividend_lo) % MASK_OUT_ABOVE_32(divisor); - quotient = REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(dividend_lo) / MASK_OUT_ABOVE_32(divisor); - } - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); - return; - } - m68ki_exception_illegal(); - -#endif -} - - -M68KMAKE_OP(divl, 32, ., .) -{ -#if M68K_USE_64_BIT - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint64 divisor = M68KMAKE_GET_OPER_AY_32; - uint64 dividend = 0; - uint64 quotient = 0; - uint64 remainder = 0; - - if(divisor != 0) - { - if(BIT_A(word2)) /* 64 bit */ - { - dividend = REG_D[word2 & 7]; - dividend <<= 32; - dividend |= REG_D[(word2 >> 12) & 7]; - - if(BIT_B(word2)) /* signed */ - { - quotient = (uint64)((sint64)dividend / (sint64)((sint32)divisor)); - remainder = (uint64)((sint64)dividend % (sint64)((sint32)divisor)); - if((sint64)quotient != (sint64)((sint32)quotient)) - { - FLAG_V = VFLAG_SET; - return; - } - } - else /* unsigned */ - { - quotient = dividend / divisor; - if(quotient > 0xffffffff) - { - FLAG_V = VFLAG_SET; - return; - } - remainder = dividend % divisor; - } - } - else /* 32 bit */ - { - dividend = REG_D[(word2 >> 12) & 7]; - if(BIT_B(word2)) /* signed */ - { - quotient = (uint64)((sint64)((sint32)dividend) / (sint64)((sint32)divisor)); - remainder = (uint64)((sint64)((sint32)dividend) % (sint64)((sint32)divisor)); - } - else /* unsigned */ - { - quotient = dividend / divisor; - remainder = dividend % divisor; - } - } - - REG_D[word2 & 7] = remainder; - REG_D[(word2 >> 12) & 7] = quotient; - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); - return; - } - m68ki_exception_illegal(); - -#else - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint divisor = M68KMAKE_GET_OPER_AY_32; - uint dividend_hi = REG_D[word2 & 7]; - uint dividend_lo = REG_D[(word2 >> 12) & 7]; - uint quotient = 0; - uint remainder = 0; - uint dividend_neg = 0; - uint divisor_neg = 0; - sint i; - uint overflow; - - if(divisor != 0) - { - /* quad / long : long quotient, long remainder */ - if(BIT_A(word2)) - { - if(BIT_B(word2)) /* signed */ - { - /* special case in signed divide */ - if(dividend_hi == 0 && dividend_lo == 0x80000000 && divisor == 0xffffffff) - { - REG_D[word2 & 7] = 0; - REG_D[(word2 >> 12) & 7] = 0x80000000; - - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - if(GET_MSB_32(dividend_hi)) - { - dividend_neg = 1; - dividend_hi = (uint)MASK_OUT_ABOVE_32((-(sint)dividend_hi) - (dividend_lo != 0)); - dividend_lo = (uint)MASK_OUT_ABOVE_32(-(sint)dividend_lo); - } - if(GET_MSB_32(divisor)) - { - divisor_neg = 1; - divisor = (uint)MASK_OUT_ABOVE_32(-(sint)divisor); - - } - } - - /* if the upper long is greater than the divisor, we're overflowing. */ - if(dividend_hi >= divisor) - { - FLAG_V = VFLAG_SET; - return; - } - - for(i = 31; i >= 0; i--) - { - quotient <<= 1; - remainder = (remainder << 1) + ((dividend_hi >> i) & 1); - if(remainder >= divisor) - { - remainder -= divisor; - quotient++; - } - } - for(i = 31; i >= 0; i--) - { - quotient <<= 1; - overflow = GET_MSB_32(remainder); - remainder = (remainder << 1) + ((dividend_lo >> i) & 1); - if(remainder >= divisor || overflow) - { - remainder -= divisor; - quotient++; - } - } - - if(BIT_B(word2)) /* signed */ - { - if(quotient > 0x7fffffff) - { - FLAG_V = VFLAG_SET; - return; - } - if(dividend_neg) - { - remainder = (uint)MASK_OUT_ABOVE_32(-(sint)remainder); - quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); - } - if(divisor_neg) - quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); - } - - REG_D[word2 & 7] = remainder; - REG_D[(word2 >> 12) & 7] = quotient; - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - - /* long / long: long quotient, maybe long remainder */ - if(BIT_B(word2)) /* signed */ - { - /* Special case in divide */ - if(dividend_lo == 0x80000000 && divisor == 0xffffffff) - { - FLAG_N = NFLAG_SET; - FLAG_Z = ZFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - REG_D[(word2 >> 12) & 7] = 0x80000000; - REG_D[word2 & 7] = 0; - return; - } - REG_D[word2 & 7] = MAKE_INT_32(dividend_lo) % MAKE_INT_32(divisor); - quotient = REG_D[(word2 >> 12) & 7] = MAKE_INT_32(dividend_lo) / MAKE_INT_32(divisor); - } - else - { - REG_D[word2 & 7] = MASK_OUT_ABOVE_32(dividend_lo) % MASK_OUT_ABOVE_32(divisor); - quotient = REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(dividend_lo) / MASK_OUT_ABOVE_32(divisor); - } - - FLAG_N = NFLAG_32(quotient); - FLAG_Z = quotient; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); - return; - } - m68ki_exception_illegal(); - -#endif -} - - -M68KMAKE_OP(eor, 8, ., d) -{ - uint res = MASK_OUT_ABOVE_8(DY ^= MASK_OUT_ABOVE_8(DX)); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eor, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eor, 16, ., d) -{ - uint res = MASK_OUT_ABOVE_16(DY ^= MASK_OUT_ABOVE_16(DX)); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eor, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eor, 32, ., d) -{ - uint res = DY ^= DX; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eor, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = DX ^ m68ki_read_32(ea); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 8, ., d) -{ - uint res = MASK_OUT_ABOVE_8(DY ^= OPER_I_8()); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 8, ., .) -{ - uint src = OPER_I_8(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = src ^ m68ki_read_8(ea); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 16, ., d) -{ - uint res = MASK_OUT_ABOVE_16(DY ^= OPER_I_16()); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 16, ., .) -{ - uint src = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = src ^ m68ki_read_16(ea); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 32, ., d) -{ - uint res = DY ^= OPER_I_32(); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 32, ., .) -{ - uint src = OPER_I_32(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = src ^ m68ki_read_32(ea); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(eori, 16, toc, .) -{ - m68ki_set_ccr(m68ki_get_ccr() ^ OPER_I_8()); -} - - -M68KMAKE_OP(eori, 16, tos, .) -{ - if(FLAG_S) - { - uint src = OPER_I_16(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_set_sr(m68ki_get_sr() ^ src); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(exg, 32, dd, .) -{ - uint* reg_a = &DX; - uint* reg_b = &DY; - uint tmp = *reg_a; - *reg_a = *reg_b; - *reg_b = tmp; -} - - -M68KMAKE_OP(exg, 32, aa, .) -{ - uint* reg_a = &AX; - uint* reg_b = &AY; - uint tmp = *reg_a; - *reg_a = *reg_b; - *reg_b = tmp; -} - - -M68KMAKE_OP(exg, 32, da, .) -{ - uint* reg_a = &DX; - uint* reg_b = &AY; - uint tmp = *reg_a; - *reg_a = *reg_b; - *reg_b = tmp; -} - - -M68KMAKE_OP(ext, 16, ., .) -{ - uint* r_dst = &DY; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | MASK_OUT_ABOVE_8(*r_dst) | (GET_MSB_8(*r_dst) ? 0xff00 : 0); - - FLAG_N = NFLAG_16(*r_dst); - FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(ext, 32, ., .) -{ - uint* r_dst = &DY; - - *r_dst = MASK_OUT_ABOVE_16(*r_dst) | (GET_MSB_16(*r_dst) ? 0xffff0000 : 0); - - FLAG_N = NFLAG_32(*r_dst); - FLAG_Z = *r_dst; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(extb, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint* r_dst = &DY; - - *r_dst = MASK_OUT_ABOVE_8(*r_dst) | (GET_MSB_8(*r_dst) ? 0xffffff00 : 0); - - FLAG_N = NFLAG_32(*r_dst); - FLAG_Z = *r_dst; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(illegal, 0, ., .) -{ - m68ki_exception_illegal(); -} - -M68KMAKE_OP(jmp, 32, ., .) -{ - m68ki_jump(M68KMAKE_GET_EA_AY_32); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); -} - - -M68KMAKE_OP(jsr, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - m68ki_jump(ea); -} - - -M68KMAKE_OP(lea, 32, ., .) -{ - AX = M68KMAKE_GET_EA_AY_32; -} - - -M68KMAKE_OP(link, 16, ., a7) -{ - REG_A[7] -= 4; - m68ki_write_32(REG_A[7], REG_A[7]); - REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); -} - - -M68KMAKE_OP(link, 16, ., .) -{ - uint* r_dst = &AY; - - m68ki_push_32(*r_dst); - *r_dst = REG_A[7]; - REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); -} - - -M68KMAKE_OP(link, 32, ., a7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_A[7] -= 4; - m68ki_write_32(REG_A[7], REG_A[7]); - REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32()); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(link, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint* r_dst = &AY; - - m68ki_push_32(*r_dst); - *r_dst = REG_A[7]; - REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32()); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(lsr, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = src >> shift; - - if(shift != 0) - USE_CYCLES(shift<> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> (shift - 1))<<8; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst &= 0xffff0000; - FLAG_X = XFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsr, 32, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = *r_dst; - uint res = src >> shift; - - if(shift != 0) - { - USE_CYCLES(shift<> (shift - 1))<<8; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst = 0; - FLAG_X = FLAG_C = (shift == 32 ? GET_MSB_32(src)>>23 : 0); - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsr, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = src >> 1; - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_CLEAR; - FLAG_Z = res; - FLAG_C = FLAG_X = src << 8; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsl, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = MASK_OUT_ABOVE_8(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = MASK_OUT_ABOVE_16(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> (8-shift); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsl, 32, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32(src << shift); - - if(shift != 0) - USE_CYCLES(shift<> (24-shift); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsl, 8, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = MASK_OUT_ABOVE_8(src << shift); - - if(shift != 0) - { - USE_CYCLES(shift<> 8; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst &= 0xffff0000; - FLAG_X = XFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsl, 32, r, .) -{ - uint* r_dst = &DY; - uint shift = DX & 0x3f; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32(src << shift); - - if(shift != 0) - { - USE_CYCLES(shift<> (32 - shift)) << 8; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - *r_dst = 0; - FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; - FLAG_N = NFLAG_CLEAR; - FLAG_Z = ZFLAG_SET; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(lsl, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = MASK_OUT_ABOVE_16(src << 1); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_X = FLAG_C = src >> 7; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, d, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, d, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, ai, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AX_AI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, ai, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AX_AI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pi7, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_A7_PI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pi, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AX_PI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pi7, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_A7_PI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pi, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AX_PI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pd7, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_A7_PD_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pd, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AX_PD_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pd7, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_A7_PD_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, pd, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AX_PD_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, di, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AX_DI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, di, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AX_DI_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, ix, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AX_IX_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, ix, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AX_IX_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, aw, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AW_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, aw, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AW_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, al, d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - uint ea = EA_AL_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 8, al, .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - uint ea = EA_AL_8(); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, d, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, d, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, d, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ai, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AX_AI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ai, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AX_AI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ai, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AX_AI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pi, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AX_PI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pi, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AX_PI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pi, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AX_PI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pd, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AX_PD_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pd, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AX_PD_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, pd, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AX_PD_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, di, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AX_DI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, di, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AX_DI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, di, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AX_DI_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ix, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AX_IX_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ix, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AX_IX_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, ix, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AX_IX_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, aw, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AW_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, aw, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AW_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, aw, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AW_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, al, d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - uint ea = EA_AL_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, al, a) -{ - uint res = MASK_OUT_ABOVE_16(AY); - uint ea = EA_AL_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 16, al, .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - uint ea = EA_AL_16(); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, d, d) -{ - uint res = DY; - uint* r_dst = &DX; - - *r_dst = res; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, d, a) -{ - uint res = AY; - uint* r_dst = &DX; - - *r_dst = res; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, d, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint* r_dst = &DX; - - *r_dst = res; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ai, d) -{ - uint res = DY; - uint ea = EA_AX_AI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ai, a) -{ - uint res = AY; - uint ea = EA_AX_AI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ai, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AX_AI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pi, d) -{ - uint res = DY; - uint ea = EA_AX_PI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pi, a) -{ - uint res = AY; - uint ea = EA_AX_PI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pi, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AX_PI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pd, d) -{ - uint res = DY; - uint ea = EA_AX_PD_32(); - - m68ki_write_16(ea+2, res & 0xFFFF ); - m68ki_write_16(ea, (res >> 16) & 0xFFFF ); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pd, a) -{ - uint res = AY; - uint ea = EA_AX_PD_32(); - - m68ki_write_16(ea+2, res & 0xFFFF ); - m68ki_write_16(ea, (res >> 16) & 0xFFFF ); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, pd, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AX_PD_32(); - - m68ki_write_16(ea+2, res & 0xFFFF ); - m68ki_write_16(ea, (res >> 16) & 0xFFFF ); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, di, d) -{ - uint res = DY; - uint ea = EA_AX_DI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, di, a) -{ - uint res = AY; - uint ea = EA_AX_DI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, di, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AX_DI_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ix, d) -{ - uint res = DY; - uint ea = EA_AX_IX_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ix, a) -{ - uint res = AY; - uint ea = EA_AX_IX_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, ix, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AX_IX_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, aw, d) -{ - uint res = DY; - uint ea = EA_AW_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, aw, a) -{ - uint res = AY; - uint ea = EA_AW_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, aw, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AW_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, al, d) -{ - uint res = DY; - uint ea = EA_AL_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, al, a) -{ - uint res = AY; - uint ea = EA_AL_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move, 32, al, .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - uint ea = EA_AL_32(); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(movea, 16, ., d) -{ - AX = MAKE_INT_16(DY); -} - - -M68KMAKE_OP(movea, 16, ., a) -{ - AX = MAKE_INT_16(AY); -} - - -M68KMAKE_OP(movea, 16, ., .) -{ - AX = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); -} - - -M68KMAKE_OP(movea, 32, ., d) -{ - AX = DY; -} - - -M68KMAKE_OP(movea, 32, ., a) -{ - AX = AY; -} - - -M68KMAKE_OP(movea, 32, ., .) -{ - AX = M68KMAKE_GET_OPER_AY_32; -} - - -M68KMAKE_OP(move, 16, frc, d) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - DY = MASK_OUT_BELOW_16(DY) | m68ki_get_ccr(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(move, 16, frc, .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - m68ki_write_16(M68KMAKE_GET_EA_AY_16, m68ki_get_ccr()); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(move, 16, toc, d) -{ - m68ki_set_ccr(DY); -} - - -M68KMAKE_OP(move, 16, toc, .) -{ - m68ki_set_ccr(M68KMAKE_GET_OPER_AY_16); -} - - -M68KMAKE_OP(move, 16, frs, d) -{ - if(CPU_TYPE_IS_000(CPU_TYPE) || FLAG_S) /* NS990408 */ - { - DY = MASK_OUT_BELOW_16(DY) | m68ki_get_sr(); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(move, 16, frs, .) -{ - if(CPU_TYPE_IS_000(CPU_TYPE) || FLAG_S) /* NS990408 */ - { - uint ea = M68KMAKE_GET_EA_AY_16; - m68ki_write_16(ea, m68ki_get_sr()); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(move, 16, tos, d) -{ - if(FLAG_S) - { - m68ki_set_sr(DY); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(move, 16, tos, .) -{ - if(FLAG_S) - { - uint new_sr = M68KMAKE_GET_OPER_AY_16; - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_set_sr(new_sr); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(move, 32, fru, .) -{ - if(FLAG_S) - { - AY = REG_USP; - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(move, 32, tou, .) -{ - if(FLAG_S) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - REG_USP = AY; - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(movec, 32, cr, .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - if(FLAG_S) - { - uint word2 = OPER_I_16(); - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - switch (word2 & 0xfff) - { - case 0x000: /* SFC */ - REG_DA[(word2 >> 12) & 15] = REG_SFC; - return; - case 0x001: /* DFC */ - REG_DA[(word2 >> 12) & 15] = REG_DFC; - return; - case 0x002: /* CACR */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_DA[(word2 >> 12) & 15] = REG_CACR; - return; - } - return; - case 0x800: /* USP */ - REG_DA[(word2 >> 12) & 15] = REG_USP; - return; - case 0x801: /* VBR */ - REG_DA[(word2 >> 12) & 15] = REG_VBR; - return; - case 0x802: /* CAAR */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_DA[(word2 >> 12) & 15] = REG_CAAR; - return; - } - m68ki_exception_illegal(); - break; - case 0x803: /* MSP */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_DA[(word2 >> 12) & 15] = FLAG_M ? REG_SP : REG_MSP; - return; - } - m68ki_exception_illegal(); - return; - case 0x804: /* ISP */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_DA[(word2 >> 12) & 15] = FLAG_M ? REG_ISP : REG_SP; - return; - } - m68ki_exception_illegal(); - return; - case 0x003: /* TC */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x004: /* ITT0 */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x005: /* ITT1 */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x006: /* DTT0 */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x007: /* DTT1 */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x805: /* MMUSR */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x806: /* URP */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x807: /* SRP */ - if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - default: - m68ki_exception_illegal(); - return; - } - } - m68ki_exception_privilege_violation(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(movec, 32, rc, .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - if(FLAG_S) - { - uint word2 = OPER_I_16(); - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - switch (word2 & 0xfff) - { - case 0x000: /* SFC */ - REG_SFC = REG_DA[(word2 >> 12) & 15] & 7; - return; - case 0x001: /* DFC */ - REG_DFC = REG_DA[(word2 >> 12) & 15] & 7; - return; - case 0x002: /* CACR */ - /* Only EC020 and later have CACR */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* 68030 can write all bits except 5-7, 040 can write all */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - REG_CACR = REG_DA[(word2 >> 12) & 15]; - } - else if (CPU_TYPE_IS_030_PLUS(CPU_TYPE)) - { - REG_CACR = REG_DA[(word2 >> 12) & 15] & 0xff1f; - } - else - { - REG_CACR = REG_DA[(word2 >> 12) & 15] & 0x0f; - } - return; - } - m68ki_exception_illegal(); - return; - case 0x800: /* USP */ - REG_USP = REG_DA[(word2 >> 12) & 15]; - return; - case 0x801: /* VBR */ - REG_VBR = REG_DA[(word2 >> 12) & 15]; - return; - case 0x802: /* CAAR */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_CAAR = REG_DA[(word2 >> 12) & 15]; - return; - } - m68ki_exception_illegal(); - return; - case 0x803: /* MSP */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* we are in supervisor mode so just check for M flag */ - if(!FLAG_M) - { - REG_MSP = REG_DA[(word2 >> 12) & 15]; - return; - } - REG_SP = REG_DA[(word2 >> 12) & 15]; - return; - } - m68ki_exception_illegal(); - return; - case 0x804: /* ISP */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - if(!FLAG_M) - { - REG_SP = REG_DA[(word2 >> 12) & 15]; - return; - } - REG_ISP = REG_DA[(word2 >> 12) & 15]; - return; - } - m68ki_exception_illegal(); - return; - case 0x003: /* TC */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x004: /* ITT0 */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x005: /* ITT1 */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x006: /* DTT0 */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x007: /* DTT1 */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x805: /* MMUSR */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x806: /* URP */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - case 0x807: /* SRP */ - if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) - { - /* TODO */ - return; - } - m68ki_exception_illegal(); - return; - default: - m68ki_exception_illegal(); - return; - } - } - m68ki_exception_privilege_violation(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(movem, 16, re, pd) -{ - uint i = 0; - uint register_list = OPER_I_16(); - uint ea = AY; - uint count = 0; - - for(; i < 16; i++) - if(register_list & (1 << i)) - { - ea -= 2; - m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[15-i])); - count++; - } - AY = ea; - - USE_CYCLES(count<> 16) & 0xFFFF ); - count++; - } - AY = ea; - - USE_CYCLES(count<> 8)); - m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); -} - - -M68KMAKE_OP(movep, 32, re, .) -{ - uint ea = EA_AY_DI_32(); - uint src = DX; - - m68ki_write_8(ea, MASK_OUT_ABOVE_8(src >> 24)); - m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 16)); - m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 8)); - m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); -} - - -M68KMAKE_OP(movep, 16, er, .) -{ - uint ea = EA_AY_DI_16(); - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | ((m68ki_read_8(ea) << 8) + m68ki_read_8(ea + 2)); -} - - -M68KMAKE_OP(movep, 32, er, .) -{ - uint ea = EA_AY_DI_32(); - - DX = (m68ki_read_8(ea) << 24) + (m68ki_read_8(ea + 2) << 16) - + (m68ki_read_8(ea + 4) << 8) + m68ki_read_8(ea + 6); -} - - -M68KMAKE_OP(moves, 8, ., .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - if(FLAG_S) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_8; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(BIT_B(word2)) /* Register to memory */ - { - m68ki_write_8_fc(ea, REG_DFC, MASK_OUT_ABOVE_8(REG_DA[(word2 >> 12) & 15])); - return; - } - if(BIT_F(word2)) /* Memory to address register */ - { - REG_A[(word2 >> 12) & 7] = MAKE_INT_8(m68ki_read_8_fc(ea, REG_SFC)); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - /* Memory to data register */ - REG_D[(word2 >> 12) & 7] = MASK_OUT_BELOW_8(REG_D[(word2 >> 12) & 7]) | m68ki_read_8_fc(ea, REG_SFC); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - m68ki_exception_privilege_violation(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(moves, 16, ., .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - if(FLAG_S) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(BIT_B(word2)) /* Register to memory */ - { - m68ki_write_16_fc(ea, REG_DFC, MASK_OUT_ABOVE_16(REG_DA[(word2 >> 12) & 15])); - return; - } - if(BIT_F(word2)) /* Memory to address register */ - { - REG_A[(word2 >> 12) & 7] = MAKE_INT_16(m68ki_read_16_fc(ea, REG_SFC)); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - /* Memory to data register */ - REG_D[(word2 >> 12) & 7] = MASK_OUT_BELOW_16(REG_D[(word2 >> 12) & 7]) | m68ki_read_16_fc(ea, REG_SFC); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - m68ki_exception_privilege_violation(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(moves, 32, ., .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - if(FLAG_S) - { - uint word2 = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_32; - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(BIT_B(word2)) /* Register to memory */ - { - m68ki_write_32_fc(ea, REG_DFC, REG_DA[(word2 >> 12) & 15]); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - /* Memory to register */ - REG_DA[(word2 >> 12) & 15] = m68ki_read_32_fc(ea, REG_SFC); - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - USE_CYCLES(2); - return; - } - m68ki_exception_privilege_violation(); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(moveq, 32, ., .) -{ - uint res = DX = MAKE_INT_8(MASK_OUT_ABOVE_8(REG_IR)); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(move16, 32, ., .) -{ - uint16 w2 = OPER_I_16(); - int ax = REG_IR & 7; - int ay = (w2 >> 12) & 7; - - m68ki_write_32(REG_A[ay], m68ki_read_32(REG_A[ax])); - m68ki_write_32(REG_A[ay]+4, m68ki_read_32(REG_A[ax]+4)); - m68ki_write_32(REG_A[ay]+8, m68ki_read_32(REG_A[ax]+8)); - m68ki_write_32(REG_A[ay]+12, m68ki_read_32(REG_A[ax]+12)); - - REG_A[ax] += 16; - REG_A[ay] += 16; -} - - -M68KMAKE_OP(muls, 16, ., d) -{ - uint* r_dst = &DX; - uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(DY) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); - - *r_dst = res; - - FLAG_Z = res; - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(muls, 16, ., .) -{ - uint* r_dst = &DX; - uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(M68KMAKE_GET_OPER_AY_16) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); - - *r_dst = res; - - FLAG_Z = res; - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(mulu, 16, ., d) -{ - uint* r_dst = &DX; - uint res = MASK_OUT_ABOVE_16(DY) * MASK_OUT_ABOVE_16(*r_dst); - - *r_dst = res; - - FLAG_Z = res; - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(mulu, 16, ., .) -{ - uint* r_dst = &DX; - uint res = M68KMAKE_GET_OPER_AY_16 * MASK_OUT_ABOVE_16(*r_dst); - - *r_dst = res; - - FLAG_Z = res; - FLAG_N = NFLAG_32(res); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(mull, 32, ., d) -{ -#if M68K_USE_64_BIT - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint64 src = DY; - uint64 dst = REG_D[(word2 >> 12) & 7]; - uint64 res; - - FLAG_C = CFLAG_CLEAR; - - if(BIT_B(word2)) /* signed */ - { - res = (sint64)((sint32)src) * (sint64)((sint32)dst); - if(!BIT_A(word2)) - { - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_N = NFLAG_32(res); - FLAG_V = ((sint64)res != (sint32)res)<<7; - REG_D[(word2 >> 12) & 7] = FLAG_Z; - return; - } - FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); - FLAG_N = NFLAG_64(res); - FLAG_V = VFLAG_CLEAR; - REG_D[word2 & 7] = (res >> 32); - REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); - return; - } - - res = src * dst; - if(!BIT_A(word2)) - { - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_N = NFLAG_32(res); - FLAG_V = (res > 0xffffffff)<<7; - REG_D[(word2 >> 12) & 7] = FLAG_Z; - return; - } - FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); - FLAG_N = NFLAG_64(res); - FLAG_V = VFLAG_CLEAR; - REG_D[word2 & 7] = (res >> 32); - REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); - return; - } - m68ki_exception_illegal(); - -#else - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint src = DY; - uint dst = REG_D[(word2 >> 12) & 7]; - uint neg = GET_MSB_32(src ^ dst); - uint src1; - uint src2; - uint dst1; - uint dst2; - uint r1; - uint r2; - uint r3; - uint r4; - uint lo; - uint hi; - - FLAG_C = CFLAG_CLEAR; - - if(BIT_B(word2)) /* signed */ - { - if(GET_MSB_32(src)) - src = (uint)MASK_OUT_ABOVE_32(-(sint)src); - if(GET_MSB_32(dst)) - dst = (uint)MASK_OUT_ABOVE_32(-(sint)dst); - } - - src1 = MASK_OUT_ABOVE_16(src); - src2 = src>>16; - dst1 = MASK_OUT_ABOVE_16(dst); - dst2 = dst>>16; - - - r1 = src1 * dst1; - r2 = src1 * dst2; - r3 = src2 * dst1; - r4 = src2 * dst2; - - lo = r1 + (MASK_OUT_ABOVE_16(r2)<<16) + (MASK_OUT_ABOVE_16(r3)<<16); - hi = r4 + (r2>>16) + (r3>>16) + (((r1>>16) + MASK_OUT_ABOVE_16(r2) + MASK_OUT_ABOVE_16(r3)) >> 16); - - if(BIT_B(word2) && neg) - { - hi = (uint)MASK_OUT_ABOVE_32((-(sint)hi) - (lo != 0)); - lo = (uint)MASK_OUT_ABOVE_32(-(sint)lo); - } - - if(BIT_A(word2)) - { - REG_D[word2 & 7] = hi; - REG_D[(word2 >> 12) & 7] = lo; - FLAG_N = NFLAG_32(hi); - FLAG_Z = hi | lo; - FLAG_V = VFLAG_CLEAR; - return; - } - - REG_D[(word2 >> 12) & 7] = lo; - FLAG_N = NFLAG_32(lo); - FLAG_Z = lo; - if(BIT_B(word2)) - FLAG_V = (!((GET_MSB_32(lo) && hi == 0xffffffff) || (!GET_MSB_32(lo) && !hi)))<<7; - else - FLAG_V = (hi != 0) << 7; - return; - } - m68ki_exception_illegal(); - -#endif -} - - -M68KMAKE_OP(mull, 32, ., .) -{ -#if M68K_USE_64_BIT - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint64 src = M68KMAKE_GET_OPER_AY_32; - uint64 dst = REG_D[(word2 >> 12) & 7]; - uint64 res; - - FLAG_C = CFLAG_CLEAR; - - if(BIT_B(word2)) /* signed */ - { - res = (sint64)((sint32)src) * (sint64)((sint32)dst); - if(!BIT_A(word2)) - { - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_N = NFLAG_32(res); - FLAG_V = ((sint64)res != (sint32)res)<<7; - REG_D[(word2 >> 12) & 7] = FLAG_Z; - return; - } - FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); - FLAG_N = NFLAG_64(res); - FLAG_V = VFLAG_CLEAR; - REG_D[word2 & 7] = (res >> 32); - REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); - return; - } - - res = src * dst; - if(!BIT_A(word2)) - { - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_N = NFLAG_32(res); - FLAG_V = (res > 0xffffffff)<<7; - REG_D[(word2 >> 12) & 7] = FLAG_Z; - return; - } - FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); - FLAG_N = NFLAG_64(res); - FLAG_V = VFLAG_CLEAR; - REG_D[word2 & 7] = (res >> 32); - REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); - return; - } - m68ki_exception_illegal(); - -#else - - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint word2 = OPER_I_16(); - uint src = M68KMAKE_GET_OPER_AY_32; - uint dst = REG_D[(word2 >> 12) & 7]; - uint neg = GET_MSB_32(src ^ dst); - uint src1; - uint src2; - uint dst1; - uint dst2; - uint r1; - uint r2; - uint r3; - uint r4; - uint lo; - uint hi; - - FLAG_C = CFLAG_CLEAR; - - if(BIT_B(word2)) /* signed */ - { - if(GET_MSB_32(src)) - src = (uint)MASK_OUT_ABOVE_32(-(sint)src); - if(GET_MSB_32(dst)) - dst = (uint)MASK_OUT_ABOVE_32(-(sint)dst); - } - - src1 = MASK_OUT_ABOVE_16(src); - src2 = src>>16; - dst1 = MASK_OUT_ABOVE_16(dst); - dst2 = dst>>16; - - - r1 = src1 * dst1; - r2 = src1 * dst2; - r3 = src2 * dst1; - r4 = src2 * dst2; - - lo = r1 + (MASK_OUT_ABOVE_16(r2)<<16) + (MASK_OUT_ABOVE_16(r3)<<16); - hi = r4 + (r2>>16) + (r3>>16) + (((r1>>16) + MASK_OUT_ABOVE_16(r2) + MASK_OUT_ABOVE_16(r3)) >> 16); - - if(BIT_B(word2) && neg) - { - hi = (uint)MASK_OUT_ABOVE_32((-(sint)hi) - (lo != 0)); - lo = (uint)MASK_OUT_ABOVE_32(-(sint)lo); - } - - if(BIT_A(word2)) - { - REG_D[word2 & 7] = hi; - REG_D[(word2 >> 12) & 7] = lo; - FLAG_N = NFLAG_32(hi); - FLAG_Z = hi | lo; - FLAG_V = VFLAG_CLEAR; - return; - } - - REG_D[(word2 >> 12) & 7] = lo; - FLAG_N = NFLAG_32(lo); - FLAG_Z = lo; - if(BIT_B(word2)) - FLAG_V = (!((GET_MSB_32(lo) && hi == 0xffffffff) || (!GET_MSB_32(lo) && !hi)))<<7; - else - FLAG_V = (hi != 0) << 7; - return; - } - m68ki_exception_illegal(); - -#endif -} - - -M68KMAKE_OP(nbcd, 8, ., d) -{ - uint* r_dst = &DY; - uint dst = *r_dst; - uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); - - if(res != 0x9a) - { - FLAG_V = ~res; /* Undefined V behavior */ - - if((res & 0x0f) == 0xa) - res = (res & 0xf0) + 0x10; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; - - FLAG_Z |= res; - FLAG_C = CFLAG_SET; - FLAG_X = XFLAG_SET; - } - else - { - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_X = XFLAG_CLEAR; - } - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ -} - - -M68KMAKE_OP(nbcd, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); - - if(res != 0x9a) - { - FLAG_V = ~res; /* Undefined V behavior */ - - if((res & 0x0f) == 0xa) - res = (res & 0xf0) + 0x10; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - - m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); - - FLAG_Z |= res; - FLAG_C = CFLAG_SET; - FLAG_X = XFLAG_SET; - } - else - { - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - FLAG_X = XFLAG_CLEAR; - } - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ -} - - -M68KMAKE_OP(neg, 8, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - MASK_OUT_ABOVE_8(*r_dst); - - FLAG_N = NFLAG_8(res); - FLAG_C = FLAG_X = CFLAG_8(res); - FLAG_V = *r_dst & res; - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(neg, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - uint res = 0 - src; - - FLAG_N = NFLAG_8(res); - FLAG_C = FLAG_X = CFLAG_8(res); - FLAG_V = src & res; - FLAG_Z = MASK_OUT_ABOVE_8(res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(neg, 16, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - MASK_OUT_ABOVE_16(*r_dst); - - FLAG_N = NFLAG_16(res); - FLAG_C = FLAG_X = CFLAG_16(res); - FLAG_V = (*r_dst & res)>>8; - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(neg, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = 0 - src; - - FLAG_N = NFLAG_16(res); - FLAG_C = FLAG_X = CFLAG_16(res); - FLAG_V = (src & res)>>8; - FLAG_Z = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(neg, 32, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - *r_dst; - - FLAG_N = NFLAG_32(res); - FLAG_C = FLAG_X = CFLAG_SUB_32(*r_dst, 0, res); - FLAG_V = (*r_dst & res)>>24; - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(neg, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint src = m68ki_read_32(ea); - uint res = 0 - src; - - FLAG_N = NFLAG_32(res); - FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); - FLAG_V = (src & res)>>24; - FLAG_Z = MASK_OUT_ABOVE_32(res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(negx, 8, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - MASK_OUT_ABOVE_8(*r_dst) - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = *r_dst & res; - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; -} - - -M68KMAKE_OP(negx, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = m68ki_read_8(ea); - uint res = 0 - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = src & res; - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(negx, 16, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - MASK_OUT_ABOVE_16(*r_dst) - XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = (*r_dst & res)>>8; - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; -} - - -M68KMAKE_OP(negx, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = (src & res)>>8; - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - m68ki_write_16(ea, res); -} - - -M68KMAKE_OP(negx, 32, ., d) -{ - uint* r_dst = &DY; - uint res = 0 - MASK_OUT_ABOVE_32(*r_dst) - XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(*r_dst, 0, res); - FLAG_V = (*r_dst & res)>>24; - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - *r_dst = res; -} - - -M68KMAKE_OP(negx, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint src = m68ki_read_32(ea); - uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); - FLAG_V = (src & res)>>24; - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - m68ki_write_32(ea, res); -} - - -M68KMAKE_OP(nop, 0, ., .) -{ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ -} - - -M68KMAKE_OP(not, 8, ., d) -{ - uint* r_dst = &DY; - uint res = MASK_OUT_ABOVE_8(~*r_dst); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(not, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(not, 16, ., d) -{ - uint* r_dst = &DY; - uint res = MASK_OUT_ABOVE_16(~*r_dst); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(not, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(not, 32, ., d) -{ - uint* r_dst = &DY; - uint res = *r_dst = MASK_OUT_ABOVE_32(~*r_dst); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(not, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 8, er, d) -{ - uint res = MASK_OUT_ABOVE_8((DX |= MASK_OUT_ABOVE_8(DY))); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 8, er, .) -{ - uint res = MASK_OUT_ABOVE_8((DX |= M68KMAKE_GET_OPER_AY_8)); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 16, er, d) -{ - uint res = MASK_OUT_ABOVE_16((DX |= MASK_OUT_ABOVE_16(DY))); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 16, er, .) -{ - uint res = MASK_OUT_ABOVE_16((DX |= M68KMAKE_GET_OPER_AY_16)); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 32, er, d) -{ - uint res = DX |= DY; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 32, er, .) -{ - uint res = DX |= M68KMAKE_GET_OPER_AY_32; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 8, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 16, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(or, 32, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = DX | m68ki_read_32(ea); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 8, ., d) -{ - uint res = MASK_OUT_ABOVE_8((DY |= OPER_I_8())); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 8, ., .) -{ - uint src = OPER_I_8(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); - - m68ki_write_8(ea, res); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 16, ., d) -{ - uint res = MASK_OUT_ABOVE_16(DY |= OPER_I_16()); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 16, ., .) -{ - uint src = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 32, ., d) -{ - uint res = DY |= OPER_I_32(); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 32, ., .) -{ - uint src = OPER_I_32(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint res = src | m68ki_read_32(ea); - - m68ki_write_32(ea, res); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ori, 16, toc, .) -{ - m68ki_set_ccr(m68ki_get_ccr() | OPER_I_8()); -} - - -M68KMAKE_OP(ori, 16, tos, .) -{ - if(FLAG_S) - { - uint src = OPER_I_16(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_set_sr(m68ki_get_sr() | src); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(pack, 16, rr, .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: DX and DY are reversed in Motorola's docs */ - uint src = DY + OPER_I_16(); - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | ((src >> 4) & 0x00f0) | (src & 0x000f); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(pack, 16, mm, ax7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint ea_src = EA_AY_PD_8(); - uint src = m68ki_read_8(ea_src); - ea_src = EA_AY_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); - - m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(pack, 16, mm, ay7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint ea_src = EA_A7_PD_8(); - uint src = m68ki_read_8(ea_src); - ea_src = EA_A7_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); - - m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(pack, 16, mm, axy7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint ea_src = EA_A7_PD_8(); - uint src = m68ki_read_8(ea_src); - ea_src = EA_A7_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); - - m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(pack, 16, mm, .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint ea_src = EA_AY_PD_8(); - uint src = m68ki_read_8(ea_src); - ea_src = EA_AY_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); - - m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(pea, 32, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - - m68ki_push_32(ea); -} - -M68KMAKE_OP(pflush, 32, ., .) -{ - if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) - { - fprintf(stderr,"68040: unhandled PFLUSH\n"); - return; - } - m68ki_exception_1111(); -} - -M68KMAKE_OP(pmmu, 32, ., .) -{ - if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) - { - m68881_mmu_ops(); - } - else - { - m68ki_exception_1111(); - } -} - -M68KMAKE_OP(reset, 0, ., .) -{ - if(FLAG_S) - { - m68ki_output_reset(); /* auto-disable (see m68kcpu.h) */ - USE_CYCLES(CYC_RESET); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(ror, 8, s, .) -{ - uint* r_dst = &DY; - uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint shift = orig_shift & 7; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = ROR_8(src, shift); - - if(orig_shift != 0) - USE_CYCLES(orig_shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = ROR_16(src, shift); - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint64 src = *r_dst; - uint res = ROR_32(src, shift); - - if(shift != 0) - USE_CYCLES(shift<> ((shift - 1) & 15)) << 8; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ror, 32, r, .) -{ - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - uint shift = orig_shift & 31; - uint64 src = *r_dst; - uint res = ROR_32(src, shift); - - if(orig_shift != 0) - { - USE_CYCLES(orig_shift<> ((shift - 1) & 31)) << 8; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(ror, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = ROR_16(src, 1); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = src << 8; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rol, 8, s, .) -{ - uint* r_dst = &DY; - uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint shift = orig_shift & 7; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = ROL_8(src, shift); - - if(orig_shift != 0) - USE_CYCLES(orig_shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = ROL_16(src, shift); - - if(shift != 0) - USE_CYCLES(shift<> (8-shift); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rol, 32, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint64 src = *r_dst; - uint res = ROL_32(src, shift); - - if(shift != 0) - USE_CYCLES(shift<> (24-shift); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rol, 8, r, .) -{ - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - uint shift = orig_shift & 7; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = ROL_8(src, shift); - - if(orig_shift != 0) - { - USE_CYCLES(orig_shift<> 8; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - FLAG_C = (src & 1)<<8; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_16(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rol, 32, r, .) -{ - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - uint shift = orig_shift & 31; - uint64 src = *r_dst; - uint res = ROL_32(src, shift); - - if(orig_shift != 0) - { - USE_CYCLES(orig_shift<> ((32 - shift) & 0x1f)) << 8; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = CFLAG_CLEAR; - FLAG_N = NFLAG_32(src); - FLAG_Z = src; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rol, 16, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = m68ki_read_16(ea); - uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_C = src >> 7; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxr, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = ROR_9(src | (XFLAG_AS_1() << 8), shift); - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = ROR_17(src | (XFLAG_AS_1() << 16), shift); - - if(shift != 0) - USE_CYCLES(shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxr, 32, s, .) -{ -#if M68K_USE_64_BIT - - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint64 src = *r_dst; - uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); - - if(shift != 0) - USE_CYCLES(shift<> 24; - res = MASK_OUT_ABOVE_32(res); - - *r_dst = res; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - -#else - - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); - uint new_x_flag = src & (1 << (shift - 1)); - - if(shift != 0) - USE_CYCLES(shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = FLAG_X; - FLAG_N = NFLAG_16(*r_dst); - FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxr, 32, r, .) -{ -#if M68K_USE_64_BIT - - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - - if(orig_shift != 0) - { - uint shift = orig_shift % 33; - uint64 src = *r_dst; - uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); - - res = ROR_33_64(res, shift); - - USE_CYCLES(orig_shift<> 24; - res = MASK_OUT_ABOVE_32(res); - - *r_dst = res; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = FLAG_X; - FLAG_N = NFLAG_32(*r_dst); - FLAG_Z = *r_dst; - FLAG_V = VFLAG_CLEAR; - -#else - - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - uint shift = orig_shift % 33; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); - uint new_x_flag = src & (1 << (shift - 1)); - - if(orig_shift != 0) - USE_CYCLES(orig_shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxl, 8, s, .) -{ - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_8(*r_dst); - uint res = ROL_9(src | (XFLAG_AS_1() << 8), shift); - - if(shift != 0) - USE_CYCLES(shift<> 9) - 1) & 7) + 1; - uint src = MASK_OUT_ABOVE_16(*r_dst); - uint res = ROL_17(src | (XFLAG_AS_1() << 16), shift); - - if(shift != 0) - USE_CYCLES(shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxl, 32, s, .) -{ -#if M68K_USE_64_BIT - - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint64 src = *r_dst; - uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); - - if(shift != 0) - USE_CYCLES(shift<> 24; - res = MASK_OUT_ABOVE_32(res); - - *r_dst = res; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - -#else - - uint* r_dst = &DY; - uint shift = (((REG_IR >> 9) - 1) & 7) + 1; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); - uint new_x_flag = src & (1 << (32 - shift)); - - if(shift != 0) - USE_CYCLES(shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = FLAG_X; - FLAG_N = NFLAG_16(*r_dst); - FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(roxl, 32, r, .) -{ -#if M68K_USE_64_BIT - - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - - if(orig_shift != 0) - { - uint shift = orig_shift % 33; - uint64 src = *r_dst; - uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); - - res = ROL_33_64(res, shift); - - USE_CYCLES(orig_shift<> 24; - res = MASK_OUT_ABOVE_32(res); - - *r_dst = res; - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - return; - } - - FLAG_C = FLAG_X; - FLAG_N = NFLAG_32(*r_dst); - FLAG_Z = *r_dst; - FLAG_V = VFLAG_CLEAR; - -#else - - uint* r_dst = &DY; - uint orig_shift = DX & 0x3f; - uint shift = orig_shift % 33; - uint src = *r_dst; - uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); - uint new_x_flag = src & (1 << (32 - shift)); - - if(orig_shift != 0) - USE_CYCLES(orig_shift<> 8; - res = MASK_OUT_ABOVE_16(res); - - m68ki_write_16(ea, res); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(rtd, 32, ., .) -{ - if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) - { - uint new_pc = m68ki_pull_32(); - - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); - m68ki_jump(new_pc); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(rte, 32, ., .) -{ - if(FLAG_S) - { - uint new_sr; - uint new_pc; - uint format_word; - - m68ki_rte_callback(); /* auto-disable (see m68kcpu.h) */ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - - if(CPU_TYPE_IS_000(CPU_TYPE)) - { - new_sr = m68ki_pull_16(); - new_pc = m68ki_pull_32(); - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - - return; - } - - if(CPU_TYPE_IS_010(CPU_TYPE)) - { - format_word = m68ki_read_16(REG_A[7]+6) >> 12; - if(format_word == 0) - { - new_sr = m68ki_pull_16(); - new_pc = m68ki_pull_32(); - m68ki_fake_pull_16(); /* format word */ - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - return; - } else if (format_word == 8) { - /* Format 8 stack frame -- 68010 only. 29 word bus/address error */ - new_sr = m68ki_pull_16(); - new_pc = m68ki_pull_32(); - m68ki_fake_pull_16(); /* format word */ - m68ki_fake_pull_16(); /* special status word */ - m68ki_fake_pull_32(); /* fault address */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* data output buffer */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* data input buffer */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* instruction input buffer */ - m68ki_fake_pull_32(); /* internal information, 16 words */ - m68ki_fake_pull_32(); /* (actually, we use 8 DWORDs) */ - m68ki_fake_pull_32(); - m68ki_fake_pull_32(); - m68ki_fake_pull_32(); - m68ki_fake_pull_32(); - m68ki_fake_pull_32(); - m68ki_fake_pull_32(); - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - return; - } - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - /* Not handling other exception types (9) */ - m68ki_exception_format_error(); - return; - } - - /* Otherwise it's 020 */ -rte_loop: - format_word = m68ki_read_16(REG_A[7]+6) >> 12; - switch(format_word) - { - case 0: /* Normal */ - new_sr = m68ki_pull_16(); - new_pc = m68ki_pull_32(); - m68ki_fake_pull_16(); /* format word */ - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - return; - case 1: /* Throwaway */ - new_sr = m68ki_pull_16(); - m68ki_fake_pull_32(); /* program counter */ - m68ki_fake_pull_16(); /* format word */ - m68ki_set_sr_noint(new_sr); - goto rte_loop; - case 2: /* Trap */ - new_sr = m68ki_pull_16(); - new_pc = m68ki_pull_32(); - m68ki_fake_pull_16(); /* format word */ - m68ki_fake_pull_32(); /* address */ - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - return; - } - /* Not handling long or short bus fault */ - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; - m68ki_exception_format_error(); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(rtm, 32, ., .) -{ - if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(rtr, 32, ., .) -{ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_set_ccr(m68ki_pull_16()); - m68ki_jump(m68ki_pull_32()); -} - - -M68KMAKE_OP(rts, 32, ., .) -{ - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_jump(m68ki_pull_32()); -} - - -M68KMAKE_OP(sbcd, 8, rr, .) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; - res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res += 0xa0; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; -} - - -M68KMAKE_OP(sbcd, 8, mm, ax7) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; - res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res += 0xa0; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(sbcd, 8, mm, ay7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; - res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res += 0xa0; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(sbcd, 8, mm, axy7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; - res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res += 0xa0; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(sbcd, 8, mm, .) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; - res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) - res += 0xa0; - - res = MASK_OUT_ABOVE_8(res); - - FLAG_V &= res; /* Undefined V behavior part II */ - FLAG_N = NFLAG_8(res); /* Undefined N behavior */ - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(st, 8, ., d) -{ - DY |= 0xff; -} - - -M68KMAKE_OP(st, 8, ., .) -{ - m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0xff); -} - - -M68KMAKE_OP(sf, 8, ., d) -{ - DY &= 0xffffff00; -} - - -M68KMAKE_OP(sf, 8, ., .) -{ - m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0); -} - - -M68KMAKE_OP(scc, 8, ., d) -{ - if(M68KMAKE_CC) - { - DY |= 0xff; - USE_CYCLES(CYC_SCC_R_TRUE); - return; - } - DY &= 0xffffff00; -} - - -M68KMAKE_OP(scc, 8, ., .) -{ - m68ki_write_8(M68KMAKE_GET_EA_AY_8, M68KMAKE_CC ? 0xff : 0); -} - - -M68KMAKE_OP(stop, 0, ., .) -{ - if(FLAG_S) - { - uint new_sr = OPER_I_16(); - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - CPU_STOPPED |= STOP_LEVEL_STOP; - m68ki_set_sr(new_sr); - if(m68ki_remaining_cycles >= CYC_INSTRUCTION[REG_IR]) - m68ki_remaining_cycles = CYC_INSTRUCTION[REG_IR]; - else - USE_ALL_CYCLES(); - return; - } - m68ki_exception_privilege_violation(); -} - - -M68KMAKE_OP(sub, 8, er, d) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_8(DY); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(sub, 8, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_8; - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(sub, 16, er, d) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(DY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(sub, 16, er, a) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(AY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(sub, 16, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_16; - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(sub, 32, er, d) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(sub, 32, er, a) -{ - uint* r_dst = &DX; - uint src = AY; - uint dst = *r_dst; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(sub, 32, er, .) -{ - uint* r_dst = &DX; - uint src = M68KMAKE_GET_OPER_AY_32; - uint dst = *r_dst; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(sub, 8, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint src = MASK_OUT_ABOVE_8(DX); - uint dst = m68ki_read_8(ea); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(sub, 16, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_16; - uint src = MASK_OUT_ABOVE_16(DX); - uint dst = m68ki_read_16(ea); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(sub, 32, re, .) -{ - uint ea = M68KMAKE_GET_EA_AY_32; - uint src = DX; - uint dst = m68ki_read_32(ea); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(suba, 16, ., d) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(DY)); -} - - -M68KMAKE_OP(suba, 16, ., a) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(AY)); -} - - -M68KMAKE_OP(suba, 16, ., .) -{ - uint* r_dst = &AX; - uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); -} - - -M68KMAKE_OP(suba, 32, ., d) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - DY); -} - - -M68KMAKE_OP(suba, 32, ., a) -{ - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - AY); -} - - -M68KMAKE_OP(suba, 32, ., .) -{ - uint src = M68KMAKE_GET_OPER_AY_32; - uint* r_dst = &AX; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); -} - - -M68KMAKE_OP(subi, 8, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_8(); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(subi, 8, ., .) -{ - uint src = OPER_I_8(); - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(subi, 16, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_16(); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(subi, 16, ., .) -{ - uint src = OPER_I_16(); - uint ea = M68KMAKE_GET_EA_AY_16; - uint dst = m68ki_read_16(ea); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(subi, 32, ., d) -{ - uint* r_dst = &DY; - uint src = OPER_I_32(); - uint dst = *r_dst; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(subi, 32, ., .) -{ - uint src = OPER_I_32(); - uint ea = M68KMAKE_GET_EA_AY_32; - uint dst = m68ki_read_32(ea); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(subq, 8, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(subq, 8, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint res = dst - src; - - FLAG_N = NFLAG_8(res); - FLAG_Z = MASK_OUT_ABOVE_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - m68ki_write_8(ea, FLAG_Z); -} - - -M68KMAKE_OP(subq, 16, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; -} - - -M68KMAKE_OP(subq, 16, ., a) -{ - uint* r_dst = &AY; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); -} - - -M68KMAKE_OP(subq, 16, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_16; - uint dst = m68ki_read_16(ea); - uint res = dst - src; - - FLAG_N = NFLAG_16(res); - FLAG_Z = MASK_OUT_ABOVE_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - m68ki_write_16(ea, FLAG_Z); -} - - -M68KMAKE_OP(subq, 32, ., d) -{ - uint* r_dst = &DY; - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint dst = *r_dst; - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - *r_dst = FLAG_Z; -} - - -M68KMAKE_OP(subq, 32, ., a) -{ - uint* r_dst = &AY; - - *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); -} - - -M68KMAKE_OP(subq, 32, ., .) -{ - uint src = (((REG_IR >> 9) - 1) & 7) + 1; - uint ea = M68KMAKE_GET_EA_AY_32; - uint dst = m68ki_read_32(ea); - uint res = dst - src; - - FLAG_N = NFLAG_32(res); - FLAG_Z = MASK_OUT_ABOVE_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - m68ki_write_32(ea, FLAG_Z); -} - - -M68KMAKE_OP(subx, 8, rr, .) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_8(DY); - uint dst = MASK_OUT_ABOVE_8(*r_dst); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; -} - - -M68KMAKE_OP(subx, 16, rr, .) -{ - uint* r_dst = &DX; - uint src = MASK_OUT_ABOVE_16(DY); - uint dst = MASK_OUT_ABOVE_16(*r_dst); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; -} - - -M68KMAKE_OP(subx, 32, rr, .) -{ - uint* r_dst = &DX; - uint src = DY; - uint dst = *r_dst; - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - *r_dst = res; -} - - -M68KMAKE_OP(subx, 8, mm, ax7) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(subx, 8, mm, ay7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(subx, 8, mm, axy7) -{ - uint src = OPER_A7_PD_8(); - uint ea = EA_A7_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(subx, 8, mm, .) -{ - uint src = OPER_AY_PD_8(); - uint ea = EA_AX_PD_8(); - uint dst = m68ki_read_8(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_8(res); - FLAG_X = FLAG_C = CFLAG_8(res); - FLAG_V = VFLAG_SUB_8(src, dst, res); - - res = MASK_OUT_ABOVE_8(res); - FLAG_Z |= res; - - m68ki_write_8(ea, res); -} - - -M68KMAKE_OP(subx, 16, mm, .) -{ - uint src = OPER_AY_PD_16(); - uint ea = EA_AX_PD_16(); - uint dst = m68ki_read_16(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_16(res); - FLAG_X = FLAG_C = CFLAG_16(res); - FLAG_V = VFLAG_SUB_16(src, dst, res); - - res = MASK_OUT_ABOVE_16(res); - FLAG_Z |= res; - - m68ki_write_16(ea, res); -} - - -M68KMAKE_OP(subx, 32, mm, .) -{ - uint src = OPER_AY_PD_32(); - uint ea = EA_AX_PD_32(); - uint dst = m68ki_read_32(ea); - uint res = dst - src - XFLAG_AS_1(); - - FLAG_N = NFLAG_32(res); - FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); - FLAG_V = VFLAG_SUB_32(src, dst, res); - - res = MASK_OUT_ABOVE_32(res); - FLAG_Z |= res; - - m68ki_write_32(ea, res); -} - - -M68KMAKE_OP(swap, 32, ., .) -{ - uint* r_dst = &DY; - - FLAG_Z = MASK_OUT_ABOVE_32(*r_dst<<16); - *r_dst = (*r_dst>>16) | FLAG_Z; - - FLAG_Z = *r_dst; - FLAG_N = NFLAG_32(*r_dst); - FLAG_C = CFLAG_CLEAR; - FLAG_V = VFLAG_CLEAR; -} - - -M68KMAKE_OP(tas, 8, ., d) -{ - uint* r_dst = &DY; - - FLAG_Z = MASK_OUT_ABOVE_8(*r_dst); - FLAG_N = NFLAG_8(*r_dst); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - *r_dst |= 0x80; -} - - -M68KMAKE_OP(tas, 8, ., .) -{ - uint ea = M68KMAKE_GET_EA_AY_8; - uint dst = m68ki_read_8(ea); - uint allow_writeback; - - FLAG_Z = dst; - FLAG_N = NFLAG_8(dst); - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - - /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback - disabled in order to function properly. Some Amiga software may also rely - on this, but only when accessing specific addresses so additional functionality - will be needed. */ - allow_writeback = m68ki_tas_callback(); - - if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80); -} - - -M68KMAKE_OP(trap, 0, ., .) -{ - /* Trap#n stacks exception frame type 0 */ - m68ki_exception_trapN(EXCEPTION_TRAP_BASE + (REG_IR & 0xf)); /* HJB 990403 */ -} - - -M68KMAKE_OP(trapt, 0, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapt, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 2; // JFF else stackframe & return addresses are incorrect - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapt, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 4; // JFF else stackframe & return addresses are incorrect - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapf, 0, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapf, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 2; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapf, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 4; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapcc, 0, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - if(M68KMAKE_CC) - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapcc, 16, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 2; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ - if(M68KMAKE_CC) - { - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapcc, 32, ., .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - REG_PC += 4; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ - if(M68KMAKE_CC) - { - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ - return; - } - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(trapv, 0, ., .) -{ - if(COND_VC()) - { - return; - } - m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ -} - - -M68KMAKE_OP(tst, 8, ., d) -{ - uint res = MASK_OUT_ABOVE_8(DY); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 8, ., .) -{ - uint res = M68KMAKE_GET_OPER_AY_8; - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 8, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCDI_8(); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 8, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCIX_8(); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 8, ., i) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_I_8(); - - FLAG_N = NFLAG_8(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 16, ., d) -{ - uint res = MASK_OUT_ABOVE_16(DY); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 16, ., a) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = MAKE_INT_16(AY); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 16, ., .) -{ - uint res = M68KMAKE_GET_OPER_AY_16; - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 16, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCDI_16(); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 16, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCIX_16(); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 16, ., i) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_I_16(); - - FLAG_N = NFLAG_16(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 32, ., d) -{ - uint res = DY; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 32, ., a) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = AY; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 32, ., .) -{ - uint res = M68KMAKE_GET_OPER_AY_32; - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; -} - - -M68KMAKE_OP(tst, 32, ., pcdi) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCDI_32(); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 32, ., pcix) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_PCIX_32(); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(tst, 32, ., i) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint res = OPER_I_32(); - - FLAG_N = NFLAG_32(res); - FLAG_Z = res; - FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(unlk, 32, ., a7) -{ - REG_A[7] = m68ki_read_32(REG_A[7]); -} - - -M68KMAKE_OP(unlk, 32, ., .) -{ - uint* r_dst = &AY; - - REG_A[7] = *r_dst; - *r_dst = m68ki_pull_32(); -} - - -M68KMAKE_OP(unpk, 16, rr, .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: DX and DY are reversed in Motorola's docs */ - uint src = DY; - uint* r_dst = &DX; - - *r_dst = MASK_OUT_BELOW_16(*r_dst) | (((((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16()) & 0xffff); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(unpk, 16, mm, ax7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint src = OPER_AY_PD_8(); - uint ea_dst; - - src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); - ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, src & 0xff); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(unpk, 16, mm, ay7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint src = OPER_A7_PD_8(); - uint ea_dst; - - src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); - ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, src & 0xff); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(unpk, 16, mm, axy7) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - uint src = OPER_A7_PD_8(); - uint ea_dst; - - src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); - ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, src & 0xff); - return; - } - m68ki_exception_illegal(); -} - - -M68KMAKE_OP(unpk, 16, mm, .) -{ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Note: AX and AY are reversed in Motorola's docs */ - uint src = OPER_AY_PD_8(); - uint ea_dst; - - src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); - ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, src & 0xff); - return; - } - m68ki_exception_illegal(); -} - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -M68KMAKE_END +/* +must fix: + callm + chk +*/ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.32 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* Special thanks to Bart Trzynadlowski for his insight into the + * undocumented features of this chip: + * + * http://dynarec.com/~bart/files/68knotes.txt + */ + + +/* Input file for m68kmake + * ----------------------- + * + * All sections begin with 80 X's in a row followed by an end-of-line + * sequence. + * After this, m68kmake will expect to find one of the following section + * identifiers: + * M68KMAKE_PROTOTYPE_HEADER - header for opcode handler prototypes + * M68KMAKE_PROTOTYPE_FOOTER - footer for opcode handler prototypes + * M68KMAKE_TABLE_HEADER - header for opcode handler jumptable + * M68KMAKE_TABLE_FOOTER - footer for opcode handler jumptable + * M68KMAKE_TABLE_BODY - the table itself + * M68KMAKE_OPCODE_HANDLER_HEADER - header for opcode handler implementation + * M68KMAKE_OPCODE_HANDLER_FOOTER - footer for opcode handler implementation + * M68KMAKE_OPCODE_HANDLER_BODY - body section for opcode handler implementation + * + * NOTE: M68KMAKE_OPCODE_HANDLER_BODY must be last in the file and + * M68KMAKE_TABLE_BODY must be second last in the file. + * + * The M68KMAKE_OPHANDLER_BODY section contains the opcode handler + * primitives themselves. Each opcode handler begins with: + * M68KMAKE_OP(A, B, C, D) + * + * where A is the opcode handler name, B is the size of the operation, + * C denotes any special processing mode, and D denotes a specific + * addressing mode. + * For C and D where nothing is specified, use "." + * + * Example: + * M68KMAKE_OP(abcd, 8, rr, .) abcd, size 8, register to register, default EA + * M68KMAKE_OP(abcd, 8, mm, ax7) abcd, size 8, memory to memory, register X is A7 + * M68KMAKE_OP(tst, 16, ., pcix) tst, size 16, PCIX addressing + * + * All opcode handler primitives end with a closing curly brace "}" at column 1 + * + * NOTE: Do not place a M68KMAKE_OP() directive inside the opcode handler, + * and do not put a closing curly brace at column 1 unless it is + * marking the end of the handler! + * + * Inside the handler, m68kmake will recognize M68KMAKE_GET_OPER_xx_xx, + * M68KMAKE_GET_EA_xx_xx, and M68KMAKE_CC directives, and create multiple + * opcode handlers to handle variations in the opcode handler. + * Note: M68KMAKE_CC will only be interpreted in condition code opcodes. + * As well, M68KMAKE_GET_EA_xx_xx and M68KMAKE_GET_OPER_xx_xx will only + * be interpreted on instructions where the corresponding table entry + * specifies multiple effective addressing modes. + * Example: + * clr 32 . . 0100001010...... A+-DXWL... U U U 12 6 4 + * + * This table entry says that the clr.l opcde has 7 variations (A+-DXWL). + * It is run in user or supervisor mode for all CPUs, and uses 12 cycles for + * 68000, 6 cycles for 68010, and 4 cycles for 68020. + */ + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_PROTOTYPE_HEADER + +#ifndef M68KOPS__HEADER +#define M68KOPS__HEADER + +/* ======================================================================== */ +/* ============================ OPCODE HANDLERS =========================== */ +/* ======================================================================== */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_PROTOTYPE_FOOTER + + +/* Build the opcode handler table */ +void m68ki_build_opcode_table(void); + +extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ +extern unsigned char m68ki_cycles[][0x10000]; + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KOPS__HEADER */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_TABLE_HEADER + +/* ======================================================================== */ +/* ========================= OPCODE TABLE BUILDER ========================= */ +/* ======================================================================== */ + +#include +#include "m68kops.h" + +#define NUM_CPU_TYPES 5 + +void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ +unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */ + +/* This is used to generate the opcode handler jump table */ +typedef struct +{ + void (*opcode_handler)(void); /* handler function */ + unsigned int mask; /* mask on opcode */ + unsigned int match; /* what to match after masking */ + unsigned char cycles[NUM_CPU_TYPES]; /* cycles each cpu type takes */ +} opcode_handler_struct; + + +/* Opcode handler table */ +static const opcode_handler_struct m68k_opcode_handler_table[] = +{ +/* function mask match 000 010 020 040 */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_TABLE_FOOTER + + {0, 0, 0, {0, 0, 0, 0, 0}} +}; + + +/* Build the opcode handler jump table */ +void m68ki_build_opcode_table(void) +{ + const opcode_handler_struct *ostruct; + int cycle_cost; + int instr; + int i; + int j; + int k; + + for(i = 0; i < 0x10000; i++) + { + /* default to illegal */ + m68ki_instruction_jump_table[i] = m68k_op_illegal; + for(k=0;kmask != 0xff00) + { + for(i = 0;i < 0x10000;i++) + { + if((i & ostruct->mask) == ostruct->match) + { + m68ki_instruction_jump_table[i] = ostruct->opcode_handler; + for(k=0;kcycles[k]; + } + } + ostruct++; + } + while(ostruct->mask == 0xff00) + { + for(i = 0;i <= 0xff;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + for(k=0;kmatch | i] = ostruct->cycles[k]; + } + ostruct++; + } + while(ostruct->mask == 0xf1f8) + { + for(i = 0;i < 8;i++) + { + for(j = 0;j < 8;j++) + { + instr = ostruct->match | (i << 9) | j; + m68ki_instruction_jump_table[instr] = ostruct->opcode_handler; + for(k=0;kcycles[k]; + // For all shift operations with known shift distance (encoded in instruction word) + if((instr & 0xf000) == 0xe000 && (!(instr & 0x20))) + { + // On the 68000 and 68010 shift distance affect execution time. + // Add the cycle cost of shifting; 2 times the shift distance + cycle_cost = ((((i-1)&7)+1)<<1); + m68ki_cycles[0][instr] += cycle_cost; + m68ki_cycles[1][instr] += cycle_cost; + // On the 68020 shift distance does not affect execution time + m68ki_cycles[2][instr] += 0; + } + } + } + ostruct++; + } + while(ostruct->mask == 0xfff0) + { + for(i = 0;i <= 0x0f;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + for(k=0;kmatch | i] = ostruct->cycles[k]; + } + ostruct++; + } + while(ostruct->mask == 0xf1ff) + { + for(i = 0;i <= 0x07;i++) + { + m68ki_instruction_jump_table[ostruct->match | (i << 9)] = ostruct->opcode_handler; + for(k=0;kmatch | (i << 9)] = ostruct->cycles[k]; + } + ostruct++; + } + while(ostruct->mask == 0xfff8) + { + for(i = 0;i <= 0x07;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + for(k=0;kmatch | i] = ostruct->cycles[k]; + } + ostruct++; + } + while(ostruct->mask == 0xffff) + { + m68ki_instruction_jump_table[ostruct->match] = ostruct->opcode_handler; + for(k=0;kmatch] = ostruct->cycles[k]; + ostruct++; + } +} + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_OPCODE_HANDLER_HEADER + +#include +#include "m68kcpu.h" +extern void m68040_fpu_op0(void); +extern void m68040_fpu_op1(void); +extern void m68881_mmu_ops(void); + +/* ======================================================================== */ +/* ========================= INSTRUCTION HANDLERS ========================= */ +/* ======================================================================== */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_OPCODE_HANDLER_FOOTER + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_TABLE_BODY + +The following table is arranged as follows: + +name: Opcode mnemonic + +size: Operation size + +spec proc: Special processing mode: + .: normal + s: static operand + r: register operand + rr: register to register + mm: memory to memory + er: effective address to register + re: register to effective address + dd: data register to data register + da: data register to address register + aa: address register to address register + cr: control register to register + rc: register to control register + toc: to condition code register + tos: to status register + tou: to user stack pointer + frc: from condition code register + frs: from status register + fru: from user stack pointer + * for move.x, the special processing mode is a specific + destination effective addressing mode. + +spec ea: Specific effective addressing mode: + .: normal + i: immediate + d: data register + a: address register + ai: address register indirect + pi: address register indirect with postincrement + pd: address register indirect with predecrement + di: address register indirect with displacement + ix: address register indirect with index + aw: absolute word address + al: absolute long address + pcdi: program counter relative with displacement + pcix: program counter relative with index + a7: register specified in instruction is A7 + ax7: register field X of instruction is A7 + ay7: register field Y of instruction is A7 + axy7: register fields X and Y of instruction are A7 + +bit pattern: Pattern to recognize this opcode. "." means don't care. + +allowed ea: List of allowed addressing modes: + .: not present + A: address register indirect + +: ARI (address register indirect) with postincrement + -: ARI with predecrement + D: ARI with displacement + X: ARI with index + W: absolute word address + L: absolute long address + d: program counter indirect with displacement + x: program counter indirect with index + I: immediate +mode: CPU operating mode for each cpu type. U = user or supervisor, + S = supervisor only, "." = opcode not present. + +cpu cycles: Base number of cycles required to execute this opcode on the + specified CPU type. + Use "." if CPU does not have this opcode. + + + + spec spec allowed ea mode cpu cycles +name size proc ea bit pattern A+-DXWLdxI 0 1 2 3 4 000 010 020 030 040 comments +====== ==== ==== ==== ================ ========== = = = = = === === === === === ============= +M68KMAKE_TABLE_START +1010 0 . . 1010............ .......... U U U U U 4 4 4 4 4 +1111 0 . . 1111............ .......... U U U U U 4 4 4 4 4 +040fpu0 32 . . 11110010........ .......... . . . . U . . . . 0 +040fpu1 32 . . 11110011........ .......... . . . . U . . . . 0 +abcd 8 rr . 1100...100000... .......... U U U U U 6 6 4 4 4 +abcd 8 mm ax7 1100111100001... .......... U U U U U 18 18 16 16 16 +abcd 8 mm ay7 1100...100001111 .......... U U U U U 18 18 16 16 16 +abcd 8 mm axy7 1100111100001111 .......... U U U U U 18 18 16 16 16 +abcd 8 mm . 1100...100001... .......... U U U U U 18 18 16 16 16 +add 8 er d 1101...000000... .......... U U U U U 4 4 2 2 2 +add 8 er . 1101...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +add 16 er d 1101...001000... .......... U U U U U 4 4 2 2 2 +add 16 er a 1101...001001... .......... U U U U U 4 4 2 2 2 +add 16 er . 1101...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +add 32 er d 1101...010000... .......... U U U U U 6 6 2 2 2 +add 32 er a 1101...010001... .......... U U U U U 6 6 2 2 2 +add 32 er . 1101...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 +add 8 re . 1101...100...... A+-DXWL... U U U U U 8 8 4 4 4 +add 16 re . 1101...101...... A+-DXWL... U U U U U 8 8 4 4 4 +add 32 re . 1101...110...... A+-DXWL... U U U U U 12 12 4 4 4 +adda 16 . d 1101...011000... .......... U U U U U 8 8 2 2 2 +adda 16 . a 1101...011001... .......... U U U U U 8 8 2 2 2 +adda 16 . . 1101...011...... A+-DXWLdxI U U U U U 8 8 2 2 2 +adda 32 . d 1101...111000... .......... U U U U U 6 6 2 2 2 +adda 32 . a 1101...111001... .......... U U U U U 6 6 2 2 2 +adda 32 . . 1101...111...... A+-DXWLdxI U U U U U 6 6 2 2 2 +addi 8 . d 0000011000000... .......... U U U U U 8 8 2 2 2 +addi 8 . . 0000011000...... A+-DXWL... U U U U U 12 12 4 4 4 +addi 16 . d 0000011001000... .......... U U U U U 8 8 2 2 2 +addi 16 . . 0000011001...... A+-DXWL... U U U U U 12 12 4 4 4 +addi 32 . d 0000011010000... .......... U U U U U 16 14 2 2 2 +addi 32 . . 0000011010...... A+-DXWL... U U U U U 20 20 4 4 4 +addq 8 . d 0101...000000... .......... U U U U U 4 4 2 2 2 +addq 8 . . 0101...000...... A+-DXWL... U U U U U 8 8 4 4 4 +addq 16 . d 0101...001000... .......... U U U U U 4 4 2 2 2 +addq 16 . a 0101...001001... .......... U U U U U 4 4 2 2 2 +addq 16 . . 0101...001...... A+-DXWL... U U U U U 8 8 4 4 4 +addq 32 . d 0101...010000... .......... U U U U U 8 8 2 2 2 +addq 32 . a 0101...010001... .......... U U U U U 8 8 2 2 2 +addq 32 . . 0101...010...... A+-DXWL... U U U U U 12 12 4 4 4 +addx 8 rr . 1101...100000... .......... U U U U U 4 4 2 2 2 +addx 16 rr . 1101...101000... .......... U U U U U 4 4 2 2 2 +addx 32 rr . 1101...110000... .......... U U U U U 8 6 2 2 2 +addx 8 mm ax7 1101111100001... .......... U U U U U 18 18 12 12 12 +addx 8 mm ay7 1101...100001111 .......... U U U U U 18 18 12 12 12 +addx 8 mm axy7 1101111100001111 .......... U U U U U 18 18 12 12 12 +addx 8 mm . 1101...100001... .......... U U U U U 18 18 12 12 12 +addx 16 mm . 1101...101001... .......... U U U U U 18 18 12 12 12 +addx 32 mm . 1101...110001... .......... U U U U U 30 30 12 12 12 +and 8 er d 1100...000000... .......... U U U U U 4 4 2 2 2 +and 8 er . 1100...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +and 16 er d 1100...001000... .......... U U U U U 4 4 2 2 2 +and 16 er . 1100...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +and 32 er d 1100...010000... .......... U U U U U 6 6 2 2 2 +and 32 er . 1100...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 +and 8 re . 1100...100...... A+-DXWL... U U U U U 8 8 4 4 4 +and 16 re . 1100...101...... A+-DXWL... U U U U U 8 8 4 4 4 +and 32 re . 1100...110...... A+-DXWL... U U U U U 12 12 4 4 4 +andi 16 toc . 0000001000111100 .......... U U U U U 20 16 12 12 12 +andi 16 tos . 0000001001111100 .......... S S S S S 20 16 12 12 12 +andi 8 . d 0000001000000... .......... U U U U U 8 8 2 2 2 +andi 8 . . 0000001000...... A+-DXWL... U U U U U 12 12 4 4 4 +andi 16 . d 0000001001000... .......... U U U U U 8 8 2 2 2 +andi 16 . . 0000001001...... A+-DXWL... U U U U U 12 12 4 4 4 +andi 32 . d 0000001010000... .......... U U U U U 14 14 2 2 2 +andi 32 . . 0000001010...... A+-DXWL... U U U U U 20 20 4 4 4 +asr 8 s . 1110...000000... .......... U U U U U 6 6 6 6 6 +asr 16 s . 1110...001000... .......... U U U U U 6 6 6 6 6 +asr 32 s . 1110...010000... .......... U U U U U 8 8 6 6 6 +asr 8 r . 1110...000100... .......... U U U U U 6 6 6 6 6 +asr 16 r . 1110...001100... .......... U U U U U 6 6 6 6 6 +asr 32 r . 1110...010100... .......... U U U U U 8 8 6 6 6 +asr 16 . . 1110000011...... A+-DXWL... U U U U U 8 8 5 5 5 +asl 8 s . 1110...100000... .......... U U U U U 6 6 8 8 8 +asl 16 s . 1110...101000... .......... U U U U U 6 6 8 8 8 +asl 32 s . 1110...110000... .......... U U U U U 8 8 8 8 8 +asl 8 r . 1110...100100... .......... U U U U U 6 6 8 8 8 +asl 16 r . 1110...101100... .......... U U U U U 6 6 8 8 8 +asl 32 r . 1110...110100... .......... U U U U U 8 8 8 8 8 +asl 16 . . 1110000111...... A+-DXWL... U U U U U 8 8 6 6 6 +bcc 8 . . 0110............ .......... U U U U U 10 10 6 6 6 +bcc 16 . . 0110....00000000 .......... U U U U U 10 10 6 6 6 +bcc 32 . . 0110....11111111 .......... U U U U U 10 10 6 6 6 +bchg 8 r . 0000...101...... A+-DXWL... U U U U U 8 8 4 4 4 +bchg 32 r d 0000...101000... .......... U U U U U 8 8 4 4 4 +bchg 8 s . 0000100001...... A+-DXWL... U U U U U 12 12 4 4 4 +bchg 32 s d 0000100001000... .......... U U U U U 12 12 4 4 4 +bclr 8 r . 0000...110...... A+-DXWL... U U U U U 8 10 4 4 4 +bclr 32 r d 0000...110000... .......... U U U U U 10 10 4 4 4 +bclr 8 s . 0000100010...... A+-DXWL... U U U U U 12 12 4 4 4 +bclr 32 s d 0000100010000... .......... U U U U U 14 14 4 4 4 +bfchg 32 . d 1110101011000... .......... . . U U U . . 12 12 12 timing not quite correct +bfchg 32 . . 1110101011...... A..DXWL... . . U U U . . 20 20 20 +bfclr 32 . d 1110110011000... .......... . . U U U . . 12 12 12 +bfclr 32 . . 1110110011...... A..DXWL... . . U U U . . 20 20 20 +bfexts 32 . d 1110101111000... .......... . . U U U . . 8 8 8 +bfexts 32 . . 1110101111...... A..DXWLdx. . . U U U . . 15 15 15 +bfextu 32 . d 1110100111000... .......... . . U U U . . 8 8 8 +bfextu 32 . . 1110100111...... A..DXWLdx. . . U U U . . 15 15 15 +bfffo 32 . d 1110110111000... .......... . . U U U . . 18 18 18 +bfffo 32 . . 1110110111...... A..DXWLdx. . . U U U . . 28 28 28 +bfins 32 . d 1110111111000... .......... . . U U U . . 10 10 10 +bfins 32 . . 1110111111...... A..DXWL... . . U U U . . 17 17 17 +bfset 32 . d 1110111011000... .......... . . U U U . . 12 12 12 +bfset 32 . . 1110111011...... A..DXWL... . . U U U . . 20 20 20 +bftst 32 . d 1110100011000... .......... . . U U U . . 6 6 6 +bftst 32 . . 1110100011...... A..DXWLdx. . . U U U . . 13 13 13 +bkpt 0 . . 0100100001001... .......... . U U U U . 10 10 10 10 +bra 8 . . 01100000........ .......... U U U U U 10 10 10 10 10 +bra 16 . . 0110000000000000 .......... U U U U U 10 10 10 10 10 +bra 32 . . 0110000011111111 .......... U U U U U 10 10 10 10 10 +bset 32 r d 0000...111000... .......... U U U U U 8 8 4 4 4 +bset 8 r . 0000...111...... A+-DXWL... U U U U U 8 8 4 4 4 +bset 8 s . 0000100011...... A+-DXWL... U U U U U 12 12 4 4 4 +bset 32 s d 0000100011000... .......... U U U U U 12 12 4 4 4 +bsr 8 . . 01100001........ .......... U U U U U 18 18 7 7 7 +bsr 16 . . 0110000100000000 .......... U U U U U 18 18 7 7 7 +bsr 32 . . 0110000111111111 .......... U U U U U 18 18 7 7 7 +btst 8 r . 0000...100...... A+-DXWLdxI U U U U U 4 4 4 4 4 +btst 32 r d 0000...100000... .......... U U U U U 6 6 4 4 4 +btst 8 s . 0000100000...... A+-DXWLdx. U U U U U 8 8 4 4 4 +btst 32 s d 0000100000000... .......... U U U U U 10 10 4 4 4 +callm 32 . . 0000011011...... A..DXWLdx. . . U U U . . 60 60 60 not properly emulated +cas 8 . . 0000101011...... A+-DXWL... . . U U U . . 12 12 12 +cas 16 . . 0000110011...... A+-DXWL... . . U U U . . 12 12 12 +cas 32 . . 0000111011...... A+-DXWL... . . U U U . . 12 12 12 +cas2 16 . . 0000110011111100 .......... . . U U U . . 12 12 12 +cas2 32 . . 0000111011111100 .......... . . U U U . . 12 12 12 +chk 16 . d 0100...110000... .......... U U U U U 10 8 8 8 8 +chk 16 . . 0100...110...... A+-DXWLdxI U U U U U 10 8 8 8 8 +chk 32 . d 0100...100000... .......... . . U U U . . 8 8 8 +chk 32 . . 0100...100...... A+-DXWLdxI . . U U U . . 8 8 8 +chk2cmp2 8 . pcdi 0000000011111010 .......... . . U U U . . 23 23 23 +chk2cmp2 8 . pcix 0000000011111011 .......... . . U U U . . 23 23 23 +chk2cmp2 8 . . 0000000011...... A..DXWL... . . U U U . . 18 18 18 +chk2cmp2 16 . pcdi 0000001011111010 .......... . . U U U . . 23 23 23 +chk2cmp2 16 . pcix 0000001011111011 .......... . . U U U . . 23 23 23 +chk2cmp2 16 . . 0000001011...... A..DXWL... . . U U U . . 18 18 18 +chk2cmp2 32 . pcdi 0000010011111010 .......... . . U U U . . 23 23 23 +chk2cmp2 32 . pcix 0000010011111011 .......... . . U U U . . 23 23 23 +chk2cmp2 32 . . 0000010011...... A..DXWL... . . U U U . . 18 18 18 +clr 8 . d 0100001000000... .......... U U U U U 4 4 2 2 2 +clr 8 . . 0100001000...... A+-DXWL... U U U U U 8 4 4 4 4 +clr 16 . d 0100001001000... .......... U U U U U 4 4 2 2 2 +clr 16 . . 0100001001...... A+-DXWL... U U U U U 8 4 4 4 4 +clr 32 . d 0100001010000... .......... U U U U U 6 6 2 2 2 +clr 32 . . 0100001010...... A+-DXWL... U U U U U 12 6 4 4 4 +cmp 8 . d 1011...000000... .......... U U U U U 4 4 2 2 2 +cmp 8 . . 1011...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +cmp 16 . d 1011...001000... .......... U U U U U 4 4 2 2 2 +cmp 16 . a 1011...001001... .......... U U U U U 4 4 2 2 2 +cmp 16 . . 1011...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +cmp 32 . d 1011...010000... .......... U U U U U 6 6 2 2 2 +cmp 32 . a 1011...010001... .......... U U U U U 6 6 2 2 2 +cmp 32 . . 1011...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 +cmpa 16 . d 1011...011000... .......... U U U U U 6 6 4 4 4 +cmpa 16 . a 1011...011001... .......... U U U U U 6 6 4 4 4 +cmpa 16 . . 1011...011...... A+-DXWLdxI U U U U U 6 6 4 4 4 +cmpa 32 . d 1011...111000... .......... U U U U U 6 6 4 4 4 +cmpa 32 . a 1011...111001... .......... U U U U U 6 6 4 4 4 +cmpa 32 . . 1011...111...... A+-DXWLdxI U U U U U 6 6 4 4 4 +cmpi 8 . d 0000110000000... .......... U U U U U 8 8 2 2 2 +cmpi 8 . . 0000110000...... A+-DXWL... U U U U U 8 8 2 2 2 +cmpi 8 . pcdi 0000110000111010 .......... . . U U U . . 7 7 7 +cmpi 8 . pcix 0000110000111011 .......... . . U U U . . 9 9 9 +cmpi 16 . d 0000110001000... .......... U U U U U 8 8 2 2 2 +cmpi 16 . . 0000110001...... A+-DXWL... U U U U U 8 8 2 2 2 +cmpi 16 . pcdi 0000110001111010 .......... . . U U U . . 7 7 7 +cmpi 16 . pcix 0000110001111011 .......... . . U U U . . 9 9 9 +cmpi 32 . d 0000110010000... .......... U U U U U 14 12 2 2 2 +cmpi 32 . . 0000110010...... A+-DXWL... U U U U U 12 12 2 2 2 +cmpi 32 . pcdi 0000110010111010 .......... . . U U U . . 7 7 7 +cmpi 32 . pcix 0000110010111011 .......... . . U U U . . 9 9 9 +cmpm 8 . ax7 1011111100001... .......... U U U U U 12 12 9 9 9 +cmpm 8 . ay7 1011...100001111 .......... U U U U U 12 12 9 9 9 +cmpm 8 . axy7 1011111100001111 .......... U U U U U 12 12 9 9 9 +cmpm 8 . . 1011...100001... .......... U U U U U 12 12 9 9 9 +cmpm 16 . . 1011...101001... .......... U U U U U 12 12 9 9 9 +cmpm 32 . . 1011...110001... .......... U U U U U 20 20 9 9 9 +cpbcc 32 . . 1111...01....... .......... . . U U . . . 4 4 . unemulated +cpdbcc 32 . . 1111...001001... .......... . . U U . . . 4 4 . unemulated +cpgen 32 . . 1111...000...... .......... . . U U . . . 4 4 . unemulated +cpscc 32 . . 1111...001...... .......... . . U U . . . 4 4 . unemulated +cptrapcc 32 . . 1111...001111... .......... . . U U . . . 4 4 . unemulated +dbt 16 . . 0101000011001... .......... U U U U U 12 12 6 6 6 +dbf 16 . . 0101000111001... .......... U U U U U 12 12 6 6 6 +dbcc 16 . . 0101....11001... .......... U U U U U 12 12 6 6 6 +divs 16 . d 1000...111000... .......... U U U U U 158 122 56 56 56 +divs 16 . . 1000...111...... A+-DXWLdxI U U U U U 158 122 56 56 56 +divu 16 . d 1000...011000... .......... U U U U U 140 108 44 44 44 +divu 16 . . 1000...011...... A+-DXWLdxI U U U U U 140 108 44 44 44 +divl 32 . d 0100110001000... .......... . . U U U . . 84 84 84 +divl 32 . . 0100110001...... A+-DXWLdxI . . U U U . . 84 84 84 +eor 8 . d 1011...100000... .......... U U U U U 4 4 2 2 2 +eor 8 . . 1011...100...... A+-DXWL... U U U U U 8 8 4 4 4 +eor 16 . d 1011...101000... .......... U U U U U 4 4 2 2 2 +eor 16 . . 1011...101...... A+-DXWL... U U U U U 8 8 4 4 4 +eor 32 . d 1011...110000... .......... U U U U U 8 6 2 2 2 +eor 32 . . 1011...110...... A+-DXWL... U U U U U 12 12 4 4 4 +eori 16 toc . 0000101000111100 .......... U U U U U 20 16 12 12 12 +eori 16 tos . 0000101001111100 .......... S S S S S 20 16 12 12 12 +eori 8 . d 0000101000000... .......... U U U U U 8 8 2 2 2 +eori 8 . . 0000101000...... A+-DXWL... U U U U U 12 12 4 4 4 +eori 16 . d 0000101001000... .......... U U U U U 8 8 2 2 2 +eori 16 . . 0000101001...... A+-DXWL... U U U U U 12 12 4 4 4 +eori 32 . d 0000101010000... .......... U U U U U 16 14 2 2 2 +eori 32 . . 0000101010...... A+-DXWL... U U U U U 20 20 4 4 4 +exg 32 dd . 1100...101000... .......... U U U U U 6 6 2 2 2 +exg 32 aa . 1100...101001... .......... U U U U U 6 6 2 2 2 +exg 32 da . 1100...110001... .......... U U U U U 6 6 2 2 2 +ext 16 . . 0100100010000... .......... U U U U U 4 4 4 4 4 +ext 32 . . 0100100011000... .......... U U U U U 4 4 4 4 4 +extb 32 . . 0100100111000... .......... . . U U U . . 4 4 4 +illegal 0 . . 0100101011111100 .......... U U U U U 4 4 4 4 4 +jmp 32 . . 0100111011...... A..DXWLdx. U U U U U 4 4 0 0 0 +jsr 32 . . 0100111010...... A..DXWLdx. U U U U U 12 12 0 0 0 +lea 32 . . 0100...111...... A..DXWLdx. U U U U U 0 0 2 2 2 +link 16 . a7 0100111001010111 .......... U U U U U 16 16 5 5 5 +link 16 . . 0100111001010... .......... U U U U U 16 16 5 5 5 +link 32 . a7 0100100000001111 .......... . . U U U . . 6 6 6 +link 32 . . 0100100000001... .......... . . U U U . . 6 6 6 +lsr 8 s . 1110...000001... .......... U U U U U 6 6 4 4 4 +lsr 16 s . 1110...001001... .......... U U U U U 6 6 4 4 4 +lsr 32 s . 1110...010001... .......... U U U U U 8 8 4 4 4 +lsr 8 r . 1110...000101... .......... U U U U U 6 6 6 6 6 +lsr 16 r . 1110...001101... .......... U U U U U 6 6 6 6 6 +lsr 32 r . 1110...010101... .......... U U U U U 8 8 6 6 6 +lsr 16 . . 1110001011...... A+-DXWL... U U U U U 8 8 5 5 5 +lsl 8 s . 1110...100001... .......... U U U U U 6 6 4 4 4 +lsl 16 s . 1110...101001... .......... U U U U U 6 6 4 4 4 +lsl 32 s . 1110...110001... .......... U U U U U 8 8 4 4 4 +lsl 8 r . 1110...100101... .......... U U U U U 6 6 6 6 6 +lsl 16 r . 1110...101101... .......... U U U U U 6 6 6 6 6 +lsl 32 r . 1110...110101... .......... U U U U U 8 8 6 6 6 +lsl 16 . . 1110001111...... A+-DXWL... U U U U U 8 8 5 5 5 +move 8 d d 0001...000000... .......... U U U U U 4 4 2 2 2 +move 8 d . 0001...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +move 8 ai d 0001...010000... .......... U U U U U 8 8 4 4 4 +move 8 ai . 0001...010...... A+-DXWLdxI U U U U U 8 8 4 4 4 +move 8 pi d 0001...011000... .......... U U U U U 8 8 4 4 4 +move 8 pi . 0001...011...... A+-DXWLdxI U U U U U 8 8 4 4 4 +move 8 pi7 d 0001111011000... .......... U U U U U 8 8 4 4 4 +move 8 pi7 . 0001111011...... A+-DXWLdxI U U U U U 8 8 4 4 4 +move 8 pd d 0001...100000... .......... U U U U U 8 8 5 5 5 +move 8 pd . 0001...100...... A+-DXWLdxI U U U U U 8 8 5 5 5 +move 8 pd7 d 0001111100000... .......... U U U U U 8 8 5 5 5 +move 8 pd7 . 0001111100...... A+-DXWLdxI U U U U U 8 8 5 5 5 +move 8 di d 0001...101000... .......... U U U U U 12 12 5 5 5 +move 8 di . 0001...101...... A+-DXWLdxI U U U U U 12 12 5 5 5 +move 8 ix d 0001...110000... .......... U U U U U 14 14 7 7 7 +move 8 ix . 0001...110...... A+-DXWLdxI U U U U U 14 14 7 7 7 +move 8 aw d 0001000111000... .......... U U U U U 12 12 4 4 4 +move 8 aw . 0001000111...... A+-DXWLdxI U U U U U 12 12 4 4 4 +move 8 al d 0001001111000... .......... U U U U U 16 16 6 6 6 +move 8 al . 0001001111...... A+-DXWLdxI U U U U U 16 16 6 6 6 +move 16 d d 0011...000000... .......... U U U U U 4 4 2 2 2 +move 16 d a 0011...000001... .......... U U U U U 4 4 2 2 2 +move 16 d . 0011...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +move 16 ai d 0011...010000... .......... U U U U U 8 8 4 4 4 +move 16 ai a 0011...010001... .......... U U U U U 8 8 4 4 4 +move 16 ai . 0011...010...... A+-DXWLdxI U U U U U 8 8 4 4 4 +move 16 pi d 0011...011000... .......... U U U U U 8 8 4 4 4 +move 16 pi a 0011...011001... .......... U U U U U 8 8 4 4 4 +move 16 pi . 0011...011...... A+-DXWLdxI U U U U U 8 8 4 4 4 +move 16 pd d 0011...100000... .......... U U U U U 8 8 5 5 5 +move 16 pd a 0011...100001... .......... U U U U U 8 8 5 5 5 +move 16 pd . 0011...100...... A+-DXWLdxI U U U U U 8 8 5 5 5 +move 16 di d 0011...101000... .......... U U U U U 12 12 5 5 5 +move 16 di a 0011...101001... .......... U U U U U 12 12 5 5 5 +move 16 di . 0011...101...... A+-DXWLdxI U U U U U 12 12 5 5 5 +move 16 ix d 0011...110000... .......... U U U U U 14 14 7 7 7 +move 16 ix a 0011...110001... .......... U U U U U 14 14 7 7 7 +move 16 ix . 0011...110...... A+-DXWLdxI U U U U U 14 14 7 7 7 +move 16 aw d 0011000111000... .......... U U U U U 12 12 4 4 4 +move 16 aw a 0011000111001... .......... U U U U U 12 12 4 4 4 +move 16 aw . 0011000111...... A+-DXWLdxI U U U U U 12 12 4 4 4 +move 16 al d 0011001111000... .......... U U U U U 16 16 6 6 6 +move 16 al a 0011001111001... .......... U U U U U 16 16 6 6 6 +move 16 al . 0011001111...... A+-DXWLdxI U U U U U 16 16 6 6 6 +move 32 d d 0010...000000... .......... U U U U U 4 4 2 2 2 +move 32 d a 0010...000001... .......... U U U U U 4 4 2 2 2 +move 32 d . 0010...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +move 32 ai d 0010...010000... .......... U U U U U 12 12 4 4 4 +move 32 ai a 0010...010001... .......... U U U U U 12 12 4 4 4 +move 32 ai . 0010...010...... A+-DXWLdxI U U U U U 12 12 4 4 4 +move 32 pi d 0010...011000... .......... U U U U U 12 12 4 4 4 +move 32 pi a 0010...011001... .......... U U U U U 12 12 4 4 4 +move 32 pi . 0010...011...... A+-DXWLdxI U U U U U 12 12 4 4 4 +move 32 pd d 0010...100000... .......... U U U U U 12 14 5 5 5 +move 32 pd a 0010...100001... .......... U U U U U 12 14 5 5 5 +move 32 pd . 0010...100...... A+-DXWLdxI U U U U U 12 14 5 5 5 +move 32 di d 0010...101000... .......... U U U U U 16 16 5 5 5 +move 32 di a 0010...101001... .......... U U U U U 16 16 5 5 5 +move 32 di . 0010...101...... A+-DXWLdxI U U U U U 16 16 5 5 5 +move 32 ix d 0010...110000... .......... U U U U U 18 18 7 7 7 +move 32 ix a 0010...110001... .......... U U U U U 18 18 7 7 7 +move 32 ix . 0010...110...... A+-DXWLdxI U U U U U 18 18 7 7 7 +move 32 aw d 0010000111000... .......... U U U U U 16 16 4 4 4 +move 32 aw a 0010000111001... .......... U U U U U 16 16 4 4 4 +move 32 aw . 0010000111...... A+-DXWLdxI U U U U U 16 16 4 4 4 +move 32 al d 0010001111000... .......... U U U U U 20 20 6 6 6 +move 32 al a 0010001111001... .......... U U U U U 20 20 6 6 6 +move 32 al . 0010001111...... A+-DXWLdxI U U U U U 20 20 6 6 6 +movea 16 . d 0011...001000... .......... U U U U U 4 4 2 2 2 +movea 16 . a 0011...001001... .......... U U U U U 4 4 2 2 2 +movea 16 . . 0011...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +movea 32 . d 0010...001000... .......... U U U U U 4 4 2 2 2 +movea 32 . a 0010...001001... .......... U U U U U 4 4 2 2 2 +movea 32 . . 0010...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +move 16 frc d 0100001011000... .......... . U U U U . 4 4 4 4 +move 16 frc . 0100001011...... A+-DXWL... . U U U U . 8 4 4 4 +move 16 toc d 0100010011000... .......... U U U U U 12 12 4 4 4 +move 16 toc . 0100010011...... A+-DXWLdxI U U U U U 12 12 4 4 4 +move 16 frs d 0100000011000... .......... U S S S S 6 4 8 8 8 U only for 000 +move 16 frs . 0100000011...... A+-DXWL... U S S S S 8 8 8 8 8 U only for 000 +move 16 tos d 0100011011000... .......... S S S S S 12 12 8 8 8 +move 16 tos . 0100011011...... A+-DXWLdxI S S S S S 12 12 8 8 8 +move 32 fru . 0100111001101... .......... S S S S S 4 6 2 2 2 +move 32 tou . 0100111001100... .......... S S S S S 4 6 2 2 2 +movec 32 cr . 0100111001111010 .......... . S S S S . 12 6 6 6 +movec 32 rc . 0100111001111011 .......... . S S S S . 10 12 12 12 +movem 16 re pd 0100100010100... .......... U U U U U 8 8 4 4 4 +movem 16 re . 0100100010...... A..DXWL... U U U U U 8 8 4 4 4 +movem 32 re pd 0100100011100... .......... U U U U U 8 8 4 4 4 +movem 32 re . 0100100011...... A..DXWL... U U U U U 8 8 4 4 4 +movem 16 er pi 0100110010011... .......... U U U U U 12 12 8 8 8 +movem 16 er pcdi 0100110010111010 .......... U U U U U 16 16 9 9 9 +movem 16 er pcix 0100110010111011 .......... U U U U U 18 18 11 11 11 +movem 16 er . 0100110010...... A..DXWL... U U U U U 12 12 8 8 8 +movem 32 er pi 0100110011011... .......... U U U U U 12 12 8 8 8 +movem 32 er pcdi 0100110011111010 .......... U U U U U 16 16 9 9 9 +movem 32 er pcix 0100110011111011 .......... U U U U U 18 18 11 11 11 +movem 32 er . 0100110011...... A..DXWL... U U U U U 12 12 8 8 8 +movep 16 er . 0000...100001... .......... U U U U U 16 16 12 12 12 +movep 32 er . 0000...101001... .......... U U U U U 24 24 18 18 18 +movep 16 re . 0000...110001... .......... U U U U U 16 16 11 11 11 +movep 32 re . 0000...111001... .......... U U U U U 24 24 17 17 17 +moveq 32 . . 0111...0........ .......... U U U U U 4 4 2 2 2 +moves 8 . . 0000111000...... A+-DXWL... . S S S S . 14 5 5 5 +moves 16 . . 0000111001...... A+-DXWL... . S S S S . 14 5 5 5 +moves 32 . . 0000111010...... A+-DXWL... . S S S S . 16 5 5 5 +move16 32 . . 1111011000100... .......... . . . . U . . . . 4 TODO: correct timing +muls 16 . d 1100...111000... .......... U U U U U 54 32 27 27 27 +muls 16 . . 1100...111...... A+-DXWLdxI U U U U U 54 32 27 27 27 +mulu 16 . d 1100...011000... .......... U U U U U 54 30 27 27 27 +mulu 16 . . 1100...011...... A+-DXWLdxI U U U U U 54 30 27 27 27 +mull 32 . d 0100110000000... .......... . . U U U . . 43 43 43 +mull 32 . . 0100110000...... A+-DXWLdxI . . U U U . . 43 43 43 +nbcd 8 . d 0100100000000... .......... U U U U U 6 6 6 6 6 +nbcd 8 . . 0100100000...... A+-DXWL... U U U U U 8 8 6 6 6 +neg 8 . d 0100010000000... .......... U U U U U 4 4 2 2 2 +neg 8 . . 0100010000...... A+-DXWL... U U U U U 8 8 4 4 4 +neg 16 . d 0100010001000... .......... U U U U U 4 4 2 2 2 +neg 16 . . 0100010001...... A+-DXWL... U U U U U 8 8 4 4 4 +neg 32 . d 0100010010000... .......... U U U U U 6 6 2 2 2 +neg 32 . . 0100010010...... A+-DXWL... U U U U U 12 12 4 4 4 +negx 8 . d 0100000000000... .......... U U U U U 4 4 2 2 2 +negx 8 . . 0100000000...... A+-DXWL... U U U U U 8 8 4 4 4 +negx 16 . d 0100000001000... .......... U U U U U 4 4 2 2 2 +negx 16 . . 0100000001...... A+-DXWL... U U U U U 8 8 4 4 4 +negx 32 . d 0100000010000... .......... U U U U U 6 6 2 2 2 +negx 32 . . 0100000010...... A+-DXWL... U U U U U 12 12 4 4 4 +nop 0 . . 0100111001110001 .......... U U U U U 4 4 2 2 2 +not 8 . d 0100011000000... .......... U U U U U 4 4 2 2 2 +not 8 . . 0100011000...... A+-DXWL... U U U U U 8 8 4 4 4 +not 16 . d 0100011001000... .......... U U U U U 4 4 2 2 2 +not 16 . . 0100011001...... A+-DXWL... U U U U U 8 8 4 4 4 +not 32 . d 0100011010000... .......... U U U U U 6 6 2 2 2 +not 32 . . 0100011010...... A+-DXWL... U U U U U 12 12 4 4 4 +or 8 er d 1000...000000... .......... U U U U U 4 4 2 2 2 +or 8 er . 1000...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +or 16 er d 1000...001000... .......... U U U U U 4 4 2 2 2 +or 16 er . 1000...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +or 32 er d 1000...010000... .......... U U U U U 6 6 2 2 2 +or 32 er . 1000...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 +or 8 re . 1000...100...... A+-DXWL... U U U U U 8 8 4 4 4 +or 16 re . 1000...101...... A+-DXWL... U U U U U 8 8 4 4 4 +or 32 re . 1000...110...... A+-DXWL... U U U U U 12 12 4 4 4 +ori 16 toc . 0000000000111100 .......... U U U U U 20 16 12 12 12 +ori 16 tos . 0000000001111100 .......... S S S S S 20 16 12 12 12 +ori 8 . d 0000000000000... .......... U U U U U 8 8 2 2 2 +ori 8 . . 0000000000...... A+-DXWL... U U U U U 12 12 4 4 4 +ori 16 . d 0000000001000... .......... U U U U U 8 8 2 2 2 +ori 16 . . 0000000001...... A+-DXWL... U U U U U 12 12 4 4 4 +ori 32 . d 0000000010000... .......... U U U U U 16 14 2 2 2 +ori 32 . . 0000000010...... A+-DXWL... U U U U U 20 20 4 4 4 +pack 16 rr . 1000...101000... .......... . . U U U . . 6 6 6 +pack 16 mm ax7 1000111101001... .......... . . U U U . . 13 13 13 +pack 16 mm ay7 1000...101001111 .......... . . U U U . . 13 13 13 +pack 16 mm axy7 1000111101001111 .......... . . U U U . . 13 13 13 +pack 16 mm . 1000...101001... .......... . . U U U . . 13 13 13 +pea 32 . . 0100100001...... A..DXWLdx. U U U U U 6 6 5 5 5 +pflush 32 . . 1111010100011000 .......... . . . . S . . . . 4 TODO: correct timing +pmmu 32 . . 1111000......... .......... . . S S S . . 8 8 8 +reset 0 . . 0100111001110000 .......... S S S S S 0 0 0 0 0 +ror 8 s . 1110...000011... .......... U U U U U 6 6 8 8 8 +ror 16 s . 1110...001011... .......... U U U U U 6 6 8 8 8 +ror 32 s . 1110...010011... .......... U U U U U 8 8 8 8 8 +ror 8 r . 1110...000111... .......... U U U U U 6 6 8 8 8 +ror 16 r . 1110...001111... .......... U U U U U 6 6 8 8 8 +ror 32 r . 1110...010111... .......... U U U U U 8 8 8 8 8 +ror 16 . . 1110011011...... A+-DXWL... U U U U U 8 8 7 7 7 +rol 8 s . 1110...100011... .......... U U U U U 6 6 8 8 8 +rol 16 s . 1110...101011... .......... U U U U U 6 6 8 8 8 +rol 32 s . 1110...110011... .......... U U U U U 8 8 8 8 8 +rol 8 r . 1110...100111... .......... U U U U U 6 6 8 8 8 +rol 16 r . 1110...101111... .......... U U U U U 6 6 8 8 8 +rol 32 r . 1110...110111... .......... U U U U U 8 8 8 8 8 +rol 16 . . 1110011111...... A+-DXWL... U U U U U 8 8 7 7 7 +roxr 8 s . 1110...000010... .......... U U U U U 6 6 12 12 12 +roxr 16 s . 1110...001010... .......... U U U U U 6 6 12 12 12 +roxr 32 s . 1110...010010... .......... U U U U U 8 8 12 12 12 +roxr 8 r . 1110...000110... .......... U U U U U 6 6 12 12 12 +roxr 16 r . 1110...001110... .......... U U U U U 6 6 12 12 12 +roxr 32 r . 1110...010110... .......... U U U U U 8 8 12 12 12 +roxr 16 . . 1110010011...... A+-DXWL... U U U U U 8 8 5 5 5 +roxl 8 s . 1110...100010... .......... U U U U U 6 6 12 12 12 +roxl 16 s . 1110...101010... .......... U U U U U 6 6 12 12 12 +roxl 32 s . 1110...110010... .......... U U U U U 8 8 12 12 12 +roxl 8 r . 1110...100110... .......... U U U U U 6 6 12 12 12 +roxl 16 r . 1110...101110... .......... U U U U U 6 6 12 12 12 +roxl 32 r . 1110...110110... .......... U U U U U 8 8 12 12 12 +roxl 16 . . 1110010111...... A+-DXWL... U U U U U 8 8 5 5 5 +rtd 32 . . 0100111001110100 .......... . U U U U . 16 10 10 10 +rte 32 . . 0100111001110011 .......... S S S S S 20 24 20 20 20 bus fault not emulated +rtm 32 . . 000001101100.... .......... . . U U U . . 19 19 19 not properly emulated +rtr 32 . . 0100111001110111 .......... U U U U U 20 20 14 14 14 +rts 32 . . 0100111001110101 .......... U U U U U 16 16 10 10 10 +sbcd 8 rr . 1000...100000... .......... U U U U U 6 6 4 4 4 +sbcd 8 mm ax7 1000111100001... .......... U U U U U 18 18 16 16 16 +sbcd 8 mm ay7 1000...100001111 .......... U U U U U 18 18 16 16 16 +sbcd 8 mm axy7 1000111100001111 .......... U U U U U 18 18 16 16 16 +sbcd 8 mm . 1000...100001... .......... U U U U U 18 18 16 16 16 +st 8 . d 0101000011000... .......... U U U U U 6 4 4 4 4 +st 8 . . 0101000011...... A+-DXWL... U U U U U 8 8 6 6 6 +sf 8 . d 0101000111000... .......... U U U U U 4 4 4 4 4 +sf 8 . . 0101000111...... A+-DXWL... U U U U U 8 8 6 6 6 +scc 8 . d 0101....11000... .......... U U U U U 4 4 4 4 4 +scc 8 . . 0101....11...... A+-DXWL... U U U U U 8 8 6 6 6 +stop 0 . . 0100111001110010 .......... S S S S S 4 4 8 8 8 +sub 8 er d 1001...000000... .......... U U U U U 4 4 2 2 2 +sub 8 er . 1001...000...... A+-DXWLdxI U U U U U 4 4 2 2 2 +sub 16 er d 1001...001000... .......... U U U U U 4 4 2 2 2 +sub 16 er a 1001...001001... .......... U U U U U 4 4 2 2 2 +sub 16 er . 1001...001...... A+-DXWLdxI U U U U U 4 4 2 2 2 +sub 32 er d 1001...010000... .......... U U U U U 6 6 2 2 2 +sub 32 er a 1001...010001... .......... U U U U U 6 6 2 2 2 +sub 32 er . 1001...010...... A+-DXWLdxI U U U U U 6 6 2 2 2 +sub 8 re . 1001...100...... A+-DXWL... U U U U U 8 8 4 4 4 +sub 16 re . 1001...101...... A+-DXWL... U U U U U 8 8 4 4 4 +sub 32 re . 1001...110...... A+-DXWL... U U U U U 12 12 4 4 4 +suba 16 . d 1001...011000... .......... U U U U U 8 8 2 2 2 +suba 16 . a 1001...011001... .......... U U U U U 8 8 2 2 2 +suba 16 . . 1001...011...... A+-DXWLdxI U U U U U 8 8 2 2 2 +suba 32 . d 1001...111000... .......... U U U U U 6 6 2 2 2 +suba 32 . a 1001...111001... .......... U U U U U 6 6 2 2 2 +suba 32 . . 1001...111...... A+-DXWLdxI U U U U U 6 6 2 2 2 +subi 8 . d 0000010000000... .......... U U U U U 8 8 2 2 2 +subi 8 . . 0000010000...... A+-DXWL... U U U U U 12 12 4 4 4 +subi 16 . d 0000010001000... .......... U U U U U 8 8 2 2 2 +subi 16 . . 0000010001...... A+-DXWL... U U U U U 12 12 4 4 4 +subi 32 . d 0000010010000... .......... U U U U U 16 14 2 2 2 +subi 32 . . 0000010010...... A+-DXWL... U U U U U 20 20 4 4 4 +subq 8 . d 0101...100000... .......... U U U U U 4 4 2 2 2 +subq 8 . . 0101...100...... A+-DXWL... U U U U U 8 8 4 4 4 +subq 16 . d 0101...101000... .......... U U U U U 4 4 2 2 2 +subq 16 . a 0101...101001... .......... U U U U U 8 4 2 2 2 +subq 16 . . 0101...101...... A+-DXWL... U U U U U 8 8 4 4 4 +subq 32 . d 0101...110000... .......... U U U U U 8 8 2 2 2 +subq 32 . a 0101...110001... .......... U U U U U 8 8 2 2 2 +subq 32 . . 0101...110...... A+-DXWL... U U U U U 12 12 4 4 4 +subx 8 rr . 1001...100000... .......... U U U U U 4 4 2 2 2 +subx 16 rr . 1001...101000... .......... U U U U U 4 4 2 2 2 +subx 32 rr . 1001...110000... .......... U U U U U 8 6 2 2 2 +subx 8 mm ax7 1001111100001... .......... U U U U U 18 18 12 12 12 +subx 8 mm ay7 1001...100001111 .......... U U U U U 18 18 12 12 12 +subx 8 mm axy7 1001111100001111 .......... U U U U U 18 18 12 12 12 +subx 8 mm . 1001...100001... .......... U U U U U 18 18 12 12 12 +subx 16 mm . 1001...101001... .......... U U U U U 18 18 12 12 12 +subx 32 mm . 1001...110001... .......... U U U U U 30 30 12 12 12 +swap 32 . . 0100100001000... .......... U U U U U 4 4 4 4 4 +tas 8 . d 0100101011000... .......... U U U U U 4 4 4 4 4 +tas 8 . . 0100101011...... A+-DXWL... U U U U U 14 14 12 12 12 +trap 0 . . 010011100100.... .......... U U U U U 4 4 4 4 4 +trapt 0 . . 0101000011111100 .......... . . U U U . . 4 4 4 +trapt 16 . . 0101000011111010 .......... . . U U U . . 6 6 6 +trapt 32 . . 0101000011111011 .......... . . U U U . . 8 8 8 +trapf 0 . . 0101000111111100 .......... . . U U U . . 4 4 4 +trapf 16 . . 0101000111111010 .......... . . U U U . . 6 6 6 +trapf 32 . . 0101000111111011 .......... . . U U U . . 8 8 8 +trapcc 0 . . 0101....11111100 .......... . . U U U . . 4 4 4 +trapcc 16 . . 0101....11111010 .......... . . U U U . . 6 6 6 +trapcc 32 . . 0101....11111011 .......... . . U U U . . 8 8 8 +trapv 0 . . 0100111001110110 .......... U U U U U 4 4 4 4 4 +tst 8 . d 0100101000000... .......... U U U U U 4 4 2 2 2 +tst 8 . . 0100101000...... A+-DXWL... U U U U U 4 4 2 2 2 +tst 8 . pcdi 0100101000111010 .......... . . U U U . . 7 7 7 +tst 8 . pcix 0100101000111011 .......... . . U U U . . 9 9 9 +tst 8 . i 0100101000111100 .......... . . U U U . . 6 6 6 +tst 16 . d 0100101001000... .......... U U U U U 4 4 2 2 2 +tst 16 . a 0100101001001... .......... . . U U U . . 2 2 2 +tst 16 . . 0100101001...... A+-DXWL... U U U U U 4 4 2 2 2 +tst 16 . pcdi 0100101001111010 .......... . . U U U . . 7 7 7 +tst 16 . pcix 0100101001111011 .......... . . U U U . . 9 9 9 +tst 16 . i 0100101001111100 .......... . . U U U . . 6 6 6 +tst 32 . d 0100101010000... .......... U U U U U 4 4 2 2 2 +tst 32 . a 0100101010001... .......... . . U U U . . 2 2 2 +tst 32 . . 0100101010...... A+-DXWL... U U U U U 4 4 2 2 2 +tst 32 . pcdi 0100101010111010 .......... . . U U U . . 7 7 7 +tst 32 . pcix 0100101010111011 .......... . . U U U . . 9 9 9 +tst 32 . i 0100101010111100 .......... . . U U U . . 6 6 6 +unlk 32 . a7 0100111001011111 .......... U U U U U 12 12 6 6 6 +unlk 32 . . 0100111001011... .......... U U U U U 12 12 6 6 6 +unpk 16 rr . 1000...110000... .......... . . U U U . . 8 8 8 +unpk 16 mm ax7 1000111110001... .......... . . U U U . . 13 13 13 +unpk 16 mm ay7 1000...110001111 .......... . . U U U . . 13 13 13 +unpk 16 mm axy7 1000111110001111 .......... . . U U U . . 13 13 13 +unpk 16 mm . 1000...110001... .......... . . U U U . . 13 13 13 + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_OPCODE_HANDLER_BODY + +M68KMAKE_OP(1010, 0, ., .) +{ + m68ki_exception_1010(); +} + + +M68KMAKE_OP(1111, 0, ., .) +{ + m68ki_exception_1111(); +} + + +M68KMAKE_OP(040fpu0, 32, ., .) +{ + if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) + { + m68040_fpu_op0(); + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(040fpu1, 32, ., .) +{ + if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) + { + m68040_fpu_op1(); + return; + } + m68ki_exception_1111(); +} + + + +M68KMAKE_OP(abcd, 8, rr, .) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +M68KMAKE_OP(abcd, 8, mm, ax7) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(abcd, 8, mm, ay7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(abcd, 8, mm, axy7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(abcd, 8, mm, .) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(add, 8, er, d) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(add, 8, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_8; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(add, 16, er, d) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(add, 16, er, a) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(add, 16, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_16; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(add, 32, er, d) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(add, 32, er, a) +{ + uint* r_dst = &DX; + uint src = AY; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(add, 32, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_32; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(add, 8, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(add, 16, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(add, 32, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(adda, 16, ., d) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(DY)); +} + + +M68KMAKE_OP(adda, 16, ., a) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(AY)); +} + + +M68KMAKE_OP(adda, 16, ., .) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +M68KMAKE_OP(adda, 32, ., d) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + DY); +} + + +M68KMAKE_OP(adda, 32, ., a) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + AY); +} + + +M68KMAKE_OP(adda, 32, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_32; + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +M68KMAKE_OP(addi, 8, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(addi, 8, ., .) +{ + uint src = OPER_I_8(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(addi, 16, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(addi, 16, ., .) +{ + uint src = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(addi, 32, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(addi, 32, ., .) +{ + uint src = OPER_I_32(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(addq, 8, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(addq, 8, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(addq, 16, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(addq, 16, ., a) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); +} + + +M68KMAKE_OP(addq, 16, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_16; + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(addq, 32, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(addq, 32, ., a) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); +} + + +M68KMAKE_OP(addq, 32, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_32; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(addx, 8, rr, .) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +M68KMAKE_OP(addx, 16, rr, .) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +M68KMAKE_OP(addx, 32, rr, .) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +M68KMAKE_OP(addx, 8, mm, ax7) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(addx, 8, mm, ay7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(addx, 8, mm, axy7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(addx, 8, mm, .) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(addx, 16, mm, .) +{ + uint src = OPER_AY_PD_16(); + uint ea = EA_AX_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +M68KMAKE_OP(addx, 32, mm, .) +{ + uint src = OPER_AY_PD_32(); + uint ea = EA_AX_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +M68KMAKE_OP(and, 8, er, d) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (DY | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 8, er, .) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (M68KMAKE_GET_OPER_AY_8 | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 16, er, d) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (DY | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 16, er, .) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (M68KMAKE_GET_OPER_AY_16 | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 32, er, d) +{ + FLAG_Z = DX &= DY; + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 32, er, .) +{ + FLAG_Z = DX &= M68KMAKE_GET_OPER_AY_32; + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(and, 8, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(and, 16, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(and, 32, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +M68KMAKE_OP(andi, 8, ., d) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DY &= (OPER_I_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(andi, 8, ., .) +{ + uint src = OPER_I_8(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(andi, 16, ., d) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DY &= (OPER_I_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(andi, 16, ., .) +{ + uint src = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +M68KMAKE_OP(andi, 32, ., d) +{ + FLAG_Z = DY &= (OPER_I_32()); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(andi, 32, ., .) +{ + uint src = OPER_I_32(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +M68KMAKE_OP(andi, 16, toc, .) +{ + m68ki_set_ccr(m68ki_get_ccr() & OPER_I_8()); +} + + +M68KMAKE_OP(andi, 16, tos, .) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_set_sr(m68ki_get_sr() & src); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(asr, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> (shift - 1))<<8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + if(GET_MSB_16(src)) + { + *r_dst |= 0xffff; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(asr, 32, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> (shift - 1))<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + if(GET_MSB_32(src)) + { + *r_dst = 0xffffffff; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(asr, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +M68KMAKE_OP(asl, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> (8-shift); + src &= m68ki_shift_16_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; +} + + +M68KMAKE_OP(asl, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> (24-shift); + src &= m68ki_shift_32_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; +} + + +M68KMAKE_OP(asl, 8, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift<> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + src &= m68ki_shift_16_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = FLAG_C = ((shift == 16 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = (!(src == 0))<<7; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(asl, 32, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift<> (32 - shift)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + src &= m68ki_shift_32_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = (!(src == 0))<<7; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(asl, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +M68KMAKE_OP(bcc, 8, ., .) +{ + if(M68KMAKE_CC) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +M68KMAKE_OP(bcc, 16, ., .) +{ + if(M68KMAKE_CC) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +M68KMAKE_OP(bcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + if(M68KMAKE_CC) + { + uint offset = OPER_I_32(); + REG_PC -= 4; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_32(offset); + return; + } + REG_PC += 4; + return; + } + else + { + if(M68KMAKE_CC) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); + } +} + + +M68KMAKE_OP(bchg, 32, r, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst ^= mask; +} + + +M68KMAKE_OP(bchg, 8, r, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +M68KMAKE_OP(bchg, 32, s, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst ^= mask; +} + + +M68KMAKE_OP(bchg, 8, s, .) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +M68KMAKE_OP(bclr, 32, r, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst &= ~mask; +} + + +M68KMAKE_OP(bclr, 8, r, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +M68KMAKE_OP(bclr, 32, s, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst &= ~mask; +} + + +M68KMAKE_OP(bclr, 8, s, .) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +M68KMAKE_OP(bfchg, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint* data = &DY; + uint64 mask; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + offset &= 31; + width = ((width-1) & 31) + 1; + + mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask = ROR_32(mask, offset); + + FLAG_N = NFLAG_32(*data<>6)&31; + uint width = word2; + uint mask_base; + uint data_long; + uint mask_long; + uint data_byte = 0; + uint mask_byte = 0; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask_long = mask_base >> offset; + + data_long = m68ki_read_32(ea); + FLAG_N = NFLAG_32(data_long << offset); + FLAG_Z = data_long & mask_long; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, data_long ^ mask_long); + + if((width + offset) > 32) + { + mask_byte = MASK_OUT_ABOVE_8(mask_base); + data_byte = m68ki_read_8(ea+4); + FLAG_Z |= (data_byte & mask_byte); + m68ki_write_8(ea+4, data_byte ^ mask_byte); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfclr, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint* data = &DY; + uint64 mask; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + + offset &= 31; + width = ((width-1) & 31) + 1; + + + mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask = ROR_32(mask, offset); + + FLAG_N = NFLAG_32(*data<>6)&31; + uint width = word2; + uint mask_base; + uint data_long; + uint mask_long; + uint data_byte = 0; + uint mask_byte = 0; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask_long = mask_base >> offset; + + data_long = m68ki_read_32(ea); + FLAG_N = NFLAG_32(data_long << offset); + FLAG_Z = data_long & mask_long; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, data_long & ~mask_long); + + if((width + offset) > 32) + { + mask_byte = MASK_OUT_ABOVE_8(mask_base); + data_byte = m68ki_read_8(ea+4); + FLAG_Z |= (data_byte & mask_byte); + m68ki_write_8(ea+4, data_byte & ~mask_byte); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfexts, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint64 data = DY; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + offset &= 31; + width = ((width-1) & 31) + 1; + + data = ROL_32(data, offset); + FLAG_N = NFLAG_32(data); + data = MAKE_INT_32(data) >> (32 - width); + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + REG_D[(word2>>12)&7] = data; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfexts, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint offset = (word2>>6)&31; + uint width = word2; + uint data; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + data = m68ki_read_32(ea); + + data = MASK_OUT_ABOVE_32(data< 32) + data |= (m68ki_read_8(ea+4) << offset) >> 8; + + FLAG_N = NFLAG_32(data); + data = MAKE_INT_32(data) >> (32 - width); + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + REG_D[(word2 >> 12) & 7] = data; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfextu, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint64 data = DY; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + offset &= 31; + width = ((width-1) & 31) + 1; + + data = ROL_32(data, offset); + FLAG_N = NFLAG_32(data); + data >>= 32 - width; + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + REG_D[(word2>>12)&7] = data; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfextu, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint offset = (word2>>6)&31; + uint width = word2; + uint data; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + data = m68ki_read_32(ea); + data = MASK_OUT_ABOVE_32(data< 32) + data |= (m68ki_read_8(ea+4) << offset) >> 8; + + FLAG_N = NFLAG_32(data); + data >>= (32 - width); + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + REG_D[(word2 >> 12) & 7] = data; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfffo, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint64 data = DY; + uint bit; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + offset &= 31; + width = ((width-1) & 31) + 1; + + data = ROL_32(data, offset); + FLAG_N = NFLAG_32(data); + data >>= 32 - width; + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + for(bit = 1<<(width-1);bit && !(data & bit);bit>>= 1) + offset++; + + REG_D[(word2>>12)&7] = offset; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfffo, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint offset = (word2>>6)&31; + sint local_offset; + uint width = word2; + uint data; + uint bit; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + local_offset = offset % 8; + if(local_offset < 0) + { + local_offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + data = m68ki_read_32(ea); + data = MASK_OUT_ABOVE_32(data< 32) + data |= (m68ki_read_8(ea+4) << local_offset) >> 8; + + FLAG_N = NFLAG_32(data); + data >>= (32 - width); + + FLAG_Z = data; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + for(bit = 1<<(width-1);bit && !(data & bit);bit>>= 1) + offset++; + + REG_D[(word2>>12)&7] = offset; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfins, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint* data = &DY; + uint64 mask; + uint64 insert = REG_D[(word2>>12)&7]; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + + offset &= 31; + width = ((width-1) & 31) + 1; + + + mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask = ROR_32(mask, offset); + + insert = MASK_OUT_ABOVE_32(insert << (32 - width)); + FLAG_N = NFLAG_32(insert); + FLAG_Z = insert; + insert = ROR_32(insert, offset); + + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + *data &= ~mask; + *data |= insert; + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfins, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint offset = (word2>>6)&31; + uint width = word2; + uint insert_base = REG_D[(word2>>12)&7]; + uint insert_long; + uint insert_byte; + uint mask_base; + uint data_long; + uint mask_long; + uint data_byte = 0; + uint mask_byte = 0; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask_long = mask_base >> offset; + + insert_base = MASK_OUT_ABOVE_32(insert_base << (32 - width)); + FLAG_N = NFLAG_32(insert_base); + FLAG_Z = insert_base; + insert_long = insert_base >> offset; + + data_long = m68ki_read_32(ea); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, (data_long & ~mask_long) | insert_long); + + if((width + offset) > 32) + { + mask_byte = MASK_OUT_ABOVE_8(mask_base); + insert_byte = MASK_OUT_ABOVE_8(insert_base); + data_byte = m68ki_read_8(ea+4); + FLAG_Z |= (data_byte & mask_byte); + m68ki_write_8(ea+4, (data_byte & ~mask_byte) | insert_byte); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bfset, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint* data = &DY; + uint64 mask; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + + offset &= 31; + width = ((width-1) & 31) + 1; + + + mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask = ROR_32(mask, offset); + + FLAG_N = NFLAG_32(*data<>6)&31; + uint width = word2; + uint mask_base; + uint data_long; + uint mask_long; + uint data_byte = 0; + uint mask_byte = 0; + uint ea = M68KMAKE_GET_EA_AY_8; + + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + + mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask_long = mask_base >> offset; + + data_long = m68ki_read_32(ea); + FLAG_N = NFLAG_32(data_long << offset); + FLAG_Z = data_long & mask_long; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, data_long | mask_long); + + if((width + offset) > 32) + { + mask_byte = MASK_OUT_ABOVE_8(mask_base); + data_byte = m68ki_read_8(ea+4); + FLAG_Z |= (data_byte & mask_byte); + m68ki_write_8(ea+4, data_byte | mask_byte); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bftst, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint offset = (word2>>6)&31; + uint width = word2; + uint* data = &DY; + uint64 mask; + + + if(BIT_B(word2)) + offset = REG_D[offset&7]; + if(BIT_5(word2)) + width = REG_D[width&7]; + + + offset &= 31; + width = ((width-1) & 31) + 1; + + + mask = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask = ROR_32(mask, offset); + + FLAG_N = NFLAG_32(*data<>6)&31; + uint width = word2; + uint mask_base; + uint data_long; + uint mask_long; + uint data_byte = 0; + uint mask_byte = 0; + uint ea = M68KMAKE_GET_EA_AY_8; + + if(BIT_B(word2)) + offset = MAKE_INT_32(REG_D[offset&7]); + if(BIT_5(word2)) + width = REG_D[width&7]; + + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } + width = ((width-1) & 31) + 1; + + + mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width)); + mask_long = mask_base >> offset; + + data_long = m68ki_read_32(ea); + FLAG_N = ((data_long & (0x80000000 >> offset))<>24; + FLAG_Z = data_long & mask_long; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + if((width + offset) > 32) + { + mask_byte = MASK_OUT_ABOVE_8(mask_base); + data_byte = m68ki_read_8(ea+4); + FLAG_Z |= (data_byte & mask_byte); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bkpt, 0, ., .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + m68ki_bkpt_ack(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE) ? REG_IR & 7 : 0); /* auto-disable (see m68kcpu.h) */ + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(bra, 8, ., .) +{ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + if(REG_PC == REG_PPC) + USE_ALL_CYCLES(); +} + + +M68KMAKE_OP(bra, 16, ., .) +{ + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_16(offset); + if(REG_PC == REG_PPC) + USE_ALL_CYCLES(); +} + + +M68KMAKE_OP(bra, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint offset = OPER_I_32(); + REG_PC -= 4; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_32(offset); + if(REG_PC == REG_PPC) + USE_ALL_CYCLES(); + return; + } + else + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + if(REG_PC == REG_PPC) + USE_ALL_CYCLES(); + } +} + + +M68KMAKE_OP(bset, 32, r, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst |= mask; +} + + +M68KMAKE_OP(bset, 8, r, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +M68KMAKE_OP(bset, 32, s, d) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst |= mask; +} + + +M68KMAKE_OP(bset, 8, s, .) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +M68KMAKE_OP(bsr, 8, ., .) +{ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_push_32(REG_PC); + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +} + + +M68KMAKE_OP(bsr, 16, ., .) +{ + uint offset = OPER_I_16(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_push_32(REG_PC); + REG_PC -= 2; + m68ki_branch_16(offset); +} + + +M68KMAKE_OP(bsr, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint offset = OPER_I_32(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_push_32(REG_PC); + REG_PC -= 4; + m68ki_branch_32(offset); + return; + } + else + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_push_32(REG_PC); + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + } +} + + +M68KMAKE_OP(btst, 32, r, d) +{ + FLAG_Z = DY & (1 << (DX & 0x1f)); +} + + +M68KMAKE_OP(btst, 8, r, .) +{ + FLAG_Z = M68KMAKE_GET_OPER_AY_8 & (1 << (DX & 7)); +} + + +M68KMAKE_OP(btst, 32, s, d) +{ + FLAG_Z = DY & (1 << (OPER_I_8() & 0x1f)); +} + + +M68KMAKE_OP(btst, 8, s, .) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = M68KMAKE_GET_OPER_AY_8 & (1 << bit); +} + + +M68KMAKE_OP(callm, 32, ., .) +{ + /* note: watch out for pcrelative modes */ + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + { + uint ea = M68KMAKE_GET_EA_AY_32; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + REG_PC += 2; +(void)ea; /* just to avoid an 'unused variable' warning */ + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cas, 8, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint dest = m68ki_read_8(ea); + uint* compare = ®_D[word2 & 7]; + uint res = dest - MASK_OUT_ABOVE_8(*compare); + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(*compare, dest, res); + FLAG_C = CFLAG_8(res); + + if(COND_NE()) + *compare = MASK_OUT_BELOW_8(*compare) | dest; + else + { + USE_CYCLES(3); + m68ki_write_8(ea, MASK_OUT_ABOVE_8(REG_D[(word2 >> 6) & 7])); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cas, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint dest = m68ki_read_16(ea); + uint* compare = ®_D[word2 & 7]; + uint res = dest - MASK_OUT_ABOVE_16(*compare); + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(*compare, dest, res); + FLAG_C = CFLAG_16(res); + + if(COND_NE()) + *compare = MASK_OUT_BELOW_16(*compare) | dest; + else + { + USE_CYCLES(3); + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_D[(word2 >> 6) & 7])); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cas, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint dest = m68ki_read_32(ea); + uint* compare = ®_D[word2 & 7]; + uint res = dest - *compare; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(*compare, dest, res); + FLAG_C = CFLAG_SUB_32(*compare, dest, res); + + if(COND_NE()) + *compare = dest; + else + { + USE_CYCLES(3); + m68ki_write_32(ea, REG_D[(word2 >> 6) & 7]); + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cas2, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_32(); + uint* compare1 = ®_D[(word2 >> 16) & 7]; + uint ea1 = REG_DA[(word2 >> 28) & 15]; + uint dest1 = m68ki_read_16(ea1); + uint res1 = dest1 - MASK_OUT_ABOVE_16(*compare1); + uint* compare2 = ®_D[word2 & 7]; + uint ea2 = REG_DA[(word2 >> 12) & 15]; + uint dest2 = m68ki_read_16(ea2); + uint res2; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_16(res1); + FLAG_Z = MASK_OUT_ABOVE_16(res1); + FLAG_V = VFLAG_SUB_16(*compare1, dest1, res1); + FLAG_C = CFLAG_16(res1); + + if(COND_EQ()) + { + res2 = dest2 - MASK_OUT_ABOVE_16(*compare2); + + FLAG_N = NFLAG_16(res2); + FLAG_Z = MASK_OUT_ABOVE_16(res2); + FLAG_V = VFLAG_SUB_16(*compare2, dest2, res2); + FLAG_C = CFLAG_16(res2); + + if(COND_EQ()) + { + USE_CYCLES(3); + m68ki_write_16(ea1, REG_D[(word2 >> 22) & 7]); + m68ki_write_16(ea2, REG_D[(word2 >> 6) & 7]); + return; + } + } + *compare1 = BIT_1F(word2) ? (uint)MAKE_INT_16(dest1) : MASK_OUT_BELOW_16(*compare1) | dest1; + *compare2 = BIT_F(word2) ? (uint)MAKE_INT_16(dest2) : MASK_OUT_BELOW_16(*compare2) | dest2; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cas2, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_32(); + uint* compare1 = ®_D[(word2 >> 16) & 7]; + uint ea1 = REG_DA[(word2 >> 28) & 15]; + uint dest1 = m68ki_read_32(ea1); + uint res1 = dest1 - *compare1; + uint* compare2 = ®_D[word2 & 7]; + uint ea2 = REG_DA[(word2 >> 12) & 15]; + uint dest2 = m68ki_read_32(ea2); + uint res2; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_32(res1); + FLAG_Z = MASK_OUT_ABOVE_32(res1); + FLAG_V = VFLAG_SUB_32(*compare1, dest1, res1); + FLAG_C = CFLAG_SUB_32(*compare1, dest1, res1); + + if(COND_EQ()) + { + res2 = dest2 - *compare2; + + FLAG_N = NFLAG_32(res2); + FLAG_Z = MASK_OUT_ABOVE_32(res2); + FLAG_V = VFLAG_SUB_32(*compare2, dest2, res2); + FLAG_C = CFLAG_SUB_32(*compare2, dest2, res2); + + if(COND_EQ()) + { + USE_CYCLES(3); + m68ki_write_32(ea1, REG_D[(word2 >> 22) & 7]); + m68ki_write_32(ea2, REG_D[(word2 >> 6) & 7]); + return; + } + } + *compare1 = dest1; + *compare2 = dest2; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk, 16, ., d) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(DY); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +M68KMAKE_OP(chk, 16, ., .) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +M68KMAKE_OP(chk, 32, ., d) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + sint src = MAKE_INT_32(DX); + sint bound = MAKE_INT_32(DY); + + FLAG_Z = ZFLAG_32(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + sint src = MAKE_INT_32(DX); + sint bound = MAKE_INT_32(M68KMAKE_GET_OPER_AY_32); + + FLAG_Z = ZFLAG_32(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 8, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + uint ea = EA_PCDI_8(); + sint lower_bound = m68ki_read_pcrel_8(ea); + sint upper_bound = m68ki_read_pcrel_8(ea + 1); + + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + + + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 8, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + uint ea = EA_PCIX_8(); + sint lower_bound = m68ki_read_pcrel_8(ea); + sint upper_bound = m68ki_read_pcrel_8(ea + 1); + + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => ||, faster operation short circuits + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 8, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + uint ea = M68KMAKE_GET_EA_AY_8; + sint lower_bound = (int8)m68ki_read_8(ea); + sint upper_bound = (int8)m68ki_read_8(ea + 1); + + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 16, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + uint ea = EA_PCDI_16(); + sint lower_bound = (int16)m68ki_read_pcrel_16(ea); + sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); + + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 16, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + uint ea = EA_PCIX_16(); + sint lower_bound = (int16)m68ki_read_pcrel_16(ea); + sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); + + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + uint ea = M68KMAKE_GET_EA_AY_16; + sint lower_bound = (int16)m68ki_read_16(ea); + sint upper_bound = (int16)m68ki_read_16(ea + 2); + + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 32, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = EA_PCDI_32(); + sint lower_bound = m68ki_read_pcrel_32(ea); + sint upper_bound = m68ki_read_pcrel_32(ea + 4); + + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 32, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + sint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = EA_PCIX_32(); + sint lower_bound = m68ki_read_32(ea); + sint upper_bound = m68ki_read_32(ea + 4); + + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(chk2cmp2, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + // JFF changed the logic. chk2/cmp2 uses signed values, not unsigned + sint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = M68KMAKE_GET_EA_AY_32; + sint lower_bound = m68ki_read_32(ea); + sint upper_bound = m68ki_read_32(ea + 4); + + FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + + FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + + if(COND_CS() && BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(clr, 8, ., d) +{ + DY &= 0xffffff00; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(clr, 8, ., .) +{ + m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(clr, 16, ., d) +{ + DY &= 0xffff0000; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(clr, 16, ., .) +{ + m68ki_write_16(M68KMAKE_GET_EA_AY_16, 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(clr, 32, ., d) +{ + DY = 0; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(clr, 32, ., .) +{ + m68ki_write_32(M68KMAKE_GET_EA_AY_32, 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +M68KMAKE_OP(cmp, 8, ., d) +{ + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmp, 8, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_8; + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmp, 16, ., d) +{ + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmp, 16, ., a) +{ + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmp, 16, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_16; + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmp, 32, ., d) +{ + uint src = DY; + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmp, 32, ., a) +{ + uint src = AY; + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmp, 32, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_32; + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 16, ., d) +{ + uint src = MAKE_INT_16(DY); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 16, ., a) +{ + uint src = MAKE_INT_16(AY); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 16, ., .) +{ + uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 32, ., d) +{ + uint src = DY; + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 32, ., a) +{ + uint src = AY; + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpa, 32, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_32; + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpi, 8, ., d) +{ + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(DY); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpi, 8, ., .) +{ + uint src = OPER_I_8(); + uint dst = M68KMAKE_GET_OPER_AY_8; + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpi, 8, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_8(); + uint dst = OPER_PCDI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpi, 8, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_8(); + uint dst = OPER_PCIX_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpi, 16, ., d) +{ + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(DY); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmpi, 16, ., .) +{ + uint src = OPER_I_16(); + uint dst = M68KMAKE_GET_OPER_AY_16; + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmpi, 16, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_16(); + uint dst = OPER_PCDI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpi, 16, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_16(); + uint dst = OPER_PCIX_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpi, 32, ., d) +{ + uint src = OPER_I_32(); + uint dst = DY; + uint res = dst - src; + + m68ki_cmpild_callback(src, REG_IR & 7); /* auto-disable (see m68kcpu.h) */ + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpi, 32, ., .) +{ + uint src = OPER_I_32(); + uint dst = M68KMAKE_GET_OPER_AY_32; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cmpi, 32, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_32(); + uint dst = OPER_PCDI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpi, 32, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_I_32(); + uint dst = OPER_PCIX_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(cmpm, 8, ., ax7) +{ + uint src = OPER_AY_PI_8(); + uint dst = OPER_A7_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpm, 8, ., ay7) +{ + uint src = OPER_A7_PI_8(); + uint dst = OPER_AX_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpm, 8, ., axy7) +{ + uint src = OPER_A7_PI_8(); + uint dst = OPER_A7_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpm, 8, ., .) +{ + uint src = OPER_AY_PI_8(); + uint dst = OPER_AX_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +M68KMAKE_OP(cmpm, 16, ., .) +{ + uint src = OPER_AY_PI_16(); + uint dst = OPER_AX_PI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +M68KMAKE_OP(cmpm, 32, ., .) +{ + uint src = OPER_AY_PI_32(); + uint dst = OPER_AX_PI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +M68KMAKE_OP(cpbcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(cpdbcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(cpgen, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(cpscc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(cptrapcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + // JFF: unsupported, but at least if the trap doesn't occur, app should still work, so at least PC increase is correct + REG_PC += 4; + return; + } + m68ki_exception_1111(); +} + + +M68KMAKE_OP(dbt, 16, ., .) +{ + REG_PC += 2; +} + + +M68KMAKE_OP(dbf, 16, ., .) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); +} + + +M68KMAKE_OP(dbcc, 16, ., .) +{ + if(M68KMAKE_NOT_CC) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +M68KMAKE_OP(divs, 16, ., d) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(DY); + sint quotient; + sint remainder; + + if(src != 0) + { + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +M68KMAKE_OP(divs, 16, ., .) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); + sint quotient; + sint remainder; + + if(src != 0) + { + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +M68KMAKE_OP(divu, 16, ., d) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +M68KMAKE_OP(divu, 16, ., .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_16; + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +M68KMAKE_OP(divl, 32, ., d) +{ +#if M68K_USE_64_BIT + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint64 divisor = DY; + uint64 dividend = 0; + uint64 quotient = 0; + uint64 remainder = 0; + + if(divisor != 0) + { + if(BIT_A(word2)) /* 64 bit */ + { + dividend = REG_D[word2 & 7]; + dividend <<= 32; + dividend |= REG_D[(word2 >> 12) & 7]; + + if(BIT_B(word2)) /* signed */ + { + quotient = (uint64)((sint64)dividend / (sint64)((sint32)divisor)); + remainder = (uint64)((sint64)dividend % (sint64)((sint32)divisor)); + if((sint64)quotient != (sint64)((sint32)quotient)) + { + FLAG_V = VFLAG_SET; + return; + } + } + else /* unsigned */ + { + quotient = dividend / divisor; + if(quotient > 0xffffffff) + { + FLAG_V = VFLAG_SET; + return; + } + remainder = dividend % divisor; + } + } + else /* 32 bit */ + { + dividend = REG_D[(word2 >> 12) & 7]; + if(BIT_B(word2)) /* signed */ + { + quotient = (uint64)((sint64)((sint32)dividend) / (sint64)((sint32)divisor)); + remainder = (uint64)((sint64)((sint32)dividend) % (sint64)((sint32)divisor)); + } + else /* unsigned */ + { + quotient = dividend / divisor; + remainder = dividend % divisor; + } + } + + REG_D[word2 & 7] = remainder; + REG_D[(word2 >> 12) & 7] = quotient; + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); + return; + } + m68ki_exception_illegal(); + +#else + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint divisor = DY; + uint dividend_hi = REG_D[word2 & 7]; + uint dividend_lo = REG_D[(word2 >> 12) & 7]; + uint quotient = 0; + uint remainder = 0; + uint dividend_neg = 0; + uint divisor_neg = 0; + sint i; + uint overflow; + + if(divisor != 0) + { + /* quad / long : long quotient, long remainder */ + if(BIT_A(word2)) + { + if(BIT_B(word2)) /* signed */ + { + /* special case in signed divide */ + if(dividend_hi == 0 && dividend_lo == 0x80000000 && divisor == 0xffffffff) + { + REG_D[word2 & 7] = 0; + REG_D[(word2 >> 12) & 7] = 0x80000000; + + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + if(GET_MSB_32(dividend_hi)) + { + dividend_neg = 1; + dividend_hi = (uint)MASK_OUT_ABOVE_32((-(sint)dividend_hi) - (dividend_lo != 0)); + dividend_lo = (uint)MASK_OUT_ABOVE_32(-(sint)dividend_lo); + } + if(GET_MSB_32(divisor)) + { + divisor_neg = 1; + divisor = (uint)MASK_OUT_ABOVE_32(-(sint)divisor); + + } + } + + /* if the upper long is greater than the divisor, we're overflowing. */ + if(dividend_hi >= divisor) + { + FLAG_V = VFLAG_SET; + return; + } + + for(i = 31; i >= 0; i--) + { + quotient <<= 1; + remainder = (remainder << 1) + ((dividend_hi >> i) & 1); + if(remainder >= divisor) + { + remainder -= divisor; + quotient++; + } + } + for(i = 31; i >= 0; i--) + { + quotient <<= 1; + overflow = GET_MSB_32(remainder); + remainder = (remainder << 1) + ((dividend_lo >> i) & 1); + if(remainder >= divisor || overflow) + { + remainder -= divisor; + quotient++; + } + } + + if(BIT_B(word2)) /* signed */ + { + if(quotient > 0x7fffffff) + { + FLAG_V = VFLAG_SET; + return; + } + if(dividend_neg) + { + remainder = (uint)MASK_OUT_ABOVE_32(-(sint)remainder); + quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); + } + if(divisor_neg) + quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); + } + + REG_D[word2 & 7] = remainder; + REG_D[(word2 >> 12) & 7] = quotient; + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + + /* long / long: long quotient, maybe long remainder */ + if(BIT_B(word2)) /* signed */ + { + /* Special case in divide */ + if(dividend_lo == 0x80000000 && divisor == 0xffffffff) + { + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + REG_D[(word2 >> 12) & 7] = 0x80000000; + REG_D[word2 & 7] = 0; + return; + } + REG_D[word2 & 7] = MAKE_INT_32(dividend_lo) % MAKE_INT_32(divisor); + quotient = REG_D[(word2 >> 12) & 7] = MAKE_INT_32(dividend_lo) / MAKE_INT_32(divisor); + } + else + { + REG_D[word2 & 7] = MASK_OUT_ABOVE_32(dividend_lo) % MASK_OUT_ABOVE_32(divisor); + quotient = REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(dividend_lo) / MASK_OUT_ABOVE_32(divisor); + } + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); + return; + } + m68ki_exception_illegal(); + +#endif +} + + +M68KMAKE_OP(divl, 32, ., .) +{ +#if M68K_USE_64_BIT + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint64 divisor = M68KMAKE_GET_OPER_AY_32; + uint64 dividend = 0; + uint64 quotient = 0; + uint64 remainder = 0; + + if(divisor != 0) + { + if(BIT_A(word2)) /* 64 bit */ + { + dividend = REG_D[word2 & 7]; + dividend <<= 32; + dividend |= REG_D[(word2 >> 12) & 7]; + + if(BIT_B(word2)) /* signed */ + { + quotient = (uint64)((sint64)dividend / (sint64)((sint32)divisor)); + remainder = (uint64)((sint64)dividend % (sint64)((sint32)divisor)); + if((sint64)quotient != (sint64)((sint32)quotient)) + { + FLAG_V = VFLAG_SET; + return; + } + } + else /* unsigned */ + { + quotient = dividend / divisor; + if(quotient > 0xffffffff) + { + FLAG_V = VFLAG_SET; + return; + } + remainder = dividend % divisor; + } + } + else /* 32 bit */ + { + dividend = REG_D[(word2 >> 12) & 7]; + if(BIT_B(word2)) /* signed */ + { + quotient = (uint64)((sint64)((sint32)dividend) / (sint64)((sint32)divisor)); + remainder = (uint64)((sint64)((sint32)dividend) % (sint64)((sint32)divisor)); + } + else /* unsigned */ + { + quotient = dividend / divisor; + remainder = dividend % divisor; + } + } + + REG_D[word2 & 7] = remainder; + REG_D[(word2 >> 12) & 7] = quotient; + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); + return; + } + m68ki_exception_illegal(); + +#else + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint divisor = M68KMAKE_GET_OPER_AY_32; + uint dividend_hi = REG_D[word2 & 7]; + uint dividend_lo = REG_D[(word2 >> 12) & 7]; + uint quotient = 0; + uint remainder = 0; + uint dividend_neg = 0; + uint divisor_neg = 0; + sint i; + uint overflow; + + if(divisor != 0) + { + /* quad / long : long quotient, long remainder */ + if(BIT_A(word2)) + { + if(BIT_B(word2)) /* signed */ + { + /* special case in signed divide */ + if(dividend_hi == 0 && dividend_lo == 0x80000000 && divisor == 0xffffffff) + { + REG_D[word2 & 7] = 0; + REG_D[(word2 >> 12) & 7] = 0x80000000; + + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + if(GET_MSB_32(dividend_hi)) + { + dividend_neg = 1; + dividend_hi = (uint)MASK_OUT_ABOVE_32((-(sint)dividend_hi) - (dividend_lo != 0)); + dividend_lo = (uint)MASK_OUT_ABOVE_32(-(sint)dividend_lo); + } + if(GET_MSB_32(divisor)) + { + divisor_neg = 1; + divisor = (uint)MASK_OUT_ABOVE_32(-(sint)divisor); + + } + } + + /* if the upper long is greater than the divisor, we're overflowing. */ + if(dividend_hi >= divisor) + { + FLAG_V = VFLAG_SET; + return; + } + + for(i = 31; i >= 0; i--) + { + quotient <<= 1; + remainder = (remainder << 1) + ((dividend_hi >> i) & 1); + if(remainder >= divisor) + { + remainder -= divisor; + quotient++; + } + } + for(i = 31; i >= 0; i--) + { + quotient <<= 1; + overflow = GET_MSB_32(remainder); + remainder = (remainder << 1) + ((dividend_lo >> i) & 1); + if(remainder >= divisor || overflow) + { + remainder -= divisor; + quotient++; + } + } + + if(BIT_B(word2)) /* signed */ + { + if(quotient > 0x7fffffff) + { + FLAG_V = VFLAG_SET; + return; + } + if(dividend_neg) + { + remainder = (uint)MASK_OUT_ABOVE_32(-(sint)remainder); + quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); + } + if(divisor_neg) + quotient = (uint)MASK_OUT_ABOVE_32(-(sint)quotient); + } + + REG_D[word2 & 7] = remainder; + REG_D[(word2 >> 12) & 7] = quotient; + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + + /* long / long: long quotient, maybe long remainder */ + if(BIT_B(word2)) /* signed */ + { + /* Special case in divide */ + if(dividend_lo == 0x80000000 && divisor == 0xffffffff) + { + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + REG_D[(word2 >> 12) & 7] = 0x80000000; + REG_D[word2 & 7] = 0; + return; + } + REG_D[word2 & 7] = MAKE_INT_32(dividend_lo) % MAKE_INT_32(divisor); + quotient = REG_D[(word2 >> 12) & 7] = MAKE_INT_32(dividend_lo) / MAKE_INT_32(divisor); + } + else + { + REG_D[word2 & 7] = MASK_OUT_ABOVE_32(dividend_lo) % MASK_OUT_ABOVE_32(divisor); + quotient = REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(dividend_lo) / MASK_OUT_ABOVE_32(divisor); + } + + FLAG_N = NFLAG_32(quotient); + FLAG_Z = quotient; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); + return; + } + m68ki_exception_illegal(); + +#endif +} + + +M68KMAKE_OP(eor, 8, ., d) +{ + uint res = MASK_OUT_ABOVE_8(DY ^= MASK_OUT_ABOVE_8(DX)); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eor, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eor, 16, ., d) +{ + uint res = MASK_OUT_ABOVE_16(DY ^= MASK_OUT_ABOVE_16(DX)); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eor, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eor, 32, ., d) +{ + uint res = DY ^= DX; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eor, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 8, ., d) +{ + uint res = MASK_OUT_ABOVE_8(DY ^= OPER_I_8()); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 8, ., .) +{ + uint src = OPER_I_8(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 16, ., d) +{ + uint res = MASK_OUT_ABOVE_16(DY ^= OPER_I_16()); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 16, ., .) +{ + uint src = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 32, ., d) +{ + uint res = DY ^= OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 32, ., .) +{ + uint src = OPER_I_32(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(eori, 16, toc, .) +{ + m68ki_set_ccr(m68ki_get_ccr() ^ OPER_I_8()); +} + + +M68KMAKE_OP(eori, 16, tos, .) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_set_sr(m68ki_get_sr() ^ src); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(exg, 32, dd, .) +{ + uint* reg_a = &DX; + uint* reg_b = &DY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +M68KMAKE_OP(exg, 32, aa, .) +{ + uint* reg_a = &AX; + uint* reg_b = &AY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +M68KMAKE_OP(exg, 32, da, .) +{ + uint* reg_a = &DX; + uint* reg_b = &AY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +M68KMAKE_OP(ext, 16, ., .) +{ + uint* r_dst = &DY; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | MASK_OUT_ABOVE_8(*r_dst) | (GET_MSB_8(*r_dst) ? 0xff00 : 0); + + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(ext, 32, ., .) +{ + uint* r_dst = &DY; + + *r_dst = MASK_OUT_ABOVE_16(*r_dst) | (GET_MSB_16(*r_dst) ? 0xffff0000 : 0); + + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(extb, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint* r_dst = &DY; + + *r_dst = MASK_OUT_ABOVE_8(*r_dst) | (GET_MSB_8(*r_dst) ? 0xffffff00 : 0); + + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(illegal, 0, ., .) +{ + m68ki_exception_illegal(); +} + +M68KMAKE_OP(jmp, 32, ., .) +{ + m68ki_jump(M68KMAKE_GET_EA_AY_32); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + if(REG_PC == REG_PPC) + USE_ALL_CYCLES(); +} + + +M68KMAKE_OP(jsr, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +M68KMAKE_OP(lea, 32, ., .) +{ + AX = M68KMAKE_GET_EA_AY_32; +} + + +M68KMAKE_OP(link, 16, ., a7) +{ + REG_A[7] -= 4; + m68ki_write_32(REG_A[7], REG_A[7]); + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); +} + + +M68KMAKE_OP(link, 16, ., .) +{ + uint* r_dst = &AY; + + m68ki_push_32(*r_dst); + *r_dst = REG_A[7]; + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); +} + + +M68KMAKE_OP(link, 32, ., a7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_A[7] -= 4; + m68ki_write_32(REG_A[7], REG_A[7]); + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32()); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(link, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint* r_dst = &AY; + + m68ki_push_32(*r_dst); + *r_dst = REG_A[7]; + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32()); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(lsr, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift<> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> (shift - 1))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsr, 32, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift<> (shift - 1))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = (shift == 32 ? GET_MSB_32(src)>>23 : 0); + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsr, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> (8-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + USE_CYCLES(shift<> (24-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 8, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift<> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 32, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift<> (32 - shift)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, d, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, d, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, ai, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_AI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, ai, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AX_AI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pi7, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_A7_PI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pi, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_PI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pi7, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_A7_PI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pi, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AX_PI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pd7, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_A7_PD_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pd, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_PD_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pd7, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_A7_PD_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, pd, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AX_PD_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, di, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_DI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, di, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AX_DI_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, ix, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_IX_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, ix, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AX_IX_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, aw, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AW_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, aw, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AW_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, al, d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AL_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 8, al, .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + uint ea = EA_AL_8(); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, d, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, d, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, d, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ai, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_AI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ai, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_AI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ai, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AX_AI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pi, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_PI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pi, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_PI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pi, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AX_PI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pd, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_PD_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pd, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_PD_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, pd, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AX_PD_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, di, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_DI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, di, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_DI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, di, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AX_DI_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ix, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_IX_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ix, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_IX_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, ix, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AX_IX_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, aw, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AW_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, aw, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AW_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, aw, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AW_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, al, d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AL_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, al, a) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AL_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 16, al, .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + uint ea = EA_AL_16(); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, d, d) +{ + uint res = DY; + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, d, a) +{ + uint res = AY; + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, d, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ai, d) +{ + uint res = DY; + uint ea = EA_AX_AI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ai, a) +{ + uint res = AY; + uint ea = EA_AX_AI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ai, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AX_AI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pi, d) +{ + uint res = DY; + uint ea = EA_AX_PI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pi, a) +{ + uint res = AY; + uint ea = EA_AX_PI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pi, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AX_PI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pd, d) +{ + uint res = DY; + uint ea = EA_AX_PD_32(); + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pd, a) +{ + uint res = AY; + uint ea = EA_AX_PD_32(); + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, pd, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AX_PD_32(); + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, di, d) +{ + uint res = DY; + uint ea = EA_AX_DI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, di, a) +{ + uint res = AY; + uint ea = EA_AX_DI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, di, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AX_DI_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ix, d) +{ + uint res = DY; + uint ea = EA_AX_IX_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ix, a) +{ + uint res = AY; + uint ea = EA_AX_IX_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, ix, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AX_IX_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, aw, d) +{ + uint res = DY; + uint ea = EA_AW_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, aw, a) +{ + uint res = AY; + uint ea = EA_AW_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, aw, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AW_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, al, d) +{ + uint res = DY; + uint ea = EA_AL_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, al, a) +{ + uint res = AY; + uint ea = EA_AL_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move, 32, al, .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + uint ea = EA_AL_32(); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(movea, 16, ., d) +{ + AX = MAKE_INT_16(DY); +} + + +M68KMAKE_OP(movea, 16, ., a) +{ + AX = MAKE_INT_16(AY); +} + + +M68KMAKE_OP(movea, 16, ., .) +{ + AX = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); +} + + +M68KMAKE_OP(movea, 32, ., d) +{ + AX = DY; +} + + +M68KMAKE_OP(movea, 32, ., a) +{ + AX = AY; +} + + +M68KMAKE_OP(movea, 32, ., .) +{ + AX = M68KMAKE_GET_OPER_AY_32; +} + + +M68KMAKE_OP(move, 16, frc, d) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + DY = MASK_OUT_BELOW_16(DY) | m68ki_get_ccr(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(move, 16, frc, .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + m68ki_write_16(M68KMAKE_GET_EA_AY_16, m68ki_get_ccr()); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(move, 16, toc, d) +{ + m68ki_set_ccr(DY); +} + + +M68KMAKE_OP(move, 16, toc, .) +{ + m68ki_set_ccr(M68KMAKE_GET_OPER_AY_16); +} + + +M68KMAKE_OP(move, 16, frs, d) +{ + if(CPU_TYPE_IS_000(CPU_TYPE) || FLAG_S) /* NS990408 */ + { + DY = MASK_OUT_BELOW_16(DY) | m68ki_get_sr(); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(move, 16, frs, .) +{ + if(CPU_TYPE_IS_000(CPU_TYPE) || FLAG_S) /* NS990408 */ + { + uint ea = M68KMAKE_GET_EA_AY_16; + m68ki_write_16(ea, m68ki_get_sr()); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(move, 16, tos, d) +{ + if(FLAG_S) + { + m68ki_set_sr(DY); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(move, 16, tos, .) +{ + if(FLAG_S) + { + uint new_sr = M68KMAKE_GET_OPER_AY_16; + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(move, 32, fru, .) +{ + if(FLAG_S) + { + AY = REG_USP; + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(move, 32, tou, .) +{ + if(FLAG_S) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + REG_USP = AY; + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(movec, 32, cr, .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + if(FLAG_S) + { + uint word2 = OPER_I_16(); + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + switch (word2 & 0xfff) + { + case 0x000: /* SFC */ + REG_DA[(word2 >> 12) & 15] = REG_SFC; + return; + case 0x001: /* DFC */ + REG_DA[(word2 >> 12) & 15] = REG_DFC; + return; + case 0x002: /* CACR */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_DA[(word2 >> 12) & 15] = REG_CACR; + return; + } + return; + case 0x800: /* USP */ + REG_DA[(word2 >> 12) & 15] = REG_USP; + return; + case 0x801: /* VBR */ + REG_DA[(word2 >> 12) & 15] = REG_VBR; + return; + case 0x802: /* CAAR */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_DA[(word2 >> 12) & 15] = REG_CAAR; + return; + } + m68ki_exception_illegal(); + break; + case 0x803: /* MSP */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_DA[(word2 >> 12) & 15] = FLAG_M ? REG_SP : REG_MSP; + return; + } + m68ki_exception_illegal(); + return; + case 0x804: /* ISP */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_DA[(word2 >> 12) & 15] = FLAG_M ? REG_ISP : REG_SP; + return; + } + m68ki_exception_illegal(); + return; + case 0x003: /* TC */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x004: /* ITT0 */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x005: /* ITT1 */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x006: /* DTT0 */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x007: /* DTT1 */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x805: /* MMUSR */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x806: /* URP */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x807: /* SRP */ + if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + default: + m68ki_exception_illegal(); + return; + } + } + m68ki_exception_privilege_violation(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(movec, 32, rc, .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + if(FLAG_S) + { + uint word2 = OPER_I_16(); + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + switch (word2 & 0xfff) + { + case 0x000: /* SFC */ + REG_SFC = REG_DA[(word2 >> 12) & 15] & 7; + return; + case 0x001: /* DFC */ + REG_DFC = REG_DA[(word2 >> 12) & 15] & 7; + return; + case 0x002: /* CACR */ + /* Only EC020 and later have CACR */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* 68030 can write all bits except 5-7, 040 can write all */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + REG_CACR = REG_DA[(word2 >> 12) & 15]; + } + else if (CPU_TYPE_IS_030_PLUS(CPU_TYPE)) + { + REG_CACR = REG_DA[(word2 >> 12) & 15] & 0xff1f; + } + else + { + REG_CACR = REG_DA[(word2 >> 12) & 15] & 0x0f; + } + return; + } + m68ki_exception_illegal(); + return; + case 0x800: /* USP */ + REG_USP = REG_DA[(word2 >> 12) & 15]; + return; + case 0x801: /* VBR */ + REG_VBR = REG_DA[(word2 >> 12) & 15]; + return; + case 0x802: /* CAAR */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_CAAR = REG_DA[(word2 >> 12) & 15]; + return; + } + m68ki_exception_illegal(); + return; + case 0x803: /* MSP */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* we are in supervisor mode so just check for M flag */ + if(!FLAG_M) + { + REG_MSP = REG_DA[(word2 >> 12) & 15]; + return; + } + REG_SP = REG_DA[(word2 >> 12) & 15]; + return; + } + m68ki_exception_illegal(); + return; + case 0x804: /* ISP */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + if(!FLAG_M) + { + REG_SP = REG_DA[(word2 >> 12) & 15]; + return; + } + REG_ISP = REG_DA[(word2 >> 12) & 15]; + return; + } + m68ki_exception_illegal(); + return; + case 0x003: /* TC */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x004: /* ITT0 */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x005: /* ITT1 */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x006: /* DTT0 */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x007: /* DTT1 */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x805: /* MMUSR */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x806: /* URP */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + case 0x807: /* SRP */ + if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) + { + /* TODO */ + return; + } + m68ki_exception_illegal(); + return; + default: + m68ki_exception_illegal(); + return; + } + } + m68ki_exception_privilege_violation(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(movem, 16, re, pd) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = AY; + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + ea -= 2; + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[15-i])); + count++; + } + AY = ea; + + USE_CYCLES(count<> 16) & 0xFFFF ); + count++; + } + AY = ea; + + USE_CYCLES(count<> 8)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); +} + + +M68KMAKE_OP(movep, 32, re, .) +{ + uint ea = EA_AY_DI_32(); + uint src = DX; + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(src >> 24)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 16)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 8)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); +} + + +M68KMAKE_OP(movep, 16, er, .) +{ + uint ea = EA_AY_DI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | ((m68ki_read_8(ea) << 8) + m68ki_read_8(ea + 2)); +} + + +M68KMAKE_OP(movep, 32, er, .) +{ + uint ea = EA_AY_DI_32(); + + DX = (m68ki_read_8(ea) << 24) + (m68ki_read_8(ea + 2) << 16) + + (m68ki_read_8(ea + 4) << 8) + m68ki_read_8(ea + 6); +} + + +M68KMAKE_OP(moves, 8, ., .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + if(FLAG_S) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_8; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + if(BIT_B(word2)) /* Register to memory */ + { + m68ki_write_8_fc(ea, REG_DFC, MASK_OUT_ABOVE_8(REG_DA[(word2 >> 12) & 15])); + return; + } + if(BIT_F(word2)) /* Memory to address register */ + { + REG_A[(word2 >> 12) & 7] = MAKE_INT_8(m68ki_read_8_fc(ea, REG_SFC)); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + /* Memory to data register */ + REG_D[(word2 >> 12) & 7] = MASK_OUT_BELOW_8(REG_D[(word2 >> 12) & 7]) | m68ki_read_8_fc(ea, REG_SFC); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + m68ki_exception_privilege_violation(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(moves, 16, ., .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + if(FLAG_S) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + if(BIT_B(word2)) /* Register to memory */ + { + m68ki_write_16_fc(ea, REG_DFC, MASK_OUT_ABOVE_16(REG_DA[(word2 >> 12) & 15])); + return; + } + if(BIT_F(word2)) /* Memory to address register */ + { + REG_A[(word2 >> 12) & 7] = MAKE_INT_16(m68ki_read_16_fc(ea, REG_SFC)); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + /* Memory to data register */ + REG_D[(word2 >> 12) & 7] = MASK_OUT_BELOW_16(REG_D[(word2 >> 12) & 7]) | m68ki_read_16_fc(ea, REG_SFC); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + m68ki_exception_privilege_violation(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(moves, 32, ., .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + if(FLAG_S) + { + uint word2 = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_32; + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + if(BIT_B(word2)) /* Register to memory */ + { + m68ki_write_32_fc(ea, REG_DFC, REG_DA[(word2 >> 12) & 15]); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + /* Memory to register */ + REG_DA[(word2 >> 12) & 15] = m68ki_read_32_fc(ea, REG_SFC); + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + USE_CYCLES(2); + return; + } + m68ki_exception_privilege_violation(); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(moveq, 32, ., .) +{ + uint res = DX = MAKE_INT_8(MASK_OUT_ABOVE_8(REG_IR)); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(move16, 32, ., .) +{ + uint16 w2 = OPER_I_16(); + int ax = REG_IR & 7; + int ay = (w2 >> 12) & 7; + + m68ki_write_32(REG_A[ay], m68ki_read_32(REG_A[ax])); + m68ki_write_32(REG_A[ay]+4, m68ki_read_32(REG_A[ax]+4)); + m68ki_write_32(REG_A[ay]+8, m68ki_read_32(REG_A[ax]+8)); + m68ki_write_32(REG_A[ay]+12, m68ki_read_32(REG_A[ax]+12)); + + REG_A[ax] += 16; + REG_A[ay] += 16; +} + + +M68KMAKE_OP(muls, 16, ., d) +{ + uint* r_dst = &DX; + uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(DY) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(muls, 16, ., .) +{ + uint* r_dst = &DX; + uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(M68KMAKE_GET_OPER_AY_16) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(mulu, 16, ., d) +{ + uint* r_dst = &DX; + uint res = MASK_OUT_ABOVE_16(DY) * MASK_OUT_ABOVE_16(*r_dst); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(mulu, 16, ., .) +{ + uint* r_dst = &DX; + uint res = M68KMAKE_GET_OPER_AY_16 * MASK_OUT_ABOVE_16(*r_dst); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(mull, 32, ., d) +{ +#if M68K_USE_64_BIT + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint64 src = DY; + uint64 dst = REG_D[(word2 >> 12) & 7]; + uint64 res; + + FLAG_C = CFLAG_CLEAR; + + if(BIT_B(word2)) /* signed */ + { + res = (sint64)((sint32)src) * (sint64)((sint32)dst); + if(!BIT_A(word2)) + { + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_N = NFLAG_32(res); + FLAG_V = ((sint64)res != (sint32)res)<<7; + REG_D[(word2 >> 12) & 7] = FLAG_Z; + return; + } + FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); + FLAG_N = NFLAG_64(res); + FLAG_V = VFLAG_CLEAR; + REG_D[word2 & 7] = (res >> 32); + REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); + return; + } + + res = src * dst; + if(!BIT_A(word2)) + { + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_N = NFLAG_32(res); + FLAG_V = (res > 0xffffffff)<<7; + REG_D[(word2 >> 12) & 7] = FLAG_Z; + return; + } + FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); + FLAG_N = NFLAG_64(res); + FLAG_V = VFLAG_CLEAR; + REG_D[word2 & 7] = (res >> 32); + REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); + return; + } + m68ki_exception_illegal(); + +#else + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint src = DY; + uint dst = REG_D[(word2 >> 12) & 7]; + uint neg = GET_MSB_32(src ^ dst); + uint src1; + uint src2; + uint dst1; + uint dst2; + uint r1; + uint r2; + uint r3; + uint r4; + uint lo; + uint hi; + + FLAG_C = CFLAG_CLEAR; + + if(BIT_B(word2)) /* signed */ + { + if(GET_MSB_32(src)) + src = (uint)MASK_OUT_ABOVE_32(-(sint)src); + if(GET_MSB_32(dst)) + dst = (uint)MASK_OUT_ABOVE_32(-(sint)dst); + } + + src1 = MASK_OUT_ABOVE_16(src); + src2 = src>>16; + dst1 = MASK_OUT_ABOVE_16(dst); + dst2 = dst>>16; + + + r1 = src1 * dst1; + r2 = src1 * dst2; + r3 = src2 * dst1; + r4 = src2 * dst2; + + lo = r1 + (MASK_OUT_ABOVE_16(r2)<<16) + (MASK_OUT_ABOVE_16(r3)<<16); + hi = r4 + (r2>>16) + (r3>>16) + (((r1>>16) + MASK_OUT_ABOVE_16(r2) + MASK_OUT_ABOVE_16(r3)) >> 16); + + if(BIT_B(word2) && neg) + { + hi = (uint)MASK_OUT_ABOVE_32((-(sint)hi) - (lo != 0)); + lo = (uint)MASK_OUT_ABOVE_32(-(sint)lo); + } + + if(BIT_A(word2)) + { + REG_D[word2 & 7] = hi; + REG_D[(word2 >> 12) & 7] = lo; + FLAG_N = NFLAG_32(hi); + FLAG_Z = hi | lo; + FLAG_V = VFLAG_CLEAR; + return; + } + + REG_D[(word2 >> 12) & 7] = lo; + FLAG_N = NFLAG_32(lo); + FLAG_Z = lo; + if(BIT_B(word2)) + FLAG_V = (!((GET_MSB_32(lo) && hi == 0xffffffff) || (!GET_MSB_32(lo) && !hi)))<<7; + else + FLAG_V = (hi != 0) << 7; + return; + } + m68ki_exception_illegal(); + +#endif +} + + +M68KMAKE_OP(mull, 32, ., .) +{ +#if M68K_USE_64_BIT + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint64 src = M68KMAKE_GET_OPER_AY_32; + uint64 dst = REG_D[(word2 >> 12) & 7]; + uint64 res; + + FLAG_C = CFLAG_CLEAR; + + if(BIT_B(word2)) /* signed */ + { + res = (sint64)((sint32)src) * (sint64)((sint32)dst); + if(!BIT_A(word2)) + { + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_N = NFLAG_32(res); + FLAG_V = ((sint64)res != (sint32)res)<<7; + REG_D[(word2 >> 12) & 7] = FLAG_Z; + return; + } + FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); + FLAG_N = NFLAG_64(res); + FLAG_V = VFLAG_CLEAR; + REG_D[word2 & 7] = (res >> 32); + REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); + return; + } + + res = src * dst; + if(!BIT_A(word2)) + { + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_N = NFLAG_32(res); + FLAG_V = (res > 0xffffffff)<<7; + REG_D[(word2 >> 12) & 7] = FLAG_Z; + return; + } + FLAG_Z = MASK_OUT_ABOVE_32(res) | (res>>32); + FLAG_N = NFLAG_64(res); + FLAG_V = VFLAG_CLEAR; + REG_D[word2 & 7] = (res >> 32); + REG_D[(word2 >> 12) & 7] = MASK_OUT_ABOVE_32(res); + return; + } + m68ki_exception_illegal(); + +#else + + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint word2 = OPER_I_16(); + uint src = M68KMAKE_GET_OPER_AY_32; + uint dst = REG_D[(word2 >> 12) & 7]; + uint neg = GET_MSB_32(src ^ dst); + uint src1; + uint src2; + uint dst1; + uint dst2; + uint r1; + uint r2; + uint r3; + uint r4; + uint lo; + uint hi; + + FLAG_C = CFLAG_CLEAR; + + if(BIT_B(word2)) /* signed */ + { + if(GET_MSB_32(src)) + src = (uint)MASK_OUT_ABOVE_32(-(sint)src); + if(GET_MSB_32(dst)) + dst = (uint)MASK_OUT_ABOVE_32(-(sint)dst); + } + + src1 = MASK_OUT_ABOVE_16(src); + src2 = src>>16; + dst1 = MASK_OUT_ABOVE_16(dst); + dst2 = dst>>16; + + + r1 = src1 * dst1; + r2 = src1 * dst2; + r3 = src2 * dst1; + r4 = src2 * dst2; + + lo = r1 + (MASK_OUT_ABOVE_16(r2)<<16) + (MASK_OUT_ABOVE_16(r3)<<16); + hi = r4 + (r2>>16) + (r3>>16) + (((r1>>16) + MASK_OUT_ABOVE_16(r2) + MASK_OUT_ABOVE_16(r3)) >> 16); + + if(BIT_B(word2) && neg) + { + hi = (uint)MASK_OUT_ABOVE_32((-(sint)hi) - (lo != 0)); + lo = (uint)MASK_OUT_ABOVE_32(-(sint)lo); + } + + if(BIT_A(word2)) + { + REG_D[word2 & 7] = hi; + REG_D[(word2 >> 12) & 7] = lo; + FLAG_N = NFLAG_32(hi); + FLAG_Z = hi | lo; + FLAG_V = VFLAG_CLEAR; + return; + } + + REG_D[(word2 >> 12) & 7] = lo; + FLAG_N = NFLAG_32(lo); + FLAG_Z = lo; + if(BIT_B(word2)) + FLAG_V = (!((GET_MSB_32(lo) && hi == 0xffffffff) || (!GET_MSB_32(lo) && !hi)))<<7; + else + FLAG_V = (hi != 0) << 7; + return; + } + m68ki_exception_illegal(); + +#endif +} + + +M68KMAKE_OP(nbcd, 8, ., d) +{ + uint* r_dst = &DY; + uint dst = *r_dst; + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +M68KMAKE_OP(nbcd, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +M68KMAKE_OP(neg, 8, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_8(*r_dst); + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = *r_dst & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(neg, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(neg, 16, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_16(*r_dst); + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (*r_dst & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(neg, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(neg, 32, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - *r_dst; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(*r_dst, 0, res); + FLAG_V = (*r_dst & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(neg, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(negx, 8, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_8(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = *r_dst & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +M68KMAKE_OP(negx, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(negx, 16, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_16(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (*r_dst & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +M68KMAKE_OP(negx, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +M68KMAKE_OP(negx, 32, ., d) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_32(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(*r_dst, 0, res); + FLAG_V = (*r_dst & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +M68KMAKE_OP(negx, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +M68KMAKE_OP(nop, 0, ., .) +{ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ +} + + +M68KMAKE_OP(not, 8, ., d) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_8(~*r_dst); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(not, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(not, 16, ., d) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(~*r_dst); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(not, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(not, 32, ., d) +{ + uint* r_dst = &DY; + uint res = *r_dst = MASK_OUT_ABOVE_32(~*r_dst); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(not, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 8, er, d) +{ + uint res = MASK_OUT_ABOVE_8((DX |= MASK_OUT_ABOVE_8(DY))); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 8, er, .) +{ + uint res = MASK_OUT_ABOVE_8((DX |= M68KMAKE_GET_OPER_AY_8)); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 16, er, d) +{ + uint res = MASK_OUT_ABOVE_16((DX |= MASK_OUT_ABOVE_16(DY))); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 16, er, .) +{ + uint res = MASK_OUT_ABOVE_16((DX |= M68KMAKE_GET_OPER_AY_16)); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 32, er, d) +{ + uint res = DX |= DY; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 32, er, .) +{ + uint res = DX |= M68KMAKE_GET_OPER_AY_32; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 8, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 16, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(or, 32, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 8, ., d) +{ + uint res = MASK_OUT_ABOVE_8((DY |= OPER_I_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 8, ., .) +{ + uint src = OPER_I_8(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 16, ., d) +{ + uint res = MASK_OUT_ABOVE_16(DY |= OPER_I_16()); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 16, ., .) +{ + uint src = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 32, ., d) +{ + uint res = DY |= OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 32, ., .) +{ + uint src = OPER_I_32(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ori, 16, toc, .) +{ + m68ki_set_ccr(m68ki_get_ccr() | OPER_I_8()); +} + + +M68KMAKE_OP(ori, 16, tos, .) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_set_sr(m68ki_get_sr() | src); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(pack, 16, rr, .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: DX and DY are reversed in Motorola's docs */ + uint src = DY + OPER_I_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | ((src >> 4) & 0x00f0) | (src & 0x000f); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(pack, 16, mm, ax7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint ea_src = EA_AY_PD_8(); + uint src = m68ki_read_8(ea_src); + ea_src = EA_AY_PD_8(); + src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + + m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(pack, 16, mm, ay7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint ea_src = EA_A7_PD_8(); + uint src = m68ki_read_8(ea_src); + ea_src = EA_A7_PD_8(); + src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + + m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(pack, 16, mm, axy7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint ea_src = EA_A7_PD_8(); + uint src = m68ki_read_8(ea_src); + ea_src = EA_A7_PD_8(); + src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + + m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(pack, 16, mm, .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint ea_src = EA_AY_PD_8(); + uint src = m68ki_read_8(ea_src); + ea_src = EA_AY_PD_8(); + src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + + m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(pea, 32, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + + m68ki_push_32(ea); +} + +M68KMAKE_OP(pflush, 32, ., .) +{ + if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) + { + fprintf(stderr,"68040: unhandled PFLUSH\n"); + return; + } + m68ki_exception_1111(); +} + +M68KMAKE_OP(pmmu, 32, ., .) +{ + if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) + { + m68881_mmu_ops(); + } + else + { + m68ki_exception_1111(); + } +} + +M68KMAKE_OP(reset, 0, ., .) +{ + if(FLAG_S) + { + m68ki_output_reset(); /* auto-disable (see m68kcpu.h) */ + USE_CYCLES(CYC_RESET); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(ror, 8, s, .) +{ + uint* r_dst = &DY; + uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_8(src, shift); + + if(orig_shift != 0) + USE_CYCLES(orig_shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_16(src, shift); + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint res = ROR_32(src, shift); + + if(shift != 0) + USE_CYCLES(shift<> ((shift - 1) & 15)) << 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ror, 32, r, .) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 31; + uint64 src = *r_dst; + uint res = ROR_32(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift<> ((shift - 1) & 31)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ror, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 8, s, .) +{ + uint* r_dst = &DY; + uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_8(src, shift); + + if(orig_shift != 0) + USE_CYCLES(orig_shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_16(src, shift); + + if(shift != 0) + USE_CYCLES(shift<> (8-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint res = ROL_32(src, shift); + + if(shift != 0) + USE_CYCLES(shift<> (24-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 8, r, .) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_8(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift<> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + FLAG_C = (src & 1)<<8; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 32, r, .) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 31; + uint64 src = *r_dst; + uint res = ROL_32(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift<> ((32 - shift) & 0x1f)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 16, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxr, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_9(src | (XFLAG_AS_1() << 8), shift); + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), shift); + + if(shift != 0) + USE_CYCLES(shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxr, 32, s, .) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + if(shift != 0) + USE_CYCLES(shift<> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); + uint new_x_flag = src & (1 << (shift - 1)); + + if(shift != 0) + USE_CYCLES(shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxr, 32, r, .) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 33; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + res = ROR_33_64(res, shift); + + USE_CYCLES(orig_shift<> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift % 33; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); + uint new_x_flag = src & (1 << (shift - 1)); + + if(orig_shift != 0) + USE_CYCLES(orig_shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxl, 8, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_9(src | (XFLAG_AS_1() << 8), shift); + + if(shift != 0) + USE_CYCLES(shift<> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), shift); + + if(shift != 0) + USE_CYCLES(shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxl, 32, s, .) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + if(shift != 0) + USE_CYCLES(shift<> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); + uint new_x_flag = src & (1 << (32 - shift)); + + if(shift != 0) + USE_CYCLES(shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxl, 32, r, .) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 33; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + res = ROL_33_64(res, shift); + + USE_CYCLES(orig_shift<> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift % 33; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); + uint new_x_flag = src & (1 << (32 - shift)); + + if(orig_shift != 0) + USE_CYCLES(orig_shift<> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rtd, 32, ., .) +{ + if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) + { + uint new_pc = m68ki_pull_32(); + + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); + m68ki_jump(new_pc); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(rte, 32, ., .) +{ + if(FLAG_S) + { + uint new_sr; + uint new_pc; + uint format_word; + + m68ki_rte_callback(); /* auto-disable (see m68kcpu.h) */ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + + if(CPU_TYPE_IS_000(CPU_TYPE)) + { + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + + return; + } + + if(CPU_TYPE_IS_010(CPU_TYPE)) + { + format_word = m68ki_read_16(REG_A[7]+6) >> 12; + if(format_word == 0) + { + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* format word */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + } else if (format_word == 8) { + /* Format 8 stack frame -- 68010 only. 29 word bus/address error */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* format word */ + m68ki_fake_pull_16(); /* special status word */ + m68ki_fake_pull_32(); /* fault address */ + m68ki_fake_pull_16(); /* unused/reserved */ + m68ki_fake_pull_16(); /* data output buffer */ + m68ki_fake_pull_16(); /* unused/reserved */ + m68ki_fake_pull_16(); /* data input buffer */ + m68ki_fake_pull_16(); /* unused/reserved */ + m68ki_fake_pull_16(); /* instruction input buffer */ + m68ki_fake_pull_32(); /* internal information, 16 words */ + m68ki_fake_pull_32(); /* (actually, we use 8 DWORDs) */ + m68ki_fake_pull_32(); + m68ki_fake_pull_32(); + m68ki_fake_pull_32(); + m68ki_fake_pull_32(); + m68ki_fake_pull_32(); + m68ki_fake_pull_32(); + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + } + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + /* Not handling other exception types (9) */ + m68ki_exception_format_error(); + return; + } + + /* Otherwise it's 020 */ +rte_loop: + format_word = m68ki_read_16(REG_A[7]+6) >> 12; + switch(format_word) + { + case 0: /* Normal */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* format word */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + case 1: /* Throwaway */ + new_sr = m68ki_pull_16(); + m68ki_fake_pull_32(); /* program counter */ + m68ki_fake_pull_16(); /* format word */ + m68ki_set_sr_noint(new_sr); + goto rte_loop; + case 2: /* Trap */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* format word */ + m68ki_fake_pull_32(); /* address */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + } + /* Not handling long or short bus fault */ + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + m68ki_exception_format_error(); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(rtm, 32, ., .) +{ + if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, + m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(rtr, 32, ., .) +{ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_set_ccr(m68ki_pull_16()); + m68ki_jump(m68ki_pull_32()); +} + + +M68KMAKE_OP(rts, 32, ., .) +{ + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_jump(m68ki_pull_32()); +} + + +M68KMAKE_OP(sbcd, 8, rr, .) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res += 0xa0; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +M68KMAKE_OP(sbcd, 8, mm, ax7) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res += 0xa0; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(sbcd, 8, mm, ay7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res += 0xa0; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(sbcd, 8, mm, axy7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res += 0xa0; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(sbcd, 8, mm, .) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res += 0xa0; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(st, 8, ., d) +{ + DY |= 0xff; +} + + +M68KMAKE_OP(st, 8, ., .) +{ + m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0xff); +} + + +M68KMAKE_OP(sf, 8, ., d) +{ + DY &= 0xffffff00; +} + + +M68KMAKE_OP(sf, 8, ., .) +{ + m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0); +} + + +M68KMAKE_OP(scc, 8, ., d) +{ + if(M68KMAKE_CC) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +M68KMAKE_OP(scc, 8, ., .) +{ + m68ki_write_8(M68KMAKE_GET_EA_AY_8, M68KMAKE_CC ? 0xff : 0); +} + + +M68KMAKE_OP(stop, 0, ., .) +{ + if(FLAG_S) + { + uint new_sr = OPER_I_16(); + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + CPU_STOPPED |= STOP_LEVEL_STOP; + m68ki_set_sr(new_sr); + if(m68ki_remaining_cycles >= CYC_INSTRUCTION[REG_IR]) + m68ki_remaining_cycles = CYC_INSTRUCTION[REG_IR]; + else + USE_ALL_CYCLES(); + return; + } + m68ki_exception_privilege_violation(); +} + + +M68KMAKE_OP(sub, 8, er, d) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(sub, 8, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_8; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(sub, 16, er, d) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(sub, 16, er, a) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(sub, 16, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_16; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(sub, 32, er, d) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(sub, 32, er, a) +{ + uint* r_dst = &DX; + uint src = AY; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(sub, 32, er, .) +{ + uint* r_dst = &DX; + uint src = M68KMAKE_GET_OPER_AY_32; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(sub, 8, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(sub, 16, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_16; + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(sub, 32, re, .) +{ + uint ea = M68KMAKE_GET_EA_AY_32; + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(suba, 16, ., d) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(DY)); +} + + +M68KMAKE_OP(suba, 16, ., a) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(AY)); +} + + +M68KMAKE_OP(suba, 16, ., .) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +M68KMAKE_OP(suba, 32, ., d) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - DY); +} + + +M68KMAKE_OP(suba, 32, ., a) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - AY); +} + + +M68KMAKE_OP(suba, 32, ., .) +{ + uint src = M68KMAKE_GET_OPER_AY_32; + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +M68KMAKE_OP(subi, 8, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(subi, 8, ., .) +{ + uint src = OPER_I_8(); + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(subi, 16, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(subi, 16, ., .) +{ + uint src = OPER_I_16(); + uint ea = M68KMAKE_GET_EA_AY_16; + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(subi, 32, ., d) +{ + uint* r_dst = &DY; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(subi, 32, ., .) +{ + uint src = OPER_I_32(); + uint ea = M68KMAKE_GET_EA_AY_32; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(subq, 8, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(subq, 8, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +M68KMAKE_OP(subq, 16, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +M68KMAKE_OP(subq, 16, ., a) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); +} + + +M68KMAKE_OP(subq, 16, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_16; + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +M68KMAKE_OP(subq, 32, ., d) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + *r_dst = FLAG_Z; +} + + +M68KMAKE_OP(subq, 32, ., a) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); +} + + +M68KMAKE_OP(subq, 32, ., .) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = M68KMAKE_GET_EA_AY_32; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +M68KMAKE_OP(subx, 8, rr, .) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +M68KMAKE_OP(subx, 16, rr, .) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +M68KMAKE_OP(subx, 32, rr, .) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +M68KMAKE_OP(subx, 8, mm, ax7) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(subx, 8, mm, ay7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(subx, 8, mm, axy7) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(subx, 8, mm, .) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +M68KMAKE_OP(subx, 16, mm, .) +{ + uint src = OPER_AY_PD_16(); + uint ea = EA_AX_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +M68KMAKE_OP(subx, 32, mm, .) +{ + uint src = OPER_AY_PD_32(); + uint ea = EA_AX_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +M68KMAKE_OP(swap, 32, ., .) +{ + uint* r_dst = &DY; + + FLAG_Z = MASK_OUT_ABOVE_32(*r_dst<<16); + *r_dst = (*r_dst>>16) | FLAG_Z; + + FLAG_Z = *r_dst; + FLAG_N = NFLAG_32(*r_dst); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(tas, 8, ., d) +{ + uint* r_dst = &DY; + + FLAG_Z = MASK_OUT_ABOVE_8(*r_dst); + FLAG_N = NFLAG_8(*r_dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst |= 0x80; +} + + +M68KMAKE_OP(tas, 8, ., .) +{ + uint ea = M68KMAKE_GET_EA_AY_8; + uint dst = m68ki_read_8(ea); + uint allow_writeback; + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + allow_writeback = m68ki_tas_callback(); + + if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80); +} + + +M68KMAKE_OP(trap, 0, ., .) +{ + /* Trap#n stacks exception frame type 0 */ + m68ki_exception_trapN(EXCEPTION_TRAP_BASE + (REG_IR & 0xf)); /* HJB 990403 */ +} + + +M68KMAKE_OP(trapt, 0, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapt, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 2; // JFF else stackframe & return addresses are incorrect + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapt, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 4; // JFF else stackframe & return addresses are incorrect + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapf, 0, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapf, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 2; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapf, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 4; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapcc, 0, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + if(M68KMAKE_CC) + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapcc, 16, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 2; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ + if(M68KMAKE_CC) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_PC += 4; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ + if(M68KMAKE_CC) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapv, 0, ., .) +{ + if(COND_VC()) + { + return; + } + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ +} + + +M68KMAKE_OP(tst, 8, ., d) +{ + uint res = MASK_OUT_ABOVE_8(DY); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 8, ., .) +{ + uint res = M68KMAKE_GET_OPER_AY_8; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 8, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCDI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 8, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCIX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 8, ., i) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_I_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 16, ., d) +{ + uint res = MASK_OUT_ABOVE_16(DY); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 16, ., a) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = MAKE_INT_16(AY); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 16, ., .) +{ + uint res = M68KMAKE_GET_OPER_AY_16; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 16, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCDI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 16, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCIX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 16, ., i) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_I_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 32, ., d) +{ + uint res = DY; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 32, ., a) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = AY; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 32, ., .) +{ + uint res = M68KMAKE_GET_OPER_AY_32; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +M68KMAKE_OP(tst, 32, ., pcdi) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCDI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 32, ., pcix) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_PCIX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(tst, 32, ., i) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint res = OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(unlk, 32, ., a7) +{ + REG_A[7] = m68ki_read_32(REG_A[7]); +} + + +M68KMAKE_OP(unlk, 32, ., .) +{ + uint* r_dst = &AY; + + REG_A[7] = *r_dst; + *r_dst = m68ki_pull_32(); +} + + +M68KMAKE_OP(unpk, 16, rr, .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: DX and DY are reversed in Motorola's docs */ + uint src = DY; + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | (((((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16()) & 0xffff); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(unpk, 16, mm, ax7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint src = OPER_AY_PD_8(); + uint ea_dst; + + src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, src & 0xff); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(unpk, 16, mm, ay7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint src = OPER_A7_PD_8(); + uint ea_dst; + + src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, src & 0xff); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(unpk, 16, mm, axy7) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + uint src = OPER_A7_PD_8(); + uint ea_dst; + + src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, src & 0xff); + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(unpk, 16, mm, .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Note: AX and AY are reversed in Motorola's docs */ + uint src = OPER_AY_PD_8(); + uint ea_dst; + + src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, src & 0xff); + return; + } + m68ki_exception_illegal(); +} + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_END diff --git a/AltairZ80/m68k/m68kasm.c b/AltairZ80/m68k/m68kasm.c index 4158ece7..2fac834c 100644 --- a/AltairZ80/m68k/m68kasm.c +++ b/AltairZ80/m68k/m68kasm.c @@ -1,4052 +1,4052 @@ -/* A Bison parser, made by GNU Bison 3.6.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.6.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* First part of user prologue. */ -#line 1 "m68kasm.y" - - -/* m68k_parse.c: line assembler for generic m68k_cpu - - - - Copyright (c) 2009-2010, Holger Veit - - - - Permission is hereby granted, free of charge, to any person obtaining a - - copy of this software and associated documentation files (the "Software"), - - to deal in the Software without restriction, including without limitation - - the rights to use, copy, modify, merge, publish, distribute, sublicense, - - and/or sell copies of the Software, and to permit persons to whom the - - Software is furnished to do so, subject to the following conditions: - - - - The above copyright notice and this permission notice shall be included in - - all copies or substantial portions of the Software. - - - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - - HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - - Except as contained in this notice, the name of Holger Veit et al shall not be - - used in advertising or otherwise to promote the sale, use or other dealings - - in this Software without prior written authorization from Holger Veit et al. - - - - 04-Oct-09 HV Initial version - - 20-Sep-14 PS Adapted for AltairZ80 - - - - use "bison m68kasm.y -o m68kasm.c" to create m68kasm.c - -*/ - - - -#include "sim_defs.h" - -#include - -#include - - - -struct _ea { - - int ea; - - int cnt; - - t_value arg[10]; - -}; - -struct _rea { - - int reg; - - struct _ea ea; - -}; - -struct _mask { - - int x; - - int d; - -}; - -struct _brop { - - int opc; - - int len; - -}; - - - -static int oplen; - -const static int movemx[] = { 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, - - 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080 }; - -const static int movemd[] = { 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001, - - 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100 }; - -static int yyrc; - -static int yyerrc; - -static int yylex(void); - -static int _genop(t_value arg); - -static int _genea(struct _ea arg); - -static int _genbr(t_value arg,t_value,int); - -static void yyerror(char* s); - - - -#define YYDEBUG 1 - - -#line 141 "m68kasm.c" - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - - -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - A0 = 258, /* A0 */ - A1 = 259, /* A1 */ - A2 = 260, /* A2 */ - A3 = 261, /* A3 */ - A4 = 262, /* A4 */ - A5 = 263, /* A5 */ - A6 = 264, /* A6 */ - A7 = 265, /* A7 */ - D0 = 266, /* D0 */ - D1 = 267, /* D1 */ - D2 = 268, /* D2 */ - D3 = 269, /* D3 */ - D4 = 270, /* D4 */ - D5 = 271, /* D5 */ - D6 = 272, /* D6 */ - D7 = 273, /* D7 */ - CCR = 274, /* CCR */ - SR = 275, /* SR */ - USP = 276, /* USP */ - PC = 277, /* PC */ - NUMBER = 278, /* NUMBER */ - ABCD = 279, /* ABCD */ - ADD = 280, /* ADD */ - ADDA = 281, /* ADDA */ - ADDI = 282, /* ADDI */ - ADDQ = 283, /* ADDQ */ - ADDX = 284, /* ADDX */ - AND = 285, /* AND */ - ANDI = 286, /* ANDI */ - OR = 287, /* OR */ - ORI = 288, /* ORI */ - SBCD = 289, /* SBCD */ - SUB = 290, /* SUB */ - SUBA = 291, /* SUBA */ - SUBI = 292, /* SUBI */ - SUBQ = 293, /* SUBQ */ - SUBX = 294, /* SUBX */ - ASL = 295, /* ASL */ - ASR = 296, /* ASR */ - LSL = 297, /* LSL */ - LSR = 298, /* LSR */ - ROL = 299, /* ROL */ - ROR = 300, /* ROR */ - ROXL = 301, /* ROXL */ - ROXR = 302, /* ROXR */ - BCC = 303, /* BCC */ - BCS = 304, /* BCS */ - BEQ = 305, /* BEQ */ - BGE = 306, /* BGE */ - BGT = 307, /* BGT */ - BHI = 308, /* BHI */ - BLE = 309, /* BLE */ - BLS = 310, /* BLS */ - BLT = 311, /* BLT */ - BMI = 312, /* BMI */ - BNE = 313, /* BNE */ - BPL = 314, /* BPL */ - BVC = 315, /* BVC */ - BVS = 316, /* BVS */ - BSR = 317, /* BSR */ - BRA = 318, /* BRA */ - BCLR = 319, /* BCLR */ - BSET = 320, /* BSET */ - BCHG = 321, /* BCHG */ - BTST = 322, /* BTST */ - CHK = 323, /* CHK */ - CMP = 324, /* CMP */ - CMPA = 325, /* CMPA */ - CMPI = 326, /* CMPI */ - CMPM = 327, /* CMPM */ - EOR = 328, /* EOR */ - EORI = 329, /* EORI */ - EXG = 330, /* EXG */ - EXT = 331, /* EXT */ - DIVU = 332, /* DIVU */ - DIVS = 333, /* DIVS */ - MULU = 334, /* MULU */ - MULS = 335, /* MULS */ - DBCC = 336, /* DBCC */ - DBCS = 337, /* DBCS */ - DBEQ = 338, /* DBEQ */ - DBF = 339, /* DBF */ - DBGE = 340, /* DBGE */ - DBGT = 341, /* DBGT */ - DBHI = 342, /* DBHI */ - DBLE = 343, /* DBLE */ - DBLS = 344, /* DBLS */ - DBLT = 345, /* DBLT */ - DBMI = 346, /* DBMI */ - DBNE = 347, /* DBNE */ - DBPL = 348, /* DBPL */ - DBT = 349, /* DBT */ - DBVC = 350, /* DBVC */ - DBVS = 351, /* DBVS */ - SCC = 352, /* SCC */ - SCS = 353, /* SCS */ - SEQ = 354, /* SEQ */ - SF = 355, /* SF */ - SGE = 356, /* SGE */ - SGT = 357, /* SGT */ - SHI = 358, /* SHI */ - SLE = 359, /* SLE */ - SLS = 360, /* SLS */ - SLT = 361, /* SLT */ - SMI = 362, /* SMI */ - SNE = 363, /* SNE */ - SPL = 364, /* SPL */ - ST = 365, /* ST */ - SVC = 366, /* SVC */ - SVS = 367, /* SVS */ - ILLEGAL = 368, /* ILLEGAL */ - NOP = 369, /* NOP */ - RESET = 370, /* RESET */ - RTE = 371, /* RTE */ - RTR = 372, /* RTR */ - RTS = 373, /* RTS */ - TRAPV = 374, /* TRAPV */ - JMP = 375, /* JMP */ - JSR = 376, /* JSR */ - LEA = 377, /* LEA */ - LINK = 378, /* LINK */ - MOVE = 379, /* MOVE */ - MOVEA = 380, /* MOVEA */ - MOVEM = 381, /* MOVEM */ - MOVEP = 382, /* MOVEP */ - MOVEQ = 383, /* MOVEQ */ - CLR = 384, /* CLR */ - NEG = 385, /* NEG */ - NEGX = 386, /* NEGX */ - NBCD = 387, /* NBCD */ - NOT = 388, /* NOT */ - PEA = 389, /* PEA */ - STOP = 390, /* STOP */ - TAS = 391, /* TAS */ - SWAP = 392, /* SWAP */ - TRAP = 393, /* TRAP */ - TST = 394, /* TST */ - UNLK = 395, /* UNLK */ - PREDEC = 396, /* PREDEC */ - POSTINC = 397, /* POSTINC */ - BSIZE = 398, /* BSIZE */ - WSIZE = 399, /* WSIZE */ - LSIZE = 400, /* LSIZE */ - SSIZE = 401 /* SSIZE */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 71 "m68kasm.y" - - - int rc; - - int reg; - - int wl; - - int opc; - - struct _ea ea; - - t_value num; - - struct _rea rea; - - struct _mask mask; - - struct _brop brop; - - -#line 346 "m68kasm.c" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - -int yyparse (void); - - -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_A0 = 3, /* A0 */ - YYSYMBOL_A1 = 4, /* A1 */ - YYSYMBOL_A2 = 5, /* A2 */ - YYSYMBOL_A3 = 6, /* A3 */ - YYSYMBOL_A4 = 7, /* A4 */ - YYSYMBOL_A5 = 8, /* A5 */ - YYSYMBOL_A6 = 9, /* A6 */ - YYSYMBOL_A7 = 10, /* A7 */ - YYSYMBOL_D0 = 11, /* D0 */ - YYSYMBOL_D1 = 12, /* D1 */ - YYSYMBOL_D2 = 13, /* D2 */ - YYSYMBOL_D3 = 14, /* D3 */ - YYSYMBOL_D4 = 15, /* D4 */ - YYSYMBOL_D5 = 16, /* D5 */ - YYSYMBOL_D6 = 17, /* D6 */ - YYSYMBOL_D7 = 18, /* D7 */ - YYSYMBOL_CCR = 19, /* CCR */ - YYSYMBOL_SR = 20, /* SR */ - YYSYMBOL_USP = 21, /* USP */ - YYSYMBOL_PC = 22, /* PC */ - YYSYMBOL_NUMBER = 23, /* NUMBER */ - YYSYMBOL_ABCD = 24, /* ABCD */ - YYSYMBOL_ADD = 25, /* ADD */ - YYSYMBOL_ADDA = 26, /* ADDA */ - YYSYMBOL_ADDI = 27, /* ADDI */ - YYSYMBOL_ADDQ = 28, /* ADDQ */ - YYSYMBOL_ADDX = 29, /* ADDX */ - YYSYMBOL_AND = 30, /* AND */ - YYSYMBOL_ANDI = 31, /* ANDI */ - YYSYMBOL_OR = 32, /* OR */ - YYSYMBOL_ORI = 33, /* ORI */ - YYSYMBOL_SBCD = 34, /* SBCD */ - YYSYMBOL_SUB = 35, /* SUB */ - YYSYMBOL_SUBA = 36, /* SUBA */ - YYSYMBOL_SUBI = 37, /* SUBI */ - YYSYMBOL_SUBQ = 38, /* SUBQ */ - YYSYMBOL_SUBX = 39, /* SUBX */ - YYSYMBOL_ASL = 40, /* ASL */ - YYSYMBOL_ASR = 41, /* ASR */ - YYSYMBOL_LSL = 42, /* LSL */ - YYSYMBOL_LSR = 43, /* LSR */ - YYSYMBOL_ROL = 44, /* ROL */ - YYSYMBOL_ROR = 45, /* ROR */ - YYSYMBOL_ROXL = 46, /* ROXL */ - YYSYMBOL_ROXR = 47, /* ROXR */ - YYSYMBOL_BCC = 48, /* BCC */ - YYSYMBOL_BCS = 49, /* BCS */ - YYSYMBOL_BEQ = 50, /* BEQ */ - YYSYMBOL_BGE = 51, /* BGE */ - YYSYMBOL_BGT = 52, /* BGT */ - YYSYMBOL_BHI = 53, /* BHI */ - YYSYMBOL_BLE = 54, /* BLE */ - YYSYMBOL_BLS = 55, /* BLS */ - YYSYMBOL_BLT = 56, /* BLT */ - YYSYMBOL_BMI = 57, /* BMI */ - YYSYMBOL_BNE = 58, /* BNE */ - YYSYMBOL_BPL = 59, /* BPL */ - YYSYMBOL_BVC = 60, /* BVC */ - YYSYMBOL_BVS = 61, /* BVS */ - YYSYMBOL_BSR = 62, /* BSR */ - YYSYMBOL_BRA = 63, /* BRA */ - YYSYMBOL_BCLR = 64, /* BCLR */ - YYSYMBOL_BSET = 65, /* BSET */ - YYSYMBOL_BCHG = 66, /* BCHG */ - YYSYMBOL_BTST = 67, /* BTST */ - YYSYMBOL_CHK = 68, /* CHK */ - YYSYMBOL_CMP = 69, /* CMP */ - YYSYMBOL_CMPA = 70, /* CMPA */ - YYSYMBOL_CMPI = 71, /* CMPI */ - YYSYMBOL_CMPM = 72, /* CMPM */ - YYSYMBOL_EOR = 73, /* EOR */ - YYSYMBOL_EORI = 74, /* EORI */ - YYSYMBOL_EXG = 75, /* EXG */ - YYSYMBOL_EXT = 76, /* EXT */ - YYSYMBOL_DIVU = 77, /* DIVU */ - YYSYMBOL_DIVS = 78, /* DIVS */ - YYSYMBOL_MULU = 79, /* MULU */ - YYSYMBOL_MULS = 80, /* MULS */ - YYSYMBOL_DBCC = 81, /* DBCC */ - YYSYMBOL_DBCS = 82, /* DBCS */ - YYSYMBOL_DBEQ = 83, /* DBEQ */ - YYSYMBOL_DBF = 84, /* DBF */ - YYSYMBOL_DBGE = 85, /* DBGE */ - YYSYMBOL_DBGT = 86, /* DBGT */ - YYSYMBOL_DBHI = 87, /* DBHI */ - YYSYMBOL_DBLE = 88, /* DBLE */ - YYSYMBOL_DBLS = 89, /* DBLS */ - YYSYMBOL_DBLT = 90, /* DBLT */ - YYSYMBOL_DBMI = 91, /* DBMI */ - YYSYMBOL_DBNE = 92, /* DBNE */ - YYSYMBOL_DBPL = 93, /* DBPL */ - YYSYMBOL_DBT = 94, /* DBT */ - YYSYMBOL_DBVC = 95, /* DBVC */ - YYSYMBOL_DBVS = 96, /* DBVS */ - YYSYMBOL_SCC = 97, /* SCC */ - YYSYMBOL_SCS = 98, /* SCS */ - YYSYMBOL_SEQ = 99, /* SEQ */ - YYSYMBOL_SF = 100, /* SF */ - YYSYMBOL_SGE = 101, /* SGE */ - YYSYMBOL_SGT = 102, /* SGT */ - YYSYMBOL_SHI = 103, /* SHI */ - YYSYMBOL_SLE = 104, /* SLE */ - YYSYMBOL_SLS = 105, /* SLS */ - YYSYMBOL_SLT = 106, /* SLT */ - YYSYMBOL_SMI = 107, /* SMI */ - YYSYMBOL_SNE = 108, /* SNE */ - YYSYMBOL_SPL = 109, /* SPL */ - YYSYMBOL_ST = 110, /* ST */ - YYSYMBOL_SVC = 111, /* SVC */ - YYSYMBOL_SVS = 112, /* SVS */ - YYSYMBOL_ILLEGAL = 113, /* ILLEGAL */ - YYSYMBOL_NOP = 114, /* NOP */ - YYSYMBOL_RESET = 115, /* RESET */ - YYSYMBOL_RTE = 116, /* RTE */ - YYSYMBOL_RTR = 117, /* RTR */ - YYSYMBOL_RTS = 118, /* RTS */ - YYSYMBOL_TRAPV = 119, /* TRAPV */ - YYSYMBOL_JMP = 120, /* JMP */ - YYSYMBOL_JSR = 121, /* JSR */ - YYSYMBOL_LEA = 122, /* LEA */ - YYSYMBOL_LINK = 123, /* LINK */ - YYSYMBOL_MOVE = 124, /* MOVE */ - YYSYMBOL_MOVEA = 125, /* MOVEA */ - YYSYMBOL_MOVEM = 126, /* MOVEM */ - YYSYMBOL_MOVEP = 127, /* MOVEP */ - YYSYMBOL_MOVEQ = 128, /* MOVEQ */ - YYSYMBOL_CLR = 129, /* CLR */ - YYSYMBOL_NEG = 130, /* NEG */ - YYSYMBOL_NEGX = 131, /* NEGX */ - YYSYMBOL_NBCD = 132, /* NBCD */ - YYSYMBOL_NOT = 133, /* NOT */ - YYSYMBOL_PEA = 134, /* PEA */ - YYSYMBOL_STOP = 135, /* STOP */ - YYSYMBOL_TAS = 136, /* TAS */ - YYSYMBOL_SWAP = 137, /* SWAP */ - YYSYMBOL_TRAP = 138, /* TRAP */ - YYSYMBOL_TST = 139, /* TST */ - YYSYMBOL_UNLK = 140, /* UNLK */ - YYSYMBOL_PREDEC = 141, /* PREDEC */ - YYSYMBOL_POSTINC = 142, /* POSTINC */ - YYSYMBOL_BSIZE = 143, /* BSIZE */ - YYSYMBOL_WSIZE = 144, /* WSIZE */ - YYSYMBOL_LSIZE = 145, /* LSIZE */ - YYSYMBOL_SSIZE = 146, /* SSIZE */ - YYSYMBOL_147_ = 147, /* '#' */ - YYSYMBOL_148_ = 148, /* ',' */ - YYSYMBOL_149_ = 149, /* '/' */ - YYSYMBOL_150_ = 150, /* '-' */ - YYSYMBOL_151_ = 151, /* '(' */ - YYSYMBOL_152_ = 152, /* ')' */ - YYSYMBOL_YYACCEPT = 153, /* $accept */ - YYSYMBOL_stmt = 154, /* stmt */ - YYSYMBOL_arop = 155, /* arop */ - YYSYMBOL_bcdop = 156, /* bcdop */ - YYSYMBOL_dualop = 157, /* dualop */ - YYSYMBOL_immop = 158, /* immop */ - YYSYMBOL_immop2 = 159, /* immop2 */ - YYSYMBOL_qop = 160, /* qop */ - YYSYMBOL_shftop = 161, /* shftop */ - YYSYMBOL_brop = 162, /* brop */ - YYSYMBOL_btop = 163, /* btop */ - YYSYMBOL_monop = 164, /* monop */ - YYSYMBOL_mdop = 165, /* mdop */ - YYSYMBOL_dbop = 166, /* dbop */ - YYSYMBOL_direct = 167, /* direct */ - YYSYMBOL_jop = 168, /* jop */ - YYSYMBOL_shftarg = 169, /* shftarg */ - YYSYMBOL_bcdarg = 170, /* bcdarg */ - YYSYMBOL_dualarg = 171, /* dualarg */ - YYSYMBOL_areg = 172, /* areg */ - YYSYMBOL_dreg = 173, /* dreg */ - YYSYMBOL_szs = 174, /* szs */ - YYSYMBOL_szwl = 175, /* szwl */ - YYSYMBOL_szbwl = 176, /* szbwl */ - YYSYMBOL_szmv = 177, /* szmv */ - YYSYMBOL_szm = 178, /* szm */ - YYSYMBOL_reglist = 179, /* reglist */ - YYSYMBOL_regs = 180, /* regs */ - YYSYMBOL_eama = 181, /* eama */ - YYSYMBOL_eaa = 182, /* eaa */ - YYSYMBOL_ead = 183, /* ead */ - YYSYMBOL_eaall = 184, /* eaall */ - YYSYMBOL_eada = 185, /* eada */ - YYSYMBOL_eadas = 186, /* eadas */ - YYSYMBOL_eac = 187, /* eac */ - YYSYMBOL_eacai = 188, /* eacai */ - YYSYMBOL_eacad = 189, /* eacad */ - YYSYMBOL_ea0 = 190, /* ea0 */ - YYSYMBOL_ea1 = 191, /* ea1 */ - YYSYMBOL_ea2 = 192, /* ea2 */ - YYSYMBOL_ea3 = 193, /* ea3 */ - YYSYMBOL_ea4 = 194, /* ea4 */ - YYSYMBOL_ea5 = 195, /* ea5 */ - YYSYMBOL_ea6 = 196, /* ea6 */ - YYSYMBOL_ea70 = 197, /* ea70 */ - YYSYMBOL_ea72 = 198, /* ea72 */ - YYSYMBOL_ea73 = 199, /* ea73 */ - YYSYMBOL_ea74 = 200, /* ea74 */ - YYSYMBOL_easr = 201 /* easr */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int16 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if !defined yyoverflow - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* !defined yyoverflow */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 266 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 928 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 153 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 49 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 276 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 462 - -#define YYMAXUTOK 401 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 147, 2, 2, 2, 2, - 151, 152, 2, 2, 148, 150, 2, 149, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146 -}; - -#if YYDEBUG - /* YYRLINEYYN -- Source line where rule number YYN was defined. */ -static const yytype_int16 yyrline[] = -{ - 0, 112, 112, 113, 114, 116, 117, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 160, 161, 164, 165, 166, 167, 171, - 172, 173, 174, 178, 179, 180, 184, 185, 186, 190, - 191, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 249, - 250, 251, 252, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 282, 283, 284, 285, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 308, 309, 310, 311, - 312, 313, 314, 318, 319, 320, 323, 324, 327, 328, - 331, 334, 337, 338, 339, 340, 341, 342, 343, 344, - 347, 348, 349, 350, 351, 352, 353, 354, 357, 360, - 361, 364, 365, 366, 369, 370, 371, 374, 375, 378, - 379, 382, 383, 384, 386, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, - 391, 391, 391, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 393, 393, 394, 394, 394, 394, 394, - 394, 394, 395, 395, 396, 396, 396, 396, 396, 396, - 397, 397, 397, 397, 397, 398, 398, 398, 398, 398, - 401, 403, 405, 407, 409, 411, 413, 415, 418, 420, - 423, 424, 426, 428, 431, 435, 436 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if YYDEBUG || 0 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "\"end of file\"", "error", "\"invalid token\"", "A0", "A1", "A2", "A3", - "A4", "A5", "A6", "A7", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", - "CCR", "SR", "USP", "PC", "NUMBER", "ABCD", "ADD", "ADDA", "ADDI", - "ADDQ", "ADDX", "AND", "ANDI", "OR", "ORI", "SBCD", "SUB", "SUBA", - "SUBI", "SUBQ", "SUBX", "ASL", "ASR", "LSL", "LSR", "ROL", "ROR", "ROXL", - "ROXR", "BCC", "BCS", "BEQ", "BGE", "BGT", "BHI", "BLE", "BLS", "BLT", - "BMI", "BNE", "BPL", "BVC", "BVS", "BSR", "BRA", "BCLR", "BSET", "BCHG", - "BTST", "CHK", "CMP", "CMPA", "CMPI", "CMPM", "EOR", "EORI", "EXG", - "EXT", "DIVU", "DIVS", "MULU", "MULS", "DBCC", "DBCS", "DBEQ", "DBF", - "DBGE", "DBGT", "DBHI", "DBLE", "DBLS", "DBLT", "DBMI", "DBNE", "DBPL", - "DBT", "DBVC", "DBVS", "SCC", "SCS", "SEQ", "SF", "SGE", "SGT", "SHI", - "SLE", "SLS", "SLT", "SMI", "SNE", "SPL", "ST", "SVC", "SVS", "ILLEGAL", - "NOP", "RESET", "RTE", "RTR", "RTS", "TRAPV", "JMP", "JSR", "LEA", - "LINK", "MOVE", "MOVEA", "MOVEM", "MOVEP", "MOVEQ", "CLR", "NEG", "NEGX", - "NBCD", "NOT", "PEA", "STOP", "TAS", "SWAP", "TRAP", "TST", "UNLK", - "PREDEC", "POSTINC", "BSIZE", "WSIZE", "LSIZE", "SSIZE", "'#'", "','", - "'/'", "'-'", "'('", "')'", "$accept", "stmt", "arop", "bcdop", "dualop", - "immop", "immop2", "qop", "shftop", "brop", "btop", "monop", "mdop", - "dbop", "direct", "jop", "shftarg", "bcdarg", "dualarg", "areg", "dreg", - "szs", "szwl", "szbwl", "szmv", "szm", "reglist", "regs", "eama", "eaa", - "ead", "eaall", "eada", "eadas", "eac", "eacai", "eacad", "ea0", "ea1", - "ea2", "ea3", "ea4", "ea5", "ea6", "ea70", "ea72", "ea73", "ea74", - "easr", YY_NULLPTR -}; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - return yytname[yysymbol]; -} -#endif - -#ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_int16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 35, 44, 47, - 45, 40, 41 -}; -#endif - -#define YYPACT_NINF (-343) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-1) - -#define yytable_value_is_error(Yyn) \ - 0 - - /* YYPACTSTATE-NUM -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 675, -343, -126, -343, -126, -126, -126, -126, -126, -126, - -126, -343, -126, -343, -126, -126, -126, 456, 456, 456, - 456, 456, 456, 456, 456, -139, -139, -139, -139, -139, - -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, - -139, -343, -343, -343, -343, 477, -126, -107, -126, -126, - -126, -126, 626, -107, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -20, - 642, 141, -105, -107, -107, -137, -126, -126, -126, -343, - -126, -343, -82, -343, 646, -80, -126, 642, 72, -107, - 557, 18, -72, -65, -50, -343, 78, 31, 76, 477, - 646, -343, -20, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, 642, 85, 203, - -343, 236, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, 236, -343, 236, -343, 236, -343, 236, - -343, 236, -343, 236, -343, 236, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -37, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, 18, -343, -343, 18, -343, -42, - 646, -343, -36, -35, 646, 203, -32, -343, -343, -343, - -343, -343, -343, -29, -27, -19, -343, -343, -343, -13, - 18, -343, -343, 76, 538, 41, 92, -343, -343, -343, - -343, 100, -343, 113, -343, -343, -343, 18, -343, -10, - -9, -343, -8, -7, 119, 120, 129, -343, 131, 8, - 581, -343, -343, -343, -343, -343, -343, -343, -343, 15, - 16, -343, 19, -343, -143, -138, 149, -343, 25, -343, - -343, -343, -343, -343, -343, -343, 646, -343, 27, -343, - 29, 642, 32, 33, 626, 626, -343, 22, 642, 37, - 76, 642, 155, 39, 40, 35, 36, 43, 45, 47, - -343, -343, -343, -343, -343, 166, 51, 54, 57, -343, - -343, 66, 646, 77, 515, 646, 71, 73, 74, 83, - 76, -84, 646, 197, -343, 605, -107, -343, -343, 84, - 646, -343, 646, 642, 93, -42, 76, -343, -343, -343, - -343, -343, 211, -343, -343, -343, 546, 642, 642, 646, - -135, 626, 626, 90, 88, 646, 646, 642, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - 76, 546, 515, 76, -343, 642, -343, -343, -68, -67, - -343, 646, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, 581, -343, -343, -343, - -343, -343, -343, -343, -343, 642, -343, -343, -343, -343, - -343, -343, -343, -343, 626, -343, 626, -343, -343, 91, - -107, -107, -107, -107, 104, 106, 107, 109, -343, -343, - -343, -343 -}; - - /* YYDEFACTSTATE-NUM -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int16 yydefact[] = -{ - 0, 45, 0, 43, 0, 0, 0, 0, 0, 0, - 0, 47, 0, 44, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 110, 111, 109, 112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 137, 136, 139, 138, 140, 141, - 142, 154, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 155, 152, 153, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, - 0, 165, 0, 134, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, - 0, 24, 0, 191, 192, 193, 49, 53, 59, 46, - 50, 56, 51, 58, 52, 55, 60, 48, 172, 173, - 174, 175, 176, 177, 178, 179, 271, 0, 0, 0, - 261, 0, 61, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 0, 63, 0, 65, 0, 67, 0, - 69, 0, 71, 0, 73, 0, 75, 188, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 180, 181, 182, 183, 184, 185, - 186, 187, 260, 0, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 0, 189, 190, 0, 54, 0, - 0, 57, 0, 0, 0, 0, 0, 244, 245, 246, - 247, 248, 249, 0, 0, 0, 194, 195, 196, 0, - 0, 197, 198, 0, 0, 0, 0, 113, 115, 116, - 117, 0, 40, 0, 135, 42, 1, 0, 2, 0, - 0, 3, 0, 0, 0, 0, 0, 8, 0, 0, - 0, 12, 235, 236, 237, 238, 239, 240, 241, 0, - 0, 25, 0, 274, 0, 0, 0, 62, 0, 64, - 66, 68, 70, 72, 74, 76, 0, 234, 0, 233, - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, - 0, 0, 0, 0, 0, 201, 202, 0, 199, 0, - 250, 251, 252, 253, 254, 0, 0, 0, 0, 38, - 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 264, 0, 269, 263, 262, 0, - 0, 11, 0, 0, 0, 0, 0, 20, 21, 22, - 19, 26, 0, 29, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 168, 169, - 170, 215, 216, 217, 218, 219, 220, 221, 222, 171, - 0, 0, 0, 0, 9, 0, 14, 17, 0, 0, - 268, 0, 166, 13, 15, 16, 18, 27, 275, 276, - 242, 28, 243, 32, 203, 204, 0, 33, 255, 256, - 257, 258, 259, 200, 34, 0, 35, 36, 37, 39, - 4, 6, 5, 10, 0, 270, 0, 265, 167, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 273, 272, - 267, 266 -}; - - /* YYPGOTONTERM-NUM. */ -static const yytype_int16 yypgoto[] = -{ - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, 248, -343, -343, -39, - -51, 811, -53, 812, -343, -343, -276, -343, 559, -162, - 115, -150, -120, -159, 128, -343, -343, -34, -342, -25, - 108, 137, -30, 38, 69, 26, 28, -33, -343 -}; - - /* YYDEFGOTONTERM-NUM. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 297, 268, 271, 160, - 212, 188, 227, 136, 250, 253, 327, 328, 307, 390, - 213, 308, 420, 421, 236, 329, 427, 282, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 422 -}; - - /* YYTABLEYYPACT[STATE-NUM] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 234, 233, 392, 156, 357, 355, 157, 187, 281, 356, - 256, 214, 223, 232, 358, 218, 426, 133, 134, 135, - 215, 148, 149, 150, 151, 152, 153, 154, 155, 204, - 205, 206, 207, 208, 209, 210, 211, 225, 226, 251, - 252, 156, 204, 205, 206, 207, 208, 209, 210, 211, - 254, 255, 204, 205, 206, 207, 208, 209, 210, 211, - 392, 243, 249, 262, 405, 261, 267, 263, 356, 238, - 272, 221, 266, 222, 237, 274, 279, 310, 265, 290, - 444, 446, 275, 219, 445, 447, 269, 204, 205, 206, - 207, 208, 209, 210, 211, 214, 223, 276, 286, 218, - 323, 277, 238, 283, 215, 433, 434, 237, 293, 311, - 298, 306, 314, 315, 220, 338, 318, 341, 292, 319, - 295, 320, 298, 339, 298, 241, 298, 242, 298, 321, - 298, 235, 298, 324, 298, 322, 340, 239, 342, 343, - 344, 345, 346, 347, 148, 149, 150, 151, 152, 153, - 154, 155, 348, 216, 349, 221, 350, 222, 241, 157, - 242, 244, 245, 352, 353, 158, 287, 219, 240, 159, - 239, 354, 359, 360, 358, 362, 375, 363, 278, 313, - 365, 366, 217, 316, 372, 378, 379, 376, 377, 383, - 309, 380, 335, 309, 381, 382, 317, 288, 220, 384, - 373, 240, 385, 326, 336, 386, 148, 149, 150, 151, - 152, 153, 154, 155, 387, 325, 309, 157, 157, 400, - 407, 401, 402, 286, 332, 337, 294, 280, 283, 330, - 404, 403, 411, 309, 417, 357, 284, 216, 435, 335, - 442, 295, 441, 447, 289, 0, 416, 204, 205, 206, - 207, 208, 209, 210, 211, 361, 458, 270, 459, 460, - 291, 461, 0, 368, 370, 285, 217, 0, 0, 0, - 0, 0, 364, 0, 0, 367, 369, 0, 0, 371, - 440, 0, 374, 443, 246, 247, 248, 0, 0, 0, - 286, 287, 333, 0, 399, 283, 0, 0, 0, 0, - 0, 406, 0, 410, 0, 0, 0, 0, 388, 412, - 391, 413, 0, 0, 396, 0, 409, 0, 0, 393, - 286, 0, 288, 334, 414, 283, 0, 0, 425, 0, - 326, 326, 0, 0, 437, 438, 286, 312, 423, 424, - 0, 283, 325, 325, 0, 0, 286, 0, 439, 0, - 430, 283, 0, 0, 436, 428, 0, 0, 287, 0, - 448, 284, 331, 0, 0, 0, 409, 0, 391, 0, - 286, 286, 396, 286, 0, 283, 283, 393, 283, 0, - 0, 0, 397, 296, 0, 0, 0, 317, 287, 288, - 285, 0, 0, 451, 0, 453, 449, 454, 455, 456, - 457, 0, 0, 0, 287, 450, 0, 452, 0, 0, - 0, 0, 0, 398, 287, 0, 0, 0, 431, 288, - 0, 299, 0, 300, 0, 301, 0, 302, 284, 303, - 0, 304, 0, 305, 0, 288, 0, 0, 287, 287, - 397, 287, 0, 0, 0, 288, 0, 0, 0, 432, - 0, 0, 394, 0, 0, 0, 0, 285, 284, 148, - 149, 150, 151, 152, 153, 154, 155, 0, 0, 288, - 288, 398, 288, 415, 284, 0, 0, 0, 0, 156, - 389, 395, 0, 0, 284, 0, 0, 285, 204, 205, - 206, 207, 208, 209, 210, 211, 0, 0, 0, 0, - 156, 0, 0, 285, 0, 0, 0, 0, 284, 284, - 394, 284, 0, 285, 0, 0, 0, 429, 148, 149, - 150, 151, 152, 153, 154, 155, 204, 205, 206, 207, - 208, 209, 210, 211, 0, 0, 0, 285, 285, 395, - 285, 148, 149, 150, 151, 152, 153, 154, 155, 204, - 205, 206, 207, 208, 209, 210, 211, 204, 205, 206, - 207, 208, 209, 210, 211, 418, 419, 0, 204, 205, - 206, 207, 208, 209, 210, 211, 162, 174, 176, 178, - 180, 182, 184, 186, 148, 149, 150, 151, 152, 153, - 154, 155, 0, 0, 0, 0, 0, 157, 0, 133, - 134, 135, 0, 158, 351, 0, 0, 159, 148, 149, - 150, 151, 152, 153, 154, 155, 0, 0, 157, 0, - 0, 0, 0, 0, 158, 0, 0, 408, 159, 148, - 149, 150, 151, 152, 153, 154, 155, 204, 205, 206, - 207, 208, 209, 210, 211, 148, 149, 150, 151, 152, - 153, 154, 155, 0, 0, 0, 157, 204, 205, 206, - 207, 208, 209, 210, 211, 0, 280, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 273, 0, 0, 0, 0, 0, 0, 157, 0, 280, - 0, 0, 0, 0, 0, 0, 0, 280, 157, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 0, 145, 146, 147, 161, - 173, 175, 177, 179, 181, 183, 185, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 0, 0, 0, 0, 0, 0, 224, 0, - 228, 229, 230, 231, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 257, 258, - 259, 0, 260, 0, 0, 0, 0, 0, 264 -}; - -static const yytype_int16 yycheck[] = -{ - 53, 52, 344, 23, 142, 148, 141, 146, 128, 152, - 147, 45, 45, 52, 152, 45, 151, 143, 144, 145, - 45, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 144, 145, 144, - 145, 23, 11, 12, 13, 14, 15, 16, 17, 18, - 103, 104, 11, 12, 13, 14, 15, 16, 17, 18, - 402, 100, 101, 114, 148, 147, 119, 147, 152, 99, - 121, 45, 0, 45, 99, 147, 127, 227, 117, 130, - 148, 148, 147, 45, 152, 152, 120, 11, 12, 13, - 14, 15, 16, 17, 18, 129, 129, 147, 128, 129, - 250, 23, 132, 128, 129, 381, 382, 132, 23, 151, - 161, 148, 148, 148, 45, 23, 148, 267, 157, 148, - 159, 148, 173, 23, 175, 99, 177, 99, 179, 148, - 181, 151, 183, 253, 185, 148, 23, 99, 148, 148, - 148, 148, 23, 23, 3, 4, 5, 6, 7, 8, - 9, 10, 23, 45, 23, 129, 148, 129, 132, 141, - 132, 20, 21, 148, 148, 147, 128, 129, 99, 151, - 132, 152, 23, 148, 152, 148, 21, 148, 147, 230, - 148, 148, 45, 234, 147, 150, 150, 148, 148, 23, - 224, 148, 151, 227, 149, 148, 235, 128, 129, 148, - 320, 132, 148, 254, 255, 148, 3, 4, 5, 6, - 7, 8, 9, 10, 148, 254, 250, 141, 141, 148, - 23, 148, 148, 253, 254, 255, 23, 151, 253, 254, - 350, 148, 148, 267, 23, 142, 128, 129, 148, 151, - 402, 280, 401, 152, 129, -1, 366, 11, 12, 13, - 14, 15, 16, 17, 18, 306, 152, 120, 152, 152, - 132, 152, -1, 314, 315, 128, 129, -1, -1, -1, - -1, -1, 311, -1, -1, 314, 315, -1, -1, 318, - 400, -1, 321, 403, 143, 144, 145, -1, -1, -1, - 320, 253, 254, -1, 345, 320, -1, -1, -1, -1, - -1, 352, -1, 356, -1, -1, -1, -1, 342, 360, - 344, 362, -1, -1, 344, -1, 355, -1, -1, 344, - 350, -1, 253, 254, 363, 350, -1, -1, 379, -1, - 381, 382, -1, -1, 385, 386, 366, 229, 377, 378, - -1, 366, 381, 382, -1, -1, 376, -1, 387, -1, - 380, 376, -1, -1, 384, 380, -1, -1, 320, -1, - 411, 253, 254, -1, -1, -1, 405, -1, 402, -1, - 400, 401, 402, 403, -1, 400, 401, 402, 403, -1, - -1, -1, 344, 147, -1, -1, -1, 426, 350, 320, - 253, -1, -1, 444, -1, 446, 435, 450, 451, 452, - 453, -1, -1, -1, 366, 444, -1, 446, -1, -1, - -1, -1, -1, 344, 376, -1, -1, -1, 380, 350, - -1, 173, -1, 175, -1, 177, -1, 179, 320, 181, - -1, 183, -1, 185, -1, 366, -1, -1, 400, 401, - 402, 403, -1, -1, -1, 376, -1, -1, -1, 380, - -1, -1, 344, -1, -1, -1, -1, 320, 350, 3, - 4, 5, 6, 7, 8, 9, 10, -1, -1, 400, - 401, 402, 403, 365, 366, -1, -1, -1, -1, 23, - 343, 344, -1, -1, 376, -1, -1, 350, 11, 12, - 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, - 23, -1, -1, 366, -1, -1, -1, -1, 400, 401, - 402, 403, -1, 376, -1, -1, -1, 380, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, -1, -1, 400, 401, 402, - 403, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, -1, 11, 12, - 13, 14, 15, 16, 17, 18, 17, 18, 19, 20, - 21, 22, 23, 24, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, 141, -1, 143, - 144, 145, -1, 147, 23, -1, -1, 151, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, 141, -1, - -1, -1, -1, -1, 147, -1, -1, 22, 151, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, 141, 11, 12, 13, - 14, 15, 16, 17, 18, -1, 151, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 121, -1, -1, -1, -1, -1, -1, 141, -1, 151, - -1, -1, -1, -1, -1, -1, -1, 151, 141, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 4, 5, 6, 7, - 8, 9, 10, -1, 12, -1, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, -1, -1, -1, -1, -1, -1, 46, -1, - 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 106, 107, - 108, -1, 110, -1, -1, -1, -1, -1, 116 -}; - - /* YYSTOSSTATE-NUM -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 143, 144, 145, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 3, 4, - 5, 6, 7, 8, 9, 10, 23, 141, 147, 151, - 172, 176, 181, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 176, 181, 176, 181, 176, 181, 176, - 181, 176, 181, 176, 181, 176, 181, 146, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 11, 12, 13, 14, 15, 16, - 17, 18, 173, 183, 190, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 176, 144, 145, 175, 176, 176, - 176, 176, 172, 173, 175, 151, 187, 192, 195, 196, - 197, 198, 199, 172, 20, 21, 143, 144, 145, 172, - 177, 144, 145, 178, 175, 175, 147, 176, 176, 176, - 176, 147, 173, 147, 176, 172, 0, 175, 170, 190, - 194, 171, 173, 181, 147, 147, 147, 23, 147, 173, - 151, 185, 190, 192, 193, 194, 195, 196, 197, 183, - 173, 187, 172, 23, 23, 172, 147, 169, 173, 169, - 169, 169, 169, 169, 169, 169, 148, 181, 184, 190, - 184, 151, 193, 173, 148, 148, 173, 172, 148, 148, - 148, 148, 148, 184, 185, 172, 173, 179, 180, 188, - 192, 193, 195, 196, 197, 151, 173, 195, 23, 23, - 23, 184, 148, 148, 148, 148, 23, 23, 23, 23, - 148, 23, 148, 148, 152, 148, 152, 142, 152, 23, - 148, 173, 148, 148, 172, 148, 148, 172, 173, 172, - 173, 172, 147, 185, 172, 21, 148, 148, 150, 150, - 148, 149, 148, 23, 148, 148, 148, 148, 190, 194, - 182, 190, 191, 192, 193, 194, 195, 196, 197, 173, - 148, 148, 148, 148, 185, 148, 173, 23, 22, 172, - 175, 148, 173, 173, 172, 193, 185, 23, 19, 20, - 185, 186, 201, 172, 172, 173, 151, 189, 192, 194, - 195, 196, 197, 179, 179, 148, 195, 173, 173, 172, - 185, 186, 182, 185, 148, 152, 148, 152, 173, 172, - 172, 173, 172, 173, 175, 175, 175, 175, 152, 152, - 152, 152 -}; - - /* YYR1YYN -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 153, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 155, 155, 156, 156, 156, 156, 157, - 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, - 160, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, - 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 167, 167, 167, 167, - 167, 167, 167, 168, 168, 168, 169, 169, 170, 170, - 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, - 173, 173, 173, 173, 173, 173, 173, 173, 174, 175, - 175, 176, 176, 176, 177, 177, 177, 178, 178, 179, - 179, 180, 180, 180, 180, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, - 182, 182, 182, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 184, 184, 185, 185, 185, 185, 185, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, - 190, 191, 192, 193, 194, 195, 196, 196, 197, 197, - 198, 198, 199, 199, 200, 201, 201 -}; - - /* YYR2YYN -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 2, 2, 5, 5, 5, 1, 2, 4, - 5, 4, 2, 5, 4, 5, 5, 4, 5, 4, - 4, 4, 4, 3, 1, 2, 4, 5, 5, 4, - 4, 4, 5, 5, 5, 5, 5, 5, 3, 5, - 2, 3, 2, 1, 1, 1, 2, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, - 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, - 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 4, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 3, 3, 5, 8, 8, 4, 3, - 5, 1, 8, 8, 2, 1, 1 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -# ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - FILE *yyoutput = yyo; - YYUSE (yyoutput); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yykind < YYNTOKENS) - YYPRINT (yyo, yytoknum[yykind], *yyvaluep); -# endif - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - yy_symbol_value_print (yyo, yykind, yyvaluep); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, - int yyrule) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)]); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - - - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep) -{ - YYUSE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - yy_state_fast_t yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize; - - /* The state stack. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss; - yy_state_t *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yynerrs = 0; - yystate = 0; - yyerrstatus = 0; - - yystacksize = YYINITDEPTH; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - goto yyexhaustedlab; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - /* Discard the shifted token. */ - yychar = YYEMPTY; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 112 "m68kasm.y" - { _genop((yyvsp[-1].opc) | (yyvsp[0].opc)); yyrc = -1; } -#line 1979 "m68kasm.c" - break; - - case 3: -#line 113 "m68kasm.y" - { _genop((yyvsp[-1].opc) | (yyvsp[0].rea).reg | (yyvsp[0].rea).ea.ea); yyrc = _genea((yyvsp[0].rea).ea) -1; } -#line 1985 "m68kasm.c" - break; - - case 4: -#line 114 "m68kasm.y" - { _genop((yyvsp[-4].opc) | (yyvsp[0].ea).ea); if (oplen==0) { _genop((yyvsp[-2].num) & 0xff); yyrc = _genea((yyvsp[0].ea)) - 3; } - - else if (oplen==1) { _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } else { _genop((yyvsp[-2].num)>>16); _genop((yyvsp[-2].num) & 0xffff); yyrc = _genea((yyvsp[0].ea))-5; } } -#line 1992 "m68kasm.c" - break; - - case 5: -#line 116 "m68kasm.y" - { _genop((yyvsp[-4].opc) | (((yyvsp[-2].num)&7)<<9) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 1998 "m68kasm.c" - break; - - case 6: -#line 117 "m68kasm.y" - { _genop((yyvsp[-4].opc) | (yyvsp[0].ea).ea); if (oplen==0) { _genop((yyvsp[-2].num) & 0xff); yyrc = _genea((yyvsp[0].ea)) - 3; } - - else if (oplen==1) { _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } else { _genop((yyvsp[-2].num)>>16); _genop((yyvsp[-2].num) & 0xffff); yyrc = _genea((yyvsp[0].ea))-5; } } -#line 2005 "m68kasm.c" - break; - - case 7: -#line 119 "m68kasm.y" - { _genop((yyvsp[0].rea).reg); if (((yyvsp[0].rea).reg&0xc0)==0xc0) yyrc = _genea((yyvsp[0].rea).ea) - 1; else { yyrc = -1; } } -#line 2011 "m68kasm.c" - break; - - case 8: -#line 120 "m68kasm.y" - { yyrc = _genbr((yyvsp[-1].brop).opc,(yyvsp[0].num),(yyvsp[-1].brop).len); } -#line 2017 "m68kasm.c" - break; - - case 9: -#line 121 "m68kasm.y" - { _genop((yyvsp[-3].opc) | ((yyvsp[-2].reg)<<9) | 0x100 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 2023 "m68kasm.c" - break; - - case 10: -#line 122 "m68kasm.y" - { _genop((yyvsp[-4].opc) | 0x0800 | (yyvsp[0].ea).ea); _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } -#line 2029 "m68kasm.c" - break; - - case 11: -#line 123 "m68kasm.y" - { _genop(0x4180 | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2035 "m68kasm.c" - break; - - case 12: -#line 124 "m68kasm.y" - { _genop((yyvsp[-1].opc) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 2041 "m68kasm.c" - break; - - case 13: -#line 125 "m68kasm.y" - { _genop(0xb000 | ((yyvsp[-3].wl)<<6) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2047 "m68kasm.c" - break; - - case 14: -#line 126 "m68kasm.y" - { _genop((yyvsp[-3].opc) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2053 "m68kasm.c" - break; - - case 15: -#line 127 "m68kasm.y" - { _genop(0xb0c0 | ((yyvsp[-3].wl)<<8) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2059 "m68kasm.c" - break; - - case 16: -#line 128 "m68kasm.y" - { _genop(0xb108 | ((yyvsp[0].ea).ea<<9) | ((yyvsp[-3].wl)<<6) | (yyvsp[-2].ea).ea); yyrc = -1; } -#line 2065 "m68kasm.c" - break; - - case 17: -#line 129 "m68kasm.y" - { yyrc = _genbr((yyvsp[-3].opc) | (yyvsp[-2].reg), (yyvsp[0].num), 1); } -#line 2071 "m68kasm.c" - break; - - case 18: -#line 130 "m68kasm.y" - { _genop(0xb000 | ((yyvsp[-3].wl) << 6) | 0x100 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 2077 "m68kasm.c" - break; - - case 19: -#line 131 "m68kasm.y" - { _genop(0xc140 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } -#line 2083 "m68kasm.c" - break; - - case 20: -#line 132 "m68kasm.y" - { _genop(0xc148 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } -#line 2089 "m68kasm.c" - break; - - case 21: -#line 133 "m68kasm.y" - { _genop(0xc188 | ((yyvsp[0].reg)<<9) | (yyvsp[-2].reg)); yyrc = -1; } -#line 2095 "m68kasm.c" - break; - - case 22: -#line 134 "m68kasm.y" - { _genop(0xc188 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } -#line 2101 "m68kasm.c" - break; - - case 23: -#line 135 "m68kasm.y" - { _genop(0x4840 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].reg)); yyrc = -1; } -#line 2107 "m68kasm.c" - break; - - case 24: -#line 136 "m68kasm.y" - { _genop((yyvsp[0].opc)); yyrc = -1; } -#line 2113 "m68kasm.c" - break; - - case 25: -#line 137 "m68kasm.y" - { _genop((yyvsp[-1].opc) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) -1; } -#line 2119 "m68kasm.c" - break; - - case 26: -#line 138 "m68kasm.y" - { _genop(0x41c0 | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2125 "m68kasm.c" - break; - - case 27: -#line 139 "m68kasm.y" - { _genop(0x4e50 | (yyvsp[-3].reg)); _genop((yyvsp[0].num)); yyrc = -3; } -#line 2131 "m68kasm.c" - break; - - case 28: -#line 140 "m68kasm.y" - { if ((yyvsp[0].ea).ea==074) { _genop(0x44c0 | ((yyvsp[0].ea).cnt==1?0x0200:0x0000) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } - - else { int tmp = (((yyvsp[0].ea).ea&070)>>3)|(((yyvsp[0].ea).ea&7)<<3); _genop(0x0000 | ((yyvsp[-3].wl)<<12) | (tmp<<6) | (yyvsp[-2].ea).ea); - - yyrc = _genea((yyvsp[-2].ea)) - 1; yyrc += _genea((yyvsp[0].ea)); } } -#line 2139 "m68kasm.c" - break; - - case 29: -#line 143 "m68kasm.y" - { _genop(0x40c0 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 2145 "m68kasm.c" - break; - - case 30: -#line 144 "m68kasm.y" - { _genop(0x4e68 | (yyvsp[0].reg)); yyrc = -1; } -#line 2151 "m68kasm.c" - break; - - case 31: -#line 145 "m68kasm.y" - { _genop(0x4e60 | (yyvsp[-2].reg)); yyrc = -1; } -#line 2157 "m68kasm.c" - break; - - case 32: -#line 146 "m68kasm.y" - { _genop(0x0040 | ((yyvsp[-3].wl)<<12) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2163 "m68kasm.c" - break; - - case 33: -#line 147 "m68kasm.y" - { _genop(0x4880 | ((yyvsp[-3].wl)<<6) | (yyvsp[0].ea).ea); _genop(((yyvsp[0].ea).ea&070)==040 ? (yyvsp[-2].mask).d : (yyvsp[-2].mask).x); yyrc = _genea((yyvsp[0].ea)) - 3; } -#line 2169 "m68kasm.c" - break; - - case 34: -#line 148 "m68kasm.y" - { _genop(0x4c80 | ((yyvsp[-3].wl)<<6) | (yyvsp[-2].ea).ea); _genop((yyvsp[0].mask).x); yyrc = _genea((yyvsp[-2].ea)) - 3; } -#line 2175 "m68kasm.c" - break; - - case 35: -#line 149 "m68kasm.y" - { _genop(0x0108 | ((yyvsp[-2].reg)<<9) | ((yyvsp[-3].wl)<<6) | ((yyvsp[0].ea).ea & 7)); yyrc = _genea((yyvsp[0].ea)) - 1; } -#line 2181 "m68kasm.c" - break; - - case 36: -#line 150 "m68kasm.y" - { _genop(0x0188 | ((yyvsp[0].reg)<<9) | ((yyvsp[-3].wl)<<6) | ((yyvsp[-2].ea).ea & 7)); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2187 "m68kasm.c" - break; - - case 37: -#line 151 "m68kasm.y" - { _genop(0x7000 | ((yyvsp[0].reg)<<9) | ((yyvsp[-2].num)&0xff)); yyrc = -1; } -#line 2193 "m68kasm.c" - break; - - case 38: -#line 152 "m68kasm.y" - { _genop(0x4e72); yyrc = _genop((yyvsp[0].num)&0xffff) - 1; } -#line 2199 "m68kasm.c" - break; - - case 39: -#line 153 "m68kasm.y" - { _genop((yyvsp[-4].opc) | ((yyvsp[0].reg)<<9) | ((yyvsp[-3].wl)<<8) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } -#line 2205 "m68kasm.c" - break; - - case 40: -#line 154 "m68kasm.y" - { _genop(0x4840 | (yyvsp[0].reg)); yyrc = -1; } -#line 2211 "m68kasm.c" - break; - - case 41: -#line 155 "m68kasm.y" - { _genop(0x4e40 | ((yyvsp[0].num) & 0x0f)); yyrc = -1; } -#line 2217 "m68kasm.c" - break; - - case 42: -#line 156 "m68kasm.y" - { _genop(0x4e58 | (yyvsp[0].reg)); yyrc = -1; } -#line 2223 "m68kasm.c" - break; - - case 43: -#line 160 "m68kasm.y" - { (yyval.opc) = 0xd0c0; } -#line 2229 "m68kasm.c" - break; - - case 44: -#line 161 "m68kasm.y" - { (yyval.opc) = 0x90c0; } -#line 2235 "m68kasm.c" - break; - - case 45: -#line 164 "m68kasm.y" - { (yyval.opc) = 0xc100; } -#line 2241 "m68kasm.c" - break; - - case 46: -#line 165 "m68kasm.y" - { (yyval.opc) = 0xd100 | ((yyvsp[0].wl)<<6); } -#line 2247 "m68kasm.c" - break; - - case 47: -#line 166 "m68kasm.y" - { (yyval.opc) = 0x8100; } -#line 2253 "m68kasm.c" - break; - - case 48: -#line 167 "m68kasm.y" - { (yyval.opc) = 0x9100 | ((yyvsp[0].wl)<<6); } -#line 2259 "m68kasm.c" - break; - - case 49: -#line 171 "m68kasm.y" - { (yyval.opc) = 0xd000 | ((yyvsp[0].wl)<<6); } -#line 2265 "m68kasm.c" - break; - - case 50: -#line 172 "m68kasm.y" - { (yyval.opc) = 0xc000 | ((yyvsp[0].wl)<<6); } -#line 2271 "m68kasm.c" - break; - - case 51: -#line 173 "m68kasm.y" - { (yyval.opc) = 0x8000 | ((yyvsp[0].wl)<<6); } -#line 2277 "m68kasm.c" - break; - - case 52: -#line 174 "m68kasm.y" - { (yyval.opc) = 0x9000 | ((yyvsp[0].wl)<<6); } -#line 2283 "m68kasm.c" - break; - - case 53: -#line 178 "m68kasm.y" - { (yyval.opc) = 0x0600 | ((yyvsp[0].wl)<<6); } -#line 2289 "m68kasm.c" - break; - - case 54: -#line 179 "m68kasm.y" - { (yyval.opc) = 0x0c00 | ((yyvsp[0].wl)<<6); } -#line 2295 "m68kasm.c" - break; - - case 55: -#line 180 "m68kasm.y" - { (yyval.opc) = 0x0400 | ((yyvsp[0].wl)<<6); } -#line 2301 "m68kasm.c" - break; - - case 56: -#line 184 "m68kasm.y" - { (yyval.opc) = 0x0200 | ((yyvsp[0].wl)<<6); } -#line 2307 "m68kasm.c" - break; - - case 57: -#line 185 "m68kasm.y" - { (yyval.opc) = 0x0a00 | ((yyvsp[0].wl)<<6); } -#line 2313 "m68kasm.c" - break; - - case 58: -#line 186 "m68kasm.y" - { (yyval.opc) = 0x0000 | ((yyvsp[0].wl)<<6); } -#line 2319 "m68kasm.c" - break; - - case 59: -#line 190 "m68kasm.y" - { (yyval.opc) = 0x5000 | ((yyvsp[0].wl)<<6); } -#line 2325 "m68kasm.c" - break; - - case 60: -#line 191 "m68kasm.y" - { (yyval.opc) = 0x5100 | ((yyvsp[0].wl)<<6); } -#line 2331 "m68kasm.c" - break; - - case 61: -#line 195 "m68kasm.y" - { (yyval.rea).reg = 0xe1c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2337 "m68kasm.c" - break; - - case 62: -#line 196 "m68kasm.y" - { (yyval.rea).reg = 0xe100 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2343 "m68kasm.c" - break; - - case 63: -#line 197 "m68kasm.y" - { (yyval.rea).reg = 0xe0c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2349 "m68kasm.c" - break; - - case 64: -#line 198 "m68kasm.y" - { (yyval.rea).reg = 0xe000 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2355 "m68kasm.c" - break; - - case 65: -#line 199 "m68kasm.y" - { (yyval.rea).reg = 0xe3c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2361 "m68kasm.c" - break; - - case 66: -#line 200 "m68kasm.y" - { (yyval.rea).reg = 0xe108 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2367 "m68kasm.c" - break; - - case 67: -#line 201 "m68kasm.y" - { (yyval.rea).reg = 0xe2c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2373 "m68kasm.c" - break; - - case 68: -#line 202 "m68kasm.y" - { (yyval.rea).reg = 0xe008 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2379 "m68kasm.c" - break; - - case 69: -#line 203 "m68kasm.y" - { (yyval.rea).reg = 0xe7c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2385 "m68kasm.c" - break; - - case 70: -#line 204 "m68kasm.y" - { (yyval.rea).reg = 0xe118 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2391 "m68kasm.c" - break; - - case 71: -#line 205 "m68kasm.y" - { (yyval.rea).reg = 0xe6c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2397 "m68kasm.c" - break; - - case 72: -#line 206 "m68kasm.y" - { (yyval.rea).reg = 0xe018 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2403 "m68kasm.c" - break; - - case 73: -#line 207 "m68kasm.y" - { (yyval.rea).reg = 0xe5c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2409 "m68kasm.c" - break; - - case 74: -#line 208 "m68kasm.y" - { (yyval.rea).reg = 0xe100 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2415 "m68kasm.c" - break; - - case 75: -#line 209 "m68kasm.y" - { (yyval.rea).reg = 0xe4c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } -#line 2421 "m68kasm.c" - break; - - case 76: -#line 210 "m68kasm.y" - { (yyval.rea).reg = 0xe000 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } -#line 2427 "m68kasm.c" - break; - - case 77: -#line 214 "m68kasm.y" - { (yyval.brop).opc = 0x6400; (yyval.brop).len = 1; } -#line 2433 "m68kasm.c" - break; - - case 78: -#line 215 "m68kasm.y" - { (yyval.brop).opc = 0x6500; (yyval.brop).len = 1; } -#line 2439 "m68kasm.c" - break; - - case 79: -#line 216 "m68kasm.y" - { (yyval.brop).opc = 0x6700; (yyval.brop).len = 1; } -#line 2445 "m68kasm.c" - break; - - case 80: -#line 217 "m68kasm.y" - { (yyval.brop).opc = 0x6c00; (yyval.brop).len = 1; } -#line 2451 "m68kasm.c" - break; - - case 81: -#line 218 "m68kasm.y" - { (yyval.brop).opc = 0x6e00; (yyval.brop).len = 1; } -#line 2457 "m68kasm.c" - break; - - case 82: -#line 219 "m68kasm.y" - { (yyval.brop).opc = 0x6200; (yyval.brop).len = 1; } -#line 2463 "m68kasm.c" - break; - - case 83: -#line 220 "m68kasm.y" - { (yyval.brop).opc = 0x6f00; (yyval.brop).len = 1; } -#line 2469 "m68kasm.c" - break; - - case 84: -#line 221 "m68kasm.y" - { (yyval.brop).opc = 0x6300; (yyval.brop).len = 1; } -#line 2475 "m68kasm.c" - break; - - case 85: -#line 222 "m68kasm.y" - { (yyval.brop).opc = 0x6d00; (yyval.brop).len = 1; } -#line 2481 "m68kasm.c" - break; - - case 86: -#line 223 "m68kasm.y" - { (yyval.brop).opc = 0x6b00; (yyval.brop).len = 1; } -#line 2487 "m68kasm.c" - break; - - case 87: -#line 224 "m68kasm.y" - { (yyval.brop).opc = 0x6600; (yyval.brop).len = 1; } -#line 2493 "m68kasm.c" - break; - - case 88: -#line 225 "m68kasm.y" - { (yyval.brop).opc = 0x6a00; (yyval.brop).len = 1; } -#line 2499 "m68kasm.c" - break; - - case 89: -#line 226 "m68kasm.y" - { (yyval.brop).opc = 0x6800; (yyval.brop).len = 1; } -#line 2505 "m68kasm.c" - break; - - case 90: -#line 227 "m68kasm.y" - { (yyval.brop).opc = 0x6900; (yyval.brop).len = 1; } -#line 2511 "m68kasm.c" - break; - - case 91: -#line 228 "m68kasm.y" - { (yyval.brop).opc = 0x6100; (yyval.brop).len = 1; } -#line 2517 "m68kasm.c" - break; - - case 92: -#line 229 "m68kasm.y" - { (yyval.brop).opc = 0x6000; (yyval.brop).len = 1; } -#line 2523 "m68kasm.c" - break; - - case 93: -#line 230 "m68kasm.y" - { (yyval.brop).opc = 0x6400; (yyval.brop).len = 0; } -#line 2529 "m68kasm.c" - break; - - case 94: -#line 231 "m68kasm.y" - { (yyval.brop).opc = 0x6500; (yyval.brop).len = 0; } -#line 2535 "m68kasm.c" - break; - - case 95: -#line 232 "m68kasm.y" - { (yyval.brop).opc = 0x6700; (yyval.brop).len = 0; } -#line 2541 "m68kasm.c" - break; - - case 96: -#line 233 "m68kasm.y" - { (yyval.brop).opc = 0x6c00; (yyval.brop).len = 0; } -#line 2547 "m68kasm.c" - break; - - case 97: -#line 234 "m68kasm.y" - { (yyval.brop).opc = 0x6e00; (yyval.brop).len = 0; } -#line 2553 "m68kasm.c" - break; - - case 98: -#line 235 "m68kasm.y" - { (yyval.brop).opc = 0x6200; (yyval.brop).len = 0; } -#line 2559 "m68kasm.c" - break; - - case 99: -#line 236 "m68kasm.y" - { (yyval.brop).opc = 0x6f00; (yyval.brop).len = 0; } -#line 2565 "m68kasm.c" - break; - - case 100: -#line 237 "m68kasm.y" - { (yyval.brop).opc = 0x6300; (yyval.brop).len = 0; } -#line 2571 "m68kasm.c" - break; - - case 101: -#line 238 "m68kasm.y" - { (yyval.brop).opc = 0x6d00; (yyval.brop).len = 0; } -#line 2577 "m68kasm.c" - break; - - case 102: -#line 239 "m68kasm.y" - { (yyval.brop).opc = 0x6b00; (yyval.brop).len = 0; } -#line 2583 "m68kasm.c" - break; - - case 103: -#line 240 "m68kasm.y" - { (yyval.brop).opc = 0x6600; (yyval.brop).len = 0; } -#line 2589 "m68kasm.c" - break; - - case 104: -#line 241 "m68kasm.y" - { (yyval.brop).opc = 0x6a00; (yyval.brop).len = 0; } -#line 2595 "m68kasm.c" - break; - - case 105: -#line 242 "m68kasm.y" - { (yyval.brop).opc = 0x6800; (yyval.brop).len = 0; } -#line 2601 "m68kasm.c" - break; - - case 106: -#line 243 "m68kasm.y" - { (yyval.brop).opc = 0x6900; (yyval.brop).len = 0; } -#line 2607 "m68kasm.c" - break; - - case 107: -#line 244 "m68kasm.y" - { (yyval.brop).opc = 0x6100; (yyval.brop).len = 0; } -#line 2613 "m68kasm.c" - break; - - case 108: -#line 245 "m68kasm.y" - { (yyval.brop).opc = 0x6000; (yyval.brop).len = 0; } -#line 2619 "m68kasm.c" - break; - - case 109: -#line 249 "m68kasm.y" - { (yyval.opc) = 0x0040; } -#line 2625 "m68kasm.c" - break; - - case 110: -#line 250 "m68kasm.y" - { (yyval.opc) = 0x0080; } -#line 2631 "m68kasm.c" - break; - - case 111: -#line 251 "m68kasm.y" - { (yyval.opc) = 0x00c0; } -#line 2637 "m68kasm.c" - break; - - case 112: -#line 252 "m68kasm.y" - { (yyval.opc) = 0x0000; } -#line 2643 "m68kasm.c" - break; - - case 113: -#line 256 "m68kasm.y" - { (yyval.opc) = 0x4200 | ((yyvsp[0].wl)<<6); } -#line 2649 "m68kasm.c" - break; - - case 114: -#line 257 "m68kasm.y" - { (yyval.opc) = 0x4800; } -#line 2655 "m68kasm.c" - break; - - case 115: -#line 258 "m68kasm.y" - { (yyval.opc) = 0x4400 | ((yyvsp[0].wl)<<6); } -#line 2661 "m68kasm.c" - break; - - case 116: -#line 259 "m68kasm.y" - { (yyval.opc) = 0x4000 | ((yyvsp[0].wl)<<6); } -#line 2667 "m68kasm.c" - break; - - case 117: -#line 260 "m68kasm.y" - { (yyval.opc) = 0x4600 | ((yyvsp[0].wl)<<6); } -#line 2673 "m68kasm.c" - break; - - case 118: -#line 261 "m68kasm.y" - { (yyval.opc) = 0x54c0; } -#line 2679 "m68kasm.c" - break; - - case 119: -#line 262 "m68kasm.y" - { (yyval.opc) = 0x55c0; } -#line 2685 "m68kasm.c" - break; - - case 120: -#line 263 "m68kasm.y" - { (yyval.opc) = 0x57c0; } -#line 2691 "m68kasm.c" - break; - - case 121: -#line 264 "m68kasm.y" - { (yyval.opc) = 0x51c0; } -#line 2697 "m68kasm.c" - break; - - case 122: -#line 265 "m68kasm.y" - { (yyval.opc) = 0x5cc0; } -#line 2703 "m68kasm.c" - break; - - case 123: -#line 266 "m68kasm.y" - { (yyval.opc) = 0x5ec0; } -#line 2709 "m68kasm.c" - break; - - case 124: -#line 267 "m68kasm.y" - { (yyval.opc) = 0x52c0; } -#line 2715 "m68kasm.c" - break; - - case 125: -#line 268 "m68kasm.y" - { (yyval.opc) = 0x5fc0; } -#line 2721 "m68kasm.c" - break; - - case 126: -#line 269 "m68kasm.y" - { (yyval.opc) = 0x53c0; } -#line 2727 "m68kasm.c" - break; - - case 127: -#line 270 "m68kasm.y" - { (yyval.opc) = 0x5dc0; } -#line 2733 "m68kasm.c" - break; - - case 128: -#line 271 "m68kasm.y" - { (yyval.opc) = 0x5bc0; } -#line 2739 "m68kasm.c" - break; - - case 129: -#line 272 "m68kasm.y" - { (yyval.opc) = 0x56c0; } -#line 2745 "m68kasm.c" - break; - - case 130: -#line 273 "m68kasm.y" - { (yyval.opc) = 0x5ac0; } -#line 2751 "m68kasm.c" - break; - - case 131: -#line 274 "m68kasm.y" - { (yyval.opc) = 0x50c0; } -#line 2757 "m68kasm.c" - break; - - case 132: -#line 275 "m68kasm.y" - { (yyval.opc) = 0x58c0; } -#line 2763 "m68kasm.c" - break; - - case 133: -#line 276 "m68kasm.y" - { (yyval.opc) = 0x59c0; } -#line 2769 "m68kasm.c" - break; - - case 134: -#line 277 "m68kasm.y" - { (yyval.opc) = 0x4ac0; } -#line 2775 "m68kasm.c" - break; - - case 135: -#line 278 "m68kasm.y" - { (yyval.opc) = 0x4a00 | ((yyvsp[0].wl)<<6); } -#line 2781 "m68kasm.c" - break; - - case 136: -#line 282 "m68kasm.y" - { (yyval.opc) = 0x81c0; } -#line 2787 "m68kasm.c" - break; - - case 137: -#line 283 "m68kasm.y" - { (yyval.opc) = 0x80c0; } -#line 2793 "m68kasm.c" - break; - - case 138: -#line 284 "m68kasm.y" - { (yyval.opc) = 0xc1c0; } -#line 2799 "m68kasm.c" - break; - - case 139: -#line 285 "m68kasm.y" - { (yyval.opc) = 0xc0c0; } -#line 2805 "m68kasm.c" - break; - - case 140: -#line 289 "m68kasm.y" - { (yyval.opc) = 0x54c8; } -#line 2811 "m68kasm.c" - break; - - case 141: -#line 290 "m68kasm.y" - { (yyval.opc) = 0x55c8; } -#line 2817 "m68kasm.c" - break; - - case 142: -#line 291 "m68kasm.y" - { (yyval.opc) = 0x57c8; } -#line 2823 "m68kasm.c" - break; - - case 143: -#line 292 "m68kasm.y" - { (yyval.opc) = 0x5cc8; } -#line 2829 "m68kasm.c" - break; - - case 144: -#line 293 "m68kasm.y" - { (yyval.opc) = 0x5ec8; } -#line 2835 "m68kasm.c" - break; - - case 145: -#line 294 "m68kasm.y" - { (yyval.opc) = 0x52c8; } -#line 2841 "m68kasm.c" - break; - - case 146: -#line 295 "m68kasm.y" - { (yyval.opc) = 0x5fc8; } -#line 2847 "m68kasm.c" - break; - - case 147: -#line 296 "m68kasm.y" - { (yyval.opc) = 0x53c8; } -#line 2853 "m68kasm.c" - break; - - case 148: -#line 297 "m68kasm.y" - { (yyval.opc) = 0x5dc8; } -#line 2859 "m68kasm.c" - break; - - case 149: -#line 298 "m68kasm.y" - { (yyval.opc) = 0x5bc8; } -#line 2865 "m68kasm.c" - break; - - case 150: -#line 299 "m68kasm.y" - { (yyval.opc) = 0x56c8; } -#line 2871 "m68kasm.c" - break; - - case 151: -#line 300 "m68kasm.y" - { (yyval.opc) = 0x5ac8; } -#line 2877 "m68kasm.c" - break; - - case 152: -#line 301 "m68kasm.y" - { (yyval.opc) = 0x58c8; } -#line 2883 "m68kasm.c" - break; - - case 153: -#line 302 "m68kasm.y" - { (yyval.opc) = 0x59c8; } -#line 2889 "m68kasm.c" - break; - - case 154: -#line 303 "m68kasm.y" - { (yyval.opc) = 0x51c8; } -#line 2895 "m68kasm.c" - break; - - case 155: -#line 304 "m68kasm.y" - { (yyval.opc) = 0x50c8; } -#line 2901 "m68kasm.c" - break; - - case 156: -#line 308 "m68kasm.y" - { (yyval.opc) = 0x4afc; } -#line 2907 "m68kasm.c" - break; - - case 157: -#line 309 "m68kasm.y" - { (yyval.opc) = 0x4e71; } -#line 2913 "m68kasm.c" - break; - - case 158: -#line 310 "m68kasm.y" - { (yyval.opc) = 0x4e70; } -#line 2919 "m68kasm.c" - break; - - case 159: -#line 311 "m68kasm.y" - { (yyval.opc) = 0x4e73; } -#line 2925 "m68kasm.c" - break; - - case 160: -#line 312 "m68kasm.y" - { (yyval.opc) = 0x4e77; } -#line 2931 "m68kasm.c" - break; - - case 161: -#line 313 "m68kasm.y" - { (yyval.opc) = 0x4e75; } -#line 2937 "m68kasm.c" - break; - - case 162: -#line 314 "m68kasm.y" - { (yyval.opc) = 0x4e76; } -#line 2943 "m68kasm.c" - break; - - case 163: -#line 318 "m68kasm.y" - { (yyval.opc) = 0x4ec0; } -#line 2949 "m68kasm.c" - break; - - case 164: -#line 319 "m68kasm.y" - { (yyval.opc) = 0x4e80; } -#line 2955 "m68kasm.c" - break; - - case 165: -#line 320 "m68kasm.y" - { (yyval.opc) = 0x4840; } -#line 2961 "m68kasm.c" - break; - - case 166: -#line 323 "m68kasm.y" - { (yyval.opc) = ((yyvsp[-2].reg)<<9) | 0x20 | (yyvsp[0].reg); } -#line 2967 "m68kasm.c" - break; - - case 167: -#line 324 "m68kasm.y" - { (yyval.opc) = (((yyvsp[-2].num) & 7)<<9) | (yyvsp[0].reg); } -#line 2973 "m68kasm.c" - break; - - case 168: -#line 327 "m68kasm.y" - { (yyval.opc) = (((yyvsp[-2].ea).ea & 7) << 9) | ((yyvsp[0].ea).ea & 7); } -#line 2979 "m68kasm.c" - break; - - case 169: -#line 328 "m68kasm.y" - { (yyval.opc) = (((yyvsp[-2].ea).ea & 7) << 9) | 0x0008 | ((yyvsp[0].ea).ea & 7); } -#line 2985 "m68kasm.c" - break; - - case 170: -#line 331 "m68kasm.y" - { if (((yyvsp[0].ea).ea & 070)==0) { /* dx,dy must be swapped */ - - (yyval.rea).reg = ((yyvsp[0].ea).ea & 7)<<9; (yyvsp[0].ea).ea = (yyvsp[-2].reg) & 7; (yyval.rea).ea = (yyvsp[0].ea); } - - else { (yyval.rea).reg = ((yyvsp[-2].reg)<<9) | 0x100; (yyval.rea).ea = (yyvsp[0].ea); } } -#line 2993 "m68kasm.c" - break; - - case 171: -#line 334 "m68kasm.y" - { (yyval.rea).reg = ((yyvsp[0].reg)<<9); (yyval.rea).ea = (yyvsp[-2].ea); } -#line 2999 "m68kasm.c" - break; - - case 172: -#line 337 "m68kasm.y" - { (yyval.reg)=0; } -#line 3005 "m68kasm.c" - break; - - case 173: -#line 338 "m68kasm.y" - { (yyval.reg)=1; } -#line 3011 "m68kasm.c" - break; - - case 174: -#line 339 "m68kasm.y" - { (yyval.reg)=2; } -#line 3017 "m68kasm.c" - break; - - case 175: -#line 340 "m68kasm.y" - { (yyval.reg)=3; } -#line 3023 "m68kasm.c" - break; - - case 176: -#line 341 "m68kasm.y" - { (yyval.reg)=4; } -#line 3029 "m68kasm.c" - break; - - case 177: -#line 342 "m68kasm.y" - { (yyval.reg)=5; } -#line 3035 "m68kasm.c" - break; - - case 178: -#line 343 "m68kasm.y" - { (yyval.reg)=6; } -#line 3041 "m68kasm.c" - break; - - case 179: -#line 344 "m68kasm.y" - { (yyval.reg)=7; } -#line 3047 "m68kasm.c" - break; - - case 180: -#line 347 "m68kasm.y" - { (yyval.reg)=0; } -#line 3053 "m68kasm.c" - break; - - case 181: -#line 348 "m68kasm.y" - { (yyval.reg)=1; } -#line 3059 "m68kasm.c" - break; - - case 182: -#line 349 "m68kasm.y" - { (yyval.reg)=2; } -#line 3065 "m68kasm.c" - break; - - case 183: -#line 350 "m68kasm.y" - { (yyval.reg)=3; } -#line 3071 "m68kasm.c" - break; - - case 184: -#line 351 "m68kasm.y" - { (yyval.reg)=4; } -#line 3077 "m68kasm.c" - break; - - case 185: -#line 352 "m68kasm.y" - { (yyval.reg)=5; } -#line 3083 "m68kasm.c" - break; - - case 186: -#line 353 "m68kasm.y" - { (yyval.reg)=6; } -#line 3089 "m68kasm.c" - break; - - case 187: -#line 354 "m68kasm.y" - { (yyval.reg)=7; } -#line 3095 "m68kasm.c" - break; - - case 188: -#line 357 "m68kasm.y" - { (yyval.wl) = 1; oplen = 0; } -#line 3101 "m68kasm.c" - break; - - case 189: -#line 360 "m68kasm.y" - { (yyval.wl) = 0; oplen = 1; } -#line 3107 "m68kasm.c" - break; - - case 190: -#line 361 "m68kasm.y" - { (yyval.wl) = 1; oplen = 2; } -#line 3113 "m68kasm.c" - break; - - case 191: -#line 364 "m68kasm.y" - { (yyval.wl) = 0; oplen = 0; } -#line 3119 "m68kasm.c" - break; - - case 192: -#line 365 "m68kasm.y" - { (yyval.wl) = 1; oplen = 1; } -#line 3125 "m68kasm.c" - break; - - case 193: -#line 366 "m68kasm.y" - { (yyval.wl) = 2; oplen = 2; } -#line 3131 "m68kasm.c" - break; - - case 194: -#line 369 "m68kasm.y" - { (yyval.wl) = 1; oplen = 0; } -#line 3137 "m68kasm.c" - break; - - case 195: -#line 370 "m68kasm.y" - { (yyval.wl) = 3; oplen = 1; } -#line 3143 "m68kasm.c" - break; - - case 196: -#line 371 "m68kasm.y" - { (yyval.wl) = 2; oplen = 2; } -#line 3149 "m68kasm.c" - break; - - case 197: -#line 374 "m68kasm.y" - { (yyval.wl) = 3; oplen = 1; } -#line 3155 "m68kasm.c" - break; - - case 198: -#line 375 "m68kasm.y" - { (yyval.wl) = 2; oplen = 2; } -#line 3161 "m68kasm.c" - break; - - case 199: -#line 378 "m68kasm.y" - { (yyval.mask) = (yyvsp[0].mask); } -#line 3167 "m68kasm.c" - break; - - case 200: -#line 379 "m68kasm.y" - { (yyval.mask).x = (yyvsp[-2].mask).x | (yyvsp[0].mask).x; (yyval.mask).d = (yyvsp[-2].mask).d | (yyvsp[0].mask).d; } -#line 3173 "m68kasm.c" - break; - - case 201: -#line 382 "m68kasm.y" - { (yyval.mask).x = movemx[(yyvsp[0].reg)]; (yyval.mask).d = movemd[(yyvsp[0].reg)]; } -#line 3179 "m68kasm.c" - break; - - case 202: -#line 383 "m68kasm.y" - { (yyval.mask).x = movemx[(yyvsp[0].reg)+8]; (yyval.mask).d = movemd[(yyvsp[0].reg)+8]; } -#line 3185 "m68kasm.c" - break; - - case 203: -#line 384 "m68kasm.y" - { int i,l=(yyvsp[-2].reg),h=(yyvsp[0].reg); if (l>h) { l=(yyvsp[0].reg); h=(yyvsp[-2].reg); } (yyval.mask).x = (yyval.mask).d = 0; - - for (i=l; i<=h; i++) { (yyval.mask).d |= movemx[i]; (yyval.mask).d |= movemd[i]; } } -#line 3192 "m68kasm.c" - break; - - case 204: -#line 386 "m68kasm.y" - { int i,l=(yyvsp[-2].reg),h=(yyvsp[0].reg); if (l>h) { l=(yyvsp[0].reg); h=(yyvsp[-2].reg); } (yyval.mask).x = (yyval.mask).d = 0; - - for (i=l; i<=h; i++) { (yyval.mask).x |= movemx[i+8]; (yyval.mask).d |= movemd[i+8]; } } -#line 3199 "m68kasm.c" - break; - - case 260: -#line 401 "m68kasm.y" - { (yyval.ea).ea = (yyvsp[0].reg); (yyval.ea).cnt = 0; } -#line 3205 "m68kasm.c" - break; - - case 261: -#line 403 "m68kasm.y" - { (yyval.ea).ea = 010 | (yyvsp[0].reg); (yyval.ea).cnt = 0; } -#line 3211 "m68kasm.c" - break; - - case 262: -#line 405 "m68kasm.y" - { (yyval.ea).ea = 020 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } -#line 3217 "m68kasm.c" - break; - - case 263: -#line 407 "m68kasm.y" - { (yyval.ea).ea = 030 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } -#line 3223 "m68kasm.c" - break; - - case 264: -#line 409 "m68kasm.y" - { (yyval.ea).ea = 040 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } -#line 3229 "m68kasm.c" - break; - - case 265: -#line 411 "m68kasm.y" - { (yyval.ea).ea = 050 | (yyvsp[-1].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-3].num); } -#line 3235 "m68kasm.c" - break; - - case 266: -#line 414 "m68kasm.y" - { (yyval.ea).ea = 060 | (yyvsp[-4].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = 0x8000 | ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } -#line 3241 "m68kasm.c" - break; - - case 267: -#line 416 "m68kasm.y" - { (yyval.ea).ea = 060 | (yyvsp[-4].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } -#line 3247 "m68kasm.c" - break; - - case 268: -#line 418 "m68kasm.y" - { if ((yyvsp[0].wl)==0) { (yyval.ea).ea = 070; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-2].num); } - - else { (yyval.ea).ea = 071; (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[-2].num) >> 16; (yyval.ea).arg[1] = (yyvsp[-2].num) & 0xffff; } } -#line 3254 "m68kasm.c" - break; - - case 269: -#line 420 "m68kasm.y" - { int tmp = ((yyvsp[-1].num)>>15) & 0x1ffff; if (tmp==0 || tmp==0x1ffff) { (yyval.ea).ea = 070; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-1].num); } - - else { (yyval.ea).ea = 070; (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[-1].num) >> 16; (yyval.ea).arg[1] = (yyvsp[-1].num) & 0xffff; } } -#line 3261 "m68kasm.c" - break; - - case 270: -#line 423 "m68kasm.y" - { (yyval.ea).ea = 072; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-3].num); } -#line 3267 "m68kasm.c" - break; - - case 271: -#line 424 "m68kasm.y" - { (yyval.ea).ea = 072; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num); } -#line 3273 "m68kasm.c" - break; - - case 272: -#line 427 "m68kasm.y" - { (yyval.ea).ea = 073; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = 0x8000 | ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } -#line 3279 "m68kasm.c" - break; - - case 273: -#line 429 "m68kasm.y" - { (yyval.ea).ea = 073; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } -#line 3285 "m68kasm.c" - break; - - case 274: -#line 431 "m68kasm.y" - { (yyval.ea).ea = 074; if (oplen==0) { (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num) & 0xff; } - - else if (oplen==1) { (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num) & 0xffff; } - - else { (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[0].num) >> 16; (yyval.ea).arg[1] = (yyvsp[0].num) & 0xffff; } } -#line 3293 "m68kasm.c" - break; - - case 275: -#line 435 "m68kasm.y" - { (yyval.ea).ea = 074; (yyval.ea).cnt = 0; } -#line 3299 "m68kasm.c" - break; - - case 276: -#line 436 "m68kasm.y" - { (yyval.ea).ea = 074; (yyval.ea).cnt = 1; } -#line 3305 "m68kasm.c" - break; - - -#line 3309 "m68kasm.c" - - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - yyerror (YY_("syntax error")); - } - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - - -#if !defined yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - - -/*-----------------------------------------------------. -| yyreturn -- parsing is finished, return the result. | -`-----------------------------------------------------*/ -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - - return yyresult; -} - -#line 437 "m68kasm.y" - - - - -static void yyerror(char* s) - -{ - - /* do not emit anything, but set error flag */ - - yyerrc = 1; - -} - - - -struct _optable { - - char* mnem; - - int token; - -}; - - - -static struct _optable ops[] = { - - { "abcd", ABCD }, { "add", ADD }, { "adda", ADDA }, { "addi", ADDI }, - - { "addq", ADDQ }, { "addx", ADDX }, { "and", AND }, { "andi", ANDI }, - - { "asl", ASL }, { "asr", ASR }, { "bcc", BCC }, { "bcs", BCS }, - - { "beq", BEQ }, { "bge", BGE }, { "bgt", BGT }, { "bhi", BHI }, - - { "ble", BLE }, { "bls", BLS }, { "blt", BLT }, { "bmi", BMI }, - - { "bne", BNE }, { "bpl", BPL }, { "bvc", BVC }, { "bvs", BVS }, - - { "bchg", BCHG }, { "bclr", BCLR }, { "bra", BRA }, { "bset", BSET }, - - { "bsr", BSR }, { "btst", BTST }, { "chk", CHK }, { "clr", CLR }, - - { "cmp", CMP }, { "cmpa", CMPA }, { "cmpi", CMPI }, { "cmpm", CMPM }, - - { "dbcc", DBCC }, { "dbcs", DBCS }, { "dbeq", DBEQ }, { "dbf", DBF }, - - { "dbge", DBGE }, { "dbgt", DBGT }, { "dbhi", DBHI }, { "dble", DBLE }, - - { "dbls", DBLS }, { "dblt", DBLT }, { "dbmi", DBMI }, { "dbne", DBNE }, - - { "dbpl", DBPL }, { "dbt", DBT }, { "dbvc", DBVC }, { "dbvs", DBVS }, - - { "divs", DIVS }, { "divu", DIVU }, { "eor", EOR }, { "eori", EORI }, - - { "exg", EXG }, { "ext", EXT }, { "illegal",ILLEGAL }, { "jmp", JMP }, - - { "jsr", JSR }, { "lea", LEA }, { "link", LINK }, { "lsl", LSL }, - - { "lsr", LSR }, { "move", MOVE }, { "movea", MOVEA }, { "movem", MOVEM }, - - { "movep", MOVEP }, { "moveq", MOVEQ }, { "muls", MULS }, { "mulu", MULU }, - - { "nbcd", NBCD }, { "neg", NEG }, { "negx", NEGX }, { "nop", NOP }, - - { "not", NOT }, { "or", OR }, { "ori", ORI }, { "pea", PEA }, - - { "reset", RESET }, { "rol", ROL }, { "ror", ROR }, { "roxl", ROXL }, - - { "roxr", ROXR }, { "rte", RTE }, { "rtr", RTR }, - - { "rts", RTS }, { "scc", SCC }, { "scs", SCS }, { "seq", SEQ }, - - { "sf", SF }, { "sge", SGE }, { "sgt", SGT }, { "shi", SHI }, - - { "sle", SLE }, { "sls", SLS }, { "slt", SLT }, { "smi", SMI }, - - { "sne", SNE }, { "spl", SPL }, { "st", ST }, { "svc", SVC }, - - { "svs", SVS }, { "stop", STOP }, { "sub", SUB }, { "suba", SUBA }, - - { "subi", SUBI }, { "subq", SUBQ }, { "subx", SUBX }, { "swap", SWAP }, - - { "tas", TAS }, { "trap", TRAP }, { "trapv", TRAPV }, { "tst", TST }, - - { "unlk", UNLK }, { "a0", A0 }, { "a1", A1 }, { "a2", A2 }, - - { "a3", A3 }, { "a4", A4 }, { "a5", A5 }, { "a6", A6 }, - - { "a7", A7 }, { "d0", D0 }, { "d1", D1 }, { "d2", D2 }, - - { "d3", D3 }, { "d4", D4 }, { "d5", D5 }, { "d6", D6 }, - - { "d7", D7 }, { "ccr", CCR }, { "sr", SR }, { "usp", USP }, - - { "pc", PC }, - - { 0, 0 } - -}; - - - -typedef struct _ophash { - - struct _ophash* next; - - struct _optable* op; - -} OPHASH; - -#define OPHASHSIZE 97 - - - -static OPHASH **ophash = 0; - - - -static int getophash(const char* s) - -{ - - int h = 0; - - while (*s++) h += (int)*s; - - return h % OPHASHSIZE; - -} - - - -static int oplookup(const char* s) - -{ - - int idx = getophash(s); - - OPHASH* oph = ophash[idx]; - - if (oph) { - - if (oph->next) { - - while (oph) { - - if (!strcmp(s,oph->op->mnem)) return oph->op->token; - - oph = oph->next; - - } - - return 0; - - } - - return oph->op->token; - - } - - return 0; - -} - - - -static void init_ophash() - -{ - - struct _optable* op = ops; - - OPHASH* oph; - - ophash = (OPHASH**)calloc(sizeof(OPHASH*),OPHASHSIZE); - - while (op->mnem) { - - int idx = getophash(op->mnem); - - oph = (OPHASH*)malloc(sizeof(OPHASH)); - - oph->next = ophash[idx]; - - oph->op = op; - - ophash[idx] = oph; - - op++; - - } - -} - - - -static char* yystream; - - - -static int yylex() - -{ - - char ident[30]; - - char *p = ident; - - char c = yystream[0]; - - - - while (c != 0 && (c=='\t' || c==' ')) { - - c = *++yystream; - - } - - if (c==0) return EOF; - - - - if (isalpha(c)) { - - while (isalnum(c) && (p-ident)<28) { - - *p++ = tolower(c); c = *++yystream; - - } - - *p = 0; - - if (p>ident) { return oplookup(ident); } - - return EOF; - - } else if (isdigit(c)) { - - *p++ = c; - - if (yystream[1]=='x' || yystream[1]=='X') { *p++ = 'x'; yystream++; } - - c = *++yystream; - - while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) { - - *p++ = c; c = *++yystream; - - } - - *p = 0; - - yylval.num = strtol(ident,0,0); - - return NUMBER; - - } else if (c=='$') { - - if (isdigit(yystream[1]) || isxdigit(yystream[1])) { - - c = *++yystream; - - while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) { - - *p++ = c; c = *++yystream; - - } - - *p = 0; - - yylval.num = strtol(ident,0,16); - - return NUMBER; - - } else return '$'; - - } else if (c == '-' && yystream[1] == '(') { - - yystream += 2; return PREDEC; - - } else if (c == ')' && yystream[1] == '+') { - - yystream += 2; return POSTINC; - - } else if (c == '.') { - - switch (yystream[1]) { - - case 'b': yystream += 2; return BSIZE; - - case 'w': yystream += 2; return WSIZE; - - case 'l': yystream += 2; return LSIZE; - - case 's': yystream += 2; return SSIZE; - - default: yystream++; return '.'; - - } - - } else { - - ++yystream; return c; - - } - -} - - - -static t_value *yyvalptr; - -static t_addr yyaddr; - - - -t_stat parse_sym_m68k(char* c, t_addr a, UNIT* u, t_value* val, int32 sw) - -{ - - char ch; - - - - if (!ophash) init_ophash(); - - - - yyvalptr = val; - - yyaddr = a; - - - - yystream = c; - - yyerrc = 0; - - - - ch = *yystream; - - while (ch != 0 && (ch=='\t' || ch==' ')) { - - ch = *++yystream; - - } - - if (ch == 0) return 0; - - - - if (sw & SWMASK('Y')) yydebug = 1 - yydebug; - - if ((sw & SWMASK('A')) || ch=='\'') { - - if ((ch = yystream[1])) { - - val[0] = (uint32)ch; - - return SCPE_OK; - - } else return SCPE_ARG; - - } - - if ((sw & SWMASK('C')) || ch=='"') { - - if ((ch = yystream[1])) { - - val[0] = ((uint32)ch << 8) | (uint32)yystream[1]; - - return SCPE_OK; - - } else return SCPE_ARG; - - } - - - - yyparse(); - -// sim_printf("rc=%d\n",yyrc); - - if (yyerrc) return SCPE_ARG; - - return yyrc; - -} - - - -static int _genop(t_value arg) - -{ - -// sim_printf("_genop(%x)@%x\n",arg,(int)yyvalptr); - - *yyvalptr = (arg >> 8) & 0xff; - - yyvalptr++; - - *yyvalptr = arg & 0xff; - - yyvalptr++; - - return -1; - -} - - - -static int _genea(struct _ea arg) - -{ - - int i; - - for (i=0; i. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 1 "m68kasm.y" + + +/* m68k_parse.c: line assembler for generic m68k_cpu + + + + Copyright (c) 2009-2010, Holger Veit + + + + Permission is hereby granted, free of charge, to any person obtaining a + + copy of this software and associated documentation files (the "Software"), + + to deal in the Software without restriction, including without limitation + + the rights to use, copy, modify, merge, publish, distribute, sublicense, + + and/or sell copies of the Software, and to permit persons to whom the + + Software is furnished to do so, subject to the following conditions: + + + + The above copyright notice and this permission notice shall be included in + + all copies or substantial portions of the Software. + + + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + + HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + + Except as contained in this notice, the name of Holger Veit et al shall not be + + used in advertising or otherwise to promote the sale, use or other dealings + + in this Software without prior written authorization from Holger Veit et al. + + + + 04-Oct-09 HV Initial version + + 20-Sep-14 PS Adapted for AltairZ80 + + + + use "bison m68kasm.y -o m68kasm.c" to create m68kasm.c + +*/ + + + +#include "sim_defs.h" + +#include + +#include + + + +struct _ea { + + int ea; + + int cnt; + + t_value arg[10]; + +}; + +struct _rea { + + int reg; + + struct _ea ea; + +}; + +struct _mask { + + int x; + + int d; + +}; + +struct _brop { + + int opc; + + int len; + +}; + + + +static int oplen; + +const static int movemx[] = { 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, + + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080 }; + +const static int movemd[] = { 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001, + + 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100 }; + +static int yyrc; + +static int yyerrc; + +static int yylex(void); + +static int _genop(t_value arg); + +static int _genea(struct _ea arg); + +static int _genbr(t_value arg,t_value,int); + +static void yyerror(char* s); + + + +#define YYDEBUG 1 + + +#line 141 "m68kasm.c" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + + +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + A0 = 258, /* A0 */ + A1 = 259, /* A1 */ + A2 = 260, /* A2 */ + A3 = 261, /* A3 */ + A4 = 262, /* A4 */ + A5 = 263, /* A5 */ + A6 = 264, /* A6 */ + A7 = 265, /* A7 */ + D0 = 266, /* D0 */ + D1 = 267, /* D1 */ + D2 = 268, /* D2 */ + D3 = 269, /* D3 */ + D4 = 270, /* D4 */ + D5 = 271, /* D5 */ + D6 = 272, /* D6 */ + D7 = 273, /* D7 */ + CCR = 274, /* CCR */ + SR = 275, /* SR */ + USP = 276, /* USP */ + PC = 277, /* PC */ + NUMBER = 278, /* NUMBER */ + ABCD = 279, /* ABCD */ + ADD = 280, /* ADD */ + ADDA = 281, /* ADDA */ + ADDI = 282, /* ADDI */ + ADDQ = 283, /* ADDQ */ + ADDX = 284, /* ADDX */ + AND = 285, /* AND */ + ANDI = 286, /* ANDI */ + OR = 287, /* OR */ + ORI = 288, /* ORI */ + SBCD = 289, /* SBCD */ + SUB = 290, /* SUB */ + SUBA = 291, /* SUBA */ + SUBI = 292, /* SUBI */ + SUBQ = 293, /* SUBQ */ + SUBX = 294, /* SUBX */ + ASL = 295, /* ASL */ + ASR = 296, /* ASR */ + LSL = 297, /* LSL */ + LSR = 298, /* LSR */ + ROL = 299, /* ROL */ + ROR = 300, /* ROR */ + ROXL = 301, /* ROXL */ + ROXR = 302, /* ROXR */ + BCC = 303, /* BCC */ + BCS = 304, /* BCS */ + BEQ = 305, /* BEQ */ + BGE = 306, /* BGE */ + BGT = 307, /* BGT */ + BHI = 308, /* BHI */ + BLE = 309, /* BLE */ + BLS = 310, /* BLS */ + BLT = 311, /* BLT */ + BMI = 312, /* BMI */ + BNE = 313, /* BNE */ + BPL = 314, /* BPL */ + BVC = 315, /* BVC */ + BVS = 316, /* BVS */ + BSR = 317, /* BSR */ + BRA = 318, /* BRA */ + BCLR = 319, /* BCLR */ + BSET = 320, /* BSET */ + BCHG = 321, /* BCHG */ + BTST = 322, /* BTST */ + CHK = 323, /* CHK */ + CMP = 324, /* CMP */ + CMPA = 325, /* CMPA */ + CMPI = 326, /* CMPI */ + CMPM = 327, /* CMPM */ + EOR = 328, /* EOR */ + EORI = 329, /* EORI */ + EXG = 330, /* EXG */ + EXT = 331, /* EXT */ + DIVU = 332, /* DIVU */ + DIVS = 333, /* DIVS */ + MULU = 334, /* MULU */ + MULS = 335, /* MULS */ + DBCC = 336, /* DBCC */ + DBCS = 337, /* DBCS */ + DBEQ = 338, /* DBEQ */ + DBF = 339, /* DBF */ + DBGE = 340, /* DBGE */ + DBGT = 341, /* DBGT */ + DBHI = 342, /* DBHI */ + DBLE = 343, /* DBLE */ + DBLS = 344, /* DBLS */ + DBLT = 345, /* DBLT */ + DBMI = 346, /* DBMI */ + DBNE = 347, /* DBNE */ + DBPL = 348, /* DBPL */ + DBT = 349, /* DBT */ + DBVC = 350, /* DBVC */ + DBVS = 351, /* DBVS */ + SCC = 352, /* SCC */ + SCS = 353, /* SCS */ + SEQ = 354, /* SEQ */ + SF = 355, /* SF */ + SGE = 356, /* SGE */ + SGT = 357, /* SGT */ + SHI = 358, /* SHI */ + SLE = 359, /* SLE */ + SLS = 360, /* SLS */ + SLT = 361, /* SLT */ + SMI = 362, /* SMI */ + SNE = 363, /* SNE */ + SPL = 364, /* SPL */ + ST = 365, /* ST */ + SVC = 366, /* SVC */ + SVS = 367, /* SVS */ + ILLEGAL = 368, /* ILLEGAL */ + NOP = 369, /* NOP */ + RESET = 370, /* RESET */ + RTE = 371, /* RTE */ + RTR = 372, /* RTR */ + RTS = 373, /* RTS */ + TRAPV = 374, /* TRAPV */ + JMP = 375, /* JMP */ + JSR = 376, /* JSR */ + LEA = 377, /* LEA */ + LINK = 378, /* LINK */ + MOVE = 379, /* MOVE */ + MOVEA = 380, /* MOVEA */ + MOVEM = 381, /* MOVEM */ + MOVEP = 382, /* MOVEP */ + MOVEQ = 383, /* MOVEQ */ + CLR = 384, /* CLR */ + NEG = 385, /* NEG */ + NEGX = 386, /* NEGX */ + NBCD = 387, /* NBCD */ + NOT = 388, /* NOT */ + PEA = 389, /* PEA */ + STOP = 390, /* STOP */ + TAS = 391, /* TAS */ + SWAP = 392, /* SWAP */ + TRAP = 393, /* TRAP */ + TST = 394, /* TST */ + UNLK = 395, /* UNLK */ + PREDEC = 396, /* PREDEC */ + POSTINC = 397, /* POSTINC */ + BSIZE = 398, /* BSIZE */ + WSIZE = 399, /* WSIZE */ + LSIZE = 400, /* LSIZE */ + SSIZE = 401 /* SSIZE */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 71 "m68kasm.y" + + + int rc; + + int reg; + + int wl; + + int opc; + + struct _ea ea; + + t_value num; + + struct _rea rea; + + struct _mask mask; + + struct _brop brop; + + +#line 346 "m68kasm.c" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + + +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_A0 = 3, /* A0 */ + YYSYMBOL_A1 = 4, /* A1 */ + YYSYMBOL_A2 = 5, /* A2 */ + YYSYMBOL_A3 = 6, /* A3 */ + YYSYMBOL_A4 = 7, /* A4 */ + YYSYMBOL_A5 = 8, /* A5 */ + YYSYMBOL_A6 = 9, /* A6 */ + YYSYMBOL_A7 = 10, /* A7 */ + YYSYMBOL_D0 = 11, /* D0 */ + YYSYMBOL_D1 = 12, /* D1 */ + YYSYMBOL_D2 = 13, /* D2 */ + YYSYMBOL_D3 = 14, /* D3 */ + YYSYMBOL_D4 = 15, /* D4 */ + YYSYMBOL_D5 = 16, /* D5 */ + YYSYMBOL_D6 = 17, /* D6 */ + YYSYMBOL_D7 = 18, /* D7 */ + YYSYMBOL_CCR = 19, /* CCR */ + YYSYMBOL_SR = 20, /* SR */ + YYSYMBOL_USP = 21, /* USP */ + YYSYMBOL_PC = 22, /* PC */ + YYSYMBOL_NUMBER = 23, /* NUMBER */ + YYSYMBOL_ABCD = 24, /* ABCD */ + YYSYMBOL_ADD = 25, /* ADD */ + YYSYMBOL_ADDA = 26, /* ADDA */ + YYSYMBOL_ADDI = 27, /* ADDI */ + YYSYMBOL_ADDQ = 28, /* ADDQ */ + YYSYMBOL_ADDX = 29, /* ADDX */ + YYSYMBOL_AND = 30, /* AND */ + YYSYMBOL_ANDI = 31, /* ANDI */ + YYSYMBOL_OR = 32, /* OR */ + YYSYMBOL_ORI = 33, /* ORI */ + YYSYMBOL_SBCD = 34, /* SBCD */ + YYSYMBOL_SUB = 35, /* SUB */ + YYSYMBOL_SUBA = 36, /* SUBA */ + YYSYMBOL_SUBI = 37, /* SUBI */ + YYSYMBOL_SUBQ = 38, /* SUBQ */ + YYSYMBOL_SUBX = 39, /* SUBX */ + YYSYMBOL_ASL = 40, /* ASL */ + YYSYMBOL_ASR = 41, /* ASR */ + YYSYMBOL_LSL = 42, /* LSL */ + YYSYMBOL_LSR = 43, /* LSR */ + YYSYMBOL_ROL = 44, /* ROL */ + YYSYMBOL_ROR = 45, /* ROR */ + YYSYMBOL_ROXL = 46, /* ROXL */ + YYSYMBOL_ROXR = 47, /* ROXR */ + YYSYMBOL_BCC = 48, /* BCC */ + YYSYMBOL_BCS = 49, /* BCS */ + YYSYMBOL_BEQ = 50, /* BEQ */ + YYSYMBOL_BGE = 51, /* BGE */ + YYSYMBOL_BGT = 52, /* BGT */ + YYSYMBOL_BHI = 53, /* BHI */ + YYSYMBOL_BLE = 54, /* BLE */ + YYSYMBOL_BLS = 55, /* BLS */ + YYSYMBOL_BLT = 56, /* BLT */ + YYSYMBOL_BMI = 57, /* BMI */ + YYSYMBOL_BNE = 58, /* BNE */ + YYSYMBOL_BPL = 59, /* BPL */ + YYSYMBOL_BVC = 60, /* BVC */ + YYSYMBOL_BVS = 61, /* BVS */ + YYSYMBOL_BSR = 62, /* BSR */ + YYSYMBOL_BRA = 63, /* BRA */ + YYSYMBOL_BCLR = 64, /* BCLR */ + YYSYMBOL_BSET = 65, /* BSET */ + YYSYMBOL_BCHG = 66, /* BCHG */ + YYSYMBOL_BTST = 67, /* BTST */ + YYSYMBOL_CHK = 68, /* CHK */ + YYSYMBOL_CMP = 69, /* CMP */ + YYSYMBOL_CMPA = 70, /* CMPA */ + YYSYMBOL_CMPI = 71, /* CMPI */ + YYSYMBOL_CMPM = 72, /* CMPM */ + YYSYMBOL_EOR = 73, /* EOR */ + YYSYMBOL_EORI = 74, /* EORI */ + YYSYMBOL_EXG = 75, /* EXG */ + YYSYMBOL_EXT = 76, /* EXT */ + YYSYMBOL_DIVU = 77, /* DIVU */ + YYSYMBOL_DIVS = 78, /* DIVS */ + YYSYMBOL_MULU = 79, /* MULU */ + YYSYMBOL_MULS = 80, /* MULS */ + YYSYMBOL_DBCC = 81, /* DBCC */ + YYSYMBOL_DBCS = 82, /* DBCS */ + YYSYMBOL_DBEQ = 83, /* DBEQ */ + YYSYMBOL_DBF = 84, /* DBF */ + YYSYMBOL_DBGE = 85, /* DBGE */ + YYSYMBOL_DBGT = 86, /* DBGT */ + YYSYMBOL_DBHI = 87, /* DBHI */ + YYSYMBOL_DBLE = 88, /* DBLE */ + YYSYMBOL_DBLS = 89, /* DBLS */ + YYSYMBOL_DBLT = 90, /* DBLT */ + YYSYMBOL_DBMI = 91, /* DBMI */ + YYSYMBOL_DBNE = 92, /* DBNE */ + YYSYMBOL_DBPL = 93, /* DBPL */ + YYSYMBOL_DBT = 94, /* DBT */ + YYSYMBOL_DBVC = 95, /* DBVC */ + YYSYMBOL_DBVS = 96, /* DBVS */ + YYSYMBOL_SCC = 97, /* SCC */ + YYSYMBOL_SCS = 98, /* SCS */ + YYSYMBOL_SEQ = 99, /* SEQ */ + YYSYMBOL_SF = 100, /* SF */ + YYSYMBOL_SGE = 101, /* SGE */ + YYSYMBOL_SGT = 102, /* SGT */ + YYSYMBOL_SHI = 103, /* SHI */ + YYSYMBOL_SLE = 104, /* SLE */ + YYSYMBOL_SLS = 105, /* SLS */ + YYSYMBOL_SLT = 106, /* SLT */ + YYSYMBOL_SMI = 107, /* SMI */ + YYSYMBOL_SNE = 108, /* SNE */ + YYSYMBOL_SPL = 109, /* SPL */ + YYSYMBOL_ST = 110, /* ST */ + YYSYMBOL_SVC = 111, /* SVC */ + YYSYMBOL_SVS = 112, /* SVS */ + YYSYMBOL_ILLEGAL = 113, /* ILLEGAL */ + YYSYMBOL_NOP = 114, /* NOP */ + YYSYMBOL_RESET = 115, /* RESET */ + YYSYMBOL_RTE = 116, /* RTE */ + YYSYMBOL_RTR = 117, /* RTR */ + YYSYMBOL_RTS = 118, /* RTS */ + YYSYMBOL_TRAPV = 119, /* TRAPV */ + YYSYMBOL_JMP = 120, /* JMP */ + YYSYMBOL_JSR = 121, /* JSR */ + YYSYMBOL_LEA = 122, /* LEA */ + YYSYMBOL_LINK = 123, /* LINK */ + YYSYMBOL_MOVE = 124, /* MOVE */ + YYSYMBOL_MOVEA = 125, /* MOVEA */ + YYSYMBOL_MOVEM = 126, /* MOVEM */ + YYSYMBOL_MOVEP = 127, /* MOVEP */ + YYSYMBOL_MOVEQ = 128, /* MOVEQ */ + YYSYMBOL_CLR = 129, /* CLR */ + YYSYMBOL_NEG = 130, /* NEG */ + YYSYMBOL_NEGX = 131, /* NEGX */ + YYSYMBOL_NBCD = 132, /* NBCD */ + YYSYMBOL_NOT = 133, /* NOT */ + YYSYMBOL_PEA = 134, /* PEA */ + YYSYMBOL_STOP = 135, /* STOP */ + YYSYMBOL_TAS = 136, /* TAS */ + YYSYMBOL_SWAP = 137, /* SWAP */ + YYSYMBOL_TRAP = 138, /* TRAP */ + YYSYMBOL_TST = 139, /* TST */ + YYSYMBOL_UNLK = 140, /* UNLK */ + YYSYMBOL_PREDEC = 141, /* PREDEC */ + YYSYMBOL_POSTINC = 142, /* POSTINC */ + YYSYMBOL_BSIZE = 143, /* BSIZE */ + YYSYMBOL_WSIZE = 144, /* WSIZE */ + YYSYMBOL_LSIZE = 145, /* LSIZE */ + YYSYMBOL_SSIZE = 146, /* SSIZE */ + YYSYMBOL_147_ = 147, /* '#' */ + YYSYMBOL_148_ = 148, /* ',' */ + YYSYMBOL_149_ = 149, /* '/' */ + YYSYMBOL_150_ = 150, /* '-' */ + YYSYMBOL_151_ = 151, /* '(' */ + YYSYMBOL_152_ = 152, /* ')' */ + YYSYMBOL_YYACCEPT = 153, /* $accept */ + YYSYMBOL_stmt = 154, /* stmt */ + YYSYMBOL_arop = 155, /* arop */ + YYSYMBOL_bcdop = 156, /* bcdop */ + YYSYMBOL_dualop = 157, /* dualop */ + YYSYMBOL_immop = 158, /* immop */ + YYSYMBOL_immop2 = 159, /* immop2 */ + YYSYMBOL_qop = 160, /* qop */ + YYSYMBOL_shftop = 161, /* shftop */ + YYSYMBOL_brop = 162, /* brop */ + YYSYMBOL_btop = 163, /* btop */ + YYSYMBOL_monop = 164, /* monop */ + YYSYMBOL_mdop = 165, /* mdop */ + YYSYMBOL_dbop = 166, /* dbop */ + YYSYMBOL_direct = 167, /* direct */ + YYSYMBOL_jop = 168, /* jop */ + YYSYMBOL_shftarg = 169, /* shftarg */ + YYSYMBOL_bcdarg = 170, /* bcdarg */ + YYSYMBOL_dualarg = 171, /* dualarg */ + YYSYMBOL_areg = 172, /* areg */ + YYSYMBOL_dreg = 173, /* dreg */ + YYSYMBOL_szs = 174, /* szs */ + YYSYMBOL_szwl = 175, /* szwl */ + YYSYMBOL_szbwl = 176, /* szbwl */ + YYSYMBOL_szmv = 177, /* szmv */ + YYSYMBOL_szm = 178, /* szm */ + YYSYMBOL_reglist = 179, /* reglist */ + YYSYMBOL_regs = 180, /* regs */ + YYSYMBOL_eama = 181, /* eama */ + YYSYMBOL_eaa = 182, /* eaa */ + YYSYMBOL_ead = 183, /* ead */ + YYSYMBOL_eaall = 184, /* eaall */ + YYSYMBOL_eada = 185, /* eada */ + YYSYMBOL_eadas = 186, /* eadas */ + YYSYMBOL_eac = 187, /* eac */ + YYSYMBOL_eacai = 188, /* eacai */ + YYSYMBOL_eacad = 189, /* eacad */ + YYSYMBOL_ea0 = 190, /* ea0 */ + YYSYMBOL_ea1 = 191, /* ea1 */ + YYSYMBOL_ea2 = 192, /* ea2 */ + YYSYMBOL_ea3 = 193, /* ea3 */ + YYSYMBOL_ea4 = 194, /* ea4 */ + YYSYMBOL_ea5 = 195, /* ea5 */ + YYSYMBOL_ea6 = 196, /* ea6 */ + YYSYMBOL_ea70 = 197, /* ea70 */ + YYSYMBOL_ea72 = 198, /* ea72 */ + YYSYMBOL_ea73 = 199, /* ea73 */ + YYSYMBOL_ea74 = 200, /* ea74 */ + YYSYMBOL_easr = 201 /* easr */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if !defined yyoverflow + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* !defined yyoverflow */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 266 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 928 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 153 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 49 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 276 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 462 + +#define YYMAXUTOK 401 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 147, 2, 2, 2, 2, + 151, 152, 2, 2, 148, 150, 2, 149, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146 +}; + +#if YYDEBUG + /* YYRLINEYYN -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 112, 112, 113, 114, 116, 117, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 160, 161, 164, 165, 166, 167, 171, + 172, 173, 174, 178, 179, 180, 184, 185, 186, 190, + 191, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 249, + 250, 251, 252, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 282, 283, 284, 285, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 308, 309, 310, 311, + 312, 313, 314, 318, 319, 320, 323, 324, 327, 328, + 331, 334, 337, 338, 339, 340, 341, 342, 343, 344, + 347, 348, 349, 350, 351, 352, 353, 354, 357, 360, + 361, 364, 365, 366, 369, 370, 371, 374, 375, 378, + 379, 382, 383, 384, 386, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, + 391, 391, 391, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 393, 393, 394, 394, 394, 394, 394, + 394, 394, 395, 395, 396, 396, 396, 396, 396, 396, + 397, 397, 397, 397, 397, 398, 398, 398, 398, 398, + 401, 403, 405, 407, 409, 411, 413, 415, 418, 420, + 423, 424, 426, 428, 431, 435, 436 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "\"end of file\"", "error", "\"invalid token\"", "A0", "A1", "A2", "A3", + "A4", "A5", "A6", "A7", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "CCR", "SR", "USP", "PC", "NUMBER", "ABCD", "ADD", "ADDA", "ADDI", + "ADDQ", "ADDX", "AND", "ANDI", "OR", "ORI", "SBCD", "SUB", "SUBA", + "SUBI", "SUBQ", "SUBX", "ASL", "ASR", "LSL", "LSR", "ROL", "ROR", "ROXL", + "ROXR", "BCC", "BCS", "BEQ", "BGE", "BGT", "BHI", "BLE", "BLS", "BLT", + "BMI", "BNE", "BPL", "BVC", "BVS", "BSR", "BRA", "BCLR", "BSET", "BCHG", + "BTST", "CHK", "CMP", "CMPA", "CMPI", "CMPM", "EOR", "EORI", "EXG", + "EXT", "DIVU", "DIVS", "MULU", "MULS", "DBCC", "DBCS", "DBEQ", "DBF", + "DBGE", "DBGT", "DBHI", "DBLE", "DBLS", "DBLT", "DBMI", "DBNE", "DBPL", + "DBT", "DBVC", "DBVS", "SCC", "SCS", "SEQ", "SF", "SGE", "SGT", "SHI", + "SLE", "SLS", "SLT", "SMI", "SNE", "SPL", "ST", "SVC", "SVS", "ILLEGAL", + "NOP", "RESET", "RTE", "RTR", "RTS", "TRAPV", "JMP", "JSR", "LEA", + "LINK", "MOVE", "MOVEA", "MOVEM", "MOVEP", "MOVEQ", "CLR", "NEG", "NEGX", + "NBCD", "NOT", "PEA", "STOP", "TAS", "SWAP", "TRAP", "TST", "UNLK", + "PREDEC", "POSTINC", "BSIZE", "WSIZE", "LSIZE", "SSIZE", "'#'", "','", + "'/'", "'-'", "'('", "')'", "$accept", "stmt", "arop", "bcdop", "dualop", + "immop", "immop2", "qop", "shftop", "brop", "btop", "monop", "mdop", + "dbop", "direct", "jop", "shftarg", "bcdarg", "dualarg", "areg", "dreg", + "szs", "szwl", "szbwl", "szmv", "szm", "reglist", "regs", "eama", "eaa", + "ead", "eaall", "eada", "eadas", "eac", "eacai", "eacad", "ea0", "ea1", + "ea2", "ea3", "ea4", "ea5", "ea6", "ea70", "ea72", "ea73", "ea74", + "easr", YY_NULLPTR +}; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif + +#ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_int16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 35, 44, 47, + 45, 40, 41 +}; +#endif + +#define YYPACT_NINF (-343) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-1) + +#define yytable_value_is_error(Yyn) \ + 0 + + /* YYPACTSTATE-NUM -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 675, -343, -126, -343, -126, -126, -126, -126, -126, -126, + -126, -343, -126, -343, -126, -126, -126, 456, 456, 456, + 456, 456, 456, 456, 456, -139, -139, -139, -139, -139, + -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, + -139, -343, -343, -343, -343, 477, -126, -107, -126, -126, + -126, -126, 626, -107, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -20, + 642, 141, -105, -107, -107, -137, -126, -126, -126, -343, + -126, -343, -82, -343, 646, -80, -126, 642, 72, -107, + 557, 18, -72, -65, -50, -343, 78, 31, 76, 477, + 646, -343, -20, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, 642, 85, 203, + -343, 236, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, 236, -343, 236, -343, 236, -343, 236, + -343, 236, -343, 236, -343, 236, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -37, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, 18, -343, -343, 18, -343, -42, + 646, -343, -36, -35, 646, 203, -32, -343, -343, -343, + -343, -343, -343, -29, -27, -19, -343, -343, -343, -13, + 18, -343, -343, 76, 538, 41, 92, -343, -343, -343, + -343, 100, -343, 113, -343, -343, -343, 18, -343, -10, + -9, -343, -8, -7, 119, 120, 129, -343, 131, 8, + 581, -343, -343, -343, -343, -343, -343, -343, -343, 15, + 16, -343, 19, -343, -143, -138, 149, -343, 25, -343, + -343, -343, -343, -343, -343, -343, 646, -343, 27, -343, + 29, 642, 32, 33, 626, 626, -343, 22, 642, 37, + 76, 642, 155, 39, 40, 35, 36, 43, 45, 47, + -343, -343, -343, -343, -343, 166, 51, 54, 57, -343, + -343, 66, 646, 77, 515, 646, 71, 73, 74, 83, + 76, -84, 646, 197, -343, 605, -107, -343, -343, 84, + 646, -343, 646, 642, 93, -42, 76, -343, -343, -343, + -343, -343, 211, -343, -343, -343, 546, 642, 642, 646, + -135, 626, 626, 90, 88, 646, 646, 642, -343, -343, + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + 76, 546, 515, 76, -343, 642, -343, -343, -68, -67, + -343, 646, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, 581, -343, -343, -343, + -343, -343, -343, -343, -343, 642, -343, -343, -343, -343, + -343, -343, -343, -343, 626, -343, 626, -343, -343, 91, + -107, -107, -107, -107, 104, 106, 107, 109, -343, -343, + -343, -343 +}; + + /* YYDEFACTSTATE-NUM -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int16 yydefact[] = +{ + 0, 45, 0, 43, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 44, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 110, 111, 109, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 137, 136, 139, 138, 140, 141, + 142, 154, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 155, 152, 153, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, + 0, 165, 0, 134, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 24, 0, 191, 192, 193, 49, 53, 59, 46, + 50, 56, 51, 58, 52, 55, 60, 48, 172, 173, + 174, 175, 176, 177, 178, 179, 271, 0, 0, 0, + 261, 0, 61, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 0, 63, 0, 65, 0, 67, 0, + 69, 0, 71, 0, 73, 0, 75, 188, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 180, 181, 182, 183, 184, 185, + 186, 187, 260, 0, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 0, 189, 190, 0, 54, 0, + 0, 57, 0, 0, 0, 0, 0, 244, 245, 246, + 247, 248, 249, 0, 0, 0, 194, 195, 196, 0, + 0, 197, 198, 0, 0, 0, 0, 113, 115, 116, + 117, 0, 40, 0, 135, 42, 1, 0, 2, 0, + 0, 3, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 12, 235, 236, 237, 238, 239, 240, 241, 0, + 0, 25, 0, 274, 0, 0, 0, 62, 0, 64, + 66, 68, 70, 72, 74, 76, 0, 234, 0, 233, + 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 201, 202, 0, 199, 0, + 250, 251, 252, 253, 254, 0, 0, 0, 0, 38, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 264, 0, 269, 263, 262, 0, + 0, 11, 0, 0, 0, 0, 0, 20, 21, 22, + 19, 26, 0, 29, 30, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 168, 169, + 170, 215, 216, 217, 218, 219, 220, 221, 222, 171, + 0, 0, 0, 0, 9, 0, 14, 17, 0, 0, + 268, 0, 166, 13, 15, 16, 18, 27, 275, 276, + 242, 28, 243, 32, 203, 204, 0, 33, 255, 256, + 257, 258, 259, 200, 34, 0, 35, 36, 37, 39, + 4, 6, 5, 10, 0, 270, 0, 265, 167, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 273, 272, + 267, 266 +}; + + /* YYPGOTONTERM-NUM. */ +static const yytype_int16 yypgoto[] = +{ + -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + -343, -343, -343, -343, -343, -343, 248, -343, -343, -39, + -51, 811, -53, 812, -343, -343, -276, -343, 559, -162, + 115, -150, -120, -159, 128, -343, -343, -34, -342, -25, + 108, 137, -30, 38, 69, 26, 28, -33, -343 +}; + + /* YYDEFGOTONTERM-NUM. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 297, 268, 271, 160, + 212, 188, 227, 136, 250, 253, 327, 328, 307, 390, + 213, 308, 420, 421, 236, 329, 427, 282, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 422 +}; + + /* YYTABLEYYPACT[STATE-NUM] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 234, 233, 392, 156, 357, 355, 157, 187, 281, 356, + 256, 214, 223, 232, 358, 218, 426, 133, 134, 135, + 215, 148, 149, 150, 151, 152, 153, 154, 155, 204, + 205, 206, 207, 208, 209, 210, 211, 225, 226, 251, + 252, 156, 204, 205, 206, 207, 208, 209, 210, 211, + 254, 255, 204, 205, 206, 207, 208, 209, 210, 211, + 392, 243, 249, 262, 405, 261, 267, 263, 356, 238, + 272, 221, 266, 222, 237, 274, 279, 310, 265, 290, + 444, 446, 275, 219, 445, 447, 269, 204, 205, 206, + 207, 208, 209, 210, 211, 214, 223, 276, 286, 218, + 323, 277, 238, 283, 215, 433, 434, 237, 293, 311, + 298, 306, 314, 315, 220, 338, 318, 341, 292, 319, + 295, 320, 298, 339, 298, 241, 298, 242, 298, 321, + 298, 235, 298, 324, 298, 322, 340, 239, 342, 343, + 344, 345, 346, 347, 148, 149, 150, 151, 152, 153, + 154, 155, 348, 216, 349, 221, 350, 222, 241, 157, + 242, 244, 245, 352, 353, 158, 287, 219, 240, 159, + 239, 354, 359, 360, 358, 362, 375, 363, 278, 313, + 365, 366, 217, 316, 372, 378, 379, 376, 377, 383, + 309, 380, 335, 309, 381, 382, 317, 288, 220, 384, + 373, 240, 385, 326, 336, 386, 148, 149, 150, 151, + 152, 153, 154, 155, 387, 325, 309, 157, 157, 400, + 407, 401, 402, 286, 332, 337, 294, 280, 283, 330, + 404, 403, 411, 309, 417, 357, 284, 216, 435, 335, + 442, 295, 441, 447, 289, 0, 416, 204, 205, 206, + 207, 208, 209, 210, 211, 361, 458, 270, 459, 460, + 291, 461, 0, 368, 370, 285, 217, 0, 0, 0, + 0, 0, 364, 0, 0, 367, 369, 0, 0, 371, + 440, 0, 374, 443, 246, 247, 248, 0, 0, 0, + 286, 287, 333, 0, 399, 283, 0, 0, 0, 0, + 0, 406, 0, 410, 0, 0, 0, 0, 388, 412, + 391, 413, 0, 0, 396, 0, 409, 0, 0, 393, + 286, 0, 288, 334, 414, 283, 0, 0, 425, 0, + 326, 326, 0, 0, 437, 438, 286, 312, 423, 424, + 0, 283, 325, 325, 0, 0, 286, 0, 439, 0, + 430, 283, 0, 0, 436, 428, 0, 0, 287, 0, + 448, 284, 331, 0, 0, 0, 409, 0, 391, 0, + 286, 286, 396, 286, 0, 283, 283, 393, 283, 0, + 0, 0, 397, 296, 0, 0, 0, 317, 287, 288, + 285, 0, 0, 451, 0, 453, 449, 454, 455, 456, + 457, 0, 0, 0, 287, 450, 0, 452, 0, 0, + 0, 0, 0, 398, 287, 0, 0, 0, 431, 288, + 0, 299, 0, 300, 0, 301, 0, 302, 284, 303, + 0, 304, 0, 305, 0, 288, 0, 0, 287, 287, + 397, 287, 0, 0, 0, 288, 0, 0, 0, 432, + 0, 0, 394, 0, 0, 0, 0, 285, 284, 148, + 149, 150, 151, 152, 153, 154, 155, 0, 0, 288, + 288, 398, 288, 415, 284, 0, 0, 0, 0, 156, + 389, 395, 0, 0, 284, 0, 0, 285, 204, 205, + 206, 207, 208, 209, 210, 211, 0, 0, 0, 0, + 156, 0, 0, 285, 0, 0, 0, 0, 284, 284, + 394, 284, 0, 285, 0, 0, 0, 429, 148, 149, + 150, 151, 152, 153, 154, 155, 204, 205, 206, 207, + 208, 209, 210, 211, 0, 0, 0, 285, 285, 395, + 285, 148, 149, 150, 151, 152, 153, 154, 155, 204, + 205, 206, 207, 208, 209, 210, 211, 204, 205, 206, + 207, 208, 209, 210, 211, 418, 419, 0, 204, 205, + 206, 207, 208, 209, 210, 211, 162, 174, 176, 178, + 180, 182, 184, 186, 148, 149, 150, 151, 152, 153, + 154, 155, 0, 0, 0, 0, 0, 157, 0, 133, + 134, 135, 0, 158, 351, 0, 0, 159, 148, 149, + 150, 151, 152, 153, 154, 155, 0, 0, 157, 0, + 0, 0, 0, 0, 158, 0, 0, 408, 159, 148, + 149, 150, 151, 152, 153, 154, 155, 204, 205, 206, + 207, 208, 209, 210, 211, 148, 149, 150, 151, 152, + 153, 154, 155, 0, 0, 0, 157, 204, 205, 206, + 207, 208, 209, 210, 211, 0, 280, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 0, 0, 157, 0, 280, + 0, 0, 0, 0, 0, 0, 0, 280, 157, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 137, 138, 139, 140, + 141, 142, 143, 0, 144, 0, 145, 146, 147, 161, + 173, 175, 177, 179, 181, 183, 185, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 0, 0, 0, 0, 0, 0, 224, 0, + 228, 229, 230, 231, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 257, 258, + 259, 0, 260, 0, 0, 0, 0, 0, 264 +}; + +static const yytype_int16 yycheck[] = +{ + 53, 52, 344, 23, 142, 148, 141, 146, 128, 152, + 147, 45, 45, 52, 152, 45, 151, 143, 144, 145, + 45, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 144, 145, 144, + 145, 23, 11, 12, 13, 14, 15, 16, 17, 18, + 103, 104, 11, 12, 13, 14, 15, 16, 17, 18, + 402, 100, 101, 114, 148, 147, 119, 147, 152, 99, + 121, 45, 0, 45, 99, 147, 127, 227, 117, 130, + 148, 148, 147, 45, 152, 152, 120, 11, 12, 13, + 14, 15, 16, 17, 18, 129, 129, 147, 128, 129, + 250, 23, 132, 128, 129, 381, 382, 132, 23, 151, + 161, 148, 148, 148, 45, 23, 148, 267, 157, 148, + 159, 148, 173, 23, 175, 99, 177, 99, 179, 148, + 181, 151, 183, 253, 185, 148, 23, 99, 148, 148, + 148, 148, 23, 23, 3, 4, 5, 6, 7, 8, + 9, 10, 23, 45, 23, 129, 148, 129, 132, 141, + 132, 20, 21, 148, 148, 147, 128, 129, 99, 151, + 132, 152, 23, 148, 152, 148, 21, 148, 147, 230, + 148, 148, 45, 234, 147, 150, 150, 148, 148, 23, + 224, 148, 151, 227, 149, 148, 235, 128, 129, 148, + 320, 132, 148, 254, 255, 148, 3, 4, 5, 6, + 7, 8, 9, 10, 148, 254, 250, 141, 141, 148, + 23, 148, 148, 253, 254, 255, 23, 151, 253, 254, + 350, 148, 148, 267, 23, 142, 128, 129, 148, 151, + 402, 280, 401, 152, 129, -1, 366, 11, 12, 13, + 14, 15, 16, 17, 18, 306, 152, 120, 152, 152, + 132, 152, -1, 314, 315, 128, 129, -1, -1, -1, + -1, -1, 311, -1, -1, 314, 315, -1, -1, 318, + 400, -1, 321, 403, 143, 144, 145, -1, -1, -1, + 320, 253, 254, -1, 345, 320, -1, -1, -1, -1, + -1, 352, -1, 356, -1, -1, -1, -1, 342, 360, + 344, 362, -1, -1, 344, -1, 355, -1, -1, 344, + 350, -1, 253, 254, 363, 350, -1, -1, 379, -1, + 381, 382, -1, -1, 385, 386, 366, 229, 377, 378, + -1, 366, 381, 382, -1, -1, 376, -1, 387, -1, + 380, 376, -1, -1, 384, 380, -1, -1, 320, -1, + 411, 253, 254, -1, -1, -1, 405, -1, 402, -1, + 400, 401, 402, 403, -1, 400, 401, 402, 403, -1, + -1, -1, 344, 147, -1, -1, -1, 426, 350, 320, + 253, -1, -1, 444, -1, 446, 435, 450, 451, 452, + 453, -1, -1, -1, 366, 444, -1, 446, -1, -1, + -1, -1, -1, 344, 376, -1, -1, -1, 380, 350, + -1, 173, -1, 175, -1, 177, -1, 179, 320, 181, + -1, 183, -1, 185, -1, 366, -1, -1, 400, 401, + 402, 403, -1, -1, -1, 376, -1, -1, -1, 380, + -1, -1, 344, -1, -1, -1, -1, 320, 350, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, 400, + 401, 402, 403, 365, 366, -1, -1, -1, -1, 23, + 343, 344, -1, -1, 376, -1, -1, 350, 11, 12, + 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, + 23, -1, -1, 366, -1, -1, -1, -1, 400, 401, + 402, 403, -1, 376, -1, -1, -1, 380, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, -1, -1, -1, 400, 401, 402, + 403, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, -1, 11, 12, + 13, 14, 15, 16, 17, 18, 17, 18, 19, 20, + 21, 22, 23, 24, 3, 4, 5, 6, 7, 8, + 9, 10, -1, -1, -1, -1, -1, 141, -1, 143, + 144, 145, -1, 147, 23, -1, -1, 151, 3, 4, + 5, 6, 7, 8, 9, 10, -1, -1, 141, -1, + -1, -1, -1, -1, 147, -1, -1, 22, 151, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 3, 4, 5, 6, 7, + 8, 9, 10, -1, -1, -1, 141, 11, 12, 13, + 14, 15, 16, 17, 18, -1, 151, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 121, -1, -1, -1, -1, -1, -1, 141, -1, 151, + -1, -1, -1, -1, -1, -1, -1, 151, 141, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 4, 5, 6, 7, + 8, 9, 10, -1, 12, -1, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, -1, -1, -1, -1, -1, -1, 46, -1, + 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 106, 107, + 108, -1, 110, -1, -1, -1, -1, -1, 116 +}; + + /* YYSTOSSTATE-NUM -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 143, 144, 145, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 3, 4, + 5, 6, 7, 8, 9, 10, 23, 141, 147, 151, + 172, 176, 181, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 176, 181, 176, 181, 176, 181, 176, + 181, 176, 181, 176, 181, 176, 181, 146, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 11, 12, 13, 14, 15, 16, + 17, 18, 173, 183, 190, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 176, 144, 145, 175, 176, 176, + 176, 176, 172, 173, 175, 151, 187, 192, 195, 196, + 197, 198, 199, 172, 20, 21, 143, 144, 145, 172, + 177, 144, 145, 178, 175, 175, 147, 176, 176, 176, + 176, 147, 173, 147, 176, 172, 0, 175, 170, 190, + 194, 171, 173, 181, 147, 147, 147, 23, 147, 173, + 151, 185, 190, 192, 193, 194, 195, 196, 197, 183, + 173, 187, 172, 23, 23, 172, 147, 169, 173, 169, + 169, 169, 169, 169, 169, 169, 148, 181, 184, 190, + 184, 151, 193, 173, 148, 148, 173, 172, 148, 148, + 148, 148, 148, 184, 185, 172, 173, 179, 180, 188, + 192, 193, 195, 196, 197, 151, 173, 195, 23, 23, + 23, 184, 148, 148, 148, 148, 23, 23, 23, 23, + 148, 23, 148, 148, 152, 148, 152, 142, 152, 23, + 148, 173, 148, 148, 172, 148, 148, 172, 173, 172, + 173, 172, 147, 185, 172, 21, 148, 148, 150, 150, + 148, 149, 148, 23, 148, 148, 148, 148, 190, 194, + 182, 190, 191, 192, 193, 194, 195, 196, 197, 173, + 148, 148, 148, 148, 185, 148, 173, 23, 22, 172, + 175, 148, 173, 173, 172, 193, 185, 23, 19, 20, + 185, 186, 201, 172, 172, 173, 151, 189, 192, 194, + 195, 196, 197, 179, 179, 148, 195, 173, 173, 172, + 185, 186, 182, 185, 148, 152, 148, 152, 173, 172, + 172, 173, 172, 173, 175, 175, 175, 175, 152, 152, + 152, 152 +}; + + /* YYR1YYN -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 153, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 155, 155, 156, 156, 156, 156, 157, + 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, + 160, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, + 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 167, 167, 167, 167, + 167, 167, 167, 168, 168, 168, 169, 169, 170, 170, + 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, + 173, 173, 173, 173, 173, 173, 173, 173, 174, 175, + 175, 176, 176, 176, 177, 177, 177, 178, 178, 179, + 179, 180, 180, 180, 180, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, + 182, 182, 182, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 184, 184, 185, 185, 185, 185, 185, + 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, + 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, + 190, 191, 192, 193, 194, 195, 196, 196, 197, 197, + 198, 198, 199, 199, 200, 201, 201 +}; + + /* YYR2YYN -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 2, 2, 5, 5, 5, 1, 2, 4, + 5, 4, 2, 5, 4, 5, 5, 4, 5, 4, + 4, 4, 4, 3, 1, 2, 4, 5, 5, 4, + 4, 4, 5, 5, 5, 5, 5, 5, 3, 5, + 2, 3, 2, 1, 1, 1, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, + 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 4, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 3, 3, 5, 8, 8, 4, 3, + 5, 1, 8, 8, 2, 1, 1 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +# ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yykind < YYNTOKENS) + YYPRINT (yyo, yytoknum[yykind], *yyvaluep); +# endif + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + + + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize; + + /* The state stack. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss; + yy_state_t *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yynerrs = 0; + yystate = 0; + yyerrstatus = 0; + + yystacksize = YYINITDEPTH; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 112 "m68kasm.y" + { _genop((yyvsp[-1].opc) | (yyvsp[0].opc)); yyrc = -1; } +#line 1979 "m68kasm.c" + break; + + case 3: +#line 113 "m68kasm.y" + { _genop((yyvsp[-1].opc) | (yyvsp[0].rea).reg | (yyvsp[0].rea).ea.ea); yyrc = _genea((yyvsp[0].rea).ea) -1; } +#line 1985 "m68kasm.c" + break; + + case 4: +#line 114 "m68kasm.y" + { _genop((yyvsp[-4].opc) | (yyvsp[0].ea).ea); if (oplen==0) { _genop((yyvsp[-2].num) & 0xff); yyrc = _genea((yyvsp[0].ea)) - 3; } + + else if (oplen==1) { _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } else { _genop((yyvsp[-2].num)>>16); _genop((yyvsp[-2].num) & 0xffff); yyrc = _genea((yyvsp[0].ea))-5; } } +#line 1992 "m68kasm.c" + break; + + case 5: +#line 116 "m68kasm.y" + { _genop((yyvsp[-4].opc) | (((yyvsp[-2].num)&7)<<9) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 1998 "m68kasm.c" + break; + + case 6: +#line 117 "m68kasm.y" + { _genop((yyvsp[-4].opc) | (yyvsp[0].ea).ea); if (oplen==0) { _genop((yyvsp[-2].num) & 0xff); yyrc = _genea((yyvsp[0].ea)) - 3; } + + else if (oplen==1) { _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } else { _genop((yyvsp[-2].num)>>16); _genop((yyvsp[-2].num) & 0xffff); yyrc = _genea((yyvsp[0].ea))-5; } } +#line 2005 "m68kasm.c" + break; + + case 7: +#line 119 "m68kasm.y" + { _genop((yyvsp[0].rea).reg); if (((yyvsp[0].rea).reg&0xc0)==0xc0) yyrc = _genea((yyvsp[0].rea).ea) - 1; else { yyrc = -1; } } +#line 2011 "m68kasm.c" + break; + + case 8: +#line 120 "m68kasm.y" + { yyrc = _genbr((yyvsp[-1].brop).opc,(yyvsp[0].num),(yyvsp[-1].brop).len); } +#line 2017 "m68kasm.c" + break; + + case 9: +#line 121 "m68kasm.y" + { _genop((yyvsp[-3].opc) | ((yyvsp[-2].reg)<<9) | 0x100 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 2023 "m68kasm.c" + break; + + case 10: +#line 122 "m68kasm.y" + { _genop((yyvsp[-4].opc) | 0x0800 | (yyvsp[0].ea).ea); _genop((yyvsp[-2].num)); yyrc = _genea((yyvsp[0].ea)) - 3; } +#line 2029 "m68kasm.c" + break; + + case 11: +#line 123 "m68kasm.y" + { _genop(0x4180 | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2035 "m68kasm.c" + break; + + case 12: +#line 124 "m68kasm.y" + { _genop((yyvsp[-1].opc) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 2041 "m68kasm.c" + break; + + case 13: +#line 125 "m68kasm.y" + { _genop(0xb000 | ((yyvsp[-3].wl)<<6) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2047 "m68kasm.c" + break; + + case 14: +#line 126 "m68kasm.y" + { _genop((yyvsp[-3].opc) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2053 "m68kasm.c" + break; + + case 15: +#line 127 "m68kasm.y" + { _genop(0xb0c0 | ((yyvsp[-3].wl)<<8) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2059 "m68kasm.c" + break; + + case 16: +#line 128 "m68kasm.y" + { _genop(0xb108 | ((yyvsp[0].ea).ea<<9) | ((yyvsp[-3].wl)<<6) | (yyvsp[-2].ea).ea); yyrc = -1; } +#line 2065 "m68kasm.c" + break; + + case 17: +#line 129 "m68kasm.y" + { yyrc = _genbr((yyvsp[-3].opc) | (yyvsp[-2].reg), (yyvsp[0].num), 1); } +#line 2071 "m68kasm.c" + break; + + case 18: +#line 130 "m68kasm.y" + { _genop(0xb000 | ((yyvsp[-3].wl) << 6) | 0x100 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 2077 "m68kasm.c" + break; + + case 19: +#line 131 "m68kasm.y" + { _genop(0xc140 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } +#line 2083 "m68kasm.c" + break; + + case 20: +#line 132 "m68kasm.y" + { _genop(0xc148 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } +#line 2089 "m68kasm.c" + break; + + case 21: +#line 133 "m68kasm.y" + { _genop(0xc188 | ((yyvsp[0].reg)<<9) | (yyvsp[-2].reg)); yyrc = -1; } +#line 2095 "m68kasm.c" + break; + + case 22: +#line 134 "m68kasm.y" + { _genop(0xc188 | ((yyvsp[-2].reg)<<9) | (yyvsp[0].reg)); yyrc = -1; } +#line 2101 "m68kasm.c" + break; + + case 23: +#line 135 "m68kasm.y" + { _genop(0x4840 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].reg)); yyrc = -1; } +#line 2107 "m68kasm.c" + break; + + case 24: +#line 136 "m68kasm.y" + { _genop((yyvsp[0].opc)); yyrc = -1; } +#line 2113 "m68kasm.c" + break; + + case 25: +#line 137 "m68kasm.y" + { _genop((yyvsp[-1].opc) | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) -1; } +#line 2119 "m68kasm.c" + break; + + case 26: +#line 138 "m68kasm.y" + { _genop(0x41c0 | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2125 "m68kasm.c" + break; + + case 27: +#line 139 "m68kasm.y" + { _genop(0x4e50 | (yyvsp[-3].reg)); _genop((yyvsp[0].num)); yyrc = -3; } +#line 2131 "m68kasm.c" + break; + + case 28: +#line 140 "m68kasm.y" + { if ((yyvsp[0].ea).ea==074) { _genop(0x44c0 | ((yyvsp[0].ea).cnt==1?0x0200:0x0000) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } + + else { int tmp = (((yyvsp[0].ea).ea&070)>>3)|(((yyvsp[0].ea).ea&7)<<3); _genop(0x0000 | ((yyvsp[-3].wl)<<12) | (tmp<<6) | (yyvsp[-2].ea).ea); + + yyrc = _genea((yyvsp[-2].ea)) - 1; yyrc += _genea((yyvsp[0].ea)); } } +#line 2139 "m68kasm.c" + break; + + case 29: +#line 143 "m68kasm.y" + { _genop(0x40c0 | (yyvsp[0].ea).ea); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 2145 "m68kasm.c" + break; + + case 30: +#line 144 "m68kasm.y" + { _genop(0x4e68 | (yyvsp[0].reg)); yyrc = -1; } +#line 2151 "m68kasm.c" + break; + + case 31: +#line 145 "m68kasm.y" + { _genop(0x4e60 | (yyvsp[-2].reg)); yyrc = -1; } +#line 2157 "m68kasm.c" + break; + + case 32: +#line 146 "m68kasm.y" + { _genop(0x0040 | ((yyvsp[-3].wl)<<12) | ((yyvsp[0].reg)<<9) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2163 "m68kasm.c" + break; + + case 33: +#line 147 "m68kasm.y" + { _genop(0x4880 | ((yyvsp[-3].wl)<<6) | (yyvsp[0].ea).ea); _genop(((yyvsp[0].ea).ea&070)==040 ? (yyvsp[-2].mask).d : (yyvsp[-2].mask).x); yyrc = _genea((yyvsp[0].ea)) - 3; } +#line 2169 "m68kasm.c" + break; + + case 34: +#line 148 "m68kasm.y" + { _genop(0x4c80 | ((yyvsp[-3].wl)<<6) | (yyvsp[-2].ea).ea); _genop((yyvsp[0].mask).x); yyrc = _genea((yyvsp[-2].ea)) - 3; } +#line 2175 "m68kasm.c" + break; + + case 35: +#line 149 "m68kasm.y" + { _genop(0x0108 | ((yyvsp[-2].reg)<<9) | ((yyvsp[-3].wl)<<6) | ((yyvsp[0].ea).ea & 7)); yyrc = _genea((yyvsp[0].ea)) - 1; } +#line 2181 "m68kasm.c" + break; + + case 36: +#line 150 "m68kasm.y" + { _genop(0x0188 | ((yyvsp[0].reg)<<9) | ((yyvsp[-3].wl)<<6) | ((yyvsp[-2].ea).ea & 7)); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2187 "m68kasm.c" + break; + + case 37: +#line 151 "m68kasm.y" + { _genop(0x7000 | ((yyvsp[0].reg)<<9) | ((yyvsp[-2].num)&0xff)); yyrc = -1; } +#line 2193 "m68kasm.c" + break; + + case 38: +#line 152 "m68kasm.y" + { _genop(0x4e72); yyrc = _genop((yyvsp[0].num)&0xffff) - 1; } +#line 2199 "m68kasm.c" + break; + + case 39: +#line 153 "m68kasm.y" + { _genop((yyvsp[-4].opc) | ((yyvsp[0].reg)<<9) | ((yyvsp[-3].wl)<<8) | (yyvsp[-2].ea).ea); yyrc = _genea((yyvsp[-2].ea)) - 1; } +#line 2205 "m68kasm.c" + break; + + case 40: +#line 154 "m68kasm.y" + { _genop(0x4840 | (yyvsp[0].reg)); yyrc = -1; } +#line 2211 "m68kasm.c" + break; + + case 41: +#line 155 "m68kasm.y" + { _genop(0x4e40 | ((yyvsp[0].num) & 0x0f)); yyrc = -1; } +#line 2217 "m68kasm.c" + break; + + case 42: +#line 156 "m68kasm.y" + { _genop(0x4e58 | (yyvsp[0].reg)); yyrc = -1; } +#line 2223 "m68kasm.c" + break; + + case 43: +#line 160 "m68kasm.y" + { (yyval.opc) = 0xd0c0; } +#line 2229 "m68kasm.c" + break; + + case 44: +#line 161 "m68kasm.y" + { (yyval.opc) = 0x90c0; } +#line 2235 "m68kasm.c" + break; + + case 45: +#line 164 "m68kasm.y" + { (yyval.opc) = 0xc100; } +#line 2241 "m68kasm.c" + break; + + case 46: +#line 165 "m68kasm.y" + { (yyval.opc) = 0xd100 | ((yyvsp[0].wl)<<6); } +#line 2247 "m68kasm.c" + break; + + case 47: +#line 166 "m68kasm.y" + { (yyval.opc) = 0x8100; } +#line 2253 "m68kasm.c" + break; + + case 48: +#line 167 "m68kasm.y" + { (yyval.opc) = 0x9100 | ((yyvsp[0].wl)<<6); } +#line 2259 "m68kasm.c" + break; + + case 49: +#line 171 "m68kasm.y" + { (yyval.opc) = 0xd000 | ((yyvsp[0].wl)<<6); } +#line 2265 "m68kasm.c" + break; + + case 50: +#line 172 "m68kasm.y" + { (yyval.opc) = 0xc000 | ((yyvsp[0].wl)<<6); } +#line 2271 "m68kasm.c" + break; + + case 51: +#line 173 "m68kasm.y" + { (yyval.opc) = 0x8000 | ((yyvsp[0].wl)<<6); } +#line 2277 "m68kasm.c" + break; + + case 52: +#line 174 "m68kasm.y" + { (yyval.opc) = 0x9000 | ((yyvsp[0].wl)<<6); } +#line 2283 "m68kasm.c" + break; + + case 53: +#line 178 "m68kasm.y" + { (yyval.opc) = 0x0600 | ((yyvsp[0].wl)<<6); } +#line 2289 "m68kasm.c" + break; + + case 54: +#line 179 "m68kasm.y" + { (yyval.opc) = 0x0c00 | ((yyvsp[0].wl)<<6); } +#line 2295 "m68kasm.c" + break; + + case 55: +#line 180 "m68kasm.y" + { (yyval.opc) = 0x0400 | ((yyvsp[0].wl)<<6); } +#line 2301 "m68kasm.c" + break; + + case 56: +#line 184 "m68kasm.y" + { (yyval.opc) = 0x0200 | ((yyvsp[0].wl)<<6); } +#line 2307 "m68kasm.c" + break; + + case 57: +#line 185 "m68kasm.y" + { (yyval.opc) = 0x0a00 | ((yyvsp[0].wl)<<6); } +#line 2313 "m68kasm.c" + break; + + case 58: +#line 186 "m68kasm.y" + { (yyval.opc) = 0x0000 | ((yyvsp[0].wl)<<6); } +#line 2319 "m68kasm.c" + break; + + case 59: +#line 190 "m68kasm.y" + { (yyval.opc) = 0x5000 | ((yyvsp[0].wl)<<6); } +#line 2325 "m68kasm.c" + break; + + case 60: +#line 191 "m68kasm.y" + { (yyval.opc) = 0x5100 | ((yyvsp[0].wl)<<6); } +#line 2331 "m68kasm.c" + break; + + case 61: +#line 195 "m68kasm.y" + { (yyval.rea).reg = 0xe1c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2337 "m68kasm.c" + break; + + case 62: +#line 196 "m68kasm.y" + { (yyval.rea).reg = 0xe100 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2343 "m68kasm.c" + break; + + case 63: +#line 197 "m68kasm.y" + { (yyval.rea).reg = 0xe0c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2349 "m68kasm.c" + break; + + case 64: +#line 198 "m68kasm.y" + { (yyval.rea).reg = 0xe000 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2355 "m68kasm.c" + break; + + case 65: +#line 199 "m68kasm.y" + { (yyval.rea).reg = 0xe3c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2361 "m68kasm.c" + break; + + case 66: +#line 200 "m68kasm.y" + { (yyval.rea).reg = 0xe108 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2367 "m68kasm.c" + break; + + case 67: +#line 201 "m68kasm.y" + { (yyval.rea).reg = 0xe2c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2373 "m68kasm.c" + break; + + case 68: +#line 202 "m68kasm.y" + { (yyval.rea).reg = 0xe008 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2379 "m68kasm.c" + break; + + case 69: +#line 203 "m68kasm.y" + { (yyval.rea).reg = 0xe7c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2385 "m68kasm.c" + break; + + case 70: +#line 204 "m68kasm.y" + { (yyval.rea).reg = 0xe118 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2391 "m68kasm.c" + break; + + case 71: +#line 205 "m68kasm.y" + { (yyval.rea).reg = 0xe6c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2397 "m68kasm.c" + break; + + case 72: +#line 206 "m68kasm.y" + { (yyval.rea).reg = 0xe018 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2403 "m68kasm.c" + break; + + case 73: +#line 207 "m68kasm.y" + { (yyval.rea).reg = 0xe5c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2409 "m68kasm.c" + break; + + case 74: +#line 208 "m68kasm.y" + { (yyval.rea).reg = 0xe100 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2415 "m68kasm.c" + break; + + case 75: +#line 209 "m68kasm.y" + { (yyval.rea).reg = 0xe4c0 | (yyvsp[0].ea).ea; (yyval.rea).ea = (yyvsp[0].ea); } +#line 2421 "m68kasm.c" + break; + + case 76: +#line 210 "m68kasm.y" + { (yyval.rea).reg = 0xe000 | ((yyvsp[-1].wl)<<6) | (yyvsp[0].opc); } +#line 2427 "m68kasm.c" + break; + + case 77: +#line 214 "m68kasm.y" + { (yyval.brop).opc = 0x6400; (yyval.brop).len = 1; } +#line 2433 "m68kasm.c" + break; + + case 78: +#line 215 "m68kasm.y" + { (yyval.brop).opc = 0x6500; (yyval.brop).len = 1; } +#line 2439 "m68kasm.c" + break; + + case 79: +#line 216 "m68kasm.y" + { (yyval.brop).opc = 0x6700; (yyval.brop).len = 1; } +#line 2445 "m68kasm.c" + break; + + case 80: +#line 217 "m68kasm.y" + { (yyval.brop).opc = 0x6c00; (yyval.brop).len = 1; } +#line 2451 "m68kasm.c" + break; + + case 81: +#line 218 "m68kasm.y" + { (yyval.brop).opc = 0x6e00; (yyval.brop).len = 1; } +#line 2457 "m68kasm.c" + break; + + case 82: +#line 219 "m68kasm.y" + { (yyval.brop).opc = 0x6200; (yyval.brop).len = 1; } +#line 2463 "m68kasm.c" + break; + + case 83: +#line 220 "m68kasm.y" + { (yyval.brop).opc = 0x6f00; (yyval.brop).len = 1; } +#line 2469 "m68kasm.c" + break; + + case 84: +#line 221 "m68kasm.y" + { (yyval.brop).opc = 0x6300; (yyval.brop).len = 1; } +#line 2475 "m68kasm.c" + break; + + case 85: +#line 222 "m68kasm.y" + { (yyval.brop).opc = 0x6d00; (yyval.brop).len = 1; } +#line 2481 "m68kasm.c" + break; + + case 86: +#line 223 "m68kasm.y" + { (yyval.brop).opc = 0x6b00; (yyval.brop).len = 1; } +#line 2487 "m68kasm.c" + break; + + case 87: +#line 224 "m68kasm.y" + { (yyval.brop).opc = 0x6600; (yyval.brop).len = 1; } +#line 2493 "m68kasm.c" + break; + + case 88: +#line 225 "m68kasm.y" + { (yyval.brop).opc = 0x6a00; (yyval.brop).len = 1; } +#line 2499 "m68kasm.c" + break; + + case 89: +#line 226 "m68kasm.y" + { (yyval.brop).opc = 0x6800; (yyval.brop).len = 1; } +#line 2505 "m68kasm.c" + break; + + case 90: +#line 227 "m68kasm.y" + { (yyval.brop).opc = 0x6900; (yyval.brop).len = 1; } +#line 2511 "m68kasm.c" + break; + + case 91: +#line 228 "m68kasm.y" + { (yyval.brop).opc = 0x6100; (yyval.brop).len = 1; } +#line 2517 "m68kasm.c" + break; + + case 92: +#line 229 "m68kasm.y" + { (yyval.brop).opc = 0x6000; (yyval.brop).len = 1; } +#line 2523 "m68kasm.c" + break; + + case 93: +#line 230 "m68kasm.y" + { (yyval.brop).opc = 0x6400; (yyval.brop).len = 0; } +#line 2529 "m68kasm.c" + break; + + case 94: +#line 231 "m68kasm.y" + { (yyval.brop).opc = 0x6500; (yyval.brop).len = 0; } +#line 2535 "m68kasm.c" + break; + + case 95: +#line 232 "m68kasm.y" + { (yyval.brop).opc = 0x6700; (yyval.brop).len = 0; } +#line 2541 "m68kasm.c" + break; + + case 96: +#line 233 "m68kasm.y" + { (yyval.brop).opc = 0x6c00; (yyval.brop).len = 0; } +#line 2547 "m68kasm.c" + break; + + case 97: +#line 234 "m68kasm.y" + { (yyval.brop).opc = 0x6e00; (yyval.brop).len = 0; } +#line 2553 "m68kasm.c" + break; + + case 98: +#line 235 "m68kasm.y" + { (yyval.brop).opc = 0x6200; (yyval.brop).len = 0; } +#line 2559 "m68kasm.c" + break; + + case 99: +#line 236 "m68kasm.y" + { (yyval.brop).opc = 0x6f00; (yyval.brop).len = 0; } +#line 2565 "m68kasm.c" + break; + + case 100: +#line 237 "m68kasm.y" + { (yyval.brop).opc = 0x6300; (yyval.brop).len = 0; } +#line 2571 "m68kasm.c" + break; + + case 101: +#line 238 "m68kasm.y" + { (yyval.brop).opc = 0x6d00; (yyval.brop).len = 0; } +#line 2577 "m68kasm.c" + break; + + case 102: +#line 239 "m68kasm.y" + { (yyval.brop).opc = 0x6b00; (yyval.brop).len = 0; } +#line 2583 "m68kasm.c" + break; + + case 103: +#line 240 "m68kasm.y" + { (yyval.brop).opc = 0x6600; (yyval.brop).len = 0; } +#line 2589 "m68kasm.c" + break; + + case 104: +#line 241 "m68kasm.y" + { (yyval.brop).opc = 0x6a00; (yyval.brop).len = 0; } +#line 2595 "m68kasm.c" + break; + + case 105: +#line 242 "m68kasm.y" + { (yyval.brop).opc = 0x6800; (yyval.brop).len = 0; } +#line 2601 "m68kasm.c" + break; + + case 106: +#line 243 "m68kasm.y" + { (yyval.brop).opc = 0x6900; (yyval.brop).len = 0; } +#line 2607 "m68kasm.c" + break; + + case 107: +#line 244 "m68kasm.y" + { (yyval.brop).opc = 0x6100; (yyval.brop).len = 0; } +#line 2613 "m68kasm.c" + break; + + case 108: +#line 245 "m68kasm.y" + { (yyval.brop).opc = 0x6000; (yyval.brop).len = 0; } +#line 2619 "m68kasm.c" + break; + + case 109: +#line 249 "m68kasm.y" + { (yyval.opc) = 0x0040; } +#line 2625 "m68kasm.c" + break; + + case 110: +#line 250 "m68kasm.y" + { (yyval.opc) = 0x0080; } +#line 2631 "m68kasm.c" + break; + + case 111: +#line 251 "m68kasm.y" + { (yyval.opc) = 0x00c0; } +#line 2637 "m68kasm.c" + break; + + case 112: +#line 252 "m68kasm.y" + { (yyval.opc) = 0x0000; } +#line 2643 "m68kasm.c" + break; + + case 113: +#line 256 "m68kasm.y" + { (yyval.opc) = 0x4200 | ((yyvsp[0].wl)<<6); } +#line 2649 "m68kasm.c" + break; + + case 114: +#line 257 "m68kasm.y" + { (yyval.opc) = 0x4800; } +#line 2655 "m68kasm.c" + break; + + case 115: +#line 258 "m68kasm.y" + { (yyval.opc) = 0x4400 | ((yyvsp[0].wl)<<6); } +#line 2661 "m68kasm.c" + break; + + case 116: +#line 259 "m68kasm.y" + { (yyval.opc) = 0x4000 | ((yyvsp[0].wl)<<6); } +#line 2667 "m68kasm.c" + break; + + case 117: +#line 260 "m68kasm.y" + { (yyval.opc) = 0x4600 | ((yyvsp[0].wl)<<6); } +#line 2673 "m68kasm.c" + break; + + case 118: +#line 261 "m68kasm.y" + { (yyval.opc) = 0x54c0; } +#line 2679 "m68kasm.c" + break; + + case 119: +#line 262 "m68kasm.y" + { (yyval.opc) = 0x55c0; } +#line 2685 "m68kasm.c" + break; + + case 120: +#line 263 "m68kasm.y" + { (yyval.opc) = 0x57c0; } +#line 2691 "m68kasm.c" + break; + + case 121: +#line 264 "m68kasm.y" + { (yyval.opc) = 0x51c0; } +#line 2697 "m68kasm.c" + break; + + case 122: +#line 265 "m68kasm.y" + { (yyval.opc) = 0x5cc0; } +#line 2703 "m68kasm.c" + break; + + case 123: +#line 266 "m68kasm.y" + { (yyval.opc) = 0x5ec0; } +#line 2709 "m68kasm.c" + break; + + case 124: +#line 267 "m68kasm.y" + { (yyval.opc) = 0x52c0; } +#line 2715 "m68kasm.c" + break; + + case 125: +#line 268 "m68kasm.y" + { (yyval.opc) = 0x5fc0; } +#line 2721 "m68kasm.c" + break; + + case 126: +#line 269 "m68kasm.y" + { (yyval.opc) = 0x53c0; } +#line 2727 "m68kasm.c" + break; + + case 127: +#line 270 "m68kasm.y" + { (yyval.opc) = 0x5dc0; } +#line 2733 "m68kasm.c" + break; + + case 128: +#line 271 "m68kasm.y" + { (yyval.opc) = 0x5bc0; } +#line 2739 "m68kasm.c" + break; + + case 129: +#line 272 "m68kasm.y" + { (yyval.opc) = 0x56c0; } +#line 2745 "m68kasm.c" + break; + + case 130: +#line 273 "m68kasm.y" + { (yyval.opc) = 0x5ac0; } +#line 2751 "m68kasm.c" + break; + + case 131: +#line 274 "m68kasm.y" + { (yyval.opc) = 0x50c0; } +#line 2757 "m68kasm.c" + break; + + case 132: +#line 275 "m68kasm.y" + { (yyval.opc) = 0x58c0; } +#line 2763 "m68kasm.c" + break; + + case 133: +#line 276 "m68kasm.y" + { (yyval.opc) = 0x59c0; } +#line 2769 "m68kasm.c" + break; + + case 134: +#line 277 "m68kasm.y" + { (yyval.opc) = 0x4ac0; } +#line 2775 "m68kasm.c" + break; + + case 135: +#line 278 "m68kasm.y" + { (yyval.opc) = 0x4a00 | ((yyvsp[0].wl)<<6); } +#line 2781 "m68kasm.c" + break; + + case 136: +#line 282 "m68kasm.y" + { (yyval.opc) = 0x81c0; } +#line 2787 "m68kasm.c" + break; + + case 137: +#line 283 "m68kasm.y" + { (yyval.opc) = 0x80c0; } +#line 2793 "m68kasm.c" + break; + + case 138: +#line 284 "m68kasm.y" + { (yyval.opc) = 0xc1c0; } +#line 2799 "m68kasm.c" + break; + + case 139: +#line 285 "m68kasm.y" + { (yyval.opc) = 0xc0c0; } +#line 2805 "m68kasm.c" + break; + + case 140: +#line 289 "m68kasm.y" + { (yyval.opc) = 0x54c8; } +#line 2811 "m68kasm.c" + break; + + case 141: +#line 290 "m68kasm.y" + { (yyval.opc) = 0x55c8; } +#line 2817 "m68kasm.c" + break; + + case 142: +#line 291 "m68kasm.y" + { (yyval.opc) = 0x57c8; } +#line 2823 "m68kasm.c" + break; + + case 143: +#line 292 "m68kasm.y" + { (yyval.opc) = 0x5cc8; } +#line 2829 "m68kasm.c" + break; + + case 144: +#line 293 "m68kasm.y" + { (yyval.opc) = 0x5ec8; } +#line 2835 "m68kasm.c" + break; + + case 145: +#line 294 "m68kasm.y" + { (yyval.opc) = 0x52c8; } +#line 2841 "m68kasm.c" + break; + + case 146: +#line 295 "m68kasm.y" + { (yyval.opc) = 0x5fc8; } +#line 2847 "m68kasm.c" + break; + + case 147: +#line 296 "m68kasm.y" + { (yyval.opc) = 0x53c8; } +#line 2853 "m68kasm.c" + break; + + case 148: +#line 297 "m68kasm.y" + { (yyval.opc) = 0x5dc8; } +#line 2859 "m68kasm.c" + break; + + case 149: +#line 298 "m68kasm.y" + { (yyval.opc) = 0x5bc8; } +#line 2865 "m68kasm.c" + break; + + case 150: +#line 299 "m68kasm.y" + { (yyval.opc) = 0x56c8; } +#line 2871 "m68kasm.c" + break; + + case 151: +#line 300 "m68kasm.y" + { (yyval.opc) = 0x5ac8; } +#line 2877 "m68kasm.c" + break; + + case 152: +#line 301 "m68kasm.y" + { (yyval.opc) = 0x58c8; } +#line 2883 "m68kasm.c" + break; + + case 153: +#line 302 "m68kasm.y" + { (yyval.opc) = 0x59c8; } +#line 2889 "m68kasm.c" + break; + + case 154: +#line 303 "m68kasm.y" + { (yyval.opc) = 0x51c8; } +#line 2895 "m68kasm.c" + break; + + case 155: +#line 304 "m68kasm.y" + { (yyval.opc) = 0x50c8; } +#line 2901 "m68kasm.c" + break; + + case 156: +#line 308 "m68kasm.y" + { (yyval.opc) = 0x4afc; } +#line 2907 "m68kasm.c" + break; + + case 157: +#line 309 "m68kasm.y" + { (yyval.opc) = 0x4e71; } +#line 2913 "m68kasm.c" + break; + + case 158: +#line 310 "m68kasm.y" + { (yyval.opc) = 0x4e70; } +#line 2919 "m68kasm.c" + break; + + case 159: +#line 311 "m68kasm.y" + { (yyval.opc) = 0x4e73; } +#line 2925 "m68kasm.c" + break; + + case 160: +#line 312 "m68kasm.y" + { (yyval.opc) = 0x4e77; } +#line 2931 "m68kasm.c" + break; + + case 161: +#line 313 "m68kasm.y" + { (yyval.opc) = 0x4e75; } +#line 2937 "m68kasm.c" + break; + + case 162: +#line 314 "m68kasm.y" + { (yyval.opc) = 0x4e76; } +#line 2943 "m68kasm.c" + break; + + case 163: +#line 318 "m68kasm.y" + { (yyval.opc) = 0x4ec0; } +#line 2949 "m68kasm.c" + break; + + case 164: +#line 319 "m68kasm.y" + { (yyval.opc) = 0x4e80; } +#line 2955 "m68kasm.c" + break; + + case 165: +#line 320 "m68kasm.y" + { (yyval.opc) = 0x4840; } +#line 2961 "m68kasm.c" + break; + + case 166: +#line 323 "m68kasm.y" + { (yyval.opc) = ((yyvsp[-2].reg)<<9) | 0x20 | (yyvsp[0].reg); } +#line 2967 "m68kasm.c" + break; + + case 167: +#line 324 "m68kasm.y" + { (yyval.opc) = (((yyvsp[-2].num) & 7)<<9) | (yyvsp[0].reg); } +#line 2973 "m68kasm.c" + break; + + case 168: +#line 327 "m68kasm.y" + { (yyval.opc) = (((yyvsp[-2].ea).ea & 7) << 9) | ((yyvsp[0].ea).ea & 7); } +#line 2979 "m68kasm.c" + break; + + case 169: +#line 328 "m68kasm.y" + { (yyval.opc) = (((yyvsp[-2].ea).ea & 7) << 9) | 0x0008 | ((yyvsp[0].ea).ea & 7); } +#line 2985 "m68kasm.c" + break; + + case 170: +#line 331 "m68kasm.y" + { if (((yyvsp[0].ea).ea & 070)==0) { /* dx,dy must be swapped */ + + (yyval.rea).reg = ((yyvsp[0].ea).ea & 7)<<9; (yyvsp[0].ea).ea = (yyvsp[-2].reg) & 7; (yyval.rea).ea = (yyvsp[0].ea); } + + else { (yyval.rea).reg = ((yyvsp[-2].reg)<<9) | 0x100; (yyval.rea).ea = (yyvsp[0].ea); } } +#line 2993 "m68kasm.c" + break; + + case 171: +#line 334 "m68kasm.y" + { (yyval.rea).reg = ((yyvsp[0].reg)<<9); (yyval.rea).ea = (yyvsp[-2].ea); } +#line 2999 "m68kasm.c" + break; + + case 172: +#line 337 "m68kasm.y" + { (yyval.reg)=0; } +#line 3005 "m68kasm.c" + break; + + case 173: +#line 338 "m68kasm.y" + { (yyval.reg)=1; } +#line 3011 "m68kasm.c" + break; + + case 174: +#line 339 "m68kasm.y" + { (yyval.reg)=2; } +#line 3017 "m68kasm.c" + break; + + case 175: +#line 340 "m68kasm.y" + { (yyval.reg)=3; } +#line 3023 "m68kasm.c" + break; + + case 176: +#line 341 "m68kasm.y" + { (yyval.reg)=4; } +#line 3029 "m68kasm.c" + break; + + case 177: +#line 342 "m68kasm.y" + { (yyval.reg)=5; } +#line 3035 "m68kasm.c" + break; + + case 178: +#line 343 "m68kasm.y" + { (yyval.reg)=6; } +#line 3041 "m68kasm.c" + break; + + case 179: +#line 344 "m68kasm.y" + { (yyval.reg)=7; } +#line 3047 "m68kasm.c" + break; + + case 180: +#line 347 "m68kasm.y" + { (yyval.reg)=0; } +#line 3053 "m68kasm.c" + break; + + case 181: +#line 348 "m68kasm.y" + { (yyval.reg)=1; } +#line 3059 "m68kasm.c" + break; + + case 182: +#line 349 "m68kasm.y" + { (yyval.reg)=2; } +#line 3065 "m68kasm.c" + break; + + case 183: +#line 350 "m68kasm.y" + { (yyval.reg)=3; } +#line 3071 "m68kasm.c" + break; + + case 184: +#line 351 "m68kasm.y" + { (yyval.reg)=4; } +#line 3077 "m68kasm.c" + break; + + case 185: +#line 352 "m68kasm.y" + { (yyval.reg)=5; } +#line 3083 "m68kasm.c" + break; + + case 186: +#line 353 "m68kasm.y" + { (yyval.reg)=6; } +#line 3089 "m68kasm.c" + break; + + case 187: +#line 354 "m68kasm.y" + { (yyval.reg)=7; } +#line 3095 "m68kasm.c" + break; + + case 188: +#line 357 "m68kasm.y" + { (yyval.wl) = 1; oplen = 0; } +#line 3101 "m68kasm.c" + break; + + case 189: +#line 360 "m68kasm.y" + { (yyval.wl) = 0; oplen = 1; } +#line 3107 "m68kasm.c" + break; + + case 190: +#line 361 "m68kasm.y" + { (yyval.wl) = 1; oplen = 2; } +#line 3113 "m68kasm.c" + break; + + case 191: +#line 364 "m68kasm.y" + { (yyval.wl) = 0; oplen = 0; } +#line 3119 "m68kasm.c" + break; + + case 192: +#line 365 "m68kasm.y" + { (yyval.wl) = 1; oplen = 1; } +#line 3125 "m68kasm.c" + break; + + case 193: +#line 366 "m68kasm.y" + { (yyval.wl) = 2; oplen = 2; } +#line 3131 "m68kasm.c" + break; + + case 194: +#line 369 "m68kasm.y" + { (yyval.wl) = 1; oplen = 0; } +#line 3137 "m68kasm.c" + break; + + case 195: +#line 370 "m68kasm.y" + { (yyval.wl) = 3; oplen = 1; } +#line 3143 "m68kasm.c" + break; + + case 196: +#line 371 "m68kasm.y" + { (yyval.wl) = 2; oplen = 2; } +#line 3149 "m68kasm.c" + break; + + case 197: +#line 374 "m68kasm.y" + { (yyval.wl) = 3; oplen = 1; } +#line 3155 "m68kasm.c" + break; + + case 198: +#line 375 "m68kasm.y" + { (yyval.wl) = 2; oplen = 2; } +#line 3161 "m68kasm.c" + break; + + case 199: +#line 378 "m68kasm.y" + { (yyval.mask) = (yyvsp[0].mask); } +#line 3167 "m68kasm.c" + break; + + case 200: +#line 379 "m68kasm.y" + { (yyval.mask).x = (yyvsp[-2].mask).x | (yyvsp[0].mask).x; (yyval.mask).d = (yyvsp[-2].mask).d | (yyvsp[0].mask).d; } +#line 3173 "m68kasm.c" + break; + + case 201: +#line 382 "m68kasm.y" + { (yyval.mask).x = movemx[(yyvsp[0].reg)]; (yyval.mask).d = movemd[(yyvsp[0].reg)]; } +#line 3179 "m68kasm.c" + break; + + case 202: +#line 383 "m68kasm.y" + { (yyval.mask).x = movemx[(yyvsp[0].reg)+8]; (yyval.mask).d = movemd[(yyvsp[0].reg)+8]; } +#line 3185 "m68kasm.c" + break; + + case 203: +#line 384 "m68kasm.y" + { int i,l=(yyvsp[-2].reg),h=(yyvsp[0].reg); if (l>h) { l=(yyvsp[0].reg); h=(yyvsp[-2].reg); } (yyval.mask).x = (yyval.mask).d = 0; + + for (i=l; i<=h; i++) { (yyval.mask).d |= movemx[i]; (yyval.mask).d |= movemd[i]; } } +#line 3192 "m68kasm.c" + break; + + case 204: +#line 386 "m68kasm.y" + { int i,l=(yyvsp[-2].reg),h=(yyvsp[0].reg); if (l>h) { l=(yyvsp[0].reg); h=(yyvsp[-2].reg); } (yyval.mask).x = (yyval.mask).d = 0; + + for (i=l; i<=h; i++) { (yyval.mask).x |= movemx[i+8]; (yyval.mask).d |= movemd[i+8]; } } +#line 3199 "m68kasm.c" + break; + + case 260: +#line 401 "m68kasm.y" + { (yyval.ea).ea = (yyvsp[0].reg); (yyval.ea).cnt = 0; } +#line 3205 "m68kasm.c" + break; + + case 261: +#line 403 "m68kasm.y" + { (yyval.ea).ea = 010 | (yyvsp[0].reg); (yyval.ea).cnt = 0; } +#line 3211 "m68kasm.c" + break; + + case 262: +#line 405 "m68kasm.y" + { (yyval.ea).ea = 020 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } +#line 3217 "m68kasm.c" + break; + + case 263: +#line 407 "m68kasm.y" + { (yyval.ea).ea = 030 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } +#line 3223 "m68kasm.c" + break; + + case 264: +#line 409 "m68kasm.y" + { (yyval.ea).ea = 040 | (yyvsp[-1].reg); (yyval.ea).cnt = 0; } +#line 3229 "m68kasm.c" + break; + + case 265: +#line 411 "m68kasm.y" + { (yyval.ea).ea = 050 | (yyvsp[-1].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-3].num); } +#line 3235 "m68kasm.c" + break; + + case 266: +#line 414 "m68kasm.y" + { (yyval.ea).ea = 060 | (yyvsp[-4].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = 0x8000 | ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } +#line 3241 "m68kasm.c" + break; + + case 267: +#line 416 "m68kasm.y" + { (yyval.ea).ea = 060 | (yyvsp[-4].reg); (yyval.ea).cnt = 1; (yyval.ea).arg[0] = ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } +#line 3247 "m68kasm.c" + break; + + case 268: +#line 418 "m68kasm.y" + { if ((yyvsp[0].wl)==0) { (yyval.ea).ea = 070; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-2].num); } + + else { (yyval.ea).ea = 071; (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[-2].num) >> 16; (yyval.ea).arg[1] = (yyvsp[-2].num) & 0xffff; } } +#line 3254 "m68kasm.c" + break; + + case 269: +#line 420 "m68kasm.y" + { int tmp = ((yyvsp[-1].num)>>15) & 0x1ffff; if (tmp==0 || tmp==0x1ffff) { (yyval.ea).ea = 070; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-1].num); } + + else { (yyval.ea).ea = 070; (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[-1].num) >> 16; (yyval.ea).arg[1] = (yyvsp[-1].num) & 0xffff; } } +#line 3261 "m68kasm.c" + break; + + case 270: +#line 423 "m68kasm.y" + { (yyval.ea).ea = 072; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[-3].num); } +#line 3267 "m68kasm.c" + break; + + case 271: +#line 424 "m68kasm.y" + { (yyval.ea).ea = 072; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num); } +#line 3273 "m68kasm.c" + break; + + case 272: +#line 427 "m68kasm.y" + { (yyval.ea).ea = 073; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = 0x8000 | ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } +#line 3279 "m68kasm.c" + break; + + case 273: +#line 429 "m68kasm.y" + { (yyval.ea).ea = 073; (yyval.ea).cnt = 1; (yyval.ea).arg[0] = ((yyvsp[-2].reg)<<12) | ((yyvsp[-1].wl)<<11) | ((yyvsp[-6].num) & 0xff); } +#line 3285 "m68kasm.c" + break; + + case 274: +#line 431 "m68kasm.y" + { (yyval.ea).ea = 074; if (oplen==0) { (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num) & 0xff; } + + else if (oplen==1) { (yyval.ea).cnt = 1; (yyval.ea).arg[0] = (yyvsp[0].num) & 0xffff; } + + else { (yyval.ea).cnt = 2; (yyval.ea).arg[0] = (yyvsp[0].num) >> 16; (yyval.ea).arg[1] = (yyvsp[0].num) & 0xffff; } } +#line 3293 "m68kasm.c" + break; + + case 275: +#line 435 "m68kasm.y" + { (yyval.ea).ea = 074; (yyval.ea).cnt = 0; } +#line 3299 "m68kasm.c" + break; + + case 276: +#line 436 "m68kasm.y" + { (yyval.ea).ea = 074; (yyval.ea).cnt = 1; } +#line 3305 "m68kasm.c" + break; + + +#line 3309 "m68kasm.c" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + yyerror (YY_("syntax error")); + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + + return yyresult; +} + +#line 437 "m68kasm.y" + + + + +static void yyerror(char* s) + +{ + + /* do not emit anything, but set error flag */ + + yyerrc = 1; + +} + + + +struct _optable { + + char* mnem; + + int token; + +}; + + + +static struct _optable ops[] = { + + { "abcd", ABCD }, { "add", ADD }, { "adda", ADDA }, { "addi", ADDI }, + + { "addq", ADDQ }, { "addx", ADDX }, { "and", AND }, { "andi", ANDI }, + + { "asl", ASL }, { "asr", ASR }, { "bcc", BCC }, { "bcs", BCS }, + + { "beq", BEQ }, { "bge", BGE }, { "bgt", BGT }, { "bhi", BHI }, + + { "ble", BLE }, { "bls", BLS }, { "blt", BLT }, { "bmi", BMI }, + + { "bne", BNE }, { "bpl", BPL }, { "bvc", BVC }, { "bvs", BVS }, + + { "bchg", BCHG }, { "bclr", BCLR }, { "bra", BRA }, { "bset", BSET }, + + { "bsr", BSR }, { "btst", BTST }, { "chk", CHK }, { "clr", CLR }, + + { "cmp", CMP }, { "cmpa", CMPA }, { "cmpi", CMPI }, { "cmpm", CMPM }, + + { "dbcc", DBCC }, { "dbcs", DBCS }, { "dbeq", DBEQ }, { "dbf", DBF }, + + { "dbge", DBGE }, { "dbgt", DBGT }, { "dbhi", DBHI }, { "dble", DBLE }, + + { "dbls", DBLS }, { "dblt", DBLT }, { "dbmi", DBMI }, { "dbne", DBNE }, + + { "dbpl", DBPL }, { "dbt", DBT }, { "dbvc", DBVC }, { "dbvs", DBVS }, + + { "divs", DIVS }, { "divu", DIVU }, { "eor", EOR }, { "eori", EORI }, + + { "exg", EXG }, { "ext", EXT }, { "illegal",ILLEGAL }, { "jmp", JMP }, + + { "jsr", JSR }, { "lea", LEA }, { "link", LINK }, { "lsl", LSL }, + + { "lsr", LSR }, { "move", MOVE }, { "movea", MOVEA }, { "movem", MOVEM }, + + { "movep", MOVEP }, { "moveq", MOVEQ }, { "muls", MULS }, { "mulu", MULU }, + + { "nbcd", NBCD }, { "neg", NEG }, { "negx", NEGX }, { "nop", NOP }, + + { "not", NOT }, { "or", OR }, { "ori", ORI }, { "pea", PEA }, + + { "reset", RESET }, { "rol", ROL }, { "ror", ROR }, { "roxl", ROXL }, + + { "roxr", ROXR }, { "rte", RTE }, { "rtr", RTR }, + + { "rts", RTS }, { "scc", SCC }, { "scs", SCS }, { "seq", SEQ }, + + { "sf", SF }, { "sge", SGE }, { "sgt", SGT }, { "shi", SHI }, + + { "sle", SLE }, { "sls", SLS }, { "slt", SLT }, { "smi", SMI }, + + { "sne", SNE }, { "spl", SPL }, { "st", ST }, { "svc", SVC }, + + { "svs", SVS }, { "stop", STOP }, { "sub", SUB }, { "suba", SUBA }, + + { "subi", SUBI }, { "subq", SUBQ }, { "subx", SUBX }, { "swap", SWAP }, + + { "tas", TAS }, { "trap", TRAP }, { "trapv", TRAPV }, { "tst", TST }, + + { "unlk", UNLK }, { "a0", A0 }, { "a1", A1 }, { "a2", A2 }, + + { "a3", A3 }, { "a4", A4 }, { "a5", A5 }, { "a6", A6 }, + + { "a7", A7 }, { "d0", D0 }, { "d1", D1 }, { "d2", D2 }, + + { "d3", D3 }, { "d4", D4 }, { "d5", D5 }, { "d6", D6 }, + + { "d7", D7 }, { "ccr", CCR }, { "sr", SR }, { "usp", USP }, + + { "pc", PC }, + + { 0, 0 } + +}; + + + +typedef struct _ophash { + + struct _ophash* next; + + struct _optable* op; + +} OPHASH; + +#define OPHASHSIZE 97 + + + +static OPHASH **ophash = 0; + + + +static int getophash(const char* s) + +{ + + int h = 0; + + while (*s++) h += (int)*s; + + return h % OPHASHSIZE; + +} + + + +static int oplookup(const char* s) + +{ + + int idx = getophash(s); + + OPHASH* oph = ophash[idx]; + + if (oph) { + + if (oph->next) { + + while (oph) { + + if (!strcmp(s,oph->op->mnem)) return oph->op->token; + + oph = oph->next; + + } + + return 0; + + } + + return oph->op->token; + + } + + return 0; + +} + + + +static void init_ophash() + +{ + + struct _optable* op = ops; + + OPHASH* oph; + + ophash = (OPHASH**)calloc(sizeof(OPHASH*),OPHASHSIZE); + + while (op->mnem) { + + int idx = getophash(op->mnem); + + oph = (OPHASH*)malloc(sizeof(OPHASH)); + + oph->next = ophash[idx]; + + oph->op = op; + + ophash[idx] = oph; + + op++; + + } + +} + + + +static char* yystream; + + + +static int yylex() + +{ + + char ident[30]; + + char *p = ident; + + char c = yystream[0]; + + + + while (c != 0 && (c=='\t' || c==' ')) { + + c = *++yystream; + + } + + if (c==0) return EOF; + + + + if (isalpha(c)) { + + while (isalnum(c) && (p-ident)<28) { + + *p++ = tolower(c); c = *++yystream; + + } + + *p = 0; + + if (p>ident) { return oplookup(ident); } + + return EOF; + + } else if (isdigit(c)) { + + *p++ = c; + + if (yystream[1]=='x' || yystream[1]=='X') { *p++ = 'x'; yystream++; } + + c = *++yystream; + + while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) { + + *p++ = c; c = *++yystream; + + } + + *p = 0; + + yylval.num = strtol(ident,0,0); + + return NUMBER; + + } else if (c=='$') { + + if (isdigit(yystream[1]) || isxdigit(yystream[1])) { + + c = *++yystream; + + while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) { + + *p++ = c; c = *++yystream; + + } + + *p = 0; + + yylval.num = strtol(ident,0,16); + + return NUMBER; + + } else return '$'; + + } else if (c == '-' && yystream[1] == '(') { + + yystream += 2; return PREDEC; + + } else if (c == ')' && yystream[1] == '+') { + + yystream += 2; return POSTINC; + + } else if (c == '.') { + + switch (yystream[1]) { + + case 'b': yystream += 2; return BSIZE; + + case 'w': yystream += 2; return WSIZE; + + case 'l': yystream += 2; return LSIZE; + + case 's': yystream += 2; return SSIZE; + + default: yystream++; return '.'; + + } + + } else { + + ++yystream; return c; + + } + +} + + + +static t_value *yyvalptr; + +static t_addr yyaddr; + + + +t_stat parse_sym_m68k(char* c, t_addr a, UNIT* u, t_value* val, int32 sw) + +{ + + char ch; + + + + if (!ophash) init_ophash(); + + + + yyvalptr = val; + + yyaddr = a; + + + + yystream = c; + + yyerrc = 0; + + + + ch = *yystream; + + while (ch != 0 && (ch=='\t' || ch==' ')) { + + ch = *++yystream; + + } + + if (ch == 0) return 0; + + + + if (sw & SWMASK('Y')) yydebug = 1 - yydebug; + + if ((sw & SWMASK('A')) || ch=='\'') { + + if ((ch = yystream[1])) { + + val[0] = (uint32)ch; + + return SCPE_OK; + + } else return SCPE_ARG; + + } + + if ((sw & SWMASK('C')) || ch=='"') { + + if ((ch = yystream[1])) { + + val[0] = ((uint32)ch << 8) | (uint32)yystream[1]; + + return SCPE_OK; + + } else return SCPE_ARG; + + } + + + + yyparse(); + +// sim_printf("rc=%d\n",yyrc); + + if (yyerrc) return SCPE_ARG; + + return yyrc; + +} + + + +static int _genop(t_value arg) + +{ + +// sim_printf("_genop(%x)@%x\n",arg,(int)yyvalptr); + + *yyvalptr = (arg >> 8) & 0xff; + + yyvalptr++; + + *yyvalptr = arg & 0xff; + + yyvalptr++; + + return -1; + +} + + + +static int _genea(struct _ea arg) + +{ + + int i; + + for (i=0; i - #ifdef _BSD_SETJMP_H - sigjmp_buf m68ki_aerr_trap; - #else - jmp_buf m68ki_aerr_trap; - #endif + #include + #ifdef _BSD_SETJMP_H + sigjmp_buf m68ki_aerr_trap; + #else + jmp_buf m68ki_aerr_trap; + #endif #endif /* M68K_EMULATE_ADDRESS_ERROR */ /* ======================================================================== */ @@ -616,422 +616,422 @@ static void default_instr_hook_callback(unsigned int pc) /* Access the internals of the CPU */ unsigned int m68k_get_reg(void* context, m68k_register_t regnum) { - m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu; + m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu; - switch(regnum) - { - case M68K_REG_D0: return cpu->dar[0]; - case M68K_REG_D1: return cpu->dar[1]; - case M68K_REG_D2: return cpu->dar[2]; - case M68K_REG_D3: return cpu->dar[3]; - case M68K_REG_D4: return cpu->dar[4]; - case M68K_REG_D5: return cpu->dar[5]; - case M68K_REG_D6: return cpu->dar[6]; - case M68K_REG_D7: return cpu->dar[7]; - case M68K_REG_A0: return cpu->dar[8]; - case M68K_REG_A1: return cpu->dar[9]; - case M68K_REG_A2: return cpu->dar[10]; - case M68K_REG_A3: return cpu->dar[11]; - case M68K_REG_A4: return cpu->dar[12]; - case M68K_REG_A5: return cpu->dar[13]; - case M68K_REG_A6: return cpu->dar[14]; - case M68K_REG_A7: return cpu->dar[15]; - case M68K_REG_PC: return MASK_OUT_ABOVE_32(cpu->pc); - case M68K_REG_SR: return cpu->t1_flag | - cpu->t0_flag | - (cpu->s_flag << 11) | - (cpu->m_flag << 11) | - cpu->int_mask | - ((cpu->x_flag & XFLAG_SET) >> 4) | - ((cpu->n_flag & NFLAG_SET) >> 4) | - ((!cpu->not_z_flag) << 2) | - ((cpu->v_flag & VFLAG_SET) >> 6) | - ((cpu->c_flag & CFLAG_SET) >> 8); - case M68K_REG_SP: return cpu->dar[15]; - case M68K_REG_USP: return cpu->s_flag ? cpu->sp[0] : cpu->dar[15]; - case M68K_REG_ISP: return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4]; - case M68K_REG_MSP: return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6]; - case M68K_REG_SFC: return cpu->sfc; - case M68K_REG_DFC: return cpu->dfc; - case M68K_REG_VBR: return cpu->vbr; - case M68K_REG_CACR: return cpu->cacr; - case M68K_REG_CAAR: return cpu->caar; - case M68K_REG_PREF_ADDR: return cpu->pref_addr; - case M68K_REG_PREF_DATA: return cpu->pref_data; - case M68K_REG_PPC: return MASK_OUT_ABOVE_32(cpu->ppc); - case M68K_REG_IR: return cpu->ir; - case M68K_REG_CPU_TYPE: - switch(cpu->cpu_type) - { - case CPU_TYPE_000: return (unsigned int)M68K_CPU_TYPE_68000; - case CPU_TYPE_010: return (unsigned int)M68K_CPU_TYPE_68010; - case CPU_TYPE_EC020: return (unsigned int)M68K_CPU_TYPE_68EC020; - case CPU_TYPE_020: return (unsigned int)M68K_CPU_TYPE_68020; - case CPU_TYPE_040: return (unsigned int)M68K_CPU_TYPE_68040; - } - return M68K_CPU_TYPE_INVALID; - default: return 0; - } - return 0; + switch(regnum) + { + case M68K_REG_D0: return cpu->dar[0]; + case M68K_REG_D1: return cpu->dar[1]; + case M68K_REG_D2: return cpu->dar[2]; + case M68K_REG_D3: return cpu->dar[3]; + case M68K_REG_D4: return cpu->dar[4]; + case M68K_REG_D5: return cpu->dar[5]; + case M68K_REG_D6: return cpu->dar[6]; + case M68K_REG_D7: return cpu->dar[7]; + case M68K_REG_A0: return cpu->dar[8]; + case M68K_REG_A1: return cpu->dar[9]; + case M68K_REG_A2: return cpu->dar[10]; + case M68K_REG_A3: return cpu->dar[11]; + case M68K_REG_A4: return cpu->dar[12]; + case M68K_REG_A5: return cpu->dar[13]; + case M68K_REG_A6: return cpu->dar[14]; + case M68K_REG_A7: return cpu->dar[15]; + case M68K_REG_PC: return MASK_OUT_ABOVE_32(cpu->pc); + case M68K_REG_SR: return cpu->t1_flag | + cpu->t0_flag | + (cpu->s_flag << 11) | + (cpu->m_flag << 11) | + cpu->int_mask | + ((cpu->x_flag & XFLAG_SET) >> 4) | + ((cpu->n_flag & NFLAG_SET) >> 4) | + ((!cpu->not_z_flag) << 2) | + ((cpu->v_flag & VFLAG_SET) >> 6) | + ((cpu->c_flag & CFLAG_SET) >> 8); + case M68K_REG_SP: return cpu->dar[15]; + case M68K_REG_USP: return cpu->s_flag ? cpu->sp[0] : cpu->dar[15]; + case M68K_REG_ISP: return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4]; + case M68K_REG_MSP: return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6]; + case M68K_REG_SFC: return cpu->sfc; + case M68K_REG_DFC: return cpu->dfc; + case M68K_REG_VBR: return cpu->vbr; + case M68K_REG_CACR: return cpu->cacr; + case M68K_REG_CAAR: return cpu->caar; + case M68K_REG_PREF_ADDR: return cpu->pref_addr; + case M68K_REG_PREF_DATA: return cpu->pref_data; + case M68K_REG_PPC: return MASK_OUT_ABOVE_32(cpu->ppc); + case M68K_REG_IR: return cpu->ir; + case M68K_REG_CPU_TYPE: + switch(cpu->cpu_type) + { + case CPU_TYPE_000: return (unsigned int)M68K_CPU_TYPE_68000; + case CPU_TYPE_010: return (unsigned int)M68K_CPU_TYPE_68010; + case CPU_TYPE_EC020: return (unsigned int)M68K_CPU_TYPE_68EC020; + case CPU_TYPE_020: return (unsigned int)M68K_CPU_TYPE_68020; + case CPU_TYPE_040: return (unsigned int)M68K_CPU_TYPE_68040; + } + return M68K_CPU_TYPE_INVALID; + default: return 0; + } + return 0; } void m68k_set_reg(m68k_register_t regnum, unsigned int value) { - switch(regnum) - { - case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; - case M68K_REG_SR: m68ki_set_sr_noint_nosp(value); return; - case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_USP: if(FLAG_S) - REG_USP = MASK_OUT_ABOVE_32(value); - else - REG_SP = MASK_OUT_ABOVE_32(value); - return; - case M68K_REG_ISP: if(FLAG_S && !FLAG_M) - REG_SP = MASK_OUT_ABOVE_32(value); - else - REG_ISP = MASK_OUT_ABOVE_32(value); - return; - case M68K_REG_MSP: if(FLAG_S && FLAG_M) - REG_SP = MASK_OUT_ABOVE_32(value); - else - REG_MSP = MASK_OUT_ABOVE_32(value); - return; - case M68K_REG_VBR: REG_VBR = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_SFC: REG_SFC = value & 7; return; - case M68K_REG_DFC: REG_DFC = value & 7; return; - case M68K_REG_CACR: REG_CACR = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_CAAR: REG_CAAR = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_PPC: REG_PPC = MASK_OUT_ABOVE_32(value); return; - case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return; - case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return; - default: return; - } + switch(regnum) + { + case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; + case M68K_REG_SR: m68ki_set_sr_noint_nosp(value); return; + case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_USP: if(FLAG_S) + REG_USP = MASK_OUT_ABOVE_32(value); + else + REG_SP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_ISP: if(FLAG_S && !FLAG_M) + REG_SP = MASK_OUT_ABOVE_32(value); + else + REG_ISP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_MSP: if(FLAG_S && FLAG_M) + REG_SP = MASK_OUT_ABOVE_32(value); + else + REG_MSP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_VBR: REG_VBR = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_SFC: REG_SFC = value & 7; return; + case M68K_REG_DFC: REG_DFC = value & 7; return; + case M68K_REG_CACR: REG_CACR = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_CAAR: REG_CAAR = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_PPC: REG_PPC = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return; + case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return; + default: return; + } } /* Set the callbacks */ void m68k_set_int_ack_callback(int (*callback)(int int_level)) { - CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback; + CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback; } void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data)) { - CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback; + CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback; } void m68k_set_reset_instr_callback(void (*callback)(void)) { - CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback; + CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback; } void m68k_set_cmpild_instr_callback(void (*callback)(unsigned int, int)) { - CALLBACK_CMPILD_INSTR = callback ? callback : default_cmpild_instr_callback; + CALLBACK_CMPILD_INSTR = callback ? callback : default_cmpild_instr_callback; } void m68k_set_rte_instr_callback(void (*callback)(void)) { - CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback; + CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback; } void m68k_set_tas_instr_callback(int (*callback)(void)) { - CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback; + CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback; } void m68k_set_illg_instr_callback(int (*callback)(int)) { - CALLBACK_ILLG_INSTR = callback ? callback : default_illg_instr_callback; + CALLBACK_ILLG_INSTR = callback ? callback : default_illg_instr_callback; } void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc)) { - CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback; + CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback; } void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)) { - CALLBACK_SET_FC = callback ? callback : default_set_fc_callback; + CALLBACK_SET_FC = callback ? callback : default_set_fc_callback; } void m68k_set_instr_hook_callback(void (*callback)(unsigned int pc)) { - CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback; + CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback; } /* Set the CPU type. */ void m68k_set_cpu_type(unsigned int cpu_type) { - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - CPU_TYPE = CPU_TYPE_000; - CPU_ADDRESS_MASK = 0x00ffffff; - CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[0]; - CYC_EXCEPTION = m68ki_exception_cycle_table[0]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 2; - CYC_DBCC_F_NOEXP = -2; - CYC_DBCC_F_EXP = 2; - CYC_SCC_R_TRUE = 2; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 3; - CYC_SHIFT = 1; - CYC_RESET = 132; - HAS_PMMU = 0; - return; - case M68K_CPU_TYPE_SCC68070: - m68k_set_cpu_type(M68K_CPU_TYPE_68010); - CPU_ADDRESS_MASK = 0xffffffff; - CPU_TYPE = CPU_TYPE_SCC070; - return; - case M68K_CPU_TYPE_68010: - CPU_TYPE = CPU_TYPE_010; - CPU_ADDRESS_MASK = 0x00ffffff; - CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[1]; - CYC_EXCEPTION = m68ki_exception_cycle_table[1]; - CYC_BCC_NOTAKE_B = -4; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 6; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 3; - CYC_SHIFT = 1; - CYC_RESET = 130; - HAS_PMMU = 0; - return; - case M68K_CPU_TYPE_68EC020: - CPU_TYPE = CPU_TYPE_EC020; - CPU_ADDRESS_MASK = 0x00ffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[2]; - CYC_EXCEPTION = m68ki_exception_cycle_table[2]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 0; - return; - case M68K_CPU_TYPE_68020: - CPU_TYPE = CPU_TYPE_020; - CPU_ADDRESS_MASK = 0xffffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[2]; - CYC_EXCEPTION = m68ki_exception_cycle_table[2]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 0; - return; - case M68K_CPU_TYPE_68030: - CPU_TYPE = CPU_TYPE_030; - CPU_ADDRESS_MASK = 0xffffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[3]; - CYC_EXCEPTION = m68ki_exception_cycle_table[3]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 1; - return; - case M68K_CPU_TYPE_68EC030: - CPU_TYPE = CPU_TYPE_EC030; - CPU_ADDRESS_MASK = 0xffffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[3]; - CYC_EXCEPTION = m68ki_exception_cycle_table[3]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 0; /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */ - return; - case M68K_CPU_TYPE_68040: // TODO: these values are not correct - CPU_TYPE = CPU_TYPE_040; - CPU_ADDRESS_MASK = 0xffffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[4]; - CYC_EXCEPTION = m68ki_exception_cycle_table[4]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 1; - return; - case M68K_CPU_TYPE_68EC040: // Just a 68040 without pmmu apparently... - CPU_TYPE = CPU_TYPE_EC040; - CPU_ADDRESS_MASK = 0xffffffff; - CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - CYC_INSTRUCTION = m68ki_cycles[4]; - CYC_EXCEPTION = m68ki_exception_cycle_table[4]; - CYC_BCC_NOTAKE_B = -2; - CYC_BCC_NOTAKE_W = 0; - CYC_DBCC_F_NOEXP = 0; - CYC_DBCC_F_EXP = 4; - CYC_SCC_R_TRUE = 0; - CYC_MOVEM_W = 2; - CYC_MOVEM_L = 2; - CYC_SHIFT = 0; - CYC_RESET = 518; - HAS_PMMU = 0; - return; - case M68K_CPU_TYPE_68LC040: - CPU_TYPE = CPU_TYPE_LC040; - m68ki_cpu.sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ - m68ki_cpu.cyc_instruction = m68ki_cycles[4]; - m68ki_cpu.cyc_exception = m68ki_exception_cycle_table[4]; - m68ki_cpu.cyc_bcc_notake_b = -2; - m68ki_cpu.cyc_bcc_notake_w = 0; - m68ki_cpu.cyc_dbcc_f_noexp = 0; - m68ki_cpu.cyc_dbcc_f_exp = 4; - m68ki_cpu.cyc_scc_r_true = 0; - m68ki_cpu.cyc_movem_w = 2; - m68ki_cpu.cyc_movem_l = 2; - m68ki_cpu.cyc_shift = 0; - m68ki_cpu.cyc_reset = 518; - HAS_PMMU = 1; - return; - } + switch(cpu_type) + { + case M68K_CPU_TYPE_68000: + CPU_TYPE = CPU_TYPE_000; + CPU_ADDRESS_MASK = 0x00ffffff; + CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[0]; + CYC_EXCEPTION = m68ki_exception_cycle_table[0]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 2; + CYC_DBCC_F_NOEXP = -2; + CYC_DBCC_F_EXP = 2; + CYC_SCC_R_TRUE = 2; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 3; + CYC_SHIFT = 1; + CYC_RESET = 132; + HAS_PMMU = 0; + return; + case M68K_CPU_TYPE_SCC68070: + m68k_set_cpu_type(M68K_CPU_TYPE_68010); + CPU_ADDRESS_MASK = 0xffffffff; + CPU_TYPE = CPU_TYPE_SCC070; + return; + case M68K_CPU_TYPE_68010: + CPU_TYPE = CPU_TYPE_010; + CPU_ADDRESS_MASK = 0x00ffffff; + CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[1]; + CYC_EXCEPTION = m68ki_exception_cycle_table[1]; + CYC_BCC_NOTAKE_B = -4; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 6; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 3; + CYC_SHIFT = 1; + CYC_RESET = 130; + HAS_PMMU = 0; + return; + case M68K_CPU_TYPE_68EC020: + CPU_TYPE = CPU_TYPE_EC020; + CPU_ADDRESS_MASK = 0x00ffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[2]; + CYC_EXCEPTION = m68ki_exception_cycle_table[2]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 0; + return; + case M68K_CPU_TYPE_68020: + CPU_TYPE = CPU_TYPE_020; + CPU_ADDRESS_MASK = 0xffffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[2]; + CYC_EXCEPTION = m68ki_exception_cycle_table[2]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 0; + return; + case M68K_CPU_TYPE_68030: + CPU_TYPE = CPU_TYPE_030; + CPU_ADDRESS_MASK = 0xffffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[3]; + CYC_EXCEPTION = m68ki_exception_cycle_table[3]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 1; + return; + case M68K_CPU_TYPE_68EC030: + CPU_TYPE = CPU_TYPE_EC030; + CPU_ADDRESS_MASK = 0xffffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[3]; + CYC_EXCEPTION = m68ki_exception_cycle_table[3]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 0; /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */ + return; + case M68K_CPU_TYPE_68040: // TODO: these values are not correct + CPU_TYPE = CPU_TYPE_040; + CPU_ADDRESS_MASK = 0xffffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[4]; + CYC_EXCEPTION = m68ki_exception_cycle_table[4]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 1; + return; + case M68K_CPU_TYPE_68EC040: // Just a 68040 without pmmu apparently... + CPU_TYPE = CPU_TYPE_EC040; + CPU_ADDRESS_MASK = 0xffffffff; + CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + CYC_INSTRUCTION = m68ki_cycles[4]; + CYC_EXCEPTION = m68ki_exception_cycle_table[4]; + CYC_BCC_NOTAKE_B = -2; + CYC_BCC_NOTAKE_W = 0; + CYC_DBCC_F_NOEXP = 0; + CYC_DBCC_F_EXP = 4; + CYC_SCC_R_TRUE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + HAS_PMMU = 0; + return; + case M68K_CPU_TYPE_68LC040: + CPU_TYPE = CPU_TYPE_LC040; + m68ki_cpu.sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */ + m68ki_cpu.cyc_instruction = m68ki_cycles[4]; + m68ki_cpu.cyc_exception = m68ki_exception_cycle_table[4]; + m68ki_cpu.cyc_bcc_notake_b = -2; + m68ki_cpu.cyc_bcc_notake_w = 0; + m68ki_cpu.cyc_dbcc_f_noexp = 0; + m68ki_cpu.cyc_dbcc_f_exp = 4; + m68ki_cpu.cyc_scc_r_true = 0; + m68ki_cpu.cyc_movem_w = 2; + m68ki_cpu.cyc_movem_l = 2; + m68ki_cpu.cyc_shift = 0; + m68ki_cpu.cyc_reset = 518; + HAS_PMMU = 1; + return; + } } /* Execute some instructions until we use up num_cycles clock cycles */ /* ASG: removed per-instruction interrupt checks */ int m68k_execute(int num_cycles) { - /* eat up any reset cycles */ - if (RESET_CYCLES) { - int rc = RESET_CYCLES; - RESET_CYCLES = 0; - num_cycles -= rc; - if (num_cycles <= 0) - return rc; - } + /* eat up any reset cycles */ + if (RESET_CYCLES) { + int rc = RESET_CYCLES; + RESET_CYCLES = 0; + num_cycles -= rc; + if (num_cycles <= 0) + return rc; + } - /* Set our pool of clock cycles available */ - SET_CYCLES(num_cycles); - m68ki_initial_cycles = num_cycles; + /* Set our pool of clock cycles available */ + SET_CYCLES(num_cycles); + m68ki_initial_cycles = num_cycles; - /* See if interrupts came in */ - m68ki_check_interrupts(); + /* See if interrupts came in */ + m68ki_check_interrupts(); - /* Make sure we're not stopped */ - if(!CPU_STOPPED) - { - /* Return point if we had an address error */ - m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */ + /* Make sure we're not stopped */ + if(!CPU_STOPPED) + { + /* Return point if we had an address error */ + m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */ - m68ki_check_bus_error_trap(); + m68ki_check_bus_error_trap(); - /* Main loop. Keep going until we run out of clock cycles */ - do - { - int i; - /* Set tracing accodring to T1. (T0 is done inside instruction) */ - m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */ + /* Main loop. Keep going until we run out of clock cycles */ + do + { + int i; + /* Set tracing accodring to T1. (T0 is done inside instruction) */ + m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */ - /* Set the address space for reads */ - m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */ + /* Set the address space for reads */ + m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */ - /* Call external hook to peek at CPU */ - m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */ + /* Call external hook to peek at CPU */ + m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */ - /* Record previous program counter */ - REG_PPC = REG_PC; + /* Record previous program counter */ + REG_PPC = REG_PC; - /* Record previous D/A register state (in case of bus error) */ - for (i = 15; i >= 0; i--){ - REG_DA_SAVE[i] = REG_DA[i]; - } + /* Record previous D/A register state (in case of bus error) */ + for (i = 15; i >= 0; i--){ + REG_DA_SAVE[i] = REG_DA[i]; + } - /* Read an instruction and call its handler */ - REG_IR = m68ki_read_imm_16(); - m68ki_instruction_jump_table[REG_IR](); - USE_CYCLES(CYC_INSTRUCTION[REG_IR]); + /* Read an instruction and call its handler */ + REG_IR = m68ki_read_imm_16(); + m68ki_instruction_jump_table[REG_IR](); + USE_CYCLES(CYC_INSTRUCTION[REG_IR]); - /* Trace m68k_exception, if necessary */ - m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ - } while(GET_CYCLES() > 0); + /* Trace m68k_exception, if necessary */ + m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ + } while(GET_CYCLES() > 0); - /* set previous PC to current PC for the next entry into the loop */ - REG_PPC = REG_PC; - } - else - SET_CYCLES(0); + /* set previous PC to current PC for the next entry into the loop */ + REG_PPC = REG_PC; + } + else + SET_CYCLES(0); - /* return how many clocks we used */ - return m68ki_initial_cycles - GET_CYCLES(); + /* return how many clocks we used */ + return m68ki_initial_cycles - GET_CYCLES(); } int m68k_cycles_run(void) { - return m68ki_initial_cycles - GET_CYCLES(); + return m68ki_initial_cycles - GET_CYCLES(); } int m68k_cycles_remaining(void) { - return GET_CYCLES(); + return GET_CYCLES(); } /* Change the timeslice */ void m68k_modify_timeslice(int cycles) { - m68ki_initial_cycles += cycles; - ADD_CYCLES(cycles); + m68ki_initial_cycles += cycles; + ADD_CYCLES(cycles); } void m68k_end_timeslice(void) { - m68ki_initial_cycles = GET_CYCLES(); - SET_CYCLES(0); + m68ki_initial_cycles = GET_CYCLES(); + SET_CYCLES(0); } @@ -1041,130 +1041,130 @@ void m68k_end_timeslice(void) */ void m68k_set_irq(unsigned int int_level) { - uint old_level = CPU_INT_LEVEL; - CPU_INT_LEVEL = int_level << 8; + uint old_level = CPU_INT_LEVEL; + CPU_INT_LEVEL = int_level << 8; - /* A transition from < 7 to 7 always interrupts (NMI) */ - /* Note: Level 7 can also level trigger like a normal IRQ */ - if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700) - m68ki_cpu.nmi_pending = TRUE; + /* A transition from < 7 to 7 always interrupts (NMI) */ + /* Note: Level 7 can also level trigger like a normal IRQ */ + if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700) + m68ki_cpu.nmi_pending = TRUE; } void m68k_set_virq(unsigned int level, unsigned int active) { - uint state = m68ki_cpu.virq_state; - uint blevel; + uint state = m68ki_cpu.virq_state; + uint blevel; - if(active) - state |= 1 << level; - else - state &= ~(1 << level); - m68ki_cpu.virq_state = state; + if(active) + state |= 1 << level; + else + state &= ~(1 << level); + m68ki_cpu.virq_state = state; - for(blevel = 7; blevel > 0; blevel--) - if(state & (1 << blevel)) - break; - m68k_set_irq(blevel); + for(blevel = 7; blevel > 0; blevel--) + if(state & (1 << blevel)) + break; + m68k_set_irq(blevel); } unsigned int m68k_get_virq(unsigned int level) { - return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0; + return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0; } void m68k_init(void) { - static uint emulation_initialized = 0; + static uint emulation_initialized = 0; - /* The first call to this function initializes the opcode handler jump table */ - if(!emulation_initialized) - { - m68ki_build_opcode_table(); - emulation_initialized = 1; - } + /* The first call to this function initializes the opcode handler jump table */ + if(!emulation_initialized) + { + m68ki_build_opcode_table(); + emulation_initialized = 1; + } - m68k_set_int_ack_callback(NULL); - m68k_set_bkpt_ack_callback(NULL); - m68k_set_reset_instr_callback(NULL); - m68k_set_cmpild_instr_callback(NULL); - m68k_set_rte_instr_callback(NULL); - m68k_set_tas_instr_callback(NULL); - m68k_set_illg_instr_callback(NULL); - m68k_set_pc_changed_callback(NULL); - m68k_set_fc_callback(NULL); - m68k_set_instr_hook_callback(NULL); + m68k_set_int_ack_callback(NULL); + m68k_set_bkpt_ack_callback(NULL); + m68k_set_reset_instr_callback(NULL); + m68k_set_cmpild_instr_callback(NULL); + m68k_set_rte_instr_callback(NULL); + m68k_set_tas_instr_callback(NULL); + m68k_set_illg_instr_callback(NULL); + m68k_set_pc_changed_callback(NULL); + m68k_set_fc_callback(NULL); + m68k_set_instr_hook_callback(NULL); } /* Trigger a Bus Error exception */ void m68k_pulse_bus_error(void) { - m68ki_exception_bus_error(); + m68ki_exception_bus_error(); } /* Pulse the RESET line on the CPU */ void m68k_pulse_reset(void) { - /* Disable the PMMU on reset */ - m68ki_cpu.pmmu_enabled = 0; + /* Disable the PMMU on reset */ + m68ki_cpu.pmmu_enabled = 0; - /* Clear all stop levels and eat up all remaining cycles */ - CPU_STOPPED = 0; - SET_CYCLES(0); + /* Clear all stop levels and eat up all remaining cycles */ + CPU_STOPPED = 0; + SET_CYCLES(0); - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; - CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; + CPU_INSTR_MODE = INSTRUCTION_YES; - /* Turn off tracing */ - FLAG_T1 = FLAG_T0 = 0; - m68ki_clear_trace(); - /* Interrupt mask to level 7 */ - FLAG_INT_MASK = 0x0700; - CPU_INT_LEVEL = 0; - m68ki_cpu.virq_state = 0; - /* Reset VBR */ - REG_VBR = 0; - /* Go to supervisor mode */ - m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); + /* Turn off tracing */ + FLAG_T1 = FLAG_T0 = 0; + m68ki_clear_trace(); + /* Interrupt mask to level 7 */ + FLAG_INT_MASK = 0x0700; + CPU_INT_LEVEL = 0; + m68ki_cpu.virq_state = 0; + /* Reset VBR */ + REG_VBR = 0; + /* Go to supervisor mode */ + m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); - /* Invalidate the prefetch queue */ + /* Invalidate the prefetch queue */ #if M68K_EMULATE_PREFETCH - /* Set to arbitrary number since our first fetch is from 0 */ - CPU_PREF_ADDR = 0x1000; + /* Set to arbitrary number since our first fetch is from 0 */ + CPU_PREF_ADDR = 0x1000; #endif /* M68K_EMULATE_PREFETCH */ - /* Read the initial stack pointer and program counter */ - m68ki_jump(0); - REG_SP = m68ki_read_imm_32(); - REG_PC = m68ki_read_imm_32(); - m68ki_jump(REG_PC); + /* Read the initial stack pointer and program counter */ + m68ki_jump(0); + REG_SP = m68ki_read_imm_32(); + REG_PC = m68ki_read_imm_32(); + m68ki_jump(REG_PC); - CPU_RUN_MODE = RUN_MODE_NORMAL; + CPU_RUN_MODE = RUN_MODE_NORMAL; - RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET]; + RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET]; } /* Pulse the HALT line on the CPU */ void m68k_pulse_halt(void) { - CPU_STOPPED |= STOP_LEVEL_HALT; + CPU_STOPPED |= STOP_LEVEL_HALT; } /* Get and set the current CPU context */ /* This is to allow for multiple CPUs */ unsigned int m68k_context_size() { - return sizeof(m68ki_cpu_core); + return sizeof(m68ki_cpu_core); } unsigned int m68k_get_context(void* dst) { - if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu; - return sizeof(m68ki_cpu_core); + if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu; + return sizeof(m68ki_cpu_core); } void m68k_set_context(void* src) { - if(src) m68ki_cpu = *(m68ki_cpu_core*)src; + if(src) m68ki_cpu = *(m68ki_cpu_core*)src; } /* ======================================================================== */ @@ -1174,48 +1174,48 @@ void m68k_set_context(void* src) #if M68K_COMPILE_FOR_MAME == OPT_ON static struct { - UINT16 sr; - UINT8 stopped; - UINT8 halted; + UINT16 sr; + UINT8 stopped; + UINT8 halted; } m68k_substate; static void m68k_prepare_substate(void) { - m68k_substate.sr = m68ki_get_sr(); - m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0; - m68k_substate.halted = (CPU_STOPPED & STOP_LEVEL_HALT) != 0; + m68k_substate.sr = m68ki_get_sr(); + m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0; + m68k_substate.halted = (CPU_STOPPED & STOP_LEVEL_HALT) != 0; } static void m68k_post_load(void) { - m68ki_set_sr_noint_nosp(m68k_substate.sr); - CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0 - | m68k_substate.halted ? STOP_LEVEL_HALT : 0; - m68ki_jump(REG_PC); + m68ki_set_sr_noint_nosp(m68k_substate.sr); + CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0 + | m68k_substate.halted ? STOP_LEVEL_HALT : 0; + m68ki_jump(REG_PC); } void m68k_state_register(const char *type, int index) { - /* Note, D covers A because the dar array is common, REG_A=REG_D+8 */ - state_save_register_item_array(type, index, REG_D); - state_save_register_item(type, index, REG_PPC); - state_save_register_item(type, index, REG_PC); - state_save_register_item(type, index, REG_USP); - state_save_register_item(type, index, REG_ISP); - state_save_register_item(type, index, REG_MSP); - state_save_register_item(type, index, REG_VBR); - state_save_register_item(type, index, REG_SFC); - state_save_register_item(type, index, REG_DFC); - state_save_register_item(type, index, REG_CACR); - state_save_register_item(type, index, REG_CAAR); - state_save_register_item(type, index, m68k_substate.sr); - state_save_register_item(type, index, CPU_INT_LEVEL); - state_save_register_item(type, index, m68k_substate.stopped); - state_save_register_item(type, index, m68k_substate.halted); - state_save_register_item(type, index, CPU_PREF_ADDR); - state_save_register_item(type, index, CPU_PREF_DATA); - state_save_register_func_presave(m68k_prepare_substate); - state_save_register_func_postload(m68k_post_load); + /* Note, D covers A because the dar array is common, REG_A=REG_D+8 */ + state_save_register_item_array(type, index, REG_D); + state_save_register_item(type, index, REG_PPC); + state_save_register_item(type, index, REG_PC); + state_save_register_item(type, index, REG_USP); + state_save_register_item(type, index, REG_ISP); + state_save_register_item(type, index, REG_MSP); + state_save_register_item(type, index, REG_VBR); + state_save_register_item(type, index, REG_SFC); + state_save_register_item(type, index, REG_DFC); + state_save_register_item(type, index, REG_CACR); + state_save_register_item(type, index, REG_CAAR); + state_save_register_item(type, index, m68k_substate.sr); + state_save_register_item(type, index, CPU_INT_LEVEL); + state_save_register_item(type, index, m68k_substate.stopped); + state_save_register_item(type, index, m68k_substate.halted); + state_save_register_item(type, index, CPU_PREF_ADDR); + state_save_register_item(type, index, CPU_PREF_DATA); + state_save_register_func_presave(m68k_prepare_substate); + state_save_register_func_postload(m68k_post_load); } #endif /* M68K_COMPILE_FOR_MAME */ diff --git a/AltairZ80/m68k/m68kcpu.h b/AltairZ80/m68k/m68kcpu.h index 5adca63e..5befb393 100755 --- a/AltairZ80/m68k/m68kcpu.h +++ b/AltairZ80/m68k/m68kcpu.h @@ -49,9 +49,9 @@ extern "C" { /* Check for > 32bit sizes */ #if UINT_MAX > 0xffffffff - #define M68K_INT_GT_32_BIT 1 + #define M68K_INT_GT_32_BIT 1 #else - #define M68K_INT_GT_32_BIT 0 + #define M68K_INT_GT_32_BIT 0 #endif /* Data types used in this emulation core */ @@ -66,9 +66,9 @@ extern "C" { #undef sint #undef uint -typedef signed char sint8; /* ASG: changed from char to signed char */ +typedef signed char sint8; /* ASG: changed from char to signed char */ typedef signed short sint16; -typedef signed int sint32; /* AWJ: changed from long to int */ +typedef signed int sint32; /* AWJ: changed from long to int */ /* signed and unsigned int must be at least 32 bits wide */ typedef signed int sint; @@ -98,46 +98,46 @@ typedef uint32 uint64; /* Allow for architectures that don't have 8-bit sizes */ #if UCHAR_MAX == 0xff - #define MAKE_INT_8(A) (sint8)(A) + #define MAKE_INT_8(A) (sint8)(A) #else - #undef sint8 - #define sint8 signed int - #undef uint8 - #define uint8 unsigned int - static inline sint MAKE_INT_8(uint value) - { - return (value & 0x80) ? value | ~0xff : value & 0xff; - } + #undef sint8 + #define sint8 signed int + #undef uint8 + #define uint8 unsigned int + static inline sint MAKE_INT_8(uint value) + { + return (value & 0x80) ? value | ~0xff : value & 0xff; + } #endif /* UCHAR_MAX == 0xff */ /* Allow for architectures that don't have 16-bit sizes */ #if USHRT_MAX == 0xffff - #define MAKE_INT_16(A) (sint16)(A) + #define MAKE_INT_16(A) (sint16)(A) #else - #undef sint16 - #define sint16 signed int - #undef uint16 - #define uint16 unsigned int - static inline sint MAKE_INT_16(uint value) - { - return (value & 0x8000) ? value | ~0xffff : value & 0xffff; - } + #undef sint16 + #define sint16 signed int + #undef uint16 + #define uint16 unsigned int + static inline sint MAKE_INT_16(uint value) + { + return (value & 0x8000) ? value | ~0xffff : value & 0xffff; + } #endif /* USHRT_MAX == 0xffff */ /* Allow for architectures that don't have 32-bit sizes */ #if UINT_MAX == 0xffffffff - #define MAKE_INT_32(A) (sint32)(A) + #define MAKE_INT_32(A) (sint32)(A) #else - #undef sint32 - #define sint32 signed int - #undef uint32 - #define uint32 unsigned int - static inline sint MAKE_INT_32(uint value) - { - return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; - } + #undef sint32 + #define sint32 signed int + #undef uint32 + #define uint32 unsigned int + static inline sint MAKE_INT_32(uint value) + { + return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; + } #endif /* UINT_MAX == 0xffffffff */ @@ -173,7 +173,7 @@ typedef uint32 uint64; #define FUNCTION_CODE_CPU_SPACE 7 /* CPU types for deciding what to emulate */ -#define CPU_TYPE_000 (0x00000001) +#define CPU_TYPE_000 (0x00000001) #define CPU_TYPE_008 (0x00000002) #define CPU_TYPE_010 (0x00000004) #define CPU_TYPE_EC020 (0x00000008) @@ -268,11 +268,11 @@ typedef uint32 uint64; /* No need to mask if we are 32 bit */ #if M68K_INT_GT_32_BIT || M68K_USE_64_BIT - #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) - #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) + #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) + #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) #else - #define MASK_OUT_ABOVE_32(A) (A) - #define MASK_OUT_BELOW_32(A) 0 + #define MASK_OUT_ABOVE_32(A) (A) + #define MASK_OUT_BELOW_32(A) 0 #endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */ /* Simulate address lines of 68k family */ @@ -285,22 +285,22 @@ typedef uint32 uint64; /* Some > 32-bit optimizations */ #if M68K_INT_GT_32_BIT - /* Shift left and right */ - #define LSR_32(A, C) ((A) >> (C)) - #define LSL_32(A, C) ((A) << (C)) + /* Shift left and right */ + #define LSR_32(A, C) ((A) >> (C)) + #define LSL_32(A, C) ((A) << (C)) #else - /* We have to do this because the morons at ANSI decided that shifts - * by >= data size are undefined. - */ - #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) - #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) + /* We have to do this because the morons at ANSI decided that shifts + * by >= data size are undefined. + */ + #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) + #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) #endif /* M68K_INT_GT_32_BIT */ #if M68K_USE_64_BIT - #define LSL_32_64(A, C) ((A) << (C)) - #define LSR_32_64(A, C) ((A) >> (C)) - #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) - #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) + #define LSL_32_64(A, C) ((A) << (C)) + #define LSR_32_64(A, C) ((A) >> (C)) + #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) + #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) #endif /* M68K_USE_64_BIT */ #define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) @@ -328,7 +328,7 @@ typedef uint32 uint64; #define REG_DA_SAVE m68ki_cpu.dar_save #define REG_D m68ki_cpu.dar #define REG_A (m68ki_cpu.dar+8) -#define REG_PPC m68ki_cpu.ppc +#define REG_PPC m68ki_cpu.ppc #define REG_PC m68ki_cpu.pc #define REG_SP_BASE m68ki_cpu.sp #define REG_USP m68ki_cpu.sp[0] @@ -378,9 +378,9 @@ typedef uint32 uint64; #define CYC_MOVEM_L m68ki_cpu.cyc_movem_l #define CYC_SHIFT m68ki_cpu.cyc_shift #define CYC_RESET m68ki_cpu.cyc_reset -#define HAS_PMMU m68ki_cpu.has_pmmu -#define PMMU_ENABLED m68ki_cpu.pmmu_enabled -#define RESET_CYCLES m68ki_cpu.reset_cycles +#define HAS_PMMU m68ki_cpu.has_pmmu +#define PMMU_ENABLED m68ki_cpu.pmmu_enabled +#define RESET_CYCLES m68ki_cpu.reset_cycles #define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback @@ -403,56 +403,56 @@ typedef uint32 uint64; /* Disable certain comparisons if we're not using all CPU types */ #if M68K_EMULATE_040 #define CPU_TYPE_IS_040_PLUS(A) ((A) & (CPU_TYPE_040 | CPU_TYPE_EC040)) - #define CPU_TYPE_IS_040_LESS(A) 1 + #define CPU_TYPE_IS_040_LESS(A) 1 #else - #define CPU_TYPE_IS_040_PLUS(A) 0 - #define CPU_TYPE_IS_040_LESS(A) 1 + #define CPU_TYPE_IS_040_PLUS(A) 0 + #define CPU_TYPE_IS_040_LESS(A) 1 #endif #if M68K_EMULATE_030 #define CPU_TYPE_IS_030_PLUS(A) ((A) & (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)) #define CPU_TYPE_IS_030_LESS(A) 1 #else -#define CPU_TYPE_IS_030_PLUS(A) 0 +#define CPU_TYPE_IS_030_PLUS(A) 0 #define CPU_TYPE_IS_030_LESS(A) 1 #endif #if M68K_EMULATE_020 #define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)) - #define CPU_TYPE_IS_020_LESS(A) 1 + #define CPU_TYPE_IS_020_LESS(A) 1 #else - #define CPU_TYPE_IS_020_PLUS(A) 0 - #define CPU_TYPE_IS_020_LESS(A) 1 + #define CPU_TYPE_IS_020_PLUS(A) 0 + #define CPU_TYPE_IS_020_LESS(A) 1 #endif #if M68K_EMULATE_EC020 #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)) - #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020)) + #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020)) #else - #define CPU_TYPE_IS_EC020_PLUS(A) CPU_TYPE_IS_020_PLUS(A) - #define CPU_TYPE_IS_EC020_LESS(A) CPU_TYPE_IS_020_LESS(A) + #define CPU_TYPE_IS_EC020_PLUS(A) CPU_TYPE_IS_020_PLUS(A) + #define CPU_TYPE_IS_EC020_LESS(A) CPU_TYPE_IS_020_LESS(A) #endif #if M68K_EMULATE_010 - #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010) + #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010) #define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_040 | CPU_TYPE_EC040)) #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010)) #else - #define CPU_TYPE_IS_010(A) 0 - #define CPU_TYPE_IS_010_PLUS(A) CPU_TYPE_IS_EC020_PLUS(A) - #define CPU_TYPE_IS_010_LESS(A) CPU_TYPE_IS_EC020_LESS(A) + #define CPU_TYPE_IS_010(A) 0 + #define CPU_TYPE_IS_010_PLUS(A) CPU_TYPE_IS_EC020_PLUS(A) + #define CPU_TYPE_IS_010_LESS(A) CPU_TYPE_IS_EC020_LESS(A) #endif #if M68K_EMULATE_020 || M68K_EMULATE_EC020 - #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) + #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) #else - #define CPU_TYPE_IS_020_VARIANT(A) 0 + #define CPU_TYPE_IS_020_VARIANT(A) 0 #endif #if M68K_EMULATE_040 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010 - #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000) + #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000) #else - #define CPU_TYPE_IS_000(A) 1 + #define CPU_TYPE_IS_000(A) 1 #endif @@ -468,217 +468,217 @@ typedef uint32 uint64; /* Enable or disable callback functions */ #if M68K_EMULATE_INT_ACK - #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER - #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A) - #else - #define m68ki_int_ack(A) CALLBACK_INT_ACK(A) - #endif + #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER + #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A) + #else + #define m68ki_int_ack(A) CALLBACK_INT_ACK(A) + #endif #else - /* Default action is to used autovector mode, which is most common */ - #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR + /* Default action is to used autovector mode, which is most common */ + #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR #endif /* M68K_EMULATE_INT_ACK */ #if M68K_EMULATE_BKPT_ACK - #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER - #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A) - #else - #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A) - #endif + #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER + #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A) + #else + #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A) + #endif #else - #define m68ki_bkpt_ack(A) + #define m68ki_bkpt_ack(A) #endif /* M68K_EMULATE_BKPT_ACK */ #if M68K_EMULATE_RESET - #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER - #define m68ki_output_reset() M68K_RESET_CALLBACK() - #else - #define m68ki_output_reset() CALLBACK_RESET_INSTR() - #endif + #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER + #define m68ki_output_reset() M68K_RESET_CALLBACK() + #else + #define m68ki_output_reset() CALLBACK_RESET_INSTR() + #endif #else - #define m68ki_output_reset() + #define m68ki_output_reset() #endif /* M68K_EMULATE_RESET */ #if M68K_CMPILD_HAS_CALLBACK - #if M68K_CMPILD_HAS_CALLBACK == OPT_SPECIFY_HANDLER - #define m68ki_cmpild_callback(v,r) M68K_CMPILD_CALLBACK(v,r) - #else - #define m68ki_cmpild_callback(v,r) CALLBACK_CMPILD_INSTR(v,r) - #endif + #if M68K_CMPILD_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_cmpild_callback(v,r) M68K_CMPILD_CALLBACK(v,r) + #else + #define m68ki_cmpild_callback(v,r) CALLBACK_CMPILD_INSTR(v,r) + #endif #else - #define m68ki_cmpild_callback(v,r) + #define m68ki_cmpild_callback(v,r) #endif /* M68K_CMPILD_HAS_CALLBACK */ #if M68K_RTE_HAS_CALLBACK - #if M68K_RTE_HAS_CALLBACK == OPT_SPECIFY_HANDLER - #define m68ki_rte_callback() M68K_RTE_CALLBACK() - #else - #define m68ki_rte_callback() CALLBACK_RTE_INSTR() - #endif + #if M68K_RTE_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_rte_callback() M68K_RTE_CALLBACK() + #else + #define m68ki_rte_callback() CALLBACK_RTE_INSTR() + #endif #else - #define m68ki_rte_callback() + #define m68ki_rte_callback() #endif /* M68K_RTE_HAS_CALLBACK */ #if M68K_TAS_HAS_CALLBACK - #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER - #define m68ki_tas_callback() M68K_TAS_CALLBACK() - #else - #define m68ki_tas_callback() CALLBACK_TAS_INSTR() - #endif + #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_tas_callback() M68K_TAS_CALLBACK() + #else + #define m68ki_tas_callback() CALLBACK_TAS_INSTR() + #endif #else - #define m68ki_tas_callback() 1 + #define m68ki_tas_callback() 1 #endif /* M68K_TAS_HAS_CALLBACK */ #if M68K_ILLG_HAS_CALLBACK - #if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER - #define m68ki_illg_callback(opcode) M68K_ILLG_CALLBACK(opcode) - #else - #define m68ki_illg_callback(opcode) CALLBACK_ILLG_INSTR(opcode) - #endif + #if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_illg_callback(opcode) M68K_ILLG_CALLBACK(opcode) + #else + #define m68ki_illg_callback(opcode) CALLBACK_ILLG_INSTR(opcode) + #endif #else - #define m68ki_illg_callback(opcode) 0 // Default is 0 = not handled, exception will occur + #define m68ki_illg_callback(opcode) 0 // Default is 0 = not handled, exception will occur #endif /* M68K_ILLG_HAS_CALLBACK */ #if M68K_INSTRUCTION_HOOK - #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER - #define m68ki_instr_hook(pc) M68K_INSTRUCTION_CALLBACK(pc) - #else - #define m68ki_instr_hook(pc) CALLBACK_INSTR_HOOK(pc) - #endif + #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER + #define m68ki_instr_hook(pc) M68K_INSTRUCTION_CALLBACK(pc) + #else + #define m68ki_instr_hook(pc) CALLBACK_INSTR_HOOK(pc) + #endif #else - #define m68ki_instr_hook(pc) + #define m68ki_instr_hook(pc) #endif /* M68K_INSTRUCTION_HOOK */ #if M68K_MONITOR_PC - #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER - #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A)) - #else - #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A)) - #endif + #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER + #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A)) + #else + #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A)) + #endif #else - #define m68ki_pc_changed(A) + #define m68ki_pc_changed(A) #endif /* M68K_MONITOR_PC */ /* Enable or disable function code emulation */ #if M68K_EMULATE_FC - #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER - #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A) - #else - #define m68ki_set_fc(A) CALLBACK_SET_FC(A) - #endif - #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA - #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM - #define m68ki_get_address_space() m68ki_address_space + #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER + #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A) + #else + #define m68ki_set_fc(A) CALLBACK_SET_FC(A) + #endif + #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA + #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM + #define m68ki_get_address_space() m68ki_address_space #else - #define m68ki_set_fc(A) - #define m68ki_use_data_space() - #define m68ki_use_program_space() - #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA + #define m68ki_set_fc(A) + #define m68ki_use_data_space() + #define m68ki_use_program_space() + #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA #endif /* M68K_EMULATE_FC */ /* Enable or disable trace emulation */ #if M68K_EMULATE_TRACE - /* Initiates trace checking before each instruction (t1) */ - #define m68ki_trace_t1() m68ki_tracing = FLAG_T1 - /* adds t0 to trace checking if we encounter change of flow */ - #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0 - /* Clear all tracing */ - #define m68ki_clear_trace() m68ki_tracing = 0 - /* Cause a trace exception if we are tracing */ - #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace() + /* Initiates trace checking before each instruction (t1) */ + #define m68ki_trace_t1() m68ki_tracing = FLAG_T1 + /* adds t0 to trace checking if we encounter change of flow */ + #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0 + /* Clear all tracing */ + #define m68ki_clear_trace() m68ki_tracing = 0 + /* Cause a trace exception if we are tracing */ + #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace() #else - #define m68ki_trace_t1() - #define m68ki_trace_t0() - #define m68ki_clear_trace() - #define m68ki_exception_if_trace() + #define m68ki_trace_t1() + #define m68ki_trace_t0() + #define m68ki_clear_trace() + #define m68ki_exception_if_trace() #endif /* M68K_EMULATE_TRACE */ /* Address error */ #if M68K_EMULATE_ADDRESS_ERROR - #include + #include /* sigjmp() on Mac OS X and *BSD in general saves signal contexts and is super-slow, use sigsetjmp() to tell it not to */ #ifdef _BSD_SETJMP_H extern sigjmp_buf m68ki_aerr_trap; #define m68ki_set_address_error_trap(m68k) \ - if(sigsetjmp(m68ki_aerr_trap, 0) != 0) \ - { \ - m68ki_exception_address_error(m68k); \ - if(CPU_STOPPED) \ - { \ - if (m68ki_remaining_cycles > 0) \ - m68ki_remaining_cycles = 0; \ - return m68ki_initial_cycles; \ - } \ - } + if(sigsetjmp(m68ki_aerr_trap, 0) != 0) \ + { \ + m68ki_exception_address_error(m68k); \ + if(CPU_STOPPED) \ + { \ + if (m68ki_remaining_cycles > 0) \ + m68ki_remaining_cycles = 0; \ + return m68ki_initial_cycles; \ + } \ + } #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ - if((ADDR)&1) \ - { \ - m68ki_aerr_address = ADDR; \ - m68ki_aerr_write_mode = WRITE_MODE; \ - m68ki_aerr_fc = FC; \ - siglongjmp(m68ki_aerr_trap, 1); \ - } + if((ADDR)&1) \ + { \ + m68ki_aerr_address = ADDR; \ + m68ki_aerr_write_mode = WRITE_MODE; \ + m68ki_aerr_fc = FC; \ + siglongjmp(m68ki_aerr_trap, 1); \ + } #else extern jmp_buf m68ki_aerr_trap; - #define m68ki_set_address_error_trap() \ - if(setjmp(m68ki_aerr_trap) != 0) \ - { \ - m68ki_exception_address_error(); \ - if(CPU_STOPPED) \ - { \ - SET_CYCLES(0); \ - return m68ki_initial_cycles; \ - } \ - /* ensure we don't re-enter execution loop after an - address error if there's no more cycles remaining */ \ - if(GET_CYCLES() <= 0) \ - { \ - /* return how many clocks we used */ \ - return m68ki_initial_cycles - GET_CYCLES(); \ - } \ - } + #define m68ki_set_address_error_trap() \ + if(setjmp(m68ki_aerr_trap) != 0) \ + { \ + m68ki_exception_address_error(); \ + if(CPU_STOPPED) \ + { \ + SET_CYCLES(0); \ + return m68ki_initial_cycles; \ + } \ + /* ensure we don't re-enter execution loop after an + address error if there's no more cycles remaining */ \ + if(GET_CYCLES() <= 0) \ + { \ + /* return how many clocks we used */ \ + return m68ki_initial_cycles - GET_CYCLES(); \ + } \ + } - #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ - if((ADDR)&1) \ - { \ - m68ki_aerr_address = ADDR; \ - m68ki_aerr_write_mode = WRITE_MODE; \ - m68ki_aerr_fc = FC; \ - longjmp(m68ki_aerr_trap, 1); \ - } + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ + if((ADDR)&1) \ + { \ + m68ki_aerr_address = ADDR; \ + m68ki_aerr_write_mode = WRITE_MODE; \ + m68ki_aerr_fc = FC; \ + longjmp(m68ki_aerr_trap, 1); \ + } #endif - #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) \ - if (CPU_TYPE_IS_010_LESS(CPU_TYPE)) \ - { \ - m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ - } + #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) \ + if (CPU_TYPE_IS_010_LESS(CPU_TYPE)) \ + { \ + m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ + } #else - #define m68ki_set_address_error_trap() - #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) - #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) + #define m68ki_set_address_error_trap() + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) + #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) #endif /* M68K_ADDRESS_ERROR */ /* Logging */ #if M68K_LOG_ENABLE - #include - extern FILE* M68K_LOG_FILEHANDLE - extern const char *const m68ki_cpu_names[]; + #include + extern FILE* M68K_LOG_FILEHANDLE + extern const char *const m68ki_cpu_names[]; - #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A - #if M68K_LOG_1010_1111 - #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A - #else - #define M68K_DO_LOG_EMU(A) - #endif + #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A + #if M68K_LOG_1010_1111 + #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A + #else + #define M68K_DO_LOG_EMU(A) + #endif #else - #define M68K_DO_LOG(A) - #define M68K_DO_LOG_EMU(A) + #define M68K_DO_LOG(A) + #define M68K_DO_LOG_EMU(A) #endif @@ -761,11 +761,11 @@ extern jmp_buf m68ki_aerr_trap; #define CFLAG_16(A) ((A)>>8) #if M68K_INT_GT_32_BIT - #define CFLAG_ADD_32(S, D, R) ((R)>>24) - #define CFLAG_SUB_32(S, D, R) ((R)>>24) + #define CFLAG_ADD_32(S, D, R) ((R)>>24) + #define CFLAG_SUB_32(S, D, R) ((R)>>24) #else - #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) - #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) + #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) + #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) #endif /* M68K_INT_GT_32_BIT */ #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) @@ -850,18 +850,18 @@ extern jmp_buf m68ki_aerr_trap; /* Get the condition code register */ #define m68ki_get_ccr() ((COND_XS() >> 4) | \ - (COND_MI() >> 4) | \ - (COND_EQ() << 2) | \ - (COND_VS() >> 6) | \ - (COND_CS() >> 8)) + (COND_MI() >> 4) | \ + (COND_EQ() << 2) | \ + (COND_VS() >> 6) | \ + (COND_CS() >> 8)) /* Get the status register */ #define m68ki_get_sr() ( FLAG_T1 | \ - FLAG_T0 | \ - (FLAG_S << 11) | \ - (FLAG_M << 11) | \ - FLAG_INT_MASK | \ - m68ki_get_ccr()) + FLAG_T0 | \ + (FLAG_S << 11) | \ + (FLAG_M << 11) | \ + FLAG_INT_MASK | \ + m68ki_get_ccr()) @@ -899,14 +899,14 @@ extern jmp_buf m68ki_aerr_trap; #define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A) /* Read from the program space */ -#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) -#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) -#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* Read from the data space */ -#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) -#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) -#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) @@ -916,87 +916,87 @@ extern jmp_buf m68ki_aerr_trap; typedef union { - uint64 i; - double f; + uint64 i; + double f; } fp_reg; typedef struct { - uint cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */ - uint dar[16]; /* Data and Address Registers */ - uint dar_save[16]; /* Saved Data and Address Registers (pushed onto the - stack when a bus error occurs)*/ - uint ppc; /* Previous program counter */ - uint pc; /* Program Counter */ - uint sp[7]; /* User, Interrupt, and Master Stack Pointers */ - uint vbr; /* Vector Base Register (m68010+) */ - uint sfc; /* Source Function Code Register (m68010+) */ - uint dfc; /* Destination Function Code Register (m68010+) */ - uint cacr; /* Cache Control Register (m68020, unemulated) */ - uint caar; /* Cache Address Register (m68020, unemulated) */ - uint ir; /* Instruction Register */ - floatx80 fpr[8]; /* FPU Data Register (m68030/040) */ - uint fpiar; /* FPU Instruction Address Register (m68040) */ - uint fpsr; /* FPU Status Register (m68040) */ - uint fpcr; /* FPU Control Register (m68040) */ - uint t1_flag; /* Trace 1 */ - uint t0_flag; /* Trace 0 */ - uint s_flag; /* Supervisor */ - uint m_flag; /* Master/Interrupt state */ - uint x_flag; /* Extend */ - uint n_flag; /* Negative */ - uint not_z_flag; /* Zero, inverted for speedups */ - uint v_flag; /* Overflow */ - uint c_flag; /* Carry */ - uint int_mask; /* I0-I2 */ - uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */ - uint stopped; /* Stopped state */ - uint pref_addr; /* Last prefetch address */ - uint pref_data; /* Data in the prefetch queue */ - uint address_mask; /* Available address pins */ - uint sr_mask; /* Implemented status register bits */ - uint instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ - uint run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ - int has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ - int pmmu_enabled; /* Indicates if the PMMU is enabled */ - int fpu_just_reset; /* Indicates the FPU was just reset */ - uint reset_cycles; + uint cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */ + uint dar[16]; /* Data and Address Registers */ + uint dar_save[16]; /* Saved Data and Address Registers (pushed onto the + stack when a bus error occurs)*/ + uint ppc; /* Previous program counter */ + uint pc; /* Program Counter */ + uint sp[7]; /* User, Interrupt, and Master Stack Pointers */ + uint vbr; /* Vector Base Register (m68010+) */ + uint sfc; /* Source Function Code Register (m68010+) */ + uint dfc; /* Destination Function Code Register (m68010+) */ + uint cacr; /* Cache Control Register (m68020, unemulated) */ + uint caar; /* Cache Address Register (m68020, unemulated) */ + uint ir; /* Instruction Register */ + floatx80 fpr[8]; /* FPU Data Register (m68030/040) */ + uint fpiar; /* FPU Instruction Address Register (m68040) */ + uint fpsr; /* FPU Status Register (m68040) */ + uint fpcr; /* FPU Control Register (m68040) */ + uint t1_flag; /* Trace 1 */ + uint t0_flag; /* Trace 0 */ + uint s_flag; /* Supervisor */ + uint m_flag; /* Master/Interrupt state */ + uint x_flag; /* Extend */ + uint n_flag; /* Negative */ + uint not_z_flag; /* Zero, inverted for speedups */ + uint v_flag; /* Overflow */ + uint c_flag; /* Carry */ + uint int_mask; /* I0-I2 */ + uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */ + uint stopped; /* Stopped state */ + uint pref_addr; /* Last prefetch address */ + uint pref_data; /* Data in the prefetch queue */ + uint address_mask; /* Available address pins */ + uint sr_mask; /* Implemented status register bits */ + uint instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ + uint run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ + int has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ + int pmmu_enabled; /* Indicates if the PMMU is enabled */ + int fpu_just_reset; /* Indicates the FPU was just reset */ + uint reset_cycles; - /* Clocks required for instructions / exceptions */ - uint cyc_bcc_notake_b; - uint cyc_bcc_notake_w; - uint cyc_dbcc_f_noexp; - uint cyc_dbcc_f_exp; - uint cyc_scc_r_true; - uint cyc_movem_w; - uint cyc_movem_l; - uint cyc_shift; - uint cyc_reset; + /* Clocks required for instructions / exceptions */ + uint cyc_bcc_notake_b; + uint cyc_bcc_notake_w; + uint cyc_dbcc_f_noexp; + uint cyc_dbcc_f_exp; + uint cyc_scc_r_true; + uint cyc_movem_w; + uint cyc_movem_l; + uint cyc_shift; + uint cyc_reset; - /* Virtual IRQ lines state */ - uint virq_state; - uint nmi_pending; + /* Virtual IRQ lines state */ + uint virq_state; + uint nmi_pending; - /* PMMU registers */ - uint mmu_crp_aptr, mmu_crp_limit; - uint mmu_srp_aptr, mmu_srp_limit; - uint mmu_tc; - uint16 mmu_sr; + /* PMMU registers */ + uint mmu_crp_aptr, mmu_crp_limit; + uint mmu_srp_aptr, mmu_srp_limit; + uint mmu_tc; + uint16 mmu_sr; - const uint8* cyc_instruction; - const uint8* cyc_exception; + const uint8* cyc_instruction; + const uint8* cyc_exception; - /* Callbacks to host */ - int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */ - void (*bkpt_ack_callback)(unsigned int data); /* Breakpoint Acknowledge */ - void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */ - void (*cmpild_instr_callback)(unsigned int, int); /* Called when a CMPI.L #v, Dn instruction is encountered */ - void (*rte_instr_callback)(void); /* Called when a RTE instruction is encountered */ - int (*tas_instr_callback)(void); /* Called when a TAS instruction is encountered, allows / disallows writeback */ - int (*illg_instr_callback)(int); /* Called when an illegal instruction is encountered, allows handling */ - void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */ - void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */ - void (*instr_hook_callback)(unsigned int pc); /* Called every instruction cycle prior to execution */ + /* Callbacks to host */ + int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */ + void (*bkpt_ack_callback)(unsigned int data); /* Breakpoint Acknowledge */ + void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */ + void (*cmpild_instr_callback)(unsigned int, int); /* Called when a CMPI.L #v, Dn instruction is encountered */ + void (*rte_instr_callback)(void); /* Called when a RTE instruction is encountered */ + int (*tas_instr_callback)(void); /* Called when a TAS instruction is encountered, allows / disallows writeback */ + int (*illg_instr_callback)(int); /* Called when an illegal instruction is encountered, allows handling */ + void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */ + void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */ + void (*instr_hook_callback)(unsigned int pc); /* Called every instruction cycle prior to execution */ } m68ki_cpu_core; @@ -1039,78 +1039,78 @@ extern uint pmmu_translate_addr(uint addr_in); */ static inline uint m68ki_read_imm_16(void) { - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ #if M68K_SEPARATE_READS #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif #endif #if M68K_EMULATE_PREFETCH { - uint result; - if(REG_PC != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = REG_PC; - CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); - } - result = MASK_OUT_ABOVE_16(CPU_PREF_DATA); - REG_PC += 2; - CPU_PREF_ADDR = REG_PC; - CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); - return result; + uint result; + if(REG_PC != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + } + result = MASK_OUT_ABOVE_16(CPU_PREF_DATA); + REG_PC += 2; + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + return result; } #else - REG_PC += 2; - return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2)); + REG_PC += 2; + return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2)); #endif /* M68K_EMULATE_PREFETCH */ } static inline uint m68ki_read_imm_8(void) { - /* map read immediate 8 to read immediate 16 */ - return MASK_OUT_ABOVE_8(m68ki_read_imm_16()); + /* map read immediate 8 to read immediate 16 */ + return MASK_OUT_ABOVE_8(m68ki_read_imm_16()); } static inline uint m68ki_read_imm_32(void) { #if M68K_SEPARATE_READS #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif #endif #if M68K_EMULATE_PREFETCH - uint temp_val; + uint temp_val; - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - if(REG_PC != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = REG_PC; - CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); - } - temp_val = MASK_OUT_ABOVE_16(CPU_PREF_DATA); - REG_PC += 2; - CPU_PREF_ADDR = REG_PC; - CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + if(REG_PC != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + } + temp_val = MASK_OUT_ABOVE_16(CPU_PREF_DATA); + REG_PC += 2; + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); - temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(CPU_PREF_DATA)); - REG_PC += 2; - CPU_PREF_ADDR = REG_PC; - CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(CPU_PREF_DATA)); + REG_PC += 2; + CPU_PREF_ADDR = REG_PC; + CPU_PREF_DATA = m68k_read_immediate_16(ADDRESS_68K(CPU_PREF_ADDR)); - return temp_val; + return temp_val; #else - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ - REG_PC += 4; - return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4)); + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + REG_PC += 4; + return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4)); #endif /* M68K_EMULATE_PREFETCH */ } @@ -1124,95 +1124,95 @@ static inline uint m68ki_read_imm_32(void) */ static inline uint m68ki_read_8_fc(uint address, uint fc) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - return m68k_read_memory_8(ADDRESS_68K(address)); + return m68k_read_memory_8(ADDRESS_68K(address)); } static inline uint m68ki_read_16_fc(uint address, uint fc) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - return m68k_read_memory_16(ADDRESS_68K(address)); + return m68k_read_memory_16(ADDRESS_68K(address)); } static inline uint m68ki_read_32_fc(uint address, uint fc) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - return m68k_read_memory_32(ADDRESS_68K(address)); + return m68k_read_memory_32(ADDRESS_68K(address)); } static inline void m68ki_write_8_fc(uint address, uint fc, uint value) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - m68k_write_memory_8(ADDRESS_68K(address), value); + m68k_write_memory_8(ADDRESS_68K(address), value); } static inline void m68ki_write_16_fc(uint address, uint fc, uint value) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - m68k_write_memory_16(ADDRESS_68K(address), value); + m68k_write_memory_16(ADDRESS_68K(address), value); } static inline void m68ki_write_32_fc(uint address, uint fc, uint value) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - m68k_write_memory_32(ADDRESS_68K(address), value); + m68k_write_memory_32(ADDRESS_68K(address), value); } #if M68K_SIMULATE_PD_WRITES static inline void m68ki_write_32_pd_fc(uint address, uint fc, uint value) { - (void)fc; - m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ + (void)fc; + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ #if M68K_EMULATE_PMMU - if (PMMU_ENABLED) - address = pmmu_translate_addr(address); + if (PMMU_ENABLED) + address = pmmu_translate_addr(address); #endif - m68k_write_memory_32_pd(ADDRESS_68K(address), value); + m68k_write_memory_32_pd(ADDRESS_68K(address), value); } #endif @@ -1223,16 +1223,16 @@ static inline void m68ki_write_32_pd_fc(uint address, uint fc, uint value) */ static inline uint m68ki_get_ea_pcdi(void) { - uint old_pc = REG_PC; - m68ki_use_program_space(); /* auto-disable */ - return old_pc + MAKE_INT_16(m68ki_read_imm_16()); + uint old_pc = REG_PC; + m68ki_use_program_space(); /* auto-disable */ + return old_pc + MAKE_INT_16(m68ki_read_imm_16()); } static inline uint m68ki_get_ea_pcix(void) { - m68ki_use_program_space(); /* auto-disable */ - return m68ki_get_ea_ix(REG_PC); + m68ki_use_program_space(); /* auto-disable */ + return m68ki_get_ea_ix(REG_PC); } /* Indexed addressing modes are encoded as follows: @@ -1279,73 +1279,73 @@ static inline uint m68ki_get_ea_pcix(void) */ static inline uint m68ki_get_ea_ix(uint An) { - /* An = base register */ - uint extension = m68ki_read_imm_16(); - uint Xn = 0; /* Index register */ - uint bd = 0; /* Base Displacement */ - uint od = 0; /* Outer Displacement */ + /* An = base register */ + uint extension = m68ki_read_imm_16(); + uint Xn = 0; /* Index register */ + uint bd = 0; /* Base Displacement */ + uint od = 0; /* Outer Displacement */ - if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) - { - /* Calculate index */ - Xn = REG_DA[extension>>12]; /* Xn */ - if(!BIT_B(extension)) /* W/L */ - Xn = MAKE_INT_16(Xn); + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) + { + /* Calculate index */ + Xn = REG_DA[extension>>12]; /* Xn */ + if(!BIT_B(extension)) /* W/L */ + Xn = MAKE_INT_16(Xn); - /* Add base register and displacement and return */ - return An + Xn + MAKE_INT_8(extension); - } + /* Add base register and displacement and return */ + return An + Xn + MAKE_INT_8(extension); + } - /* Brief extension format */ - if(!BIT_8(extension)) - { - /* Calculate index */ - Xn = REG_DA[extension>>12]; /* Xn */ - if(!BIT_B(extension)) /* W/L */ - Xn = MAKE_INT_16(Xn); - /* Add scale if proper CPU type */ - if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - Xn <<= (extension>>9) & 3; /* SCALE */ + /* Brief extension format */ + if(!BIT_8(extension)) + { + /* Calculate index */ + Xn = REG_DA[extension>>12]; /* Xn */ + if(!BIT_B(extension)) /* W/L */ + Xn = MAKE_INT_16(Xn); + /* Add scale if proper CPU type */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + Xn <<= (extension>>9) & 3; /* SCALE */ - /* Add base register and displacement and return */ - return An + Xn + MAKE_INT_8(extension); - } + /* Add base register and displacement and return */ + return An + Xn + MAKE_INT_8(extension); + } - /* Full extension format */ + /* Full extension format */ - USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]); + USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]); - /* Check if base register is present */ - if(BIT_7(extension)) /* BS */ - An = 0; /* An */ + /* Check if base register is present */ + if(BIT_7(extension)) /* BS */ + An = 0; /* An */ - /* Check if index is present */ - if(!BIT_6(extension)) /* IS */ - { - Xn = REG_DA[extension>>12]; /* Xn */ - if(!BIT_B(extension)) /* W/L */ - Xn = MAKE_INT_16(Xn); - Xn <<= (extension>>9) & 3; /* SCALE */ - } + /* Check if index is present */ + if(!BIT_6(extension)) /* IS */ + { + Xn = REG_DA[extension>>12]; /* Xn */ + if(!BIT_B(extension)) /* W/L */ + Xn = MAKE_INT_16(Xn); + Xn <<= (extension>>9) & 3; /* SCALE */ + } - /* Check if base displacement is present */ - if(BIT_5(extension)) /* BD SIZE */ - bd = BIT_4(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16()); + /* Check if base displacement is present */ + if(BIT_5(extension)) /* BD SIZE */ + bd = BIT_4(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16()); - /* If no indirect action, we are done */ - if(!(extension&7)) /* No Memory Indirect */ - return An + bd + Xn; + /* If no indirect action, we are done */ + if(!(extension&7)) /* No Memory Indirect */ + return An + bd + Xn; - /* Check if outer displacement is present */ - if(BIT_1(extension)) /* I/IS: od */ - od = BIT_0(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16()); + /* Check if outer displacement is present */ + if(BIT_1(extension)) /* I/IS: od */ + od = BIT_0(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16()); - /* Postindex */ - if(BIT_2(extension)) /* I/IS: 0 = preindex, 1 = postindex */ - return m68ki_read_32(An + bd) + Xn + od; + /* Postindex */ + if(BIT_2(extension)) /* I/IS: 0 = preindex, 1 = postindex */ + return m68ki_read_32(An + bd) + Xn + od; - /* Preindex */ - return m68ki_read_32(An + bd + Xn) + od; + /* Preindex */ + return m68ki_read_32(An + bd + Xn) + od; } @@ -1405,26 +1405,26 @@ static inline uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_re /* Push/pull data from the stack */ static inline void m68ki_push_16(uint value) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); - m68ki_write_16(REG_SP, value); + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); + m68ki_write_16(REG_SP, value); } static inline void m68ki_push_32(uint value) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); - m68ki_write_32(REG_SP, value); + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); + m68ki_write_32(REG_SP, value); } static inline uint m68ki_pull_16(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); - return m68ki_read_16(REG_SP-2); + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); + return m68ki_read_16(REG_SP-2); } static inline uint m68ki_pull_32(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); - return m68ki_read_32(REG_SP-4); + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); + return m68ki_read_32(REG_SP-4); } @@ -1433,22 +1433,22 @@ static inline uint m68ki_pull_32(void) */ static inline void m68ki_fake_push_16(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); } static inline void m68ki_fake_push_32(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); } static inline void m68ki_fake_pull_16(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); } static inline void m68ki_fake_pull_32(void) { - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); } @@ -1460,15 +1460,15 @@ static inline void m68ki_fake_pull_32(void) */ static inline void m68ki_jump(uint new_pc) { - REG_PC = new_pc; - m68ki_pc_changed(REG_PC); + REG_PC = new_pc; + m68ki_pc_changed(REG_PC); } static inline void m68ki_jump_vector(uint vector) { - REG_PC = (vector<<2) + REG_VBR; - REG_PC = m68ki_read_data_32(REG_PC); - m68ki_pc_changed(REG_PC); + REG_PC = (vector<<2) + REG_VBR; + REG_PC = m68ki_read_data_32(REG_PC); + m68ki_pc_changed(REG_PC); } @@ -1479,18 +1479,18 @@ static inline void m68ki_jump_vector(uint vector) */ static inline void m68ki_branch_8(uint offset) { - REG_PC += MAKE_INT_8(offset); + REG_PC += MAKE_INT_8(offset); } static inline void m68ki_branch_16(uint offset) { - REG_PC += MAKE_INT_16(offset); + REG_PC += MAKE_INT_16(offset); } static inline void m68ki_branch_32(uint offset) { - REG_PC += offset; - m68ki_pc_changed(REG_PC); + REG_PC += offset; + m68ki_pc_changed(REG_PC); } /* ---------------------------- Status Register --------------------------- */ @@ -1500,12 +1500,12 @@ static inline void m68ki_branch_32(uint offset) */ static inline void m68ki_set_s_flag(uint value) { - /* Backup the old stack pointer */ - REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; - /* Set the S flag */ - FLAG_S = value; - /* Set the new stack pointer */ - REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; + /* Backup the old stack pointer */ + REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; + /* Set the S flag */ + FLAG_S = value; + /* Set the new stack pointer */ + REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; } /* Set the S and M flags and change the active stack pointer. @@ -1513,46 +1513,46 @@ static inline void m68ki_set_s_flag(uint value) */ static inline void m68ki_set_sm_flag(uint value) { - /* Backup the old stack pointer */ - REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; - /* Set the S and M flags */ - FLAG_S = value & SFLAG_SET; - FLAG_M = value & MFLAG_SET; - /* Set the new stack pointer */ - REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; + /* Backup the old stack pointer */ + REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; + /* Set the S and M flags */ + FLAG_S = value & SFLAG_SET; + FLAG_M = value & MFLAG_SET; + /* Set the new stack pointer */ + REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; } /* Set the S and M flags. Don't touch the stack pointer. */ static inline void m68ki_set_sm_flag_nosp(uint value) { - /* Set the S and M flags */ - FLAG_S = value & SFLAG_SET; - FLAG_M = value & MFLAG_SET; + /* Set the S and M flags */ + FLAG_S = value & SFLAG_SET; + FLAG_M = value & MFLAG_SET; } /* Set the condition code register */ static inline void m68ki_set_ccr(uint value) { - FLAG_X = BIT_4(value) << 4; - FLAG_N = BIT_3(value) << 4; - FLAG_Z = !BIT_2(value); - FLAG_V = BIT_1(value) << 6; - FLAG_C = BIT_0(value) << 8; + FLAG_X = BIT_4(value) << 4; + FLAG_N = BIT_3(value) << 4; + FLAG_Z = !BIT_2(value); + FLAG_V = BIT_1(value) << 6; + FLAG_C = BIT_0(value) << 8; } /* Set the status register but don't check for interrupts */ static inline void m68ki_set_sr_noint(uint value) { - /* Mask out the "unimplemented" bits */ - value &= CPU_SR_MASK; + /* Mask out the "unimplemented" bits */ + value &= CPU_SR_MASK; - /* Now set the status register */ - FLAG_T1 = BIT_F(value); - FLAG_T0 = BIT_E(value); - FLAG_INT_MASK = value & 0x0700; - m68ki_set_ccr(value); - m68ki_set_sm_flag((value >> 11) & 6); + /* Now set the status register */ + FLAG_T1 = BIT_F(value); + FLAG_T0 = BIT_E(value); + FLAG_INT_MASK = value & 0x0700; + m68ki_set_ccr(value); + m68ki_set_sm_flag((value >> 11) & 6); } /* Set the status register but don't check for interrupts nor @@ -1560,22 +1560,22 @@ static inline void m68ki_set_sr_noint(uint value) */ static inline void m68ki_set_sr_noint_nosp(uint value) { - /* Mask out the "unimplemented" bits */ - value &= CPU_SR_MASK; + /* Mask out the "unimplemented" bits */ + value &= CPU_SR_MASK; - /* Now set the status register */ - FLAG_T1 = BIT_F(value); - FLAG_T0 = BIT_E(value); - FLAG_INT_MASK = value & 0x0700; - m68ki_set_ccr(value); - m68ki_set_sm_flag_nosp((value >> 11) & 6); + /* Now set the status register */ + FLAG_T1 = BIT_F(value); + FLAG_T0 = BIT_E(value); + FLAG_INT_MASK = value & 0x0700; + m68ki_set_ccr(value); + m68ki_set_sm_flag_nosp((value >> 11) & 6); } /* Set the status register and check for interrupts */ static inline void m68ki_set_sr(uint value) { - m68ki_set_sr_noint(value); - m68ki_check_interrupts(); + m68ki_set_sr_noint(value); + m68ki_check_interrupts(); } @@ -1584,23 +1584,23 @@ static inline void m68ki_set_sr(uint value) /* Initiate exception processing */ static inline uint m68ki_init_exception(void) { - /* Save the old status register */ - uint sr = m68ki_get_sr(); + /* Save the old status register */ + uint sr = m68ki_get_sr(); - /* Turn off trace flag, clear pending traces */ - FLAG_T1 = FLAG_T0 = 0; - m68ki_clear_trace(); - /* Enter supervisor mode */ - m68ki_set_s_flag(SFLAG_SET); + /* Turn off trace flag, clear pending traces */ + FLAG_T1 = FLAG_T0 = 0; + m68ki_clear_trace(); + /* Enter supervisor mode */ + m68ki_set_s_flag(SFLAG_SET); - return sr; + return sr; } /* 3 word stack frame (68000 only) */ static inline void m68ki_stack_frame_3word(uint pc, uint sr) { - m68ki_push_32(pc); - m68ki_push_16(sr); + m68ki_push_32(pc); + m68ki_push_16(sr); } /* Format 0 stack frame. @@ -1608,15 +1608,15 @@ static inline void m68ki_stack_frame_3word(uint pc, uint sr) */ static inline void m68ki_stack_frame_0000(uint pc, uint sr, uint vector) { - /* Stack a 3-word frame if we are 68000 */ - if(CPU_TYPE == CPU_TYPE_000) - { - m68ki_stack_frame_3word(pc, sr); - return; - } - m68ki_push_16(vector<<2); - m68ki_push_32(pc); - m68ki_push_16(sr); + /* Stack a 3-word frame if we are 68000 */ + if(CPU_TYPE == CPU_TYPE_000) + { + m68ki_stack_frame_3word(pc, sr); + return; + } + m68ki_push_16(vector<<2); + m68ki_push_32(pc); + m68ki_push_16(sr); } /* Format 1 stack frame (68020). @@ -1624,9 +1624,9 @@ static inline void m68ki_stack_frame_0000(uint pc, uint sr, uint vector) */ static inline void m68ki_stack_frame_0001(uint pc, uint sr, uint vector) { - m68ki_push_16(0x1000 | (vector<<2)); - m68ki_push_32(pc); - m68ki_push_16(sr); + m68ki_push_16(0x1000 | (vector<<2)); + m68ki_push_32(pc); + m68ki_push_16(sr); } /* Format 2 stack frame. @@ -1634,10 +1634,10 @@ static inline void m68ki_stack_frame_0001(uint pc, uint sr, uint vector) */ static inline void m68ki_stack_frame_0010(uint sr, uint vector) { - m68ki_push_32(REG_PPC); - m68ki_push_16(0x2000 | (vector<<2)); - m68ki_push_32(REG_PC); - m68ki_push_16(sr); + m68ki_push_32(REG_PPC); + m68ki_push_16(0x2000 | (vector<<2)); + m68ki_push_32(REG_PC); + m68ki_push_16(sr); } @@ -1645,16 +1645,16 @@ static inline void m68ki_stack_frame_0010(uint sr, uint vector) */ static inline void m68ki_stack_frame_buserr(uint sr) { - m68ki_push_32(REG_PC); - m68ki_push_16(sr); - m68ki_push_16(REG_IR); - m68ki_push_32(m68ki_aerr_address); /* access address */ - /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC - * R/W 0 = write, 1 = read - * I/N 0 = instruction, 1 = not - * FC 3-bit function code - */ - m68ki_push_16(m68ki_aerr_write_mode | CPU_INSTR_MODE | m68ki_aerr_fc); + m68ki_push_32(REG_PC); + m68ki_push_16(sr); + m68ki_push_16(REG_IR); + m68ki_push_32(m68ki_aerr_address); /* access address */ + /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC + * R/W 0 = write, 1 = read + * I/N 0 = instruction, 1 = not + * FC 3-bit function code + */ + m68ki_push_16(m68ki_aerr_write_mode | CPU_INSTR_MODE | m68ki_aerr_fc); } /* Format 8 stack frame (68010). @@ -1662,51 +1662,51 @@ static inline void m68ki_stack_frame_buserr(uint sr) */ static inline void m68ki_stack_frame_1000(uint pc, uint sr, uint vector) { - /* VERSION - * NUMBER - * INTERNAL INFORMATION, 16 WORDS - */ - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); - m68ki_fake_push_32(); + /* VERSION + * NUMBER + * INTERNAL INFORMATION, 16 WORDS + */ + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); + m68ki_fake_push_32(); - /* INSTRUCTION INPUT BUFFER */ - m68ki_push_16(0); + /* INSTRUCTION INPUT BUFFER */ + m68ki_push_16(0); - /* UNUSED, RESERVED (not written) */ - m68ki_fake_push_16(); + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); - /* DATA INPUT BUFFER */ - m68ki_push_16(0); + /* DATA INPUT BUFFER */ + m68ki_push_16(0); - /* UNUSED, RESERVED (not written) */ - m68ki_fake_push_16(); + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); - /* DATA OUTPUT BUFFER */ - m68ki_push_16(0); + /* DATA OUTPUT BUFFER */ + m68ki_push_16(0); - /* UNUSED, RESERVED (not written) */ - m68ki_fake_push_16(); + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); - /* FAULT ADDRESS */ - m68ki_push_32(0); + /* FAULT ADDRESS */ + m68ki_push_32(0); - /* SPECIAL STATUS WORD */ - m68ki_push_16(0); + /* SPECIAL STATUS WORD */ + m68ki_push_16(0); - /* 1000, VECTOR OFFSET */ - m68ki_push_16(0x8000 | (vector<<2)); + /* 1000, VECTOR OFFSET */ + m68ki_push_16(0x8000 | (vector<<2)); - /* PROGRAM COUNTER */ - m68ki_push_32(pc); + /* PROGRAM COUNTER */ + m68ki_push_32(pc); - /* STATUS REGISTER */ - m68ki_push_16(sr); + /* STATUS REGISTER */ + m68ki_push_16(sr); } /* Format A stack frame (short bus fault). @@ -1716,44 +1716,44 @@ static inline void m68ki_stack_frame_1000(uint pc, uint sr, uint vector) */ static inline void m68ki_stack_frame_1010(uint sr, uint vector, uint pc) { - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* DATA OUTPUT BUFFER (2 words) */ - m68ki_push_32(0); + /* DATA OUTPUT BUFFER (2 words) */ + m68ki_push_32(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* DATA CYCLE FAULT ADDRESS (2 words) */ - m68ki_push_32(0); + /* DATA CYCLE FAULT ADDRESS (2 words) */ + m68ki_push_32(0); - /* INSTRUCTION PIPE STAGE B */ - m68ki_push_16(0); + /* INSTRUCTION PIPE STAGE B */ + m68ki_push_16(0); - /* INSTRUCTION PIPE STAGE C */ - m68ki_push_16(0); + /* INSTRUCTION PIPE STAGE C */ + m68ki_push_16(0); - /* SPECIAL STATUS REGISTER */ - m68ki_push_16(0); + /* SPECIAL STATUS REGISTER */ + m68ki_push_16(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* 1010, VECTOR OFFSET */ - m68ki_push_16(0xa000 | (vector<<2)); + /* 1010, VECTOR OFFSET */ + m68ki_push_16(0xa000 | (vector<<2)); - /* PROGRAM COUNTER */ - m68ki_push_32(pc); + /* PROGRAM COUNTER */ + m68ki_push_32(pc); - /* STATUS REGISTER */ - m68ki_push_16(sr); + /* STATUS REGISTER */ + m68ki_push_16(sr); } /* Format B stack frame (long bus fault). @@ -1763,69 +1763,69 @@ static inline void m68ki_stack_frame_1010(uint sr, uint vector, uint pc) */ static inline void m68ki_stack_frame_1011(uint sr, uint vector, uint pc) { - /* INTERNAL REGISTERS (18 words) */ - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); - m68ki_push_32(0); + /* INTERNAL REGISTERS (18 words) */ + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); + m68ki_push_32(0); - /* VERSION# (4 bits), INTERNAL INFORMATION */ - m68ki_push_16(0); + /* VERSION# (4 bits), INTERNAL INFORMATION */ + m68ki_push_16(0); - /* INTERNAL REGISTERS (3 words) */ - m68ki_push_32(0); - m68ki_push_16(0); + /* INTERNAL REGISTERS (3 words) */ + m68ki_push_32(0); + m68ki_push_16(0); - /* DATA INTPUT BUFFER (2 words) */ - m68ki_push_32(0); + /* DATA INTPUT BUFFER (2 words) */ + m68ki_push_32(0); - /* INTERNAL REGISTERS (2 words) */ - m68ki_push_32(0); + /* INTERNAL REGISTERS (2 words) */ + m68ki_push_32(0); - /* STAGE B ADDRESS (2 words) */ - m68ki_push_32(0); + /* STAGE B ADDRESS (2 words) */ + m68ki_push_32(0); - /* INTERNAL REGISTER (4 words) */ - m68ki_push_32(0); - m68ki_push_32(0); + /* INTERNAL REGISTER (4 words) */ + m68ki_push_32(0); + m68ki_push_32(0); - /* DATA OUTPUT BUFFER (2 words) */ - m68ki_push_32(0); + /* DATA OUTPUT BUFFER (2 words) */ + m68ki_push_32(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* DATA CYCLE FAULT ADDRESS (2 words) */ - m68ki_push_32(0); + /* DATA CYCLE FAULT ADDRESS (2 words) */ + m68ki_push_32(0); - /* INSTRUCTION PIPE STAGE B */ - m68ki_push_16(0); + /* INSTRUCTION PIPE STAGE B */ + m68ki_push_16(0); - /* INSTRUCTION PIPE STAGE C */ - m68ki_push_16(0); + /* INSTRUCTION PIPE STAGE C */ + m68ki_push_16(0); - /* SPECIAL STATUS REGISTER */ - m68ki_push_16(0); + /* SPECIAL STATUS REGISTER */ + m68ki_push_16(0); - /* INTERNAL REGISTER */ - m68ki_push_16(0); + /* INTERNAL REGISTER */ + m68ki_push_16(0); - /* 1011, VECTOR OFFSET */ - m68ki_push_16(0xb000 | (vector<<2)); + /* 1011, VECTOR OFFSET */ + m68ki_push_16(0xb000 | (vector<<2)); - /* PROGRAM COUNTER */ - m68ki_push_32(pc); + /* PROGRAM COUNTER */ + m68ki_push_32(pc); - /* STATUS REGISTER */ - m68ki_push_16(sr); + /* STATUS REGISTER */ + m68ki_push_16(sr); } @@ -1834,74 +1834,74 @@ static inline void m68ki_stack_frame_1011(uint sr, uint vector, uint pc) */ static inline void m68ki_exception_trap(uint vector) { - uint sr = m68ki_init_exception(); + uint sr = m68ki_init_exception(); - if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) - m68ki_stack_frame_0000(REG_PC, sr, vector); - else - m68ki_stack_frame_0010(sr, vector); + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) + m68ki_stack_frame_0000(REG_PC, sr, vector); + else + m68ki_stack_frame_0010(sr, vector); - m68ki_jump_vector(vector); + m68ki_jump_vector(vector); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]); } /* Trap#n stacks a 0 frame but behaves like group2 otherwise */ static inline void m68ki_exception_trapN(uint vector) { - uint sr = m68ki_init_exception(); - m68ki_stack_frame_0000(REG_PC, sr, vector); - m68ki_jump_vector(vector); + uint sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC, sr, vector); + m68ki_jump_vector(vector); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]); } /* Exception for trace mode */ static inline void m68ki_exception_trace(void) { - uint sr = m68ki_init_exception(); + uint sr = m68ki_init_exception(); - if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) - { - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - if(CPU_TYPE_IS_000(CPU_TYPE)) - { - CPU_INSTR_MODE = INSTRUCTION_NO; - } - #endif /* M68K_EMULATE_ADDRESS_ERROR */ - m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE); - } - else - m68ki_stack_frame_0010(sr, EXCEPTION_TRACE); + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) + { + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + if(CPU_TYPE_IS_000(CPU_TYPE)) + { + CPU_INSTR_MODE = INSTRUCTION_NO; + } + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE); + } + else + m68ki_stack_frame_0010(sr, EXCEPTION_TRACE); - m68ki_jump_vector(EXCEPTION_TRACE); + m68ki_jump_vector(EXCEPTION_TRACE); - /* Trace nullifies a STOP instruction */ - CPU_STOPPED &= ~STOP_LEVEL_STOP; + /* Trace nullifies a STOP instruction */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; - /* Use up some clock cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); } /* Exception for privilege violation */ static inline void m68ki_exception_privilege_violation(void) { - uint sr = m68ki_init_exception(); + uint sr = m68ki_init_exception(); - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - if(CPU_TYPE_IS_000(CPU_TYPE)) - { - CPU_INSTR_MODE = INSTRUCTION_NO; - } - #endif /* M68K_EMULATE_ADDRESS_ERROR */ + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + if(CPU_TYPE_IS_000(CPU_TYPE)) + { + CPU_INSTR_MODE = INSTRUCTION_NO; + } + #endif /* M68K_EMULATE_ADDRESS_ERROR */ - m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION); - m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); + m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION); + m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); } extern jmp_buf m68ki_bus_error_jmp_buf; @@ -1911,38 +1911,38 @@ extern jmp_buf m68ki_bus_error_jmp_buf; /* Exception for bus error */ static inline void m68ki_exception_bus_error(void) { - uint sr; - int i; + uint sr; + int i; - /* If we were processing a bus error, address error, or reset, - * while writing the stack frame, this is a catastrophic failure. - * Halt the CPU - */ - if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET_WSF) - { - m68k_read_memory_8(0x00ffff01); - CPU_STOPPED = STOP_LEVEL_HALT; - return; - } - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF; + /* If we were processing a bus error, address error, or reset, + * while writing the stack frame, this is a catastrophic failure. + * Halt the CPU + */ + if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET_WSF) + { + m68k_read_memory_8(0x00ffff01); + CPU_STOPPED = STOP_LEVEL_HALT; + return; + } + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF; - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION[REG_IR]); - for (i = 15; i >= 0; i--){ - REG_DA[i] = REG_DA_SAVE[i]; - } + for (i = 15; i >= 0; i--){ + REG_DA[i] = REG_DA_SAVE[i]; + } - sr = m68ki_init_exception(); + sr = m68ki_init_exception(); - /* Note: This is implemented for 68010 only! */ - m68ki_stack_frame_1000(REG_PPC, sr, EXCEPTION_BUS_ERROR); + /* Note: This is implemented for 68010 only! */ + m68ki_stack_frame_1000(REG_PPC, sr, EXCEPTION_BUS_ERROR); - m68ki_jump_vector(EXCEPTION_BUS_ERROR); + m68ki_jump_vector(EXCEPTION_BUS_ERROR); - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; - longjmp(m68ki_bus_error_jmp_buf, 1); + longjmp(m68ki_bus_error_jmp_buf, 1); } extern int cpu_log_enabled; @@ -1950,38 +1950,38 @@ extern int cpu_log_enabled; /* Exception for A-Line instructions */ static inline void m68ki_exception_1010(void) { - uint sr; + uint sr; #if M68K_LOG_1010_1111 == OPT_ON - M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, - m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); #endif - sr = m68ki_init_exception(); - m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1010); - m68ki_jump_vector(EXCEPTION_1010); + sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1010); + m68ki_jump_vector(EXCEPTION_1010); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); } /* Exception for F-Line instructions */ static inline void m68ki_exception_1111(void) { - uint sr; + uint sr; #if M68K_LOG_1010_1111 == OPT_ON - M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, - m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); #endif - sr = m68ki_init_exception(); - m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1111); - m68ki_jump_vector(EXCEPTION_1111); + sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1111); + m68ki_jump_vector(EXCEPTION_1111); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); } #if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER @@ -1991,142 +1991,142 @@ extern int m68ki_illg_callback(int); /* Exception for illegal instructions */ static inline void m68ki_exception_illegal(void) { - uint sr; + uint sr; - M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, - m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); - if (m68ki_illg_callback(REG_IR)) - return; + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); + if (m68ki_illg_callback(REG_IR)) + return; - sr = m68ki_init_exception(); + sr = m68ki_init_exception(); - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - if(CPU_TYPE_IS_000(CPU_TYPE)) - { - CPU_INSTR_MODE = INSTRUCTION_NO; - } - #endif /* M68K_EMULATE_ADDRESS_ERROR */ + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + if(CPU_TYPE_IS_000(CPU_TYPE)) + { + CPU_INSTR_MODE = INSTRUCTION_NO; + } + #endif /* M68K_EMULATE_ADDRESS_ERROR */ - m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION_M68K); - m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION_M68K); + m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION_M68K); + m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION_M68K); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION_M68K] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION_M68K] - CYC_INSTRUCTION[REG_IR]); } /* Exception for format errror in RTE */ static inline void m68ki_exception_format_error(void) { - uint sr = m68ki_init_exception(); - m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR); - m68ki_jump_vector(EXCEPTION_FORMAT_ERROR); + uint sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR); + m68ki_jump_vector(EXCEPTION_FORMAT_ERROR); - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]); + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]); } /* Exception for address error */ static inline void m68ki_exception_address_error(void) { - uint sr = m68ki_init_exception(); + uint sr = m68ki_init_exception(); - /* If we were processing a bus error, address error, or reset, - * while writing the stack frame, this is a catastrophic failure. - * Halt the CPU - */ - if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET_WSF) - { - m68k_read_memory_8(0x00ffff01); - CPU_STOPPED = STOP_LEVEL_HALT; - return; - } - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF; + /* If we were processing a bus error, address error, or reset, + * while writing the stack frame, this is a catastrophic failure. + * Halt the CPU + */ + if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET_WSF) + { + m68k_read_memory_8(0x00ffff01); + CPU_STOPPED = STOP_LEVEL_HALT; + return; + } + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF; - /* Note: This is implemented for 68000 only! */ - m68ki_stack_frame_buserr(sr); + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(sr); - m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR); + m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR); - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; - /* Use up some clock cycles. Note that we don't need to undo the - instruction's cycles here as we've longjmp:ed directly from the - instruction handler without passing the part of the excecute loop - that deducts instruction cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR]); + /* Use up some clock cycles. Note that we don't need to undo the + instruction's cycles here as we've longjmp:ed directly from the + instruction handler without passing the part of the excecute loop + that deducts instruction cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR]); } /* Service an interrupt request and start exception processing */ static inline void m68ki_exception_interrupt(uint int_level) { - uint vector; - uint sr; - uint new_pc; + uint vector; + uint sr; + uint new_pc; - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - if(CPU_TYPE_IS_000(CPU_TYPE)) - { - CPU_INSTR_MODE = INSTRUCTION_NO; - } - #endif /* M68K_EMULATE_ADDRESS_ERROR */ + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + if(CPU_TYPE_IS_000(CPU_TYPE)) + { + CPU_INSTR_MODE = INSTRUCTION_NO; + } + #endif /* M68K_EMULATE_ADDRESS_ERROR */ - /* Turn off the stopped state */ - CPU_STOPPED &= ~STOP_LEVEL_STOP; + /* Turn off the stopped state */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; - /* If we are halted, don't do anything */ - if(CPU_STOPPED) - return; + /* If we are halted, don't do anything */ + if(CPU_STOPPED) + return; - /* Acknowledge the interrupt */ - vector = m68ki_int_ack(int_level); + /* Acknowledge the interrupt */ + vector = m68ki_int_ack(int_level); - /* Get the interrupt vector */ - if(vector == M68K_INT_ACK_AUTOVECTOR) - /* Use the autovectors. This is the most commonly used implementation */ - vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; - else if(vector == M68K_INT_ACK_SPURIOUS) - /* Called if no devices respond to the interrupt acknowledge */ - vector = EXCEPTION_SPURIOUS_INTERRUPT; - else if(vector > 255) - { - M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n", - m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector)); - return; - } + /* Get the interrupt vector */ + if(vector == M68K_INT_ACK_AUTOVECTOR) + /* Use the autovectors. This is the most commonly used implementation */ + vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; + else if(vector == M68K_INT_ACK_SPURIOUS) + /* Called if no devices respond to the interrupt acknowledge */ + vector = EXCEPTION_SPURIOUS_INTERRUPT; + else if(vector > 255) + { + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n", + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector)); + return; + } - /* Start exception processing */ - sr = m68ki_init_exception(); + /* Start exception processing */ + sr = m68ki_init_exception(); - /* Set the interrupt mask to the level of the one being serviced */ - FLAG_INT_MASK = int_level<<8; + /* Set the interrupt mask to the level of the one being serviced */ + FLAG_INT_MASK = int_level<<8; - /* Get the new PC */ - new_pc = m68ki_read_data_32((vector<<2) + REG_VBR); + /* Get the new PC */ + new_pc = m68ki_read_data_32((vector<<2) + REG_VBR); - /* If vector is uninitialized, call the uninitialized interrupt vector */ - if(new_pc == 0) - new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR); + /* If vector is uninitialized, call the uninitialized interrupt vector */ + if(new_pc == 0) + new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR); - /* Generate a stack frame */ - m68ki_stack_frame_0000(REG_PC, sr, vector); - if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) - { - /* Create throwaway frame */ - m68ki_set_sm_flag(FLAG_S); /* clear M */ - sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */ - m68ki_stack_frame_0001(REG_PC, sr, vector); - } + /* Generate a stack frame */ + m68ki_stack_frame_0000(REG_PC, sr, vector); + if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + /* Create throwaway frame */ + m68ki_set_sm_flag(FLAG_S); /* clear M */ + sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */ + m68ki_stack_frame_0001(REG_PC, sr, vector); + } - m68ki_jump(new_pc); + m68ki_jump(new_pc); - /* Defer cycle counting until later */ - USE_CYCLES(CYC_EXCEPTION[vector]); + /* Defer cycle counting until later */ + USE_CYCLES(CYC_EXCEPTION[vector]); #if !M68K_EMULATE_INT_ACK - /* Automatically clear IRQ if we are not using an acknowledge scheme */ - CPU_INT_LEVEL = 0; + /* Automatically clear IRQ if we are not using an acknowledge scheme */ + CPU_INT_LEVEL = 0; #endif /* M68K_EMULATE_INT_ACK */ } @@ -2134,13 +2134,13 @@ static inline void m68ki_exception_interrupt(uint int_level) /* ASG: Check for interrupts */ static inline void m68ki_check_interrupts(void) { - if(m68ki_cpu.nmi_pending) - { - m68ki_cpu.nmi_pending = FALSE; - m68ki_exception_interrupt(7); - } - else if(CPU_INT_LEVEL > FLAG_INT_MASK) - m68ki_exception_interrupt(CPU_INT_LEVEL>>8); + if(m68ki_cpu.nmi_pending) + { + m68ki_cpu.nmi_pending = FALSE; + m68ki_exception_interrupt(7); + } + else if(CPU_INT_LEVEL > FLAG_INT_MASK) + m68ki_exception_interrupt(CPU_INT_LEVEL>>8); } diff --git a/AltairZ80/m68k/m68kdasm.c b/AltairZ80/m68k/m68kdasm.c index 25cbcb07..f7ab7a6e 100755 --- a/AltairZ80/m68k/m68kdasm.c +++ b/AltairZ80/m68k/m68kdasm.c @@ -99,21 +99,21 @@ #define TYPE_68030 8 #define TYPE_68040 16 -#define M68000_ONLY TYPE_68000 +#define M68000_ONLY TYPE_68000 -#define M68010_ONLY TYPE_68010 -#define M68010_LESS (TYPE_68000 | TYPE_68010) -#define M68010_PLUS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040) +#define M68010_ONLY TYPE_68010 +#define M68010_LESS (TYPE_68000 | TYPE_68010) +#define M68010_PLUS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040) -#define M68020_ONLY TYPE_68020 -#define M68020_LESS (TYPE_68010 | TYPE_68020) -#define M68020_PLUS (TYPE_68020 | TYPE_68030 | TYPE_68040) +#define M68020_ONLY TYPE_68020 +#define M68020_LESS (TYPE_68010 | TYPE_68020) +#define M68020_PLUS (TYPE_68020 | TYPE_68030 | TYPE_68040) -#define M68030_ONLY TYPE_68030 -#define M68030_LESS (TYPE_68010 | TYPE_68020 | TYPE_68030) -#define M68030_PLUS (TYPE_68030 | TYPE_68040) +#define M68030_ONLY TYPE_68030 +#define M68030_LESS (TYPE_68010 | TYPE_68020 | TYPE_68030) +#define M68030_PLUS (TYPE_68030 | TYPE_68040) -#define M68040_PLUS TYPE_68040 +#define M68040_PLUS TYPE_68040 /* Extension word formats */ @@ -139,7 +139,7 @@ /* Opcode flags */ #if M68K_COMPILE_FOR_MAME == OPT_ON -#define SET_OPCODE_FLAGS(x) g_opcode_type = x; +#define SET_OPCODE_FLAGS(x) g_opcode_type = x; #define COMBINE_OPCODE_FLAGS(x) ((x) | g_opcode_type | DASMFLAG_SUPPORTED) #else #define SET_OPCODE_FLAGS(x) @@ -194,10 +194,10 @@ static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr); /* used to build opcode handler jump table */ typedef struct { - void (*opcode_handler)(void); /* handler function */ - uint mask; /* mask on opcode */ - uint match; /* what to match after masking */ - uint ea_mask; /* what ea modes are allowed */ + void (*opcode_handler)(void); /* handler function */ + uint mask; /* mask on opcode */ + uint match; /* what to match after masking */ + uint ea_mask; /* what ea modes are allowed */ } opcode_struct; @@ -228,8 +228,8 @@ static const uint g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; static const uint g_5bit_data_table[32] = { - 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; static const char *const g_cc[16] = @@ -237,75 +237,75 @@ static const char *const g_cc[16] = static const char *const g_cpcc[64] = {/* 000 001 010 011 100 101 110 111 */ - "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ - "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ - "sf", "seq", "gt", "ge", "lt", "le", "gl", "gle", /* 010 */ + "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ + "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ + "sf", "seq", "gt", "ge", "lt", "le", "gl", "gle", /* 010 */ "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ - "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ + "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ }; static const char *const g_mmuregs[8] = { - "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" + "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" }; static const char *const g_mmucond[16] = { - "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", - "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" + "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", + "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" }; /* ======================================================================== */ /* =========================== UTILITY FUNCTIONS ========================== */ /* ======================================================================== */ -#define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES) \ - if(!(g_cpu_type & ALLOWED_CPU_TYPES)) \ - { \ - if((g_cpu_ir & 0xf000) == 0xf000) \ - d68000_1111(); \ - else d68000_illegal(); \ - return; \ - } +#define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES) \ + if(!(g_cpu_type & ALLOWED_CPU_TYPES)) \ + { \ + if((g_cpu_ir & 0xf000) == 0xf000) \ + d68000_1111(); \ + else d68000_illegal(); \ + return; \ + } static uint dasm_read_imm_8(uint advance) { - uint result; - if (g_rawop) - result = g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - else - result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xff; - g_cpu_pc += advance; - return result; + uint result; + if (g_rawop) + result = g_rawop[g_cpu_pc + 1 - g_rawbasepc]; + else + result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xff; + g_cpu_pc += advance; + return result; } static uint dasm_read_imm_16(uint advance) { - uint result; - if (g_rawop) - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - else - result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xffff; - g_cpu_pc += advance; - return result; + uint result; + if (g_rawop) + result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 8) | + g_rawop[g_cpu_pc + 1 - g_rawbasepc]; + else + result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xffff; + g_cpu_pc += advance; + return result; } static uint dasm_read_imm_32(uint advance) { - uint result; - if (g_rawop) - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 24) | - (g_rawop[g_cpu_pc + 1 - g_rawbasepc] << 16) | - (g_rawop[g_cpu_pc + 2 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 3 - g_rawbasepc]; - else - result = m68k_read_disassembler_32(g_cpu_pc & g_address_mask) & 0xffffffff; - g_cpu_pc += advance; - return result; + uint result; + if (g_rawop) + result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 24) | + (g_rawop[g_cpu_pc + 1 - g_rawbasepc] << 16) | + (g_rawop[g_cpu_pc + 2 - g_rawbasepc] << 8) | + g_rawop[g_cpu_pc + 3 - g_rawbasepc]; + else + result = m68k_read_disassembler_32(g_cpu_pc & g_address_mask) & 0xffffffff; + g_cpu_pc += advance; + return result; } #define read_imm_8() dasm_read_imm_8(2) @@ -331,331 +331,331 @@ static uint dasm_read_imm_32(uint advance) static int sext_7bit_int(int value) { - return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); + return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); } /* 100% portable signed int generators */ static int make_int_8(int value) { - return (value & 0x80) ? value | ~0xff : value & 0xff; + return (value & 0x80) ? value | ~0xff : value & 0xff; } static int make_int_16(int value) { - return (value & 0x8000) ? value | ~0xffff : value & 0xffff; + return (value & 0x8000) ? value | ~0xffff : value & 0xffff; } static int make_int_32(int value) { - return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; + return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; } /* Get string representation of hex values */ static char* make_signed_hex_str_8(uint val) { - static char str[20]; + static char str[20]; - val &= 0xff; + val &= 0xff; - if(val == 0x80) - sprintf(str, "-$80"); - else if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); - else - sprintf(str, "$%x", val & 0x7f); + if(val == 0x80) + sprintf(str, "-$80"); + else if(val & 0x80) + sprintf(str, "-$%x", (0-val) & 0x7f); + else + sprintf(str, "$%x", val & 0x7f); - return str; + return str; } static char* make_signed_hex_str_16(uint val) { - static char str[20]; + static char str[20]; - val &= 0xffff; + val &= 0xffff; - if(val == 0x8000) - sprintf(str, "-$8000"); - else if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); - else - sprintf(str, "$%x", val & 0x7fff); + if(val == 0x8000) + sprintf(str, "-$8000"); + else if(val & 0x8000) + sprintf(str, "-$%x", (0-val) & 0x7fff); + else + sprintf(str, "$%x", val & 0x7fff); - return str; + return str; } static char* make_signed_hex_str_32(uint val) { - static char str[20]; + static char str[20]; - val &= 0xffffffff; + val &= 0xffffffff; - if(val == 0x80000000) - sprintf(str, "-$80000000"); - else if(val & 0x80000000) - sprintf(str, "-$%x", (0-val) & 0x7fffffff); - else - sprintf(str, "$%x", val & 0x7fffffff); + if(val == 0x80000000) + sprintf(str, "-$80000000"); + else if(val & 0x80000000) + sprintf(str, "-$%x", (0-val) & 0x7fffffff); + else + sprintf(str, "$%x", val & 0x7fffffff); - return str; + return str; } /* make string of immediate value */ static char* get_imm_str_s(uint size) { - static char str[15]; - if(size == 0) - sprintf(str, "#%s", make_signed_hex_str_8(read_imm_8())); - else if(size == 1) - sprintf(str, "#%s", make_signed_hex_str_16(read_imm_16())); - else - sprintf(str, "#%s", make_signed_hex_str_32(read_imm_32())); - return str; + static char str[15]; + if(size == 0) + sprintf(str, "#%s", make_signed_hex_str_8(read_imm_8())); + else if(size == 1) + sprintf(str, "#%s", make_signed_hex_str_16(read_imm_16())); + else + sprintf(str, "#%s", make_signed_hex_str_32(read_imm_32())); + return str; } static char* get_imm_str_u(uint size) { - static char str[15]; - if(size == 0) - sprintf(str, "#$%x", read_imm_8() & 0xff); - else if(size == 1) - sprintf(str, "#$%x", read_imm_16() & 0xffff); - else - sprintf(str, "#$%x", read_imm_32() & 0xffffffff); - return str; + static char str[15]; + if(size == 0) + sprintf(str, "#$%x", read_imm_8() & 0xff); + else if(size == 1) + sprintf(str, "#$%x", read_imm_16() & 0xffff); + else + sprintf(str, "#$%x", read_imm_32() & 0xffffffff); + return str; } /* Make string of effective address mode */ static char* get_ea_mode_str(uint instruction, uint size) { - static char b1[64]; - static char b2[64]; - static char* mode = b2; - uint extension; - uint base; - uint outer; - char base_reg[4]; - char index_reg[8]; - uint preindex; - uint postindex; - uint comma = 0; - uint temp_value; + static char b1[64]; + static char b2[64]; + static char* mode = b2; + uint extension; + uint base; + uint outer; + char base_reg[4]; + char index_reg[8]; + uint preindex; + uint postindex; + uint comma = 0; + uint temp_value; - /* Switch buffers so we don't clobber on a double-call to this function */ - mode = mode == b1 ? b2 : b1; + /* Switch buffers so we don't clobber on a double-call to this function */ + mode = mode == b1 ? b2 : b1; - switch(instruction & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - /* data register direct */ - sprintf(mode, "D%d", instruction&7); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - /* address register direct */ - sprintf(mode, "A%d", instruction&7); - break; - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - /* address register indirect */ - sprintf(mode, "(A%d)", instruction&7); - break; - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - /* address register indirect with postincrement */ - sprintf(mode, "(A%d)+", instruction&7); - break; - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: - /* address register indirect with predecrement */ - sprintf(mode, "-(A%d)", instruction&7); - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - /* address register indirect with displacement*/ - sprintf(mode, "(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); - break; - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - /* address register indirect with index */ - extension = read_imm_16(); + switch(instruction & 0x3f) + { + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: + /* data register direct */ + sprintf(mode, "D%d", instruction&7); + break; + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: + /* address register direct */ + sprintf(mode, "A%d", instruction&7); + break; + case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + /* address register indirect */ + sprintf(mode, "(A%d)", instruction&7); + break; + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + /* address register indirect with postincrement */ + sprintf(mode, "(A%d)+", instruction&7); + break; + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + /* address register indirect with predecrement */ + sprintf(mode, "-(A%d)", instruction&7); + break; + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: + /* address register indirect with displacement*/ + sprintf(mode, "(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); + break; + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + /* address register indirect with index */ + extension = read_imm_16(); - if(EXT_FULL(extension)) - { - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); - break; - } - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - sprintf(base_reg, "A%d", instruction&7); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; + if(EXT_FULL(extension)) + { + if(EXT_EFFECTIVE_ZERO(extension)) + { + strcpy(mode, "0"); + break; + } + base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; + outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; + if(EXT_BASE_REGISTER_PRESENT(extension)) + sprintf(base_reg, "A%d", instruction&7); + else + *base_reg = 0; + if(EXT_INDEX_REGISTER_PRESENT(extension)) + { + sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + if(EXT_INDEX_SCALE(extension)) + sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); + } + else + *index_reg = 0; + preindex = (extension&7) > 0 && (extension&7) < 4; + postindex = (extension&7) > 4; - strcpy(mode, "("); - if(preindex || postindex) - strcat(mode, "["); - if(base) - { - if (EXT_BASE_DISPLACEMENT_LONG(extension)) - { - strcat(mode, make_signed_hex_str_32(base)); - } - else - { - strcat(mode, make_signed_hex_str_16(base)); - } - comma = 1; - } - if(*base_reg) - { - if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; - } - if(postindex) - { - strcat(mode, "]"); - comma = 1; - } - if(*index_reg) - { - if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; - } - if(preindex) - { - strcat(mode, "]"); - comma = 1; - } - if(outer) - { - if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); - } - strcat(mode, ")"); - break; - } + strcpy(mode, "("); + if(preindex || postindex) + strcat(mode, "["); + if(base) + { + if (EXT_BASE_DISPLACEMENT_LONG(extension)) + { + strcat(mode, make_signed_hex_str_32(base)); + } + else + { + strcat(mode, make_signed_hex_str_16(base)); + } + comma = 1; + } + if(*base_reg) + { + if(comma) + strcat(mode, ","); + strcat(mode, base_reg); + comma = 1; + } + if(postindex) + { + strcat(mode, "]"); + comma = 1; + } + if(*index_reg) + { + if(comma) + strcat(mode, ","); + strcat(mode, index_reg); + comma = 1; + } + if(preindex) + { + strcat(mode, "]"); + comma = 1; + } + if(outer) + { + if(comma) + strcat(mode, ","); + strcat(mode, make_signed_hex_str_16(outer)); + } + strcat(mode, ")"); + break; + } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(A%d,%c%d.%c", instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; - case 0x38: - /* absolute short address */ - sprintf(mode, "$%x.w", read_imm_16()); - break; - case 0x39: - /* absolute long address */ - sprintf(mode, "$%x.l", read_imm_32()); - break; - case 0x3a: - /* program counter with displacement */ - temp_value = read_imm_16(); - sprintf(mode, "(%s,PC)", make_signed_hex_str_16(temp_value)); - sprintf(g_helper_str, "; ($%x)", (make_int_16(temp_value) + g_cpu_pc-2) & 0xffffffff); - break; - case 0x3b: - /* program counter with index */ - extension = read_imm_16(); + if(EXT_8BIT_DISPLACEMENT(extension) == 0) + sprintf(mode, "(A%d,%c%d.%c", instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + else + sprintf(mode, "(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + if(EXT_INDEX_SCALE(extension)) + sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); + strcat(mode, ")"); + break; + case 0x38: + /* absolute short address */ + sprintf(mode, "$%x.w", read_imm_16()); + break; + case 0x39: + /* absolute long address */ + sprintf(mode, "$%x.l", read_imm_32()); + break; + case 0x3a: + /* program counter with displacement */ + temp_value = read_imm_16(); + sprintf(mode, "(%s,PC)", make_signed_hex_str_16(temp_value)); + sprintf(g_helper_str, "; ($%x)", (make_int_16(temp_value) + g_cpu_pc-2) & 0xffffffff); + break; + case 0x3b: + /* program counter with index */ + extension = read_imm_16(); - if(EXT_FULL(extension)) - { - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); - break; - } - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - strcpy(base_reg, "PC"); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; + if(EXT_FULL(extension)) + { + if(EXT_EFFECTIVE_ZERO(extension)) + { + strcpy(mode, "0"); + break; + } + base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; + outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; + if(EXT_BASE_REGISTER_PRESENT(extension)) + strcpy(base_reg, "PC"); + else + *base_reg = 0; + if(EXT_INDEX_REGISTER_PRESENT(extension)) + { + sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + if(EXT_INDEX_SCALE(extension)) + sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); + } + else + *index_reg = 0; + preindex = (extension&7) > 0 && (extension&7) < 4; + postindex = (extension&7) > 4; - strcpy(mode, "("); - if(preindex || postindex) - strcat(mode, "["); - if(base) - { - strcat(mode, make_signed_hex_str_16(base)); - comma = 1; - } - if(*base_reg) - { - if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; - } - if(postindex) - { - strcat(mode, "]"); - comma = 1; - } - if(*index_reg) - { - if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; - } - if(preindex) - { - strcat(mode, "]"); - comma = 1; - } - if(outer) - { - if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); - } - strcat(mode, ")"); - break; - } + strcpy(mode, "("); + if(preindex || postindex) + strcat(mode, "["); + if(base) + { + strcat(mode, make_signed_hex_str_16(base)); + comma = 1; + } + if(*base_reg) + { + if(comma) + strcat(mode, ","); + strcat(mode, base_reg); + comma = 1; + } + if(postindex) + { + strcat(mode, "]"); + comma = 1; + } + if(*index_reg) + { + if(comma) + strcat(mode, ","); + strcat(mode, index_reg); + comma = 1; + } + if(preindex) + { + strcat(mode, "]"); + comma = 1; + } + if(outer) + { + if(comma) + strcat(mode, ","); + strcat(mode, make_signed_hex_str_16(outer)); + } + strcat(mode, ")"); + break; + } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(PC,%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; - case 0x3c: - /* Immediate */ - sprintf(mode, "%s", get_imm_str_u(size)); - break; - default: - sprintf(mode, "INVALID %x", instruction & 0x3f); - } - return mode; + if(EXT_8BIT_DISPLACEMENT(extension) == 0) + sprintf(mode, "(PC,%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + else + sprintf(mode, "(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); + if(EXT_INDEX_SCALE(extension)) + sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); + strcat(mode, ")"); + break; + case 0x3c: + /* Immediate */ + sprintf(mode, "%s", get_imm_str_u(size)); + break; + default: + sprintf(mode, "INVALID %x", instruction & 0x3f); + } + return mode; } @@ -700,573 +700,573 @@ static char* get_ea_mode_str(uint instruction, uint size) static void d68000_illegal(void) { - sprintf(g_dasm_str, "dc.w $%04x; ILLEGAL", g_cpu_ir); + sprintf(g_dasm_str, "dc.w $%04x; ILLEGAL", g_cpu_ir); } static void d68000_1010(void) { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1010", g_cpu_ir); + sprintf(g_dasm_str, "dc.w $%04x; opcode 1010", g_cpu_ir); } static void d68000_1111(void) { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1111", g_cpu_ir); + sprintf(g_dasm_str, "dc.w $%04x; opcode 1111", g_cpu_ir); } static void d68000_abcd_rr(void) { - sprintf(g_dasm_str, "abcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "abcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_abcd_mm(void) { - sprintf(g_dasm_str, "abcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "abcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_add_er_8(void) { - sprintf(g_dasm_str, "add.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "add.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_add_er_16(void) { - sprintf(g_dasm_str, "add.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "add.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_add_er_32(void) { - sprintf(g_dasm_str, "add.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "add.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_add_re_8(void) { - sprintf(g_dasm_str, "add.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "add.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_add_re_16(void) { - sprintf(g_dasm_str, "add.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "add.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_add_re_32(void) { - sprintf(g_dasm_str, "add.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "add.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_adda_16(void) { - sprintf(g_dasm_str, "adda.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "adda.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_adda_32(void) { - sprintf(g_dasm_str, "adda.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "adda.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_addi_8(void) { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "addi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_s8(); + sprintf(g_dasm_str, "addi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_addi_16(void) { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "addi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str = get_imm_str_s16(); + sprintf(g_dasm_str, "addi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_addi_32(void) { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "addi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str = get_imm_str_s32(); + sprintf(g_dasm_str, "addi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_addq_8(void) { - sprintf(g_dasm_str, "addq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "addq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); } static void d68000_addq_16(void) { - sprintf(g_dasm_str, "addq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "addq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); } static void d68000_addq_32(void) { - sprintf(g_dasm_str, "addq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "addq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); } static void d68000_addx_rr_8(void) { - sprintf(g_dasm_str, "addx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_addx_rr_16(void) { - sprintf(g_dasm_str, "addx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_addx_rr_32(void) { - sprintf(g_dasm_str, "addx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_addx_mm_8(void) { - sprintf(g_dasm_str, "addx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_addx_mm_16(void) { - sprintf(g_dasm_str, "addx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_addx_mm_32(void) { - sprintf(g_dasm_str, "addx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "addx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_and_er_8(void) { - sprintf(g_dasm_str, "and.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "and.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_and_er_16(void) { - sprintf(g_dasm_str, "and.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "and.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_and_er_32(void) { - sprintf(g_dasm_str, "and.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "and.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_and_re_8(void) { - sprintf(g_dasm_str, "and.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "and.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_and_re_16(void) { - sprintf(g_dasm_str, "and.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "and.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_and_re_32(void) { - sprintf(g_dasm_str, "and.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "and.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_andi_8(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "andi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "andi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_andi_16(void) { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "andi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str = get_imm_str_u16(); + sprintf(g_dasm_str, "andi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_andi_32(void) { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "andi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str = get_imm_str_u32(); + sprintf(g_dasm_str, "andi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_andi_to_ccr(void) { - sprintf(g_dasm_str, "andi %s, CCR", get_imm_str_u8()); + sprintf(g_dasm_str, "andi %s, CCR", get_imm_str_u8()); } static void d68000_andi_to_sr(void) { - sprintf(g_dasm_str, "andi %s, SR", get_imm_str_u16()); + sprintf(g_dasm_str, "andi %s, SR", get_imm_str_u16()); } static void d68000_asr_s_8(void) { - sprintf(g_dasm_str, "asr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asr_s_16(void) { - sprintf(g_dasm_str, "asr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asr_s_32(void) { - sprintf(g_dasm_str, "asr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asr_r_8(void) { - sprintf(g_dasm_str, "asr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asr_r_16(void) { - sprintf(g_dasm_str, "asr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asr_r_32(void) { - sprintf(g_dasm_str, "asr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asr_ea(void) { - sprintf(g_dasm_str, "asr.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "asr.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_asl_s_8(void) { - sprintf(g_dasm_str, "asl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asl_s_16(void) { - sprintf(g_dasm_str, "asl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asl_s_32(void) { - sprintf(g_dasm_str, "asl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "asl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_asl_r_8(void) { - sprintf(g_dasm_str, "asl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asl_r_16(void) { - sprintf(g_dasm_str, "asl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asl_r_32(void) { - sprintf(g_dasm_str, "asl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "asl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_asl_ea(void) { - sprintf(g_dasm_str, "asl.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "asl.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_bcc_8(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_8(g_cpu_ir)); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_8(g_cpu_ir)); } static void d68000_bcc_16(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); } static void d68020_bcc_32(void) { - uint temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "b%-2s $%x; (2+)", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); + uint temp_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "b%-2s $%x; (2+)", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); } static void d68000_bchg_r(void) { - sprintf(g_dasm_str, "bchg D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "bchg D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_bchg_s(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bchg %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "bchg %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_bclr_r(void) { - sprintf(g_dasm_str, "bclr D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "bclr D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_bclr_s(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bclr %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "bclr %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68010_bkpt(void) { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "bkpt #%d; (1+)", g_cpu_ir&7); + LIMIT_CPU_TYPES(M68010_PLUS); + sprintf(g_dasm_str, "bkpt #%d; (1+)", g_cpu_ir&7); } static void d68020_bfchg(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); } static void d68020_bfclr(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); } static void d68020_bfexts(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfexts %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfexts %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); } static void d68020_bfextu(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfextu %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfextu %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); } static void d68020_bfffo(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfffo %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfffo %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7); } static void d68020_bfins(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); } static void d68020_bfset(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); } static void d68020_bftst(void) { - uint extension; - char offset[3]; - char width[3]; + uint extension; + char offset[3]; + char width[3]; - LIMIT_CPU_TYPES(M68020_PLUS); + LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + if(BIT_B(extension)) + sprintf(offset, "D%d", (extension>>6)&7); + else + sprintf(offset, "%d", (extension>>6)&31); + if(BIT_5(extension)) + sprintf(width, "D%d", extension&7); + else + sprintf(width, "%d", g_5bit_data_table[extension&31]); + sprintf(g_dasm_str, "bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); } static void d68000_bra_8(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_8(g_cpu_ir)); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_8(g_cpu_ir)); } static void d68000_bra_16(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_16(read_imm_16())); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_16(read_imm_16())); } static void d68020_bra_32(void) { - uint temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bra $%x; (2+)", temp_pc + read_imm_32()); + uint temp_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "bra $%x; (2+)", temp_pc + read_imm_32()); } static void d68000_bset_r(void) { - sprintf(g_dasm_str, "bset D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "bset D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_bset_s(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bset %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "bset %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_bsr_8(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_8(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_8(g_cpu_ir)); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_bsr_16(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_16(read_imm_16())); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68020_bsr_32(void) { - uint temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bsr $%x; (2+)", temp_pc + read_imm_32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + uint temp_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "bsr $%x; (2+)", temp_pc + read_imm_32()); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_btst_r(void) { - sprintf(g_dasm_str, "btst D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "btst D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_btst_s(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "btst %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "btst %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68020_callm(void) { - char* str; - LIMIT_CPU_TYPES(M68020_ONLY); - str = get_imm_str_u8(); + char* str; + LIMIT_CPU_TYPES(M68020_ONLY); + str = get_imm_str_u8(); - sprintf(g_dasm_str, "callm %s, %s; (2)", str, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "callm %s, %s; (2)", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68020_cas_8(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_8(g_cpu_ir)); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68020_cas_16(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_16(g_cpu_ir)); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68020_cas_32(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_32(g_cpu_ir)); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68020_cas2_16(void) @@ -1277,1879 +1277,1879 @@ f e d c b a 9 8 7 6 5 4 3 2 1 0 DARn2 0 0 0 Du2 0 0 0 Dc2 */ - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.w D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)", - (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_32(); + sprintf(g_dasm_str, "cas2.w D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)", + (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, + BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, + BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68020_cas2_32(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.l D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)", - (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_32(); + sprintf(g_dasm_str, "cas2.l D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)", + (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, + BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, + BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68000_chk_16(void) { - sprintf(g_dasm_str, "chk.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + sprintf(g_dasm_str, "chk.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68020_chk_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "chk.l %s, D%d; (2+)", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "chk.l %s, D%d; (2+)", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68020_chk2_cmp2_8(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.b %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "%s.b %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68020_chk2_cmp2_16(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.w %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "%s.w %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68020_chk2_cmp2_32(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.l %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + sprintf(g_dasm_str, "%s.l %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68040_cinv(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - switch((g_cpu_ir>>3)&3) - { - case 0: - sprintf(g_dasm_str, "cinv (illegal scope); (4)"); - break; - case 1: - sprintf(g_dasm_str, "cinvl %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); - break; - case 2: - sprintf(g_dasm_str, "cinvp %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); - break; - case 3: - sprintf(g_dasm_str, "cinva %d; (4)", (g_cpu_ir>>6)&3); - break; - } + LIMIT_CPU_TYPES(M68040_PLUS); + switch((g_cpu_ir>>3)&3) + { + case 0: + sprintf(g_dasm_str, "cinv (illegal scope); (4)"); + break; + case 1: + sprintf(g_dasm_str, "cinvl %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); + break; + case 2: + sprintf(g_dasm_str, "cinvp %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); + break; + case 3: + sprintf(g_dasm_str, "cinva %d; (4)", (g_cpu_ir>>6)&3); + break; + } } static void d68000_clr_8(void) { - sprintf(g_dasm_str, "clr.b %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "clr.b %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_clr_16(void) { - sprintf(g_dasm_str, "clr.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "clr.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_clr_32(void) { - sprintf(g_dasm_str, "clr.l %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "clr.l %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_cmp_8(void) { - sprintf(g_dasm_str, "cmp.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmp.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_cmp_16(void) { - sprintf(g_dasm_str, "cmp.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmp.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_cmp_32(void) { - sprintf(g_dasm_str, "cmp.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmp.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_cmpa_16(void) { - sprintf(g_dasm_str, "cmpa.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmpa.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_cmpa_32(void) { - sprintf(g_dasm_str, "cmpa.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmpa.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_cmpi_8(void) { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_s8(); + sprintf(g_dasm_str, "cmpi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68020_cmpi_pcdi_8(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s8(); + sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68020_cmpi_pcix_8(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s8(); + sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_cmpi_16(void) { - char* str; - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str; + str = get_imm_str_s16(); + sprintf(g_dasm_str, "cmpi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68020_cmpi_pcdi_16(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s16(); + sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68020_cmpi_pcix_16(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s16(); + sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_cmpi_32(void) { - char* str; - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str; + str = get_imm_str_s32(); + sprintf(g_dasm_str, "cmpi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68020_cmpi_pcdi_32(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s32(); + sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68020_cmpi_pcix_32(void) { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + char* str; + LIMIT_CPU_TYPES(M68010_PLUS); + str = get_imm_str_s32(); + sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_cmpm_8(void) { - sprintf(g_dasm_str, "cmpm.b (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmpm.b (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_cmpm_16(void) { - sprintf(g_dasm_str, "cmpm.w (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmpm.w (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_cmpm_32(void) { - sprintf(g_dasm_str, "cmpm.l (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "cmpm.l (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68020_cpbcc_16(void) { - uint extension; - uint new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + uint extension; + uint new_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + new_pc += make_int_16(read_imm_16()); + sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } static void d68020_cpbcc_32(void) { - uint extension; - uint new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - new_pc += read_imm_32(); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + uint extension; + uint new_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); + new_pc += read_imm_32(); + sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } static void d68020_cpdbcc(void) { - uint extension1; - uint extension2; - uint new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], g_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); + uint extension1; + uint extension2; + uint new_pc = g_cpu_pc; + LIMIT_CPU_TYPES(M68020_PLUS); + extension1 = read_imm_16(); + extension2 = read_imm_16(); + new_pc += make_int_16(read_imm_16()); + sprintf(g_dasm_str, "%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], g_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); } static void d68020_cpgen(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "%dgen %s; (2-3)", (g_cpu_ir>>9)&7, get_imm_str_u32()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "%dgen %s; (2-3)", (g_cpu_ir>>9)&7, get_imm_str_u32()); } static void d68020_cprestore(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) - { - sprintf(g_dasm_str, "frestore %s", get_ea_mode_str_8(g_cpu_ir)); - } - else - { - sprintf(g_dasm_str, "%drestore %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); - } + LIMIT_CPU_TYPES(M68020_PLUS); + if (((g_cpu_ir>>9)&7) == 1) + { + sprintf(g_dasm_str, "frestore %s", get_ea_mode_str_8(g_cpu_ir)); + } + else + { + sprintf(g_dasm_str, "%drestore %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + } } static void d68020_cpsave(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) - { - sprintf(g_dasm_str, "fsave %s", get_ea_mode_str_8(g_cpu_ir)); - } - else - { - sprintf(g_dasm_str, "%dsave %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); - } + LIMIT_CPU_TYPES(M68020_PLUS); + if (((g_cpu_ir>>9)&7) == 1) + { + sprintf(g_dasm_str, "fsave %s", get_ea_mode_str_8(g_cpu_ir)); + } + else + { + sprintf(g_dasm_str, "%dsave %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + } } static void d68020_cpscc(void) { - uint extension1; - uint extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%ds%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_ea_mode_str_8(g_cpu_ir), extension2); + uint extension1; + uint extension2; + LIMIT_CPU_TYPES(M68020_PLUS); + extension1 = read_imm_16(); + extension2 = read_imm_16(); + sprintf(g_dasm_str, "%ds%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_ea_mode_str_8(g_cpu_ir), extension2); } static void d68020_cptrapcc_0(void) { - uint extension1; - uint extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], extension2); + uint extension1; + uint extension2; + LIMIT_CPU_TYPES(M68020_PLUS); + extension1 = read_imm_16(); + extension2 = read_imm_16(); + sprintf(g_dasm_str, "%dtrap%-4s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], extension2); } static void d68020_cptrapcc_16(void) { - uint extension1; - uint extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); + uint extension1; + uint extension2; + LIMIT_CPU_TYPES(M68020_PLUS); + extension1 = read_imm_16(); + extension2 = read_imm_16(); + sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); } static void d68020_cptrapcc_32(void) { - uint extension1; - uint extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); + uint extension1; + uint extension2; + LIMIT_CPU_TYPES(M68020_PLUS); + extension1 = read_imm_16(); + extension2 = read_imm_16(); + sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); } static void d68040_cpush(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - switch((g_cpu_ir>>3)&3) - { - case 0: - sprintf(g_dasm_str, "cpush (illegal scope); (4)"); - break; - case 1: - sprintf(g_dasm_str, "cpushl %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); - break; - case 2: - sprintf(g_dasm_str, "cpushp %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); - break; - case 3: - sprintf(g_dasm_str, "cpusha %d; (4)", (g_cpu_ir>>6)&3); - break; - } + LIMIT_CPU_TYPES(M68040_PLUS); + switch((g_cpu_ir>>3)&3) + { + case 0: + sprintf(g_dasm_str, "cpush (illegal scope); (4)"); + break; + case 1: + sprintf(g_dasm_str, "cpushl %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); + break; + case 2: + sprintf(g_dasm_str, "cpushp %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7); + break; + case 3: + sprintf(g_dasm_str, "cpusha %d; (4)", (g_cpu_ir>>6)&3); + break; + } } static void d68000_dbra(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "dbra D%d, $%x", g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "dbra D%d, $%x", g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_dbcc(void) { - uint temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "db%-2s D%d, $%x", g_cc[(g_cpu_ir>>8)&0xf], g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + uint temp_pc = g_cpu_pc; + sprintf(g_dasm_str, "db%-2s D%d, $%x", g_cc[(g_cpu_ir>>8)&0xf], g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_divs(void) { - sprintf(g_dasm_str, "divs.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "divs.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_divu(void) { - sprintf(g_dasm_str, "divu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "divu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68020_divl(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); - if(BIT_A(extension)) - sprintf(g_dasm_str, "div%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); - else if((extension&7) == ((extension>>12)&7)) - sprintf(g_dasm_str, "div%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); - else - sprintf(g_dasm_str, "div%cl.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + if(BIT_A(extension)) + sprintf(g_dasm_str, "div%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + else if((extension&7) == ((extension>>12)&7)) + sprintf(g_dasm_str, "div%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + else + sprintf(g_dasm_str, "div%cl.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); } static void d68000_eor_8(void) { - sprintf(g_dasm_str, "eor.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "eor.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_eor_16(void) { - sprintf(g_dasm_str, "eor.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "eor.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_eor_32(void) { - sprintf(g_dasm_str, "eor.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "eor.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_eori_8(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "eori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "eori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_eori_16(void) { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "eori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str = get_imm_str_u16(); + sprintf(g_dasm_str, "eori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_eori_32(void) { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "eori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str = get_imm_str_u32(); + sprintf(g_dasm_str, "eori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_eori_to_ccr(void) { - sprintf(g_dasm_str, "eori %s, CCR", get_imm_str_u8()); + sprintf(g_dasm_str, "eori %s, CCR", get_imm_str_u8()); } static void d68000_eori_to_sr(void) { - sprintf(g_dasm_str, "eori %s, SR", get_imm_str_u16()); + sprintf(g_dasm_str, "eori %s, SR", get_imm_str_u16()); } static void d68000_exg_dd(void) { - sprintf(g_dasm_str, "exg D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "exg D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_exg_aa(void) { - sprintf(g_dasm_str, "exg A%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "exg A%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_exg_da(void) { - sprintf(g_dasm_str, "exg D%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "exg D%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_ext_16(void) { - sprintf(g_dasm_str, "ext.w D%d", g_cpu_ir&7); + sprintf(g_dasm_str, "ext.w D%d", g_cpu_ir&7); } static void d68000_ext_32(void) { - sprintf(g_dasm_str, "ext.l D%d", g_cpu_ir&7); + sprintf(g_dasm_str, "ext.l D%d", g_cpu_ir&7); } static void d68020_extb_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "extb.l D%d; (2+)", g_cpu_ir&7); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "extb.l D%d; (2+)", g_cpu_ir&7); } static void d68040_fpu(void) { - char float_data_format[8][3] = - { - ".l", ".s", ".x", ".p", ".w", ".d", ".b", ".p" - }; + char float_data_format[8][3] = + { + ".l", ".s", ".x", ".p", ".w", ".d", ".b", ".p" + }; - char mnemonic[40]; - uint32 w2, src, dst_reg; - LIMIT_CPU_TYPES(M68030_PLUS); - w2 = read_imm_16(); + char mnemonic[40]; + uint32 w2, src, dst_reg; + LIMIT_CPU_TYPES(M68030_PLUS); + w2 = read_imm_16(); - src = (w2 >> 10) & 0x7; - dst_reg = (w2 >> 7) & 0x7; + src = (w2 >> 10) & 0x7; + dst_reg = (w2 >> 7) & 0x7; - // special override for FMOVECR - if ((((w2 >> 13) & 0x7) == 2) && (((w2>>10)&0x7) == 7)) - { - sprintf(g_dasm_str, "fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); - return; - } + // special override for FMOVECR + if ((((w2 >> 13) & 0x7) == 2) && (((w2>>10)&0x7) == 7)) + { + sprintf(g_dasm_str, "fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); + return; + } - switch ((w2 >> 13) & 0x7) - { - case 0x0: - case 0x2: - { - switch(w2 & 0x7f) - { - case 0x00: sprintf(mnemonic, "fmove"); break; - case 0x01: sprintf(mnemonic, "fint"); break; - case 0x02: sprintf(mnemonic, "fsinh"); break; - case 0x03: sprintf(mnemonic, "fintrz"); break; - case 0x04: sprintf(mnemonic, "fsqrt"); break; - case 0x06: sprintf(mnemonic, "flognp1"); break; - case 0x08: sprintf(mnemonic, "fetoxm1"); break; - case 0x09: sprintf(mnemonic, "ftanh1"); break; - case 0x0a: sprintf(mnemonic, "fatan"); break; - case 0x0c: sprintf(mnemonic, "fasin"); break; - case 0x0d: sprintf(mnemonic, "fatanh"); break; - case 0x0e: sprintf(mnemonic, "fsin"); break; - case 0x0f: sprintf(mnemonic, "ftan"); break; - case 0x10: sprintf(mnemonic, "fetox"); break; - case 0x11: sprintf(mnemonic, "ftwotox"); break; - case 0x12: sprintf(mnemonic, "ftentox"); break; - case 0x14: sprintf(mnemonic, "flogn"); break; - case 0x15: sprintf(mnemonic, "flog10"); break; - case 0x16: sprintf(mnemonic, "flog2"); break; - case 0x18: sprintf(mnemonic, "fabs"); break; - case 0x19: sprintf(mnemonic, "fcosh"); break; - case 0x1a: sprintf(mnemonic, "fneg"); break; - case 0x1c: sprintf(mnemonic, "facos"); break; - case 0x1d: sprintf(mnemonic, "fcos"); break; - case 0x1e: sprintf(mnemonic, "fgetexp"); break; - case 0x1f: sprintf(mnemonic, "fgetman"); break; - case 0x20: sprintf(mnemonic, "fdiv"); break; - case 0x21: sprintf(mnemonic, "fmod"); break; - case 0x22: sprintf(mnemonic, "fadd"); break; - case 0x23: sprintf(mnemonic, "fmul"); break; - case 0x24: sprintf(mnemonic, "fsgldiv"); break; - case 0x25: sprintf(mnemonic, "frem"); break; - case 0x26: sprintf(mnemonic, "fscale"); break; - case 0x27: sprintf(mnemonic, "fsglmul"); break; - case 0x28: sprintf(mnemonic, "fsub"); break; - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - sprintf(mnemonic, "fsincos"); break; - case 0x38: sprintf(mnemonic, "fcmp"); break; - case 0x3a: sprintf(mnemonic, "ftst"); break; - case 0x41: sprintf(mnemonic, "fssqrt"); break; - case 0x45: sprintf(mnemonic, "fdsqrt"); break; - case 0x58: sprintf(mnemonic, "fsabs"); break; - case 0x5a: sprintf(mnemonic, "fsneg"); break; - case 0x5c: sprintf(mnemonic, "fdabs"); break; - case 0x5e: sprintf(mnemonic, "fdneg"); break; - case 0x60: sprintf(mnemonic, "fsdiv"); break; - case 0x62: sprintf(mnemonic, "fsadd"); break; - case 0x63: sprintf(mnemonic, "fsmul"); break; - case 0x64: sprintf(mnemonic, "fddiv"); break; - case 0x66: sprintf(mnemonic, "fdadd"); break; - case 0x67: sprintf(mnemonic, "fdmul"); break; - case 0x68: sprintf(mnemonic, "fssub"); break; - case 0x6c: sprintf(mnemonic, "fdsub"); break; + switch ((w2 >> 13) & 0x7) + { + case 0x0: + case 0x2: + { + switch(w2 & 0x7f) + { + case 0x00: sprintf(mnemonic, "fmove"); break; + case 0x01: sprintf(mnemonic, "fint"); break; + case 0x02: sprintf(mnemonic, "fsinh"); break; + case 0x03: sprintf(mnemonic, "fintrz"); break; + case 0x04: sprintf(mnemonic, "fsqrt"); break; + case 0x06: sprintf(mnemonic, "flognp1"); break; + case 0x08: sprintf(mnemonic, "fetoxm1"); break; + case 0x09: sprintf(mnemonic, "ftanh1"); break; + case 0x0a: sprintf(mnemonic, "fatan"); break; + case 0x0c: sprintf(mnemonic, "fasin"); break; + case 0x0d: sprintf(mnemonic, "fatanh"); break; + case 0x0e: sprintf(mnemonic, "fsin"); break; + case 0x0f: sprintf(mnemonic, "ftan"); break; + case 0x10: sprintf(mnemonic, "fetox"); break; + case 0x11: sprintf(mnemonic, "ftwotox"); break; + case 0x12: sprintf(mnemonic, "ftentox"); break; + case 0x14: sprintf(mnemonic, "flogn"); break; + case 0x15: sprintf(mnemonic, "flog10"); break; + case 0x16: sprintf(mnemonic, "flog2"); break; + case 0x18: sprintf(mnemonic, "fabs"); break; + case 0x19: sprintf(mnemonic, "fcosh"); break; + case 0x1a: sprintf(mnemonic, "fneg"); break; + case 0x1c: sprintf(mnemonic, "facos"); break; + case 0x1d: sprintf(mnemonic, "fcos"); break; + case 0x1e: sprintf(mnemonic, "fgetexp"); break; + case 0x1f: sprintf(mnemonic, "fgetman"); break; + case 0x20: sprintf(mnemonic, "fdiv"); break; + case 0x21: sprintf(mnemonic, "fmod"); break; + case 0x22: sprintf(mnemonic, "fadd"); break; + case 0x23: sprintf(mnemonic, "fmul"); break; + case 0x24: sprintf(mnemonic, "fsgldiv"); break; + case 0x25: sprintf(mnemonic, "frem"); break; + case 0x26: sprintf(mnemonic, "fscale"); break; + case 0x27: sprintf(mnemonic, "fsglmul"); break; + case 0x28: sprintf(mnemonic, "fsub"); break; + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + sprintf(mnemonic, "fsincos"); break; + case 0x38: sprintf(mnemonic, "fcmp"); break; + case 0x3a: sprintf(mnemonic, "ftst"); break; + case 0x41: sprintf(mnemonic, "fssqrt"); break; + case 0x45: sprintf(mnemonic, "fdsqrt"); break; + case 0x58: sprintf(mnemonic, "fsabs"); break; + case 0x5a: sprintf(mnemonic, "fsneg"); break; + case 0x5c: sprintf(mnemonic, "fdabs"); break; + case 0x5e: sprintf(mnemonic, "fdneg"); break; + case 0x60: sprintf(mnemonic, "fsdiv"); break; + case 0x62: sprintf(mnemonic, "fsadd"); break; + case 0x63: sprintf(mnemonic, "fsmul"); break; + case 0x64: sprintf(mnemonic, "fddiv"); break; + case 0x66: sprintf(mnemonic, "fdadd"); break; + case 0x67: sprintf(mnemonic, "fdmul"); break; + case 0x68: sprintf(mnemonic, "fssub"); break; + case 0x6c: sprintf(mnemonic, "fdsub"); break; - default: sprintf(mnemonic, "FPU (?)"); break; - } + default: sprintf(mnemonic, "FPU (?)"); break; + } - if (w2 & 0x4000) - { - sprintf(g_dasm_str, "%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(g_cpu_ir), dst_reg); - } - else - { - sprintf(g_dasm_str, "%s.x FP%d, FP%d", mnemonic, src, dst_reg); - } - break; - } + if (w2 & 0x4000) + { + sprintf(g_dasm_str, "%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(g_cpu_ir), dst_reg); + } + else + { + sprintf(g_dasm_str, "%s.x FP%d, FP%d", mnemonic, src, dst_reg); + } + break; + } - case 0x3: - { - switch ((w2>>10)&7) - { - case 3: // packed decimal w/fixed k-factor - sprintf(g_dasm_str, "fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), sext_7bit_int(w2&0x7f)); - break; + case 0x3: + { + switch ((w2>>10)&7) + { + case 3: // packed decimal w/fixed k-factor + sprintf(g_dasm_str, "fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), sext_7bit_int(w2&0x7f)); + break; - case 7: // packed decimal w/dynamic k-factor (register) - sprintf(g_dasm_str, "fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); - break; + case 7: // packed decimal w/dynamic k-factor (register) + sprintf(g_dasm_str, "fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); + break; - default: - sprintf(g_dasm_str, "fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir)); - break; - } - break; - } + default: + sprintf(g_dasm_str, "fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir)); + break; + } + break; + } - case 0x4: // ea to control - { - sprintf(g_dasm_str, "fmovem.l %s, ", get_ea_mode_str_32(g_cpu_ir)); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - break; - } + case 0x4: // ea to control + { + sprintf(g_dasm_str, "fmovem.l %s, ", get_ea_mode_str_32(g_cpu_ir)); + if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); + if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); + if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); + break; + } - case 0x5: // control to ea - { - - strcpy(g_dasm_str, "fmovem.l "); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); - break; - } + case 0x5: // control to ea + { + + strcpy(g_dasm_str, "fmovem.l "); + if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); + if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); + if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); + strcat(g_dasm_str, ", "); + strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); + break; + } - case 0x6: // memory to FPU, list - { - char temp[32]; + case 0x6: // memory to FPU, list + { + char temp[32]; - if ((w2>>11) & 1) // dynamic register list - { - sprintf(g_dasm_str, "fmovem.x %s, D%d", get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); - } - else // static register list - { - int i; + if ((w2>>11) & 1) // dynamic register list + { + sprintf(g_dasm_str, "fmovem.x %s, D%d", get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); + } + else // static register list + { + int i; - sprintf(g_dasm_str, "fmovem.x %s, ", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "fmovem.x %s, ", get_ea_mode_str_32(g_cpu_ir)); - for (i = 0; i < 8; i++) - { - if (w2 & (1<>12) & 1) // postincrement or control - { - sprintf(temp, "FP%d ", 7-i); - } - else // predecrement - { - sprintf(temp, "FP%d ", i); - } - strcat(g_dasm_str, temp); - } - } - } - break; - } + for (i = 0; i < 8; i++) + { + if (w2 & (1<>12) & 1) // postincrement or control + { + sprintf(temp, "FP%d ", 7-i); + } + else // predecrement + { + sprintf(temp, "FP%d ", i); + } + strcat(g_dasm_str, temp); + } + } + } + break; + } - case 0x7: // FPU to memory, list - { - char temp[32]; + case 0x7: // FPU to memory, list + { + char temp[32]; - if ((w2>>11) & 1) // dynamic register list - { - sprintf(g_dasm_str, "fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(g_cpu_ir)); - } - else // static register list - { - int i; + if ((w2>>11) & 1) // dynamic register list + { + sprintf(g_dasm_str, "fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(g_cpu_ir)); + } + else // static register list + { + int i; - sprintf(g_dasm_str, "fmovem.x "); + sprintf(g_dasm_str, "fmovem.x "); - for (i = 0; i < 8; i++) - { - if (w2 & (1<>12) & 1) // postincrement or control - { - sprintf(temp, "FP%d ", 7-i); - } - else // predecrement - { - sprintf(temp, "FP%d ", i); - } - strcat(g_dasm_str, temp); - } - } + for (i = 0; i < 8; i++) + { + if (w2 & (1<>12) & 1) // postincrement or control + { + sprintf(temp, "FP%d ", 7-i); + } + else // predecrement + { + sprintf(temp, "FP%d ", i); + } + strcat(g_dasm_str, temp); + } + } - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); - } - break; - } + strcat(g_dasm_str, ", "); + strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); + } + break; + } - default: - { - sprintf(g_dasm_str, "FPU (?) "); - break; - } - } + default: + { + sprintf(g_dasm_str, "FPU (?) "); + break; + } + } } static void d68000_jmp(void) { - sprintf(g_dasm_str, "jmp %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "jmp %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_jsr(void) { - sprintf(g_dasm_str, "jsr %s", get_ea_mode_str_32(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + sprintf(g_dasm_str, "jsr %s", get_ea_mode_str_32(g_cpu_ir)); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_lea(void) { - sprintf(g_dasm_str, "lea %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "lea %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_link_16(void) { - sprintf(g_dasm_str, "link A%d, %s", g_cpu_ir&7, get_imm_str_s16()); + sprintf(g_dasm_str, "link A%d, %s", g_cpu_ir&7, get_imm_str_s16()); } static void d68020_link_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "link A%d, %s; (2+)", g_cpu_ir&7, get_imm_str_s32()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "link A%d, %s; (2+)", g_cpu_ir&7, get_imm_str_s32()); } static void d68000_lsr_s_8(void) { - sprintf(g_dasm_str, "lsr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsr_s_16(void) { - sprintf(g_dasm_str, "lsr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsr_s_32(void) { - sprintf(g_dasm_str, "lsr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsr_r_8(void) { - sprintf(g_dasm_str, "lsr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsr_r_16(void) { - sprintf(g_dasm_str, "lsr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsr_r_32(void) { - sprintf(g_dasm_str, "lsr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsr_ea(void) { - sprintf(g_dasm_str, "lsr.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "lsr.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_lsl_s_8(void) { - sprintf(g_dasm_str, "lsl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsl_s_16(void) { - sprintf(g_dasm_str, "lsl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsl_s_32(void) { - sprintf(g_dasm_str, "lsl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_lsl_r_8(void) { - sprintf(g_dasm_str, "lsl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsl_r_16(void) { - sprintf(g_dasm_str, "lsl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsl_r_32(void) { - sprintf(g_dasm_str, "lsl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "lsl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_lsl_ea(void) { - sprintf(g_dasm_str, "lsl.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "lsl.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_move_8(void) { - char* str = get_ea_mode_str_8(g_cpu_ir); - sprintf(g_dasm_str, "move.b %s, %s", str, get_ea_mode_str_8(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + char* str = get_ea_mode_str_8(g_cpu_ir); + sprintf(g_dasm_str, "move.b %s, %s", str, get_ea_mode_str_8(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); } static void d68000_move_16(void) { - char* str = get_ea_mode_str_16(g_cpu_ir); - sprintf(g_dasm_str, "move.w %s, %s", str, get_ea_mode_str_16(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + char* str = get_ea_mode_str_16(g_cpu_ir); + sprintf(g_dasm_str, "move.w %s, %s", str, get_ea_mode_str_16(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); } static void d68000_move_32(void) { - char* str = get_ea_mode_str_32(g_cpu_ir); - sprintf(g_dasm_str, "move.l %s, %s", str, get_ea_mode_str_32(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + char* str = get_ea_mode_str_32(g_cpu_ir); + sprintf(g_dasm_str, "move.l %s, %s", str, get_ea_mode_str_32(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); } static void d68000_movea_16(void) { - sprintf(g_dasm_str, "movea.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "movea.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_movea_32(void) { - sprintf(g_dasm_str, "movea.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "movea.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_move_to_ccr(void) { - sprintf(g_dasm_str, "move %s, CCR", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "move %s, CCR", get_ea_mode_str_8(g_cpu_ir)); } static void d68010_move_fr_ccr(void) { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "move CCR, %s; (1+)", get_ea_mode_str_8(g_cpu_ir)); + LIMIT_CPU_TYPES(M68010_PLUS); + sprintf(g_dasm_str, "move CCR, %s; (1+)", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_move_fr_sr(void) { - sprintf(g_dasm_str, "move SR, %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "move SR, %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_move_to_sr(void) { - sprintf(g_dasm_str, "move %s, SR", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "move %s, SR", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_move_fr_usp(void) { - sprintf(g_dasm_str, "move USP, A%d", g_cpu_ir&7); + sprintf(g_dasm_str, "move USP, A%d", g_cpu_ir&7); } static void d68000_move_to_usp(void) { - sprintf(g_dasm_str, "move A%d, USP", g_cpu_ir&7); + sprintf(g_dasm_str, "move A%d, USP", g_cpu_ir&7); } static void d68010_movec(void) { - uint extension; - char* reg_name; - char* processor; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); + uint extension; + char* reg_name; + char* processor; + LIMIT_CPU_TYPES(M68010_PLUS); + extension = read_imm_16(); - switch(extension & 0xfff) - { - case 0x000: - reg_name = "SFC"; - processor = "1+"; - break; - case 0x001: - reg_name = "DFC"; - processor = "1+"; - break; - case 0x800: - reg_name = "USP"; - processor = "1+"; - break; - case 0x801: - reg_name = "VBR"; - processor = "1+"; - break; - case 0x002: - reg_name = "CACR"; - processor = "2+"; - break; - case 0x802: - reg_name = "CAAR"; - processor = "2,3"; - break; - case 0x803: - reg_name = "MSP"; - processor = "2+"; - break; - case 0x804: - reg_name = "ISP"; - processor = "2+"; - break; - case 0x003: - reg_name = "TC"; - processor = "4+"; - break; - case 0x004: - reg_name = "ITT0"; - processor = "4+"; - break; - case 0x005: - reg_name = "ITT1"; - processor = "4+"; - break; - case 0x006: - reg_name = "DTT0"; - processor = "4+"; - break; - case 0x007: - reg_name = "DTT1"; - processor = "4+"; - break; - case 0x805: - reg_name = "MMUSR"; - processor = "4+"; - break; - case 0x806: - reg_name = "URP"; - processor = "4+"; - break; - case 0x807: - reg_name = "SRP"; - processor = "4+"; - break; - default: - reg_name = make_signed_hex_str_16(extension & 0xfff); - processor = "?"; - } + switch(extension & 0xfff) + { + case 0x000: + reg_name = "SFC"; + processor = "1+"; + break; + case 0x001: + reg_name = "DFC"; + processor = "1+"; + break; + case 0x800: + reg_name = "USP"; + processor = "1+"; + break; + case 0x801: + reg_name = "VBR"; + processor = "1+"; + break; + case 0x002: + reg_name = "CACR"; + processor = "2+"; + break; + case 0x802: + reg_name = "CAAR"; + processor = "2,3"; + break; + case 0x803: + reg_name = "MSP"; + processor = "2+"; + break; + case 0x804: + reg_name = "ISP"; + processor = "2+"; + break; + case 0x003: + reg_name = "TC"; + processor = "4+"; + break; + case 0x004: + reg_name = "ITT0"; + processor = "4+"; + break; + case 0x005: + reg_name = "ITT1"; + processor = "4+"; + break; + case 0x006: + reg_name = "DTT0"; + processor = "4+"; + break; + case 0x007: + reg_name = "DTT1"; + processor = "4+"; + break; + case 0x805: + reg_name = "MMUSR"; + processor = "4+"; + break; + case 0x806: + reg_name = "URP"; + processor = "4+"; + break; + case 0x807: + reg_name = "SRP"; + processor = "4+"; + break; + default: + reg_name = make_signed_hex_str_16(extension & 0xfff); + processor = "?"; + } - if(BIT_0(g_cpu_ir)) - sprintf(g_dasm_str, "movec %c%d, %s; (%s)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); - else - sprintf(g_dasm_str, "movec %s, %c%d; (%s)", reg_name, BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, processor); + if(BIT_0(g_cpu_ir)) + sprintf(g_dasm_str, "movec %c%d, %s; (%s)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); + else + sprintf(g_dasm_str, "movec %s, %c%d; (%s)", reg_name, BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, processor); } static void d68000_movem_pd_16(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1<<(15-i))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(15-(i+1))))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(7-i))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(7-(i+1))))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1<<(15-i))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(15-(i+1))))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "D%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(7-i))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(7-(i+1))))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_movem_pd_32(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1<<(15-i))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(15-(i+1))))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(7-i))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(7-(i+1))))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1<<(15-i))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(15-(i+1))))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "D%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(7-i))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(7-(i+1))))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_movem_er_16(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1< 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(i+8))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(i+8+1)))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.w %s, %s", get_ea_mode_str_16(g_cpu_ir), buffer); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1< 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(i+8))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(i+8+1)))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.w %s, %s", get_ea_mode_str_16(g_cpu_ir), buffer); } static void d68000_movem_er_32(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1< 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(i+8))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(i+8+1)))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.l %s, %s", get_ea_mode_str_32(g_cpu_ir), buffer); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1< 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(i+8))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(i+8+1)))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.l %s, %s", get_ea_mode_str_32(g_cpu_ir), buffer); } static void d68000_movem_re_16(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1< 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(i+8))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(i+8+1)))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1< 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(i+8))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(i+8+1)))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_movem_re_32(void) { - uint data = read_imm_16(); - char buffer[40]; - uint first; - uint run_length; - uint i; + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; - buffer[0] = 0; - for(i=0;i<8;i++) - { - if(data&(1< 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); - } - } - for(i=0;i<8;i++) - { - if(data&(1<<(i+8))) - { - first = i; - run_length = 0; - while(i<7 && (data&(1<<(i+8+1)))) - { - i++; - run_length++; - } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); - if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); - } - } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1< 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + for(i=0;i<8;i++) + { + if(data&(1<<(i+8))) + { + first = i; + run_length = 0; + while(i<7 && (data&(1<<(i+8+1)))) + { + i++; + run_length++; + } + if(buffer[0] != 0) + strcat(buffer, "/"); + sprintf(buffer+strlen(buffer), "A%d", first); + if(run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_movep_re_16(void) { - sprintf(g_dasm_str, "movep.w D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + sprintf(g_dasm_str, "movep.w D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); } static void d68000_movep_re_32(void) { - sprintf(g_dasm_str, "movep.l D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + sprintf(g_dasm_str, "movep.l D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); } static void d68000_movep_er_16(void) { - sprintf(g_dasm_str, "movep.w ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "movep.w ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_movep_er_32(void) { - sprintf(g_dasm_str, "movep.l ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "movep.l ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68010_moves_8(void) { - uint extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.b %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir)); - else - sprintf(g_dasm_str, "moves.b %s, %c%d; (1+)", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68010_PLUS); + extension = read_imm_16(); + if(BIT_B(extension)) + sprintf(g_dasm_str, "moves.b %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir)); + else + sprintf(g_dasm_str, "moves.b %s, %c%d; (1+)", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68010_moves_16(void) { - uint extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.w %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(g_cpu_ir)); - else - sprintf(g_dasm_str, "moves.w %s, %c%d; (1+)", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68010_PLUS); + extension = read_imm_16(); + if(BIT_B(extension)) + sprintf(g_dasm_str, "moves.w %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(g_cpu_ir)); + else + sprintf(g_dasm_str, "moves.w %s, %c%d; (1+)", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68010_moves_32(void) { - uint extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.l %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(g_cpu_ir)); - else - sprintf(g_dasm_str, "moves.l %s, %c%d; (1+)", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + uint extension; + LIMIT_CPU_TYPES(M68010_PLUS); + extension = read_imm_16(); + if(BIT_B(extension)) + sprintf(g_dasm_str, "moves.l %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(g_cpu_ir)); + else + sprintf(g_dasm_str, "moves.l %s, %c%d; (1+)", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); } static void d68000_moveq(void) { - sprintf(g_dasm_str, "moveq #%s, D%d", make_signed_hex_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "moveq #%s, D%d", make_signed_hex_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68040_move16_pi_pi(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, (A%d)+; (4)", g_cpu_ir&7, (read_imm_16()>>12)&7); + LIMIT_CPU_TYPES(M68040_PLUS); + sprintf(g_dasm_str, "move16 (A%d)+, (A%d)+; (4)", g_cpu_ir&7, (read_imm_16()>>12)&7); } static void d68040_move16_pi_al(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + LIMIT_CPU_TYPES(M68040_PLUS); + sprintf(g_dasm_str, "move16 (A%d)+, %s; (4)", g_cpu_ir&7, get_imm_str_u32()); } static void d68040_move16_al_pi(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d)+; (4)", get_imm_str_u32(), g_cpu_ir&7); + LIMIT_CPU_TYPES(M68040_PLUS); + sprintf(g_dasm_str, "move16 %s, (A%d)+; (4)", get_imm_str_u32(), g_cpu_ir&7); } static void d68040_move16_ai_al(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d), %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + LIMIT_CPU_TYPES(M68040_PLUS); + sprintf(g_dasm_str, "move16 (A%d), %s; (4)", g_cpu_ir&7, get_imm_str_u32()); } static void d68040_move16_al_ai(void) { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d); (4)", get_imm_str_u32(), g_cpu_ir&7); + LIMIT_CPU_TYPES(M68040_PLUS); + sprintf(g_dasm_str, "move16 %s, (A%d); (4)", get_imm_str_u32(), g_cpu_ir&7); } static void d68000_muls(void) { - sprintf(g_dasm_str, "muls.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "muls.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_mulu(void) { - sprintf(g_dasm_str, "mulu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "mulu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68020_mull(void) { - uint extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + uint extension; + LIMIT_CPU_TYPES(M68020_PLUS); + extension = read_imm_16(); - if(BIT_A(extension)) - sprintf(g_dasm_str, "mul%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); - else - sprintf(g_dasm_str, "mul%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + if(BIT_A(extension)) + sprintf(g_dasm_str, "mul%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + else + sprintf(g_dasm_str, "mul%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); } static void d68000_nbcd(void) { - sprintf(g_dasm_str, "nbcd %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "nbcd %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_neg_8(void) { - sprintf(g_dasm_str, "neg.b %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "neg.b %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_neg_16(void) { - sprintf(g_dasm_str, "neg.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "neg.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_neg_32(void) { - sprintf(g_dasm_str, "neg.l %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "neg.l %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_negx_8(void) { - sprintf(g_dasm_str, "negx.b %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "negx.b %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_negx_16(void) { - sprintf(g_dasm_str, "negx.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "negx.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_negx_32(void) { - sprintf(g_dasm_str, "negx.l %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "negx.l %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_nop(void) { - sprintf(g_dasm_str, "nop"); + sprintf(g_dasm_str, "nop"); } static void d68000_not_8(void) { - sprintf(g_dasm_str, "not.b %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "not.b %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_not_16(void) { - sprintf(g_dasm_str, "not.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "not.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_not_32(void) { - sprintf(g_dasm_str, "not.l %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "not.l %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_or_er_8(void) { - sprintf(g_dasm_str, "or.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "or.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_or_er_16(void) { - sprintf(g_dasm_str, "or.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "or.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_or_er_32(void) { - sprintf(g_dasm_str, "or.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "or.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_or_re_8(void) { - sprintf(g_dasm_str, "or.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "or.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_or_re_16(void) { - sprintf(g_dasm_str, "or.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "or.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_or_re_32(void) { - sprintf(g_dasm_str, "or.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "or.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_ori_8(void) { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "ori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_u8(); + sprintf(g_dasm_str, "ori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_ori_16(void) { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "ori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str = get_imm_str_u16(); + sprintf(g_dasm_str, "ori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_ori_32(void) { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "ori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str = get_imm_str_u32(); + sprintf(g_dasm_str, "ori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_ori_to_ccr(void) { - sprintf(g_dasm_str, "ori %s, CCR", get_imm_str_u8()); + sprintf(g_dasm_str, "ori %s, CCR", get_imm_str_u8()); } static void d68000_ori_to_sr(void) { - sprintf(g_dasm_str, "ori %s, SR", get_imm_str_u16()); + sprintf(g_dasm_str, "ori %s, SR", get_imm_str_u16()); } static void d68020_pack_rr(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "pack D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); } static void d68020_pack_mm(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "pack -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); } static void d68000_pea(void) { - sprintf(g_dasm_str, "pea %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "pea %s", get_ea_mode_str_32(g_cpu_ir)); } // this is a 68040-specific form of PFLUSH static void d68040_pflush(void) { - LIMIT_CPU_TYPES(M68040_PLUS); + LIMIT_CPU_TYPES(M68040_PLUS); - if (g_cpu_ir & 0x10) - { - sprintf(g_dasm_str, "pflusha%s", (g_cpu_ir & 8) ? "" : "n"); - } - else - { - sprintf(g_dasm_str, "pflush%s(A%d)", (g_cpu_ir & 8) ? "" : "n", g_cpu_ir & 7); - } + if (g_cpu_ir & 0x10) + { + sprintf(g_dasm_str, "pflusha%s", (g_cpu_ir & 8) ? "" : "n"); + } + else + { + sprintf(g_dasm_str, "pflush%s(A%d)", (g_cpu_ir & 8) ? "" : "n", g_cpu_ir & 7); + } } static void d68000_reset(void) { - sprintf(g_dasm_str, "reset"); + sprintf(g_dasm_str, "reset"); } static void d68000_ror_s_8(void) { - sprintf(g_dasm_str, "ror.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "ror.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_ror_s_16(void) { - sprintf(g_dasm_str, "ror.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7],g_cpu_ir&7); + sprintf(g_dasm_str, "ror.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7],g_cpu_ir&7); } static void d68000_ror_s_32(void) { - sprintf(g_dasm_str, "ror.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "ror.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_ror_r_8(void) { - sprintf(g_dasm_str, "ror.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "ror.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_ror_r_16(void) { - sprintf(g_dasm_str, "ror.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "ror.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_ror_r_32(void) { - sprintf(g_dasm_str, "ror.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "ror.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_ror_ea(void) { - sprintf(g_dasm_str, "ror.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "ror.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_rol_s_8(void) { - sprintf(g_dasm_str, "rol.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "rol.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_rol_s_16(void) { - sprintf(g_dasm_str, "rol.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "rol.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_rol_s_32(void) { - sprintf(g_dasm_str, "rol.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "rol.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_rol_r_8(void) { - sprintf(g_dasm_str, "rol.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "rol.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_rol_r_16(void) { - sprintf(g_dasm_str, "rol.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "rol.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_rol_r_32(void) { - sprintf(g_dasm_str, "rol.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "rol.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_rol_ea(void) { - sprintf(g_dasm_str, "rol.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "rol.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_roxr_s_8(void) { - sprintf(g_dasm_str, "roxr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxr_s_16(void) { - sprintf(g_dasm_str, "roxr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxr_s_32(void) { - sprintf(g_dasm_str, "roxr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxr_r_8(void) { - sprintf(g_dasm_str, "roxr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxr_r_16(void) { - sprintf(g_dasm_str, "roxr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxr_r_32(void) { - sprintf(g_dasm_str, "roxr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxr_ea(void) { - sprintf(g_dasm_str, "roxr.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "roxr.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_roxl_s_8(void) { - sprintf(g_dasm_str, "roxl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxl_s_16(void) { - sprintf(g_dasm_str, "roxl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxl_s_32(void) { - sprintf(g_dasm_str, "roxl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); } static void d68000_roxl_r_8(void) { - sprintf(g_dasm_str, "roxl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxl_r_16(void) { - sprintf(g_dasm_str, "roxl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxl_r_32(void) { - sprintf(g_dasm_str, "roxl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + sprintf(g_dasm_str, "roxl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); } static void d68000_roxl_ea(void) { - sprintf(g_dasm_str, "roxl.w %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "roxl.w %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68010_rtd(void) { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "rtd %s; (1+)", get_imm_str_s16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + LIMIT_CPU_TYPES(M68010_PLUS); + sprintf(g_dasm_str, "rtd %s; (1+)", get_imm_str_s16()); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); } static void d68000_rte(void) { - sprintf(g_dasm_str, "rte"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + sprintf(g_dasm_str, "rte"); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); } static void d68020_rtm(void) { - LIMIT_CPU_TYPES(M68020_ONLY); - sprintf(g_dasm_str, "rtm %c%d; (2+)", BIT_3(g_cpu_ir) ? 'A' : 'D', g_cpu_ir&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + LIMIT_CPU_TYPES(M68020_ONLY); + sprintf(g_dasm_str, "rtm %c%d; (2+)", BIT_3(g_cpu_ir) ? 'A' : 'D', g_cpu_ir&7); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); } static void d68000_rtr(void) { - sprintf(g_dasm_str, "rtr"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + sprintf(g_dasm_str, "rtr"); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); } static void d68000_rts(void) { - sprintf(g_dasm_str, "rts"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + sprintf(g_dasm_str, "rts"); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); } static void d68000_sbcd_rr(void) { - sprintf(g_dasm_str, "sbcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "sbcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_sbcd_mm(void) { - sprintf(g_dasm_str, "sbcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "sbcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_scc(void) { - sprintf(g_dasm_str, "s%-2s %s", g_cc[(g_cpu_ir>>8)&0xf], get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "s%-2s %s", g_cc[(g_cpu_ir>>8)&0xf], get_ea_mode_str_8(g_cpu_ir)); } static void d68000_stop(void) { - sprintf(g_dasm_str, "stop %s", get_imm_str_s16()); + sprintf(g_dasm_str, "stop %s", get_imm_str_s16()); } static void d68000_sub_er_8(void) { - sprintf(g_dasm_str, "sub.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "sub.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_sub_er_16(void) { - sprintf(g_dasm_str, "sub.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "sub.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_sub_er_32(void) { - sprintf(g_dasm_str, "sub.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "sub.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_sub_re_8(void) { - sprintf(g_dasm_str, "sub.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "sub.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_sub_re_16(void) { - sprintf(g_dasm_str, "sub.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "sub.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_sub_re_32(void) { - sprintf(g_dasm_str, "sub.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "sub.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_suba_16(void) { - sprintf(g_dasm_str, "suba.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "suba.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_suba_32(void) { - sprintf(g_dasm_str, "suba.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "suba.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); } static void d68000_subi_8(void) { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "subi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + char* str = get_imm_str_s8(); + sprintf(g_dasm_str, "subi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); } static void d68000_subi_16(void) { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "subi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + char* str = get_imm_str_s16(); + sprintf(g_dasm_str, "subi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); } static void d68000_subi_32(void) { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "subi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + char* str = get_imm_str_s32(); + sprintf(g_dasm_str, "subi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); } static void d68000_subq_8(void) { - sprintf(g_dasm_str, "subq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "subq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); } static void d68000_subq_16(void) { - sprintf(g_dasm_str, "subq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "subq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); } static void d68000_subq_32(void) { - sprintf(g_dasm_str, "subq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "subq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); } static void d68000_subx_rr_8(void) { - sprintf(g_dasm_str, "subx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_subx_rr_16(void) { - sprintf(g_dasm_str, "subx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_subx_rr_32(void) { - sprintf(g_dasm_str, "subx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_subx_mm_8(void) { - sprintf(g_dasm_str, "subx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_subx_mm_16(void) { - sprintf(g_dasm_str, "subx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_subx_mm_32(void) { - sprintf(g_dasm_str, "subx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + sprintf(g_dasm_str, "subx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); } static void d68000_swap(void) { - sprintf(g_dasm_str, "swap D%d", g_cpu_ir&7); + sprintf(g_dasm_str, "swap D%d", g_cpu_ir&7); } static void d68000_tas(void) { - sprintf(g_dasm_str, "tas %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "tas %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_trap(void) { - sprintf(g_dasm_str, "trap #$%x", g_cpu_ir&0xf); + sprintf(g_dasm_str, "trap #$%x", g_cpu_ir&0xf); } static void d68020_trapcc_0(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s; (2+)", g_cc[(g_cpu_ir>>8)&0xf]); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "trap%-2s; (2+)", g_cc[(g_cpu_ir>>8)&0xf]); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68020_trapcc_16(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u16()); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68020_trapcc_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u32()); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_trapv(void) { - sprintf(g_dasm_str, "trapv"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + sprintf(g_dasm_str, "trapv"); + SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); } static void d68000_tst_8(void) { - sprintf(g_dasm_str, "tst.b %s", get_ea_mode_str_8(g_cpu_ir)); + sprintf(g_dasm_str, "tst.b %s", get_ea_mode_str_8(g_cpu_ir)); } static void d68020_tst_pcdi_8(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); } static void d68020_tst_pcix_8(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); } static void d68020_tst_i_8(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); } static void d68000_tst_16(void) { - sprintf(g_dasm_str, "tst.w %s", get_ea_mode_str_16(g_cpu_ir)); + sprintf(g_dasm_str, "tst.w %s", get_ea_mode_str_16(g_cpu_ir)); } static void d68020_tst_a_16(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); } static void d68020_tst_pcdi_16(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); } static void d68020_tst_pcix_16(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); } static void d68020_tst_i_16(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); } static void d68000_tst_32(void) { - sprintf(g_dasm_str, "tst.l %s", get_ea_mode_str_32(g_cpu_ir)); + sprintf(g_dasm_str, "tst.l %s", get_ea_mode_str_32(g_cpu_ir)); } static void d68020_tst_a_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); } static void d68020_tst_pcdi_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); } static void d68020_tst_pcix_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); } static void d68020_tst_i_32(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); } static void d68000_unlk(void) { - sprintf(g_dasm_str, "unlk A%d", g_cpu_ir&7); + sprintf(g_dasm_str, "unlk A%d", g_cpu_ir&7); } static void d68020_unpk_rr(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "unpk D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); } static void d68020_unpk_mm(void) { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + LIMIT_CPU_TYPES(M68020_PLUS); + sprintf(g_dasm_str, "unpk -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); } @@ -3164,125 +3164,125 @@ static void d68020_unpk_mm(void) // PFLUSHR: 1010000000000000 static void d68851_p000(void) { - char* str; - uint modes = read_imm_16(); + char* str; + uint modes = read_imm_16(); - // do this after fetching the second PMOVE word so we properly get the 3rd if necessary - str = get_ea_mode_str_32(g_cpu_ir); + // do this after fetching the second PMOVE word so we properly get the 3rd if necessary + str = get_ea_mode_str_32(g_cpu_ir); - if ((modes & 0xfde0) == 0x2000) // PLOAD - { - if (modes & 0x0200) - { - sprintf(g_dasm_str, "pload #%d, %s", (modes>>10)&7, str); - } - else - { - sprintf(g_dasm_str, "pload %s, #%d", str, (modes>>10)&7); - } - return; - } + if ((modes & 0xfde0) == 0x2000) // PLOAD + { + if (modes & 0x0200) + { + sprintf(g_dasm_str, "pload #%d, %s", (modes>>10)&7, str); + } + else + { + sprintf(g_dasm_str, "pload %s, #%d", str, (modes>>10)&7); + } + return; + } - if ((modes & 0xe200) == 0x2000) // PFLUSH - { - sprintf(g_dasm_str, "pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); - return; - } + if ((modes & 0xe200) == 0x2000) // PFLUSH + { + sprintf(g_dasm_str, "pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); + return; + } - if (modes == 0xa000) // PFLUSHR - { - sprintf(g_dasm_str, "pflushr %s", str); - } + if (modes == 0xa000) // PFLUSHR + { + sprintf(g_dasm_str, "pflushr %s", str); + } - if (modes == 0x2800) // PVALID (FORMAT 1) - { - sprintf(g_dasm_str, "pvalid VAL, %s", str); - return; - } + if (modes == 0x2800) // PVALID (FORMAT 1) + { + sprintf(g_dasm_str, "pvalid VAL, %s", str); + return; + } - if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) - { - sprintf(g_dasm_str, "pvalid A%d, %s", modes & 0xf, str); - return; - } + if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) + { + sprintf(g_dasm_str, "pvalid A%d, %s", modes & 0xf, str); + return; + } - if ((modes & 0xe000) == 0x8000) // PTEST - { - sprintf(g_dasm_str, "ptest #%d, %s", modes & 0x1f, str); - return; - } + if ((modes & 0xe000) == 0x8000) // PTEST + { + sprintf(g_dasm_str, "ptest #%d, %s", modes & 0x1f, str); + return; + } - switch ((modes>>13) & 0x7) - { - case 0: // MC68030/040 form with FD bit - case 2: // MC68881 form, FD never set - if (modes & 0x0100) - { - if (modes & 0x0200) - { - sprintf(g_dasm_str, "pmovefd %s, %s", g_mmuregs[(modes>>10)&7], str); - } - else - { - sprintf(g_dasm_str, "pmovefd %s, %s", str, g_mmuregs[(modes>>10)&7]); - } - } - else - { - if (modes & 0x0200) - { - sprintf(g_dasm_str, "pmove %s, %s", g_mmuregs[(modes>>10)&7], str); - } - else - { - sprintf(g_dasm_str, "pmove %s, %s", str, g_mmuregs[(modes>>10)&7]); - } - } - break; + switch ((modes>>13) & 0x7) + { + case 0: // MC68030/040 form with FD bit + case 2: // MC68881 form, FD never set + if (modes & 0x0100) + { + if (modes & 0x0200) + { + sprintf(g_dasm_str, "pmovefd %s, %s", g_mmuregs[(modes>>10)&7], str); + } + else + { + sprintf(g_dasm_str, "pmovefd %s, %s", str, g_mmuregs[(modes>>10)&7]); + } + } + else + { + if (modes & 0x0200) + { + sprintf(g_dasm_str, "pmove %s, %s", g_mmuregs[(modes>>10)&7], str); + } + else + { + sprintf(g_dasm_str, "pmove %s, %s", str, g_mmuregs[(modes>>10)&7]); + } + } + break; - case 3: // MC68030 to/from status reg - if (modes & 0x0200) - { - sprintf(g_dasm_str, "pmove mmusr, %s", str); - } - else - { - sprintf(g_dasm_str, "pmove %s, mmusr", str); - } - break; + case 3: // MC68030 to/from status reg + if (modes & 0x0200) + { + sprintf(g_dasm_str, "pmove mmusr, %s", str); + } + else + { + sprintf(g_dasm_str, "pmove %s, mmusr", str); + } + break; - default: - sprintf(g_dasm_str, "pmove [unknown form] %s", str); - break; - } + default: + sprintf(g_dasm_str, "pmove [unknown form] %s", str); + break; + } } static void d68851_pbcc16(void) { - uint32 temp_pc = g_cpu_pc; + uint32 temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); + sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); } static void d68851_pbcc32(void) { - uint32 temp_pc = g_cpu_pc; + uint32 temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); + sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); } static void d68851_pdbcc(void) { - uint32 temp_pc = g_cpu_pc; - uint16 modes = read_imm_16(); + uint32 temp_pc = g_cpu_pc; + uint16 modes = read_imm_16(); - sprintf(g_dasm_str, "pb%s %x", g_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); + sprintf(g_dasm_str, "pb%s %x", g_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); } // PScc: 0000000000xxxxxx static void d68851_p001(void) { - sprintf(g_dasm_str, "MMU 001 group"); + sprintf(g_dasm_str, "MMU 001 group"); } /* ======================================================================== */ @@ -3307,412 +3307,412 @@ static void d68851_p001(void) static const opcode_struct g_opcode_info[] = { /* opcode handler mask match ea mask */ - {d68000_1010 , 0xf000, 0xa000, 0x000}, - {d68000_1111 , 0xf000, 0xf000, 0x000}, - {d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, - {d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, - {d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, - {d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, - {d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, - {d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, - {d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, - {d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, - {d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, - {d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, - {d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, - {d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, - {d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, - {d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, - {d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, - {d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, - {d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, - {d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, - {d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, - {d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, - {d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, - {d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, - {d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, - {d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, - {d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, - {d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, - {d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, - {d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, - {d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, - {d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, - {d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, - {d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, - {d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, - {d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, - {d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, - {d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, - {d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, - {d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, - {d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, - {d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, - {d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, - {d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, - {d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, - {d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, - {d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, - {d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, - {d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, - {d68000_bcc_8 , 0xf000, 0x6000, 0x000}, - {d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, - {d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, - {d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, - {d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, - {d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, - {d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, - {d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, - {d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, - {d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, - {d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, - {d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, - {d68020_bfins , 0xffc0, 0xefc0, 0xa78}, - {d68020_bfset , 0xffc0, 0xeec0, 0xa78}, - {d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, - {d68010_bkpt , 0xfff8, 0x4848, 0x000}, - {d68000_bra_8 , 0xff00, 0x6000, 0x000}, - {d68000_bra_16 , 0xffff, 0x6000, 0x000}, - {d68020_bra_32 , 0xffff, 0x60ff, 0x000}, - {d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, - {d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, - {d68000_bsr_8 , 0xff00, 0x6100, 0x000}, - {d68000_bsr_16 , 0xffff, 0x6100, 0x000}, - {d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, - {d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, - {d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, - {d68020_callm , 0xffc0, 0x06c0, 0x27b}, - {d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, - {d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, - {d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, - {d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, - {d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, - {d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, - {d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, - {d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, - {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, - {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, - {d68040_cinv , 0xff20, 0xf400, 0x000}, - {d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, - {d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, - {d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, - {d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, - {d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, - {d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, - {d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, - {d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, - {d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, - {d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, - {d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, - {d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, - {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, - {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, - {d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, - {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, - {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, - {d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, - {d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, - {d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, - {d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, - {d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, - {d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, - {d68020_cpgen , 0xf1c0, 0xf000, 0x000}, - {d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, - {d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, - {d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, - {d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, - {d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, - {d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, - {d68040_cpush , 0xff20, 0xf420, 0x000}, - {d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, - {d68000_dbra , 0xfff8, 0x51c8, 0x000}, - {d68000_divs , 0xf1c0, 0x81c0, 0xbff}, - {d68000_divu , 0xf1c0, 0x80c0, 0xbff}, - {d68020_divl , 0xffc0, 0x4c40, 0xbff}, - {d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, - {d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, - {d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, - {d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, - {d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, - {d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, - {d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, - {d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, - {d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, - {d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, - {d68000_exg_da , 0xf1f8, 0xc188, 0x000}, - {d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, - {d68000_ext_16 , 0xfff8, 0x4880, 0x000}, - {d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, - {d68040_fpu , 0xffc0, 0xf200, 0x000}, - {d68000_illegal , 0xffff, 0x4afc, 0x000}, - {d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, - {d68000_jsr , 0xffc0, 0x4e80, 0x27b}, - {d68000_lea , 0xf1c0, 0x41c0, 0x27b}, - {d68000_link_16 , 0xfff8, 0x4e50, 0x000}, - {d68020_link_32 , 0xfff8, 0x4808, 0x000}, - {d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, - {d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, - {d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, - {d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, - {d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, - {d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, - {d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, - {d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, - {d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, - {d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, - {d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, - {d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, - {d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, - {d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, - {d68000_move_8 , 0xf000, 0x1000, 0xbff}, - {d68000_move_16 , 0xf000, 0x3000, 0xfff}, - {d68000_move_32 , 0xf000, 0x2000, 0xfff}, - {d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, - {d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, - {d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, - {d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, - {d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, - {d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, - {d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, - {d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, - {d68010_movec , 0xfffe, 0x4e7a, 0x000}, - {d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, - {d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, - {d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, - {d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, - {d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, - {d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, - {d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, - {d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, - {d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, - {d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, - {d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, - {d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, - {d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, - {d68000_moveq , 0xf100, 0x7000, 0x000}, - {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, - {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, - {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, - {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, - {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, - {d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, - {d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, - {d68020_mull , 0xffc0, 0x4c00, 0xbff}, - {d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, - {d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, - {d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, - {d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, - {d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, - {d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, - {d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, - {d68000_nop , 0xffff, 0x4e71, 0x000}, - {d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, - {d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, - {d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, - {d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, - {d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, - {d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, - {d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, - {d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, - {d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, - {d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, - {d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, - {d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, - {d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, - {d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, - {d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, - {d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, - {d68000_pea , 0xffc0, 0x4840, 0x27b}, - {d68040_pflush , 0xffe0, 0xf500, 0x000}, - {d68000_reset , 0xffff, 0x4e70, 0x000}, - {d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, - {d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, - {d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, - {d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, - {d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, - {d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, - {d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, - {d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, - {d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, - {d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, - {d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, - {d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, - {d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, - {d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, - {d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, - {d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, - {d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, - {d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, - {d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, - {d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, - {d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, - {d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, - {d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, - {d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, - {d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, - {d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, - {d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, - {d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, - {d68010_rtd , 0xffff, 0x4e74, 0x000}, - {d68000_rte , 0xffff, 0x4e73, 0x000}, - {d68020_rtm , 0xfff0, 0x06c0, 0x000}, - {d68000_rtr , 0xffff, 0x4e77, 0x000}, - {d68000_rts , 0xffff, 0x4e75, 0x000}, - {d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, - {d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, - {d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, - {d68000_stop , 0xffff, 0x4e72, 0x000}, - {d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, - {d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, - {d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, - {d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, - {d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, - {d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, - {d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, - {d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, - {d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, - {d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, - {d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, - {d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, - {d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, - {d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, - {d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, - {d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, - {d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, - {d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, - {d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, - {d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, - {d68000_swap , 0xfff8, 0x4840, 0x000}, - {d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, - {d68000_trap , 0xfff0, 0x4e40, 0x000}, - {d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, - {d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, - {d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, - {d68000_trapv , 0xffff, 0x4e76, 0x000}, - {d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, - {d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, - {d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, - {d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, - {d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, - {d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, - {d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, - {d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, - {d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, - {d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, - {d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, - {d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, - {d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, - {d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, - {d68000_unlk , 0xfff8, 0x4e58, 0x000}, - {d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, - {d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, - {d68851_p000 , 0xffc0, 0xf000, 0x000}, - {d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, - {d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, - {d68851_pdbcc , 0xfff8, 0xf048, 0x000}, - {d68851_p001 , 0xffc0, 0xf040, 0x000}, - {0, 0, 0, 0} + {d68000_1010 , 0xf000, 0xa000, 0x000}, + {d68000_1111 , 0xf000, 0xf000, 0x000}, + {d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, + {d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, + {d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, + {d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, + {d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, + {d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, + {d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, + {d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, + {d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, + {d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, + {d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, + {d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, + {d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, + {d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, + {d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, + {d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, + {d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, + {d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, + {d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, + {d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, + {d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, + {d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, + {d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, + {d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, + {d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, + {d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, + {d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, + {d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, + {d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, + {d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, + {d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, + {d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, + {d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, + {d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, + {d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, + {d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, + {d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, + {d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, + {d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, + {d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, + {d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, + {d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, + {d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, + {d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, + {d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, + {d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, + {d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, + {d68000_bcc_8 , 0xf000, 0x6000, 0x000}, + {d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, + {d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, + {d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, + {d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, + {d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, + {d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, + {d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, + {d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, + {d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, + {d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, + {d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, + {d68020_bfins , 0xffc0, 0xefc0, 0xa78}, + {d68020_bfset , 0xffc0, 0xeec0, 0xa78}, + {d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, + {d68010_bkpt , 0xfff8, 0x4848, 0x000}, + {d68000_bra_8 , 0xff00, 0x6000, 0x000}, + {d68000_bra_16 , 0xffff, 0x6000, 0x000}, + {d68020_bra_32 , 0xffff, 0x60ff, 0x000}, + {d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, + {d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, + {d68000_bsr_8 , 0xff00, 0x6100, 0x000}, + {d68000_bsr_16 , 0xffff, 0x6100, 0x000}, + {d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, + {d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, + {d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, + {d68020_callm , 0xffc0, 0x06c0, 0x27b}, + {d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, + {d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, + {d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, + {d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, + {d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, + {d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, + {d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, + {d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, + {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, + {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, + {d68040_cinv , 0xff20, 0xf400, 0x000}, + {d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, + {d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, + {d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, + {d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, + {d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, + {d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, + {d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, + {d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, + {d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, + {d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, + {d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, + {d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, + {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, + {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, + {d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, + {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, + {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, + {d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, + {d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, + {d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, + {d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, + {d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, + {d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, + {d68020_cpgen , 0xf1c0, 0xf000, 0x000}, + {d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, + {d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, + {d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, + {d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, + {d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, + {d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, + {d68040_cpush , 0xff20, 0xf420, 0x000}, + {d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, + {d68000_dbra , 0xfff8, 0x51c8, 0x000}, + {d68000_divs , 0xf1c0, 0x81c0, 0xbff}, + {d68000_divu , 0xf1c0, 0x80c0, 0xbff}, + {d68020_divl , 0xffc0, 0x4c40, 0xbff}, + {d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, + {d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, + {d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, + {d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, + {d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, + {d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, + {d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, + {d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, + {d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, + {d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, + {d68000_exg_da , 0xf1f8, 0xc188, 0x000}, + {d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, + {d68000_ext_16 , 0xfff8, 0x4880, 0x000}, + {d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, + {d68040_fpu , 0xffc0, 0xf200, 0x000}, + {d68000_illegal , 0xffff, 0x4afc, 0x000}, + {d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, + {d68000_jsr , 0xffc0, 0x4e80, 0x27b}, + {d68000_lea , 0xf1c0, 0x41c0, 0x27b}, + {d68000_link_16 , 0xfff8, 0x4e50, 0x000}, + {d68020_link_32 , 0xfff8, 0x4808, 0x000}, + {d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, + {d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, + {d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, + {d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, + {d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, + {d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, + {d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, + {d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, + {d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, + {d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, + {d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, + {d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, + {d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, + {d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, + {d68000_move_8 , 0xf000, 0x1000, 0xbff}, + {d68000_move_16 , 0xf000, 0x3000, 0xfff}, + {d68000_move_32 , 0xf000, 0x2000, 0xfff}, + {d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, + {d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, + {d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, + {d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, + {d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, + {d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, + {d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, + {d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, + {d68010_movec , 0xfffe, 0x4e7a, 0x000}, + {d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, + {d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, + {d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, + {d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, + {d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, + {d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, + {d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, + {d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, + {d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, + {d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, + {d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, + {d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, + {d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, + {d68000_moveq , 0xf100, 0x7000, 0x000}, + {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, + {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, + {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, + {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, + {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, + {d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, + {d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, + {d68020_mull , 0xffc0, 0x4c00, 0xbff}, + {d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, + {d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, + {d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, + {d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, + {d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, + {d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, + {d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, + {d68000_nop , 0xffff, 0x4e71, 0x000}, + {d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, + {d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, + {d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, + {d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, + {d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, + {d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, + {d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, + {d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, + {d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, + {d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, + {d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, + {d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, + {d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, + {d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, + {d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, + {d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, + {d68000_pea , 0xffc0, 0x4840, 0x27b}, + {d68040_pflush , 0xffe0, 0xf500, 0x000}, + {d68000_reset , 0xffff, 0x4e70, 0x000}, + {d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, + {d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, + {d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, + {d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, + {d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, + {d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, + {d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, + {d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, + {d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, + {d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, + {d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, + {d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, + {d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, + {d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, + {d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, + {d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, + {d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, + {d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, + {d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, + {d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, + {d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, + {d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, + {d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, + {d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, + {d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, + {d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, + {d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, + {d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, + {d68010_rtd , 0xffff, 0x4e74, 0x000}, + {d68000_rte , 0xffff, 0x4e73, 0x000}, + {d68020_rtm , 0xfff0, 0x06c0, 0x000}, + {d68000_rtr , 0xffff, 0x4e77, 0x000}, + {d68000_rts , 0xffff, 0x4e75, 0x000}, + {d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, + {d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, + {d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, + {d68000_stop , 0xffff, 0x4e72, 0x000}, + {d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, + {d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, + {d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, + {d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, + {d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, + {d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, + {d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, + {d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, + {d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, + {d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, + {d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, + {d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, + {d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, + {d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, + {d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, + {d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, + {d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, + {d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, + {d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, + {d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, + {d68000_swap , 0xfff8, 0x4840, 0x000}, + {d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, + {d68000_trap , 0xfff0, 0x4e40, 0x000}, + {d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, + {d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, + {d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, + {d68000_trapv , 0xffff, 0x4e76, 0x000}, + {d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, + {d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, + {d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, + {d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, + {d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, + {d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, + {d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, + {d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, + {d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, + {d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, + {d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, + {d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, + {d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, + {d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, + {d68000_unlk , 0xfff8, 0x4e58, 0x000}, + {d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, + {d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, + {d68851_p000 , 0xffc0, 0xf000, 0x000}, + {d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, + {d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, + {d68851_pdbcc , 0xfff8, 0xf048, 0x000}, + {d68851_p001 , 0xffc0, 0xf040, 0x000}, + {0, 0, 0, 0} }; /* Check if opcode is using a valid ea mode */ static int valid_ea(uint opcode, uint mask) { - if(mask == 0) - return 1; + if(mask == 0) + return 1; - switch(opcode & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - return (mask & 0x800) != 0; - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - return (mask & 0x400) != 0; - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - return (mask & 0x200) != 0; - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - return (mask & 0x100) != 0; - case 0x20: case 0x21: case 0x22: case 0x23: - case 0x24: case 0x25: case 0x26: case 0x27: - return (mask & 0x080) != 0; - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - return (mask & 0x040) != 0; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - return (mask & 0x020) != 0; - case 0x38: - return (mask & 0x010) != 0; - case 0x39: - return (mask & 0x008) != 0; - case 0x3a: - return (mask & 0x002) != 0; - case 0x3b: - return (mask & 0x001) != 0; - case 0x3c: - return (mask & 0x004) != 0; - } - return 0; + switch(opcode & 0x3f) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + return (mask & 0x800) != 0; + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + return (mask & 0x400) != 0; + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + return (mask & 0x200) != 0; + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + return (mask & 0x100) != 0; + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x24: case 0x25: case 0x26: case 0x27: + return (mask & 0x080) != 0; + case 0x28: case 0x29: case 0x2a: case 0x2b: + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + return (mask & 0x040) != 0; + case 0x30: case 0x31: case 0x32: case 0x33: + case 0x34: case 0x35: case 0x36: case 0x37: + return (mask & 0x020) != 0; + case 0x38: + return (mask & 0x010) != 0; + case 0x39: + return (mask & 0x008) != 0; + case 0x3a: + return (mask & 0x002) != 0; + case 0x3b: + return (mask & 0x001) != 0; + case 0x3c: + return (mask & 0x004) != 0; + } + return 0; } /* Used by qsort */ static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr) { - uint a = ((const opcode_struct*)aptr)->mask; - uint b = ((const opcode_struct*)bptr)->mask; + uint a = ((const opcode_struct*)aptr)->mask; + uint b = ((const opcode_struct*)bptr)->mask; - a = ((a & 0xAAAA) >> 1) + (a & 0x5555); - a = ((a & 0xCCCC) >> 2) + (a & 0x3333); - a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F); - a = ((a & 0xFF00) >> 8) + (a & 0x00FF); + a = ((a & 0xAAAA) >> 1) + (a & 0x5555); + a = ((a & 0xCCCC) >> 2) + (a & 0x3333); + a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F); + a = ((a & 0xFF00) >> 8) + (a & 0x00FF); - b = ((b & 0xAAAA) >> 1) + (b & 0x5555); - b = ((b & 0xCCCC) >> 2) + (b & 0x3333); - b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F); - b = ((b & 0xFF00) >> 8) + (b & 0x00FF); + b = ((b & 0xAAAA) >> 1) + (b & 0x5555); + b = ((b & 0xCCCC) >> 2) + (b & 0x3333); + b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F); + b = ((b & 0xFF00) >> 8) + (b & 0x00FF); - return b - a; /* reversed to get greatest to least sorting */ + return b - a; /* reversed to get greatest to least sorting */ } /* build the opcode handler jump table */ static void build_opcode_table(void) { - uint i; - uint opcode; - opcode_struct* ostruct; - opcode_struct opcode_info[ARRAY_LENGTH(g_opcode_info)]; + uint i; + uint opcode; + opcode_struct* ostruct; + opcode_struct opcode_info[ARRAY_LENGTH(g_opcode_info)]; - memcpy(opcode_info, g_opcode_info, sizeof(g_opcode_info)); - qsort((void *)opcode_info, ARRAY_LENGTH(opcode_info)-1, sizeof(opcode_info[0]), compare_nof_true_bits); + memcpy(opcode_info, g_opcode_info, sizeof(g_opcode_info)); + qsort((void *)opcode_info, ARRAY_LENGTH(opcode_info)-1, sizeof(opcode_info[0]), compare_nof_true_bits); - for(i=0;i<0x10000;i++) - { - g_instruction_table[i] = d68000_illegal; /* default to illegal */ - opcode = i; - /* search through opcode info for a match */ - for(ostruct = opcode_info;ostruct->opcode_handler != 0;ostruct++) - { - /* match opcode mask and allowed ea modes */ - if((opcode & ostruct->mask) == ostruct->match) - { - /* Handle destination ea for move instructions */ - if((ostruct->opcode_handler == d68000_move_8 || - ostruct->opcode_handler == d68000_move_16 || - ostruct->opcode_handler == d68000_move_32) && - !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) - continue; - if(valid_ea(opcode, ostruct->ea_mask)) - { - g_instruction_table[i] = ostruct->opcode_handler; - break; - } - } - } - } + for(i=0;i<0x10000;i++) + { + g_instruction_table[i] = d68000_illegal; /* default to illegal */ + opcode = i; + /* search through opcode info for a match */ + for(ostruct = opcode_info;ostruct->opcode_handler != 0;ostruct++) + { + /* match opcode mask and allowed ea modes */ + if((opcode & ostruct->mask) == ostruct->match) + { + /* Handle destination ea for move instructions */ + if((ostruct->opcode_handler == d68000_move_8 || + ostruct->opcode_handler == d68000_move_16 || + ostruct->opcode_handler == d68000_move_32) && + !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) + continue; + if(valid_ea(opcode, ostruct->ea_mask)) + { + g_instruction_table[i] = ostruct->opcode_handler; + break; + } + } + } + } } @@ -3724,277 +3724,277 @@ static void build_opcode_table(void) /* Disasemble one instruction at pc and store in str_buff */ unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type) { - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - g_cpu_type = TYPE_68000; - g_address_mask = 0x00ffffff; - break; - case M68K_CPU_TYPE_68010: - g_cpu_type = TYPE_68010; - g_address_mask = 0x00ffffff; - break; - case M68K_CPU_TYPE_68EC020: - g_cpu_type = TYPE_68020; - g_address_mask = 0x00ffffff; - break; - case M68K_CPU_TYPE_68020: - g_cpu_type = TYPE_68020; - g_address_mask = 0xffffffff; - break; - case M68K_CPU_TYPE_68EC030: - case M68K_CPU_TYPE_68030: - g_cpu_type = TYPE_68030; - g_address_mask = 0xffffffff; - break; - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - g_cpu_type = TYPE_68040; - g_address_mask = 0xffffffff; - break; - default: - return 0; - } + if(!g_initialized) + { + build_opcode_table(); + g_initialized = 1; + } + switch(cpu_type) + { + case M68K_CPU_TYPE_68000: + g_cpu_type = TYPE_68000; + g_address_mask = 0x00ffffff; + break; + case M68K_CPU_TYPE_68010: + g_cpu_type = TYPE_68010; + g_address_mask = 0x00ffffff; + break; + case M68K_CPU_TYPE_68EC020: + g_cpu_type = TYPE_68020; + g_address_mask = 0x00ffffff; + break; + case M68K_CPU_TYPE_68020: + g_cpu_type = TYPE_68020; + g_address_mask = 0xffffffff; + break; + case M68K_CPU_TYPE_68EC030: + case M68K_CPU_TYPE_68030: + g_cpu_type = TYPE_68030; + g_address_mask = 0xffffffff; + break; + case M68K_CPU_TYPE_68040: + case M68K_CPU_TYPE_68EC040: + case M68K_CPU_TYPE_68LC040: + g_cpu_type = TYPE_68040; + g_address_mask = 0xffffffff; + break; + default: + return 0; + } - g_cpu_pc = pc; - g_helper_str[0] = 0; - g_cpu_ir = read_imm_16(); - g_opcode_type = 0; - g_instruction_table[g_cpu_ir](); - sprintf(str_buff, "%s%s", g_dasm_str, g_helper_str); - return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc); + g_cpu_pc = pc; + g_helper_str[0] = 0; + g_cpu_ir = read_imm_16(); + g_opcode_type = 0; + g_instruction_table[g_cpu_ir](); + sprintf(str_buff, "%s%s", g_dasm_str, g_helper_str); + return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc); } char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type) { - static char buff[100]; - buff[0] = 0; - m68k_disassemble(buff, pc, cpu_type); - return buff; + static char buff[100]; + buff[0] = 0; + m68k_disassemble(buff, pc, cpu_type); + return buff; } unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type) { - unsigned int result; - (void)argdata; + unsigned int result; + (void)argdata; - g_rawop = opdata; - g_rawbasepc = pc; - result = m68k_disassemble(str_buff, pc, cpu_type); - g_rawop = NULL; - return result; + g_rawop = opdata; + g_rawbasepc = pc; + result = m68k_disassemble(str_buff, pc, cpu_type); + g_rawop = NULL; + return result; } /* Check if the instruction is a valid one */ unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type) { - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } + if(!g_initialized) + { + build_opcode_table(); + g_initialized = 1; + } - instruction &= 0xffff; - if(g_instruction_table[instruction] == d68000_illegal) - return 0; + instruction &= 0xffff; + if(g_instruction_table[instruction] == d68000_illegal) + return 0; - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - if(g_instruction_table[instruction] == d68010_bkpt) - return 0; - if(g_instruction_table[instruction] == d68010_move_fr_ccr) - return 0; - if(g_instruction_table[instruction] == d68010_movec) - return 0; - if(g_instruction_table[instruction] == d68010_moves_8) - return 0; - if(g_instruction_table[instruction] == d68010_moves_16) - return 0; - if(g_instruction_table[instruction] == d68010_moves_32) - return 0; - if(g_instruction_table[instruction] == d68010_rtd) - return 0; - // Fallthrough - case M68K_CPU_TYPE_68010: - if(g_instruction_table[instruction] == d68020_bcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_bfchg) - return 0; - if(g_instruction_table[instruction] == d68020_bfclr) - return 0; - if(g_instruction_table[instruction] == d68020_bfexts) - return 0; - if(g_instruction_table[instruction] == d68020_bfextu) - return 0; - if(g_instruction_table[instruction] == d68020_bfffo) - return 0; - if(g_instruction_table[instruction] == d68020_bfins) - return 0; - if(g_instruction_table[instruction] == d68020_bfset) - return 0; - if(g_instruction_table[instruction] == d68020_bftst) - return 0; - if(g_instruction_table[instruction] == d68020_bra_32) - return 0; - if(g_instruction_table[instruction] == d68020_bsr_32) - return 0; - if(g_instruction_table[instruction] == d68020_callm) - return 0; - if(g_instruction_table[instruction] == d68020_cas_8) - return 0; - if(g_instruction_table[instruction] == d68020_cas_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas_32) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_8) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_16) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_divl) - return 0; - if(g_instruction_table[instruction] == d68020_extb_32) - return 0; - if(g_instruction_table[instruction] == d68020_link_32) - return 0; - if(g_instruction_table[instruction] == d68020_mull) - return 0; - if(g_instruction_table[instruction] == d68020_pack_rr) - return 0; - if(g_instruction_table[instruction] == d68020_pack_mm) - return 0; - if(g_instruction_table[instruction] == d68020_rtm) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_32) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_rr) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_mm) - return 0; - // Fallthrough - case M68K_CPU_TYPE_68EC020: - case M68K_CPU_TYPE_68020: - case M68K_CPU_TYPE_68030: - case M68K_CPU_TYPE_68EC030: - if(g_instruction_table[instruction] == d68040_cinv) - return 0; - if(g_instruction_table[instruction] == d68040_cpush) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_ai_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_ai) - return 0; - // Fallthrough - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68040_pflush) - return 0; - } - if(cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 && - (g_instruction_table[instruction] == d68020_callm || - g_instruction_table[instruction] == d68020_rtm)) - return 0; + switch(cpu_type) + { + case M68K_CPU_TYPE_68000: + if(g_instruction_table[instruction] == d68010_bkpt) + return 0; + if(g_instruction_table[instruction] == d68010_move_fr_ccr) + return 0; + if(g_instruction_table[instruction] == d68010_movec) + return 0; + if(g_instruction_table[instruction] == d68010_moves_8) + return 0; + if(g_instruction_table[instruction] == d68010_moves_16) + return 0; + if(g_instruction_table[instruction] == d68010_moves_32) + return 0; + if(g_instruction_table[instruction] == d68010_rtd) + return 0; + // Fallthrough + case M68K_CPU_TYPE_68010: + if(g_instruction_table[instruction] == d68020_bcc_32) + return 0; + if(g_instruction_table[instruction] == d68020_bfchg) + return 0; + if(g_instruction_table[instruction] == d68020_bfclr) + return 0; + if(g_instruction_table[instruction] == d68020_bfexts) + return 0; + if(g_instruction_table[instruction] == d68020_bfextu) + return 0; + if(g_instruction_table[instruction] == d68020_bfffo) + return 0; + if(g_instruction_table[instruction] == d68020_bfins) + return 0; + if(g_instruction_table[instruction] == d68020_bfset) + return 0; + if(g_instruction_table[instruction] == d68020_bftst) + return 0; + if(g_instruction_table[instruction] == d68020_bra_32) + return 0; + if(g_instruction_table[instruction] == d68020_bsr_32) + return 0; + if(g_instruction_table[instruction] == d68020_callm) + return 0; + if(g_instruction_table[instruction] == d68020_cas_8) + return 0; + if(g_instruction_table[instruction] == d68020_cas_16) + return 0; + if(g_instruction_table[instruction] == d68020_cas_32) + return 0; + if(g_instruction_table[instruction] == d68020_cas2_16) + return 0; + if(g_instruction_table[instruction] == d68020_cas2_32) + return 0; + if(g_instruction_table[instruction] == d68020_chk_32) + return 0; + if(g_instruction_table[instruction] == d68020_chk2_cmp2_8) + return 0; + if(g_instruction_table[instruction] == d68020_chk2_cmp2_16) + return 0; + if(g_instruction_table[instruction] == d68020_chk2_cmp2_32) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcdi_8) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcix_8) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcdi_16) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcix_16) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcdi_32) + return 0; + if(g_instruction_table[instruction] == d68020_cmpi_pcix_32) + return 0; + if(g_instruction_table[instruction] == d68020_cpbcc_16) + return 0; + if(g_instruction_table[instruction] == d68020_cpbcc_32) + return 0; + if(g_instruction_table[instruction] == d68020_cpdbcc) + return 0; + if(g_instruction_table[instruction] == d68020_cpgen) + return 0; + if(g_instruction_table[instruction] == d68020_cprestore) + return 0; + if(g_instruction_table[instruction] == d68020_cpsave) + return 0; + if(g_instruction_table[instruction] == d68020_cpscc) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_0) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_16) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_32) + return 0; + if(g_instruction_table[instruction] == d68020_divl) + return 0; + if(g_instruction_table[instruction] == d68020_extb_32) + return 0; + if(g_instruction_table[instruction] == d68020_link_32) + return 0; + if(g_instruction_table[instruction] == d68020_mull) + return 0; + if(g_instruction_table[instruction] == d68020_pack_rr) + return 0; + if(g_instruction_table[instruction] == d68020_pack_mm) + return 0; + if(g_instruction_table[instruction] == d68020_rtm) + return 0; + if(g_instruction_table[instruction] == d68020_trapcc_0) + return 0; + if(g_instruction_table[instruction] == d68020_trapcc_16) + return 0; + if(g_instruction_table[instruction] == d68020_trapcc_32) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcdi_8) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcix_8) + return 0; + if(g_instruction_table[instruction] == d68020_tst_i_8) + return 0; + if(g_instruction_table[instruction] == d68020_tst_a_16) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcdi_16) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcix_16) + return 0; + if(g_instruction_table[instruction] == d68020_tst_i_16) + return 0; + if(g_instruction_table[instruction] == d68020_tst_a_32) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcdi_32) + return 0; + if(g_instruction_table[instruction] == d68020_tst_pcix_32) + return 0; + if(g_instruction_table[instruction] == d68020_tst_i_32) + return 0; + if(g_instruction_table[instruction] == d68020_unpk_rr) + return 0; + if(g_instruction_table[instruction] == d68020_unpk_mm) + return 0; + // Fallthrough + case M68K_CPU_TYPE_68EC020: + case M68K_CPU_TYPE_68020: + case M68K_CPU_TYPE_68030: + case M68K_CPU_TYPE_68EC030: + if(g_instruction_table[instruction] == d68040_cinv) + return 0; + if(g_instruction_table[instruction] == d68040_cpush) + return 0; + if(g_instruction_table[instruction] == d68040_move16_pi_pi) + return 0; + if(g_instruction_table[instruction] == d68040_move16_pi_al) + return 0; + if(g_instruction_table[instruction] == d68040_move16_al_pi) + return 0; + if(g_instruction_table[instruction] == d68040_move16_ai_al) + return 0; + if(g_instruction_table[instruction] == d68040_move16_al_ai) + return 0; + // Fallthrough + case M68K_CPU_TYPE_68040: + case M68K_CPU_TYPE_68EC040: + case M68K_CPU_TYPE_68LC040: + if(g_instruction_table[instruction] == d68020_cpbcc_16) + return 0; + if(g_instruction_table[instruction] == d68020_cpbcc_32) + return 0; + if(g_instruction_table[instruction] == d68020_cpdbcc) + return 0; + if(g_instruction_table[instruction] == d68020_cpgen) + return 0; + if(g_instruction_table[instruction] == d68020_cprestore) + return 0; + if(g_instruction_table[instruction] == d68020_cpsave) + return 0; + if(g_instruction_table[instruction] == d68020_cpscc) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_0) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_16) + return 0; + if(g_instruction_table[instruction] == d68020_cptrapcc_32) + return 0; + if(g_instruction_table[instruction] == d68040_pflush) + return 0; + } + if(cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 && + (g_instruction_table[instruction] == d68020_callm || + g_instruction_table[instruction] == d68020_rtm)) + return 0; - return 1; + return 1; } // f028 2215 0008 diff --git a/AltairZ80/m68k/m68kfpu.c b/AltairZ80/m68k/m68kfpu.c index dd39aa8a..0d0973e0 100644 --- a/AltairZ80/m68k/m68kfpu.c +++ b/AltairZ80/m68k/m68kfpu.c @@ -1,1769 +1,1769 @@ -#include -#include -#include - -extern void exit(int); - -static void fatalerror(const char *format, ...) { - va_list ap; - va_start(ap,format); - vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong - va_end(ap); - exit(1); -} - -#define FPCC_N 0x08000000 -#define FPCC_Z 0x04000000 -#define FPCC_I 0x02000000 -#define FPCC_NAN 0x01000000 - -#define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000) -#define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000) -#define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff) - -extern flag floatx80_is_nan( floatx80 a ); - -// masks for packed dwords, positive k-factor -static uint32 pkmask2[18] = -{ - 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, - 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff -}; - -static uint32 pkmask3[18] = -{ - 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, - 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, -}; - -static inline double fx80_to_double(floatx80 fx) -{ - uint64 d; - double *foo; - - foo = (double *)&d; - - d = floatx80_to_float64(fx); - - return *foo; -} - -static inline floatx80 double_to_fx80(double in) -{ - uint64 *d; - - d = (uint64 *)∈ - - return float64_to_floatx80(*d); -} - -static inline floatx80 load_extended_float80(uint32 ea) -{ - uint32 d1,d2; - uint16 d3; - floatx80 fp; - - d3 = m68ki_read_16(ea); - d1 = m68ki_read_32(ea+4); - d2 = m68ki_read_32(ea+8); - - fp.high = d3; - fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff); - - return fp; -} - -static inline void store_extended_float80(uint32 ea, floatx80 fpr) -{ - m68ki_write_16(ea+0, fpr.high); - m68ki_write_16(ea+2, 0); - m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff); - m68ki_write_32(ea+8, fpr.low&0xffffffff); -} - -static inline floatx80 load_pack_float80(uint32 ea) -{ - uint32 dw1, dw2, dw3; - floatx80 result; - double tmp; - char str[128], *ch; - - dw1 = m68ki_read_32(ea); - dw2 = m68ki_read_32(ea+4); - dw3 = m68ki_read_32(ea+8); - - ch = &str[0]; - if (dw1 & 0x80000000) // mantissa sign - { - *ch++ = '-'; - } - *ch++ = (char)((dw1 & 0xf) + '0'); - *ch++ = '.'; - *ch++ = (char)(((dw2 >> 28) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 24) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 20) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 16) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 12) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 8) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 4) & 0xf) + '0'); - *ch++ = (char)(((dw2 >> 0) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 28) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 24) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 20) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 16) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 12) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 8) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 4) & 0xf) + '0'); - *ch++ = (char)(((dw3 >> 0) & 0xf) + '0'); - *ch++ = 'E'; - if (dw1 & 0x40000000) // exponent sign - { - *ch++ = '-'; - } - *ch++ = (char)(((dw1 >> 24) & 0xf) + '0'); - *ch++ = (char)(((dw1 >> 20) & 0xf) + '0'); - *ch++ = (char)(((dw1 >> 16) & 0xf) + '0'); - *ch = '\0'; - - sscanf(str, "%le", &tmp); - - result = double_to_fx80(tmp); - - return result; -} - -static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr) -{ - uint32 dw1, dw2, dw3; - char str[128], *ch; - int i, j, exp; - - dw1 = dw2 = dw3 = 0; - ch = &str[0]; - - sprintf(str, "%.16e", fx80_to_double(fpr)); - - if (*ch == '-') - { - ch++; - dw1 = 0x80000000; - } - - if (*ch == '+') - { - ch++; - } - - dw1 |= (*ch++ - '0'); - - if (*ch == '.') - { - ch++; - } - - // handle negative k-factor here - if ((k <= 0) && (k >= -13)) - { - exp = 0; - for (i = 0; i < 3; i++) - { - if (ch[18+i] >= '0' && ch[18+i] <= '9') - { - exp = (exp << 4) | (ch[18+i] - '0'); - } - } - - if (ch[17] == '-') - { - exp = -exp; - } - - k = -k; - // last digit is (k + exponent - 1) - k += (exp - 1); - - // round up the last significant mantissa digit - if (ch[k+1] >= '5') - { - ch[k]++; - } - - // zero out the rest of the mantissa digits - for (j = (k+1); j < 16; j++) - { - ch[j] = '0'; - } - - // now zero out K to avoid tripping the positive K detection below - k = 0; - } - - // crack 8 digits of the mantissa - for (i = 0; i < 8; i++) - { - dw2 <<= 4; - if (*ch >= '0' && *ch <= '9') - { - dw2 |= *ch++ - '0'; - } - } - - // next 8 digits of the mantissa - for (i = 0; i < 8; i++) - { - dw3 <<= 4; - if (*ch >= '0' && *ch <= '9') - dw3 |= *ch++ - '0'; - } - - // handle masking if k is positive - if (k >= 1) - { - if (k <= 17) - { - dw2 &= pkmask2[k]; - dw3 &= pkmask3[k]; - } - else - { - dw2 &= pkmask2[17]; - dw3 &= pkmask3[17]; -// m68ki_cpu.fpcr |= (need to set OPERR bit) - } - } - - // finally, crack the exponent - if (*ch == 'e' || *ch == 'E') - { - ch++; - if (*ch == '-') - { - ch++; - dw1 |= 0x40000000; - } - - if (*ch == '+') - { - ch++; - } - - j = 0; - for (i = 0; i < 3; i++) - { - if (*ch >= '0' && *ch <= '9') - { - j = (j << 4) | (*ch++ - '0'); - } - } - - dw1 |= (j << 16); - } - - m68ki_write_32(ea, dw1); - m68ki_write_32(ea+4, dw2); - m68ki_write_32(ea+8, dw3); -} - -static inline void SET_CONDITION_CODES(floatx80 reg) -{ - REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN); - - // sign flag - if (reg.high & 0x8000) - { - REG_FPSR |= FPCC_N; - } - - // zero flag - if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0)) - { - REG_FPSR |= FPCC_Z; - } - - // infinity flag - if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0)) - { - REG_FPSR |= FPCC_I; - } - - // NaN flag - if (floatx80_is_nan(reg)) - { - REG_FPSR |= FPCC_NAN; - } -} - -static inline int TEST_CONDITION(int condition) -{ - int n = (REG_FPSR & FPCC_N) != 0; - int z = (REG_FPSR & FPCC_Z) != 0; - int nan = (REG_FPSR & FPCC_NAN) != 0; - int r = 0; - switch (condition) - { - case 0x10: - case 0x00: return 0; // False - - case 0x11: - case 0x01: return (z); // Equal - - case 0x12: - case 0x02: return (!(nan || z || n)); // Greater Than - - case 0x13: - case 0x03: return (z || !(nan || n)); // Greater or Equal - - case 0x14: - case 0x04: return (n && !(nan || z)); // Less Than - - case 0x15: - case 0x05: return (z || (n && !nan)); // Less Than or Equal - - case 0x16: - case 0x06: return !nan && !z; - - case 0x17: - case 0x07: return !nan; - - case 0x18: - case 0x08: return nan; - - case 0x19: - case 0x09: return nan || z; - - case 0x1a: - case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal - - case 0x1b: - case 0x0b: return (nan || z || !n); // Not Less Than - - case 0x1c: - case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than - - case 0x1d: - case 0x0d: return (nan || z || n); // Not Greater Than - - case 0x1e: - case 0x0e: return (!z); // Not Equal - - case 0x1f: - case 0x0f: return 1; // True - - default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition); - } - - return r; -} - -static uint8 READ_EA_8(int ea) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - return REG_D[reg]; - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - return m68ki_read_8(ea); - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_8(); - return m68ki_read_8(ea); - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_8(); - return m68ki_read_8(ea); - } - case 7: - { - switch (reg) - { - case 0: // (xxx).W - { - uint32 ea = (uint32)OPER_I_16(); - return m68ki_read_8(ea); - } - case 1: // (xxx).L - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - return m68ki_read_8(ea); - } - case 4: // # - { - return OPER_I_8(); - } - default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - - return 0; -} - -static uint16 READ_EA_16(int ea) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - return (uint16)(REG_D[reg]); - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - return m68ki_read_16(ea); - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_16(); - return m68ki_read_16(ea); - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_16(); - return m68ki_read_16(ea); - } - case 7: - { - switch (reg) - { - case 0: // (xxx).W - { - uint32 ea = (uint32)OPER_I_16(); - return m68ki_read_16(ea); - } - case 1: // (xxx).L - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - return m68ki_read_16(ea); - } - case 4: // # - { - return OPER_I_16(); - } - - default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - - return 0; -} - -static uint32 READ_EA_32(int ea) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - return REG_D[reg]; - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - return m68ki_read_32(ea); - } - case 3: // (An)+ - { - uint32 ea = EA_AY_PI_32(); - return m68ki_read_32(ea); - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_32(); - return m68ki_read_32(ea); - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_32(); - return m68ki_read_32(ea); - } - case 7: - { - switch (reg) - { - case 0: // (xxx).W - { - uint32 ea = (uint32)OPER_I_16(); - return m68ki_read_32(ea); - } - case 1: // (xxx).L - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - return m68ki_read_32(ea); - } - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_32(); - return m68ki_read_32(ea); - } - case 4: // # - { - return OPER_I_32(); - } - default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - return 0; -} - -static uint64 READ_EA_64(int ea) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - uint32 h1, h2; - - switch (mode) - { - case 2: // (An) - { - uint32 ea = REG_A[reg]; - h1 = m68ki_read_32(ea+0); - h2 = m68ki_read_32(ea+4); - return (uint64)(h1) << 32 | (uint64)(h2); - } - case 3: // (An)+ - { - uint32 ea = REG_A[reg]; - REG_A[reg] += 8; - h1 = m68ki_read_32(ea+0); - h2 = m68ki_read_32(ea+4); - return (uint64)(h1) << 32 | (uint64)(h2); - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_32(); - h1 = m68ki_read_32(ea+0); - h2 = m68ki_read_32(ea+4); - return (uint64)(h1) << 32 | (uint64)(h2); - } - case 7: - { - switch (reg) - { - case 4: // # - { - h1 = OPER_I_32(); - h2 = OPER_I_32(); - return (uint64)(h1) << 32 | (uint64)(h2); - } - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_32(); - h1 = m68ki_read_32(ea+0); - h2 = m68ki_read_32(ea+4); - return (uint64)(h1) << 32 | (uint64)(h2); - } - default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - - return 0; -} - - -static floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea) -{ - floatx80 fpr; - - switch (mode) - { - case 2: // (An) - { - uint32 ea = REG_A[reg]; - fpr = load_extended_float80(ea); - break; - } - - case 3: // (An)+ - { - uint32 ea = REG_A[reg]; - REG_A[reg] += 12; - fpr = load_extended_float80(ea); - break; - } - case 5: // (d16, An) (added by JFF) - { - fpr = load_extended_float80(di_mode_ea); - break; - - } - case 7: // extended modes - { - switch (reg) - { - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_32(); - fpr = load_extended_float80(ea); - } - break; - - case 3: // (d16,PC,Dx.w) - { - uint32 ea = EA_PCIX_32(); - fpr = load_extended_float80(ea); - } - break; - case 4: // immediate (JFF) - { - uint32 ea = REG_PC; - fpr = load_extended_float80(ea); - REG_PC += 12; - } - break; - default: - fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - break; - } - } - break; - - default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break; - } - - return fpr; -} - -static floatx80 READ_EA_PACK(int ea) -{ - floatx80 fpr; - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 2: // (An) - { - uint32 ea = REG_A[reg]; - fpr = load_pack_float80(ea); - break; - } - - case 3: // (An)+ - { - uint32 ea = REG_A[reg]; - REG_A[reg] += 12; - fpr = load_pack_float80(ea); - break; - } - - case 7: // extended modes - { - switch (reg) - { - case 3: // (d16,PC,Dx.w) - { - uint32 ea = EA_PCIX_32(); - fpr = load_pack_float80(ea); - } - break; - - default: - fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - break; - } - } - break; - - default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break; - } - - return fpr; -} - -static void WRITE_EA_8(int ea, uint8 data) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - REG_D[reg] = data; - break; - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - m68ki_write_8(ea, data); - break; - } - case 3: // (An)+ - { - uint32 ea = EA_AY_PI_8(); - m68ki_write_8(ea, data); - break; - } - case 4: // -(An) - { - uint32 ea = EA_AY_PD_8(); - m68ki_write_8(ea, data); - break; - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_8(); - m68ki_write_8(ea, data); - break; - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_8(); - m68ki_write_8(ea, data); - break; - } - case 7: - { - switch (reg) - { - case 1: // (xxx).B - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - m68ki_write_8(ea, data); - break; - } - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_16(); - m68ki_write_8(ea, data); - break; - } - default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); - } -} - -static void WRITE_EA_16(int ea, uint16 data) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - REG_D[reg] = data; - break; - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - m68ki_write_16(ea, data); - break; - } - case 3: // (An)+ - { - uint32 ea = EA_AY_PI_16(); - m68ki_write_16(ea, data); - break; - } - case 4: // -(An) - { - uint32 ea = EA_AY_PD_16(); - m68ki_write_16(ea, data); - break; - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_16(); - m68ki_write_16(ea, data); - break; - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_16(); - m68ki_write_16(ea, data); - break; - } - case 7: - { - switch (reg) - { - case 1: // (xxx).W - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - m68ki_write_16(ea, data); - break; - } - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_16(); - m68ki_write_16(ea, data); - break; - } - default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); - } -} - -static void WRITE_EA_32(int ea, uint32 data) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 0: // Dn - { - REG_D[reg] = data; - break; - } - case 1: // An - { - REG_A[reg] = data; - break; - } - case 2: // (An) - { - uint32 ea = REG_A[reg]; - m68ki_write_32(ea, data); - break; - } - case 3: // (An)+ - { - uint32 ea = EA_AY_PI_32(); - m68ki_write_32(ea, data); - break; - } - case 4: // -(An) - { - uint32 ea = EA_AY_PD_32(); - m68ki_write_32(ea, data); - break; - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_32(); - m68ki_write_32(ea, data); - break; - } - case 6: // (An) + (Xn) + d8 - { - uint32 ea = EA_AY_IX_32(); - m68ki_write_32(ea, data); - break; - } - case 7: - { - switch (reg) - { - case 1: // (xxx).L - { - uint32 d1 = OPER_I_16(); - uint32 d2 = OPER_I_16(); - uint32 ea = (d1 << 16) | d2; - m68ki_write_32(ea, data); - break; - } - case 2: // (d16, PC) - { - uint32 ea = EA_PCDI_32(); - m68ki_write_32(ea, data); - break; - } - default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); - } -} - -static void WRITE_EA_64(int ea, uint64 data) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 2: // (An) - { - uint32 ea = REG_A[reg]; - m68ki_write_32(ea, (uint32)(data >> 32)); - m68ki_write_32(ea+4, (uint32)(data)); - break; - } - case 4: // -(An) - { - uint32 ea; - REG_A[reg] -= 8; - ea = REG_A[reg]; - m68ki_write_32(ea+0, (uint32)(data >> 32)); - m68ki_write_32(ea+4, (uint32)(data)); - break; - } - case 5: // (d16, An) - { - uint32 ea = EA_AY_DI_32(); - m68ki_write_32(ea+0, (uint32)(data >> 32)); - m68ki_write_32(ea+4, (uint32)(data)); - break; - } - default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (uint32)(data >> 32), (uint32)(data), REG_PC); - } -} - -static void WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea) -{ - - - switch (mode) - { - case 2: // (An) - { - uint32 ea; - ea = REG_A[reg]; - store_extended_float80(ea, fpr); - break; - } - - case 3: // (An)+ - { - uint32 ea; - ea = REG_A[reg]; - store_extended_float80(ea, fpr); - REG_A[reg] += 12; - break; - } - - case 4: // -(An) - { - uint32 ea; - REG_A[reg] -= 12; - ea = REG_A[reg]; - store_extended_float80(ea, fpr); - break; - } - case 5: // (d16, An) (added by JFF) - { - // EA_AY_DI_32() should not be done here because fmovem would increase - // PC each time, reading incorrect displacement & advancing PC too much - // uint32 ea = EA_AY_DI_32(); - store_extended_float80(di_mode_ea, fpr); - break; - - } - case 7: - { - switch (reg) - { - default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - } - break; - } - default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - } -} - -static void WRITE_EA_PACK(int ea, int k, floatx80 fpr) -{ - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - - switch (mode) - { - case 2: // (An) - { - uint32 ea; - ea = REG_A[reg]; - store_pack_float80(ea, k, fpr); - break; - } - - case 3: // (An)+ - { - uint32 ea; - ea = REG_A[reg]; - store_pack_float80(ea, k, fpr); - REG_A[reg] += 12; - break; - } - - case 4: // -(An) - { - uint32 ea; - REG_A[reg] -= 12; - ea = REG_A[reg]; - store_pack_float80(ea, k, fpr); - break; - } - - case 7: - { - switch (reg) - { - default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - } - } - break; - default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); - } -} - - -static void fpgen_rm_reg(uint16 w2) -{ - int ea = REG_IR & 0x3f; - int rm = (w2 >> 14) & 0x1; - int src = (w2 >> 10) & 0x7; - int dst = (w2 >> 7) & 0x7; - int opmode = w2 & 0x7f; - floatx80 source; - - // fmovecr #$f, fp0 f200 5c0f - - if (rm) - { - switch (src) - { - case 0: // Long-Word Integer - { - sint32 d = READ_EA_32(ea); - source = int32_to_floatx80(d); - break; - } - case 1: // Single-precision Real - { - uint32 d = READ_EA_32(ea); - source = float32_to_floatx80(d); - break; - } - case 2: // Extended-precision Real - { - int imode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - uint32 di_mode_ea = imode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; - source = READ_EA_FPE(imode,reg,di_mode_ea); - break; - } - case 3: // Packed-decimal Real - { - source = READ_EA_PACK(ea); - break; - } - case 4: // Word Integer - { - sint16 d = READ_EA_16(ea); - source = int32_to_floatx80((sint32)d); - break; - } - case 5: // Double-precision Real - { - uint64 d = READ_EA_64(ea); - - source = float64_to_floatx80(d); - break; - } - case 6: // Byte Integer - { - sint8 d = READ_EA_8(ea); - source = int32_to_floatx80((sint32)d); - break; - } - case 7: // FMOVECR load from constant ROM - { - switch (w2 & 0x7f) - { - case 0x0: // Pi - source.high = 0x4000; - source.low = U64(0xc90fdaa22168c235); - break; - - case 0xb: // log10(2) - source.high = 0x3ffd; - source.low = U64(0x9a209a84fbcff798); - break; - - case 0xc: // e - source.high = 0x4000; - source.low = U64(0xadf85458a2bb4a9b); - break; - - case 0xd: // log2(e) - source.high = 0x3fff; - source.low = U64(0xb8aa3b295c17f0bc); - break; - - case 0xe: // log10(e) - source.high = 0x3ffd; - source.low = U64(0xde5bd8a937287195); - break; - - case 0xf: // 0.0 - source = int32_to_floatx80((sint32)0); - break; - - case 0x30: // ln(2) - source.high = 0x3ffe; - source.low = U64(0xb17217f7d1cf79ac); - break; - - case 0x31: // ln(10) - source.high = 0x4000; - source.low = U64(0x935d8dddaaa8ac17); - break; - - case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense) - source = int32_to_floatx80((sint32)1); - break; - - case 0x33: // 10^1 - source = int32_to_floatx80((sint32)10); - break; - - case 0x34: // 10^2 - source = int32_to_floatx80((sint32)10*10); - break; - - default: - fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4); - break; - } - - // handle it right here, the usual opmode bits aren't valid in the FMOVECR case - REG_FP[dst] = source; - SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR - USE_CYCLES(4); - return; - } - default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4); - } - } - else - { - source = REG_FP[src]; - } - - - - switch (opmode) - { - case 0x00: // FMOVE - { - REG_FP[dst] = source; - SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes - USE_CYCLES(4); - break; - } - case 0x01: // Fsint - { - sint32 temp; - temp = floatx80_to_int32(source); - REG_FP[dst] = int32_to_floatx80(temp); - SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes - break; - } - case 0x03: // FsintRZ - { - sint32 temp; - temp = floatx80_to_int32_round_to_zero(source); - REG_FP[dst] = int32_to_floatx80(temp); - SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes - break; - } - case 0x04: // FSQRT - { - REG_FP[dst] = floatx80_sqrt(source); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(109); - break; - } - case 0x18: // FABS - { - REG_FP[dst] = source; - REG_FP[dst].high &= 0x7fff; - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(3); - break; - } - case 0x1a: // FNEG - { - REG_FP[dst] = source; - REG_FP[dst].high ^= 0x8000; - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(3); - break; - } - case 0x1e: // FGETEXP - { - sint16 temp; - temp = source.high; // get the exponent - temp -= 0x3fff; // take off the bias - REG_FP[dst] = double_to_fx80((double)temp); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(6); - break; - } - case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80) - case 0x20: // FDIV - { - REG_FP[dst] = floatx80_div(REG_FP[dst], source); - SET_CONDITION_CODES(REG_FP[dst]); // JFF - USE_CYCLES(43); - break; - } - case 0x22: // FADD - { - REG_FP[dst] = floatx80_add(REG_FP[dst], source); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(9); - break; - } - case 0x63: // FSMULS (JFF) (source has already been converted to floatx80) - case 0x23: // FMUL - { - REG_FP[dst] = floatx80_mul(REG_FP[dst], source); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(11); - break; - } - case 0x25: // FREM - { - REG_FP[dst] = floatx80_rem(REG_FP[dst], source); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(43); // guess - break; - } - case 0x28: // FSUB - { - REG_FP[dst] = floatx80_sub(REG_FP[dst], source); - SET_CONDITION_CODES(REG_FP[dst]); - USE_CYCLES(9); - break; - } - case 0x38: // FCMP - { - floatx80 res; - res = floatx80_sub(REG_FP[dst], source); - SET_CONDITION_CODES(res); - USE_CYCLES(7); - break; - } - case 0x3a: // FTST - { - floatx80 res; - res = source; - SET_CONDITION_CODES(res); - USE_CYCLES(7); - break; - } - - default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4); - } -} - -static void fmove_reg_mem(uint16 w2) -{ - int ea = REG_IR & 0x3f; - int src = (w2 >> 7) & 0x7; - int dst = (w2 >> 10) & 0x7; - int k = (w2 & 0x7f); - - switch (dst) - { - case 0: // Long-Word Integer - { - sint32 d = (sint32)floatx80_to_int32(REG_FP[src]); - WRITE_EA_32(ea, d); - break; - } - case 1: // Single-precision Real - { - uint32 d = floatx80_to_float32(REG_FP[src]); - WRITE_EA_32(ea, d); - break; - } - case 2: // Extended-precision Real - { - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - uint32 di_mode_ea = mode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; - WRITE_EA_FPE(mode, reg, REG_FP[src], di_mode_ea); - break; - } - case 3: // Packed-decimal Real with Static K-factor - { - // sign-extend k - k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f); - WRITE_EA_PACK(ea, k, REG_FP[src]); - break; - } - case 4: // Word Integer - { - WRITE_EA_16(ea, (sint16)floatx80_to_int32(REG_FP[src])); - break; - } - case 5: // Double-precision Real - { - uint64 d; - - d = floatx80_to_float64(REG_FP[src]); - - WRITE_EA_64(ea, d); - break; - } - case 6: // Byte Integer - { - WRITE_EA_8(ea, (sint8)floatx80_to_int32(REG_FP[src])); - break; - } - case 7: // Packed-decimal Real with Dynamic K-factor - { - WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]); - break; - } - } - - USE_CYCLES(12); -} - -static void fmove_fpcr(uint16 w2) -{ - int ea = REG_IR & 0x3f; - int dir = (w2 >> 13) & 0x1; - int reg = (w2 >> 10) & 0x7; - - if (dir) // From system control reg to - { - if (reg & 4) WRITE_EA_32(ea, REG_FPCR); - if (reg & 2) WRITE_EA_32(ea, REG_FPSR); - if (reg & 1) WRITE_EA_32(ea, REG_FPIAR); - } - else // From to system control reg - { - if (reg & 4) - { - REG_FPCR = READ_EA_32(ea); - // JFF: need to update rounding mode from softfloat module - float_rounding_mode = (REG_FPCR >> 4) & 0x3; - } - if (reg & 2) REG_FPSR = READ_EA_32(ea); - if (reg & 1) REG_FPIAR = READ_EA_32(ea); - } - - USE_CYCLES(10); -} - -static void fmovem(uint16 w2) -{ - int i; - int ea = REG_IR & 0x3f; - int dir = (w2 >> 13) & 0x1; - int mode = (w2 >> 11) & 0x3; - int reglist = w2 & 0xff; - - if (dir) // From FP regs to mem - { - switch (mode) - { - case 2: // (JFF): Static register list, postincrement or control addressing mode. - { - int imode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - int di_mode = imode == 5; - uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; - for (i=0; i < 8; i++) - { - if (reglist & (1 << i)) - { - WRITE_EA_FPE(imode,reg, REG_FP[7-i],di_mode_ea); - USE_CYCLES(2); - if (di_mode) - { - di_mode_ea += 12; - } - } - } - break; - } - case 0: // Static register list, predecrement addressing mode - { - int imode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - // the "di_mode_ea" parameter kludge is required here else WRITE_EA_FPE would have - // to call EA_AY_DI_32() (that advances PC & reads displacement) each time - // when the proper behaviour is 1) read once, 2) increment ea for each matching register - // this forces to pre-read the mode (named "imode") so we can decide to read displacement, only once - int di_mode = imode == 5; - uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; - for (i=0; i < 8; i++) - { - if (reglist & (1 << i)) - { - WRITE_EA_FPE(imode,reg, REG_FP[i],di_mode_ea); - USE_CYCLES(2); - if (di_mode) - { - di_mode_ea += 12; - } - } - } - break; - } - - default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); - } - } - else // From mem to FP regs - { - switch (mode) - { - case 2: // Static register list, postincrement addressing mode - { - int imode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - int di_mode = imode == 5; - uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; - for (i=0; i < 8; i++) - { - if (reglist & (1 << i)) - { - REG_FP[7-i] = READ_EA_FPE(imode,reg,di_mode_ea); - USE_CYCLES(2); - if (di_mode) - { - di_mode_ea += 12; - } - } - } - break; - } - - default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); - } - } -} - -static void fscc() -{ - // added by JFF, this seems to work properly now - int condition = OPER_I_16() & 0x3f; - - int cc = TEST_CONDITION(condition); - int mode = (REG_IR & 0x38) >> 3; - int v = (cc ? 0xff : 0x00); - - switch (mode) - { - case 0: // fscc Dx - { - // If the specified floating-point condition is true, sets the byte integer operand at - // the destination to TRUE (all ones); otherwise, sets the byte to FALSE (all zeros). - - REG_D[REG_IR & 7] = (REG_D[REG_IR & 7] & 0xFFFFFF00) | v; - break; - } - case 5: // (disp,Ax) - { - int reg = REG_IR & 7; - uint32 ea = REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16()); - m68ki_write_8(ea,v); - break; - } - - default: - { - // unimplemented see fpu_uae.cpp around line 1300 - fatalerror("040fpu0: fscc: mode %d not implemented at %08X\n", mode, REG_PC-4); - } - } - USE_CYCLES(7); // JFF unsure of the number of cycles!! -} -static void fbcc16(void) -{ - sint32 offset; - int condition = REG_IR & 0x3f; - - offset = (sint16)(OPER_I_16()); - - // TODO: condition and jump!!! - if (TEST_CONDITION(condition)) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_16(offset-2); - } - - USE_CYCLES(7); - } - -static void fbcc32(void) -{ - sint32 offset; - int condition = REG_IR & 0x3f; - - offset = OPER_I_32(); - - // TODO: condition and jump!!! - if (TEST_CONDITION(condition)) - { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_32(offset-4); - } - - USE_CYCLES(7); -} - - -void m68040_fpu_op0() -{ - m68ki_cpu.fpu_just_reset = 0; - - switch ((REG_IR >> 6) & 0x3) - { - case 0: - { - uint16 w2 = OPER_I_16(); - switch ((w2 >> 13) & 0x7) - { - case 0x0: // FPU ALU FP, FP - case 0x2: // FPU ALU ea, FP - { - fpgen_rm_reg(w2); - break; - } - - case 0x3: // FMOVE FP, ea - { - fmove_reg_mem(w2); - break; - } - - case 0x4: // FMOVEM ea, FPCR - case 0x5: // FMOVEM FPCR, ea - { - fmove_fpcr(w2); - break; - } - - case 0x6: // FMOVEM ea, list - case 0x7: // FMOVEM list, ea - { - fmovem(w2); - break; - } - - default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4); - } - break; - } - - case 1: // FScc (JFF) - { - fscc(); - break; - } - case 2: // FBcc disp16 - { - fbcc16(); - break; - } - case 3: // FBcc disp32 - { - fbcc32(); - break; - } - - default: fatalerror("M68kFPU: unimplemented main op %d at %08X\n", (m68ki_cpu.ir >> 6) & 0x3, REG_PC-4); - } -} - -static void perform_fsave(uint32 addr, int inc) -{ - if (inc) - { - // 68881 IDLE, version 0x1f - m68ki_write_32(addr, 0x1f180000); - m68ki_write_32(addr+4, 0); - m68ki_write_32(addr+8, 0); - m68ki_write_32(addr+12, 0); - m68ki_write_32(addr+16, 0); - m68ki_write_32(addr+20, 0); - m68ki_write_32(addr+24, 0x70000000); - } - else - { - m68ki_write_32(addr, 0x70000000); - m68ki_write_32(addr-4, 0); - m68ki_write_32(addr-8, 0); - m68ki_write_32(addr-12, 0); - m68ki_write_32(addr-16, 0); - m68ki_write_32(addr-20, 0); - m68ki_write_32(addr-24, 0x1f180000); - } -} - -// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0 -static void do_frestore_null() -{ - int i; - - REG_FPCR = 0; - REG_FPSR = 0; - REG_FPIAR = 0; - for (i = 0; i < 8; i++) - { - REG_FP[i].high = 0x7fff; - REG_FP[i].low = U64(0xffffffffffffffff); - } - - // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL - // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!) - m68ki_cpu.fpu_just_reset = 1; -} - -void m68040_fpu_op1() -{ - int ea = REG_IR & 0x3f; - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - uint32 addr, temp; - - switch ((REG_IR >> 6) & 0x3) - { - case 0: // FSAVE - { - switch (mode) - { - case 3: // (An)+ - addr = EA_AY_PI_32(); - - if (m68ki_cpu.fpu_just_reset) - { - m68ki_write_32(addr, 0); - } - else - { - // we normally generate an IDLE frame - REG_A[reg] += 6*4; - perform_fsave(addr, 1); - } - break; - - case 4: // -(An) - addr = EA_AY_PD_32(); - - if (m68ki_cpu.fpu_just_reset) - { - m68ki_write_32(addr, 0); - } - else - { - // we normally generate an IDLE frame - REG_A[reg] -= 6*4; - perform_fsave(addr, 0); - } - break; - - default: - fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC); - } - break; - } - break; - - case 1: // FRESTORE - { - switch (mode) - { - case 2: // (An) - addr = REG_A[reg]; - temp = m68ki_read_32(addr); - - // check for NULL frame - if (temp & 0xff000000) - { - // we don't handle non-NULL frames and there's no pre/post inc/dec to do here - m68ki_cpu.fpu_just_reset = 0; - } - else - { - do_frestore_null(); - } - break; - - case 3: // (An)+ - addr = EA_AY_PI_32(); - temp = m68ki_read_32(addr); - - // check for NULL frame - if (temp & 0xff000000) - { - m68ki_cpu.fpu_just_reset = 0; - - // how about an IDLE frame? - if ((temp & 0x00ff0000) == 0x00180000) - { - REG_A[reg] += 6*4; - } // check UNIMP - else if ((temp & 0x00ff0000) == 0x00380000) - { - REG_A[reg] += 14*4; - } // check BUSY - else if ((temp & 0x00ff0000) == 0x00b40000) - { - REG_A[reg] += 45*4; - } - } - else - { - do_frestore_null(); - } - break; - - default: - fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC); - } - break; - } - break; - - default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2); - } -} - - - +#include +#include +#include + +extern void exit(int); + +static void fatalerror(const char *format, ...) { + va_list ap; + va_start(ap,format); + vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong + va_end(ap); + exit(1); +} + +#define FPCC_N 0x08000000 +#define FPCC_Z 0x04000000 +#define FPCC_I 0x02000000 +#define FPCC_NAN 0x01000000 + +#define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000) +#define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000) +#define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff) + +extern flag floatx80_is_nan( floatx80 a ); + +// masks for packed dwords, positive k-factor +static uint32 pkmask2[18] = +{ + 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, + 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff +}; + +static uint32 pkmask3[18] = +{ + 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, + 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, +}; + +static inline double fx80_to_double(floatx80 fx) +{ + uint64 d; + double *foo; + + foo = (double *)&d; + + d = floatx80_to_float64(fx); + + return *foo; +} + +static inline floatx80 double_to_fx80(double in) +{ + uint64 *d; + + d = (uint64 *)∈ + + return float64_to_floatx80(*d); +} + +static inline floatx80 load_extended_float80(uint32 ea) +{ + uint32 d1,d2; + uint16 d3; + floatx80 fp; + + d3 = m68ki_read_16(ea); + d1 = m68ki_read_32(ea+4); + d2 = m68ki_read_32(ea+8); + + fp.high = d3; + fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff); + + return fp; +} + +static inline void store_extended_float80(uint32 ea, floatx80 fpr) +{ + m68ki_write_16(ea+0, fpr.high); + m68ki_write_16(ea+2, 0); + m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff); + m68ki_write_32(ea+8, fpr.low&0xffffffff); +} + +static inline floatx80 load_pack_float80(uint32 ea) +{ + uint32 dw1, dw2, dw3; + floatx80 result; + double tmp; + char str[128], *ch; + + dw1 = m68ki_read_32(ea); + dw2 = m68ki_read_32(ea+4); + dw3 = m68ki_read_32(ea+8); + + ch = &str[0]; + if (dw1 & 0x80000000) // mantissa sign + { + *ch++ = '-'; + } + *ch++ = (char)((dw1 & 0xf) + '0'); + *ch++ = '.'; + *ch++ = (char)(((dw2 >> 28) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 24) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 20) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 16) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 12) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 8) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 4) & 0xf) + '0'); + *ch++ = (char)(((dw2 >> 0) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 28) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 24) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 20) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 16) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 12) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 8) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 4) & 0xf) + '0'); + *ch++ = (char)(((dw3 >> 0) & 0xf) + '0'); + *ch++ = 'E'; + if (dw1 & 0x40000000) // exponent sign + { + *ch++ = '-'; + } + *ch++ = (char)(((dw1 >> 24) & 0xf) + '0'); + *ch++ = (char)(((dw1 >> 20) & 0xf) + '0'); + *ch++ = (char)(((dw1 >> 16) & 0xf) + '0'); + *ch = '\0'; + + sscanf(str, "%le", &tmp); + + result = double_to_fx80(tmp); + + return result; +} + +static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr) +{ + uint32 dw1, dw2, dw3; + char str[128], *ch; + int i, j, exp; + + dw1 = dw2 = dw3 = 0; + ch = &str[0]; + + sprintf(str, "%.16e", fx80_to_double(fpr)); + + if (*ch == '-') + { + ch++; + dw1 = 0x80000000; + } + + if (*ch == '+') + { + ch++; + } + + dw1 |= (*ch++ - '0'); + + if (*ch == '.') + { + ch++; + } + + // handle negative k-factor here + if ((k <= 0) && (k >= -13)) + { + exp = 0; + for (i = 0; i < 3; i++) + { + if (ch[18+i] >= '0' && ch[18+i] <= '9') + { + exp = (exp << 4) | (ch[18+i] - '0'); + } + } + + if (ch[17] == '-') + { + exp = -exp; + } + + k = -k; + // last digit is (k + exponent - 1) + k += (exp - 1); + + // round up the last significant mantissa digit + if (ch[k+1] >= '5') + { + ch[k]++; + } + + // zero out the rest of the mantissa digits + for (j = (k+1); j < 16; j++) + { + ch[j] = '0'; + } + + // now zero out K to avoid tripping the positive K detection below + k = 0; + } + + // crack 8 digits of the mantissa + for (i = 0; i < 8; i++) + { + dw2 <<= 4; + if (*ch >= '0' && *ch <= '9') + { + dw2 |= *ch++ - '0'; + } + } + + // next 8 digits of the mantissa + for (i = 0; i < 8; i++) + { + dw3 <<= 4; + if (*ch >= '0' && *ch <= '9') + dw3 |= *ch++ - '0'; + } + + // handle masking if k is positive + if (k >= 1) + { + if (k <= 17) + { + dw2 &= pkmask2[k]; + dw3 &= pkmask3[k]; + } + else + { + dw2 &= pkmask2[17]; + dw3 &= pkmask3[17]; +// m68ki_cpu.fpcr |= (need to set OPERR bit) + } + } + + // finally, crack the exponent + if (*ch == 'e' || *ch == 'E') + { + ch++; + if (*ch == '-') + { + ch++; + dw1 |= 0x40000000; + } + + if (*ch == '+') + { + ch++; + } + + j = 0; + for (i = 0; i < 3; i++) + { + if (*ch >= '0' && *ch <= '9') + { + j = (j << 4) | (*ch++ - '0'); + } + } + + dw1 |= (j << 16); + } + + m68ki_write_32(ea, dw1); + m68ki_write_32(ea+4, dw2); + m68ki_write_32(ea+8, dw3); +} + +static inline void SET_CONDITION_CODES(floatx80 reg) +{ + REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN); + + // sign flag + if (reg.high & 0x8000) + { + REG_FPSR |= FPCC_N; + } + + // zero flag + if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0)) + { + REG_FPSR |= FPCC_Z; + } + + // infinity flag + if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0)) + { + REG_FPSR |= FPCC_I; + } + + // NaN flag + if (floatx80_is_nan(reg)) + { + REG_FPSR |= FPCC_NAN; + } +} + +static inline int TEST_CONDITION(int condition) +{ + int n = (REG_FPSR & FPCC_N) != 0; + int z = (REG_FPSR & FPCC_Z) != 0; + int nan = (REG_FPSR & FPCC_NAN) != 0; + int r = 0; + switch (condition) + { + case 0x10: + case 0x00: return 0; // False + + case 0x11: + case 0x01: return (z); // Equal + + case 0x12: + case 0x02: return (!(nan || z || n)); // Greater Than + + case 0x13: + case 0x03: return (z || !(nan || n)); // Greater or Equal + + case 0x14: + case 0x04: return (n && !(nan || z)); // Less Than + + case 0x15: + case 0x05: return (z || (n && !nan)); // Less Than or Equal + + case 0x16: + case 0x06: return !nan && !z; + + case 0x17: + case 0x07: return !nan; + + case 0x18: + case 0x08: return nan; + + case 0x19: + case 0x09: return nan || z; + + case 0x1a: + case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal + + case 0x1b: + case 0x0b: return (nan || z || !n); // Not Less Than + + case 0x1c: + case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than + + case 0x1d: + case 0x0d: return (nan || z || n); // Not Greater Than + + case 0x1e: + case 0x0e: return (!z); // Not Equal + + case 0x1f: + case 0x0f: return 1; // True + + default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition); + } + + return r; +} + +static uint8 READ_EA_8(int ea) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + return REG_D[reg]; + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + return m68ki_read_8(ea); + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_8(); + return m68ki_read_8(ea); + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_8(); + return m68ki_read_8(ea); + } + case 7: + { + switch (reg) + { + case 0: // (xxx).W + { + uint32 ea = (uint32)OPER_I_16(); + return m68ki_read_8(ea); + } + case 1: // (xxx).L + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + return m68ki_read_8(ea); + } + case 4: // # + { + return OPER_I_8(); + } + default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + + return 0; +} + +static uint16 READ_EA_16(int ea) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + return (uint16)(REG_D[reg]); + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + return m68ki_read_16(ea); + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_16(); + return m68ki_read_16(ea); + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_16(); + return m68ki_read_16(ea); + } + case 7: + { + switch (reg) + { + case 0: // (xxx).W + { + uint32 ea = (uint32)OPER_I_16(); + return m68ki_read_16(ea); + } + case 1: // (xxx).L + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + return m68ki_read_16(ea); + } + case 4: // # + { + return OPER_I_16(); + } + + default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + + return 0; +} + +static uint32 READ_EA_32(int ea) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + return REG_D[reg]; + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + return m68ki_read_32(ea); + } + case 3: // (An)+ + { + uint32 ea = EA_AY_PI_32(); + return m68ki_read_32(ea); + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_32(); + return m68ki_read_32(ea); + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_32(); + return m68ki_read_32(ea); + } + case 7: + { + switch (reg) + { + case 0: // (xxx).W + { + uint32 ea = (uint32)OPER_I_16(); + return m68ki_read_32(ea); + } + case 1: // (xxx).L + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + return m68ki_read_32(ea); + } + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_32(); + return m68ki_read_32(ea); + } + case 4: // # + { + return OPER_I_32(); + } + default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + return 0; +} + +static uint64 READ_EA_64(int ea) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 h1, h2; + + switch (mode) + { + case 2: // (An) + { + uint32 ea = REG_A[reg]; + h1 = m68ki_read_32(ea+0); + h2 = m68ki_read_32(ea+4); + return (uint64)(h1) << 32 | (uint64)(h2); + } + case 3: // (An)+ + { + uint32 ea = REG_A[reg]; + REG_A[reg] += 8; + h1 = m68ki_read_32(ea+0); + h2 = m68ki_read_32(ea+4); + return (uint64)(h1) << 32 | (uint64)(h2); + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_32(); + h1 = m68ki_read_32(ea+0); + h2 = m68ki_read_32(ea+4); + return (uint64)(h1) << 32 | (uint64)(h2); + } + case 7: + { + switch (reg) + { + case 4: // # + { + h1 = OPER_I_32(); + h2 = OPER_I_32(); + return (uint64)(h1) << 32 | (uint64)(h2); + } + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_32(); + h1 = m68ki_read_32(ea+0); + h2 = m68ki_read_32(ea+4); + return (uint64)(h1) << 32 | (uint64)(h2); + } + default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + + return 0; +} + + +static floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea) +{ + floatx80 fpr; + + switch (mode) + { + case 2: // (An) + { + uint32 ea = REG_A[reg]; + fpr = load_extended_float80(ea); + break; + } + + case 3: // (An)+ + { + uint32 ea = REG_A[reg]; + REG_A[reg] += 12; + fpr = load_extended_float80(ea); + break; + } + case 5: // (d16, An) (added by JFF) + { + fpr = load_extended_float80(di_mode_ea); + break; + + } + case 7: // extended modes + { + switch (reg) + { + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_32(); + fpr = load_extended_float80(ea); + } + break; + + case 3: // (d16,PC,Dx.w) + { + uint32 ea = EA_PCIX_32(); + fpr = load_extended_float80(ea); + } + break; + case 4: // immediate (JFF) + { + uint32 ea = REG_PC; + fpr = load_extended_float80(ea); + REG_PC += 12; + } + break; + default: + fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + break; + } + } + break; + + default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break; + } + + return fpr; +} + +static floatx80 READ_EA_PACK(int ea) +{ + floatx80 fpr; + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 2: // (An) + { + uint32 ea = REG_A[reg]; + fpr = load_pack_float80(ea); + break; + } + + case 3: // (An)+ + { + uint32 ea = REG_A[reg]; + REG_A[reg] += 12; + fpr = load_pack_float80(ea); + break; + } + + case 7: // extended modes + { + switch (reg) + { + case 3: // (d16,PC,Dx.w) + { + uint32 ea = EA_PCIX_32(); + fpr = load_pack_float80(ea); + } + break; + + default: + fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + break; + } + } + break; + + default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break; + } + + return fpr; +} + +static void WRITE_EA_8(int ea, uint8 data) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + REG_D[reg] = data; + break; + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + m68ki_write_8(ea, data); + break; + } + case 3: // (An)+ + { + uint32 ea = EA_AY_PI_8(); + m68ki_write_8(ea, data); + break; + } + case 4: // -(An) + { + uint32 ea = EA_AY_PD_8(); + m68ki_write_8(ea, data); + break; + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_8(); + m68ki_write_8(ea, data); + break; + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_8(); + m68ki_write_8(ea, data); + break; + } + case 7: + { + switch (reg) + { + case 1: // (xxx).B + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + m68ki_write_8(ea, data); + break; + } + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_16(); + m68ki_write_8(ea, data); + break; + } + default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); + } +} + +static void WRITE_EA_16(int ea, uint16 data) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + REG_D[reg] = data; + break; + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + m68ki_write_16(ea, data); + break; + } + case 3: // (An)+ + { + uint32 ea = EA_AY_PI_16(); + m68ki_write_16(ea, data); + break; + } + case 4: // -(An) + { + uint32 ea = EA_AY_PD_16(); + m68ki_write_16(ea, data); + break; + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_16(); + m68ki_write_16(ea, data); + break; + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_16(); + m68ki_write_16(ea, data); + break; + } + case 7: + { + switch (reg) + { + case 1: // (xxx).W + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + m68ki_write_16(ea, data); + break; + } + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_16(); + m68ki_write_16(ea, data); + break; + } + default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); + } +} + +static void WRITE_EA_32(int ea, uint32 data) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 0: // Dn + { + REG_D[reg] = data; + break; + } + case 1: // An + { + REG_A[reg] = data; + break; + } + case 2: // (An) + { + uint32 ea = REG_A[reg]; + m68ki_write_32(ea, data); + break; + } + case 3: // (An)+ + { + uint32 ea = EA_AY_PI_32(); + m68ki_write_32(ea, data); + break; + } + case 4: // -(An) + { + uint32 ea = EA_AY_PD_32(); + m68ki_write_32(ea, data); + break; + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_32(); + m68ki_write_32(ea, data); + break; + } + case 6: // (An) + (Xn) + d8 + { + uint32 ea = EA_AY_IX_32(); + m68ki_write_32(ea, data); + break; + } + case 7: + { + switch (reg) + { + case 1: // (xxx).L + { + uint32 d1 = OPER_I_16(); + uint32 d2 = OPER_I_16(); + uint32 ea = (d1 << 16) | d2; + m68ki_write_32(ea, data); + break; + } + case 2: // (d16, PC) + { + uint32 ea = EA_PCDI_32(); + m68ki_write_32(ea, data); + break; + } + default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC); + } +} + +static void WRITE_EA_64(int ea, uint64 data) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 2: // (An) + { + uint32 ea = REG_A[reg]; + m68ki_write_32(ea, (uint32)(data >> 32)); + m68ki_write_32(ea+4, (uint32)(data)); + break; + } + case 4: // -(An) + { + uint32 ea; + REG_A[reg] -= 8; + ea = REG_A[reg]; + m68ki_write_32(ea+0, (uint32)(data >> 32)); + m68ki_write_32(ea+4, (uint32)(data)); + break; + } + case 5: // (d16, An) + { + uint32 ea = EA_AY_DI_32(); + m68ki_write_32(ea+0, (uint32)(data >> 32)); + m68ki_write_32(ea+4, (uint32)(data)); + break; + } + default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (uint32)(data >> 32), (uint32)(data), REG_PC); + } +} + +static void WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea) +{ + + + switch (mode) + { + case 2: // (An) + { + uint32 ea; + ea = REG_A[reg]; + store_extended_float80(ea, fpr); + break; + } + + case 3: // (An)+ + { + uint32 ea; + ea = REG_A[reg]; + store_extended_float80(ea, fpr); + REG_A[reg] += 12; + break; + } + + case 4: // -(An) + { + uint32 ea; + REG_A[reg] -= 12; + ea = REG_A[reg]; + store_extended_float80(ea, fpr); + break; + } + case 5: // (d16, An) (added by JFF) + { + // EA_AY_DI_32() should not be done here because fmovem would increase + // PC each time, reading incorrect displacement & advancing PC too much + // uint32 ea = EA_AY_DI_32(); + store_extended_float80(di_mode_ea, fpr); + break; + + } + case 7: + { + switch (reg) + { + default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + } + break; + } + default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + } +} + +static void WRITE_EA_PACK(int ea, int k, floatx80 fpr) +{ + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + + switch (mode) + { + case 2: // (An) + { + uint32 ea; + ea = REG_A[reg]; + store_pack_float80(ea, k, fpr); + break; + } + + case 3: // (An)+ + { + uint32 ea; + ea = REG_A[reg]; + store_pack_float80(ea, k, fpr); + REG_A[reg] += 12; + break; + } + + case 4: // -(An) + { + uint32 ea; + REG_A[reg] -= 12; + ea = REG_A[reg]; + store_pack_float80(ea, k, fpr); + break; + } + + case 7: + { + switch (reg) + { + default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + } + } + break; + default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); + } +} + + +static void fpgen_rm_reg(uint16 w2) +{ + int ea = REG_IR & 0x3f; + int rm = (w2 >> 14) & 0x1; + int src = (w2 >> 10) & 0x7; + int dst = (w2 >> 7) & 0x7; + int opmode = w2 & 0x7f; + floatx80 source; + + // fmovecr #$f, fp0 f200 5c0f + + if (rm) + { + switch (src) + { + case 0: // Long-Word Integer + { + sint32 d = READ_EA_32(ea); + source = int32_to_floatx80(d); + break; + } + case 1: // Single-precision Real + { + uint32 d = READ_EA_32(ea); + source = float32_to_floatx80(d); + break; + } + case 2: // Extended-precision Real + { + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 di_mode_ea = imode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; + source = READ_EA_FPE(imode,reg,di_mode_ea); + break; + } + case 3: // Packed-decimal Real + { + source = READ_EA_PACK(ea); + break; + } + case 4: // Word Integer + { + sint16 d = READ_EA_16(ea); + source = int32_to_floatx80((sint32)d); + break; + } + case 5: // Double-precision Real + { + uint64 d = READ_EA_64(ea); + + source = float64_to_floatx80(d); + break; + } + case 6: // Byte Integer + { + sint8 d = READ_EA_8(ea); + source = int32_to_floatx80((sint32)d); + break; + } + case 7: // FMOVECR load from constant ROM + { + switch (w2 & 0x7f) + { + case 0x0: // Pi + source.high = 0x4000; + source.low = U64(0xc90fdaa22168c235); + break; + + case 0xb: // log10(2) + source.high = 0x3ffd; + source.low = U64(0x9a209a84fbcff798); + break; + + case 0xc: // e + source.high = 0x4000; + source.low = U64(0xadf85458a2bb4a9b); + break; + + case 0xd: // log2(e) + source.high = 0x3fff; + source.low = U64(0xb8aa3b295c17f0bc); + break; + + case 0xe: // log10(e) + source.high = 0x3ffd; + source.low = U64(0xde5bd8a937287195); + break; + + case 0xf: // 0.0 + source = int32_to_floatx80((sint32)0); + break; + + case 0x30: // ln(2) + source.high = 0x3ffe; + source.low = U64(0xb17217f7d1cf79ac); + break; + + case 0x31: // ln(10) + source.high = 0x4000; + source.low = U64(0x935d8dddaaa8ac17); + break; + + case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense) + source = int32_to_floatx80((sint32)1); + break; + + case 0x33: // 10^1 + source = int32_to_floatx80((sint32)10); + break; + + case 0x34: // 10^2 + source = int32_to_floatx80((sint32)10*10); + break; + + default: + fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4); + break; + } + + // handle it right here, the usual opmode bits aren't valid in the FMOVECR case + REG_FP[dst] = source; + SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR + USE_CYCLES(4); + return; + } + default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4); + } + } + else + { + source = REG_FP[src]; + } + + + + switch (opmode) + { + case 0x00: // FMOVE + { + REG_FP[dst] = source; + SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes + USE_CYCLES(4); + break; + } + case 0x01: // Fsint + { + sint32 temp; + temp = floatx80_to_int32(source); + REG_FP[dst] = int32_to_floatx80(temp); + SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes + break; + } + case 0x03: // FsintRZ + { + sint32 temp; + temp = floatx80_to_int32_round_to_zero(source); + REG_FP[dst] = int32_to_floatx80(temp); + SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes + break; + } + case 0x04: // FSQRT + { + REG_FP[dst] = floatx80_sqrt(source); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(109); + break; + } + case 0x18: // FABS + { + REG_FP[dst] = source; + REG_FP[dst].high &= 0x7fff; + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(3); + break; + } + case 0x1a: // FNEG + { + REG_FP[dst] = source; + REG_FP[dst].high ^= 0x8000; + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(3); + break; + } + case 0x1e: // FGETEXP + { + sint16 temp; + temp = source.high; // get the exponent + temp -= 0x3fff; // take off the bias + REG_FP[dst] = double_to_fx80((double)temp); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(6); + break; + } + case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80) + case 0x20: // FDIV + { + REG_FP[dst] = floatx80_div(REG_FP[dst], source); + SET_CONDITION_CODES(REG_FP[dst]); // JFF + USE_CYCLES(43); + break; + } + case 0x22: // FADD + { + REG_FP[dst] = floatx80_add(REG_FP[dst], source); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(9); + break; + } + case 0x63: // FSMULS (JFF) (source has already been converted to floatx80) + case 0x23: // FMUL + { + REG_FP[dst] = floatx80_mul(REG_FP[dst], source); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(11); + break; + } + case 0x25: // FREM + { + REG_FP[dst] = floatx80_rem(REG_FP[dst], source); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(43); // guess + break; + } + case 0x28: // FSUB + { + REG_FP[dst] = floatx80_sub(REG_FP[dst], source); + SET_CONDITION_CODES(REG_FP[dst]); + USE_CYCLES(9); + break; + } + case 0x38: // FCMP + { + floatx80 res; + res = floatx80_sub(REG_FP[dst], source); + SET_CONDITION_CODES(res); + USE_CYCLES(7); + break; + } + case 0x3a: // FTST + { + floatx80 res; + res = source; + SET_CONDITION_CODES(res); + USE_CYCLES(7); + break; + } + + default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4); + } +} + +static void fmove_reg_mem(uint16 w2) +{ + int ea = REG_IR & 0x3f; + int src = (w2 >> 7) & 0x7; + int dst = (w2 >> 10) & 0x7; + int k = (w2 & 0x7f); + + switch (dst) + { + case 0: // Long-Word Integer + { + sint32 d = (sint32)floatx80_to_int32(REG_FP[src]); + WRITE_EA_32(ea, d); + break; + } + case 1: // Single-precision Real + { + uint32 d = floatx80_to_float32(REG_FP[src]); + WRITE_EA_32(ea, d); + break; + } + case 2: // Extended-precision Real + { + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 di_mode_ea = mode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; + WRITE_EA_FPE(mode, reg, REG_FP[src], di_mode_ea); + break; + } + case 3: // Packed-decimal Real with Static K-factor + { + // sign-extend k + k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f); + WRITE_EA_PACK(ea, k, REG_FP[src]); + break; + } + case 4: // Word Integer + { + WRITE_EA_16(ea, (sint16)floatx80_to_int32(REG_FP[src])); + break; + } + case 5: // Double-precision Real + { + uint64 d; + + d = floatx80_to_float64(REG_FP[src]); + + WRITE_EA_64(ea, d); + break; + } + case 6: // Byte Integer + { + WRITE_EA_8(ea, (sint8)floatx80_to_int32(REG_FP[src])); + break; + } + case 7: // Packed-decimal Real with Dynamic K-factor + { + WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]); + break; + } + } + + USE_CYCLES(12); +} + +static void fmove_fpcr(uint16 w2) +{ + int ea = REG_IR & 0x3f; + int dir = (w2 >> 13) & 0x1; + int reg = (w2 >> 10) & 0x7; + + if (dir) // From system control reg to + { + if (reg & 4) WRITE_EA_32(ea, REG_FPCR); + if (reg & 2) WRITE_EA_32(ea, REG_FPSR); + if (reg & 1) WRITE_EA_32(ea, REG_FPIAR); + } + else // From to system control reg + { + if (reg & 4) + { + REG_FPCR = READ_EA_32(ea); + // JFF: need to update rounding mode from softfloat module + float_rounding_mode = (REG_FPCR >> 4) & 0x3; + } + if (reg & 2) REG_FPSR = READ_EA_32(ea); + if (reg & 1) REG_FPIAR = READ_EA_32(ea); + } + + USE_CYCLES(10); +} + +static void fmovem(uint16 w2) +{ + int i; + int ea = REG_IR & 0x3f; + int dir = (w2 >> 13) & 0x1; + int mode = (w2 >> 11) & 0x3; + int reglist = w2 & 0xff; + + if (dir) // From FP regs to mem + { + switch (mode) + { + case 2: // (JFF): Static register list, postincrement or control addressing mode. + { + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + int di_mode = imode == 5; + uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; + for (i=0; i < 8; i++) + { + if (reglist & (1 << i)) + { + WRITE_EA_FPE(imode,reg, REG_FP[7-i],di_mode_ea); + USE_CYCLES(2); + if (di_mode) + { + di_mode_ea += 12; + } + } + } + break; + } + case 0: // Static register list, predecrement addressing mode + { + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + // the "di_mode_ea" parameter kludge is required here else WRITE_EA_FPE would have + // to call EA_AY_DI_32() (that advances PC & reads displacement) each time + // when the proper behaviour is 1) read once, 2) increment ea for each matching register + // this forces to pre-read the mode (named "imode") so we can decide to read displacement, only once + int di_mode = imode == 5; + uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; + for (i=0; i < 8; i++) + { + if (reglist & (1 << i)) + { + WRITE_EA_FPE(imode,reg, REG_FP[i],di_mode_ea); + USE_CYCLES(2); + if (di_mode) + { + di_mode_ea += 12; + } + } + } + break; + } + + default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); + } + } + else // From mem to FP regs + { + switch (mode) + { + case 2: // Static register list, postincrement addressing mode + { + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + int di_mode = imode == 5; + uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0; + for (i=0; i < 8; i++) + { + if (reglist & (1 << i)) + { + REG_FP[7-i] = READ_EA_FPE(imode,reg,di_mode_ea); + USE_CYCLES(2); + if (di_mode) + { + di_mode_ea += 12; + } + } + } + break; + } + + default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); + } + } +} + +static void fscc() +{ + // added by JFF, this seems to work properly now + int condition = OPER_I_16() & 0x3f; + + int cc = TEST_CONDITION(condition); + int mode = (REG_IR & 0x38) >> 3; + int v = (cc ? 0xff : 0x00); + + switch (mode) + { + case 0: // fscc Dx + { + // If the specified floating-point condition is true, sets the byte integer operand at + // the destination to TRUE (all ones); otherwise, sets the byte to FALSE (all zeros). + + REG_D[REG_IR & 7] = (REG_D[REG_IR & 7] & 0xFFFFFF00) | v; + break; + } + case 5: // (disp,Ax) + { + int reg = REG_IR & 7; + uint32 ea = REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16()); + m68ki_write_8(ea,v); + break; + } + + default: + { + // unimplemented see fpu_uae.cpp around line 1300 + fatalerror("040fpu0: fscc: mode %d not implemented at %08X\n", mode, REG_PC-4); + } + } + USE_CYCLES(7); // JFF unsure of the number of cycles!! +} +static void fbcc16(void) +{ + sint32 offset; + int condition = REG_IR & 0x3f; + + offset = (sint16)(OPER_I_16()); + + // TODO: condition and jump!!! + if (TEST_CONDITION(condition)) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_16(offset-2); + } + + USE_CYCLES(7); + } + +static void fbcc32(void) +{ + sint32 offset; + int condition = REG_IR & 0x3f; + + offset = OPER_I_32(); + + // TODO: condition and jump!!! + if (TEST_CONDITION(condition)) + { + m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ + m68ki_branch_32(offset-4); + } + + USE_CYCLES(7); +} + + +void m68040_fpu_op0() +{ + m68ki_cpu.fpu_just_reset = 0; + + switch ((REG_IR >> 6) & 0x3) + { + case 0: + { + uint16 w2 = OPER_I_16(); + switch ((w2 >> 13) & 0x7) + { + case 0x0: // FPU ALU FP, FP + case 0x2: // FPU ALU ea, FP + { + fpgen_rm_reg(w2); + break; + } + + case 0x3: // FMOVE FP, ea + { + fmove_reg_mem(w2); + break; + } + + case 0x4: // FMOVEM ea, FPCR + case 0x5: // FMOVEM FPCR, ea + { + fmove_fpcr(w2); + break; + } + + case 0x6: // FMOVEM ea, list + case 0x7: // FMOVEM list, ea + { + fmovem(w2); + break; + } + + default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4); + } + break; + } + + case 1: // FScc (JFF) + { + fscc(); + break; + } + case 2: // FBcc disp16 + { + fbcc16(); + break; + } + case 3: // FBcc disp32 + { + fbcc32(); + break; + } + + default: fatalerror("M68kFPU: unimplemented main op %d at %08X\n", (m68ki_cpu.ir >> 6) & 0x3, REG_PC-4); + } +} + +static void perform_fsave(uint32 addr, int inc) +{ + if (inc) + { + // 68881 IDLE, version 0x1f + m68ki_write_32(addr, 0x1f180000); + m68ki_write_32(addr+4, 0); + m68ki_write_32(addr+8, 0); + m68ki_write_32(addr+12, 0); + m68ki_write_32(addr+16, 0); + m68ki_write_32(addr+20, 0); + m68ki_write_32(addr+24, 0x70000000); + } + else + { + m68ki_write_32(addr, 0x70000000); + m68ki_write_32(addr-4, 0); + m68ki_write_32(addr-8, 0); + m68ki_write_32(addr-12, 0); + m68ki_write_32(addr-16, 0); + m68ki_write_32(addr-20, 0); + m68ki_write_32(addr-24, 0x1f180000); + } +} + +// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0 +static void do_frestore_null() +{ + int i; + + REG_FPCR = 0; + REG_FPSR = 0; + REG_FPIAR = 0; + for (i = 0; i < 8; i++) + { + REG_FP[i].high = 0x7fff; + REG_FP[i].low = U64(0xffffffffffffffff); + } + + // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL + // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!) + m68ki_cpu.fpu_just_reset = 1; +} + +void m68040_fpu_op1() +{ + int ea = REG_IR & 0x3f; + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 addr, temp; + + switch ((REG_IR >> 6) & 0x3) + { + case 0: // FSAVE + { + switch (mode) + { + case 3: // (An)+ + addr = EA_AY_PI_32(); + + if (m68ki_cpu.fpu_just_reset) + { + m68ki_write_32(addr, 0); + } + else + { + // we normally generate an IDLE frame + REG_A[reg] += 6*4; + perform_fsave(addr, 1); + } + break; + + case 4: // -(An) + addr = EA_AY_PD_32(); + + if (m68ki_cpu.fpu_just_reset) + { + m68ki_write_32(addr, 0); + } + else + { + // we normally generate an IDLE frame + REG_A[reg] -= 6*4; + perform_fsave(addr, 0); + } + break; + + default: + fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC); + } + break; + } + break; + + case 1: // FRESTORE + { + switch (mode) + { + case 2: // (An) + addr = REG_A[reg]; + temp = m68ki_read_32(addr); + + // check for NULL frame + if (temp & 0xff000000) + { + // we don't handle non-NULL frames and there's no pre/post inc/dec to do here + m68ki_cpu.fpu_just_reset = 0; + } + else + { + do_frestore_null(); + } + break; + + case 3: // (An)+ + addr = EA_AY_PI_32(); + temp = m68ki_read_32(addr); + + // check for NULL frame + if (temp & 0xff000000) + { + m68ki_cpu.fpu_just_reset = 0; + + // how about an IDLE frame? + if ((temp & 0x00ff0000) == 0x00180000) + { + REG_A[reg] += 6*4; + } // check UNIMP + else if ((temp & 0x00ff0000) == 0x00380000) + { + REG_A[reg] += 14*4; + } // check BUSY + else if ((temp & 0x00ff0000) == 0x00b40000) + { + REG_A[reg] += 45*4; + } + } + else + { + do_frestore_null(); + } + break; + + default: + fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC); + } + break; + } + break; + + default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2); + } +} + + + diff --git a/AltairZ80/m68k/m68kmake.c b/AltairZ80/m68k/m68kmake.c index 928ebd2c..af482ced 100644 --- a/AltairZ80/m68k/m68kmake.c +++ b/AltairZ80/m68k/m68kmake.c @@ -1,1408 +1,1408 @@ -/* ======================================================================== */ -/* ========================= LICENSING & COPYRIGHT ======================== */ -/* ======================================================================== */ -/* - * MUSASHI - * Version 4.60 - * - * A portable Motorola M680x0 processor emulation engine. - * Copyright Karl Stenerud. All rights reserved. - * FPU and MMU by R. Belmont. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - -/* ======================================================================== */ -/* ============================ CODE GENERATOR ============================ */ -/* ======================================================================== */ -/* - * This is the code generator program which will generate the opcode table - * and the final opcode handlers. - * - * It requires an input file to function (default m68k_in.c), but you can - * specify your own like so: - * - * m68kmake - * - * where output path is the path where the output files should be placed, and - * input file is the file to use for input. - * - * If you modify the input file greatly from its released form, you may have - * to tweak the configuration section a bit since I'm using static allocation - * to keep things simple. - * - * - * TODO: - build a better code generator for the move instruction. - * - Add callm and rtm instructions - * - Fix RTE to handle other format words - * - Add address error (and bus error?) handling - */ - - -static const char g_version[] = "4.60"; - -/* ======================================================================== */ -/* =============================== INCLUDES =============================== */ -/* ======================================================================== */ - -#include -#include -#include -#include -#include - - - -/* ======================================================================== */ -/* ============================= CONFIGURATION ============================ */ -/* ======================================================================== */ - -#define M68K_MAX_PATH 1024 -#define M68K_MAX_DIR 1024 - -#define MAX_LINE_LENGTH 200 /* length of 1 line */ -#define MAX_BODY_LENGTH 300 /* Number of lines in 1 function */ -#define MAX_REPLACE_LENGTH 30 /* Max number of replace strings */ -#define MAX_INSERT_LENGTH 5000 /* Max size of insert piece */ -#define MAX_NAME_LENGTH 30 /* Max length of ophandler name */ -#define MAX_SPEC_PROC_LENGTH 4 /* Max length of special processing str */ -#define MAX_SPEC_EA_LENGTH 5 /* Max length of specified EA str */ -#define EA_ALLOWED_LENGTH 11 /* Max length of ea allowed str */ -#define MAX_OPCODE_INPUT_TABLE_LENGTH 1000 /* Max length of opcode handler tbl */ -#define MAX_OPCODE_OUTPUT_TABLE_LENGTH 3000 /* Max length of opcode handler tbl */ - -/* Default filenames */ -#define FILENAME_INPUT "m68k_in.c" -#define FILENAME_PROTOTYPE "m68kops.h" -#define FILENAME_TABLE "m68kops.c" - - -/* Identifier sequences recognized by this program */ - -#define ID_INPUT_SEPARATOR "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - -#define ID_BASE "M68KMAKE" -#define ID_PROTOTYPE_HEADER ID_BASE "_PROTOTYPE_HEADER" -#define ID_PROTOTYPE_FOOTER ID_BASE "_PROTOTYPE_FOOTER" -#define ID_TABLE_HEADER ID_BASE "_TABLE_HEADER" -#define ID_TABLE_FOOTER ID_BASE "_TABLE_FOOTER" -#define ID_TABLE_BODY ID_BASE "_TABLE_BODY" -#define ID_TABLE_START ID_BASE "_TABLE_START" -#define ID_OPHANDLER_HEADER ID_BASE "_OPCODE_HANDLER_HEADER" -#define ID_OPHANDLER_FOOTER ID_BASE "_OPCODE_HANDLER_FOOTER" -#define ID_OPHANDLER_BODY ID_BASE "_OPCODE_HANDLER_BODY" -#define ID_END ID_BASE "_END" - -#define ID_OPHANDLER_NAME ID_BASE "_OP" -#define ID_OPHANDLER_EA_AY_8 ID_BASE "_GET_EA_AY_8" -#define ID_OPHANDLER_EA_AY_16 ID_BASE "_GET_EA_AY_16" -#define ID_OPHANDLER_EA_AY_32 ID_BASE "_GET_EA_AY_32" -#define ID_OPHANDLER_OPER_AY_8 ID_BASE "_GET_OPER_AY_8" -#define ID_OPHANDLER_OPER_AY_16 ID_BASE "_GET_OPER_AY_16" -#define ID_OPHANDLER_OPER_AY_32 ID_BASE "_GET_OPER_AY_32" -#define ID_OPHANDLER_CC ID_BASE "_CC" -#define ID_OPHANDLER_NOT_CC ID_BASE "_NOT_CC" - - -#ifndef DECL_SPEC -#define DECL_SPEC -#endif /* DECL_SPEC */ - - - -/* ======================================================================== */ -/* ============================== PROTOTYPES ============================== */ -/* ======================================================================== */ - -enum { - CPU_TYPE_000=0, - CPU_TYPE_010, - CPU_TYPE_020, - CPU_TYPE_030, - CPU_TYPE_040, - NUM_CPUS -}; - -#define UNSPECIFIED "." -#define UNSPECIFIED_CH '.' - -#define HAS_NO_EA_MODE(A) (strcmp(A, "..........") == 0) -#define HAS_EA_AI(A) ((A)[0] == 'A') -#define HAS_EA_PI(A) ((A)[1] == '+') -#define HAS_EA_PD(A) ((A)[2] == '-') -#define HAS_EA_DI(A) ((A)[3] == 'D') -#define HAS_EA_IX(A) ((A)[4] == 'X') -#define HAS_EA_AW(A) ((A)[5] == 'W') -#define HAS_EA_AL(A) ((A)[6] == 'L') -#define HAS_EA_PCDI(A) ((A)[7] == 'd') -#define HAS_EA_PCIX(A) ((A)[8] == 'x') -#define HAS_EA_I(A) ((A)[9] == 'I') - -enum -{ - EA_MODE_NONE, /* No special addressing mode */ - EA_MODE_AI, /* Address register indirect */ - EA_MODE_PI, /* Address register indirect with postincrement */ - EA_MODE_PI7, /* Address register 7 indirect with postincrement */ - EA_MODE_PD, /* Address register indirect with predecrement */ - EA_MODE_PD7, /* Address register 7 indirect with predecrement */ - EA_MODE_DI, /* Address register indirect with displacement */ - EA_MODE_IX, /* Address register indirect with index */ - EA_MODE_AW, /* Absolute word */ - EA_MODE_AL, /* Absolute long */ - EA_MODE_PCDI, /* Program counter indirect with displacement */ - EA_MODE_PCIX, /* Program counter indirect with index */ - EA_MODE_I /* Immediate */ -}; - - -/* Everything we need to know about an opcode */ -typedef struct -{ - char name[MAX_NAME_LENGTH]; /* opcode handler name */ - unsigned char size; /* Size of operation */ - char spec_proc[MAX_SPEC_PROC_LENGTH]; /* Special processing mode */ - char spec_ea[MAX_SPEC_EA_LENGTH]; /* Specified effective addressing mode */ - unsigned char bits; /* Number of significant bits (used for sorting the table) */ - unsigned short op_mask; /* Mask to apply for matching an opcode to a handler */ - unsigned short op_match; /* Value to match after masking */ - char ea_allowed[EA_ALLOWED_LENGTH]; /* Effective addressing modes allowed */ - char cpu_mode[NUM_CPUS]; /* User or supervisor mode */ - char cpus[NUM_CPUS+1]; /* Allowed CPUs */ - unsigned char cycles[NUM_CPUS]; /* cycles for 000, 010, 020, 030, 040 */ -} opcode_struct; - - -/* All modifications necessary for a specific EA mode of an instruction */ -typedef struct -{ - char* fname_add; - char* ea_add; - unsigned int mask_add; - unsigned int match_add; -} ea_info_struct; - - -/* Holds the body of a function */ -typedef struct -{ - char body[MAX_BODY_LENGTH][MAX_LINE_LENGTH+1]; - int length; -} body_struct; - - -/* Holds a sequence of search / replace strings */ -typedef struct -{ - char replace[MAX_REPLACE_LENGTH][2][MAX_LINE_LENGTH+1]; - int length; -} replace_struct; - - -/* Function Prototypes */ -void error_exit(const char* fmt, ...); -void perror_exit(const char* fmt, ...); -int check_strsncpy(char* dst, char* src, int maxlength); -int check_atoi(char* str, int *result); -int skip_spaces(char* str); -int num_bits(int value); -int atoh(char* buff); -int fgetline(char* buff, int nchars, FILE* file); -int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type); -opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea); -opcode_struct* find_illegal_opcode(void); -int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea); -void add_replace_string(replace_struct* replace, char* search_str, char* replace_str); -void write_body(FILE* filep, body_struct* body, replace_struct* replace); -void get_base_name(char* base_name, opcode_struct* op); -void write_function_name(FILE* filep, char* base_name); -void add_opcode_output_table_entry(opcode_struct* op, char* name); -static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr); -void print_opcode_output_table(FILE* filep); -void write_table_entry(FILE* filep, opcode_struct* op); -void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode); -void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode); -void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op); -void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset); -void process_opcode_handlers(FILE* filep); -void populate_table(void); -void read_insert(char* insert); - - - -/* ======================================================================== */ -/* ================================= DATA ================================= */ -/* ======================================================================== */ - -/* Name of the input file */ -char g_input_filename[M68K_MAX_PATH] = FILENAME_INPUT; - -/* File handles */ -FILE* g_input_file = NULL; -FILE* g_prototype_file = NULL; -FILE* g_table_file = NULL; - -int g_num_functions = 0; /* Number of functions processed */ -int g_num_primitives = 0; /* Number of function primitives read */ -int g_line_number = 1; /* Current line number */ - -/* Opcode handler table */ -opcode_struct g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH]; - -opcode_struct g_opcode_output_table[MAX_OPCODE_OUTPUT_TABLE_LENGTH]; -int g_opcode_output_table_length = 0; - -const ea_info_struct g_ea_info_table[13] = -{/* fname ea mask match */ - {"", "", 0x00, 0x00}, /* EA_MODE_NONE */ - {"ai", "AY_AI", 0x38, 0x10}, /* EA_MODE_AI */ - {"pi", "AY_PI", 0x38, 0x18}, /* EA_MODE_PI */ - {"pi7", "A7_PI", 0x3f, 0x1f}, /* EA_MODE_PI7 */ - {"pd", "AY_PD", 0x38, 0x20}, /* EA_MODE_PD */ - {"pd7", "A7_PD", 0x3f, 0x27}, /* EA_MODE_PD7 */ - {"di", "AY_DI", 0x38, 0x28}, /* EA_MODE_DI */ - {"ix", "AY_IX", 0x38, 0x30}, /* EA_MODE_IX */ - {"aw", "AW", 0x3f, 0x38}, /* EA_MODE_AW */ - {"al", "AL", 0x3f, 0x39}, /* EA_MODE_AL */ - {"pcdi", "PCDI", 0x3f, 0x3a}, /* EA_MODE_PCDI */ - {"pcix", "PCIX", 0x3f, 0x3b}, /* EA_MODE_PCIX */ - {"i", "I", 0x3f, 0x3c}, /* EA_MODE_I */ -}; - - -const char *const g_cc_table[16][2] = -{ - { "t", "T"}, /* 0000 */ - { "f", "F"}, /* 0001 */ - {"hi", "HI"}, /* 0010 */ - {"ls", "LS"}, /* 0011 */ - {"cc", "CC"}, /* 0100 */ - {"cs", "CS"}, /* 0101 */ - {"ne", "NE"}, /* 0110 */ - {"eq", "EQ"}, /* 0111 */ - {"vc", "VC"}, /* 1000 */ - {"vs", "VS"}, /* 1001 */ - {"pl", "PL"}, /* 1010 */ - {"mi", "MI"}, /* 1011 */ - {"ge", "GE"}, /* 1100 */ - {"lt", "LT"}, /* 1101 */ - {"gt", "GT"}, /* 1110 */ - {"le", "LE"}, /* 1111 */ -}; - -/* size to index translator (0 -> 0, 8 and 16 -> 1, 32 -> 2) */ -const int g_size_select_table[33] = -{ - 0, /* unsized */ - 0, 0, 0, 0, 0, 0, 0, 1, /* 8 */ - 0, 0, 0, 0, 0, 0, 0, 1, /* 16 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 /* 32 */ -}; - -/* Extra cycles required for certain EA modes */ -/* TODO: correct timings for 030, 040 */ -const int g_ea_cycle_table[13][NUM_CPUS][3] = -{/* 000 010 020 030 040 */ - {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */ - {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AI */ - {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI */ - {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI7 */ - {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD */ - {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD7 */ - {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_DI */ - {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_IX */ - {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AW */ - {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AL */ - {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PCDI */ - {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_PCIX */ - {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */ -}; - -/* Extra cycles for JMP instruction (000, 010) */ -const int g_jmp_cycle_table[13] = -{ - 0, /* EA_MODE_NONE */ - 4, /* EA_MODE_AI */ - 0, /* EA_MODE_PI */ - 0, /* EA_MODE_PI7 */ - 0, /* EA_MODE_PD */ - 0, /* EA_MODE_PD7 */ - 6, /* EA_MODE_DI */ - 10, /* EA_MODE_IX */ - 6, /* EA_MODE_AW */ - 8, /* EA_MODE_AL */ - 6, /* EA_MODE_PCDI */ - 10, /* EA_MODE_PCIX */ - 0, /* EA_MODE_I */ -}; - -/* Extra cycles for JSR instruction (000, 010) */ -const int g_jsr_cycle_table[13] = -{ - 0, /* EA_MODE_NONE */ - 4, /* EA_MODE_AI */ - 0, /* EA_MODE_PI */ - 0, /* EA_MODE_PI7 */ - 0, /* EA_MODE_PD */ - 0, /* EA_MODE_PD7 */ - 6, /* EA_MODE_DI */ - 10, /* EA_MODE_IX */ - 6, /* EA_MODE_AW */ - 8, /* EA_MODE_AL */ - 6, /* EA_MODE_PCDI */ - 10, /* EA_MODE_PCIX */ - 0, /* EA_MODE_I */ -}; - -/* Extra cycles for LEA instruction (000, 010) */ -const int g_lea_cycle_table[13] = -{ - 0, /* EA_MODE_NONE */ - 4, /* EA_MODE_AI */ - 0, /* EA_MODE_PI */ - 0, /* EA_MODE_PI7 */ - 0, /* EA_MODE_PD */ - 0, /* EA_MODE_PD7 */ - 8, /* EA_MODE_DI */ - 12, /* EA_MODE_IX */ - 8, /* EA_MODE_AW */ - 12, /* EA_MODE_AL */ - 8, /* EA_MODE_PCDI */ - 12, /* EA_MODE_PCIX */ - 0, /* EA_MODE_I */ -}; - -/* Extra cycles for PEA instruction (000, 010) */ -const int g_pea_cycle_table[13] = -{ - 0, /* EA_MODE_NONE */ - 6, /* EA_MODE_AI */ - 0, /* EA_MODE_PI */ - 0, /* EA_MODE_PI7 */ - 0, /* EA_MODE_PD */ - 0, /* EA_MODE_PD7 */ - 10, /* EA_MODE_DI */ - 14, /* EA_MODE_IX */ - 10, /* EA_MODE_AW */ - 14, /* EA_MODE_AL */ - 10, /* EA_MODE_PCDI */ - 14, /* EA_MODE_PCIX */ - 0, /* EA_MODE_I */ -}; - -/* Extra cycles for MOVEM instruction (000, 010) */ -const int g_movem_cycle_table[13] = -{ - 0, /* EA_MODE_NONE */ - 0, /* EA_MODE_AI */ - 0, /* EA_MODE_PI */ - 0, /* EA_MODE_PI7 */ - 0, /* EA_MODE_PD */ - 0, /* EA_MODE_PD7 */ - 4, /* EA_MODE_DI */ - 6, /* EA_MODE_IX */ - 4, /* EA_MODE_AW */ - 8, /* EA_MODE_AL */ - 0, /* EA_MODE_PCDI */ - 0, /* EA_MODE_PCIX */ - 0, /* EA_MODE_I */ -}; - -/* Extra cycles for MOVES instruction (010) */ -const int g_moves_cycle_table[13][3] = -{ - { 0, 0, 0}, /* EA_MODE_NONE */ - { 0, 4, 6}, /* EA_MODE_AI */ - { 0, 4, 6}, /* EA_MODE_PI */ - { 0, 4, 6}, /* EA_MODE_PI7 */ - { 0, 6, 12}, /* EA_MODE_PD */ - { 0, 6, 12}, /* EA_MODE_PD7 */ - { 0, 12, 16}, /* EA_MODE_DI */ - { 0, 16, 20}, /* EA_MODE_IX */ - { 0, 12, 16}, /* EA_MODE_AW */ - { 0, 16, 20}, /* EA_MODE_AL */ - { 0, 0, 0}, /* EA_MODE_PCDI */ - { 0, 0, 0}, /* EA_MODE_PCIX */ - { 0, 0, 0}, /* EA_MODE_I */ -}; - -/* Extra cycles for CLR instruction (010) */ -const int g_clr_cycle_table[13][3] = -{ - { 0, 0, 0}, /* EA_MODE_NONE */ - { 0, 4, 6}, /* EA_MODE_AI */ - { 0, 4, 6}, /* EA_MODE_PI */ - { 0, 4, 6}, /* EA_MODE_PI7 */ - { 0, 6, 8}, /* EA_MODE_PD */ - { 0, 6, 8}, /* EA_MODE_PD7 */ - { 0, 8, 10}, /* EA_MODE_DI */ - { 0, 10, 14}, /* EA_MODE_IX */ - { 0, 8, 10}, /* EA_MODE_AW */ - { 0, 10, 14}, /* EA_MODE_AL */ - { 0, 0, 0}, /* EA_MODE_PCDI */ - { 0, 0, 0}, /* EA_MODE_PCIX */ - { 0, 0, 0}, /* EA_MODE_I */ -}; - - - -/* ======================================================================== */ -/* =========================== UTILITY FUNCTIONS ========================== */ -/* ======================================================================== */ - -/* Print an error message and exit with status error */ -void error_exit(const char* fmt, ...) -{ - va_list args; - fprintf(stderr, "In %s, near or on line %d:\n\t", g_input_filename, g_line_number); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); - - if(g_prototype_file) fclose(g_prototype_file); - if(g_table_file) fclose(g_table_file); - if(g_input_file) fclose(g_input_file); - - exit(EXIT_FAILURE); -} - -/* Print an error message, call perror(), and exit with status error */ -void perror_exit(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - perror(""); - - if(g_prototype_file) fclose(g_prototype_file); - if(g_table_file) fclose(g_table_file); - if(g_input_file) fclose(g_input_file); - - exit(EXIT_FAILURE); -} - - -/* copy until 0 or space and exit with error if we read too far */ -int check_strsncpy(char* dst, char* src, int maxlength) -{ - char* p = dst; - while(*src && *src != ' ') - { - *p++ = *src++; - if(p - dst > maxlength) - error_exit("Field too long"); - } - *p = 0; - return p - dst; -} - -/* copy until 0 or specified character and exit with error if we read too far */ -int check_strcncpy(char* dst, char* src, char delim, int maxlength) -{ - char* p = dst; - while(*src && *src != delim) - { - *p++ = *src++; - if(p - dst > maxlength) - error_exit("Field too long"); - } - *p = 0; - return p - dst; -} - -/* convert ascii to integer and exit with error if we find invalid data */ -int check_atoi(char* str, int *result) -{ - int accum = 0; - char* p = str; - while(*p >= '0' && *p <= '9') - { - accum *= 10; - accum += *p++ - '0'; - } - if(*p != ' ' && *p != 0) - error_exit("Malformed integer value (%c)", *p); - *result = accum; - return p - str; -} - -/* Skip past spaces in a string */ -int skip_spaces(char* str) -{ - char* p = str; - - while(*p == ' ') - p++; - - return p - str; -} - -/* Count the number of set bits in a value */ -int num_bits(int value) -{ - value = ((value & 0xaaaa) >> 1) + (value & 0x5555); - value = ((value & 0xcccc) >> 2) + (value & 0x3333); - value = ((value & 0xf0f0) >> 4) + (value & 0x0f0f); - value = ((value & 0xff00) >> 8) + (value & 0x00ff); - return value; -} - -/* Convert a hex value written in ASCII */ -int atoh(char* buff) -{ - int accum = 0; - - for(;;buff++) - { - if(*buff >= '0' && *buff <= '9') - { - accum <<= 4; - accum += *buff - '0'; - } - else if(*buff >= 'a' && *buff <= 'f') - { - accum <<= 4; - accum += *buff - 'a' + 10; - } - else break; - } - return accum; -} - -/* Get a line of text from a file, discarding any end-of-line characters */ -int fgetline(char* buff, int nchars, FILE* file) -{ - int length; - - if(fgets(buff, nchars, file) == NULL) - return -1; - if(buff[0] == '\r') - memmove(buff, buff + 1, nchars - 1); - - length = strlen(buff); - while(length && (buff[length-1] == '\r' || buff[length-1] == '\n')) - length--; - buff[length] = 0; - g_line_number++; - - return length; -} - - - -/* ======================================================================== */ -/* =========================== HELPER FUNCTIONS =========================== */ -/* ======================================================================== */ - -/* Calculate the number of cycles an opcode requires */ -int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type) -{ - int size = g_size_select_table[op->size]; - - if(op->cpus[cpu_type] == '.') - return 0; - - if(cpu_type < CPU_TYPE_020) - { - if(cpu_type == CPU_TYPE_010) - { - if(strcmp(op->name, "moves") == 0) - return op->cycles[cpu_type] + g_moves_cycle_table[ea_mode][size]; - if(strcmp(op->name, "clr") == 0) - return op->cycles[cpu_type] + g_clr_cycle_table[ea_mode][size]; - } - - /* ASG: added these cases -- immediate modes take 2 extra cycles here */ - if(cpu_type == CPU_TYPE_000 && ea_mode == EA_MODE_I && - ((strcmp(op->name, "add") == 0 && strcmp(op->spec_proc, "er") == 0) || - strcmp(op->name, "adda") == 0 || - (strcmp(op->name, "and") == 0 && strcmp(op->spec_proc, "er") == 0) || - (strcmp(op->name, "or") == 0 && strcmp(op->spec_proc, "er") == 0) || - (strcmp(op->name, "sub") == 0 && strcmp(op->spec_proc, "er") == 0) || - strcmp(op->name, "suba") == 0)) - return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size] + 2; - - if(strcmp(op->name, "jmp") == 0) - return op->cycles[cpu_type] + g_jmp_cycle_table[ea_mode]; - if(strcmp(op->name, "jsr") == 0) - return op->cycles[cpu_type] + g_jsr_cycle_table[ea_mode]; - if(strcmp(op->name, "lea") == 0) - return op->cycles[cpu_type] + g_lea_cycle_table[ea_mode]; - if(strcmp(op->name, "pea") == 0) - return op->cycles[cpu_type] + g_pea_cycle_table[ea_mode]; - if(strcmp(op->name, "movem") == 0) - return op->cycles[cpu_type] + g_movem_cycle_table[ea_mode]; - } - return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size]; -} - -/* Find an opcode in the opcode handler list */ -opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea) -{ - opcode_struct* op; - - - for(op = g_opcode_input_table;op < &g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];op++) - { - if( strcmp(name, op->name) == 0 && - (size == op->size) && - strcmp(spec_proc, op->spec_proc) == 0 && - strcmp(spec_ea, op->spec_ea) == 0) - return op; - } - return NULL; -} - -/* Specifically find the illegal opcode in the list */ -opcode_struct* find_illegal_opcode(void) -{ - opcode_struct* op; - - for(op = g_opcode_input_table;op < &g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];op++) - { - if(strcmp(op->name, "illegal") == 0) - return op; - } - return NULL; -} - -/* Parse an opcode handler name */ -int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea) -{ - char* ptr = strstr(src, ID_OPHANDLER_NAME); - - if(ptr == NULL) - return 0; - - ptr += strlen(ID_OPHANDLER_NAME) + 1; - - ptr += check_strcncpy(name, ptr, ',', MAX_NAME_LENGTH); - if(*ptr != ',') return 0; - ptr++; - ptr += skip_spaces(ptr); - - *size = atoi(ptr); - ptr = strstr(ptr, ","); - if(ptr == NULL) return 0; - ptr++; - ptr += skip_spaces(ptr); - - ptr += check_strcncpy(spec_proc, ptr, ',', MAX_SPEC_PROC_LENGTH); - if(*ptr != ',') return 0; - ptr++; - ptr += skip_spaces(ptr); - - ptr += check_strcncpy(spec_ea, ptr, ')', MAX_SPEC_EA_LENGTH); - if(*ptr != ')') return 0; - ptr++; - ptr += skip_spaces(ptr); - - return 1; -} - - -/* Add a search/replace pair to a replace structure */ -void add_replace_string(replace_struct* replace, char* search_str, char* replace_str) -{ - if(replace->length >= MAX_REPLACE_LENGTH) - error_exit("overflow in replace structure"); - - strcpy(replace->replace[replace->length][0], search_str); - strcpy(replace->replace[replace->length++][1], replace_str); -} - -/* Write a function body while replacing any selected strings */ -void write_body(FILE* filep, body_struct* body, replace_struct* replace) -{ - int i; - int j; - char* ptr; - char output[MAX_LINE_LENGTH+1]; - char temp_buff[MAX_LINE_LENGTH+1]; - int found; - - for(i=0;ilength;i++) - { - strcpy(output, body->body[i]); - /* Check for the base directive header */ - if(strstr(output, ID_BASE) != NULL) - { - /* Search for any text we need to replace */ - found = 0; - for(j=0;jlength;j++) - { - ptr = strstr(output, replace->replace[j][0]); - if(ptr) - { - /* We found something to replace */ - found = 1; - strcpy(temp_buff, ptr+strlen(replace->replace[j][0])); - strcpy(ptr, replace->replace[j][1]); - strcat(ptr, temp_buff); - } - } - /* Found a directive with no matching replace string */ - if(!found) - error_exit("Unknown " ID_BASE " directive [%s]", output); - } - fprintf(filep, "%s\n", output); - } - fprintf(filep, "\n\n"); -} - -/* Generate a base function name from an opcode struct */ -void get_base_name(char* base_name, opcode_struct* op) -{ - sprintf(base_name, "m68k_op_%s", op->name); - if(op->size > 0) - sprintf(base_name+strlen(base_name), "_%d", op->size); - if(strcmp(op->spec_proc, UNSPECIFIED) != 0) - sprintf(base_name+strlen(base_name), "_%s", op->spec_proc); - if(strcmp(op->spec_ea, UNSPECIFIED) != 0) - sprintf(base_name+strlen(base_name), "_%s", op->spec_ea); -} - -/* Write the name of an opcode handler function */ -void write_function_name(FILE* filep, char* base_name) -{ - fprintf(filep, "static void %s(void)\n", base_name); -} - -void add_opcode_output_table_entry(opcode_struct* op, char* name) -{ - opcode_struct* ptr; - if(g_opcode_output_table_length > MAX_OPCODE_OUTPUT_TABLE_LENGTH) - error_exit("Opcode output table overflow"); - - ptr = g_opcode_output_table + g_opcode_output_table_length++; - - *ptr = *op; - strcpy(ptr->name, name); - ptr->bits = num_bits(ptr->op_mask); -} - -/* - * Comparison function for qsort() - * For entries with an equal number of set bits in - * the mask compare the match values - */ -static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr) -{ - const opcode_struct *a = aptr, *b = bptr; - if(a->bits != b->bits) - return a->bits - b->bits; - if(a->op_mask != b->op_mask) - return a->op_mask - b->op_mask; - return a->op_match - b->op_match; -} - -void print_opcode_output_table(FILE* filep) -{ - int i; - qsort((void *)g_opcode_output_table, g_opcode_output_table_length, sizeof(g_opcode_output_table[0]), compare_nof_true_bits); - - for(i=0;iname, op->op_mask, op->op_match); - - for(i=0;icycles[i]); - if(i < NUM_CPUS-1) - fprintf(filep, ", "); - } - - fprintf(filep, "}},\n"); -} - -/* Fill out an opcode struct with a specific addressing mode of the source opcode struct */ -void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode) -{ - int i; - - *dst = *src; - - for(i=0;icycles[i] = get_oper_cycles(dst, ea_mode, i); - if(strcmp(dst->spec_ea, UNSPECIFIED) == 0 && ea_mode != EA_MODE_NONE) - sprintf(dst->spec_ea, "%s", g_ea_info_table[ea_mode].fname_add); - dst->op_mask |= g_ea_info_table[ea_mode].mask_add; - dst->op_match |= g_ea_info_table[ea_mode].match_add; -} - - -/* Generate a final opcode handler from the provided data */ -void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode) -{ - char str[MAX_LINE_LENGTH+1]; - opcode_struct* op = malloc(sizeof(opcode_struct)); - - /* Set the opcode structure and write the tables, prototypes, etc */ - set_opcode_struct(opinfo, op, ea_mode); - get_base_name(str, op); - add_opcode_output_table_entry(op, str); - write_function_name(filep, str); - - /* Add any replace strings needed */ - if(ea_mode != EA_MODE_NONE) - { - sprintf(str, "EA_%s_8()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_EA_AY_8, str); - sprintf(str, "EA_%s_16()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_EA_AY_16, str); - sprintf(str, "EA_%s_32()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_EA_AY_32, str); - sprintf(str, "OPER_%s_8()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_OPER_AY_8, str); - sprintf(str, "OPER_%s_16()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_OPER_AY_16, str); - sprintf(str, "OPER_%s_32()", g_ea_info_table[ea_mode].ea_add); - add_replace_string(replace, ID_OPHANDLER_OPER_AY_32, str); - } - - /* Now write the function body with the selected replace strings */ - write_body(filep, body, replace); - g_num_functions++; - free(op); -} - -/* Generate opcode variants based on available addressing modes */ -void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op) -{ - int old_length = replace->length; - - /* No ea modes available for this opcode */ - if(HAS_NO_EA_MODE(op->ea_allowed)) - { - generate_opcode_handler(filep, body, replace, op, EA_MODE_NONE); - return; - } - - /* Check for and create specific opcodes for each available addressing mode */ - if(HAS_EA_AI(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_AI); - replace->length = old_length; - if(HAS_EA_PI(op->ea_allowed)) - { - generate_opcode_handler(filep, body, replace, op, EA_MODE_PI); - replace->length = old_length; - if(op->size == 8) - generate_opcode_handler(filep, body, replace, op, EA_MODE_PI7); - } - replace->length = old_length; - if(HAS_EA_PD(op->ea_allowed)) - { - generate_opcode_handler(filep, body, replace, op, EA_MODE_PD); - replace->length = old_length; - if(op->size == 8) - generate_opcode_handler(filep, body, replace, op, EA_MODE_PD7); - } - replace->length = old_length; - if(HAS_EA_DI(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_DI); - replace->length = old_length; - if(HAS_EA_IX(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_IX); - replace->length = old_length; - if(HAS_EA_AW(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_AW); - replace->length = old_length; - if(HAS_EA_AL(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_AL); - replace->length = old_length; - if(HAS_EA_PCDI(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_PCDI); - replace->length = old_length; - if(HAS_EA_PCIX(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_PCIX); - replace->length = old_length; - if(HAS_EA_I(op->ea_allowed)) - generate_opcode_handler(filep, body, replace, op, EA_MODE_I); - replace->length = old_length; -} - -/* Generate variants of condition code opcodes */ -void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset) -{ - char repl[20]; - char replnot[20]; - int i; - int old_length = replace->length; - opcode_struct* op = malloc(sizeof(opcode_struct)); - - *op = *op_in; - - op->op_mask |= 0x0f00; - - /* Do all condition codes except t and f */ - for(i=2;i<16;i++) - { - /* Add replace strings for this condition code */ - sprintf(repl, "COND_%s()", g_cc_table[i][1]); - sprintf(replnot, "COND_NOT_%s()", g_cc_table[i][1]); - - add_replace_string(replace, ID_OPHANDLER_CC, repl); - add_replace_string(replace, ID_OPHANDLER_NOT_CC, replnot); - - /* Set the new opcode info */ - strcpy(op->name+offset, g_cc_table[i][0]); - - op->op_match = (op->op_match & 0xf0ff) | (i<<8); - - /* Generate all opcode variants for this modified opcode */ - generate_opcode_ea_variants(filep, body, replace, op); - /* Remove the above replace strings */ - replace->length = old_length; - } - free(op); -} - -/* Process the opcode handlers section of the input file */ -void process_opcode_handlers(FILE* filep) -{ - FILE* input_file = g_input_file; - char func_name[MAX_LINE_LENGTH+1]; - char oper_name[MAX_LINE_LENGTH+1]; - int oper_size; - char oper_spec_proc[MAX_LINE_LENGTH+1]; - char oper_spec_ea[MAX_LINE_LENGTH+1]; - opcode_struct* opinfo; - replace_struct* replace = malloc(sizeof(replace_struct)); - body_struct* body = malloc(sizeof(body_struct)); - - for(;;) - { - /* Find the first line of the function */ - func_name[0] = 0; - while(strstr(func_name, ID_OPHANDLER_NAME) == NULL) - { - if(strcmp(func_name, ID_INPUT_SEPARATOR) == 0) - { - free(replace); - free(body); - return; /* all done */ - } - if(fgetline(func_name, MAX_LINE_LENGTH, input_file) < 0) - error_exit("Premature end of file when getting function name"); - } - /* Get the rest of the function */ - for(body->length=0;;body->length++) - { - if(body->length > MAX_BODY_LENGTH) - error_exit("Function too long"); - - if(fgetline(body->body[body->length], MAX_LINE_LENGTH, input_file) < 0) - error_exit("Premature end of file when getting function body"); - - if(body->body[body->length][0] == '}') - { - body->length++; - break; - } - } - - g_num_primitives++; - - /* Extract the function name information */ - if(!extract_opcode_info(func_name, oper_name, &oper_size, oper_spec_proc, oper_spec_ea)) - error_exit("Invalid " ID_OPHANDLER_NAME " format"); - - /* Find the corresponding table entry */ - opinfo = find_opcode(oper_name, oper_size, oper_spec_proc, oper_spec_ea); - if(opinfo == NULL) - error_exit("Unable to find matching table entry for %s", func_name); - - replace->length = 0; - - /* Generate opcode variants */ - if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0) - generate_opcode_cc_variants(filep, body, replace, opinfo, 1); - else if(strcmp(opinfo->name, "dbcc") == 0) - generate_opcode_cc_variants(filep, body, replace, opinfo, 2); - else if(strcmp(opinfo->name, "trapcc") == 0) - generate_opcode_cc_variants(filep, body, replace, opinfo, 4); - else - generate_opcode_ea_variants(filep, body, replace, opinfo); - } - - free(replace); - free(body); -} - - -/* Populate the opcode handler table from the input file */ -void populate_table(void) -{ - char* ptr; - char bitpattern[17]; - opcode_struct* op; - char buff[MAX_LINE_LENGTH]; - int i; - int temp; - - buff[0] = 0; - - /* Find the start of the table */ - while(strcmp(buff, ID_TABLE_START) != 0) - if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) - error_exit("(table_start) Premature EOF while reading table"); - - /* Process the entire table */ - for(op = g_opcode_input_table;;op++) - { - if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) - error_exit("(inline) Premature EOF while reading table"); - if(strlen(buff) == 0) - continue; - /* We finish when we find an input separator */ - if(strcmp(buff, ID_INPUT_SEPARATOR) == 0) - break; - - /* Extract the info from the table */ - ptr = buff; - - /* Name */ - ptr += skip_spaces(ptr); - ptr += check_strsncpy(op->name, ptr, MAX_NAME_LENGTH); - - /* Size */ - ptr += skip_spaces(ptr); - ptr += check_atoi(ptr, &temp); - op->size = (unsigned char)temp; - - /* Special processing */ - ptr += skip_spaces(ptr); - ptr += check_strsncpy(op->spec_proc, ptr, MAX_SPEC_PROC_LENGTH); - - /* Specified EA Mode */ - ptr += skip_spaces(ptr); - ptr += check_strsncpy(op->spec_ea, ptr, MAX_SPEC_EA_LENGTH); - - /* Bit Pattern (more processing later) */ - ptr += skip_spaces(ptr); - ptr += check_strsncpy(bitpattern, ptr, 17); - - /* Allowed Addressing Mode List */ - ptr += skip_spaces(ptr); - ptr += check_strsncpy(op->ea_allowed, ptr, EA_ALLOWED_LENGTH); - - /* CPU operating mode (U = user or supervisor, S = supervisor only */ - ptr += skip_spaces(ptr); - for(i=0;icpu_mode[i] = *ptr++; - ptr += skip_spaces(ptr); - } - - /* Allowed CPUs for this instruction */ - for(i=0;icpus[i] = UNSPECIFIED_CH; - op->cycles[i] = 0; - ptr++; - } - else - { - op->cpus[i] = '0' + i; - ptr += check_atoi(ptr, &temp); - op->cycles[i] = (unsigned char)temp; - } - } - - /* generate mask and match from bitpattern */ - op->op_mask = 0; - op->op_match = 0; - for(i=0;i<16;i++) - { - op->op_mask |= (bitpattern[i] != '.') << (15-i); - op->op_match |= (bitpattern[i] == '1') << (15-i); - } - } - /* Terminate the list */ - op->name[0] = 0; -} - -/* Read a header or footer insert from the input file */ -void read_insert(char* insert) -{ - char* ptr = insert; - char* overflow = insert + MAX_INSERT_LENGTH - MAX_LINE_LENGTH; - int length; - char* first_blank = NULL; - - first_blank = NULL; - - /* Skip any leading blank lines */ - for(length = 0;length == 0;length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file)) - if(ptr >= overflow) - error_exit("Buffer overflow reading inserts"); - if(length < 0) - error_exit("Premature EOF while reading inserts"); - - /* Advance and append newline */ - ptr += length; - strcpy(ptr++, "\n"); - - /* Read until next separator */ - for(;;) - { - /* Read a new line */ - if(ptr >= overflow) - error_exit("Buffer overflow reading inserts"); - if((length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file)) < 0) - error_exit("Premature EOF while reading inserts"); - - /* Stop if we read a separator */ - if(strcmp(ptr, ID_INPUT_SEPARATOR) == 0) - break; - - /* keep track in case there are trailing blanks */ - if(length == 0) - { - if(first_blank == NULL) - first_blank = ptr; - } - else - first_blank = NULL; - - /* Advance and append newline */ - ptr += length; - strcpy(ptr++, "\n"); - } - - /* kill any trailing blank lines */ - if(first_blank) - ptr = first_blank; - *ptr++ = 0; -} - - - -/* ======================================================================== */ -/* ============================= MAIN FUNCTION ============================ */ -/* ======================================================================== */ - -int main(int argc, char **argv) -{ - /* File stuff */ - char output_path[M68K_MAX_DIR] = ""; - char filename[M68K_MAX_PATH*2]; - /* Section identifier */ - char section_id[MAX_LINE_LENGTH+1]; - /* Inserts */ - char temp_insert[MAX_INSERT_LENGTH+1]; - char prototype_footer_insert[MAX_INSERT_LENGTH+1]; - char table_header_insert[MAX_INSERT_LENGTH+1]; - char table_footer_insert[MAX_INSERT_LENGTH+1]; - char ophandler_header_insert[MAX_INSERT_LENGTH+1]; - char ophandler_footer_insert[MAX_INSERT_LENGTH+1]; - /* Flags if we've processed certain parts already */ - int prototype_header_read = 0; - int prototype_footer_read = 0; - int table_header_read = 0; - int table_footer_read = 0; - int ophandler_header_read = 0; - int ophandler_footer_read = 0; - int table_body_read = 0; - int ophandler_body_read = 0; - - printf("\n\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, 68040 emulator\n", g_version); - printf("\t\tCopyright Karl Stenerud (kstenerud@gmail.com)\n\n"); - - /* Check if output path and source for the input file are given */ - if(argc > 1) - { - char *ptr; - strcpy(output_path, argv[1]); - - for(ptr = strchr(output_path, '\\'); ptr; ptr = strchr(ptr, '\\')) - *ptr = '/'; - if(output_path[strlen(output_path)-1] != '/') - strcat(output_path, "/"); - if(argc > 2) - strcpy(g_input_filename, argv[2]); - } - - - /* Open the files we need */ - sprintf(filename, "%s%s", output_path, FILENAME_PROTOTYPE); - if((g_prototype_file = fopen(filename, "wt")) == NULL) - perror_exit("Unable to create prototype file (%s)\n", filename); - - sprintf(filename, "%s%s", output_path, FILENAME_TABLE); - if((g_table_file = fopen(filename, "wt")) == NULL) - perror_exit("Unable to create table file (%s)\n", filename); - - if((g_input_file=fopen(g_input_filename, "rt")) == NULL) - perror_exit("can't open %s for input", g_input_filename); - - - /* Get to the first section of the input file */ - section_id[0] = 0; - while(strcmp(section_id, ID_INPUT_SEPARATOR) != 0) - if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0) - error_exit("Premature EOF while reading input file"); - - /* Now process all sections */ - for(;;) - { - if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0) - error_exit("Premature EOF while reading input file"); - if(strcmp(section_id, ID_PROTOTYPE_HEADER) == 0) - { - if(prototype_header_read) - error_exit("Duplicate prototype header"); - read_insert(temp_insert); - fprintf(g_prototype_file, "%s\n\n", temp_insert); - prototype_header_read = 1; - } - else if(strcmp(section_id, ID_TABLE_HEADER) == 0) - { - if(table_header_read) - error_exit("Duplicate table header"); - read_insert(table_header_insert); - table_header_read = 1; - } - else if(strcmp(section_id, ID_OPHANDLER_HEADER) == 0) - { - if(ophandler_header_read) - error_exit("Duplicate opcode handler header"); - read_insert(ophandler_header_insert); - ophandler_header_read = 1; - } - else if(strcmp(section_id, ID_PROTOTYPE_FOOTER) == 0) - { - if(prototype_footer_read) - error_exit("Duplicate prototype footer"); - read_insert(prototype_footer_insert); - prototype_footer_read = 1; - } - else if(strcmp(section_id, ID_TABLE_FOOTER) == 0) - { - if(table_footer_read) - error_exit("Duplicate table footer"); - read_insert(table_footer_insert); - table_footer_read = 1; - } - else if(strcmp(section_id, ID_OPHANDLER_FOOTER) == 0) - { - if(ophandler_footer_read) - error_exit("Duplicate opcode handler footer"); - read_insert(ophandler_footer_insert); - ophandler_footer_read = 1; - } - else if(strcmp(section_id, ID_TABLE_BODY) == 0) - { - if(!prototype_header_read) - error_exit("Table body encountered before prototype header"); - if(!table_header_read) - error_exit("Table body encountered before table header"); - if(!ophandler_header_read) - error_exit("Table body encountered before opcode handler header"); - - if(table_body_read) - error_exit("Duplicate table body"); - - populate_table(); - table_body_read = 1; - } - else if(strcmp(section_id, ID_OPHANDLER_BODY) == 0) - { - if(!prototype_header_read) - error_exit("Opcode handlers encountered before prototype header"); - if(!table_header_read) - error_exit("Opcode handlers encountered before table header"); - if(!ophandler_header_read) - error_exit("Opcode handlers encountered before opcode handler header"); - if(!table_body_read) - error_exit("Opcode handlers encountered before table body"); - - if(ophandler_body_read) - error_exit("Duplicate opcode handler section"); - - fprintf(g_table_file, "%s\n\n", ophandler_header_insert); - process_opcode_handlers(g_table_file); - fprintf(g_table_file, "%s\n\n", ophandler_footer_insert); - - ophandler_body_read = 1; - } - else if(strcmp(section_id, ID_END) == 0) - { - /* End of input file. Do a sanity check and then write footers */ - if(!prototype_header_read) - error_exit("Missing prototype header"); - if(!prototype_footer_read) - error_exit("Missing prototype footer"); - if(!table_header_read) - error_exit("Missing table header"); - if(!table_footer_read) - error_exit("Missing table footer"); - if(!table_body_read) - error_exit("Missing table body"); - if(!ophandler_header_read) - error_exit("Missing opcode handler header"); - if(!ophandler_footer_read) - error_exit("Missing opcode handler footer"); - if(!ophandler_body_read) - error_exit("Missing opcode handler body"); - - fprintf(g_table_file, "%s\n\n", table_header_insert); - print_opcode_output_table(g_table_file); - fprintf(g_table_file, "%s\n\n", table_footer_insert); - - fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert); - - break; - } - else - { - error_exit("Unknown section identifier: %s", section_id); - } - } - - /* Close all files and exit */ - fclose(g_prototype_file); - fclose(g_table_file); - fclose(g_input_file); - - printf("Generated %d opcode handlers from %d primitives\n", g_num_functions, g_num_primitives); - - return 0; -} - - - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 4.60 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * FPU and MMU by R. Belmont. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + + +/* ======================================================================== */ +/* ============================ CODE GENERATOR ============================ */ +/* ======================================================================== */ +/* + * This is the code generator program which will generate the opcode table + * and the final opcode handlers. + * + * It requires an input file to function (default m68k_in.c), but you can + * specify your own like so: + * + * m68kmake + * + * where output path is the path where the output files should be placed, and + * input file is the file to use for input. + * + * If you modify the input file greatly from its released form, you may have + * to tweak the configuration section a bit since I'm using static allocation + * to keep things simple. + * + * + * TODO: - build a better code generator for the move instruction. + * - Add callm and rtm instructions + * - Fix RTE to handle other format words + * - Add address error (and bus error?) handling + */ + + +static const char g_version[] = "4.60"; + +/* ======================================================================== */ +/* =============================== INCLUDES =============================== */ +/* ======================================================================== */ + +#include +#include +#include +#include +#include + + + +/* ======================================================================== */ +/* ============================= CONFIGURATION ============================ */ +/* ======================================================================== */ + +#define M68K_MAX_PATH 1024 +#define M68K_MAX_DIR 1024 + +#define MAX_LINE_LENGTH 200 /* length of 1 line */ +#define MAX_BODY_LENGTH 300 /* Number of lines in 1 function */ +#define MAX_REPLACE_LENGTH 30 /* Max number of replace strings */ +#define MAX_INSERT_LENGTH 5000 /* Max size of insert piece */ +#define MAX_NAME_LENGTH 30 /* Max length of ophandler name */ +#define MAX_SPEC_PROC_LENGTH 4 /* Max length of special processing str */ +#define MAX_SPEC_EA_LENGTH 5 /* Max length of specified EA str */ +#define EA_ALLOWED_LENGTH 11 /* Max length of ea allowed str */ +#define MAX_OPCODE_INPUT_TABLE_LENGTH 1000 /* Max length of opcode handler tbl */ +#define MAX_OPCODE_OUTPUT_TABLE_LENGTH 3000 /* Max length of opcode handler tbl */ + +/* Default filenames */ +#define FILENAME_INPUT "m68k_in.c" +#define FILENAME_PROTOTYPE "m68kops.h" +#define FILENAME_TABLE "m68kops.c" + + +/* Identifier sequences recognized by this program */ + +#define ID_INPUT_SEPARATOR "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + +#define ID_BASE "M68KMAKE" +#define ID_PROTOTYPE_HEADER ID_BASE "_PROTOTYPE_HEADER" +#define ID_PROTOTYPE_FOOTER ID_BASE "_PROTOTYPE_FOOTER" +#define ID_TABLE_HEADER ID_BASE "_TABLE_HEADER" +#define ID_TABLE_FOOTER ID_BASE "_TABLE_FOOTER" +#define ID_TABLE_BODY ID_BASE "_TABLE_BODY" +#define ID_TABLE_START ID_BASE "_TABLE_START" +#define ID_OPHANDLER_HEADER ID_BASE "_OPCODE_HANDLER_HEADER" +#define ID_OPHANDLER_FOOTER ID_BASE "_OPCODE_HANDLER_FOOTER" +#define ID_OPHANDLER_BODY ID_BASE "_OPCODE_HANDLER_BODY" +#define ID_END ID_BASE "_END" + +#define ID_OPHANDLER_NAME ID_BASE "_OP" +#define ID_OPHANDLER_EA_AY_8 ID_BASE "_GET_EA_AY_8" +#define ID_OPHANDLER_EA_AY_16 ID_BASE "_GET_EA_AY_16" +#define ID_OPHANDLER_EA_AY_32 ID_BASE "_GET_EA_AY_32" +#define ID_OPHANDLER_OPER_AY_8 ID_BASE "_GET_OPER_AY_8" +#define ID_OPHANDLER_OPER_AY_16 ID_BASE "_GET_OPER_AY_16" +#define ID_OPHANDLER_OPER_AY_32 ID_BASE "_GET_OPER_AY_32" +#define ID_OPHANDLER_CC ID_BASE "_CC" +#define ID_OPHANDLER_NOT_CC ID_BASE "_NOT_CC" + + +#ifndef DECL_SPEC +#define DECL_SPEC +#endif /* DECL_SPEC */ + + + +/* ======================================================================== */ +/* ============================== PROTOTYPES ============================== */ +/* ======================================================================== */ + +enum { + CPU_TYPE_000=0, + CPU_TYPE_010, + CPU_TYPE_020, + CPU_TYPE_030, + CPU_TYPE_040, + NUM_CPUS +}; + +#define UNSPECIFIED "." +#define UNSPECIFIED_CH '.' + +#define HAS_NO_EA_MODE(A) (strcmp(A, "..........") == 0) +#define HAS_EA_AI(A) ((A)[0] == 'A') +#define HAS_EA_PI(A) ((A)[1] == '+') +#define HAS_EA_PD(A) ((A)[2] == '-') +#define HAS_EA_DI(A) ((A)[3] == 'D') +#define HAS_EA_IX(A) ((A)[4] == 'X') +#define HAS_EA_AW(A) ((A)[5] == 'W') +#define HAS_EA_AL(A) ((A)[6] == 'L') +#define HAS_EA_PCDI(A) ((A)[7] == 'd') +#define HAS_EA_PCIX(A) ((A)[8] == 'x') +#define HAS_EA_I(A) ((A)[9] == 'I') + +enum +{ + EA_MODE_NONE, /* No special addressing mode */ + EA_MODE_AI, /* Address register indirect */ + EA_MODE_PI, /* Address register indirect with postincrement */ + EA_MODE_PI7, /* Address register 7 indirect with postincrement */ + EA_MODE_PD, /* Address register indirect with predecrement */ + EA_MODE_PD7, /* Address register 7 indirect with predecrement */ + EA_MODE_DI, /* Address register indirect with displacement */ + EA_MODE_IX, /* Address register indirect with index */ + EA_MODE_AW, /* Absolute word */ + EA_MODE_AL, /* Absolute long */ + EA_MODE_PCDI, /* Program counter indirect with displacement */ + EA_MODE_PCIX, /* Program counter indirect with index */ + EA_MODE_I /* Immediate */ +}; + + +/* Everything we need to know about an opcode */ +typedef struct +{ + char name[MAX_NAME_LENGTH]; /* opcode handler name */ + unsigned char size; /* Size of operation */ + char spec_proc[MAX_SPEC_PROC_LENGTH]; /* Special processing mode */ + char spec_ea[MAX_SPEC_EA_LENGTH]; /* Specified effective addressing mode */ + unsigned char bits; /* Number of significant bits (used for sorting the table) */ + unsigned short op_mask; /* Mask to apply for matching an opcode to a handler */ + unsigned short op_match; /* Value to match after masking */ + char ea_allowed[EA_ALLOWED_LENGTH]; /* Effective addressing modes allowed */ + char cpu_mode[NUM_CPUS]; /* User or supervisor mode */ + char cpus[NUM_CPUS+1]; /* Allowed CPUs */ + unsigned char cycles[NUM_CPUS]; /* cycles for 000, 010, 020, 030, 040 */ +} opcode_struct; + + +/* All modifications necessary for a specific EA mode of an instruction */ +typedef struct +{ + char* fname_add; + char* ea_add; + unsigned int mask_add; + unsigned int match_add; +} ea_info_struct; + + +/* Holds the body of a function */ +typedef struct +{ + char body[MAX_BODY_LENGTH][MAX_LINE_LENGTH+1]; + int length; +} body_struct; + + +/* Holds a sequence of search / replace strings */ +typedef struct +{ + char replace[MAX_REPLACE_LENGTH][2][MAX_LINE_LENGTH+1]; + int length; +} replace_struct; + + +/* Function Prototypes */ +void error_exit(const char* fmt, ...); +void perror_exit(const char* fmt, ...); +int check_strsncpy(char* dst, char* src, int maxlength); +int check_atoi(char* str, int *result); +int skip_spaces(char* str); +int num_bits(int value); +int atoh(char* buff); +int fgetline(char* buff, int nchars, FILE* file); +int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type); +opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea); +opcode_struct* find_illegal_opcode(void); +int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea); +void add_replace_string(replace_struct* replace, char* search_str, char* replace_str); +void write_body(FILE* filep, body_struct* body, replace_struct* replace); +void get_base_name(char* base_name, opcode_struct* op); +void write_function_name(FILE* filep, char* base_name); +void add_opcode_output_table_entry(opcode_struct* op, char* name); +static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr); +void print_opcode_output_table(FILE* filep); +void write_table_entry(FILE* filep, opcode_struct* op); +void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode); +void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode); +void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op); +void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset); +void process_opcode_handlers(FILE* filep); +void populate_table(void); +void read_insert(char* insert); + + + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +/* Name of the input file */ +char g_input_filename[M68K_MAX_PATH] = FILENAME_INPUT; + +/* File handles */ +FILE* g_input_file = NULL; +FILE* g_prototype_file = NULL; +FILE* g_table_file = NULL; + +int g_num_functions = 0; /* Number of functions processed */ +int g_num_primitives = 0; /* Number of function primitives read */ +int g_line_number = 1; /* Current line number */ + +/* Opcode handler table */ +opcode_struct g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH]; + +opcode_struct g_opcode_output_table[MAX_OPCODE_OUTPUT_TABLE_LENGTH]; +int g_opcode_output_table_length = 0; + +const ea_info_struct g_ea_info_table[13] = +{/* fname ea mask match */ + {"", "", 0x00, 0x00}, /* EA_MODE_NONE */ + {"ai", "AY_AI", 0x38, 0x10}, /* EA_MODE_AI */ + {"pi", "AY_PI", 0x38, 0x18}, /* EA_MODE_PI */ + {"pi7", "A7_PI", 0x3f, 0x1f}, /* EA_MODE_PI7 */ + {"pd", "AY_PD", 0x38, 0x20}, /* EA_MODE_PD */ + {"pd7", "A7_PD", 0x3f, 0x27}, /* EA_MODE_PD7 */ + {"di", "AY_DI", 0x38, 0x28}, /* EA_MODE_DI */ + {"ix", "AY_IX", 0x38, 0x30}, /* EA_MODE_IX */ + {"aw", "AW", 0x3f, 0x38}, /* EA_MODE_AW */ + {"al", "AL", 0x3f, 0x39}, /* EA_MODE_AL */ + {"pcdi", "PCDI", 0x3f, 0x3a}, /* EA_MODE_PCDI */ + {"pcix", "PCIX", 0x3f, 0x3b}, /* EA_MODE_PCIX */ + {"i", "I", 0x3f, 0x3c}, /* EA_MODE_I */ +}; + + +const char *const g_cc_table[16][2] = +{ + { "t", "T"}, /* 0000 */ + { "f", "F"}, /* 0001 */ + {"hi", "HI"}, /* 0010 */ + {"ls", "LS"}, /* 0011 */ + {"cc", "CC"}, /* 0100 */ + {"cs", "CS"}, /* 0101 */ + {"ne", "NE"}, /* 0110 */ + {"eq", "EQ"}, /* 0111 */ + {"vc", "VC"}, /* 1000 */ + {"vs", "VS"}, /* 1001 */ + {"pl", "PL"}, /* 1010 */ + {"mi", "MI"}, /* 1011 */ + {"ge", "GE"}, /* 1100 */ + {"lt", "LT"}, /* 1101 */ + {"gt", "GT"}, /* 1110 */ + {"le", "LE"}, /* 1111 */ +}; + +/* size to index translator (0 -> 0, 8 and 16 -> 1, 32 -> 2) */ +const int g_size_select_table[33] = +{ + 0, /* unsized */ + 0, 0, 0, 0, 0, 0, 0, 1, /* 8 */ + 0, 0, 0, 0, 0, 0, 0, 1, /* 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 /* 32 */ +}; + +/* Extra cycles required for certain EA modes */ +/* TODO: correct timings for 030, 040 */ +const int g_ea_cycle_table[13][NUM_CPUS][3] = +{/* 000 010 020 030 040 */ + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AI */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI7 */ + {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD */ + {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD7 */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_DI */ + {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_IX */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AW */ + {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AL */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PCDI */ + {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_PCIX */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */ +}; + +/* Extra cycles for JMP instruction (000, 010) */ +const int g_jmp_cycle_table[13] = +{ + 0, /* EA_MODE_NONE */ + 4, /* EA_MODE_AI */ + 0, /* EA_MODE_PI */ + 0, /* EA_MODE_PI7 */ + 0, /* EA_MODE_PD */ + 0, /* EA_MODE_PD7 */ + 6, /* EA_MODE_DI */ + 10, /* EA_MODE_IX */ + 6, /* EA_MODE_AW */ + 8, /* EA_MODE_AL */ + 6, /* EA_MODE_PCDI */ + 10, /* EA_MODE_PCIX */ + 0, /* EA_MODE_I */ +}; + +/* Extra cycles for JSR instruction (000, 010) */ +const int g_jsr_cycle_table[13] = +{ + 0, /* EA_MODE_NONE */ + 4, /* EA_MODE_AI */ + 0, /* EA_MODE_PI */ + 0, /* EA_MODE_PI7 */ + 0, /* EA_MODE_PD */ + 0, /* EA_MODE_PD7 */ + 6, /* EA_MODE_DI */ + 10, /* EA_MODE_IX */ + 6, /* EA_MODE_AW */ + 8, /* EA_MODE_AL */ + 6, /* EA_MODE_PCDI */ + 10, /* EA_MODE_PCIX */ + 0, /* EA_MODE_I */ +}; + +/* Extra cycles for LEA instruction (000, 010) */ +const int g_lea_cycle_table[13] = +{ + 0, /* EA_MODE_NONE */ + 4, /* EA_MODE_AI */ + 0, /* EA_MODE_PI */ + 0, /* EA_MODE_PI7 */ + 0, /* EA_MODE_PD */ + 0, /* EA_MODE_PD7 */ + 8, /* EA_MODE_DI */ + 12, /* EA_MODE_IX */ + 8, /* EA_MODE_AW */ + 12, /* EA_MODE_AL */ + 8, /* EA_MODE_PCDI */ + 12, /* EA_MODE_PCIX */ + 0, /* EA_MODE_I */ +}; + +/* Extra cycles for PEA instruction (000, 010) */ +const int g_pea_cycle_table[13] = +{ + 0, /* EA_MODE_NONE */ + 6, /* EA_MODE_AI */ + 0, /* EA_MODE_PI */ + 0, /* EA_MODE_PI7 */ + 0, /* EA_MODE_PD */ + 0, /* EA_MODE_PD7 */ + 10, /* EA_MODE_DI */ + 14, /* EA_MODE_IX */ + 10, /* EA_MODE_AW */ + 14, /* EA_MODE_AL */ + 10, /* EA_MODE_PCDI */ + 14, /* EA_MODE_PCIX */ + 0, /* EA_MODE_I */ +}; + +/* Extra cycles for MOVEM instruction (000, 010) */ +const int g_movem_cycle_table[13] = +{ + 0, /* EA_MODE_NONE */ + 0, /* EA_MODE_AI */ + 0, /* EA_MODE_PI */ + 0, /* EA_MODE_PI7 */ + 0, /* EA_MODE_PD */ + 0, /* EA_MODE_PD7 */ + 4, /* EA_MODE_DI */ + 6, /* EA_MODE_IX */ + 4, /* EA_MODE_AW */ + 8, /* EA_MODE_AL */ + 0, /* EA_MODE_PCDI */ + 0, /* EA_MODE_PCIX */ + 0, /* EA_MODE_I */ +}; + +/* Extra cycles for MOVES instruction (010) */ +const int g_moves_cycle_table[13][3] = +{ + { 0, 0, 0}, /* EA_MODE_NONE */ + { 0, 4, 6}, /* EA_MODE_AI */ + { 0, 4, 6}, /* EA_MODE_PI */ + { 0, 4, 6}, /* EA_MODE_PI7 */ + { 0, 6, 12}, /* EA_MODE_PD */ + { 0, 6, 12}, /* EA_MODE_PD7 */ + { 0, 12, 16}, /* EA_MODE_DI */ + { 0, 16, 20}, /* EA_MODE_IX */ + { 0, 12, 16}, /* EA_MODE_AW */ + { 0, 16, 20}, /* EA_MODE_AL */ + { 0, 0, 0}, /* EA_MODE_PCDI */ + { 0, 0, 0}, /* EA_MODE_PCIX */ + { 0, 0, 0}, /* EA_MODE_I */ +}; + +/* Extra cycles for CLR instruction (010) */ +const int g_clr_cycle_table[13][3] = +{ + { 0, 0, 0}, /* EA_MODE_NONE */ + { 0, 4, 6}, /* EA_MODE_AI */ + { 0, 4, 6}, /* EA_MODE_PI */ + { 0, 4, 6}, /* EA_MODE_PI7 */ + { 0, 6, 8}, /* EA_MODE_PD */ + { 0, 6, 8}, /* EA_MODE_PD7 */ + { 0, 8, 10}, /* EA_MODE_DI */ + { 0, 10, 14}, /* EA_MODE_IX */ + { 0, 8, 10}, /* EA_MODE_AW */ + { 0, 10, 14}, /* EA_MODE_AL */ + { 0, 0, 0}, /* EA_MODE_PCDI */ + { 0, 0, 0}, /* EA_MODE_PCIX */ + { 0, 0, 0}, /* EA_MODE_I */ +}; + + + +/* ======================================================================== */ +/* =========================== UTILITY FUNCTIONS ========================== */ +/* ======================================================================== */ + +/* Print an error message and exit with status error */ +void error_exit(const char* fmt, ...) +{ + va_list args; + fprintf(stderr, "In %s, near or on line %d:\n\t", g_input_filename, g_line_number); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + + if(g_prototype_file) fclose(g_prototype_file); + if(g_table_file) fclose(g_table_file); + if(g_input_file) fclose(g_input_file); + + exit(EXIT_FAILURE); +} + +/* Print an error message, call perror(), and exit with status error */ +void perror_exit(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + perror(""); + + if(g_prototype_file) fclose(g_prototype_file); + if(g_table_file) fclose(g_table_file); + if(g_input_file) fclose(g_input_file); + + exit(EXIT_FAILURE); +} + + +/* copy until 0 or space and exit with error if we read too far */ +int check_strsncpy(char* dst, char* src, int maxlength) +{ + char* p = dst; + while(*src && *src != ' ') + { + *p++ = *src++; + if(p - dst > maxlength) + error_exit("Field too long"); + } + *p = 0; + return p - dst; +} + +/* copy until 0 or specified character and exit with error if we read too far */ +int check_strcncpy(char* dst, char* src, char delim, int maxlength) +{ + char* p = dst; + while(*src && *src != delim) + { + *p++ = *src++; + if(p - dst > maxlength) + error_exit("Field too long"); + } + *p = 0; + return p - dst; +} + +/* convert ascii to integer and exit with error if we find invalid data */ +int check_atoi(char* str, int *result) +{ + int accum = 0; + char* p = str; + while(*p >= '0' && *p <= '9') + { + accum *= 10; + accum += *p++ - '0'; + } + if(*p != ' ' && *p != 0) + error_exit("Malformed integer value (%c)", *p); + *result = accum; + return p - str; +} + +/* Skip past spaces in a string */ +int skip_spaces(char* str) +{ + char* p = str; + + while(*p == ' ') + p++; + + return p - str; +} + +/* Count the number of set bits in a value */ +int num_bits(int value) +{ + value = ((value & 0xaaaa) >> 1) + (value & 0x5555); + value = ((value & 0xcccc) >> 2) + (value & 0x3333); + value = ((value & 0xf0f0) >> 4) + (value & 0x0f0f); + value = ((value & 0xff00) >> 8) + (value & 0x00ff); + return value; +} + +/* Convert a hex value written in ASCII */ +int atoh(char* buff) +{ + int accum = 0; + + for(;;buff++) + { + if(*buff >= '0' && *buff <= '9') + { + accum <<= 4; + accum += *buff - '0'; + } + else if(*buff >= 'a' && *buff <= 'f') + { + accum <<= 4; + accum += *buff - 'a' + 10; + } + else break; + } + return accum; +} + +/* Get a line of text from a file, discarding any end-of-line characters */ +int fgetline(char* buff, int nchars, FILE* file) +{ + int length; + + if(fgets(buff, nchars, file) == NULL) + return -1; + if(buff[0] == '\r') + memmove(buff, buff + 1, nchars - 1); + + length = strlen(buff); + while(length && (buff[length-1] == '\r' || buff[length-1] == '\n')) + length--; + buff[length] = 0; + g_line_number++; + + return length; +} + + + +/* ======================================================================== */ +/* =========================== HELPER FUNCTIONS =========================== */ +/* ======================================================================== */ + +/* Calculate the number of cycles an opcode requires */ +int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type) +{ + int size = g_size_select_table[op->size]; + + if(op->cpus[cpu_type] == '.') + return 0; + + if(cpu_type < CPU_TYPE_020) + { + if(cpu_type == CPU_TYPE_010) + { + if(strcmp(op->name, "moves") == 0) + return op->cycles[cpu_type] + g_moves_cycle_table[ea_mode][size]; + if(strcmp(op->name, "clr") == 0) + return op->cycles[cpu_type] + g_clr_cycle_table[ea_mode][size]; + } + + /* ASG: added these cases -- immediate modes take 2 extra cycles here */ + if(cpu_type == CPU_TYPE_000 && ea_mode == EA_MODE_I && + ((strcmp(op->name, "add") == 0 && strcmp(op->spec_proc, "er") == 0) || + strcmp(op->name, "adda") == 0 || + (strcmp(op->name, "and") == 0 && strcmp(op->spec_proc, "er") == 0) || + (strcmp(op->name, "or") == 0 && strcmp(op->spec_proc, "er") == 0) || + (strcmp(op->name, "sub") == 0 && strcmp(op->spec_proc, "er") == 0) || + strcmp(op->name, "suba") == 0)) + return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size] + 2; + + if(strcmp(op->name, "jmp") == 0) + return op->cycles[cpu_type] + g_jmp_cycle_table[ea_mode]; + if(strcmp(op->name, "jsr") == 0) + return op->cycles[cpu_type] + g_jsr_cycle_table[ea_mode]; + if(strcmp(op->name, "lea") == 0) + return op->cycles[cpu_type] + g_lea_cycle_table[ea_mode]; + if(strcmp(op->name, "pea") == 0) + return op->cycles[cpu_type] + g_pea_cycle_table[ea_mode]; + if(strcmp(op->name, "movem") == 0) + return op->cycles[cpu_type] + g_movem_cycle_table[ea_mode]; + } + return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size]; +} + +/* Find an opcode in the opcode handler list */ +opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea) +{ + opcode_struct* op; + + + for(op = g_opcode_input_table;op < &g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];op++) + { + if( strcmp(name, op->name) == 0 && + (size == op->size) && + strcmp(spec_proc, op->spec_proc) == 0 && + strcmp(spec_ea, op->spec_ea) == 0) + return op; + } + return NULL; +} + +/* Specifically find the illegal opcode in the list */ +opcode_struct* find_illegal_opcode(void) +{ + opcode_struct* op; + + for(op = g_opcode_input_table;op < &g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];op++) + { + if(strcmp(op->name, "illegal") == 0) + return op; + } + return NULL; +} + +/* Parse an opcode handler name */ +int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea) +{ + char* ptr = strstr(src, ID_OPHANDLER_NAME); + + if(ptr == NULL) + return 0; + + ptr += strlen(ID_OPHANDLER_NAME) + 1; + + ptr += check_strcncpy(name, ptr, ',', MAX_NAME_LENGTH); + if(*ptr != ',') return 0; + ptr++; + ptr += skip_spaces(ptr); + + *size = atoi(ptr); + ptr = strstr(ptr, ","); + if(ptr == NULL) return 0; + ptr++; + ptr += skip_spaces(ptr); + + ptr += check_strcncpy(spec_proc, ptr, ',', MAX_SPEC_PROC_LENGTH); + if(*ptr != ',') return 0; + ptr++; + ptr += skip_spaces(ptr); + + ptr += check_strcncpy(spec_ea, ptr, ')', MAX_SPEC_EA_LENGTH); + if(*ptr != ')') return 0; + ptr++; + ptr += skip_spaces(ptr); + + return 1; +} + + +/* Add a search/replace pair to a replace structure */ +void add_replace_string(replace_struct* replace, char* search_str, char* replace_str) +{ + if(replace->length >= MAX_REPLACE_LENGTH) + error_exit("overflow in replace structure"); + + strcpy(replace->replace[replace->length][0], search_str); + strcpy(replace->replace[replace->length++][1], replace_str); +} + +/* Write a function body while replacing any selected strings */ +void write_body(FILE* filep, body_struct* body, replace_struct* replace) +{ + int i; + int j; + char* ptr; + char output[MAX_LINE_LENGTH+1]; + char temp_buff[MAX_LINE_LENGTH+1]; + int found; + + for(i=0;ilength;i++) + { + strcpy(output, body->body[i]); + /* Check for the base directive header */ + if(strstr(output, ID_BASE) != NULL) + { + /* Search for any text we need to replace */ + found = 0; + for(j=0;jlength;j++) + { + ptr = strstr(output, replace->replace[j][0]); + if(ptr) + { + /* We found something to replace */ + found = 1; + strcpy(temp_buff, ptr+strlen(replace->replace[j][0])); + strcpy(ptr, replace->replace[j][1]); + strcat(ptr, temp_buff); + } + } + /* Found a directive with no matching replace string */ + if(!found) + error_exit("Unknown " ID_BASE " directive [%s]", output); + } + fprintf(filep, "%s\n", output); + } + fprintf(filep, "\n\n"); +} + +/* Generate a base function name from an opcode struct */ +void get_base_name(char* base_name, opcode_struct* op) +{ + sprintf(base_name, "m68k_op_%s", op->name); + if(op->size > 0) + sprintf(base_name+strlen(base_name), "_%d", op->size); + if(strcmp(op->spec_proc, UNSPECIFIED) != 0) + sprintf(base_name+strlen(base_name), "_%s", op->spec_proc); + if(strcmp(op->spec_ea, UNSPECIFIED) != 0) + sprintf(base_name+strlen(base_name), "_%s", op->spec_ea); +} + +/* Write the name of an opcode handler function */ +void write_function_name(FILE* filep, char* base_name) +{ + fprintf(filep, "static void %s(void)\n", base_name); +} + +void add_opcode_output_table_entry(opcode_struct* op, char* name) +{ + opcode_struct* ptr; + if(g_opcode_output_table_length > MAX_OPCODE_OUTPUT_TABLE_LENGTH) + error_exit("Opcode output table overflow"); + + ptr = g_opcode_output_table + g_opcode_output_table_length++; + + *ptr = *op; + strcpy(ptr->name, name); + ptr->bits = num_bits(ptr->op_mask); +} + +/* + * Comparison function for qsort() + * For entries with an equal number of set bits in + * the mask compare the match values + */ +static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr) +{ + const opcode_struct *a = aptr, *b = bptr; + if(a->bits != b->bits) + return a->bits - b->bits; + if(a->op_mask != b->op_mask) + return a->op_mask - b->op_mask; + return a->op_match - b->op_match; +} + +void print_opcode_output_table(FILE* filep) +{ + int i; + qsort((void *)g_opcode_output_table, g_opcode_output_table_length, sizeof(g_opcode_output_table[0]), compare_nof_true_bits); + + for(i=0;iname, op->op_mask, op->op_match); + + for(i=0;icycles[i]); + if(i < NUM_CPUS-1) + fprintf(filep, ", "); + } + + fprintf(filep, "}},\n"); +} + +/* Fill out an opcode struct with a specific addressing mode of the source opcode struct */ +void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode) +{ + int i; + + *dst = *src; + + for(i=0;icycles[i] = get_oper_cycles(dst, ea_mode, i); + if(strcmp(dst->spec_ea, UNSPECIFIED) == 0 && ea_mode != EA_MODE_NONE) + sprintf(dst->spec_ea, "%s", g_ea_info_table[ea_mode].fname_add); + dst->op_mask |= g_ea_info_table[ea_mode].mask_add; + dst->op_match |= g_ea_info_table[ea_mode].match_add; +} + + +/* Generate a final opcode handler from the provided data */ +void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode) +{ + char str[MAX_LINE_LENGTH+1]; + opcode_struct* op = malloc(sizeof(opcode_struct)); + + /* Set the opcode structure and write the tables, prototypes, etc */ + set_opcode_struct(opinfo, op, ea_mode); + get_base_name(str, op); + add_opcode_output_table_entry(op, str); + write_function_name(filep, str); + + /* Add any replace strings needed */ + if(ea_mode != EA_MODE_NONE) + { + sprintf(str, "EA_%s_8()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_EA_AY_8, str); + sprintf(str, "EA_%s_16()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_EA_AY_16, str); + sprintf(str, "EA_%s_32()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_EA_AY_32, str); + sprintf(str, "OPER_%s_8()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_OPER_AY_8, str); + sprintf(str, "OPER_%s_16()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_OPER_AY_16, str); + sprintf(str, "OPER_%s_32()", g_ea_info_table[ea_mode].ea_add); + add_replace_string(replace, ID_OPHANDLER_OPER_AY_32, str); + } + + /* Now write the function body with the selected replace strings */ + write_body(filep, body, replace); + g_num_functions++; + free(op); +} + +/* Generate opcode variants based on available addressing modes */ +void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op) +{ + int old_length = replace->length; + + /* No ea modes available for this opcode */ + if(HAS_NO_EA_MODE(op->ea_allowed)) + { + generate_opcode_handler(filep, body, replace, op, EA_MODE_NONE); + return; + } + + /* Check for and create specific opcodes for each available addressing mode */ + if(HAS_EA_AI(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_AI); + replace->length = old_length; + if(HAS_EA_PI(op->ea_allowed)) + { + generate_opcode_handler(filep, body, replace, op, EA_MODE_PI); + replace->length = old_length; + if(op->size == 8) + generate_opcode_handler(filep, body, replace, op, EA_MODE_PI7); + } + replace->length = old_length; + if(HAS_EA_PD(op->ea_allowed)) + { + generate_opcode_handler(filep, body, replace, op, EA_MODE_PD); + replace->length = old_length; + if(op->size == 8) + generate_opcode_handler(filep, body, replace, op, EA_MODE_PD7); + } + replace->length = old_length; + if(HAS_EA_DI(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_DI); + replace->length = old_length; + if(HAS_EA_IX(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_IX); + replace->length = old_length; + if(HAS_EA_AW(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_AW); + replace->length = old_length; + if(HAS_EA_AL(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_AL); + replace->length = old_length; + if(HAS_EA_PCDI(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_PCDI); + replace->length = old_length; + if(HAS_EA_PCIX(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_PCIX); + replace->length = old_length; + if(HAS_EA_I(op->ea_allowed)) + generate_opcode_handler(filep, body, replace, op, EA_MODE_I); + replace->length = old_length; +} + +/* Generate variants of condition code opcodes */ +void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset) +{ + char repl[20]; + char replnot[20]; + int i; + int old_length = replace->length; + opcode_struct* op = malloc(sizeof(opcode_struct)); + + *op = *op_in; + + op->op_mask |= 0x0f00; + + /* Do all condition codes except t and f */ + for(i=2;i<16;i++) + { + /* Add replace strings for this condition code */ + sprintf(repl, "COND_%s()", g_cc_table[i][1]); + sprintf(replnot, "COND_NOT_%s()", g_cc_table[i][1]); + + add_replace_string(replace, ID_OPHANDLER_CC, repl); + add_replace_string(replace, ID_OPHANDLER_NOT_CC, replnot); + + /* Set the new opcode info */ + strcpy(op->name+offset, g_cc_table[i][0]); + + op->op_match = (op->op_match & 0xf0ff) | (i<<8); + + /* Generate all opcode variants for this modified opcode */ + generate_opcode_ea_variants(filep, body, replace, op); + /* Remove the above replace strings */ + replace->length = old_length; + } + free(op); +} + +/* Process the opcode handlers section of the input file */ +void process_opcode_handlers(FILE* filep) +{ + FILE* input_file = g_input_file; + char func_name[MAX_LINE_LENGTH+1]; + char oper_name[MAX_LINE_LENGTH+1]; + int oper_size; + char oper_spec_proc[MAX_LINE_LENGTH+1]; + char oper_spec_ea[MAX_LINE_LENGTH+1]; + opcode_struct* opinfo; + replace_struct* replace = malloc(sizeof(replace_struct)); + body_struct* body = malloc(sizeof(body_struct)); + + for(;;) + { + /* Find the first line of the function */ + func_name[0] = 0; + while(strstr(func_name, ID_OPHANDLER_NAME) == NULL) + { + if(strcmp(func_name, ID_INPUT_SEPARATOR) == 0) + { + free(replace); + free(body); + return; /* all done */ + } + if(fgetline(func_name, MAX_LINE_LENGTH, input_file) < 0) + error_exit("Premature end of file when getting function name"); + } + /* Get the rest of the function */ + for(body->length=0;;body->length++) + { + if(body->length > MAX_BODY_LENGTH) + error_exit("Function too long"); + + if(fgetline(body->body[body->length], MAX_LINE_LENGTH, input_file) < 0) + error_exit("Premature end of file when getting function body"); + + if(body->body[body->length][0] == '}') + { + body->length++; + break; + } + } + + g_num_primitives++; + + /* Extract the function name information */ + if(!extract_opcode_info(func_name, oper_name, &oper_size, oper_spec_proc, oper_spec_ea)) + error_exit("Invalid " ID_OPHANDLER_NAME " format"); + + /* Find the corresponding table entry */ + opinfo = find_opcode(oper_name, oper_size, oper_spec_proc, oper_spec_ea); + if(opinfo == NULL) + error_exit("Unable to find matching table entry for %s", func_name); + + replace->length = 0; + + /* Generate opcode variants */ + if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0) + generate_opcode_cc_variants(filep, body, replace, opinfo, 1); + else if(strcmp(opinfo->name, "dbcc") == 0) + generate_opcode_cc_variants(filep, body, replace, opinfo, 2); + else if(strcmp(opinfo->name, "trapcc") == 0) + generate_opcode_cc_variants(filep, body, replace, opinfo, 4); + else + generate_opcode_ea_variants(filep, body, replace, opinfo); + } + + free(replace); + free(body); +} + + +/* Populate the opcode handler table from the input file */ +void populate_table(void) +{ + char* ptr; + char bitpattern[17]; + opcode_struct* op; + char buff[MAX_LINE_LENGTH]; + int i; + int temp; + + buff[0] = 0; + + /* Find the start of the table */ + while(strcmp(buff, ID_TABLE_START) != 0) + if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) + error_exit("(table_start) Premature EOF while reading table"); + + /* Process the entire table */ + for(op = g_opcode_input_table;;op++) + { + if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0) + error_exit("(inline) Premature EOF while reading table"); + if(strlen(buff) == 0) + continue; + /* We finish when we find an input separator */ + if(strcmp(buff, ID_INPUT_SEPARATOR) == 0) + break; + + /* Extract the info from the table */ + ptr = buff; + + /* Name */ + ptr += skip_spaces(ptr); + ptr += check_strsncpy(op->name, ptr, MAX_NAME_LENGTH); + + /* Size */ + ptr += skip_spaces(ptr); + ptr += check_atoi(ptr, &temp); + op->size = (unsigned char)temp; + + /* Special processing */ + ptr += skip_spaces(ptr); + ptr += check_strsncpy(op->spec_proc, ptr, MAX_SPEC_PROC_LENGTH); + + /* Specified EA Mode */ + ptr += skip_spaces(ptr); + ptr += check_strsncpy(op->spec_ea, ptr, MAX_SPEC_EA_LENGTH); + + /* Bit Pattern (more processing later) */ + ptr += skip_spaces(ptr); + ptr += check_strsncpy(bitpattern, ptr, 17); + + /* Allowed Addressing Mode List */ + ptr += skip_spaces(ptr); + ptr += check_strsncpy(op->ea_allowed, ptr, EA_ALLOWED_LENGTH); + + /* CPU operating mode (U = user or supervisor, S = supervisor only */ + ptr += skip_spaces(ptr); + for(i=0;icpu_mode[i] = *ptr++; + ptr += skip_spaces(ptr); + } + + /* Allowed CPUs for this instruction */ + for(i=0;icpus[i] = UNSPECIFIED_CH; + op->cycles[i] = 0; + ptr++; + } + else + { + op->cpus[i] = '0' + i; + ptr += check_atoi(ptr, &temp); + op->cycles[i] = (unsigned char)temp; + } + } + + /* generate mask and match from bitpattern */ + op->op_mask = 0; + op->op_match = 0; + for(i=0;i<16;i++) + { + op->op_mask |= (bitpattern[i] != '.') << (15-i); + op->op_match |= (bitpattern[i] == '1') << (15-i); + } + } + /* Terminate the list */ + op->name[0] = 0; +} + +/* Read a header or footer insert from the input file */ +void read_insert(char* insert) +{ + char* ptr = insert; + char* overflow = insert + MAX_INSERT_LENGTH - MAX_LINE_LENGTH; + int length; + char* first_blank = NULL; + + first_blank = NULL; + + /* Skip any leading blank lines */ + for(length = 0;length == 0;length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file)) + if(ptr >= overflow) + error_exit("Buffer overflow reading inserts"); + if(length < 0) + error_exit("Premature EOF while reading inserts"); + + /* Advance and append newline */ + ptr += length; + strcpy(ptr++, "\n"); + + /* Read until next separator */ + for(;;) + { + /* Read a new line */ + if(ptr >= overflow) + error_exit("Buffer overflow reading inserts"); + if((length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file)) < 0) + error_exit("Premature EOF while reading inserts"); + + /* Stop if we read a separator */ + if(strcmp(ptr, ID_INPUT_SEPARATOR) == 0) + break; + + /* keep track in case there are trailing blanks */ + if(length == 0) + { + if(first_blank == NULL) + first_blank = ptr; + } + else + first_blank = NULL; + + /* Advance and append newline */ + ptr += length; + strcpy(ptr++, "\n"); + } + + /* kill any trailing blank lines */ + if(first_blank) + ptr = first_blank; + *ptr++ = 0; +} + + + +/* ======================================================================== */ +/* ============================= MAIN FUNCTION ============================ */ +/* ======================================================================== */ + +int main(int argc, char **argv) +{ + /* File stuff */ + char output_path[M68K_MAX_DIR] = ""; + char filename[M68K_MAX_PATH*2]; + /* Section identifier */ + char section_id[MAX_LINE_LENGTH+1]; + /* Inserts */ + char temp_insert[MAX_INSERT_LENGTH+1]; + char prototype_footer_insert[MAX_INSERT_LENGTH+1]; + char table_header_insert[MAX_INSERT_LENGTH+1]; + char table_footer_insert[MAX_INSERT_LENGTH+1]; + char ophandler_header_insert[MAX_INSERT_LENGTH+1]; + char ophandler_footer_insert[MAX_INSERT_LENGTH+1]; + /* Flags if we've processed certain parts already */ + int prototype_header_read = 0; + int prototype_footer_read = 0; + int table_header_read = 0; + int table_footer_read = 0; + int ophandler_header_read = 0; + int ophandler_footer_read = 0; + int table_body_read = 0; + int ophandler_body_read = 0; + + printf("\n\tMusashi v%s 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, 68040 emulator\n", g_version); + printf("\t\tCopyright Karl Stenerud (kstenerud@gmail.com)\n\n"); + + /* Check if output path and source for the input file are given */ + if(argc > 1) + { + char *ptr; + strcpy(output_path, argv[1]); + + for(ptr = strchr(output_path, '\\'); ptr; ptr = strchr(ptr, '\\')) + *ptr = '/'; + if(output_path[strlen(output_path)-1] != '/') + strcat(output_path, "/"); + if(argc > 2) + strcpy(g_input_filename, argv[2]); + } + + + /* Open the files we need */ + sprintf(filename, "%s%s", output_path, FILENAME_PROTOTYPE); + if((g_prototype_file = fopen(filename, "wt")) == NULL) + perror_exit("Unable to create prototype file (%s)\n", filename); + + sprintf(filename, "%s%s", output_path, FILENAME_TABLE); + if((g_table_file = fopen(filename, "wt")) == NULL) + perror_exit("Unable to create table file (%s)\n", filename); + + if((g_input_file=fopen(g_input_filename, "rt")) == NULL) + perror_exit("can't open %s for input", g_input_filename); + + + /* Get to the first section of the input file */ + section_id[0] = 0; + while(strcmp(section_id, ID_INPUT_SEPARATOR) != 0) + if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0) + error_exit("Premature EOF while reading input file"); + + /* Now process all sections */ + for(;;) + { + if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0) + error_exit("Premature EOF while reading input file"); + if(strcmp(section_id, ID_PROTOTYPE_HEADER) == 0) + { + if(prototype_header_read) + error_exit("Duplicate prototype header"); + read_insert(temp_insert); + fprintf(g_prototype_file, "%s\n\n", temp_insert); + prototype_header_read = 1; + } + else if(strcmp(section_id, ID_TABLE_HEADER) == 0) + { + if(table_header_read) + error_exit("Duplicate table header"); + read_insert(table_header_insert); + table_header_read = 1; + } + else if(strcmp(section_id, ID_OPHANDLER_HEADER) == 0) + { + if(ophandler_header_read) + error_exit("Duplicate opcode handler header"); + read_insert(ophandler_header_insert); + ophandler_header_read = 1; + } + else if(strcmp(section_id, ID_PROTOTYPE_FOOTER) == 0) + { + if(prototype_footer_read) + error_exit("Duplicate prototype footer"); + read_insert(prototype_footer_insert); + prototype_footer_read = 1; + } + else if(strcmp(section_id, ID_TABLE_FOOTER) == 0) + { + if(table_footer_read) + error_exit("Duplicate table footer"); + read_insert(table_footer_insert); + table_footer_read = 1; + } + else if(strcmp(section_id, ID_OPHANDLER_FOOTER) == 0) + { + if(ophandler_footer_read) + error_exit("Duplicate opcode handler footer"); + read_insert(ophandler_footer_insert); + ophandler_footer_read = 1; + } + else if(strcmp(section_id, ID_TABLE_BODY) == 0) + { + if(!prototype_header_read) + error_exit("Table body encountered before prototype header"); + if(!table_header_read) + error_exit("Table body encountered before table header"); + if(!ophandler_header_read) + error_exit("Table body encountered before opcode handler header"); + + if(table_body_read) + error_exit("Duplicate table body"); + + populate_table(); + table_body_read = 1; + } + else if(strcmp(section_id, ID_OPHANDLER_BODY) == 0) + { + if(!prototype_header_read) + error_exit("Opcode handlers encountered before prototype header"); + if(!table_header_read) + error_exit("Opcode handlers encountered before table header"); + if(!ophandler_header_read) + error_exit("Opcode handlers encountered before opcode handler header"); + if(!table_body_read) + error_exit("Opcode handlers encountered before table body"); + + if(ophandler_body_read) + error_exit("Duplicate opcode handler section"); + + fprintf(g_table_file, "%s\n\n", ophandler_header_insert); + process_opcode_handlers(g_table_file); + fprintf(g_table_file, "%s\n\n", ophandler_footer_insert); + + ophandler_body_read = 1; + } + else if(strcmp(section_id, ID_END) == 0) + { + /* End of input file. Do a sanity check and then write footers */ + if(!prototype_header_read) + error_exit("Missing prototype header"); + if(!prototype_footer_read) + error_exit("Missing prototype footer"); + if(!table_header_read) + error_exit("Missing table header"); + if(!table_footer_read) + error_exit("Missing table footer"); + if(!table_body_read) + error_exit("Missing table body"); + if(!ophandler_header_read) + error_exit("Missing opcode handler header"); + if(!ophandler_footer_read) + error_exit("Missing opcode handler footer"); + if(!ophandler_body_read) + error_exit("Missing opcode handler body"); + + fprintf(g_table_file, "%s\n\n", table_header_insert); + print_opcode_output_table(g_table_file); + fprintf(g_table_file, "%s\n\n", table_footer_insert); + + fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert); + + break; + } + else + { + error_exit("Unknown section identifier: %s", section_id); + } + } + + /* Close all files and exit */ + fclose(g_prototype_file); + fclose(g_table_file); + fclose(g_input_file); + + printf("Generated %d opcode handlers from %d primitives\n", g_num_functions, g_num_primitives); + + return 0; +} + + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ diff --git a/AltairZ80/m68k/m68kmmu.h b/AltairZ80/m68k/m68kmmu.h index b6d90986..164e9a94 100644 --- a/AltairZ80/m68k/m68kmmu.h +++ b/AltairZ80/m68k/m68kmmu.h @@ -1,321 +1,321 @@ -/* - m68kmmu.h - PMMU implementation for 68851/68030/68040 - - By R. Belmont - - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. -*/ - -/* - pmmu_translate_addr: perform 68851/68030-style PMMU address translation -*/ -uint pmmu_translate_addr(uint addr_in) -{ - uint32 addr_out, tbl_entry = 0, tbl_entry2, tamode = 0, tbmode = 0, tcmode = 0; - uint root_aptr, root_limit, tofs, is, abits, bbits, cbits; - uint resolved, tptr, shift; - - resolved = 0; - addr_out = addr_in; - - // if SRP is enabled and we're in supervisor mode, use it - if ((m68ki_cpu.mmu_tc & 0x02000000) && (m68ki_get_sr() & 0x2000)) - { - root_aptr = m68ki_cpu.mmu_srp_aptr; - root_limit = m68ki_cpu.mmu_srp_limit; - } - else // else use the CRP - { - root_aptr = m68ki_cpu.mmu_crp_aptr; - root_limit = m68ki_cpu.mmu_crp_limit; - } - - // get initial shift (# of top bits to ignore) - is = (m68ki_cpu.mmu_tc>>16) & 0xf; - abits = (m68ki_cpu.mmu_tc>>12)&0xf; - bbits = (m68ki_cpu.mmu_tc>>8)&0xf; - cbits = (m68ki_cpu.mmu_tc>>4)&0xf; - -// fprintf(stderr,"PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68ki_cpu.mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits); - - // get table A offset - tofs = (addr_in<>(32-abits); - - // find out what format table A is - switch (root_limit & 3) - { - case 0: // invalid, should cause MMU exception - case 1: // page descriptor, should cause direct mapping - fatalerror("680x0 PMMU: Unhandled root mode\n"); - break; - - case 2: // valid 4 byte descriptors - tofs *= 4; -// fprintf(stderr,"PMMU: reading table A entry at %08x\n", tofs + (root_aptr & 0xfffffffc)); - tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); - tamode = tbl_entry & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs); - break; - - case 3: // valid 8 byte descriptors - tofs *= 8; -// fprintf(stderr,"PMMU: reading table A entries at %08x\n", tofs + (root_aptr & 0xfffffffc)); - tbl_entry2 = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); - tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)+4); - tamode = tbl_entry2 & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); - break; - } - - // get table B offset and pointer - tofs = (addr_in<<(is+abits))>>(32-bbits); - tptr = tbl_entry & 0xfffffff0; - - // find out what format table B is, if any - switch (tamode) - { - case 0: // invalid, should cause MMU exception - fatalerror("680x0 PMMU: Unhandled Table A mode %d (addr_in %08x)\n", tamode, addr_in); - break; - - case 2: // 4-byte table B descriptor - tofs *= 4; -// fprintf(stderr,"PMMU: reading table B entry at %08x\n", tofs + tptr); - tbl_entry = m68k_read_memory_32( tofs + tptr); - tbmode = tbl_entry & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); - break; - - case 3: // 8-byte table B descriptor - tofs *= 8; -// fprintf(stderr,"PMMU: reading table B entries at %08x\n", tofs + tptr); - tbl_entry2 = m68k_read_memory_32( tofs + tptr); - tbl_entry = m68k_read_memory_32( tofs + tptr + 4); - tbmode = tbl_entry2 & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); - break; - - case 1: // early termination descriptor - tbl_entry &= 0xffffff00; - - shift = is+abits; - addr_out = ((addr_in<>shift) + tbl_entry; - resolved = 1; - break; - } - - // if table A wasn't early-out, continue to process table B - if (!resolved) - { - // get table C offset and pointer - tofs = (addr_in<<(is+abits+bbits))>>(32-cbits); - tptr = tbl_entry & 0xfffffff0; - - switch (tbmode) - { - case 0: // invalid, should cause MMU exception - fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); - break; - - case 2: // 4-byte table C descriptor - tofs *= 4; -// fprintf(stderr,"PMMU: reading table C entry at %08x\n", tofs + tptr); - tbl_entry = m68k_read_memory_32(tofs + tptr); - tcmode = tbl_entry & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); - break; - - case 3: // 8-byte table C descriptor - tofs *= 8; -// fprintf(stderr,"PMMU: reading table C entries at %08x\n", tofs + tptr); - tbl_entry2 = m68k_read_memory_32(tofs + tptr); - tbl_entry = m68k_read_memory_32(tofs + tptr + 4); - tcmode = tbl_entry2 & 3; -// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); - break; - - case 1: // termination descriptor - tbl_entry &= 0xffffff00; - - shift = is+abits+bbits; - addr_out = ((addr_in<>shift) + tbl_entry; - resolved = 1; - break; - } - } - - if (!resolved) - { - switch (tcmode) - { - case 0: // invalid, should cause MMU exception - case 2: // 4-byte ??? descriptor - case 3: // 8-byte ??? descriptor - fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); - break; - - case 1: // termination descriptor - tbl_entry &= 0xffffff00; - - shift = is+abits+bbits+cbits; - addr_out = ((addr_in<>shift) + tbl_entry; - resolved = 1; - break; - } - } - - -// fprintf(stderr,"PMMU: [%08x] => [%08x]\n", addr_in, addr_out); - - return addr_out; -} - -/* - - m68881_mmu_ops: COP 0 MMU opcode handling - -*/ - -void m68881_mmu_ops(void) -{ - uint16 modes; - uint32 ea = m68ki_cpu.ir & 0x3f; - uint64 temp64; - - // catch the 2 "weird" encodings up front (PBcc) - if ((m68ki_cpu.ir & 0xffc0) == 0xf0c0) - { - fprintf(stderr,"680x0: unhandled PBcc\n"); - return; - } - else if ((m68ki_cpu.ir & 0xffc0) == 0xf080) - { - fprintf(stderr,"680x0: unhandled PBcc\n"); - return; - } - else // the rest are 1111000xxxXXXXXX where xxx is the instruction family - { - switch ((m68ki_cpu.ir>>9) & 0x7) - { - case 0: - modes = OPER_I_16(); - - if ((modes & 0xfde0) == 0x2000) // PLOAD - { - fprintf(stderr,"680x0: unhandled PLOAD\n"); - return; - } - else if ((modes & 0xe200) == 0x2000) // PFLUSH - { - fprintf(stderr,"680x0: unhandled PFLUSH PC=%x\n", REG_PC); - return; - } - else if (modes == 0xa000) // PFLUSHR - { - fprintf(stderr,"680x0: unhandled PFLUSHR\n"); - return; - } - else if (modes == 0x2800) // PVALID (FORMAT 1) - { - fprintf(stderr,"680x0: unhandled PVALID1\n"); - return; - } - else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) - { - fprintf(stderr,"680x0: unhandled PVALID2\n"); - return; - } - else if ((modes & 0xe000) == 0x8000) // PTEST - { - fprintf(stderr,"680x0: unhandled PTEST\n"); - return; - } - else - { - switch ((modes>>13) & 0x7) - { - case 0: // MC68030/040 form with FD bit - case 2: // MC68881 form, FD never set - if (modes & 0x200) - { - switch ((modes>>10) & 7) - { - case 0: // translation control register - WRITE_EA_32(ea, m68ki_cpu.mmu_tc); - break; - - case 2: // supervisor root pointer - WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_srp_limit<<32 | (uint64)m68ki_cpu.mmu_srp_aptr); - break; - - case 3: // CPU root pointer - WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_crp_limit<<32 | (uint64)m68ki_cpu.mmu_crp_aptr); - break; - - default: - fprintf(stderr,"680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); - break; - } - } - else - { - switch ((modes>>10) & 7) - { - case 0: // translation control register - m68ki_cpu.mmu_tc = READ_EA_32(ea); - - if (m68ki_cpu.mmu_tc & 0x80000000) - { - m68ki_cpu.pmmu_enabled = 1; - } - else - { - m68ki_cpu.pmmu_enabled = 0; - } - break; - - case 2: // supervisor root pointer - temp64 = READ_EA_64(ea); - m68ki_cpu.mmu_srp_limit = (temp64>>32) & 0xffffffff; - m68ki_cpu.mmu_srp_aptr = temp64 & 0xffffffff; - break; - - case 3: // CPU root pointer - temp64 = READ_EA_64(ea); - m68ki_cpu.mmu_crp_limit = (temp64>>32) & 0xffffffff; - m68ki_cpu.mmu_crp_aptr = temp64 & 0xffffffff; - break; - - default: - fprintf(stderr,"680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); - break; - } - } - break; - - case 3: // MC68030 to/from status reg - if (modes & 0x200) - { - WRITE_EA_32(ea, m68ki_cpu.mmu_sr); - } - else - { - m68ki_cpu.mmu_sr = READ_EA_32(ea); - } - break; - - default: - fprintf(stderr,"680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, REG_PC); - break; - } - } - break; - - default: - fprintf(stderr,"680x0: unknown PMMU instruction group %d\n", (m68ki_cpu.ir>>9) & 0x7); - break; - } - } -} - +/* + m68kmmu.h - PMMU implementation for 68851/68030/68040 + + By R. Belmont + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. +*/ + +/* + pmmu_translate_addr: perform 68851/68030-style PMMU address translation +*/ +uint pmmu_translate_addr(uint addr_in) +{ + uint32 addr_out, tbl_entry = 0, tbl_entry2, tamode = 0, tbmode = 0, tcmode = 0; + uint root_aptr, root_limit, tofs, is, abits, bbits, cbits; + uint resolved, tptr, shift; + + resolved = 0; + addr_out = addr_in; + + // if SRP is enabled and we're in supervisor mode, use it + if ((m68ki_cpu.mmu_tc & 0x02000000) && (m68ki_get_sr() & 0x2000)) + { + root_aptr = m68ki_cpu.mmu_srp_aptr; + root_limit = m68ki_cpu.mmu_srp_limit; + } + else // else use the CRP + { + root_aptr = m68ki_cpu.mmu_crp_aptr; + root_limit = m68ki_cpu.mmu_crp_limit; + } + + // get initial shift (# of top bits to ignore) + is = (m68ki_cpu.mmu_tc>>16) & 0xf; + abits = (m68ki_cpu.mmu_tc>>12)&0xf; + bbits = (m68ki_cpu.mmu_tc>>8)&0xf; + cbits = (m68ki_cpu.mmu_tc>>4)&0xf; + +// fprintf(stderr,"PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68ki_cpu.mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits); + + // get table A offset + tofs = (addr_in<>(32-abits); + + // find out what format table A is + switch (root_limit & 3) + { + case 0: // invalid, should cause MMU exception + case 1: // page descriptor, should cause direct mapping + fatalerror("680x0 PMMU: Unhandled root mode\n"); + break; + + case 2: // valid 4 byte descriptors + tofs *= 4; +// fprintf(stderr,"PMMU: reading table A entry at %08x\n", tofs + (root_aptr & 0xfffffffc)); + tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); + tamode = tbl_entry & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs); + break; + + case 3: // valid 8 byte descriptors + tofs *= 8; +// fprintf(stderr,"PMMU: reading table A entries at %08x\n", tofs + (root_aptr & 0xfffffffc)); + tbl_entry2 = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); + tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)+4); + tamode = tbl_entry2 & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); + break; + } + + // get table B offset and pointer + tofs = (addr_in<<(is+abits))>>(32-bbits); + tptr = tbl_entry & 0xfffffff0; + + // find out what format table B is, if any + switch (tamode) + { + case 0: // invalid, should cause MMU exception + fatalerror("680x0 PMMU: Unhandled Table A mode %d (addr_in %08x)\n", tamode, addr_in); + break; + + case 2: // 4-byte table B descriptor + tofs *= 4; +// fprintf(stderr,"PMMU: reading table B entry at %08x\n", tofs + tptr); + tbl_entry = m68k_read_memory_32( tofs + tptr); + tbmode = tbl_entry & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); + break; + + case 3: // 8-byte table B descriptor + tofs *= 8; +// fprintf(stderr,"PMMU: reading table B entries at %08x\n", tofs + tptr); + tbl_entry2 = m68k_read_memory_32( tofs + tptr); + tbl_entry = m68k_read_memory_32( tofs + tptr + 4); + tbmode = tbl_entry2 & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); + break; + + case 1: // early termination descriptor + tbl_entry &= 0xffffff00; + + shift = is+abits; + addr_out = ((addr_in<>shift) + tbl_entry; + resolved = 1; + break; + } + + // if table A wasn't early-out, continue to process table B + if (!resolved) + { + // get table C offset and pointer + tofs = (addr_in<<(is+abits+bbits))>>(32-cbits); + tptr = tbl_entry & 0xfffffff0; + + switch (tbmode) + { + case 0: // invalid, should cause MMU exception + fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); + break; + + case 2: // 4-byte table C descriptor + tofs *= 4; +// fprintf(stderr,"PMMU: reading table C entry at %08x\n", tofs + tptr); + tbl_entry = m68k_read_memory_32(tofs + tptr); + tcmode = tbl_entry & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); + break; + + case 3: // 8-byte table C descriptor + tofs *= 8; +// fprintf(stderr,"PMMU: reading table C entries at %08x\n", tofs + tptr); + tbl_entry2 = m68k_read_memory_32(tofs + tptr); + tbl_entry = m68k_read_memory_32(tofs + tptr + 4); + tcmode = tbl_entry2 & 3; +// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); + break; + + case 1: // termination descriptor + tbl_entry &= 0xffffff00; + + shift = is+abits+bbits; + addr_out = ((addr_in<>shift) + tbl_entry; + resolved = 1; + break; + } + } + + if (!resolved) + { + switch (tcmode) + { + case 0: // invalid, should cause MMU exception + case 2: // 4-byte ??? descriptor + case 3: // 8-byte ??? descriptor + fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); + break; + + case 1: // termination descriptor + tbl_entry &= 0xffffff00; + + shift = is+abits+bbits+cbits; + addr_out = ((addr_in<>shift) + tbl_entry; + resolved = 1; + break; + } + } + + +// fprintf(stderr,"PMMU: [%08x] => [%08x]\n", addr_in, addr_out); + + return addr_out; +} + +/* + + m68881_mmu_ops: COP 0 MMU opcode handling + +*/ + +void m68881_mmu_ops(void) +{ + uint16 modes; + uint32 ea = m68ki_cpu.ir & 0x3f; + uint64 temp64; + + // catch the 2 "weird" encodings up front (PBcc) + if ((m68ki_cpu.ir & 0xffc0) == 0xf0c0) + { + fprintf(stderr,"680x0: unhandled PBcc\n"); + return; + } + else if ((m68ki_cpu.ir & 0xffc0) == 0xf080) + { + fprintf(stderr,"680x0: unhandled PBcc\n"); + return; + } + else // the rest are 1111000xxxXXXXXX where xxx is the instruction family + { + switch ((m68ki_cpu.ir>>9) & 0x7) + { + case 0: + modes = OPER_I_16(); + + if ((modes & 0xfde0) == 0x2000) // PLOAD + { + fprintf(stderr,"680x0: unhandled PLOAD\n"); + return; + } + else if ((modes & 0xe200) == 0x2000) // PFLUSH + { + fprintf(stderr,"680x0: unhandled PFLUSH PC=%x\n", REG_PC); + return; + } + else if (modes == 0xa000) // PFLUSHR + { + fprintf(stderr,"680x0: unhandled PFLUSHR\n"); + return; + } + else if (modes == 0x2800) // PVALID (FORMAT 1) + { + fprintf(stderr,"680x0: unhandled PVALID1\n"); + return; + } + else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) + { + fprintf(stderr,"680x0: unhandled PVALID2\n"); + return; + } + else if ((modes & 0xe000) == 0x8000) // PTEST + { + fprintf(stderr,"680x0: unhandled PTEST\n"); + return; + } + else + { + switch ((modes>>13) & 0x7) + { + case 0: // MC68030/040 form with FD bit + case 2: // MC68881 form, FD never set + if (modes & 0x200) + { + switch ((modes>>10) & 7) + { + case 0: // translation control register + WRITE_EA_32(ea, m68ki_cpu.mmu_tc); + break; + + case 2: // supervisor root pointer + WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_srp_limit<<32 | (uint64)m68ki_cpu.mmu_srp_aptr); + break; + + case 3: // CPU root pointer + WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_crp_limit<<32 | (uint64)m68ki_cpu.mmu_crp_aptr); + break; + + default: + fprintf(stderr,"680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); + break; + } + } + else + { + switch ((modes>>10) & 7) + { + case 0: // translation control register + m68ki_cpu.mmu_tc = READ_EA_32(ea); + + if (m68ki_cpu.mmu_tc & 0x80000000) + { + m68ki_cpu.pmmu_enabled = 1; + } + else + { + m68ki_cpu.pmmu_enabled = 0; + } + break; + + case 2: // supervisor root pointer + temp64 = READ_EA_64(ea); + m68ki_cpu.mmu_srp_limit = (temp64>>32) & 0xffffffff; + m68ki_cpu.mmu_srp_aptr = temp64 & 0xffffffff; + break; + + case 3: // CPU root pointer + temp64 = READ_EA_64(ea); + m68ki_cpu.mmu_crp_limit = (temp64>>32) & 0xffffffff; + m68ki_cpu.mmu_crp_aptr = temp64 & 0xffffffff; + break; + + default: + fprintf(stderr,"680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); + break; + } + } + break; + + case 3: // MC68030 to/from status reg + if (modes & 0x200) + { + WRITE_EA_32(ea, m68ki_cpu.mmu_sr); + } + else + { + m68ki_cpu.mmu_sr = READ_EA_32(ea); + } + break; + + default: + fprintf(stderr,"680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, REG_PC); + break; + } + } + break; + + default: + fprintf(stderr,"680x0: unknown PMMU instruction group %d\n", (m68ki_cpu.ir>>9) & 0x7); + break; + } + } +} + diff --git a/AltairZ80/m68k/softfloat/softfloat.c b/AltairZ80/m68k/softfloat/softfloat.c index fd65afa4..b71900fd 100644 --- a/AltairZ80/m68k/softfloat/softfloat.c +++ b/AltairZ80/m68k/softfloat/softfloat.c @@ -1,4940 +1,4940 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include "../m68kcpu.h" // which includes softfloat.h after defining the basic types - -/*---------------------------------------------------------------------------- -| Floating-point rounding mode, extended double-precision rounding precision, -| and exception flags. -*----------------------------------------------------------------------------*/ -int8 float_exception_flags = 0; -#ifdef FLOATX80 -int8 floatx80_rounding_precision = 80; -#endif - -int8 float_rounding_mode = float_round_nearest_even; - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize" - -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the largest -| positive or negative integer is returned. -*----------------------------------------------------------------------------*/ - -static int32 roundAndPackInt32( flag zSign, bits64 absZ ) -{ - int8 roundingMode; - flag roundNearestEven; - int8 roundIncrement, roundBits; - int32 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - roundIncrement = 0x40; - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - roundIncrement = 0; - } - else { - roundIncrement = 0x7F; - if ( zSign ) { - if ( roundingMode == float_round_up ) roundIncrement = 0; - } - else { - if ( roundingMode == float_round_down ) roundIncrement = 0; - } - } - } - roundBits = absZ & 0x7F; - absZ = ( absZ + roundIncrement )>>7; - absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - z = (int32)absZ; - if ( zSign ) z = - z; - if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { - float_raise( float_flag_invalid ); - return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( roundBits ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest positive or negative integer is -| returned. -*----------------------------------------------------------------------------*/ - -static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) -{ - int8 roundingMode; - flag roundNearestEven, increment; - int64 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) absZ1 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && absZ1; - } - else { - increment = ( roundingMode == float_round_up ) && absZ1; - } - } - } - if ( increment ) { - ++absZ0; - if ( absZ0 == 0 ) goto overflow; - absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); - } - z = absZ0; - if ( zSign ) z = - z; - if ( z && ( ( z < 0 ) ^ zSign ) ) { - overflow: - float_raise( float_flag_invalid ); - return - zSign ? (sbits64) LIT64( 0x8000000000000000 ) - : (sbits64) LIT64( 0x7FFFFFFFFFFFFFFF ); - } - if ( absZ1 ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline bits32 extractFloat32Frac( float32 a ) -{ - return a & 0x007FFFFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline int16 extractFloat32Exp( float32 a ) -{ - return ( a>>23 ) & 0xFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat32Sign( float32 a ) -{ - return a>>31; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( aSig ) - 8; - *zSigPtr = aSig<>7; - zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float32 - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( zSig ) - 1; - return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat64Sign( float64 a ) -{ - return a>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal double-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( aSig ) - 11; - *zSigPtr = aSig<>10; - zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float64 - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( zSig ) - 1; - return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the quadruple-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat128Sign( float128 a ) -{ - return a.high>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat128Subnormal( - bits64 aSig0, - bits64 aSig1, - int32 *zExpPtr, - bits64 *zSig0Ptr, - bits64 *zSig1Ptr - ) -{ - int8 shiftCount; - - if ( aSig0 == 0 ) { - shiftCount = countLeadingZeros64( aSig1 ) - 15; - if ( shiftCount < 0 ) { - *zSig0Ptr = aSig1>>( - shiftCount ); - *zSig1Ptr = aSig1<<( shiftCount & 63 ); - } - else { - *zSig0Ptr = aSig1<>( - shiftCount ); - if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64, aSigExtra; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64( aSign, aSig64, aSigExtra ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64_round_to_zero( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64; - int64 z; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( a != 0xDF000000 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float32_to_float64( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); - return packFloat64( aSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float32_to_floatx80( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - aSig |= 0x00800000; - return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float32_to_float128( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_round_to_int( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 lastBitMask, roundBitsMask; - int8 roundingMode; - float32 z; - - aExp = extractFloat32Exp( a ); - if ( 0x96 <= aExp ) { - if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN( a, a ); - } - return a; - } - if ( aExp <= 0x7E ) { - if ( (bits32) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat32Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_down: - return aSign ? 0xBF800000 : 0; - case float_round_up: - return aSign ? 0x80000000 : 0x3F800000; - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - if ( 0 < expDiff ) { - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - zSig = 0x40000000 + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= 0x20000000; - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits32) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the single-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_add( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return addFloat32Sigs( a, b, aSign ); - } - else { - return subFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sub( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return subFloat32Sigs( a, b, aSign ); - } - else { - return addFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_mul( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig; - bits64 zSig64; - bits32 zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x7F; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); - zSig = (bits32)zSig64; - if ( 0 <= (sbits32) ( zSig<<1 ) ) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the single-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_div( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x7D; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = ( ( (bits64) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the single-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_rem( float32 a, float32 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits32 aSig, bSig; - bits32 q; - bits64 aSig64, bSig64, q64; - bits32 alternateASig; - sbits32 sigMean; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); -// bSign = extractFloat32Sign( b ); - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig |= 0x00800000; - bSig |= 0x00800000; - if ( expDiff < 32 ) { - aSig <<= 8; - bSig <<= 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - if ( 0 < expDiff ) { - q = ( ( (bits64) aSig )<<32 ) / bSig; - q >>= 32 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - } - else { - if ( bSig <= aSig ) aSig -= bSig; - aSig64 = ( (bits64) aSig )<<40; - bSig64 = ( (bits64) bSig )<<40; - expDiff -= 64; - while ( 0 < expDiff ) { - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - aSig64 = - ( ( bSig * q64 )<<38 ); - expDiff -= 62; - } - expDiff += 64; - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - q = (bits32)(q64>>( 64 - expDiff )); - bSig <<= 6; - aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits32) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits32) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sqrt( float32 a ) -{ - flag aSign; - int16 aExp, zExp; - bits32 aSig, zSig; - bits64 rem, term; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, 0 ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; - aSig = ( aSig | 0x00800000 )<<8; - zSig = estimateSqrt32( aExp, aSig ) + 2; - if ( ( zSig & 0x7F ) <= 5 ) { - if ( zSig < 2 ) { - zSig = 0x7FFFFFFF; - goto roundAndPack; - } - aSig >>= aExp & 1; - term = ( (bits64) zSig ) * zSig; - rem = ( ( (bits64) aSig )<<32 ) - term; - while ( (sbits64) rem < 0 ) { - --zSig; - rem += ( ( (bits64) zSig )<<1 ) | 1; - } - zSig |= ( rem != 0 ); - } - shift32RightJamming( zSig, 1, &zSig ); - roundAndPack: - return roundAndPackFloat32( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq_signaling( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32_round_to_zero( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = (int32)aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the single-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float64_to_float32( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - bits32 zSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 22, &aSig ); - zSig = (bits32)aSig; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x381; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float64_to_floatx80( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - return - packFloatx80( - aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the quadruple-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float64_to_float128( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_round_to_int( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float64 z; - - aExp = extractFloat64Exp( a ); - if ( 0x433 <= aExp ) { - if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (bits64) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat64Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_down: - return aSign ? LIT64( 0xBFF0000000000000 ) : 0; - case float_round_up: - return - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if ( 0 < expDiff ) { - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= LIT64( 0x2000000000000000 ); - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits64) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |= LIT64( 0x4000000000000000 ); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |= LIT64( 0x4000000000000000 ); - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the double-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_add( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return addFloat64Sigs( a, b, aSign ); - } - else { - return subFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sub( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return subFloat64Sigs( a, b, aSign ); - } - else { - return addFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_mul( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FF; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (sbits64) ( zSig0<<1 ) ) { - zSig0 <<= 1; - --zExp; - } - return roundAndPackFloat64( zSign, zExp, zSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the double-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_div( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - bits64 rem0, rem1; - bits64 term0, term1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FD; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <= 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |= ( rem1 != 0 ); - } - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the double-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_rem( float64 a, float64 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits64 aSig, bSig; - bits64 q, alternateASig; - sbits64 sigMean; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); -// bSign = extractFloat64Sign( b ); - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - aSig = - ( ( bSig>>2 ) * q ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits64) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits64) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sqrt( float64 a ) -{ - flag aSign; - int16 aExp, zExp; - bits64 aSig, zSig, doubleZSig; - bits64 rem0, rem1, term0, term1; -// float64 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, a ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; - aSig |= LIT64( 0x0010000000000000 ); - zSig = estimateSqrt32( aExp, (bits32)(aSig>>21) ); - aSig <<= 9 - ( aExp & 1 ); - zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); - if ( ( zSig & 0x1FF ) <= 5 ) { - doubleZSig = zSig<<1; - mul64To128( zSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - doubleZSig -= 2; - add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); - } - zSig |= ( ( rem0 | rem1 ) != 0 ); - } - return roundAndPackFloat64( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The invalid exception is raised -| if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq_signaling( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic---which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN, the -| largest positive integer is returned. Otherwise, if the conversion -| overflows, the largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - shiftCount = 0x4037 - aExp; - if ( shiftCount <= 0 ) shiftCount = 1; - shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN, the largest positive integer is returned. -| Otherwise, if the conversion overflows, the largest integer with the same -| sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32_round_to_zero( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = (int32)aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 floatx80_to_float32( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 33, &aSig ); - if ( aExp || aSig ) aExp -= 0x3F81; - return roundAndPackFloat32( aSign, aExp, (bits32)aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 floatx80_to_float64( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig, zSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shift64RightJamming( aSig, 1, &zSig ); - if ( aExp || aSig ) aExp -= 0x3C01; - return roundAndPackFloat64( aSign, aExp, zSig ); - -} - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the quadruple-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 floatx80_to_float128( floatx80 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); - } - shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the extended double-precision floating-point value `a' to an integer, -| and returns the result as an extended quadruple-precision floating-point -| value. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_round_to_int( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - floatx80 z; - - aExp = extractFloatx80Exp( a ); - if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FFF ) { - if ( ( aExp == 0 ) - && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { - return a; - } - float_exception_flags |= float_flag_inexact; - aSign = extractFloatx80Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) - ) { - return - packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - break; - case float_round_down: - return - aSign ? - packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) - : packFloatx80( 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloatx80( 1, 0, 0 ) - : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - return packFloatx80( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x403E - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.low += lastBitMask>>1; - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z.low += roundBitsMask; - } - } - z.low &= ~ roundBitsMask; - if ( z.low == 0 ) { - ++z.high; - z.low = LIT64( 0x8000000000000000 ); - } - if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the extended double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is -| negated before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - return a; - } - zSig1 = 0; - zSig0 = aSig + bSig; - if ( aExp == 0 ) { - normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); - goto roundAndPack; - } - zExp = aExp; - goto shiftRight1; - } - zSig0 = aSig + bSig; - if ( (sbits64) zSig0 < 0 ) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= LIT64( 0x8000000000000000 ); - ++zExp; - roundAndPack: - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the extended -| double-precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - zSig1 = 0; - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - bBigger: - sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - aBigger: - sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - return - normalizeRoundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the extended double-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_add( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return addFloatx80Sigs( a, b, aSign ); - } - else { - return subFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sub( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return subFloatx80Sigs( a, b, aSign ); - } - else { - return addFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_mul( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FFE; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - if ( 0 < (sbits64) zSig0 ) { - shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); - --zExp; - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_div( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - bits64 rem0, rem1, rem2, term0, term1, term2; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - goto invalid; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if ( bSig <= aSig ) { - shift128Right( aSig, 0, 1, &aSig, &rem1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig, rem1, bSig ); - mul64To128( bSig, zSig0, &term0, &term1 ); - sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, bSig ); - if ( (bits64) ( zSig1<<1 ) <= 8 ) { - mul64To128( bSig, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); - } - zSig1 |= ( ( rem1 | rem2 ) != 0 ); - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the extended double-precision floating-point value -| `a' with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_rem( floatx80 a, floatx80 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig; - bits64 q, term0, term1, alternateASig0, alternateASig1; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); -// bSign = extractFloatx80Sign( b ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( (bits64) ( aSig0<<1 ) == 0 ) return a; - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - bSig |= LIT64( 0x8000000000000000 ); - zSign = aSign; - expDiff = aExp - bExp; - aSig1 = 0; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); - expDiff = 0; - } - q = ( bSig <= aSig0 ); - if ( q ) aSig0 -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - mul64To128( bSig, q, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); - while ( le128( term0, term1, aSig0, aSig1 ) ) { - ++q; - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - } - } - else { - term1 = 0; - term0 = bSig; - } - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) - && ( q & 1 ) ) - ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - zSign = ! zSign; - } - return - normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sqrt( floatx80 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; - zSig0 = estimateSqrt32( aExp, aSig0>>32 ); - shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= doubleZSig0; - return - roundAndPackFloatx80( - floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than or equal to the corresponding value `b', and 0 otherwise. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is equal -| to the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq_signaling( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs -| do not cause an exception. Otherwise, the comparison is performed according -| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause -| an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; - if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); - aSig0 |= ( aSig1 != 0 ); - shiftCount = 0x4028 - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); - return roundAndPackInt32( aSign, aSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32_round_to_zero( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1, savedASig; - int32 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - aSig0 |= ( aSig1 != 0 ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig0 |= LIT64( 0x0001000000000000 ); - shiftCount = 0x402F - aExp; - savedASig = aSig0; - aSig0 >>= shiftCount; - z = (int32)aSig0; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); - if ( (bits64) ( aSig1<>( - shiftCount ); - if ( aSig1 - || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the single-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float128_to_float32( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - bits32 zSig; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat32( float128ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - aSig0 |= ( aSig1 != 0 ); - shift64RightJamming( aSig0, 18, &aSig0 ); - zSig = (bits32)aSig0; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x3F81; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float128_to_float64( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat64( float128ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - aSig0 |= ( aSig1 != 0 ); - if ( aExp || aSig0 ) { - aSig0 |= LIT64( 0x4000000000000000 ); - aExp -= 0x3C01; - } - return roundAndPackFloat64( aSign, aExp, aSig0 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the extended double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float128_to_floatx80( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloatx80( float128ToCommonNaN( a ) ); - } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); - return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the quadruple-precision floating-point value `a' to an integer, and -| returns the result as a quadruple-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_round_to_int( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float128 z; - - aExp = extractFloat128Exp( a ); - if ( 0x402F <= aExp ) { - if ( 0x406F <= aExp ) { - if ( ( aExp == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) - ) { - return propagateFloat128NaN( a, a ); - } - return a; - } - lastBitMask = 1; - lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - if ( lastBitMask ) { - add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else { - if ( (sbits64) z.low < 0 ) { - ++z.high; - if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; - } - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); - } - } - z.low &= ~ roundBitsMask; - } - else { - if ( aExp < 0x3FFF ) { - if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat128Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) - && ( extractFloat128Frac0( a ) - | extractFloat128Frac1( a ) ) - ) { - return packFloat128( aSign, 0x3FFF, 0, 0 ); - } - break; - case float_round_down: - return - aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) - : packFloat128( 0, 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloat128( 1, 0, 0, 0 ) - : packFloat128( 0, 0x3FFF, 0, 0 ); - } - return packFloat128( aSign, 0, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x402F - aExp; - roundBitsMask = lastBitMask - 1; - z.low = 0; - z.high = a.high; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.high += lastBitMask>>1; - if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { - z.high &= ~ lastBitMask; - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - z.high |= ( a.low != 0 ); - z.high += roundBitsMask; - } - } - z.high &= ~ roundBitsMask; - } - if ( ( z.low != a.low ) || ( z.high != a.high ) ) { - float_exception_flags |= float_flag_inexact; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the quadruple-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - int32 expDiff; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - return a; - } - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); - zSig2 = 0; - zSig0 |= LIT64( 0x0002000000000000 ); - zExp = aExp; - goto shiftRight1; - } - aSig0 |= LIT64( 0x0001000000000000 ); - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - --zExp; - if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; - ++zExp; - shiftRight1: - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - roundAndPack: - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the quadruple- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; - int32 expDiff; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig0 < aSig0 ) goto aBigger; - if ( aSig0 < bSig0 ) goto bBigger; - if ( bSig1 < aSig1 ) goto aBigger; - if ( aSig1 < bSig1 ) goto bBigger; - return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - bSig0 |= LIT64( 0x4000000000000000 ); - bBigger: - sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); - aSig0 |= LIT64( 0x4000000000000000 ); - aBigger: - sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the quadruple-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_add( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return addFloat128Sigs( a, b, aSign ); - } - else { - return subFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sub( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return subFloat128Sigs( a, b, aSign ); - } - else { - return addFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_mul( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - zExp = aExp + bExp - 0x4000; - aSig0 |= LIT64( 0x0001000000000000 ); - shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); - mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); - add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zSig2 |= ( zSig3 != 0 ); - if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - ++zExp; - } - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the quadruple-precision floating-point value -| `a' by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_div( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - goto invalid; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0, 0, 0 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = aExp - bExp + 0x3FFD; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { - shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); - mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); - sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); - } - zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); - if ( ( zSig1 & 0x3FFF ) <= 4 ) { - mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); - sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the quadruple-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_rem( float128 a, float128 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; - bits64 allZero, alternateASig0, alternateASig1, sigMean1; - sbits64 sigMean0; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); -// bSign = extractFloat128Sign( b ); - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return a; - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - expDiff = aExp - bExp; - if ( expDiff < -1 ) return a; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), - aSig1, - 15 - ( expDiff < 0 ), - &aSig0, - &aSig1 - ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - q = le128( bSig0, bSig1, aSig0, aSig1 ); - if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); - shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); - sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); - expDiff -= 61; - } - if ( -64 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - q >>= - expDiff; - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - expDiff += 52; - if ( expDiff < 0 ) { - shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - } - else { - shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); - } - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); - } - else { - shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - } - do { - alternateASig0 = aSig0; - alternateASig1 = aSig1; - ++q; - sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <= (sbits64) aSig0 ); - add128( - aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); - if ( ( sigMean0 < 0 ) - || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - } - zSign = ( (sbits64) aSig0 < 0 ); - if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); - return - normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the quadruple-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sqrt( float128 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; - aSig0 |= LIT64( 0x0001000000000000 ); - zSig0 = estimateSqrt32( aExp, (bits32)(aSig0>>17 )); - shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & 0x1FFF ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq_signaling( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif + +/*============================================================================ + +This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +#include "../m68kcpu.h" // which includes softfloat.h after defining the basic types + +/*---------------------------------------------------------------------------- +| Floating-point rounding mode, extended double-precision rounding precision, +| and exception flags. +*----------------------------------------------------------------------------*/ +int8 float_exception_flags = 0; +#ifdef FLOATX80 +int8 floatx80_rounding_precision = 80; +#endif + +int8 float_rounding_mode = float_round_nearest_even; + +/*---------------------------------------------------------------------------- +| Functions and definitions to determine: (1) whether tininess for underflow +| is detected before or after rounding by default, (2) what (if anything) +| happens when exceptions are raised, (3) how signaling NaNs are distinguished +| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +| are propagated from function inputs to output. These details are target- +| specific. +*----------------------------------------------------------------------------*/ +#include "softfloat-specialize" + +/*---------------------------------------------------------------------------- +| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 +| and 7, and returns the properly rounded 32-bit integer corresponding to the +| input. If `zSign' is 1, the input is negated before being converted to an +| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input +| is simply rounded to an integer, with the inexact exception raised if the +| input cannot be represented exactly as an integer. However, if the fixed- +| point input is too large, the invalid exception is raised and the largest +| positive or negative integer is returned. +*----------------------------------------------------------------------------*/ + +static int32 roundAndPackInt32( flag zSign, bits64 absZ ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + int32 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = absZ & 0x7F; + absZ = ( absZ + roundIncrement )>>7; + absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + z = (int32)absZ; + if ( zSign ) z = - z; + if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { + float_raise( float_flag_invalid ); + return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +| `absZ1', with binary point between bits 63 and 64 (between the input words), +| and returns the properly rounded 64-bit integer corresponding to the input. +| If `zSign' is 1, the input is negated before being converted to an integer. +| Ordinarily, the fixed-point input is simply rounded to an integer, with +| the inexact exception raised if the input cannot be represented exactly as +| an integer. However, if the fixed-point input is too large, the invalid +| exception is raised and the largest positive or negative integer is +| returned. +*----------------------------------------------------------------------------*/ + +static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) +{ + int8 roundingMode; + flag roundNearestEven, increment; + int64 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) absZ1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && absZ1; + } + else { + increment = ( roundingMode == float_round_up ) && absZ1; + } + } + } + if ( increment ) { + ++absZ0; + if ( absZ0 == 0 ) goto overflow; + absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + } + z = absZ0; + if ( zSign ) z = - z; + if ( z && ( ( z < 0 ) ^ zSign ) ) { + overflow: + float_raise( float_flag_invalid ); + return + zSign ? (sbits64) LIT64( 0x8000000000000000 ) + : (sbits64) LIT64( 0x7FFFFFFFFFFFFFFF ); + } + if ( absZ1 ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline bits32 extractFloat32Frac( float32 a ) +{ + return a & 0x007FFFFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline int16 extractFloat32Exp( float32 a ) +{ + return ( a>>23 ) & 0xFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat32Sign( float32 a ) +{ + return a>>31; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal single-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper single-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat32' except that `zSig' does not have to be normalized. +| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat64Sign( float64 a ) +{ + return a>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ) - 11; + *zSigPtr = aSig<>10; + zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper double-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat64' except that `zSig' does not have to be normalized. +| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float64 + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( zSig ) - 1; + return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the quadruple-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +static inline flag extractFloat128Sign( float128 a ) +{ + return a.high>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal quadruple-precision floating-point value +| represented by the denormalized significand formed by the concatenation of +| `aSig0' and `aSig1'. The normalized exponent is stored at the location +| pointed to by `zExpPtr'. The most significant 49 bits of the normalized +| significand are stored at the location pointed to by `zSig0Ptr', and the +| least significant 64 bits of the normalized significand are stored at the +| location pointed to by `zSig1Ptr'. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat128Subnormal( + bits64 aSig0, + bits64 aSig1, + int32 *zExpPtr, + bits64 *zSig0Ptr, + bits64 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros64( aSig1 ) - 15; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 63 ); + } + else { + *zSig0Ptr = aSig1<>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64, aSigExtra; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = 0xBE - aExp; + if ( shiftCount < 0 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + if ( aExp ) aSig |= 0x00800000; + aSig64 = aSig; + aSig64 <<= 40; + shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); + return roundAndPackInt64( aSign, aSig64, aSigExtra ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest positive integer is returned. Otherwise, if the +| conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64; + int64 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0xBE; + if ( 0 <= shiftCount ) { + if ( a != 0xDF000000 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig64 = aSig | 0x00800000; + aSig64 <<= 40; + z = aSig64>>( - shiftCount ); + if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the extended double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float32_to_floatx80( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + aSig |= 0x00800000; + return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float32_to_float128( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the single-precision floating-point value `a' to an integer, and +| returns the result as a single-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the single-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the single- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the single-precision floating-point values `a' +| and `b'. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig; + bits64 zSig64; + bits32 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + zSig = (bits32)zSig64; + if ( 0 <= (sbits32) ( zSig<<1 ) ) { + zSig <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the single-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = ( ( (bits64) aSig )<<32 ) / bSig; + if ( ( zSig & 0x3F ) == 0 ) { + zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the single-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q; + bits64 aSig64, bSig64, q64; + bits32 alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); +// bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig |= 0x00800000; + bSig |= 0x00800000; + if ( expDiff < 32 ) { + aSig <<= 8; + bSig <<= 8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + if ( 0 < expDiff ) { + q = ( ( (bits64) aSig )<<32 ) / bSig; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + } + else { + if ( bSig <= aSig ) aSig -= bSig; + aSig64 = ( (bits64) aSig )<<40; + bSig64 = ( (bits64) bSig )<<40; + expDiff -= 64; + while ( 0 < expDiff ) { + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + aSig64 = - ( ( bSig * q64 )<<38 ); + expDiff -= 62; + } + expDiff += 64; + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + q = (bits32)(q64>>( 64 - expDiff )); + bSig <<= 6; + aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the single-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits64 rem, term; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0x7FFFFFFF; + goto roundAndPack; + } + aSig >>= aExp & 1; + term = ( (bits64) zSig ) * zSig; + rem = ( ( (bits64) aSig )<<32 ) - term; + while ( (sbits64) rem < 0 ) { + --zSig; + rem += ( ( (bits64) zSig )<<1 ) | 1; + } + zSig |= ( rem != 0 ); + } + shift32RightJamming( zSig, 1, &zSig ); + roundAndPack: + return roundAndPackFloat32( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq( float32 a, float32 b ) +{ + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq_signaling( float32 a, float32 b ) +{ + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. +| If `a' is a NaN, the largest positive integer is returned. Otherwise, if +| the conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = (int32)aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the single-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + bits32 zSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 22, &aSig ); + zSig = (bits32)aSig; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x381; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the extended double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float64_to_floatx80( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + return + packFloatx80( + aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the quadruple-precision floating-point format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float64_to_float128( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the double-precision floating-point value `a' to an integer, and +| returns the result as a double-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FF ) { + if ( (bits64) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { + return packFloat64( aSign, 0x3FF, 0 ); + } + break; + case float_round_down: + return aSign ? LIT64( 0xBFF0000000000000 ) : 0; + case float_round_up: + return + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); + } + return packFloat64( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x433 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the double-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 9; + bSig <<= 9; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); + zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= LIT64( 0x2000000000000000 ); + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits64) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the double- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 10; + bSig <<= 10; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + bSig |= LIT64( 0x4000000000000000 ); + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + aSig |= LIT64( 0x4000000000000000 ); + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the double-precision floating-point values `a' +| and `b'. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FF; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1; + bits64 term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0 ); + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FD; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64( aSig, 0, bSig ); + if ( ( zSig & 0x1FF ) <= 2 ) { + mul64To128( bSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the double-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, zSign; + int16 aExp, bExp, expDiff; + bits64 aSig, bSig; + bits64 q, alternateASig; + sbits64 sigMean; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); +// bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits64) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits64) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the double-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits64 aSig, zSig, doubleZSig; + bits64 rem0, rem1, term0, term1; +// float64 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig |= LIT64( 0x0010000000000000 ); + zSig = estimateSqrt32( aExp, (bits32)(aSig>>21) ); + aSig <<= 9 - ( aExp & 1 ); + zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); + if ( ( zSig & 0x1FF ) <= 5 ) { + doubleZSig = zSig<<1; + mul64To128( zSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + doubleZSig -= 2; + add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + return roundAndPackFloat64( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq( float64 a, float64 b ) +{ + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. The invalid exception is raised +| if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq_signaling( float64 a, float64 b ) +{ + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic---which means in particular that the conversion +| is rounded according to the current rounding mode. If `a' is a NaN, the +| largest positive integer is returned. Otherwise, if the conversion +| overflows, the largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + shiftCount = 0x4037 - aExp; + if ( shiftCount <= 0 ) shiftCount = 1; + shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic, except that the conversion is always rounded +| toward zero. If `a' is a NaN, the largest positive integer is returned. +| Otherwise, if the conversion overflows, the largest integer with the same +| sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32_round_to_zero( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + shiftCount = 0x403E - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = (int32)aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the single-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 floatx80_to_float32( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 33, &aSig ); + if ( aExp || aSig ) aExp -= 0x3F81; + return roundAndPackFloat32( aSign, aExp, (bits32)aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the double-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 floatx80_to_float64( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig, zSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shift64RightJamming( aSig, 1, &zSig ); + if ( aExp || aSig ) aExp -= 0x3C01; + return roundAndPackFloat64( aSign, aExp, zSig ); + +} + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the extended double-precision floating- +| point value `a' to the quadruple-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 floatx80_to_float128( floatx80 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); + } + shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the extended double-precision floating-point value `a' to an integer, +| and returns the result as an extended quadruple-precision floating-point +| value. The operation is performed according to the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_round_to_int( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + floatx80 z; + + aExp = extractFloatx80Exp( a ); + if ( 0x403E <= aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + return propagateFloatx80NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FFF ) { + if ( ( aExp == 0 ) + && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + return a; + } + float_exception_flags |= float_flag_inexact; + aSign = extractFloatx80Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + ) { + return + packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + break; + case float_round_down: + return + aSign ? + packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) + : packFloatx80( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloatx80( 1, 0, 0 ) + : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + return packFloatx80( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x403E - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.low += lastBitMask>>1; + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z.low += roundBitsMask; + } + } + z.low &= ~ roundBitsMask; + if ( z.low == 0 ) { + ++z.high; + z.low = LIT64( 0x8000000000000000 ); + } + if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the extended double- +| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is +| negated before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + return a; + } + zSig1 = 0; + zSig0 = aSig + bSig; + if ( aExp == 0 ) { + normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); + goto roundAndPack; + } + zExp = aExp; + goto shiftRight1; + } + zSig0 = aSig + bSig; + if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= LIT64( 0x8000000000000000 ); + ++zExp; + roundAndPack: + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the extended +| double-precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + zSig1 = 0; + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + bBigger: + sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + aBigger: + sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + return + normalizeRoundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the extended double-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_add( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return addFloatx80Sigs( a, b, aSign ); + } + else { + return subFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the extended double-precision floating- +| point values `a' and `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sub( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return subFloatx80Sigs( a, b, aSign ); + } + else { + return addFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the extended double-precision floating- +| point values `a' and `b'. The operation is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_mul( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) goto invalid; + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FFE; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + if ( 0 < (sbits64) zSig0 ) { + shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); + --zExp; + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the extended double-precision floating-point +| value `a' by the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_div( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + bits64 rem0, rem1, rem2, term0, term1, term2; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + goto invalid; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FFE; + rem1 = 0; + if ( bSig <= aSig ) { + shift128Right( aSig, 0, 1, &aSig, &rem1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig, rem1, bSig ); + mul64To128( bSig, zSig0, &term0, &term1 ); + sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, bSig ); + if ( (bits64) ( zSig1<<1 ) <= 8 ) { + mul64To128( bSig, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); + } + zSig1 |= ( ( rem1 | rem2 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the extended double-precision floating-point value +| `a' with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_rem( floatx80 a, floatx80 b ) +{ + flag aSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig; + bits64 q, term0, term1, alternateASig0, alternateASig1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); +// bSign = extractFloatx80Sign( b ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + bSig |= LIT64( 0x8000000000000000 ); + zSign = aSign; + expDiff = aExp - bExp; + aSig1 = 0; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); + expDiff = 0; + } + q = ( bSig <= aSig0 ); + if ( q ) aSig0 -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul64To128( bSig, q, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); + while ( le128( term0, term1, aSig0, aSig1 ) ) { + ++q; + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + } + } + else { + term1 = 0; + term0 = bSig; + } + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) + && ( q & 1 ) ) + ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + zSign = ! zSign; + } + return + normalizeRoundAndPackFloatx80( + 80, zSign, bExp + expDiff, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the extended double-precision floating-point +| value `a'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sqrt( floatx80 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; + zSig0 = estimateSqrt32( aExp, aSig0>>32 ); + shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= doubleZSig0; + return + roundAndPackFloatx80( + floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq( floatx80 a, floatx80 b ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| less than or equal to the corresponding value `b', and 0 otherwise. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| less than the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is equal +| to the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq_signaling( floatx80 a, floatx80 b ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is less +| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs +| do not cause an exception. Otherwise, the comparison is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is less +| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause +| an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; + if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); + aSig0 |= ( aSig1 != 0 ); + shiftCount = 0x4028 - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); + return roundAndPackInt32( aSign, aSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest positive integer is returned. Otherwise, if the +| conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32_round_to_zero( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1, savedASig; + int32 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + aSig0 |= ( aSig1 != 0 ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig0 |= LIT64( 0x0001000000000000 ); + shiftCount = 0x402F - aExp; + savedASig = aSig0; + aSig0 >>= shiftCount; + z = (int32)aSig0; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); + if ( (bits64) ( aSig1<>( - shiftCount ); + if ( aSig1 + || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the single-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float128_to_float32( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + bits32 zSig; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat32( float128ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + aSig0 |= ( aSig1 != 0 ); + shift64RightJamming( aSig0, 18, &aSig0 ); + zSig = (bits32)aSig0; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x3F81; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the double-precision floating-point format. The conversion +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float128_to_float64( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat64( float128ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + aSig0 |= ( aSig1 != 0 ); + if ( aExp || aSig0 ) { + aSig0 |= LIT64( 0x4000000000000000 ); + aExp -= 0x3C01; + } + return roundAndPackFloat64( aSign, aExp, aSig0 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the extended double-precision floating-point format. The +| conversion is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float128_to_floatx80( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloatx80( float128ToCommonNaN( a ) ); + } + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); + return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the quadruple-precision floating-point value `a' to an integer, and +| returns the result as a quadruple-precision floating-point value. The +| operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_round_to_int( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float128 z; + + aExp = extractFloat128Exp( a ); + if ( 0x402F <= aExp ) { + if ( 0x406F <= aExp ) { + if ( ( aExp == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) + ) { + return propagateFloat128NaN( a, a ); + } + return a; + } + lastBitMask = 1; + lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( (sbits64) z.low < 0 ) { + ++z.high; + if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp < 0x3FFF ) { + if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat128Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) + && ( extractFloat128Frac0( a ) + | extractFloat128Frac1( a ) ) + ) { + return packFloat128( aSign, 0x3FFF, 0, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) + : packFloat128( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat128( 1, 0, 0, 0 ) + : packFloat128( 0, 0x3FFF, 0, 0 ); + } + return packFloat128( aSign, 0, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x402F - aExp; + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the quadruple-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int32 expDiff; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + return a; + } + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= LIT64( 0x0002000000000000 ); + zExp = aExp; + goto shiftRight1; + } + aSig0 |= LIT64( 0x0001000000000000 ); + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; + ++zExp; + shiftRight1: + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the quadruple- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int32 expDiff; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= LIT64( 0x4000000000000000 ); + bBigger: + sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= LIT64( 0x4000000000000000 ); + aBigger: + sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the quadruple-precision floating-point values +| `a' and `b'. The operation is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_add( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return addFloat128Sigs( a, b, aSign ); + } + else { + return subFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sub( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return subFloat128Sigs( a, b, aSign ); + } + else { + return addFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_mul( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x4000; + aSig0 |= LIT64( 0x0001000000000000 ); + shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); + mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( zSig3 != 0 ); + if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the quadruple-precision floating-point value +| `a' by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_div( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + goto invalid; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FFD; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { + shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); + mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FFF ) <= 4 ) { + mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the quadruple-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_rem( float128 a, float128 b ) +{ + flag aSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + bits64 allZero, alternateASig0, alternateASig1, sigMean1; + sbits64 sigMean0; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); +// bSign = extractFloat128Sign( b ); + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), + aSig1, + 15 - ( expDiff < 0 ), + &aSig0, + &aSig1 + ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + q = le128( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); + shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); + sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 61; + } + if ( -64 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + expDiff += 52; + if ( expDiff < 0 ) { + shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= (sbits64) aSig0 ); + add128( + aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits64) aSig0 < 0 ); + if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the quadruple-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sqrt( float128 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; + aSig0 |= LIT64( 0x0001000000000000 ); + zSig0 = estimateSqrt32( aExp, (bits32)(aSig0>>17 )); + shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & 0x1FFF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq( float128 a, float128 b ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq_signaling( float128 a, float128 b ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif diff --git a/AltairZ80/m68k/softfloat/softfloat.h b/AltairZ80/m68k/softfloat/softfloat.h index 92135e66..1ed4bccc 100644 --- a/AltairZ80/m68k/softfloat/softfloat.h +++ b/AltairZ80/m68k/softfloat/softfloat.h @@ -47,13 +47,13 @@ typedef bits32 float32; typedef bits64 float64; #ifdef FLOATX80 typedef struct { - bits16 high; - bits64 low; + bits16 high; + bits64 low; } floatx80; #endif #ifdef FLOAT128 typedef struct { - bits64 high, low; + bits64 high, low; } float128; #endif @@ -69,8 +69,8 @@ typedef struct { *----------------------------------------------------------------------------*/ extern int8 float_detect_tininess; enum { - float_tininess_after_rounding = 0, - float_tininess_before_rounding = 1 + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 }; /*---------------------------------------------------------------------------- @@ -78,10 +78,10 @@ enum { *----------------------------------------------------------------------------*/ extern int8 float_rounding_mode; enum { - float_round_nearest_even = 0, - float_round_to_zero = 1, - float_round_down = 2, - float_round_up = 3 + float_round_nearest_even = 0, + float_round_to_zero = 1, + float_round_down = 2, + float_round_up = 3 }; /*---------------------------------------------------------------------------- @@ -89,8 +89,8 @@ enum { *----------------------------------------------------------------------------*/ extern int8 float_exception_flags; enum { - float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, - float_flag_underflow = 0x10, float_flag_inexact = 0x20 + float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, + float_flag_underflow = 0x10, float_flag_inexact = 0x20 }; /*---------------------------------------------------------------------------- @@ -208,11 +208,11 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b); static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) { - floatx80 z; + floatx80 z; - z.low = zSig; - z.high = ( ( (bits16) zSign )<<15 ) + zExp; - return z; + z.low = zSig; + z.high = ( ( (bits16) zSign )<<15 ) + zExp; + return z; } @@ -301,13 +301,13 @@ flag float128_is_signaling_nan( float128 ); *----------------------------------------------------------------------------*/ static inline float128 - packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) + packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) { - float128 z; + float128 z; - z.low = zSig1; - z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; - return z; + z.low = zSig1; + z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; + return z; } @@ -333,92 +333,92 @@ static inline float128 *----------------------------------------------------------------------------*/ static inline float128 - roundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) + roundAndPackFloat128( + flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) { - int8 roundingMode; - flag roundNearestEven, increment, isTiny; + int8 roundingMode; + flag roundNearestEven, increment, isTiny; - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) zSig2 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - if ( 0x7FFD <= (bits32) zExp ) { - if ( ( 0x7FFD < zExp ) - || ( ( zExp == 0x7FFD ) - && eq128( - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ), - zSig0, - zSig1 - ) - && increment - ) - ) { - float_raise( float_flag_overflow | float_flag_inexact ); - if ( ( roundingMode == float_round_to_zero ) - || ( zSign && ( roundingMode == float_round_up ) ) - || ( ! zSign && ( roundingMode == float_round_down ) ) - ) { - return - packFloat128( - zSign, - 0x7FFE, - LIT64( 0x0000FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( zExp < 0 ) { - isTiny = - ( float_detect_tininess == float_tininess_before_rounding ) - || ( zExp < -1 ) - || ! increment - || lt128( - zSig0, - zSig1, - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); - zExp = 0; - if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); - if ( roundNearestEven ) { - increment = ( (sbits64) zSig2 < 0 ); - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - } - if ( zSig2 ) float_exception_flags |= float_flag_inexact; - if ( increment ) { - add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); - zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); - } - else { - if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; - } - return packFloat128( zSign, zExp, zSig0, zSig1 ); + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) zSig2 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + if ( 0x7FFD <= (bits32) zExp ) { + if ( ( 0x7FFD < zExp ) + || ( ( zExp == 0x7FFD ) + && eq128( + LIT64( 0x0001FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ), + zSig0, + zSig1 + ) + && increment + ) + ) { + float_raise( float_flag_overflow | float_flag_inexact ); + if ( ( roundingMode == float_round_to_zero ) + || ( zSign && ( roundingMode == float_round_up ) ) + || ( ! zSign && ( roundingMode == float_round_down ) ) + ) { + return + packFloat128( + zSign, + 0x7FFE, + LIT64( 0x0000FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ) + ); + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ! increment + || lt128( + zSig0, + zSig1, + LIT64( 0x0001FFFFFFFFFFFF ), + LIT64( 0xFFFFFFFFFFFFFFFF ) + ); + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); + zExp = 0; + if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); + if ( roundNearestEven ) { + increment = ( (sbits64) zSig2 < 0 ); + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig2; + } + else { + increment = ( roundingMode == float_round_up ) && zSig2; + } + } + } + } + if ( zSig2 ) float_exception_flags |= float_flag_inexact; + if ( increment ) { + add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); + zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); + } + else { + if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; + } + return packFloat128( zSign, zExp, zSig0, zSig1 ); } @@ -433,28 +433,28 @@ static inline float128 *----------------------------------------------------------------------------*/ static inline float128 - normalizeRoundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) + normalizeRoundAndPackFloat128( + flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) { - int8 shiftCount; - bits64 zSig2; + int8 shiftCount; + bits64 zSig2; - if ( zSig0 == 0 ) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - shiftCount = countLeadingZeros64( zSig0 ) - 15; - if ( 0 <= shiftCount ) { - zSig2 = 0; - shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); - } - zExp -= shiftCount; - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + if ( zSig0 == 0 ) { + zSig0 = zSig1; + zSig1 = 0; + zExp -= 64; + } + shiftCount = countLeadingZeros64( zSig0 ) - 15; + if ( 0 <= shiftCount ) { + zSig2 = 0; + shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); + } + else { + shift128ExtraRightJamming( + zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); + } + zExp -= shiftCount; + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); } #endif diff --git a/AltairZ80/mmd.c b/AltairZ80/mmd.c index 09ae0993..c5f47ab6 100644 --- a/AltairZ80/mmd.c +++ b/AltairZ80/mmd.c @@ -1,7 +1,7 @@ /*** mmd.c: Morrow Micro-Decision - + Created by Patrick Linstruth (patrick@deltecent.com) - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation @@ -62,7 +62,7 @@ 40 Cylinders 5 Sectors/Track 1024 Bytes per Track - + Tracks 0-1 Bootable Image (10K) Double sided disks have 80 tracks, with even numbered tracks on side 0 @@ -214,2326 +214,2326 @@ static uint8 mmd_mem[MMD_ROM_SIZE]; /* 4K Banked Memory */ /* MD2 1.3 ROM is 2048 bytes */ static uint8 mmd_rom_13[MMD_ROM_SIZE] = { - 0xc3, 0x1d, 0x00, 0xc3, 0xba, 0x01, 0xc3, 0x10, - 0x04, 0xc3, 0xd3, 0x01, 0xc3, 0xe0, 0x01, 0xc3, - 0x64, 0x02, 0xc3, 0x93, 0x03, 0xc3, 0xdd, 0x03, - 0xc3, 0x96, 0x01, 0xd4, 0x05, 0xed, 0x46, 0x31, - 0x00, 0x00, 0xfd, 0x21, 0xf3, 0x05, 0xcd, 0x5b, - 0x00, 0x11, 0x0f, 0x07, 0xcd, 0xb1, 0x01, 0xcd, - 0x81, 0x00, 0xcd, 0xac, 0x00, 0xcd, 0x90, 0x00, - 0xcd, 0x00, 0xfc, 0x11, 0x8a, 0x07, 0xcd, 0xba, - 0x01, 0xcd, 0x78, 0x03, 0xfe, 0x0d, 0x20, 0xf9, - 0x11, 0x78, 0x00, 0xcd, 0xba, 0x01, 0xc3, 0x76, - 0x01, 0xcd, 0xba, 0x01, 0x11, 0xf3, 0x06, 0xcd, - 0xba, 0x01, 0x76, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, - 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, - 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, - 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, - 0x0d, 0x0a, 0x00, 0x3a, 0xa0, 0x00, 0xc5, 0xf6, - 0x04, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x07, 0xcd, - 0x9f, 0x00, 0x11, 0xd9, 0x07, 0x20, 0xc2, 0xc9, - 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, 0xcd, 0x9f, - 0x00, 0x11, 0xc6, 0x07, 0x20, 0xb3, 0xc9, 0xaf, - 0xf5, 0xf1, 0xae, 0x23, 0x0b, 0xf5, 0x78, 0xb1, - 0x20, 0xf7, 0xf1, 0xc9, 0x21, 0xc4, 0x00, 0x11, - 0x00, 0xfc, 0x01, 0xb2, 0x00, 0xed, 0xb0, 0x01, - 0x45, 0x03, 0xd5, 0xe1, 0x13, 0x36, 0xff, 0xed, - 0xb0, 0x36, 0x1f, 0xc9, 0xdb, 0xf6, 0x3a, 0x00, - 0x00, 0xfe, 0xc3, 0xd3, 0xf6, 0x20, 0x03, 0xc3, - 0x3b, 0x00, 0x11, 0x57, 0x07, 0xcd, 0xba, 0x01, - 0xdb, 0xf6, 0x21, 0x00, 0x00, 0x01, 0xff, 0xfb, - 0xcd, 0x31, 0xfc, 0xb7, 0xd3, 0xf6, 0x11, 0xc6, - 0x07, 0xc2, 0x51, 0x00, 0x11, 0x7b, 0x07, 0xcd, - 0xba, 0x01, 0xc3, 0x3b, 0x00, 0x22, 0xb2, 0xfc, - 0x21, 0x84, 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, - 0x18, 0x5e, 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, - 0x28, 0x05, 0xcd, 0x57, 0xfc, 0x18, 0x07, 0xdd, - 0x21, 0x77, 0xfc, 0xcd, 0x5b, 0xfc, 0xe1, 0x18, - 0xe2, 0xaf, 0xc9, 0xdd, 0x21, 0x79, 0xfc, 0x2a, - 0xb2, 0xfc, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, - 0x67, 0xcd, 0x75, 0xfc, 0x23, 0x23, 0x23, 0x78, - 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, - 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, - 0x01, 0xc9, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, 0xc9, - 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x41, - 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, 0x01, - 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, 0x41, - 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, 0x41, - 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, 0x42, - 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x21, 0xd4, - 0x05, 0x11, 0x00, 0xff, 0x01, 0x42, 0x00, 0xed, - 0xb0, 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, - 0xff, 0xcd, 0x33, 0x04, 0xcd, 0x64, 0x02, 0xdd, - 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, 0xd3, - 0x06, 0xc3, 0x51, 0x00, 0xdb, 0xfd, 0xcb, 0x47, - 0x28, 0xfa, 0x79, 0xd3, 0xfc, 0xc9, 0xdb, 0xfd, - 0xcb, 0x4f, 0x28, 0xfa, 0xdb, 0xfc, 0xe6, 0x7f, - 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xc3, 0x01, - 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xc3, 0x01, - 0x13, 0x18, 0xf7, 0x4f, 0xd5, 0xe5, 0xfd, 0x6e, - 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xd2, 0x01, 0xe1, - 0xd1, 0xc9, 0xe9, 0x21, 0x93, 0x03, 0xdd, 0x75, - 0x0a, 0xdd, 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, - 0x21, 0xdd, 0x03, 0xdd, 0x75, 0x0a, 0xdd, 0x74, - 0x0b, 0x0e, 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0xb8, - 0x04, 0x23, 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, - 0x16, 0xdd, 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, - 0x0f, 0x0f, 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, - 0x11, 0x80, 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, - 0xff, 0x11, 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, - 0x16, 0x01, 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, - 0xdd, 0x70, 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, - 0x06, 0xdd, 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, - 0xcb, 0x56, 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, - 0x28, 0x03, 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, - 0x07, 0x07, 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, - 0xdd, 0x70, 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, - 0xa6, 0xdd, 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, - 0x05, 0x00, 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, - 0x7e, 0xdd, 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x11, - 0x00, 0x03, 0xc5, 0xd5, 0x3e, 0x08, 0xcd, 0x35, - 0x04, 0xcd, 0x09, 0x03, 0xfd, 0xe5, 0xcd, 0xc9, - 0x02, 0xcd, 0xfd, 0x02, 0xfd, 0xe1, 0x06, 0x07, - 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, - 0x21, 0x05, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, - 0xdd, 0x7e, 0x0e, 0xe6, 0x40, 0x28, 0x2d, 0xcd, - 0x83, 0x05, 0x3e, 0x01, 0xb9, 0x28, 0x15, 0x3e, - 0x06, 0xb9, 0xcc, 0x0a, 0x04, 0x3e, 0x02, 0xb9, - 0xcc, 0x30, 0x04, 0x1c, 0x3e, 0x0b, 0xb8, 0xcc, - 0x2c, 0x04, 0x10, 0xb6, 0xdd, 0x7e, 0x07, 0xfe, - 0xff, 0x28, 0x0a, 0xcd, 0x17, 0x03, 0x38, 0x05, - 0xb7, 0xc2, 0x64, 0x02, 0x4f, 0xdd, 0x71, 0x07, - 0xc9, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, 0x15, - 0x00, 0x19, 0x46, 0x23, 0xcd, 0x11, 0x05, 0xcd, - 0x18, 0x05, 0xed, 0xa3, 0x20, 0xf9, 0xdd, 0x46, - 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, 0x56, - 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, 0x0b, - 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, 0x66, - 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, 0xcb, - 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x00, 0xfd, - 0xe9, 0x21, 0xcf, 0x05, 0xd5, 0x16, 0x00, 0xcb, - 0x2b, 0x19, 0xd1, 0x7e, 0xd3, 0xf7, 0xc9, 0x79, - 0x07, 0x5f, 0x16, 0x00, 0x21, 0x14, 0x06, 0x19, - 0x5e, 0x23, 0x56, 0xc5, 0xd5, 0x11, 0x88, 0x06, - 0xcd, 0xba, 0x01, 0x3e, 0x41, 0xdd, 0x86, 0x00, - 0xcd, 0xc3, 0x01, 0x11, 0x7b, 0x00, 0xcd, 0xba, - 0x01, 0xd1, 0xcd, 0xba, 0x01, 0xcd, 0x52, 0x03, - 0xc1, 0xc9, 0xcd, 0xba, 0x01, 0xcd, 0x78, 0x03, - 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0x78, 0x00, 0xc3, - 0xba, 0x01, 0x11, 0x9f, 0x06, 0xcd, 0xba, 0x01, - 0xcd, 0x78, 0x03, 0xe6, 0xdf, 0x5f, 0xfe, 0x41, - 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, 0xd6, - 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0xc3, 0x01, - 0x11, 0x78, 0x00, 0xcd, 0xba, 0x01, 0xf1, 0xc9, - 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, 0x19, 0xcd, - 0xd2, 0x01, 0xe1, 0xc9, 0xe6, 0x20, 0x28, 0x36, - 0xdb, 0xfa, 0xfe, 0xf0, 0x28, 0x0b, 0x1b, 0x7b, - 0xb2, 0x28, 0x2d, 0xdb, 0xfa, 0xfe, 0xf0, 0x20, - 0xeb, 0xed, 0xa2, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, - 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, - 0x28, 0x14, 0xed, 0xa2, 0x20, 0xf4, 0x1d, 0xf2, - 0x9d, 0x03, 0xd1, 0x15, 0xd5, 0xf2, 0x9d, 0x03, - 0xfb, 0x76, 0xdb, 0xf8, 0xed, 0xa2, 0xd1, 0xc9, - 0x3e, 0x08, 0xd3, 0xf7, 0xdb, 0xf5, 0xdb, 0xfa, - 0xcb, 0x6f, 0x20, 0xf8, 0x18, 0xf0, 0xe6, 0x20, - 0x28, 0xec, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, - 0x1b, 0x7b, 0xb2, 0x28, 0xe3, 0xdb, 0xfa, 0xfe, - 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, - 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, - 0xe6, 0x20, 0x28, 0xca, 0xed, 0xa3, 0x20, 0xf4, - 0x1d, 0xf2, 0xe7, 0x03, 0xd1, 0x15, 0xd5, 0xf2, - 0xe7, 0x03, 0xfb, 0x76, 0xdb, 0xf8, 0xed, 0xa3, - 0xd1, 0xc9, 0x1d, 0x15, 0xc0, 0x06, 0x01, 0xc9, - 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, - 0x0b, 0x86, 0xdd, 0x7e, 0x00, 0xf5, 0xfd, 0x7e, - 0x00, 0xdd, 0x77, 0x00, 0xcd, 0x33, 0x04, 0xf1, - 0xdd, 0x77, 0x00, 0xc9, 0x1e, 0x00, 0x18, 0x03, - 0xcd, 0x0a, 0x04, 0x3e, 0x00, 0xc5, 0xd5, 0x4f, - 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0xb8, 0x04, 0x7e, - 0xe6, 0x07, 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, - 0x28, 0x1b, 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, - 0x28, 0x0f, 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, - 0xf5, 0xd5, 0xe5, 0xc4, 0xa5, 0x04, 0xe1, 0xd1, - 0xf1, 0xcd, 0x4d, 0x05, 0xc1, 0xcb, 0x76, 0x28, - 0x0f, 0x3e, 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, - 0x27, 0xdd, 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xdb, - 0x3e, 0x07, 0xd3, 0xf7, 0xdb, 0xf5, 0xe6, 0x07, - 0x57, 0xa3, 0xf5, 0x7a, 0xb3, 0xd3, 0xf8, 0xfd, - 0x77, 0x12, 0xcd, 0xc9, 0x04, 0xdd, 0x7e, 0x08, - 0xcb, 0x59, 0x28, 0x03, 0xba, 0x28, 0x06, 0xcd, - 0x2a, 0x05, 0xf1, 0x37, 0xf5, 0xf1, 0x23, 0xcd, - 0xd1, 0x04, 0xd1, 0xc1, 0xc9, 0x3c, 0xcb, 0xf7, - 0xfd, 0x5e, 0x0f, 0xfd, 0x56, 0x10, 0x12, 0xfd, - 0x5e, 0x0d, 0xfd, 0x56, 0x0e, 0xc3, 0x42, 0x03, - 0xfd, 0xe5, 0xe1, 0x11, 0x1a, 0x00, 0x19, 0x57, - 0x07, 0x07, 0x07, 0x82, 0x5f, 0x16, 0x00, 0x19, - 0xc9, 0xe5, 0x11, 0x07, 0x00, 0x19, 0x56, 0xe1, - 0xc9, 0xfd, 0x46, 0x12, 0x0e, 0xf8, 0x56, 0x1e, - 0x00, 0x23, 0x30, 0x28, 0xed, 0x5e, 0x3e, 0x00, - 0xed, 0x47, 0x20, 0x0c, 0xfb, 0x1b, 0x7a, 0xb3, - 0x28, 0x08, 0x0e, 0xf8, 0xed, 0x41, 0x18, 0xf5, - 0x56, 0xfb, 0xed, 0x41, 0x18, 0xfc, 0xed, 0x46, - 0x33, 0x33, 0xcd, 0x76, 0x05, 0x7a, 0xbe, 0x30, - 0x04, 0x56, 0x18, 0x01, 0xc0, 0xed, 0x41, 0xed, - 0x41, 0x00, 0x1b, 0x7a, 0xb3, 0xc2, 0x05, 0x05, - 0xc9, 0xdb, 0xfa, 0xcb, 0x67, 0x20, 0xfa, 0xc9, - 0xdb, 0xfa, 0xe6, 0xc0, 0xfe, 0x80, 0x20, 0xf8, - 0xc9, 0xdb, 0xfa, 0xe6, 0xc0, 0xfe, 0xc0, 0x20, - 0xf8, 0xc9, 0xcd, 0x18, 0x05, 0x3e, 0x07, 0xb1, - 0xd3, 0xfb, 0xcd, 0x18, 0x05, 0x3e, 0x03, 0xa6, - 0xcb, 0x59, 0x28, 0x03, 0xdd, 0xb6, 0x09, 0xd3, - 0xfb, 0xcb, 0x59, 0xc8, 0xcd, 0x18, 0x05, 0xdd, - 0x7e, 0x08, 0xd3, 0xfb, 0xc9, 0xe5, 0x23, 0x23, - 0x23, 0xcd, 0x18, 0x05, 0x3e, 0x03, 0xd3, 0xfb, - 0x01, 0xfb, 0x02, 0xcd, 0x18, 0x05, 0xed, 0xa3, - 0x20, 0xf9, 0xe1, 0xc9, 0xcd, 0x18, 0x05, 0x3e, - 0x08, 0xd3, 0xfb, 0xcd, 0x21, 0x05, 0xdb, 0xfb, - 0xcd, 0x21, 0x05, 0xdb, 0xfb, 0xc9, 0xcd, 0x64, - 0x05, 0xe5, 0xd5, 0x11, 0x05, 0x00, 0x19, 0x77, - 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, 0xcb, 0x0f, - 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, 0x4e, 0xc0, - 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, 0xdd, 0xcb, - 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x6e, - 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, 0xc0, 0xdd, - 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, 0x0f, 0x46, - 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, 0xdd, 0xcb, - 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x5e, - 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, 0xc9, 0x08, - 0x09, 0x07, 0x0a, 0x06, 0x00, 0x00, 0x01, 0x01, - 0x14, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x93, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x09, 0x46, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x05, 0x1c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x9c, 0x01, 0xa6, 0x01, 0x01, 0xd8, 0x58, - 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x35, 0x06, - 0x28, 0x06, 0x46, 0x06, 0x46, 0x06, 0x52, 0x06, - 0x68, 0x06, 0x5d, 0x06, 0x68, 0x06, 0x79, 0x06, - 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, - 0x61, 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, - 0x63, 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, - 0x74, 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0xae, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, - 0x75, 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, - 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, - 0x44, 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, - 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, - 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, - 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, - 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, - 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, - 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, - 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, - 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, - 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, - 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, - 0x76, 0x2e, 0x20, 0x31, 0x2e, 0x33, 0x0d, 0x0a, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x20, 0x4d, - 0x6f, 0x72, 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, - 0x73, 0x69, 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, - 0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, - 0x73, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, - 0x3a, 0x20, 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x20, 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, - 0x0a, 0x00, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, - 0x20, 0x43, 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, - 0x6b, 0x65, 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, - 0x20, 0x44, 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, - 0x52, 0x4e, 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, - 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x00, 0x07, 0x07, 0x52, 0x4f, 0x4d, 0x20, 0x4d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, + 0xc3, 0x1d, 0x00, 0xc3, 0xba, 0x01, 0xc3, 0x10, + 0x04, 0xc3, 0xd3, 0x01, 0xc3, 0xe0, 0x01, 0xc3, + 0x64, 0x02, 0xc3, 0x93, 0x03, 0xc3, 0xdd, 0x03, + 0xc3, 0x96, 0x01, 0xd4, 0x05, 0xed, 0x46, 0x31, + 0x00, 0x00, 0xfd, 0x21, 0xf3, 0x05, 0xcd, 0x5b, + 0x00, 0x11, 0x0f, 0x07, 0xcd, 0xb1, 0x01, 0xcd, + 0x81, 0x00, 0xcd, 0xac, 0x00, 0xcd, 0x90, 0x00, + 0xcd, 0x00, 0xfc, 0x11, 0x8a, 0x07, 0xcd, 0xba, + 0x01, 0xcd, 0x78, 0x03, 0xfe, 0x0d, 0x20, 0xf9, + 0x11, 0x78, 0x00, 0xcd, 0xba, 0x01, 0xc3, 0x76, + 0x01, 0xcd, 0xba, 0x01, 0x11, 0xf3, 0x06, 0xcd, + 0xba, 0x01, 0x76, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, + 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, + 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, + 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, + 0x0d, 0x0a, 0x00, 0x3a, 0xa0, 0x00, 0xc5, 0xf6, + 0x04, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x07, 0xcd, + 0x9f, 0x00, 0x11, 0xd9, 0x07, 0x20, 0xc2, 0xc9, + 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, 0xcd, 0x9f, + 0x00, 0x11, 0xc6, 0x07, 0x20, 0xb3, 0xc9, 0xaf, + 0xf5, 0xf1, 0xae, 0x23, 0x0b, 0xf5, 0x78, 0xb1, + 0x20, 0xf7, 0xf1, 0xc9, 0x21, 0xc4, 0x00, 0x11, + 0x00, 0xfc, 0x01, 0xb2, 0x00, 0xed, 0xb0, 0x01, + 0x45, 0x03, 0xd5, 0xe1, 0x13, 0x36, 0xff, 0xed, + 0xb0, 0x36, 0x1f, 0xc9, 0xdb, 0xf6, 0x3a, 0x00, + 0x00, 0xfe, 0xc3, 0xd3, 0xf6, 0x20, 0x03, 0xc3, + 0x3b, 0x00, 0x11, 0x57, 0x07, 0xcd, 0xba, 0x01, + 0xdb, 0xf6, 0x21, 0x00, 0x00, 0x01, 0xff, 0xfb, + 0xcd, 0x31, 0xfc, 0xb7, 0xd3, 0xf6, 0x11, 0xc6, + 0x07, 0xc2, 0x51, 0x00, 0x11, 0x7b, 0x07, 0xcd, + 0xba, 0x01, 0xc3, 0x3b, 0x00, 0x22, 0xb2, 0xfc, + 0x21, 0x84, 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, + 0x18, 0x5e, 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, + 0x28, 0x05, 0xcd, 0x57, 0xfc, 0x18, 0x07, 0xdd, + 0x21, 0x77, 0xfc, 0xcd, 0x5b, 0xfc, 0xe1, 0x18, + 0xe2, 0xaf, 0xc9, 0xdd, 0x21, 0x79, 0xfc, 0x2a, + 0xb2, 0xfc, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, + 0x67, 0xcd, 0x75, 0xfc, 0x23, 0x23, 0x23, 0x78, + 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, + 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, + 0x01, 0xc9, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, 0xc9, + 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x41, + 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, 0x01, + 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, 0x41, + 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, 0x41, + 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, 0x42, + 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x21, 0xd4, + 0x05, 0x11, 0x00, 0xff, 0x01, 0x42, 0x00, 0xed, + 0xb0, 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, + 0xff, 0xcd, 0x33, 0x04, 0xcd, 0x64, 0x02, 0xdd, + 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, 0xd3, + 0x06, 0xc3, 0x51, 0x00, 0xdb, 0xfd, 0xcb, 0x47, + 0x28, 0xfa, 0x79, 0xd3, 0xfc, 0xc9, 0xdb, 0xfd, + 0xcb, 0x4f, 0x28, 0xfa, 0xdb, 0xfc, 0xe6, 0x7f, + 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xc3, 0x01, + 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xc3, 0x01, + 0x13, 0x18, 0xf7, 0x4f, 0xd5, 0xe5, 0xfd, 0x6e, + 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xd2, 0x01, 0xe1, + 0xd1, 0xc9, 0xe9, 0x21, 0x93, 0x03, 0xdd, 0x75, + 0x0a, 0xdd, 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, + 0x21, 0xdd, 0x03, 0xdd, 0x75, 0x0a, 0xdd, 0x74, + 0x0b, 0x0e, 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0xb8, + 0x04, 0x23, 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, + 0x16, 0xdd, 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, + 0x0f, 0x0f, 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, + 0x11, 0x80, 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, + 0xff, 0x11, 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, + 0x16, 0x01, 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, + 0xdd, 0x70, 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, + 0x06, 0xdd, 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, + 0xcb, 0x56, 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, + 0x28, 0x03, 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, + 0x07, 0x07, 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, + 0xdd, 0x70, 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, + 0xa6, 0xdd, 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, + 0x05, 0x00, 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, + 0x7e, 0xdd, 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x11, + 0x00, 0x03, 0xc5, 0xd5, 0x3e, 0x08, 0xcd, 0x35, + 0x04, 0xcd, 0x09, 0x03, 0xfd, 0xe5, 0xcd, 0xc9, + 0x02, 0xcd, 0xfd, 0x02, 0xfd, 0xe1, 0x06, 0x07, + 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, + 0x21, 0x05, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, + 0xdd, 0x7e, 0x0e, 0xe6, 0x40, 0x28, 0x2d, 0xcd, + 0x83, 0x05, 0x3e, 0x01, 0xb9, 0x28, 0x15, 0x3e, + 0x06, 0xb9, 0xcc, 0x0a, 0x04, 0x3e, 0x02, 0xb9, + 0xcc, 0x30, 0x04, 0x1c, 0x3e, 0x0b, 0xb8, 0xcc, + 0x2c, 0x04, 0x10, 0xb6, 0xdd, 0x7e, 0x07, 0xfe, + 0xff, 0x28, 0x0a, 0xcd, 0x17, 0x03, 0x38, 0x05, + 0xb7, 0xc2, 0x64, 0x02, 0x4f, 0xdd, 0x71, 0x07, + 0xc9, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, 0x15, + 0x00, 0x19, 0x46, 0x23, 0xcd, 0x11, 0x05, 0xcd, + 0x18, 0x05, 0xed, 0xa3, 0x20, 0xf9, 0xdd, 0x46, + 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, 0x56, + 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, 0x0b, + 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, 0x66, + 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, 0xcb, + 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x00, 0xfd, + 0xe9, 0x21, 0xcf, 0x05, 0xd5, 0x16, 0x00, 0xcb, + 0x2b, 0x19, 0xd1, 0x7e, 0xd3, 0xf7, 0xc9, 0x79, + 0x07, 0x5f, 0x16, 0x00, 0x21, 0x14, 0x06, 0x19, + 0x5e, 0x23, 0x56, 0xc5, 0xd5, 0x11, 0x88, 0x06, + 0xcd, 0xba, 0x01, 0x3e, 0x41, 0xdd, 0x86, 0x00, + 0xcd, 0xc3, 0x01, 0x11, 0x7b, 0x00, 0xcd, 0xba, + 0x01, 0xd1, 0xcd, 0xba, 0x01, 0xcd, 0x52, 0x03, + 0xc1, 0xc9, 0xcd, 0xba, 0x01, 0xcd, 0x78, 0x03, + 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0x78, 0x00, 0xc3, + 0xba, 0x01, 0x11, 0x9f, 0x06, 0xcd, 0xba, 0x01, + 0xcd, 0x78, 0x03, 0xe6, 0xdf, 0x5f, 0xfe, 0x41, + 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, 0xd6, + 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0xc3, 0x01, + 0x11, 0x78, 0x00, 0xcd, 0xba, 0x01, 0xf1, 0xc9, + 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, 0x19, 0xcd, + 0xd2, 0x01, 0xe1, 0xc9, 0xe6, 0x20, 0x28, 0x36, + 0xdb, 0xfa, 0xfe, 0xf0, 0x28, 0x0b, 0x1b, 0x7b, + 0xb2, 0x28, 0x2d, 0xdb, 0xfa, 0xfe, 0xf0, 0x20, + 0xeb, 0xed, 0xa2, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, + 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, + 0x28, 0x14, 0xed, 0xa2, 0x20, 0xf4, 0x1d, 0xf2, + 0x9d, 0x03, 0xd1, 0x15, 0xd5, 0xf2, 0x9d, 0x03, + 0xfb, 0x76, 0xdb, 0xf8, 0xed, 0xa2, 0xd1, 0xc9, + 0x3e, 0x08, 0xd3, 0xf7, 0xdb, 0xf5, 0xdb, 0xfa, + 0xcb, 0x6f, 0x20, 0xf8, 0x18, 0xf0, 0xe6, 0x20, + 0x28, 0xec, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, + 0x1b, 0x7b, 0xb2, 0x28, 0xe3, 0xdb, 0xfa, 0xfe, + 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, + 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, + 0xe6, 0x20, 0x28, 0xca, 0xed, 0xa3, 0x20, 0xf4, + 0x1d, 0xf2, 0xe7, 0x03, 0xd1, 0x15, 0xd5, 0xf2, + 0xe7, 0x03, 0xfb, 0x76, 0xdb, 0xf8, 0xed, 0xa3, + 0xd1, 0xc9, 0x1d, 0x15, 0xc0, 0x06, 0x01, 0xc9, + 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, + 0x0b, 0x86, 0xdd, 0x7e, 0x00, 0xf5, 0xfd, 0x7e, + 0x00, 0xdd, 0x77, 0x00, 0xcd, 0x33, 0x04, 0xf1, + 0xdd, 0x77, 0x00, 0xc9, 0x1e, 0x00, 0x18, 0x03, + 0xcd, 0x0a, 0x04, 0x3e, 0x00, 0xc5, 0xd5, 0x4f, + 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0xb8, 0x04, 0x7e, + 0xe6, 0x07, 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, + 0x28, 0x1b, 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, + 0x28, 0x0f, 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, + 0xf5, 0xd5, 0xe5, 0xc4, 0xa5, 0x04, 0xe1, 0xd1, + 0xf1, 0xcd, 0x4d, 0x05, 0xc1, 0xcb, 0x76, 0x28, + 0x0f, 0x3e, 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, + 0x27, 0xdd, 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xdb, + 0x3e, 0x07, 0xd3, 0xf7, 0xdb, 0xf5, 0xe6, 0x07, + 0x57, 0xa3, 0xf5, 0x7a, 0xb3, 0xd3, 0xf8, 0xfd, + 0x77, 0x12, 0xcd, 0xc9, 0x04, 0xdd, 0x7e, 0x08, + 0xcb, 0x59, 0x28, 0x03, 0xba, 0x28, 0x06, 0xcd, + 0x2a, 0x05, 0xf1, 0x37, 0xf5, 0xf1, 0x23, 0xcd, + 0xd1, 0x04, 0xd1, 0xc1, 0xc9, 0x3c, 0xcb, 0xf7, + 0xfd, 0x5e, 0x0f, 0xfd, 0x56, 0x10, 0x12, 0xfd, + 0x5e, 0x0d, 0xfd, 0x56, 0x0e, 0xc3, 0x42, 0x03, + 0xfd, 0xe5, 0xe1, 0x11, 0x1a, 0x00, 0x19, 0x57, + 0x07, 0x07, 0x07, 0x82, 0x5f, 0x16, 0x00, 0x19, + 0xc9, 0xe5, 0x11, 0x07, 0x00, 0x19, 0x56, 0xe1, + 0xc9, 0xfd, 0x46, 0x12, 0x0e, 0xf8, 0x56, 0x1e, + 0x00, 0x23, 0x30, 0x28, 0xed, 0x5e, 0x3e, 0x00, + 0xed, 0x47, 0x20, 0x0c, 0xfb, 0x1b, 0x7a, 0xb3, + 0x28, 0x08, 0x0e, 0xf8, 0xed, 0x41, 0x18, 0xf5, + 0x56, 0xfb, 0xed, 0x41, 0x18, 0xfc, 0xed, 0x46, + 0x33, 0x33, 0xcd, 0x76, 0x05, 0x7a, 0xbe, 0x30, + 0x04, 0x56, 0x18, 0x01, 0xc0, 0xed, 0x41, 0xed, + 0x41, 0x00, 0x1b, 0x7a, 0xb3, 0xc2, 0x05, 0x05, + 0xc9, 0xdb, 0xfa, 0xcb, 0x67, 0x20, 0xfa, 0xc9, + 0xdb, 0xfa, 0xe6, 0xc0, 0xfe, 0x80, 0x20, 0xf8, + 0xc9, 0xdb, 0xfa, 0xe6, 0xc0, 0xfe, 0xc0, 0x20, + 0xf8, 0xc9, 0xcd, 0x18, 0x05, 0x3e, 0x07, 0xb1, + 0xd3, 0xfb, 0xcd, 0x18, 0x05, 0x3e, 0x03, 0xa6, + 0xcb, 0x59, 0x28, 0x03, 0xdd, 0xb6, 0x09, 0xd3, + 0xfb, 0xcb, 0x59, 0xc8, 0xcd, 0x18, 0x05, 0xdd, + 0x7e, 0x08, 0xd3, 0xfb, 0xc9, 0xe5, 0x23, 0x23, + 0x23, 0xcd, 0x18, 0x05, 0x3e, 0x03, 0xd3, 0xfb, + 0x01, 0xfb, 0x02, 0xcd, 0x18, 0x05, 0xed, 0xa3, + 0x20, 0xf9, 0xe1, 0xc9, 0xcd, 0x18, 0x05, 0x3e, + 0x08, 0xd3, 0xfb, 0xcd, 0x21, 0x05, 0xdb, 0xfb, + 0xcd, 0x21, 0x05, 0xdb, 0xfb, 0xc9, 0xcd, 0x64, + 0x05, 0xe5, 0xd5, 0x11, 0x05, 0x00, 0x19, 0x77, + 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, 0xcb, 0x0f, + 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, 0x4e, 0xc0, + 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, 0xdd, 0xcb, + 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x6e, + 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, 0xc0, 0xdd, + 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, 0x0f, 0x46, + 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, 0xdd, 0xcb, + 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x5e, + 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, 0xc9, 0x08, + 0x09, 0x07, 0x0a, 0x06, 0x00, 0x00, 0x01, 0x01, + 0x14, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x93, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x09, 0x46, 0x00, 0x00, 0x00, 0x01, 0x03, + 0x05, 0x1c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x9c, 0x01, 0xa6, 0x01, 0x01, 0xd8, 0x58, + 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x35, 0x06, + 0x28, 0x06, 0x46, 0x06, 0x46, 0x06, 0x52, 0x06, + 0x68, 0x06, 0x5d, 0x06, 0x68, 0x06, 0x79, 0x06, + 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, + 0x61, 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, + 0x74, 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0xae, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, + 0x75, 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, + 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, + 0x44, 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, + 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, + 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, + 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, + 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, + 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, + 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, + 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, + 0x76, 0x2e, 0x20, 0x31, 0x2e, 0x33, 0x0d, 0x0a, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x20, 0x4d, + 0x6f, 0x72, 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, + 0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, + 0x3a, 0x20, 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x20, 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, + 0x0a, 0x00, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x20, 0x43, 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, + 0x6b, 0x65, 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, + 0x20, 0x44, 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, + 0x52, 0x4e, 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, + 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x00, 0x07, 0x07, 0x52, 0x4f, 0x4d, 0x20, 0x4d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, }; /* MD3 2.3 ROM is 4096 bytes */ static uint8 mmd_rom_23[MMD_ROM_SIZE] = { - 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x5d, - 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, - 0x92, 0x03, 0xc3, 0xd3, 0x04, 0xc3, 0x2a, 0x05, - 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, - 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, - 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, - 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, - 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, - 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, - 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, - 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, - 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, - 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, - 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x72, - 0x06, 0x91, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, - 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, - 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, - 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, - 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, - 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, - 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, - 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, - 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, - 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, - 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, - 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, - 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, - 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, - 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, - 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, - 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, - 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, - 0x40, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, - 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, - 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, - 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, - 0x01, 0xcd, 0xb6, 0x04, 0x11, 0xab, 0x0e, 0xcd, - 0xc3, 0x01, 0xcd, 0x70, 0x05, 0xcd, 0x92, 0x03, - 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, - 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, - 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, - 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, - 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, - 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, - 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, - 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, - 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, - 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, - 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, - 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, - 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, - 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, - 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, - 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, - 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, - 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, - 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, - 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, - 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, - 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, - 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, - 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, - 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, - 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, - 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, - 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, - 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, - 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, - 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, - 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x33, 0x06, - 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, - 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, - 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, - 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, - 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, - 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, - 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, - 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, - 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, - 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, - 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, - 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, - 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, - 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, - 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, - 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, - 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, - 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, - 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, - 0xc9, 0x21, 0xd3, 0x04, 0xdd, 0x75, 0x0a, 0xdd, - 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x2a, - 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, - 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x33, 0x06, 0x23, - 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, - 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, - 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, - 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, - 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, - 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, - 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, - 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, - 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, - 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, - 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, - 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, - 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, - 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, - 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, - 0xd5, 0xcd, 0x74, 0x05, 0xfd, 0xe5, 0xcd, 0x0f, - 0x04, 0xcd, 0x43, 0x04, 0xfd, 0xe1, 0x06, 0x07, - 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, - 0xa6, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, - 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, - 0x0d, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, - 0x06, 0xb9, 0xcc, 0x57, 0x05, 0x3e, 0x02, 0xb9, - 0xcc, 0x6c, 0x05, 0x3e, 0x05, 0xb9, 0xcc, 0xfa, - 0x03, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, - 0x70, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, - 0xfe, 0x28, 0x0a, 0xcd, 0x4f, 0x04, 0x38, 0x05, - 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, - 0x79, 0xc9, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, - 0xf5, 0xdd, 0x36, 0x08, 0x03, 0xcd, 0x74, 0x05, - 0xf1, 0xdd, 0x77, 0x08, 0xc3, 0x6c, 0x05, 0x0e, - 0xfb, 0xdd, 0xe5, 0xe1, 0x11, 0x15, 0x00, 0x19, - 0x46, 0x23, 0xcd, 0x90, 0x06, 0xcd, 0x9d, 0x06, - 0xed, 0xa3, 0x20, 0xf9, 0xdd, 0x46, 0x0c, 0xdd, - 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, 0x56, 0x03, 0x15, - 0xdd, 0x6e, 0x0a, 0xdd, 0x66, 0x0b, 0xe5, 0xfd, - 0xe1, 0xdd, 0x6e, 0x05, 0xdd, 0x66, 0x06, 0xc9, - 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, 0xcb, 0x6f, 0x28, - 0xf7, 0xd5, 0x11, 0x00, 0x00, 0xfd, 0xe9, 0x79, - 0x07, 0x5f, 0x16, 0x00, 0x21, 0x0c, 0x0f, 0x19, - 0x5e, 0x23, 0x56, 0xc5, 0xd5, 0x11, 0xb0, 0x0b, - 0xcd, 0xc3, 0x01, 0x3e, 0x41, 0xdd, 0x86, 0x00, - 0xcd, 0xcc, 0x01, 0x11, 0xae, 0x0e, 0xcd, 0xc3, - 0x01, 0xd1, 0xcd, 0xc3, 0x01, 0x3e, 0xff, 0xdd, - 0xbe, 0x07, 0x37, 0xc4, 0x90, 0x04, 0xc1, 0xc9, - 0xcd, 0xc3, 0x01, 0xcd, 0xb6, 0x04, 0xfe, 0x0d, - 0x20, 0xf9, 0x11, 0xab, 0x0e, 0xc3, 0xc3, 0x01, - 0x11, 0xc7, 0x0b, 0xcd, 0xc3, 0x01, 0xcd, 0xb6, - 0x04, 0xe6, 0xdf, 0x5f, 0xfe, 0x41, 0x37, 0x28, - 0x08, 0xfe, 0x52, 0x28, 0x04, 0xd6, 0x49, 0x20, - 0xed, 0xf5, 0x7b, 0xcd, 0xcc, 0x01, 0x11, 0xab, - 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc9, 0xc5, 0xe5, - 0xfd, 0x6e, 0x18, 0xfd, 0x66, 0x19, 0xcd, 0xdd, - 0x01, 0xe1, 0xc1, 0xc9, 0xe6, 0x20, 0x28, 0x36, - 0xdb, 0xfa, 0xfe, 0xf0, 0x28, 0x0b, 0x1b, 0x7b, - 0xb2, 0x28, 0x2d, 0xdb, 0xfa, 0xfe, 0xf0, 0x20, - 0xeb, 0xed, 0xa2, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, - 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, - 0x28, 0x14, 0xed, 0xa2, 0x20, 0xf4, 0x1d, 0xf2, - 0xdd, 0x04, 0xd1, 0x15, 0xd5, 0xf2, 0xdd, 0x04, - 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa2, 0xd1, 0xc9, - 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, 0xe5, 0xc5, 0x0e, - 0xf7, 0xfd, 0x7e, 0x12, 0x47, 0xcb, 0xdf, 0xed, - 0x79, 0xdb, 0xfa, 0xcb, 0x6f, 0x20, 0xfa, 0xed, - 0x41, 0xc1, 0xe9, 0xe6, 0x20, 0x28, 0xdf, 0xdb, - 0xfa, 0xfe, 0xb0, 0x28, 0x0b, 0x1b, 0x7b, 0xb2, - 0x28, 0xd6, 0xdb, 0xfa, 0xfe, 0xb0, 0x20, 0xeb, - 0xed, 0xa3, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, 0x01, - 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, 0x28, - 0xbd, 0xed, 0xa3, 0x20, 0xf4, 0x1d, 0xf2, 0x34, - 0x05, 0xd1, 0x15, 0xd5, 0xf2, 0x34, 0x05, 0xfb, - 0x76, 0xdb, 0xf7, 0xed, 0xa3, 0xd1, 0xc9, 0x04, - 0x15, 0xc0, 0x06, 0x01, 0xc9, 0xfd, 0xcb, 0x0b, - 0x4e, 0x20, 0x04, 0xfd, 0xcb, 0x0b, 0x86, 0xfd, - 0x36, 0x01, 0x00, 0xc9, 0xcd, 0x57, 0x05, 0xc8, - 0x3e, 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, - 0x4f, 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x33, 0x06, - 0x7e, 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, - 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, - 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, - 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, - 0xe5, 0xc4, 0x20, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, - 0xd2, 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, - 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, - 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, - 0xe6, 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, - 0x47, 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, - 0xb3, 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x44, - 0x06, 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, - 0xb7, 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, - 0x28, 0x06, 0xcd, 0xaf, 0x06, 0xf1, 0x37, 0xf5, - 0xf1, 0xc5, 0xe5, 0xcd, 0x4c, 0x06, 0xe1, 0xc1, - 0xcb, 0x59, 0xcc, 0x00, 0x06, 0xd1, 0xc1, 0xc9, - 0xcd, 0x9d, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, - 0x9d, 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, - 0xa6, 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, - 0xaf, 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, - 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, - 0x10, 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, - 0xc3, 0x80, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, - 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, - 0x16, 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, - 0x19, 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, - 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, - 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, - 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, - 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, - 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x00, - 0x07, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, - 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, - 0xb3, 0xc2, 0x81, 0x06, 0xc9, 0xcd, 0xe9, 0x06, - 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, - 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, - 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, - 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, - 0x9d, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, - 0x9d, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, - 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, - 0xc8, 0xcd, 0x9d, 0x06, 0xdd, 0x7e, 0x08, 0xd3, - 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0x9d, - 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, - 0xcd, 0x9d, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, - 0xc9, 0xcd, 0x9d, 0x06, 0x3e, 0x08, 0xd3, 0xfb, - 0xcd, 0xa6, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, - 0x80, 0xc8, 0xcd, 0xa6, 0x06, 0xdb, 0xfb, 0xc9, - 0xcd, 0xe9, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, - 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, - 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, - 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, - 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, - 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, - 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, - 0xdd, 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, - 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, - 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x23, 0xff, - 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, - 0xb6, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, - 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, - 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, - 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, - 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, - 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, - 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, - 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, - 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, - 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, - 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, - 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, - 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, - 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, - 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, - 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, - 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, - 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, - 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, - 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, - 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, - 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, - 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, - 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, - 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, - 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, - 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, - 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, - 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, - 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, - 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, - 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, - 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, - 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, - 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, - 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, - 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, - 0xb6, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, - 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, - 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, - 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, - 0xc3, 0x01, 0xcd, 0xb6, 0x04, 0x11, 0xab, 0x0e, - 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, - 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, - 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, - 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, - 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, - 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, - 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, - 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, - 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, - 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, - 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, - 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, - 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, - 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, - 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, - 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, - 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, - 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, - 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, - 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, - 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, - 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, - 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, - 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, - 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, - 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, - 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, - 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, - 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, - 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, - 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, - 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, - 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, - 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, - 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, - 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, - 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, - 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, - 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, - 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, - 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, - 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, - 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, - 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, - 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, - 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, - 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, - 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, - 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, - 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, - 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, - 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, - 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, - 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, - 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, - 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, - 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, - 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, - 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, - 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, - 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, - 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, - 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, - 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, - 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, - 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, - 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, - 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, - 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, - 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, - 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, - 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, - 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, - 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, - 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, - 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, - 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, - 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, - 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, - 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, - 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, - 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, - 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, - 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, - 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, - 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, - 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, - 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, - 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, - 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, - 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, - 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, - 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, - 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, - 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, - 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, - 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, - 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, - 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, - 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, - 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, - 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, - 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, - 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, - 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, - 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, - 0x00, 0x00, 0x00, 0xd3, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, - 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, - 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, - 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, - 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, - 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, - 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, - 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, - 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x5d, + 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, + 0x92, 0x03, 0xc3, 0xd3, 0x04, 0xc3, 0x2a, 0x05, + 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, + 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, + 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, + 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, + 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, + 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, + 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, + 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, + 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, + 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, + 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x72, + 0x06, 0x91, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, + 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, + 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, + 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, + 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, + 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, + 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, + 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, + 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, + 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, + 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, + 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, + 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, + 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, + 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, + 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, + 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, + 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, + 0x40, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, + 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, + 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, + 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, + 0x01, 0xcd, 0xb6, 0x04, 0x11, 0xab, 0x0e, 0xcd, + 0xc3, 0x01, 0xcd, 0x70, 0x05, 0xcd, 0x92, 0x03, + 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, + 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, + 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, + 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, + 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, + 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, + 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, + 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, + 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, + 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, + 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, + 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, + 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, + 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, + 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, + 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, + 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, + 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, + 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, + 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, + 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, + 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, + 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, + 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, + 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, + 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, + 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, + 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, + 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, + 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, + 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, + 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x33, 0x06, + 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, + 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, + 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, + 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, + 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, + 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, + 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, + 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, + 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, + 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, + 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, + 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, + 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, + 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, + 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, + 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, + 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, + 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, + 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, + 0xc9, 0x21, 0xd3, 0x04, 0xdd, 0x75, 0x0a, 0xdd, + 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x2a, + 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, + 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x33, 0x06, 0x23, + 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, + 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, + 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, + 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, + 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, + 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, + 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, + 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, + 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, + 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, + 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, + 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, + 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, + 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, + 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, + 0xd5, 0xcd, 0x74, 0x05, 0xfd, 0xe5, 0xcd, 0x0f, + 0x04, 0xcd, 0x43, 0x04, 0xfd, 0xe1, 0x06, 0x07, + 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, + 0xa6, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, + 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, + 0x0d, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, + 0x06, 0xb9, 0xcc, 0x57, 0x05, 0x3e, 0x02, 0xb9, + 0xcc, 0x6c, 0x05, 0x3e, 0x05, 0xb9, 0xcc, 0xfa, + 0x03, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, + 0x70, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, + 0xfe, 0x28, 0x0a, 0xcd, 0x4f, 0x04, 0x38, 0x05, + 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, + 0x79, 0xc9, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, + 0xf5, 0xdd, 0x36, 0x08, 0x03, 0xcd, 0x74, 0x05, + 0xf1, 0xdd, 0x77, 0x08, 0xc3, 0x6c, 0x05, 0x0e, + 0xfb, 0xdd, 0xe5, 0xe1, 0x11, 0x15, 0x00, 0x19, + 0x46, 0x23, 0xcd, 0x90, 0x06, 0xcd, 0x9d, 0x06, + 0xed, 0xa3, 0x20, 0xf9, 0xdd, 0x46, 0x0c, 0xdd, + 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, 0x56, 0x03, 0x15, + 0xdd, 0x6e, 0x0a, 0xdd, 0x66, 0x0b, 0xe5, 0xfd, + 0xe1, 0xdd, 0x6e, 0x05, 0xdd, 0x66, 0x06, 0xc9, + 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, 0xcb, 0x6f, 0x28, + 0xf7, 0xd5, 0x11, 0x00, 0x00, 0xfd, 0xe9, 0x79, + 0x07, 0x5f, 0x16, 0x00, 0x21, 0x0c, 0x0f, 0x19, + 0x5e, 0x23, 0x56, 0xc5, 0xd5, 0x11, 0xb0, 0x0b, + 0xcd, 0xc3, 0x01, 0x3e, 0x41, 0xdd, 0x86, 0x00, + 0xcd, 0xcc, 0x01, 0x11, 0xae, 0x0e, 0xcd, 0xc3, + 0x01, 0xd1, 0xcd, 0xc3, 0x01, 0x3e, 0xff, 0xdd, + 0xbe, 0x07, 0x37, 0xc4, 0x90, 0x04, 0xc1, 0xc9, + 0xcd, 0xc3, 0x01, 0xcd, 0xb6, 0x04, 0xfe, 0x0d, + 0x20, 0xf9, 0x11, 0xab, 0x0e, 0xc3, 0xc3, 0x01, + 0x11, 0xc7, 0x0b, 0xcd, 0xc3, 0x01, 0xcd, 0xb6, + 0x04, 0xe6, 0xdf, 0x5f, 0xfe, 0x41, 0x37, 0x28, + 0x08, 0xfe, 0x52, 0x28, 0x04, 0xd6, 0x49, 0x20, + 0xed, 0xf5, 0x7b, 0xcd, 0xcc, 0x01, 0x11, 0xab, + 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc9, 0xc5, 0xe5, + 0xfd, 0x6e, 0x18, 0xfd, 0x66, 0x19, 0xcd, 0xdd, + 0x01, 0xe1, 0xc1, 0xc9, 0xe6, 0x20, 0x28, 0x36, + 0xdb, 0xfa, 0xfe, 0xf0, 0x28, 0x0b, 0x1b, 0x7b, + 0xb2, 0x28, 0x2d, 0xdb, 0xfa, 0xfe, 0xf0, 0x20, + 0xeb, 0xed, 0xa2, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, + 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, + 0x28, 0x14, 0xed, 0xa2, 0x20, 0xf4, 0x1d, 0xf2, + 0xdd, 0x04, 0xd1, 0x15, 0xd5, 0xf2, 0xdd, 0x04, + 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa2, 0xd1, 0xc9, + 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, 0xe5, 0xc5, 0x0e, + 0xf7, 0xfd, 0x7e, 0x12, 0x47, 0xcb, 0xdf, 0xed, + 0x79, 0xdb, 0xfa, 0xcb, 0x6f, 0x20, 0xfa, 0xed, + 0x41, 0xc1, 0xe9, 0xe6, 0x20, 0x28, 0xdf, 0xdb, + 0xfa, 0xfe, 0xb0, 0x28, 0x0b, 0x1b, 0x7b, 0xb2, + 0x28, 0xd6, 0xdb, 0xfa, 0xfe, 0xb0, 0x20, 0xeb, + 0xed, 0xa3, 0xd1, 0xd5, 0x7b, 0xb2, 0x20, 0x01, + 0x05, 0xfb, 0x76, 0xdb, 0xfa, 0xe6, 0x20, 0x28, + 0xbd, 0xed, 0xa3, 0x20, 0xf4, 0x1d, 0xf2, 0x34, + 0x05, 0xd1, 0x15, 0xd5, 0xf2, 0x34, 0x05, 0xfb, + 0x76, 0xdb, 0xf7, 0xed, 0xa3, 0xd1, 0xc9, 0x04, + 0x15, 0xc0, 0x06, 0x01, 0xc9, 0xfd, 0xcb, 0x0b, + 0x4e, 0x20, 0x04, 0xfd, 0xcb, 0x0b, 0x86, 0xfd, + 0x36, 0x01, 0x00, 0xc9, 0xcd, 0x57, 0x05, 0xc8, + 0x3e, 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, + 0x4f, 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x33, 0x06, + 0x7e, 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, + 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, + 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, + 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, + 0xe5, 0xc4, 0x20, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, + 0xd2, 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, + 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, + 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, + 0xe6, 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, + 0x47, 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, + 0xb3, 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x44, + 0x06, 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, + 0xb7, 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, + 0x28, 0x06, 0xcd, 0xaf, 0x06, 0xf1, 0x37, 0xf5, + 0xf1, 0xc5, 0xe5, 0xcd, 0x4c, 0x06, 0xe1, 0xc1, + 0xcb, 0x59, 0xcc, 0x00, 0x06, 0xd1, 0xc1, 0xc9, + 0xcd, 0x9d, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, + 0x9d, 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, + 0xa6, 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, + 0xaf, 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, + 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, + 0x10, 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, + 0xc3, 0x80, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, + 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, + 0x16, 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, + 0x19, 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, + 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, + 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, + 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, + 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, + 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x00, + 0x07, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, + 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, + 0xb3, 0xc2, 0x81, 0x06, 0xc9, 0xcd, 0xe9, 0x06, + 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, + 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, + 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, + 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, + 0x9d, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, + 0x9d, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, + 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, + 0xc8, 0xcd, 0x9d, 0x06, 0xdd, 0x7e, 0x08, 0xd3, + 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0x9d, + 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, + 0xcd, 0x9d, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, + 0xc9, 0xcd, 0x9d, 0x06, 0x3e, 0x08, 0xd3, 0xfb, + 0xcd, 0xa6, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, + 0x80, 0xc8, 0xcd, 0xa6, 0x06, 0xdb, 0xfb, 0xc9, + 0xcd, 0xe9, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, + 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, + 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, + 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, + 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, + 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, + 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, + 0xdd, 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, + 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, + 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x23, 0xff, + 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, + 0xb6, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, + 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, + 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, + 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, + 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, + 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, + 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, + 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, + 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, + 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, + 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, + 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, + 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, + 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, + 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, + 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, + 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, + 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, + 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, + 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, + 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, + 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, + 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, + 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, + 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, + 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, + 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, + 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, + 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, + 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, + 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, + 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, + 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, + 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, + 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, + 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, + 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, + 0xb6, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, + 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, + 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, + 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, + 0xc3, 0x01, 0xcd, 0xb6, 0x04, 0x11, 0xab, 0x0e, + 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, + 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, + 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, + 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, + 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, + 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, + 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, + 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, + 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, + 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, + 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, + 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, + 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, + 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, + 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, + 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, + 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, + 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, + 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, + 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, + 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, + 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, + 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, + 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, + 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, + 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, + 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, + 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, + 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, + 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, + 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, + 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, + 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, + 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, + 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, + 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, + 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, + 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, + 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, + 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, + 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, + 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, + 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, + 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, + 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, + 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, + 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, + 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, + 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, + 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, + 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, + 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, + 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, + 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, + 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, + 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, + 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, + 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, + 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, + 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, + 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x33, 0x0d, 0x0a, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, + 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, + 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, + 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, + 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, + 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, + 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, + 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, + 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, + 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, + 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, + 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, + 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, + 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, + 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, + 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, + 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, + 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, + 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, + 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, + 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, + 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, + 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, + 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, + 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, + 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, + 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, + 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, + 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, + 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, + 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, + 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, + 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, + 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0xd3, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, + 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, + 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, + 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, + 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, + 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, + 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, + 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, + 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; /* MD3 2.4 ROM is 4096 bytes */ static uint8 mmd_rom_24[MMD_ROM_SIZE] = { - 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x70, - 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, - 0x92, 0x03, 0xc3, 0xe6, 0x04, 0xc3, 0x3d, 0x05, - 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, - 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, - 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, - 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, - 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, - 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, - 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, - 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, - 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, - 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, - 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, - 0x06, 0xdd, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, - 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, - 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, - 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, - 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, - 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, - 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, - 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, - 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, - 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, - 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, - 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, - 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, - 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, - 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, - 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, - 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, - 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, - 0x60, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, - 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, - 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, - 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, - 0x01, 0xcd, 0xc9, 0x04, 0x11, 0xab, 0x0e, 0xcd, - 0xc3, 0x01, 0xcd, 0x7f, 0x05, 0xcd, 0x92, 0x03, - 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, - 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, - 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, - 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, - 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, - 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, - 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, - 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, - 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, - 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, - 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, - 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, - 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, - 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, - 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, - 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, - 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, - 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, - 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, - 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, - 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, - 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, - 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, - 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, - 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, - 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, - 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, - 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, - 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, - 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, - 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, - 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x42, 0x06, - 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, - 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, - 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, - 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, - 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, - 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, - 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, - 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, - 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, - 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, - 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, - 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, - 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, - 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, - 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, - 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, - 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, - 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, - 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, - 0xc9, 0x21, 0xe6, 0x04, 0xdd, 0x75, 0x0a, 0xdd, - 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x3d, - 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, - 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x42, 0x06, 0x23, - 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, - 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, - 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, - 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, - 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, - 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, - 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, - 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, - 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, - 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, - 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, - 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, - 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, - 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, - 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, - 0xd5, 0xcd, 0x83, 0x05, 0xfd, 0xe5, 0xcd, 0x22, - 0x04, 0xcd, 0x56, 0x04, 0xfd, 0xe1, 0x06, 0x07, - 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, - 0xb5, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, - 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, - 0x1c, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, - 0x06, 0xb9, 0xcc, 0x6a, 0x05, 0x3e, 0x02, 0xb9, - 0xcc, 0xfa, 0x03, 0x3e, 0x05, 0xb9, 0xcc, 0x09, - 0x04, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, - 0x7f, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, - 0xfe, 0x28, 0x0a, 0xcd, 0x62, 0x04, 0x38, 0x05, - 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, - 0x79, 0xc9, 0xcd, 0x6a, 0x05, 0xc8, 0xcd, 0x7f, - 0x05, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0x18, - 0x0a, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0xcd, - 0x6a, 0x05, 0xc8, 0xf5, 0xdd, 0x36, 0x08, 0x03, - 0xcd, 0x83, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, - 0x7f, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, - 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0x9f, 0x06, - 0xcd, 0xac, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xdd, - 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, - 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, - 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, - 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, - 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x00, - 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, 0x21, - 0x0c, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, 0xd5, - 0x11, 0xb0, 0x0b, 0xcd, 0xc3, 0x01, 0x3e, 0x41, - 0xdd, 0x86, 0x00, 0xcd, 0xcc, 0x01, 0x11, 0xae, - 0x0e, 0xcd, 0xc3, 0x01, 0xd1, 0xcd, 0xc3, 0x01, - 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, 0xa3, - 0x04, 0xc1, 0xc9, 0xcd, 0xc3, 0x01, 0xcd, 0xc9, - 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0xab, 0x0e, - 0xc3, 0xc3, 0x01, 0x11, 0xc7, 0x0b, 0xcd, 0xc3, - 0x01, 0xcd, 0xc9, 0x04, 0xe6, 0xdf, 0x5f, 0xfe, - 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, - 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0xcc, - 0x01, 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, - 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, - 0x19, 0xcd, 0xdd, 0x01, 0xe1, 0xc1, 0xc9, 0xe6, - 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, 0x28, - 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, 0xfa, - 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, 0xd5, - 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, - 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, 0x20, - 0xf4, 0x1d, 0xf2, 0xf0, 0x04, 0xd1, 0x15, 0xd5, - 0xf2, 0xf0, 0x04, 0xfb, 0x76, 0xdb, 0xf7, 0xed, - 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, - 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, 0x47, - 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, 0x6f, - 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, 0x20, - 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, - 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, 0xfe, - 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, - 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, - 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, 0xf4, - 0x1d, 0xf2, 0x47, 0x05, 0xd1, 0x15, 0xd5, 0xf2, - 0x47, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa3, - 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, 0xc9, - 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, - 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, 0x3e, - 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, 0x4f, - 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x42, 0x06, 0x7e, - 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, 0x5f, - 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, 0xfd, - 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, 0xfd, - 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, 0xe5, - 0xc4, 0x2f, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, 0xe1, - 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, 0x13, - 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, 0xbe, - 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, 0xe6, - 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, 0x47, - 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, 0xb3, - 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x53, 0x06, - 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, 0xb7, - 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, 0x28, - 0x06, 0xcd, 0xbe, 0x06, 0xf1, 0x37, 0xf5, 0xf1, - 0xc5, 0xe5, 0xcd, 0x5b, 0x06, 0xe1, 0xc1, 0xcb, - 0x59, 0xcc, 0x0f, 0x06, 0xd1, 0xc1, 0xc9, 0xcd, - 0xac, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, 0xac, - 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, 0xb5, - 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, 0xbe, - 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, 0x3c, - 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, 0x10, - 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, 0xc3, - 0x93, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, 0x00, - 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, 0x16, - 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, 0x19, - 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, 0x0e, - 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, 0xed, - 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, 0xfb, - 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, 0xed, - 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, 0x18, - 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x0f, 0x07, - 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, 0xc0, - 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, 0xb3, - 0xc2, 0x90, 0x06, 0xc9, 0xcd, 0xf8, 0x06, 0xdb, - 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, 0xcb, - 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, 0xc0, - 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, 0xe6, - 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, 0xac, - 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, 0xac, - 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, 0x03, - 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, 0xc8, - 0xcd, 0xac, 0x06, 0xdd, 0x7e, 0x08, 0xd3, 0xfb, - 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0xac, 0x06, - 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, 0xcd, - 0xac, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, 0xc9, - 0xcd, 0xac, 0x06, 0x3e, 0x08, 0xd3, 0xfb, 0xcd, - 0xb5, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, 0x80, - 0xc8, 0xcd, 0xb5, 0x06, 0xdb, 0xfb, 0xc9, 0xcd, - 0xf8, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, 0x19, - 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, 0xcb, - 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, 0x4e, - 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, 0xdd, - 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, - 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, 0xc0, - 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, 0x0f, - 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, 0xdd, - 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, - 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, 0xc0, - 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, 0xdd, - 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x24, 0xff, - 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, - 0xc9, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, - 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, - 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, - 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, - 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, - 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, - 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, - 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, - 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, - 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, - 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, - 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, - 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, - 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, - 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, - 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, - 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, - 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, - 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, - 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, - 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, - 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, - 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, - 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, - 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, - 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, - 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, - 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, - 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, - 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, - 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, - 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, - 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, - 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, - 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, - 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, - 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, - 0xc9, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, - 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, - 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, - 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, - 0xc3, 0x01, 0xcd, 0xc9, 0x04, 0x11, 0xab, 0x0e, - 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, - 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, - 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, - 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, - 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, - 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, - 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, - 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, - 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, - 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, - 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, - 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, - 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, - 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, - 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, - 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, - 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, - 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, - 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, - 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, - 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, - 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, - 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, - 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, - 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, - 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, - 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, - 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, - 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, - 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, - 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, - 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, - 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, - 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, - 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, - 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, - 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, - 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, - 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, - 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, - 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, - 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, - 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, - 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, - 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, - 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, - 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, - 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, - 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, - 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, - 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, - 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, - 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, - 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, - 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, - 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, - 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, - 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, - 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, - 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, - 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, - 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, - 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, - 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, - 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, - 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, - 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, - 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x34, 0x0d, 0x0a, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, - 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, - 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, - 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, - 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, - 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, - 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, - 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, - 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, - 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, - 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, - 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, - 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, - 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, - 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, - 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, - 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, - 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, - 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, - 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, - 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, - 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, - 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, - 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, - 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, - 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, - 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, - 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, - 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, - 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, - 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, - 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, - 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, - 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, - 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, - 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, - 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, - 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, - 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, - 0x00, 0x00, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, - 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, - 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, - 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, - 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, - 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, - 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, - 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, - 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x70, + 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, + 0x92, 0x03, 0xc3, 0xe6, 0x04, 0xc3, 0x3d, 0x05, + 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, + 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, + 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, + 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, + 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, + 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, + 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, + 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, + 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, + 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, + 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, + 0x06, 0xdd, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, + 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, + 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, + 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, + 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, + 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, + 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, + 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, + 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, + 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, + 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, + 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, + 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, + 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, + 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, + 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, + 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, + 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, + 0x60, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, + 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, + 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, + 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, + 0x01, 0xcd, 0xc9, 0x04, 0x11, 0xab, 0x0e, 0xcd, + 0xc3, 0x01, 0xcd, 0x7f, 0x05, 0xcd, 0x92, 0x03, + 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, + 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, + 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, + 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, + 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, + 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, + 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, + 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, + 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, + 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, + 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, + 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, + 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, + 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, + 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, + 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, + 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, + 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, + 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, + 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, + 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, + 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, + 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, + 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, + 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, + 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, + 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, + 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, + 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, + 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, + 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, + 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x42, 0x06, + 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, + 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, + 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, + 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, + 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, + 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, + 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, + 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, + 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, + 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, + 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, + 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, + 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, + 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, + 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, + 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, + 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, + 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, + 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, + 0xc9, 0x21, 0xe6, 0x04, 0xdd, 0x75, 0x0a, 0xdd, + 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x3d, + 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, + 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x42, 0x06, 0x23, + 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, + 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, + 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, + 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, + 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, + 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, + 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, + 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, + 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, + 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, + 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, + 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, + 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, + 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, + 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, + 0xd5, 0xcd, 0x83, 0x05, 0xfd, 0xe5, 0xcd, 0x22, + 0x04, 0xcd, 0x56, 0x04, 0xfd, 0xe1, 0x06, 0x07, + 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, + 0xb5, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, + 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, + 0x1c, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, + 0x06, 0xb9, 0xcc, 0x6a, 0x05, 0x3e, 0x02, 0xb9, + 0xcc, 0xfa, 0x03, 0x3e, 0x05, 0xb9, 0xcc, 0x09, + 0x04, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, + 0x7f, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, + 0xfe, 0x28, 0x0a, 0xcd, 0x62, 0x04, 0x38, 0x05, + 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, + 0x79, 0xc9, 0xcd, 0x6a, 0x05, 0xc8, 0xcd, 0x7f, + 0x05, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0x18, + 0x0a, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0xcd, + 0x6a, 0x05, 0xc8, 0xf5, 0xdd, 0x36, 0x08, 0x03, + 0xcd, 0x83, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, + 0x7f, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, + 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0x9f, 0x06, + 0xcd, 0xac, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xdd, + 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, + 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, + 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, + 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, + 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x00, + 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, 0x21, + 0x0c, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, 0xd5, + 0x11, 0xb0, 0x0b, 0xcd, 0xc3, 0x01, 0x3e, 0x41, + 0xdd, 0x86, 0x00, 0xcd, 0xcc, 0x01, 0x11, 0xae, + 0x0e, 0xcd, 0xc3, 0x01, 0xd1, 0xcd, 0xc3, 0x01, + 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, 0xa3, + 0x04, 0xc1, 0xc9, 0xcd, 0xc3, 0x01, 0xcd, 0xc9, + 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0xab, 0x0e, + 0xc3, 0xc3, 0x01, 0x11, 0xc7, 0x0b, 0xcd, 0xc3, + 0x01, 0xcd, 0xc9, 0x04, 0xe6, 0xdf, 0x5f, 0xfe, + 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, + 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0xcc, + 0x01, 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, + 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, + 0x19, 0xcd, 0xdd, 0x01, 0xe1, 0xc1, 0xc9, 0xe6, + 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, 0x28, + 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, 0xfa, + 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, 0xd5, + 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, + 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, 0x20, + 0xf4, 0x1d, 0xf2, 0xf0, 0x04, 0xd1, 0x15, 0xd5, + 0xf2, 0xf0, 0x04, 0xfb, 0x76, 0xdb, 0xf7, 0xed, + 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, + 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, 0x47, + 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, 0x6f, + 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, 0x20, + 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, + 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, 0xfe, + 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, + 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, + 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, 0xf4, + 0x1d, 0xf2, 0x47, 0x05, 0xd1, 0x15, 0xd5, 0xf2, + 0x47, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa3, + 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, 0xc9, + 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, + 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, 0x3e, + 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, 0x4f, + 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x42, 0x06, 0x7e, + 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, 0x5f, + 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, 0xfd, + 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, 0xfd, + 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, 0xe5, + 0xc4, 0x2f, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, 0xe1, + 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, 0x13, + 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, 0xbe, + 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, 0xe6, + 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, 0x47, + 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, 0xb3, + 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x53, 0x06, + 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, 0xb7, + 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, 0x28, + 0x06, 0xcd, 0xbe, 0x06, 0xf1, 0x37, 0xf5, 0xf1, + 0xc5, 0xe5, 0xcd, 0x5b, 0x06, 0xe1, 0xc1, 0xcb, + 0x59, 0xcc, 0x0f, 0x06, 0xd1, 0xc1, 0xc9, 0xcd, + 0xac, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, 0xac, + 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, 0xb5, + 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, 0xbe, + 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, 0x3c, + 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, 0x10, + 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, 0xc3, + 0x93, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, 0x00, + 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, 0x16, + 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, 0x19, + 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, 0x0e, + 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, 0xed, + 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, 0xfb, + 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, 0xed, + 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, 0x18, + 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x0f, 0x07, + 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, 0xc0, + 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, 0xb3, + 0xc2, 0x90, 0x06, 0xc9, 0xcd, 0xf8, 0x06, 0xdb, + 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, 0xcb, + 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, 0xc0, + 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, 0xe6, + 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, 0xac, + 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, 0xac, + 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, 0x03, + 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, 0xc8, + 0xcd, 0xac, 0x06, 0xdd, 0x7e, 0x08, 0xd3, 0xfb, + 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0xac, 0x06, + 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, 0xcd, + 0xac, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, 0xc9, + 0xcd, 0xac, 0x06, 0x3e, 0x08, 0xd3, 0xfb, 0xcd, + 0xb5, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, 0x80, + 0xc8, 0xcd, 0xb5, 0x06, 0xdb, 0xfb, 0xc9, 0xcd, + 0xf8, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, 0x19, + 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, 0xcb, + 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, 0x4e, + 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, 0xdd, + 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, + 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, 0xc0, + 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, 0x0f, + 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, 0xdd, + 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, + 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, 0xc0, + 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, 0xdd, + 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x24, 0xff, + 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, + 0xc9, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, + 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, + 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, + 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, + 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, + 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, + 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, + 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, + 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, + 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, + 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, + 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, + 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, + 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, + 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, + 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, + 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, + 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, + 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, + 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, + 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, + 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, + 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, + 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, + 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, + 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, + 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, + 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, + 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, + 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, + 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, + 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, + 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, + 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, + 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, + 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, + 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, + 0xc9, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, + 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, + 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, + 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, + 0xc3, 0x01, 0xcd, 0xc9, 0x04, 0x11, 0xab, 0x0e, + 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, + 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, + 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, + 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, + 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, + 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, + 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, + 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, + 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, + 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, + 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, + 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, + 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, + 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, + 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, + 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, + 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, + 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, + 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, + 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, + 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, + 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, + 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, + 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, + 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, + 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, + 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, + 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, + 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, + 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, + 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, + 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, + 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, + 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, + 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, + 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, + 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, + 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, + 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, + 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, + 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, + 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, + 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, + 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, + 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, + 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, + 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, + 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, + 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, + 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, + 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, + 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, + 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, + 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, + 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, + 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, + 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, + 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, + 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, + 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, + 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x34, 0x0d, 0x0a, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, + 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, + 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, + 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, + 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, + 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, + 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, + 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, + 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, + 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, + 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, + 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, + 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, + 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, + 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, + 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, + 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, + 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, + 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, + 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, + 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, + 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, + 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, + 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, + 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, + 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, + 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, + 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, + 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, + 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, + 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, + 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, + 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, + 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, + 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, + 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, + 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, + 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, + 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, + 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, + 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, + 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; /* MD3 2.5 ROM is 4096 bytes */ static uint8 mmd_rom_25[MMD_ROM_SIZE] = { - 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x89, - 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, - 0x92, 0x03, 0xc3, 0xff, 0x04, 0xc3, 0x56, 0x05, - 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, - 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, - 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, - 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, - 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, - 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, - 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, - 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, - 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, - 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, - 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, - 0x06, 0x9b, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, - 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, - 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, - 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, - 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, - 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, - 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, - 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, - 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, - 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, - 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, - 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, - 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, - 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, - 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, - 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, - 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, - 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, - 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, - 0x60, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, - 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, - 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, - 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, - 0x01, 0xcd, 0xe2, 0x04, 0x11, 0xab, 0x0e, 0xcd, - 0xc3, 0x01, 0xcd, 0x98, 0x05, 0xcd, 0x92, 0x03, - 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, - 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, - 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, - 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, - 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, - 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, - 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, - 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, - 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, - 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, - 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, - 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, - 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, - 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, - 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, - 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, - 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, - 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, - 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, - 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, - 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, - 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, - 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, - 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, - 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, - 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, - 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, - 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, - 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, - 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, - 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, - 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, - 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x5b, 0x06, - 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, - 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, - 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, - 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, - 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, - 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, - 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, - 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, - 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, - 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, - 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, - 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, - 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, - 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, - 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, - 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, - 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, - 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, - 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, - 0xc9, 0x21, 0xff, 0x04, 0xdd, 0x75, 0x0a, 0xdd, - 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x56, - 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, - 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x5b, 0x06, 0x23, - 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, - 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, - 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, - 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, - 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, - 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, - 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, - 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, - 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, - 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, - 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, - 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, - 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, - 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, - 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, - 0xd5, 0xcd, 0x9c, 0x05, 0xfd, 0xe5, 0xcd, 0x3b, - 0x04, 0xcd, 0x6f, 0x04, 0xfd, 0xe1, 0x06, 0x07, - 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, - 0xce, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, - 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, - 0x35, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, - 0x06, 0xb9, 0xcc, 0x22, 0x04, 0x3e, 0x02, 0xb9, - 0xcc, 0xfa, 0x03, 0x3e, 0x05, 0xb9, 0xcc, 0x09, - 0x04, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, - 0x98, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, - 0xfe, 0x28, 0x0a, 0xcd, 0x7b, 0x04, 0x38, 0x05, - 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, - 0x79, 0xc9, 0xcd, 0x83, 0x05, 0xc8, 0xcd, 0x98, - 0x05, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0x18, - 0x0a, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0xcd, - 0x83, 0x05, 0xc8, 0xf5, 0xdd, 0x36, 0x08, 0x03, - 0xcd, 0x9c, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, - 0x98, 0x05, 0xcd, 0x83, 0x05, 0xc8, 0xcd, 0x98, - 0x05, 0xdd, 0x7e, 0x08, 0xf5, 0xdd, 0x36, 0x08, - 0x0a, 0xcd, 0x9c, 0x05, 0xf1, 0xdd, 0x77, 0x08, - 0xc3, 0x9c, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, - 0x11, 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0xb8, - 0x06, 0xcd, 0xc5, 0x06, 0xed, 0xa3, 0x20, 0xf9, - 0xdd, 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, - 0xdd, 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, - 0x66, 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, - 0xdd, 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, - 0xfa, 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, - 0x00, 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, - 0x21, 0x0c, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, - 0xd5, 0x11, 0xb0, 0x0b, 0xcd, 0xc3, 0x01, 0x3e, - 0x41, 0xdd, 0x86, 0x00, 0xcd, 0xcc, 0x01, 0x11, - 0xae, 0x0e, 0xcd, 0xc3, 0x01, 0xd1, 0xcd, 0xc3, - 0x01, 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, - 0xbc, 0x04, 0xc1, 0xc9, 0xcd, 0xc3, 0x01, 0xcd, - 0xe2, 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0xab, - 0x0e, 0xc3, 0xc3, 0x01, 0x11, 0xc7, 0x0b, 0xcd, - 0xc3, 0x01, 0xcd, 0xe2, 0x04, 0xe6, 0xdf, 0x5f, - 0xfe, 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, - 0x04, 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, - 0xcc, 0x01, 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, - 0xf1, 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, - 0x66, 0x19, 0xcd, 0xdd, 0x01, 0xe1, 0xc1, 0xc9, - 0xe6, 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, - 0x28, 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, - 0xfa, 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, - 0xd5, 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, - 0xdb, 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, - 0x20, 0xf4, 0x1d, 0xf2, 0x09, 0x05, 0xd1, 0x15, - 0xd5, 0xf2, 0x09, 0x05, 0xfb, 0x76, 0xdb, 0xf7, - 0xed, 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, - 0xfd, 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, - 0x47, 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, - 0x6f, 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, - 0x20, 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, - 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, - 0xfe, 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, - 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, - 0xfa, 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, - 0xf4, 0x1d, 0xf2, 0x60, 0x05, 0xd1, 0x15, 0xd5, - 0xf2, 0x60, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, - 0xa3, 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, - 0xc9, 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, - 0xcb, 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, - 0x3e, 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, - 0x4f, 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x5b, 0x06, - 0x7e, 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, - 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, - 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, - 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, - 0xe5, 0xc4, 0x48, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, - 0xfa, 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, - 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, - 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, - 0xe6, 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, - 0x47, 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, - 0xb3, 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x6c, - 0x06, 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, - 0xb7, 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, - 0x28, 0x06, 0xcd, 0xd7, 0x06, 0xf1, 0x37, 0xf5, - 0xf1, 0xc5, 0xe5, 0xcd, 0x74, 0x06, 0xe1, 0xc1, - 0xcb, 0x59, 0xcc, 0x28, 0x06, 0xd1, 0xc1, 0xc9, - 0xcd, 0xc5, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, - 0xc5, 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, - 0xce, 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, - 0xd7, 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, - 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, - 0x10, 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, - 0xc3, 0xac, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, - 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, - 0x16, 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, - 0x19, 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, - 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, - 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, - 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, - 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, - 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x28, - 0x07, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, - 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, - 0xb3, 0xc2, 0xa9, 0x06, 0xc9, 0xcd, 0x11, 0x07, - 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, - 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, - 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, - 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, - 0xc5, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, - 0xc5, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, - 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, - 0xc8, 0xcd, 0xc5, 0x06, 0xdd, 0x7e, 0x08, 0xd3, - 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0xc5, - 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, - 0xcd, 0xc5, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, - 0xc9, 0xcd, 0xc5, 0x06, 0x3e, 0x08, 0xd3, 0xfb, - 0xcd, 0xce, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, - 0x80, 0xc8, 0xcd, 0xce, 0x06, 0xdb, 0xfb, 0xc9, - 0xcd, 0x11, 0x07, 0xe5, 0xd5, 0x11, 0x05, 0x00, - 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, - 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, - 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, - 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, - 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, - 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, - 0xdd, 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, - 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, - 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x25, 0xff, - 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, - 0xe2, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, - 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, - 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, - 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, - 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, - 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, - 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, - 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, - 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, - 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, - 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, - 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, - 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, - 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, - 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, - 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, - 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, - 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, - 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, - 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, - 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, - 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, - 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, - 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, - 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, - 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, - 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, - 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, - 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, - 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, - 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, - 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, - 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, - 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, - 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, - 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, - 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, - 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, - 0xe2, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, - 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, - 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, - 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, - 0xc3, 0x01, 0xcd, 0xe2, 0x04, 0x11, 0xab, 0x0e, - 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, - 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, - 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, - 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, - 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, - 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, - 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, - 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, - 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, - 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, - 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, - 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, - 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, - 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, - 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, - 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, - 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, - 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, - 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, - 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, - 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, - 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, - 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, - 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, - 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, - 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, - 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, - 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, - 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, - 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, - 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, - 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, - 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, - 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, - 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, - 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, - 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, - 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, - 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, - 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, - 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, - 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, - 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, - 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, - 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, - 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, - 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, - 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, - 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, - 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, - 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, - 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, - 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, - 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, - 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, - 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, - 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, - 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, - 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, - 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, - 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, - 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, - 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, - 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, - 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, - 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, - 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, - 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, - 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, - 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, - 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, - 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x35, 0x0d, 0x0a, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, - 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, - 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, - 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, - 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, - 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, - 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, - 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, - 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, - 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, - 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, - 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, - 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, - 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, - 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, - 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, - 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, - 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, - 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, - 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, - 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, - 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, - 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, - 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, - 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, - 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, - 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, - 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, - 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, - 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, - 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, - 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, - 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, - 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, - 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, - 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, - 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, - 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, - 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, - 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, - 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, - 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, - 0x00, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, - 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, - 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, - 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, - 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, - 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, - 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, - 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, - 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x26, 0x00, 0xc3, 0xc3, 0x01, 0xc3, 0x89, + 0x05, 0xc3, 0x01, 0x03, 0xc3, 0x0e, 0x03, 0xc3, + 0x92, 0x03, 0xc3, 0xff, 0x04, 0xc3, 0x56, 0x05, + 0xc3, 0x57, 0x01, 0xb1, 0x0e, 0xc3, 0x98, 0x01, + 0xc3, 0xde, 0x01, 0xc3, 0xf1, 0x01, 0xed, 0x46, + 0x31, 0x00, 0x00, 0xfd, 0x21, 0xd0, 0x0e, 0xcd, + 0x85, 0x00, 0xcd, 0x53, 0x00, 0x11, 0x37, 0x0c, + 0xcd, 0xba, 0x01, 0xcd, 0xaa, 0x00, 0xcd, 0xe9, + 0x00, 0xcd, 0xca, 0x00, 0xcd, 0x00, 0xfc, 0xdb, + 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0x01, 0x08, + 0xc3, 0x03, 0x01, 0x3e, 0x80, 0xd3, 0xfd, 0xd3, + 0xff, 0xd3, 0xfd, 0xd3, 0xff, 0x3e, 0x40, 0xd3, + 0xfd, 0xd3, 0xff, 0x3e, 0xce, 0xd3, 0xfd, 0xd3, + 0xff, 0x3e, 0x37, 0xd3, 0xfd, 0xd3, 0xff, 0xc9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, + 0x06, 0x9b, 0x9e, 0x3f, 0x0a, 0x3e, 0x3e, 0xd3, + 0xf3, 0x3e, 0xff, 0xd3, 0xf0, 0x3e, 0xff, 0xd3, + 0xf0, 0x3e, 0x7e, 0xd3, 0xf3, 0x3e, 0x0d, 0xd3, + 0xf1, 0x3e, 0x00, 0xd3, 0xf1, 0x3e, 0xbe, 0xd3, + 0xf3, 0x3e, 0x68, 0xd3, 0xf2, 0x3e, 0x00, 0xd3, + 0xf2, 0xc9, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0xf4, 0x0c, 0xcd, + 0xc3, 0x01, 0x18, 0x00, 0xdb, 0xf5, 0xcb, 0x6f, + 0xca, 0x47, 0x00, 0x11, 0x1b, 0x0c, 0xcd, 0xc3, + 0x01, 0x76, 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, + 0xcd, 0xdc, 0x00, 0xc8, 0x11, 0x07, 0x0d, 0xcd, + 0xc3, 0x01, 0x18, 0xe0, 0xaf, 0xf5, 0xf1, 0xae, + 0x23, 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, + 0xc9, 0x21, 0x3f, 0x0a, 0x11, 0x00, 0xfc, 0x01, + 0x00, 0x01, 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, + 0xe1, 0x13, 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, + 0x00, 0x77, 0xc9, 0xcd, 0x5d, 0x01, 0x3a, 0xea, + 0x0e, 0xe6, 0x03, 0xcb, 0x57, 0x28, 0x01, 0x0f, + 0x4f, 0x3a, 0xeb, 0x0e, 0xe6, 0x03, 0x47, 0x04, + 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb1, 0x11, 0x00, + 0x60, 0xd3, 0xf7, 0x1b, 0x7a, 0xb3, 0x28, 0x13, + 0xdb, 0xf5, 0xcb, 0x57, 0x28, 0xf5, 0x1b, 0x7a, + 0xb3, 0x28, 0x08, 0xdb, 0xf5, 0xcb, 0x57, 0x20, + 0xf5, 0x18, 0x0f, 0x11, 0xb8, 0x0c, 0xcd, 0xc3, + 0x01, 0xcd, 0xe2, 0x04, 0x11, 0xab, 0x0e, 0xcd, + 0xc3, 0x01, 0xcd, 0x98, 0x05, 0xcd, 0x92, 0x03, + 0xdd, 0x7e, 0x07, 0xb7, 0xca, 0x00, 0xfe, 0x11, + 0xfb, 0x0b, 0xc3, 0xbc, 0x00, 0x21, 0xb1, 0x0e, + 0x11, 0x00, 0xff, 0x01, 0x5d, 0x00, 0xed, 0xb0, + 0xdd, 0x21, 0x00, 0xff, 0xfd, 0x21, 0x1f, 0xff, + 0xc9, 0x06, 0xff, 0x18, 0x02, 0x06, 0xfd, 0x78, + 0x41, 0x4f, 0xed, 0x78, 0xcb, 0x47, 0x28, 0xfa, + 0x78, 0x0d, 0xed, 0x79, 0xc9, 0x06, 0xff, 0x18, + 0x02, 0x06, 0xfd, 0x48, 0xed, 0x78, 0xcb, 0x4f, + 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, + 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, + 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, + 0x21, 0x40, 0x00, 0xdb, 0xf5, 0xcb, 0x5f, 0x28, + 0x07, 0x2b, 0x7d, 0xb4, 0x20, 0xf5, 0x3d, 0xc9, + 0xaf, 0xc9, 0x06, 0x32, 0x3e, 0x0a, 0xcd, 0xcc, + 0x01, 0x10, 0xf9, 0x1a, 0xb7, 0xc8, 0xcd, 0xcc, + 0x01, 0x13, 0x18, 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, + 0xfd, 0x6e, 0x16, 0xfd, 0x66, 0x17, 0xcd, 0xdd, + 0x01, 0xe1, 0xd1, 0xc1, 0xc9, 0xe9, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xde, 0xfd, 0xcb, + 0x0b, 0xd6, 0xfd, 0x36, 0x0a, 0x02, 0xc3, 0x56, + 0x02, 0xfd, 0xcb, 0x0b, 0x9e, 0xfd, 0x71, 0x0a, + 0x79, 0xfe, 0x02, 0x20, 0x18, 0xfd, 0x7e, 0x08, + 0xfd, 0x77, 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0x77, + 0x05, 0xfd, 0x7e, 0x01, 0xfd, 0x77, 0x06, 0xfd, + 0x7e, 0x02, 0xfd, 0x77, 0x07, 0xfd, 0x7e, 0x04, + 0xb7, 0x28, 0x33, 0xfd, 0x35, 0x04, 0xfd, 0x7e, + 0x00, 0xfd, 0xbe, 0x05, 0x20, 0x28, 0xfd, 0x7e, + 0x01, 0xfd, 0xbe, 0x06, 0x20, 0x20, 0xfd, 0x7e, + 0x02, 0xfd, 0xbe, 0x07, 0x20, 0x18, 0xfd, 0x34, + 0x07, 0xfd, 0x7e, 0x09, 0xfd, 0xbe, 0x07, 0x30, + 0x07, 0xfd, 0x34, 0x06, 0xfd, 0x36, 0x07, 0x01, + 0xfd, 0xcb, 0x0b, 0x96, 0x18, 0x08, 0xfd, 0x36, + 0x04, 0x00, 0xfd, 0xcb, 0x0b, 0xd6, 0xdd, 0x36, + 0x07, 0x00, 0xfd, 0x7e, 0x00, 0xcd, 0x5b, 0x06, + 0x23, 0x7e, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, + 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, + 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, + 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, + 0x2b, 0xcb, 0x2b, 0x1c, 0xfd, 0x73, 0x03, 0x78, + 0xa2, 0xfd, 0x77, 0x0c, 0xfd, 0xcb, 0x0b, 0x46, + 0xfd, 0xcb, 0x0b, 0xc6, 0x28, 0x22, 0xfd, 0x7e, + 0x00, 0xdd, 0xbe, 0x00, 0x20, 0x10, 0xfd, 0x7e, + 0x01, 0xdd, 0xbe, 0x01, 0x20, 0x08, 0xfd, 0x7e, + 0x03, 0xdd, 0xbe, 0x02, 0x28, 0x2a, 0xaf, 0xfd, + 0xcb, 0x0b, 0x4e, 0xc4, 0x0e, 0x03, 0xb7, 0xc0, + 0xfd, 0x7e, 0x00, 0xdd, 0x77, 0x00, 0xfd, 0x7e, + 0x01, 0xdd, 0x77, 0x01, 0xfd, 0x7e, 0x03, 0xdd, + 0x77, 0x02, 0xaf, 0xfd, 0xcb, 0x0b, 0x56, 0xc4, + 0x01, 0x03, 0xb7, 0xc0, 0xfd, 0xcb, 0x0b, 0x8e, + 0xfd, 0x6e, 0x0c, 0x26, 0x00, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0xdd, 0x5e, 0x05, 0xdd, + 0x56, 0x06, 0x19, 0xfd, 0x5e, 0x14, 0xfd, 0x56, + 0x15, 0x01, 0x80, 0x00, 0xfd, 0xcb, 0x0b, 0x5e, + 0x3e, 0x00, 0xc0, 0xfd, 0xcb, 0x0b, 0xce, 0xeb, + 0xc9, 0x21, 0xff, 0x04, 0xdd, 0x75, 0x0a, 0xdd, + 0x74, 0x0b, 0x0e, 0x06, 0x18, 0x0b, 0x21, 0x56, + 0x05, 0xdd, 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, + 0x05, 0xdd, 0x7e, 0x00, 0xcd, 0x5b, 0x06, 0x23, + 0x7e, 0xe6, 0x40, 0xb1, 0xdd, 0x77, 0x16, 0xdd, + 0x36, 0x15, 0x09, 0x3e, 0x18, 0xa6, 0x0f, 0x0f, + 0x0f, 0xdd, 0x77, 0x1b, 0x06, 0x80, 0x11, 0x80, + 0x00, 0xfe, 0x00, 0x28, 0x11, 0x06, 0xff, 0x11, + 0x00, 0x00, 0xfe, 0x01, 0x28, 0x08, 0x16, 0x01, + 0xfe, 0x02, 0x28, 0x02, 0x16, 0x03, 0xdd, 0x70, + 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, 0x20, 0x06, 0xdd, + 0x73, 0x0c, 0xdd, 0x72, 0x0d, 0xaf, 0xcb, 0x56, + 0xdd, 0x46, 0x01, 0xdd, 0x4e, 0x02, 0x28, 0x03, + 0xcb, 0x18, 0x17, 0xdd, 0x77, 0x19, 0x07, 0x07, + 0xdd, 0x77, 0x09, 0xdd, 0x70, 0x08, 0xdd, 0x70, + 0x18, 0xdd, 0x71, 0x1a, 0x3e, 0x03, 0xa6, 0xdd, + 0xb6, 0x09, 0xdd, 0x77, 0x17, 0x11, 0x05, 0x00, + 0x19, 0x7e, 0xdd, 0x77, 0x1c, 0x23, 0x7e, 0xdd, + 0x77, 0x1d, 0xdd, 0x46, 0x04, 0x16, 0x03, 0xc5, + 0xd5, 0xcd, 0x9c, 0x05, 0xfd, 0xe5, 0xcd, 0x3b, + 0x04, 0xcd, 0x6f, 0x04, 0xfd, 0xe1, 0x06, 0x07, + 0xdd, 0xe5, 0xe1, 0x11, 0x0e, 0x00, 0x19, 0xcd, + 0xce, 0x06, 0xed, 0xa2, 0x20, 0xf9, 0xd1, 0xc1, + 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, 0x28, 0x35, 0xcd, + 0x35, 0x07, 0x3e, 0x01, 0xb9, 0x28, 0x1d, 0x3e, + 0x06, 0xb9, 0xcc, 0x22, 0x04, 0x3e, 0x02, 0xb9, + 0xcc, 0xfa, 0x03, 0x3e, 0x05, 0xb9, 0xcc, 0x09, + 0x04, 0xdd, 0x7e, 0x04, 0x0f, 0x3c, 0xb8, 0xcc, + 0x98, 0x05, 0x10, 0xb3, 0xdd, 0x7e, 0x07, 0xfe, + 0xfe, 0x28, 0x0a, 0xcd, 0x7b, 0x04, 0x38, 0x05, + 0xb7, 0xc2, 0x92, 0x03, 0x4f, 0xdd, 0x71, 0x07, + 0x79, 0xc9, 0xcd, 0x83, 0x05, 0xc8, 0xcd, 0x98, + 0x05, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0x18, + 0x0a, 0xdd, 0x7e, 0x08, 0xfe, 0x03, 0xd0, 0xcd, + 0x83, 0x05, 0xc8, 0xf5, 0xdd, 0x36, 0x08, 0x03, + 0xcd, 0x9c, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, + 0x98, 0x05, 0xcd, 0x83, 0x05, 0xc8, 0xcd, 0x98, + 0x05, 0xdd, 0x7e, 0x08, 0xf5, 0xdd, 0x36, 0x08, + 0x0a, 0xcd, 0x9c, 0x05, 0xf1, 0xdd, 0x77, 0x08, + 0xc3, 0x9c, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, + 0x11, 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0xb8, + 0x06, 0xcd, 0xc5, 0x06, 0xed, 0xa3, 0x20, 0xf9, + 0xdd, 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, + 0xdd, 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, + 0x66, 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, + 0xdd, 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, + 0xfa, 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, + 0x00, 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, + 0x21, 0x0c, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, + 0xd5, 0x11, 0xb0, 0x0b, 0xcd, 0xc3, 0x01, 0x3e, + 0x41, 0xdd, 0x86, 0x00, 0xcd, 0xcc, 0x01, 0x11, + 0xae, 0x0e, 0xcd, 0xc3, 0x01, 0xd1, 0xcd, 0xc3, + 0x01, 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, + 0xbc, 0x04, 0xc1, 0xc9, 0xcd, 0xc3, 0x01, 0xcd, + 0xe2, 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0xab, + 0x0e, 0xc3, 0xc3, 0x01, 0x11, 0xc7, 0x0b, 0xcd, + 0xc3, 0x01, 0xcd, 0xe2, 0x04, 0xe6, 0xdf, 0x5f, + 0xfe, 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, + 0x04, 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, + 0xcc, 0x01, 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, + 0xf1, 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, + 0x66, 0x19, 0xcd, 0xdd, 0x01, 0xe1, 0xc1, 0xc9, + 0xe6, 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, + 0x28, 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, + 0xfa, 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, + 0xd5, 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, + 0xdb, 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, + 0x20, 0xf4, 0x1d, 0xf2, 0x09, 0x05, 0xd1, 0x15, + 0xd5, 0xf2, 0x09, 0x05, 0xfb, 0x76, 0xdb, 0xf7, + 0xed, 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, + 0xfd, 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, + 0x47, 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, + 0x6f, 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, + 0x20, 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, + 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, + 0xfe, 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, + 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, + 0xfa, 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, + 0xf4, 0x1d, 0xf2, 0x60, 0x05, 0xd1, 0x15, 0xd5, + 0xf2, 0x60, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, + 0xa3, 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, + 0xc9, 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, + 0xcb, 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, + 0x3e, 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, + 0x4f, 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0x5b, 0x06, + 0x7e, 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, + 0x5f, 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, + 0xfd, 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, + 0xfd, 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, + 0xe5, 0xc4, 0x48, 0x06, 0xe1, 0xd1, 0xf1, 0xcd, + 0xfa, 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, + 0x13, 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, + 0xbe, 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, + 0xe6, 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, + 0x47, 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, + 0xb3, 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xcd, 0x6c, + 0x06, 0xdd, 0x7e, 0x08, 0xcb, 0x59, 0x28, 0x0a, + 0xb7, 0x20, 0x04, 0xcb, 0x99, 0x18, 0x03, 0xba, + 0x28, 0x06, 0xcd, 0xd7, 0x06, 0xf1, 0x37, 0xf5, + 0xf1, 0xc5, 0xe5, 0xcd, 0x74, 0x06, 0xe1, 0xc1, + 0xcb, 0x59, 0xcc, 0x28, 0x06, 0xd1, 0xc1, 0xc9, + 0xcd, 0xc5, 0x06, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, + 0xc5, 0x06, 0x3e, 0x03, 0xa6, 0xd3, 0xfb, 0xcd, + 0xce, 0x06, 0xdb, 0xfb, 0xe6, 0x10, 0xc0, 0xcd, + 0xd7, 0x06, 0x3e, 0xff, 0xb7, 0x37, 0x18, 0x2c, + 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, 0x0f, 0xfd, 0x56, + 0x10, 0x12, 0xfd, 0x5e, 0x0d, 0xfd, 0x56, 0x0e, + 0xc3, 0xac, 0x04, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, + 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, + 0x16, 0x00, 0x19, 0xc9, 0xe5, 0x11, 0x07, 0x00, + 0x19, 0x56, 0xe1, 0xc9, 0x23, 0xfd, 0x46, 0x12, + 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, + 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, + 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, + 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, + 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0x28, + 0x07, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, + 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, + 0xb3, 0xc2, 0xa9, 0x06, 0xc9, 0xcd, 0x11, 0x07, + 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, + 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, + 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, + 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, + 0xc5, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, + 0xc5, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, + 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, + 0xc8, 0xcd, 0xc5, 0x06, 0xdd, 0x7e, 0x08, 0xd3, + 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0xc5, + 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, + 0xcd, 0xc5, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, + 0xc9, 0xcd, 0xc5, 0x06, 0x3e, 0x08, 0xd3, 0xfb, + 0xcd, 0xce, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, + 0x80, 0xc8, 0xcd, 0xce, 0x06, 0xdb, 0xfb, 0xc9, + 0xcd, 0x11, 0x07, 0xe5, 0xd5, 0x11, 0x05, 0x00, + 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, + 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, + 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, + 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, + 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, + 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x76, 0xc0, + 0xdd, 0xcb, 0x10, 0x46, 0xc0, 0x0c, 0xdd, 0xcb, + 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x66, + 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, 0x0c, 0xc9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x13, 0x22, 0x25, 0xff, + 0xff, 0x11, 0x41, 0x0d, 0xcd, 0xc3, 0x01, 0xcd, + 0xe2, 0x04, 0xfe, 0x31, 0xfa, 0x07, 0x08, 0xfe, + 0x3a, 0xf2, 0x07, 0x08, 0xf5, 0xcd, 0xcc, 0x01, + 0x11, 0xab, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xd6, + 0x30, 0xfe, 0x04, 0xf2, 0x29, 0x08, 0x32, 0xfe, + 0xff, 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x3b, + 0x08, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0xdd, + 0x01, 0x18, 0xc6, 0x4d, 0x08, 0x4d, 0x08, 0x4d, + 0x08, 0xa3, 0x08, 0xcd, 0x08, 0x21, 0x09, 0xc9, + 0x09, 0x1a, 0x0a, 0x3d, 0x0a, 0x3e, 0x20, 0x32, + 0xfd, 0xff, 0x3e, 0x5f, 0x47, 0x3a, 0xfd, 0xff, + 0xcd, 0x80, 0x08, 0x05, 0x28, 0x08, 0x3c, 0xf2, + 0x58, 0x08, 0x3e, 0x20, 0x18, 0xf2, 0xcd, 0x9e, + 0x08, 0xc0, 0x3e, 0x0d, 0xcd, 0x80, 0x08, 0x3e, + 0x0a, 0xcd, 0x80, 0x08, 0x3a, 0xfd, 0xff, 0x3c, + 0xfa, 0x4d, 0x08, 0x32, 0xfd, 0xff, 0x18, 0xd2, + 0xf5, 0xc5, 0x4f, 0x3a, 0xfe, 0xff, 0xfe, 0x01, + 0x20, 0x05, 0xcd, 0x75, 0x01, 0x18, 0x0c, 0xfe, + 0x02, 0x20, 0x05, 0xcd, 0x71, 0x01, 0x18, 0x03, + 0xcd, 0x98, 0x01, 0xc1, 0xf1, 0xc9, 0xdb, 0xfd, + 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, 0xaf, 0x57, 0x4f, + 0xcd, 0x71, 0x01, 0xcd, 0x85, 0x01, 0xba, 0x20, + 0x0f, 0xcd, 0x9e, 0x08, 0x20, 0x05, 0x7a, 0x3c, + 0xf2, 0xa6, 0x08, 0x11, 0x49, 0x0e, 0x18, 0x03, + 0x11, 0x3f, 0x0e, 0xcd, 0xc3, 0x01, 0x11, 0x34, + 0x0e, 0xcd, 0xc3, 0x01, 0xc9, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0xcd, 0xee, 0x08, 0x21, 0x00, + 0x00, 0x01, 0xff, 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, + 0x28, 0x03, 0xcd, 0xf6, 0x08, 0xcd, 0xfe, 0x08, + 0xcd, 0x9e, 0x08, 0x28, 0xe9, 0xc9, 0xaf, 0x32, + 0xfe, 0xff, 0x32, 0xfd, 0xff, 0xc9, 0x3a, 0xfd, + 0xff, 0x3c, 0x32, 0xfd, 0xff, 0xc9, 0x11, 0x15, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfe, 0xff, 0x3c, + 0x32, 0xfe, 0xff, 0xcd, 0xb3, 0xfc, 0x11, 0xae, + 0x0e, 0xcd, 0xc3, 0x01, 0x3a, 0xfd, 0xff, 0xcd, + 0xb3, 0xfc, 0x11, 0x24, 0x0e, 0xcd, 0xc3, 0x01, + 0xc9, 0xcd, 0x3e, 0x09, 0xdd, 0x36, 0x01, 0x27, + 0xdd, 0x36, 0x03, 0x05, 0xcd, 0x74, 0x09, 0xcd, + 0xee, 0x08, 0xcd, 0x9b, 0x09, 0xcd, 0xac, 0x09, + 0xcd, 0x9e, 0x08, 0x28, 0xf5, 0xc9, 0xcd, 0x5d, + 0x01, 0x11, 0x53, 0x0e, 0xcd, 0xc3, 0x01, 0xcd, + 0xe2, 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, + 0xfe, 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, + 0x11, 0x6e, 0x0e, 0xcd, 0xc3, 0x01, 0xf1, 0xc6, + 0x41, 0xcd, 0xcc, 0x01, 0x11, 0xde, 0x0c, 0xcd, + 0xc3, 0x01, 0xcd, 0xe2, 0x04, 0x11, 0xab, 0x0e, + 0xcd, 0xc3, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, + 0x00, 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, + 0x70, 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, + 0xb6, 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, + 0x0c, 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, + 0x70, 0x06, 0xc9, 0x11, 0x96, 0x0e, 0xcd, 0xc3, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x0e, 0x03, + 0xcd, 0xc0, 0x09, 0xc9, 0x11, 0xa3, 0x0e, 0xcd, + 0xc3, 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, + 0x03, 0xcd, 0xc0, 0x09, 0xcd, 0xfe, 0x08, 0xc9, + 0xdd, 0x7e, 0x07, 0xfe, 0x00, 0xc4, 0xf6, 0x08, + 0xc9, 0xcd, 0x3e, 0x09, 0x06, 0x00, 0x0e, 0x27, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x03, 0x01, 0xcd, 0xee, 0x08, 0xc5, + 0xcd, 0xfd, 0x09, 0xc1, 0xcd, 0xed, 0x09, 0xcd, + 0x9e, 0x08, 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, + 0xf3, 0x09, 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, + 0xfe, 0x08, 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, + 0xcd, 0xc0, 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, + 0x36, 0x07, 0xff, 0xcd, 0x01, 0x03, 0xcd, 0xc0, + 0x09, 0xc9, 0xcd, 0x5d, 0x01, 0xaf, 0xdd, 0x77, + 0x00, 0xdd, 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, + 0xdd, 0x36, 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, + 0xdd, 0x36, 0x07, 0xfe, 0xcd, 0x01, 0x03, 0xcd, + 0x9e, 0x08, 0x28, 0xf4, 0xc9, 0xf1, 0xc9, 0xdb, + 0xf6, 0x3a, 0x00, 0x00, 0xfe, 0xc3, 0xd3, 0xf6, + 0x20, 0x03, 0xc3, 0x47, 0x00, 0x11, 0x85, 0x0c, + 0xcd, 0xc3, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, + 0xfb, 0xcd, 0x2a, 0xfc, 0xb7, 0xc2, 0xd4, 0x00, + 0x11, 0xa9, 0x0c, 0xcd, 0xc3, 0x01, 0xc3, 0x47, + 0x00, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, 0xd2, + 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, 0x5e, + 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, 0x05, + 0xcd, 0x54, 0xfc, 0x18, 0x07, 0xdd, 0x21, 0x74, + 0xfc, 0xcd, 0x58, 0xfc, 0xe1, 0x18, 0xe2, 0xaf, + 0xd3, 0xf6, 0xc9, 0xdd, 0x21, 0x76, 0xfc, 0x2a, + 0x00, 0xfd, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, + 0x67, 0xcd, 0x72, 0xfc, 0x23, 0x23, 0x23, 0x78, + 0xbc, 0xd8, 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, + 0xf0, 0xdd, 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, + 0x01, 0xc9, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, + 0xcc, 0x8a, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, + 0xc9, 0xd5, 0x11, 0x1a, 0x0d, 0xcd, 0xc3, 0x01, + 0xdb, 0xf6, 0x7e, 0xd3, 0xf6, 0xcd, 0xb3, 0xfc, + 0x11, 0x24, 0x0d, 0xcd, 0xc3, 0x01, 0xd1, 0x7a, + 0xcd, 0xb3, 0xfc, 0x11, 0x2f, 0x0d, 0xcd, 0xc3, + 0x01, 0x7c, 0xcd, 0xb3, 0xfc, 0x7d, 0xcd, 0xb3, + 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, + 0x0f, 0xcd, 0xc4, 0xfc, 0xf1, 0xe6, 0x0f, 0xcd, + 0xc4, 0xfc, 0xc9, 0xfe, 0x0a, 0xfa, 0xcb, 0xfc, + 0xc6, 0x07, 0xc6, 0x30, 0x4f, 0xcd, 0xcc, 0x01, + 0xc9, 0xff, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, + 0x41, 0xff, 0x42, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x02, 0x00, 0x42, 0x00, 0x40, 0xff, + 0x41, 0xaa, 0x00, 0x55, 0x02, 0xaa, 0x01, 0xaa, + 0x41, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x00, 0x55, + 0x42, 0x55, 0x41, 0x55, 0x40, 0x00, 0x80, 0x57, + 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0xae, 0x00, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0xae, 0x00, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, + 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, + 0x6e, 0x64, 0xae, 0x00, 0x4c, 0x6f, 0x73, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0xae, 0x00, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0xae, 0x00, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xae, + 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xae, 0x00, + 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, + 0x64, 0x72, 0x69, 0x76, 0x65, 0xa0, 0x00, 0x0d, + 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x52, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x41, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x3a, 0xa0, 0x00, 0x0a, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x43, 0x50, 0x2f, + 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x2e, 0x00, 0x0d, 0x0a, 0x50, 0x75, 0x73, + 0x68, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, + 0x67, 0x61, 0x69, 0x6e, 0x2e, 0xa0, 0x00, 0x0d, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x2d, + 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, 0x52, 0x65, + 0x76, 0x2e, 0x20, 0x32, 0x2e, 0x35, 0x0d, 0x0a, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, 0x2c, 0x20, + 0x31, 0x39, 0x38, 0x33, 0x20, 0x4d, 0x6f, 0x72, + 0x72, 0x6f, 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, + 0x67, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, + 0x00, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, + 0x4f, 0x2e, 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, + 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x20, 0x5b, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, + 0x5d, 0x20, 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, + 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, + 0x07, 0x52, 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x00, 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, + 0x61, 0x64, 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, + 0x61, 0x74, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, + 0x65, 0x6e, 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, + 0x20, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5c, 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, + 0x6f, 0x72, 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3e, 0x20, 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, + 0x2d, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, + 0x73, 0x74, 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x73, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, + 0x0d, 0x0a, 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, + 0x70, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, + 0x6e, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, + 0x0d, 0x0a, 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, + 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, + 0x57, 0x0d, 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, + 0x43, 0x20, 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, + 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, + 0x56, 0x46, 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x0d, 0x0a, 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, + 0x74, 0x0d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, + 0x73, 0x73, 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, + 0x61, 0x72, 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, + 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, + 0x00, 0x0d, 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, + 0x64, 0x20, 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, + 0x41, 0x2d, 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, + 0x65, 0x64, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, + 0x74, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, + 0x57, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x2e, 0x2e, 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x14, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x01, + 0x89, 0x01, 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, + 0x05, 0x1c, 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, + 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, + 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, + 0x05, 0x6f, 0x03, 0x05, 0x1c, 0xff, 0x4c, 0x0b, + 0x3f, 0x0b, 0x5d, 0x0b, 0x5d, 0x0b, 0x69, 0x0b, + 0x7f, 0x0b, 0x74, 0x0b, 0x7f, 0x0b, 0x90, 0x0b, + 0xa1, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; /* MD3 3.1 ROM is 4096 bytes */ static uint8 mmd_rom_31[MMD_ROM_SIZE] = { - 0xc3, 0x2c, 0x00, 0xc3, 0x68, 0x01, 0xc3, 0x30, - 0x05, 0xc3, 0xa4, 0x02, 0xc3, 0xb1, 0x02, 0xc3, - 0x35, 0x03, 0xc3, 0xa6, 0x04, 0xc3, 0xfd, 0x04, - 0xc3, 0x79, 0x00, 0x87, 0x0f, 0xc3, 0x40, 0x01, - 0xc3, 0x82, 0x01, 0xc3, 0x94, 0x01, 0xc3, 0x2d, - 0x08, 0xc3, 0x12, 0x07, 0xed, 0x46, 0x31, 0xfe, - 0xff, 0xfd, 0x21, 0xa6, 0x0f, 0xcd, 0x85, 0x00, - 0x11, 0x03, 0x0d, 0xcd, 0x51, 0x01, 0xcd, 0xb9, - 0x00, 0xcd, 0xd7, 0x00, 0xcd, 0x00, 0xfc, 0xdb, - 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0xef, 0x08, - 0xcd, 0x08, 0x01, 0xcd, 0x3f, 0x05, 0xdd, 0x36, - 0x07, 0xfe, 0xcd, 0x35, 0x03, 0xfe, 0x06, 0x20, - 0x10, 0x11, 0x8e, 0x0d, 0xcd, 0x68, 0x01, 0xcd, - 0x89, 0x04, 0x11, 0x81, 0x0f, 0xcd, 0x68, 0x01, - 0x3d, 0xb7, 0xc4, 0x35, 0x03, 0xb7, 0xca, 0x00, - 0xfe, 0x11, 0xc7, 0x0c, 0xc3, 0xc9, 0x00, 0x2a, - 0x06, 0xfc, 0x37, 0x0b, 0x0b, 0x21, 0x93, 0x00, - 0x06, 0x13, 0x4e, 0x23, 0x7e, 0x23, 0xed, 0x79, - 0x10, 0xf8, 0xc9, 0xf3, 0x3e, 0xf0, 0xff, 0xf0, - 0xff, 0xf3, 0x7e, 0xf1, 0x0d, 0xf1, 0x00, 0xf3, - 0xbe, 0xf2, 0x68, 0xf2, 0x00, 0xfd, 0x80, 0xff, - 0x80, 0xfd, 0x80, 0xff, 0x80, 0xfd, 0x40, 0xff, - 0x40, 0xfd, 0xce, 0xff, 0xce, 0xfd, 0x37, 0xff, - 0x37, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, 0x11, - 0xca, 0x0d, 0xcd, 0xfb, 0x00, 0xc8, 0xcd, 0x68, - 0x01, 0xdb, 0xf5, 0xcb, 0x6f, 0xca, 0x47, 0x00, - 0x11, 0xe7, 0x0c, 0xcd, 0x68, 0x01, 0x76, 0x21, - 0x0b, 0x0b, 0x11, 0x00, 0xfc, 0x01, 0x00, 0x01, - 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, 0xe1, 0x13, - 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, 0x00, 0x77, - 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, 0x11, 0xdd, - 0x0d, 0x18, 0xc7, 0xaf, 0xf5, 0xf1, 0xae, 0x23, - 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, 0xc9, - 0x21, 0x87, 0x0f, 0x11, 0x00, 0xff, 0x01, 0x5d, - 0x00, 0xed, 0xb0, 0xdd, 0x21, 0x00, 0xff, 0xfd, - 0x21, 0x1f, 0xff, 0xc9, 0x06, 0xff, 0x18, 0x02, - 0x06, 0xfd, 0x79, 0x48, 0xed, 0x40, 0xcb, 0x40, - 0x28, 0xfa, 0x0d, 0xed, 0x79, 0xc9, 0x0e, 0xff, - 0x18, 0x02, 0x0e, 0xfd, 0xed, 0x78, 0xcb, 0x4f, - 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, - 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, - 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, - 0xc9, 0x21, 0x00, 0x00, 0x2b, 0x7c, 0xb5, 0x20, - 0xfb, 0xcd, 0x68, 0x01, 0x06, 0x32, 0x3e, 0x0a, - 0xcd, 0x71, 0x01, 0x10, 0xf9, 0x11, 0x09, 0x0d, - 0x1a, 0xb7, 0xc8, 0xcd, 0x71, 0x01, 0x13, 0x18, - 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, 0xfd, 0x6e, 0x16, - 0xfd, 0x66, 0x17, 0xcd, 0x01, 0x08, 0xe1, 0xd1, - 0xc1, 0xc9, 0xfd, 0x36, 0x04, 0x00, 0xfd, 0xcb, - 0x0b, 0xde, 0xfd, 0xcb, 0x0b, 0xd6, 0xfd, 0x36, - 0x0a, 0x02, 0x18, 0x65, 0xfd, 0xcb, 0x0b, 0x9e, - 0xfd, 0x71, 0x0a, 0x79, 0xfe, 0x02, 0x20, 0x18, - 0xfd, 0x7e, 0x08, 0xfd, 0x77, 0x04, 0xfd, 0x7e, - 0x00, 0xfd, 0x77, 0x05, 0xfd, 0x7e, 0x01, 0xfd, - 0x77, 0x06, 0xfd, 0x7e, 0x02, 0xfd, 0x77, 0x07, - 0xfd, 0x7e, 0x04, 0xb7, 0x28, 0x33, 0xfd, 0x35, - 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0xbe, 0x05, 0x20, - 0x28, 0xfd, 0x7e, 0x01, 0xfd, 0xbe, 0x06, 0x20, - 0x20, 0xfd, 0x7e, 0x02, 0xfd, 0xbe, 0x07, 0x20, - 0x18, 0xfd, 0x34, 0x07, 0xfd, 0x7e, 0x09, 0xfd, - 0xbe, 0x07, 0x30, 0x07, 0xfd, 0x34, 0x06, 0xfd, - 0x36, 0x07, 0x01, 0xfd, 0xcb, 0x0b, 0x96, 0x18, - 0x08, 0xfd, 0x36, 0x04, 0x00, 0xfd, 0xcb, 0x0b, - 0xd6, 0xfd, 0x7e, 0x00, 0xcd, 0xf3, 0x05, 0x23, - 0x7e, 0x2b, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, - 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, - 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, - 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, - 0x2b, 0xcb, 0x2b, 0xcb, 0x76, 0x20, 0x01, 0x1c, - 0xfd, 0x73, 0x03, 0x78, 0xa2, 0xfd, 0x77, 0x0c, - 0xfd, 0xcb, 0x0b, 0x46, 0xfd, 0xcb, 0x0b, 0xc6, - 0x28, 0x22, 0xfd, 0x7e, 0x00, 0xdd, 0xbe, 0x00, - 0x20, 0x10, 0xfd, 0x7e, 0x01, 0xdd, 0xbe, 0x01, - 0x20, 0x08, 0xfd, 0x7e, 0x03, 0xdd, 0xbe, 0x02, - 0x28, 0x2a, 0xaf, 0xfd, 0xcb, 0x0b, 0x4e, 0xc4, - 0xb1, 0x02, 0xb7, 0xc0, 0xfd, 0x7e, 0x00, 0xdd, - 0x77, 0x00, 0xfd, 0x7e, 0x01, 0xdd, 0x77, 0x01, - 0xfd, 0x7e, 0x03, 0xdd, 0x77, 0x02, 0xaf, 0xfd, - 0xcb, 0x0b, 0x56, 0xc4, 0xa4, 0x02, 0xb7, 0xc0, - 0xfd, 0xcb, 0x0b, 0x8e, 0xfd, 0x6e, 0x0c, 0x26, - 0x00, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, - 0xdd, 0x5e, 0x05, 0xdd, 0x56, 0x06, 0x19, 0xfd, - 0x5e, 0x14, 0xfd, 0x56, 0x15, 0x01, 0x80, 0x00, - 0xaf, 0xfd, 0xcb, 0x0b, 0x5e, 0xc0, 0xfd, 0xcb, - 0x0b, 0xce, 0xeb, 0xc9, 0x21, 0xa6, 0x04, 0xdd, - 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, 0x06, 0x18, - 0x0b, 0x21, 0xfd, 0x04, 0xdd, 0x75, 0x0a, 0xdd, - 0x74, 0x0b, 0x0e, 0x05, 0xdd, 0x7e, 0x00, 0xcd, - 0xf3, 0x05, 0x23, 0x7e, 0xe6, 0x40, 0xb1, 0xdd, - 0x77, 0x16, 0xdd, 0x36, 0x15, 0x09, 0x3e, 0x18, - 0xa6, 0x0f, 0x0f, 0x0f, 0xdd, 0x77, 0x1b, 0x06, - 0x80, 0x11, 0x80, 0x00, 0xfe, 0x00, 0x28, 0x11, - 0x06, 0xff, 0x11, 0x00, 0x00, 0xfe, 0x01, 0x28, - 0x08, 0x16, 0x01, 0xfe, 0x02, 0x28, 0x02, 0x16, - 0x03, 0xdd, 0x70, 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, - 0x20, 0x06, 0xdd, 0x73, 0x0c, 0xdd, 0x72, 0x0d, - 0xaf, 0xcb, 0x56, 0xdd, 0x46, 0x01, 0xdd, 0x4e, - 0x02, 0x28, 0x03, 0xcb, 0x18, 0x17, 0xdd, 0x77, - 0x19, 0x07, 0x07, 0xdd, 0x77, 0x09, 0xdd, 0x70, - 0x08, 0xdd, 0x70, 0x18, 0xdd, 0x71, 0x1a, 0x3e, - 0x03, 0xa6, 0xdd, 0xb6, 0x09, 0xdd, 0x77, 0x17, - 0x11, 0x05, 0x00, 0x19, 0x7e, 0xdd, 0x77, 0x1c, - 0x23, 0x7e, 0xdd, 0x77, 0x1d, 0xdd, 0x46, 0x04, - 0x16, 0x03, 0xc5, 0xd5, 0xcd, 0x43, 0x05, 0xfd, - 0xe5, 0xcd, 0xd2, 0x03, 0xcd, 0x06, 0x04, 0xfd, - 0xe1, 0x06, 0x07, 0xdd, 0xe5, 0xe1, 0x11, 0x0e, - 0x00, 0x19, 0xcd, 0x5e, 0x06, 0xed, 0xa2, 0x20, - 0xf9, 0xd1, 0xc1, 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, - 0x28, 0x35, 0xcd, 0xc5, 0x06, 0x3e, 0x01, 0xb9, - 0x28, 0x1d, 0x3e, 0x06, 0xb9, 0xcc, 0xb9, 0x03, - 0x3e, 0x02, 0xb9, 0xcc, 0x9d, 0x03, 0x3e, 0x05, - 0xb9, 0xcc, 0xa0, 0x03, 0xdd, 0x7e, 0x04, 0x0f, - 0x3c, 0xb8, 0xcc, 0x3f, 0x05, 0x10, 0xb3, 0xdd, - 0x7e, 0x07, 0xfe, 0xfe, 0x28, 0x0a, 0xcd, 0x12, - 0x04, 0x38, 0x05, 0xb7, 0xc2, 0x35, 0x03, 0x4f, - 0xdd, 0x71, 0x07, 0x79, 0xc9, 0xcd, 0x3f, 0x05, - 0xcd, 0x2a, 0x05, 0xc8, 0xdd, 0x7e, 0x08, 0xfe, - 0x03, 0xd0, 0xf5, 0xdd, 0x36, 0x08, 0x03, 0xcd, - 0x43, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, 0x3f, - 0x05, 0xcd, 0x2a, 0x05, 0xc8, 0xcd, 0x3f, 0x05, - 0xdd, 0x7e, 0x08, 0xf5, 0xdd, 0x36, 0x08, 0x0a, - 0xcd, 0x43, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, - 0x43, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, - 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0x48, 0x06, - 0xcd, 0x55, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xdd, - 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, - 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, - 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, - 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, - 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x80, - 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, 0x21, - 0xe2, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, 0xd5, - 0x11, 0x7c, 0x0c, 0xcd, 0x68, 0x01, 0x3e, 0x41, - 0xdd, 0x86, 0x00, 0xcd, 0x71, 0x01, 0x11, 0x84, - 0x0f, 0xcd, 0x68, 0x01, 0xd1, 0xcd, 0x68, 0x01, - 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, 0x63, - 0x04, 0xc1, 0xc9, 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, - 0x0f, 0xfd, 0x56, 0x10, 0x12, 0xfd, 0x5e, 0x0d, - 0xfd, 0x56, 0x0e, 0xcd, 0x68, 0x01, 0xcd, 0x89, - 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0x81, 0x0f, - 0xc3, 0x68, 0x01, 0x11, 0x93, 0x0c, 0xcd, 0x68, - 0x01, 0xcd, 0x89, 0x04, 0xe6, 0xdf, 0x5f, 0xfe, - 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, - 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0x71, - 0x01, 0x11, 0x81, 0x0f, 0xcd, 0x68, 0x01, 0xf1, - 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, - 0x19, 0xcd, 0x01, 0x08, 0xe1, 0xc1, 0xc9, 0xe6, - 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, 0x28, - 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, 0xfa, - 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, 0xd5, - 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, - 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, 0x20, - 0xf4, 0x1d, 0xf2, 0xb0, 0x04, 0xd1, 0x15, 0xd5, - 0xf2, 0xb0, 0x04, 0xfb, 0x76, 0xdb, 0xf7, 0xed, - 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, - 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, 0x47, - 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, 0x6f, - 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, 0x20, - 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, - 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, 0xfe, - 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, - 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, - 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, 0xf4, - 0x1d, 0xf2, 0x07, 0x05, 0xd1, 0x15, 0xd5, 0xf2, - 0x07, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa3, - 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, 0xc9, - 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, - 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, 0x3e, - 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, 0x4f, - 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0xf3, 0x05, 0x7e, - 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, 0x5f, - 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, 0xfd, - 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, 0xfd, - 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, 0xe5, - 0xc4, 0x43, 0x04, 0xe1, 0xd1, 0xf1, 0xcd, 0x8a, - 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, 0x13, - 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, 0xbe, - 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, 0xe6, - 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, 0x47, - 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, 0xb3, - 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xe5, 0x11, 0x07, - 0x00, 0x19, 0x56, 0xe1, 0xdd, 0x7e, 0x08, 0xcb, - 0x59, 0x28, 0x0a, 0xb7, 0x20, 0x04, 0xcb, 0x99, - 0x18, 0x03, 0xba, 0x28, 0x06, 0xcd, 0x67, 0x06, - 0xf1, 0x37, 0xf5, 0xf1, 0xc5, 0xe5, 0xcd, 0x04, - 0x06, 0xe1, 0xc1, 0xcb, 0x59, 0xcc, 0xd3, 0x05, - 0xd1, 0xc1, 0xc9, 0xcd, 0x55, 0x06, 0x3e, 0x04, - 0xd3, 0xfb, 0xcd, 0x55, 0x06, 0x3e, 0x03, 0xa6, - 0xd3, 0xfb, 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xe6, - 0x10, 0xc0, 0xcd, 0x67, 0x06, 0x3e, 0xff, 0xb7, - 0x37, 0x18, 0x11, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, - 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, - 0x16, 0x00, 0x19, 0xc9, 0x23, 0xfd, 0x46, 0x12, - 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, - 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, - 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, - 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, - 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0xb8, - 0x06, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, - 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, - 0xb3, 0xc2, 0x39, 0x06, 0xc9, 0xcd, 0xa1, 0x06, - 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, - 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, - 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, - 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, - 0x55, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, - 0x55, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, - 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, - 0xc8, 0xcd, 0x55, 0x06, 0xdd, 0x7e, 0x08, 0xd3, - 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0x55, - 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, - 0xcd, 0x55, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, - 0xc9, 0xcd, 0x55, 0x06, 0x3e, 0x08, 0xd3, 0xfb, - 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, - 0x80, 0xc8, 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xc9, - 0xcd, 0xa1, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, - 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, - 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, - 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, - 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, - 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, - 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, - 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x46, 0xc0, - 0x0c, 0xdd, 0xcb, 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, - 0xcb, 0x0f, 0x66, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, - 0x66, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, - 0x0c, 0xc9, 0xfd, 0x6e, 0x08, 0xfd, 0x66, 0x09, - 0xfd, 0xe5, 0xe5, 0xfd, 0xe1, 0xfd, 0x7e, 0x12, - 0xb7, 0x20, 0x2a, 0x3e, 0x1f, 0xb9, 0xda, 0xee, - 0x07, 0x3e, 0x1b, 0xb9, 0x20, 0x07, 0xfd, 0x36, - 0x12, 0x01, 0xfd, 0xe1, 0xc9, 0xfd, 0xe1, 0xfd, - 0x6e, 0x02, 0xfd, 0x66, 0x03, 0xcd, 0x02, 0x08, - 0xb7, 0xca, 0xc3, 0x07, 0xfd, 0x6e, 0x06, 0xfd, - 0x66, 0x07, 0xc3, 0xde, 0x07, 0xfe, 0x01, 0x28, - 0x54, 0xfe, 0x02, 0x28, 0x71, 0xfd, 0x7e, 0x14, - 0x81, 0xfd, 0x77, 0x17, 0xfd, 0x36, 0x12, 0x00, - 0xfd, 0xe5, 0xe1, 0x11, 0x16, 0x00, 0x19, 0xeb, - 0x1a, 0xfd, 0x86, 0x13, 0x12, 0xfd, 0x7e, 0x15, - 0xf5, 0x1f, 0x9f, 0x47, 0x7b, 0x90, 0x5f, 0xfd, - 0xe5, 0xe1, 0xcd, 0xe3, 0x07, 0x1a, 0x4f, 0xf1, - 0xcb, 0x4f, 0xf5, 0xc4, 0x15, 0x08, 0xcd, 0xf0, - 0x07, 0xd5, 0x11, 0x06, 0x00, 0xcd, 0xf2, 0x07, - 0xd1, 0x7b, 0x80, 0x04, 0x80, 0x5f, 0x1a, 0x4f, - 0xf1, 0xc4, 0x15, 0x08, 0xcd, 0xf0, 0x07, 0x11, - 0x0c, 0x00, 0xf1, 0x18, 0x4d, 0x3e, 0x3d, 0xb9, - 0x28, 0x2d, 0xfd, 0x36, 0x12, 0x00, 0xfd, 0xe1, - 0xfd, 0x6e, 0x00, 0xfd, 0x66, 0x01, 0xcd, 0x02, - 0x08, 0xb7, 0x20, 0x13, 0xc5, 0x0e, 0x1b, 0xcd, - 0xf0, 0x07, 0xc1, 0x48, 0x18, 0x2a, 0xfd, 0x71, - 0x16, 0xfd, 0x36, 0x12, 0x03, 0x18, 0x0c, 0xfd, - 0x6e, 0x04, 0xfd, 0x66, 0x05, 0x18, 0x07, 0xfd, - 0x36, 0x12, 0x02, 0xfd, 0xe1, 0xc9, 0x09, 0x5e, - 0x23, 0x56, 0xeb, 0x7e, 0xfe, 0xff, 0xc8, 0x4f, - 0xcd, 0xf0, 0x07, 0x23, 0x18, 0xf5, 0xfd, 0xe1, - 0xdd, 0xe9, 0xfd, 0xe5, 0xe1, 0x19, 0x18, 0xeb, - 0x3e, 0x05, 0xd1, 0xc9, 0x13, 0x22, 0x31, 0xff, - 0xff, 0xe9, 0x41, 0x0e, 0x00, 0x7e, 0xb8, 0x20, - 0x04, 0xaf, 0x47, 0x3d, 0xc9, 0xd6, 0xff, 0xc8, - 0x23, 0x0c, 0x0c, 0x18, 0xf0, 0xc5, 0x79, 0x0e, - 0x30, 0xd6, 0x0a, 0x38, 0x03, 0x0c, 0x18, 0xf9, - 0x47, 0x3e, 0x30, 0xb9, 0xc4, 0xf0, 0x07, 0x3e, - 0x3a, 0x80, 0xc1, 0x4f, 0xc9, 0xe5, 0x3e, 0x04, - 0xb9, 0x38, 0xc5, 0xfd, 0x71, 0x00, 0xcb, 0x43, - 0x20, 0x7d, 0x79, 0xcd, 0xf3, 0x05, 0xcb, 0x7e, - 0x20, 0x75, 0x23, 0xe5, 0xc5, 0xcd, 0xbb, 0x08, - 0xc1, 0xe1, 0xb7, 0x20, 0xab, 0xe5, 0xdd, 0x6e, - 0x05, 0xdd, 0x66, 0x06, 0x11, 0x99, 0x00, 0x19, - 0x06, 0x19, 0x1e, 0x00, 0x3e, 0x00, 0x2b, 0xae, - 0x57, 0xb3, 0x5f, 0x7a, 0x10, 0xf8, 0x23, 0xb7, - 0x7b, 0x11, 0xe0, 0x08, 0x20, 0x19, 0xb7, 0x28, - 0x16, 0xe5, 0xdd, 0x6e, 0x05, 0xdd, 0x66, 0x06, - 0x11, 0x89, 0x00, 0x19, 0xeb, 0xe1, 0xcb, 0x56, - 0x28, 0x05, 0xe1, 0xcb, 0xd6, 0x18, 0x03, 0xe1, - 0xcb, 0x96, 0xaf, 0x26, 0x00, 0x69, 0x29, 0x29, - 0x29, 0x29, 0xc1, 0x09, 0xe5, 0xd5, 0x11, 0x0a, - 0x00, 0x19, 0x5e, 0x23, 0x56, 0xe1, 0xd5, 0x20, - 0x05, 0x01, 0x0f, 0x00, 0xed, 0xb0, 0xe1, 0x7e, - 0xfd, 0x77, 0x09, 0x23, 0x23, 0x23, 0x7e, 0x3c, - 0xfd, 0x77, 0x08, 0xd1, 0x3e, 0x00, 0xc9, 0xf6, - 0xff, 0x18, 0xd0, 0xc5, 0xaf, 0xfd, 0xcb, 0x0b, - 0x4e, 0xc4, 0xb1, 0x02, 0xfd, 0xcb, 0x0b, 0x8e, - 0xfd, 0xcb, 0x0b, 0x86, 0xc1, 0xb7, 0xc0, 0xdd, - 0x71, 0x00, 0xdd, 0x36, 0x01, 0x00, 0xdd, 0x36, - 0x02, 0x01, 0xcd, 0x30, 0x05, 0xc3, 0xa4, 0x02, - 0x28, 0x00, 0x04, 0x0f, 0x01, 0x5e, 0x00, 0x7f, - 0x00, 0xc0, 0x00, 0x20, 0x00, 0x02, 0x00, 0x11, - 0x17, 0x0e, 0xcd, 0x68, 0x01, 0xcd, 0x89, 0x04, - 0xfe, 0x31, 0x38, 0xf9, 0xfe, 0x3a, 0x30, 0xf5, - 0xf5, 0xcd, 0x71, 0x01, 0x11, 0x81, 0x0f, 0xcd, - 0x68, 0x01, 0xf1, 0xd6, 0x30, 0x32, 0xff, 0xff, - 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x22, 0x09, - 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0x01, 0x08, - 0x18, 0xcd, 0x34, 0x09, 0x34, 0x09, 0x34, 0x09, - 0x7e, 0x09, 0xa8, 0x09, 0xf8, 0x09, 0x97, 0x0a, - 0xe8, 0x0a, 0x06, 0x01, 0x21, 0xfe, 0xff, 0x36, - 0x20, 0x06, 0x4f, 0x7e, 0xcd, 0x5b, 0x09, 0x3c, - 0xf2, 0x45, 0x09, 0x3e, 0x20, 0x10, 0xf5, 0xcd, - 0x79, 0x09, 0xc0, 0x3e, 0x0d, 0xcd, 0x5b, 0x09, - 0x3e, 0x0a, 0xcd, 0x5b, 0x09, 0x34, 0xfa, 0x34, - 0x09, 0x18, 0xde, 0xf5, 0xc5, 0x4f, 0x3a, 0xff, - 0xff, 0xfe, 0x01, 0x20, 0x05, 0xcd, 0x20, 0x01, - 0x18, 0x0c, 0xfe, 0x02, 0x20, 0x05, 0xcd, 0x1c, - 0x01, 0x18, 0x03, 0xcd, 0x40, 0x01, 0xc1, 0xf1, - 0xc9, 0xdb, 0xfd, 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, - 0xaf, 0x57, 0x4f, 0xcd, 0x1c, 0x01, 0xcd, 0x2e, - 0x01, 0xba, 0x20, 0x0f, 0xcd, 0x79, 0x09, 0x20, - 0x05, 0x7a, 0x3c, 0xf2, 0x81, 0x09, 0x11, 0x1f, - 0x0f, 0x18, 0x03, 0x11, 0x15, 0x0f, 0xcd, 0x68, - 0x01, 0x11, 0x0a, 0x0f, 0xcd, 0x68, 0x01, 0xc9, - 0x11, 0x5b, 0x0d, 0xcd, 0x68, 0x01, 0xcd, 0xc6, - 0x09, 0x21, 0x00, 0x00, 0x01, 0xff, 0xfb, 0xcd, - 0x27, 0xfc, 0xcd, 0xce, 0x09, 0xcd, 0xd5, 0x09, - 0xcd, 0x79, 0x09, 0x28, 0xec, 0xc9, 0xaf, 0x32, - 0xff, 0xff, 0x32, 0xfe, 0xff, 0xc9, 0xb7, 0xc8, - 0x21, 0xfe, 0xff, 0x34, 0xc9, 0x11, 0xeb, 0x0e, - 0xcd, 0x68, 0x01, 0x3a, 0xff, 0xff, 0x3c, 0x32, - 0xff, 0xff, 0xcd, 0xb8, 0xfc, 0x11, 0x84, 0x0f, - 0xcd, 0x68, 0x01, 0x3a, 0xfe, 0xff, 0xcd, 0xb8, - 0xfc, 0x11, 0xfa, 0x0e, 0xcd, 0x68, 0x01, 0xc9, - 0xcd, 0x15, 0x0a, 0xdd, 0x36, 0x01, 0x27, 0xdd, - 0x36, 0x03, 0x05, 0xcd, 0x4b, 0x0a, 0xcd, 0xc6, - 0x09, 0xcd, 0x72, 0x0a, 0xcd, 0x83, 0x0a, 0xcd, - 0x79, 0x09, 0x28, 0xf5, 0xc9, 0xcd, 0x08, 0x01, - 0x11, 0x29, 0x0f, 0xcd, 0x68, 0x01, 0xcd, 0x89, - 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, 0xfe, - 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, 0x11, - 0x44, 0x0f, 0xcd, 0x68, 0x01, 0xf1, 0xc6, 0x41, - 0xcd, 0x71, 0x01, 0x11, 0xb4, 0x0d, 0xcd, 0x68, - 0x01, 0xcd, 0x89, 0x04, 0x11, 0x81, 0x0f, 0xcd, - 0x68, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, 0x00, - 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, 0x70, - 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, 0xb6, - 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, 0x0c, - 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, 0x70, - 0x06, 0xc9, 0x11, 0x6c, 0x0f, 0xcd, 0x68, 0x01, - 0xdd, 0x36, 0x07, 0xff, 0xcd, 0xb1, 0x02, 0xcd, - 0xce, 0x09, 0xc9, 0x11, 0x79, 0x0f, 0xcd, 0x68, - 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0xa4, 0x02, - 0xcd, 0xce, 0x09, 0xcd, 0xd5, 0x09, 0xc9, 0xcd, - 0x15, 0x0a, 0x06, 0x00, 0x0e, 0x27, 0xdd, 0x36, - 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, 0xdd, 0x36, - 0x03, 0x01, 0xcd, 0xc6, 0x09, 0xc5, 0xcd, 0xcb, - 0x0a, 0xc1, 0xcd, 0xbb, 0x0a, 0xcd, 0x79, 0x09, - 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, 0xc1, 0x0a, - 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, 0xd5, 0x09, - 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, 0x01, 0xdd, - 0x36, 0x07, 0xff, 0xcd, 0xa4, 0x02, 0xcd, 0xce, - 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, 0x36, 0x07, - 0xff, 0xcd, 0xa4, 0x02, 0xcd, 0xce, 0x09, 0xc9, - 0xcd, 0x08, 0x01, 0xaf, 0xdd, 0x77, 0x00, 0xdd, - 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, 0xdd, 0x36, - 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, 0xdd, 0x36, - 0x07, 0xfe, 0xcd, 0xa4, 0x02, 0xcd, 0x79, 0x09, - 0x28, 0xf4, 0xc9, 0xdb, 0xf6, 0x3a, 0x00, 0x00, - 0xfe, 0xc3, 0xd3, 0xf6, 0xc8, 0x11, 0x5b, 0x0d, - 0xcd, 0x68, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, - 0xfb, 0xcd, 0x27, 0xfc, 0xb7, 0x11, 0xdd, 0x0d, - 0xc2, 0xc6, 0x00, 0x11, 0x7f, 0x0d, 0xcd, 0x68, - 0x01, 0xc9, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, - 0xd2, 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, - 0x5e, 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, - 0x05, 0xcd, 0x56, 0xfc, 0x18, 0x07, 0xdd, 0x21, - 0x76, 0xfc, 0xcd, 0x5a, 0xfc, 0xe1, 0x18, 0xe2, - 0x3e, 0xc3, 0x32, 0x00, 0x00, 0xaf, 0xd3, 0xf6, - 0xc9, 0xdd, 0x21, 0x78, 0xfc, 0x2a, 0x00, 0xfd, - 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, 0x67, 0xcd, - 0x74, 0xfc, 0x23, 0x23, 0x23, 0x78, 0xbc, 0xd8, - 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, 0xf0, 0xdd, - 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, 0x01, 0xc9, - 0x5f, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, - 0x8d, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, 0xc9, - 0xd5, 0x11, 0xf0, 0x0d, 0xcd, 0x68, 0x01, 0xdb, - 0xf6, 0xd1, 0xd5, 0x7b, 0xd3, 0xf6, 0xcd, 0xb8, - 0xfc, 0x11, 0xfa, 0x0d, 0xcd, 0x68, 0x01, 0xd1, - 0x7a, 0xcd, 0xb8, 0xfc, 0x11, 0x05, 0x0e, 0xcd, - 0x68, 0x01, 0x7c, 0xcd, 0xb8, 0xfc, 0x7d, 0xcd, - 0xb8, 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, - 0xe6, 0x0f, 0xcd, 0xc5, 0xfc, 0xf1, 0xe6, 0x0f, - 0xfe, 0x0a, 0x38, 0x02, 0xc6, 0x07, 0xc6, 0x30, - 0x4f, 0xcd, 0x71, 0x01, 0xc9, 0xff, 0x00, 0x00, - 0x01, 0xff, 0x02, 0x00, 0x41, 0xff, 0x42, 0xff, - 0x40, 0x00, 0x00, 0xff, 0x01, 0x00, 0x02, 0x00, - 0x42, 0x00, 0x40, 0xff, 0x41, 0xaa, 0x00, 0x55, - 0x02, 0xaa, 0x01, 0xaa, 0x41, 0x55, 0x01, 0xaa, - 0x40, 0x55, 0x00, 0x55, 0x42, 0x55, 0x41, 0x55, - 0x40, 0x00, 0x80, 0x57, 0x72, 0x6f, 0x6e, 0x67, - 0x20, 0x74, 0x72, 0x61, 0x63, 0x6b, 0xae, 0x00, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x70, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0xae, - 0x00, 0x44, 0x61, 0x74, 0x61, 0x20, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0xae, 0x00, 0x4e, 0x6f, 0x74, - 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xae, 0x00, - 0x4c, 0x6f, 0x73, 0x74, 0x20, 0x64, 0x61, 0x74, - 0x61, 0xae, 0x00, 0x44, 0x72, 0x69, 0x76, 0x65, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, - 0x64, 0x79, 0xae, 0x00, 0x49, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0xae, 0x00, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0xae, 0x00, 0x0d, 0x0a, 0x44, 0x69, - 0x73, 0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x20, 0x6f, 0x6e, 0x20, 0x64, 0x72, 0x69, 0x76, - 0x65, 0xa0, 0x00, 0x0d, 0x0a, 0x54, 0x79, 0x70, - 0x65, 0x20, 0x52, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, - 0x2c, 0x20, 0x41, 0x20, 0x74, 0x6f, 0x20, 0x61, - 0x62, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x6f, 0x72, - 0x20, 0x49, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, - 0x6e, 0x6f, 0x72, 0x65, 0x3a, 0xa0, 0x00, 0x0a, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, - 0x20, 0x43, 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, - 0x6b, 0x65, 0x74, 0x74, 0x65, 0x2e, 0x00, 0x0d, - 0x0a, 0x50, 0x75, 0x73, 0x68, 0x20, 0x72, 0x65, - 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, - 0x2e, 0xa0, 0x00, 0x1b, 0x25, 0x1b, 0x47, 0x30, - 0x00, 0x0d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, - 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, - 0x52, 0x65, 0x76, 0x2e, 0x20, 0x33, 0x2e, 0x31, - 0x0d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, - 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, - 0x2c, 0x31, 0x39, 0x38, 0x33, 0x2c, 0x31, 0x39, - 0x38, 0x34, 0x20, 0x4d, 0x6f, 0x72, 0x72, 0x6f, - 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, - 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0d, - 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, - 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, 0x00, 0x4d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x4f, 0x2e, - 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x49, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, 0x50, 0x2f, - 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x72, 0x69, - 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x5b, - 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5d, 0x20, - 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, 0x4d, 0x20, - 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, 0x07, 0x52, - 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, - 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, 0x61, 0x64, - 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, 0x61, 0x74, - 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x00, 0x0d, - 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, 0x65, 0x6e, - 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, 0x20, 0x50, - 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, - 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, 0x6f, 0x72, - 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x20, - 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, 0x2d, 0x50, - 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, - 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, 0x73, 0x74, - 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x20, - 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, 0x0d, 0x0a, - 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x20, - 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, - 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, 0x0d, 0x0a, - 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, 0x29, 0x20, - 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, 0x57, 0x0d, - 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, - 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, 0x65, 0x73, - 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, 0x56, 0x46, - 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, - 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x0d, - 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, - 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, 0x6e, 0x64, - 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, 0x73, 0x73, - 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, 0x61, 0x72, - 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, 0x0a, 0x46, - 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x00, 0x0d, - 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, - 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x64, - 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, - 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, 0x41, 0x2d, - 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, 0x49, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x64, - 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, - 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x72, 0x69, - 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, 0x57, 0x72, - 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x2e, 0x2e, - 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, - 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x0a, 0x00, 0xfe, 0x00, 0x00, - 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, 0x00, 0x00, - 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x32, 0x01, - 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, 0x05, 0x1c, - 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, 0x03, 0x05, - 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, 0x6f, 0x03, - 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, 0x05, 0x6f, - 0x03, 0x05, 0x1c, 0xff, 0x18, 0x0c, 0x0b, 0x0c, - 0x29, 0x0c, 0x29, 0x0c, 0x35, 0x0c, 0x4b, 0x0c, - 0x40, 0x0c, 0x4b, 0x0c, 0x5c, 0x0c, 0x6d, 0x0c, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x2c, 0x00, 0xc3, 0x68, 0x01, 0xc3, 0x30, + 0x05, 0xc3, 0xa4, 0x02, 0xc3, 0xb1, 0x02, 0xc3, + 0x35, 0x03, 0xc3, 0xa6, 0x04, 0xc3, 0xfd, 0x04, + 0xc3, 0x79, 0x00, 0x87, 0x0f, 0xc3, 0x40, 0x01, + 0xc3, 0x82, 0x01, 0xc3, 0x94, 0x01, 0xc3, 0x2d, + 0x08, 0xc3, 0x12, 0x07, 0xed, 0x46, 0x31, 0xfe, + 0xff, 0xfd, 0x21, 0xa6, 0x0f, 0xcd, 0x85, 0x00, + 0x11, 0x03, 0x0d, 0xcd, 0x51, 0x01, 0xcd, 0xb9, + 0x00, 0xcd, 0xd7, 0x00, 0xcd, 0x00, 0xfc, 0xdb, + 0xfc, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, 0xef, 0x08, + 0xcd, 0x08, 0x01, 0xcd, 0x3f, 0x05, 0xdd, 0x36, + 0x07, 0xfe, 0xcd, 0x35, 0x03, 0xfe, 0x06, 0x20, + 0x10, 0x11, 0x8e, 0x0d, 0xcd, 0x68, 0x01, 0xcd, + 0x89, 0x04, 0x11, 0x81, 0x0f, 0xcd, 0x68, 0x01, + 0x3d, 0xb7, 0xc4, 0x35, 0x03, 0xb7, 0xca, 0x00, + 0xfe, 0x11, 0xc7, 0x0c, 0xc3, 0xc9, 0x00, 0x2a, + 0x06, 0xfc, 0x37, 0x0b, 0x0b, 0x21, 0x93, 0x00, + 0x06, 0x13, 0x4e, 0x23, 0x7e, 0x23, 0xed, 0x79, + 0x10, 0xf8, 0xc9, 0xf3, 0x3e, 0xf0, 0xff, 0xf0, + 0xff, 0xf3, 0x7e, 0xf1, 0x0d, 0xf1, 0x00, 0xf3, + 0xbe, 0xf2, 0x68, 0xf2, 0x00, 0xfd, 0x80, 0xff, + 0x80, 0xfd, 0x80, 0xff, 0x80, 0xfd, 0x40, 0xff, + 0x40, 0xfd, 0xce, 0xff, 0xce, 0xfd, 0x37, 0xff, + 0x37, 0x21, 0x00, 0x00, 0x01, 0xfd, 0x0f, 0x11, + 0xca, 0x0d, 0xcd, 0xfb, 0x00, 0xc8, 0xcd, 0x68, + 0x01, 0xdb, 0xf5, 0xcb, 0x6f, 0xca, 0x47, 0x00, + 0x11, 0xe7, 0x0c, 0xcd, 0x68, 0x01, 0x76, 0x21, + 0x0b, 0x0b, 0x11, 0x00, 0xfc, 0x01, 0x00, 0x01, + 0xed, 0xb0, 0x01, 0xf7, 0x02, 0xd5, 0xe1, 0x13, + 0x36, 0xff, 0xed, 0xb0, 0x3a, 0x82, 0x00, 0x77, + 0x21, 0x00, 0xfc, 0x01, 0xf8, 0x03, 0x11, 0xdd, + 0x0d, 0x18, 0xc7, 0xaf, 0xf5, 0xf1, 0xae, 0x23, + 0x0b, 0xf5, 0x78, 0xb1, 0x20, 0xf7, 0xf1, 0xc9, + 0x21, 0x87, 0x0f, 0x11, 0x00, 0xff, 0x01, 0x5d, + 0x00, 0xed, 0xb0, 0xdd, 0x21, 0x00, 0xff, 0xfd, + 0x21, 0x1f, 0xff, 0xc9, 0x06, 0xff, 0x18, 0x02, + 0x06, 0xfd, 0x79, 0x48, 0xed, 0x40, 0xcb, 0x40, + 0x28, 0xfa, 0x0d, 0xed, 0x79, 0xc9, 0x0e, 0xff, + 0x18, 0x02, 0x0e, 0xfd, 0xed, 0x78, 0xcb, 0x4f, + 0x28, 0xfa, 0x0d, 0xed, 0x78, 0xe6, 0x7f, 0xc9, + 0xdb, 0xf5, 0xcb, 0x67, 0x20, 0xfa, 0x79, 0xd3, + 0xf4, 0x3e, 0x80, 0xd3, 0xf5, 0xaf, 0xd3, 0xf5, + 0xc9, 0x21, 0x00, 0x00, 0x2b, 0x7c, 0xb5, 0x20, + 0xfb, 0xcd, 0x68, 0x01, 0x06, 0x32, 0x3e, 0x0a, + 0xcd, 0x71, 0x01, 0x10, 0xf9, 0x11, 0x09, 0x0d, + 0x1a, 0xb7, 0xc8, 0xcd, 0x71, 0x01, 0x13, 0x18, + 0xf7, 0x4f, 0xc5, 0xd5, 0xe5, 0xfd, 0x6e, 0x16, + 0xfd, 0x66, 0x17, 0xcd, 0x01, 0x08, 0xe1, 0xd1, + 0xc1, 0xc9, 0xfd, 0x36, 0x04, 0x00, 0xfd, 0xcb, + 0x0b, 0xde, 0xfd, 0xcb, 0x0b, 0xd6, 0xfd, 0x36, + 0x0a, 0x02, 0x18, 0x65, 0xfd, 0xcb, 0x0b, 0x9e, + 0xfd, 0x71, 0x0a, 0x79, 0xfe, 0x02, 0x20, 0x18, + 0xfd, 0x7e, 0x08, 0xfd, 0x77, 0x04, 0xfd, 0x7e, + 0x00, 0xfd, 0x77, 0x05, 0xfd, 0x7e, 0x01, 0xfd, + 0x77, 0x06, 0xfd, 0x7e, 0x02, 0xfd, 0x77, 0x07, + 0xfd, 0x7e, 0x04, 0xb7, 0x28, 0x33, 0xfd, 0x35, + 0x04, 0xfd, 0x7e, 0x00, 0xfd, 0xbe, 0x05, 0x20, + 0x28, 0xfd, 0x7e, 0x01, 0xfd, 0xbe, 0x06, 0x20, + 0x20, 0xfd, 0x7e, 0x02, 0xfd, 0xbe, 0x07, 0x20, + 0x18, 0xfd, 0x34, 0x07, 0xfd, 0x7e, 0x09, 0xfd, + 0xbe, 0x07, 0x30, 0x07, 0xfd, 0x34, 0x06, 0xfd, + 0x36, 0x07, 0x01, 0xfd, 0xcb, 0x0b, 0x96, 0x18, + 0x08, 0xfd, 0x36, 0x04, 0x00, 0xfd, 0xcb, 0x0b, + 0xd6, 0xfd, 0x7e, 0x00, 0xcd, 0xf3, 0x05, 0x23, + 0x7e, 0x2b, 0xfd, 0x5e, 0x02, 0x1d, 0x53, 0xe6, + 0x18, 0x06, 0x00, 0xfe, 0x00, 0x28, 0x14, 0x06, + 0x01, 0xfe, 0x08, 0x28, 0x0c, 0x06, 0x03, 0xfe, + 0x10, 0x28, 0x04, 0x06, 0x07, 0xcb, 0x2b, 0xcb, + 0x2b, 0xcb, 0x2b, 0xcb, 0x76, 0x20, 0x01, 0x1c, + 0xfd, 0x73, 0x03, 0x78, 0xa2, 0xfd, 0x77, 0x0c, + 0xfd, 0xcb, 0x0b, 0x46, 0xfd, 0xcb, 0x0b, 0xc6, + 0x28, 0x22, 0xfd, 0x7e, 0x00, 0xdd, 0xbe, 0x00, + 0x20, 0x10, 0xfd, 0x7e, 0x01, 0xdd, 0xbe, 0x01, + 0x20, 0x08, 0xfd, 0x7e, 0x03, 0xdd, 0xbe, 0x02, + 0x28, 0x2a, 0xaf, 0xfd, 0xcb, 0x0b, 0x4e, 0xc4, + 0xb1, 0x02, 0xb7, 0xc0, 0xfd, 0x7e, 0x00, 0xdd, + 0x77, 0x00, 0xfd, 0x7e, 0x01, 0xdd, 0x77, 0x01, + 0xfd, 0x7e, 0x03, 0xdd, 0x77, 0x02, 0xaf, 0xfd, + 0xcb, 0x0b, 0x56, 0xc4, 0xa4, 0x02, 0xb7, 0xc0, + 0xfd, 0xcb, 0x0b, 0x8e, 0xfd, 0x6e, 0x0c, 0x26, + 0x00, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0xdd, 0x5e, 0x05, 0xdd, 0x56, 0x06, 0x19, 0xfd, + 0x5e, 0x14, 0xfd, 0x56, 0x15, 0x01, 0x80, 0x00, + 0xaf, 0xfd, 0xcb, 0x0b, 0x5e, 0xc0, 0xfd, 0xcb, + 0x0b, 0xce, 0xeb, 0xc9, 0x21, 0xa6, 0x04, 0xdd, + 0x75, 0x0a, 0xdd, 0x74, 0x0b, 0x0e, 0x06, 0x18, + 0x0b, 0x21, 0xfd, 0x04, 0xdd, 0x75, 0x0a, 0xdd, + 0x74, 0x0b, 0x0e, 0x05, 0xdd, 0x7e, 0x00, 0xcd, + 0xf3, 0x05, 0x23, 0x7e, 0xe6, 0x40, 0xb1, 0xdd, + 0x77, 0x16, 0xdd, 0x36, 0x15, 0x09, 0x3e, 0x18, + 0xa6, 0x0f, 0x0f, 0x0f, 0xdd, 0x77, 0x1b, 0x06, + 0x80, 0x11, 0x80, 0x00, 0xfe, 0x00, 0x28, 0x11, + 0x06, 0xff, 0x11, 0x00, 0x00, 0xfe, 0x01, 0x28, + 0x08, 0x16, 0x01, 0xfe, 0x02, 0x28, 0x02, 0x16, + 0x03, 0xdd, 0x70, 0x1e, 0xdd, 0xcb, 0x0d, 0x7e, + 0x20, 0x06, 0xdd, 0x73, 0x0c, 0xdd, 0x72, 0x0d, + 0xaf, 0xcb, 0x56, 0xdd, 0x46, 0x01, 0xdd, 0x4e, + 0x02, 0x28, 0x03, 0xcb, 0x18, 0x17, 0xdd, 0x77, + 0x19, 0x07, 0x07, 0xdd, 0x77, 0x09, 0xdd, 0x70, + 0x08, 0xdd, 0x70, 0x18, 0xdd, 0x71, 0x1a, 0x3e, + 0x03, 0xa6, 0xdd, 0xb6, 0x09, 0xdd, 0x77, 0x17, + 0x11, 0x05, 0x00, 0x19, 0x7e, 0xdd, 0x77, 0x1c, + 0x23, 0x7e, 0xdd, 0x77, 0x1d, 0xdd, 0x46, 0x04, + 0x16, 0x03, 0xc5, 0xd5, 0xcd, 0x43, 0x05, 0xfd, + 0xe5, 0xcd, 0xd2, 0x03, 0xcd, 0x06, 0x04, 0xfd, + 0xe1, 0x06, 0x07, 0xdd, 0xe5, 0xe1, 0x11, 0x0e, + 0x00, 0x19, 0xcd, 0x5e, 0x06, 0xed, 0xa2, 0x20, + 0xf9, 0xd1, 0xc1, 0xdd, 0x7e, 0x0e, 0xe6, 0xc0, + 0x28, 0x35, 0xcd, 0xc5, 0x06, 0x3e, 0x01, 0xb9, + 0x28, 0x1d, 0x3e, 0x06, 0xb9, 0xcc, 0xb9, 0x03, + 0x3e, 0x02, 0xb9, 0xcc, 0x9d, 0x03, 0x3e, 0x05, + 0xb9, 0xcc, 0xa0, 0x03, 0xdd, 0x7e, 0x04, 0x0f, + 0x3c, 0xb8, 0xcc, 0x3f, 0x05, 0x10, 0xb3, 0xdd, + 0x7e, 0x07, 0xfe, 0xfe, 0x28, 0x0a, 0xcd, 0x12, + 0x04, 0x38, 0x05, 0xb7, 0xc2, 0x35, 0x03, 0x4f, + 0xdd, 0x71, 0x07, 0x79, 0xc9, 0xcd, 0x3f, 0x05, + 0xcd, 0x2a, 0x05, 0xc8, 0xdd, 0x7e, 0x08, 0xfe, + 0x03, 0xd0, 0xf5, 0xdd, 0x36, 0x08, 0x03, 0xcd, + 0x43, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, 0x3f, + 0x05, 0xcd, 0x2a, 0x05, 0xc8, 0xcd, 0x3f, 0x05, + 0xdd, 0x7e, 0x08, 0xf5, 0xdd, 0x36, 0x08, 0x0a, + 0xcd, 0x43, 0x05, 0xf1, 0xdd, 0x77, 0x08, 0xc3, + 0x43, 0x05, 0x0e, 0xfb, 0xdd, 0xe5, 0xe1, 0x11, + 0x15, 0x00, 0x19, 0x46, 0x23, 0xcd, 0x48, 0x06, + 0xcd, 0x55, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xdd, + 0x46, 0x0c, 0xdd, 0x5e, 0x0d, 0xcb, 0xbb, 0xdd, + 0x56, 0x03, 0x15, 0xdd, 0x6e, 0x0a, 0xdd, 0x66, + 0x0b, 0xe5, 0xfd, 0xe1, 0xdd, 0x6e, 0x05, 0xdd, + 0x66, 0x06, 0xc9, 0xcb, 0x7f, 0xc0, 0xdb, 0xfa, + 0xcb, 0x6f, 0x28, 0xf7, 0xd5, 0x11, 0x00, 0x80, + 0xfd, 0xe9, 0x79, 0x07, 0x5f, 0x16, 0x00, 0x21, + 0xe2, 0x0f, 0x19, 0x5e, 0x23, 0x56, 0xc5, 0xd5, + 0x11, 0x7c, 0x0c, 0xcd, 0x68, 0x01, 0x3e, 0x41, + 0xdd, 0x86, 0x00, 0xcd, 0x71, 0x01, 0x11, 0x84, + 0x0f, 0xcd, 0x68, 0x01, 0xd1, 0xcd, 0x68, 0x01, + 0x3e, 0xff, 0xdd, 0xbe, 0x07, 0x37, 0xc4, 0x63, + 0x04, 0xc1, 0xc9, 0x3c, 0xcb, 0xf7, 0xfd, 0x5e, + 0x0f, 0xfd, 0x56, 0x10, 0x12, 0xfd, 0x5e, 0x0d, + 0xfd, 0x56, 0x0e, 0xcd, 0x68, 0x01, 0xcd, 0x89, + 0x04, 0xfe, 0x0d, 0x20, 0xf9, 0x11, 0x81, 0x0f, + 0xc3, 0x68, 0x01, 0x11, 0x93, 0x0c, 0xcd, 0x68, + 0x01, 0xcd, 0x89, 0x04, 0xe6, 0xdf, 0x5f, 0xfe, + 0x41, 0x37, 0x28, 0x08, 0xfe, 0x52, 0x28, 0x04, + 0xd6, 0x49, 0x20, 0xed, 0xf5, 0x7b, 0xcd, 0x71, + 0x01, 0x11, 0x81, 0x0f, 0xcd, 0x68, 0x01, 0xf1, + 0xc9, 0xc5, 0xe5, 0xfd, 0x6e, 0x18, 0xfd, 0x66, + 0x19, 0xcd, 0x01, 0x08, 0xe1, 0xc1, 0xc9, 0xe6, + 0x20, 0x28, 0x36, 0xdb, 0xfa, 0xfe, 0xf0, 0x28, + 0x0b, 0x1b, 0x7b, 0xb2, 0x28, 0x2d, 0xdb, 0xfa, + 0xfe, 0xf0, 0x20, 0xeb, 0xed, 0xa2, 0xd1, 0xd5, + 0x7b, 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, + 0xfa, 0xe6, 0x20, 0x28, 0x14, 0xed, 0xa2, 0x20, + 0xf4, 0x1d, 0xf2, 0xb0, 0x04, 0xd1, 0x15, 0xd5, + 0xf2, 0xb0, 0x04, 0xfb, 0x76, 0xdb, 0xf7, 0xed, + 0xa2, 0xd1, 0xc9, 0xd1, 0xe1, 0xfd, 0xe1, 0xfd, + 0xe5, 0xc5, 0x0e, 0xf7, 0xfd, 0x7e, 0x12, 0x47, + 0xcb, 0xdf, 0xed, 0x79, 0xdb, 0xfa, 0xcb, 0x6f, + 0x20, 0xfa, 0xed, 0x41, 0xc1, 0xe9, 0xe6, 0x20, + 0x28, 0xdf, 0xdb, 0xfa, 0xfe, 0xb0, 0x28, 0x0b, + 0x1b, 0x7b, 0xb2, 0x28, 0xd6, 0xdb, 0xfa, 0xfe, + 0xb0, 0x20, 0xeb, 0xed, 0xa3, 0xd1, 0xd5, 0x7b, + 0xb2, 0x20, 0x01, 0x05, 0xfb, 0x76, 0xdb, 0xfa, + 0xe6, 0x20, 0x28, 0xbd, 0xed, 0xa3, 0x20, 0xf4, + 0x1d, 0xf2, 0x07, 0x05, 0xd1, 0x15, 0xd5, 0xf2, + 0x07, 0x05, 0xfb, 0x76, 0xdb, 0xf7, 0xed, 0xa3, + 0xd1, 0xc9, 0x04, 0x15, 0xc0, 0x06, 0x01, 0xc9, + 0xfd, 0xcb, 0x0b, 0x4e, 0x20, 0x04, 0xfd, 0xcb, + 0x0b, 0x86, 0xfd, 0x36, 0x01, 0x00, 0xc9, 0x3e, + 0x00, 0x18, 0x02, 0x3e, 0x08, 0xc5, 0xd5, 0x4f, + 0xdd, 0x7e, 0x00, 0xf5, 0xcd, 0xf3, 0x05, 0x7e, + 0xe6, 0x07, 0xcb, 0x57, 0x28, 0x01, 0x0f, 0x5f, + 0x23, 0xf1, 0xfd, 0xbe, 0x11, 0x28, 0x1b, 0xfd, + 0x77, 0x11, 0xcb, 0x7e, 0xc5, 0x28, 0x0f, 0xfd, + 0xbe, 0x13, 0xfd, 0x77, 0x13, 0xf5, 0xd5, 0xe5, + 0xc4, 0x43, 0x04, 0xe1, 0xd1, 0xf1, 0xcd, 0x8a, + 0x06, 0xc1, 0xcb, 0x76, 0x28, 0x0f, 0x3e, 0x13, + 0xcb, 0x6e, 0x28, 0x02, 0x3e, 0x27, 0xdd, 0xbe, + 0x08, 0x30, 0x02, 0xcb, 0xd3, 0xdb, 0xf5, 0xe6, + 0x03, 0x57, 0xa3, 0xf5, 0x7e, 0xe6, 0x03, 0x47, + 0x04, 0x3e, 0x08, 0x07, 0x10, 0xfd, 0xb2, 0xb3, + 0xd3, 0xf7, 0xfd, 0x77, 0x12, 0xe5, 0x11, 0x07, + 0x00, 0x19, 0x56, 0xe1, 0xdd, 0x7e, 0x08, 0xcb, + 0x59, 0x28, 0x0a, 0xb7, 0x20, 0x04, 0xcb, 0x99, + 0x18, 0x03, 0xba, 0x28, 0x06, 0xcd, 0x67, 0x06, + 0xf1, 0x37, 0xf5, 0xf1, 0xc5, 0xe5, 0xcd, 0x04, + 0x06, 0xe1, 0xc1, 0xcb, 0x59, 0xcc, 0xd3, 0x05, + 0xd1, 0xc1, 0xc9, 0xcd, 0x55, 0x06, 0x3e, 0x04, + 0xd3, 0xfb, 0xcd, 0x55, 0x06, 0x3e, 0x03, 0xa6, + 0xd3, 0xfb, 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xe6, + 0x10, 0xc0, 0xcd, 0x67, 0x06, 0x3e, 0xff, 0xb7, + 0x37, 0x18, 0x11, 0xfd, 0xe5, 0xe1, 0x11, 0x1a, + 0x00, 0x19, 0x57, 0x07, 0x07, 0x07, 0x82, 0x5f, + 0x16, 0x00, 0x19, 0xc9, 0x23, 0xfd, 0x46, 0x12, + 0x0e, 0xf7, 0x56, 0x1e, 0x00, 0x23, 0x30, 0x28, + 0xed, 0x5e, 0x3e, 0x00, 0xed, 0x47, 0x20, 0x0c, + 0xfb, 0x1b, 0x7a, 0xb3, 0x28, 0x08, 0x0e, 0xf7, + 0xed, 0x41, 0x18, 0xf5, 0x56, 0xfb, 0xed, 0x41, + 0x18, 0xfc, 0xed, 0x46, 0x33, 0x33, 0xcd, 0xb8, + 0x06, 0x7a, 0xbe, 0x30, 0x04, 0x56, 0x18, 0x01, + 0xc0, 0xed, 0x41, 0xed, 0x41, 0x00, 0x1b, 0x7a, + 0xb3, 0xc2, 0x39, 0x06, 0xc9, 0xcd, 0xa1, 0x06, + 0xdb, 0xfa, 0xe6, 0x0f, 0x20, 0xf7, 0xdb, 0xfa, + 0xcb, 0x67, 0x20, 0xf4, 0xc9, 0xdb, 0xfa, 0xe6, + 0xc0, 0xfe, 0x80, 0x20, 0xf8, 0xc9, 0xdb, 0xfa, + 0xe6, 0xc0, 0xfe, 0xc0, 0x20, 0xf8, 0xc9, 0xcd, + 0x55, 0x06, 0x3e, 0x07, 0xb1, 0xd3, 0xfb, 0xcd, + 0x55, 0x06, 0x3e, 0x03, 0xa6, 0xcb, 0x59, 0x28, + 0x03, 0xdd, 0xb6, 0x09, 0xd3, 0xfb, 0xcb, 0x59, + 0xc8, 0xcd, 0x55, 0x06, 0xdd, 0x7e, 0x08, 0xd3, + 0xfb, 0xc9, 0xe5, 0x23, 0x23, 0x23, 0xcd, 0x55, + 0x06, 0x3e, 0x03, 0xd3, 0xfb, 0x01, 0xfb, 0x02, + 0xcd, 0x55, 0x06, 0xed, 0xa3, 0x20, 0xf9, 0xe1, + 0xc9, 0xcd, 0x55, 0x06, 0x3e, 0x08, 0xd3, 0xfb, + 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xe6, 0xc0, 0xfe, + 0x80, 0xc8, 0xcd, 0x5e, 0x06, 0xdb, 0xfb, 0xc9, + 0xcd, 0xa1, 0x06, 0xe5, 0xd5, 0x11, 0x05, 0x00, + 0x19, 0x77, 0xd1, 0xe1, 0xc9, 0x0e, 0x01, 0xdd, + 0xcb, 0x0f, 0x4e, 0xc0, 0x0c, 0xdd, 0xcb, 0x10, + 0x4e, 0xc0, 0xdd, 0xcb, 0x10, 0x66, 0xc0, 0x0c, + 0xdd, 0xcb, 0x10, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, + 0x0f, 0x6e, 0xc0, 0x0c, 0xdd, 0xcb, 0x0f, 0x7e, + 0xc0, 0xdd, 0xcb, 0x0f, 0x56, 0xc0, 0xdd, 0xcb, + 0x0f, 0x46, 0xc0, 0xdd, 0xcb, 0x10, 0x46, 0xc0, + 0x0c, 0xdd, 0xcb, 0x0e, 0x5e, 0xc0, 0x0c, 0xdd, + 0xcb, 0x0f, 0x66, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, + 0x66, 0xc0, 0x0c, 0xdd, 0xcb, 0x0e, 0x7e, 0xc0, + 0x0c, 0xc9, 0xfd, 0x6e, 0x08, 0xfd, 0x66, 0x09, + 0xfd, 0xe5, 0xe5, 0xfd, 0xe1, 0xfd, 0x7e, 0x12, + 0xb7, 0x20, 0x2a, 0x3e, 0x1f, 0xb9, 0xda, 0xee, + 0x07, 0x3e, 0x1b, 0xb9, 0x20, 0x07, 0xfd, 0x36, + 0x12, 0x01, 0xfd, 0xe1, 0xc9, 0xfd, 0xe1, 0xfd, + 0x6e, 0x02, 0xfd, 0x66, 0x03, 0xcd, 0x02, 0x08, + 0xb7, 0xca, 0xc3, 0x07, 0xfd, 0x6e, 0x06, 0xfd, + 0x66, 0x07, 0xc3, 0xde, 0x07, 0xfe, 0x01, 0x28, + 0x54, 0xfe, 0x02, 0x28, 0x71, 0xfd, 0x7e, 0x14, + 0x81, 0xfd, 0x77, 0x17, 0xfd, 0x36, 0x12, 0x00, + 0xfd, 0xe5, 0xe1, 0x11, 0x16, 0x00, 0x19, 0xeb, + 0x1a, 0xfd, 0x86, 0x13, 0x12, 0xfd, 0x7e, 0x15, + 0xf5, 0x1f, 0x9f, 0x47, 0x7b, 0x90, 0x5f, 0xfd, + 0xe5, 0xe1, 0xcd, 0xe3, 0x07, 0x1a, 0x4f, 0xf1, + 0xcb, 0x4f, 0xf5, 0xc4, 0x15, 0x08, 0xcd, 0xf0, + 0x07, 0xd5, 0x11, 0x06, 0x00, 0xcd, 0xf2, 0x07, + 0xd1, 0x7b, 0x80, 0x04, 0x80, 0x5f, 0x1a, 0x4f, + 0xf1, 0xc4, 0x15, 0x08, 0xcd, 0xf0, 0x07, 0x11, + 0x0c, 0x00, 0xf1, 0x18, 0x4d, 0x3e, 0x3d, 0xb9, + 0x28, 0x2d, 0xfd, 0x36, 0x12, 0x00, 0xfd, 0xe1, + 0xfd, 0x6e, 0x00, 0xfd, 0x66, 0x01, 0xcd, 0x02, + 0x08, 0xb7, 0x20, 0x13, 0xc5, 0x0e, 0x1b, 0xcd, + 0xf0, 0x07, 0xc1, 0x48, 0x18, 0x2a, 0xfd, 0x71, + 0x16, 0xfd, 0x36, 0x12, 0x03, 0x18, 0x0c, 0xfd, + 0x6e, 0x04, 0xfd, 0x66, 0x05, 0x18, 0x07, 0xfd, + 0x36, 0x12, 0x02, 0xfd, 0xe1, 0xc9, 0x09, 0x5e, + 0x23, 0x56, 0xeb, 0x7e, 0xfe, 0xff, 0xc8, 0x4f, + 0xcd, 0xf0, 0x07, 0x23, 0x18, 0xf5, 0xfd, 0xe1, + 0xdd, 0xe9, 0xfd, 0xe5, 0xe1, 0x19, 0x18, 0xeb, + 0x3e, 0x05, 0xd1, 0xc9, 0x13, 0x22, 0x31, 0xff, + 0xff, 0xe9, 0x41, 0x0e, 0x00, 0x7e, 0xb8, 0x20, + 0x04, 0xaf, 0x47, 0x3d, 0xc9, 0xd6, 0xff, 0xc8, + 0x23, 0x0c, 0x0c, 0x18, 0xf0, 0xc5, 0x79, 0x0e, + 0x30, 0xd6, 0x0a, 0x38, 0x03, 0x0c, 0x18, 0xf9, + 0x47, 0x3e, 0x30, 0xb9, 0xc4, 0xf0, 0x07, 0x3e, + 0x3a, 0x80, 0xc1, 0x4f, 0xc9, 0xe5, 0x3e, 0x04, + 0xb9, 0x38, 0xc5, 0xfd, 0x71, 0x00, 0xcb, 0x43, + 0x20, 0x7d, 0x79, 0xcd, 0xf3, 0x05, 0xcb, 0x7e, + 0x20, 0x75, 0x23, 0xe5, 0xc5, 0xcd, 0xbb, 0x08, + 0xc1, 0xe1, 0xb7, 0x20, 0xab, 0xe5, 0xdd, 0x6e, + 0x05, 0xdd, 0x66, 0x06, 0x11, 0x99, 0x00, 0x19, + 0x06, 0x19, 0x1e, 0x00, 0x3e, 0x00, 0x2b, 0xae, + 0x57, 0xb3, 0x5f, 0x7a, 0x10, 0xf8, 0x23, 0xb7, + 0x7b, 0x11, 0xe0, 0x08, 0x20, 0x19, 0xb7, 0x28, + 0x16, 0xe5, 0xdd, 0x6e, 0x05, 0xdd, 0x66, 0x06, + 0x11, 0x89, 0x00, 0x19, 0xeb, 0xe1, 0xcb, 0x56, + 0x28, 0x05, 0xe1, 0xcb, 0xd6, 0x18, 0x03, 0xe1, + 0xcb, 0x96, 0xaf, 0x26, 0x00, 0x69, 0x29, 0x29, + 0x29, 0x29, 0xc1, 0x09, 0xe5, 0xd5, 0x11, 0x0a, + 0x00, 0x19, 0x5e, 0x23, 0x56, 0xe1, 0xd5, 0x20, + 0x05, 0x01, 0x0f, 0x00, 0xed, 0xb0, 0xe1, 0x7e, + 0xfd, 0x77, 0x09, 0x23, 0x23, 0x23, 0x7e, 0x3c, + 0xfd, 0x77, 0x08, 0xd1, 0x3e, 0x00, 0xc9, 0xf6, + 0xff, 0x18, 0xd0, 0xc5, 0xaf, 0xfd, 0xcb, 0x0b, + 0x4e, 0xc4, 0xb1, 0x02, 0xfd, 0xcb, 0x0b, 0x8e, + 0xfd, 0xcb, 0x0b, 0x86, 0xc1, 0xb7, 0xc0, 0xdd, + 0x71, 0x00, 0xdd, 0x36, 0x01, 0x00, 0xdd, 0x36, + 0x02, 0x01, 0xcd, 0x30, 0x05, 0xc3, 0xa4, 0x02, + 0x28, 0x00, 0x04, 0x0f, 0x01, 0x5e, 0x00, 0x7f, + 0x00, 0xc0, 0x00, 0x20, 0x00, 0x02, 0x00, 0x11, + 0x17, 0x0e, 0xcd, 0x68, 0x01, 0xcd, 0x89, 0x04, + 0xfe, 0x31, 0x38, 0xf9, 0xfe, 0x3a, 0x30, 0xf5, + 0xf5, 0xcd, 0x71, 0x01, 0x11, 0x81, 0x0f, 0xcd, + 0x68, 0x01, 0xf1, 0xd6, 0x30, 0x32, 0xff, 0xff, + 0x3d, 0x07, 0x4f, 0xaf, 0x47, 0x21, 0x22, 0x09, + 0x09, 0x5e, 0x23, 0x56, 0xeb, 0xcd, 0x01, 0x08, + 0x18, 0xcd, 0x34, 0x09, 0x34, 0x09, 0x34, 0x09, + 0x7e, 0x09, 0xa8, 0x09, 0xf8, 0x09, 0x97, 0x0a, + 0xe8, 0x0a, 0x06, 0x01, 0x21, 0xfe, 0xff, 0x36, + 0x20, 0x06, 0x4f, 0x7e, 0xcd, 0x5b, 0x09, 0x3c, + 0xf2, 0x45, 0x09, 0x3e, 0x20, 0x10, 0xf5, 0xcd, + 0x79, 0x09, 0xc0, 0x3e, 0x0d, 0xcd, 0x5b, 0x09, + 0x3e, 0x0a, 0xcd, 0x5b, 0x09, 0x34, 0xfa, 0x34, + 0x09, 0x18, 0xde, 0xf5, 0xc5, 0x4f, 0x3a, 0xff, + 0xff, 0xfe, 0x01, 0x20, 0x05, 0xcd, 0x20, 0x01, + 0x18, 0x0c, 0xfe, 0x02, 0x20, 0x05, 0xcd, 0x1c, + 0x01, 0x18, 0x03, 0xcd, 0x40, 0x01, 0xc1, 0xf1, + 0xc9, 0xdb, 0xfd, 0xcb, 0x4f, 0xc9, 0xdb, 0xfe, + 0xaf, 0x57, 0x4f, 0xcd, 0x1c, 0x01, 0xcd, 0x2e, + 0x01, 0xba, 0x20, 0x0f, 0xcd, 0x79, 0x09, 0x20, + 0x05, 0x7a, 0x3c, 0xf2, 0x81, 0x09, 0x11, 0x1f, + 0x0f, 0x18, 0x03, 0x11, 0x15, 0x0f, 0xcd, 0x68, + 0x01, 0x11, 0x0a, 0x0f, 0xcd, 0x68, 0x01, 0xc9, + 0x11, 0x5b, 0x0d, 0xcd, 0x68, 0x01, 0xcd, 0xc6, + 0x09, 0x21, 0x00, 0x00, 0x01, 0xff, 0xfb, 0xcd, + 0x27, 0xfc, 0xcd, 0xce, 0x09, 0xcd, 0xd5, 0x09, + 0xcd, 0x79, 0x09, 0x28, 0xec, 0xc9, 0xaf, 0x32, + 0xff, 0xff, 0x32, 0xfe, 0xff, 0xc9, 0xb7, 0xc8, + 0x21, 0xfe, 0xff, 0x34, 0xc9, 0x11, 0xeb, 0x0e, + 0xcd, 0x68, 0x01, 0x3a, 0xff, 0xff, 0x3c, 0x32, + 0xff, 0xff, 0xcd, 0xb8, 0xfc, 0x11, 0x84, 0x0f, + 0xcd, 0x68, 0x01, 0x3a, 0xfe, 0xff, 0xcd, 0xb8, + 0xfc, 0x11, 0xfa, 0x0e, 0xcd, 0x68, 0x01, 0xc9, + 0xcd, 0x15, 0x0a, 0xdd, 0x36, 0x01, 0x27, 0xdd, + 0x36, 0x03, 0x05, 0xcd, 0x4b, 0x0a, 0xcd, 0xc6, + 0x09, 0xcd, 0x72, 0x0a, 0xcd, 0x83, 0x0a, 0xcd, + 0x79, 0x09, 0x28, 0xf5, 0xc9, 0xcd, 0x08, 0x01, + 0x11, 0x29, 0x0f, 0xcd, 0x68, 0x01, 0xcd, 0x89, + 0x04, 0xe6, 0xdf, 0xd6, 0x41, 0x38, 0xf7, 0xfe, + 0x04, 0x30, 0xf3, 0xdd, 0x77, 0x00, 0xf5, 0x11, + 0x44, 0x0f, 0xcd, 0x68, 0x01, 0xf1, 0xc6, 0x41, + 0xcd, 0x71, 0x01, 0x11, 0xb4, 0x0d, 0xcd, 0x68, + 0x01, 0xcd, 0x89, 0x04, 0x11, 0x81, 0x0f, 0xcd, + 0x68, 0x01, 0xc9, 0x01, 0x5f, 0xaa, 0x21, 0x00, + 0x80, 0xe5, 0x11, 0x02, 0x80, 0x71, 0x23, 0x70, + 0x2b, 0x01, 0x00, 0x08, 0xed, 0xb0, 0x01, 0xb6, + 0x6d, 0x71, 0x23, 0x70, 0x2b, 0x01, 0x00, 0x0c, + 0xed, 0xb0, 0xc1, 0xdd, 0x71, 0x05, 0xdd, 0x70, + 0x06, 0xc9, 0x11, 0x6c, 0x0f, 0xcd, 0x68, 0x01, + 0xdd, 0x36, 0x07, 0xff, 0xcd, 0xb1, 0x02, 0xcd, + 0xce, 0x09, 0xc9, 0x11, 0x79, 0x0f, 0xcd, 0x68, + 0x01, 0xdd, 0x36, 0x07, 0xff, 0xcd, 0xa4, 0x02, + 0xcd, 0xce, 0x09, 0xcd, 0xd5, 0x09, 0xc9, 0xcd, + 0x15, 0x0a, 0x06, 0x00, 0x0e, 0x27, 0xdd, 0x36, + 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, 0xdd, 0x36, + 0x03, 0x01, 0xcd, 0xc6, 0x09, 0xc5, 0xcd, 0xcb, + 0x0a, 0xc1, 0xcd, 0xbb, 0x0a, 0xcd, 0x79, 0x09, + 0x28, 0xf3, 0xc9, 0x04, 0x0d, 0xfa, 0xc1, 0x0a, + 0xc9, 0x78, 0x41, 0x4f, 0xc5, 0xcd, 0xd5, 0x09, + 0xc1, 0x18, 0xf0, 0xc5, 0xdd, 0x70, 0x01, 0xdd, + 0x36, 0x07, 0xff, 0xcd, 0xa4, 0x02, 0xcd, 0xce, + 0x09, 0xc1, 0xdd, 0x71, 0x01, 0xdd, 0x36, 0x07, + 0xff, 0xcd, 0xa4, 0x02, 0xcd, 0xce, 0x09, 0xc9, + 0xcd, 0x08, 0x01, 0xaf, 0xdd, 0x77, 0x00, 0xdd, + 0x77, 0x01, 0xdd, 0x36, 0x03, 0x01, 0xdd, 0x36, + 0x05, 0x00, 0xdd, 0x36, 0x06, 0x80, 0xdd, 0x36, + 0x07, 0xfe, 0xcd, 0xa4, 0x02, 0xcd, 0x79, 0x09, + 0x28, 0xf4, 0xc9, 0xdb, 0xf6, 0x3a, 0x00, 0x00, + 0xfe, 0xc3, 0xd3, 0xf6, 0xc8, 0x11, 0x5b, 0x0d, + 0xcd, 0x68, 0x01, 0x21, 0x00, 0x00, 0x01, 0xff, + 0xfb, 0xcd, 0x27, 0xfc, 0xb7, 0x11, 0xdd, 0x0d, + 0xc2, 0xc6, 0x00, 0x11, 0x7f, 0x0d, 0xcd, 0x68, + 0x01, 0xc9, 0xdb, 0xf6, 0x22, 0x00, 0xfd, 0x21, + 0xd2, 0xfc, 0x56, 0x23, 0xcb, 0x7e, 0x20, 0x18, + 0x5e, 0xcb, 0x73, 0xcb, 0xb3, 0x23, 0xe5, 0x28, + 0x05, 0xcd, 0x56, 0xfc, 0x18, 0x07, 0xdd, 0x21, + 0x76, 0xfc, 0xcd, 0x5a, 0xfc, 0xe1, 0x18, 0xe2, + 0x3e, 0xc3, 0x32, 0x00, 0x00, 0xaf, 0xd3, 0xf6, + 0xc9, 0xdd, 0x21, 0x78, 0xfc, 0x2a, 0x00, 0xfd, + 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, 0x67, 0xcd, + 0x74, 0xfc, 0x23, 0x23, 0x23, 0x78, 0xbc, 0xd8, + 0x20, 0xf5, 0x79, 0xbd, 0xd8, 0x18, 0xf0, 0xdd, + 0xe9, 0x72, 0xc9, 0x7e, 0xba, 0x20, 0x01, 0xc9, + 0x5f, 0xd3, 0xf6, 0xdb, 0xf5, 0xcb, 0x6f, 0xcc, + 0x8d, 0xfc, 0xf1, 0xf1, 0xf1, 0x3e, 0xff, 0xc9, + 0xd5, 0x11, 0xf0, 0x0d, 0xcd, 0x68, 0x01, 0xdb, + 0xf6, 0xd1, 0xd5, 0x7b, 0xd3, 0xf6, 0xcd, 0xb8, + 0xfc, 0x11, 0xfa, 0x0d, 0xcd, 0x68, 0x01, 0xd1, + 0x7a, 0xcd, 0xb8, 0xfc, 0x11, 0x05, 0x0e, 0xcd, + 0x68, 0x01, 0x7c, 0xcd, 0xb8, 0xfc, 0x7d, 0xcd, + 0xb8, 0xfc, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f, 0x0f, + 0xe6, 0x0f, 0xcd, 0xc5, 0xfc, 0xf1, 0xe6, 0x0f, + 0xfe, 0x0a, 0x38, 0x02, 0xc6, 0x07, 0xc6, 0x30, + 0x4f, 0xcd, 0x71, 0x01, 0xc9, 0xff, 0x00, 0x00, + 0x01, 0xff, 0x02, 0x00, 0x41, 0xff, 0x42, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x01, 0x00, 0x02, 0x00, + 0x42, 0x00, 0x40, 0xff, 0x41, 0xaa, 0x00, 0x55, + 0x02, 0xaa, 0x01, 0xaa, 0x41, 0x55, 0x01, 0xaa, + 0x40, 0x55, 0x00, 0x55, 0x42, 0x55, 0x41, 0x55, + 0x40, 0x00, 0x80, 0x57, 0x72, 0x6f, 0x6e, 0x67, + 0x20, 0x74, 0x72, 0x61, 0x63, 0x6b, 0xae, 0x00, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x70, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0xae, + 0x00, 0x44, 0x61, 0x74, 0x61, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0xae, 0x00, 0x4e, 0x6f, 0x74, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xae, 0x00, + 0x4c, 0x6f, 0x73, 0x74, 0x20, 0x64, 0x61, 0x74, + 0x61, 0xae, 0x00, 0x44, 0x72, 0x69, 0x76, 0x65, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, + 0x64, 0x79, 0xae, 0x00, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0xae, 0x00, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0xae, 0x00, 0x0d, 0x0a, 0x44, 0x69, + 0x73, 0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x20, 0x6f, 0x6e, 0x20, 0x64, 0x72, 0x69, 0x76, + 0x65, 0xa0, 0x00, 0x0d, 0x0a, 0x54, 0x79, 0x70, + 0x65, 0x20, 0x52, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, + 0x2c, 0x20, 0x41, 0x20, 0x74, 0x6f, 0x20, 0x61, + 0x62, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x6f, 0x72, + 0x20, 0x49, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, + 0x6e, 0x6f, 0x72, 0x65, 0x3a, 0xa0, 0x00, 0x0a, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x6e, + 0x20, 0x43, 0x50, 0x2f, 0x4d, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, + 0x6b, 0x65, 0x74, 0x74, 0x65, 0x2e, 0x00, 0x0d, + 0x0a, 0x50, 0x75, 0x73, 0x68, 0x20, 0x72, 0x65, + 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, + 0x2e, 0xa0, 0x00, 0x1b, 0x25, 0x1b, 0x47, 0x30, + 0x00, 0x0d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x2d, + 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x4f, 0x4d, 0x20, + 0x52, 0x65, 0x76, 0x2e, 0x20, 0x33, 0x2e, 0x31, + 0x0d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x38, 0x32, + 0x2c, 0x31, 0x39, 0x38, 0x33, 0x2c, 0x31, 0x39, + 0x38, 0x34, 0x20, 0x4d, 0x6f, 0x72, 0x72, 0x6f, + 0x77, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0d, + 0x0a, 0x0a, 0x00, 0x54, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x20, 0x2d, 0x2d, 0x20, 0x70, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, + 0x64, 0x20, 0x62, 0x79, 0x3a, 0x20, 0x00, 0x4d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x4f, 0x2e, + 0x4b, 0x2e, 0x0d, 0x0a, 0x0a, 0x00, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x20, 0x43, 0x50, 0x2f, + 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x20, 0x41, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x5b, + 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5d, 0x20, + 0x07, 0x00, 0x07, 0x07, 0x52, 0x4f, 0x4d, 0x20, + 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x00, 0x07, 0x07, 0x52, + 0x41, 0x4d, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, + 0x07, 0x07, 0x0d, 0x0a, 0x52, 0x65, 0x61, 0x64, + 0x20, 0x00, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x00, 0x20, 0x61, 0x74, + 0x20, 0x52, 0x41, 0x4d, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x00, 0x0d, + 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x20, 0x4d, 0x65, 0x6e, + 0x75, 0x0d, 0x0a, 0x0a, 0x31, 0x29, 0x20, 0x50, + 0x6f, 0x72, 0x74, 0x20, 0x31, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, + 0x0d, 0x0a, 0x32, 0x29, 0x20, 0x50, 0x6f, 0x72, + 0x74, 0x20, 0x32, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x20, + 0x42, 0x61, 0x72, 0x62, 0x65, 0x72, 0x2d, 0x50, + 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, + 0x65, 0x72, 0x6e, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x0d, 0x0a, 0x33, 0x29, 0x20, 0x43, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x20, + 0x70, 0x6f, 0x72, 0x74, 0x20, 0x2f, 0x0d, 0x0a, + 0x34, 0x29, 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x20, + 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, + 0x70, 0x6f, 0x72, 0x74, 0x20, 0x32, 0x0d, 0x0a, + 0x35, 0x29, 0x20, 0x52, 0x41, 0x4d, 0x20, 0x74, + 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x36, 0x29, 0x20, + 0x46, 0x44, 0x43, 0x20, 0x52, 0x2f, 0x57, 0x0d, + 0x0a, 0x37, 0x29, 0x20, 0x46, 0x44, 0x43, 0x20, + 0x73, 0x65, 0x65, 0x6b, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x0d, 0x0a, 0x38, 0x29, 0x20, 0x56, 0x46, + 0x4f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x0d, 0x0a, + 0x39, 0x29, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x0d, + 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, + 0x23, 0x3a, 0x00, 0x0d, 0x0a, 0x45, 0x6e, 0x64, + 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, 0x73, 0x73, + 0x20, 0x00, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x20, 0x73, 0x6f, 0x20, 0x66, 0x61, 0x72, + 0x2e, 0x00, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x00, 0x0d, 0x0a, 0x46, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x00, 0x0d, + 0x0a, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, + 0x00, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x65, 0x73, 0x74, 0x20, 0x28, 0x41, 0x2d, + 0x44, 0x29, 0x3a, 0x00, 0x0d, 0x0a, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x64, + 0x20, 0x64, 0x69, 0x73, 0x6b, 0x65, 0x74, 0x74, + 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x72, 0x69, + 0x76, 0x65, 0x20, 0x00, 0x0d, 0x0a, 0x57, 0x72, + 0x69, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x2e, 0x2e, + 0x00, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, + 0x00, 0x0d, 0x0a, 0x00, 0x3a, 0xa0, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x0a, 0x00, 0xfe, 0x00, 0x00, + 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, 0x00, 0x00, + 0x00, 0x01, 0x03, 0x05, 0x1c, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x32, 0x01, + 0x01, 0xd8, 0x58, 0x05, 0x6f, 0x03, 0x05, 0x1c, + 0xff, 0x02, 0x59, 0x58, 0x05, 0x6f, 0x03, 0x05, + 0x1c, 0xff, 0x04, 0x5a, 0x58, 0x05, 0x6f, 0x03, + 0x05, 0x1c, 0xff, 0x04, 0x5b, 0x58, 0x05, 0x6f, + 0x03, 0x05, 0x1c, 0xff, 0x18, 0x0c, 0x0b, 0x0c, + 0x29, 0x0c, 0x29, 0x0c, 0x35, 0x0c, 0x4b, 0x0c, + 0x40, 0x0c, 0x4b, 0x0c, 0x5c, 0x0c, 0x6d, 0x0c, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; static uint8 *mmd_rom = mmd_rom_31; /* Default 3.1 ROM */ @@ -3263,7 +3263,7 @@ static t_stat mmd_config_line(DEVICE *dev, TMLN *tmln, int baud) { char config[20]; const char *fmt; - + t_stat r = SCPE_IERR; if (tmln->serport) { diff --git a/AltairZ80/s100_djhdc.c b/AltairZ80/s100_djhdc.c index 79f036f2..7479c94b 100644 --- a/AltairZ80/s100_djhdc.c +++ b/AltairZ80/s100_djhdc.c @@ -1,864 +1,864 @@ -/************************************************************************* - * * - * Copyright (c) 2022 Howard M. Harte. * - * https://github.com/hharte * - * * - * Permission is hereby granted, free of charge, to any person obtaining * - * a copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to * - * the following conditions: * - * * - * The above copyright notice and this permission notice shall be * - * included in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- * - * INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * - * SOFTWARE. * - * * - * Except as contained in this notice, the names of The Authors shall * - * not be used in advertising or otherwise to promote the sale, use or * - * other dealings in this Software without prior written authorization * - * from the Authors. * - * * - * Based on s100_disk3.c * - * * - * Module Description: * - * Morrow Disk Jockey HDC-DMA Hard Disk Controller module for SIMH. * - * Reference: * - * http://www.bitsavers.org/pdf/morrow/boards/HDC_DMA_Technical_Manual_1983.pdf * - * * - *************************************************************************/ - -#include "altairz80_defs.h" -#include "sim_imd.h" - -#define DEV_NAME "DJHDC" - -#define DJHDC_MAX_CYLS 1024 -#define DJHDC_MAX_HEADS 8 -#define DJHDC_MAX_SPT 256 - -/* Debug flags */ -#define ERROR_MSG (1 << 0) -#define SEEK_MSG (1 << 1) -#define OPCODE_MSG (1 << 2) -#define RD_DATA_MSG (1 << 3) -#define WR_DATA_MSG (1 << 4) -#define IRQ_MSG (1 << 5) -#define VERBOSE_MSG (1 << 6) -#define FORMAT_MSG (1 << 7) - -#define DJHDC_MAX_DRIVES 4 - -/* DJHDC I/O Ports */ -#define DJHDC_RESET 0 /* Reset */ -#define DJHDC_START 1 /* Start */ - -#define DJHDC_LINK_ADDR 0x000050 /* Default link address in RAM */ - -#define DJHDC_STEP_DIR 0x10 /* Bit 4, Step OUT */ - -#define DJHDC_IRQ_EN_MASK 0x80 /* Interrupt enable mask */ - -#define DJHDC_OPCODE_READ_DATA 0x00 -#define DJHDC_OPCODE_WRITE_DATA 0x01 -#define DJHDC_OPCODE_READ_HEADER 0x02 -#define DJHDC_OPCODE_FORMAT_TRACK 0x03 -#define DJHDC_OPCODE_LOAD_CONSTANTS 0x04 -#define DJHDC_OPCODE_SENSE_STATUS 0x05 -#define DJHDC_OPCODE_NOOP 0x06 - -#define DJHDC_STATUS_BUSY 0x00 /* Busy */ -#define DJHDC_STATUS_NOT_READY 0x01 /* Drive not ready */ -#define DJHDC_STATUS_HEADER_NOT_FOUND 0x04 /* Sector header not found */ -#define DJHDC_STATUS_DATA_NOT_FOUND 0x05 /* Sector data not found */ -#define DJHDC_STATUS_DATA_OVERRUN 0x06 /* Data overrun(channel error) */ -#define DJHDC_STATUS_DATA_CRC_ERROR 0x07 /* Data CRC error */ -#define DJHDC_STATUS_WRITE_FAULT 0x08 /* Write fault */ -#define DJHDC_STATUS_HEADER_CRC_ERROR 0x09 /* Sector header CRC error */ -#define DJHDC_STATUS_ILLEGAL_COMMAND 0xA0 /* Illegal command */ -#define DJHDC_STATUS_COMPLETE 0xFF /* Successful completion */ - -#define DJHDC_TRACK_0_DETECT (1 << 0) /* 0 = track 0. */ -#define DJHDC_WRITE_FAULT_SIGNAL (1 << 1) /* Drive Write fault (0). */ -#define DJHDC_DRIVE_READY_SIGNAL (1 << 2) /* Drive is up to speed (0). */ - -#define DJHDC_OPCODE_MASK 0x07 - -#define DJHDC_IOPB_LEN 16 - -#define DJHDC_IOPB_SELDRV 0 -#define DJHDC_IOPB_STEP_L 1 -#define DJHDC_IOPB_STEP_H 2 -#define DJHDC_IOPB_SEL_HD 3 -#define DJHDC_IOPB_DMA_L 4 -#define DJHDC_IOPB_DMA_H 5 -#define DJHDC_IOPB_DMA_E 6 -#define DJHDC_IOPB_ARG0 7 -#define DJHDC_IOPB_ARG1 8 -#define DJHDC_IOPB_ARG2 9 -#define DJHDC_IOPB_ARG3 10 -#define DJHDC_IOPB_OPCODE 11 -#define DJHDC_IOPB_STATUS 12 -#define DJHDC_IOPB_LINK 13 -#define DJHDC_IOPB_LINK_H 14 -#define DJHDC_IOPB_LINK_E 15 - -#define DJHDC_INT 1 /* DJHDC interrupts tied to VI1 */ - -typedef struct { - UNIT *uptr; - DISK_INFO *imd; - uint16 sectsize; /* sector size, not including pre/postamble */ - uint16 nsectors; /* number of sectors/track */ - uint16 nheads; /* number of heads */ - uint16 ntracks; /* number of tracks */ - uint16 res_tracks; /* Number of reserved tracks on drive. */ - uint16 track; /* Current Track */ - - uint16 cur_sect; /* current starting sector of transfer */ - uint16 cur_cyl; /* Current Track */ - uint16 cur_head; /* Number of sectors to transfer */ - uint16 cur_sectsize;/* Current sector size */ - uint8 ready; /* Is drive ready? */ -} DJHDC_DRIVE_INFO; - -typedef struct { - PNP_INFO pnp; /* Plug and Play */ - uint8 sel_drive; /* Currently selected drive */ - uint8 mode; /* mode (0xFF=absolute, 0x00=logical) */ - uint8 ndrives; /* Number of drives attached to the controller */ - - uint32 link_addr; /* Link Address for next IOPB */ - uint32 dma_addr; /* DMA Address for the current IOPB */ - - uint16 steps; /* Step count */ - uint8 step_dir; /* Step direction, 1 = out. */ - uint8 irq_enable; - uint8 step_delay; - uint8 head_settle_time; - uint8 sector_size_code; - - DJHDC_DRIVE_INFO drive[DJHDC_MAX_DRIVES]; - uint8 iopb[16]; -} DJHDC_INFO; - -static DJHDC_INFO djhdc_info_data = { { 0x0, 0, 0x54, 2 } }; -static DJHDC_INFO *djhdc_info = &djhdc_info_data; - -/* Disk geometries: - * IMI SCRIBE - * Sectsize: 1024 1024 - * Sectors: 8 8 - * Heads: 6 4 - * Tracks: 306 480 - */ - -/* Default geometry for a 15MB hard disk. */ -#define SCRIBE_SECTSIZE 1024 -#define SCRIBE_NSECTORS 8 -#define SCRIBE_NHEADS 4 -#define SCRIBE_NTRACKS 480 - -static const char* djhdc_opcode_str[] = { - "Read Data ", - "Write Data ", - "Read Header ", - "Format Track ", - "Load Constants", - "Sense Status ", - "No Operation ", - "Invalid " -}; - -static int32 ntracks = SCRIBE_NTRACKS; -static int32 nheads = SCRIBE_NHEADS; -static int32 nsectors = SCRIBE_NSECTORS; -static int32 sectsize = SCRIBE_SECTSIZE; - -extern uint32 PCX; -extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type, - int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap); -extern int32 find_unit_index(UNIT *uptr); -extern void raise_scp300f_interrupt(uint8 intnum); - -/* These are needed for DMA. */ -extern void PutByteDMA(const uint32 Addr, const uint32 Value); -extern uint8 GetByteDMA(const uint32 Addr); - -#define UNIT_V_DJHDC_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */ -#define UNIT_DJHDC_VERBOSE (1 << UNIT_V_DJHDC_VERBOSE) -#define DJHDC_CAPACITY (SCRIBE_NTRACKS * SCRIBE_NHEADS * \ - SCRIBE_NSECTORS * SCRIBE_SECTSIZE) /* Default Disk Capacity */ - -static t_stat djhdc_reset(DEVICE *djhdc_dev); -static t_stat djhdc_attach(UNIT *uptr, CONST char *cptr); -static t_stat djhdc_detach(UNIT *uptr); -static t_stat djhdc_unit_set_geometry(UNIT* uptr, int32 value, CONST char* cptr, void* desc); -static t_stat djhdc_unit_show_geometry(FILE* st, UNIT* uptr, int32 value, CONST void* desc); -static int DJHDC_Validate_CHSN(DJHDC_DRIVE_INFO* pDrive); -#ifdef DJHDC_INTERRUPTS -static void raise_djhdc_interrupt(void); -#endif /* DJHDC_INTERRUPTS */ - -static const char* djhdc_description(DEVICE *dptr); - -static int32 djhdcdev(const int32 port, const int32 io, const int32 data); - -/* static uint8 DJHDC_Read(const uint32 Addr); */ -static uint8 DJHDC_Write(const uint32 Addr, uint8 cData); - -static UNIT djhdc_unit[] = { - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) } -}; - -static REG djhdc_reg[] = { - { DRDATAD (NTRACKS, ntracks, 10, - "Number of tracks"), }, - { DRDATAD (NHEADS, nheads, 8, - "Number of heads"), }, - { DRDATAD (NSECTORS, nsectors, 8, - "Number of sectors per track"), }, - { DRDATAD (SECTSIZE, sectsize, 11, - "Sector size not including pre/postamble"), }, - { HRDATAD (SEL_DRIVE, djhdc_info_data.sel_drive, 3, - "Currently selected drive"), }, - { HRDATAD (MODE, djhdc_info_data.mode, 8, - "Mode (0xFF=absolute, 0x00=logical)"), }, - { HRDATAD (NDRIVES, djhdc_info_data.ndrives, 8, - "Number of drives attached to the controller"), }, - { HRDATAD (LINK_ADDR, djhdc_info_data.link_addr, 32, - "Link address for next IOPB"), }, - { HRDATAD (DMA_ADDR, djhdc_info_data.dma_addr, 32, - "DMA address for the current IOPB"), }, - { BRDATAD (IOPB, djhdc_info_data.iopb, 16, 8, 16, - "IOPB command register"), }, - { NULL } -}; - -#define DJHDC_NAME "Morrow HDC/DMA Hard Disk Controller" - -static const char* djhdc_description(DEVICE *dptr) { - if (dptr == NULL) { - return NULL; - } - return DJHDC_NAME; -} - -static MTAB djhdc_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", - &set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" }, - { MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "GEOMETRY", "GEOMETRY", - &djhdc_unit_set_geometry, &djhdc_unit_show_geometry, NULL, - "Set disk geometry C:nnnn/H:n/S:nnn/N:nnnn" }, - { 0 } -}; - -/* Debug Flags */ -static DEBTAB djhdc_dt[] = { - { "ERROR", ERROR_MSG, "Error messages" }, - { "SEEK", SEEK_MSG, "Seek messages" }, - { "OPCODE", OPCODE_MSG, "Opcode messages" }, - { "READ", RD_DATA_MSG, "Read messages" }, - { "WRITE", WR_DATA_MSG, "Write messages" }, - { "IRQ", IRQ_MSG, "IRQ messages" }, - { "VERBOSE", VERBOSE_MSG, "Verbose messages" }, - { "FORMAT", FORMAT_MSG, "Format messages" }, - { NULL, 0 } -}; - -DEVICE djhdc_dev = { - DEV_NAME, djhdc_unit, djhdc_reg, djhdc_mod, - DJHDC_MAX_DRIVES, 10, 31, 1, DJHDC_MAX_DRIVES, DJHDC_MAX_DRIVES, - NULL, NULL, &djhdc_reset, - NULL, &djhdc_attach, &djhdc_detach, - &djhdc_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), ERROR_MSG, - djhdc_dt, NULL, NULL, NULL, NULL, NULL, &djhdc_description -}; - -/* Reset routine */ -static t_stat djhdc_reset(DEVICE *dptr) -{ - PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; - - if(dptr->flags & DEV_DIS) { /* Disconnect I/O Ports */ - sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &djhdcdev, "djhdcdev", TRUE); - } else { - /* Connect DJHDC at base address */ - if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &djhdcdev, "djhdcdev", FALSE) != 0) { - sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base); - return SCPE_ARG; - } - } - - djhdc_info->link_addr = DJHDC_LINK_ADDR; /* After RESET, the link pointer is at 0x000050. */ - - return SCPE_OK; -} - - -/* Attach routine */ -static t_stat djhdc_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r = SCPE_OK; - DJHDC_DRIVE_INFO *pDrive; - int i = 0; - - i = find_unit_index(uptr); - if (i == -1) { - return (SCPE_IERR); - } - pDrive = &djhdc_info->drive[i]; - - pDrive->ready = 1; - pDrive->track = 5; - - if (pDrive->ntracks == 0) { - /* If geometry was not specified, default to Miniscribe 15MB */ - pDrive->ntracks = SCRIBE_NTRACKS; - pDrive->nheads = SCRIBE_NHEADS; - pDrive->nsectors = SCRIBE_NSECTORS; - pDrive->sectsize = SCRIBE_SECTSIZE; - } - - r = attach_unit(uptr, cptr); /* attach unit */ - if ( r != SCPE_OK) /* error? */ - return r; - - /* Determine length of this disk */ - if(sim_fsize(uptr->fileref) != 0) { - uptr->capac = sim_fsize(uptr->fileref); - } else { - uptr->capac = (pDrive->ntracks * pDrive->nsectors * pDrive->nheads * pDrive->sectsize); - } - - pDrive->uptr = uptr; - - /* Default for new file is DSK */ - uptr->u3 = IMAGE_TYPE_DSK; - - if(uptr->capac > 0) { - r = assignDiskType(uptr); - if (r != SCPE_OK) { - djhdc_detach(uptr); - return r; - } - } - - if (uptr->flags & UNIT_DJHDC_VERBOSE) - sim_printf("DJHDC%d, attached to '%s', type=%s, len=%d\n", i, cptr, - uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", - uptr->capac); - - if(uptr->u3 == IMAGE_TYPE_IMD) { - if(uptr->capac < 318000) { - sim_printf("Cannot create IMD files with SIMH.\nCopy an existing file and format it with CP/M.\n"); - djhdc_detach(uptr); - return SCPE_OPENERR; - } - - if (uptr->flags & UNIT_DJHDC_VERBOSE) - sim_printf("--------------------------------------------------------\n"); - djhdc_info->drive[i].imd = diskOpenEx((uptr->fileref), (uptr->flags & UNIT_DJHDC_VERBOSE), - &djhdc_dev, VERBOSE_MSG, VERBOSE_MSG); - if (uptr->flags & UNIT_DJHDC_VERBOSE) - sim_printf("\n"); - } else { - djhdc_info->drive[i].imd = NULL; - } - - return SCPE_OK; -} - - -/* Detach routine */ -static t_stat djhdc_detach(UNIT *uptr) -{ - DJHDC_DRIVE_INFO *pDrive; - t_stat r; - int32 i; - - i = find_unit_index(uptr); - - if (i == -1) { - return (SCPE_IERR); - } - - pDrive = &djhdc_info->drive[i]; - - pDrive->ready = 0; - - if (uptr->flags & UNIT_DJHDC_VERBOSE) - sim_printf("Detach DJHDC%d\n", i); - - r = detach_unit(uptr); /* detach unit */ - if ( r != SCPE_OK) - return r; - - return SCPE_OK; -} - -/* Set geometry of the disk drive */ -static t_stat djhdc_unit_set_geometry(UNIT* uptr, int32 value, CONST char* cptr, void* desc) -{ - DJHDC_DRIVE_INFO* pDrive; - int32 i; - int32 result; - uint16 newCyls, newHeads, newSPT, newSecLen; - - i = find_unit_index(uptr); - - if (i == -1) { - return (SCPE_IERR); - } - - pDrive = &djhdc_info->drive[i]; - - if (cptr == NULL) - return SCPE_ARG; - - result = sscanf(cptr, "C:%hd/H:%hd/S:%hd/N:%hd", &newCyls, &newHeads, &newSPT, &newSecLen); - if (result != 4) - return SCPE_ARG; - - /* Validate Cyl, Heads, Sector, Length are valid for the HDC-1001 */ - if (newCyls < 1 || newCyls > DJHDC_MAX_CYLS) { - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of cylinders must be 1-%d.\n", - djhdc_info->sel_drive, DJHDC_MAX_CYLS); - return SCPE_ARG; - } - if (newHeads < 1 || newHeads > DJHDC_MAX_HEADS) { - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of heads must be 1-%d.\n", - djhdc_info->sel_drive, DJHDC_MAX_HEADS); - return SCPE_ARG; - } - if (newSPT < 1 || newSPT > DJHDC_MAX_SPT) { - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of sectors per track must be 1-%d.\n", - djhdc_info->sel_drive, DJHDC_MAX_SPT); - return SCPE_ARG; - } - if (newSecLen != 2048 && newSecLen != 1024 && newSecLen != 512 && newSecLen != 256 && newSecLen != 128) { - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Sector length must be 128, 256, 512, 1024, or 2048.\n", - djhdc_info->sel_drive); - return SCPE_ARG; - } - - pDrive->ntracks = newCyls; - pDrive->nheads = newHeads; - pDrive->nsectors = newSPT; - pDrive->sectsize = newSecLen; - - return SCPE_OK; -} - -/* Show geometry of the disk drive */ -static t_stat djhdc_unit_show_geometry(FILE* st, UNIT* uptr, int32 value, CONST void* desc) -{ - DJHDC_DRIVE_INFO* pDrive; - int32 i; - - i = find_unit_index(uptr); - - if (i == -1) { - return (SCPE_IERR); - } - - pDrive = &djhdc_info->drive[i]; - - fprintf(st, "C:%d/H:%d/S:%d/N:%d", - pDrive->ntracks, pDrive->nheads, pDrive->nsectors, pDrive->sectsize); - - return SCPE_OK; -} - -static int32 djhdcdev(const int32 port, const int32 io, const int32 data) -{ - sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME ": " ADDRESS_FORMAT - " IO %s, Port %02x\n", PCX, io ? "WR" : "RD", port); - if(io) { - DJHDC_Write(port, (uint8)data); - return 0; - } else { - return(0xFF); - } -} - -static uint8 DJHDC_Write(const uint32 Addr, uint8 cData) -{ - uint32 next_link; - uint8 result = DJHDC_STATUS_COMPLETE; - uint8 i; - uint8 opcode; - - DJHDC_DRIVE_INFO *pDrive; - - /* RESET */ - if ((Addr & 1) == DJHDC_RESET) { - djhdc_info->link_addr = DJHDC_LINK_ADDR - DJHDC_IOPB_LINK; - - sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: RESET\n", - djhdc_info->sel_drive); - - return 0; - } - - /* START */ - - /* Read first three bytes of IOPB (link address) */ - for (i = DJHDC_IOPB_LINK; i < DJHDC_IOPB_LEN; i++) { - djhdc_info->iopb[i] = GetByteDMA((djhdc_info->link_addr) + i); - } - - next_link = djhdc_info->iopb[DJHDC_IOPB_LINK + 0]; - next_link |= djhdc_info->iopb[DJHDC_IOPB_LINK+1] << 8; - next_link |= djhdc_info->iopb[DJHDC_IOPB_LINK+2] << 16; - - /* Point IOPB to new link */ - djhdc_info->link_addr = next_link; - - /* Read remaineder of IOPB */ - for(i = 0; i < DJHDC_IOPB_LEN-3; i++) { - djhdc_info->iopb[i] = GetByteDMA((djhdc_info->link_addr) + i); - } - - /* Process the IOPB */ - djhdc_info->iopb[DJHDC_IOPB_OPCODE] = djhdc_info->iopb[DJHDC_IOPB_OPCODE] & DJHDC_OPCODE_MASK; - - opcode = djhdc_info->iopb[DJHDC_IOPB_OPCODE]; - djhdc_info->sel_drive = djhdc_info->iopb[DJHDC_IOPB_SELDRV] & 0x03; - djhdc_info->step_dir = (djhdc_info->iopb[DJHDC_IOPB_SELDRV] & DJHDC_STEP_DIR) ? 1 : 0; - - djhdc_info->steps = djhdc_info->iopb[DJHDC_IOPB_STEP_L]; - djhdc_info->steps |= djhdc_info->iopb[DJHDC_IOPB_STEP_H] << 8; - - djhdc_info->dma_addr = djhdc_info->iopb[DJHDC_IOPB_DMA_L]; - djhdc_info->dma_addr |= djhdc_info->iopb[DJHDC_IOPB_DMA_H] << 8; - djhdc_info->dma_addr |= djhdc_info->iopb[DJHDC_IOPB_DMA_E] << 16; - - sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: SEEK=%d %s, LINK=0x%05x, OPCODE=%x, %s DMA@0x%05x\n", - djhdc_info->sel_drive, - djhdc_info->steps, - djhdc_info->step_dir ? "OUT" : "IN", - djhdc_info->link_addr, - djhdc_info->iopb[DJHDC_IOPB_OPCODE], - djhdc_opcode_str[djhdc_info->iopb[DJHDC_IOPB_OPCODE]], - djhdc_info->dma_addr); - - pDrive = &djhdc_info->drive[djhdc_info->sel_drive]; - - if(pDrive->ready) { - /* Seek phase */ - if (djhdc_info->step_dir) { - /* Step Out */ - if (djhdc_info->steps >= pDrive->cur_cyl) { - pDrive->cur_cyl = 0; - sim_debug(SEEK_MSG, &djhdc_dev, DEV_NAME "[%d]: HOME\n", - djhdc_info->sel_drive); - } - else { - pDrive->cur_cyl -= djhdc_info->steps; - } - } - else { - /* Step In */ - pDrive->cur_cyl += djhdc_info->steps; - } - - sim_debug(SEEK_MSG, &djhdc_dev, DEV_NAME "[%d]: Current track: %d\n", - djhdc_info->sel_drive, - pDrive->cur_cyl); - - - /* Perform command */ - switch(opcode) { - case DJHDC_OPCODE_READ_DATA: - case DJHDC_OPCODE_WRITE_DATA: - { - uint32 track_len; - uint32 xfr_len; - uint32 file_offset; - uint32 xfr_count = 0; - uint8* dataBuffer; - size_t rtn; - - pDrive->cur_cyl = djhdc_info->iopb[DJHDC_IOPB_ARG0] | (djhdc_info->iopb[DJHDC_IOPB_ARG1] << 8); - pDrive->cur_head = djhdc_info->iopb[DJHDC_IOPB_ARG2]; - pDrive->cur_sect = djhdc_info->iopb[DJHDC_IOPB_ARG3] - 1; - - if (DJHDC_Validate_CHSN(pDrive) != SCPE_OK) { - result = DJHDC_STATUS_HEADER_NOT_FOUND; - break; - } - - track_len = pDrive->nsectors * pDrive->nheads * pDrive->sectsize; - - file_offset = (pDrive->cur_cyl * track_len); /* Calculate offset based on current track */ - file_offset += pDrive->nsectors * pDrive->cur_head * pDrive->sectsize; - file_offset += pDrive->cur_sect * pDrive->sectsize; - - xfr_len = pDrive->sectsize; - - dataBuffer = (uint8*)malloc(xfr_len); - if (dataBuffer == NULL) { - sim_printf("%s: error allocating memory\n", __FUNCTION__); - return (0); - } - - if (sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET) == 0) { - - if (opcode == DJHDC_OPCODE_READ_DATA) { /* Read */ - rtn = sim_fread(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref); - - sim_debug(RD_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " READ @0x%05x C:%04d/H:%d/S:%04d len=%d, file_offset=%d, %s\n", - djhdc_info->sel_drive, - PCX, - djhdc_info->dma_addr, - pDrive->cur_cyl, - pDrive->cur_head, - pDrive->cur_sect, - xfr_len, - file_offset, - rtn == (size_t)xfr_len ? "OK" : "NOK"); - - - /* Perform DMA Transfer */ - for (xfr_count = 0; xfr_count < xfr_len; xfr_count++) { - PutByteDMA(djhdc_info->dma_addr + xfr_count, dataBuffer[xfr_count]); - } - } - else { /* Write */ - sim_debug(WR_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " WRITE @0x%05x C:%04d/H:%d/S:%04d file_offset=%d, len=%d\n", - djhdc_info->sel_drive, - PCX, djhdc_info->dma_addr, - pDrive->cur_cyl, - pDrive->cur_head, - pDrive->cur_sect, - file_offset, - xfr_len); - - /* Perform DMA Transfer */ - for (xfr_count = 0; xfr_count < xfr_len; xfr_count++) { - dataBuffer[xfr_count] = GetByteDMA(djhdc_info->dma_addr + xfr_count); - } - - sim_fwrite(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref); - } - } - else { - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " READWRITE: sim_fseek error.\n", djhdc_info->sel_drive, PCX); - } - - free(dataBuffer); - - break; - } - case DJHDC_OPCODE_READ_HEADER: - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " READ_HEADER: not implemented.\n", djhdc_info->sel_drive, PCX); - result = DJHDC_STATUS_HEADER_NOT_FOUND; - break; - case DJHDC_OPCODE_FORMAT_TRACK: - { - uint32 track_len; - uint32 file_offset; - uint8* fmtBuffer; - uint8 head; - uint8 gap; - uint8 sector_count; - uint8 sector_size_code; - uint8 fill_byte; - - head = ~(djhdc_info->iopb[DJHDC_IOPB_SEL_HD] >> 2) & 7; - gap = djhdc_info->iopb[DJHDC_IOPB_ARG0]; - sector_count = 255 - djhdc_info->iopb[DJHDC_IOPB_ARG1]; - sector_size_code = djhdc_info->iopb[DJHDC_IOPB_ARG2]; - fill_byte = djhdc_info->iopb[DJHDC_IOPB_ARG3]; - - switch (sector_size_code) { - case 0xFF: - pDrive->cur_sectsize = 128; - break; - case 0xFE: - pDrive->cur_sectsize = 256; - break; - case 0xFC: - pDrive->cur_sectsize = 512; - break; - case 0xF8: - pDrive->cur_sectsize = 1024; - break; - case 0xF0: - pDrive->cur_sectsize = 2048; - break; - default: - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME ": Invalid sector size code: 0x%02x.\n", - djhdc_info->sector_size_code); - pDrive->cur_sectsize = 0; - result = DJHDC_STATUS_ILLEGAL_COMMAND; - break; - } - - if (DJHDC_Validate_CHSN(pDrive) != SCPE_OK) { - result = DJHDC_STATUS_HEADER_NOT_FOUND; - break; - } - - track_len = pDrive->nheads * sector_count * pDrive->sectsize; - - file_offset = pDrive->cur_cyl * track_len; /* Calculate offset based on current track */ - file_offset += head * sector_count * pDrive->sectsize; - - sim_debug(FORMAT_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " FORMAT C:%d/H:%d, Gap=%d, Fill=0x%02x, Count=%d, Sector Size:=%d, file offset: 0x%08x\n", - djhdc_info->sel_drive, - PCX, - pDrive->cur_cyl, - head, - gap, - fill_byte, - sector_count, - pDrive->sectsize, - file_offset); - - fmtBuffer = (uint8*)malloc(track_len); - - if (fmtBuffer == NULL) { - sim_printf("%s: error allocating memory\n", __FUNCTION__); - return (0); - } - - memset(fmtBuffer, fill_byte, track_len); - - if (sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET) == 0) { - sim_fwrite(fmtBuffer, 1, track_len, (pDrive->uptr)->fileref); - } - else { - sim_debug(WR_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " FORMAT: sim_fseek error.\n", djhdc_info->sel_drive, PCX); - result = DJHDC_STATUS_WRITE_FAULT; - } - - free(fmtBuffer); - - break; - } - case DJHDC_OPCODE_LOAD_CONSTANTS: - djhdc_info->irq_enable = (djhdc_info->iopb[DJHDC_IOPB_ARG1] & DJHDC_IRQ_EN_MASK) ? 1 : 0; - djhdc_info->step_delay = djhdc_info->iopb[DJHDC_IOPB_ARG1] & ~DJHDC_IRQ_EN_MASK; - djhdc_info->head_settle_time = djhdc_info->iopb[DJHDC_IOPB_ARG2]; - djhdc_info->sector_size_code = djhdc_info->iopb[DJHDC_IOPB_ARG3]; - - switch (djhdc_info->sector_size_code) { - case 0x00: - pDrive->cur_sectsize = 128; - break; - case 0x01: - pDrive->cur_sectsize = 256; - break; - case 0x03: - pDrive->cur_sectsize = 512; - break; - case 0x07: - pDrive->cur_sectsize = 1024; - break; - case 0x0F: - pDrive->cur_sectsize = 2048; - break; - default: - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME ": Invalid sector size code: 0x%02x.\n", - djhdc_info->sector_size_code); - pDrive->cur_sectsize = 0; - result = DJHDC_STATUS_ILLEGAL_COMMAND; - break; - } - - sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " Load Constants: Interrupt Enable: %d, step delay: %d, head settle time: %d, sector size %d (code: 0x%02x)\n", - djhdc_info->sel_drive, PCX, - djhdc_info->irq_enable, - djhdc_info->step_delay, - djhdc_info->head_settle_time, - pDrive->sectsize, - djhdc_info->sector_size_code); - break; - case DJHDC_OPCODE_SENSE_STATUS: - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " SENSE_STATUS: not implemented.\n", djhdc_info->sel_drive, PCX); - result = DJHDC_DRIVE_READY_SIGNAL; - if (pDrive->cur_cyl != 0) result = DJHDC_TRACK_0_DETECT; - break; - case DJHDC_OPCODE_NOOP: - sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " NOOP\n", djhdc_info->sel_drive, PCX); - break; - - default: - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT - " OPCODE=%x Unsupported\n", - djhdc_info->sel_drive, - PCX, - opcode & DJHDC_OPCODE_MASK); - result = DJHDC_STATUS_ILLEGAL_COMMAND; - break; - } - } else { /* Drive not ready */ - result = DJHDC_STATUS_NOT_READY; - } - /* Return status */ - djhdc_info->iopb[DJHDC_IOPB_STATUS] = result; - - /* Update IOPB in host memory */ - PutByteDMA(djhdc_info->link_addr + DJHDC_IOPB_STATUS, djhdc_info->iopb[DJHDC_IOPB_STATUS]); - -#ifdef DJHDC_INTERRUPTS - if(djhdc_info->irq_enable) { - raise_djhdc_interrupt(); - } -#endif /* DJHDC_INTERRUPTS */ - - return 0; -} - -/* Validate that Cyl, Head, Sector, Sector Length are valid for the current - * disk drive geometry. - */ -static int DJHDC_Validate_CHSN(DJHDC_DRIVE_INFO* pDrive) -{ - int status = SCPE_OK; - - /* Check to make sure we're operating on a valid C/H/S/N. */ - if ((pDrive->cur_cyl >= pDrive->ntracks) || - (pDrive->cur_head >= pDrive->nheads) || - (pDrive->cur_sect >= pDrive->nsectors) || - (pDrive->cur_sectsize != pDrive->sectsize)) - { - - sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: " ADDRESS_FORMAT - " ID Not Found (check disk geometry.)\n", djhdc_info->sel_drive, PCX); - - status = SCPE_IOERR; - } - - return (status); -} - -#ifdef DJHDC_INTERRUPTS -static void raise_djhdc_interrupt(void) -{ - sim_debug(IRQ_MSG, &djhdc_dev, DEV_NAME ": " ADDRESS_FORMAT " Interrupt\n", PCX); - - raise_scp300f_interrupt(DJHDC_INT); -} -#endif /* DJHDC_INTERRUPTS */ +/************************************************************************* + * * + * Copyright (c) 2022 Howard M. Harte. * + * https://github.com/hharte * + * * + * Permission is hereby granted, free of charge, to any person obtaining * + * a copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to * + * the following conditions: * + * * + * The above copyright notice and this permission notice shall be * + * included in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- * + * INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + * * + * Except as contained in this notice, the names of The Authors shall * + * not be used in advertising or otherwise to promote the sale, use or * + * other dealings in this Software without prior written authorization * + * from the Authors. * + * * + * Based on s100_disk3.c * + * * + * Module Description: * + * Morrow Disk Jockey HDC-DMA Hard Disk Controller module for SIMH. * + * Reference: * + * http://www.bitsavers.org/pdf/morrow/boards/HDC_DMA_Technical_Manual_1983.pdf * + * * + *************************************************************************/ + +#include "altairz80_defs.h" +#include "sim_imd.h" + +#define DEV_NAME "DJHDC" + +#define DJHDC_MAX_CYLS 1024 +#define DJHDC_MAX_HEADS 8 +#define DJHDC_MAX_SPT 256 + +/* Debug flags */ +#define ERROR_MSG (1 << 0) +#define SEEK_MSG (1 << 1) +#define OPCODE_MSG (1 << 2) +#define RD_DATA_MSG (1 << 3) +#define WR_DATA_MSG (1 << 4) +#define IRQ_MSG (1 << 5) +#define VERBOSE_MSG (1 << 6) +#define FORMAT_MSG (1 << 7) + +#define DJHDC_MAX_DRIVES 4 + +/* DJHDC I/O Ports */ +#define DJHDC_RESET 0 /* Reset */ +#define DJHDC_START 1 /* Start */ + +#define DJHDC_LINK_ADDR 0x000050 /* Default link address in RAM */ + +#define DJHDC_STEP_DIR 0x10 /* Bit 4, Step OUT */ + +#define DJHDC_IRQ_EN_MASK 0x80 /* Interrupt enable mask */ + +#define DJHDC_OPCODE_READ_DATA 0x00 +#define DJHDC_OPCODE_WRITE_DATA 0x01 +#define DJHDC_OPCODE_READ_HEADER 0x02 +#define DJHDC_OPCODE_FORMAT_TRACK 0x03 +#define DJHDC_OPCODE_LOAD_CONSTANTS 0x04 +#define DJHDC_OPCODE_SENSE_STATUS 0x05 +#define DJHDC_OPCODE_NOOP 0x06 + +#define DJHDC_STATUS_BUSY 0x00 /* Busy */ +#define DJHDC_STATUS_NOT_READY 0x01 /* Drive not ready */ +#define DJHDC_STATUS_HEADER_NOT_FOUND 0x04 /* Sector header not found */ +#define DJHDC_STATUS_DATA_NOT_FOUND 0x05 /* Sector data not found */ +#define DJHDC_STATUS_DATA_OVERRUN 0x06 /* Data overrun(channel error) */ +#define DJHDC_STATUS_DATA_CRC_ERROR 0x07 /* Data CRC error */ +#define DJHDC_STATUS_WRITE_FAULT 0x08 /* Write fault */ +#define DJHDC_STATUS_HEADER_CRC_ERROR 0x09 /* Sector header CRC error */ +#define DJHDC_STATUS_ILLEGAL_COMMAND 0xA0 /* Illegal command */ +#define DJHDC_STATUS_COMPLETE 0xFF /* Successful completion */ + +#define DJHDC_TRACK_0_DETECT (1 << 0) /* 0 = track 0. */ +#define DJHDC_WRITE_FAULT_SIGNAL (1 << 1) /* Drive Write fault (0). */ +#define DJHDC_DRIVE_READY_SIGNAL (1 << 2) /* Drive is up to speed (0). */ + +#define DJHDC_OPCODE_MASK 0x07 + +#define DJHDC_IOPB_LEN 16 + +#define DJHDC_IOPB_SELDRV 0 +#define DJHDC_IOPB_STEP_L 1 +#define DJHDC_IOPB_STEP_H 2 +#define DJHDC_IOPB_SEL_HD 3 +#define DJHDC_IOPB_DMA_L 4 +#define DJHDC_IOPB_DMA_H 5 +#define DJHDC_IOPB_DMA_E 6 +#define DJHDC_IOPB_ARG0 7 +#define DJHDC_IOPB_ARG1 8 +#define DJHDC_IOPB_ARG2 9 +#define DJHDC_IOPB_ARG3 10 +#define DJHDC_IOPB_OPCODE 11 +#define DJHDC_IOPB_STATUS 12 +#define DJHDC_IOPB_LINK 13 +#define DJHDC_IOPB_LINK_H 14 +#define DJHDC_IOPB_LINK_E 15 + +#define DJHDC_INT 1 /* DJHDC interrupts tied to VI1 */ + +typedef struct { + UNIT *uptr; + DISK_INFO *imd; + uint16 sectsize; /* sector size, not including pre/postamble */ + uint16 nsectors; /* number of sectors/track */ + uint16 nheads; /* number of heads */ + uint16 ntracks; /* number of tracks */ + uint16 res_tracks; /* Number of reserved tracks on drive. */ + uint16 track; /* Current Track */ + + uint16 cur_sect; /* current starting sector of transfer */ + uint16 cur_cyl; /* Current Track */ + uint16 cur_head; /* Number of sectors to transfer */ + uint16 cur_sectsize;/* Current sector size */ + uint8 ready; /* Is drive ready? */ +} DJHDC_DRIVE_INFO; + +typedef struct { + PNP_INFO pnp; /* Plug and Play */ + uint8 sel_drive; /* Currently selected drive */ + uint8 mode; /* mode (0xFF=absolute, 0x00=logical) */ + uint8 ndrives; /* Number of drives attached to the controller */ + + uint32 link_addr; /* Link Address for next IOPB */ + uint32 dma_addr; /* DMA Address for the current IOPB */ + + uint16 steps; /* Step count */ + uint8 step_dir; /* Step direction, 1 = out. */ + uint8 irq_enable; + uint8 step_delay; + uint8 head_settle_time; + uint8 sector_size_code; + + DJHDC_DRIVE_INFO drive[DJHDC_MAX_DRIVES]; + uint8 iopb[16]; +} DJHDC_INFO; + +static DJHDC_INFO djhdc_info_data = { { 0x0, 0, 0x54, 2 } }; +static DJHDC_INFO *djhdc_info = &djhdc_info_data; + +/* Disk geometries: + * IMI SCRIBE + * Sectsize: 1024 1024 + * Sectors: 8 8 + * Heads: 6 4 + * Tracks: 306 480 + */ + +/* Default geometry for a 15MB hard disk. */ +#define SCRIBE_SECTSIZE 1024 +#define SCRIBE_NSECTORS 8 +#define SCRIBE_NHEADS 4 +#define SCRIBE_NTRACKS 480 + +static const char* djhdc_opcode_str[] = { + "Read Data ", + "Write Data ", + "Read Header ", + "Format Track ", + "Load Constants", + "Sense Status ", + "No Operation ", + "Invalid " +}; + +static int32 ntracks = SCRIBE_NTRACKS; +static int32 nheads = SCRIBE_NHEADS; +static int32 nsectors = SCRIBE_NSECTORS; +static int32 sectsize = SCRIBE_SECTSIZE; + +extern uint32 PCX; +extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type, + int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap); +extern int32 find_unit_index(UNIT *uptr); +extern void raise_scp300f_interrupt(uint8 intnum); + +/* These are needed for DMA. */ +extern void PutByteDMA(const uint32 Addr, const uint32 Value); +extern uint8 GetByteDMA(const uint32 Addr); + +#define UNIT_V_DJHDC_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */ +#define UNIT_DJHDC_VERBOSE (1 << UNIT_V_DJHDC_VERBOSE) +#define DJHDC_CAPACITY (SCRIBE_NTRACKS * SCRIBE_NHEADS * \ + SCRIBE_NSECTORS * SCRIBE_SECTSIZE) /* Default Disk Capacity */ + +static t_stat djhdc_reset(DEVICE *djhdc_dev); +static t_stat djhdc_attach(UNIT *uptr, CONST char *cptr); +static t_stat djhdc_detach(UNIT *uptr); +static t_stat djhdc_unit_set_geometry(UNIT* uptr, int32 value, CONST char* cptr, void* desc); +static t_stat djhdc_unit_show_geometry(FILE* st, UNIT* uptr, int32 value, CONST void* desc); +static int DJHDC_Validate_CHSN(DJHDC_DRIVE_INFO* pDrive); +#ifdef DJHDC_INTERRUPTS +static void raise_djhdc_interrupt(void); +#endif /* DJHDC_INTERRUPTS */ + +static const char* djhdc_description(DEVICE *dptr); + +static int32 djhdcdev(const int32 port, const int32 io, const int32 data); + +/* static uint8 DJHDC_Read(const uint32 Addr); */ +static uint8 DJHDC_Write(const uint32 Addr, uint8 cData); + +static UNIT djhdc_unit[] = { + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DJHDC_CAPACITY) } +}; + +static REG djhdc_reg[] = { + { DRDATAD (NTRACKS, ntracks, 10, + "Number of tracks"), }, + { DRDATAD (NHEADS, nheads, 8, + "Number of heads"), }, + { DRDATAD (NSECTORS, nsectors, 8, + "Number of sectors per track"), }, + { DRDATAD (SECTSIZE, sectsize, 11, + "Sector size not including pre/postamble"), }, + { HRDATAD (SEL_DRIVE, djhdc_info_data.sel_drive, 3, + "Currently selected drive"), }, + { HRDATAD (MODE, djhdc_info_data.mode, 8, + "Mode (0xFF=absolute, 0x00=logical)"), }, + { HRDATAD (NDRIVES, djhdc_info_data.ndrives, 8, + "Number of drives attached to the controller"), }, + { HRDATAD (LINK_ADDR, djhdc_info_data.link_addr, 32, + "Link address for next IOPB"), }, + { HRDATAD (DMA_ADDR, djhdc_info_data.dma_addr, 32, + "DMA address for the current IOPB"), }, + { BRDATAD (IOPB, djhdc_info_data.iopb, 16, 8, 16, + "IOPB command register"), }, + { NULL } +}; + +#define DJHDC_NAME "Morrow HDC/DMA Hard Disk Controller" + +static const char* djhdc_description(DEVICE *dptr) { + if (dptr == NULL) { + return NULL; + } + return DJHDC_NAME; +} + +static MTAB djhdc_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", + &set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" }, + { MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "GEOMETRY", "GEOMETRY", + &djhdc_unit_set_geometry, &djhdc_unit_show_geometry, NULL, + "Set disk geometry C:nnnn/H:n/S:nnn/N:nnnn" }, + { 0 } +}; + +/* Debug Flags */ +static DEBTAB djhdc_dt[] = { + { "ERROR", ERROR_MSG, "Error messages" }, + { "SEEK", SEEK_MSG, "Seek messages" }, + { "OPCODE", OPCODE_MSG, "Opcode messages" }, + { "READ", RD_DATA_MSG, "Read messages" }, + { "WRITE", WR_DATA_MSG, "Write messages" }, + { "IRQ", IRQ_MSG, "IRQ messages" }, + { "VERBOSE", VERBOSE_MSG, "Verbose messages" }, + { "FORMAT", FORMAT_MSG, "Format messages" }, + { NULL, 0 } +}; + +DEVICE djhdc_dev = { + DEV_NAME, djhdc_unit, djhdc_reg, djhdc_mod, + DJHDC_MAX_DRIVES, 10, 31, 1, DJHDC_MAX_DRIVES, DJHDC_MAX_DRIVES, + NULL, NULL, &djhdc_reset, + NULL, &djhdc_attach, &djhdc_detach, + &djhdc_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), ERROR_MSG, + djhdc_dt, NULL, NULL, NULL, NULL, NULL, &djhdc_description +}; + +/* Reset routine */ +static t_stat djhdc_reset(DEVICE *dptr) +{ + PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; + + if(dptr->flags & DEV_DIS) { /* Disconnect I/O Ports */ + sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &djhdcdev, "djhdcdev", TRUE); + } else { + /* Connect DJHDC at base address */ + if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &djhdcdev, "djhdcdev", FALSE) != 0) { + sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base); + return SCPE_ARG; + } + } + + djhdc_info->link_addr = DJHDC_LINK_ADDR; /* After RESET, the link pointer is at 0x000050. */ + + return SCPE_OK; +} + + +/* Attach routine */ +static t_stat djhdc_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat r = SCPE_OK; + DJHDC_DRIVE_INFO *pDrive; + int i = 0; + + i = find_unit_index(uptr); + if (i == -1) { + return (SCPE_IERR); + } + pDrive = &djhdc_info->drive[i]; + + pDrive->ready = 1; + pDrive->track = 5; + + if (pDrive->ntracks == 0) { + /* If geometry was not specified, default to Miniscribe 15MB */ + pDrive->ntracks = SCRIBE_NTRACKS; + pDrive->nheads = SCRIBE_NHEADS; + pDrive->nsectors = SCRIBE_NSECTORS; + pDrive->sectsize = SCRIBE_SECTSIZE; + } + + r = attach_unit(uptr, cptr); /* attach unit */ + if ( r != SCPE_OK) /* error? */ + return r; + + /* Determine length of this disk */ + if(sim_fsize(uptr->fileref) != 0) { + uptr->capac = sim_fsize(uptr->fileref); + } else { + uptr->capac = (pDrive->ntracks * pDrive->nsectors * pDrive->nheads * pDrive->sectsize); + } + + pDrive->uptr = uptr; + + /* Default for new file is DSK */ + uptr->u3 = IMAGE_TYPE_DSK; + + if(uptr->capac > 0) { + r = assignDiskType(uptr); + if (r != SCPE_OK) { + djhdc_detach(uptr); + return r; + } + } + + if (uptr->flags & UNIT_DJHDC_VERBOSE) + sim_printf("DJHDC%d, attached to '%s', type=%s, len=%d\n", i, cptr, + uptr->u3 == IMAGE_TYPE_IMD ? "IMD" : uptr->u3 == IMAGE_TYPE_CPT ? "CPT" : "DSK", + uptr->capac); + + if(uptr->u3 == IMAGE_TYPE_IMD) { + if(uptr->capac < 318000) { + sim_printf("Cannot create IMD files with SIMH.\nCopy an existing file and format it with CP/M.\n"); + djhdc_detach(uptr); + return SCPE_OPENERR; + } + + if (uptr->flags & UNIT_DJHDC_VERBOSE) + sim_printf("--------------------------------------------------------\n"); + djhdc_info->drive[i].imd = diskOpenEx((uptr->fileref), (uptr->flags & UNIT_DJHDC_VERBOSE), + &djhdc_dev, VERBOSE_MSG, VERBOSE_MSG); + if (uptr->flags & UNIT_DJHDC_VERBOSE) + sim_printf("\n"); + } else { + djhdc_info->drive[i].imd = NULL; + } + + return SCPE_OK; +} + + +/* Detach routine */ +static t_stat djhdc_detach(UNIT *uptr) +{ + DJHDC_DRIVE_INFO *pDrive; + t_stat r; + int32 i; + + i = find_unit_index(uptr); + + if (i == -1) { + return (SCPE_IERR); + } + + pDrive = &djhdc_info->drive[i]; + + pDrive->ready = 0; + + if (uptr->flags & UNIT_DJHDC_VERBOSE) + sim_printf("Detach DJHDC%d\n", i); + + r = detach_unit(uptr); /* detach unit */ + if ( r != SCPE_OK) + return r; + + return SCPE_OK; +} + +/* Set geometry of the disk drive */ +static t_stat djhdc_unit_set_geometry(UNIT* uptr, int32 value, CONST char* cptr, void* desc) +{ + DJHDC_DRIVE_INFO* pDrive; + int32 i; + int32 result; + uint16 newCyls, newHeads, newSPT, newSecLen; + + i = find_unit_index(uptr); + + if (i == -1) { + return (SCPE_IERR); + } + + pDrive = &djhdc_info->drive[i]; + + if (cptr == NULL) + return SCPE_ARG; + + result = sscanf(cptr, "C:%hd/H:%hd/S:%hd/N:%hd", &newCyls, &newHeads, &newSPT, &newSecLen); + if (result != 4) + return SCPE_ARG; + + /* Validate Cyl, Heads, Sector, Length are valid for the HDC-1001 */ + if (newCyls < 1 || newCyls > DJHDC_MAX_CYLS) { + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of cylinders must be 1-%d.\n", + djhdc_info->sel_drive, DJHDC_MAX_CYLS); + return SCPE_ARG; + } + if (newHeads < 1 || newHeads > DJHDC_MAX_HEADS) { + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of heads must be 1-%d.\n", + djhdc_info->sel_drive, DJHDC_MAX_HEADS); + return SCPE_ARG; + } + if (newSPT < 1 || newSPT > DJHDC_MAX_SPT) { + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Number of sectors per track must be 1-%d.\n", + djhdc_info->sel_drive, DJHDC_MAX_SPT); + return SCPE_ARG; + } + if (newSecLen != 2048 && newSecLen != 1024 && newSecLen != 512 && newSecLen != 256 && newSecLen != 128) { + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: Sector length must be 128, 256, 512, 1024, or 2048.\n", + djhdc_info->sel_drive); + return SCPE_ARG; + } + + pDrive->ntracks = newCyls; + pDrive->nheads = newHeads; + pDrive->nsectors = newSPT; + pDrive->sectsize = newSecLen; + + return SCPE_OK; +} + +/* Show geometry of the disk drive */ +static t_stat djhdc_unit_show_geometry(FILE* st, UNIT* uptr, int32 value, CONST void* desc) +{ + DJHDC_DRIVE_INFO* pDrive; + int32 i; + + i = find_unit_index(uptr); + + if (i == -1) { + return (SCPE_IERR); + } + + pDrive = &djhdc_info->drive[i]; + + fprintf(st, "C:%d/H:%d/S:%d/N:%d", + pDrive->ntracks, pDrive->nheads, pDrive->nsectors, pDrive->sectsize); + + return SCPE_OK; +} + +static int32 djhdcdev(const int32 port, const int32 io, const int32 data) +{ + sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME ": " ADDRESS_FORMAT + " IO %s, Port %02x\n", PCX, io ? "WR" : "RD", port); + if(io) { + DJHDC_Write(port, (uint8)data); + return 0; + } else { + return(0xFF); + } +} + +static uint8 DJHDC_Write(const uint32 Addr, uint8 cData) +{ + uint32 next_link; + uint8 result = DJHDC_STATUS_COMPLETE; + uint8 i; + uint8 opcode; + + DJHDC_DRIVE_INFO *pDrive; + + /* RESET */ + if ((Addr & 1) == DJHDC_RESET) { + djhdc_info->link_addr = DJHDC_LINK_ADDR - DJHDC_IOPB_LINK; + + sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: RESET\n", + djhdc_info->sel_drive); + + return 0; + } + + /* START */ + + /* Read first three bytes of IOPB (link address) */ + for (i = DJHDC_IOPB_LINK; i < DJHDC_IOPB_LEN; i++) { + djhdc_info->iopb[i] = GetByteDMA((djhdc_info->link_addr) + i); + } + + next_link = djhdc_info->iopb[DJHDC_IOPB_LINK + 0]; + next_link |= djhdc_info->iopb[DJHDC_IOPB_LINK+1] << 8; + next_link |= djhdc_info->iopb[DJHDC_IOPB_LINK+2] << 16; + + /* Point IOPB to new link */ + djhdc_info->link_addr = next_link; + + /* Read remaineder of IOPB */ + for(i = 0; i < DJHDC_IOPB_LEN-3; i++) { + djhdc_info->iopb[i] = GetByteDMA((djhdc_info->link_addr) + i); + } + + /* Process the IOPB */ + djhdc_info->iopb[DJHDC_IOPB_OPCODE] = djhdc_info->iopb[DJHDC_IOPB_OPCODE] & DJHDC_OPCODE_MASK; + + opcode = djhdc_info->iopb[DJHDC_IOPB_OPCODE]; + djhdc_info->sel_drive = djhdc_info->iopb[DJHDC_IOPB_SELDRV] & 0x03; + djhdc_info->step_dir = (djhdc_info->iopb[DJHDC_IOPB_SELDRV] & DJHDC_STEP_DIR) ? 1 : 0; + + djhdc_info->steps = djhdc_info->iopb[DJHDC_IOPB_STEP_L]; + djhdc_info->steps |= djhdc_info->iopb[DJHDC_IOPB_STEP_H] << 8; + + djhdc_info->dma_addr = djhdc_info->iopb[DJHDC_IOPB_DMA_L]; + djhdc_info->dma_addr |= djhdc_info->iopb[DJHDC_IOPB_DMA_H] << 8; + djhdc_info->dma_addr |= djhdc_info->iopb[DJHDC_IOPB_DMA_E] << 16; + + sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: SEEK=%d %s, LINK=0x%05x, OPCODE=%x, %s DMA@0x%05x\n", + djhdc_info->sel_drive, + djhdc_info->steps, + djhdc_info->step_dir ? "OUT" : "IN", + djhdc_info->link_addr, + djhdc_info->iopb[DJHDC_IOPB_OPCODE], + djhdc_opcode_str[djhdc_info->iopb[DJHDC_IOPB_OPCODE]], + djhdc_info->dma_addr); + + pDrive = &djhdc_info->drive[djhdc_info->sel_drive]; + + if(pDrive->ready) { + /* Seek phase */ + if (djhdc_info->step_dir) { + /* Step Out */ + if (djhdc_info->steps >= pDrive->cur_cyl) { + pDrive->cur_cyl = 0; + sim_debug(SEEK_MSG, &djhdc_dev, DEV_NAME "[%d]: HOME\n", + djhdc_info->sel_drive); + } + else { + pDrive->cur_cyl -= djhdc_info->steps; + } + } + else { + /* Step In */ + pDrive->cur_cyl += djhdc_info->steps; + } + + sim_debug(SEEK_MSG, &djhdc_dev, DEV_NAME "[%d]: Current track: %d\n", + djhdc_info->sel_drive, + pDrive->cur_cyl); + + + /* Perform command */ + switch(opcode) { + case DJHDC_OPCODE_READ_DATA: + case DJHDC_OPCODE_WRITE_DATA: + { + uint32 track_len; + uint32 xfr_len; + uint32 file_offset; + uint32 xfr_count = 0; + uint8* dataBuffer; + size_t rtn; + + pDrive->cur_cyl = djhdc_info->iopb[DJHDC_IOPB_ARG0] | (djhdc_info->iopb[DJHDC_IOPB_ARG1] << 8); + pDrive->cur_head = djhdc_info->iopb[DJHDC_IOPB_ARG2]; + pDrive->cur_sect = djhdc_info->iopb[DJHDC_IOPB_ARG3] - 1; + + if (DJHDC_Validate_CHSN(pDrive) != SCPE_OK) { + result = DJHDC_STATUS_HEADER_NOT_FOUND; + break; + } + + track_len = pDrive->nsectors * pDrive->nheads * pDrive->sectsize; + + file_offset = (pDrive->cur_cyl * track_len); /* Calculate offset based on current track */ + file_offset += pDrive->nsectors * pDrive->cur_head * pDrive->sectsize; + file_offset += pDrive->cur_sect * pDrive->sectsize; + + xfr_len = pDrive->sectsize; + + dataBuffer = (uint8*)malloc(xfr_len); + if (dataBuffer == NULL) { + sim_printf("%s: error allocating memory\n", __FUNCTION__); + return (0); + } + + if (sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET) == 0) { + + if (opcode == DJHDC_OPCODE_READ_DATA) { /* Read */ + rtn = sim_fread(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref); + + sim_debug(RD_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " READ @0x%05x C:%04d/H:%d/S:%04d len=%d, file_offset=%d, %s\n", + djhdc_info->sel_drive, + PCX, + djhdc_info->dma_addr, + pDrive->cur_cyl, + pDrive->cur_head, + pDrive->cur_sect, + xfr_len, + file_offset, + rtn == (size_t)xfr_len ? "OK" : "NOK"); + + + /* Perform DMA Transfer */ + for (xfr_count = 0; xfr_count < xfr_len; xfr_count++) { + PutByteDMA(djhdc_info->dma_addr + xfr_count, dataBuffer[xfr_count]); + } + } + else { /* Write */ + sim_debug(WR_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " WRITE @0x%05x C:%04d/H:%d/S:%04d file_offset=%d, len=%d\n", + djhdc_info->sel_drive, + PCX, djhdc_info->dma_addr, + pDrive->cur_cyl, + pDrive->cur_head, + pDrive->cur_sect, + file_offset, + xfr_len); + + /* Perform DMA Transfer */ + for (xfr_count = 0; xfr_count < xfr_len; xfr_count++) { + dataBuffer[xfr_count] = GetByteDMA(djhdc_info->dma_addr + xfr_count); + } + + sim_fwrite(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref); + } + } + else { + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " READWRITE: sim_fseek error.\n", djhdc_info->sel_drive, PCX); + } + + free(dataBuffer); + + break; + } + case DJHDC_OPCODE_READ_HEADER: + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " READ_HEADER: not implemented.\n", djhdc_info->sel_drive, PCX); + result = DJHDC_STATUS_HEADER_NOT_FOUND; + break; + case DJHDC_OPCODE_FORMAT_TRACK: + { + uint32 track_len; + uint32 file_offset; + uint8* fmtBuffer; + uint8 head; + uint8 gap; + uint8 sector_count; + uint8 sector_size_code; + uint8 fill_byte; + + head = ~(djhdc_info->iopb[DJHDC_IOPB_SEL_HD] >> 2) & 7; + gap = djhdc_info->iopb[DJHDC_IOPB_ARG0]; + sector_count = 255 - djhdc_info->iopb[DJHDC_IOPB_ARG1]; + sector_size_code = djhdc_info->iopb[DJHDC_IOPB_ARG2]; + fill_byte = djhdc_info->iopb[DJHDC_IOPB_ARG3]; + + switch (sector_size_code) { + case 0xFF: + pDrive->cur_sectsize = 128; + break; + case 0xFE: + pDrive->cur_sectsize = 256; + break; + case 0xFC: + pDrive->cur_sectsize = 512; + break; + case 0xF8: + pDrive->cur_sectsize = 1024; + break; + case 0xF0: + pDrive->cur_sectsize = 2048; + break; + default: + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME ": Invalid sector size code: 0x%02x.\n", + djhdc_info->sector_size_code); + pDrive->cur_sectsize = 0; + result = DJHDC_STATUS_ILLEGAL_COMMAND; + break; + } + + if (DJHDC_Validate_CHSN(pDrive) != SCPE_OK) { + result = DJHDC_STATUS_HEADER_NOT_FOUND; + break; + } + + track_len = pDrive->nheads * sector_count * pDrive->sectsize; + + file_offset = pDrive->cur_cyl * track_len; /* Calculate offset based on current track */ + file_offset += head * sector_count * pDrive->sectsize; + + sim_debug(FORMAT_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " FORMAT C:%d/H:%d, Gap=%d, Fill=0x%02x, Count=%d, Sector Size:=%d, file offset: 0x%08x\n", + djhdc_info->sel_drive, + PCX, + pDrive->cur_cyl, + head, + gap, + fill_byte, + sector_count, + pDrive->sectsize, + file_offset); + + fmtBuffer = (uint8*)malloc(track_len); + + if (fmtBuffer == NULL) { + sim_printf("%s: error allocating memory\n", __FUNCTION__); + return (0); + } + + memset(fmtBuffer, fill_byte, track_len); + + if (sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET) == 0) { + sim_fwrite(fmtBuffer, 1, track_len, (pDrive->uptr)->fileref); + } + else { + sim_debug(WR_DATA_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " FORMAT: sim_fseek error.\n", djhdc_info->sel_drive, PCX); + result = DJHDC_STATUS_WRITE_FAULT; + } + + free(fmtBuffer); + + break; + } + case DJHDC_OPCODE_LOAD_CONSTANTS: + djhdc_info->irq_enable = (djhdc_info->iopb[DJHDC_IOPB_ARG1] & DJHDC_IRQ_EN_MASK) ? 1 : 0; + djhdc_info->step_delay = djhdc_info->iopb[DJHDC_IOPB_ARG1] & ~DJHDC_IRQ_EN_MASK; + djhdc_info->head_settle_time = djhdc_info->iopb[DJHDC_IOPB_ARG2]; + djhdc_info->sector_size_code = djhdc_info->iopb[DJHDC_IOPB_ARG3]; + + switch (djhdc_info->sector_size_code) { + case 0x00: + pDrive->cur_sectsize = 128; + break; + case 0x01: + pDrive->cur_sectsize = 256; + break; + case 0x03: + pDrive->cur_sectsize = 512; + break; + case 0x07: + pDrive->cur_sectsize = 1024; + break; + case 0x0F: + pDrive->cur_sectsize = 2048; + break; + default: + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME ": Invalid sector size code: 0x%02x.\n", + djhdc_info->sector_size_code); + pDrive->cur_sectsize = 0; + result = DJHDC_STATUS_ILLEGAL_COMMAND; + break; + } + + sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " Load Constants: Interrupt Enable: %d, step delay: %d, head settle time: %d, sector size %d (code: 0x%02x)\n", + djhdc_info->sel_drive, PCX, + djhdc_info->irq_enable, + djhdc_info->step_delay, + djhdc_info->head_settle_time, + pDrive->sectsize, + djhdc_info->sector_size_code); + break; + case DJHDC_OPCODE_SENSE_STATUS: + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT " SENSE_STATUS: not implemented.\n", djhdc_info->sel_drive, PCX); + result = DJHDC_DRIVE_READY_SIGNAL; + if (pDrive->cur_cyl != 0) result = DJHDC_TRACK_0_DETECT; + break; + case DJHDC_OPCODE_NOOP: + sim_debug(VERBOSE_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " NOOP\n", djhdc_info->sel_drive, PCX); + break; + + default: + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "[%d]: " ADDRESS_FORMAT + " OPCODE=%x Unsupported\n", + djhdc_info->sel_drive, + PCX, + opcode & DJHDC_OPCODE_MASK); + result = DJHDC_STATUS_ILLEGAL_COMMAND; + break; + } + } else { /* Drive not ready */ + result = DJHDC_STATUS_NOT_READY; + } + /* Return status */ + djhdc_info->iopb[DJHDC_IOPB_STATUS] = result; + + /* Update IOPB in host memory */ + PutByteDMA(djhdc_info->link_addr + DJHDC_IOPB_STATUS, djhdc_info->iopb[DJHDC_IOPB_STATUS]); + +#ifdef DJHDC_INTERRUPTS + if(djhdc_info->irq_enable) { + raise_djhdc_interrupt(); + } +#endif /* DJHDC_INTERRUPTS */ + + return 0; +} + +/* Validate that Cyl, Head, Sector, Sector Length are valid for the current + * disk drive geometry. + */ +static int DJHDC_Validate_CHSN(DJHDC_DRIVE_INFO* pDrive) +{ + int status = SCPE_OK; + + /* Check to make sure we're operating on a valid C/H/S/N. */ + if ((pDrive->cur_cyl >= pDrive->ntracks) || + (pDrive->cur_head >= pDrive->nheads) || + (pDrive->cur_sect >= pDrive->nsectors) || + (pDrive->cur_sectsize != pDrive->sectsize)) + { + + sim_debug(ERROR_MSG, &djhdc_dev, DEV_NAME "%d: " ADDRESS_FORMAT + " ID Not Found (check disk geometry.)\n", djhdc_info->sel_drive, PCX); + + status = SCPE_IOERR; + } + + return (status); +} + +#ifdef DJHDC_INTERRUPTS +static void raise_djhdc_interrupt(void) +{ + sim_debug(IRQ_MSG, &djhdc_dev, DEV_NAME ": " ADDRESS_FORMAT " Interrupt\n", PCX); + + raise_scp300f_interrupt(DJHDC_INT); +} +#endif /* DJHDC_INTERRUPTS */ diff --git a/AltairZ80/s100_tdd.c b/AltairZ80/s100_tdd.c index df1e5b26..33f230f0 100644 --- a/AltairZ80/s100_tdd.c +++ b/AltairZ80/s100_tdd.c @@ -1,180 +1,180 @@ -/************************************************************************* - * * - * Copyright (c) 2022 Howard M. Harte. * - * https://github.com/hharte * - * * - * Permission is hereby granted, free of charge, to any person obtaining * - * a copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to * - * the following conditions: * - * * - * The above copyright notice and this permission notice shall be * - * included in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- * - * INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * - * SOFTWARE. * - * * - * Except as contained in this notice, the names of The Authors shall * - * not be used in advertising or otherwise to promote the sale, use or * - * other dealings in this Software without prior written authorization * - * from the Authors. * - * * - * Based on s100_64fdc.c * - * * - * Module Description: * - * Tarbell Double-Density Floppy Controller module for SIMH. * - * This module is a wrapper around the wd179x FDC module. * - * * - * Reference: * - * http://www.bitsavers.org/pdf/tarbell/Tarbell_Double_Density_Floppy_Disk_Interface_Jul81.pdf - * * - *************************************************************************/ - -#include "altairz80_defs.h" -#include "sim_defs.h" -#include "wd179x.h" - -#define DEV_NAME "TDD" - -/* Debug flags */ -#define STATUS_MSG (1 << 0) -#define DRIVE_MSG (1 << 1) -#define VERBOSE_MSG (1 << 2) -#define IRQ_MSG (1 << 3) - -#define TDD_MAX_DRIVES 4 - -#define TDD_IO_BASE 0x7C -#define TDD_IO_SIZE 0x2 -#define TDD_IO_MASK (TDD_IO_SIZE - 1) - -typedef struct { - PNP_INFO pnp; /* Plug and Play */ -} TDD_INFO; - -extern WD179X_INFO_PUB *wd179x_infop; - -static TDD_INFO tdd_info_data = { { 0x0000, 0, TDD_IO_BASE, TDD_IO_SIZE } }; - -extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type, - int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap); - -extern uint32 PCX; /* external view of PC */ - -#define TDD_CAPACITY (77*1*26*128) /* Default SSSD 8" (IBM 3740) Disk Capacity */ - -static t_stat tdd_reset(DEVICE *tdd_dev); - -static int32 tdd_control(const int32 port, const int32 io, const int32 data); -static const char* tdd_description(DEVICE *dptr); - -#define TDD_FLAG_EOJ (1 << 7) /* End of Job (INTRQ) */ - -static UNIT tdd_unit[] = { - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, - { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) } -}; - -static REG tdd_reg[] = { - { NULL } -}; - -#define TDD_NAME "Tarbell Double-Density FDC" - -static const char* tdd_description(DEVICE *dptr) { - if (dptr == NULL) { - return NULL; - } - return TDD_NAME; -} - -static MTAB tdd_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", - &set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" }, - { 0 } -}; - -/* Debug Flags */ -static DEBTAB tdd_dt[] = { - { "STATUS", STATUS_MSG, "Status messages" }, - { "DRIVE", DRIVE_MSG, "Drive messages" }, - { "VERBOSE", VERBOSE_MSG, "Verbose messages" }, - { "IRQ", IRQ_MSG, "IRQ messages" }, - { NULL, 0 } -}; - -DEVICE tdd_dev = { - DEV_NAME, tdd_unit, tdd_reg, tdd_mod, - TDD_MAX_DRIVES, 10, 31, 1, TDD_MAX_DRIVES, TDD_MAX_DRIVES, - NULL, NULL, &tdd_reset, - NULL, &wd179x_attach, &wd179x_detach, - &tdd_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), 0, - tdd_dt, NULL, NULL, NULL, NULL, NULL, &tdd_description -}; - -/* Reset routine */ -static t_stat tdd_reset(DEVICE *dptr) -{ - PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; - - if(dptr->flags & DEV_DIS) { /* Disconnect ROM and I/O Ports */ - /* Unmap I/O Ports */ - sim_map_resource(pnp->io_base, 1, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", TRUE); - } else { - /* Connect TDD Disk Flags and Control Register */ - if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", FALSE) != 0) { - sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base); - return SCPE_ARG; - } - } - - return SCPE_OK; -} - -/* Tarbell pp. 12-5 Disk Control/Status */ -static int32 tdd_control(const int32 port, const int32 io, const int32 data) -{ - int32 result = 0; - if(io) { /* I/O Write */ - if ((port & TDD_IO_MASK) == 0) { - wd179x_infop->fdc_head = (data & 0x40) >> 6; - wd179x_infop->sel_drive = (data & 0x30) >> 4; - wd179x_infop->ddens = (data & 0x08) >> 3; - - sim_debug(DRIVE_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT " WR CTRL(0x%02x) = 0x%02x: Drive: %d, Head: %d, %s-Density.\n", - PCX, port, - data & 0xFF, - wd179x_infop->sel_drive, - wd179x_infop->fdc_head, - wd179x_infop->ddens == 1 ? "Double" : "Single"); - } else { - sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT - " Write Extended Address, Port 0x%02x=0x%02x\n", PCX, port, data); - } - } else { /* I/O Read */ - if ((port & TDD_IO_MASK) == 0) { - result = (wd179x_infop->intrq) ? 0 : TDD_FLAG_EOJ; - sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT - " Read EOJ, Port 0x%02x Result 0x%02x\n", PCX, port, result); - } else { - result = (wd179x_infop->drq) ? TDD_FLAG_EOJ : 0; - sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT - " Read DRQ, Port 0x%02x Result 0x%02x\n", PCX, port, result); - } - } - - return result; -} +/************************************************************************* + * * + * Copyright (c) 2022 Howard M. Harte. * + * https://github.com/hharte * + * * + * Permission is hereby granted, free of charge, to any person obtaining * + * a copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to * + * the following conditions: * + * * + * The above copyright notice and this permission notice shall be * + * included in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- * + * INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + * * + * Except as contained in this notice, the names of The Authors shall * + * not be used in advertising or otherwise to promote the sale, use or * + * other dealings in this Software without prior written authorization * + * from the Authors. * + * * + * Based on s100_64fdc.c * + * * + * Module Description: * + * Tarbell Double-Density Floppy Controller module for SIMH. * + * This module is a wrapper around the wd179x FDC module. * + * * + * Reference: * + * http://www.bitsavers.org/pdf/tarbell/Tarbell_Double_Density_Floppy_Disk_Interface_Jul81.pdf + * * + *************************************************************************/ + +#include "altairz80_defs.h" +#include "sim_defs.h" +#include "wd179x.h" + +#define DEV_NAME "TDD" + +/* Debug flags */ +#define STATUS_MSG (1 << 0) +#define DRIVE_MSG (1 << 1) +#define VERBOSE_MSG (1 << 2) +#define IRQ_MSG (1 << 3) + +#define TDD_MAX_DRIVES 4 + +#define TDD_IO_BASE 0x7C +#define TDD_IO_SIZE 0x2 +#define TDD_IO_MASK (TDD_IO_SIZE - 1) + +typedef struct { + PNP_INFO pnp; /* Plug and Play */ +} TDD_INFO; + +extern WD179X_INFO_PUB *wd179x_infop; + +static TDD_INFO tdd_info_data = { { 0x0000, 0, TDD_IO_BASE, TDD_IO_SIZE } }; + +extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type, + int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap); + +extern uint32 PCX; /* external view of PC */ + +#define TDD_CAPACITY (77*1*26*128) /* Default SSSD 8" (IBM 3740) Disk Capacity */ + +static t_stat tdd_reset(DEVICE *tdd_dev); + +static int32 tdd_control(const int32 port, const int32 io, const int32 data); +static const char* tdd_description(DEVICE *dptr); + +#define TDD_FLAG_EOJ (1 << 7) /* End of Job (INTRQ) */ + +static UNIT tdd_unit[] = { + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, + { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) } +}; + +static REG tdd_reg[] = { + { NULL } +}; + +#define TDD_NAME "Tarbell Double-Density FDC" + +static const char* tdd_description(DEVICE *dptr) { + if (dptr == NULL) { + return NULL; + } + return TDD_NAME; +} + +static MTAB tdd_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", + &set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" }, + { 0 } +}; + +/* Debug Flags */ +static DEBTAB tdd_dt[] = { + { "STATUS", STATUS_MSG, "Status messages" }, + { "DRIVE", DRIVE_MSG, "Drive messages" }, + { "VERBOSE", VERBOSE_MSG, "Verbose messages" }, + { "IRQ", IRQ_MSG, "IRQ messages" }, + { NULL, 0 } +}; + +DEVICE tdd_dev = { + DEV_NAME, tdd_unit, tdd_reg, tdd_mod, + TDD_MAX_DRIVES, 10, 31, 1, TDD_MAX_DRIVES, TDD_MAX_DRIVES, + NULL, NULL, &tdd_reset, + NULL, &wd179x_attach, &wd179x_detach, + &tdd_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), 0, + tdd_dt, NULL, NULL, NULL, NULL, NULL, &tdd_description +}; + +/* Reset routine */ +static t_stat tdd_reset(DEVICE *dptr) +{ + PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; + + if(dptr->flags & DEV_DIS) { /* Disconnect ROM and I/O Ports */ + /* Unmap I/O Ports */ + sim_map_resource(pnp->io_base, 1, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", TRUE); + } else { + /* Connect TDD Disk Flags and Control Register */ + if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", FALSE) != 0) { + sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base); + return SCPE_ARG; + } + } + + return SCPE_OK; +} + +/* Tarbell pp. 12-5 Disk Control/Status */ +static int32 tdd_control(const int32 port, const int32 io, const int32 data) +{ + int32 result = 0; + if(io) { /* I/O Write */ + if ((port & TDD_IO_MASK) == 0) { + wd179x_infop->fdc_head = (data & 0x40) >> 6; + wd179x_infop->sel_drive = (data & 0x30) >> 4; + wd179x_infop->ddens = (data & 0x08) >> 3; + + sim_debug(DRIVE_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT " WR CTRL(0x%02x) = 0x%02x: Drive: %d, Head: %d, %s-Density.\n", + PCX, port, + data & 0xFF, + wd179x_infop->sel_drive, + wd179x_infop->fdc_head, + wd179x_infop->ddens == 1 ? "Double" : "Single"); + } else { + sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT + " Write Extended Address, Port 0x%02x=0x%02x\n", PCX, port, data); + } + } else { /* I/O Read */ + if ((port & TDD_IO_MASK) == 0) { + result = (wd179x_infop->intrq) ? 0 : TDD_FLAG_EOJ; + sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT + " Read EOJ, Port 0x%02x Result 0x%02x\n", PCX, port, result); + } else { + result = (wd179x_infop->drq) ? TDD_FLAG_EOJ : 0; + sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT + " Read DRQ, Port 0x%02x Result 0x%02x\n", PCX, port, result); + } + } + + return result; +} diff --git a/AltairZ80/wd179x.c b/AltairZ80/wd179x.c index 0a0b8e6c..804ea35d 100644 --- a/AltairZ80/wd179x.c +++ b/AltairZ80/wd179x.c @@ -1203,15 +1203,15 @@ static uint8 Do1793Command(uint8 cCommand) " Verify ", wd179x_info->sel_drive, PCX); if (pDrive->uptr->u3 == IMAGE_TYPE_IMD) { if (sectSeek(pDrive->imd, pDrive->track, wd179x_info->fdc_head) != SCPE_OK) { - sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n"); - wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ + sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n"); + wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ } else if (testMode(pDrive)) { - wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ - sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n"); + wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ + sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n"); } else { - sim_debug(SEEK_MSG, &wd179x_dev, "Ok\n"); + sim_debug(SEEK_MSG, &wd179x_dev, "Ok\n"); } - } + } } if (pDrive->track == 0) { diff --git a/BESM6/besm6_tty.c b/BESM6/besm6_tty.c index c1fb758b..5d17f018 100644 --- a/BESM6/besm6_tty.c +++ b/BESM6/besm6_tty.c @@ -1252,7 +1252,7 @@ void vt_receive() * HYC needs to be typed * to re-initialize the line */ - TTY_IN |= mask; /* "long start" */ + TTY_IN |= mask; /* "long start" */ break; } switch (tty_unit[num].flags & TTY_CHARSET_MASK) { diff --git a/BESM6/expect.ini b/BESM6/expect.ini index cad2d9b0..a424ea20 100755 --- a/BESM6/expect.ini +++ b/BESM6/expect.ini @@ -1,31 +1,31 @@ -# Attaching the input device -at -t fs0 input.txt -# Waiting for the end of initial setup -expect -r "ДATA.*\n" -do dispak.ini -# Now we're ready to send commands from the front panel -echo Requesting input from the punch tape reader (FS8), it takes a few seconds -d 6 1 -d 5 10 -set cpu req -expect -r "Л0.*\n" -go - -# The process had been started, check state every 10 model seconds -send after=1000000 "WCPP\r" -expect -p -r "4199.*\n" send after=10000000 "WCPP\r"; go -expect -c "KЗ" step 10000000 -expect -c "HET\r\n" step 10000 -go -echo Enabling the printer (ONL A0) -d 6 10 -d 5 1 -set cpu req -expect -r "ECT.*\n" -go -echo Checking for the printing to finish -send "HOMB\r" -expect -p -r "A0.*\n" send "HOMB\r"; go -expect -c "HET\r\n" -go -echo Done +# Attaching the input device +at -t fs0 input.txt +# Waiting for the end of initial setup +expect -r "ДATA.*\n" +do dispak.ini +# Now we're ready to send commands from the front panel +echo Requesting input from the punch tape reader (FS8), it takes a few seconds +d 6 1 +d 5 10 +set cpu req +expect -r "Л0.*\n" +go + +# The process had been started, check state every 10 model seconds +send after=1000000 "WCPP\r" +expect -p -r "4199.*\n" send after=10000000 "WCPP\r"; go +expect -c "KЗ" step 10000000 +expect -c "HET\r\n" step 10000 +go +echo Enabling the printer (ONL A0) +d 6 10 +d 5 1 +set cpu req +expect -r "ECT.*\n" +go +echo Checking for the printing to finish +send "HOMB\r" +expect -p -r "A0.*\n" send "HOMB\r"; go +expect -c "HET\r\n" +go +echo Done diff --git a/Intel-Systems/common/i8080.c b/Intel-Systems/common/i8080.c index d7500489..ca5f02f5 100644 --- a/Intel-Systems/common/i8080.c +++ b/Intel-Systems/common/i8080.c @@ -1363,12 +1363,12 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) chk -= addr >> 8; for (i=0; i> 8; for (i=0; i<=(end - addr); i++) { byte = get_mbyte(addr + i); - fprintf(fileref, "%02X", byte & BYTEMASK); + fprintf(fileref, "%02X", byte & BYTEMASK); chk -= byte; chk &= BYTEMASK; cnt++; } fprintf(fileref, "%02X\n", chk); - addr = end; + addr = end; } fprintf(fileref,":00000001FF\n"); //EOF record } else { //binary diff --git a/NOVA/nova_pt.c b/NOVA/nova_pt.c index c58d1b8a..b66e5095 100644 --- a/NOVA/nova_pt.c +++ b/NOVA/nova_pt.c @@ -1,299 +1,299 @@ -/* nova_pt.c: NOVA paper tape read/punch simulator - - Copyright (c) 1993-2016, Robert M. Supnik - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - ptr paper tape reader - ptp paper tape punch - - 13-May-16 RMS Lengthened wait time for DCC BASIC timing error - 28-Mar-15 RMS Revised to use sim_printf - 04-Jul-07 BKR added PTR and PTP device DISABLE capability, - added 7B/8B support PTR and PTP (default is 8B), - DEV_SET/CLR macros now used, - PTR and PTP can now be DISABLED - 25-Apr-03 RMS Revised for extended file support - 03-Oct-02 RMS Added DIBs - 30-May-02 RMS Widened POS to 32b - 29-Nov-01 RMS Added read only unit support - - -Notes: - - data masked to 7- or 8- bits, based on 7B or 8B, default is 8-bits - - register TIME is the delay between character read or write operations - - register POS show the number of characters read from or sent to the PTR or PTP - - register STOP_IOE determines return value issued if output to unattached PTR or PTP is attempted -*/ - -#include "nova_defs.h" - -extern int32 int_req, dev_busy, dev_done, dev_disable ; -extern int32 SR ; - -extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ; - - -int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */ - -int32 ptr (int32 pulse, int32 code, int32 AC); -int32 ptp (int32 pulse, int32 code, int32 AC); -t_stat ptr_svc (UNIT *uptr); -t_stat ptp_svc (UNIT *uptr); -t_stat ptr_reset (DEVICE *dptr); -t_stat ptp_reset (DEVICE *dptr); -t_stat ptr_boot (int32 unitno, DEVICE *dptr); - - -/* 7 or 8 bit data mask support for either device */ - -#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */ -#define UNIT_8B (1 << UNIT_V_8B) - - -/* PTR data structures - - ptr_dev PTR device descriptor - ptr_unit PTR unit descriptor - ptr_reg PTR register list -*/ - -DIB ptr_dib = { DEV_PTR, INT_PTR, PI_PTR, &ptr }; - -UNIT ptr_unit = { /* 2007-May-30, bkr */ - UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_8B, 0), 300 - }; - -REG ptr_reg[] = { - { ORDATA (BUF, ptr_unit.buf, 8) }, - { FLDATA (BUSY, dev_busy, INT_V_PTR) }, - { FLDATA (DONE, dev_done, INT_V_PTR) }, - { FLDATA (DISABLE, dev_disable, INT_V_PTR) }, - { FLDATA (INT, int_req, INT_V_PTR) }, - { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, ptr_stopioe, 0) }, - { NULL } - }; - -MTAB ptr_mod[] = /* 2007-May-30, bkr */ - { - { UNIT_8B, 0, "7b", "7B", NULL }, - { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, - { 0, 0, NULL, NULL, NULL } - } ; - -DEVICE ptr_dev = { - "PTR", &ptr_unit, ptr_reg, ptr_mod /* 2007-May-30, bkr */, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &ptr_reset, - &ptr_boot, NULL, NULL, - &ptr_dib, DEV_DISABLE /* 2007-May-30, bkr */ - }; - -/* PTP data structures - - ptp_dev PTP device descriptor - ptp_unit PTP unit descriptor - ptp_reg PTP register list -*/ - -DIB ptp_dib = { DEV_PTP, INT_PTP, PI_PTP, &ptp }; - -UNIT ptp_unit = - { - UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_8B, 0), SERIAL_OUT_WAIT - }; - -REG ptp_reg[] = { - { ORDATA (BUF, ptp_unit.buf, 8) }, - { FLDATA (BUSY, dev_busy, INT_V_PTP) }, - { FLDATA (DONE, dev_done, INT_V_PTP) }, - { FLDATA (DISABLE, dev_disable, INT_V_PTP) }, - { FLDATA (INT, int_req, INT_V_PTP) }, - { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, ptp_stopioe, 0) }, - { NULL } - }; - -MTAB ptp_mod[] = - { - { UNIT_8B, 0, "7b", "7B", NULL }, - { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, - { 0, 0, NULL, NULL, NULL } - } ; - -DEVICE ptp_dev = - { - "PTP", &ptp_unit, ptp_reg, ptp_mod /* 2007-May-30, bkr */, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &ptp_reset, - NULL, NULL, NULL, - &ptp_dib, DEV_DISABLE /* 2007-May-30, bkr */ - }; - - -/* Paper tape reader: IOT routine */ - -int32 ptr (int32 pulse, int32 code, int32 AC) -{ -int32 iodata; - -iodata = (code == ioDIA)? - ptr_unit.buf & 0377 - : 0; -switch (pulse) - { /* decode IR<8:9> */ - case iopS: /* start */ - DEV_SET_BUSY( INT_PTR ) ; - DEV_CLR_DONE( INT_PTR ) ; - DEV_UPDATE_INTR ; - sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */ - break; - - case iopC: /* clear */ - DEV_CLR_BUSY( INT_PTR ) ; - DEV_CLR_DONE( INT_PTR ) ; - DEV_UPDATE_INTR ; - sim_cancel (&ptr_unit); /* deactivate unit */ - break; - } /* end switch */ - -return iodata; -} - - -/* Unit service */ - -t_stat ptr_svc (UNIT *uptr) -{ -int32 temp; - -if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */ - return IORETURN (ptr_stopioe, SCPE_UNATT); -if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ - if (feof (ptr_unit.fileref)) { - if (ptr_stopioe) - sim_printf ("PTR end of file\n"); - else return SCPE_OK; - } - else sim_perror ("PTR I/O error"); - clearerr (ptr_unit.fileref); - return SCPE_IOERR; - } - -DEV_CLR_BUSY( INT_PTR ) ; -DEV_SET_DONE( INT_PTR ) ; -DEV_UPDATE_INTR ; -ptr_unit.buf = temp & ((ptr_unit.flags & UNIT_8B)? 0377: 0177); -++(ptr_unit.pos); -return SCPE_OK; -} - - -/* Reset routine */ - -t_stat ptr_reset (DEVICE *dptr) -{ -ptr_unit.buf = 0; /* */ -DEV_CLR_BUSY( INT_PTR ) ; -DEV_CLR_DONE( INT_PTR ) ; -DEV_UPDATE_INTR ; -sim_cancel (&ptr_unit); /* deactivate unit */ -return SCPE_OK; -} - - -/* Boot routine */ - -t_stat ptr_boot (int32 unitno, DEVICE *dptr) -{ -ptr_reset( dptr ) ; -/* set position to 0? */ -cpu_boot( unitno, dptr ) ; -SR = /* low-speed: no high-order bit set */ DEV_PTR ; -return ( SCPE_OK ); -} /* end of 'ptr_boot' */ - - - - - -/* Paper tape punch: IOT routine */ - -int32 ptp (int32 pulse, int32 code, int32 AC) -{ -if (code == ioDOA) - ptp_unit.buf = AC & 0377; - -switch (pulse) - { /* decode IR<8:9> */ - case iopS: /* start */ - DEV_SET_BUSY( INT_PTP ) ; - DEV_CLR_DONE( INT_PTP ) ; - DEV_UPDATE_INTR ; - sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */ - break; - - case iopC: /* clear */ - DEV_CLR_BUSY( INT_PTP ) ; - DEV_CLR_DONE( INT_PTP ) ; - DEV_UPDATE_INTR ; - sim_cancel (&ptp_unit); /* deactivate unit */ - break; - } /* end switch */ - -return 0; -} - - -/* Unit service */ - -t_stat ptp_svc (UNIT *uptr) -{ -DEV_CLR_BUSY( INT_PTP ) ; -DEV_SET_DONE( INT_PTP ) ; -DEV_UPDATE_INTR ; -if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */ - return IORETURN (ptp_stopioe, SCPE_UNATT); -if (putc ((ptp_unit.buf & ((ptp_unit.flags & UNIT_8B)? 0377: 0177)), ptp_unit.fileref) == EOF) { - sim_perror ("PTP I/O error"); - clearerr (ptp_unit.fileref); - return SCPE_IOERR; - } -++(ptp_unit.pos); -return SCPE_OK; -} - - -/* Reset routine */ - -t_stat ptp_reset (DEVICE *dptr) -{ -ptp_unit.buf = 0; /* */ -DEV_CLR_BUSY( INT_PTP ) ; -DEV_CLR_DONE( INT_PTP ) ; -DEV_UPDATE_INTR ; -sim_cancel (&ptp_unit); /* deactivate unit */ -return SCPE_OK; -} +/* nova_pt.c: NOVA paper tape read/punch simulator + + Copyright (c) 1993-2016, Robert M. Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Robert M Supnik shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. + + ptr paper tape reader + ptp paper tape punch + + 13-May-16 RMS Lengthened wait time for DCC BASIC timing error + 28-Mar-15 RMS Revised to use sim_printf + 04-Jul-07 BKR added PTR and PTP device DISABLE capability, + added 7B/8B support PTR and PTP (default is 8B), + DEV_SET/CLR macros now used, + PTR and PTP can now be DISABLED + 25-Apr-03 RMS Revised for extended file support + 03-Oct-02 RMS Added DIBs + 30-May-02 RMS Widened POS to 32b + 29-Nov-01 RMS Added read only unit support + + +Notes: + - data masked to 7- or 8- bits, based on 7B or 8B, default is 8-bits + - register TIME is the delay between character read or write operations + - register POS show the number of characters read from or sent to the PTR or PTP + - register STOP_IOE determines return value issued if output to unattached PTR or PTP is attempted +*/ + +#include "nova_defs.h" + +extern int32 int_req, dev_busy, dev_done, dev_disable ; +extern int32 SR ; + +extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ; + + +int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */ + +int32 ptr (int32 pulse, int32 code, int32 AC); +int32 ptp (int32 pulse, int32 code, int32 AC); +t_stat ptr_svc (UNIT *uptr); +t_stat ptp_svc (UNIT *uptr); +t_stat ptr_reset (DEVICE *dptr); +t_stat ptp_reset (DEVICE *dptr); +t_stat ptr_boot (int32 unitno, DEVICE *dptr); + + +/* 7 or 8 bit data mask support for either device */ + +#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */ +#define UNIT_8B (1 << UNIT_V_8B) + + +/* PTR data structures + + ptr_dev PTR device descriptor + ptr_unit PTR unit descriptor + ptr_reg PTR register list +*/ + +DIB ptr_dib = { DEV_PTR, INT_PTR, PI_PTR, &ptr }; + +UNIT ptr_unit = { /* 2007-May-30, bkr */ + UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_8B, 0), 300 + }; + +REG ptr_reg[] = { + { ORDATA (BUF, ptr_unit.buf, 8) }, + { FLDATA (BUSY, dev_busy, INT_V_PTR) }, + { FLDATA (DONE, dev_done, INT_V_PTR) }, + { FLDATA (DISABLE, dev_disable, INT_V_PTR) }, + { FLDATA (INT, int_req, INT_V_PTR) }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, + { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, ptr_stopioe, 0) }, + { NULL } + }; + +MTAB ptr_mod[] = /* 2007-May-30, bkr */ + { + { UNIT_8B, 0, "7b", "7B", NULL }, + { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, + { 0, 0, NULL, NULL, NULL } + } ; + +DEVICE ptr_dev = { + "PTR", &ptr_unit, ptr_reg, ptr_mod /* 2007-May-30, bkr */, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &ptr_reset, + &ptr_boot, NULL, NULL, + &ptr_dib, DEV_DISABLE /* 2007-May-30, bkr */ + }; + +/* PTP data structures + + ptp_dev PTP device descriptor + ptp_unit PTP unit descriptor + ptp_reg PTP register list +*/ + +DIB ptp_dib = { DEV_PTP, INT_PTP, PI_PTP, &ptp }; + +UNIT ptp_unit = + { + UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_8B, 0), SERIAL_OUT_WAIT + }; + +REG ptp_reg[] = { + { ORDATA (BUF, ptp_unit.buf, 8) }, + { FLDATA (BUSY, dev_busy, INT_V_PTP) }, + { FLDATA (DONE, dev_done, INT_V_PTP) }, + { FLDATA (DISABLE, dev_disable, INT_V_PTP) }, + { FLDATA (INT, int_req, INT_V_PTP) }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, + { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, ptp_stopioe, 0) }, + { NULL } + }; + +MTAB ptp_mod[] = + { + { UNIT_8B, 0, "7b", "7B", NULL }, + { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, + { 0, 0, NULL, NULL, NULL } + } ; + +DEVICE ptp_dev = + { + "PTP", &ptp_unit, ptp_reg, ptp_mod /* 2007-May-30, bkr */, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &ptp_reset, + NULL, NULL, NULL, + &ptp_dib, DEV_DISABLE /* 2007-May-30, bkr */ + }; + + +/* Paper tape reader: IOT routine */ + +int32 ptr (int32 pulse, int32 code, int32 AC) +{ +int32 iodata; + +iodata = (code == ioDIA)? + ptr_unit.buf & 0377 + : 0; +switch (pulse) + { /* decode IR<8:9> */ + case iopS: /* start */ + DEV_SET_BUSY( INT_PTR ) ; + DEV_CLR_DONE( INT_PTR ) ; + DEV_UPDATE_INTR ; + sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */ + break; + + case iopC: /* clear */ + DEV_CLR_BUSY( INT_PTR ) ; + DEV_CLR_DONE( INT_PTR ) ; + DEV_UPDATE_INTR ; + sim_cancel (&ptr_unit); /* deactivate unit */ + break; + } /* end switch */ + +return iodata; +} + + +/* Unit service */ + +t_stat ptr_svc (UNIT *uptr) +{ +int32 temp; + +if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */ + return IORETURN (ptr_stopioe, SCPE_UNATT); +if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ + if (feof (ptr_unit.fileref)) { + if (ptr_stopioe) + sim_printf ("PTR end of file\n"); + else return SCPE_OK; + } + else sim_perror ("PTR I/O error"); + clearerr (ptr_unit.fileref); + return SCPE_IOERR; + } + +DEV_CLR_BUSY( INT_PTR ) ; +DEV_SET_DONE( INT_PTR ) ; +DEV_UPDATE_INTR ; +ptr_unit.buf = temp & ((ptr_unit.flags & UNIT_8B)? 0377: 0177); +++(ptr_unit.pos); +return SCPE_OK; +} + + +/* Reset routine */ + +t_stat ptr_reset (DEVICE *dptr) +{ +ptr_unit.buf = 0; /* */ +DEV_CLR_BUSY( INT_PTR ) ; +DEV_CLR_DONE( INT_PTR ) ; +DEV_UPDATE_INTR ; +sim_cancel (&ptr_unit); /* deactivate unit */ +return SCPE_OK; +} + + +/* Boot routine */ + +t_stat ptr_boot (int32 unitno, DEVICE *dptr) +{ +ptr_reset( dptr ) ; +/* set position to 0? */ +cpu_boot( unitno, dptr ) ; +SR = /* low-speed: no high-order bit set */ DEV_PTR ; +return ( SCPE_OK ); +} /* end of 'ptr_boot' */ + + + + + +/* Paper tape punch: IOT routine */ + +int32 ptp (int32 pulse, int32 code, int32 AC) +{ +if (code == ioDOA) + ptp_unit.buf = AC & 0377; + +switch (pulse) + { /* decode IR<8:9> */ + case iopS: /* start */ + DEV_SET_BUSY( INT_PTP ) ; + DEV_CLR_DONE( INT_PTP ) ; + DEV_UPDATE_INTR ; + sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */ + break; + + case iopC: /* clear */ + DEV_CLR_BUSY( INT_PTP ) ; + DEV_CLR_DONE( INT_PTP ) ; + DEV_UPDATE_INTR ; + sim_cancel (&ptp_unit); /* deactivate unit */ + break; + } /* end switch */ + +return 0; +} + + +/* Unit service */ + +t_stat ptp_svc (UNIT *uptr) +{ +DEV_CLR_BUSY( INT_PTP ) ; +DEV_SET_DONE( INT_PTP ) ; +DEV_UPDATE_INTR ; +if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */ + return IORETURN (ptp_stopioe, SCPE_UNATT); +if (putc ((ptp_unit.buf & ((ptp_unit.flags & UNIT_8B)? 0377: 0177)), ptp_unit.fileref) == EOF) { + sim_perror ("PTP I/O error"); + clearerr (ptp_unit.fileref); + return SCPE_IOERR; + } +++(ptp_unit.pos); +return SCPE_OK; +} + + +/* Reset routine */ + +t_stat ptp_reset (DEVICE *dptr) +{ +ptp_unit.buf = 0; /* */ +DEV_CLR_BUSY( INT_PTP ) ; +DEV_CLR_DONE( INT_PTP ) ; +DEV_UPDATE_INTR ; +sim_cancel (&ptp_unit); /* deactivate unit */ +return SCPE_OK; +} diff --git a/PDP11/ddcmp_sync.md b/PDP11/ddcmp_sync.md index d2f514ce..0f21190c 100644 --- a/PDP11/ddcmp_sync.md +++ b/PDP11/ddcmp_sync.md @@ -1,9 +1,9 @@ -# DDCMP synchronous line interface - -The DDCMP synchronous interface supported by the DUP and DMC device emulations, is a USB connected device that implements synchronous links for use by DDCMP. - -When used with SIMH, the synchronous interface allows an emulated DMC-11 or DUP-11 (including KMC/DUP) to be connected to a system that uses a real synchronous link for DDCMP, for example an actual DMC-11 device. The interface can support either RS-232 connectons for the DUP-11 or DMC-11 "remote" line cards, or the "integral modem" coaxial cable connection implemented in the DMC "local" line card. Speeds in the range 500 to 56k bits per second (for RS-232) or 56k to 1M bits per second (for integral modem) are supported. - -The DDCMP synchronous line interface is an open source design. All the design files (schematics, circuit board layout, firmware, and documentation) may be found on GitHub at [this link](https://github.com/pkoning2/ddcmp "DDCMP Framer on GitHub"). - -Note that at the moment, no boards, kits, or assembled units are offered. If you want a framer, you would need to obtain a circuit board and assemble it. The documentation in the GitHub design files explains how to do this. The design uses all "through hole" parts, so modest electronics assembly skills suffice to build a unit. +# DDCMP synchronous line interface + +The DDCMP synchronous interface supported by the DUP and DMC device emulations, is a USB connected device that implements synchronous links for use by DDCMP. + +When used with SIMH, the synchronous interface allows an emulated DMC-11 or DUP-11 (including KMC/DUP) to be connected to a system that uses a real synchronous link for DDCMP, for example an actual DMC-11 device. The interface can support either RS-232 connectons for the DUP-11 or DMC-11 "remote" line cards, or the "integral modem" coaxial cable connection implemented in the DMC "local" line card. Speeds in the range 500 to 56k bits per second (for RS-232) or 56k to 1M bits per second (for integral modem) are supported. + +The DDCMP synchronous line interface is an open source design. All the design files (schematics, circuit board layout, firmware, and documentation) may be found on GitHub at [this link](https://github.com/pkoning2/ddcmp "DDCMP Framer on GitHub"). + +Note that at the moment, no boards, kits, or assembled units are offered. If you want a framer, you would need to obtain a circuit board and assemble it. The documentation in the GitHub design files explains how to do this. The design uses all "through hole" parts, so modest electronics assembly skills suffice to build a unit. diff --git a/PDP11/pdp11_dz.c b/PDP11/pdp11_dz.c index 5f4c288b..2e81aefd 100644 --- a/PDP11/pdp11_dz.c +++ b/PDP11/pdp11_dz.c @@ -844,8 +844,8 @@ for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { for (muxln = 0; muxln < DZ_LINES; muxln++) { TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln]; - if (lp->serconfig) - tmxr_set_config_line (lp, lp->serconfig); /* make settings consistent */ + if (lp->serconfig) + tmxr_set_config_line (lp, lp->serconfig); /* make settings consistent */ } if (!dz_mctl || (0 == (dz_csr[dz] & CSR_MSE))) /* enabled? */ continue; @@ -873,10 +873,10 @@ for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { for (muxln = 0; muxln < DZ_LINES; muxln++) { TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln]; - free (lp->serconfig); - lp->serconfig = NULL; + free (lp->serconfig); + lp->serconfig = NULL; } - } + } return r; } diff --git a/PDP11/pdp11_mb.c b/PDP11/pdp11_mb.c index 3ee63514..57935407 100644 --- a/PDP11/pdp11_mb.c +++ b/PDP11/pdp11_mb.c @@ -46,17 +46,17 @@ static uint32 history[HSIZE]; /* BITS IN MBCSR */ #define MBINTE 0100 #define MBAFRZ 0200 -#define MBXAYR 0400 /* X= TV_WINDOWS) return; sim_debug (DBG_VID, &tv_dev, "Render display %d buffer %d\n", - display, buffer); + display, buffer); for (i = 0; i < (TV_PIXELS / 8); i += 2) render_word (buffer, i); tv_updated[display] = 1; diff --git a/PDP18B/tests/test340.simh b/PDP18B/tests/test340.simh index 55e1ff90..b4b2d9d2 100644 --- a/PDP18B/tests/test340.simh +++ b/PDP18B/tests/test340.simh @@ -1,27 +1,27 @@ -set g2out disabled - -set debug stdout -set dpy enabled -set dpy debug - -# Small test program. -dep -m 100 law 1000 -dep -m 101 idla -dep -m 102 idsi -dep -m 103 jmp 102 -dep -m 104 jmp 100 - -# Small display list. -#Go to point mode, set scale, set intensity. -dep 1000 020117 -#Stay in point mode, set x=1000. -dep 1001 021000 -#Go to vector mode, set y=1000. -dep 1002 301000 -#Escape, intensify, delta x=100. -dep 1003 600100 -#Stop. -dep 1004 003000 - -dep pc 100 -# Ready to go or single step. +set g2out disabled + +set debug stdout +set dpy enabled +set dpy debug + +# Small test program. +dep -m 100 law 1000 +dep -m 101 idla +dep -m 102 idsi +dep -m 103 jmp 102 +dep -m 104 jmp 100 + +# Small display list. +#Go to point mode, set scale, set intensity. +dep 1000 020117 +#Stay in point mode, set x=1000. +dep 1001 021000 +#Go to vector mode, set y=1000. +dep 1002 301000 +#Escape, intensify, delta x=100. +dep 1003 600100 +#Stop. +dep 1004 003000 + +dep pc 100 +# Ready to go or single step. diff --git a/TX-0/tx0_defs.h b/TX-0/tx0_defs.h index 4939d2cc..2b1feaa2 100644 --- a/TX-0/tx0_defs.h +++ b/TX-0/tx0_defs.h @@ -90,4 +90,4 @@ #define UNIT_MODE_TEST (1 << UNIT_V_MODE) -#endif /* TX0_DEFS_H_ */ +#endif /* TX0_DEFS_H_ */ diff --git a/display/iii.c b/display/iii.c index 396f5d5a..94f83e8d 100644 --- a/display/iii.c +++ b/display/iii.c @@ -97,7 +97,7 @@ iii_draw_line(int x1, int y1, int x2, int y2, int l) if (dy == 0) { for (i = 1; i < dx; i++) { display_point(x1, y1, l, 0); - x1+=ax; + x1+=ax; } return; } diff --git a/imlac/tests/ssv.simh b/imlac/tests/ssv.simh index f6158fc7..73ec79b8 100644 --- a/imlac/tests/ssv.simh +++ b/imlac/tests/ssv.simh @@ -1,9 +1,9 @@ -# Attach to a server. If the remote port isn't telnet, append ;notelnet. -attach tty 12345,connect=localhost:23 -# Configure a bootstrap ROM; some programs require this. -set rom type=stty -# Load SSV version 22. -load -s ssv22.iml -# Reset and run. -reset -go +# Attach to a server. If the remote port isn't telnet, append ;notelnet. +attach tty 12345,connect=localhost:23 +# Configure a bootstrap ROM; some programs require this. +set rom type=stty +# Load SSV version 22. +load -s ssv22.iml +# Reset and run. +reset +go diff --git a/scp.c b/scp.c index 41f8d80b..bf4803b3 100644 --- a/scp.c +++ b/scp.c @@ -6637,10 +6637,10 @@ if (vdelt) { if (1) { char mode[] = S_xstr(SIM_VERSION_MODE); - if (NULL != strchr (mode, '\"')) { /* Quoted String? */ - mode[strlen (mode) - 1] = '\0'; /* strip quotes */ - memmove (mode, mode + 1, strlen (mode)); - } + if (NULL != strchr (mode, '\"')) { /* Quoted String? */ + mode[strlen (mode) - 1] = '\0'; /* strip quotes */ + memmove (mode, mode + 1, strlen (mode)); + } fprintf (st, " %s", mode); setenv ("SIM_VERSION_MODE", mode, 1); } diff --git a/slirp_glue/qemu/main-loop.h b/slirp_glue/qemu/main-loop.h index 97fe597f..3cce3694 100644 --- a/slirp_glue/qemu/main-loop.h +++ b/slirp_glue/qemu/main-loop.h @@ -1,43 +1,43 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_MAIN_LOOP_H -#define QEMU_MAIN_LOOP_H 1 - - -/** - * qemu_notify_event: Force processing of pending events. - * - * Similar to signaling a condition variable, qemu_notify_event forces - * main_loop_wait to look at pending events and exit. The caller of - * main_loop_wait will usually call it again very soon, so qemu_notify_event - * also has the side effect of recalculating the sets of file descriptors - * that the main loop waits for. - * - * Calling qemu_notify_event is rarely necessary, because main loop - * services (bottom halves and timers) call it themselves. - */ -void qemu_notify_event(void); - -#endif +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef QEMU_MAIN_LOOP_H +#define QEMU_MAIN_LOOP_H 1 + + +/** + * qemu_notify_event: Force processing of pending events. + * + * Similar to signaling a condition variable, qemu_notify_event forces + * main_loop_wait to look at pending events and exit. The caller of + * main_loop_wait will usually call it again very soon, so qemu_notify_event + * also has the side effect of recalculating the sets of file descriptors + * that the main loop waits for. + * + * Calling qemu_notify_event is rarely necessary, because main loop + * services (bottom halves and timers) call it themselves. + */ +void qemu_notify_event(void); + +#endif diff --git a/slirp_glue/qemu/monitor/monitor.h b/slirp_glue/qemu/monitor/monitor.h index 174214e2..e088c162 100644 --- a/slirp_glue/qemu/monitor/monitor.h +++ b/slirp_glue/qemu/monitor/monitor.h @@ -1,8 +1,8 @@ -#ifndef MONITOR_H -#define MONITOR_H - -#include "qemu-common.h" - -void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); - -#endif /* !MONITOR_H */ +#ifndef MONITOR_H +#define MONITOR_H + +#include "qemu-common.h" + +void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); + +#endif /* !MONITOR_H */ diff --git a/slirp_glue/qemu/qemu-common.h b/slirp_glue/qemu/qemu-common.h index e86c1a60..b4158e99 100644 --- a/slirp_glue/qemu/qemu-common.h +++ b/slirp_glue/qemu/qemu-common.h @@ -1,54 +1,54 @@ - -/* Common header file that is included by all of QEMU. - * - * This file is supposed to be included only by .c files. No header file should - * depend on qemu-common.h, as this would easily lead to circular header - * dependencies. - * - * If a header file uses a definition from qemu-common.h, that definition - * must be moved to a separate header file, and the header that uses it - * must include that header. - */ -#ifndef QEMU_COMMON_H -#define QEMU_COMMON_H - -#include "qemu/osdep.h" -#include "qemu/typedefs.h" - -#include "glib.h" -#include "config-host.h" - -#if defined(O_BINARY) /* O_BINARY isn't used in slirp */ -#undef O_BINARY /* Avoid potential redefinition elsewhere */ -#endif - -/* HOST_LONG_BITS is the size of a native pointer in bits. */ -#if UINTPTR_MAX == UINT32_MAX -# define HOST_LONG_BITS 32 -#elif UINTPTR_MAX == UINT64_MAX -# define HOST_LONG_BITS 64 -#else -# error Unknown pointer size -#endif - -/* util/cutils.c */ -/** - * pstrcpy: - * @buf: buffer to copy string into - * @buf_size: size of @buf in bytes - * @str: string to copy - * - * Copy @str into @buf, including the trailing NUL, but do not - * write more than @buf_size bytes. The resulting buffer is - * always NUL terminated (even if the source string was too long). - * If @buf_size is zero or negative then no bytes are copied. - * - * This function is similar to strncpy(), but avoids two of that - * function's problems: - * * if @str fits in the buffer, pstrcpy() does not zero-fill the - * remaining space at the end of @buf - * * if @str is too long, pstrcpy() will copy the first @buf_size-1 - * bytes and then add a NUL - */ -void pstrcpy(char *buf, int buf_size, const char *str); -#endif + +/* Common header file that is included by all of QEMU. + * + * This file is supposed to be included only by .c files. No header file should + * depend on qemu-common.h, as this would easily lead to circular header + * dependencies. + * + * If a header file uses a definition from qemu-common.h, that definition + * must be moved to a separate header file, and the header that uses it + * must include that header. + */ +#ifndef QEMU_COMMON_H +#define QEMU_COMMON_H + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" + +#include "glib.h" +#include "config-host.h" + +#if defined(O_BINARY) /* O_BINARY isn't used in slirp */ +#undef O_BINARY /* Avoid potential redefinition elsewhere */ +#endif + +/* HOST_LONG_BITS is the size of a native pointer in bits. */ +#if UINTPTR_MAX == UINT32_MAX +# define HOST_LONG_BITS 32 +#elif UINTPTR_MAX == UINT64_MAX +# define HOST_LONG_BITS 64 +#else +# error Unknown pointer size +#endif + +/* util/cutils.c */ +/** + * pstrcpy: + * @buf: buffer to copy string into + * @buf_size: size of @buf in bytes + * @str: string to copy + * + * Copy @str into @buf, including the trailing NUL, but do not + * write more than @buf_size bytes. The resulting buffer is + * always NUL terminated (even if the source string was too long). + * If @buf_size is zero or negative then no bytes are copied. + * + * This function is similar to strncpy(), but avoids two of that + * function's problems: + * * if @str fits in the buffer, pstrcpy() does not zero-fill the + * remaining space at the end of @buf + * * if @str is too long, pstrcpy() will copy the first @buf_size-1 + * bytes and then add a NUL + */ +void pstrcpy(char *buf, int buf_size, const char *str); +#endif diff --git a/slirp_glue/qemu/queue.h b/slirp_glue/qemu/queue.h index 4f16ff72..3126c9e6 100644 --- a/slirp_glue/qemu/queue.h +++ b/slirp_glue/qemu/queue.h @@ -1,431 +1,431 @@ -/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ - -/* - * QEMU version: Copy from netbsd, removed debug code, removed some of - * the implementations. Left in singly-linked lists, lists, simple - * queues, and tail queues. - */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef QEMU_SYS_QUEUE_H_ -#define QEMU_SYS_QUEUE_H_ - -/* - * This file defines four types of data structures: singly-linked lists, - * lists, simple queues, and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The - * elements are singly linked for minimum space and pointer manipulation - * overhead at the expense of O(n) removal for arbitrary elements. New - * elements can be added to the list after an existing element or at the - * head of the list. Elements being removed from the head of the list - * should use the explicit macro for this purpose for optimum - * efficiency. A singly-linked list may only be traversed in the forward - * direction. Singly-linked lists are ideal for applications with large - * datasets and few or no removals or for implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * List definitions. - */ -#define QLIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define QLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define QLIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ -#define QLIST_INIT(head) do { \ - (head)->lh_first = NULL; \ -} while (/*CONSTCOND*/0) - -#define QLIST_SWAP(dstlist, srclist, field) do { \ - void *tmplist; \ - tmplist = (srclist)->lh_first; \ - (srclist)->lh_first = (dstlist)->lh_first; \ - if ((srclist)->lh_first != NULL) { \ - (srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \ - } \ - (dstlist)->lh_first = tmplist; \ - if ((dstlist)->lh_first != NULL) { \ - (dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \ - } \ -} while (/*CONSTCOND*/0) - -#define QLIST_FIX_HEAD_PTR(head, field) do { \ - if ((head)->lh_first != NULL) { \ - (head)->lh_first->field.le_prev = &(head)->lh_first; \ - } \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (/*CONSTCOND*/0) - -#define QLIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_FOREACH(var, head, field) \ - for ((var) = ((head)->lh_first); \ - (var); \ - (var) = ((var)->field.le_next)) - -#define QLIST_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->lh_first); \ - (var) && ((next_var) = ((var)->field.le_next), 1); \ - (var) = (next_var)) - -/* - * List access methods. - */ -#define QLIST_EMPTY(head) ((head)->lh_first == NULL) -#define QLIST_FIRST(head) ((head)->lh_first) -#define QLIST_NEXT(elm, field) ((elm)->field.le_next) - - -/* - * Singly-linked List definitions. - */ -#define QSLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define QSLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define QSLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define QSLIST_INIT(head) do { \ - (head)->slh_first = NULL; \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_AFTER(slistelm, field) do { \ - (slistelm)->field.sle_next = \ - QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_FOREACH(var, head, field) \ - for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) - -#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = QSLIST_FIRST((head)); \ - (var) && ((tvar) = QSLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -/* - * Singly-linked List access methods. - */ -#define QSLIST_EMPTY(head) ((head)->slh_first == NULL) -#define QSLIST_FIRST(head) ((head)->slh_first) -#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next) - - -/* - * Simple queue definitions. - */ -#define QSIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define QSIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define QSIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue functions. - */ -#define QSIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \ - QSIMPLEQ_INIT(removed); \ - if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \ - if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \ - (head)->sqh_last = &(head)->sqh_first; \ - } \ - (removed)->sqh_last = &(elm)->field.sqe_next; \ - (elm)->field.sqe_next = NULL; \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \ - if ((head)->sqh_first == (elm)) { \ - QSIMPLEQ_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->sqh_first; \ - while (curelm->field.sqe_next != (elm)) \ - curelm = curelm->field.sqe_next; \ - if ((curelm->field.sqe_next = \ - curelm->field.sqe_next->field.sqe_next) == NULL) \ - (head)->sqh_last = &(curelm)->field.sqe_next; \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->sqh_first); \ - (var); \ - (var) = ((var)->field.sqe_next)) - -#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \ - for ((var) = ((head)->sqh_first); \ - (var) && ((next = ((var)->field.sqe_next)), 1); \ - (var) = (next)) - -#define QSIMPLEQ_CONCAT(head1, head2) do { \ - if (!QSIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - QSIMPLEQ_INIT((head2)); \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_LAST(head, type, field) \ - (QSIMPLEQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ - ((char *)((head)->sqh_last) - offsetof(struct type, field)))) - -/* - * Simple queue access methods. - */ -#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) -#define QSIMPLEQ_FIRST(head) ((head)->sqh_first) -#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - - -/* - * Tail queue definitions. - */ -#define Q_TAILQ_HEAD(name, type, qual) \ -struct name { \ - qual type *tqh_first; /* first element */ \ - qual type *qual *tqh_last; /* addr of last next element */ \ -} -#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) - -#define QTAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define Q_TAILQ_ENTRY(type, qual) \ -struct { \ - qual type *tqe_next; /* next element */ \ - qual type *qual *tqe_prev; /* address of previous next element */\ -} -#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,) - -/* - * Tail queue functions. - */ -#define QTAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_FOREACH(var, head, field) \ - for ((var) = ((head)->tqh_first); \ - (var); \ - (var) = ((var)->field.tqe_next)) - -#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->tqh_first); \ - (var) && ((next_var) = ((var)->field.tqe_next), 1); \ - (var) = (next_var)) - -#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ - (var); \ - (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) - -/* - * Tail queue access methods. - */ -#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL) -#define QTAILQ_FIRST(head) ((head)->tqh_first) -#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define QTAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define QTAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#endif /* !QEMU_SYS_QUEUE_H_ */ +/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ + +/* + * QEMU version: Copy from netbsd, removed debug code, removed some of + * the implementations. Left in singly-linked lists, lists, simple + * queues, and tail queues. + */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef QEMU_SYS_QUEUE_H_ +#define QEMU_SYS_QUEUE_H_ + +/* + * This file defines four types of data structures: singly-linked lists, + * lists, simple queues, and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The + * elements are singly linked for minimum space and pointer manipulation + * overhead at the expense of O(n) removal for arbitrary elements. New + * elements can be added to the list after an existing element or at the + * head of the list. Elements being removed from the head of the list + * should use the explicit macro for this purpose for optimum + * efficiency. A singly-linked list may only be traversed in the forward + * direction. Singly-linked lists are ideal for applications with large + * datasets and few or no removals or for implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * List definitions. + */ +#define QLIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define QLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define QLIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ +#define QLIST_INIT(head) do { \ + (head)->lh_first = NULL; \ +} while (/*CONSTCOND*/0) + +#define QLIST_SWAP(dstlist, srclist, field) do { \ + void *tmplist; \ + tmplist = (srclist)->lh_first; \ + (srclist)->lh_first = (dstlist)->lh_first; \ + if ((srclist)->lh_first != NULL) { \ + (srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \ + } \ + (dstlist)->lh_first = tmplist; \ + if ((dstlist)->lh_first != NULL) { \ + (dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \ + } \ +} while (/*CONSTCOND*/0) + +#define QLIST_FIX_HEAD_PTR(head, field) do { \ + if ((head)->lh_first != NULL) { \ + (head)->lh_first->field.le_prev = &(head)->lh_first; \ + } \ +} while (/*CONSTCOND*/0) + +#define QLIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (/*CONSTCOND*/0) + +#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (/*CONSTCOND*/0) + +#define QLIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (/*CONSTCOND*/0) + +#define QLIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (/*CONSTCOND*/0) + +#define QLIST_FOREACH(var, head, field) \ + for ((var) = ((head)->lh_first); \ + (var); \ + (var) = ((var)->field.le_next)) + +#define QLIST_FOREACH_SAFE(var, head, field, next_var) \ + for ((var) = ((head)->lh_first); \ + (var) && ((next_var) = ((var)->field.le_next), 1); \ + (var) = (next_var)) + +/* + * List access methods. + */ +#define QLIST_EMPTY(head) ((head)->lh_first == NULL) +#define QLIST_FIRST(head) ((head)->lh_first) +#define QLIST_NEXT(elm, field) ((elm)->field.le_next) + + +/* + * Singly-linked List definitions. + */ +#define QSLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define QSLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define QSLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define QSLIST_INIT(head) do { \ + (head)->slh_first = NULL; \ +} while (/*CONSTCOND*/0) + +#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define QSLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define QSLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (/*CONSTCOND*/0) + +#define QSLIST_REMOVE_AFTER(slistelm, field) do { \ + (slistelm)->field.sle_next = \ + QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \ +} while (/*CONSTCOND*/0) + +#define QSLIST_FOREACH(var, head, field) \ + for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = QSLIST_FIRST((head)); \ + (var) && ((tvar) = QSLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +/* + * Singly-linked List access methods. + */ +#define QSLIST_EMPTY(head) ((head)->slh_first == NULL) +#define QSLIST_FIRST(head) ((head)->slh_first) +#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next) + + +/* + * Simple queue definitions. + */ +#define QSIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define QSIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define QSIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue functions. + */ +#define QSIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \ + QSIMPLEQ_INIT(removed); \ + if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \ + if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \ + (head)->sqh_last = &(head)->sqh_first; \ + } \ + (removed)->sqh_last = &(elm)->field.sqe_next; \ + (elm)->field.sqe_next = NULL; \ + } \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \ + if ((head)->sqh_first == (elm)) { \ + QSIMPLEQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->sqh_first; \ + while (curelm->field.sqe_next != (elm)) \ + curelm = curelm->field.sqe_next; \ + if ((curelm->field.sqe_next = \ + curelm->field.sqe_next->field.sqe_next) == NULL) \ + (head)->sqh_last = &(curelm)->field.sqe_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->sqh_first); \ + (var); \ + (var) = ((var)->field.sqe_next)) + +#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \ + for ((var) = ((head)->sqh_first); \ + (var) && ((next = ((var)->field.sqe_next)), 1); \ + (var) = (next)) + +#define QSIMPLEQ_CONCAT(head1, head2) do { \ + if (!QSIMPLEQ_EMPTY((head2))) { \ + *(head1)->sqh_last = (head2)->sqh_first; \ + (head1)->sqh_last = (head2)->sqh_last; \ + QSIMPLEQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) + +#define QSIMPLEQ_LAST(head, type, field) \ + (QSIMPLEQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->sqh_last) - offsetof(struct type, field)))) + +/* + * Simple queue access methods. + */ +#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) +#define QSIMPLEQ_FIRST(head) ((head)->sqh_first) +#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + + +/* + * Tail queue definitions. + */ +#define Q_TAILQ_HEAD(name, type, qual) \ +struct name { \ + qual type *tqh_first; /* first element */ \ + qual type *qual *tqh_last; /* addr of last next element */ \ +} +#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) + +#define QTAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define Q_TAILQ_ENTRY(type, qual) \ +struct { \ + qual type *tqe_next; /* next element */ \ + qual type *qual *tqe_prev; /* address of previous next element */\ +} +#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,) + +/* + * Tail queue functions. + */ +#define QTAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define QTAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->tqh_first); \ + (var); \ + (var) = ((var)->field.tqe_next)) + +#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \ + for ((var) = ((head)->tqh_first); \ + (var) && ((next_var) = ((var)->field.tqe_next), 1); \ + (var) = (next_var)) + +#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ + (var); \ + (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) + +/* + * Tail queue access methods. + */ +#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL) +#define QTAILQ_FIRST(head) ((head)->tqh_first) +#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define QTAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +#define QTAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#endif /* !QEMU_SYS_QUEUE_H_ */ diff --git a/slirp_glue/qemu/sockets.h b/slirp_glue/qemu/sockets.h index 099925c3..14ad2989 100644 --- a/slirp_glue/qemu/sockets.h +++ b/slirp_glue/qemu/sockets.h @@ -1,52 +1,52 @@ -/* headers to use the BSD sockets */ -#ifndef QEMU_SOCKET_H -#define QEMU_SOCKET_H - -#ifdef _WIN32 -#include -#include -#include - -#define socket_error() WSAGetLastError() - -extern char *socket_strerror(int errcode); -#define strerror socket_strerror - -int inet_aton(const char *cp, struct in_addr *ia); - -#else - -#include -#include -#include -#include -#include -#include -#include - -#define socket_error() errno - -#endif /* !_WIN32 */ - -/* misc helpers */ -int qemu_socket(int domain, int type, int protocol); -int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int socket_set_cork(int fd, int v); -int socket_set_nodelay(int fd); -void qemu_set_block(int fd); -void qemu_set_nonblock(int fd); -int socket_set_fast_reuse(int fd); - -#ifdef _WIN32 -/* MinGW needs type casts for the 'buf' and 'optval' arguments. */ -#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \ - sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen) - -/* Windows has different names for the same constants with the same values */ -#define SHUT_RD 0 -#define SHUT_WR 1 -#define SHUT_RDWR 2 -#endif - - -#endif /* QEMU_SOCKET_H */ +/* headers to use the BSD sockets */ +#ifndef QEMU_SOCKET_H +#define QEMU_SOCKET_H + +#ifdef _WIN32 +#include +#include +#include + +#define socket_error() WSAGetLastError() + +extern char *socket_strerror(int errcode); +#define strerror socket_strerror + +int inet_aton(const char *cp, struct in_addr *ia); + +#else + +#include +#include +#include +#include +#include +#include +#include + +#define socket_error() errno + +#endif /* !_WIN32 */ + +/* misc helpers */ +int qemu_socket(int domain, int type, int protocol); +int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int socket_set_cork(int fd, int v); +int socket_set_nodelay(int fd); +void qemu_set_block(int fd); +void qemu_set_nonblock(int fd); +int socket_set_fast_reuse(int fd); + +#ifdef _WIN32 +/* MinGW needs type casts for the 'buf' and 'optval' arguments. */ +#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \ + sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen) + +/* Windows has different names for the same constants with the same values */ +#define SHUT_RD 0 +#define SHUT_WR 1 +#define SHUT_RDWR 2 +#endif + + +#endif /* QEMU_SOCKET_H */ diff --git a/slirp_glue/qemu/sysemu/char.h b/slirp_glue/qemu/sysemu/char.h index 142e1164..339a254f 100644 --- a/slirp_glue/qemu/sysemu/char.h +++ b/slirp_glue/qemu/sysemu/char.h @@ -1,21 +1,21 @@ -#ifndef QEMU_CHAR_H -#define QEMU_CHAR_H - -#include "qemu-common.h" - -/** - * @qemu_chr_fe_write: - * - * Write data to a character backend from the front end. This function - * will send data from the front end to the back end. This function - * is thread-safe. - * - * @buf the data - * @len the number of bytes to send - * - * Returns: the number of bytes consumed - */ -int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); - - -#endif +#ifndef QEMU_CHAR_H +#define QEMU_CHAR_H + +#include "qemu-common.h" + +/** + * @qemu_chr_fe_write: + * + * Write data to a character backend from the front end. This function + * will send data from the front end to the back end. This function + * is thread-safe. + * + * @buf the data + * @len the number of bytes to send + * + * Returns: the number of bytes consumed + */ +int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); + + +#endif diff --git a/slirp_glue/qemu/sysemu/os-win32.h b/slirp_glue/qemu/sysemu/os-win32.h index 09122d6e..fff060a9 100644 --- a/slirp_glue/qemu/sysemu/os-win32.h +++ b/slirp_glue/qemu/sysemu/os-win32.h @@ -1,112 +1,112 @@ -/* - * win32 specific declarations - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2010 Jes Sorensen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_OS_WIN32_H -#define QEMU_OS_WIN32_H - -#include -#include - -#if defined(_WIN64) -/* MinGW-w64 has a 32 bit off_t, but we want 64 bit off_t. */ -# define off_t off64_t - -/* MinGW-w64 stdio.h defines SYS_OPEN. Allow a redefinition in arm-semi.c. */ -# undef SYS_OPEN -#endif - -/* Workaround for older versions of MinGW. */ -#ifndef ECONNREFUSED -# define ECONNREFUSED WSAECONNREFUSED -#endif -#ifndef EINPROGRESS -# define EINPROGRESS WSAEINPROGRESS -#endif -#ifndef EHOSTUNREACH -# define EHOSTUNREACH WSAEHOSTUNREACH -#endif -#ifndef EINTR -# define EINTR WSAEINTR -#endif -#ifndef EINPROGRESS -# define EINPROGRESS WSAEINPROGRESS -#endif -#ifndef ENETUNREACH -# define ENETUNREACH WSAENETUNREACH -#endif -#ifndef ENOTCONN -# define ENOTCONN WSAENOTCONN -#endif -#ifndef EWOULDBLOCK -# define EWOULDBLOCK WSAEWOULDBLOCK -#endif - -#if defined(_WIN64) -/* On w64, setjmp is implemented by _setjmp which needs a second parameter. - * If this parameter is NULL, longjump does no stack unwinding. - * That is what we need for QEMU. Passing the value of register rsp (default) - * lets longjmp try a stack unwinding which will crash with generated code. */ -# undef setjmp -# define setjmp(env) _setjmp(env, NULL) -#endif -/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify - * "longjmp and don't touch the signal masks". Since we know that the - * savemask parameter will always be zero we can safely define these - * in terms of setjmp/longjmp on Win32. - */ -#define sigjmp_buf jmp_buf -#define sigsetjmp(env, savemask) setjmp(env) -#define siglongjmp(env, val) longjmp(env, val) - -/* Missing POSIX functions. Don't use MinGW-w64 macros. */ -#ifndef CONFIG_LOCALTIME_R -#undef gmtime_r -struct tm *gmtime_r(const time_t *timep, struct tm *result); -#undef localtime_r -struct tm *localtime_r(const time_t *timep, struct tm *result); -#endif /* CONFIG_LOCALTIME_R */ - - -static inline void os_setup_signal_handling(void) {} -static inline void os_daemonize(void) {} -static inline void os_setup_post(void) {} -void os_set_line_buffering(void); -static inline void os_set_proc_name(const char *dummy) {} - -size_t getpagesize(void); - -#if !defined(EPROTONOSUPPORT) -# define EPROTONOSUPPORT EINVAL -#endif - -int setenv(const char *name, const char *value, int overwrite); - -typedef struct { - long tv_sec; - long tv_usec; -} qemu_timeval; -int qemu_gettimeofday(qemu_timeval *tp); - -#endif +/* + * win32 specific declarations + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2010 Jes Sorensen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef QEMU_OS_WIN32_H +#define QEMU_OS_WIN32_H + +#include +#include + +#if defined(_WIN64) +/* MinGW-w64 has a 32 bit off_t, but we want 64 bit off_t. */ +# define off_t off64_t + +/* MinGW-w64 stdio.h defines SYS_OPEN. Allow a redefinition in arm-semi.c. */ +# undef SYS_OPEN +#endif + +/* Workaround for older versions of MinGW. */ +#ifndef ECONNREFUSED +# define ECONNREFUSED WSAECONNREFUSED +#endif +#ifndef EINPROGRESS +# define EINPROGRESS WSAEINPROGRESS +#endif +#ifndef EHOSTUNREACH +# define EHOSTUNREACH WSAEHOSTUNREACH +#endif +#ifndef EINTR +# define EINTR WSAEINTR +#endif +#ifndef EINPROGRESS +# define EINPROGRESS WSAEINPROGRESS +#endif +#ifndef ENETUNREACH +# define ENETUNREACH WSAENETUNREACH +#endif +#ifndef ENOTCONN +# define ENOTCONN WSAENOTCONN +#endif +#ifndef EWOULDBLOCK +# define EWOULDBLOCK WSAEWOULDBLOCK +#endif + +#if defined(_WIN64) +/* On w64, setjmp is implemented by _setjmp which needs a second parameter. + * If this parameter is NULL, longjump does no stack unwinding. + * That is what we need for QEMU. Passing the value of register rsp (default) + * lets longjmp try a stack unwinding which will crash with generated code. */ +# undef setjmp +# define setjmp(env) _setjmp(env, NULL) +#endif +/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify + * "longjmp and don't touch the signal masks". Since we know that the + * savemask parameter will always be zero we can safely define these + * in terms of setjmp/longjmp on Win32. + */ +#define sigjmp_buf jmp_buf +#define sigsetjmp(env, savemask) setjmp(env) +#define siglongjmp(env, val) longjmp(env, val) + +/* Missing POSIX functions. Don't use MinGW-w64 macros. */ +#ifndef CONFIG_LOCALTIME_R +#undef gmtime_r +struct tm *gmtime_r(const time_t *timep, struct tm *result); +#undef localtime_r +struct tm *localtime_r(const time_t *timep, struct tm *result); +#endif /* CONFIG_LOCALTIME_R */ + + +static inline void os_setup_signal_handling(void) {} +static inline void os_daemonize(void) {} +static inline void os_setup_post(void) {} +void os_set_line_buffering(void); +static inline void os_set_proc_name(const char *dummy) {} + +size_t getpagesize(void); + +#if !defined(EPROTONOSUPPORT) +# define EPROTONOSUPPORT EINVAL +#endif + +int setenv(const char *name, const char *value, int overwrite); + +typedef struct { + long tv_sec; + long tv_usec; +} qemu_timeval; +int qemu_gettimeofday(qemu_timeval *tp); + +#endif diff --git a/slirp_glue/qemu/timer.h b/slirp_glue/qemu/timer.h index 2a429139..ba7918b2 100644 --- a/slirp_glue/qemu/timer.h +++ b/slirp_glue/qemu/timer.h @@ -1,95 +1,95 @@ -#ifndef QEMU_TIMER_H -#define QEMU_TIMER_H - -#include "qemu/typedefs.h" -#include "qemu-common.h" - -#define NANOSECONDS_PER_SECOND 1000000000LL - -/* timers */ - -#define SCALE_MS 1000000 -#define SCALE_US 1000 -#define SCALE_NS 1 - -/** - * QEMUClockType: - * - * The following clock types are available: - * - * @QEMU_CLOCK_REALTIME: Real time clock - * - * The real time clock should be used only for stuff which does not - * change the virtual machine state, as it is run even if the virtual - * machine is stopped. The real time clock has a frequency of 1000 - * Hz. - * - * @QEMU_CLOCK_VIRTUAL: virtual clock - * - * The virtual clock is only run during the emulation. It is stopped - * when the virtual machine is stopped. Virtual timers use a high - * precision clock, usually cpu cycles (use ticks_per_sec). - * - * @QEMU_CLOCK_HOST: host clock - * - * The host clock should be use for device models that emulate accurate - * real time sources. It will continue to run when the virtual machine - * is suspended, and it will reflect system time changes the host may - * undergo (e.g. due to NTP). The host clock has the same precision as - * the virtual clock. - * - * @QEMU_CLOCK_VIRTUAL_RT: realtime clock used for icount warp - * - * Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL. - * In icount mode, this clock counts nanoseconds while the virtual - * machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL - * while the CPUs are sleeping and thus not executing instructions. - */ - -typedef enum { - QEMU_CLOCK_REALTIME = 0, - QEMU_CLOCK_VIRTUAL = 1, - QEMU_CLOCK_HOST = 2, - QEMU_CLOCK_VIRTUAL_RT = 3, - QEMU_CLOCK_MAX -} QEMUClockType; - - - - -/* - * QEMUClockType - */ - -/* - * qemu_clock_get_ns; - * @type: the clock type - * - * Get the nanosecond value of a clock with - * type @type - * - * Returns: the clock value in nanoseconds - */ -#if defined(__cplusplus) -extern "C" { -#endif -int64_t qemu_clock_get_ns(QEMUClockType type); -#if defined(__cplusplus) -} -#endif - -/** - * qemu_clock_get_ms; - * @type: the clock type - * - * Get the millisecond value of a clock with - * type @type - * - * Returns: the clock value in milliseconds - */ -static inline int64_t qemu_clock_get_ms(QEMUClockType type) -{ - return qemu_clock_get_ns(type) / SCALE_MS; -} - -#endif +#ifndef QEMU_TIMER_H +#define QEMU_TIMER_H + +#include "qemu/typedefs.h" +#include "qemu-common.h" + +#define NANOSECONDS_PER_SECOND 1000000000LL + +/* timers */ + +#define SCALE_MS 1000000 +#define SCALE_US 1000 +#define SCALE_NS 1 + +/** + * QEMUClockType: + * + * The following clock types are available: + * + * @QEMU_CLOCK_REALTIME: Real time clock + * + * The real time clock should be used only for stuff which does not + * change the virtual machine state, as it is run even if the virtual + * machine is stopped. The real time clock has a frequency of 1000 + * Hz. + * + * @QEMU_CLOCK_VIRTUAL: virtual clock + * + * The virtual clock is only run during the emulation. It is stopped + * when the virtual machine is stopped. Virtual timers use a high + * precision clock, usually cpu cycles (use ticks_per_sec). + * + * @QEMU_CLOCK_HOST: host clock + * + * The host clock should be use for device models that emulate accurate + * real time sources. It will continue to run when the virtual machine + * is suspended, and it will reflect system time changes the host may + * undergo (e.g. due to NTP). The host clock has the same precision as + * the virtual clock. + * + * @QEMU_CLOCK_VIRTUAL_RT: realtime clock used for icount warp + * + * Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL. + * In icount mode, this clock counts nanoseconds while the virtual + * machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL + * while the CPUs are sleeping and thus not executing instructions. + */ + +typedef enum { + QEMU_CLOCK_REALTIME = 0, + QEMU_CLOCK_VIRTUAL = 1, + QEMU_CLOCK_HOST = 2, + QEMU_CLOCK_VIRTUAL_RT = 3, + QEMU_CLOCK_MAX +} QEMUClockType; + + + + +/* + * QEMUClockType + */ + +/* + * qemu_clock_get_ns; + * @type: the clock type + * + * Get the nanosecond value of a clock with + * type @type + * + * Returns: the clock value in nanoseconds + */ +#if defined(__cplusplus) +extern "C" { +#endif +int64_t qemu_clock_get_ns(QEMUClockType type); +#if defined(__cplusplus) +} +#endif + +/** + * qemu_clock_get_ms; + * @type: the clock type + * + * Get the millisecond value of a clock with + * type @type + * + * Returns: the clock value in milliseconds + */ +static inline int64_t qemu_clock_get_ms(QEMUClockType type) +{ + return qemu_clock_get_ns(type) / SCALE_MS; +} + +#endif diff --git a/slirp_glue/qemu/typedefs.h b/slirp_glue/qemu/typedefs.h index 9ed4a300..404ce222 100644 --- a/slirp_glue/qemu/typedefs.h +++ b/slirp_glue/qemu/typedefs.h @@ -1,11 +1,11 @@ -#ifndef QEMU_TYPEDEFS_H -#define QEMU_TYPEDEFS_H - -/* A load of opaque types so that device init declarations don't have to - pull in all the real definitions. */ -struct Monitor; -typedef struct Monitor Monitor; -typedef struct CharDriverState CharDriverState; -typedef struct QEMUFile QEMUFile; - -#endif /* QEMU_TYPEDEFS_H */ +#ifndef QEMU_TYPEDEFS_H +#define QEMU_TYPEDEFS_H + +/* A load of opaque types so that device init declarations don't have to + pull in all the real definitions. */ +struct Monitor; +typedef struct Monitor Monitor; +typedef struct CharDriverState CharDriverState; +typedef struct QEMUFile QEMUFile; + +#endif /* QEMU_TYPEDEFS_H */ diff --git a/swtp6800/common/m6800.c b/swtp6800/common/m6800.c index df755638..600376a2 100644 --- a/swtp6800/common/m6800.c +++ b/swtp6800/common/m6800.c @@ -2051,13 +2051,13 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) chk += addr >> 8; for (i=0; i> 8; for (i=0; i<=(end - addr); i++) { byte = CPU_BD_get_mbyte(addr + i); - fprintf(fileref, "%02X", byte); + fprintf(fileref, "%02X", byte); chk += byte; chk &= BYTEMASK; cnt++; } chk = (~chk) & BYTEMASK; fprintf(fileref, "%02X\n", chk); - addr = end; + addr = end; } fprintf(fileref,"S9\n"); //EOF record } else { //binary diff --git a/swtp6800/common/mp-s.c b/swtp6800/common/mp-s.c index c6d2c7da..7267d195 100644 --- a/swtp6800/common/mp-s.c +++ b/swtp6800/common/mp-s.c @@ -335,23 +335,23 @@ int32 sio0d(int32 io, int32 data) case 0x11: // PTR on ptr_flag = 1; ptr_unit.u3 |= RXF; - printf("Reader on\n"); + printf("Reader on\n"); break; case 0x12: // PTP on ptp_flag = 1; ptp_unit.u3 |= TXE; - printf("Punch on\n"); + printf("Punch on\n"); break; case 0x13: // PTR off ptr_flag = 0; if (ptr_unit.pos) - printf("Reader off-%d bytes read\n", ptr_unit.pos); + printf("Reader off-%d bytes read\n", ptr_unit.pos); ptr_unit.pos = 0; break; case 0x14: // PTP off ptp_flag = 0; if (ptp_unit.pos) - printf("Punch off-%d bytes written\n", ptp_unit.pos); + printf("Punch off-%d bytes written\n", ptp_unit.pos); ptp_unit.pos = 0; break; default: // ignore all other characters diff --git a/tt2500/tests/tt2500_test.ini b/tt2500/tests/tt2500_test.ini index 51010d57..054ca8ed 100644 --- a/tt2500/tests/tt2500_test.ini +++ b/tt2500/tests/tt2500_test.ini @@ -1,17 +1,17 @@ -cd %~p0 - -set tv disabled -set crt disabled - -on error goto failed - -break 1235 - -load test.ascii -run 100 - -:failed -if (PC != 669) echof "\n*** TEST FAILED\n"; exit 1 - -echof "\n*** TEST PASSED\n" -exit 0 +cd %~p0 + +set tv disabled +set crt disabled + +on error goto failed + +break 1235 + +load test.ascii +run 100 + +:failed +if (PC != 669) echof "\n*** TEST FAILED\n"; exit 1 + +echof "\n*** TEST PASSED\n" +exit 0 diff --git a/tt2500/tt2500_dpy.c b/tt2500/tt2500_dpy.c index 7d9ff112..225fba0b 100644 --- a/tt2500/tt2500_dpy.c +++ b/tt2500/tt2500_dpy.c @@ -63,7 +63,7 @@ int dpy_quit = FALSE; 4000 6000 -tv-off tv-off-const 1 001 (unused) +tv-off tv-off-const 1 001 (unused) tv-green-const 2 010 (unused) tv-blank green-blank-const 4 100 (flash) diff --git a/tt2500/tt2500_rom.c b/tt2500/tt2500_rom.c index b0405147..c2cc98aa 100644 --- a/tt2500/tt2500_rom.c +++ b/tt2500/tt2500_rom.c @@ -1,99 +1,99 @@ -/* tt2500_cpu.c: TT2500 bootstrap ROM contents. - - Copyright (c) 2020, Lars Brinkhoff - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Lars Brinkhoff shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Lars Brinkhoff. -*/ - -#include "tt2500_defs.h" - -uint16 tt2500_rom[] = -{ -/* BEGIN 0 */ 0010000, /* (NOP) */ -/* 1 */ 0010000, /* (NOP) */ -/* 2 */ 0010000, /* (NOP) */ -/* START 3 */ 0040025, /* (PUSHJ GETC & GET CHAR) */ -/* 4 */ 0007001, /* (SUBI 0 WD & IS WORD "LOGO") */ -/* 5 */ 0147577, /* (147577) */ -/* 6 */ 0133774, /* (BNE START) */ -/* 7 */ 0040022, /* (PUSHJ GETW) */ -/* 10 */ 0074201, /* (GET ADR WD) */ -/* 11 */ 0040022, /* (PUSHJ GETW) */ -/* 12 */ 0074301, /* (GET CNT WD) */ -/* LOOP 13 */ 0040022, /* (PUSHJ GETW) */ -/* 14 */ 0004220, /* (DEC ADR) */ -/* 15 */ 0025100, /* (CWRITE WD) */ -/* 16 */ 0004320, /* (DEC CNT) */ -/* 17 */ 0133773, /* (BNE LOOP) */ -/* 20 */ 0074023, /* (GET 0 XR) */ -/* 21 */ 0050100, /* (JUMP 100) */ -/* GETW 22 */ 0040025, /* (PUSHJ GETC) */ -/* 23 */ 0040025, /* (PUSHJ GETC) */ -/* 24 */ 0040025, /* (PUSHJ GETC) */ -/* GETC 25 */ 0073320, /* (DIS INTS 2) */ -/* 26 */ 0050025, /* (JUMP GETC) */ -/* 27 */ 0010000, /* (NOP) */ -/* 30 */ 0074424, /* (GET CH UART) */ -/* 31 */ 0001444, /* (ANDI CH CH) */ -/* 32 */ 0000017, /* (17) */ -/* 33 */ 0004114, /* (ROT WD 14) */ -/* 34 */ 0001141, /* (ANDI WD WD) */ -/* 35 */ 0177760, /* (177760) */ -/* 36 */ 0002104, /* (IOR WD CH) */ -/* 37 */ 0076016 /* (POPJ) */ - - -#if 0 - 0010000, /* NOP */ - 0010000, /* NOP */ - 0010000, /* NOP */ - 0040025, /* PUSHJ GETC Call subroutine to read TTY character. */ - 0007001, /* SUBI 0 WD 32-bit instruction computes 147577 - WD */ - 0147577, /* 147577 (The constant "LOGO" is stored here.) */ - 0133774, /* BNE START Branch to START if result Not zero. */ - 0040022, /* PUSHJ GETW Reads 4 characters to make 16-bit word. */ - 0074201, /* GET ADR WD Move word from WD to ADR (register 2). */ - 0040022, /* PUSHJ GETW Get next data word into WD. */ - 0074301, /* GET CNT WD Move it to CNT. */ - 0040022, /* PUSHJ GETW Get another data word. */ - 0004220, /* DEC ADR Decrement the Address and use it to */ - 0025100, /* CWRITE WD write [WD] into control memory. */ - 0004320, /* DEC CNT Decrement the word in CNT (count). */ - 0133773, /* BNE LOOP Branch to LOOP unless CNT is zero. */ - 0074023, /* GET 0 XR Makes PC leave Bootstrap Loader. */ - 0050100, /* JUMP 100 Jump to location 100. */ - 0040025, /* PUSHJ GETC Get 4 bits and shift into WD. */ - 0040025, /* PUSHJ GETC Get 4 more. */ - 0040025, /* PUSHJ GETC Get 4 more. */ - 0073320, /* DIS INTS 2 Skip 2 steps if TTY interrupt active. */ - 0050025, /* JUMP GETC If not, go back and wait. */ - 0010000, /* NOP (Skip over this.) */ - 0074424, /* GET CH UART Put the character into CH. */ - 0001444, /* ANDI CH CH Mask out all but last four bits by */ - 0000017, /* 17 ANDing with 0 000 000 000 001 111. */ - 0004114, /* ROT WD 14 Rotate WD four places right. */ - 0001141, /* ANDI WD WD Zero out last four bits by */ - 0177760, /* 177760 ANDing with 1 111 111 111 110 000. */ - 0002104, /* IOR WD CH Finally, OR them together. */ - 0075600, /* POPJ Return to calling program. */ -#endif -}; +/* tt2500_cpu.c: TT2500 bootstrap ROM contents. + + Copyright (c) 2020, Lars Brinkhoff + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Lars Brinkhoff shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Lars Brinkhoff. +*/ + +#include "tt2500_defs.h" + +uint16 tt2500_rom[] = +{ +/* BEGIN 0 */ 0010000, /* (NOP) */ +/* 1 */ 0010000, /* (NOP) */ +/* 2 */ 0010000, /* (NOP) */ +/* START 3 */ 0040025, /* (PUSHJ GETC & GET CHAR) */ +/* 4 */ 0007001, /* (SUBI 0 WD & IS WORD "LOGO") */ +/* 5 */ 0147577, /* (147577) */ +/* 6 */ 0133774, /* (BNE START) */ +/* 7 */ 0040022, /* (PUSHJ GETW) */ +/* 10 */ 0074201, /* (GET ADR WD) */ +/* 11 */ 0040022, /* (PUSHJ GETW) */ +/* 12 */ 0074301, /* (GET CNT WD) */ +/* LOOP 13 */ 0040022, /* (PUSHJ GETW) */ +/* 14 */ 0004220, /* (DEC ADR) */ +/* 15 */ 0025100, /* (CWRITE WD) */ +/* 16 */ 0004320, /* (DEC CNT) */ +/* 17 */ 0133773, /* (BNE LOOP) */ +/* 20 */ 0074023, /* (GET 0 XR) */ +/* 21 */ 0050100, /* (JUMP 100) */ +/* GETW 22 */ 0040025, /* (PUSHJ GETC) */ +/* 23 */ 0040025, /* (PUSHJ GETC) */ +/* 24 */ 0040025, /* (PUSHJ GETC) */ +/* GETC 25 */ 0073320, /* (DIS INTS 2) */ +/* 26 */ 0050025, /* (JUMP GETC) */ +/* 27 */ 0010000, /* (NOP) */ +/* 30 */ 0074424, /* (GET CH UART) */ +/* 31 */ 0001444, /* (ANDI CH CH) */ +/* 32 */ 0000017, /* (17) */ +/* 33 */ 0004114, /* (ROT WD 14) */ +/* 34 */ 0001141, /* (ANDI WD WD) */ +/* 35 */ 0177760, /* (177760) */ +/* 36 */ 0002104, /* (IOR WD CH) */ +/* 37 */ 0076016 /* (POPJ) */ + + +#if 0 + 0010000, /* NOP */ + 0010000, /* NOP */ + 0010000, /* NOP */ + 0040025, /* PUSHJ GETC Call subroutine to read TTY character. */ + 0007001, /* SUBI 0 WD 32-bit instruction computes 147577 - WD */ + 0147577, /* 147577 (The constant "LOGO" is stored here.) */ + 0133774, /* BNE START Branch to START if result Not zero. */ + 0040022, /* PUSHJ GETW Reads 4 characters to make 16-bit word. */ + 0074201, /* GET ADR WD Move word from WD to ADR (register 2). */ + 0040022, /* PUSHJ GETW Get next data word into WD. */ + 0074301, /* GET CNT WD Move it to CNT. */ + 0040022, /* PUSHJ GETW Get another data word. */ + 0004220, /* DEC ADR Decrement the Address and use it to */ + 0025100, /* CWRITE WD write [WD] into control memory. */ + 0004320, /* DEC CNT Decrement the word in CNT (count). */ + 0133773, /* BNE LOOP Branch to LOOP unless CNT is zero. */ + 0074023, /* GET 0 XR Makes PC leave Bootstrap Loader. */ + 0050100, /* JUMP 100 Jump to location 100. */ + 0040025, /* PUSHJ GETC Get 4 bits and shift into WD. */ + 0040025, /* PUSHJ GETC Get 4 more. */ + 0040025, /* PUSHJ GETC Get 4 more. */ + 0073320, /* DIS INTS 2 Skip 2 steps if TTY interrupt active. */ + 0050025, /* JUMP GETC If not, go back and wait. */ + 0010000, /* NOP (Skip over this.) */ + 0074424, /* GET CH UART Put the character into CH. */ + 0001444, /* ANDI CH CH Mask out all but last four bits by */ + 0000017, /* 17 ANDing with 0 000 000 000 001 111. */ + 0004114, /* ROT WD 14 Rotate WD four places right. */ + 0001141, /* ANDI WD WD Zero out last four bits by */ + 0177760, /* 177760 ANDing with 1 111 111 111 110 000. */ + 0002104, /* IOR WD CH Finally, OR them together. */ + 0075600, /* POPJ Return to calling program. */ +#endif +};