From 0eb9b358a95fa30f3daac0ce06a7cc1a81a5c2a1 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 29 May 2007 18:37:13 +0000 Subject: [PATCH 1/1] Adding 1.0.1/2 uncompressed tarballs to tags for historical purposes. --- INSTALL | 52 + Makefile.unix | 58 + Makefile.win32 | 91 + bios/readme.txt | 3 + docs/README | 106 + docs/WHATSNEW | 14 + docs/gpl.txt | 342 ++ eeproms/00000000.eep | Bin 0 -> 128 bytes fix-unix.sh | 21 + src/Jagem.cpp | 338 ++ src/anajoy.cpp | 91 + src/blitter.cpp | 1517 ++++++ src/cdbios.cpp | 840 ++++ src/cdi.cpp | 316 ++ src/cdrom.cpp | 177 + src/clock.cpp | 76 + src/crc32.cpp | 125 + src/dsound_dummy.cpp | 294 ++ src/dsp.cpp | 3227 ++++++++++++ src/eeprom.cpp | 428 ++ src/gpu.cpp | 2522 ++++++++++ src/include/SDLptc.h | 258 + src/include/anajoy.h | 14 + src/include/blit_c.h | 8915 +++++++++++++++++++++++++++++++++ src/include/blit_i.h | 226 + src/include/blitter.h | 19 + src/include/blittertest.h | 0 src/include/cdbios.h | 14 + src/include/cdi.h | 55 + src/include/cdrom.h | 16 + src/include/clock.h | 14 + src/include/crc32.h | 6 + src/include/cry2rgb.h | 74 + src/include/dsnd.h | 20 + src/include/dsp.h | 36 + src/include/eeprom.h | 16 + src/include/fbmpop1.h | 145 + src/include/fbmpop16.h | 146 + src/include/fbmpop16p.h | 131 + src/include/fbmpop1p.h | 170 + src/include/fbmpop2.h | 268 + src/include/fbmpop24.h | 74 + src/include/fbmpop24p.h | 99 + src/include/fbmpop2p.h | 317 ++ src/include/fbmpop4.h | 178 + src/include/fbmpop4p.h | 221 + src/include/fbmpop8.h | 104 + src/include/fbmpop8p.h | 129 + src/include/gpu.h | 38 + src/include/gpuopcodes.h | 0 src/include/harddisk.h | 120 + src/include/ide.h | 16 + src/include/idectrl.h | 24 + src/include/jagdasm.h | 9 + src/include/jaguar.h | 54 + src/include/jerry.h | 27 + src/include/joystick.h | 15 + src/include/log.h | 22 + src/include/m68kdasmAG.h | 1 + src/include/mamegpu.h | 781 +++ src/include/memory.h | 29 + src/include/objectp.h | 20 + src/include/pcm.h | 18 + src/include/tom.h | 67 + src/include/types.h | 42 + src/include/version.h | 23 + src/include/wavetable.h | 258 + src/include/zbmpop1.h | 53 + src/include/zbmpop16.h | 130 + src/include/zbmpop16p.h | 130 + src/include/zbmpop1p.h | 53 + src/include/zbmpop2.h | 150 + src/include/zbmpop24.h | 0 src/include/zbmpop24p.h | 0 src/include/zbmpop2p.h | 150 + src/include/zbmpop4.h | 149 + src/include/zbmpop4p.h | 149 + src/include/zbmpop8.h | 112 + src/include/zbmpop8p.h | 112 + src/jagdasm.cpp | 160 + src/jaguar.cpp | 1022 ++++ src/jerry.cpp | 690 +++ src/joystick.cpp | 268 + src/log.cpp | 22 + src/m68k.h | 346 ++ src/m68k_in.c | 9989 +++++++++++++++++++++++++++++++++++++ src/m68kconf.h | 194 + src/m68kcpu.c | 894 ++++ src/m68kcpu.h | 1838 +++++++ src/m68kdasm.c | 3443 +++++++++++++ src/m68kdasmAG.cpp | 2344 +++++++++ src/m68kmake.c | 1414 ++++++ src/memory.cpp | 184 + src/objectp.cpp | 785 +++ src/pcm.cpp | 236 + src/tom.cpp | 1239 +++++ src/version.cpp | 18 + tools/fix-unix.sh | 21 + 98 files changed, 50162 insertions(+) create mode 100644 INSTALL create mode 100644 Makefile.unix create mode 100644 Makefile.win32 create mode 100644 bios/readme.txt create mode 100644 docs/README create mode 100644 docs/WHATSNEW create mode 100644 docs/gpl.txt create mode 100644 eeproms/00000000.eep create mode 100644 fix-unix.sh create mode 100644 src/Jagem.cpp create mode 100644 src/anajoy.cpp create mode 100644 src/blitter.cpp create mode 100644 src/cdbios.cpp create mode 100644 src/cdi.cpp create mode 100644 src/cdrom.cpp create mode 100644 src/clock.cpp create mode 100644 src/crc32.cpp create mode 100644 src/dsound_dummy.cpp create mode 100644 src/dsp.cpp create mode 100644 src/eeprom.cpp create mode 100644 src/gpu.cpp create mode 100644 src/include/SDLptc.h create mode 100644 src/include/anajoy.h create mode 100644 src/include/blit_c.h create mode 100644 src/include/blit_i.h create mode 100644 src/include/blitter.h create mode 100644 src/include/blittertest.h create mode 100644 src/include/cdbios.h create mode 100644 src/include/cdi.h create mode 100644 src/include/cdrom.h create mode 100644 src/include/clock.h create mode 100644 src/include/crc32.h create mode 100644 src/include/cry2rgb.h create mode 100644 src/include/dsnd.h create mode 100644 src/include/dsp.h create mode 100644 src/include/eeprom.h create mode 100644 src/include/fbmpop1.h create mode 100644 src/include/fbmpop16.h create mode 100644 src/include/fbmpop16p.h create mode 100644 src/include/fbmpop1p.h create mode 100644 src/include/fbmpop2.h create mode 100644 src/include/fbmpop24.h create mode 100644 src/include/fbmpop24p.h create mode 100644 src/include/fbmpop2p.h create mode 100644 src/include/fbmpop4.h create mode 100644 src/include/fbmpop4p.h create mode 100644 src/include/fbmpop8.h create mode 100644 src/include/fbmpop8p.h create mode 100644 src/include/gpu.h create mode 100644 src/include/gpuopcodes.h create mode 100644 src/include/harddisk.h create mode 100644 src/include/ide.h create mode 100644 src/include/idectrl.h create mode 100644 src/include/jagdasm.h create mode 100644 src/include/jaguar.h create mode 100644 src/include/jerry.h create mode 100644 src/include/joystick.h create mode 100644 src/include/log.h create mode 100644 src/include/m68kdasmAG.h create mode 100644 src/include/mamegpu.h create mode 100644 src/include/memory.h create mode 100644 src/include/objectp.h create mode 100644 src/include/pcm.h create mode 100644 src/include/tom.h create mode 100644 src/include/types.h create mode 100644 src/include/version.h create mode 100644 src/include/wavetable.h create mode 100644 src/include/zbmpop1.h create mode 100644 src/include/zbmpop16.h create mode 100644 src/include/zbmpop16p.h create mode 100644 src/include/zbmpop1p.h create mode 100644 src/include/zbmpop2.h create mode 100644 src/include/zbmpop24.h create mode 100644 src/include/zbmpop24p.h create mode 100644 src/include/zbmpop2p.h create mode 100644 src/include/zbmpop4.h create mode 100644 src/include/zbmpop4p.h create mode 100644 src/include/zbmpop8.h create mode 100644 src/include/zbmpop8p.h create mode 100644 src/jagdasm.cpp create mode 100644 src/jaguar.cpp create mode 100644 src/jerry.cpp create mode 100644 src/joystick.cpp create mode 100644 src/log.cpp create mode 100644 src/m68k.h create mode 100644 src/m68k_in.c create mode 100644 src/m68kconf.h create mode 100644 src/m68kcpu.c create mode 100644 src/m68kcpu.h create mode 100644 src/m68kdasm.c create mode 100644 src/m68kdasmAG.cpp create mode 100644 src/m68kmake.c create mode 100644 src/memory.cpp create mode 100644 src/objectp.cpp create mode 100644 src/pcm.cpp create mode 100644 src/tom.cpp create mode 100644 src/version.cpp create mode 100644 tools/fix-unix.sh diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..340239a --- /dev/null +++ b/INSTALL @@ -0,0 +1,52 @@ +Virtual Jaguar v1.0.0 GCC/SDL release INSTALL +--------------------------------------------- + +- Requirements : + +To compile Virtual Jaguar you need to check if you have the minimum +requirements for compiling the sources : + +- GCC v2.95 of v3.x; +- SDL v1.2.5 or higher; +- nasm v0.98.x or higher; +- supported OS (BeOS, Linux, FreeBSD and WIN32 through mingw); + other OS' may work to but you may need to change some items + in the Makefile(s). + +Optionally you need a Atari Jaguar (CD) boot ROM which is available +on the Internet. We can't include the boot ROM since it's still +copyrighted. + +Also, I would recommend that you have at least 20MB of free space. +The .o's can be quite big and the binary is likely to be about a +1.5MB in size (with UPX or strip this could downsize to about 800K). + +- Compiling : + +If you sure you have the minimum software requirements, you can safely +compile Virtual Jaguar v1.0.0 GCC/SDL release by doing the following : + +1) On UN*X systems first do the command : sh ./fix-unix.sh +2) Go to the src/star026c directory and start on of the scripts : + + ./build_s68000.win32 (for WIN32 systems with mingw) + ./build_s68000.unix (for UN*X systems with gcc) + +3) After the generation of the 68000.o file, you can now compile the + program with the following commands : + + make -f Makefile.win32 (for WIN32 systems with mingw) + make -f Makefile.unix (for UN*X systems with gcc) + +4) Optionally you can manually strip jag_em[.exe] to downsize the binary. + + +That's it! You're done! You can now start the emulator with ./jag_em[.exe]. +See the output for more details or consult the docs/README for more info. + +For more info, go to http://sdlemu.ngemu.com or send use an e-mail to the +following e-mail address : sdlemu AT ngemu DOT com. + +SDLEMU + + diff --git a/Makefile.unix b/Makefile.unix new file mode 100644 index 0000000..6f05602 --- /dev/null +++ b/Makefile.unix @@ -0,0 +1,58 @@ +CC = gcc +LD = gcc +NASM = nasm + +CFLAGS = -Wall -O3 -D__PORT__ -D__GCCUNIX__ -DSPEED_CONTROL -Dstricmp="strcasecmp" -fomit-frame-pointer `sdl-config --cflags` + +LDFLAGS = $(CFLAGS) + +TARGET = jag_em + +OBJ = \ + src/version.o \ + src/tom.o \ + src/pcm.o \ + src/objectp.o \ + src/memory.o \ + src/m68kdasm.o \ + src/log.o \ + src/joystick.o \ + src/jerry.o \ + src/jaguar.o \ + src/jagdasm.o \ + src/Jagem.o \ + src/gpu.o \ + src/eeprom.o \ + src/dsp.o \ + src/dsound_dummy.o \ + src/crc32.o \ + src/clock.o \ + src/cdrom.o \ + src/cdi.o \ + src/cdbios.o \ + src/blitter.o \ + src/anajoy.o \ + src/star026c/s68000.o + +LIBS = `sdl-config --libs` -lstdc++ + +all: $(TARGET) + +INCS = -I. `sdl-config --cflags` + +THECC = $(CC) $(CFLAGS) $(INCS) + +%.o: %.asm + $(NASM) -f elf -o $@ $< + +%.o: %.c + $(THECC) -c $< -o $@ + +%.o: %.cpp + $(THECC) -c $< -o $@ + +jag_em: $(OBJ) + $(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) + +clean: + rm -f jag_em *.o src/*.o src/star026c/*.o diff --git a/Makefile.win32 b/Makefile.win32 new file mode 100644 index 0000000..7b1ae9c --- /dev/null +++ b/Makefile.win32 @@ -0,0 +1,91 @@ +CC = gcc +LD = gcc +NASM = nasm + +CFLAGS = -Wall -O3 -D__PORT__ -D__GCCWIN32__ -Dstricmp="strcasecmp" \ + -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES +# -fomit-frame-pointer `sdl-config --cflags` +# -fomit-frame-pointer `sdl-config --cflags` -DTOM_DEBUG + +LDFLAGS = $(CFLAGS) + +TARGET = jag_em + +OBJS = \ + obj/version.o \ + obj/pcm.o \ + obj/objectp.o \ + obj/memory.o \ + obj/m68kdasmAG.o \ + obj/log.o \ + obj/jerry.o \ + obj/jaguar.o \ + obj/jagdasm.o \ + obj/eeprom.o \ + obj/dsound_dummy.o \ + obj/crc32.o \ + obj/clock.o \ + obj/cdrom.o \ + obj/cdi.o \ + obj/cdbios.o \ + obj/blitter.o \ + obj/anajoy.o \ + obj/tom.o \ + obj/joystick.o \ + obj/Jagem.o \ + obj/gpu.o \ + obj/dsp.o \ + obj/m68kcpu.o obj/m68kops.o obj/m68kopac.o obj/m68kopdm.o obj/m68kopnz.o + +LIBS = `sdl-config --libs` -lstdc++ + +INCS = -I. -Isrc -Isrc/include `sdl-config --cflags` + +THECC = $(CC) $(CFLAGS) $(INCS) + +all: obj $(TARGET) + +clean: + rm -rf obj + rm -f jag_em.exe + +obj: + mkdir obj + +obj/%.o: src/%.asm + $(NASM) -f win32 -o $@ $< + +obj/%.o: src/%.c + $(THECC) -c $< -o $@ + +obj/%.o: src/%.cpp + $(THECC) -c $< -o $@ + +jag_em: $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + upx -9 jag_em.exe + +# +# Musashi specific stuffola +# + +obj/m68kcpu.o: obj/m68kops.h src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Iobj -c src/m68kcpu.c -o obj/m68kcpu.o + +obj/m68kops.o: obj/m68kmake.exe obj/m68kops.h obj/m68kops.c src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Isrc -c obj/m68kops.c -o obj/m68kops.o + +obj/m68kopac.o: obj/m68kmake.exe obj/m68kops.h obj/m68kopac.c src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Isrc -c obj/m68kopac.c -o obj/m68kopac.o + +obj/m68kopdm.o: obj/m68kmake.exe obj/m68kops.h obj/m68kopdm.c src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Isrc -c obj/m68kopdm.c -o obj/m68kopdm.o + +obj/m68kopnz.o: obj/m68kmake.exe obj/m68kops.h obj/m68kopnz.c src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Isrc -c obj/m68kopnz.c -o obj/m68kopnz.o + +obj/m68kops.h: obj/m68kmake.exe + obj/m68kmake obj src/m68k_in.c + +obj/m68kmake.exe: src/m68kmake.c src/m68k_in.c + $(CC) $(WARNINGS) src/m68kmake.c -o obj/m68kmake.exe diff --git a/bios/readme.txt b/bios/readme.txt new file mode 100644 index 0000000..3b1d01a --- /dev/null +++ b/bios/readme.txt @@ -0,0 +1,3 @@ +Place the bios here + +jagboot.rom (128 Kb) diff --git a/docs/README b/docs/README new file mode 100644 index 0000000..7865403 --- /dev/null +++ b/docs/README @@ -0,0 +1,106 @@ +Virtual Jaguar v1.0.0 GCC/SDL release README +-------------------------------------------- + +- DISCLAIMER - + +Ported by SDLEMU (Niels Wagenaar & Caz) and is based upon the original work +from Potato Emulation. For requirements please consult the INSTALL file for +more information about supported OS' and software requirements. + +The use of this software is entirely at your own risk. We can't be held +responsible for damage done to you hard- and/or software. This software +requires the use of the Atari Jaguar (CD) boot ROM and/or Commercial ROM +images. You may only use the ROM images if you own the cartridges itself. +The use of Commercial ROM's without owning the original cartridge is +illegal in most countries and could result in fines and/or legal actions. + +This software is released under the GPL license. For more information I +should direct you to the GPL.TXT. You may hack/change the code anyway you +like. You may not commercially sell this software. + +If you make changes, release the sourcecode to the public and send us the +changes you made to the original authors. + +The products and brands used in these documents and/or sourcecode are owned +but the desired company in question. + +- What is Virtual Jaguar GCC/SDL? + +Virtual Jaguar is software dedicated to emulate the Atari Jaguar hardware +on you standard P.C. The software was originally developed by Potato Emulation +(http://potato.emu-france.com) and was released under the GPL license on +25 June 2003. + +Virtual Jaguar GCC/SDL is a port of the MS Visual C++/SDL sourcecode so that +we can enjoy Atari Jaguar emulation on every platform which uses the GCC +compiler and what can make use of the Simple Directmedia Layer library (SDL). + +Currently Virtual Jaguar GCC/SDL compiles on WIN32, using mingw, and several +UN*X based systems (BeOS, Linux and FreeBSD). It may run on other systems +as well but we can not garantee that. + +The port was done by the SDLEMU crew (http://sdlemu.ngemu.com) and especially +by Niels Wagenaar and Caz. You may contact us by e-mail (sdlemu@ngemu.com) or +leave a message on the SDLEMU Official Forum (see the website). + +More information about SDL can be found at http://www.libsdl.org. + +- Using Virtual Jaguar GCC/SDL + +After compiling the binary (see INSTALL) you can now run original Atari Jaguar +games. These games are distributed on cartridges and can there for not be used +on a P.C. To use these games on Virtual Jaguar GCC/SDL you need to get ROM +images. Besides that ROM imgaes from Commercial games you must also obtain the +Atari Jaguar (CD) boot ROM which you must copy to the BIOS directory. +For legal issues concerning ROM images please consult the DISCLAIMER at the +beginning of this file. + +After obaining the Atari Jaguar (CD) boot ROM and several ROM's you can now +use Virtual Jaguar using the following command : + +./jag_em romfile -switch + +The context of ROMFILE is the filename of the UNCOMPRESSED Atari Jaguar ROM +dump. You can also use switches. By just typing ./jag_em you get an overview +of the options you can use. WIN32 users should look into the stdout.txt for +that information. + +If you succesfully start the emulator with the game you should see a window +(or fullscreen) which shows the game. If the game doesn't comply to a CRC +check the game will display a black screen, this means that the game is +probably a hack or a new game which isn't supported. You may add the CRC +check to the sources yourself (src/crc32.cpp). + +This emulator also emulates the Atari Jaguar Analog gamepads. By using the +following keyboard or joystick settings you can (possibly) play the game : + +Atari Button A : Z or joystick button 1 +Atari Button B : X or joystick button 2 +Atari Button C : C or joystick button 3 +Atari Buttons 1 - 10 : Keypad 0 - 9 (0 = 10) +Atari Start/Pause : ENTER +Atari Select : TAB +Atari UP : UP or joystick UP +Atari DOWN : DOWN or joystick DOWN +Atari LEFT : LEFT or joystick LEFT +Atari RIGHT : RIGHT or joystick RIGHT + +With ESC you can easily stop Virtual Jaguar GCC/SDL which will get you back +to you command prompt. If you want to change the key layout, simply hack the +src/joystick.cpp and change the keys :) + +- Finally + +If you find bugs, enhance the code or simply have questions. Drop us an e-mail +at sdlemu AT ngemu DOT com or drop a message on the SDLEMU Official Forum. + +More information about this projects (releases/WIP) can be found at the SDLEMU +website : http://sdlemu.ngemu.com. + +I hope you enjoy the emulator and will use it wisely! + +Special thanks go to guys over at ngemu.com and #ngemu (EFNET). Also the author +who originally developed this emulator is thanked for releasing the sources to +the public. + +SDLEMU diff --git a/docs/WHATSNEW b/docs/WHATSNEW new file mode 100644 index 0000000..2e768ee --- /dev/null +++ b/docs/WHATSNEW @@ -0,0 +1,14 @@ +Virtual Jaguar v1.0.0 GCC/SDL - initial source release +------------------------------------------------------ + +* Converted VC++ assembly to standard GNU assembly; +* Fixed small bugs in SDL related items (keyboard/graphics); +* Added *some* optimalisations to the graphics sources; +* Added joystick support (not tested); +* Added joystick port support (not tested); +* Added frameskip support; + +Source only release. Tested on BeOS, Linux, FreeBSD and WIN32. +SOUND emulation was NOT done. Need help with this one :) + +SDLEMU (Niels Wagenaar & Caz) - http://sdlemu.ngemu.com diff --git a/docs/gpl.txt b/docs/gpl.txt new file mode 100644 index 0000000..1bcc46f --- /dev/null +++ b/docs/gpl.txt @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/eeproms/00000000.eep b/eeproms/00000000.eep new file mode 100644 index 0000000000000000000000000000000000000000..00bc0474794e909101dcb2b0c7c809cfbe2bd665 GIT binary patch literal 128 LcmZQz7+3%R0Du4i literal 0 HcmV?d00001 diff --git a/fix-unix.sh b/fix-unix.sh new file mode 100644 index 0000000..4a1a732 --- /dev/null +++ b/fix-unix.sh @@ -0,0 +1,21 @@ +#! /bin/sh +# +# Sets up the Allegro package for building under Unix, converting text +# files from CR/LF to LF format. + + +echo "Converting NeoPocott files to Unix format..." + +find . -type f "(" \ + -name "*.c*" -o -name "*.cfg" -o \ + -name "*.h" -o -name "*.s" -o \ + -name "*.txt" -o -name "*.asm" -o \ + -name "Makefile*" -o -name "readme.*" \ + ")" \ + -exec sh -c "echo {}; + mv {} _tmpfile; + tr -d \\\r < _tmpfile > {}; + touch -r _tmpfile {}; + rm _tmpfile" \; + +echo "Done!" diff --git a/src/Jagem.cpp b/src/Jagem.cpp new file mode 100644 index 0000000..a5024a5 --- /dev/null +++ b/src/Jagem.cpp @@ -0,0 +1,338 @@ +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef __PORT__ +#include "stdafx.h" +#include +#include +#endif // #ifndef __PORT__ +#include + +/* Added by SDLEMU (http://sdlemu.ngemu.com) */ +/* Added for GCC UNIX compatibility */ +#ifdef __GCCUNIX__ +#include +#endif // #ifdef __GCCUNIX__ + +#include +#include "SDLptc.h" +#include "jaguar.h" + +/* Enable this (uncomment) for speed control */ +//#define SPEED_CONTROL + +Surface * surface; +Format format(16, 0x007C00, 0x00003E0, 0x0000001F); +uint8 finished = 0; +Console console; + +int fullscreen = 0; +char * jaguar_boot_dir; + +void main_screen_switch(void) +{ + fullscreen = !fullscreen; + if (fullscreen) + console.option("fullscreen output"); + else + console.option("windowed output"); + console.close(); + console.open("WIP VERSION", tom_width, tom_height, format); +} + +#ifdef __PORT__ + +/* Added/changed by SDLEMU http://sdlemu.ngemu.com */ + +int main(int argc, char * argv[]) +{ + uint32 startTime, totalFrames;//, endTime;//, w, h; +// int32 * vs; + uint32 nNormalLast = 0; + int32 nNormalFrac = 0; +// int32 i = 0; +//unused int32 nTime = 0; +//unused int32 nCount = 0; + int32 nFrameskip = 1; // Frameskip + int32 nFrame = 0; // No. of Frame + int32 nJoyport = 0; // Joystick port + + printf("Virtual Jaguar/SDL v1.0.1 (GCC/SDL Port)\n"); + printf("Based upon Virtual Jaguar core v1.0.0 by Potato emulation.\n"); + printf("Written by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)\n"); + printf("Portions massaged by James L. Hammons (WIN32)\n"); + printf("Contact : http://sdlemu.ngemu.com/ | sdlemu@ngemu.com\n"); + + if (argc <= 1) + { + printf("Usage : \n\n"); + printf("jag_em [switches] ]\n"); + printf(" -fullscreen : Enable fullscreen mode \n"); + printf(" -window : Enable windowed mode (default) \n"); + printf(" -frameskip 1-10 : Enable frameskip 1 (default) - 10\n"); + printf(" -joystick : Enable joystick/gamepad \n"); + printf(" -joyport 0-3 : Select desired joystick port \n"); + return true; + } + + jaguar_boot_dir = (char *)malloc(1024); + getcwd(jaguar_boot_dir, 1024); + + log_init("jag_em.log"); + + memory_init(); + version_init(); + version_display(log_get()); + jaguar_init(argv[1]); + jaguar_reset(); + + /* Setting up the backbuffer */ + int16 * backbuffer = (int16 *)malloc(845 * 525 * sizeof(int16)); + memset(backbuffer, 0xAA, tom_getVideoModeWidth() * tom_getVideoModeHeight() * sizeof(int16)); + + /* Setting up the primary SDL display */ +//Already defined! Format format(16, 0x007C00, 0x00003E0, 0x0000001F); + surface = new Surface(tom_getVideoModeWidth(), tom_getVideoModeHeight(), format); + console.option("windowed output"); + + /* Checking the switches ;) */ + for(int i=0; (i 3) + nJoyport = 3; + } + + if (!strcmp(argv[i], "-frameskip")) + { + nFrameskip = atoi(argv[++i]) + 1; + if (nFrameskip > 10) + nFrameskip = 10; + #ifdef SPEED_CONTROL + nFrameskip = 0; + #endif + } + } + + /* Initialize Joystick support under SDL */ + if (console.JoyEnabled() == 1) + { + if (SDL_NumJoysticks() <= 0) + { + console.option("joystick disabled"); + printf("No joystick(s) or joypad(s) detected on your system. Using keyboards....\n"); + } + else + { + if ((console.joystick = SDL_JoystickOpen(nJoyport)) == 0) + { + console.option("joystick disabled"); + printf("Unable to open a Joystick on port : %d\n", (int)nJoyport); + } + else + printf("Using: %s\n", SDL_JoystickName(nJoyport)); + } + } + + /* Open the display and start emulating some l337 Atari Jaguar games :P */ + console.open("Virtual Jaguar", tom_getVideoModeWidth(), tom_getVideoModeHeight(), format); + + totalFrames = 0; + startTime = clock(); + nNormalLast = 0; // Last value of timeGetTime() + nNormalFrac = 0; // Extra fraction we did + nNormalLast = SDL_GetTicks(); //timeGetTime(); + + while (!finished) + { +#ifdef SPEED_CONTROL + nTime = SDL_GetTicks() - nNormalLast; // calcule le temps écoulé depuis le dernier affichage + // nTime est en mili-secondes. + // détermine le nombre de trames à passer + 1 + nCount = (nTime * 600 - nNormalFrac) / 10000; + + // si le nombre de trames à passer + 1 est nul ou négatif, + // ne rien faire pendant 2 ms + if (nCount <= 0) + { + //Sleep(2); + //SDL_Delay(1); + } // No need to do anything for a bit + else + { + nNormalFrac += nCount * 10000; // + nNormalLast += nNormalFrac / 600; // add the duration of nNormalFrac frames + nNormalFrac %= 600; // + + // Pas plus de 9 (10-1) trames non affichées + if (nCount > 10) + nCount = 10; + for(int i=0; ilock(); + memcpy(vs, backbuffer, tom_width * tom_height * 2); + surface->unlock(); + surface->copy(console); + console.update(); + nFrame = 0; + } + else + nFrame++; + + joystick_exec(); + +#ifdef SPEED_CONTROL + } +#endif + } + + int elapsedTime = clock() - startTime; + int fps = (1000 * totalFrames) / elapsedTime; + fprintf(log_get(), "Statistics: %i fps\n", fps); + + if (console.JoyEnabled() == 1) {} + +// fprintf(log_get(), "--> About to do jaguar_done...\n"); + jaguar_done(); + version_done(); + memory_done(); + log_done(); + console.close(); // Close SDL items as last! + return 0; +} + +#else + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + uint32 startTime, endTime, totalFrames; + unsigned int nNormalLast=0; + int nNormalFrac=0; + int nTime=0,nCount=0; int i=0; + + jaguar_boot_dir=(char*)malloc(1024); + _getcwd(jaguar_boot_dir,1024); + + log_init("jagem.log"); + // 15 bits RGB555 + SDL_Event app_input_event; + + memory_init(); + version_init(); + version_display(log_get()); + jaguar_init(); + jaguar_reset(); + + + int16 * backbuffer = (int16 *)malloc(845 * 525 * sizeof(int16)); + memset(backbuffer, 0xAA, tom_getVideoModeWidth() * tom_getVideoModeHeight() * sizeof(int16)); + surface=new Surface(tom_getVideoModeWidth(),tom_getVideoModeHeight(),format); + console.option("DirectX"); + console.option("windowed output"); +// console.option("fullscreen output"); + console.option("center window"); + console.open("WIP VERSION",tom_getVideoModeWidth(),tom_getVideoModeHeight(),format); + uint32 surfacePitch=(surface->pitch()>>1); + + totalFrames=0; + startTime=clock(); + nNormalLast=0;// Last value of timeGetTime() + nNormalFrac=0; // Extra fraction we did + nNormalLast=timeGetTime(); + while (!finished) + { + while ( SDL_PollEvent(&app_input_event) ) + { + if ( app_input_event.type == SDL_QUIT ) + { + finished = 1; + } + } + joystick_exec(); +#define SPEED_CONTROL +#ifdef SPEED_CONTROL + nTime=timeGetTime()-nNormalLast; // calcule le temps écoulé depuis le dernier affichage + // nTime est en mili-secondes. + // détermine le nombre de trames à passer + 1 + nCount=(nTime*600 - nNormalFrac) /10000; + + // si le nombre de trames à passer + 1 est nul ou négatif, + // ne rien faire pendant 2 ms + if (nCount<=0) + { + Sleep(2); + } // No need to do anything for a bit + else + { + nNormalFrac+=nCount*10000; // + nNormalLast+=nNormalFrac/600; // add the duration of nNormalFrac frames + nNormalFrac%=600; // + + // Pas plus de 9 (10-1) trames non affichées + if (nCount>10) + nCount=10; + for (i=0;ilock(); + uint32 w,h; + w=tom_width; + h=tom_height; + + memcpy(vs,backbuffer,w*h*2); + surface->unlock(); + surface->copy(console); + + console.update(); +#ifdef SPEED_CONTROL + } +#endif + } + int elapsedTime=clock()-startTime; + int fps=(1000*totalFrames)/elapsedTime; + fprintf(log_get(),"statistics: %i fps\n",fps); + + console.close(); + + jaguar_done(); + version_done(); + memory_done(); + log_done(); + return 0; + +} + +#endif + diff --git a/src/anajoy.cpp b/src/anajoy.cpp new file mode 100644 index 0000000..8994271 --- /dev/null +++ b/src/anajoy.cpp @@ -0,0 +1,91 @@ +#include "jaguar.h" + +static uint8 anajoy_ram[2]; +static uint8 analog_x, analog_y; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void anajoy_init(void) +{ + anajoy_reset(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void anajoy_reset(void) +{ + memset(anajoy_ram,0x00,2); + analog_x=128; + analog_y=128; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void anajoy_done(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void anajoy_byte_write(uint32 offset, uint8 data) +{ + anajoy_ram[offset&0x01]=data; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void anajoy_word_write(uint32 offset, uint16 data) +{ + offset&=0x01; + anajoy_ram[offset+0]=(data>>8)&0xff; + anajoy_ram[offset+1]=data&0xff; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 anajoy_byte_read(uint32 offset) +{ + if (anajoy_ram[1]&0x01) + return(analog_y); + else + return(analog_x); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 anajoy_word_read(uint32 offset) +{ + uint16 data=anajoy_byte_read((offset+0)&0x01); + data<<=8; + data|=anajoy_byte_read((offset+1)&0x01); + return(data); +} diff --git a/src/blitter.cpp b/src/blitter.cpp new file mode 100644 index 0000000..cbe8456 --- /dev/null +++ b/src/blitter.cpp @@ -0,0 +1,1517 @@ +#define GEN_CODE +//#define LOG_BLITS +//#define USE_GENERIC_BLITTER + +#include "jaguar.h" + +#define null 0 +extern int jaguar_active_memory_dumps; + +#define REG(A) blitter_reg_read(A) +#define WREG(A,D) blitter_reg_write(A,D) + +int start_logging = 0; + +static uint8 blitter_ram[0x100]; + +#define A1_BASE ((UINT32)0x00) +#define A1_FLAGS ((UINT32)0x04) +#define A1_CLIP ((UINT32)0x08) // height and width values for clipping +#define A1_PIXEL ((UINT32)0x0c) // integer part of the pixel (Y.i and X.i) +#define A1_STEP ((UINT32)0x10) // integer part of the step +#define A1_FSTEP ((UINT32)0x14) // fractionnal part of the step +#define A1_FPIXEL ((UINT32)0x18) // fractionnal part of the pixel (Y.f and X.f) +#define A1_INC ((UINT32)0x1C) // integer part of the increment +#define A1_FINC ((UINT32)0x20) // fractionnal part of the increment +#define A2_BASE ((UINT32)0x24) +#define A2_FLAGS ((UINT32)0x28) +#define A2_MASK ((UINT32)0x2c) // modulo values for x and y (M.y and M.x) +#define A2_PIXEL ((UINT32)0x30) // integer part of the pixel (no fractionnal part for A2) +#define A2_STEP ((UINT32)0x34) // integer part of the step (no fractionnal part for A2) +#define COMMAND ((UINT32)0x38) +#define PIXLINECOUNTER ((UINT32)0x3C) +#define SRCDATA ((UINT32)0x40) +#define DSTDATA ((UINT32)0x48) +#define DSTZ ((UINT32)0x50) +#define SRCZINT ((UINT32)0x58) +#define SRCZFRAC ((UINT32)0x60) +#define PATTERNDATA ((UINT32)0x68) +#define INTENSITYINC ((UINT32)0x70) +#define ZINC ((UINT32)0x74) +#define COLLISIONCTRL ((UINT32)0x78) +#define PHRASEINT3 ((UINT32)0x7C) +#define PHRASEINT2 ((UINT32)0x80) +#define PHRASEINT1 ((UINT32)0x84) +#define PHRASEINT0 ((UINT32)0x88) +#define PHRASEZ3 ((UINT32)0x8C) +#define PHRASEZ2 ((UINT32)0x90) +#define PHRASEZ1 ((UINT32)0x94) +#define PHRASEZ0 ((UINT32)0x98) + +#define SRCEN (cmd&0x00000001) +#define SRCENZ (cmd&0x00000002) +#define SRCENX (cmd&0x00000004) +#define DSTEN (cmd&0x00000008) +#define DSTENZ (cmd&0x00000010) +#define DSTWRZ (cmd&0x00000020) +#define CLIPA1 (cmd&0x00000040) +#define DSTA2 (cmd&0x00000800) + +#define Z_OP_INF (cmd&0x00040000) +#define Z_OP_EQU (cmd&0x00080000) +#define Z_OP_SUP (cmd&0x00100000) + +#define CMPDST (cmd&0x02000000) +#define BCOMPEN (cmd&0x04000000) +#define DCOMPEN (cmd&0x08000000) + +#define LFU_NAN (cmd&0x00200000) +#define LFU_NA (cmd&0x00400000) +#define LFU_AN (cmd&0x00800000) +#define LFU_A (cmd&0x01000000) + +#define PATDSEL (cmd&0x00010000) +#define INTADD (cmd&0x00020000) +#define TOPBEN (cmd&0x00004000) +#define TOPNEN (cmd&0x00008000) +#define BKGWREN (cmd&0x10000000) +#define GOURD (cmd&0x00001000) +#define GOURZ (cmd&0x00002000) +#define SRCSHADE (cmd&0x40000000) + + +#define XADDPHR 0 +#define XADDPIX 1 +#define XADD0 2 +#define XADDINC 3 + +#define XSIGNSUB_A1 (REG(A1_FLAGS)&0x80000) +#define XSIGNSUB_A2 (REG(A2_FLAGS)&0x80000) + +#define YSIGNSUB_A1 (REG(A1_FLAGS)&0x100000) +#define YSIGNSUB_A2 (REG(A2_FLAGS)&0x100000) + +#define YADD1_A1 (REG(A1_FLAGS)&0x40000) +#define YADD1_A2 (REG(A2_FLAGS)&0x40000) + +// 1 bpp pixel read +#define PIXEL_SHIFT_1(a) (((~a##_x) >> 16) & 7) +#define PIXEL_OFFSET_1(a) (((((UINT32)a##_y >> 16) * a##_width / 8) + (((UINT32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 19) & 7)) +#define READ_PIXEL_1(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01) + +// 2 bpp pixel read +#define PIXEL_SHIFT_2(a) (((~a##_x) >> 15) & 6) +#define PIXEL_OFFSET_2(a) (((((UINT32)a##_y >> 16) * a##_width / 4) + (((UINT32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 18) & 7)) +#define READ_PIXEL_2(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03) + +// 4 bpp pixel read +#define PIXEL_SHIFT_4(a) (((~a##_x) >> 14) & 4) +#define PIXEL_OFFSET_4(a) (((((UINT32)a##_y >> 16) * (a##_width/2)) + (((UINT32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 17) & 7)) +#define READ_PIXEL_4(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f) + +// 8 bpp pixel read +#define PIXEL_OFFSET_8(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7)) +#define READ_PIXEL_8(a) (jaguar_byte_read(a##_addr+PIXEL_OFFSET_8(a))) + +// 16 bpp pixel read +#define PIXEL_OFFSET_16(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3)) +#define READ_PIXEL_16(a) (jaguar_word_read(a##_addr+(PIXEL_OFFSET_16(a)<<1))) + +// 32 bpp pixel read +#define PIXEL_OFFSET_32(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) +#define READ_PIXEL_32(a) (jaguar_long_read(a##_addr+(PIXEL_OFFSET_32(a)<<2))) + +// pixel read +#define READ_PIXEL(a,f) (\ + (((f>>3)&0x07) == 0) ? (READ_PIXEL_1(a)) : \ + (((f>>3)&0x07) == 1) ? (READ_PIXEL_2(a)) : \ + (((f>>3)&0x07) == 2) ? (READ_PIXEL_4(a)) : \ + (((f>>3)&0x07) == 3) ? (READ_PIXEL_8(a)) : \ + (((f>>3)&0x07) == 4) ? (READ_PIXEL_16(a)) : \ + (((f>>3)&0x07) == 5) ? (READ_PIXEL_32(a)) : 0) + +// 16 bpp z data read +#define ZDATA_OFFSET_16(a) (PIXEL_OFFSET_16(a) + a##_zoffs * 4) +#define READ_ZDATA_16(a) (jaguar_word_read(a##_addr+(ZDATA_OFFSET_16(a)<<1))) + +// z data read +#define READ_ZDATA(a,f) (READ_ZDATA_16(a)) + +// 16 bpp z data write +#define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); } + +// z data write +#define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); + +// 1 bpp r data read +#define READ_RDATA_1(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>19)&4)))>>(((UINT32)a##_x>>16)&0x1f))& 0x1 : (REG(r) & 0x1)) + +// 2 bpp r data read +#define READ_RDATA_2(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>18)&4)))>>(((UINT32)a##_x>>15)&0x3e))& 0x3 : (REG(r) & 0x3)) + +// 4 bpp r data read +#define READ_RDATA_4(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>17)&4)))>>(((UINT32)a##_x>>14)&0x28))& 0xf : (REG(r) & 0xf)) + +// 8 bpp r data read +#define READ_RDATA_8(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>16)&4)))>>(((UINT32)a##_x>>13)&0x18))& 0xff : (REG(r) & 0xff)) + +// 16 bpp r data read +#define READ_RDATA_16(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>15)&4)))>>(((UINT32)a##_x>>12)&0x10))&0xffff : (REG(r) & 0xffff)) + +// 32 bpp r data read +#define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r)) + + +// register data read +#define READ_RDATA(r,a,f,p) (\ + (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \ + (((f>>3)&0x07) == 1) ? (READ_RDATA_2(r,a,p)) : \ + (((f>>3)&0x07) == 2) ? (READ_RDATA_4(r,a,p)) : \ + (((f>>3)&0x07) == 3) ? (READ_RDATA_8(r,a,p)) : \ + (((f>>3)&0x07) == 4) ? (READ_RDATA_16(r,a,p)) : \ + (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0) + +// 1 bpp pixel write +#define WRITE_PIXEL_1(a,d) { jaguar_byte_write(a##_addr+PIXEL_OFFSET_1(a),(jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a))&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<>3)&0x07) { \ + case 0: WRITE_PIXEL_1(a,d); break; \ + case 1: WRITE_PIXEL_2(a,d); break; \ + case 2: WRITE_PIXEL_4(a,d); break; \ + case 3: WRITE_PIXEL_8(a,d); break; \ + case 4: WRITE_PIXEL_16(a,d); break; \ + case 5: WRITE_PIXEL_32(a,d); break; \ + }} \ + + + +// Width in Pixels of a Scanline +static uint32 blitter_scanline_width[48] = +{ + 0, 0, 0, 0, 2, 0, 0, 0, 4, + 0, 6, 0, 8, 10, 12, 14, 16, 20, + 24, 28, 32, 40, 48, 56, 64, 80, 96, + 112, 128, 160, 192, 224, 256, 320, 384, 448, + 512, 640, 768, 896, 1024, 1280, 1536, 1792, 2048, + 2560, 3072, 3584 +}; + +static uint8 * tom_ram_8; +static uint8 * paletteRam; +static uint8 src; +static uint8 dst; +static uint8 misc; +static uint8 a1ctl; +static uint8 mode; +static uint8 ity; +static uint8 zop; +static uint8 op; +static uint8 ctrl; +static uint32 a1_addr; +static uint32 a2_addr; +static int32 a1_zoffs; +static int32 a2_zoffs; +static uint32 xadd_a1_control; +static uint32 xadd_a2_control; +static int32 a1_pitch; +static int32 a2_pitch; +static uint32 n_pixels; +static uint32 n_lines; +static int32 a1_x; +static int32 a1_y; +static int32 a1_width; +static int32 a2_x; +static int32 a2_y; +static int32 a2_width; +static int32 a2_mask_x; +static int32 a2_mask_y; +static int32 a1_xadd; +static int32 a1_yadd; +static int32 a2_xadd; +static int32 a2_yadd; +static uint8 a1_phrase_mode; +static uint8 a2_phrase_mode; +static int32 a1_step_x=0; +static int32 a1_step_y=0; +static int32 a2_step_x=0; +static int32 a2_step_y=0; +static uint32 outer_loop; +static uint32 inner_loop; +static uint32 a2_psize; +static uint32 a1_psize; +static uint32 gouraud_add; +static uint32 gouraud_data; +static uint16 gint[4]; +static uint16 gfrac[4]; +static uint8 gcolour[4]; +static int gd_i[4]; +static int gd_c[4]; +static int gd_ia,gd_ca; +static int colour_index = 0; +static int32 zadd; +static uint32 z_i[4]; + +static uint8 blitter_code_cache[4096]; +static uint8 * blitter_ptr; +uint8 blitter_working = 0; + +typedef void (blitter_fn)(void); + +typedef struct s_blitter_cache +{ + uint32 hashcode; + uint8 *code; + uint32 ready; + uint8 used; + struct s_blitter_cache *next; + struct s_blitter_cache *prev; +} s_blitter_code_cache; + +s_blitter_cache *blitter_cache[256]; + +uint8 blitter_cache_init=0; +static uint8 BPP_LUT[8]={1,2,4,8,16,32,0,0}; + +FILE *blitters_code_fp; +FILE *blitters_code_init_fp; + +////////////////////////////////////////////////////////////////////////////// +// build C code for the specified blitter +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode) +{ + static uint8 inhibit_modified=0; + + fprintf(fp,"#ifndef blitter_code_0x%.8x\n",hashcode); + fprintf(fp,"#define blitter_code_0x%.8x\n",hashcode); + + fprintf(fp,"void blitter_0x%.8x(void)\n",hashcode); + fprintf(fp,"{\n"); + fprintf(fp,"\twhile (outer_loop--)\n"); + fprintf(fp,"\t{\n"); + fprintf(fp,"\t\tinner_loop=n_pixels;\n"); + fprintf(fp,"\t\twhile (inner_loop--)\n"); + fprintf(fp,"\t\t{\n"); + fprintf(fp,"\t\t\tuint32 srcdata = 0;\n"); + fprintf(fp,"\t\t\tuint32 srczdata = 0;\n"); + fprintf(fp,"\t\t\tuint32 dstdata = 0;\n"); + fprintf(fp,"\t\t\tuint32 dstzdata = 0;\n"); + fprintf(fp,"\t\t\tuint32 writedata = 0;\n"); + fprintf(fp,"\t\t\tuint32 inhibit = 0;\n"); + + char *src; + char *dst; + uint32 src_flags; + uint32 dst_flags; + + if (!DSTA2) + { + src="a2"; + dst="a1"; + src_flags=A2_FLAGS; + dst_flags=A1_FLAGS; + } + else + { + src="a1"; + dst="a2"; + src_flags=A1_FLAGS; + dst_flags=A2_FLAGS; + } + + // load src data and Z + if (SRCEN) + { + fprintf(fp,"\t\t\tsrcdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src); + if (SRCENZ) + fprintf(fp,"\t\t\tsrczdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src); + else + if (cmd & 0x001c020) + fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(src_flags))>>3)&0x07)],src,src); + } + else + { + fprintf(fp,"\t\t\tsrcdata = READ_RDATA_%i(SRCDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); + if (cmd & 0x001c020) + fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); + } + + // load dst data and Z + if (DSTEN) + { + fprintf(fp,"\t\t\tdstdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + if (DSTENZ) + fprintf(fp,"\t\t\tdstzdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + else + fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); + } + else + { + fprintf(fp,"\t\t\tdstdata = READ_RDATA_%i(DSTDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); + + if (DSTENZ) + fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); + } + + // a1 clipping + if ((cmd & 0x00000040)&&(!DSTA2)) + + { + fprintf(fp,"\t\t\tif (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1;\n"); + inhibit_modified=1; + } + if(GOURZ) + { + fprintf(fp,"\t\t\tsrczdata=z_i[colour_index]>>16;\n"); + } + // apply z comparator + if (Z_OP_INF) { fprintf(fp,"\t\t\tif (srczdata < dstzdata) inhibit = 1;\n"); inhibit_modified=1;} + if (Z_OP_EQU) { fprintf(fp,"\t\t\tif (srczdata == dstzdata) inhibit = 1;\n"); inhibit_modified=1;} + if (Z_OP_SUP) { fprintf(fp,"\t\t\tif (srczdata > dstzdata) inhibit = 1;\n"); inhibit_modified=1;} + + // apply data comparator + if (DCOMPEN) + { + if (!CMPDST) + { + // compare source pixel with pattern pixel + fprintf(fp,"\t\t\tif (srcdata == READ_RDATA_%i(PATTERNDATA, %s,%s_phrase_mode)) inhibit=1;\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); + inhibit_modified=1; + } + else + { + // compare destination pixel with pattern pixel + fprintf(fp,"\t\t\tif (dstdata == READ_RDATA_%i(PATTERNDATA, %s,%s_phrase_mode)) inhibit=1;\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); + inhibit_modified=1; + } + } + + // compute the write data and store + if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n"); + if (PATDSEL) + { + // use pattern data for write data + fprintf(fp,"\t\t\t\twritedata= READ_RDATA_%i(PATTERNDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); + } + else + if (INTADD) + { + // intensity addition + fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xff) + (dstdata & 0xff);\n"); + if (!(TOPBEN)) + fprintf(fp,"\t\t\t\tif (writedata > 0xff) writedata = 0xff;\n"); + + fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf00) + (dstdata & 0xf00);\n"); + if (!(TOPNEN)) fprintf(fp,"\t\t\t\tif (writedata > 0xfff) writedata = 0xfff;\n"); + fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf000) + (dstdata & 0xf000);\n"); + } + else + { + if (LFU_NAN) fprintf(fp,"\t\t\t\twritedata |= ~srcdata & ~dstdata;\n"); + if (LFU_NA) fprintf(fp,"\t\t\t\twritedata |= ~srcdata & dstdata;\n"); + if (LFU_AN) fprintf(fp,"\t\t\t\twritedata |= srcdata & ~dstdata;\n"); + if (LFU_A) fprintf(fp,"\t\t\t\twritedata |= srcdata & dstdata;\n"); + } + if(GOURD) + { + fprintf(fp,"\t\t\t\twritedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);\n"); + } + if(SRCSHADE) + { + fprintf(fp,"\t\t\t\t{\n"); + fprintf(fp,"\t\t\t\tint intensity = srcdata & 0xFF;\n"); + fprintf(fp,"\t\t\t\tint ia = gd_ia >> 16;\n"); + fprintf(fp,"\t\t\t\tif(ia & 0x80)\n"); + fprintf(fp,"\t\t\t\t ia = 0xFFFFFF00 | ia;\n"); + fprintf(fp,"\t\t\t\tintensity += ia;\n"); + fprintf(fp,"\t\t\t\tif(intensity < 0)\n"); + fprintf(fp,"\t\t\t\t intensity = 0;\n"); + fprintf(fp,"\t\t\t\tif(intensity > 0xFF)\n"); + fprintf(fp,"\t\t\t\t intensity = 0xFF;\n"); + fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xFF00) | intensity;\n"); + fprintf(fp,"\t\t\t\t}\n"); + } + if (inhibit_modified) + { + fprintf(fp,"\t\t\t} else { srczdata=dstzdata; writedata=dstdata; }\n"); + } + + if ((DSTA2?a2_phrase_mode:a1_phrase_mode) || BKGWREN) + { + // write to the destination + fprintf(fp,"\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + if (DSTWRZ) fprintf(fp,"\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + } + else + { + if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n"); + // write to the destination + fprintf(fp,"\t\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + if (DSTWRZ) fprintf(fp,"\t\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); + if (inhibit_modified) fprintf(fp,"\t\t\t}\n"); + } + // update x and y + fprintf(fp,"\t\t\ta1_x += a1_xadd;\n"); + fprintf(fp,"\t\t\ta1_y += a1_yadd;\n"); + fprintf(fp,"\t\t\ta2_x = (a2_x + a2_xadd) & a2_mask_x;\n"); + fprintf(fp,"\t\t\ta2_y = (a2_y + a2_yadd) & a2_mask_y;\n"); + if (GOURZ) + { + fprintf(fp,"\t\t\tz_i[colour_index]+=zadd;\n"); + } + if ((GOURD)||(SRCSHADE)) + { + fprintf(fp,"\t\t\tgd_i[colour_index] += gd_ia;\n"); + fprintf(fp,"\t\t\tgd_c[colour_index] += gd_ca;\n"); + } + if ((GOURD)||(SRCSHADE)||(GOURZ)) + { + if (a1_phrase_mode) + fprintf(fp,"\t\t\t colour_index=(colour_index+1)&0x3;\n"); + } + fprintf(fp,"\t\t}\n"); + + fprintf(fp,"\t\ta1_x+=a1_step_x;\n"); + fprintf(fp,"\t\ta1_y+=a1_step_y;\n"); + fprintf(fp,"\t\ta2_x+=a2_step_x;\n"); + fprintf(fp,"\t\ta2_y+=a2_step_y;\n"); + fprintf(fp,"\t}\n"); + + // write values back to registers + fprintf(fp,"\tWREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff));\n"); + fprintf(fp,"\tWREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff));\n"); + fprintf(fp,"\tWREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff));\n"); + fprintf(fp,"}\n"); + fprintf(fp,"#endif\n"); +} + +////////////////////////////////////////////////////////////////////////////// +// Generate a start of function in x86 assembly +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_gen_start_of_function(void) +{ + *blitter_ptr++=0x55; // push ebp + *blitter_ptr++=0x8b; // mov ebp,esp + *blitter_ptr++=0xec; +} +////////////////////////////////////////////////////////////////////////////// +// Generate a end of function in x86 assembly +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_gen_end_of_function(void) +{ + *blitter_ptr++=0x8B; // mov esp,ebp + *blitter_ptr++=0xE5; + *blitter_ptr++=0x5D; // pop ebp + *blitter_ptr++=0xC3; // ret +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#define HASHCODE_BIT(C,B) if (C) hashcode|=(1<>3)&0x07)<<0; + hashcode|=((REG(A2_FLAGS)>>3)&0x07)<<3; + + HASHCODE_BIT(DSTA2, 6); + HASHCODE_BIT(SRCEN, 7); + HASHCODE_BIT(SRCENZ, 8); + HASHCODE_BIT(DSTEN, 9); + HASHCODE_BIT(DSTENZ, 10); + HASHCODE_BIT(Z_OP_INF, 11); + HASHCODE_BIT(Z_OP_EQU, 12); + HASHCODE_BIT(Z_OP_SUP, 13); + HASHCODE_BIT(DCOMPEN, 14); + HASHCODE_BIT(CMPDST, 15); + HASHCODE_BIT(PATDSEL, 16); + HASHCODE_BIT(INTADD, 17); + HASHCODE_BIT(TOPBEN, 18); + HASHCODE_BIT(TOPNEN, 19); + HASHCODE_BIT(LFU_NAN, 20); + HASHCODE_BIT(LFU_NA, 21); + HASHCODE_BIT(LFU_AN, 22); + HASHCODE_BIT(LFU_A, 23); + HASHCODE_BIT(BKGWREN, 24); + HASHCODE_BIT(DSTWRZ, 25); + HASHCODE_BIT((cmd & 0x001c020), 26); // extra data read/write + HASHCODE_BIT((cmd & 0x00000040), 27); // source clipping + HASHCODE_BIT(a1_phrase_mode, 28); + HASHCODE_BIT(a2_phrase_mode, 29); + + + return(hashcode); +} +////////////////////////////////////////////////////////////////////////////// +// Build the blitter code for the current blitter operation in the cache +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_build_cached_code(uint32 cmd, uint32 cache_index) +{ +} +////////////////////////////////////////////////////////////////////////////// +// Check if the blitter code for the current blitter operation is cached +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +struct s_blitter_cache * blitter_in_cache(uint32 cmd) +{ + uint32 i; + uint32 hashcode=blitter_calc_hashcode(cmd); +#ifdef LOG_BLITS + fprintf(log_get(),"blitter: hashcode= 0x%.8x\n",hashcode); +#endif + struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24]; + + i=0; + while (blitter_list->next) + { + blitter_list=blitter_list->next; + + if (blitter_list->hashcode==hashcode) + return(blitter_list); + } +#ifdef GEN_CODE + blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); + blitter_list->next->prev=blitter_list; + blitter_list->next->next=null; + blitter_list=blitter_list->next; + + blitter_list->code=(uint8*)malloc(4096); + blitter_list->hashcode=hashcode; + blitter_list->ready=0; + blitter_gen_c_code(blitters_code_fp,cmd,hashcode); + fprintf(blitters_code_init_fp,"\tblitter_add(0x%.8x,(uint8*)&blitter_0x%.8x);\n",hashcode,hashcode); +#else + //fprintf(log_get(),"warning: using generic blitter for blitter 0x%.8x\n",hashcode); +#endif + return(null); +} +#ifndef USE_GENERIC_BLITTER +#include "include/blit_c.h" +#endif +////////////////////////////////////////////////////////////////////////////// +// Execute the cached blitter code for the current blitter operation +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint32 blitter_execute_cached_code(struct s_blitter_cache *blitter) +{ + if ((blitter==null)||(blitter->ready==0)) + return 0; + + blitter_fn *fn=(blitter_fn*)blitter->code; + blitter->used=1; + (*fn)(); + + return(1); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_add(uint32 hashcode, uint8 *code) +{ + struct s_blitter_cache *blitter_list=blitter_cache[(hashcode>>24)]; + +// fprintf(log_get(),"adding blitter for hashcode 0x%.8x\n",hashcode); + + while (blitter_list->next) + { + blitter_list=blitter_list->next; + + if (blitter_list->hashcode==hashcode) + return; + } + blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); + blitter_list->next->prev=blitter_list; + blitter_list->next->next=null; + blitter_list=blitter_list->next; + + blitter_list->code=code; + blitter_list->hashcode=hashcode; + blitter_list->ready=1; + blitter_list->used=0; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_list(void) +{ +/* + fprintf(log_get(),"Used blitters list:\n"); + + for (int i=0;i<256;i++) + { + struct s_blitter_cache *blitter_list=blitter_cache[i]; + + while (blitter_list->next) + { + blitter_list=blitter_list->next; + if (blitter_list->used) + fprintf(log_get(),"\t0%.8x\n",blitter_list->hashcode); + } + } +*/ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_generic(uint32 cmd) +{ + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + srcdata = 0; + srczdata = 0; + dstdata = 0; + dstzdata = 0; + writedata = 0; + inhibit = 0; + + if (!DSTA2) + { + // load src data and Z + if (SRCEN) + { + srcdata = READ_PIXEL(a2, REG(A2_FLAGS)); + if (SRCENZ) + { + srczdata = READ_ZDATA(a2, REG(A2_FLAGS)); + } + else + if (cmd & 0x001c020) + { + srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); + } + } + else + { + srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode); + if (cmd & 0x001c020) + { + srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); + } + } + + // load dst data and Z + if (DSTEN) + { + dstdata = READ_PIXEL(a1, REG(A1_FLAGS)); + if (DSTENZ) + { + dstzdata = READ_ZDATA(a1, REG(A1_FLAGS)); + } + else + { + dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode); + } + } + else + { + dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode); + + if (DSTENZ) + { + dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode); + } + } + + // a1 clipping + if (cmd & 0x00000040) + { + if ( + a1_x < 0 || + a1_y < 0 || + (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || + (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff) + ) + inhibit = 1; + } + + if(GOURZ) + srczdata=z_i[colour_index]>>16; + + // apply z comparator + if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; + if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1; + if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; + + // apply data comparator + if (DCOMPEN|BCOMPEN) + { + if (!CMPDST) + { + // compare source pixel with pattern pixel + if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit=1; + } + else + { + // compare destination pixel with pattern pixel + if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit=1; + } + if (a1_phrase_mode||a2_phrase_mode) + inhibit=!inhibit; + } + + // compute the write data and store + if (!inhibit) + { + if (PATDSEL) + { + // use pattern data for write data + writedata= READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode); + } + else + if (INTADD) + { + // intensity addition + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (!(TOPBEN) && writedata > 0xff) + writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (!(TOPNEN) && writedata > 0xfff) + writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } + else + { + if (LFU_NAN) writedata |= ~srcdata & ~dstdata; + if (LFU_NA) writedata |= ~srcdata & dstdata; + if (LFU_AN) writedata |= srcdata & ~dstdata; + if (LFU_A) writedata |= srcdata & dstdata; + } + if(GOURD) + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + + if(SRCSHADE) + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } + else + { + writedata=dstdata; + srczdata=dstzdata; + } + if (/*a1_phrase_mode || */BKGWREN || !inhibit) + { + // write to the destination + WRITE_PIXEL(a1, REG(A1_FLAGS), writedata); + if (DSTWRZ) WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata); + } + } + else + { + // load src data and Z + if (SRCEN) + { + srcdata = READ_PIXEL(a1, REG(A1_FLAGS)); + if (SRCENZ) + { + srczdata = READ_ZDATA(a1, REG(A1_FLAGS)); + } + else + if (cmd & 0x001c020) + { + srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); + } + } + else + { + srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode); + if (cmd & 0x001c020) + { + srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); + } + } + + // load dst data and Z + if (DSTEN) + { + dstdata = READ_PIXEL(a2, REG(A2_FLAGS)); + if (DSTENZ) + { + dstzdata = READ_ZDATA(a2, REG(A2_FLAGS)); + } + else + { + dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode); + } + } + else + { + dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode); + + if (DSTENZ) + { + dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode); + } + } + + if(GOURZ) + srczdata=z_i[colour_index]>>16; + + // apply z comparator + if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; + if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1; + if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; + + // apply data comparator + if (DCOMPEN|BCOMPEN) + { + if (!CMPDST) + { + // compare source pixel with pattern pixel + if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit=1; + } + else + { + // compare destination pixel with pattern pixel + if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit=1; + } + if (a1_phrase_mode||a2_phrase_mode) + inhibit=!inhibit; + } + + // compute the write data and store + if (!inhibit) + { + if (PATDSEL) + { + // use pattern data for write data + writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode); + } + else + if (INTADD) + { + // intensity addition + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (!(TOPBEN) && writedata > 0xff) + writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (!(TOPNEN) && writedata > 0xfff) + writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } + else + { + if (LFU_NAN) + writedata |= ~srcdata & ~dstdata; + if (LFU_NA) + writedata |= ~srcdata & dstdata; + if (LFU_AN) + writedata |= srcdata & ~dstdata; + if (LFU_A) + writedata |= srcdata & dstdata; + } + if(GOURD) + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + + if(SRCSHADE) + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } + else + { + writedata=dstdata; + srczdata=dstzdata; + } + + if (/*a2_phrase_mode || */BKGWREN || !inhibit) + { + // write to the destination + WRITE_PIXEL(a2, REG(A2_FLAGS), writedata); + if (DSTWRZ) + WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata); + } + } + // update x and y + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + + if (GOURZ) + z_i[colour_index]+=zadd; + + if ((GOURD)||(SRCSHADE)) + { + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + if ((GOURD)||(SRCSHADE)||(GOURZ)) + { + if(a1_phrase_mode) + colour_index=(colour_index+1)&0x3; + } + } + + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + +/* if (a2_phrase_mode) + { + a1_x+=(64/a1_psize)*a1_xadd; + } + if (a2_phrase_mode) + { + for (int nb=0;nb<(64/a2_psize)+1;nb++) + a2_x = (a2_x + a2_xadd) & a2_mask_x; + } +*/ } + + // write values back to registers + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void blitter_blit(uint32 cmd) +{ + colour_index = 0; + src = cmd & 0x07; + dst = (cmd >> 3) & 0x07; + misc = (cmd >> 6) & 0x03; + a1ctl = (cmd >> 8) & 0x7; + mode = (cmd >> 11) & 0x07; + ity = (cmd >> 14) & 0x0F; + zop = (cmd >> 18) & 0x07; + op = (cmd >> 21) & 0x0F; + ctrl = (cmd >> 25) & 0x3F; + + a1_addr = REG(A1_BASE); + a2_addr = REG(A2_BASE); + + a1_zoffs = (REG(A1_FLAGS) >> 6) & 7; + a2_zoffs = (REG(A2_FLAGS) >> 6) & 7; + + xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03; + xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03; + a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1); + a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1); + + n_pixels = REG(PIXLINECOUNTER) & 0xFFFF; + n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF; + + a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF); + a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16); + a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)]; + + a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16; + a2_y = (REG(A2_PIXEL) & 0xFFFF0000); + a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)]; + a2_mask_x = 0xFFFF | ((REG(A2_MASK) & 0x0000FFFF) << 16); + a2_mask_y = ((REG(A2_MASK) & 0xFFFF0000) | 0xFFFF); + + // + if (!(REG(A2_FLAGS) & 0x8000)) + { + a2_mask_x = 0xFFFFFFFF; // must be 16.16 + a2_mask_y = 0xFFFFFFFF; // must be 16.16 + } + + a1_phrase_mode = 0; + + // determine a1_yadd + if (YADD1_A1) + a1_yadd = 1 << 16; + else + a1_yadd = 0; + + if (YSIGNSUB_A1) + a1_yadd = -a1_yadd; + + // determine a1_xadd + switch (xadd_a1_control) + { + case XADDPHR: + // add phrase offset to X and truncate + a1_xadd = 1 << 16; + a1_phrase_mode = 1; + break; + case XADDPIX: + // add pixelsize (1) to X + a1_xadd = 1 << 16; + break; + case XADD0: + // add zero (for those nice vertical lines) + a1_xadd = 0; + break; + case XADDINC: + // add the contents of the increment register + a1_xadd = (REG(A1_INC) << 16) | (REG(A1_FINC) & 0xFFFF); + a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16); + break; + } + if (XSIGNSUB_A1) + a1_xadd = -a1_xadd; + + // determine a2_yadd + if (YADD1_A2 || YADD1_A1) + a2_yadd = 1 << 16; + else + a2_yadd = 0; + + if (YSIGNSUB_A2) + a2_yadd = -a2_yadd; + + a2_phrase_mode = 0; + + // determine a2_xadd + switch (xadd_a2_control) + { + case XADDPHR: + // add phrase offset to X and truncate + a2_xadd = 1 << 16; + a2_phrase_mode = 1; + break; + case XADDPIX: + // add pixelsize (1) to X + a2_xadd = 1 << 16; + break; + case XADD0: + // add zero (for those nice vertical lines) + a2_xadd = 0; + break; + case XADDINC: + // add the contents of the increment register + // since there is no register for a2 we just add 1 + a2_xadd = 1 << 16; + break; + } + if (XSIGNSUB_A2) + a2_xadd = -a2_xadd; + + // modify outer loop steps based on command + a1_step_x = 0; + a1_step_y = 0; + a2_step_x = 0; + a2_step_y = 0; + + if (cmd & 0x00000100) + { + a1_step_x = (REG(A1_FSTEP)&0xffff); + a1_step_y = (REG(A1_FSTEP)>>16); + } + if (cmd & 0x00000200) + { + a1_step_x += ((REG(A1_STEP)&0x0000ffff)<<16); + a1_step_y += ((REG(A1_STEP)&0xffff0000)); + } + if (cmd & 0x00000400) + { + a2_step_x = (REG(A2_STEP)&0x0000ffff)<<16; + a2_step_y = (REG(A2_STEP)&0xffff0000); + } + + outer_loop = n_lines; + + a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 7); + a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 7); + + // zbuffering + if (GOURZ) + { + zadd = jaguar_long_read(0xF02274); + + for(int v=0; v<4; v++) + z_i[v] = (int32)jaguar_long_read(0xF0228C + (v << 2)); + } + if (GOURD || GOURZ || SRCSHADE) + { + // gouraud shading + gouraud_add = jaguar_long_read(0xF02270); + + gd_c[0] = jaguar_byte_read(0xF02268); + gd_i[0] = jaguar_byte_read(0xF02269); + gd_i[0] <<= 16; + gd_i[0] |= jaguar_word_read(0xF02240); + + gd_c[1] = jaguar_byte_read(0xF0226A); + gd_i[1] = jaguar_byte_read(0xF0226B); + gd_i[1] <<= 16; + gd_i[1] |= jaguar_word_read(0xF02242); + + gd_c[2] = jaguar_byte_read(0xF0226C); + gd_i[2] = jaguar_byte_read(0xF0226D); + gd_i[2] <<= 16; + gd_i[2] |= jaguar_word_read(0xF02244); + + gd_c[3] = jaguar_byte_read(0xF0226E); + gd_i[3] = jaguar_byte_read(0xF0226F); + gd_i[3] <<= 16; + gd_i[3] |= jaguar_word_read(0xF02246); + + gd_ia = gouraud_add & 0xFFFFFF; + if (gd_ia & 0x800000) + gd_ia = 0xFF000000 | gd_ia; + + gd_ca = (gouraud_add>>24) & 0xFF; + if (gd_ca & 0x80) + gd_ca = 0xFFFFFF00 | gd_ca; + } + + // fix for zoop! and syndicate + if ((jaguar_mainRom_crc32==0x501be17c)|| + (jaguar_mainRom_crc32==0x70895c51)|| + (jaguar_mainRom_crc32==0x0f1f1497)|| + (jaguar_mainRom_crc32==0xfc8f0dcd) + ) + { + if (a1_step_x<0) + a1_step_x=(-n_pixels)*65536; + + if (a2_step_x<0) + a2_step_x=(-n_pixels)*65536;; + } + else + // fix for wolfenstein 3d + if (jaguar_mainRom_crc32==0x3966698f) + { + if (n_pixels==24) + { + if ((a1_step_x / 65536)==-28) + { + a1_step_x=-24*65536; // au lieu de -28 + a2_step_x= 0*65536; // au lieu de -8 + } + } + } + else + // fix for Tempest 2000 + if (jaguar_mainRom_crc32==0x32816d44) + { +/* + if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384))) + { + fprintf(log_get(),"Blit!\n"); + fprintf(log_get()," cmd = 0x%.8x\n",cmd); + fprintf(log_get()," a1_base = %08X\n", a1_addr); + fprintf(log_get()," a1_pitch = %d\n", a1_pitch); + fprintf(log_get()," a1_psize = %d\n", a1_psize); + fprintf(log_get()," a1_width = %d\n", a1_width); + fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0); + fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0); + fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0); + fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0); + fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0); + fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs); + + fprintf(log_get()," a2_base = %08X\n", a2_addr); + fprintf(log_get()," a2_pitch = %d\n", a2_pitch); + fprintf(log_get()," a2_psize = %d\n", a2_psize); + fprintf(log_get()," a2_width = %d\n", a2_width); + fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0); + fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0); + fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0); + fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0); + fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0); + fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x); + fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y); + fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs); + + fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines); + + fprintf(log_get()," command = %08X\n", cmd); + fprintf(log_get()," dsten = %i\n",DSTEN); + fprintf(log_get()," srcen = %i\n",SRCEN); + fprintf(log_get()," patdsel = %i\n",PATDSEL); + fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA)); + fprintf(log_get()," dcompen = %i\n",DCOMPEN); + fprintf(log_get()," bcompen = %i\n",BCOMPEN); + fprintf(log_get()," cmpdst = %i\n",CMPDST); + fprintf(log_get()," GOURZ = %i\n",GOURZ); + fprintf(log_get()," GOURD = %i\n",GOURD); + fprintf(log_get()," SRCSHADE = %i\n",SRCSHADE); + fprintf(log_get()," DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4)); + } +*/ } + +#ifdef LOG_BLITS +// if (start_logging) + { + fprintf(log_get(),"Blit!\n"); + fprintf(log_get()," cmd = 0x%.8x\n",cmd); + fprintf(log_get()," a1_base = %08X\n", a1_addr); + fprintf(log_get()," a1_pitch = %d\n", a1_pitch); + fprintf(log_get()," a1_psize = %d\n", a1_psize); + fprintf(log_get()," a1_width = %d\n", a1_width); + fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0); + fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0); + fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0); + fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0); + fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0); + fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs); + + fprintf(log_get()," a2_base = %08X\n", a2_addr); + fprintf(log_get()," a2_pitch = %d\n", a2_pitch); + fprintf(log_get()," a2_psize = %d\n", a2_psize); + fprintf(log_get()," a2_width = %d\n", a2_width); + fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0); + fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0); + fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0); + fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0); + fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0); + fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x); + fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y); + fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs); + + fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines); + + fprintf(log_get()," command = %08X\n", cmd); + fprintf(log_get()," dsten = %i\n",DSTEN); + fprintf(log_get()," srcen = %i\n",SRCEN); + fprintf(log_get()," patdsel = %i\n",PATDSEL); + fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA)); + fprintf(log_get()," dcompen = %i\n",DCOMPEN); + fprintf(log_get()," bcompen = %i\n",BCOMPEN); + fprintf(log_get()," cmpdst = %i\n",CMPDST); + fprintf(log_get()," GOURZ = %i\n",GOURZ); + fprintf(log_get()," GOURD = %i\n",GOURD); + fprintf(log_get()," SRCSHADE= %i\n",SRCSHADE); + } +#endif + + blitter_working = 1; +#ifndef USE_GENERIC_BLITTER + if (!blitter_execute_cached_code(blitter_in_cache(cmd))) +#endif + blitter_generic(cmd); + blitter_working = 0; +} + +uint32 blitter_reg_read(uint32 offset) +{ + uint32 data = blitter_ram[offset]; + data <<= 8; + data |= blitter_ram[offset+1]; + data <<= 8; + data |= blitter_ram[offset+2]; + data <<= 8; + data |= blitter_ram[offset+3]; + return data; +} + +void blitter_reg_write(uint32 offset, uint32 data) +{ + blitter_ram[offset+0] = (data>>24) & 0xFF; + blitter_ram[offset+1] = (data>>16) & 0xFF; + blitter_ram[offset+2] = (data>>8) & 0xFF; + blitter_ram[offset+3] = data & 0xFF; +} + +uint32 blitter_long_read(uint32 offset) +{ + return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2); +} + +void blitter_long_write(uint32 offset, uint32 data) +{ + blitter_word_write(offset, data >> 16); + blitter_word_write(offset+2, data & 0xFFFF); +} + +void blitter_init(void) +{ + if (!blitter_cache_init) + { + for (int i=0;i<256;i++) + { + blitter_cache[i] = (struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); + blitter_cache[i]->next=null; + blitter_cache[i]->prev=null; + } + blitter_cache_init = 1; + } +#ifndef USE_GENERIC_BLITTER + #include "include/blit_i.h" +#endif + + blitter_reset(); +#ifdef GEN_CODE + blitters_code_fp = fopen("include/blit_c.h","awrt"); + blitters_code_init_fp = fopen("include/blit_i.h","awrt"); +#endif +} + +void blitter_reset(void) +{ + memset(blitter_ram, 0x00, 0xA0); +} + +void blitter_done(void) +{ +// blitter_list(); +#ifdef GEN_CODE + fclose(blitters_code_fp); + fclose(blitters_code_init_fp); +#endif + fprintf(log_get(), "BLIT: Done.\n"); +} + +void blitter_byte_write(uint32 offset, uint8 data) +{ + offset &= 0xFF; + + if ((offset >= 0x7C) && (offset <= 0x9B)) + { + switch (offset) + { + case 0x7C: break; + case 0x7D: blitter_ram[0x69] = data; break; + case 0x7E: blitter_ram[0x40] = data; break; + case 0x7F: blitter_ram[0x41] = data; break; + + case 0x80: break; + case 0x81: blitter_ram[0x6B] = data; break; + case 0x82: blitter_ram[0x42] = data; break; + case 0x83: blitter_ram[0x43] = data; break; + + case 0x84: break; + case 0x85: blitter_ram[0x6D] = data; break; + case 0x86: blitter_ram[0x44] = data; break; + case 0x87: blitter_ram[0x45] = data; break; + + case 0x88: break; + case 0x89: blitter_ram[0x6F] = data; break; + case 0x9A: blitter_ram[0x46] = data; break; + case 0x9B: blitter_ram[0x47] = data; break; + } + } + + blitter_ram[offset] = data; +} + +void blitter_word_write(uint32 offset, uint16 data) +{ + blitter_byte_write(offset+0, (data>>8) & 0xFF); + blitter_byte_write(offset+1, data & 0xFF); + + if ((offset & 0xFF) == 0x3A) + { + uint32 cmd = blitter_ram[0x38]; + cmd <<= 8; + cmd |= blitter_ram[0x39]; + cmd <<= 8; + cmd |= blitter_ram[0x3A]; + cmd <<= 8; + cmd |= blitter_ram[0x3B]; + + blitter_blit(cmd); + } +} + +uint8 blitter_byte_read(uint32 offset) +{ + offset &= 0xFF; + + // status register + if (offset == (0x38+3)) + return 0x01; // always idle + + return blitter_ram[offset]; +} + +uint16 blitter_word_read(uint32 offset) +{ + return (blitter_byte_read(offset) << 8) | blitter_byte_read(offset+1); +} diff --git a/src/cdbios.cpp b/src/cdbios.cpp new file mode 100644 index 0000000..230f103 --- /dev/null +++ b/src/cdbios.cpp @@ -0,0 +1,840 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// 20.02.2002: fixed sector to msf conversion +// 19.02.2002: fixed a bug in toc encoding function +// +// +// +////////////////////////////////////////////////////////////////////////////// +#include "include/cdbios.h" + +/* Added by SDLEMU (http://sdlemu.ngemu.com */ +/* Some GCC UNIX includes */ +#ifdef __GCCUNIX__ + #include +#endif + +#define ERR_FLAG 0x3e00 +#define CD_TOC 0x2c00 +#define BIOS_VER 0x3004 + + +#define CDBIOS_INIT 0 +#define CDBIOS_INITM 1 +#define CDBIOS_INITF 2 + + + +#define CD_INIT 0x3000 +#define CD_MODE 0x3006 +#define CD_ACK 0x300C +#define CD_JERI 0x3012 +#define CD_SPIN 0x3018 +#define CD_STOP 0x301E +#define CD_MUTE 0x3024 +#define CD_UMUTE 0x302A +#define CD_PAUSE 0x3030 +#define CD_UPAUSE 0x3036 +#define CD_READ 0x303C +#define CD_UREAD 0x3042 +#define CD_SETUP 0x3048 +#define CD_PTR 0x304E +#define CD_OSAMP 0x3054 +#define CD_GETTOC 0x306A +#define CD_INITM 0x3060 +#define CD_INITF 0x3066 + + +char *cdbios_command[]={"init","mode","ack","jeri","spin","stop","mute","umute","pause","upause", + "read","uread","setup","ptr","osamp","getoc","initm","initf", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +#define CDROM_AUDIO_MODE 0 +#define CDROM_DATA_MODE 1 + +#define CDROM_SINGLE_SPEED 0 +#define CDROM_DOUBLE_SPEED 1 + +#define CDROM_STATUS_OK 0 +#define CDROM_STATUS_ERROR 1 + + +uint32 cdrom_mode = CDROM_DATA_MODE; +uint32 cdrom_speed = CDROM_SINGLE_SPEED; +uint32 cdrom_oversample_factor = 1; +uint32 cdbios_session=0; + +uint32 cdrom_destination_buffer_beginning; +uint32 cdrom_destination_buffer_end; +uint32 cdrom_time_code; +uint32 cdrom_seek_only; +uint32 cdrom_partition_marker; +uint32 cdrom_circular_buffer_size; + +uint32 cdbios_init_type; +uint32 *cdbios_sector_lut; +uint32 cdbios_init_done=0; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_build_sector_lut(void) +{ + uint32 last_sector=0; + int32 offset=0; + uint32 sector=0; + + s_cdi_track *last_track=&cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].tracks[cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].nb_of_tracks-1]; + + last_sector=last_track->start_lba+last_track->total_length-1; + + + cdbios_sector_lut=(uint32*)malloc((last_sector+1)*sizeof(uint32)); + memset(cdbios_sector_lut,0xff,(last_sector+1)*sizeof(uint32)); + + for (int session=0;sessionnb_of_sessions;session++) + { + for (int track=0;tracksessions[session].nb_of_tracks;track++) + { + s_cdi_track *current_track=&cdi_descriptor->sessions[session].tracks[track]; + + if (offset<((int32)(current_track->start_lba-1))) + { + fprintf(log_get(),"cdbios: postgap between %i and %i\n",offset,current_track->start_lba-1); + + // fill-in postgap + for (;offsetstart_lba;offset++) + { + cdbios_sector_lut[offset]=0xffffffff; + } + + } + fprintf(log_get(),"cdbios: data between %i and %i\n",offset,current_track->start_lba+current_track->total_length-1); + for (;offsetstart_lba+current_track->total_length;offset++) + { + cdbios_sector_lut[offset]=sector; + sector++; + } + + } + } + +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_get_time(uint32 sectors, uint32 *mm, uint32 *ss, uint32 *ff) +{ + uint32 _sectors=sectors; + + uint32 _mm=(sectors/(60*75)); + sectors-=(_mm*(60*75)); + uint32 _ss=(sectors/75); + sectors-=(_ss*75); + uint32 _ff=sectors; + + *mm=_mm; + *ss=_ss; + *ff=_ff; + + +// fprintf(log_get(),"[%.2i:%.2i:%.2i]\n",_mm,_ss,_ff); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_encode_toc(void) +{ + int i; + uint32 base=CD_TOC; + + jaguar_byte_write(base++,0x00); + jaguar_byte_write(base++,0x00); + jaguar_byte_write(base++,0x01); + + int nbtracks=0; + for (i=0;inb_of_sessions;i++) + nbtracks+=cdi_descriptor->sessions[i].nb_of_tracks; + + jaguar_byte_write(base++,nbtracks+1); + jaguar_byte_write(base++,cdi_descriptor->nb_of_sessions); + + uint32 mm=0; + uint32 ss=0; + uint32 ff=0; + + cdbios_get_time(cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].tracks[cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].nb_of_tracks-1].start_lba+ + cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].tracks[cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].nb_of_tracks-1].length+ + cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].tracks[cdi_descriptor->sessions[cdi_descriptor->nb_of_sessions-1].nb_of_tracks-1].pregap_length, + &mm,&ss,&ff); + + jaguar_byte_write(base++,mm); + jaguar_byte_write(base++,ss); + jaguar_byte_write(base++,ff); + + int track_count=1; + for (i=0;inb_of_sessions;i++) + for (int j=0;jsessions[i].nb_of_tracks;j++) + { + s_cdi_track *track=&cdi_descriptor->sessions[i].tracks[j]; + +// fprintf(log_get(),"track %i\n",track_count); + + jaguar_byte_write(base++,track_count); + cdbios_get_time(track->start_lba+track->pregap_length,&mm,&ss,&ff); + jaguar_byte_write(base++,mm); + jaguar_byte_write(base++,ss); + jaguar_byte_write(base++,ff); + jaguar_byte_write(base++,i); + cdbios_get_time(track->length,&mm,&ss,&ff); + jaguar_byte_write(base++,mm); + jaguar_byte_write(base++,ss); + jaguar_byte_write(base++,ff); + + track_count++; + } + + cdi_tracks_count=track_count; + cdi_tracks=(s_cdi_track**)malloc(track_count*sizeof(s_cdi_track*)); + track_count=0; + for (i=0;inb_of_sessions;i++) + { + for (int j=0;jsessions[i].nb_of_tracks;j++) + { + cdi_tracks[track_count]=&cdi_descriptor->sessions[i].tracks[j]; + track_count++; + } + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_decode_toc(void) +{ + uint32 addr=0x2c00; + uint32 nb_tracks; + + fprintf(log_get(),"cdbios: toc:\n"); + fprintf(log_get(),"cdbios:\n"); + addr+=2; + fprintf(log_get(),"cdbios: minimum track number: %i\n",jaguar_byte_read(addr++)); + fprintf(log_get(),"cdbios: maximum track number: %i\n",nb_tracks=jaguar_byte_read(addr++)); + fprintf(log_get(),"cdbios: number of sessions : %i\n",jaguar_byte_read(addr++)); + fprintf(log_get(),"cdbios: start of last lead out time: %.2i:%.2i:%.2i\n", + jaguar_byte_read(addr++),jaguar_byte_read(addr++),jaguar_byte_read(addr++)); + + uint32 mm,ss,ff; + + nb_tracks--; + + while (nb_tracks) + { + fprintf(log_get(),"cdbios:\n"); + fprintf(log_get(),"cdbios: track : %i\n",jaguar_byte_read(addr++)); + + mm=jaguar_byte_read(addr++); + ss=jaguar_byte_read(addr++); + ff=jaguar_byte_read(addr++); + + fprintf(log_get(),"cdbios: start at : %.2i:%.2i:%.2i\n",mm,ss,ff); + fprintf(log_get(),"cdbios: session : %i\n",jaguar_byte_read(addr++)); + + mm=jaguar_byte_read(addr++); + ss=jaguar_byte_read(addr++); + ff=jaguar_byte_read(addr++); + + fprintf(log_get(),"cdbios: duration : %.2i:%.2i:%.2i\n",mm,ss,ff); + nb_tracks--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cd_bios_boot(char *filename) +{ + cd_bios_init(); + + + cdi_fp=cdi_open(filename); + cdi_descriptor=cdi_get_descriptor(cdi_fp,log_get()); + if (cdi_descriptor==0) + { + fprintf(log_get(),"cdi: bad image\n"); + cdi_close(cdi_fp); + return; + } + cdi_dump_descriptor(log_get(),cdi_descriptor); + cdbios_build_sector_lut(); + + uint8 *code=cdi_extract_boot_code(cdi_fp,cdi_descriptor); + + // copy the code to ram + for (uint32 i=0;i>1) & 0x01; + uint32 cdrom_speed = data & 0x01; + jaguar_word_write(ERR_FLAG, CDROM_STATUS_OK); + +// fprintf(log_get(),"cdbios: %s\n",(cdrom_mode==CDROM_AUDIO_MODE)?"audio mode":"data mode"); +// fprintf(log_get(),"cdbios: %s\n",(cdrom_speed==CDROM_DOUBLE_SPEED)?"double speed":"single speed"); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_ack(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_jeri(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_spin(void) +{ +// uint16 spin=(1<<(s68000context.dreg[0]&0xffff)); + uint16 spin = (1 << (m68k_get_reg(NULL, M68K_REG_D0) & 0xFFFF)); + cdbios_session = spin; + jaguar_word_write(ERR_FLAG, CDROM_STATUS_OK); +// fprintf(log_get(),"cdbios: switching to session %i\n",spin); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_stop(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_mute(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_umute(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_pause(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_upause(void) +{ + jaguar_word_write(ERR_FLAG,CDROM_STATUS_OK); +} +void cdi_read_block(uint32 sector, uint8 *buffer, uint32 count) +{ + while (count) + { + cdi_load_sector(cdbios_sector_lut[sector],buffer); + buffer+=2352; + sector++; + count--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdbios_cmd_read(void) +{ + static uint8 cdbios_sector[2352]; + +/* cdrom_destination_buffer_beginning=s68000context.areg[0]; + cdrom_destination_buffer_end=s68000context.areg[1]; + cdrom_time_code=(s68000context.dreg[0])&0x7fffffff; + cdrom_seek_only=s68000context.dreg[0]&0x80000000;*/ + cdrom_destination_buffer_beginning = m68k_get_reg(NULL, M68K_REG_A0); + cdrom_destination_buffer_end = m68k_get_reg(NULL, M68K_REG_A1); + cdrom_time_code = m68k_get_reg(NULL, M68K_REG_D0) & 0x7FFFFFFF; + cdrom_seek_only = m68k_get_reg(NULL, M68K_REG_D0) & 0x80000000; + +/* cdrom_partition_marker=s68000context.dreg[1]; + if (s68000context.dreg[2]!=0) + cdrom_circular_buffer_size=(1<> 20) & 0x0F)) + ((cdrom_time_code >> 16) & 0x0F); + uint32 ss = (10 * ((cdrom_time_code >> 12) & 0x0F)) + ((cdrom_time_code >> 8) & 0x0F); + uint32 ff = (10 * ((cdrom_time_code >> 4) & 0x0F)) + ((cdrom_time_code >> 0) & 0x0F); + + fprintf(log_get(),"cdbios: read(0x%.8x, 0x%.8x, %.2i:%.2i:%.2i, %i) %s\n", + cdrom_destination_buffer_beginning, + cdrom_destination_buffer_end, + mm,ss,ff, + cdrom_circular_buffer_size,cdrom_seek_only?"(seek only)":""); + + if (!cdrom_seek_only) + { + if (cdbios_init_type==CDBIOS_INITM) + { + fprintf(log_get(),"cdbios: partition marker: %c%c%c%c (0x%.8x)\n", + ((cdrom_partition_marker>>24)&0xff), + ((cdrom_partition_marker>>16)&0xff), + ((cdrom_partition_marker>>8)&0xff), + (cdrom_partition_marker&0xff), + cdrom_partition_marker + ); + } + if (((int32)cdrom_circular_buffer_size)==-1) + cdrom_circular_buffer_size=0xffffffff; + + uint32 track_offset=((ss+(60*mm))*75)+ff; + + fprintf(log_get(),"cdbios: track offset: %i\n",track_offset); + uint32 nb_sectors=(cdrom_destination_buffer_end-cdrom_destination_buffer_beginning)/2352; + uint32 reste=(cdrom_destination_buffer_end-cdrom_destination_buffer_beginning)%2352; + uint32 buffer_offset=0; + uint32 nb_bytes_to_read=cdrom_destination_buffer_end-cdrom_destination_buffer_beginning+1; + + if (cdbios_init_type==CDBIOS_INITF) + { +// if (cdrom_destination_buffer_beginning==0x00046000) +// return; + + uint8 *buffer=(uint8*)malloc((nb_sectors+1)*2352); + cdi_read_block(track_offset,buffer,nb_sectors+1); + for (uint32 k=0;k>24)&0xff))&& + (alias[1]==((cdrom_partition_marker>>16)&0xff))&& + (alias[2]==((cdrom_partition_marker>>8)&0xff))&& + (alias[3]==((cdrom_partition_marker>>0)&0xff)) + ) + { + marker_count--; + if (marker_count) + { + alias+=3; + } + else + { + exit(0); + alias+=4; + for (uint32 k=0;k + #include + #include + + #define O_BINARY (0) +#endif + +#define CDI_V2 0x80000004 +#define CDI_V3 0x80000005 +#define CDI_V35 0x80000006 + +static uint8 cdi_track_start_mark[10] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; + + + +int cdi_fp; +uint32 cdi_load_address; +uint32 cdi_code_length; +s_cdi_descriptor *cdi_descriptor; +s_cdi_track **cdi_tracks; +uint32 cdi_tracks_count; + + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +int cdi_open(char *path) +{ + fprintf(log_get(),"cdi: opening %s\n",path); + return(open(path,O_BINARY|O_RDONLY)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdi_close(int fp) +{ + fprintf(log_get(),"cdi: closing\n"); + close(fp); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#ifdef __PORT__ +long tell(int fd) +{ + return lseek(fd, 0LL, SEEK_CUR); +} +#endif +s_cdi_descriptor *cdi_get_descriptor(int fp, FILE *stdfp) +{ + s_cdi_descriptor *descriptor; + + uint32 previous_position=0; + + if (fp==-1) + return(0); + + descriptor=(s_cdi_descriptor *)malloc(sizeof(s_cdi_descriptor)); + if (descriptor==0) + return(0); + + lseek(fp,0,SEEK_END); + descriptor->length=tell(fp); + if (descriptor->length<8) + { + if (stdfp) fprintf(stdfp,"cdi: image is too short (%i bytes)\n",descriptor->length); + free(descriptor); + return(0); + } + lseek(fp,descriptor->length-8,SEEK_SET); + read(fp,&descriptor->version,4); + read(fp,&descriptor->header_offset,4); + lseek(fp,descriptor->header_offset,SEEK_SET); + read(fp,&descriptor->nb_of_sessions,2); + + descriptor->sessions=(s_cdi_session *)malloc(descriptor->nb_of_sessions*sizeof(s_cdi_session)); + if (descriptor->sessions==0) + { + free(descriptor); + return(0); + } + if (stdfp) fprintf(stdfp,"cdi: %i sessions\n",descriptor->nb_of_sessions); + uint32 track_position=0; + for (uint16 session=0;sessionnb_of_sessions;session++) + { + read(fp,&descriptor->sessions[session].nb_of_tracks,2); + descriptor->sessions[session].tracks=(s_cdi_track*)malloc(descriptor->sessions[session].nb_of_tracks*sizeof(s_cdi_track)); + + if (stdfp) fprintf(stdfp,"cdi:\ncdi: reading session %i (%i tracks)\n",session,descriptor->sessions[session].nb_of_tracks); + + for (uint16 track=0;tracksessions[session].nb_of_tracks;track++) + { + static char current_start_mark[10]; + s_cdi_track *current_track=&descriptor->sessions[session].tracks[track]; + if (stdfp) fprintf(stdfp,"cdi:\ncdi: \t\treading track %i\n",track); + + uint32 temp_value; + + read(fp,&temp_value, 4); + if (temp_value != 0) + lseek(fp, 8, SEEK_CUR); // extra data (DJ 3.00.780 and up) + + read(fp,current_start_mark, 10); + if (memcmp(cdi_track_start_mark, current_start_mark, 10)) + { + if (stdfp) fprintf(stdfp,"cdi: could not find the track start mark"); + return(0); + } + read(fp,current_start_mark, 10); + if (memcmp(cdi_track_start_mark, current_start_mark, 10)) + { + if (stdfp) fprintf(stdfp,"cdi: could not find the track start mark"); + return(0); + } + + lseek(fp, 4, SEEK_CUR); + read(fp,¤t_track->filename_length, 1); + lseek(fp, current_track->filename_length, SEEK_CUR); + + lseek(fp, 11, SEEK_CUR); + lseek(fp, 4, SEEK_CUR); + lseek(fp, 4, SEEK_CUR); + read(fp,&temp_value, 4); + if (temp_value == 0x80000000) + lseek(fp, 8, SEEK_CUR); // DJ4 + lseek(fp, 2, SEEK_CUR); + + read(fp, ¤t_track->pregap_length, 4); + if (current_track->pregap_length!=150) + { + fprintf(log_get(),"cdi: warning: pregap different than 150\n"); + } + read(fp, ¤t_track->length, 4); + if (stdfp) fprintf(stdfp,"cdi: \t\t\tpregap length : %i\n", current_track->pregap_length); + if (stdfp) fprintf(stdfp,"cdi: \t\t\tlength : %i\n", current_track->length); + + lseek(fp, 6, SEEK_CUR); + + read(fp, ¤t_track->mode, 4); + if (stdfp) fprintf(stdfp,"cdi: \t\t\tmode : %i\n", current_track->mode); + + lseek(fp, 12, SEEK_CUR); + read(fp, ¤t_track->start_lba, 4); + if (stdfp) fprintf(stdfp,"cdi: \t\t\tstart lba : %i\n", current_track->start_lba); + read(fp, ¤t_track->total_length, 4); + if (stdfp) fprintf(stdfp,"cdi: \t\t\ttotal length : %i\n", current_track->total_length); + lseek(fp, 16, SEEK_CUR); + read(fp, ¤t_track->sector_size_value, 4); + if (stdfp) fprintf(stdfp,"cdi: \t\t\tsector size : %i\n", current_track->sector_size_value); + + switch(current_track->sector_size_value) + { + case 0 : current_track->sector_size = 2048; break; + case 1 : current_track->sector_size = 2336; break; + case 2 : current_track->sector_size = 2352; break; + default: { + if (stdfp) fprintf(stdfp,"cdi: \t\t\tunsupported %i bytes sector",current_track->sector_size_value); + return(0); + } + } + + if (current_track->mode > 2) + if (stdfp) fprintf(stdfp,"cdi: \t\t\ttrack mode %i not supported",current_track->mode); + + lseek(fp, 29, SEEK_CUR); + if (descriptor->version != CDI_V2) + { + lseek(fp, 5, SEEK_CUR); + read(fp,&temp_value, 4); + if (temp_value == 0xffffffff) + lseek(fp, 78, SEEK_CUR); // extra data (DJ 3.00.780 and up) + } + current_track->position=track_position; + track_position+=(current_track->pregap_length+current_track->length)*current_track->sector_size; + previous_position=track_position; + } + lseek(fp, 4, SEEK_CUR); + lseek(fp, 8, SEEK_CUR); + if (descriptor->version != CDI_V2) + lseek(fp, 1, SEEK_CUR); + + } + if (descriptor->header_offset == 0) + return(0); + + return(descriptor); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdi_dump_descriptor(FILE *fp,s_cdi_descriptor *cdi_descriptor) +{ + fprintf(fp,"cdi: %i Mb\n",cdi_descriptor->length>>20); + fprintf(fp,"cdi: format version "); + switch(cdi_descriptor->version) + { + case CDI_V2: fprintf(fp,"2\n"); break; + case CDI_V3: fprintf(fp,"3\n"); break; + case CDI_V35: fprintf(fp,"3.5\n"); break; + default: fprintf(fp,"unknown\n"); break; + } + fprintf(fp,"cdi: %i sessions\n",cdi_descriptor->nb_of_sessions); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 *cdi_extract_boot_code(int fp, s_cdi_descriptor *cdi_descriptor) +{ + s_cdi_track *boot_track=&cdi_descriptor->sessions[1].tracks[0]; + uint32 boot_track_size=boot_track->length*boot_track->sector_size; + + uint8 *boot_track_data=(uint8*)malloc(boot_track_size); + lseek(fp,2+(boot_track->position), SEEK_SET); + read(fp,boot_track_data,boot_track_size); + + uint32 *boot_track_data_32=(uint32*)boot_track_data; + uint32 offset=0; + while (offset<(boot_track_size>>2)) + { + if (boot_track_data_32[offset]==0x49205452) + break; + offset++; + } + if (offset==(boot_track_size>>2)) + { + fprintf(log_get(),"cdi: cannot find the boot code\n"); + return(NULL); + } + offset=(offset<<2)+4; + uint16 *data16=(uint16*)&boot_track_data[offset]; + cdi_load_address=*data16++; cdi_load_address<<=16; cdi_load_address|=*data16++; + cdi_code_length=*data16++; cdi_code_length<<=16; cdi_code_length|=*data16++; + fprintf(log_get(),"cdi: load address: 0x%.8x\n",cdi_load_address); + fprintf(log_get(),"cdi: length: 0x%.8x\n",cdi_code_length); + fprintf(log_get(),"cdi: byte swapping boot code\n"); + + for (uint32 i=0;i<(cdi_code_length>>1);i++) + { + uint16 sdata=data16[i]; + sdata=(sdata>>8)|(sdata<<8); + data16[i]=sdata; + } + return((uint8*)data16); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdi_load_sector(uint32 sector, uint8 *buffer) +{ + if (sector==0xffffffff) + { + memset(buffer,0x00,2352); + return; + } + + sector*=2352; + + lseek(cdi_fp,2+sector,SEEK_SET); + read(cdi_fp,buffer,2352); + + // byte swap + for (uint32 i=0;i<2352;i+=2) + { + uint8 sdata=buffer[i+0]; + buffer[i+0]=buffer[i+1]; + buffer[i+1]=sdata; + } + +} diff --git a/src/cdrom.cpp b/src/cdrom.cpp new file mode 100644 index 0000000..039d284 --- /dev/null +++ b/src/cdrom.cpp @@ -0,0 +1,177 @@ +#include "include/cdrom.h" + +//#define CDROM_LOG + +static uint8 cdrom_ram[0x100]; +static uint16 cdrom_cmd=0; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdrom_init(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdrom_reset(void) +{ + memset(cdrom_ram,0x00,0x100); + cdrom_cmd=0; + +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdrom_done(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdrom_byte_write(uint32 offset, uint8 data) +{ + offset&=0xff; + cdrom_ram[offset]=data; + +#ifdef CDROM_LOG + fprintf(log_get(),"cdrom: writing byte 0x%.2x at 0x%.8x\n",data,offset); +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void cdrom_word_write(uint32 offset, uint16 data) +{ + offset&=0xff; + cdrom_ram[offset+0]=(data>>8)&0xff; + cdrom_ram[offset+1]=data&0xff; + + // command register +/* + if (offset==0x0A) + { + cdrom_cmd=data; + if ((data&0xff00)==0x1500) + { + fprintf(log_get(),"cdrom: setting mode 0x%.2x\n",data&0xff); + return; + } + if (data==0x7001) + { + uint32 offset=cdrom_ram[0x00]; + offset<<=8; + offset|=cdrom_ram[0x01]; + offset<<=8; + offset|=cdrom_ram[0x02]; + offset<<=8; + offset|=cdrom_ram[0x03]; + + uint32 size=cdrom_ram[0x04]; + offset<<=8; + offset|=cdrom_ram[0x05]; + + fprintf(log_get(),"cdrom: READ(0x%.8x, 0x%.4x) [68k pc=0x%.8x]\n",offset,size,s68000readPC()); + return; + } + else + fprintf(log_get(),"cdrom: unknown command 0x%.4x\n",data); + } +*/ +#ifdef CDROM_LOG + fprintf(log_get(),"cdrom: writing word 0x%.4x at 0x%.8x\n",data,offset); +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 cdrom_byte_read(uint32 offset) +{ + offset&=0xff; +#ifdef CDROM_LOG + fprintf(log_get(),"cdrom: reading byte from 0x%.8x\n",offset); +#endif + return(cdrom_ram[offset]); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 cdrom_word_read(uint32 offset) +{ + offset&=0xff; + + uint16 data=0x0000; + + if (offset==0x00) + data=0x0000; + else + if (offset==0x02) + data=0x2000; + else + if (offset==0x0a) + { + if (cdrom_cmd==0x7001) + data=cdrom_cmd; + else + data=0x0400; + } + else + { + data=cdrom_ram[offset+0]; + data<<=8; + data|=cdrom_ram[offset+1]; + } +#ifdef CDROM_LOG + fprintf(log_get(),"cdrom: reading word 0x%.4x from 0x%.8x [68k pc=0x%.8x]\n",data,offset,s68000readPC()); +#endif + return(data); +} diff --git a/src/clock.cpp b/src/clock.cpp new file mode 100644 index 0000000..6bc2b37 --- /dev/null +++ b/src/clock.cpp @@ -0,0 +1,76 @@ +#include "include/jaguar.h" + + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void clock_init(void) +{ + clock_reset(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void clock_reset(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void clock_done(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void clock_byte_write(uint32 offset, uint8 data) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void clock_word_write(uint32 offset, uint16 data) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 clock_byte_read(uint32 offset) +{ + return(0xff); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 clock_word_read(uint32 offset) +{ + return(0xffff); +} diff --git a/src/crc32.cpp b/src/crc32.cpp new file mode 100644 index 0000000..48de6c8 --- /dev/null +++ b/src/crc32.cpp @@ -0,0 +1,125 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#include +#include +#include "include/crc32.h" + +unsigned long crctable[256] = +{ + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL +}; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static unsigned long update_crc(unsigned char *p, unsigned long crc, int reclen) +{ + int i; + + for (i = 0; i < reclen; i++) + crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8); + + return (crc); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +int crc32_calcCheckSum(unsigned char *data, unsigned int length) +{ + int sum; + int Xor; + unsigned int i; + int j; + + + return(update_crc(data, 0xFFFFFFFFL, length)^0xFFFFFFFFL); + sum = 0; + Xor = 0; + + + for (i = 0;i < length;i+=2) + { + j = 256 * data[i] + data[i+1]; + sum += j; + Xor ^= j; + } + sum = ((sum & 0xffff) << 16) | (Xor & 0xffff); + return sum; +} diff --git a/src/dsound_dummy.cpp b/src/dsound_dummy.cpp new file mode 100644 index 0000000..ac29c19 --- /dev/null +++ b/src/dsound_dummy.cpp @@ -0,0 +1,294 @@ +//////////////////////////////////////////////////////////////////////////////// +// Audio +//////////////////////////////////////////////////////////////////////////////// + +#include "include/jaguar.h" +#include "include/dsnd.h" + +int ym2413_enable; + +int FREQUENCE=44100; + +void dsound_reset(void); + +#define LEFT 0 +#define RIGHT 1 +#define SOUND_BUFFER (0.16) //Seconds +#define UNDEFINED 0xFFFFFF + +int chipBufferLength; //Number of bytes to hold SOUND_BUFFER seconds. + +int lastChipWrite =0; +int chipWrite =UNDEFINED; //Write Cursor + +INT16* buf1; + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// + +void ws_write_state(int fp) +{ +} + + +void ws_read_state(int fp) +{ +} + + + + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +void ws_audio_init(void) +{ +#ifdef _EMULATE_SOUND + dsound_init(GetForegroundWindow(),1,FREQUENCE); +// ws_audio_reset(); +#endif +} +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +void ws_audio_reset(void) +{ +#ifdef _EMULATE_SOUND + int i; + dsound_reset(); + + chipWrite=UNDEFINED; + + for (i=0;i<4;i++) + { + ws_audio_stop_channel(i); + ws_audio_play_channel(i); + ws_audio_clear_channel(i); + } + + IDirectSoundBuffer_SetPan(chipBuffer,0); + IDirectSoundBuffer_SetVolume(chipBuffer,0); +#endif +} + + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +void ws_audio_done(void) +{ +#ifdef _EMULATE_SOUND + system_sound_shutdown(); +#endif +} + + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +void ws_audio_clear_channel(int Channel) +{ +#ifdef _EMULATE_SOUND + + switch (Channel) + { + case 0: + case 1: + memset(buf1,0,sizeof(buf1)); + chipWrite = UNDEFINED; + break; + + case 2: + case 3: + break; + + } +#endif +} + + + +//////////////////////////////////////////////////////////////////////////////// +// start playing a channel +//////////////////////////////////////////////////////////////////////////////// +int ws_audio_play_channel(int Channel) +{ +#ifdef _EMULATE_SOUND + switch (Channel) + { + case 0: + case 1: +// if (psg_on) + IDirectSoundBuffer_Play(chipBuffer,0,0, DSBPLAY_LOOPING); + break; + case 2: + case 3: + break; + } +#endif + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// stop playing a channel +//////////////////////////////////////////////////////////////////////////////// +int ws_audio_stop_channel(int Channel) +{ +#ifdef _EMULATE_SOUND + switch (Channel) + { + case 0: + case 1: + IDirectSoundBuffer_Stop(chipBuffer); + chipWrite=UNDEFINED; + break; + + case 2: + case 3: + break; + } +#endif + return(0); +} + + + +void dsound_reset(void) +{ +#ifdef _EMULATE_SOUND + BYTE *ppvAudioPtr1, *ppvAudioPtr2; + DWORD pdwAudioBytes1, pdwAudioBytes2; + + + chipWrite = UNDEFINED; + if (chipBuffer) + { + IDirectSoundBuffer_Stop(chipBuffer); + // Fill the sound buffer + if SUCCEEDED(IDirectSoundBuffer_Lock(chipBuffer,0,0, + (LPVOID*)&ppvAudioPtr1, &pdwAudioBytes1, (LPVOID*)&ppvAudioPtr2, &pdwAudioBytes2, DSBLOCK_ENTIREBUFFER)) + { + if (ppvAudioPtr1 && pdwAudioBytes1) + memset(ppvAudioPtr1, 0, pdwAudioBytes1); + + if (ppvAudioPtr2 && pdwAudioBytes2) + memset(ppvAudioPtr2, 0, pdwAudioBytes2); + + IDirectSoundBuffer_Unlock(chipBuffer, + ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2); + } + + //Start playing +// if (psg_on) + IDirectSoundBuffer_Play(chipBuffer, 0,0, DSBPLAY_LOOPING ); + } +IDirectSoundBuffer_Play(chipBuffer, 0,0, DSBPLAY_LOOPING ); +#endif +} + + + +void system_sound_shutdown(void) +{ +#ifdef _EMULATE_SOUND + if (chipBuffer) IDirectSoundBuffer_Stop(chipBuffer); + if (chipBuffer) IDirectSoundBuffer_Release(chipBuffer); + + if (primaryBuffer) IDirectSoundBuffer_Stop(primaryBuffer); + if (primaryBuffer) IDirectSoundBuffer_Release(primaryBuffer); + if (ds) IDirectSound_Release(ds); + if (buf1) free(buf1); +#endif +} + + +void system_sound_update(void) +{ +#ifdef _EMULATE_SOUND + LPDWORD null_ptr=NULL; + int pdwAudioBytes1, pdwAudioBytes2; + int Write, LengthSamples; + UINT16 *chipPtr1, *chipPtr2; + + // UNDEFINED write cursors + IDirectSoundBuffer_GetCurrentPosition(chipBuffer, 0, (LPDWORD)&Write); + if ((chipWrite == UNDEFINED) ) + { + lastChipWrite = chipWrite= Write - 128; + return; //Wait a frame to accumulate length. + } + + + //SN76496 Sound Chips + + if (Write < lastChipWrite) //Wrap? + lastChipWrite -= chipBufferLength; + + LengthSamples = (Write - lastChipWrite) / 2; + lastChipWrite = Write; + +/* if (psg_on)*/ { + pcm_updateOne(0,buf1,LengthSamples>>1); + + if SUCCEEDED(IDirectSoundBuffer_Lock( + chipBuffer, chipWrite, LengthSamples*2, + (LPVOID*)&chipPtr1, (LPDWORD)&pdwAudioBytes1, + (LPVOID*)&chipPtr2, (LPDWORD)&pdwAudioBytes2, 0)) + { + __asm { + cld + mov eax,buf1 + mov ebx,buf1 + mov edi,chipPtr1 + mov ecx,pdwAudioBytes1 + shr ecx,2 + +Copie1: mov esi,eax + movsw + add eax,2 + mov esi,ebx + movsw + add ebx,2 + loop Copie1 + + mov edi,chipPtr2 + cmp edi,0 + je End + mov ecx,pdwAudioBytes2 + shr ecx,2 + +Copie2: + mov esi,eax + movsw + add eax,2 + mov esi,ebx + movsw + add ebx,2 + loop Copie2 + +End: } + + + IDirectSoundBuffer_Unlock(chipBuffer, + chipPtr1, pdwAudioBytes1, chipPtr2, pdwAudioBytes2); + + chipWrite+= (LengthSamples * 2); + if (chipWrite> chipBufferLength) + chipWrite-= chipBufferLength; + } + else + { + DWORD status; + chipWrite= UNDEFINED; + IDirectSoundBuffer_GetStatus(chipBuffer, &status); + if (status & DSBSTATUS_BUFFERLOST) + { + if (IDirectSoundBuffer_Restore(chipBuffer) != DS_OK) return; + /*if (psg_on)*/ IDirectSoundBuffer_Play(chipBuffer, 0, 0, DSBPLAY_LOOPING); + } + } + } +#endif +} diff --git a/src/dsp.cpp b/src/dsp.cpp new file mode 100644 index 0000000..e80fcc7 --- /dev/null +++ b/src/dsp.cpp @@ -0,0 +1,3227 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#include "include/dsp.h" + +#define CINT0FLAG 0x00200 +#define CINT1FLAG 0x00400 +#define CINT2FLAG 0x00800 +#define CINT3FLAG 0x01000 +#define CINT4FLAG 0x02000 +#define CINT04FLAGS (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG) +#define CINT5FLAG 0x20000 /* DSP only */ + +extern uint32 jaguar_mainRom_crc32; + +static void dsp_opcode_addqmod(void); +static void dsp_opcode_subqmod(void); +static void dsp_opcode_mirror(void); +static void dsp_opcode_sat32s(void); +static void dsp_opcode_sat16s(void); +static void dsp_opcode_add(void); +static void dsp_opcode_addc(void); +static void dsp_opcode_addq(void); +static void dsp_opcode_addqt(void); +static void dsp_opcode_sub(void); +static void dsp_opcode_subc(void); +static void dsp_opcode_subq(void); +static void dsp_opcode_subqt(void); +static void dsp_opcode_neg(void); +static void dsp_opcode_and(void); +static void dsp_opcode_or(void); +static void dsp_opcode_xor(void); +static void dsp_opcode_not(void); +static void dsp_opcode_btst(void); +static void dsp_opcode_bset(void); +static void dsp_opcode_bclr(void); +static void dsp_opcode_mult(void); +static void dsp_opcode_imult(void); +static void dsp_opcode_imultn(void); +static void dsp_opcode_resmac(void); +static void dsp_opcode_imacn(void); +static void dsp_opcode_div(void); +static void dsp_opcode_abs(void); +static void dsp_opcode_sh(void); +static void dsp_opcode_shlq(void); +static void dsp_opcode_shrq(void); +static void dsp_opcode_sha(void); +static void dsp_opcode_sharq(void); +static void dsp_opcode_ror(void); +static void dsp_opcode_rorq(void); +static void dsp_opcode_cmp(void); +static void dsp_opcode_cmpq(void); +static void dsp_opcode_sat8(void); +static void dsp_opcode_sat16(void); +static void dsp_opcode_move(void); +static void dsp_opcode_moveq(void); +static void dsp_opcode_moveta(void); +static void dsp_opcode_movefa(void); +static void dsp_opcode_movei(void); +static void dsp_opcode_loadb(void); +static void dsp_opcode_loadw(void); +static void dsp_opcode_load(void); +static void dsp_opcode_loadp(void); +static void dsp_opcode_load_r14_indexed(void); +static void dsp_opcode_load_r15_indexed(void); +static void dsp_opcode_storeb(void); +static void dsp_opcode_storew(void); +static void dsp_opcode_store(void); +static void dsp_opcode_storep(void); +static void dsp_opcode_store_r14_indexed(void); +static void dsp_opcode_store_r15_indexed(void); +static void dsp_opcode_move_pc(void); +static void dsp_opcode_jump(void); +static void dsp_opcode_jr(void); +static void dsp_opcode_mmult(void); +static void dsp_opcode_mtoi(void); +static void dsp_opcode_normi(void); +static void dsp_opcode_nop(void); +static void dsp_opcode_load_r14_ri(void); +static void dsp_opcode_load_r15_ri(void); +static void dsp_opcode_store_r14_ri(void); +static void dsp_opcode_store_r15_ri(void); +static void dsp_opcode_sat24(void); + +uint8 dsp_opcode_cycles[64] = +{ + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 1, 3, + 1, 18, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 2, 2, + 2, 2, 3, 4, + 5, 4, 5, 6, + 6, 1, 1, 1, + 1, 2, 2, 2, + 1, 1, 9, 3, + 3, 1, 6, 6, + 2, 2, 3, 3 +}; + +void (*dsp_opcode[64])()= +{ + dsp_opcode_add, dsp_opcode_addc, dsp_opcode_addq, dsp_opcode_addqt, + dsp_opcode_sub, dsp_opcode_subc, dsp_opcode_subq, dsp_opcode_subqt, + dsp_opcode_neg, dsp_opcode_and, dsp_opcode_or, dsp_opcode_xor, + dsp_opcode_not, dsp_opcode_btst, dsp_opcode_bset, dsp_opcode_bclr, + dsp_opcode_mult, dsp_opcode_imult, dsp_opcode_imultn, dsp_opcode_resmac, + dsp_opcode_imacn, dsp_opcode_div, dsp_opcode_abs, dsp_opcode_sh, + dsp_opcode_shlq, dsp_opcode_shrq, dsp_opcode_sha, dsp_opcode_sharq, + dsp_opcode_ror, dsp_opcode_rorq, dsp_opcode_cmp, dsp_opcode_cmpq, + dsp_opcode_subqmod, dsp_opcode_sat16s, dsp_opcode_move, dsp_opcode_moveq, + dsp_opcode_moveta, dsp_opcode_movefa, dsp_opcode_movei, dsp_opcode_loadb, + dsp_opcode_loadw, dsp_opcode_load, dsp_opcode_sat32s, dsp_opcode_load_r14_indexed, + dsp_opcode_load_r15_indexed, dsp_opcode_storeb, dsp_opcode_storew, dsp_opcode_store, + dsp_opcode_mirror, dsp_opcode_store_r14_indexed, dsp_opcode_store_r15_indexed, dsp_opcode_move_pc, + dsp_opcode_jump, dsp_opcode_jr, dsp_opcode_mmult, dsp_opcode_mtoi, + dsp_opcode_normi, dsp_opcode_nop, dsp_opcode_load_r14_ri, dsp_opcode_load_r15_ri, + dsp_opcode_store_r14_ri, dsp_opcode_store_r15_ri, dsp_opcode_nop, dsp_opcode_addqmod, +}; + +uint32 dsp_opcode_use[64]; + +char *dsp_opcode_str[64]= +{ + "add", "addc", "addq", "addqt", + "sub", "subc", "subq", "subqt", + "neg", "and", "or", "xor", + "not", "btst", "bset", "bclr", + "mult", "imult", "imultn", "resmac", + "imacn", "div", "abs", "sh", + "shlq", "shrq", "sha", "sharq", + "ror", "rorq", "cmp", "cmpq", + "subqmod", "sat16s", "move", "moveq", + "moveta", "movefa", "movei", "loadb", + "loadw", "load", "sat32s", "load_r14_indexed", + "load_r15_indexed", "storeb", "storew", "store", + "mirror", "store_r14_indexed","store_r15_indexed","move_pc", + "jump", "jr", "mmult", "mtoi", + "normi", "nop", "load_r14_ri", "load_r15_ri", + "store_r14_ri", "store_r15_ri", "nop", "addqmod", +}; + +static uint16 *mirror_table; +static uint8 *dsp_ram_8; + + +static uint32 dsp_pc; +static uint32 dsp_acc; +static uint32 dsp_remain; +static uint32 dsp_modulo; +static uint32 dsp_flags; +static uint32 dsp_matrix_control; +static uint32 dsp_pointer_to_matrix; +static uint32 dsp_data_organization; +static uint32 dsp_control; +static uint32 dsp_div_control; +static uint8 dsp_flag_z; +static uint8 dsp_flag_n; +static uint8 dsp_flag_c; +static uint8 dsp_alternate_flag_z; +static uint8 dsp_alternate_flag_n; +static uint8 dsp_alternate_flag_c; +static uint32 *dsp_reg; +static uint32 *dsp_alternate_reg; +static uint32 *dsp_reg_bank_0; +static uint32 *dsp_reg_bank_1; + +static uint32 dsp_opcode_first_parameter; +static uint32 dsp_opcode_second_parameter; + +#define dsp_running (dsp_control&0x01) + +#define Rm dsp_reg[dsp_opcode_first_parameter] +#define Rn dsp_reg[dsp_opcode_second_parameter] +#define alternate_Rm dsp_alternate_reg[dsp_opcode_first_parameter] +#define alternate_Rn dsp_alternate_reg[dsp_opcode_second_parameter] +#define imm_1 dsp_opcode_first_parameter +#define imm_2 dsp_opcode_second_parameter + +#define set_flag_z(r) dsp_flag_z=(r==0); +#define set_flag_n(r) dsp_flag_n=(r&0x80000000); + +#define reset_flag_z() dsp_flag_z=0; +#define reset_flag_n() dsp_flag_n=0; +#define reset_flag_c() dsp_flag_c=0; + +uint32 dsp_convert_zero[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 }; +uint8 *dsp_branch_condition_table=0; +#define branch_condition(x) dsp_branch_condition_table[(x) + ((jaguar_flags & 7) << 5)] + +static uint32 dsp_in_exec=0; +static uint32 dsp_releaseTimeSlice_flag=0; + +FILE *dsp_fp; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_reset_stats(void) +{ + for (uint32 i=0;i<64;i++) + dsp_opcode_use[i]=0; +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_releaseTimeslice(void) +{ + dsp_releaseTimeSlice_flag=1; +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_build_branch_condition_table(void) +{ + int i,j; + #define ZFLAG 0x00001 + #define CFLAG 0x00002 + #define NFLAG 0x00004 + + /* allocate the mirror table */ + if (!mirror_table) + mirror_table = (uint16*)malloc(65536 * sizeof(mirror_table[0])); + + /* fill in the mirror table */ + if (mirror_table) + for (int i = 0; i < 65536; i++) + mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) | + ((i >> 11) & 0x0004) | ((i >> 9) & 0x0008) | + ((i >> 7) & 0x0010) | ((i >> 5) & 0x0020) | + ((i >> 3) & 0x0040) | ((i >> 1) & 0x0080) | + ((i << 1) & 0x0100) | ((i << 3) & 0x0200) | + ((i << 5) & 0x0400) | ((i << 7) & 0x0800) | + ((i << 9) & 0x1000) | ((i << 11) & 0x2000) | + ((i << 13) & 0x4000) | ((i << 15) & 0x8000); + + if (!dsp_branch_condition_table) + { + dsp_branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(dsp_branch_condition_table[0])); + + /* fill in the condition table */ + if (dsp_branch_condition_table) + for (i = 0; i < 8; i++) + for (j = 0; j < 32; j++) + { + int result = 1; + if (j & 1) + if (i & ZFLAG) result = 0; + if (j & 2) + if (!(i & ZFLAG)) result = 0; + if (j & 4) + if (i & (CFLAG << (j >> 4))) result = 0; + if (j & 8) + if (!(i & (CFLAG << (j >> 4)))) result = 0; + dsp_branch_condition_table[i * 32 + j] = result; + } + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +unsigned dsp_byte_read(unsigned int offset) +{ +// battlemorph +// if ((offset==0xF1CFE0)||(offset==0xF1CFE2)) +// return(0xffff); + // mutant penguin + if ((jaguar_mainRom_crc32==0xbfd751a4)||(jaguar_mainRom_crc32==0x053efaf9)) + { + if (offset==0xF1CFE0) + return(0xff); + } + if ((offset>=dsp_work_ram_base)&&(offset=dsp_control_ram_base)&&(offset>24); + else + if ((offset&0x03)==1) + return((data>>16)&0xff); + else + if ((offset&0x03)==2) + return((data>>8)&0xff); + else + if ((offset&0x03)==3) + return(data&0xff); + } + return(jaguar_byte_read(offset)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +unsigned dsp_word_read(unsigned int offset) +{ + offset&=0xFFFFFFFE; + // jaguar cd bios + if (jaguar_mainRom_crc32==0xa74a97cd) + { + if (offset==0xF1A114) return(0x0000); + if (offset==0xF1A116) return(0x0000); + if (offset==0xF1B000) return(0x1234); + if (offset==0xF1B002) return(0x5678); + } +/* + if (jaguar_mainRom_crc32==0x7ae20823) + { + if (offset==0xF1B9D8) return(0x0000); + if (offset==0xF1B9Da) return(0x0000); + if (offset==0xF1B2C0) return(0x0000); + if (offset==0xF1B2C2) return(0x0000); + } +*/ + // pour permettre à wolfenstein 3d de tourner sans le dsp +/* if ((offset==0xF1B0D0)||(offset==0xF1B0D2)) + return(0); +*/ + + // pour permettre à nba jam de tourner sans le dsp + if (jaguar_mainRom_crc32==0x4faddb18) + { + if (offset==0xf1b2c0) return(0); + if (offset==0xf1b2c2) return(0); + if (offset==0xf1b240) return(0); + if (offset==0xf1b242) return(0); + if (offset==0xF1B340) return(0); + if (offset==0xF1B342) return(0); + if (offset==0xF1BAD8) return(0); + if (offset==0xF1BADA) return(0); + if (offset==0xF1B040) return(0); + if (offset==0xF1B042) return(0); + if (offset==0xF1B0C0) return(0); + if (offset==0xF1B0C2) return(0); + if (offset==0xF1B140) return(0); + if (offset==0xF1B142) return(0); + if (offset==0xF1B1C0) return(0); + if (offset==0xF1B1C2) return(0); + } + + if ((offset>=dsp_work_ram_base)&&(offset=dsp_control_ram_base)&&(offset>16); + } + return(jaguar_word_read(offset)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +unsigned dsp_long_read(unsigned int offset) +{ + offset&=0xFFFFFFFC; + + if ((offset>=dsp_work_ram_base)&&(offset=dsp_control_ram_base)&&(offset= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + { + offset -= dsp_work_ram_base; + dsp_ram_8[offset] = data; + if (dsp_in_exec == 0) + { +// s68000releaseTimeslice(); + m68k_end_timeslice(); + gpu_releaseTimeslice(); + } + return; + } + if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + { + uint32 reg = offset & 0x1C; + int bytenum = offset & 0x03; + + if ((reg >= 0x1C) && (reg <= 0x1F)) + dsp_div_control = (dsp_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3)); + else + { + uint32 old_data = dsp_long_read(offset&0xFFFFFFC); + bytenum = 3 - bytenum; // convention motorola !!! + old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3)); + dsp_long_write(offset & 0xFFFFFFC, old_data); + } + return; + } +// fprintf(log_get(),"dsp: writing %.2x at 0x%.8x\n",data,offset); + jaguar_byte_write(offset, data); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_word_write(unsigned offset, unsigned data) +{ + offset &= 0xFFFFFFFE; +// fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset); + if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + { + offset -= dsp_work_ram_base; + dsp_ram_8[offset] = data >> 8; + dsp_ram_8[offset+1] = data & 0xFF; + if (dsp_in_exec == 0) + { +// fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset+dsp_work_ram_base); +// s68000releaseTimeslice(); + m68k_end_timeslice(); + gpu_releaseTimeslice(); + } + return; + } + else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + { + if ((offset & 0x1C) == 0x1C) + { + if (offset & 0x03) + dsp_div_control = (dsp_div_control&0xffff0000)|(data&0xffff); + else + dsp_div_control = (dsp_div_control&0xffff)|((data&0xffff)<<16); + } + else + { + uint32 old_data = dsp_long_read(offset & 0xffffffc); + if (offset & 0x03) + old_data = (old_data&0xffff0000)|(data&0xffff); + else + old_data = (old_data&0xffff)|((data&0xffff)<<16); + dsp_long_write(offset & 0xffffffc, old_data); + } + return; + } + jaguar_word_write(offset, data); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_long_write(unsigned offset, unsigned data) +{ + offset &= 0xFFFFFFFC; +// fprintf(log_get(),"dsp: writing %.8x at 0x%.8x\n",data,offset); + if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + { + offset -= dsp_work_ram_base; + dsp_ram_8[offset] = data >> 24; + dsp_ram_8[offset+1] = (data>>16) & 0xFF; + dsp_ram_8[offset+2] = (data>>8) & 0xFF; + dsp_ram_8[offset+3] = data & 0xFF; + return; + } + else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + { + offset&=0x1f; + switch (offset) + { + case 0x00: + dsp_flags = data; + dsp_flag_z = dsp_flags & 0x01; + dsp_flag_c = (dsp_flags>>1) & 0x01; + dsp_flag_n = (dsp_flags>>2) & 0x01; + dsp_update_register_banks(); + dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3); + dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1); + dsp_check_irqs(); + break; + case 0x04: + dsp_matrix_control = data; + break; + case 0x08: + dsp_pointer_to_matrix = data; + break; + case 0x0C: + dsp_data_organization = data; + break; + case 0x10: + dsp_pc = data; + break; + case 0x14: + { + uint32 dsp_was_running = dsp_running; + // check for DSP->CPU interrupt + if (data & 0x02) + { +// fprintf(log_get(),"DSP->CPU interrupt\n"); + if (tom_irq_enabled(IRQ_GPU) && jaguar_interrupt_handler_is_valid(64)) + { + tom_set_pending_gpu_int(); +// s68000interrupt(7,64); +// s68000flushInterrupts(); + m68k_set_irq(7); // Set 68000 NMI... + dsp_releaseTimeslice(); + } + data &= ~(0x02); + } + // check for CPU->DSP interrupt + if (data & 0x04) + { +// fprintf(log_get(),"CPU->DSP interrupt\n"); + dsp_set_irq_line(0, 1); +// s68000releaseTimeslice(); + m68k_end_timeslice(); + gpu_releaseTimeslice(); + data &= ~(0x04); + } + // single stepping + if (data & 0x10) + { + //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not "); + } + dsp_control = data; + + // if dsp wasn't running but is now running + // execute a few cycles +#ifndef DSP_SINGLE_STEPPING + if (!dsp_was_running && dsp_running) + { + dsp_exec(200); + } +#else + if (dsp_control & 0x18) + dsp_exec(1); +#endif + break; + } + case 0x18: + dsp_modulo = data; + break; + case 0x1C: + dsp_div_control=data; + break; +// default: // unaligned long read + //__asm int 3 + } + return; + } + jaguar_word_write(offset, (data>>16) & 0xFFFF); + jaguar_word_write(offset+2, data & 0xFFFF); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 * jaguar_rom_load(char * path, uint32 * romSize); +void dsp_load_bin_at(char * path, uint32 offset) +{ + uint32 romSize; + uint8 * rom; + + rom = jaguar_rom_load(path, &romSize); + for(uint32 i=0; i0) + return; + + count=4; + // already in an interrupt handler ? + if (dsp_flags & 0x8) + return; + + // get the interrupt mask + mask = (dsp_flags >> 4) & 0x1f; + mask |= (dsp_flags >> 11) & 0x20; + + if (mask & 0x02) + { + dsp_set_irq_line(1,1); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_check_irqs(void) +{ + int bits, mask, which = 0; + + if (dsp_flags & 0x8) + return; + + // get the active interrupt bits + bits = (dsp_control >> 6) & 0x1f; + bits |= (dsp_control >> 10) & 0x20; + + // get the interrupt mask + mask = (dsp_flags >> 4) & 0x1f; + mask |= (dsp_flags >> 11) & 0x20; + +// fprintf(log_get(),"dsp: bits=%.2x mask=%.2x\n",bits,mask); + // bail if nothing is available + bits &= mask; + + if (!bits) + return; + + // determine which interrupt + if (bits & 0x01) which = 0; + if (bits & 0x02) which = 1; + if (bits & 0x04) which = 2; + if (bits & 0x08) which = 3; + if (bits & 0x10) which = 4; + if (bits & 0x20) which = 5; + +// fprintf(log_get(),"dsp: generating interrupt %i\n",which); + + dsp_flags |= 0x08; + dsp_update_register_banks(); + + // subqt #4,r31 ; pre-decrement stack pointer + // move pc,r30 ; address of interrupted code + // store r30,(r31) ; store return address + dsp_reg[31] -= 4; + dsp_reg[30]=dsp_pc; + dsp_long_write(dsp_reg[31], dsp_pc - 2); + + // movei #service_address,r30 ; pointer to ISR entry + // jump (r30) ; jump to ISR + // nop + dsp_pc = dsp_work_ram_base; + dsp_pc += which * 0x10; + dsp_reg[30]=dsp_pc; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_set_irq_line(int irqline, int state) +{ + int mask = 0x40 << irqline; + dsp_control &= ~mask; + if (state) + { + dsp_control |= mask; + dsp_check_irqs(); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_init(void) +{ + memory_malloc_secure((void**)&dsp_ram_8,0x2000,"dsp work ram"); + memory_malloc_secure((void**)&dsp_reg,32*sizeof(int32),"dsp bank 0 regs"); + memory_malloc_secure((void**)&dsp_alternate_reg,32*sizeof(int32),"dsp bank 1 regs"); + + dsp_build_branch_condition_table(); + + dsp_reset(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_reset(void) +{ + dsp_pc = 0x00f1b000; + dsp_acc = 0x00000000; + dsp_remain = 0x00000000; + dsp_modulo = 0xFFFFFFFF; + dsp_flags = 0x00040000; + dsp_matrix_control = 0x00000000; + dsp_pointer_to_matrix = 0x00000000; + dsp_data_organization = 0xffffffff; + dsp_control = 0x00012800; + dsp_div_control = 0x00000000; + dsp_in_exec = 0; + + for (int i=0;i<32;i++) + { + dsp_reg[i] = 0x00000000; + dsp_alternate_reg[i] = 0x00000000; + } + + dsp_reg_bank_0 = dsp_reg; + dsp_reg_bank_1 = dsp_alternate_reg; +// dsp_reg_bank_1 = dsp_reg; +// dsp_reg_bank_0 = dsp_alternate_reg; + + reset_flag_z(); + reset_flag_n(); + reset_flag_c(); + + dsp_alternate_flag_z=0; + dsp_alternate_flag_n=0; + dsp_alternate_flag_c=0; + + dsp_reset_stats(); + + memset(dsp_ram_8, 0xff, 0x2000); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_done(void) +{ + int i, j; + fprintf(log_get(),"dsp: stopped at pc=0x%.8x dsp_modulo=0x%.8x(dsp %s running)\n",dsp_pc,dsp_modulo,dsp_running?"was":"wasn't"); + fprintf(log_get(),"dsp: %sin interrupt handler\n",(dsp_flags & 0x8)?"":"not "); + int bits, mask; + + // get the active interrupt bits + bits = (dsp_control >> 6) & 0x1f; + bits |= (dsp_control >> 10) & 0x20; + + // get the interrupt mask + mask = (dsp_flags >> 4) & 0x1f; + mask |= (dsp_flags >> 11) & 0x20; + + fprintf(log_get(),"dsp: bits=0x%.8x mask=0x%.8x\n",bits,mask); + fprintf(log_get(),"\nregisters bank 0\n"); + for (int j=0;j<8;j++) + { + fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n", + (j<<2)+0,dsp_reg[(j<<2)+0], + (j<<2)+1,dsp_reg[(j<<2)+1], + (j<<2)+2,dsp_reg[(j<<2)+2], + (j<<2)+3,dsp_reg[(j<<2)+3]); + + } +// fprintf(log_get(),"registers bank 1\n"); +// for (j=0;j<8;j++) +// { +// fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n", +// (j<<2)+0,dsp_alternate_reg[(j<<2)+0], +// (j<<2)+1,dsp_alternate_reg[(j<<2)+1], +// (j<<2)+2,dsp_alternate_reg[(j<<2)+2], +// (j<<2)+3,dsp_alternate_reg[(j<<2)+3]); +// +// } + static char buffer[512]; + j=dsp_work_ram_base; + for (int i=0;i<4096;i++) + { + uint32 oldj=j; + j+=dasmjag(JAGUAR_DSP,buffer,j); +// fprintf(log_get(),"\t0x%.8x: %s\n",oldj,buffer); + } + +/* + fprintf(log_get(),"dsp opcodes use:\n"); + for (i=0;i<64;i++) + { + if (dsp_opcode_use[i]) + fprintf(log_get(),"\t%s %i\n",dsp_opcode_str[i],dsp_opcode_use[i]); + } +*/ + memory_free(dsp_ram_8); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void dsp_exec(int32 cycles) +{ + if ((cycles!=1)&&(jaguar_mainRom_crc32==0xba74c3ed)) + dsp_check_if_i2s_interrupt_needed(); + +#ifdef DSP_SINGLE_STEPPING + if (dsp_control&0x18) + { + cycles=1; + dsp_control&=~0x10; + } +#endif + dsp_check_irqs(); + dsp_releaseTimeSlice_flag=0; + dsp_in_exec++; + while ((cycles>0)&&(dsp_running)) + { + dsp_flag_c=(dsp_flag_c?1:0); + dsp_flag_z=(dsp_flag_z?1:0); + dsp_flag_n=(dsp_flag_n?1:0); + + +/* + if (dsp_pc==0x00f1b02c) + { + if (dsp_fp) + { + fclose(dsp_fp); + exit(0); + } + } + else + if (dsp_pc==0x00f1b032) + { + dsp_fp=fopen("c:\\bad.log","wrt"); + if (dsp_fp==NULL) + MessageBox(NULL,"Cannot open dsp log","",MB_OK); + } + if (dsp_fp) + { + fprintf(dsp_fp,"0x%.8x\n",dsp_pc); + } + +// if (dsp_pc==0x00f1b130) +// dsp_load_bin_at("SCHRIFT.DAT",0x120000); +*/ + uint16 opcode=dsp_word_read(dsp_pc); + dsp_opcode_first_parameter=(opcode&0x3e0)>>5; + dsp_opcode_second_parameter=(opcode&0x1f); + dsp_pc+=2; + dsp_opcode[opcode>>10](); + dsp_opcode_use[opcode>>10]++; + cycles-=dsp_opcode_cycles[opcode>>10]; + } + dsp_in_exec--; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_jump(void) +{ + uint32 delayed_pc = Rm; + uint32 jaguar_flags; + + // normalize flags + dsp_flag_c=dsp_flag_c?1:0; + dsp_flag_z=dsp_flag_z?1:0; + dsp_flag_n=dsp_flag_n?1:0; + + jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z; + + if (branch_condition(imm_2)) + { + dsp_exec(1); + dsp_pc=delayed_pc; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_jr(void) +{ + int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1; + + int32 delayed_pc = dsp_pc + (offset * 2); + uint32 jaguar_flags; + + // normalize flags + dsp_flag_c=dsp_flag_c?1:0; + dsp_flag_z=dsp_flag_z?1:0; + dsp_flag_n=dsp_flag_n?1:0; + + jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z; + + if (branch_condition(imm_2)) + { + dsp_exec(1); + dsp_pc=delayed_pc; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_add(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + #ifdef __GCCWIN32__ + asm( + "addl %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + asm( + "addl %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + #endif + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + add eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_addc(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + We use __GCCWIN32__ for this "bug". + */ + + #ifdef __GCCWIN32__ + + asm( + "addl %1, %2 + cmp $0, _dsp_flag_c + clc + jz 1f + stc + 1: + adc %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + #else + + asm( + "addl %1, %2 + cmp $0, dsp_flag_c + clc + jz 1f + stc + 1: + adc %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + cmp [dsp_flag_c],0 + clc + jz dsp_opcode_addc_no_carry + stc +dsp_opcode_addc_no_carry: + adc eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_addq(void) +{ + uint32 _Rn=Rn; + uint32 _Rm=dsp_convert_zero[imm_1]; + uint32 res; + +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "addl %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "addl %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + add eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sub(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "subl %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "subl %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + sub eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_subc(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "addl %1, %2 + cmp $0, _dsp_flag_c + clc + jz 1f + stc + 1: + sbb %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "addl %1, %2 + cmp $0, dsp_flag_c + clc + jz 1f + stc + 1: + sbb %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + cmp [dsp_flag_c],0 + clc + jz dsp_opcode_subc_no_carry + stc +dsp_opcode_subc_no_carry: + sbb eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_subq(void) +{ + uint32 _Rm=dsp_convert_zero[imm_1]; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "subl %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "subl %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + sub eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_cmp(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "cmpl %0, %1 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + " + : + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "cmpl %0, %1 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + " + : + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + cmp eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + }; +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_cmpq(void) +{ + static int32 sqtable[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1}; + int32 _Rm=sqtable[imm_1&0x1f]; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "cmpl %0, %1 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + " + : + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "cmpl %0, %1 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + " + : + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + cmp eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + }; +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_and(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "andl %1, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "andl %1, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + and eax,edx + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_or(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "orl %1, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "orl %1, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + or eax,edx + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_xor(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "xorl %1, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "xorl %1, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + xor eax,edx + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_not(void) +{ + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "notl %1 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "a"(_Rn)); + + #else + + asm( + "notl %1 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + not eax + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_move_pc(void) +{ + Rn = dsp_pc-2; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sat8(void) +{ + int32 _Rn=(int32)Rn; + + uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn); + set_flag_z(res); + reset_flag_n(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sat16(void) +{ + uint32 _Rn=Rn; + uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn); + set_flag_z(res); + reset_flag_n(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sat24(void) +{ + uint32 _Rn=Rn; + + uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn); + set_flag_z(res); + reset_flag_n(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_store_r14_indexed(void) +{ + dsp_long_write( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2),Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_store_r15_indexed(void) +{ + dsp_long_write( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2),Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_load_r14_ri(void) +{ + Rn=dsp_long_read(dsp_reg[14] + Rm); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_load_r15_ri(void) +{ + Rn=dsp_long_read(dsp_reg[15] + Rm); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_store_r14_ri(void) +{ + dsp_long_write(dsp_reg[14] + Rm,Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_store_r15_ri(void) +{ + dsp_long_write(dsp_reg[15] + Rm,Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_nop(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_pack(void) +{ + uint32 _Rn=Rn; + + if (Rm==0) + { + Rn =((_Rn & 0x03C00000) >> 10) | + ((_Rn & 0x0001E000) >> 5) | + ((_Rn & 0x000000FF)); + } + else + { + Rn =((_Rn & 0x0000F000) << 10) | + ((_Rn & 0x00000F00) << 5) | + ((_Rn & 0x000000FF)); + } + reset_flag_z(); + reset_flag_n(); + set_flag_z(Rn); + set_flag_n(Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_storeb(void) +{ + if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + dsp_long_write(Rm,Rn&0xff); + else + jaguar_byte_write(Rm,Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_storew(void) +{ + if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + dsp_long_write(Rm,Rn&0xffff); + else + jaguar_word_write(Rm,Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_store(void) +{ + dsp_long_write(Rm,Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_loadb(void) +{ + if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + Rn=dsp_long_read(Rm)&0xff; + else + Rn=jaguar_byte_read(Rm); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_loadw(void) +{ + if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + Rn=dsp_long_read(Rm)&0xffff; + else + Rn=jaguar_word_read(Rm); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_load(void) +{ + Rn = dsp_long_read(Rm); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_load_r14_indexed(void) +{ + Rn = dsp_long_read( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_load_r15_indexed(void) +{ + Rn = dsp_long_read( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_movei(void) +{ + Rn = ((uint32)dsp_word_read(dsp_pc)) + (((uint32)dsp_word_read(dsp_pc+2))<<16); + dsp_pc+=4; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_moveta(void) +{ + alternate_Rn = Rm; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_movefa(void) +{ + Rn = alternate_Rm; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_move(void) +{ + Rn = Rm; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_moveq(void) +{ + Rn = imm_1; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_resmac(void) +{ + Rn = dsp_acc; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_imult(void) +{ + uint32 res=Rn=((int16)Rn)*((int16)Rm); + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_mult(void) +{ + uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn); + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_bclr(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "btrl %1, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "btrl %1, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #endif + + +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + btr eax,ecx + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_btst(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "bt %0, %1 + setnc _dsp_flag_z + " + : + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "bt %0, %1 + setnc dsp_flag_z + " + : + : "c"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + bt eax,ecx + setnc [dsp_flag_z] + }; +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_bset(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "btsl %1, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "btsl %1, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + bts eax,ecx + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_subqt(void) +{ + Rn -= dsp_convert_zero[imm_1]; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_addqt(void) +{ + Rn += dsp_convert_zero[imm_1]; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_imacn(void) +{ + uint32 res=((int16)Rm) * ((int16)(Rn)); + dsp_acc += res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_mtoi(void) +{ + uint32 _Rm=Rm; + uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff); + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_normi(void) +{ + uint32 _Rm = Rm; + uint32 res = 0; + + if (_Rm) + { + while ((_Rm & 0xffc00000) == 0) + { + _Rm <<= 1; + res--; + } + while ((_Rm & 0xff800000) != 0) + { + _Rm >>= 1; + res++; + } + } + Rn = res; + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_mmult(void) +{ + int count = dsp_matrix_control&0x0f; + uint32 addr = dsp_pointer_to_matrix; // in the gpu ram + int64 accum = 0; + uint32 res; + + if (!(dsp_matrix_control & 0x10)) + { + for (int i = 0; i < count; i++) + { + int16 a; + if (i&0x01) + a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff); + else + a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff); + int16 b=((int16)dsp_word_read(addr+2)); + accum += a*b; + addr += 4; + } + } + else + { + for (int i = 0; i < count; i++) + { + int16 a; + if (i&0x01) + a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff); + else + a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff); + int16 b=((int16)dsp_word_read(addr+2)); + accum += a*b; + addr += 4 * count; + } + } + Rn = res = (int32)accum; + // carry flag to do + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_abs(void) +{ + uint32 _Rn=Rn; + uint32 res; + + if (_Rn==0x80000000) + { + set_flag_n(1); + } + else + { + dsp_flag_c = ((_Rn&0x80000000)>>31); + res= Rn = (_Rn & 0x80000000) ? -_Rn : _Rn; + reset_flag_n(); + set_flag_z(res); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_div(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + + if (_Rm) + { + if (dsp_div_control & 1) + { + dsp_remain = (((uint64)_Rn) << 16) % _Rm; + if (dsp_remain&0x80000000) + dsp_remain-=_Rm; + Rn = (((uint64)_Rn) << 16) / _Rm; + } + else + { + dsp_remain = _Rn % _Rm; + if (dsp_remain&0x80000000) + dsp_remain-=_Rm; + Rn/=_Rm; + } + } + else + Rn=0xffffffff; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_imultn(void) +{ + uint32 res=(int32)(((int16)Rn)*((int16)Rm)); + dsp_acc=(int32)res; + set_flag_z(res); + set_flag_n(res); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_neg(void) +{ + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + " + subl %1, %2 + setc _dsp_flag_c + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rn), "a"(0)); + + #else + + asm( + " + subl %1, %2 + setc dsp_flag_c + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "d"(_Rn), "a"(0)); + + #endif + +#else + __asm + { + xor eax,eax + mov edx,_Rn + sub eax,edx + setc [dsp_flag_c] + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + }; +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_shlq(void) +{ + uint32 shift=(32-dsp_convert_zero[imm_1]); + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 + setnz _dsp_flag_c + shl %%cl, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x80000000, %2 + setnz dsp_flag_c + shl %%cl, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [dsp_flag_c] + shl eax,cl + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + } +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_shrq(void) +{ + uint32 shift=dsp_convert_zero[imm_1]; + uint32 _Rn=Rn; + + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x00000001, %2 + setnz _dsp_flag_c + shr %%cl, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x00000001, %2 + setnz dsp_flag_c + shr %%cl, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x00000001 + setnz [dsp_flag_c] + shr eax,cl + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + } +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_ror(void) +{ + uint32 shift=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 + setnz _dsp_flag_c + ror %%cl, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x80000000, %2 + setnz dsp_flag_c + ror %%cl, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [dsp_flag_c] + ror eax,cl + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + } +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_rorq(void) +{ + uint32 shift=dsp_convert_zero[imm_1&0x1f]; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 + setnz _dsp_flag_c + ror %%cl, %2 + cmpl $0, %2 + setz _dsp_flag_z + sets _dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x80000000, %2 + setnz dsp_flag_c + ror %%cl, %2 + cmpl $0, %2 + setz dsp_flag_z + sets dsp_flag_n + movl %%eax, %0 + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [dsp_flag_c] + ror eax,cl + cmp eax,0 + setz [dsp_flag_z] + sets [dsp_flag_n] + mov res,eax + } +#endif + Rn=res; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sha(void) +{ + int32 sRm=(int32)Rm; + uint32 _Rn=Rn; + + if (sRm<0) + { + uint32 shift=-sRm; + if (shift>=32) shift=32; + dsp_flag_c=(_Rn&0x80000000)>>31; + while (shift) + { + _Rn<<=1; + shift--; + } + } + else + { + uint32 shift=sRm; + if (shift>=32) shift=32; + dsp_flag_c=_Rn&0x1; + while (shift) + { + _Rn=((int32)_Rn)>>1; + shift--; + } + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sharq(void) +{ + uint32 shift=dsp_convert_zero[imm_1]; + uint32 _Rn=Rn; + + dsp_flag_c = (_Rn & 0x1); + while (shift) + { + _Rn=((int32)_Rn)>>1; + shift--; + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static void dsp_opcode_sh(void) +{ + int32 sRm=(int32)Rm; + uint32 _Rn=Rn; + + if (sRm<0) + { + uint32 shift=(-sRm); + if (shift>=32) shift=32; + dsp_flag_c=(_Rn&0x80000000)>>31; + while (shift) + { + _Rn<<=1; + shift--; + } + } + else + { + uint32 shift=sRm; + if (shift>=32) shift=32; + dsp_flag_c=_Rn&0x1; + while (shift) + { + _Rn>>=1; + shift--; + } + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} + +#define CLR_ZN { dsp_flag_n=0; dsp_flag_z=0; }; +#define CLR_ZNC { dsp_flag_c=0; dsp_flag_n=0; dsp_flag_z=0; }; +#define SET_Z(r) (dsp_flag_z= ((r) == 0)) +#define SET_C_ADD(a,b) (dsp_flag_c= ((UINT32)(b) > (UINT32)(~(a))) << 1) +#define SET_C_SUB(a,b) (dsp_flag_c= ((UINT32)(b) > (UINT32)(a)) << 1) +#define SET_N(r) (dsp_flag_n= (((UINT32)(r) >> 29) & 4)) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) + +void dsp_opcode_addqmod(void) +{ + UINT32 r1 = dsp_convert_zero[imm_1]; + UINT32 r2 = Rn; + UINT32 res = r2 + r1; + res = (res & (~dsp_modulo)) | (r2 & dsp_modulo); + Rn = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res); +} +void dsp_opcode_subqmod(void) +{ + UINT32 r1 = dsp_convert_zero[imm_1]; + UINT32 r2 = Rn; + UINT32 res = r2 - r1; + res = (res & (~dsp_modulo)) | (r2 & dsp_modulo); + Rn = res; + + SET_ZNC_SUB(r2,r1,res); +} +void dsp_opcode_mirror(void) +{ + UINT32 r1 = Rn; + UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16]; + Rn = res; + CLR_ZN; SET_ZN(res); +} +void dsp_opcode_sat32s(void) +{ + INT32 r2 = (UINT32)Rn; + INT32 temp = dsp_acc >> 32; + UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2; + Rn = res; + CLR_ZN; SET_ZN(res); +} +void dsp_opcode_sat16s(void) +{ + INT32 r2 = Rn; + UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2; + Rn = res; + CLR_ZN; SET_ZN(res); +} diff --git a/src/eeprom.cpp b/src/eeprom.cpp new file mode 100644 index 0000000..f6e66bb --- /dev/null +++ b/src/eeprom.cpp @@ -0,0 +1,428 @@ +#include "eeprom.h" + +#define eeprom_LOG + +static uint16 eeprom_ram[64]; + +void eeprom_set_di(uint32 state); +void eeprom_set_cs(uint32 state); +uint32 eeprom_get_do(void); + +#define EE_STATE_START 1 +#define EE_STATE_OP_A 2 +#define EE_STATE_OP_B 3 +#define EE_STATE_0 4 +#define EE_STATE_1 5 +#define EE_STATE_2 6 +#define EE_STATE_3 7 +#define EE_STATE_0_0 8 +#define EE_READ_ADDRESS 9 +#define EE_STATE_0_0_0 10 +#define EE_STATE_0_0_1 11 +#define EE_STATE_0_0_2 12 +#define EE_STATE_0_0_3 13 +#define EE_STATE_0_0_1_0 14 +#define EE_READ_DATA 15 +#define EE_STATE_BUSY 16 +#define EE_STATE_1_0 17 +#define EE_STATE_1_1 18 +#define EE_STATE_2_0 19 +#define EE_STATE_3_0 20 + +uint16 jerry_ee_state = EE_STATE_START; +uint16 jerry_ee_op = 0; +uint16 jerry_ee_rstate = 0; +uint16 jerry_ee_address_data = 0; +uint16 jerry_ee_address_cnt = 6; +uint16 jerry_ee_data = 0; +uint16 jerry_ee_data_cnt = 16; +uint16 jerry_writes_enabled = 0; +uint16 jerry_ee_direct_jump = 0; +FILE * jerry_ee_fp; +extern char * jaguar_boot_dir; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_init(void) +{ + static char eeprom_filename[256]; + sprintf(eeprom_filename,"%s\\%s%.8x.eep",jaguar_boot_dir,jaguar_eeproms_path,jaguar_mainRom_crc32); + jerry_ee_fp=fopen(eeprom_filename,"rb"); + if (jerry_ee_fp) + { + fread(eeprom_ram,1,128,jerry_ee_fp); + fclose(jerry_ee_fp); + fprintf(log_get(),"eeprom: loaded from %s\n",eeprom_filename); + jerry_ee_fp=fopen(eeprom_filename,"wrb"); + } + else + { + fprintf(log_get(),"eeprom: creating %s\n",eeprom_filename); + jerry_ee_fp=fopen(eeprom_filename,"wb"); + if (jerry_ee_fp==NULL) + fprintf(log_get(),"eeprom: could not open/create %s\n",eeprom_filename); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_reset(void) +{ + if (jerry_ee_fp==NULL) + memset(eeprom_ram,0xff,64*2); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_done(void) +{ + if (jerry_ee_fp) + { + fwrite(eeprom_ram,1,128,jerry_ee_fp); + fclose(jerry_ee_fp); + } + else + fprintf(log_get(),"eeprom: not saved\n"); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_byte_write(uint32 offset, uint8 data) +{ + switch (offset) + { + case 0xf14001: break; + case 0xf14801: eeprom_set_di(data&0x01); break; + case 0xf15001: eeprom_set_cs(1); break; +// default: fprintf(log_get(),"eeprom: unmapped 0x%.8x\n",offset); break; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_word_write(uint32 offset, uint16 data) +{ + eeprom_byte_write(offset+0,(data>>8)&0xff); + eeprom_byte_write(offset+1,(data&0xff)); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 eeprom_byte_read(uint32 offset) +{ + switch (offset) + { + case 0xf14001: return(eeprom_get_do()); break; + case 0xf14801: break; + case 0xf15001: eeprom_set_cs(1); break; +// default: fprintf(log_get(),"eeprom: unmapped 0x%.8x\n",offset); break; + } + return(0x00); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 eeprom_word_read(uint32 offset) +{ + uint16 data=eeprom_byte_read(offset+0); + data<<=8; + data|=eeprom_byte_read(offset+1); + return(data); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_set_di(uint32 data) +{ +// fprintf(log_get(),"eeprom: di=%i\n",data); +// fprintf(log_get(),"eeprom: state %i\n",jerry_ee_state); + switch (jerry_ee_state) + { + case EE_STATE_START: { + jerry_ee_state=EE_STATE_OP_A; + break; + } + case EE_STATE_OP_A: { + jerry_ee_op=(data<<1); + jerry_ee_state=EE_STATE_OP_B; + break; + } + case EE_STATE_OP_B: { + jerry_ee_op|=data; + jerry_ee_direct_jump=0; +// fprintf(log_get(),"eeprom: opcode %i\n",jerry_ee_op); + switch (jerry_ee_op) + { + case 0: jerry_ee_state=EE_STATE_0; break; + case 1: jerry_ee_state=EE_STATE_1; break; + case 2: jerry_ee_state=EE_STATE_2; break; + case 3: jerry_ee_state=EE_STATE_3; break; + } + eeprom_set_di(data); + break; + } + case EE_STATE_0: { + jerry_ee_rstate=EE_STATE_0_0; + jerry_ee_state=EE_READ_ADDRESS; + jerry_ee_direct_jump=1; + jerry_ee_address_cnt=6; + jerry_ee_address_data=0; + break; + } + case EE_STATE_0_0: { + switch ((jerry_ee_address_data>>4)&0x03) + { + case 0: jerry_ee_state=EE_STATE_0_0_0; break; + case 1: jerry_ee_state=EE_STATE_0_0_1; break; + case 2: jerry_ee_state=EE_STATE_0_0_2; break; + case 3: jerry_ee_state=EE_STATE_0_0_3; break; + } + eeprom_set_di(data); + break; + } + case EE_STATE_0_0_0:{ + // writes disable + // fprintf(log_get(),"eeprom: read only\n"); + jerry_writes_enabled=0; + jerry_ee_state=EE_STATE_START; + break; + } + case EE_STATE_0_0_1:{ + // writes all + jerry_ee_rstate=EE_STATE_0_0_1_0; + jerry_ee_state=EE_READ_DATA; + jerry_ee_data_cnt=16; + jerry_ee_data=0; + jerry_ee_direct_jump=1; + break; + } + case EE_STATE_0_0_1_0:{ + // fprintf(log_get(),"eeprom: filling eeprom with 0x%.4x\n",data); + if (jerry_writes_enabled) + { + for (int i=0;i<64;i++) + eeprom_ram[i]=jerry_ee_data; + } + //else + // fprintf(log_get(),"eeprom: not writing because read only\n"); + jerry_ee_state=EE_STATE_BUSY; + break; + } + case EE_STATE_0_0_2:{ + // erase all + //fprintf(log_get(),"eeprom: erasing eeprom\n"); + if (jerry_writes_enabled) + { + for (int i=0;i<64;i++) + eeprom_ram[i]=0xffff; + } + jerry_ee_state=EE_STATE_BUSY; + break; + } + case EE_STATE_0_0_3:{ + // writes enable + //fprintf(log_get(),"eeprom: read/write\n"); + jerry_writes_enabled=1; + jerry_ee_state=EE_STATE_START; + break; + } + case EE_STATE_1: { + jerry_ee_rstate=EE_STATE_1_0; + jerry_ee_state=EE_READ_ADDRESS; + jerry_ee_address_cnt=6; + jerry_ee_address_data=0; + jerry_ee_direct_jump=1; + break; + } + case EE_STATE_1_0: { + jerry_ee_rstate=EE_STATE_1_1; + jerry_ee_state=EE_READ_DATA; + jerry_ee_data_cnt=16; + jerry_ee_data=0; + jerry_ee_direct_jump=1; + break; + } + case EE_STATE_1_1: { + //fprintf(log_get(),"eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data); + if (jerry_writes_enabled) + eeprom_ram[jerry_ee_address_data]=jerry_ee_data; + jerry_ee_state=EE_STATE_BUSY; + break; + } + case EE_STATE_2: { + jerry_ee_rstate=EE_STATE_2_0; + jerry_ee_state=EE_READ_ADDRESS; + jerry_ee_address_cnt=6; + jerry_ee_address_data=0; + jerry_ee_data_cnt=16; + jerry_ee_data=0; + break; + } + case EE_STATE_3: { + jerry_ee_rstate=EE_STATE_3_0; + jerry_ee_state=EE_READ_ADDRESS; + jerry_ee_address_cnt=6; + jerry_ee_address_data=0; + jerry_ee_direct_jump=1; + break; + } + case EE_STATE_3_0: { + //fprintf(log_get(),"eeprom: erasing 0x%.2x\n",jerry_ee_address_data); + if (jerry_writes_enabled) + eeprom_ram[jerry_ee_address_data]=0xffff; + jerry_ee_state=EE_STATE_BUSY; + break; + } + case EE_READ_DATA: + { + //fprintf(log_get(),"eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1); + jerry_ee_data<<=1; + jerry_ee_data|=data; + jerry_ee_data_cnt--; + if (!jerry_ee_data_cnt) + { + jerry_ee_state=jerry_ee_rstate; + if (jerry_ee_direct_jump) + eeprom_set_di(data); + } + break; + } + case EE_READ_ADDRESS: + { + jerry_ee_address_data<<=1; + jerry_ee_address_data|=data; + jerry_ee_address_cnt--; +// fprintf(log_get(),"eeprom:\t%i bits remaining\n",jerry_ee_address_cnt); + if (!jerry_ee_address_cnt) + { + jerry_ee_state=jerry_ee_rstate; + //fprintf(log_get(),"eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data); + if (jerry_ee_direct_jump) + eeprom_set_di(data); + } + break; + } + default: { + jerry_ee_state=EE_STATE_OP_A; + break; + } + + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void eeprom_set_cs(uint32 state) +{ +// fprintf(log_get(),"eeprom: cs=%i\n",state); + jerry_ee_state=EE_STATE_START; + jerry_ee_op=0; + jerry_ee_rstate=0; + jerry_ee_address_data=0; + jerry_ee_address_cnt=6; + jerry_ee_data=0; + jerry_ee_data_cnt=16; + jerry_writes_enabled=1; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint32 eeprom_get_do(void) +{ + uint16 data=1; + switch (jerry_ee_state) + { + case EE_STATE_START: { + data=1; + break; + } + case EE_STATE_BUSY: { + jerry_ee_state=EE_STATE_START; + data=0; + break; + } + case EE_STATE_2_0: { + jerry_ee_data_cnt--; + data=((eeprom_ram[jerry_ee_address_data]&(1<>jerry_ee_data_cnt); + if (!jerry_ee_data_cnt) + { + //fprintf(log_get(),"eeprom: read 0x%.4x at 0x%.2x cpu %i pc=0x%.8x\n",eeprom_ram[jerry_ee_address_data],jerry_ee_address_data,jaguar_cpu_in_exec,s68000readPC()); + jerry_ee_state=EE_STATE_START; + } + break; + } + } +// fprintf(log_get(),"eeprom: do=%i\n",data); + return(data); +} diff --git a/src/gpu.cpp b/src/gpu.cpp new file mode 100644 index 0000000..16a5341 --- /dev/null +++ b/src/gpu.cpp @@ -0,0 +1,2522 @@ +// +// GPU Core +// +// by cal16 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Cleanups, endian wrongness, and bad ASM amelioration by James L. Hammons +// Note: Endian wrongness probably stems from the MAME origins of this emu and +// the braindead way in which MAME handles memory. :-) +// + +#include "gpu.h" + +#define CINT0FLAG 0x00200 +#define CINT1FLAG 0x00400 +#define CINT2FLAG 0x00800 +#define CINT3FLAG 0x01000 +#define CINT4FLAG 0x02000 +#define CINT04FLAGS (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG) + +extern int start_logging; + +static void gpu_opcode_add(void); +static void gpu_opcode_addc(void); +static void gpu_opcode_addq(void); +static void gpu_opcode_addqt(void); +static void gpu_opcode_sub(void); +static void gpu_opcode_subc(void); +static void gpu_opcode_subq(void); +static void gpu_opcode_subqt(void); +static void gpu_opcode_neg(void); +static void gpu_opcode_and(void); +static void gpu_opcode_or(void); +static void gpu_opcode_xor(void); +static void gpu_opcode_not(void); +static void gpu_opcode_btst(void); +static void gpu_opcode_bset(void); +static void gpu_opcode_bclr(void); +static void gpu_opcode_mult(void); +static void gpu_opcode_imult(void); +static void gpu_opcode_imultn(void); +static void gpu_opcode_resmac(void); +static void gpu_opcode_imacn(void); +static void gpu_opcode_div(void); +static void gpu_opcode_abs(void); +static void gpu_opcode_sh(void); +static void gpu_opcode_shlq(void); +static void gpu_opcode_shrq(void); +static void gpu_opcode_sha(void); +static void gpu_opcode_sharq(void); +static void gpu_opcode_ror(void); +static void gpu_opcode_rorq(void); +static void gpu_opcode_cmp(void); +static void gpu_opcode_cmpq(void); +static void gpu_opcode_sat8(void); +static void gpu_opcode_sat16(void); +static void gpu_opcode_move(void); +static void gpu_opcode_moveq(void); +static void gpu_opcode_moveta(void); +static void gpu_opcode_movefa(void); +static void gpu_opcode_movei(void); +static void gpu_opcode_loadb(void); +static void gpu_opcode_loadw(void); +static void gpu_opcode_load(void); +static void gpu_opcode_loadp(void); +static void gpu_opcode_load_r14_indexed(void); +static void gpu_opcode_load_r15_indexed(void); +static void gpu_opcode_storeb(void); +static void gpu_opcode_storew(void); +static void gpu_opcode_store(void); +static void gpu_opcode_storep(void); +static void gpu_opcode_store_r14_indexed(void); +static void gpu_opcode_store_r15_indexed(void); +static void gpu_opcode_move_pc(void); +static void gpu_opcode_jump(void); +static void gpu_opcode_jr(void); +static void gpu_opcode_mmult(void); +static void gpu_opcode_mtoi(void); +static void gpu_opcode_normi(void); +static void gpu_opcode_nop(void); +static void gpu_opcode_load_r14_ri(void); +static void gpu_opcode_load_r15_ri(void); +static void gpu_opcode_store_r14_ri(void); +static void gpu_opcode_store_r15_ri(void); +static void gpu_opcode_sat24(void); +static void gpu_opcode_pack(void); + +uint8 gpu_opcode_cycles[64] = +{ + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 1, 3, + 1, 18, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 2, 2, + 2, 2, 3, 4, + 5, 4, 5, 6, + 6, 1, 1, 1, + 1, 2, 2, 2, + 1, 1, 9, 3, + 3, 1, 6, 6, + 2, 2, 3, 3 +}; + +void (*gpu_opcode[64])()= +{ + gpu_opcode_add, gpu_opcode_addc, gpu_opcode_addq, gpu_opcode_addqt, + gpu_opcode_sub, gpu_opcode_subc, gpu_opcode_subq, gpu_opcode_subqt, + gpu_opcode_neg, gpu_opcode_and, gpu_opcode_or, gpu_opcode_xor, + gpu_opcode_not, gpu_opcode_btst, gpu_opcode_bset, gpu_opcode_bclr, + gpu_opcode_mult, gpu_opcode_imult, gpu_opcode_imultn, gpu_opcode_resmac, + gpu_opcode_imacn, gpu_opcode_div, gpu_opcode_abs, gpu_opcode_sh, + gpu_opcode_shlq, gpu_opcode_shrq, gpu_opcode_sha, gpu_opcode_sharq, + gpu_opcode_ror, gpu_opcode_rorq, gpu_opcode_cmp, gpu_opcode_cmpq, + gpu_opcode_sat8, gpu_opcode_sat16, gpu_opcode_move, gpu_opcode_moveq, + gpu_opcode_moveta, gpu_opcode_movefa, gpu_opcode_movei, gpu_opcode_loadb, + gpu_opcode_loadw, gpu_opcode_load, gpu_opcode_loadp, gpu_opcode_load_r14_indexed, + gpu_opcode_load_r15_indexed, gpu_opcode_storeb, gpu_opcode_storew, gpu_opcode_store, + gpu_opcode_storep, gpu_opcode_store_r14_indexed, gpu_opcode_store_r15_indexed, gpu_opcode_move_pc, + gpu_opcode_jump, gpu_opcode_jr, gpu_opcode_mmult, gpu_opcode_mtoi, + gpu_opcode_normi, gpu_opcode_nop, gpu_opcode_load_r14_ri, gpu_opcode_load_r15_ri, + gpu_opcode_store_r14_ri, gpu_opcode_store_r15_ri, gpu_opcode_sat24, gpu_opcode_pack, +}; + +static uint8 * gpu_ram_8; +//static uint16 *gpu_ram_16; +//static uint32 *gpu_ram_32; + + +static uint32 gpu_pc; +static uint32 gpu_acc; +static uint32 gpu_remain; +static uint32 gpu_hidata; +static uint32 gpu_flags; +static uint32 gpu_matrix_control; +static uint32 gpu_pointer_to_matrix; +static uint32 gpu_data_organization; +static uint32 gpu_control; +static uint32 gpu_div_control; +static uint8 gpu_flag_z; +static uint8 gpu_flag_n; +static uint8 gpu_flag_c; +static uint8 gpu_alternate_flag_z; +static uint8 gpu_alternate_flag_n; +static uint8 gpu_alternate_flag_c; +static uint32 * gpu_reg; +static uint32 * gpu_alternate_reg; +static uint32 * gpu_reg_bank_0; +static uint32 * gpu_reg_bank_1; + +static uint32 gpu_opcode_first_parameter; +static uint32 gpu_opcode_second_parameter; + +#define GPU_RUNNING (gpu_control & 0x01) + +#define Rm gpu_reg[gpu_opcode_first_parameter] +#define Rn gpu_reg[gpu_opcode_second_parameter] +#define alternate_Rm gpu_alternate_reg[gpu_opcode_first_parameter] +#define alternate_Rn gpu_alternate_reg[gpu_opcode_second_parameter] +#define imm_1 gpu_opcode_first_parameter +#define imm_2 gpu_opcode_second_parameter + +#define set_flag_z(r) gpu_flag_z = (r==0); +#define set_flag_n(r) gpu_flag_n = ((r&0x80000000)>>31); + +#define reset_flag_z() gpu_flag_z = 0; +#define reset_flag_n() gpu_flag_n = 0; +#define reset_flag_c() gpu_flag_c = 0; + +#define CLR_ZNC (gpu_flag_z = gpu_flag_n = gpu_flag_c = 0) +#define SET_Z(r) (gpu_flag_z = ((r) == 0)) +#define SET_N(r) (gpu_flag_n = (((UINT32)(r) >> 31) & 0x01)) +#define SET_C_ADD(a,b) (gpu_flag_c = ((UINT32)(b) > (UINT32)(~(a)))) +#define SET_C_SUB(a,b) (gpu_flag_c = ((UINT32)(b) > (UINT32)(a))) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) + +uint32 gpu_convert_zero[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 }; + +uint8 * branch_condition_table = 0; +#define branch_condition(x) branch_condition_table[(x) + ((jaguar_flags & 7) << 5)] + +uint32 gpu_opcode_use[64]; + +void gpu_update_register_banks(void); + +char *gpu_opcode_str[64]= +{ + "add", "addc", "addq", "addqt", + "sub", "subc", "subq", "subqt", + "neg", "and", "or", "xor", + "not", "btst", "bset", "bclr", + "mult", "imult", "imultn", "resmac", + "imacn", "div", "abs", "sh", + "shlq", "shrq", "sha", "sharq", + "ror", "rorq", "cmp", "cmpq", + "sat8", "sat16", "move", "moveq", + "moveta", "movefa", "movei", "loadb", + "loadw", "load", "loadp", "load_r14_indexed", + "load_r15_indexed", "storeb", "storew", "store", + "storep", "store_r14_indexed","store_r15_indexed","move_pc", + "jump", "jr", "mmult", "mtoi", + "normi", "nop", "load_r14_ri", "load_r15_ri", + "store_r14_ri", "store_r15_ri", "sat24", "pack", +}; + +static uint32 gpu_in_exec = 0; +static uint32 gpu_releaseTimeSlice_flag = 0; + + +void gpu_releaseTimeslice(void) +{ + gpu_releaseTimeSlice_flag = 1; +} + +uint32 gpu_get_pc(void) +{ + return gpu_pc; +} + +void build_branch_condition_table(void) +{ +#define ZFLAG 0x00001 +#define CFLAG 0x00002 +#define NFLAG 0x00004 + + if (!branch_condition_table) + { + branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(branch_condition_table[0])); + + if (branch_condition_table) + { + for(int i=0; i<8; i++) + { + for(int j=0; j<32; j++) + { + int result = 1; + if (j & 1) + if (i & ZFLAG) + result = 0; + if (j & 2) + if (!(i & ZFLAG)) + result = 0; + if (j & 4) + if (i & (CFLAG << (j >> 4))) + result = 0; + if (j & 8) + if (!(i & (CFLAG << (j >> 4)))) + result = 0; + branch_condition_table[i * 32 + j] = result; + } + } + } + } +} + +// +// GPU byte access (read) +// + +unsigned gpu_byte_read(unsigned int offset) +{ + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + return gpu_ram_8[offset & 0xFFF]; + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + uint32 data = gpu_long_read(offset & 0xFFFFFFFC); + + if ((offset & 0x03) == 0) + return data >> 24; + else if ((offset & 0x03) == 1) + return (data >> 16) & 0xFF; + else if ((offset & 0x03) == 2) + return (data >> 8) & 0xFF; + else if ((offset & 0x03) == 3) + return data & 0xFF; + } + + return jaguar_byte_read(offset); +} + +// +// GPU word access (read) +// + +unsigned gpu_word_read(unsigned int offset) +{ + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + offset &= 0xFFF; + uint16 data = ((uint16)gpu_ram_8[offset] << 8) | (uint16)gpu_ram_8[offset+1]; + return data; + } + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { +// This looks and smells wrong... +// But it *might* be OK... + if (offset & 0x01) // Catch cases 1 & 3... (unaligned read) + return (gpu_byte_read(offset) << 8) | gpu_byte_read(offset+1); + + uint32 data = gpu_long_read(offset & 0xFFFFFFFC); + + if (offset & 0x02) // Cases 0 & 2... + return data & 0xFFFF; + else + return data >> 16; + } + + return jaguar_word_read(offset); +} + +// +// GPU dword access (read) +// + +unsigned gpu_long_read(unsigned int offset) +{ + + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + offset &= 0xFFF; + return ((uint32)gpu_ram_8[offset] << 24) | ((uint32)gpu_ram_8[offset+1] << 16) + | ((uint32)gpu_ram_8[offset+2] << 8) | (uint32)gpu_ram_8[offset+3]; + } + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + offset &= 0x1F; + switch (offset) + { + case 0x00: + gpu_flag_c = (gpu_flag_c ? 1 : 0); + gpu_flag_z = (gpu_flag_z ? 1 : 0); + gpu_flag_n = (gpu_flag_n ? 1 : 0); + + gpu_flags = (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; + + return gpu_flags & 0xFFFFC1FF; + case 0x04: + return gpu_matrix_control; + case 0x08: + return gpu_pointer_to_matrix; + case 0x0C: + return gpu_data_organization; + case 0x10: + return gpu_pc; + case 0x14: + return gpu_control; + case 0x18: + return gpu_hidata; + case 0x1C: + return gpu_remain; + default: // unaligned long read + return 0; + //exit(0); + // __asm int 3 + // } + } + // to prevent any lock-ups + } + + return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2); +} + +// +// GPU byte access (write) +// + +void gpu_byte_write(unsigned offset, unsigned data) +{ + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + gpu_ram_8[offset & 0xFFF] = data; + if (gpu_in_exec == 0) + { +// s68000releaseTimeslice(); + m68k_end_timeslice(); + dsp_releaseTimeslice(); + } + return; + } + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + uint32 reg = offset & 0x1C; + int bytenum = offset & 0x03; + +//This is definitely wrong! + if ((reg >= 0x1C) && (reg <= 0x1F)) + gpu_div_control = (gpu_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3)); + else + { + uint32 old_data = gpu_long_read(offset & 0xFFFFFFC); + bytenum = 3 - bytenum; // convention motorola !!! + old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3)); + gpu_long_write(offset & 0xFFFFFFC, old_data); + } + return; + } +// fprintf(log_get(),"gpu: writing %.2x at 0x%.8x\n",data,offset); + jaguar_byte_write(offset, data); +} + +// +// GPU word access (write) +// + +void gpu_word_write(unsigned offset, unsigned data) +{ + + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + + gpu_ram_8[offset & 0xFFF] = (data>>8) & 0xFF; + gpu_ram_8[(offset+1) & 0xFFF] = data & 0xFF; + if (gpu_in_exec == 0) + { +// s68000releaseTimeslice(); + m68k_end_timeslice(); + dsp_releaseTimeslice(); + } + return; + } + if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + if (offset & 0x01) // This is supposed to weed out unaligned writes, but does nothing... + { + //exit(0); + //__asm int 3 + } + if ((offset & 0x1C) == 0x1C) + { +//This doesn't look right either--handles cases 1, 2, & 3 all the same! + if (offset & 0x03) + gpu_div_control = (gpu_div_control&0xFFFF0000) | (data&0xFFFF); + else + gpu_div_control = (gpu_div_control&0xFFFF) | ((data&0xFFFF)<<16); + } + else + { + uint32 old_data = gpu_long_read(offset & 0xFFFFFFC); + if (offset & 0x03) + old_data = (old_data & 0xFFFF0000) | (data & 0xFFFF); + else + old_data = (old_data & 0xFFFF) | ((data & 0xFFFF) << 16); + gpu_long_write(offset & 0xFFFFFFC, old_data); + } + return; + } +// fprintf(log_get(),"gpu: writing %.4x at 0x%.8x\n",data,offset); + jaguar_word_write(offset, data); +} + +// +// GPU dword access (write) +// + +void gpu_long_write(unsigned offset, unsigned data) +{ + + if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + gpu_ram_8[offset & 0xFFF] = (data >> 24) & 0xFF; + gpu_ram_8[(offset+1) & 0xFFF] = (data >> 16) & 0xFF; + gpu_ram_8[(offset+2) & 0xFFF] = (data >> 8) & 0xFF; + gpu_ram_8[(offset+3) & 0xFFF] = data & 0xFF; + return; + } + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + offset &= 0x1F; + switch (offset) + { + case 0x00: + /*if (data&0x8) + gpu_flags=(data&(~0x08))|(gpu_flags&0x08); // update dsp_flags, but keep imask unchanged + else*/ + gpu_flags = data; + gpu_flag_z = gpu_flags & 0x01; + gpu_flag_c = (gpu_flags>>1) & 0x01; + gpu_flag_n = (gpu_flags>>2) & 0x01; + gpu_update_register_banks(); + gpu_control &= ~((gpu_flags & CINT04FLAGS) >> 3); + gpu_check_irqs(); + break; + case 0x04: + gpu_matrix_control = data; + break; + case 0x08: + gpu_pointer_to_matrix=data; + break; + case 0x0C: + gpu_data_organization=data; + break; + case 0x10: + gpu_pc = data; /*fprintf(log_get(),"setting gpu pc to 0x%.8x\n",gpu_pc);*/ + break; + case 0x14: + { + uint32 gpu_was_running = GPU_RUNNING; + + data &= (~0x7C0); // disable writes to irq pending + /*if (GPU_RUNNING) + { + fprintf(log_get(),"gpu pc is 0x%.8x\n",gpu_pc); + fclose(log_get()); + exit(0); + }*/ + // check for GPU->CPU interrupt + if (data & 0x02) + { +// fprintf(log_get(),"GPU->CPU interrupt\n"); + if (tom_irq_enabled(IRQ_GPU)) + { + if ((tom_irq_enabled(IRQ_GPU)) && (jaguar_interrupt_handler_is_valid(64))) + { + tom_set_pending_gpu_int(); +// s68000interrupt(7,64); +// s68000flushInterrupts(); + m68k_set_irq(7); // Set 68000 NMI + gpu_releaseTimeslice(); + } +/* + uint32 addr=jaguar_word_read(((IRQ_GPU+64)<<2)+0); + addr<<=16; + addr|=jaguar_word_read(((IRQ_GPU+64)<<2)+2); + if ((addr)&&(jaguar_interrupt_handler_is_valid(IRQ_GPU+64))) + { + s68000interrupt(7,IRQ_GPU+64); + s68000flushInterrupts(); + } +*/ + } + data &= ~(0x02); + } + // check for CPU->GPU interrupt + if (data & 0x04) + { + //fprintf(log_get(),"CPU->GPU interrupt\n"); + gpu_set_irq_line(0, 1); +// s68000releaseTimeslice(); + m68k_end_timeslice(); + dsp_releaseTimeslice(); + data &= ~(0x04); + } + // single stepping + if (data & 0x10) + { + //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not "); + } + gpu_control = (gpu_control & 0x107C0) | (data & (~0x107C0)); + + // if gpu wasn't running but is now running, execute a few cycles +#ifndef GPU_SINGLE_STEPPING + if ((!gpu_was_running) && (GPU_RUNNING)) + gpu_exec(200); +#else + if (gpu_control & 0x18) + gpu_exec(1); +#endif +fprintf(log_get(), "Write to GPU CTRL: %08X ", data); +if (GPU_RUNNING) + fprintf(log_get(), "-- Starting to run at %08X...", gpu_pc); +fprintf(log_get(), "\n"); + + break; + } + case 0x18: + gpu_hidata = data; + break; + case 0x1C: + gpu_div_control = data; + break; +// default: // unaligned long write + //exit(0); + //__asm int 3 + } + return; + } +// fprintf(log_get(),"gpu: writing %.8x at 0x%.8x\n",data,offset); + jaguar_word_write(offset, (data >> 16) & 0xFFFF); + jaguar_word_write(offset+2, data & 0xFFFF); +} + +void gpu_update_register_banks(void) +{ + uint32 temp; + int bank = (gpu_flags & 0x4000); + +// fprintf(log_get(),"gpu_update_register_banks at gpu pc 0x%.8x bank=%i iflag=%i\n",gpu_pc,bank?1:0,(gpu_flags&0x8)?1:0); + + if (gpu_flags & 0x8) + bank = 0; + + if ((!bank && (gpu_reg_bank_0 != gpu_reg)) || (bank && (gpu_reg_bank_1 != gpu_reg))) + { +// fprintf(log_get(),"\tswitching to bank %i\n",bank?1:0); + for(int i=0; i<32; i++) + { + temp = gpu_reg[i]; + gpu_reg[i] = gpu_alternate_reg[i]; + gpu_alternate_reg[i] = temp; + } + + // switch flags + temp = gpu_flag_z; + gpu_flag_z = gpu_alternate_flag_z; + gpu_alternate_flag_z = temp; + + temp = gpu_flag_n; + gpu_flag_n = gpu_alternate_flag_n; + gpu_alternate_flag_n = temp; + + temp = gpu_flag_c; + gpu_flag_c = gpu_alternate_flag_c; + gpu_alternate_flag_c = temp; + + if (!bank) + { + gpu_reg_bank_0 = gpu_reg; + gpu_reg_bank_1 = gpu_alternate_reg; + } + else + { + gpu_reg_bank_0 = gpu_alternate_reg; + gpu_reg_bank_1 = gpu_reg; + } + } +// else +// { +// fprintf(log_get(),"\tnot switching banks\n"); +// } +} + +void gpu_check_irqs(void) +{ + int bits, mask, which = 0; + + // get the active interrupt bits + bits = (gpu_control >> 6) & 0x1F; + bits |= (gpu_control >> 10) & 0x20; + + // get the interrupt mask + mask = (gpu_flags >> 4) & 0x1F; + mask |= (gpu_flags >> 11) & 0x20; + + // bail if nothing is available + bits &= mask; + if (!bits) + return; + + // determine which interrupt + if (bits & 0x01) which = 0; + if (bits & 0x02) which = 1; + if (bits & 0x04) which = 2; + if (bits & 0x08) which = 3; + if (bits & 0x10) which = 4; + if (bits & 0x20) which = 5; + + if (gpu_flags & 0x8) + return; + + if (start_logging) + fprintf(log_get(),"gpu: generating irg %i\n",which); + + // set the interrupt flag + gpu_flags |= 0x08; + gpu_update_register_banks(); + + // subqt #4,r31 ; pre-decrement stack pointer + // move pc,r30 ; address of interrupted code + // store r30,(r31) ; store return address + gpu_reg[31] -= 4; + gpu_reg[30] = gpu_pc - 2; + gpu_long_write(gpu_reg[31], gpu_pc - 2); + + // movei #service_address,r30 ; pointer to ISR entry + // jump (r30) ; jump to ISR + // nop + gpu_pc = gpu_work_ram_base; + gpu_pc += which * 0x10; + gpu_reg[30] = gpu_pc; +} + +void gpu_set_irq_line(int irqline, int state) +{ + if (start_logging) + fprintf(log_get(),"gpu: setting irg line %i\n",irqline); + int mask = 0x40 << irqline; + gpu_control &= ~mask; + + if (state) + { + gpu_control |= mask; + gpu_check_irqs(); + } +} + +void gpu_init(void) +{ + memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work ram"); +// gpu_ram_16=(uint16*)gpu_ram_8; +// gpu_ram_32=(uint32*)gpu_ram_8; + + memory_malloc_secure((void **)&gpu_reg, 32*sizeof(int32), "GPU bank 0 regs"); + memory_malloc_secure((void **)&gpu_alternate_reg, 32*sizeof(int32), "GPU bank 1 regs"); + + build_branch_condition_table(); + + gpu_reset(); +} + +void gpu_reset(void) +{ + gpu_pc = 0x00F03000; + gpu_acc = 0x00000000; + gpu_remain = 0x00000000; + gpu_hidata = 0x00000000; + gpu_flags = 0x00040000; + gpu_matrix_control = 0x00000000; + gpu_pointer_to_matrix = 0x00000000; + gpu_data_organization = 0xFFFFFFFF; + gpu_control = 0x00012800; + gpu_div_control = 0x00000000; + gpu_in_exec = 0; + + for(int i=0; i<32; i++) + { + gpu_reg[i] = 0x00000000; + gpu_alternate_reg[i] = 0x00000000; + } + + gpu_reg_bank_0 = gpu_reg; + gpu_reg_bank_1 = gpu_alternate_reg; +// gpu_reg_bank_1 = gpu_reg; +// gpu_reg_bank_0 = gpu_alternate_reg; + + reset_flag_z(); + reset_flag_n(); + reset_flag_c(); + + gpu_alternate_flag_z = 0; + gpu_alternate_flag_n = 0; + gpu_alternate_flag_c = 0; + + memset(gpu_ram_8, 0xFF, 0x1000); + + gpu_reset_stats(); +} + +uint32 gpu_read_pc(void) +{ + return gpu_pc; +} + +void gpu_reset_stats(void) +{ + for(uint32 i=0; i<64; i++) + gpu_opcode_use[i] = 0; +} + +void gpu_done(void) +{ + fprintf(log_get(), "GPU: stopped at PC=%08X (GPU %s running)\n", gpu_pc, GPU_RUNNING ? "was" : "wasn't"); + + // get the active interrupt bits + int bits = (gpu_control >> 6) & 0x1F; + bits |= (gpu_control >> 10) & 0x20; + + // get the interrupt mask + int mask = (gpu_flags >> 4) & 0x1F; + mask |= (gpu_flags >> 11) & 0x20; + + + fprintf(log_get(), "GPU: ibits=0x%.8x imask=0x%.8x\n", bits, mask); +// fprintf(log_get(),"\nregisters bank 0\n"); +// for (int j=0;j<8;j++) +// { +// fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n", +// (j<<2)+0,gpu_reg[(j<<2)+0], +// (j<<2)+1,gpu_reg[(j<<2)+1], +// (j<<2)+2,gpu_reg[(j<<2)+2], +// (j<<2)+3,gpu_reg[(j<<2)+3]); +// +// } +// fprintf(log_get(),"registers bank 1\n"); +// for (j=0;j<8;j++) +// { +// fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n", +// (j<<2)+0,gpu_alternate_reg[(j<<2)+0], +// (j<<2)+1,gpu_alternate_reg[(j<<2)+1], +// (j<<2)+2,gpu_alternate_reg[(j<<2)+2], +// (j<<2)+3,gpu_alternate_reg[(j<<2)+3]); +// +// } + fprintf(log_get(),"---[GPU code at 00F03000]---------------------------\n"); + static char buffer[512]; + int j = 0xF03000; + for(int i=0; i<4096; i++) + { + uint32 oldj = j; + j += dasmjag(JAGUAR_GPU, buffer, j); + fprintf(log_get(),"\t%08X: %s\n", oldj, buffer); + } + + fprintf(log_get(), "---[GPU code at %08X]---------------------------\n", gpu_pc); + j = gpu_pc - 64; + for(int i=0; i<4096; i++) + { + uint32 oldj = j; + j += dasmjag(JAGUAR_GPU, buffer, j); + fprintf(log_get(), "\t%08X: %s\n", oldj, buffer); + } + + fprintf(log_get(), "gpu opcodes use:\n"); + for(int i=0; i<64; i++) + { + if (gpu_opcode_use[i]) + fprintf(log_get(), "\t%s %lu\n", gpu_opcode_str[i], gpu_opcode_use[i]); + } + memory_free(gpu_ram_8); +} + +// +// Main GPU execution core +// + +void gpu_exec(int32 cycles) +{ + if (!GPU_RUNNING) + return; + +#ifdef GPU_SINGLE_STEPPING + if (gpu_control & 0x18) + { + cycles = 1; + gpu_control &= ~0x10; + } +#endif + gpu_check_irqs(); + gpu_releaseTimeSlice_flag = 0; + gpu_in_exec++; + + while ((cycles > 0) && GPU_RUNNING) + { + gpu_flag_c = (gpu_flag_c ? 1 : 0); + gpu_flag_z = (gpu_flag_z ? 1 : 0); + gpu_flag_n = (gpu_flag_n ? 1 : 0); + + uint16 opcode = gpu_word_read(gpu_pc); + + uint32 index = opcode >> 10; + gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5; + gpu_opcode_second_parameter = (opcode & 0x1F); + gpu_pc += 2; + gpu_opcode[index](); + cycles -= gpu_opcode_cycles[index]; + gpu_opcode_use[index]++; + } + + gpu_in_exec--; +} + +// +// GPU opcodes +// + +static void gpu_opcode_jump(void) +{ + uint32 delayed_pc = Rm; + uint32 jaguar_flags; + + // normalize flags + gpu_flag_c = (gpu_flag_c ? 1 : 0); + gpu_flag_z = (gpu_flag_z ? 1 : 0); + gpu_flag_n = (gpu_flag_n ? 1 : 0); + + jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; + + if (branch_condition(imm_2)) + { + gpu_exec(1); + gpu_pc = delayed_pc; + } +} + +static void gpu_opcode_jr(void) +{ + int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1; + + int32 delayed_pc = gpu_pc + (offset * 2); + uint32 jaguar_flags; + + // normalize flags + gpu_flag_c=gpu_flag_c?1:0; + gpu_flag_z=gpu_flag_z?1:0; + gpu_flag_n=gpu_flag_n?1:0; + + jaguar_flags=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z; + + if (branch_condition(imm_2)) + { + gpu_exec(1); + gpu_pc=delayed_pc; + } +} + +static void gpu_opcode_add(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ +#ifndef USE_ASSEMBLY +{ +/* uint32 index = opcode >> 10; + gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5; + gpu_opcode_second_parameter = (opcode & 0x1F); + gpu_pc += 2; + gpu_opcode[index](); + cycles -= gpu_opcode_cycles[index]; + gpu_opcode_use[index]++;*/ +/* int dreg = jaguar.op & 31; + UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res = r2 + r1; + jaguar.r[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/ + + UINT32 res = Rn + Rm; + CLR_ZNC; SET_ZNC_ADD(Rn, Rm, res); + Rn = res; + return; +} + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ +#else + +#ifdef __GCCWIN32__ + + asm( + "addl %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#else + + asm( + "addl %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#endif // #ifdef __GCCWIN32__ +#endif // #ifndef USE_ASSEMBLY + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + add eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif // #ifdef __PORT__ + Rn=res; +} + +static void gpu_opcode_addc(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ +#ifndef USE_ASSEMBLY +{ +/* int dreg = jaguar.op & 31; + UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res = r2 + r1 + ((jaguar.FLAGS >> 1) & 1); + jaguar.r[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/ + + UINT32 res = Rn + Rm + gpu_flag_c; + CLR_ZNC; SET_ZNC_ADD(Rn, Rm, res); + Rn = res; + return; +} + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + +#ifdef __GCCWIN32__ + + asm( + "addl %1, %2 \n\ + cmp $0, _gpu_flag_c \n\ + clc \n\ + jz 1f \n\ + stc \n\ + 1: \n\ + adc %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#else + + asm( + "addl %1, %2 \n\ + cmp $0, gpu_flag_c \n\ + clc \n\ + jz 1f \n\ + stc \n\ + 1: \n\ + adc %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#endif // #ifdef __GCCWIN32__ +#endif // #ifndef USE_ASSEMBLY + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + cmp [gpu_flag_c],0 + clc + jz gpu_opcode_addc_no_carry + stc +gpu_opcode_addc_no_carry: + adc eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_addq(void) +{ + uint32 _Rn=Rn; + uint32 _Rm=gpu_convert_zero[imm_1]; + uint32 res; +#ifdef __PORT__ +#ifndef USE_ASSEMBLY +{ +/* int dreg = jaguar.op & 31; + UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res = r2 + r1; + jaguar.r[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/ + UINT32 r1 = gpu_convert_zero[imm_1]; + UINT32 res = Rn + r1; + CLR_ZNC; SET_ZNC_ADD(Rn, r1, res); + Rn = res; + return; +} + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + +#ifdef __GCCWIN32__ + + asm( + "addl %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#else + + asm( + "addl %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + +#endif // #ifdef __GCCWIN32__ +#endif // #ifndef USE_ASSEMBLY + +#else + __asm + { + mov edx,_Rm + mov eax,_Rn + add eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_addqt(void) +{ + Rn += gpu_convert_zero[imm_1]; +} + +static void gpu_opcode_sub(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "subl %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "subl %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + sub eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_subc(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "addl %1, %2 \n\ + cmp $0, _gpu_flag_c \n\ + clc \n\ + jz 1f \n\ + stc \n\ + 1: \n\ + sbb %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "addl %1, %2 \n\ + cmp $0, gpu_flag_c \n\ + clc \n\ + jz 1f \n\ + stc \n\ + 1: \n\ + sbb %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + cmp [gpu_flag_c],0 + clc + jz gpu_opcode_subc_no_carry + stc +gpu_opcode_subc_no_carry: + mov edx,_Rm + mov eax,_Rn + sbb eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_subq(void) +{ + uint32 _Rm=gpu_convert_zero[imm_1]; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "subl %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "subl %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + sub eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_subqt(void) +{ + Rn -= gpu_convert_zero[imm_1]; +} + +static void gpu_opcode_cmp(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "cmpl %0, %1 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + " + : + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "cmpl %0, %1 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + " + : + : "d"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + cmp eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + }; +#endif +} + +static void gpu_opcode_cmpq(void) +{ + static int32 sqtable[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1}; + int32 _Rm=sqtable[imm_1&0x1f]; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "cmpl %0, %1 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + " + : + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "cmpl %0, %1 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + " + : + : "d"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + cmp eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + }; +#endif +} + +static void gpu_opcode_and(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "andl %1, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "andl %1, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + and eax,edx + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_or(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "orl %1, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "orl %1, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + or eax,edx + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_xor(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "xorl %1, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #else + + asm( + "xorl %1, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov edx,_Rm + xor eax,edx + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_not(void) +{ + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "notl %1 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "a"(_Rn)); + + #else + + asm( + "notl %1 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + not eax + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_move_pc(void) +{ + Rn = gpu_pc-2; +} + +static void gpu_opcode_sat8(void) +{ + int32 _Rn=(int32)Rn; + + uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn); + set_flag_z(res); + reset_flag_n(); +} + +static void gpu_opcode_sat16(void) +{ + int32 _Rn=(int32)Rn; + uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn); + set_flag_z(res); + reset_flag_n(); +} + +static void gpu_opcode_sat24(void) +{ + int32 _Rn=(int32)Rn; + + uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn); + set_flag_z(res); + reset_flag_n(); +} + +static void gpu_opcode_store_r14_indexed(void) +{ + gpu_long_write( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2),Rn); +} + +static void gpu_opcode_store_r15_indexed(void) +{ + gpu_long_write( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2),Rn); +} + +static void gpu_opcode_load_r14_ri(void) +{ + Rn=gpu_long_read(gpu_reg[14] + Rm); +} + +static void gpu_opcode_load_r15_ri(void) +{ + Rn=gpu_long_read(gpu_reg[15] + Rm); +} + +static void gpu_opcode_store_r14_ri(void) +{ + gpu_long_write(gpu_reg[14] + Rm,Rn); +} + +static void gpu_opcode_store_r15_ri(void) +{ + gpu_long_write(gpu_reg[15] + Rm,Rn); +} + +static void gpu_opcode_nop(void) +{ +} + +static void gpu_opcode_pack(void) +{ + uint32 _Rn=Rn; + + if (Rm==0) + { + Rn =((_Rn & 0x03C00000) >> 10) | + ((_Rn & 0x0001E000) >> 5) | + ((_Rn & 0x000000FF)); + } + else + { + Rn =((_Rn & 0x0000F000) << 10) | + ((_Rn & 0x00000F00) << 5) | + ((_Rn & 0x000000FF)); + } + reset_flag_z(); + reset_flag_n(); + set_flag_z(Rn); + set_flag_n(Rn); +} + +static void gpu_opcode_storeb(void) +{ + if ((Rm >= 0xF03000) && (Rm < 0xF04000)) + gpu_long_write(Rm,Rn&0xff); + else + jaguar_byte_write(Rm,Rn); +} + +static void gpu_opcode_storew(void) +{ + if ((Rm >= 0xF03000) && (Rm < 0xF04000)) + gpu_long_write(Rm,Rn&0xffff); + else + jaguar_word_write(Rm,Rn); +} + +static void gpu_opcode_store(void) +{ + gpu_long_write(Rm,Rn); +} + +static void gpu_opcode_storep(void) +{ + uint32 _Rm=Rm; + gpu_long_write(_Rm, gpu_hidata); + gpu_long_write(_Rm+4, Rn); +} + +static void gpu_opcode_loadb(void) +{ + if ((Rm >= 0xF03000) && (Rm < 0xF04000)) + Rn=gpu_long_read(Rm)&0xff; + else + Rn=jaguar_byte_read(Rm); +} + +static void gpu_opcode_loadw(void) +{ + if ((Rm >= 0xF03000) && (Rm < 0xF04000)) + Rn=gpu_long_read(Rm)&0xffff; + else + Rn=jaguar_word_read(Rm); +} + +static void gpu_opcode_load(void) +{ + Rn = gpu_long_read(Rm); +} + +static void gpu_opcode_loadp(void) +{ + uint32 _Rm=Rm; + + gpu_hidata = gpu_long_read(_Rm); + Rn = gpu_long_read(_Rm+4); +} + +static void gpu_opcode_load_r14_indexed(void) +{ + Rn = gpu_long_read( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2)); +} + +static void gpu_opcode_load_r15_indexed(void) +{ + Rn = gpu_long_read( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2)); +} + +static void gpu_opcode_movei(void) +{ + Rn = (uint32)gpu_word_read(gpu_pc) | ((uint32)gpu_word_read(gpu_pc + 2) << 16); + gpu_pc += 4; +} + +static void gpu_opcode_moveta(void) +{ + alternate_Rn = Rm; +} + +static void gpu_opcode_movefa(void) +{ + Rn = alternate_Rm; +} + +static void gpu_opcode_move(void) +{ + Rn = Rm; +} + +static void gpu_opcode_moveq(void) +{ + Rn = imm_1; +} + +static void gpu_opcode_resmac(void) +{ + Rn = gpu_acc; +} + +static void gpu_opcode_imult(void) +{ + uint32 res=Rn=((int16)Rn)*((int16)Rm); + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_mult(void) +{ + uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn); + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_bclr(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "btrl %1, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "btrl %1, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + btr eax,ecx + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_btst(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "bt %0, %1 \n\ + setnc _gpu_flag_z \n\ + " + : + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "bt %0, %1 \n\ + setnc gpu_flag_z \n\ + " + : + : "c"(_Rm), "a"(_Rn)); + + #endif +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + bt eax,ecx + setnc [gpu_flag_z] + }; +#endif +} + +static void gpu_opcode_bset(void) +{ + uint32 _Rm=imm_1; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "btsl %1, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #else + + asm( + "btsl %1, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(_Rm), "a"(_Rn)); + + #endif + +#else + __asm + { + mov eax,_Rn + mov ecx,_Rm + bts eax,ecx + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_imacn(void) +{ + uint32 res = ((int16)Rm) * ((int16)(Rn)); + gpu_acc += res; +} + +static void gpu_opcode_mtoi(void) +{ + uint32 _Rm=Rm; + uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff); + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_normi(void) +{ + uint32 _Rm = Rm; + uint32 res = 0; + + if (_Rm) + { + while ((_Rm & 0xffc00000) == 0) + { + _Rm <<= 1; + res--; + } + while ((_Rm & 0xff800000) != 0) + { + _Rm >>= 1; + res++; + } + } + Rn = res; + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_mmult(void) +{ + int count = gpu_matrix_control&0x0f; + uint32 addr = gpu_pointer_to_matrix; // in the gpu ram + int64 accum = 0; + uint32 res; + + if (!(gpu_matrix_control & 0x10)) + { + for (int i = 0; i < count; i++) + { + int16 a; + if (i&0x01) + a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff); + else + a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff); + + int16 b=((int16)gpu_word_read(addr+2)); + accum += a*b; + addr += 4; + } + } + else + { + for (int i = 0; i < count; i++) + { + int16 a; + if (i&0x01) + a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff); + else + a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff); + + int16 b=((int16)gpu_word_read(addr+2)); + accum += a*b; + addr += 4 * count; + } + } + Rn = res = (int32)accum; + // carry flag to do + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_abs(void) +{ + uint32 _Rn=Rn; + uint32 res; + + if (_Rn==0x80000000) + { + set_flag_n(1); + } + else + { + gpu_flag_c = ((_Rn&0x80000000)>>31); + res= Rn = (((int32)_Rn)<0) ? -_Rn : _Rn; + reset_flag_n(); + set_flag_z(res); + } +} + +static void gpu_opcode_div(void) +{ + uint32 _Rm=Rm; + uint32 _Rn=Rn; + + if (_Rm) + { + if (gpu_div_control & 1) + { + gpu_remain = (((uint64)_Rn) << 16) % _Rm; + if (gpu_remain&0x80000000) + gpu_remain-=_Rm; + Rn = (((uint64)_Rn) << 16) / _Rm; + } + else + { + gpu_remain = _Rn % _Rm; + if (gpu_remain&0x80000000) + gpu_remain-=_Rm; + Rn/=_Rm; + } + } + else + Rn=0xffffffff; +} + +static void gpu_opcode_imultn(void) +{ + uint32 res = (int32)((int16)Rn * (int16)Rm); + gpu_acc = (int32)res; + set_flag_z(res); + set_flag_n(res); +} + +static void gpu_opcode_neg(void) +{ + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "subl %1, %2 \n\ + setc _gpu_flag_c \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rn), "a"(0)); + + #else + + asm( + "subl %1, %2 \n\ + setc gpu_flag_c \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "d"(_Rn), "a"(0)); + + #endif +#else + __asm + { + xor eax,eax + mov edx,_Rn + sub eax,edx + setc [gpu_flag_c] + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + }; +#endif + Rn=res; +} + +static void gpu_opcode_shlq(void) +{ + uint32 shift=(32-gpu_convert_zero[imm_1]); + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 \n\ + setnz _gpu_flag_c \n\ + shl %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x80000000, %2 \n\ + setnz gpu_flag_c \n\ + shl %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [gpu_flag_c] + shl eax,cl + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + } +#endif + Rn=res; +} + +static void gpu_opcode_shrq(void) +{ + uint32 shift=gpu_convert_zero[imm_1]; + uint32 _Rn=Rn; + + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x00000001, %2 \n\ + setnz _gpu_flag_c \n\ + shr %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x00000001, %2 \n\ + setnz gpu_flag_c \n\ + shr %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x00000001 + setnz [gpu_flag_c] + shr eax,cl + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + } +#endif + Rn=res; +} + +static void gpu_opcode_ror(void) +{ + uint32 shift=Rm; + uint32 _Rn=Rn; + uint32 res; +#ifdef __PORT__ + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + + #ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 \n\ + setnz _gpu_flag_c \n\ + ror %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #else + + asm( + "testl $0x80000000, %2 \n\ + setnz gpu_flag_c \n\ + ror %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + + #endif + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [gpu_flag_c] + ror eax,cl + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + } +#endif + Rn=res; +} + +static void gpu_opcode_rorq(void) +{ + uint32 shift = gpu_convert_zero[imm_1 & 0x1F]; + uint32 _Rn = Rn; + uint32 res; +#ifdef __PORT__ +#ifndef USE_ASSEMBLY + +/* uint32 index = opcode >> 10; + gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5; + gpu_opcode_second_parameter = (opcode & 0x1F); + gpu_pc += 2; + gpu_opcode[index](); + cycles -= gpu_opcode_cycles[index]; + gpu_opcode_use[index]++;*/ + +/* int dreg = jaguar.op & 31; + UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res = (r2 >> r1) | (r2 << (32 - r1)); + jaguar.r[dreg] = res; + CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;*/ +{ + UINT32 r1 = gpu_convert_zero[imm_1 & 0x1F]; + UINT32 r2 = Rn; + UINT32 res = (r2 >> r1) | (r2 << (32 - r1)); + Rn = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01; + return; +} +#else + + /* + GCC on WIN32 (more importantly mingw) doesn't know the declared + variables in asm until we put a _ before it. + + So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw. + */ + +#ifdef __GCCWIN32__ + + asm( + "testl $0x80000000, %2 \n\ + setnz _gpu_flag_c \n\ + ror %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz _gpu_flag_z \n\ + sets _gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + +#else + + asm( + "testl $0x80000000, %2 \n\ + setnz gpu_flag_c \n\ + ror %%cl, %2 \n\ + cmpl $0, %2 \n\ + setz gpu_flag_z \n\ + sets gpu_flag_n \n\ + movl %%eax, %0 \n\ + " + : "=m"(res) + : "c"(shift), "a"(_Rn)); + +#endif // #ifdef __GCCWIN32__ +#endif // #ifndef USE_ASSEMBLY + +#else + __asm + { + mov ecx,shift + mov eax,_Rn + test eax,0x80000000 + setnz [gpu_flag_c] + ror eax,cl + cmp eax,0 + setz [gpu_flag_z] + sets [gpu_flag_n] + mov res,eax + } +#endif // #ifdef __PORT__ + Rn = res; +} + +static void gpu_opcode_sha(void) +{ + int32 sRm=(int32)Rm; + uint32 _Rn=Rn; + + if (sRm<0) + { + uint32 shift=-sRm; + if (shift>=32) shift=32; + gpu_flag_c=(_Rn&0x80000000)>>31; + while (shift) + { + _Rn<<=1; + shift--; + } + } + else + { + uint32 shift=sRm; + if (shift>=32) shift=32; + gpu_flag_c=_Rn&0x1; + while (shift) + { + _Rn=((int32)_Rn)>>1; + shift--; + } + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} + +static void gpu_opcode_sharq(void) +{ + uint32 shift=gpu_convert_zero[imm_1]; + uint32 _Rn=Rn; + + gpu_flag_c = (_Rn & 0x1); + while (shift) + { + _Rn=((int32)_Rn)>>1; + shift--; + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} + +static void gpu_opcode_sh(void) +{ + int32 sRm=(int32)Rm; + uint32 _Rn=Rn; + + if (sRm<0) + { + uint32 shift=(-sRm); + if (shift>=32) shift=32; + gpu_flag_c=(_Rn&0x80000000)>>31; + while (shift) + { + _Rn<<=1; + shift--; + } + } + else + { + uint32 shift=sRm; + if (shift>=32) shift=32; + gpu_flag_c=_Rn&0x1; + while (shift) + { + _Rn>>=1; + shift--; + } + } + Rn=_Rn; + set_flag_z(_Rn); + set_flag_n(_Rn); +} diff --git a/src/include/SDLptc.h b/src/include/SDLptc.h new file mode 100644 index 0000000..542926f --- /dev/null +++ b/src/include/SDLptc.h @@ -0,0 +1,258 @@ +// +// Some simple emulation classes to get PTC code running on SDL +// +// by cal16 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Cleanups in some classes and code in general by James L. Hammons +// + +#ifndef __SDLPTC_H__ +#define __SDLPTC_H__ + +#include "SDL.h" +#ifdef __PORT__ +#include +#include +#endif // #ifdef __PORT__ + +#include "types.h" + +#ifndef __PORT__ +#define randomize() srand(time(NULL)) +#define random(max) (rand() % (max)) +#endif // #ifndef __PORT__ + +class Error +{ + public: + Error(const char * msg) { strcpy(message, msg); } + void report(void) { printf("Error: %s\n", message); } + + private: + char message[1024]; +}; + +class Area +{ + public: + Area(int ll, int tt, int rr, int bb): l(ll), t(tt), r(rr), b(bb) {} + int left(void) const { return l; } + int right(void) const { return r; } + int top(void) const { return t; } + int bottom(void) const { return b; } + int width(void) const { return r - l; } + int height(void) const { return b - t; } + + private: + int l, t, r, b; +}; + + +class Format +{ + public: + Format(int pBpp, int r=0, int g=0, int b=0): bpp(pBpp), maskR(r), maskG(g), maskB(b) {} + Uint8 BPP(void) const { return bpp; } + Uint32 MaskR(void) const { return maskR; } + Uint32 MaskG(void) const { return maskG; } + Uint32 MaskB(void) const { return maskB; } + + private: + Uint8 bpp; + Uint32 maskR, maskG, maskB; +}; + +class Surface +{ + public: + Surface(int w, int h, const Format &format) + { + surface = SDL_AllocSurface(SDL_SWSURFACE, w, h, format.BPP(), + format.MaskR(), format.MaskG(), format.MaskB(), 0); + if (surface == NULL) + { + throw Error(SDL_GetError()); + } + nupdates = 0; + is_console = 0; + } + Surface(void) + { + nupdates = 0; + is_console = 1; + } + ~Surface() + { + if (!is_console) + SDL_FreeSurface(surface); + } + + virtual int width(void) { return surface->w; } + virtual int height(void) { return surface->h; } + virtual int pitch(void) { return surface->pitch; } + virtual void palette(int32 * pcolors) + { + SDL_Color colors[256]; + + for(int i=0; i<256; ++i) + colors[i].r = (pcolors[i] >> 16) & 0xFF, + colors[i].g = (pcolors[i] >> 8) & 0xFF, + colors[i].b = (pcolors[i] >> 0) & 0xFF; + SDL_SetColors(surface, colors, 0, 256); + } + + virtual void * lock(void) + { + if (SDL_MUSTLOCK(surface)) + while (SDL_LockSurface(surface) < 0) + SDL_Delay(10); + + return (Uint8 *)surface->pixels; + } + + virtual void unlock(void) + { + if (SDL_MUSTLOCK(surface)) + SDL_UnlockSurface(surface); + } + + virtual void copy(Surface &dst, const Area &srcarea, const Area &dstarea) + { + SDL_Rect srcrect, dstrect; + srcrect.x = srcarea.left(); + srcrect.y = srcarea.top(); + srcrect.w = srcarea.width(); + srcrect.h = srcarea.height(); + dstrect.x = dstarea.left(); + dstrect.y = dstarea.top(); + dstrect.w = dstarea.width(); + dstrect.h = dstarea.height(); + SDL_BlitSurface(surface, &srcrect, dst.surface, &dstrect); + dst.updates[dst.nupdates++] = dstrect; + } + virtual void copy(Surface &dst) + { + SDL_Rect srcrect, dstrect; + srcrect.x = 0; + srcrect.y = 0; + srcrect.w = surface->w; + srcrect.h = surface->h; + dstrect.x = 0; + dstrect.y = 0; + dstrect.w = surface->w; + dstrect.h = surface->h; + SDL_LowerBlit(surface, &srcrect, dst.surface, &dstrect); + dst.updates[dst.nupdates++] = dstrect; + } + + virtual void update(void) + { + /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com) */ + /* SDL_Flip is infact the same as SDL_Blitsurface but + if SDL_DOUBLEBUF | SDL_HWSURFACE is available, it + makes use of it. If not is uses SDL_Blitsurface */ + SDL_Flip(surface); + nupdates = 0; + } + + public: + SDL_Surface * surface; + + protected: + int nupdates; + SDL_Rect updates[1]; /* Definitely increase this.. */ + int is_console; +}; + +class Console: public Surface +{ + public: + Console(): Surface(), fullscreen(0), nJoystick(0) {} + ~Console() { SDL_Quit(); } + + /* Added/changed by SDLEMU (http://sdlemu.ngemu.com) */ + /* We need to close several items in SDL because of memory leaks + and core dumps and stuff :) */ + void close(void) + { + SDL_JoystickClose(joystick); + SDL_FreeSurface(surface); + SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER); + SDL_Quit(); + } + void option(char * option) + { + if (!stricmp(option, "fullscreen output")) + fullscreen = 1; + else if (!stricmp(option, "windowed output")) + fullscreen = 0; + /* Added/changed by SDLEMU (http://sdlemu.ngemu.com) */ + else if (!stricmp(option, "joystick enabled")) + nJoystick = 1; + else if (!stricmp(option, "joystick disabled")) + nJoystick = 0; + } + + /* The following was changed/added by SDLEMU (http://sdlemu.ngemu.com) */ + + void open(const char * title, int width, int height, const Format &format) + { + Uint32 flags = SDL_SWSURFACE; + + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) + throw Error(SDL_GetError()); + + const SDL_VideoInfo * info = SDL_GetVideoInfo(); // Let us get proper info about the platform. + + if (!info) + { + fprintf(stderr, "SDL is unable to get the video query : %s\n", SDL_GetError()); + exit(1); + } + + if (info->hw_available) + flags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; + + if (info->blit_hw) + flags |= SDL_HWACCEL; + + if (fullscreen) + flags |= SDL_FULLSCREEN; + + surface = SDL_SetVideoMode(width, height, 16, flags); + + if (surface == NULL) + throw Error(SDL_GetError()); + + SDL_WM_SetCaption(title, title); + } + + int key(void) + { + SDL_Event event; + int keyevent = 0; + + while (SDL_PollEvent(&event)) + { + /* Real key events trigger this function */ + if (event.type == SDL_KEYDOWN) + keyevent = 1; + + /* So do quit events -- let the app know about it */ + if (event.type == SDL_QUIT) + keyevent = 1; + } + return keyevent; + } + + int JoyEnabled(void) { return (nJoystick == 1 ? 1 : 0); } + + public: + SDL_Joystick * joystick; + + private: + int fullscreen; + int nJoystick; +}; + +#endif // #ifndef __SDLPTC_H__ diff --git a/src/include/anajoy.h b/src/include/anajoy.h new file mode 100644 index 0000000..3372ec6 --- /dev/null +++ b/src/include/anajoy.h @@ -0,0 +1,14 @@ +#ifndef __ANAJOY_H__ +#define __ANAJOY_H__ + +#include "types.h" + +void anajoy_init(void); +void anajoy_reset(void); +void anajoy_done(void); +void anajoy_byte_write(uint32, uint8); +void anajoy_word_write(uint32, uint16); +uint8 anajoy_byte_read(uint32); +uint16 anajoy_word_read(uint32); + +#endif diff --git a/src/include/blit_c.h b/src/include/blit_c.h new file mode 100644 index 0000000..ea2eda6 --- /dev/null +++ b/src/include/blit_c.h @@ -0,0 +1,8915 @@ +#ifndef blitter_code_0x30000000 +#define blitter_code_0x30000000 +void blitter_0x30000000(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010004 +#define blitter_code_0x34010004 +void blitter_0x34010004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c002a4 +#define blitter_code_0x30c002a4 +void blitter_0x30c002a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c042a4 +#define blitter_code_0x00c042a4 +void blitter_0x00c042a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c042a4 +#define blitter_code_0x08c042a4 +void blitter_0x08c042a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010024 +#define blitter_code_0x34010024 +void blitter_0x34010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010222 +#define blitter_code_0x24010222 +void blitter_0x24010222(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_4(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c04292 +#define blitter_code_0x00c04292 +void blitter_0x00c04292(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_4(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_4(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c0409b +#define blitter_code_0x00c0409b +void blitter_0x00c0409b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30000003 +#define blitter_code_0x30000003 +void blitter_0x30000003(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010003 +#define blitter_code_0x34010003 +void blitter_0x34010003(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c000ad +#define blitter_code_0x30c000ad +void blitter_0x30c000ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c0009b +#define blitter_code_0x30c0009b +void blitter_0x30c0009b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401001b +#define blitter_code_0x3401001b +void blitter_0x3401001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c000a4 +#define blitter_code_0x30c000a4 +void blitter_0x30c000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010023 +#define blitter_code_0x34010023 +void blitter_0x34010023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30000023 +#define blitter_code_0x30000023 +void blitter_0x30000023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010024 +#define blitter_code_0x24010024 +void blitter_0x24010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c000a4 +#define blitter_code_0x00c000a4 +void blitter_0x00c000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c040a4 +#define blitter_code_0x00c040a4 +void blitter_0x00c040a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010024 +#define blitter_code_0x04010024 +void blitter_0x04010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401001c +#define blitter_code_0x2401001c +void blitter_0x2401001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3000002b +#define blitter_code_0x3000002b +void blitter_0x3000002b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3000001b +#define blitter_code_0x3000001b +void blitter_0x3000001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c0009b +#define blitter_code_0x00c0009b +void blitter_0x00c0009b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1000001b +#define blitter_code_0x1000001b +void blitter_0x1000001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x10000023 +#define blitter_code_0x10000023 +void blitter_0x10000023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401001d +#define blitter_code_0x3401001d +void blitter_0x3401001d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c000e4 +#define blitter_code_0x00c000e4 +void blitter_0x00c000e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010064 +#define blitter_code_0x24010064 +void blitter_0x24010064(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c040e4 +#define blitter_code_0x00c040e4 +void blitter_0x00c040e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2000002b +#define blitter_code_0x2000002b +void blitter_0x2000002b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00a00058 +#define blitter_code_0x00a00058 +void blitter_0x00a00058(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a1, a1_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata |= ~srcdata & dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x050100d8 +#define blitter_code_0x050100d8 +void blitter_0x050100d8(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a1); + srczdata = READ_RDATA_1(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c00280 +#define blitter_code_0x00c00280 +void blitter_0x00c00280(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_1(a2); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010064 +#define blitter_code_0x04010064 +void blitter_0x04010064(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010003 +#define blitter_code_0x24010003 +void blitter_0x24010003(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010023 +#define blitter_code_0x24010023 +void blitter_0x24010023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c0429b +#define blitter_code_0x00c0429b +void blitter_0x00c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c042db +#define blitter_code_0x00c042db +void blitter_0x00c042db(void) +{ + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + uint32 compare_value=READ_RDATA_8(PATTERNDATA, a1,a1_phrase_mode); + + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + srcdata = 0; + writedata = 0; + + srcdata = READ_PIXEL_8(a1); + if (srcdata != compare_value ) + { + dstdata = READ_PIXEL_8(a2); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1401001b +#define blitter_code_0x1401001b +void blitter_0x1401001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010004 +#define blitter_code_0x24010004 +void blitter_0x24010004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x308000a4 +#define blitter_code_0x308000a4 +void blitter_0x308000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010024 +#define blitter_code_0x14010024 +void blitter_0x14010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010023 +#define blitter_code_0x14010023 +void blitter_0x14010023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30e000a4 +#define blitter_code_0x30e000a4 +void blitter_0x30e000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x10000013 +#define blitter_code_0x10000013 +void blitter_0x10000013(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c00292 +#define blitter_code_0x00c00292 +void blitter_0x00c00292(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x008000a4 +#define blitter_code_0x008000a4 +void blitter_0x008000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00800092 +#define blitter_code_0x00800092 +void blitter_0x00800092(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_RDATA_4(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & dstdata; + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2cc10023 +#define blitter_code_0x2cc10023 +void blitter_0x2cc10023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c10023 +#define blitter_code_0x34c10023 +void blitter_0x34c10023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x38c0429b +#define blitter_code_0x38c0429b +void blitter_0x38c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3cc1001b +#define blitter_code_0x3cc1001b +void blitter_0x3cc1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2cc1001b +#define blitter_code_0x2cc1001b +void blitter_0x2cc1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c0429b +#define blitter_code_0x08c0429b +void blitter_0x08c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1cc1001b +#define blitter_code_0x1cc1001b +void blitter_0x1cc1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0cc1001b +#define blitter_code_0x0cc1001b +void blitter_0x0cc1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3cc10023 +#define blitter_code_0x3cc10023 +void blitter_0x3cc10023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c0009b +#define blitter_code_0x08c0009b +void blitter_0x08c0009b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x28c0429b +#define blitter_code_0x28c0429b +void blitter_0x28c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x18c0429b +#define blitter_code_0x18c0429b +void blitter_0x18c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010005 +#define blitter_code_0x34010005 +void blitter_0x34010005(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401002d +#define blitter_code_0x3401002d +void blitter_0x3401002d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010025 +#define blitter_code_0x14010025 +void blitter_0x14010025(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010025 +#define blitter_code_0x34010025 +void blitter_0x34010025(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401006c +#define blitter_code_0x3401006c +void blitter_0x3401006c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a2, a2_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a2, a2_phrase_mode); + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401022a +#define blitter_code_0x2401022a +void blitter_0x2401022a(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401006a +#define blitter_code_0x2401006a +void blitter_0x2401006a(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a2, a2_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a2, a2_phrase_mode); + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c002e4 +#define blitter_code_0x00c002e4 +void blitter_0x00c002e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_RDATA_16(DSTZ, a2, a2_phrase_mode); + srczdata=z_i[colour_index]>>16; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010212 +#define blitter_code_0x04010212 +void blitter_0x04010212(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c010023 +#define blitter_code_0x2c010023 +void blitter_0x2c010023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3c010023 +#define blitter_code_0x3c010023 +void blitter_0x3c010023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401006b +#define blitter_code_0x3401006b +void blitter_0x3401006b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_32(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c000ad +#define blitter_code_0x00c000ad +void blitter_0x00c000ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00e002ad +#define blitter_code_0x00e002ad +void blitter_0x00e002ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c040a4 +#define blitter_code_0x08c040a4 +void blitter_0x08c040a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c000e4 +#define blitter_code_0x08c000e4 +void blitter_0x08c000e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c010024 +#define blitter_code_0x2c010024 +void blitter_0x2c010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3c010024 +#define blitter_code_0x3c010024 +void blitter_0x3c010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0c010024 +#define blitter_code_0x0c010024 +void blitter_0x0c010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1401001d +#define blitter_code_0x1401001d +void blitter_0x1401001d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c10003 +#define blitter_code_0x34c10003 +void blitter_0x34c10003(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x306002a4 +#define blitter_code_0x306002a4 +void blitter_0x306002a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c00292 +#define blitter_code_0x08c00292 +void blitter_0x08c00292(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_4(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14c10013 +#define blitter_code_0x14c10013 +void blitter_0x14c10013(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x38c0009b +#define blitter_code_0x38c0009b +void blitter_0x38c0009b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c1001b +#define blitter_code_0x34c1001b +void blitter_0x34c1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1401001c +#define blitter_code_0x1401001c +void blitter_0x1401001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c000db +#define blitter_code_0x08c000db +void blitter_0x08c000db(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 dstdata = 0; + uint32 writedata = 0; + srcdata = READ_PIXEL_8(a1); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0401001b +#define blitter_code_0x0401001b +void blitter_0x0401001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0401001d +#define blitter_code_0x0401001d +void blitter_0x0401001d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0401001c +#define blitter_code_0x0401001c +void blitter_0x0401001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x36013624 +#define blitter_code_0x36013624 +void blitter_0x36013624(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_ZDATA_16(a1); + srczdata=z_i[colour_index]>>16; + if (srczdata == dstzdata) inhibit = 1; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + WRITE_ZDATA_16(a1, srczdata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c10284 +#define blitter_code_0x04c10284 +void blitter_0x04c10284(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010004 +#define blitter_code_0x14010004 +void blitter_0x14010004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x06c076e4 +#define blitter_code_0x06c076e4 +void blitter_0x06c076e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_ZDATA_16(a2); + srczdata=z_i[colour_index]>>16; + if (srczdata == dstzdata) inhibit = 1; + if (srczdata > dstzdata) inhibit = 1; + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + WRITE_ZDATA_16(a2, srczdata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c040a4 +#define blitter_code_0x30c040a4 +void blitter_0x30c040a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c040db +#define blitter_code_0x00c040db +void blitter_0x00c040db(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a1); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c0429b +#define blitter_code_0x30c0429b +void blitter_0x30c0429b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c0409b +#define blitter_code_0x08c0409b +void blitter_0x08c0409b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c0029b +#define blitter_code_0x00c0029b +void blitter_0x00c0029b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x20c00003 +#define blitter_code_0x20c00003 +void blitter_0x20c00003(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c0001b +#define blitter_code_0x00c0001b +void blitter_0x00c0001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x20c0002b +#define blitter_code_0x20c0002b +void blitter_0x20c0002b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c0001c +#define blitter_code_0x30c0001c +void blitter_0x30c0001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c000db +#define blitter_code_0x00c000db +void blitter_0x00c000db(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a1); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c00023 +#define blitter_code_0x00c00023 +void blitter_0x00c00023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c10024 +#define blitter_code_0x34c10024 +void blitter_0x34c10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3cc10024 +#define blitter_code_0x3cc10024 +void blitter_0x3cc10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c10084 +#define blitter_code_0x04c10084 +void blitter_0x04c10084(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010004 +#define blitter_code_0x04010004 +void blitter_0x04010004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c000e4 +#define blitter_code_0x30c000e4 +void blitter_0x30c000e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c10004 +#define blitter_code_0x04c10004 +void blitter_0x04c10004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0cc10004 +#define blitter_code_0x0cc10004 +void blitter_0x0cc10004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1cc10024 +#define blitter_code_0x1cc10024 +void blitter_0x1cc10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0cc10084 +#define blitter_code_0x0cc10084 +void blitter_0x0cc10084(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24c10024 +#define blitter_code_0x24c10024 +void blitter_0x24c10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2cc10024 +#define blitter_code_0x2cc10024 +void blitter_0x2cc10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401002c +#define blitter_code_0x3401002c +void blitter_0x3401002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010014 +#define blitter_code_0x14010014 +void blitter_0x14010014(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010013 +#define blitter_code_0x14010013 +void blitter_0x14010013(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30000005 +#define blitter_code_0x30000005 +void blitter_0x30000005(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3000001d +#define blitter_code_0x3000001d +void blitter_0x3000001d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c0002c +#define blitter_code_0x30c0002c +void blitter_0x30c0002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3000002d +#define blitter_code_0x3000002d +void blitter_0x3000002d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x10000025 +#define blitter_code_0x10000025 +void blitter_0x10000025(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x28c0002c +#define blitter_code_0x28c0002c +void blitter_0x28c0002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3002022c +#define blitter_code_0x3002022c +void blitter_0x3002022c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (writedata > 0xff) writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (writedata > 0xfff) writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c040e4 +#define blitter_code_0x08c040e4 +void blitter_0x08c040e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c042a4 +#define blitter_code_0x30c042a4 +void blitter_0x30c042a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401002b +#define blitter_code_0x3401002b +void blitter_0x3401002b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010005 +#define blitter_code_0x14010005 +void blitter_0x14010005(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c01001b +#define blitter_code_0x2c01001b +void blitter_0x2c01001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401001c +#define blitter_code_0x3401001c +void blitter_0x3401001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x05010083 +#define blitter_code_0x05010083 +void blitter_0x05010083(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x05010084 +#define blitter_code_0x05010084 +void blitter_0x05010084(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010064 +#define blitter_code_0x34010064 +void blitter_0x34010064(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14010064 +#define blitter_code_0x14010064 +void blitter_0x14010064(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401021b +#define blitter_code_0x2401021b +void blitter_0x2401021b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010218 +#define blitter_code_0x24010218 +void blitter_0x24010218(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401021a +#define blitter_code_0x2401021a +void blitter_0x2401021a(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401021c +#define blitter_code_0x2401021c +void blitter_0x2401021c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c00064 +#define blitter_code_0x00c00064 +void blitter_0x00c00064(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a1, a1_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c00024 +#define blitter_code_0x00c00024 +void blitter_0x00c00024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x01c042e4 +#define blitter_code_0x01c042e4 +void blitter_0x01c042e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_RDATA_16(DSTZ, a2, a2_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + { + int intensity = srcdata & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + writedata = (srcdata & 0xFF00) | intensity; + } + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x20c0001c +#define blitter_code_0x20c0001c +void blitter_0x20c0001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010219 +#define blitter_code_0x24010219 +void blitter_0x24010219(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_2(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_2(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_2(a1); + dstzdata = READ_RDATA_2(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_2(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_2(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x08c000a4 +#define blitter_code_0x08c000a4 +void blitter_0x08c000a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c01001c +#define blitter_code_0x2c01001c +void blitter_0x2c01001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3c01001c +#define blitter_code_0x3c01001c +void blitter_0x3c01001c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c010218 +#define blitter_code_0x2c010218 +void blitter_0x2c010218(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3050021b +#define blitter_code_0x3050021b +void blitter_0x3050021b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= ~srcdata & ~dstdata; + writedata |= srcdata & ~dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c10004 +#define blitter_code_0x34c10004 +void blitter_0x34c10004(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x05010218 +#define blitter_code_0x05010218 +void blitter_0x05010218(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30020224 +#define blitter_code_0x30020224 +void blitter_0x30020224(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (writedata > 0xff) writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (writedata > 0xfff) writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24c1001b +#define blitter_code_0x24c1001b +void blitter_0x24c1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0501021b +#define blitter_code_0x0501021b +void blitter_0x0501021b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c1001b +#define blitter_code_0x04c1001b +void blitter_0x04c1001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24c10023 +#define blitter_code_0x24c10023 +void blitter_0x24c10023(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x01c040a4 +#define blitter_code_0x01c040a4 +void blitter_0x01c040a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c10024 +#define blitter_code_0x04c10024 +void blitter_0x04c10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0501021c +#define blitter_code_0x0501021c +void blitter_0x0501021c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30e00224 +#define blitter_code_0x30e00224 +void blitter_0x30e00224(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401002d +#define blitter_code_0x2401002d +void blitter_0x2401002d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401002c +#define blitter_code_0x2401002c +void blitter_0x2401002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010005 +#define blitter_code_0x24010005 +void blitter_0x24010005(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010220 +#define blitter_code_0x04010220 +void blitter_0x04010220(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c000ed +#define blitter_code_0x00c000ed +void blitter_0x00c000ed(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a1); + dstdata = READ_RDATA_32(DSTDATA, a2, a2_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x040e026d +#define blitter_code_0x040e026d +void blitter_0x040e026d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_PIXEL_32(a2); + dstzdata = READ_RDATA_32(DSTZ, a2, a2_phrase_mode); + writedata = (srcdata & 0xff) + (dstdata & 0xff); + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0c01002c +#define blitter_code_0x0c01002c +void blitter_0x0c01002c(void) +{ +// fprintf(log_get(),"blitter_0x0c01002c: 0x%.8x 0x%.8x 0x%.8x 0x%.8x cpu %i pc=0x%.8x\n", +// gd_i[0],gd_c[0],gd_ia,gd_ca,jaguar_cpu_in_exec,gpu_read_pc()); + + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 dstdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } + else + { + writedata=dstdata; + } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x040e026c +#define blitter_code_0x040e026c +void blitter_0x040e026c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_PIXEL_32(a2); + dstzdata = READ_RDATA_32(DSTZ, a2, a2_phrase_mode); + if (!inhibit) + { + writedata = (srcdata & 0xff) + (dstdata & 0xff); + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_32(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c04280 +#define blitter_code_0x00c04280 +void blitter_0x00c04280(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_1(a2); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_1(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010200 +#define blitter_code_0x04010200 +void blitter_0x04010200(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00600280 +#define blitter_code_0x00600280 +void blitter_0x00600280(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_1(a2); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + if (!inhibit) + { + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010005 +#define blitter_code_0x04010005 +void blitter_0x04010005(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_32(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0401002c +#define blitter_code_0x0401002c +void blitter_0x0401002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c000db +#define blitter_code_0x30c000db +void blitter_0x30c000db(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a1); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c002ad +#define blitter_code_0x30c002ad +void blitter_0x30c002ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3401009b +#define blitter_code_0x3401009b +void blitter_0x3401009b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04c1022d +#define blitter_code_0x04c1022d +void blitter_0x04c1022d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x008002ad +#define blitter_code_0x008002ad +void blitter_0x008002ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x14c1022d +#define blitter_code_0x14c1022d +void blitter_0x14c1022d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34c1022d +#define blitter_code_0x34c1022d +void blitter_0x34c1022d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_32(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c0029b +#define blitter_code_0x30c0029b +void blitter_0x30c0029b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24c1021b +#define blitter_code_0x24c1021b +void blitter_0x24c1021b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_8(a1); + dstzdata = READ_RDATA_8(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c042ad +#define blitter_code_0x30c042ad +void blitter_0x30c042ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_PIXEL_32(a1); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_32(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3e01261c +#define blitter_code_0x3e01261c +void blitter_0x3e01261c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_ZDATA_16(a1); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + WRITE_ZDATA_16(a1, srczdata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00e00280 +#define blitter_code_0x00e00280 +void blitter_0x00e00280(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_1(a2); + dstdata = READ_PIXEL_1(a1); + dstzdata = READ_RDATA_1(DSTZ, a1, a1_phrase_mode); + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00e00292 +#define blitter_code_0x00e00292 +void blitter_0x00e00292(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata |= ~srcdata & dstdata; + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x308002a4 +#define blitter_code_0x308002a4 +void blitter_0x308002a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x00c002a4 +#define blitter_code_0x00c002a4 +void blitter_0x00c002a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x01c042a4 +#define blitter_code_0x01c042a4 +void blitter_0x01c042a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x06c066e4 +#define blitter_code_0x06c066e4 +void blitter_0x06c066e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_ZDATA_16(a2); + if (srczdata > dstzdata) inhibit = 1; + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + WRITE_ZDATA_16(a2, srczdata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04010222 +#define blitter_code_0x04010222 +void blitter_0x04010222(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x24010224 +#define blitter_code_0x24010224 +void blitter_0x24010224(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2000001b +#define blitter_code_0x2000001b +void blitter_0x2000001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3000005b +#define blitter_code_0x3000005b +void blitter_0x3000005b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a1, a1_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a2, a2_phrase_mode); + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x38000100 +#define blitter_code_0x38000100 +void blitter_0x38000100(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1c010024 +#define blitter_code_0x1c010024 +void blitter_0x1c010024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x000242e4 +#define blitter_code_0x000242e4 +void blitter_0x000242e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_RDATA_16(DSTZ, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (writedata > 0xff) writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (writedata > 0xfff) writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2c01002c +#define blitter_code_0x2c01002c +void blitter_0x2c01002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c042e4 +#define blitter_code_0x30c042e4 +void blitter_0x30c042e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_RDATA_16(DSTZ, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_16(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3c01002c +#define blitter_code_0x3c01002c +void blitter_0x3c01002c(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0cc10212 +#define blitter_code_0x0cc10212 +void blitter_0x0cc10212(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_4(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_4(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_4(a1); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_4(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_4(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x38000301 +#define blitter_code_0x38000301 +void blitter_0x38000301(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_2(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_PIXEL_2(a1); + dstzdata = READ_RDATA_2(DSTZ, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_2(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401002b +#define blitter_code_0x2401002b +void blitter_0x2401002b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c004ad +#define blitter_code_0x30c004ad +void blitter_0x30c004ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04012000 +#define blitter_code_0x04012000 +void blitter_0x04012000(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34012000 +#define blitter_code_0x34012000 +void blitter_0x34012000(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30c004ad +#define blitter_code_0x30c004ad +void blitter_0x30c004ad(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_32(a2); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + dstzdata = READ_RDATA_32(DSTZ, a1, a1_phrase_mode); + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x04012000 +#define blitter_code_0x04012000 +void blitter_0x04012000(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_1(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34012000 +#define blitter_code_0x34012000 +void blitter_0x34012000(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_1(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_1(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30808c92 +#define blitter_code_0x30808c92 +void blitter_0x30808c92(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_4(a2); + dstdata = READ_RDATA_4(DSTDATA, a1, a1_phrase_mode); + dstzdata = READ_RDATA_4(DSTZ, a1, a1_phrase_mode); + if (srczdata < dstzdata) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_4(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0040409b +#define blitter_code_0x0040409b +void blitter_0x0040409b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x1000001d +#define blitter_code_0x1000001d +void blitter_0x1000001d(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a1, a1_phrase_mode); + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_32(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0000409b +#define blitter_code_0x0000409b +void blitter_0x0000409b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a2); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a2,a2_phrase_mode)) inhibit=1; + if (!inhibit) + { + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_8(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x0cc10024 +#define blitter_code_0x0cc10024 +void blitter_0x0cc10024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401001b +#define blitter_code_0x2401001b +void blitter_0x2401001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x01c042db +#define blitter_code_0x01c042db +void blitter_0x01c042db(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_8(a1); + dstdata = READ_PIXEL_8(a2); + dstzdata = READ_RDATA_8(DSTZ, a2, a2_phrase_mode); + if (srcdata == READ_RDATA_8(PATTERNDATA, a1,a1_phrase_mode)) inhibit=1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x34010224 +#define blitter_code_0x34010224 +void blitter_0x34010224(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_RDATA_16(DSTZ, a1, a1_phrase_mode); + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30808800 +#define blitter_code_0x30808800 +void blitter_0x30808800(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_1(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_1(DSTDATA, a1, a1_phrase_mode); + if (srczdata < dstzdata) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_1(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x06c026e4 +#define blitter_code_0x06c026e4 +void blitter_0x06c026e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + srczdata = READ_RDATA_16(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_PIXEL_16(a2); + dstzdata = READ_ZDATA_16(a2); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + WRITE_ZDATA_16(a2, srczdata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x06012624 +#define blitter_code_0x06012624 +void blitter_0x06012624(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_ZDATA_16(a1); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_16(PATTERNDATA, a1, a1_phrase_mode); + writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a1, writedata); + WRITE_ZDATA_16(a1, srczdata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + gd_i[colour_index] += gd_ia; + gd_c[colour_index] += gd_ca; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x000200e4 +#define blitter_code_0x000200e4 +void blitter_0x000200e4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a1); + dstdata = READ_RDATA_16(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata = (srcdata & 0xff) + (dstdata & 0xff); + if (writedata > 0xff) writedata = 0xff; + writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); + if (writedata > 0xfff) writedata = 0xfff; + writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + } else { srczdata=dstzdata; writedata=dstdata; } + if (!inhibit) + { + WRITE_PIXEL_16(a2, writedata); + } + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x37c026a4 +#define blitter_code_0x37c026a4 +void blitter_0x37c026a4(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_PIXEL_16(a2); + srczdata = READ_RDATA_16(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_PIXEL_16(a1); + dstzdata = READ_ZDATA_16(a1); + srczdata=z_i[colour_index]>>16; + if (srczdata > dstzdata) inhibit = 1; + if (!inhibit) + { + writedata |= srcdata & ~dstdata; + writedata |= srcdata & dstdata; + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_16(a1, writedata); + WRITE_ZDATA_16(a1, srczdata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + z_i[colour_index]+=zadd; + colour_index=(colour_index+1)&0x3; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x3c01001b +#define blitter_code_0x3c01001b +void blitter_0x3c01001b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_8(SRCDATA, a2, a2_phrase_mode); + srczdata = READ_RDATA_8(SRCZINT, a2, a2_phrase_mode); + dstdata = READ_RDATA_8(DSTDATA, a1, a1_phrase_mode); + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1; + if (!inhibit) + { + writedata= READ_RDATA_8(PATTERNDATA, a1, a1_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_8(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x2401006b +#define blitter_code_0x2401006b +void blitter_0x2401006b(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_32(SRCDATA, a1, a1_phrase_mode); + srczdata = READ_RDATA_32(SRCZINT, a1, a1_phrase_mode); + dstdata = READ_RDATA_32(DSTDATA, a2, a2_phrase_mode); + if (!inhibit) + { + writedata= READ_RDATA_32(PATTERNDATA, a2, a2_phrase_mode); + } else { srczdata=dstzdata; writedata=dstdata; } + WRITE_PIXEL_32(a2, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif +#ifndef blitter_code_0x30000024 +#define blitter_code_0x30000024 +void blitter_0x30000024(void) +{ + while (outer_loop--) + { + inner_loop=n_pixels; + while (inner_loop--) + { + uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; + uint32 writedata = 0; + uint32 inhibit = 0; + srcdata = READ_RDATA_16(SRCDATA, a2, a2_phrase_mode); + dstdata = READ_RDATA_16(DSTDATA, a1, a1_phrase_mode); + WRITE_PIXEL_16(a1, writedata); + a1_x += a1_xadd; + a1_y += a1_yadd; + a2_x = (a2_x + a2_xadd) & a2_mask_x; + a2_y = (a2_y + a2_yadd) & a2_mask_y; + } + a1_x+=a1_step_x; + a1_y+=a1_step_y; + a2_x+=a2_step_x; + a2_y+=a2_step_y; + } + WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); + WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); +} +#endif diff --git a/src/include/blit_i.h b/src/include/blit_i.h new file mode 100644 index 0000000..9e6b9f5 --- /dev/null +++ b/src/include/blit_i.h @@ -0,0 +1,226 @@ + blitter_add(0x30000000,(uint8*)&blitter_0x30000000); + blitter_add(0x34010004,(uint8*)&blitter_0x34010004); + blitter_add(0x30c002a4,(uint8*)&blitter_0x30c002a4); + blitter_add(0x00c042a4,(uint8*)&blitter_0x00c042a4); + blitter_add(0x08c042a4,(uint8*)&blitter_0x08c042a4); + blitter_add(0x34010024,(uint8*)&blitter_0x34010024); + blitter_add(0x24010222,(uint8*)&blitter_0x24010222); + blitter_add(0x00c04292,(uint8*)&blitter_0x00c04292); + blitter_add(0x00c0409b,(uint8*)&blitter_0x00c0409b); + blitter_add(0x30000003,(uint8*)&blitter_0x30000003); + blitter_add(0x34010003,(uint8*)&blitter_0x34010003); + blitter_add(0x30c000ad,(uint8*)&blitter_0x30c000ad); + blitter_add(0x30c0009b,(uint8*)&blitter_0x30c0009b); + blitter_add(0x3401001b,(uint8*)&blitter_0x3401001b); + blitter_add(0x30c000a4,(uint8*)&blitter_0x30c000a4); + blitter_add(0x34010023,(uint8*)&blitter_0x34010023); + blitter_add(0x30000023,(uint8*)&blitter_0x30000023); + blitter_add(0x24010024,(uint8*)&blitter_0x24010024); + blitter_add(0x00c000a4,(uint8*)&blitter_0x00c000a4); + blitter_add(0x00c040a4,(uint8*)&blitter_0x00c040a4); + blitter_add(0x04010024,(uint8*)&blitter_0x04010024); + blitter_add(0x2401001c,(uint8*)&blitter_0x2401001c); + blitter_add(0x3000002b,(uint8*)&blitter_0x3000002b); + blitter_add(0x3000001b,(uint8*)&blitter_0x3000001b); + blitter_add(0x00c0009b,(uint8*)&blitter_0x00c0009b); + blitter_add(0x1000001b,(uint8*)&blitter_0x1000001b); + blitter_add(0x10000023,(uint8*)&blitter_0x10000023); + blitter_add(0x3401001d,(uint8*)&blitter_0x3401001d); + blitter_add(0x00c000e4,(uint8*)&blitter_0x00c000e4); + blitter_add(0x24010064,(uint8*)&blitter_0x24010064); + blitter_add(0x00c040e4,(uint8*)&blitter_0x00c040e4); + blitter_add(0x2000002b,(uint8*)&blitter_0x2000002b); + blitter_add(0x00a00058,(uint8*)&blitter_0x00a00058); + blitter_add(0x050100d8,(uint8*)&blitter_0x050100d8); + blitter_add(0x00c00280,(uint8*)&blitter_0x00c00280); + blitter_add(0x04010064,(uint8*)&blitter_0x04010064); + blitter_add(0x24010003,(uint8*)&blitter_0x24010003); + blitter_add(0x24010023,(uint8*)&blitter_0x24010023); + blitter_add(0x00c0429b,(uint8*)&blitter_0x00c0429b); + blitter_add(0x00c042db,(uint8*)&blitter_0x00c042db); + blitter_add(0x1401001b,(uint8*)&blitter_0x1401001b); + blitter_add(0x24010004,(uint8*)&blitter_0x24010004); + blitter_add(0x308000a4,(uint8*)&blitter_0x308000a4); + blitter_add(0x14010024,(uint8*)&blitter_0x14010024); + blitter_add(0x14010023,(uint8*)&blitter_0x14010023); + blitter_add(0x30e000a4,(uint8*)&blitter_0x30e000a4); + blitter_add(0x10000013,(uint8*)&blitter_0x10000013); + blitter_add(0x00c00292,(uint8*)&blitter_0x00c00292); + blitter_add(0x008000a4,(uint8*)&blitter_0x008000a4); + blitter_add(0x00800092,(uint8*)&blitter_0x00800092); + blitter_add(0x2cc10023,(uint8*)&blitter_0x2cc10023); + blitter_add(0x34c10023,(uint8*)&blitter_0x34c10023); + blitter_add(0x38c0429b,(uint8*)&blitter_0x38c0429b); + blitter_add(0x3cc1001b,(uint8*)&blitter_0x3cc1001b); + blitter_add(0x2cc1001b,(uint8*)&blitter_0x2cc1001b); + blitter_add(0x08c0429b,(uint8*)&blitter_0x08c0429b); + blitter_add(0x1cc1001b,(uint8*)&blitter_0x1cc1001b); + blitter_add(0x0cc1001b,(uint8*)&blitter_0x0cc1001b); + blitter_add(0x3cc10023,(uint8*)&blitter_0x3cc10023); + blitter_add(0x08c0009b,(uint8*)&blitter_0x08c0009b); + blitter_add(0x28c0429b,(uint8*)&blitter_0x28c0429b); + blitter_add(0x18c0429b,(uint8*)&blitter_0x18c0429b); + blitter_add(0x34010005,(uint8*)&blitter_0x34010005); + blitter_add(0x3401002d,(uint8*)&blitter_0x3401002d); + blitter_add(0x14010025,(uint8*)&blitter_0x14010025); + blitter_add(0x34010025,(uint8*)&blitter_0x34010025); + blitter_add(0x3401006c,(uint8*)&blitter_0x3401006c); + blitter_add(0x2401022a,(uint8*)&blitter_0x2401022a); + blitter_add(0x2401006a,(uint8*)&blitter_0x2401006a); + blitter_add(0x00c002e4,(uint8*)&blitter_0x00c002e4); + blitter_add(0x04010212,(uint8*)&blitter_0x04010212); + blitter_add(0x2c010023,(uint8*)&blitter_0x2c010023); + blitter_add(0x3c010023,(uint8*)&blitter_0x3c010023); + blitter_add(0x3401006b,(uint8*)&blitter_0x3401006b); + blitter_add(0x00c000ad,(uint8*)&blitter_0x00c000ad); + blitter_add(0x00e002ad,(uint8*)&blitter_0x00e002ad); + blitter_add(0x08c040a4,(uint8*)&blitter_0x08c040a4); + blitter_add(0x08c000e4,(uint8*)&blitter_0x08c000e4); + blitter_add(0x2c010024,(uint8*)&blitter_0x2c010024); + blitter_add(0x3c010024,(uint8*)&blitter_0x3c010024); + blitter_add(0x0c010024,(uint8*)&blitter_0x0c010024); + blitter_add(0x1401001d,(uint8*)&blitter_0x1401001d); + blitter_add(0x34c10003,(uint8*)&blitter_0x34c10003); + blitter_add(0x306002a4,(uint8*)&blitter_0x306002a4); + blitter_add(0x08c00292,(uint8*)&blitter_0x08c00292); + blitter_add(0x14c10013,(uint8*)&blitter_0x14c10013); + blitter_add(0x38c0009b,(uint8*)&blitter_0x38c0009b); + blitter_add(0x34c1001b,(uint8*)&blitter_0x34c1001b); + blitter_add(0x1401001c,(uint8*)&blitter_0x1401001c); + blitter_add(0x08c000db,(uint8*)&blitter_0x08c000db); + blitter_add(0x0401001b,(uint8*)&blitter_0x0401001b); + blitter_add(0x0401001d,(uint8*)&blitter_0x0401001d); + blitter_add(0x0401001c,(uint8*)&blitter_0x0401001c); + blitter_add(0x36013624,(uint8*)&blitter_0x36013624); + blitter_add(0x04c10284,(uint8*)&blitter_0x04c10284); + blitter_add(0x14010004,(uint8*)&blitter_0x14010004); + blitter_add(0x06c076e4,(uint8*)&blitter_0x06c076e4); + blitter_add(0x30c040a4,(uint8*)&blitter_0x30c040a4); + blitter_add(0x00c040db,(uint8*)&blitter_0x00c040db); + blitter_add(0x30c0429b,(uint8*)&blitter_0x30c0429b); + blitter_add(0x08c0409b,(uint8*)&blitter_0x08c0409b); + blitter_add(0x00c0029b,(uint8*)&blitter_0x00c0029b); + blitter_add(0x20c00003,(uint8*)&blitter_0x20c00003); + blitter_add(0x00c0001b,(uint8*)&blitter_0x00c0001b); + blitter_add(0x20c0002b,(uint8*)&blitter_0x20c0002b); + blitter_add(0x30c0001c,(uint8*)&blitter_0x30c0001c); + blitter_add(0x00c000db,(uint8*)&blitter_0x00c000db); + blitter_add(0x00c00023,(uint8*)&blitter_0x00c00023); + blitter_add(0x34c10024,(uint8*)&blitter_0x34c10024); + blitter_add(0x3cc10024,(uint8*)&blitter_0x3cc10024); + blitter_add(0x04c10084,(uint8*)&blitter_0x04c10084); + blitter_add(0x04010004,(uint8*)&blitter_0x04010004); + blitter_add(0x30c000e4,(uint8*)&blitter_0x30c000e4); + blitter_add(0x04c10004,(uint8*)&blitter_0x04c10004); + blitter_add(0x0cc10004,(uint8*)&blitter_0x0cc10004); + blitter_add(0x1cc10024,(uint8*)&blitter_0x1cc10024); + blitter_add(0x0cc10084,(uint8*)&blitter_0x0cc10084); + blitter_add(0x24c10024,(uint8*)&blitter_0x24c10024); + blitter_add(0x2cc10024,(uint8*)&blitter_0x2cc10024); + blitter_add(0x3401002c,(uint8*)&blitter_0x3401002c); + blitter_add(0x14010014,(uint8*)&blitter_0x14010014); + blitter_add(0x14010013,(uint8*)&blitter_0x14010013); + blitter_add(0x30000005,(uint8*)&blitter_0x30000005); + blitter_add(0x3000001d,(uint8*)&blitter_0x3000001d); + blitter_add(0x30c0002c,(uint8*)&blitter_0x30c0002c); + blitter_add(0x3000002d,(uint8*)&blitter_0x3000002d); + blitter_add(0x10000025,(uint8*)&blitter_0x10000025); + blitter_add(0x28c0002c,(uint8*)&blitter_0x28c0002c); + blitter_add(0x3002022c,(uint8*)&blitter_0x3002022c); + blitter_add(0x08c040e4,(uint8*)&blitter_0x08c040e4); + blitter_add(0x30c042a4,(uint8*)&blitter_0x30c042a4); + blitter_add(0x3401002b,(uint8*)&blitter_0x3401002b); + blitter_add(0x14010005,(uint8*)&blitter_0x14010005); + blitter_add(0x2c01001b,(uint8*)&blitter_0x2c01001b); + blitter_add(0x3401001c,(uint8*)&blitter_0x3401001c); + blitter_add(0x05010083,(uint8*)&blitter_0x05010083); + blitter_add(0x05010084,(uint8*)&blitter_0x05010084); + blitter_add(0x34010064,(uint8*)&blitter_0x34010064); + blitter_add(0x14010064,(uint8*)&blitter_0x14010064); + blitter_add(0x2401021b,(uint8*)&blitter_0x2401021b); + blitter_add(0x24010218,(uint8*)&blitter_0x24010218); + blitter_add(0x2401021a,(uint8*)&blitter_0x2401021a); + blitter_add(0x2401021c,(uint8*)&blitter_0x2401021c); + blitter_add(0x00c00064,(uint8*)&blitter_0x00c00064); + blitter_add(0x00c00024,(uint8*)&blitter_0x00c00024); + blitter_add(0x01c042e4,(uint8*)&blitter_0x01c042e4); + blitter_add(0x20c0001c,(uint8*)&blitter_0x20c0001c); + blitter_add(0x24010219,(uint8*)&blitter_0x24010219); + blitter_add(0x08c000a4,(uint8*)&blitter_0x08c000a4); + blitter_add(0x2c01001c,(uint8*)&blitter_0x2c01001c); + blitter_add(0x3c01001c,(uint8*)&blitter_0x3c01001c); + blitter_add(0x2c010218,(uint8*)&blitter_0x2c010218); + blitter_add(0x3050021b,(uint8*)&blitter_0x3050021b); + blitter_add(0x34c10004,(uint8*)&blitter_0x34c10004); + blitter_add(0x05010218,(uint8*)&blitter_0x05010218); + blitter_add(0x30020224,(uint8*)&blitter_0x30020224); + blitter_add(0x24c1001b,(uint8*)&blitter_0x24c1001b); + blitter_add(0x0501021b,(uint8*)&blitter_0x0501021b); + blitter_add(0x04c1001b,(uint8*)&blitter_0x04c1001b); + blitter_add(0x24c10023,(uint8*)&blitter_0x24c10023); + blitter_add(0x01c040a4,(uint8*)&blitter_0x01c040a4); + blitter_add(0x04c10024,(uint8*)&blitter_0x04c10024); + blitter_add(0x0501021c,(uint8*)&blitter_0x0501021c); + blitter_add(0x30e00224,(uint8*)&blitter_0x30e00224); + blitter_add(0x2401002d,(uint8*)&blitter_0x2401002d); + blitter_add(0x2401002c,(uint8*)&blitter_0x2401002c); + blitter_add(0x24010005,(uint8*)&blitter_0x24010005); + blitter_add(0x04010220,(uint8*)&blitter_0x04010220); + blitter_add(0x00c000ed,(uint8*)&blitter_0x00c000ed); + blitter_add(0x040e026d,(uint8*)&blitter_0x040e026d); + blitter_add(0x0c01002c,(uint8*)&blitter_0x0c01002c); + blitter_add(0x040e026c,(uint8*)&blitter_0x040e026c); + blitter_add(0x00c04280,(uint8*)&blitter_0x00c04280); + blitter_add(0x04010200,(uint8*)&blitter_0x04010200); + blitter_add(0x00600280,(uint8*)&blitter_0x00600280); + blitter_add(0x04010005,(uint8*)&blitter_0x04010005); + blitter_add(0x0401002c,(uint8*)&blitter_0x0401002c); + blitter_add(0x30c000db,(uint8*)&blitter_0x30c000db); + blitter_add(0x30c002ad,(uint8*)&blitter_0x30c002ad); + blitter_add(0x3401009b,(uint8*)&blitter_0x3401009b); + blitter_add(0x04c1022d,(uint8*)&blitter_0x04c1022d); + blitter_add(0x008002ad,(uint8*)&blitter_0x008002ad); + blitter_add(0x14c1022d,(uint8*)&blitter_0x14c1022d); + blitter_add(0x34c1022d,(uint8*)&blitter_0x34c1022d); + blitter_add(0x30c0029b,(uint8*)&blitter_0x30c0029b); + blitter_add(0x24c1021b,(uint8*)&blitter_0x24c1021b); + blitter_add(0x30c042ad,(uint8*)&blitter_0x30c042ad); + blitter_add(0x3e01261c,(uint8*)&blitter_0x3e01261c); + blitter_add(0x00e00280,(uint8*)&blitter_0x00e00280); + blitter_add(0x00e00292,(uint8*)&blitter_0x00e00292); + blitter_add(0x308002a4,(uint8*)&blitter_0x308002a4); + blitter_add(0x00c002a4,(uint8*)&blitter_0x00c002a4); + blitter_add(0x01c042a4,(uint8*)&blitter_0x01c042a4); + blitter_add(0x06c066e4,(uint8*)&blitter_0x06c066e4); + blitter_add(0x04010222,(uint8*)&blitter_0x04010222); + blitter_add(0x24010224,(uint8*)&blitter_0x24010224); + blitter_add(0x2000001b,(uint8*)&blitter_0x2000001b); + blitter_add(0x3000005b,(uint8*)&blitter_0x3000005b); + blitter_add(0x38000100,(uint8*)&blitter_0x38000100); + blitter_add(0x1c010024,(uint8*)&blitter_0x1c010024); + blitter_add(0x000242e4,(uint8*)&blitter_0x000242e4); + blitter_add(0x2c01002c,(uint8*)&blitter_0x2c01002c); + blitter_add(0x30c042e4,(uint8*)&blitter_0x30c042e4); + blitter_add(0x3c01002c,(uint8*)&blitter_0x3c01002c); + blitter_add(0x0cc10212,(uint8*)&blitter_0x0cc10212); + blitter_add(0x38000301,(uint8*)&blitter_0x38000301); + blitter_add(0x2401002b,(uint8*)&blitter_0x2401002b); + blitter_add(0x30c004ad,(uint8*)&blitter_0x30c004ad); + blitter_add(0x04012000,(uint8*)&blitter_0x04012000); + blitter_add(0x34012000,(uint8*)&blitter_0x34012000); + blitter_add(0x30808c92,(uint8*)&blitter_0x30808c92); + blitter_add(0x0040409b,(uint8*)&blitter_0x0040409b); + blitter_add(0x1000001d,(uint8*)&blitter_0x1000001d); + blitter_add(0x0000409b,(uint8*)&blitter_0x0000409b); + blitter_add(0x0cc10024,(uint8*)&blitter_0x0cc10024); + blitter_add(0x2401001b,(uint8*)&blitter_0x2401001b); + blitter_add(0x01c042db,(uint8*)&blitter_0x01c042db); + blitter_add(0x34010224,(uint8*)&blitter_0x34010224); + blitter_add(0x30808800,(uint8*)&blitter_0x30808800); + blitter_add(0x06c026e4,(uint8*)&blitter_0x06c026e4); + blitter_add(0x06012624,(uint8*)&blitter_0x06012624); + blitter_add(0x000200e4,(uint8*)&blitter_0x000200e4); + blitter_add(0x37c026a4,(uint8*)&blitter_0x37c026a4); + blitter_add(0x3c01001b,(uint8*)&blitter_0x3c01001b); + blitter_add(0x2401006b,(uint8*)&blitter_0x2401006b); + blitter_add(0x30000024,(uint8*)&blitter_0x30000024); diff --git a/src/include/blitter.h b/src/include/blitter.h new file mode 100644 index 0000000..d18b999 --- /dev/null +++ b/src/include/blitter.h @@ -0,0 +1,19 @@ +#ifndef __BLITTER_H__ +#define __BLITTER_H__ + +#include "types.h" + +void blitter_init(void); +void blitter_reset(void); +void blitter_done(void); +void blitter_byte_write(uint32, uint8); +void blitter_word_write(uint32, uint16); +uint8 blitter_byte_read(uint32); +uint16 blitter_word_read(uint32); +uint32 blitter_long_read(uint32 offset); +void blitter_long_write(uint32 offset, uint32 data); +uint32 blitter_reg_read(uint32 offset); +void blitter_reg_write(uint32 offset, uint32 data); +extern uint8 blitter_working; + +#endif diff --git a/src/include/blittertest.h b/src/include/blittertest.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/cdbios.h b/src/include/cdbios.h new file mode 100644 index 0000000..5046d51 --- /dev/null +++ b/src/include/cdbios.h @@ -0,0 +1,14 @@ +#ifndef __CDBIOS_H__ +#define __CDBIOS_H__ + +#include "jaguar.h" + +void cd_bios_init(void); +void cd_bios_reset(void); +void cd_bios_done(void); +void cd_bios_process(uint32 cmd); +void cd_bios_boot(char *filename); +void cd_bios_exec(uint32 scanline); + + +#endif diff --git a/src/include/cdi.h b/src/include/cdi.h new file mode 100644 index 0000000..a7d61f4 --- /dev/null +++ b/src/include/cdi.h @@ -0,0 +1,55 @@ +#ifndef __CDI_H__ +#define __CDI_H__ + +#include "jaguar.h" +#include "types.h" +#include +#include +#ifndef __PORT__ +#include +#endif +#include + +struct s_cdi_track +{ + uint8 filename_length; + uint32 pregap_length; + uint32 length; + uint32 mode; + uint32 start_lba; + uint32 total_length; + uint32 sector_size; + uint32 sector_size_value; + uint32 position; +}; + +struct s_cdi_session +{ + uint16 nb_of_tracks; + s_cdi_track *tracks; +}; + +struct s_cdi_descriptor +{ + uint32 length; + uint32 version; + uint32 header_offset; + uint16 nb_of_sessions; + s_cdi_session *sessions; +}; + +extern int cdi_fp; +extern uint32 cdi_load_address; +extern uint32 cdi_code_length; +extern s_cdi_descriptor *cdi_descriptor; +extern s_cdi_track **cdi_tracks; +extern uint32 cdi_tracks_count; + +int cdi_open(char *path); +void cdi_close(int fp); +s_cdi_descriptor *cdi_get_descriptor(int fp, FILE *stdfp); +void cdi_dump_descriptor(FILE *fp,s_cdi_descriptor *cdi_descriptor); +uint8 *cdi_extract_boot_code(int fp, s_cdi_descriptor *cdi_descriptor); +void cdi_load_sector(uint32 sector, uint8 *buffer); + +#endif diff --git a/src/include/cdrom.h b/src/include/cdrom.h new file mode 100644 index 0000000..5b06d39 --- /dev/null +++ b/src/include/cdrom.h @@ -0,0 +1,16 @@ +#ifndef __CDROM_H__ +#define __CDROM_H__ + +#include "jaguar.h" + +void cdrom_init(void); +void cdrom_reset(void); +void cdrom_done(void); + +void cdrom_update(void); +void cdrom_byte_write(uint32 offset, uint8 data); +void cdrom_word_write(uint32 offset, uint16 data); +uint8 cdrom_byte_read(uint32 offset); +uint16 cdrom_word_read(uint32 offset); + +#endif diff --git a/src/include/clock.h b/src/include/clock.h new file mode 100644 index 0000000..d727584 --- /dev/null +++ b/src/include/clock.h @@ -0,0 +1,14 @@ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "types.h" + +void clock_init(void); +void clock_reset(void); +void clock_done(void); +void clock_byte_write(uint32, uint8); +void clock_word_write(uint32, uint16); +uint8 clock_byte_read(uint32); +uint16 clock_word_read(uint32); + +#endif diff --git a/src/include/crc32.h b/src/include/crc32.h new file mode 100644 index 0000000..fd9faa6 --- /dev/null +++ b/src/include/crc32.h @@ -0,0 +1,6 @@ +#ifndef __CRC32_H__ +#define __CRC32_H__ + +int crc32_calcCheckSum(unsigned char *data, unsigned int length); + +#endif diff --git a/src/include/cry2rgb.h b/src/include/cry2rgb.h new file mode 100644 index 0000000..735d293 --- /dev/null +++ b/src/include/cry2rgb.h @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////////////// +// Red Color Values for CrY<->RGB Color Conversion +//////////////////////////////////////////////////////////////////////////////// + + uint8 redcv[16][16] = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + // ---------------------------------------------------------------------- + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 19, 0, // 1 + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 64, 43, 21, 0, // 2 + 102,102,102,102,102,102,102,102,102,102,102,95, 71, 47, 23, 0, // 3 + 135,135,135,135,135,135,135,135,135,135,130,104,78, 52, 26, 0, // 4 + 169,169,169,169,169,169,169,169,169,170,141,113,85, 56, 28, 0, // 5 + 203,203,203,203,203,203,203,203,203,183,153,122,91, 61, 30, 0, // 6 + 237,237,237,237,237,237,237,237,230,197,164,131,98, 65, 32, 0, // 7 + 255,255,255,255,255,255,255,255,247,214,181,148,15, 82, 49, 7, // 8 + 255,255,255,255,255,255,255,255,255,235,204,173,143,112,81, 51, // 9 + 255,255,255,255,255,255,255,255,255,255,227,198,170,141,113,85, // A + 255,255,255,255,255,255,255,255,255,255,249,223,197,171,145,119, // B + 255,255,255,255,255,255,255,255,255,255,255,248,224,200,177,153, // C + 255,255,255,255,255,255,255,255,255,255,255,255,252,230,208,187, // D + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,221, // E + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F + }; + +//////////////////////////////////////////////////////////////////////////////// +// Green Color Values for CrY<->RGB Color Conversion +//////////////////////////////////////////////////////////////////////////////// + + uint8 greencv[16][16] = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + // ---------------------------------------------------------------------- + 0, 17, 34, 51,68, 85, 102,119,136,153,170,187,204,221,238,255, // 0 + 0, 19, 38, 57,77, 96, 115,134,154,173,192,211,231,250,255,255, // 1 + 0, 21, 43, 64,86, 107,129,150,172,193,215,236,255,255,255,255, // 2 + 0, 23, 47, 71,95, 119,142,166,190,214,238,255,255,255,255,255, // 3 + 0, 26, 52, 78,104,130,156,182,208,234,255,255,255,255,255,255, // 4 + 0, 28, 56, 85,113,141,170,198,226,255,255,255,255,255,255,255, // 5 + 0, 30, 61, 91,122,153,183,214,244,255,255,255,255,255,255,255, // 6 + 0, 32, 65, 98,131,164,197,230,255,255,255,255,255,255,255,255, // 7 + 0, 32, 65, 98,131,164,197,230,255,255,255,255,255,255,255,255, // 8 + 0, 30, 61, 91,122,153,183,214,244,255,255,255,255,255,255,255, // 9 + 0, 28, 56, 85,113,141,170,198,226,255,255,255,255,255,255,255, // A + 0, 26, 52, 78,104,130,156,182,208,234,255,255,255,255,255,255, // B + 0, 23, 47, 71,95, 119,142,166,190,214,238,255,255,255,255,255, // C + 0, 21, 43, 64,86, 107,129,150,172,193,215,236,255,255,255,255, // D + 0, 19, 38, 57,77, 96, 115,134,154,173,192,211,231,250,255,255, // E + 0, 17, 34, 51,68, 85, 102,119,136,153,170,187,204,221,238,255 // F + }; + +//////////////////////////////////////////////////////////////////////////////// +// Blue Color Values for CrY<->RGB Color Conversion +//////////////////////////////////////////////////////////////////////////////// + + uint8 bluecv[16][16] = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + // ---------------------------------------------------------------------- + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,221, // 1 + 255,255,255,255,255,255,255,255,255,255,255,255,252,230,208,187, // 2 + 255,255,255,255,255,255,255,255,255,255,255,248,224,200,177,153, // 3 + 255,255,255,255,255,255,255,255,255,255,249,223,197,171,145,119, // 4 + 255,255,255,255,255,255,255,255,255,255,227,198,170,141,113,85, // 5 + 255,255,255,255,255,255,255,255,255,235,204,173,143,112,81, 51, // 6 + 255,255,255,255,255,255,255,255,247,214,181,148,115,82, 49, 17, // 7 + 237,237,237,237,237,237,237,237,230,197,164,131,98, 65, 32, 0, // 8 + 203,203,203,203,203,203,203,203,203,183,153,122,91, 61, 30, 0, // 9 + 169,169,169,169,169,169,169,169,169,170,141,113,85, 56, 28, 0, // A + 135,135,135,135,135,135,135,135,135,135,130,104,78, 52, 26, 0, // B + 102,102,102,102,102,102,102,102,102,102,102,95, 71, 47, 23, 0, // C + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 64, 43, 21, 0, // D + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 19, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + }; diff --git a/src/include/dsnd.h b/src/include/dsnd.h new file mode 100644 index 0000000..62cf88c --- /dev/null +++ b/src/include/dsnd.h @@ -0,0 +1,20 @@ +#ifndef __DSOUND_H__ +#define __DSOUND_H__ + + +void ws_audio_init(void); +void ws_audio_reset(void); +void ws_audio_done(void); +int ws_audio_seal_init(void); +void ws_audio_seal_done(void); +void ws_audio_clear_channel(int Channel); +int ws_audio_play_channel(int Channel); +int ws_audio_stop_channel(int Channel); +void ws_write_state(int fp); +void ws_read_state(int fp); +void system_sound_clear(void); +void system_sound_shutdown(void); +void system_sound_update(void); + + +#endif diff --git a/src/include/dsp.h b/src/include/dsp.h new file mode 100644 index 0000000..3c6f87a --- /dev/null +++ b/src/include/dsp.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __DSP_H__ +#define __DSP_H__ + +#include "jaguar.h" + +#define dsp_control_ram_base 0x00f1a100 +#define dsp_work_ram_base 0x00f1b000 + +void dsp_init(void); +void dsp_reset(void); +void dsp_exec(int32); +void dsp_done(void); +void dsp_update_register_banks(void); +void dsp_check_irqs(void); +void dsp_set_irq_line(int irqline, int state); +unsigned dsp_byte_read(unsigned int offset); +unsigned dsp_word_read(unsigned int offset); +unsigned dsp_long_read(unsigned int offset); +void dsp_byte_write(unsigned offset, unsigned data); +void dsp_word_write(unsigned offset, unsigned data); +void dsp_long_write(unsigned offset, unsigned data); +void dsp_check_if_i2s_interrupt_needed(void); +void dsp_releaseTimeslice(void); + +#endif diff --git a/src/include/eeprom.h b/src/include/eeprom.h new file mode 100644 index 0000000..463526c --- /dev/null +++ b/src/include/eeprom.h @@ -0,0 +1,16 @@ +#ifndef __EEPROM_H__ +#define __EEPROm_H__ + +#include "jaguar.h" + +void eeprom_init(void); +void eeprom_reset(void); +void eeprom_done(void); + +void eeprom_update(void); +void eeprom_byte_write(uint32 offset, uint8 data); +void eeprom_word_write(uint32 offset, uint16 data); +uint8 eeprom_byte_read(uint32 offset); +uint16 eeprom_word_read(uint32 offset); + +#endif diff --git a/src/include/fbmpop1.h b/src/include/fbmpop1.h new file mode 100644 index 0000000..2dcf9cf --- /dev/null +++ b/src/include/fbmpop1.h @@ -0,0 +1,145 @@ + + uint32 c; + paletteRam+=(idx<<2); + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_TB_HFLIP(C) if (C) { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else current_line_buffer-=2; + + PUTPIXEL_1_TB_HFLIP(c&0x80) + PUTPIXEL_1_TB_HFLIP(c&0x40) + PUTPIXEL_1_TB_HFLIP(c&0x20) + PUTPIXEL_1_TB_HFLIP(c&0x10) + PUTPIXEL_1_TB_HFLIP(c&0x08) + PUTPIXEL_1_TB_HFLIP(c&0x04) + PUTPIXEL_1_TB_HFLIP(c&0x02) + PUTPIXEL_1_TB_HFLIP(c&0x01) + } + else + { + #define PUTPIXEL_1_B_HFLIP(C) if (C) { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[1]); } + PUTPIXEL_1_B_HFLIP(c&0x80) + PUTPIXEL_1_B_HFLIP(c&0x40) + PUTPIXEL_1_B_HFLIP(c&0x20) + PUTPIXEL_1_B_HFLIP(c&0x10) + PUTPIXEL_1_B_HFLIP(c&0x08) + PUTPIXEL_1_B_HFLIP(c&0x04) + PUTPIXEL_1_B_HFLIP(c&0x02) + PUTPIXEL_1_B_HFLIP(c&0x01) + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_TB(C) if (C) { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else current_line_buffer+=2; + + PUTPIXEL_1_TB(c&0x80) + PUTPIXEL_1_TB(c&0x40) + PUTPIXEL_1_TB(c&0x20) + PUTPIXEL_1_TB(c&0x10) + PUTPIXEL_1_TB(c&0x08) + PUTPIXEL_1_TB(c&0x04) + PUTPIXEL_1_TB(c&0x02) + PUTPIXEL_1_TB(c&0x01) + } + else + { + #define PUTPIXEL_1_B(C) if (C) { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[1]); } + PUTPIXEL_1_B(c&0x80) + PUTPIXEL_1_B(c&0x40) + PUTPIXEL_1_B(c&0x20) + PUTPIXEL_1_B(c&0x10) + PUTPIXEL_1_B(c&0x08) + PUTPIXEL_1_B(c&0x04) + PUTPIXEL_1_B(c&0x02) + PUTPIXEL_1_B(c&0x01) + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_T_HFLIP(C) if (C) { *current_line_buffer--=paletteRam[(1<<1)+0]; *current_line_buffer--=paletteRam[(1<<1)+1]; } else current_line_buffer-=2; + + PUTPIXEL_1_T_HFLIP(c&0x80) + PUTPIXEL_1_T_HFLIP(c&0x40) + PUTPIXEL_1_T_HFLIP(c&0x20) + PUTPIXEL_1_T_HFLIP(c&0x10) + PUTPIXEL_1_T_HFLIP(c&0x08) + PUTPIXEL_1_T_HFLIP(c&0x04) + PUTPIXEL_1_T_HFLIP(c&0x02) + PUTPIXEL_1_T_HFLIP(c&0x01) + } + else + { + #define PUTPIXEL_1_HFLIP(C) if (C) { *current_line_buffer--=paletteRam[(1<<1)+0]; *current_line_buffer--=paletteRam[(1<<1)+1]; } else { *current_line_buffer--=paletteRam[0]; *current_line_buffer--=paletteRam[1]; } + PUTPIXEL_1_HFLIP(c&0x80) + PUTPIXEL_1_HFLIP(c&0x40) + PUTPIXEL_1_HFLIP(c&0x20) + PUTPIXEL_1_HFLIP(c&0x10) + PUTPIXEL_1_HFLIP(c&0x08) + PUTPIXEL_1_HFLIP(c&0x04) + PUTPIXEL_1_HFLIP(c&0x02) + PUTPIXEL_1_HFLIP(c&0x01) + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_T(C) if (C) { *current_line_buffer++=paletteRam[(1<<1)+0]; *current_line_buffer++=paletteRam[(1<<1)+1]; } else current_line_buffer+=2; + + PUTPIXEL_1_T(c&0x80) + PUTPIXEL_1_T(c&0x40) + PUTPIXEL_1_T(c&0x20) + PUTPIXEL_1_T(c&0x10) + PUTPIXEL_1_T(c&0x08) + PUTPIXEL_1_T(c&0x04) + PUTPIXEL_1_T(c&0x02) + PUTPIXEL_1_T(c&0x01) + } + else + { + #define PUTPIXEL_1(C) if (C) { *current_line_buffer++=paletteRam[(1<<1)+0]; *current_line_buffer++=paletteRam[(1<<1)+1]; } else { *current_line_buffer++=paletteRam[0]; *current_line_buffer++=paletteRam[1]; } + PUTPIXEL_1(c&0x80) + PUTPIXEL_1(c&0x40) + PUTPIXEL_1(c&0x20) + PUTPIXEL_1(c&0x10) + PUTPIXEL_1(c&0x08) + PUTPIXEL_1(c&0x04) + PUTPIXEL_1(c&0x02) + PUTPIXEL_1(c&0x01) + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop16.h b/src/include/fbmpop16.h new file mode 100644 index 0000000..e05fd61 --- /dev/null +++ b/src/include/fbmpop16.h @@ -0,0 +1,146 @@ + if (flags & FLAGS_READMODIFY) + { + if (flags & FLAGS_HFLIP) + { + while (iwidth) + { + uint8 dataHi = jaguar_byte_read(ptr++), dataLo = jaguar_byte_read(ptr++); + + if (flags & FLAGS_TRANSPARENT) + { +// uint16 data = jaguar_byte_read(ptr++); +// data <<= 8; +// data |= jaguar_byte_read(ptr++); +/* if (data) + { + *current_line_buffer-- = BLEND_Y(*current_line_buffer, data >> 8); + *current_line_buffer-- = BLEND_CC(*current_line_buffer, data & 0xFF); + }*/ + if (dataHi | dataLo) + { + *current_line_buffer-- = BLEND_Y(*current_line_buffer, dataHi); + *current_line_buffer-- = BLEND_CC(*current_line_buffer, dataLo); + } + else + current_line_buffer -= 2; + } + else // !FLAGS_TRANSPARENT + { +// *current_line_buffer-- = BLEND_Y(*current_line_buffer, jaguar_byte_read(ptr++)); +// *current_line_buffer-- = BLEND_CC(*current_line_buffer, jaguar_byte_read(ptr++)); + *current_line_buffer-- = BLEND_Y(*current_line_buffer, dataHi); + *current_line_buffer-- = BLEND_CC(*current_line_buffer, dataLo); + } + iwidth--; + } + } + else // !FLAGS_HFLIP + { + while (iwidth) + { + uint8 dataHi = jaguar_byte_read(ptr++), dataLo = jaguar_byte_read(ptr++); + + if (flags & FLAGS_TRANSPARENT) + { +/* uint16 data = jaguar_byte_read(ptr++); + data <<= 8; + data |= jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++ = BLEND_Y(*current_line_buffer, data >> 8); + *current_line_buffer++ = BLEND_CC(*current_line_buffer, data & 0xFF); + }*/ + if (dataHi | dataLo) + { + *current_line_buffer++ = BLEND_Y(*current_line_buffer, dataHi); + *current_line_buffer++ = BLEND_CC(*current_line_buffer, dataLo); + } + else + current_line_buffer += 2; + } + else + { +// *current_line_buffer++ = BLEND_Y(*current_line_buffer, jaguar_byte_read(ptr++)); +// *current_line_buffer++ = BLEND_CC(*current_line_buffer, jaguar_byte_read(ptr++)); + *current_line_buffer++ = BLEND_Y(*current_line_buffer, dataHi); + *current_line_buffer++ = BLEND_CC(*current_line_buffer, dataLo); + } + iwidth--; + } + } + } + else // !FLAGS_READMODIFY + { + if (flags & FLAGS_HFLIP) + { + while (iwidth) + { + uint8 dataHi = jaguar_byte_read(ptr++), dataLo = jaguar_byte_read(ptr++); + + if (flags & FLAGS_TRANSPARENT) + { +/* uint16 data = jaguar_byte_read(ptr++); + data <<= 8; + data |= jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer-- = data >> 8; + *current_line_buffer-- = data & 0xFF; + }*/ + if (dataHi | dataLo) + *current_line_buffer-- = dataHi, + *current_line_buffer-- = dataLo; + else + current_line_buffer -= 2; + } + else + { +// *current_line_buffer-- = jaguar_byte_read(ptr++); +// *current_line_buffer-- = jaguar_byte_read(ptr++); + *current_line_buffer-- = dataHi; + *current_line_buffer-- = dataLo; + } + iwidth--; + } + } + else // !FLAGS_HFLIP + { + int count = 0; + + while (iwidth) + { + uint8 dataHi = jaguar_byte_read(ptr++), dataLo = jaguar_byte_read(ptr++); + + if (flags & FLAGS_TRANSPARENT) + { +/* uint16 data = jaguar_byte_read(ptr++); + data <<= 8; + data |= jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++ = data >> 8; + *current_line_buffer++ = data & 0xFF; + }*/ + if (dataHi | dataLo) + *current_line_buffer++ = dataHi, + *current_line_buffer++ = dataLo; + else + current_line_buffer += 2; + } + else + { +// *current_line_buffer++ = jaguar_byte_read(ptr++); +// *current_line_buffer++ = jaguar_byte_read(ptr++); + *current_line_buffer++ = dataHi; + *current_line_buffer++ = dataLo; + } + count += 2; + if (count == 8) // 8 bytes = a phrase (64 bits) + { + ptr += 8 * (pitch - 1); + count = 0; + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop16p.h b/src/include/fbmpop16p.h new file mode 100644 index 0000000..e784d89 --- /dev/null +++ b/src/include/fbmpop16p.h @@ -0,0 +1,131 @@ + int count=0; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + if (flags&FLAGS_TRANSPARENT) + { + uint16 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,(data>>8)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,(data&0xff)); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr++)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr++)); + } + count+=2; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + if (flags&FLAGS_TRANSPARENT) + { + uint16 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,(data>>8)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,(data&0xff)); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr++)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr++)); + } + count+=2; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + if (flags&FLAGS_TRANSPARENT) + { + uint16 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer--=(data>>8); + *current_line_buffer--=(data&0xff); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=jaguar_byte_read(ptr++); + *current_line_buffer--=jaguar_byte_read(ptr++); + } + count+=2; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + if (flags&FLAGS_TRANSPARENT) + { + uint16 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++=(data>>8); + *current_line_buffer++=(data&0xff); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + } + count+=2; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop1p.h b/src/include/fbmpop1p.h new file mode 100644 index 0000000..fdab43e --- /dev/null +++ b/src/include/fbmpop1p.h @@ -0,0 +1,170 @@ + + uint32 c; + paletteRam+=(idx<<2); + int count=0; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_TB_HFLIP(C) if (C) { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else current_line_buffer-=2; + + PUTPIXEL_1_TB_HFLIP(c&0x80) + PUTPIXEL_1_TB_HFLIP(c&0x40) + PUTPIXEL_1_TB_HFLIP(c&0x20) + PUTPIXEL_1_TB_HFLIP(c&0x10) + PUTPIXEL_1_TB_HFLIP(c&0x08) + PUTPIXEL_1_TB_HFLIP(c&0x04) + PUTPIXEL_1_TB_HFLIP(c&0x02) + PUTPIXEL_1_TB_HFLIP(c&0x01) + } + else + { + #define PUTPIXEL_1_B_HFLIP(C) if (C) { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else { *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[0]); *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[1]); } + PUTPIXEL_1_B_HFLIP(c&0x80) + PUTPIXEL_1_B_HFLIP(c&0x40) + PUTPIXEL_1_B_HFLIP(c&0x20) + PUTPIXEL_1_B_HFLIP(c&0x10) + PUTPIXEL_1_B_HFLIP(c&0x08) + PUTPIXEL_1_B_HFLIP(c&0x04) + PUTPIXEL_1_B_HFLIP(c&0x02) + PUTPIXEL_1_B_HFLIP(c&0x01) + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_TB(C) if (C) { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else current_line_buffer+=2; + + PUTPIXEL_1_TB(c&0x80) + PUTPIXEL_1_TB(c&0x40) + PUTPIXEL_1_TB(c&0x20) + PUTPIXEL_1_TB(c&0x10) + PUTPIXEL_1_TB(c&0x08) + PUTPIXEL_1_TB(c&0x04) + PUTPIXEL_1_TB(c&0x02) + PUTPIXEL_1_TB(c&0x01) + } + else + { + #define PUTPIXEL_1_B(C) if (C) { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(1<<1)+0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(1<<1)+1]); } else { *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[0]); *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[1]); } + PUTPIXEL_1_B(c&0x80) + PUTPIXEL_1_B(c&0x40) + PUTPIXEL_1_B(c&0x20) + PUTPIXEL_1_B(c&0x10) + PUTPIXEL_1_B(c&0x08) + PUTPIXEL_1_B(c&0x04) + PUTPIXEL_1_B(c&0x02) + PUTPIXEL_1_B(c&0x01) + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_T_HFLIP(C) if (C) { *current_line_buffer--=paletteRam[(1<<1)+0]; *current_line_buffer--=paletteRam[(1<<1)+1]; } else current_line_buffer-=2; + + PUTPIXEL_1_T_HFLIP(c&0x80) + PUTPIXEL_1_T_HFLIP(c&0x40) + PUTPIXEL_1_T_HFLIP(c&0x20) + PUTPIXEL_1_T_HFLIP(c&0x10) + PUTPIXEL_1_T_HFLIP(c&0x08) + PUTPIXEL_1_T_HFLIP(c&0x04) + PUTPIXEL_1_T_HFLIP(c&0x02) + PUTPIXEL_1_T_HFLIP(c&0x01) + } + else + { + #define PUTPIXEL_1_HFLIP(C) if (C) { *current_line_buffer--=paletteRam[(1<<1)+0]; *current_line_buffer--=paletteRam[(1<<1)+1]; } else { *current_line_buffer--=paletteRam[0]; *current_line_buffer--=paletteRam[1]; } + PUTPIXEL_1_HFLIP(c&0x80) + PUTPIXEL_1_HFLIP(c&0x40) + PUTPIXEL_1_HFLIP(c&0x20) + PUTPIXEL_1_HFLIP(c&0x10) + PUTPIXEL_1_HFLIP(c&0x08) + PUTPIXEL_1_HFLIP(c&0x04) + PUTPIXEL_1_HFLIP(c&0x02) + PUTPIXEL_1_HFLIP(c&0x01) + } + iwidth--; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + + if (flags&FLAGS_TRANSPARENT) + { + #define PUTPIXEL_1_T(C) if (C) { *current_line_buffer++=paletteRam[(1<<1)+0]; *current_line_buffer++=paletteRam[(1<<1)+1]; } else current_line_buffer+=2; + + PUTPIXEL_1_T(c&0x80) + PUTPIXEL_1_T(c&0x40) + PUTPIXEL_1_T(c&0x20) + PUTPIXEL_1_T(c&0x10) + PUTPIXEL_1_T(c&0x08) + PUTPIXEL_1_T(c&0x04) + PUTPIXEL_1_T(c&0x02) + PUTPIXEL_1_T(c&0x01) + } + else + { + #define PUTPIXEL_1(C) if (C) { *current_line_buffer++=paletteRam[(1<<1)+0]; *current_line_buffer++=paletteRam[(1<<1)+1]; } else { *current_line_buffer++=paletteRam[0]; *current_line_buffer++=paletteRam[1]; } + PUTPIXEL_1(c&0x80) + PUTPIXEL_1(c&0x40) + PUTPIXEL_1(c&0x20) + PUTPIXEL_1(c&0x10) + PUTPIXEL_1(c&0x08) + PUTPIXEL_1(c&0x04) + PUTPIXEL_1(c&0x02) + PUTPIXEL_1(c&0x01) + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop2.h b/src/include/fbmpop2.h new file mode 100644 index 0000000..9758b98 --- /dev/null +++ b/src/include/fbmpop2.h @@ -0,0 +1,268 @@ + uint32 c; + paletteRam+=idx*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + } + else + current_line_buffer-=2; + if (c1) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + } + else + current_line_buffer-=2; + if (c2) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + } + else + current_line_buffer-=2; + if (c3) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + } + else + current_line_buffer-=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + } + else + current_line_buffer+=2; + if (c1) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + } + else + current_line_buffer+=2; + if (c2) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + } + else + current_line_buffer+=2; + if (c3) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + } + else + current_line_buffer+=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + iwidth--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer--=paletteRam[(c0<<1)+0]; + *current_line_buffer--=paletteRam[(c0<<1)+1]; + } + else + current_line_buffer-=2; + if (c1) + { + *current_line_buffer--=paletteRam[(c1<<1)+0]; + *current_line_buffer--=paletteRam[(c1<<1)+1]; + } + else + current_line_buffer-=2; + if (c2) + { + *current_line_buffer--=paletteRam[(c2<<1)+0]; + *current_line_buffer--=paletteRam[(c2<<1)+1]; + } + else + current_line_buffer-=2; + if (c3) + { + *current_line_buffer--=paletteRam[(c3<<1)+0]; + *current_line_buffer--=paletteRam[(c3<<1)+1]; + } + else + current_line_buffer-=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer--=paletteRam[(c0<<1)+0]; + *current_line_buffer--=paletteRam[(c0<<1)+1]; + *current_line_buffer--=paletteRam[(c1<<1)+0]; + *current_line_buffer--=paletteRam[(c1<<1)+1]; + *current_line_buffer--=paletteRam[(c2<<1)+0]; + *current_line_buffer--=paletteRam[(c2<<1)+1]; + *current_line_buffer--=paletteRam[(c3<<1)+0]; + *current_line_buffer--=paletteRam[(c3<<1)+1]; + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer++=paletteRam[(c0<<1)+0]; + *current_line_buffer++=paletteRam[(c0<<1)+1]; + } + else + current_line_buffer+=2; + if (c1) + { + *current_line_buffer++=paletteRam[(c1<<1)+0]; + *current_line_buffer++=paletteRam[(c1<<1)+1]; + } + else + current_line_buffer+=2; + if (c2) + { + *current_line_buffer++=paletteRam[(c2<<1)+0]; + *current_line_buffer++=paletteRam[(c2<<1)+1]; + } + else + current_line_buffer+=2; + if (c3) + { + *current_line_buffer++=paletteRam[(c3<<1)+0]; + *current_line_buffer++=paletteRam[(c3<<1)+1]; + } + else + current_line_buffer+=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer++=paletteRam[(c0<<1)+0]; + *current_line_buffer++=paletteRam[(c0<<1)+1]; + *current_line_buffer++=paletteRam[(c1<<1)+0]; + *current_line_buffer++=paletteRam[(c1<<1)+1]; + *current_line_buffer++=paletteRam[(c2<<1)+0]; + *current_line_buffer++=paletteRam[(c2<<1)+1]; + *current_line_buffer++=paletteRam[(c3<<1)+0]; + *current_line_buffer++=paletteRam[(c3<<1)+1]; + iwidth--; + } + } + } + } diff --git a/src/include/fbmpop24.h b/src/include/fbmpop24.h new file mode 100644 index 0000000..3fccfb2 --- /dev/null +++ b/src/include/fbmpop24.h @@ -0,0 +1,74 @@ + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + uint32 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer--=(data>>24)&0xff; + *current_line_buffer--=(data>>16)&0xff; + *current_line_buffer--=(data>> 8)&0xff; + *current_line_buffer--=data &0xff; + } + else + current_line_buffer-=4; + iwidth--; + } + } + else + { + while (iwidth) + { + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + uint32 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++=(data>>24)&0xff; + *current_line_buffer++=(data>>16)&0xff; + *current_line_buffer++=(data>> 8)&0xff; + *current_line_buffer++=data &0xff; + } + else + current_line_buffer+=4; + iwidth--; + } + } + else + { + while (iwidth) + { + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + iwidth--; + } + } + } diff --git a/src/include/fbmpop24p.h b/src/include/fbmpop24p.h new file mode 100644 index 0000000..a1e904b --- /dev/null +++ b/src/include/fbmpop24p.h @@ -0,0 +1,99 @@ + int count=0; + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + uint32 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer--=(data>>24)&0xff; + *current_line_buffer--=(data>>16)&0xff; + *current_line_buffer--=(data>> 8)&0xff; + *current_line_buffer--=data &0xff; + } + else + current_line_buffer-=4; + count+=4; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + iwidth--; + count+=4; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + uint32 data=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + data<<=8; + data|=jaguar_byte_read(ptr++); + if (data) + { + *current_line_buffer++=(data>>24)&0xff; + *current_line_buffer++=(data>>16)&0xff; + *current_line_buffer++=(data>> 8)&0xff; + *current_line_buffer++=data &0xff; + } + else + current_line_buffer+=4; + count+=4; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + *current_line_buffer++=jaguar_byte_read(ptr++); + count+=4; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop2p.h b/src/include/fbmpop2p.h new file mode 100644 index 0000000..783274b --- /dev/null +++ b/src/include/fbmpop2p.h @@ -0,0 +1,317 @@ + int count=0; + uint32 c; + paletteRam+=idx*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + } + else + current_line_buffer-=2; + if (c1) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + } + else + current_line_buffer-=2; + if (c2) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + } + else + current_line_buffer-=2; + if (c3) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + } + else + current_line_buffer-=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + } + else + current_line_buffer+=2; + if (c1) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + } + else + current_line_buffer+=2; + if (c2) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + } + else + current_line_buffer+=2; + if (c3) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + } + else + current_line_buffer+=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c0<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c0<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c1<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c1<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c2<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c2<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(c3<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(c3<<1)+1]); + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer--=paletteRam[(c0<<1)+0]; + *current_line_buffer--=paletteRam[(c0<<1)+1]; + } + else + current_line_buffer-=2; + if (c1) + { + *current_line_buffer--=paletteRam[(c1<<1)+0]; + *current_line_buffer--=paletteRam[(c1<<1)+1]; + } + else + current_line_buffer-=2; + if (c2) + { + *current_line_buffer--=paletteRam[(c2<<1)+0]; + *current_line_buffer--=paletteRam[(c2<<1)+1]; + } + else + current_line_buffer-=2; + if (c3) + { + *current_line_buffer--=paletteRam[(c3<<1)+0]; + *current_line_buffer--=paletteRam[(c3<<1)+1]; + } + else + current_line_buffer-=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer--=paletteRam[(c0<<1)+0]; + *current_line_buffer--=paletteRam[(c0<<1)+1]; + *current_line_buffer--=paletteRam[(c1<<1)+0]; + *current_line_buffer--=paletteRam[(c1<<1)+1]; + *current_line_buffer--=paletteRam[(c2<<1)+0]; + *current_line_buffer--=paletteRam[(c2<<1)+1]; + *current_line_buffer--=paletteRam[(c3<<1)+0]; + *current_line_buffer--=paletteRam[(c3<<1)+1]; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + if (c0) + { + *current_line_buffer++=paletteRam[(c0<<1)+0]; + *current_line_buffer++=paletteRam[(c0<<1)+1]; + } + else + current_line_buffer+=2; + if (c1) + { + *current_line_buffer++=paletteRam[(c1<<1)+0]; + *current_line_buffer++=paletteRam[(c1<<1)+1]; + } + else + current_line_buffer+=2; + if (c2) + { + *current_line_buffer++=paletteRam[(c2<<1)+0]; + *current_line_buffer++=paletteRam[(c2<<1)+1]; + } + else + current_line_buffer+=2; + if (c3) + { + *current_line_buffer++=paletteRam[(c3<<1)+0]; + *current_line_buffer++=paletteRam[(c3<<1)+1]; + } + else + current_line_buffer+=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 c0=(c>>6)&0x03; + uint32 c1=(c>>4)&0x03; + uint32 c2=(c>>2)&0x03; + uint32 c3=(c>>0)&0x03; + + *current_line_buffer++=paletteRam[(c0<<1)+0]; + *current_line_buffer++=paletteRam[(c0<<1)+1]; + *current_line_buffer++=paletteRam[(c1<<1)+0]; + *current_line_buffer++=paletteRam[(c1<<1)+1]; + *current_line_buffer++=paletteRam[(c2<<1)+0]; + *current_line_buffer++=paletteRam[(c2<<1)+1]; + *current_line_buffer++=paletteRam[(c3<<1)+0]; + *current_line_buffer++=paletteRam[(c3<<1)+1]; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + } diff --git a/src/include/fbmpop4.h b/src/include/fbmpop4.h new file mode 100644 index 0000000..2d99376 --- /dev/null +++ b/src/include/fbmpop4.h @@ -0,0 +1,178 @@ + uint32 c; + if (jaguar_mainRom_crc32==0x66f8914c) + { + if (idx==12) + idx=64; + } + paletteRam+=idx*4; + + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + } + else + current_line_buffer-=2; + if (ch) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + } + else + current_line_buffer-=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + } + else + current_line_buffer+=2; + if (ch) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + } + else + current_line_buffer+=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + iwidth--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer--=paletteRam[(cl<<1)+0]; + *current_line_buffer--=paletteRam[(cl<<1)+1]; + } + else + current_line_buffer-=2; + if (ch) + { + *current_line_buffer--=paletteRam[(ch<<1)+0]; + *current_line_buffer--=paletteRam[(ch<<1)+1]; + } + else + current_line_buffer-=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer--=paletteRam[(cl<<1)+0]; + *current_line_buffer--=paletteRam[(cl<<1)+1]; + *current_line_buffer--=paletteRam[(ch<<1)+0]; + *current_line_buffer--=paletteRam[(ch<<1)+1]; + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer++=paletteRam[(cl<<1)+0]; + *current_line_buffer++=paletteRam[(cl<<1)+1]; + } + else + current_line_buffer+=2; + if (ch) + { + *current_line_buffer++=paletteRam[(ch<<1)+0]; + *current_line_buffer++=paletteRam[(ch<<1)+1]; + } + else + current_line_buffer+=2; + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer++=paletteRam[(cl<<1)+0]; + *current_line_buffer++=paletteRam[(cl<<1)+1]; + *current_line_buffer++=paletteRam[(ch<<1)+0]; + *current_line_buffer++=paletteRam[(ch<<1)+1]; + iwidth--; + } + } + } + } diff --git a/src/include/fbmpop4p.h b/src/include/fbmpop4p.h new file mode 100644 index 0000000..e7602f1 --- /dev/null +++ b/src/include/fbmpop4p.h @@ -0,0 +1,221 @@ + int count=0; + uint32 c; + paletteRam+=idx*4; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + } + else + current_line_buffer-=2; + if (ch) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + } + else + current_line_buffer-=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + } + else + current_line_buffer+=2; + if (ch) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + } + else + current_line_buffer+=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(cl<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(cl<<1)+1]); + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[(ch<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[(ch<<1)+1]); + iwidth--; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer--=paletteRam[(cl<<1)+0]; + *current_line_buffer--=paletteRam[(cl<<1)+1]; + } + else + current_line_buffer-=2; + if (ch) + { + *current_line_buffer--=paletteRam[(ch<<1)+0]; + *current_line_buffer--=paletteRam[(ch<<1)+1]; + } + else + current_line_buffer-=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer--=paletteRam[(cl<<1)+0]; + *current_line_buffer--=paletteRam[(cl<<1)+1]; + *current_line_buffer--=paletteRam[(ch<<1)+0]; + *current_line_buffer--=paletteRam[(ch<<1)+1]; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + if (cl) + { + *current_line_buffer++=paletteRam[(cl<<1)+0]; + *current_line_buffer++=paletteRam[(cl<<1)+1]; + } + else + current_line_buffer+=2; + if (ch) + { + *current_line_buffer++=paletteRam[(ch<<1)+0]; + *current_line_buffer++=paletteRam[(ch<<1)+1]; + } + else + current_line_buffer+=2; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + uint32 cl=c>>4; + uint32 ch=c&0x0f; + *current_line_buffer++=paletteRam[(cl<<1)+0]; + *current_line_buffer++=paletteRam[(cl<<1)+1]; + *current_line_buffer++=paletteRam[(ch<<1)+0]; + *current_line_buffer++=paletteRam[(ch<<1)+1]; + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + } diff --git a/src/include/fbmpop8.h b/src/include/fbmpop8.h new file mode 100644 index 0000000..e5373cb --- /dev/null +++ b/src/include/fbmpop8.h @@ -0,0 +1,104 @@ + uint32 c; + paletteRam+=(idx&0x01)*256*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + iwidth--; + } + } + } diff --git a/src/include/fbmpop8p.h b/src/include/fbmpop8p.h new file mode 100644 index 0000000..e3785d7 --- /dev/null +++ b/src/include/fbmpop8p.h @@ -0,0 +1,129 @@ + int count=0; + uint32 c; + paletteRam+=(idx&0x01)*256*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr-=8*(pitch-1); + count=0; + } + iwidth--; + } + } + else + { + while (iwidth) + { + c=jaguar_byte_read(ptr++); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + count+=1; + if (count==8) // 8 bytes = a phrase (64 bits) + { + ptr+=8*(pitch-1); + count=0; + } + iwidth--; + } + } + } diff --git a/src/include/gpu.h b/src/include/gpu.h new file mode 100644 index 0000000..b6b0f08 --- /dev/null +++ b/src/include/gpu.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __GPU_H__ +#define __GPU_H__ + +#include "jaguar.h" + +#define gpu_control_ram_base 0x00f02100 +#define gpu_work_ram_base 0x00f03000 + +void gpu_init(void); +void gpu_reset(void); +void gpu_exec(int32); +void gpu_done(void); +void gpu_update_register_banks(void); +void gpu_check_irqs(void); +void gpu_set_irq_line(int irqline, int state); +unsigned gpu_byte_read(unsigned int offset); +unsigned gpu_word_read(unsigned int offset); +unsigned gpu_long_read(unsigned int offset); +void gpu_byte_write(unsigned offset, unsigned data); +void gpu_word_write(unsigned offset, unsigned data); +void gpu_long_write(unsigned offset, unsigned data); +uint32 gpu_get_pc(void); +void gpu_releaseTimeslice(void); +void gpu_reset_stats(void); +uint32 gpu_read_pc(void); + +#endif diff --git a/src/include/gpuopcodes.h b/src/include/gpuopcodes.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/harddisk.h b/src/include/harddisk.h new file mode 100644 index 0000000..37bcf41 --- /dev/null +++ b/src/include/harddisk.h @@ -0,0 +1,120 @@ +#ifndef __HARDDISK_H__ +#define __HARDDISK_H__ + +#include "types.h" + +/*************************************************************************** + + MAME compressed hard disk header format. All numbers are stored in + Motorola (big-endian) byte ordering. The header is 76 bytes long. + + [ 0] char tag[8]; // 'MComprHD' + [ 8] UINT32 length; // length of header (including tag and length fields) + [ 12] UINT32 version; // drive format version + [ 16] UINT32 flags; // flags (see below) + [ 20] UINT32 compression; // compression type + [ 24] UINT32 blocksize; // sectors per block + [ 28] UINT32 totalblocks; // total # of block represented + [ 32] UINT32 cylinders; // number of cylinders on hard disk + [ 36] UINT32 heads; // number of heads on hard disk + [ 40] UINT32 sectors; // number of sectors on hard disk + [ 44] UINT8 md5[16]; // MD5 checksum for this drive + [ 60] UINT8 parentmd5[16]; // MD5 checksum for parent drive + [ 76] (header length) + + Flags: + 0x00000001 - set if this drive has a parent + 0x00000002 - set if this drive allows writes + +***************************************************************************/ + +/************************************* + * + * Constants + * + *************************************/ + +#define HARD_DISK_HEADER_SIZE 76 +#define HARD_DISK_HEADER_VERSION 1 + +#define HARD_DISK_SECTOR_SIZE 512 + +#define HDFLAGS_HAS_PARENT 0x00000001 +#define HDFLAGS_IS_WRITEABLE 0x00000002 + +#define HDCOMPRESSION_NONE 0 +#define HDCOMPRESSION_ZLIB 1 +#define HDCOMPRESSION_MAX 2 + +enum +{ + HDERR_NONE, + HDERR_NO_INTERFACE, + HDERR_OUT_OF_MEMORY, + HDERR_INVALID_FILE, + HDERR_INVALID_PARAMETER, + HDERR_INVALID_DATA, + HDERR_FILE_NOT_FOUND, + HDERR_REQUIRES_PARENT, + HDERR_FILE_NOT_WRITEABLE, + HDERR_READ_ERROR, + HDERR_WRITE_ERROR, + HDERR_CODEC_ERROR, + HDERR_INVALID_PARENT, + HDERR_SECTOR_OUT_OF_RANGE, + HDERR_DECOMPRESSION_ERROR, + HDERR_COMPRESSION_ERROR, + HDERR_CANT_CREATE_FILE, + HDERR_CANT_VERIFY +}; + + + +/************************************* + * + * Type definitions + * + *************************************/ + +struct hard_disk_header +{ + UINT32 length; /* length of header data */ + UINT32 version; /* drive format version */ + UINT32 flags; /* flags field */ + UINT32 compression; /* compression type */ + UINT32 blocksize; /* sectors per block */ + UINT32 totalblocks; /* total # of blocks represented */ + UINT32 cylinders; /* number of cylinders on hard disk */ + UINT32 heads; /* number of heads on hard disk */ + UINT32 sectors; /* number of sectors on hard disk */ + UINT8 md5[16]; /* MD5 checksum for this drive */ + UINT8 parentmd5[16]; /* MD5 checksum for parent drive */ +}; + + +struct hard_disk_interface +{ + void *(*open)(const char *filename, const char *mode); + void (*close)(void *file); + uint32 (*read)(void *file, UINT64 offset, UINT32 count, void *buffer); + uint32 (*write)(void *file, UINT64 offset, UINT32 count, const void *buffer); +}; + +void hard_disk_set_interface(struct hard_disk_interface *intf); + +int hard_disk_create(const char *filename, const struct hard_disk_header *header); +void *hard_disk_open(const char *filename, int writeable, void *parent); +void hard_disk_close(void *disk); +void hard_disk_close_all(void); + +UINT32 hard_disk_read(void *disk, UINT32 lbasector, UINT32 numsectors, void *buffer); +UINT32 hard_disk_write(void *disk, UINT32 lbasector, UINT32 numsectors, const void *buffer); + +int hard_disk_get_last_error(void); +const struct hard_disk_header *hard_disk_get_header(void *disk); +int hard_disk_set_header(const char *filename, const struct hard_disk_header *header); + +int hard_disk_compress(const char *rawfile, UINT32 offset, const char *newfile, const struct hard_disk_header *header, const char *difffile, void (*progress)(const char *, ...)); +int hard_disk_verify(const char *hdfile, void (*progress)(const char *, ...), UINT8 headermd5[16], UINT8 actualmd5[16]); + +#endif diff --git a/src/include/ide.h b/src/include/ide.h new file mode 100644 index 0000000..d6a72da --- /dev/null +++ b/src/include/ide.h @@ -0,0 +1,16 @@ +#ifndef __IDE_H__ +#define __IDE_H__ + +#include "jaguar.h" + +void ide_init(void); +void ide_reset(void); +void ide_done(void); + +void ide_update(void); +void ide_byte_write(uint32 offset, uint8 data); +void ide_word_write(uint32 offset, uint16 data); +uint8 ide_byte_read(uint32 offset); +uint16 ide_word_read(uint32 offset); + +#endif diff --git a/src/include/idectrl.h b/src/include/idectrl.h new file mode 100644 index 0000000..29ae71a --- /dev/null +++ b/src/include/idectrl.h @@ -0,0 +1,24 @@ +#ifndef __IDECTRL_H__ +#define __IDECTRL_H__ + +#include "types.h" +#include "harddisk.h" + +#define MAX_IDE_CONTROLLERS 1 + +struct ide_interface +{ + void (*interrupt)(int state); +}; + +int ide_controller_init(int which, struct ide_interface *intf); +void ide_controller_reset(int which); +uint8 *ide_get_features(int which); +/* +READ32_HANDLER( ide_controller32_0_r ); +WRITE32_HANDLER( ide_controller32_0_w ); + +READ16_HANDLER( ide_controller16_0_r ); +WRITE16_HANDLER( ide_controller16_0_w ); +*/ +#endif diff --git a/src/include/jagdasm.h b/src/include/jagdasm.h new file mode 100644 index 0000000..ee94495 --- /dev/null +++ b/src/include/jagdasm.h @@ -0,0 +1,9 @@ +#ifndef __JAGDASM__ +#define __JAGDASM__ + +#define JAGUAR_GPU 0 +#define JAGUAR_DSP 1 + +unsigned dasmjag(int dsp_type, char *buffer, unsigned pc); + +#endif diff --git a/src/include/jaguar.h b/src/include/jaguar.h new file mode 100644 index 0000000..08df747 --- /dev/null +++ b/src/include/jaguar.h @@ -0,0 +1,54 @@ +#ifndef __JAGUAR_H__ +#define __JAGUAR_H__ + +#include "types.h" +#include "log.h" +#include "version.h" +#include "memory.h" +//#include "../star026c/starcpu.h" +#include "m68k.h" // Musashi! Not StarCrap! (Why are you afraid to show us the source, Neill? :-) +#include "tom.h" +#include "jerry.h" +#include "gpu.h" +#include "dsp.h" +#include "objectp.h" +#include "blitter.h" +#include "clock.h" +#include "anajoy.h" +#include "joystick.h" +#include "pcm.h" +#include "jagdasm.h" +#include "dsnd.h" +#include "cdrom.h" +#include "eeprom.h" +#include "cdi.h" +#include "cdbios.h" + +extern int32 jaguar_cpu_in_exec; +extern uint32 jaguar_mainRom_crc32; +extern char * jaguar_eeproms_path; + +#ifdef __PORT__ +void jaguar_init(const char * filename); +#else +void jaguar_init(void); +#endif // #ifdef __PORT__ +void jaguar_reset(void); +void jaguar_reset_handler(void); +void jaguar_done(void); +void jaguar_exec(int16 * backbuffer, uint8 render); +unsigned jaguar_byte_read(unsigned int offset); +unsigned jaguar_word_read(unsigned int offset); +unsigned jaguar_long_read(unsigned int offset); +void jaguar_byte_write(unsigned offset, unsigned data); +void jaguar_word_write(unsigned offset, unsigned data); +void jaguar_long_write(unsigned offset, unsigned data); +uint32 jaguar_interrupt_handler_is_valid(uint32 i); +void jaguar_dasm(uint32 offset, uint32 qt); + +//Temp debug stuff + +void dump(void); +uint8 * GetRamPtr(void); + +#endif // #ifndef __JAGUAR_H__ diff --git a/src/include/jerry.h b/src/include/jerry.h new file mode 100644 index 0000000..942e5ae --- /dev/null +++ b/src/include/jerry.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __JERRY_H__ +#define __JERRY_H__ + +#include "jaguar.h" + +void jerry_init(void); +void jerry_reset(void); +void jerry_done(void); +unsigned jerry_byte_read(unsigned int offset); +unsigned jerry_word_read(unsigned int offset); +void jerry_byte_write(unsigned offset, unsigned data); +void jerry_word_write(unsigned offset, unsigned data); +void jerry_pit_exec(uint32 cycles); +void jerry_i2s_exec(uint32 cycles); + +#endif diff --git a/src/include/joystick.h b/src/include/joystick.h new file mode 100644 index 0000000..7a4a3d2 --- /dev/null +++ b/src/include/joystick.h @@ -0,0 +1,15 @@ +#ifndef __JOYSTICK_H__ +#define __JOYSTICK_H__ + +#include "types.h" + +void joystick_init(void); +void joystick_reset(void); +void joystick_done(void); +void joystick_byte_write(uint32, uint8); +void joystick_word_write(uint32, uint16); +uint8 joystick_byte_read(uint32); +uint16 joystick_word_read(uint32); +void joystick_exec(void); + +#endif diff --git a/src/include/log.h b/src/include/log.h new file mode 100644 index 0000000..e0fe1fb --- /dev/null +++ b/src/include/log.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include + +int log_init(char *); +FILE *log_get(void); +void log_done(void); + +#endif diff --git a/src/include/m68kdasmAG.h b/src/include/m68kdasmAG.h new file mode 100644 index 0000000..697f7bc --- /dev/null +++ b/src/include/m68kdasmAG.h @@ -0,0 +1 @@ +int Dasm68000(char * pBase, char * buffer, int pc); diff --git a/src/include/mamegpu.h b/src/include/mamegpu.h new file mode 100644 index 0000000..4415695 --- /dev/null +++ b/src/include/mamegpu.h @@ -0,0 +1,781 @@ +#define ZFLAG 0x00001 +#define CFLAG 0x00002 +#define NFLAG 0x00004 +#define IFLAG 0x00008 +static UINT8 * condition_table=0; + +#define CONDITION(x) condition_table[(x) + ((jaguar_FLAGS & 7) << 5)] +static UINT16 * mirror_table; + + + + +/*################################################################################################### +** MEMORY ACCESSORS +**#################################################################################################*/ + +#define ROPCODE(pc) (gpu_word_read(pc)) +uint16 jaguar_ppc; +uint16 jaguar_op; +int32 jaguar_icount; +static const UINT32 convert_zero[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 }; + +static uint32 cnt_opcode=0; +int jaguargpu_execute(int cycles) +{ + int i,j; + /* allocate the mirror table */ + if (!mirror_table) + { + mirror_table = (UINT16*)malloc(65536 * sizeof(mirror_table[0])); + + /* fill in the mirror table */ + if (mirror_table) + for (i = 0; i < 65536; i++) + mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) | + ((i >> 11) & 0x0004) | ((i >> 9) & 0x0008) | + ((i >> 7) & 0x0010) | ((i >> 5) & 0x0020) | + ((i >> 3) & 0x0040) | ((i >> 1) & 0x0080) | + ((i << 1) & 0x0100) | ((i << 3) & 0x0200) | + ((i << 5) & 0x0400) | ((i << 7) & 0x0800) | + ((i << 9) & 0x1000) | ((i << 11) & 0x2000) | + ((i << 13) & 0x4000) | ((i << 15) & 0x8000); + } + + if (!condition_table) + { + condition_table = (uint8*)malloc(32 * 8 * sizeof(condition_table[0])); + + /* fill in the condition table */ + if (condition_table) + for (i = 0; i < 8; i++) + for (j = 0; j < 32; j++) + { + int result = 1; + if (j & 1) + if (i & ZFLAG) result = 0; + if (j & 2) + if (!(i & ZFLAG)) result = 0; + if (j & 4) + if (i & (CFLAG << (j >> 4))) result = 0; + if (j & 8) + if (!(i & (CFLAG << (j >> 4)))) result = 0; + condition_table[i * 32 + j] = result; + } + } + /* if we're halted, we shouldn't be here */ + if (!gpu_running) + { + return cycles; + } + jaguar_icount=cycles; + + do + { + gpu_flag_c=(gpu_flag_c?1:0); + gpu_flag_z=(gpu_flag_z?1:0); + gpu_flag_n=(gpu_flag_n?1:0); + +// fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n); + jaguar_ppc = gpu_pc; + + /* instruction fetch */ + jaguar_op = ROPCODE(gpu_pc); + gpu_pc += 2; + + /* parse the instruction */ + (*gpu_op_table[jaguar_op >> 10])(); + jaguar_icount--; + + } while ((jaguar_icount > 0)&&(gpu_running)); + + return cycles - jaguar_icount; +} +/*################################################################################################### +** OPCODES +**#################################################################################################*/ + +void abs_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 res = gpu_reg[dreg]; + CLR_ZNC; + if (res & 0x80000000) + { + gpu_reg[dreg] = res = -res; + SET_C + } + SET_Z(res); +} + +void add_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res); +} + +void addc_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1 + gpu_flag_c; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res); +} + +void addq_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res); +} + +void addqmod_n_rn(void) /* DSP only */ +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1; + res = (res & ~gpu_hidata) | (r2 & ~gpu_hidata); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_ADD(r2,r1,res); +} + +void addqt_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1; + gpu_reg[dreg] = res; +} + +void and_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 & r1; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void bclr_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = (jaguar_op >> 5) & 31; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 & ~(1 << r1); + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void bset_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = (jaguar_op >> 5) & 31; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 | (1 << r1); + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void btst_n_rn(void) +{ + UINT32 r1 = (jaguar_op >> 5) & 31; + UINT32 r2 = gpu_reg[jaguar_op & 31]; + CLR_Z; gpu_flag_z= (~r2 >> r1) & 1; +} + +void cmp_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[jaguar_op & 31]; + UINT32 res = r2 - r1; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void cmpq_n_rn(void) +{ + UINT32 r1 = (INT8)(jaguar_op >> 2) >> 3; + UINT32 r2 = gpu_reg[jaguar_op & 31]; + UINT32 res = r2 - r1; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void div_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + if (r1) + { + if (gpu_div_control & 1) + { + gpu_reg[dreg] = ((UINT64)r2 << 16) / r1; + gpu_remain = ((UINT64)r2 << 16) % r1; + } + else + { + gpu_reg[dreg] = r2 / r1; + gpu_remain = r2 % r1; + } + } + else + gpu_reg[dreg] = 0xffffffff; +} + +void illegal(void) +{ +} + +void imacn_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[jaguar_op & 31]; + gpu_acc += (INT64)((INT16)r1 * (INT16)r2); +} + +void imult_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (INT16)r1 * (INT16)r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void imultn_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (INT16)r1 * (INT16)r2; + gpu_acc = (INT32)res; + CLR_ZN; SET_ZN(res); + + jaguar_op = ROPCODE(gpu_pc); + while ((jaguar_op >> 10) == 20) + { + r1 = gpu_reg[(jaguar_op >> 5) & 31]; + r2 = gpu_reg[jaguar_op & 31]; + gpu_acc += (INT64)((INT16)r1 * (INT16)r2); + gpu_pc += 2; + jaguar_op = ROPCODE(gpu_pc); + } + if ((jaguar_op >> 10) == 19) + { + gpu_pc += 2; + gpu_reg[jaguar_op & 31] = (UINT32)gpu_acc; + } +} + +void jr_cc_n(void) +{ + UINT32 jaguar_FLAGS; + + gpu_flag_c?(gpu_flag_c=1):(gpu_flag_c=0); + gpu_flag_z?(gpu_flag_z=1):(gpu_flag_z=0); + gpu_flag_n?(gpu_flag_n=1):(gpu_flag_n=0); + + jaguar_FLAGS=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z; + + if (CONDITION(jaguar_op & 31)) + { + INT32 r1 = (INT8)((jaguar_op >> 2) & 0xf8) >> 2; + UINT32 newpc = gpu_pc + r1; + jaguar_op = ROPCODE(gpu_pc); + // fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n); + gpu_pc = newpc; + (*gpu_op_table[jaguar_op >> 10])(); + + jaguar_icount -= 3; /* 3 wait states guaranteed */ + } +} + +void jump_cc_rn(void) +{ + UINT32 jaguar_FLAGS; + + gpu_flag_c?(gpu_flag_c=1):(gpu_flag_c=0); + gpu_flag_z?(gpu_flag_z=1):(gpu_flag_z=0); + gpu_flag_n?(gpu_flag_n=1):(gpu_flag_n=0); + + jaguar_FLAGS=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z; + if (CONDITION(jaguar_op & 31)) + { + UINT8 reg = (jaguar_op >> 5) & 31; + + /* special kludge for risky code in the cojag DSP interrupt handlers */ + UINT32 newpc = /*(jaguar_icount == bankswitch_icount) ?*/ gpu_reg[reg];// : gpu_reg[reg]; + jaguar_op = ROPCODE(gpu_pc); + // fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n); + gpu_pc = newpc; + (*gpu_op_table[jaguar_op >> 10])(); + + jaguar_icount -= 3; /* 3 wait states guaranteed */ + } +} + +void load_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_long_read(r1); +} + +void load_r14n_rn(void) +{ + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[14] + 4 * r1); +} + +void load_r15n_rn(void) +{ + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[15] + 4 * r1); +} + +void load_r14rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[14] + r1); +} + +void load_r15rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[15] + r1); +} + +void loadb_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_byte_read(r1); +} + +void loadw_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = gpu_word_read(r1); +} + +void loadp_rn_rn(void) /* GPU only */ +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_hidata = gpu_word_read(r1); + gpu_reg[jaguar_op & 31] = gpu_word_read(r1+4); +} + +void mirror_rn(void) /* DSP only */ +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[dreg]; + UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16]; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void mmult_rn_rn(void) +{ + int count = gpu_matrix_control & 15, i; + int sreg = (jaguar_op >> 5) & 31; + int dreg = jaguar_op & 31; + UINT32 addr = gpu_pointer_to_matrix; + INT64 accum = 0; + UINT32 res; + + if (!(gpu_matrix_control & 0x10)) + { + for (i = 0; i < count; i++) + { + accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr); + addr += 2; + } + } + else + { + for (i = 0; i < count; i++) + { + accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr); + addr += 2 * count; + } + } + gpu_reg[dreg] = res = (UINT32)accum; + CLR_ZN; SET_ZN(res); +} + +void move_rn_rn(void) +{ + gpu_reg[jaguar_op & 31] = gpu_reg[(jaguar_op >> 5) & 31]; +} + +void move_pc_rn(void) +{ + gpu_reg[jaguar_op & 31] = jaguar_ppc; +} + +void movefa_rn_rn(void) +{ + gpu_reg[jaguar_op & 31] = gpu_alternate_reg[(jaguar_op >> 5) & 31]; +} + +void movei_n_rn(void) +{ + UINT32 res = ROPCODE(gpu_pc) | (ROPCODE(gpu_pc + 2) << 16); + gpu_pc += 4; + gpu_reg[jaguar_op & 31] = res; +} + +void moveq_n_rn(void) +{ + gpu_reg[jaguar_op & 31] = (jaguar_op >> 5) & 31; +} + +void moveta_rn_rn(void) +{ + gpu_alternate_reg[jaguar_op & 31] = gpu_reg[(jaguar_op >> 5) & 31]; +} + +void mtoi_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_reg[jaguar_op & 31] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff); +} + +void mult_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (UINT16)r1 * (UINT16)r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void neg_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = -r2; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(0,r2,res); +} + +void nop(void) +{ +} + +void normi_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 res = 0; + while ((r1 & 0xffc00000) == 0) + { + r1 <<= 1; + res--; + } + while ((r1 & 0xff800000) != 0) + { + r1 >>= 1; + res++; + } + gpu_reg[jaguar_op & 31] = res; + CLR_ZN; SET_ZN(res); +} + +void not_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 res = ~gpu_reg[dreg]; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void or_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r1 | r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void pack_rn(void) /* GPU only */ +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res; + if (r1 == 0) /* PACK */ + res = ((r2 >> 10) & 0xf000) | ((r2 >> 5) & 0x0f00) | (r2 & 0xff); + else /* UNPACK */ + res = ((r2 & 0xf000) << 10) | ((r2 & 0x0f00) << 5) | (r2 & 0xff); + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void resmac_rn(void) +{ + gpu_reg[jaguar_op & 31] = (UINT32)gpu_acc; +} + +void ror_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31] & 31; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 >> r1) | (r2 << (32 - r1)); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 30) & 2; +} + +void rorq_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 >> r1) | (r2 << (32 - r1)); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 >> 30) & 2; +} + +void sat8_rn(void) /* GPU only */ +{ + int dreg = jaguar_op & 31; + INT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 < 0) ? 0 : (r2 > 255) ? 255 : r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void sat16_rn(void) /* GPU only */ +{ + int dreg = jaguar_op & 31; + INT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 < 0) ? 0 : (r2 > 65535) ? 65535 : r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void sat16s_rn(void) /* DSP only */ +{ + int dreg = jaguar_op & 31; + INT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void sat24_rn(void) /* GPU only */ +{ + int dreg = jaguar_op & 31; + INT32 r2 = gpu_reg[dreg]; + UINT32 res = (r2 < 0) ? 0 : (r2 > 16777215) ? 16777215 : r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void sat32s_rn(void) /* DSP only */ +{ + int dreg = jaguar_op & 31; + INT32 r2 = (UINT32)gpu_reg[dreg]; + INT32 temp = gpu_acc >> 32; + UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void sh_rn_rn(void) +{ + int dreg = jaguar_op & 31; + INT32 r1 = (INT32)gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res; + + CLR_ZNC; + if (r1 < 0) + { + res = (r1 <= -32) ? 0 : (r2 << -r1); + gpu_flag_c= (r2 >> 30) & 2; + } + else + { + res = (r1 >= 32) ? 0 : (r2 >> r1); + gpu_flag_c= (r2 << 1) & 2; + } + gpu_reg[dreg] = res; + SET_ZN(res); +} + +void sha_rn_rn(void) +{ + int dreg = jaguar_op & 31; + INT32 r1 = (INT32)gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res; + + CLR_ZNC; + if (r1 < 0) + { + res = (r1 <= -32) ? 0 : (r2 << -r1); + gpu_flag_c= (r2 >> 30) & 2; + } + else + { + res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1); + gpu_flag_c= (r2 << 1) & 2; + } + gpu_reg[dreg] = res; + SET_ZN(res); +} + +void sharq_n_rn(void) +{ + int dreg = jaguar_op & 31; + INT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (INT32)r2 >> r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 << 1) & 2; +} + +void shlq_n_rn(void) +{ + int dreg = jaguar_op & 31; + INT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 << (32 - r1); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 >> 30) & 2; +} + +void shrq_n_rn(void) +{ + int dreg = jaguar_op & 31; + INT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 >> r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 << 1) & 2; +} + +void store_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_long_write(r1, gpu_reg[jaguar_op & 31]); +} + +void store_rn_r14n(void) +{ + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + gpu_long_write(gpu_reg[14] + r1 * 4, gpu_reg[jaguar_op & 31]); +} + +void store_rn_r15n(void) +{ + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + gpu_long_write(gpu_reg[15] + r1 * 4, gpu_reg[jaguar_op & 31]); +} + +void store_rn_r14rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_long_write(gpu_reg[14] + r1, gpu_reg[jaguar_op & 31]); +} + +void store_rn_r15rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_long_write(gpu_reg[15] + r1, gpu_reg[jaguar_op & 31]); +} + +void storeb_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_byte_write(r1, gpu_reg[jaguar_op & 31]); +} + +void storew_rn_rn(void) +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_word_write(r1, gpu_reg[jaguar_op & 31]); +} + +void storep_rn_rn(void) /* GPU only */ +{ + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + gpu_long_write(r1, gpu_hidata); + gpu_long_write(r1+4, gpu_reg[jaguar_op & 31]); +} + +void sub_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; +// fprintf(log_get(),"r%i=0x%.8x r%i=0x%.8x\n",(jaguar_op >> 5) & 31,r1,dreg,r2); + UINT32 res = r2 - r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void subc_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1 - gpu_flag_c; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void subq_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void subqmod_n_rn(void) /* DSP only */ +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1; +// res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void subqt_n_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1; + gpu_reg[dreg] = res; +} + +void xor_rn_rn(void) +{ + int dreg = jaguar_op & 31; + UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r1 ^ r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} diff --git a/src/include/memory.h b/src/include/memory.h new file mode 100644 index 0000000..0073bcf --- /dev/null +++ b/src/include/memory.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +#include +#include +#include +#include "types.h" +#include "log.h" + +void memory_init(void); +void memory_done(void); +void memory_malloc_secure(void **new_ptr, UINT32 size, char *info); +void *memory_malloc(UINT32 size, char *info); +void memory_free(void *ptr); +void memory_memoryUsage(FILE *fp); + + +#endif diff --git a/src/include/objectp.h b/src/include/objectp.h new file mode 100644 index 0000000..58856c8 --- /dev/null +++ b/src/include/objectp.h @@ -0,0 +1,20 @@ +#ifndef __OBJECTP_H__ +#define __OBJECTP_H__ + +#include "types.h" + +void op_init(void); +void op_reset(void); +void op_done(void); +void op_byte_write(uint32, uint8); +void op_word_write(uint32, uint16); +uint8 op_byte_read(uint32); +uint16 op_word_read(uint32); +uint32 op_get_list_pointer(void); +void op_process_list(int16 *backbuffer, int scanline, int render); +void op_set_status_register(uint32 data); +uint32 op_get_status_register(void); +void op_set_current_object(uint64 object); + + +#endif diff --git a/src/include/pcm.h b/src/include/pcm.h new file mode 100644 index 0000000..e953ccd --- /dev/null +++ b/src/include/pcm.h @@ -0,0 +1,18 @@ +#ifndef __PCM_H__ +#define __PCM_H__ + +#include "jaguar.h" + +void pcm_init(void); +void pcm_reset(void); +void pcm_done(void); + +void pcm_update(void); +void pcm_byte_write(uint32 offset, uint8 data); +void pcm_word_write(uint32 offset, uint16 data); +uint8 pcm_byte_read(uint32 offset); +uint16 pcm_word_read(uint32 offset); +void pcm_updateOne(int channel, int16 * data, uint32 length); +void pcm_set_sample_rate(int rate); + +#endif diff --git a/src/include/tom.h b/src/include/tom.h new file mode 100644 index 0000000..f22f70a --- /dev/null +++ b/src/include/tom.h @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOM_H__ +#define __TOM_H__ + +#include "jaguar.h" + +#define TOM_VBLANK_DURATION_IN_SCANLINES 25 + +#define VIDEO_MODE_16BPP_CRY 0 +#define VIDEO_MODE_24BPP_RGB 1 +#define VIDEO_MODE_16BPP_DIRECT 2 +#define VIDEO_MODE_16BPP_RGB 3 + + +extern uint32 tom_width; +extern uint32 tom_height; + +void tom_init(void); +void tom_reset(void); +void tom_done(void); +unsigned tom_byte_read(unsigned int offset); +unsigned tom_word_read(unsigned int offset); +void tom_byte_write(unsigned offset, unsigned data); +void tom_word_write(unsigned offset, unsigned data); +void tom_exec_scanline(int16 *backbuffer, int32 scanline, int8 render); +uint32 tom_getVideoModeWidth(void); +uint32 tom_getVideoModeHeight(void); +uint8 tom_getVideoMode(void); +uint8 *tom_get_ram_pointer(void); +uint16 tom_get_hdb(void); +uint16 tom_get_vdb(void); +uint16 tom_get_scanline(void); +uint32 tom_getHBlankWidthInPixels(void); + +////////////////////////////////////////////////////////////////////////////// +// interrupts +////////////////////////////////////////////////////////////////////////////// +#define IRQ_VBLANK 0 +#define IRQ_GPU 1 +#define IRQ_HBLANK 2 +#define IRQ_OPFLAG IRQ_HBLANK +#define IRQ_TIMER 3 +#define IRQ_DSP 4 + +int tom_irq_enabled(int irq); +uint16 tom_irq_control_reg(void); +void tom_set_irq_latch(int irq, int enabled); +void tom_pit_exec(uint32 cycles); +void tom_set_pending_puck_int(void); +void tom_set_pending_timer_int(void); +void tom_set_pending_object_int(void); +void tom_set_pending_gpu_int(void); +void tom_set_pending_video_int(void); +void tom_reset_timer(void); + + +#endif diff --git a/src/include/types.h b/src/include/types.h new file mode 100644 index 0000000..e3a4be9 --- /dev/null +++ b/src/include/types.h @@ -0,0 +1,42 @@ +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Removal of unsafe macros and addition of typdefs by James L. Hammons +// + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +#ifdef __PORT__ +#include +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +#ifdef __GCCUNIX__ +typedef long long __int64; // Could probably remove this crap with some judicious pruning +#endif // #ifdef __GCCUNIX__ +typedef int HWND; +#else +#include +#endif // #ifdef __PORT__ + +// This is only good on certain intel 32-bit platforms... +// You may need to tweak to suit your specific platform. + +typedef unsigned char UINT8; +typedef signed char INT8; +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned long UINT32; +typedef signed long INT32; +typedef unsigned long long UINT64; +typedef signed long long INT64; + +typedef UINT8 uint8; +typedef INT8 int8; +typedef UINT16 uint16; +typedef INT16 int16; +typedef UINT32 uint32; +typedef INT32 int32; +typedef UINT64 uint64; +typedef INT64 int64; + +#endif // #ifndef __TYPES_H__ diff --git a/src/include/version.h b/src/include/version.h new file mode 100644 index 0000000..ac29cae --- /dev/null +++ b/src/include/version.h @@ -0,0 +1,23 @@ +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __VERSION_H__ +#define __VERSION_H__ + +#include +#include + +void version_init(void); +void version_display(FILE *); +void version_done(void); + +#endif diff --git a/src/include/wavetable.h b/src/include/wavetable.h new file mode 100644 index 0000000..71998b4 --- /dev/null +++ b/src/include/wavetable.h @@ -0,0 +1,258 @@ +const unsigned char wave_table[4096] = { + 0xFF, 0xFF, 0xC2, 0x01, 0xFF, 0xFF, 0xC4, 0x01, 0xFF, 0xFF, 0xC6, 0x01, 0xFF, 0xFF, 0xC8, 0x01, + 0xFF, 0xFF, 0xCA, 0x01, 0xFF, 0xFF, 0xCC, 0x01, 0xFF, 0xFF, 0xCE, 0x01, 0xFF, 0xFF, 0xD0, 0x01, + 0xFF, 0xFF, 0xD2, 0x01, 0xFF, 0xFF, 0xD4, 0x01, 0xFF, 0xFF, 0xD6, 0x01, 0xFF, 0xFF, 0xD8, 0x01, + 0xFF, 0xFF, 0xDA, 0x01, 0xFF, 0xFF, 0xDC, 0x01, 0xFF, 0xFF, 0xDE, 0x01, 0xFF, 0xFF, 0xE0, 0x01, + 0xFF, 0xFF, 0xE2, 0x01, 0xFF, 0xFF, 0xE4, 0x01, 0xFF, 0xFF, 0xE6, 0x01, 0xFF, 0xFF, 0xE8, 0x01, + 0xFF, 0xFF, 0xEA, 0x01, 0xFF, 0xFF, 0xEC, 0x01, 0xFF, 0xFF, 0xEE, 0x01, 0xFF, 0xFF, 0xF0, 0x01, + 0xFF, 0xFF, 0xF2, 0x01, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xF6, 0x01, 0xFF, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0xFA, 0x01, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x05, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0x00, 0x00, 0x09, 0xFF, 0x00, 0x00, 0x0B, 0xFF, 0x00, 0x00, 0x0D, 0xFF, 0x00, 0x00, 0x0F, 0xFF, + 0x00, 0x00, 0x11, 0xFF, 0x00, 0x00, 0x13, 0xFF, 0x00, 0x00, 0x15, 0xFF, 0x00, 0x00, 0x17, 0xFF, + 0x00, 0x00, 0x19, 0xFF, 0x00, 0x00, 0x1B, 0xFF, 0x00, 0x00, 0x1D, 0xFF, 0x00, 0x00, 0x1F, 0xFF, + 0x00, 0x00, 0x21, 0xFF, 0x00, 0x00, 0x23, 0xFF, 0x00, 0x00, 0x25, 0xFF, 0x00, 0x00, 0x27, 0xFF, + 0x00, 0x00, 0x29, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x00, 0x00, 0x2D, 0xFF, 0x00, 0x00, 0x2F, 0xFF, + 0x00, 0x00, 0x31, 0xFF, 0x00, 0x00, 0x33, 0xFF, 0x00, 0x00, 0x35, 0xFF, 0x00, 0x00, 0x37, 0xFF, + 0x00, 0x00, 0x39, 0xFF, 0x00, 0x00, 0x3B, 0xFF, 0x00, 0x00, 0x3D, 0xFF, 0x00, 0x00, 0x3F, 0xFF, + 0x00, 0x00, 0x3D, 0xFF, 0x00, 0x00, 0x3B, 0xFF, 0x00, 0x00, 0x39, 0xFF, 0x00, 0x00, 0x37, 0xFF, + 0x00, 0x00, 0x35, 0xFF, 0x00, 0x00, 0x33, 0xFF, 0x00, 0x00, 0x31, 0xFF, 0x00, 0x00, 0x2F, 0xFF, + 0x00, 0x00, 0x2D, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x00, 0x00, 0x29, 0xFF, 0x00, 0x00, 0x27, 0xFF, + 0x00, 0x00, 0x25, 0xFF, 0x00, 0x00, 0x23, 0xFF, 0x00, 0x00, 0x21, 0xFF, 0x00, 0x00, 0x1F, 0xFF, + 0x00, 0x00, 0x1D, 0xFF, 0x00, 0x00, 0x1B, 0xFF, 0x00, 0x00, 0x19, 0xFF, 0x00, 0x00, 0x17, 0xFF, + 0x00, 0x00, 0x15, 0xFF, 0x00, 0x00, 0x13, 0xFF, 0x00, 0x00, 0x11, 0xFF, 0x00, 0x00, 0x0F, 0xFF, + 0x00, 0x00, 0x0D, 0xFF, 0x00, 0x00, 0x0B, 0xFF, 0x00, 0x00, 0x09, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0x00, 0x00, 0x05, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFA, 0x01, 0xFF, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0xF6, 0x01, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xF2, 0x01, 0xFF, 0xFF, 0xF0, 0x01, + 0xFF, 0xFF, 0xEE, 0x01, 0xFF, 0xFF, 0xEC, 0x01, 0xFF, 0xFF, 0xEA, 0x01, 0xFF, 0xFF, 0xE8, 0x01, + 0xFF, 0xFF, 0xE6, 0x01, 0xFF, 0xFF, 0xE4, 0x01, 0xFF, 0xFF, 0xE2, 0x01, 0xFF, 0xFF, 0xE0, 0x01, + 0xFF, 0xFF, 0xDE, 0x01, 0xFF, 0xFF, 0xDC, 0x01, 0xFF, 0xFF, 0xDA, 0x01, 0xFF, 0xFF, 0xD8, 0x01, + 0xFF, 0xFF, 0xD6, 0x01, 0xFF, 0xFF, 0xD4, 0x01, 0xFF, 0xFF, 0xD2, 0x01, 0xFF, 0xFF, 0xD0, 0x01, + 0xFF, 0xFF, 0xCE, 0x01, 0xFF, 0xFF, 0xCC, 0x01, 0xFF, 0xFF, 0xCA, 0x01, 0xFF, 0xFF, 0xC8, 0x01, + 0xFF, 0xFF, 0xC6, 0x01, 0xFF, 0xFF, 0xC4, 0x01, 0xFF, 0xFF, 0xC2, 0x01, 0xFF, 0xFF, 0xC0, 0x01, + 0x00, 0x00, 0x06, 0x47, 0x00, 0x00, 0x0C, 0x8B, 0x00, 0x00, 0x12, 0xC7, 0x00, 0x00, 0x18, 0xF8, + 0x00, 0x00, 0x1F, 0x19, 0x00, 0x00, 0x25, 0x27, 0x00, 0x00, 0x2B, 0x1E, 0x00, 0x00, 0x30, 0xFB, + 0x00, 0x00, 0x36, 0xB9, 0x00, 0x00, 0x3C, 0x56, 0x00, 0x00, 0x41, 0xCD, 0x00, 0x00, 0x47, 0x1C, + 0x00, 0x00, 0x4C, 0x3F, 0x00, 0x00, 0x51, 0x33, 0x00, 0x00, 0x55, 0xF4, 0x00, 0x00, 0x5A, 0x81, + 0x00, 0x00, 0x5E, 0xD6, 0x00, 0x00, 0x62, 0xF1, 0x00, 0x00, 0x66, 0xCE, 0x00, 0x00, 0x6A, 0x6C, + 0x00, 0x00, 0x6D, 0xC9, 0x00, 0x00, 0x70, 0xE1, 0x00, 0x00, 0x73, 0xB5, 0x00, 0x00, 0x76, 0x40, + 0x00, 0x00, 0x78, 0x83, 0x00, 0x00, 0x7A, 0x7C, 0x00, 0x00, 0x7C, 0x29, 0x00, 0x00, 0x7D, 0x89, + 0x00, 0x00, 0x7E, 0x9C, 0x00, 0x00, 0x7F, 0x61, 0x00, 0x00, 0x7F, 0xD7, 0x00, 0x00, 0x7F, 0xFF, + 0x00, 0x00, 0x7F, 0xD7, 0x00, 0x00, 0x7F, 0x61, 0x00, 0x00, 0x7E, 0x9C, 0x00, 0x00, 0x7D, 0x89, + 0x00, 0x00, 0x7C, 0x29, 0x00, 0x00, 0x7A, 0x7C, 0x00, 0x00, 0x78, 0x83, 0x00, 0x00, 0x76, 0x40, + 0x00, 0x00, 0x73, 0xB5, 0x00, 0x00, 0x70, 0xE1, 0x00, 0x00, 0x6D, 0xC9, 0x00, 0x00, 0x6A, 0x6C, + 0x00, 0x00, 0x66, 0xCE, 0x00, 0x00, 0x62, 0xF1, 0x00, 0x00, 0x5E, 0xD6, 0x00, 0x00, 0x5A, 0x81, + 0x00, 0x00, 0x55, 0xF4, 0x00, 0x00, 0x51, 0x33, 0x00, 0x00, 0x4C, 0x3F, 0x00, 0x00, 0x47, 0x1C, + 0x00, 0x00, 0x41, 0xCD, 0x00, 0x00, 0x3C, 0x56, 0x00, 0x00, 0x36, 0xB9, 0x00, 0x00, 0x30, 0xFB, + 0x00, 0x00, 0x2B, 0x1E, 0x00, 0x00, 0x25, 0x27, 0x00, 0x00, 0x1F, 0x19, 0x00, 0x00, 0x18, 0xF8, + 0x00, 0x00, 0x12, 0xC7, 0x00, 0x00, 0x0C, 0x8B, 0x00, 0x00, 0x06, 0x47, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF9, 0xB9, 0xFF, 0xFF, 0xF3, 0x75, 0xFF, 0xFF, 0xED, 0x39, 0xFF, 0xFF, 0xE7, 0x08, + 0xFF, 0xFF, 0xE0, 0xE7, 0xFF, 0xFF, 0xDA, 0xD9, 0xFF, 0xFF, 0xD4, 0xE2, 0xFF, 0xFF, 0xCF, 0x05, + 0xFF, 0xFF, 0xC9, 0x47, 0xFF, 0xFF, 0xC3, 0xAA, 0xFF, 0xFF, 0xBE, 0x33, 0xFF, 0xFF, 0xB8, 0xE4, + 0xFF, 0xFF, 0xB3, 0xC1, 0xFF, 0xFF, 0xAE, 0xCD, 0xFF, 0xFF, 0xAA, 0x0C, 0xFF, 0xFF, 0xA5, 0x7F, + 0xFF, 0xFF, 0xA1, 0x2A, 0xFF, 0xFF, 0x9D, 0x0F, 0xFF, 0xFF, 0x99, 0x32, 0xFF, 0xFF, 0x95, 0x94, + 0xFF, 0xFF, 0x92, 0x37, 0xFF, 0xFF, 0x8F, 0x1F, 0xFF, 0xFF, 0x8C, 0x4B, 0xFF, 0xFF, 0x89, 0xC0, + 0xFF, 0xFF, 0x87, 0x7D, 0xFF, 0xFF, 0x85, 0x84, 0xFF, 0xFF, 0x83, 0xD7, 0xFF, 0xFF, 0x82, 0x77, + 0xFF, 0xFF, 0x81, 0x64, 0xFF, 0xFF, 0x80, 0x9F, 0xFF, 0xFF, 0x80, 0x29, 0xFF, 0xFF, 0x80, 0x01, + 0xFF, 0xFF, 0x80, 0x29, 0xFF, 0xFF, 0x80, 0x9F, 0xFF, 0xFF, 0x81, 0x64, 0xFF, 0xFF, 0x82, 0x77, + 0xFF, 0xFF, 0x83, 0xD7, 0xFF, 0xFF, 0x85, 0x84, 0xFF, 0xFF, 0x87, 0x7D, 0xFF, 0xFF, 0x89, 0xC0, + 0xFF, 0xFF, 0x8C, 0x4B, 0xFF, 0xFF, 0x8F, 0x1F, 0xFF, 0xFF, 0x92, 0x37, 0xFF, 0xFF, 0x95, 0x94, + 0xFF, 0xFF, 0x99, 0x32, 0xFF, 0xFF, 0x9D, 0x0F, 0xFF, 0xFF, 0xA1, 0x2A, 0xFF, 0xFF, 0xA5, 0x7F, + 0xFF, 0xFF, 0xAA, 0x0C, 0xFF, 0xFF, 0xAE, 0xCD, 0xFF, 0xFF, 0xB3, 0xC1, 0xFF, 0xFF, 0xB8, 0xE4, + 0xFF, 0xFF, 0xBE, 0x33, 0xFF, 0xFF, 0xC3, 0xAA, 0xFF, 0xFF, 0xC9, 0x47, 0xFF, 0xFF, 0xCF, 0x05, + 0xFF, 0xFF, 0xD4, 0xE2, 0xFF, 0xFF, 0xDA, 0xD9, 0xFF, 0xFF, 0xE0, 0xE7, 0xFF, 0xFF, 0xE7, 0x08, + 0xFF, 0xFF, 0xED, 0x39, 0xFF, 0xFF, 0xF3, 0x75, 0xFF, 0xFF, 0xF9, 0xB9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x01, 0x8E, 0x00, 0x00, 0x02, 0x3A, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x03, 0xEB, + 0x00, 0x00, 0x04, 0xEC, 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x07, 0x3D, 0x00, 0x00, 0x08, 0x88, + 0x00, 0x00, 0x09, 0xE9, 0x00, 0x00, 0x0B, 0x5E, 0x00, 0x00, 0x0C, 0xE4, 0x00, 0x00, 0x0E, 0x7B, + 0x00, 0x00, 0x10, 0x1F, 0x00, 0x00, 0x11, 0xCF, 0x00, 0x00, 0x13, 0x88, 0x00, 0x00, 0x15, 0x48, + 0x00, 0x00, 0x17, 0x0E, 0x00, 0x00, 0x18, 0xD5, 0x00, 0x00, 0x1A, 0x9C, 0x00, 0x00, 0x1C, 0x61, + 0x00, 0x00, 0x1E, 0x20, 0x00, 0x00, 0x1F, 0xD8, 0x00, 0x00, 0x21, 0x85, 0x00, 0x00, 0x23, 0x26, + 0x00, 0x00, 0x24, 0xB7, 0x00, 0x00, 0x26, 0x36, 0x00, 0x00, 0x27, 0xA1, 0x00, 0x00, 0x28, 0xF5, + 0x00, 0x00, 0x2A, 0x30, 0x00, 0x00, 0x2B, 0x4F, 0x00, 0x00, 0x2C, 0x50, 0x00, 0x00, 0x2D, 0x31, + 0x00, 0x00, 0x2D, 0xF0, 0x00, 0x00, 0x2E, 0x8B, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2F, 0x4D, + 0x00, 0x00, 0x2F, 0x70, 0x00, 0x00, 0x2F, 0x69, 0x00, 0x00, 0x2F, 0x35, 0x00, 0x00, 0x2E, 0xD3, + 0x00, 0x00, 0x2E, 0x43, 0x00, 0x00, 0x2D, 0x83, 0x00, 0x00, 0x2C, 0x93, 0x00, 0x00, 0x2B, 0x71, + 0x00, 0x00, 0x2A, 0x1E, 0x00, 0x00, 0x28, 0x99, 0x00, 0x00, 0x26, 0xE2, 0x00, 0x00, 0x24, 0xFA, + 0x00, 0x00, 0x22, 0xE0, 0x00, 0x00, 0x20, 0x94, 0x00, 0x00, 0x1E, 0x19, 0x00, 0x00, 0x1B, 0x6E, + 0x00, 0x00, 0x18, 0x94, 0x00, 0x00, 0x15, 0x8C, 0x00, 0x00, 0x12, 0x59, 0x00, 0x00, 0x0E, 0xFB, + 0x00, 0x00, 0x0B, 0x74, 0x00, 0x00, 0x07, 0xC7, 0x00, 0x00, 0x03, 0xF4, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFB, 0xEB, 0xFF, 0xFF, 0xF7, 0xB9, 0xFF, 0xFF, 0xF3, 0x6B, 0xFF, 0xFF, 0xEF, 0x06, + 0xFF, 0xFF, 0xEA, 0x8B, 0xFF, 0xFF, 0xE5, 0xFE, 0xFF, 0xFF, 0xE1, 0x63, 0xFF, 0xFF, 0xDC, 0xBC, + 0xFF, 0xFF, 0xD8, 0x0D, 0xFF, 0xFF, 0xD3, 0x5A, 0xFF, 0xFF, 0xCE, 0xA6, 0xFF, 0xFF, 0xC9, 0xF5, + 0xFF, 0xFF, 0xC5, 0x4B, 0xFF, 0xFF, 0xC0, 0xAB, 0xFF, 0xFF, 0xBC, 0x19, 0xFF, 0xFF, 0xB7, 0x99, + 0xFF, 0xFF, 0xB3, 0x2F, 0xFF, 0xFF, 0xAE, 0xDF, 0xFF, 0xFF, 0xAA, 0xAC, 0xFF, 0xFF, 0xA6, 0x9B, + 0xFF, 0xFF, 0xA2, 0xAF, 0xFF, 0xFF, 0x9E, 0xEC, 0xFF, 0xFF, 0x9B, 0x56, 0xFF, 0xFF, 0x97, 0xF0, + 0xFF, 0xFF, 0x94, 0xBF, 0xFF, 0xFF, 0x91, 0xC4, 0xFF, 0xFF, 0x8F, 0x04, 0xFF, 0xFF, 0x8C, 0x82, + 0xFF, 0xFF, 0x8A, 0x41, 0xFF, 0xFF, 0x88, 0x44, 0xFF, 0xFF, 0x86, 0x8D, 0xFF, 0xFF, 0x85, 0x20, + 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x83, 0x2B, 0xFF, 0xFF, 0x82, 0xA8, 0xFF, 0xFF, 0x82, 0x77, + 0xFF, 0xFF, 0x82, 0x9A, 0xFF, 0xFF, 0x83, 0x11, 0xFF, 0xFF, 0x83, 0xDF, 0xFF, 0xFF, 0x85, 0x05, + 0xFF, 0xFF, 0x86, 0x82, 0xFF, 0xFF, 0x88, 0x59, 0xFF, 0xFF, 0x8A, 0x88, 0xFF, 0xFF, 0x8D, 0x10, + 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x93, 0x2A, 0xFF, 0xFF, 0x96, 0xBB, 0xFF, 0xFF, 0x9A, 0xA2, + 0xFF, 0xFF, 0x9E, 0xDF, 0xFF, 0xFF, 0xA3, 0x6F, 0xFF, 0xFF, 0xA8, 0x51, 0xFF, 0xFF, 0xAD, 0x83, + 0xFF, 0xFF, 0xB3, 0x03, 0xFF, 0xFF, 0xB8, 0xCE, 0xFF, 0xFF, 0xBE, 0xE1, 0xFF, 0xFF, 0xC5, 0x39, + 0xFF, 0xFF, 0xCB, 0xD3, 0xFF, 0xFF, 0xD2, 0xAC, 0xFF, 0xFF, 0xD9, 0xC0, 0xFF, 0xFF, 0xE1, 0x0A, + 0xFF, 0xFF, 0xE8, 0x87, 0xFF, 0xFF, 0xF0, 0x32, 0xFF, 0xFF, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x69, 0x00, 0x00, 0x12, 0xC2, 0x00, 0x00, 0x1B, 0xF7, 0x00, 0x00, 0x24, 0xF9, + 0x00, 0x00, 0x2D, 0xB7, 0x00, 0x00, 0x36, 0x22, 0x00, 0x00, 0x3E, 0x29, 0x00, 0x00, 0x45, 0xBE, + 0x00, 0x00, 0x4C, 0xD5, 0x00, 0x00, 0x53, 0x61, 0x00, 0x00, 0x59, 0x57, 0x00, 0x00, 0x5E, 0xAE, + 0x00, 0x00, 0x63, 0x5D, 0x00, 0x00, 0x67, 0x5E, 0x00, 0x00, 0x6A, 0xAB, 0x00, 0x00, 0x6D, 0x40, + 0x00, 0x00, 0x6F, 0x1B, 0x00, 0x00, 0x70, 0x3D, 0x00, 0x00, 0x70, 0xA5, 0x00, 0x00, 0x70, 0x56, + 0x00, 0x00, 0x6F, 0x55, 0x00, 0x00, 0x6D, 0xA7, 0x00, 0x00, 0x6B, 0x53, 0x00, 0x00, 0x68, 0x61, + 0x00, 0x00, 0x64, 0xDB, 0x00, 0x00, 0x60, 0xCC, 0x00, 0x00, 0x5C, 0x3F, 0x00, 0x00, 0x57, 0x42, + 0x00, 0x00, 0x51, 0xE2, 0x00, 0x00, 0x4C, 0x2C, 0x00, 0x00, 0x46, 0x31, 0x00, 0x00, 0x3F, 0xFF, + 0x00, 0x00, 0x39, 0xA5, 0x00, 0x00, 0x33, 0x34, 0x00, 0x00, 0x2C, 0xBA, 0x00, 0x00, 0x26, 0x47, + 0x00, 0x00, 0x1F, 0xE9, 0x00, 0x00, 0x19, 0xAF, 0x00, 0x00, 0x13, 0xA8, 0x00, 0x00, 0x0D, 0xDF, + 0x00, 0x00, 0x08, 0x61, 0x00, 0x00, 0x03, 0x3A, 0xFF, 0xFF, 0xFE, 0x74, 0xFF, 0xFF, 0xFA, 0x17, + 0xFF, 0xFF, 0xF6, 0x2A, 0xFF, 0xFF, 0xF2, 0xB4, 0xFF, 0xFF, 0xEF, 0xBB, 0xFF, 0xFF, 0xED, 0x42, + 0xFF, 0xFF, 0xEB, 0x4A, 0xFF, 0xFF, 0xE9, 0xD5, 0xFF, 0xFF, 0xE8, 0xE2, 0xFF, 0xFF, 0xE8, 0x6E, + 0xFF, 0xFF, 0xE8, 0x76, 0xFF, 0xFF, 0xE8, 0xF5, 0xFF, 0xFF, 0xE9, 0xE5, 0xFF, 0xFF, 0xEB, 0x3D, + 0xFF, 0xFF, 0xEC, 0xF6, 0xFF, 0xFF, 0xEF, 0x06, 0xFF, 0xFF, 0xF1, 0x62, 0xFF, 0xFF, 0xF3, 0xFF, + 0xFF, 0xFF, 0xF6, 0xD1, 0xFF, 0xFF, 0xF9, 0xCA, 0xFF, 0xFF, 0xFC, 0xDF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x21, 0x00, 0x00, 0x06, 0x36, 0x00, 0x00, 0x09, 0x2F, 0x00, 0x00, 0x0C, 0x01, + 0x00, 0x00, 0x0E, 0x9E, 0x00, 0x00, 0x10, 0xFA, 0x00, 0x00, 0x13, 0x0A, 0x00, 0x00, 0x14, 0xC3, + 0x00, 0x00, 0x16, 0x1B, 0x00, 0x00, 0x17, 0x0B, 0x00, 0x00, 0x17, 0x8A, 0x00, 0x00, 0x17, 0x92, + 0x00, 0x00, 0x17, 0x1E, 0x00, 0x00, 0x16, 0x2B, 0x00, 0x00, 0x14, 0xB6, 0x00, 0x00, 0x12, 0xBE, + 0x00, 0x00, 0x10, 0x45, 0x00, 0x00, 0x0D, 0x4C, 0x00, 0x00, 0x09, 0xD6, 0x00, 0x00, 0x05, 0xE9, + 0x00, 0x00, 0x01, 0x8C, 0xFF, 0xFF, 0xFC, 0xC6, 0xFF, 0xFF, 0xF7, 0x9F, 0xFF, 0xFF, 0xF2, 0x21, + 0xFF, 0xFF, 0xEC, 0x58, 0xFF, 0xFF, 0xE6, 0x51, 0xFF, 0xFF, 0xE0, 0x17, 0xFF, 0xFF, 0xD9, 0xB9, + 0xFF, 0xFF, 0xD3, 0x46, 0xFF, 0xFF, 0xCC, 0xCC, 0xFF, 0xFF, 0xC6, 0x5B, 0xFF, 0xFF, 0xC0, 0x01, + 0xFF, 0xFF, 0xB9, 0xCF, 0xFF, 0xFF, 0xB3, 0xD4, 0xFF, 0xFF, 0xAE, 0x1E, 0xFF, 0xFF, 0xA8, 0xBE, + 0xFF, 0xFF, 0xA3, 0xC1, 0xFF, 0xFF, 0x9F, 0x34, 0xFF, 0xFF, 0x9B, 0x25, 0xFF, 0xFF, 0x97, 0x9F, + 0xFF, 0xFF, 0x94, 0xAD, 0xFF, 0xFF, 0x92, 0x59, 0xFF, 0xFF, 0x90, 0xAB, 0xFF, 0xFF, 0x8F, 0xAA, + 0xFF, 0xFF, 0x8F, 0x5B, 0xFF, 0xFF, 0x8F, 0xC3, 0xFF, 0xFF, 0x90, 0xE5, 0xFF, 0xFF, 0x92, 0xC0, + 0xFF, 0xFF, 0x95, 0x55, 0xFF, 0xFF, 0x98, 0xA2, 0xFF, 0xFF, 0x9C, 0xA3, 0xFF, 0xFF, 0xA1, 0x52, + 0xFF, 0xFF, 0xA6, 0xA9, 0xFF, 0xFF, 0xAC, 0x9F, 0xFF, 0xFF, 0xB3, 0x2B, 0xFF, 0xFF, 0xBA, 0x42, + 0xFF, 0xFF, 0xC1, 0xD7, 0xFF, 0xFF, 0xC9, 0xDE, 0xFF, 0xFF, 0xD2, 0x49, 0xFF, 0xFF, 0xDB, 0x07, + 0xFF, 0xFF, 0xE4, 0x09, 0xFF, 0xFF, 0xED, 0x3E, 0xFF, 0xFF, 0xF6, 0x97, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x0F, 0x79, 0x00, 0x00, 0x19, 0x4E, 0x00, 0x00, 0x24, 0x67, + 0x00, 0x00, 0x30, 0x92, 0x00, 0x00, 0x3D, 0x8B, 0x00, 0x00, 0x4A, 0xF0, 0x00, 0x00, 0x58, 0x42, + 0x00, 0x00, 0x64, 0xE0, 0x00, 0x00, 0x70, 0x09, 0x00, 0x00, 0x78, 0xE3, 0x00, 0x00, 0x7E, 0x7E, + 0x00, 0x00, 0x7F, 0xE5, 0x00, 0x00, 0x7C, 0x35, 0x00, 0x00, 0x72, 0xB3, 0x00, 0x00, 0x62, 0xF1, + 0x00, 0x00, 0x4C, 0xEA, 0x00, 0x00, 0x31, 0x29, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xFF, 0xEE, 0x00, + 0xFF, 0xFF, 0xCB, 0x1A, 0xFF, 0xFF, 0xAB, 0x5D, 0xFF, 0xFF, 0x92, 0x3E, 0xFF, 0xFF, 0x83, 0x1E, + 0xFF, 0xFF, 0x80, 0xC8, 0xFF, 0xFF, 0x8C, 0xE4, 0xFF, 0xFF, 0xA7, 0x6D, 0xFF, 0xFF, 0xCE, 0x4C, + 0xFF, 0xFF, 0xFD, 0x34, 0x00, 0x00, 0x2D, 0xE1, 0x00, 0x00, 0x58, 0xCA, 0x00, 0x00, 0x76, 0x40, + 0x00, 0x00, 0x7F, 0xEF, 0x00, 0x00, 0x72, 0x6A, 0x00, 0x00, 0x4E, 0x79, 0x00, 0x00, 0x19, 0xBD, + 0xFF, 0xFF, 0xDE, 0x4A, 0xFF, 0xFF, 0xA9, 0x08, 0xFF, 0xFF, 0x86, 0xFC, 0xFF, 0xFF, 0x81, 0xE4, + 0xFF, 0xFF, 0x9D, 0x07, 0xFF, 0xFF, 0xD3, 0x39, 0x00, 0x00, 0x16, 0xFE, 0x00, 0x00, 0x55, 0x5F, + 0x00, 0x00, 0x7B, 0x06, 0x00, 0x00, 0x7A, 0x8A, 0x00, 0x00, 0x51, 0xD7, 0x00, 0x00, 0x0C, 0x8B, + 0xFF, 0xFF, 0xC1, 0xA4, 0xFF, 0xFF, 0x8C, 0x61, 0xFF, 0xFF, 0x82, 0x3B, 0xFF, 0xFF, 0xA9, 0x77, + 0xFF, 0xFF, 0xF4, 0x95, 0x00, 0x00, 0x45, 0xA2, 0x00, 0x00, 0x79, 0x85, 0x00, 0x00, 0x77, 0x6B, + 0x00, 0x00, 0x3D, 0xC2, 0xFF, 0xFF, 0xE5, 0xAF, 0xFF, 0xFF, 0x99, 0x75, 0xFF, 0xFF, 0x80, 0x8C, + 0xFF, 0xFF, 0xAA, 0x4D, 0x00, 0x00, 0x02, 0xF1, 0x00, 0x00, 0x5B, 0x06, 0x00, 0x00, 0x7F, 0xFF, + 0x00, 0x00, 0x59, 0xFC, 0xFF, 0xFF, 0xFD, 0x0F, 0xFF, 0xFF, 0xA0, 0xEF, 0xFF, 0xFF, 0x80, 0x8C, + 0xFF, 0xFF, 0xB3, 0x67, 0x00, 0x00, 0x1A, 0x51, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0x77, 0x6B, + 0x00, 0x00, 0x28, 0x32, 0xFF, 0xFF, 0xBA, 0x5E, 0xFF, 0xFF, 0x80, 0x84, 0xFF, 0xFF, 0xA9, 0x77, + 0x00, 0x00, 0x17, 0xC4, 0x00, 0x00, 0x73, 0x9F, 0x00, 0x00, 0x6F, 0xC6, 0x00, 0x00, 0x0C, 0x8B, + 0xFF, 0xFF, 0x9D, 0x97, 0xFF, 0xFF, 0x85, 0x76, 0xFF, 0xFF, 0xDC, 0xAF, 0x00, 0x00, 0x55, 0x5F, + 0x00, 0x00, 0x7D, 0xE9, 0x00, 0x00, 0x2C, 0xC7, 0xFF, 0xFF, 0xAE, 0xD7, 0xFF, 0xFF, 0x81, 0xE4, + 0xFF, 0xFF, 0xD6, 0x51, 0x00, 0x00, 0x56, 0xF8, 0x00, 0x00, 0x7B, 0x7A, 0x00, 0x00, 0x19, 0xBD, + 0xFF, 0xFF, 0x9A, 0xE3, 0xFF, 0xFF, 0x8D, 0x96, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x76, 0x40, + 0x00, 0x00, 0x5C, 0x31, 0xFF, 0xFF, 0xD2, 0x1F, 0xFF, 0xFF, 0x80, 0x09, 0xFF, 0xFF, 0xCE, 0x4C, + 0x00, 0x00, 0x5C, 0x65, 0x00, 0x00, 0x73, 0x1C, 0xFF, 0xFF, 0xF1, 0xF1, 0xFF, 0xFF, 0x83, 0x1E, + 0xFF, 0xFF, 0xBE, 0x28, 0x00, 0x00, 0x54, 0xA3, 0x00, 0x00, 0x74, 0x8D, 0xFF, 0xFF, 0xEE, 0x00, + 0xFF, 0xFF, 0x81, 0x20, 0xFF, 0xFF, 0xCE, 0xD7, 0x00, 0x00, 0x66, 0x4E, 0x00, 0x00, 0x62, 0xF1, + 0xFF, 0xFF, 0xC7, 0x33, 0xFF, 0xFF, 0x83, 0xCB, 0x00, 0x00, 0x05, 0x0D, 0x00, 0x00, 0x7E, 0x7E, + 0x00, 0x00, 0x2A, 0x0E, 0xFF, 0xFF, 0x8F, 0xF7, 0xFF, 0xFF, 0xB1, 0x37, 0x00, 0x00, 0x58, 0x42, + 0x00, 0x00, 0x67, 0xC3, 0xFF, 0xFF, 0xC2, 0x75, 0xFF, 0xFF, 0x89, 0x95, 0x00, 0x00, 0x24, 0x67, + 0x00, 0x00, 0x7D, 0x78, 0xFF, 0xFF, 0xF0, 0x87, 0xFF, 0xFF, 0x80, 0x33, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xC6, 0x95, 0xFF, 0xFF, 0xCB, 0x25, 0xFF, 0xFF, 0xC9, 0xBC, 0xFF, 0xFF, 0xCD, 0x56, + 0xFF, 0xFF, 0xCD, 0x2E, 0xFF, 0xFF, 0xCE, 0x03, 0xFF, 0xFF, 0xCE, 0xC0, 0xFF, 0xFF, 0xD1, 0xAC, + 0xFF, 0xFF, 0xD6, 0x81, 0xFF, 0xFF, 0xD7, 0xD8, 0xFF, 0xFF, 0xD6, 0x23, 0xFF, 0xFF, 0xD9, 0xA3, + 0xFF, 0xFF, 0xD9, 0x6F, 0xFF, 0xFF, 0xDE, 0x63, 0xFF, 0xFF, 0xE1, 0x8B, 0xFF, 0xFF, 0xE0, 0x2F, + 0xFF, 0xFF, 0xDE, 0x31, 0xFF, 0xFF, 0xE6, 0xBA, 0xFF, 0xFF, 0xED, 0x65, 0xFF, 0xFF, 0xEA, 0x39, + 0xFF, 0xFF, 0xEB, 0xAB, 0xFF, 0xFF, 0xED, 0x8B, 0xFF, 0xFF, 0xF0, 0xBA, 0xFF, 0xFF, 0xF4, 0xC5, + 0xFF, 0xFF, 0xF5, 0x99, 0xFF, 0xFF, 0xF4, 0x3B, 0xFF, 0xFF, 0xF6, 0x89, 0xFF, 0xFF, 0xF8, 0xDF, + 0xFF, 0xFF, 0xF8, 0xAE, 0xFF, 0xFF, 0xFE, 0x67, 0xFF, 0xFF, 0xFE, 0x69, 0x00, 0x00, 0x02, 0xF5, + 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, 0x06, 0xEF, 0x00, 0x00, 0x02, 0x17, 0x00, 0x00, 0x0B, 0x0F, + 0x00, 0x00, 0x06, 0x9D, 0x00, 0x00, 0x09, 0x67, 0x00, 0x00, 0x0D, 0x64, 0x00, 0x00, 0x0C, 0x6F, + 0x00, 0x00, 0x11, 0xFC, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x17, 0x68, 0x00, 0x00, 0x16, 0x07, + 0x00, 0x00, 0x19, 0x7E, 0x00, 0x00, 0x1B, 0x11, 0x00, 0x00, 0x1D, 0xD6, 0x00, 0x00, 0x1F, 0x99, + 0x00, 0x00, 0x1E, 0x69, 0x00, 0x00, 0x25, 0x8E, 0x00, 0x00, 0x23, 0x5F, 0x00, 0x00, 0x24, 0x44, + 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x2C, 0x11, 0x00, 0x00, 0x2B, 0x65, 0x00, 0x00, 0x32, 0xBC, + 0x00, 0x00, 0x2F, 0x1F, 0x00, 0x00, 0x31, 0x21, 0x00, 0x00, 0x34, 0x14, 0x00, 0x00, 0x32, 0xF5, + 0x00, 0x00, 0x36, 0x92, 0x00, 0x00, 0x35, 0xFE, 0x00, 0x00, 0x3C, 0xE4, 0x00, 0x00, 0x3D, 0x5F, + 0x00, 0x00, 0x38, 0x91, 0x00, 0x00, 0x39, 0x21, 0x00, 0x00, 0x36, 0x58, 0x00, 0x00, 0x37, 0xD6, + 0x00, 0x00, 0x35, 0xE4, 0x00, 0x00, 0x32, 0xA6, 0x00, 0x00, 0x30, 0x6E, 0x00, 0x00, 0x2F, 0x1E, + 0x00, 0x00, 0x2A, 0x3D, 0x00, 0x00, 0x2A, 0x7D, 0x00, 0x00, 0x27, 0x24, 0x00, 0x00, 0x27, 0xA4, + 0x00, 0x00, 0x23, 0xC2, 0x00, 0x00, 0x25, 0xC2, 0x00, 0x00, 0x20, 0xA0, 0x00, 0x00, 0x20, 0xD0, + 0x00, 0x00, 0x1C, 0x6E, 0x00, 0x00, 0x17, 0xBF, 0x00, 0x00, 0x19, 0x64, 0x00, 0x00, 0x16, 0x6B, + 0x00, 0x00, 0x12, 0x42, 0x00, 0x00, 0x13, 0x6F, 0x00, 0x00, 0x11, 0x9D, 0x00, 0x00, 0x0E, 0x80, + 0x00, 0x00, 0x0F, 0xEA, 0x00, 0x00, 0x09, 0xE2, 0x00, 0x00, 0x07, 0xB8, 0x00, 0x00, 0x07, 0x98, + 0x00, 0x00, 0x06, 0x73, 0x00, 0x00, 0x02, 0xD5, 0x00, 0x00, 0x01, 0x63, 0xFF, 0xFF, 0xFD, 0xF2, + 0x00, 0x00, 0x01, 0xED, 0xFF, 0xFF, 0xFF, 0xE5, 0xFF, 0xFF, 0xF7, 0x69, 0xFF, 0xFF, 0xFC, 0x16, + 0xFF, 0xFF, 0xF4, 0xCD, 0xFF, 0xFF, 0xF4, 0x06, 0xFF, 0xFF, 0xF3, 0xC2, 0xFF, 0xFF, 0xF0, 0x30, + 0xFF, 0xFF, 0xF1, 0x72, 0xFF, 0xFF, 0xEF, 0x53, 0xFF, 0xFF, 0xE8, 0x12, 0xFF, 0xFF, 0xE7, 0x2D, + 0xFF, 0xFF, 0xE5, 0xDC, 0xFF, 0xFF, 0xE6, 0x34, 0xFF, 0xFF, 0xE2, 0xAE, 0xFF, 0xFF, 0xE2, 0xF2, + 0xFF, 0xFF, 0xE0, 0x23, 0xFF, 0xFF, 0xDB, 0xDF, 0xFF, 0xFF, 0xDC, 0x2B, 0xFF, 0xFF, 0xD8, 0x95, + 0xFF, 0xFF, 0xD6, 0xE8, 0xFF, 0xFF, 0xD8, 0xDA, 0xFF, 0xFF, 0xD1, 0x2C, 0xFF, 0xFF, 0xCE, 0x93, + 0xFF, 0xFF, 0xD1, 0x70, 0xFF, 0xFF, 0xCB, 0xA6, 0xFF, 0xFF, 0xCC, 0x70, 0xFF, 0xFF, 0xCB, 0x45, + 0xFF, 0xFF, 0xC8, 0x65, 0xFF, 0xFF, 0xC5, 0xEC, 0xFF, 0xFF, 0xC4, 0xBF, 0xFF, 0xFF, 0xC5, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x5F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0x00, 0x00, 0x5F, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xEF, 0xA6, 0x00, 0x00, 0x0F, 0x80, 0xFF, 0xFF, 0xF0, 0x04, 0x00, 0x00, 0x0E, 0xA6, + 0xFF, 0xFF, 0xED, 0x75, 0x00, 0x00, 0x1E, 0x84, 0x00, 0x00, 0x04, 0xC7, 0x00, 0x00, 0x28, 0xD4, + 0x00, 0x00, 0x08, 0x39, 0x00, 0x00, 0x16, 0x30, 0x00, 0x00, 0x21, 0x11, 0x00, 0x00, 0x0B, 0x1E, + 0xFF, 0xFF, 0xF6, 0x1E, 0xFF, 0xFF, 0xFD, 0x1F, 0xFF, 0xFF, 0xE7, 0x51, 0xFF, 0xFF, 0xCB, 0x57, + 0x00, 0x00, 0x03, 0xD6, 0x00, 0x00, 0x0D, 0xE0, 0x00, 0x00, 0x06, 0x83, 0xFF, 0xFF, 0xF8, 0x23, + 0xFF, 0xFF, 0xF5, 0x53, 0x00, 0x00, 0x1D, 0x19, 0x00, 0x00, 0x0A, 0x04, 0x00, 0x00, 0x29, 0x17, + 0x00, 0x00, 0x15, 0x24, 0x00, 0x00, 0x25, 0xA4, 0xFF, 0xFF, 0xDC, 0xB4, 0xFF, 0xFF, 0xF9, 0x57, + 0x00, 0x00, 0x19, 0x77, 0x00, 0x00, 0x2E, 0xF3, 0xFF, 0xFF, 0xD4, 0x13, 0x00, 0x00, 0x02, 0x39, + 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x04, 0x22, 0xFF, 0xFF, 0xEF, 0xE8, 0xFF, 0xFF, 0xDB, 0x2B, + 0xFF, 0xFF, 0xFE, 0x4C, 0x00, 0x00, 0x09, 0x8E, 0x00, 0x00, 0x05, 0x90, 0xFF, 0xFF, 0xFB, 0x68, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x10, 0x6F, 0x00, 0x00, 0x17, 0xA1, 0xFF, 0xFF, 0xD8, 0x31, + 0x00, 0x00, 0x10, 0xFC, 0xFF, 0xFF, 0xF0, 0x66, 0x00, 0x00, 0x0E, 0x78, 0xFF, 0xFF, 0xF0, 0x5E, + 0x00, 0x00, 0x1F, 0x83, 0x00, 0x00, 0x19, 0x74, 0xFF, 0xFF, 0xEB, 0x6F, 0xFF, 0xFF, 0xF0, 0xDE, + 0x00, 0x00, 0x2B, 0x4D, 0x00, 0x00, 0x18, 0x67, 0xFF, 0xFF, 0xCE, 0x98, 0x00, 0x00, 0x0D, 0x20, + 0x00, 0x00, 0x0A, 0x13, 0xFF, 0xFF, 0xE8, 0xD3, 0xFF, 0xFF, 0xDF, 0x60, 0x00, 0x00, 0x08, 0xDF, + 0xFF, 0xFF, 0xE1, 0x68, 0x00, 0x00, 0x11, 0x14, 0xFF, 0xFF, 0xFE, 0x44, 0xFF, 0xFF, 0xD3, 0x92, + 0x00, 0x00, 0x14, 0xA4, 0xFF, 0xFF, 0xE8, 0x95, 0xFF, 0xFF, 0xF2, 0xD8, 0x00, 0x00, 0x30, 0x8A, + 0xFF, 0xFF, 0xF9, 0x85, 0xFF, 0xFF, 0xFB, 0x89, 0x00, 0x00, 0x19, 0x0E, 0x00, 0x00, 0x21, 0x02, + 0xFF, 0xFF, 0xF2, 0x6B, 0xFF, 0xFF, 0xEE, 0x43, 0xFF, 0xFF, 0xE9, 0xFE, 0x00, 0x00, 0x0D, 0x8A, + 0xFF, 0xFF, 0xFA, 0x2B, 0x00, 0x00, 0x09, 0xA5, 0x00, 0x00, 0x1F, 0x45, 0x00, 0x00, 0x1C, 0x1D, + 0xFF, 0xFF, 0xEA, 0x2A, 0xFF, 0xFF, 0xE8, 0xDB, 0x00, 0x00, 0x11, 0xE2, 0x00, 0x00, 0x0C, 0x5A, + 0x00, 0x00, 0x14, 0xC7, 0x00, 0x00, 0x08, 0x64, 0xFF, 0xFF, 0xD7, 0x61, 0xFF, 0xFF, 0xE8, 0x6E, + 0xFF, 0xFF, 0xF0, 0x47, 0xFF, 0xFF, 0xF7, 0x6F, 0x00, 0x00, 0x02, 0x0E, 0xFF, 0xFF, 0xFE, 0xC9, + 0xFF, 0xFF, 0xF0, 0x44, 0x00, 0x00, 0x06, 0x27, 0x00, 0x00, 0x03, 0x33, 0xFF, 0xFF, 0xFA, 0x47, + 0xFF, 0xFF, 0xF5, 0xFE, 0xFF, 0xFF, 0xDC, 0x9F, 0x00, 0x00, 0x1B, 0x8D, 0x00, 0x00, 0x20, 0x7F, + 0x00, 0x00, 0x0C, 0x79, 0xFF, 0xFF, 0xE7, 0x85, 0x00, 0x00, 0x0B, 0x90, 0xFF, 0xFF, 0xDF, 0xE8, + 0x00, 0x00, 0x06, 0x90, 0x00, 0x00, 0x0A, 0xC8, 0x00, 0x00, 0x1A, 0xAF, 0x00, 0x00, 0x1E, 0xF3, + 0x00, 0x00, 0x13, 0xFD, 0xFF, 0xFF, 0xE1, 0xCC, 0x00, 0x00, 0x19, 0xA2, 0xFF, 0xFF, 0xE5, 0xC4, + 0xFF, 0xFF, 0xE4, 0xF3, 0x00, 0x00, 0x49, 0xEC, 0xFF, 0xFF, 0xF9, 0x26, 0xFF, 0xFF, 0xF3, 0x7F, + 0x00, 0x00, 0x0A, 0xBC, 0xFF, 0xFF, 0xEC, 0xFD, 0x00, 0x00, 0x0E, 0xAA, 0xFF, 0xFF, 0xFC, 0x53, + 0xFF, 0xFF, 0xFB, 0xFD, 0xFF, 0xFF, 0xF0, 0x58, 0x00, 0x00, 0x02, 0x91, 0xFF, 0xFF, 0xE3, 0x83, + 0x00, 0x00, 0x18, 0x80, 0xFF, 0xFF, 0xF1, 0x35, 0xFF, 0xFF, 0xF3, 0x0C, 0xFF, 0xFF, 0xE6, 0xD6, + } ; diff --git a/src/include/zbmpop1.h b/src/include/zbmpop1.h new file mode 100644 index 0000000..ed8d3f4 --- /dev/null +++ b/src/include/zbmpop1.h @@ -0,0 +1,53 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=(idx<<2); + + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>19)); + c=(c>>(8-((cnt>>16)&0x07)))&0x01; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[(c<<1)+0]; + *current_line_buffer--=paletteRam[(c<<1)+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[(c<<1)+0]; + *current_line_buffer--=paletteRam[(c<<1)+1]; + } + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>19)); + c=(c>>(8-((cnt>>16)&0x07)))&0x01; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[(c<<1)+0]; + *current_line_buffer++=paletteRam[(c<<1)+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[(c<<1)+0]; + *current_line_buffer++=paletteRam[(c<<1)+1]; + } + cnt+=hscale_fixed; + scaled_width--; + } + } diff --git a/src/include/zbmpop16.h b/src/include/zbmpop16.h new file mode 100644 index 0000000..e310186 --- /dev/null +++ b/src/include/zbmpop16.h @@ -0,0 +1,130 @@ + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((cnt>>16)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,(c>>8)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,(c&0xff)); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr+((cnt>>16)<<1)+0)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr+((cnt>>16)<<1)+1)); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((cnt>>16)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,(c>>8)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,(c&0xff)); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr+((cnt>>16)<<1)+0)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr+((cnt>>16)<<1)+1)); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((cnt>>16)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + if (c) + { + *current_line_buffer--=(c>>8); + *current_line_buffer--=(c&0xff); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer--=jaguar_byte_read(ptr+((cnt>>16)<<1)+0); + *current_line_buffer--=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((cnt>>16)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + if (c) + { + *current_line_buffer++=(c>>8); + *current_line_buffer++=(c&0xff); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer++=jaguar_byte_read(ptr+((cnt>>16)<<1)+0); + *current_line_buffer++=jaguar_byte_read(ptr+((cnt>>16)<<1)+1); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop16p.h b/src/include/zbmpop16p.h new file mode 100644 index 0000000..3653293 --- /dev/null +++ b/src/include/zbmpop16p.h @@ -0,0 +1,130 @@ + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,(c>>8)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,(c&0xff)); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0)); + *current_line_buffer--=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1)); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,(c>>8)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,(c&0xff)); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0)); + *current_line_buffer++=BLEND_CC(*current_line_buffer,jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1)); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + if (c) + { + *current_line_buffer--=(c>>8); + *current_line_buffer--=(c&0xff); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer--=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0); + *current_line_buffer--=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint16 c=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0);; + c<<=8; + c|=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + if (c) + { + *current_line_buffer++=(c>>8); + *current_line_buffer++=(c&0xff); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + *current_line_buffer++=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+0); + *current_line_buffer++=jaguar_byte_read(ptr+((((cnt>>16) & (~0x3))*pitch)+((cnt>>16)&0x3)<<1)+1); + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop1p.h b/src/include/zbmpop1p.h new file mode 100644 index 0000000..94fc620 --- /dev/null +++ b/src/include/zbmpop1p.h @@ -0,0 +1,53 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=(idx<<2); + + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x3f))*pitch)+((cnt>>16)&0x3f)); + c=(c>>(8-((cnt>>16)&0x07)))&0x01; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[(c<<1)+0]; + *current_line_buffer--=paletteRam[(c<<1)+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[(c<<1)+0]; + *current_line_buffer--=paletteRam[(c<<1)+1]; + } + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x3f))*pitch)+((cnt>>16)&0x3f)); + c=(c>>(8-((cnt>>16)&0x07)))&0x01; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[(c<<1)+0]; + *current_line_buffer++=paletteRam[(c<<1)+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[(c<<1)+0]; + *current_line_buffer++=paletteRam[(c<<1)+1]; + } + cnt+=hscale_fixed; + scaled_width--; + } + } diff --git a/src/include/zbmpop2.h b/src/include/zbmpop2.h new file mode 100644 index 0000000..08231e0 --- /dev/null +++ b/src/include/zbmpop2.h @@ -0,0 +1,150 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=idx*2; + + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer--=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+1]; + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer++=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+1]; + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>18)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop24.h b/src/include/zbmpop24.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/zbmpop24p.h b/src/include/zbmpop24p.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/zbmpop2p.h b/src/include/zbmpop2p.h new file mode 100644 index 0000000..ec38994 --- /dev/null +++ b/src/include/zbmpop2p.h @@ -0,0 +1,150 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=idx*2; + + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x03)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x03)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer--=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+1]; + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x03)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + if (c) + { + *current_line_buffer++=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+1]; + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x1f))*pitch)+((cnt>>16)&0x1f)); + c>>=(6-(2*((cnt>>16)&0x03))); + c&=0x03; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x03)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop4.h b/src/include/zbmpop4.h new file mode 100644 index 0000000..e4c950f --- /dev/null +++ b/src/include/zbmpop4.h @@ -0,0 +1,149 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=idx*4; + + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+1]; + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+1]; + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>17)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop4p.h b/src/include/zbmpop4p.h new file mode 100644 index 0000000..4a6ab1e --- /dev/null +++ b/src/include/zbmpop4p.h @@ -0,0 +1,149 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=idx*4; + + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[((c&0x0f)<<1)+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[((c&0x0f)<<1)+1]); + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+1]; + } + else + current_line_buffer-=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer--=paletteRam[((c&0x0f)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_TRANSPARENT) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + if (c) + { + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+1]; + } + else + current_line_buffer+=2; + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x0f))*pitch)+((cnt>>16)&0x0f)); + if (!(cnt&(1<<16))) + c>>=4; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+0]; + *current_line_buffer++=paletteRam[((c&0x0f)<<1)+1]; + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + } diff --git a/src/include/zbmpop8.h b/src/include/zbmpop8.h new file mode 100644 index 0000000..29e3d52 --- /dev/null +++ b/src/include/zbmpop8.h @@ -0,0 +1,112 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=(idx&0x1)*256*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>16)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>16)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>16)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(cnt>>16)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + } diff --git a/src/include/zbmpop8p.h b/src/include/zbmpop8p.h new file mode 100644 index 0000000..a553faf --- /dev/null +++ b/src/include/zbmpop8p.h @@ -0,0 +1,112 @@ + uint8 *paletteRam=&tom_ram_8[0x400]; + paletteRam+=(idx&0x1)*256*2; + if (flags&FLAGS_READMODIFY) + { + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x07))*pitch)+((cnt>>16)&0x07)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer--=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x07))*pitch)+((cnt>>16)&0x07)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=BLEND_Y(*current_line_buffer,paletteRam[c+0]); + *current_line_buffer++=BLEND_CC(*current_line_buffer,paletteRam[c+1]); + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + } + else + { + if (flags&FLAGS_HFLIP) + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x07))*pitch)+((cnt>>16)&0x07)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + else + current_line_buffer-=2; + } + else + { + *current_line_buffer--=paletteRam[c+0]; + *current_line_buffer--=paletteRam[c+1]; + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + else + { + while (scaled_width) + { + uint32 c=jaguar_byte_read(ptr+(((cnt>>16) & (~0x07))*pitch)+((cnt>>16)&0x07)); + c<<=1; + if (flags&FLAGS_TRANSPARENT) + { + if (c) + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + else + current_line_buffer+=2; + } + else + { + *current_line_buffer++=paletteRam[c+0]; + *current_line_buffer++=paletteRam[c+1]; + } + + cnt+=hscale_fixed; + scaled_width--; + } + } + } diff --git a/src/jagdasm.cpp b/src/jagdasm.cpp new file mode 100644 index 0000000..0042b9d --- /dev/null +++ b/src/jagdasm.cpp @@ -0,0 +1,160 @@ +#include "include/jaguar.h" + +#define ROPCODE(a) jaguar_word_read(a) + +uint8 convert_zero[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 }; + +char *condition[32] = +{ + "", + "nz,", + "z,", + "???,", + "nc,", + "nc nz,", + "nc z,", + "???,", + "c,", + "c nz,", + "c z,", + "???,", + "???,", + "???,", + "???,", + "???,", + + "???,", + "???,", + "???,", + "???,", + "nn,", + "nn nz,", + "nn z,", + "???,", + "n,", + "n nz,", + "n z,", + "???,", + "???,", + "???,", + "???,", + "never," +}; + + + +char *signed_16bit(INT16 val) +{ + static char temp[10]; + if (val < 0) + sprintf(temp, "-$%x", -val); + else + sprintf(temp, "$%x", val); + return temp; +} + +unsigned dasmjag(int dsp_type, char *buffer, unsigned pc) +{ + int op = ROPCODE(pc); + int reg1 = (op >> 5) & 31; + int reg2 = op & 31; + int size = 2; + + pc += 2; + switch (op >> 10) + { + case 0: sprintf(buffer, "+add r%d,r%d", reg1, reg2); break; + case 1: sprintf(buffer, "+addc r%d,r%d", reg1, reg2); break; + case 2: sprintf(buffer, "+addq $%x,r%d", convert_zero[reg1], reg2); break; + case 3: sprintf(buffer, "addqt $%x,r%d", convert_zero[reg1], reg2); break; + case 4: sprintf(buffer, "+sub r%d,r%d", reg1, reg2); break; + case 5: sprintf(buffer, "+subc r%d,r%d", reg1, reg2); break; + case 6: sprintf(buffer, "+subq $%x,r%d", convert_zero[reg1], reg2); break; + case 7: sprintf(buffer, "subqt $%x,r%d", convert_zero[reg1], reg2); break; + case 8: sprintf(buffer, "+neg r%d", reg2); break; + case 9: sprintf(buffer, "+and r%d,r%d", reg1, reg2); break; + case 10: sprintf(buffer, "+or r%d,r%d", reg1, reg2); break; + case 11: sprintf(buffer, "+xor r%d,r%d", reg1, reg2); break; + case 12: sprintf(buffer, "+not r%d", reg2); break; + case 13: sprintf(buffer, "+btst $%x,r%d", reg1, reg2); break; + case 14: sprintf(buffer, "+bset $%x,r%d", reg1, reg2); break; + case 15: sprintf(buffer, "+bclr $%x,r%d", reg1, reg2); break; + case 16: sprintf(buffer, "mult r%d,r%d", reg1, reg2); break; + case 17: sprintf(buffer, "imult r%d,r%d", reg1, reg2); break; + case 18: sprintf(buffer, "imultn r%d,r%d", reg1, reg2); break; + case 19: sprintf(buffer, "resmac r%d", reg2); break; + case 20: sprintf(buffer, "imacn r%d,r%d", reg1, reg2); break; + case 21: sprintf(buffer, "div r%d,r%d", reg1, reg2); break; + case 22: sprintf(buffer, "abs r%d", reg2); break; + case 23: sprintf(buffer, "sh r%d,r%d", reg1, reg2); break; + case 24: sprintf(buffer, "+shlq $%x,r%d", 32 - convert_zero[reg1], reg2); break; + case 25: sprintf(buffer, "+shrq $%x,r%d", convert_zero[reg1], reg2); break; + case 26: sprintf(buffer, "sha r%d,r%d", reg1, reg2); break; + case 27: sprintf(buffer, "sharq $%x,r%d", convert_zero[reg1], reg2); break; + case 28: sprintf(buffer, "+ror r%d,r%d", reg1, reg2); break; + case 29: sprintf(buffer, "rorq $%x,r%d", convert_zero[reg1], reg2); break; + case 30: sprintf(buffer, "+cmp r%d,r%d", reg1, reg2); break; + case 31: sprintf(buffer, "+cmpq %s,r%d", signed_16bit((INT16)(reg1 << 11) >> 11), reg2);break; + case 32: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, "sat8 r%d", reg2); + else + sprintf(buffer, "subqmod $%x,r%d", convert_zero[reg1], reg2); + break; + case 33: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, "sat16 r%d", reg2); + else + sprintf(buffer, "sat16s r%d", reg2); + break; + case 34: sprintf(buffer, "move r%d,r%d", reg1, reg2); break; + case 35: sprintf(buffer, "moveq %d,r%d", reg1, reg2); break; + case 36: sprintf(buffer, "moveta r%d,r%d", reg1, reg2); break; + case 37: sprintf(buffer, "movefa r%d,r%d", reg1, reg2); break; + case 38: sprintf(buffer, "movei $%x,r%d", ROPCODE(pc) | (ROPCODE(pc+2)<<16), reg2); size = 6; break; + case 39: sprintf(buffer, "loadb (r%d),r%d", reg1, reg2); break; + case 40: sprintf(buffer, "loadw (r%d),r%d", reg1, reg2); break; + case 41: sprintf(buffer, "load (r%d),r%d", reg1, reg2); break; + case 42: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, "loadp (r%d),r%d", reg1, reg2); + else + sprintf(buffer, "sat32s r%d", reg2); + break; + case 43: sprintf(buffer, "load (r14+$%x),r%d", convert_zero[reg1]*4, reg2);break; + case 44: sprintf(buffer, "load (r15+$%x),r%d", convert_zero[reg1]*4, reg2);break; + case 45: sprintf(buffer, "storeb r%d,(r%d)", reg2, reg1); break; + case 46: sprintf(buffer, "storew r%d,(r%d)", reg2, reg1); break; + case 47: sprintf(buffer, "store r%d,(r%d)", reg2, reg1); break; + case 48: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, "storep r%d,(r%d)", reg2, reg1); + else + sprintf(buffer, "mirror r%d", reg2); + break; + case 49: sprintf(buffer, "store r%d,(r14+$%x)", reg2, convert_zero[reg1]*4);break; + case 50: sprintf(buffer, "store r%d,(r15+$%x)", reg2, convert_zero[reg1]*4);break; + case 51: sprintf(buffer, "move pc,r%d", reg2); break; + case 52: sprintf(buffer, "jump %s(r%d)", condition[reg2], reg1); break; + case 53: sprintf(buffer, "jr %s%08X", condition[reg2], pc + ((INT8)(reg1 << 3) >> 2)); break; + case 54: sprintf(buffer, "mmult r%d,r%d", reg1, reg2); break; + case 55: sprintf(buffer, "mtoi r%d,r%d", reg1, reg2); break; + case 56: sprintf(buffer, "normi r%d,r%d", reg1, reg2); break; + case 57: sprintf(buffer, "nop"); break; + case 58: sprintf(buffer, "load (r14+r%d),r%d", reg1, reg2); break; + case 59: sprintf(buffer, "load (r15+r%d),r%d", reg1, reg2); break; + case 60: sprintf(buffer, "store r%d,(r14+r%d)", reg2, reg1); break; + case 61: sprintf(buffer, "store r%d,(r15+r%d)", reg2, reg1); break; + case 62: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, "sat24 r%d", reg2); + else + sprintf(buffer, "illegal"); + break; + case 63: if (dsp_type == JAGUAR_GPU) + sprintf(buffer, reg1 ? + "unpack r%d" : + "pack r%d", reg2); + else + sprintf(buffer, "addqmod $%x,r%d", convert_zero[reg1], reg2); + break; + } + sprintf(buffer,"%s (0x%.4x)",buffer,op); + return size; +} diff --git a/src/jaguar.cpp b/src/jaguar.cpp new file mode 100644 index 0000000..88a9f17 --- /dev/null +++ b/src/jaguar.cpp @@ -0,0 +1,1022 @@ +// +// JAGUAR.CPP +// +// by cal16 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Cleanups and endian wrongness amelioration by James L. Hammons +// Note: Endian wrongness probably stems from the MAME origins of this emu and +// the braindead way in which MAME handles memory. :-) +// + +#include "jaguar.h" +#include "m68kdasmAG.h" +#include "crc32.h" + +//#define LOG_UNMAPPED_MEMORY_ACCESSES +//#define SOUND_OUTPUT + +// Some handy macros to help converting native endian to big endian (jaguar native) + +#define SET32(r, a, v) r[a] = ((v) & 0xFF000000) >> 24, r[a+1] = ((v) & 0x00FF0000) >> 16, \ + r[a+2] = ((v) & 0x0000FF00) >> 8, r[a+3] = (v) & 0x000000FF + +// +// Function Prototypes +// + +unsigned jaguar_unknown_readbyte(unsigned address); +unsigned jaguar_unknown_readword(unsigned address); +void jaguar_unknown_writebyte(unsigned address, unsigned data); +void jaguar_unknown_writeword(unsigned address, unsigned data); + + +#ifdef SOUND_OUTPUT +int dsp_enabled = 1; +#else +int dsp_enabled = 0; +#endif +uint32 jaguar_active_memory_dumps = 0; +uint32 jaguar_use_bios = 0; +#define JAGUAR_WIP_RELEASE +#define JAGUAR_REAL_SPEED + +// +// Bios path +// + +//static char *jaguar_bootRom_path="c:/jaguarEmu/newload.img"; +static char * jaguar_bootRom_path = "./bios/jagboot.rom"; +//static char *jaguar_bootRom_path="./bios/JagOS.bin"; +char * jaguar_eeproms_path = "./eeproms/"; + +uint32 jaguar_mainRom_crc32; + +static uint32 m68k_cycles_per_scanline; +static uint32 gpu_cycles_per_scanline; +static uint32 dsp_cycles_per_scanline; +static uint32 jaguar_screen_scanlines; + +static uint8 * jaguar_mainRam = NULL; +static uint8 * jaguar_bootRom = NULL; +static uint8 * jaguar_mainRom = NULL; + + +// +// Musashi 68000 read/write/IRQ functions +// + +int irq_ack_handler(int level) +{ + int vector = M68K_INT_ACK_AUTOVECTOR; + + if (level = 7) + { + m68k_set_irq(0); // Clear the IRQ... + vector = 64; // Set user interrupt #0 + } + + return vector; +} + +//Do this in makefile??? Yes! +//#define LOG_UNMAPPED_MEMORY_ACCESSES 1 + +unsigned int m68k_read_memory_8(unsigned int address) +{ +//fprintf(log_get(), "[RM8] Addr: %08X\n", address); + unsigned int retVal = 0; + + if ((address >= 0x000000) && (address <= 0x3FFFFF)) + retVal = jaguar_mainRam[address]; + else if ((address >= 0x800000) && (address <= 0xDFFFFF)) + retVal = jaguar_mainRom[address - 0x800000]; + else if ((address >= 0xE00000) && (address <= 0xE3FFFF)) + retVal = jaguar_bootRom[address - 0xE00000]; + else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF)) + retVal = cdrom_byte_read(address); + else if ((address >= 0xF00000) && (address <= 0xF0FFFF)) + retVal = tom_byte_read(address); + else if ((address >= 0xF10000) && (address <= 0xF1FFFF)) + retVal = jerry_byte_read(address); + else + retVal = jaguar_unknown_readbyte(address); + + return retVal; +} + +unsigned int m68k_read_memory_16(unsigned int address) +{ +//fprintf(log_get(), "[RM16] Addr: %08X\n", address); + unsigned int retVal = 0; + + if ((address >= 0x000000) && (address <= 0x3FFFFE)) + retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1]; + else if ((address >= 0x800000) && (address <= 0xDFFFFE)) + retVal = (jaguar_mainRom[address - 0x800000] << 8) | jaguar_mainRom[address - 0x800000 + 1]; + else if ((address >= 0xE00000) && (address <= 0xE3FFFE)) + retVal = (jaguar_bootRom[address - 0xE00000] << 8) | jaguar_bootRom[address - 0xE00000 + 1]; + else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) + retVal = cdrom_word_read(address); + else if ((address >= 0xF00000) && (address <= 0xF0FFFE)) + retVal = tom_word_read(address); + else if ((address >= 0xF10000) && (address <= 0xF1FFFE)) + retVal = jerry_word_read(address); + else +//{ +//fprintf(log_get(), "[RM16] Unknown address: %08X\n", address); + retVal = jaguar_unknown_readword(address); +//} + + return retVal; +} + +unsigned int m68k_read_memory_32(unsigned int address) +{ +//fprintf(log_get(), "--> [RM32]\n"); + return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2); +} + +void m68k_write_memory_8(unsigned int address, unsigned int value) +{ +//fprintf(log_get(), "[WM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value); + if ((address >= 0x000000) && (address <= 0x3FFFFF)) + jaguar_mainRam[address] = value; + else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF)) + cdrom_byte_write(address, value); + else if ((address >= 0xF00000) && (address <= 0xF0FFFF)) + tom_byte_write(address, value); + else if ((address >= 0xF10000) && (address <= 0xF1FFFF)) + jerry_byte_write(address, value); + else + jaguar_unknown_writebyte(address, value); +} + +void m68k_write_memory_16(unsigned int address, unsigned int value) +{ +//fprintf(log_get(), "[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value); + if ((address >= 0x000000) && (address <= 0x3FFFFE)) + { + jaguar_mainRam[address] = value >> 8; + jaguar_mainRam[address + 1] = value & 0xFF; + } + else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) + cdrom_word_write(address, value); + else if ((address >= 0xF00000) && (address <= 0xF0FFFE)) + tom_word_write(address, value); + else if ((address >= 0xF10000) && (address <= 0xF1FFFE)) + jerry_word_write(address, value); + else + jaguar_unknown_writeword(address, value); +} + +void m68k_write_memory_32(unsigned int address, unsigned int value) +{ +//fprintf(log_get(), "--> [WM32]\n"); + m68k_write_memory_16(address, value >> 16); + m68k_write_memory_16(address + 2, value & 0xFFFF); +} + + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint32 jaguar_get_handler(uint32 i) +{ +// return (jaguar_word_read(i<<2) << 16) | jaguar_word_read((i<<2) + 2); +// return (jaguar_word_read(i*4) << 16) | jaguar_word_read((i*4) + 2); + return jaguar_long_read(i * 4); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +static char romLoadDialog_filePath[1024]; +#ifndef __PORT__ +static char romLoadDialog_initialDirectory[1024]; + +int jaguar_open_rom(HWND hWnd, char * title, char * filterString) +{ + OPENFILENAME ofn; + romLoadDialog_initialDirectory[0] = 0; + romLoadDialog_filePath[0] = 0; + + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.lpstrFile = romLoadDialog_filePath; + ofn.nMaxFile = sizeof(romLoadDialog_filePath); + ofn.lpstrFilter = filterString; + ofn.nFilterIndex = 0; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = (const char *)romLoadDialog_initialDirectory; + ofn.lpstrTitle = title; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if(GetOpenFileName(&ofn) == FALSE) + { + DWORD res = CommDlgExtendedError(); + SendMessage(hWnd, WM_MOVE, 0,0); + return 0; + } + + + SendMessage(hWnd, WM_MOVE, 0,0); + return 1; +} +#endif +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint32 jaguar_interrupt_handler_is_valid(uint32 i) +{ + uint32 handler = jaguar_get_handler(i); + if (handler && (handler != 0xFFFFFFFF)) + return 1; + else + return 0; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void s68000show_context(void) +{ +// fprintf(log_get(),"\t68k PC=0x%.6x\n",s68000readPC()); + fprintf(log_get(),"\t68k PC=0x%.6x\n", m68k_get_reg(NULL, M68K_REG_PC)); +// for (int i=0;i<8;i++) +// fprintf(log_get(),"\tD%i = 0x%.8x\n",i,s68000context.dreg[i]); + for(int i=M68K_REG_D0; i<=M68K_REG_D7; i++) + fprintf(log_get(), "\tD%i = 0x%.8x\n", i-M68K_REG_D0, m68k_get_reg(NULL, (m68k_register_t)i)); + fprintf(log_get(), "\n"); +// for (i=0;i<8;i++) +// fprintf(log_get(),"\tA%i = 0x%.8x\n",i,s68000context.areg[i]); + for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++) + fprintf(log_get(), "\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i)); + + fprintf(log_get(), "68k dasm\n"); +// jaguar_dasm(s68000readPC()-0x1000,0x20000); +// jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x1000, 0x20000); + jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x80, 0x200); + fprintf(log_get(), "..................\n"); + + + if (tom_irq_enabled(IRQ_VBLANK)) + { + fprintf(log_get(), "vblank int: enabled\n"); + jaguar_dasm(jaguar_get_handler(64), 0x200); + } + else + fprintf(log_get(), "vblank int: disabled\n"); + fprintf(log_get(), "..................\n"); + + for(int i=0; i<256; i++) + fprintf(log_get(), "handler %03i at $%08X\n", i, jaguar_get_handler(i)); +} + +// Starscream crap ripped out... + +// +// Unknown read/write byte/word routines +// + +void jaguar_unknown_writebyte(unsigned address, unsigned data) +{ +#ifdef LOG_UNMAPPED_MEMORY_ACCESSES + fprintf(log_get(), "jaguar: unknown byte %02X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC)); +#endif +} + +void jaguar_unknown_writeword(unsigned address, unsigned data) +{ +#ifdef LOG_UNMAPPED_MEMORY_ACCESSES + fprintf(log_get(), "jaguar: unknown word %04X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC)); +#endif +} + +unsigned jaguar_unknown_readbyte(unsigned address) +{ +#ifdef LOG_UNMAPPED_MEMORY_ACCESSES + fprintf(log_get(), "jaguar: unknown byte read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC)); +#endif + return 0xFF; +} + +unsigned jaguar_unknown_readword(unsigned address) +{ +#ifdef LOG_UNMAPPED_MEMORY_ACCESSES + fprintf(log_get(), "jaguar: unknown word read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC)); +#endif + return 0xFFFF; +} + +// +// Jaguar ROM loading +// + +uint8 * jaguar_rom_load(char * path, uint32 * romSize) +{ + __int64 filepos; + + fprintf(log_get(), "jaguar: loading %s...", path); + FILE * fp = fopen(path, "rb"); + if (fp == NULL) + { + fprintf(log_get(), "failed\n"); + log_done(); + exit(0); + return NULL; + } + fseek(fp, 0, SEEK_END); + + /* Added by SDLEMU (http://sdlemu.ngemu.com) */ + /* Added for GCC UNIX compatibility */ +#ifdef __GCCUNIX__ + fgetpos(fp, (fpos_t *)&filepos); +#else + fgetpos(fp, &filepos); +#endif + + *romSize = (int)filepos; + fseek(fp, 0, SEEK_SET); + uint8 * rom = (uint8 *)malloc(*romSize); + fread(rom, 1, *romSize, fp); + fclose(fp); + fprintf(log_get(), "ok (%i bytes)\n", *romSize); +// jaguar_mainRom_crc32=crc32_calcCheckSum(jaguar_mainRom,*romSize); +// fprintf(log_get(),"crc: 0x%.8x\n",jaguar_mainRom_crc32); + return rom; +} + +// +// Load a ROM at a specific address +// + +void jaguar_rom_load_to(uint8 * rom, char * path, uint32 * romSize) +{ + __int64 filepos; + + fprintf(log_get(), "jaguar: loading %s...", path); + FILE * fp = fopen(path, "rb"); + if (fp == NULL) + { + fprintf(log_get(), "failed\n"); + log_done(); + exit(0); + return; + } + fseek(fp, 0, SEEK_END); + + /* Added by SDLEMU (http://sdlemu.ngemu.com) */ + /* Added for GCC UNIX compatibility */ +#ifdef __GCCUNIX__ + fgetpos(fp, (fpos_t *)&filepos); +#else + fgetpos(fp, &filepos); +#endif + + *romSize = (int)filepos; + fseek(fp, 0, SEEK_SET); + fread(rom, 1, *romSize, fp); + fclose(fp); + fprintf(log_get(), "ok (%i bytes)\n", *romSize); +} + +// +// Byte swap a region of memory +// + +/*void jaguar_byte_swap(uint8 * rom, uint32 size) +{ + while (size > 0) + { + uint8 tmp = rom[0]; + rom[0] = rom[1]; + rom[1] = tmp; + rom += 2; + size -= 2; + } +}*/ + +// +// Disassemble instructions at the given offset +// + +void jaguar_dasm(uint32 offset, uint32 qt) +{ +#ifdef CPU_DEBUG + static char buffer[2048], mem[64]; + int pc = offset, oldpc; + + for(int i=0; i>16) | (boot<<16), 32*4); + jaguar_dasm(boot, 32*4); +} + +// +// Jaguar initialization +// + +#ifdef __PORT__ +void jaguar_init(const char * filename) +#else +void jaguar_init(void) +#endif +{ + uint32 romsize; + + jaguar_screen_scanlines = 525; // PAL screen size + m68k_cycles_per_scanline = 13300000 / (jaguar_screen_scanlines * 60); + gpu_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60); + dsp_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60); + + memory_malloc_secure((void **)&jaguar_mainRam, 0x400000, "Jaguar 68k cpu ram"); + memory_malloc_secure((void **)&jaguar_bootRom, 0x040000, "Jaguar 68k cpu boot rom"); + memory_malloc_secure((void **)&jaguar_mainRom, 0x600000, "Jaguar 68k cpu rom"); + memset(jaguar_mainRam, 0x00, 0x400000); + + jaguar_rom_load_to(jaguar_bootRom, jaguar_bootRom_path, &romsize); +// No need to do this anymore, since Starcrap is gone! +// jaguar_byte_swap(jaguar_bootRom, romsize); + memcpy(jaguar_mainRam, jaguar_bootRom, 8); +// More braindead endian dependent crap +//WAS: *((uint32 *)&jaguar_mainRam[0]) = 0x00000020; + SET32(jaguar_mainRam, 0, 0x00200000); + +#ifdef JAGUAR_WIP_RELEASE +#ifdef __PORT__ + strcpy(romLoadDialog_filePath, filename); +#else + jaguar_open_rom(GetForegroundWindow(), "Load", "Jaguar roms (*.JAG)\0*.JAG\0\0"); +#endif +//WAS: jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x20000080, 0); + jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0); + +//JLH: +/* if (jaguar_mainRom_crc32 == 0xA9F8A00E) + { + dsp_enabled = 1; + fprintf(log_get(), "--> Rayman detected, DSP enabled...\n"); + }//*/ + + + if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756) + || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8) + || (jaguar_mainRom_crc32 == 0x2630cbc4)) + dsp_enabled = 1; + + if ((jaguar_mainRom_crc32 == 0x6e90989f) || (jaguar_mainRom_crc32 == 0xfc8f0dcd) + || (jaguar_mainRom_crc32 == 0x2a512a83) || (jaguar_mainRom_crc32 == 0x41307601) + || (jaguar_mainRom_crc32 == 0x3c7bfda8) || (jaguar_mainRom_crc32 == 0x5e705756)) + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + + if (jaguar_mainRom_crc32 == 0x7ae20823) + { + dsp_enabled = 1; + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + } + if (jaguar_mainRom_crc32 == 0xe21d0e2f) + { + dsp_enabled = 1; + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + } + if (jaguar_mainRom_crc32 == 0x66f8914c) + { + gpu_cycles_per_scanline = (26591000 / 1) /(jaguar_screen_scanlines * 60); + } + if (jaguar_mainRom_crc32 == 0x5a5b9c68) + { + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + } + if (jaguar_mainRom_crc32 == 0xdcb0197a) + { + dsp_enabled = 0; // dsp not needed + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } + if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0xe21d0e2f)) + dsp_enabled = 1; + if (jaguar_mainRom_crc32 == 0x5e705756) + { + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_enabled = 1; + } + if (jaguar_mainRom_crc32 == 0x2630cbc4) + { + // ultra vortek + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_enabled = 1; + } + if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed)) + { + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_enabled = 1; + } + if (jaguar_mainRom_crc32 == 0x6e90989f) + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + + if (jaguar_mainRom_crc32 == 0x41307601) + { + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + } + + if (jaguar_mainRom_crc32 == 0x8483392b) + { + dsp_enabled = 1; + } + +#else // #ifdef JAGUAR_WIP_RELEASE +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/flashback.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pinball Fantasies.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/alien vs predator (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/cannon fodder (1995) (computer west).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/double dragon v (1995) (williams).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dragon - The Bruce Lee Story.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Syndicate.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Theme Park.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Brutal Sports Football.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/International Sensible Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Defender 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fever Pitch Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Rayman.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Tempest 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/zool 2 (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Bubsy - Fractured Furry Tails.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Raiden.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dino Olympics.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/I-War.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Attack of the Mutant Penguins.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Cybermorph.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Troy Aikman NFL Football (1995) (Williams).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Power Drive Rally (1995) (TWI).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Zoop! (1996).jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Missile Command 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Hover Strike.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/worms.bin",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Atari Kart.JAG",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/native.bin",jaguar_mainRam,0x5000, 0x50000000,0x00); + + if (jaguar_mainRom_crc32==0xe21d0e2f) + { + dsp_enabled=1; + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } + if (jaguar_mainRom_crc32==0x66f8914c) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } + if (jaguar_mainRom_crc32==0x5a5b9c68) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Cross 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0xdcb0197a) + { + dsp_enabled=0; // dsp not needed + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/wolfenstein 3d (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0); + if ((jaguar_mainRom_crc32==0x3966698f)||(jaguar_mainRom_crc32==0xe21d0e2f)) + dsp_enabled=1; +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/NBA JAM.jag",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Doom - Evil Unleashed.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x5e705756) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_enabled=1; + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x2630cbc4) + { + // ultra vortek + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_enabled=1; + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/fflbeta.rom",jaguar_mainRom,0x0000, 0x20000080,0); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fight for Your Life.jag",jaguar_mainRom,0x0000, 0x20000080,0); + if ((jaguar_mainRom_crc32==0xd46437e8)||(jaguar_mainRom_crc32==0xba74c3ed)) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); +// dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_enabled=1; + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pitfall - The Mayan Adventure.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x6e90989f) + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + +// missing some sprites +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Crescent Galaxy.jag",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x41307601) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } + +// missing vertical bar shades +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Phase Zero (2000) (PD).rom",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x8483392b) + { + dsp_enabled=1; + } +// cpu/dsp/gpu synchronization problems + + +// locks up during the game +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Club Drive.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + +// no parallax floor, locks up at the start of the game +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Kasumi Ninja.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + +// displaying the sound control dialog. no way to exit from it +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Checkered Flag.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + +// no 3d +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Iron Soldier.jag",jaguar_mainRom,0x0000, 0x20000080,0); + +// locks up at the start of the game +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Burnout.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x20ae75f4) + { + dsp_enabled=1; + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } +// locks up at the start of the game +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Val D'Isere Skiing & Snowboarding (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x4664ebd1) + { + dsp_enabled=1; + } + +// fonctionne avec le gpu et le dsp activés et gpu à frequence nominale, et dsp à 1/4 de la frequence nominale +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/white men can't jump (1995).jag",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x7ae20823) + { + dsp_enabled=1; + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } +// not working at all +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/Flip Out.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x6f57dcd2) + { + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + dsp_enabled=0; + + } + + jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0); + if (jaguar_mainRom_crc32==0x6a7c7430) + { + dsp_enabled=1; + } + + if (jaguar_mainRom_crc32==0x2f032271) + { + dsp_enabled=1; + dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); + } +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/tetris.bin",jaguar_mainRam,0x4fe4, 0x50000000,0x00); +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/painter.bin",jaguar_mainRam,0xffe4, 0x00000001,0x00); +// jaguar_load_cart("./roms/jagcd.rom",jaguar_mainRom,0x0000, 0x20000080,0); + +// jaguar_load_cart("cart.jag",jaguar_mainRom,0x0000, 0x20000080,0); + + +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\Brain Dead 13.cdi"); +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\baldies.cdi"); +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\mystdemo.cdi"); +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\battlemorph.cdi"); +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\primalrage.cdi"); +// cd_bios_boot("C:\\ftp\\jaguar\\cd\\Dragons Lair.cdi"); + +// jaguar_load_cart("C:/ftp/jaguar/roms/roms/raw.jag",jaguar_mainRam,0x4000, 0x40000000,0x00); +#endif // #ifdef JAGUAR_WIP_RELEASE + +#ifdef JAGUAR_REAL_SPEED + gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); + dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); +#endif +#ifdef SOUND_OUTPUT + ws_audio_init(); +#endif + if (jaguar_use_bios) + { + memcpy(jaguar_mainRam, jaguar_bootRom, 8); +// *((uint32 *)&jaguar_mainRam[0]) = 0x00000020; +// SET32(jaguar_mainRam, 0, 0x00200000); + } + +// s68000init(); + m68k_set_cpu_type(M68K_CPU_TYPE_68000); + gpu_init(); + dsp_init(); + tom_init(); + jerry_init(); + cdrom_init(); +} + +unsigned jaguar_byte_read(unsigned int offset) +{ + uint8 data = 0x00; + + offset &= 0xFFFFFF; + if (offset < 0x400000) +// data = (jaguar_mainRam[(offset^0x01) & 0x3FFFFF]); + data = jaguar_mainRam[offset & 0x3FFFFF]; + else if ((offset >= 0x800000) && (offset < 0xC00000)) +// data = (jaguar_mainRom[(offset^0x01)-0x800000]); + data = jaguar_mainRom[offset - 0x800000]; +// else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00)) + else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) + data = cdrom_byte_read(offset); + else if ((offset >= 0xE00000) && (offset < 0xE40000)) +// data = (jaguar_bootRom[(offset^0x01) & 0x3FFFF]); + data = jaguar_bootRom[offset & 0x3FFFF]; + else if ((offset >= 0xF00000) && (offset < 0xF10000)) + data = tom_byte_read(offset); + else if ((offset >= 0xF10000) && (offset < 0xF20000)) + data = jerry_byte_read(offset); + else + data = jaguar_unknown_readbyte(offset); + + return data; +} + +unsigned jaguar_word_read(unsigned int offset) +{ + offset &= 0xFFFFFF; + if (offset <= 0x3FFFFE) + { +// return (jaguar_mainRam[(offset+1) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+0) & 0x3FFFFF]; + return (jaguar_mainRam[(offset+0) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+1) & 0x3FFFFF]; + } + else if ((offset >= 0x800000) && (offset <= 0xBFFFFE)) + { + offset -= 0x800000; +// return (jaguar_mainRom[offset+1] << 8) | jaguar_mainRom[offset+0]; + return (jaguar_mainRom[offset+0] << 8) | jaguar_mainRom[offset+1]; + } +// else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00)) + else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE)) + return cdrom_word_read(offset); + else if ((offset >= 0xE00000) && (offset <= 0xE3FFFE)) +// return *((uint16 *)&jaguar_bootRom[offset & 0x3FFFF]); + return (jaguar_bootRom[(offset+0) & 0x3FFFF] << 8) | jaguar_bootRom[(offset+1) & 0x3FFFF]; + else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE)) + return tom_word_read(offset); + else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE)) + return jerry_word_read(offset); + + return jaguar_unknown_readword(offset); +} + +void jaguar_byte_write(unsigned offset, unsigned data) +{ + offset &= 0xFFFFFF; + if (offset < 0x400000) + { +// jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data; + jaguar_mainRam[offset & 0x3FFFFF] = data; + return; + } +// else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00)) + else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) + { + cdrom_byte_write(offset, data); + return; + } + else if ((offset >= 0xF00000) && (offset <= 0xF0FFFF)) + { + tom_byte_write(offset, data); + return; + } + else if ((offset >= 0xF10000) && (offset <= 0xF1FFFF)) + { + jerry_byte_write(offset, data); + return; + } + + jaguar_unknown_writebyte(offset, data); +} + +void jaguar_word_write(unsigned offset, unsigned data) +{ + offset &= 0xFFFFFF; + + if (offset <= 0x3FFFFE) + { +// jaguar_mainRam[(offset+0) & 0x3FFFFF] = data & 0xFF; +// jaguar_mainRam[(offset+1) & 0x3FFFFF] = (data>>8) & 0xFF; + jaguar_mainRam[(offset+0) & 0x3FFFFF] = (data>>8) & 0xFF; + jaguar_mainRam[(offset+1) & 0x3FFFFF] = data & 0xFF; + return; + } + else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE)) + { + cdrom_word_write(offset, data); + return; + } + else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE)) + { + tom_word_write(offset, data); + return; + } + else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE)) + { + jerry_word_write(offset, data); + return; + } + + jaguar_unknown_writeword(offset, data); +} + +unsigned jaguar_long_read(unsigned int offset) +{ +/* uint32 data = jaguar_word_read(offset); + data = (data<<16) | jaguar_word_read(offset+2); + return data;*/ + return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2); +} + +void jaguar_long_write(unsigned offset, unsigned data) +{ + jaguar_word_write(offset, data >> 16); + jaguar_word_write(offset+2, data & 0xFFFF); +} + +void jaguar_done(void) +{ + fprintf(log_get(), "jaguar_done() ...START\n"); +#ifdef CPU_DEBUG + fprintf(log_get(), "jaguar: top of stack: %08X\n", jaguar_long_read(0x001FFFF8)); +// fprintf(log_get(),"jaguar: cd bios version 0x%.4x\n",jaguar_word_read(0x3004)); +// fprintf(log_get(),"jaguar: vbl interrupt is %s\n",((tom_irq_enabled(IRQ_VBLANK))&&(jaguar_interrupt_handler_is_valid(64)))?"enabled":"disabled"); + s68000show_context(); +#endif +#ifdef SOUND_OUTPUT + ws_audio_done(); +#endif + cd_bios_done(); + cdrom_done(); + tom_done(); + jerry_done(); +// jaguar_regionsDone(); + memory_free(jaguar_mainRom); + memory_free(jaguar_bootRom); + memory_free(jaguar_mainRam); + fprintf(log_get(), "jaguar_done() ...END\n"); +} + +void jaguar_reset(void) +{ +// fprintf(log_get(),"jaguar_reset():\n"); +#ifdef SOUND_OUTPUT + ws_audio_reset(); +#endif + cd_bios_reset(); + tom_reset(); + jerry_reset(); + gpu_reset(); + dsp_reset(); + cdrom_reset(); +// s68000reset(); + m68k_pulse_reset(); // Reset the 68000 + fprintf(log_get(), "\t68K PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7)); +} + +void jaguar_reset_handler(void) +{ +} + +void jaguar_exec(int16 * backbuffer, uint8 render) +{ + uint32 i, vblank_duration = tom_get_vdb(); + + // vblank + if ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) + { + if (jaguar_word_read(0xF0004E) != 0xFFFF) + { + tom_set_pending_video_int(); +// s68000interrupt(7, IRQ_VBLANK+64); +// s68000flushInterrupts(); + m68k_set_irq(7); // IRQ_VBLANK+64??? Not autovectored??? No. +// Could set a global variable here, to signal that this is a VBLANK interrupt... +// Then again, since IRQ_VBLANK is set to zero, this would not be necessary in this case. + } + } + + for(i=0; i + +//#define JERRY_DEBUG + +static uint8 * jerry_ram_8; +//static uint16 *jerry_ram_16; +static uint8 * jerry_wave_rom; + + +//#define JERRY_CONFIG jerry_ram_16[0x4002>>1] +#define JERRY_CONFIG 0x4002 + +uint8 analog_x, analog_y; + +static uint32 jerry_timer_1_prescaler; +static uint32 jerry_timer_2_prescaler; +static uint32 jerry_timer_1_divider; +static uint32 jerry_timer_2_divider; +static int32 jerry_timer_1_counter; +static int32 jerry_timer_2_counter; + +static uint32 jerry_i2s_interrupt_divide = 8; +static int32 jerry_i2s_interrupt_timer = -1; +static int32 jerry_i2s_interrupt_cycles_per_scanline = 0; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_i2s_exec(uint32 cycles) +{ + jerry_i2s_interrupt_divide &= 0xFF; + + if (jerry_i2s_interrupt_timer == -1) + { + uint32 jerry_i2s_int_freq = (26591000 / 64) / (jerry_i2s_interrupt_divide + 1); + jerry_i2s_interrupt_cycles_per_scanline = 13300000 / jerry_i2s_int_freq; + jerry_i2s_interrupt_timer = jerry_i2s_interrupt_cycles_per_scanline; + //fprintf(log_get(),"jerry: i2s interrupt rate set to %i hz (every %i cpu clock cycles) jerry_i2s_interrupt_divide=%i\n",jerry_i2s_int_freq,jerry_i2s_interrupt_cycles_per_scanline,jerry_i2s_interrupt_divide); + pcm_set_sample_rate(jerry_i2s_int_freq); + } + jerry_i2s_interrupt_timer -= cycles; + // note : commented since the sound doesn't work properly else + if (1)//jerry_i2s_interrupt_timer<=0) + { + // i2s interrupt + dsp_check_if_i2s_interrupt_needed(); + //fprintf(log_get(),"jerry_i2s_interrupt_timer=%i, generating an i2s interrupt\n",jerry_i2s_interrupt_timer); + jerry_i2s_interrupt_timer += jerry_i2s_interrupt_cycles_per_scanline; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_reset_i2s_timer(void) +{ + //fprintf(log_get(),"i2s: reseting\n"); + jerry_i2s_interrupt_divide=8; + jerry_i2s_interrupt_timer=-1; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_reset_timer_1(void) +{ + if ((!jerry_timer_1_prescaler)||(!jerry_timer_1_divider)) + jerry_timer_1_counter=0; + else + jerry_timer_1_counter=(1+jerry_timer_1_prescaler)*(1+jerry_timer_1_divider); + +// if (jerry_timer_1_counter) +// fprintf(log_get(),"jerry: reseting timer 1 to 0x%.8x (%i)\n",jerry_timer_1_counter,jerry_timer_1_counter); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_reset_timer_2(void) +{ + if ((!jerry_timer_2_prescaler)||(!jerry_timer_2_divider)) + { + jerry_timer_2_counter=0; + return; + } + else + jerry_timer_2_counter=((1+jerry_timer_2_prescaler)*(1+jerry_timer_2_divider)); + +// if (jerry_timer_2_counter) +// fprintf(log_get(),"jerry: reseting timer 2 to 0x%.8x (%i)\n",jerry_timer_2_counter,jerry_timer_2_counter); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_pit_exec(uint32 cycles) +{ + if (jerry_timer_1_counter) + jerry_timer_1_counter-=cycles; + + if (jerry_timer_1_counter<=0) + { + dsp_set_irq_line(2,1); + jerry_reset_timer_1(); + } + + if (jerry_timer_2_counter) + jerry_timer_2_counter-=cycles; + + if (jerry_timer_2_counter<=0) + { + dsp_set_irq_line(3,1); + jerry_reset_timer_2(); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_wave_rom_init(void) +{ + memory_malloc_secure((void **)&jerry_wave_rom, 0x1000, "jerry wave rom"); + uint32 * jaguar_wave_rom_32 = (uint32 *)jerry_wave_rom; + +/* for (i = 0; i < 0x80; i++) + { + // F1D000 = triangle wave + jaguar_wave_rom_32[0x000 + i] = ((i <= 0x40) ? i : 0x80 - i) * 32767 / 0x40; + + // F1D200 = full sine wave + jaguar_wave_rom_32[0x080 + i] = (int)(32767. * sin(2.0 * 3.1415927 * (double)i / (double)0x80)); + + // F1D400 = amplitude modulated sine wave? + jaguar_wave_rom_32[0x100 + i] = (int)(32767. * sin(2.0 * 3.1415927 * (double)i / (double)0x80)); + + // F1D600 = sine wave and second order harmonic + jaguar_wave_rom_32[0x180 + i] = (int)(32767. * sin(2.0 * 3.1415927 * (double)i / (double)0x80)); + + // F1D800 = chirp (sine wave of increasing frequency) + jaguar_wave_rom_32[0x200 + i] = (int)(32767. * sin(2.0 * 3.1415927 * (double)i / (double)0x80)); + + // F1DA00 = traingle wave with noise + jaguar_wave_rom_32[0x280 + i] = jaguar_wave_rom_32[0x000 + i] * (rand() % 32768) / 32768; + + // F1DC00 = spike + jaguar_wave_rom_32[0x300 + i] = (i == 0x40) ? 32767 : 0; + + // F1DE00 = white noise + jaguar_wave_rom_32[0x380 + i] = rand() % 32768; + } + */ + // use real wave table dump +// Looks like this WT dump is in the wrong endian... + memcpy(jerry_wave_rom, wave_table, 0x1000); + + // reverse byte ordering +// Actually, this does nothing... + for(int i=0; i<0x400; i++) + { + uint32 data = jaguar_wave_rom_32[i]; + data = ((data&0xff000000)>>24)|((data&0x0000ff00)<<8)| + ((data&0x00ff0000)>>8) |((data&0x000000ff)<<24); + } + + // copy it to dsp ram + memcpy(&jerry_ram_8[0xD000], jerry_wave_rom, 0x1000); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_init(void) +{ + //fprintf(log_get(),"jerry_init()\n"); + clock_init(); + anajoy_init(); + joystick_init(); + eeprom_init(); + memory_malloc_secure((void **)&jerry_ram_8, 0x10000, "jerry ram"); +// jerry_ram_16 = (uint16 *)jerry_ram_8; + jerry_wave_rom_init(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_reset(void) +{ + //fprintf(log_get(),"jerry_reset()\n"); + clock_reset(); + anajoy_reset(); + joystick_reset(); + eeprom_reset(); + jerry_reset_i2s_timer(); + + memset(jerry_ram_8, 0x00, 0x10000); + jerry_ram_8[JERRY_CONFIG+1] |= 0x10; // NTSC (bit 4) + jerry_timer_1_prescaler = 0xFFFF; + jerry_timer_2_prescaler = 0xFFFF; + jerry_timer_1_divider = 0xFFFF; + jerry_timer_2_divider = 0xFFFF; + jerry_timer_1_counter = 0; + jerry_timer_2_counter = 0; + +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_done(void) +{ + //fprintf(log_get(),"jerry_done()\n"); + memory_free(jerry_ram_8); + clock_done(); + anajoy_done(); + joystick_done(); + eeprom_done(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +unsigned jerry_byte_read(unsigned int offset) +{ +#ifdef JERRY_DEBUG + fprintf(log_get(),"jerry: reading byte at 0x%.6x\n",offset); +#endif + if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + return dsp_byte_read(offset); + + if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + return dsp_byte_read(offset); + + if ((offset >= 0xF10000) && (offset <= 0xF10007)) + { + switch(offset & 0x07) + { + case 0: return(jerry_timer_1_prescaler>>8); + case 1: return(jerry_timer_1_prescaler&0xff); + case 2: return(jerry_timer_1_divider>>8); + case 3: return(jerry_timer_1_divider&0xff); + case 4: return(jerry_timer_2_prescaler>>8); + case 5: return(jerry_timer_2_prescaler&0xff); + case 6: return(jerry_timer_2_divider>>8); + case 7: return(jerry_timer_2_divider&0xff); + } + } + + if ((offset>=0xf10010)&&(offset<0xf10016)) + return(clock_byte_read(offset)); + + if ((offset>=0xf17c00)&&(offset<0xf17c02)) + return(anajoy_byte_read(offset)); + + if ((offset>=0xf14000)&&(offset<=0xf14003)) + { + return(joystick_byte_read(offset)|eeprom_byte_read(offset)); + } + + if ((offset >= 0xF14000) && (offset <= 0xF1A0FF)) + return(eeprom_byte_read(offset)); + + return jerry_ram_8[offset & 0xFFFF]; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +unsigned jerry_word_read(unsigned int offset) +{ +#ifdef JERRY_DEBUG + fprintf(log_get(),"jerry: reading word at 0x%.6x\n",offset); +#endif + if ((offset>=dsp_control_ram_base)&&(offset=dsp_work_ram_base)&&(offset=0xf10000)&&(offset<=0xf10007)) + { + switch(offset&0x07) + { + case 0: return(jerry_timer_1_prescaler); + case 2: return(jerry_timer_1_divider); + case 4: return(jerry_timer_2_prescaler); + case 6: return(jerry_timer_2_divider); + } + } + + if ((offset>=0xf10010)&&(offset<0xf10016)) + return(clock_word_read(offset)); + + if (offset==0xF10020) + return(0x00); + + if ((offset>=0xf17c00)&&(offset<0xf17c02)) + return(anajoy_word_read(offset)); + + if (offset==0xf14000) + { + uint16 dta=(joystick_word_read(offset)&0xfffe)|eeprom_word_read(offset); + //fprintf(log_get(),"reading 0x%.4x from 0xf14000\n"); + return(dta); + } + if ((offset>=0xf14002)&&(offset<0xf14003)) + return(joystick_word_read(offset)); + + if ((offset>=0xf14000)&&(offset<=0xF1A0FF)) + return(eeprom_word_read(offset)); + + + + offset&=0xffff; + if (offset==0x4002) + return(0xffff); + + + uint16 data=jerry_ram_8[offset+0]; + data<<=8; + data|=jerry_ram_8[offset+1]; + return(data); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_byte_write(unsigned offset, unsigned data) +{ +#ifdef JERRY_DEBUG + fprintf(log_get(),"jerry: writing byte %.2x at 0x%.6x\n",data,offset); +#endif + if ((offset>=dsp_control_ram_base)&&(offset=dsp_work_ram_base)&&(offset=0xf1a152)&&(offset<0xf1a154)) + { +// fprintf(log_get(),"i2s: writing 0x%.2x to SCLK\n",data); + if ((offset&0x03)==2) + jerry_i2s_interrupt_divide=(jerry_i2s_interrupt_divide&0x00ff)|(((uint32)data)<<8); + else + jerry_i2s_interrupt_divide=(jerry_i2s_interrupt_divide&0xff00)|((uint32)data); + + jerry_i2s_interrupt_timer=-1; + jerry_i2s_exec(0); + } + if ((offset>=0xf10000)&&(offset<=0xf10007)) + { + switch(offset&0x07) + { + case 0: { jerry_timer_1_prescaler=(jerry_timer_1_prescaler&0x00ff)|(data<<8); jerry_reset_timer_1(); return; } + case 1: { jerry_timer_1_prescaler=(jerry_timer_1_prescaler&0xff00)|(data); jerry_reset_timer_1(); return; } + case 2: { jerry_timer_1_divider=(jerry_timer_1_divider&0x00ff)|(data<<8); jerry_reset_timer_1(); return; } + case 3: { jerry_timer_1_divider=(jerry_timer_1_divider&0xff00)|(data); jerry_reset_timer_1(); return; } + case 4: { jerry_timer_2_prescaler=(jerry_timer_2_prescaler&0x00ff)|(data<<8); jerry_reset_timer_2(); return; } + case 5: { jerry_timer_2_prescaler=(jerry_timer_2_prescaler&0xff00)|(data); jerry_reset_timer_2(); return; } + case 6: { jerry_timer_2_divider=(jerry_timer_2_divider&0x00ff)|(data<<8); jerry_reset_timer_2(); return; } + case 7: { jerry_timer_2_divider=(jerry_timer_2_divider&0xff00)|(data); jerry_reset_timer_2(); return; } + } + } + + + if ((offset>=0xf10010)&&(offset<0xf10016)) + { + clock_byte_write(offset,data); + return; + } + if ((offset>=0xf17c00)&&(offset<0xf17c02)) + { + anajoy_byte_write(offset,data); + return; + } + if ((offset>=0xf14000)&&(offset<0xf14003)) + { + joystick_byte_write(offset,data); + eeprom_byte_write(offset,data); + return; + } + if ((offset>=0xf14000)&&(offset<=0xF1A0FF)) + { + eeprom_byte_write(offset,data); + return; + } + offset&=0xffff; + jerry_ram_8[offset]=data; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void jerry_word_write(unsigned offset, unsigned data) +{ +#ifdef JERRY_DEBUG + fprintf(log_get(), "JERRY: Writing word %04X at %06X\n", data, offset); +#endif + + if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + { + dsp_word_write(offset, data); + return; + } + if ((offset >=dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + { + dsp_word_write(offset, data); + return; + } + if (offset == 0xF1A152) + { +// fprintf(log_get(),"i2s: writing 0x%.4x to SCLK\n",data); + jerry_i2s_interrupt_divide = data & 0xFF; + jerry_i2s_interrupt_timer = -1; + jerry_i2s_exec(0); + } + + if ((offset >= 0xF10000) && (offset <= 0xF10007)) + { + switch(offset & 0x07) + { + case 0: { jerry_timer_1_prescaler=data; jerry_reset_timer_1(); return; } + case 2: { jerry_timer_1_divider=data; jerry_reset_timer_1(); return; } + case 4: { jerry_timer_2_prescaler=data; jerry_reset_timer_2(); return; } + case 6: { jerry_timer_2_divider=data; jerry_reset_timer_2(); return; } + } + } + + if ((offset >= 0xF1A148) && (offset < 0xF1A150)) + { + pcm_word_write(offset-0xF1A148, data); + return; + } + + if ((offset >= 0xF10010) && (offset < 0xF10016)) + { + clock_word_write(offset, data); + return; + } + if ((offset >= 0xf17C00) && (offset < 0xF17C02)) + { + anajoy_word_write(offset, data); + return; + } + if ((offset >= 0xF14000) && (offset < 0xF14003)) + { + joystick_word_write(offset, data); + eeprom_word_write(offset, data); + return; + } + if ((offset >= 0xF14000) && (offset <= 0xF1A0FF)) + { + eeprom_word_write(offset,data); + return; + } + + jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; + jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; + +} diff --git a/src/joystick.cpp b/src/joystick.cpp new file mode 100644 index 0000000..4d5ed8e --- /dev/null +++ b/src/joystick.cpp @@ -0,0 +1,268 @@ +#ifndef __PORT__ +#include "include/stdafx.h" +#include +#endif +#include +#include +#include "SDLptc.h" +#include "jaguar.h" + +void main_screen_switch(void); + + +#define BUTTON_U 0 +#define BUTTON_D 1 +#define BUTTON_L 2 +#define BUTTON_R 3 +#define BUTTON_1 4 +#define BUTTON_4 5 +#define BUTTON_7 6 +#define BUTTON_s 7 +#define BUTTON_0 8 +#define BUTTON_8 9 +#define BUTTON_5 10 +#define BUTTON_2 11 +#define BUTTON_d 12 +#define BUTTON_9 13 +#define BUTTON_6 14 +#define BUTTON_3 15 + + +#define BUTTON_A 16 +#define BUTTON_B 17 +#define BUTTON_C 18 +#define BUTTON_OPTION 19 +#define BUTTON_PAUSE 20 + +static uint8 joystick_ram[4]; +static uint8 joypad_0_buttons[21]; +static uint8 joypad_1_buttons[21]; +extern uint8 finished; +extern int start_logging; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_init(void) +{ + joystick_reset(); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_exec(void) +{ + + uint8 *keystate = SDL_GetKeyState(NULL); + Sint16 x = 0, y = 0; + extern Console console; + + memset(joypad_0_buttons,0,21); + memset(joypad_1_buttons,0,21); + + if ((keystate[SDLK_LALT])&(keystate[SDLK_RETURN])) main_screen_switch(); + + /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com) */ + + if (keystate[SDLK_UP]) joypad_0_buttons[BUTTON_U]=0x01; + if (keystate[SDLK_DOWN]) joypad_0_buttons[BUTTON_D]=0x01; + if (keystate[SDLK_LEFT]) joypad_0_buttons[BUTTON_L]=0x01; + if (keystate[SDLK_RIGHT]) joypad_0_buttons[BUTTON_R]=0x01; + if (keystate[SDLK_z]) joypad_0_buttons[BUTTON_A]=0x01; + if (keystate[SDLK_x]) joypad_0_buttons[BUTTON_B]=0x01; + if (keystate[SDLK_c]) joypad_0_buttons[BUTTON_C]=0x01; + if (keystate[SDLK_TAB]) joypad_0_buttons[BUTTON_OPTION]=0x01; + if (keystate[SDLK_RETURN]) joypad_0_buttons[BUTTON_PAUSE]=0x01; + if (keystate[SDLK_q]) start_logging=1; + if (keystate[SDLK_w]) gpu_reset_stats(); +//f (keystate[SDLK_u]) jaguar_long_write(0xf1c384,jaguar_long_read(0xf1c384)+1); + if (keystate[SDLK_d]) + { + dump(); + } + + if (keystate[SDLK_KP0]) joypad_0_buttons[BUTTON_0]=0x01; + if (keystate[SDLK_KP1]) joypad_0_buttons[BUTTON_1]=0x01; + if (keystate[SDLK_KP2]) joypad_0_buttons[BUTTON_2]=0x01; + if (keystate[SDLK_KP3]) joypad_0_buttons[BUTTON_3]=0x01; + if (keystate[SDLK_KP4]) joypad_0_buttons[BUTTON_4]=0x01; + if (keystate[SDLK_KP5]) joypad_0_buttons[BUTTON_5]=0x01; + if (keystate[SDLK_KP6]) joypad_0_buttons[BUTTON_6]=0x01; + if (keystate[SDLK_KP7]) joypad_0_buttons[BUTTON_7]=0x01; + if (keystate[SDLK_KP8]) joypad_0_buttons[BUTTON_8]=0x01; + if (keystate[SDLK_KP9]) joypad_0_buttons[BUTTON_9]=0x01; + + if (keystate[SDLK_ESCAPE]) finished=1; + + /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com */ + /* Joystick support */ + + if ( console.JoyEnabled() == 1 ) { + + x = SDL_JoystickGetAxis(console.joystick, 0); + y = SDL_JoystickGetAxis(console.joystick, 1); + + if ( x > 16384 ) joypad_0_buttons[BUTTON_R]=0x01; + if ( x < -16384 ) joypad_0_buttons[BUTTON_L]=0x01; + if ( y > 16384 ) joypad_0_buttons[BUTTON_D]=0x01; + if ( y < -16384 ) joypad_0_buttons[BUTTON_U]=0x01; + + if (SDL_JoystickGetButton(console.joystick, 0) == SDL_PRESSED) joypad_0_buttons[BUTTON_A]=0x01; + if (SDL_JoystickGetButton(console.joystick, 1) == SDL_PRESSED) joypad_0_buttons[BUTTON_B]=0x01; + if (SDL_JoystickGetButton(console.joystick, 2) == SDL_PRESSED) joypad_0_buttons[BUTTON_C]=0x01; + + } + + /* ADDED by SDLEMU (http://sdlemu.ngemu.com */ + /* Needed to make sure that the events queue is empty */ + SDL_PumpEvents(); + +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_reset(void) +{ + memset(joystick_ram,0x00,4); + memset(joypad_0_buttons,0,21); + memset(joypad_1_buttons,0,21); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_done(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_byte_write(uint32 offset, uint8 data) +{ + joystick_ram[offset&0x03]=data; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void joystick_word_write(uint32 offset, uint16 data) +{ + offset&=0x03; + joystick_ram[offset+0]=(data>>8)&0xff; + joystick_ram[offset+1]=data&0xff; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 joystick_byte_read(uint32 offset) +{ + offset&=0x03; + + if (offset==0) + { + uint8 data=0x00; + int pad0Index=joystick_ram[1]&0x0f; + int pad1Index=(joystick_ram[1]>>4)&0x0f; + + if (!(pad0Index&0x01)) + pad0Index=0; + else + if (!(pad0Index&0x02)) + pad0Index=1; + else + if (!(pad0Index&0x04)) + pad0Index=2; + else + pad0Index=3; + + if (!(pad1Index&0x01)) + pad1Index=0; + else + if (!(pad1Index&0x02)) + pad1Index=1; + else + if (!(pad1Index&0x04)) + pad1Index=2; + else + pad1Index=3; + + if (joypad_0_buttons[(pad0Index<<2)+0]) data|=0x01; + if (joypad_0_buttons[(pad0Index<<2)+1]) data|=0x02; + if (joypad_0_buttons[(pad0Index<<2)+2]) data|=0x04; + if (joypad_0_buttons[(pad0Index<<2)+3]) data|=0x08; + if (joypad_1_buttons[(pad1Index<<2)+0]) data|=0x10; + if (joypad_1_buttons[(pad1Index<<2)+1]) data|=0x20; + if (joypad_1_buttons[(pad1Index<<2)+2]) data|=0x40; + if (joypad_1_buttons[(pad1Index<<2)+3]) data|=0x80; + return(~data); + } + else + if (offset==3) + { + uint8 data=((1<<5)|(1<<4)|0x0f) ; + int pad0Index=joystick_ram[1]&0x0f; + int pad1Index=(joystick_ram[1]>>4)&0x0f; + + if (!(pad0Index&0x01)) + { + if (joypad_0_buttons[BUTTON_PAUSE]) data^=0x01; + if (joypad_0_buttons[BUTTON_A]) data^=0x02; + } + else + if (!(pad0Index&0x02)) + { + if (joypad_0_buttons[BUTTON_B]) data^=0x02; + } + else + if (!(pad0Index&0x04)) + { + if (joypad_0_buttons[BUTTON_C]) data^=0x02; + } + else + { + if (joypad_0_buttons[BUTTON_OPTION]) data^=0x02; + } + return(data); + } + return(joystick_ram[offset]); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 joystick_word_read(uint32 offset) +{ + uint16 data=joystick_byte_read((offset+0)&0x03); + data<<=8; + data|=joystick_byte_read((offset+1)&0x03); + return(data); +} diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000..091dec4 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,22 @@ + +#include "log.h" + +FILE * log_stream = NULL; + +int log_init(char * path) +{ + log_stream = fopen(path, "wrt"); + if (log_stream == NULL) + return 0; + return 1; +} + +FILE * log_get(void) +{ + return log_stream; +} + +void log_done(void) +{ + fclose(log_stream); +} diff --git a/src/m68k.h b/src/m68k.h new file mode 100644 index 0000000..fffe2ed --- /dev/null +++ b/src/m68k.h @@ -0,0 +1,346 @@ +#ifndef M68K__HEADER +#define M68K__HEADER + +#ifdef __cplusplus +extern "C" { +#endif + +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ + +/* ======================================================================== */ + +/* There are 7 levels of interrupt to the 68K. + * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). + */ +#define M68K_IRQ_NONE 0 +#define M68K_IRQ_1 1 +#define M68K_IRQ_2 2 +#define M68K_IRQ_3 3 +#define M68K_IRQ_4 4 +#define M68K_IRQ_5 5 +#define M68K_IRQ_6 6 +#define M68K_IRQ_7 7 + + +/* Special interrupt acknowledge values. + * Use these as special returns from the interrupt acknowledge callback + * (specified later in this header). + */ + +/* Causes an interrupt autovector (0x18 + interrupt level) to be taken. + * This happens in a real 68K if VPA or AVEC is asserted during an interrupt + * acknowledge cycle instead of DTACK. + */ +#define M68K_INT_ACK_AUTOVECTOR 0xffffffff + +/* Causes the spurious interrupt vector (0x18) to be taken + * This happens in a real 68K if BERR is asserted during the interrupt + * acknowledge cycle (i.e. no devices responded to the acknowledge). + */ +#define M68K_INT_ACK_SPURIOUS 0xfffffffe + + +/* 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_68030, /* Supported by disassembler ONLY */ + M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */ +}; + +/* 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 */ + + /* 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 */ +} m68k_register_t; + +/* ======================================================================== */ +/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */ +/* ======================================================================== */ + +/* You will have to implement these functions */ + +/* read/write functions called by the CPU to access memory. + * while values used are 32 bits, only the appropriate number + * of bits are relevant (i.e. in write_memory_8, only the lower 8 bits + * of value should be written to memory). + * + * NOTE: I have separated the immediate and PC-relative memory fetches + * from the other memory fetches because some systems require + * differentiation between PROGRAM and DATA fetches (usually + * for security setups such as encryption). + * This separation can either be achieved by setting + * M68K_SEPARATE_READS in m68kconf.h and defining + * the read functions, or by setting M68K_EMULATE_FC and + * making a function code callback function. + * Using the callback offers better emulation coverage + * because you can also monitor whether the CPU is in SYSTEM or + * USER mode, but it is also slower. + */ + +/* Read from anywhere */ +unsigned int m68k_read_memory_8(unsigned int address); +unsigned int m68k_read_memory_16(unsigned int address); +unsigned int m68k_read_memory_32(unsigned int address); + +/* Read data immediately following the PC */ +unsigned int m68k_read_immediate_16(unsigned int address); +unsigned int m68k_read_immediate_32(unsigned int address); + +/* Read data relative to the PC */ +unsigned int m68k_read_pcrelative_8(unsigned int address); +unsigned int m68k_read_pcrelative_16(unsigned int address); +unsigned int m68k_read_pcrelative_32(unsigned int address); + +/* Memory access for the disassembler */ +unsigned int m68k_read_disassembler_8 (unsigned int address); +unsigned int m68k_read_disassembler_16 (unsigned int address); +unsigned int m68k_read_disassembler_32 (unsigned int address); + +/* Write to anywhere */ +void m68k_write_memory_8(unsigned int address, unsigned int value); +void m68k_write_memory_16(unsigned int address, unsigned int value); +void m68k_write_memory_32(unsigned int address, unsigned int value); + + + +/* ======================================================================== */ +/* ============================== CALLBACKS =============================== */ +/* ======================================================================== */ + +/* These functions allow you to set callbacks to the host when specific events + * occur. Note that you must enable the corresponding value in m68kconf.h + * in order for these to do anything useful. + * Note: I have defined default callbacks which are used if you have enabled + * the corresponding #define in m68kconf.h but either haven't assigned a + * callback or have assigned a callback of NULL. + */ + +/* Set the callback for an interrupt acknowledge. + * You must enable M68K_EMULATE_INT_ACK in m68kconf.h. + * The CPU will call the callback with the interrupt level being acknowledged. + * The host program must return either a vector from 0x02-0xff, or one of the + * special interrupt acknowledge values specified earlier in this header. + * If this is not implemented, the CPU will always assume an autovectored + * interrupt, and will automatically clear the interrupt request when it + * services the interrupt. + * Default behavior: return M68K_INT_ACK_AUTOVECTOR. + */ +void m68k_set_int_ack_callback(int (*callback)(int int_level)); + + +/* Set the callback for a breakpoint acknowledge (68010+). + * You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h. + * The CPU will call the callback with whatever was in the data field of the + * BKPT instruction for 68020+, or 0 for 68010. + * Default behavior: do nothing. + */ +void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data)); + + +/* Set the callback for the RESET instruction. + * You must enable M68K_EMULATE_RESET in m68kconf.h. + * The CPU calls this callback every time it encounters a RESET instruction. + * Default behavior: do nothing. + */ +void m68k_set_reset_instr_callback(void (*callback)(void)); + + +/* Set the callback for informing of a large PC change. + * You must enable M68K_MONITOR_PC in m68kconf.h. + * The CPU calls this callback with the new PC value every time the PC changes + * by a large value (currently set for changes by longwords). + * Default behavior: do nothing. + */ +void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc)); + + +/* Set the callback for CPU function code changes. + * You must enable M68K_EMULATE_FC in m68kconf.h. + * The CPU calls this callback with the function code before every memory + * access to set the CPU's function code according to what kind of memory + * access it is (supervisor/user, program/data and such). + * Default behavior: do nothing. + */ +void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)); + + +/* Set a callback for the instruction cycle of the CPU. + * You must enable M68K_INSTRUCTION_HOOK in m68kconf.h. + * The CPU calls this callback just before fetching the opcode in the + * instruction cycle. + * Default behavior: do nothing. + */ +void m68k_set_instr_hook_callback(void (*callback)(void)); + + + +/* ======================================================================== */ +/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */ +/* ======================================================================== */ + +/* Use this function to set the CPU type you want to emulate. + * Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68010, + * M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020. + */ +void m68k_set_cpu_type(unsigned int cpu_type); + +/* Pulse the RESET pin on the CPU. + * You *MUST* reset the CPU at least once to initialize the emulation + * Note: If you didn't call m68k_set_cpu_type() before resetting + * the CPU for the first time, the CPU will be set to + * M68K_CPU_TYPE_68000. + */ +void m68k_pulse_reset(void); + +/* execute num_cycles worth of instructions. returns number of cycles used */ +int m68k_execute(int num_cycles); + +/* These functions let you read/write/modify the number of cycles left to run + * while m68k_execute() is running. + * These are useful if the 68k accesses a memory-mapped port on another device + * that requires immediate processing by another CPU. + */ +int m68k_cycles_run(void); /* Number of cycles run so far */ +int m68k_cycles_remaining(void); /* Number of cycles left */ +void m68k_modify_timeslice(int cycles); /* Modify cycles left */ +void m68k_end_timeslice(void); /* End timeslice now */ + +/* Set the IPL0-IPL2 pins on the CPU (IRQ). + * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). + * Setting IRQ to 0 will clear an interrupt request. + */ +void m68k_set_irq(unsigned int int_level); + + +/* Halt the CPU as if you pulsed the HALT pin. */ +void m68k_pulse_halt(void); + + +/* Context switching to allow multiple CPUs */ + +/* Get the size of the cpu context in bytes */ +unsigned int m68k_context_size(void); + +/* Get a cpu context */ +unsigned int m68k_get_context(void* dst); + +/* set the current cpu context */ +void m68k_set_context(void* dst); + +/* Save the current cpu context to disk. + * You must provide a function pointer of the form: + * void save_value(char* identifier, unsigned int value) + */ +void m68k_save_context( void (*save_value)(char* identifier, unsigned int value)); + +/* Load a cpu context from disk. + * You must provide a function pointer of the form: + * unsigned int load_value(char* identifier) + */ +void m68k_load_context(unsigned int (*load_value)(char* identifier)); + + + +/* Peek at the internals of a CPU context. This can either be a context + * retrieved using m68k_get_context() or the currently running context. + * If context is NULL, the currently running CPU context will be used. + */ +unsigned int m68k_get_reg(void* context, m68k_register_t reg); + +/* Poke values into the internals of the currently running CPU context */ +void m68k_set_reg(m68k_register_t reg, unsigned int value); + +/* Check if an instruction is valid for the specified CPU type */ +unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type); + +/* Disassemble 1 instruction using the epecified CPU type at pc. Stores + * disassembly in str_buff and returns the size of the instruction in bytes. + */ +unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type); + +/* ======================================================================== */ +/* ============================= CONFIGURATION ============================ */ +/* ======================================================================== */ + +/* Import the configuration for this build */ +#include "m68kconf.h" + + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* M68K__HEADER */ diff --git a/src/m68k_in.c b/src/m68k_in.c new file mode 100644 index 0000000..9793d56 --- /dev/null +++ b/src/m68k_in.c @@ -0,0 +1,9989 @@ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + +/* 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 "m68kops.h" + +#define NUM_CPU_TYPES 3 + +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 opcode_handler_struct m68k_opcode_handler_table[] = +{ +/* function mask match 000 010 020 */ + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_TABLE_FOOTER + + {0, 0, 0, {0, 0, 0}} +}; + + +/* Build the opcode handler jump table */ +void m68ki_build_opcode_table(void) +{ + opcode_handler_struct *ostruct; + 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]; + if((instr & 0xf000) == 0xe000 && (!(instr & 0x20))) + m68ki_cycles[0][instr] = m68ki_cycles[1][instr] = ostruct->cycles[k] + ((((j-1)&7)+1)<<1); + } + } + 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 "m68kcpu.h" + +/* ======================================================================== */ +/* ========================= 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 000 010 020 comments +====== ==== ==== ==== ================ ========== = = = === === === ============= +M68KMAKE_TABLE_START +1010 0 . . 1010............ .......... U U U 4 4 4 +1111 0 . . 1111............ .......... U U U 4 4 4 +abcd 8 rr . 1100...100000... .......... U U U 6 6 4 +abcd 8 mm ax7 1100111100001... .......... U U U 18 18 16 +abcd 8 mm ay7 1100...100001111 .......... U U U 18 18 16 +abcd 8 mm axy7 1100111100001111 .......... U U U 18 18 16 +abcd 8 mm . 1100...100001... .......... U U U 18 18 16 +add 8 er d 1101...000000... .......... U U U 4 4 2 +add 8 er . 1101...000...... A+-DXWLdxI U U U 4 4 2 +add 16 er d 1101...001000... .......... U U U 4 4 2 +add 16 er a 1101...001001... .......... U U U 4 4 2 +add 16 er . 1101...001...... A+-DXWLdxI U U U 4 4 2 +add 32 er d 1101...010000... .......... U U U 6 6 2 +add 32 er a 1101...010001... .......... U U U 6 6 2 +add 32 er . 1101...010...... A+-DXWLdxI U U U 6 6 2 +add 8 re . 1101...100...... A+-DXWL... U U U 8 8 4 +add 16 re . 1101...101...... A+-DXWL... U U U 8 8 4 +add 32 re . 1101...110...... A+-DXWL... U U U 12 12 4 +adda 16 . d 1101...011000... .......... U U U 8 8 2 +adda 16 . a 1101...011001... .......... U U U 8 8 2 +adda 16 . . 1101...011...... A+-DXWLdxI U U U 8 8 2 +adda 32 . d 1101...111000... .......... U U U 6 6 2 +adda 32 . a 1101...111001... .......... U U U 6 6 2 +adda 32 . . 1101...111...... A+-DXWLdxI U U U 6 6 2 +addi 8 . d 0000011000000... .......... U U U 8 8 2 +addi 8 . . 0000011000...... A+-DXWL... U U U 12 12 4 +addi 16 . d 0000011001000... .......... U U U 8 8 2 +addi 16 . . 0000011001...... A+-DXWL... U U U 12 12 4 +addi 32 . d 0000011010000... .......... U U U 16 14 2 +addi 32 . . 0000011010...... A+-DXWL... U U U 20 20 4 +addq 8 . d 0101...000000... .......... U U U 4 4 2 +addq 8 . . 0101...000...... A+-DXWL... U U U 8 8 4 +addq 16 . d 0101...001000... .......... U U U 4 4 2 +addq 16 . a 0101...001001... .......... U U U 4 4 2 +addq 16 . . 0101...001...... A+-DXWL... U U U 8 8 4 +addq 32 . d 0101...010000... .......... U U U 8 8 2 +addq 32 . a 0101...010001... .......... U U U 8 8 2 +addq 32 . . 0101...010...... A+-DXWL... U U U 12 12 4 +addx 8 rr . 1101...100000... .......... U U U 4 4 2 +addx 16 rr . 1101...101000... .......... U U U 4 4 2 +addx 32 rr . 1101...110000... .......... U U U 8 6 2 +addx 8 mm ax7 1101111100001... .......... U U U 18 18 12 +addx 8 mm ay7 1101...100001111 .......... U U U 18 18 12 +addx 8 mm axy7 1101111100001111 .......... U U U 18 18 12 +addx 8 mm . 1101...100001... .......... U U U 18 18 12 +addx 16 mm . 1101...101001... .......... U U U 18 18 12 +addx 32 mm . 1101...110001... .......... U U U 30 30 12 +and 8 er d 1100...000000... .......... U U U 4 4 2 +and 8 er . 1100...000...... A+-DXWLdxI U U U 4 4 2 +and 16 er d 1100...001000... .......... U U U 4 4 2 +and 16 er . 1100...001...... A+-DXWLdxI U U U 4 4 2 +and 32 er d 1100...010000... .......... U U U 6 6 2 +and 32 er . 1100...010...... A+-DXWLdxI U U U 6 6 2 +and 8 re . 1100...100...... A+-DXWL... U U U 8 8 4 +and 16 re . 1100...101...... A+-DXWL... U U U 8 8 4 +and 32 re . 1100...110...... A+-DXWL... U U U 12 12 4 +andi 16 toc . 0000001000111100 .......... U U U 20 16 12 +andi 16 tos . 0000001001111100 .......... S S S 20 16 12 +andi 8 . d 0000001000000... .......... U U U 8 8 2 +andi 8 . . 0000001000...... A+-DXWL... U U U 12 12 4 +andi 16 . d 0000001001000... .......... U U U 8 8 2 +andi 16 . . 0000001001...... A+-DXWL... U U U 12 12 4 +andi 32 . d 0000001010000... .......... U U U 14 14 2 +andi 32 . . 0000001010...... A+-DXWL... U U U 20 20 4 +asr 8 s . 1110...000000... .......... U U U 6 6 6 +asr 16 s . 1110...001000... .......... U U U 6 6 6 +asr 32 s . 1110...010000... .......... U U U 8 8 6 +asr 8 r . 1110...000100... .......... U U U 6 6 6 +asr 16 r . 1110...001100... .......... U U U 6 6 6 +asr 32 r . 1110...010100... .......... U U U 8 8 6 +asr 16 . . 1110000011...... A+-DXWL... U U U 8 8 5 +asl 8 s . 1110...100000... .......... U U U 6 6 8 +asl 16 s . 1110...101000... .......... U U U 6 6 8 +asl 32 s . 1110...110000... .......... U U U 8 8 8 +asl 8 r . 1110...100100... .......... U U U 6 6 8 +asl 16 r . 1110...101100... .......... U U U 6 6 8 +asl 32 r . 1110...110100... .......... U U U 8 8 8 +asl 16 . . 1110000111...... A+-DXWL... U U U 8 8 6 +bcc 8 . . 0110............ .......... U U U 8 8 6 +bcc 16 . . 0110....00000000 .......... U U U 10 10 6 +bcc 32 . . 0110....11111111 .......... . . U . . 6 +bchg 8 r . 0000...101...... A+-DXWL... U U U 8 8 4 +bchg 32 r d 0000...101000... .......... U U U 8 8 4 +bchg 8 s . 0000100001...... A+-DXWL... U U U 12 12 4 +bchg 32 s d 0000100001000... .......... U U U 12 12 4 +bclr 8 r . 0000...110...... A+-DXWL... U U U 8 10 4 +bclr 32 r d 0000...110000... .......... U U U 10 10 4 +bclr 8 s . 0000100010...... A+-DXWL... U U U 12 12 4 +bclr 32 s d 0000100010000... .......... U U U 14 14 4 +bfchg 32 . d 1110101011000... .......... . . U . . 12 timing not quite correct +bfchg 32 . . 1110101011...... A..DXWL... . . U . . 20 +bfclr 32 . d 1110110011000... .......... . . U . . 12 +bfclr 32 . . 1110110011...... A..DXWL... . . U . . 20 +bfexts 32 . d 1110101111000... .......... . . U . . 8 +bfexts 32 . . 1110101111...... A..DXWLdx. . . U . . 15 +bfextu 32 . d 1110100111000... .......... . . U . . 8 +bfextu 32 . . 1110100111...... A..DXWLdx. . . U . . 15 +bfffo 32 . d 1110110111000... .......... . . U . . 18 +bfffo 32 . . 1110110111...... A..DXWLdx. . . U . . 28 +bfins 32 . d 1110111111000... .......... . . U . . 10 +bfins 32 . . 1110111111...... A..DXWL... . . U . . 17 +bfset 32 . d 1110111011000... .......... . . U . . 12 +bfset 32 . . 1110111011...... A..DXWL... . . U . . 20 +bftst 32 . d 1110100011000... .......... . . U . . 6 +bftst 32 . . 1110100011...... A..DXWLdx. . . U . . 13 +bkpt 0 . . 0100100001001... .......... . U U . 10 10 +bra 8 . . 01100000........ .......... U U U 10 10 10 +bra 16 . . 0110000000000000 .......... U U U 10 10 10 +bra 32 . . 0110000011111111 .......... U U U . . 10 +bset 32 r d 0000...111000... .......... U U U 8 8 4 +bset 8 r . 0000...111...... A+-DXWL... U U U 8 8 4 +bset 8 s . 0000100011...... A+-DXWL... U U U 12 12 4 +bset 32 s d 0000100011000... .......... U U U 12 12 4 +bsr 8 . . 01100001........ .......... U U U 18 18 7 +bsr 16 . . 0110000100000000 .......... U U U 18 18 7 +bsr 32 . . 0110000111111111 .......... . . U . . 7 +btst 8 r . 0000...100...... A+-DXWLdxI U U U 4 4 4 +btst 32 r d 0000...100000... .......... U U U 6 6 4 +btst 8 s . 0000100000...... A+-DXWLdx. U U U 8 8 4 +btst 32 s d 0000100000000... .......... U U U 10 10 4 +callm 32 . . 0000011011...... A..DXWLdx. . . U . . 60 not properly emulated +cas 8 . . 0000101011...... A+-DXWL... . . U . . 12 +cas 16 . . 0000110011...... A+-DXWL... . . U . . 12 +cas 32 . . 0000111011...... A+-DXWL... . . U . . 12 +cas2 16 . . 0000110011111100 .......... . . U . . 12 +cas2 32 . . 0000111011111100 .......... . . U . . 12 +chk 16 . d 0100...110000... .......... U U U 10 8 8 +chk 16 . . 0100...110...... A+-DXWLdxI U U U 10 8 8 +chk 32 . d 0100...100000... .......... . . U . . 8 +chk 32 . . 0100...100...... A+-DXWLdxI . . U . . 8 +chk2cmp2 8 . . 0000000011...... A..DXWLdx. . . U . . 18 +chk2cmp2 16 . . 0000001011...... A..DXWLdx. . . U . . 18 +chk2cmp2 32 . . 0000010011...... A..DXWLdx. . . U . . 18 +clr 8 . d 0100001000000... .......... U U U 4 4 2 +clr 8 . . 0100001000...... A+-DXWL... U U U 8 4 4 +clr 16 . d 0100001001000... .......... U U U 4 4 2 +clr 16 . . 0100001001...... A+-DXWL... U U U 8 4 4 +clr 32 . d 0100001010000... .......... U U U 6 6 2 +clr 32 . . 0100001010...... A+-DXWL... U U U 12 6 4 +cmp 8 . d 1011...000000... .......... U U U 4 4 2 +cmp 8 . . 1011...000...... A+-DXWLdxI U U U 4 4 2 +cmp 16 . d 1011...001000... .......... U U U 4 4 2 +cmp 16 . a 1011...001001... .......... U U U 4 4 2 +cmp 16 . . 1011...001...... A+-DXWLdxI U U U 4 4 2 +cmp 32 . d 1011...010000... .......... U U U 6 6 2 +cmp 32 . a 1011...010001... .......... U U U 6 6 2 +cmp 32 . . 1011...010...... A+-DXWLdxI U U U 6 6 2 +cmpa 16 . d 1011...011000... .......... U U U 6 6 4 +cmpa 16 . a 1011...011001... .......... U U U 6 6 4 +cmpa 16 . . 1011...011...... A+-DXWLdxI U U U 6 6 4 +cmpa 32 . d 1011...111000... .......... U U U 6 6 4 +cmpa 32 . a 1011...111001... .......... U U U 6 6 4 +cmpa 32 . . 1011...111...... A+-DXWLdxI U U U 6 6 4 +cmpi 8 . d 0000110000000... .......... U U U 8 8 2 +cmpi 8 . . 0000110000...... A+-DXWL... U U U 8 8 2 +cmpi 8 . pcdi 0000110000111010 .......... . . U . . 7 +cmpi 8 . pcix 0000110000111011 .......... . . U . . 9 +cmpi 16 . d 0000110001000... .......... U U U 8 8 2 +cmpi 16 . . 0000110001...... A+-DXWL... U U U 8 8 2 +cmpi 16 . pcdi 0000110001111010 .......... . . U . . 7 +cmpi 16 . pcix 0000110001111011 .......... . . U . . 9 +cmpi 32 . d 0000110010000... .......... U U U 14 12 2 +cmpi 32 . . 0000110010...... A+-DXWL... U U U 12 12 2 +cmpi 32 . pcdi 0000110010111010 .......... . . U . . 7 +cmpi 32 . pcix 0000110010111011 .......... . . U . . 9 +cmpm 8 . ax7 1011111100001... .......... U U U 12 12 9 +cmpm 8 . ay7 1011...100001111 .......... U U U 12 12 9 +cmpm 8 . axy7 1011111100001111 .......... U U U 12 12 9 +cmpm 8 . . 1011...100001... .......... U U U 12 12 9 +cmpm 16 . . 1011...101001... .......... U U U 12 12 9 +cmpm 32 . . 1011...110001... .......... U U U 20 20 9 +cpbcc 32 . . 1111...01....... .......... . . U . . 4 unemulated +cpdbcc 32 . . 1111...001001... .......... . . U . . 4 unemulated +cpgen 32 . . 1111...000...... .......... . . U . . 4 unemulated +cpscc 32 . . 1111...001...... .......... . . U . . 4 unemulated +cptrapcc 32 . . 1111...001111... .......... . . U . . 4 unemulated +dbt 16 . . 0101000011001... .......... U U U 12 12 6 +dbf 16 . . 0101000111001... .......... U U U 14 14 6 +dbcc 16 . . 0101....11001... .......... U U U 12 12 6 +divs 16 . d 1000...111000... .......... U U U 158 122 56 +divs 16 . . 1000...111...... A+-DXWLdxI U U U 158 122 56 +divu 16 . d 1000...011000... .......... U U U 140 108 44 +divu 16 . . 1000...011...... A+-DXWLdxI U U U 140 108 44 +divl 32 . d 0100110001000... .......... . . U . . 84 +divl 32 . . 0100110001...... A+-DXWLdxI . . U . . 84 +eor 8 . d 1011...100000... .......... U U U 4 4 2 +eor 8 . . 1011...100...... A+-DXWL... U U U 8 8 4 +eor 16 . d 1011...101000... .......... U U U 4 4 2 +eor 16 . . 1011...101...... A+-DXWL... U U U 8 8 4 +eor 32 . d 1011...110000... .......... U U U 8 6 2 +eor 32 . . 1011...110...... A+-DXWL... U U U 12 12 4 +eori 16 toc . 0000101000111100 .......... U U U 20 16 12 +eori 16 tos . 0000101001111100 .......... S S S 20 16 12 +eori 8 . d 0000101000000... .......... U U U 8 8 2 +eori 8 . . 0000101000...... A+-DXWL... U U U 12 12 4 +eori 16 . d 0000101001000... .......... U U U 8 8 2 +eori 16 . . 0000101001...... A+-DXWL... U U U 12 12 4 +eori 32 . d 0000101010000... .......... U U U 16 14 2 +eori 32 . . 0000101010...... A+-DXWL... U U U 20 20 4 +exg 32 dd . 1100...101000... .......... U U U 6 6 2 +exg 32 aa . 1100...101001... .......... U U U 6 6 2 +exg 32 da . 1100...110001... .......... U U U 6 6 2 +ext 16 . . 0100100010000... .......... U U U 4 4 4 +ext 32 . . 0100100011000... .......... U U U 4 4 4 +extb 32 . . 0100100111000... .......... . . U . . 4 +illegal 0 . . 0100101011111100 .......... U U U 4 4 4 +jmp 32 . . 0100111011...... A..DXWLdx. U U U 4 4 0 +jsr 32 . . 0100111010...... A..DXWLdx. U U U 12 12 0 +lea 32 . . 0100...111...... A..DXWLdx. U U U 0 0 2 +link 16 . a7 0100111001010111 .......... U U U 16 16 5 +link 16 . . 0100111001010... .......... U U U 16 16 5 +link 32 . a7 0100100000001111 .......... . . U . . 6 +link 32 . . 0100100000001... .......... . . U . . 6 +lsr 8 s . 1110...000001... .......... U U U 6 6 4 +lsr 16 s . 1110...001001... .......... U U U 6 6 4 +lsr 32 s . 1110...010001... .......... U U U 8 8 4 +lsr 8 r . 1110...000101... .......... U U U 6 6 6 +lsr 16 r . 1110...001101... .......... U U U 6 6 6 +lsr 32 r . 1110...010101... .......... U U U 8 8 6 +lsr 16 . . 1110001011...... A+-DXWL... U U U 8 8 5 +lsl 8 s . 1110...100001... .......... U U U 6 6 4 +lsl 16 s . 1110...101001... .......... U U U 6 6 4 +lsl 32 s . 1110...110001... .......... U U U 8 8 4 +lsl 8 r . 1110...100101... .......... U U U 6 6 6 +lsl 16 r . 1110...101101... .......... U U U 6 6 6 +lsl 32 r . 1110...110101... .......... U U U 8 8 6 +lsl 16 . . 1110001111...... A+-DXWL... U U U 8 8 5 +move 8 d d 0001...000000... .......... U U U 4 4 2 +move 8 d . 0001...000...... A+-DXWLdxI U U U 4 4 2 +move 8 ai d 0001...010000... .......... U U U 8 8 4 +move 8 ai . 0001...010...... A+-DXWLdxI U U U 8 8 4 +move 8 pi d 0001...011000... .......... U U U 8 8 4 +move 8 pi . 0001...011...... A+-DXWLdxI U U U 8 8 4 +move 8 pi7 d 0001111011000... .......... U U U 8 8 4 +move 8 pi7 . 0001111011...... A+-DXWLdxI U U U 8 8 4 +move 8 pd d 0001...100000... .......... U U U 8 8 5 +move 8 pd . 0001...100...... A+-DXWLdxI U U U 8 8 5 +move 8 pd7 d 0001111100000... .......... U U U 8 8 5 +move 8 pd7 . 0001111100...... A+-DXWLdxI U U U 8 8 5 +move 8 di d 0001...101000... .......... U U U 12 12 5 +move 8 di . 0001...101...... A+-DXWLdxI U U U 12 12 5 +move 8 ix d 0001...110000... .......... U U U 14 14 7 +move 8 ix . 0001...110...... A+-DXWLdxI U U U 14 14 7 +move 8 aw d 0001000111000... .......... U U U 12 12 4 +move 8 aw . 0001000111...... A+-DXWLdxI U U U 12 12 4 +move 8 al d 0001001111000... .......... U U U 16 16 6 +move 8 al . 0001001111...... A+-DXWLdxI U U U 16 16 6 +move 16 d d 0011...000000... .......... U U U 4 4 2 +move 16 d a 0011...000001... .......... U U U 4 4 2 +move 16 d . 0011...000...... A+-DXWLdxI U U U 4 4 2 +move 16 ai d 0011...010000... .......... U U U 8 8 4 +move 16 ai a 0011...010001... .......... U U U 8 8 4 +move 16 ai . 0011...010...... A+-DXWLdxI U U U 8 8 4 +move 16 pi d 0011...011000... .......... U U U 8 8 4 +move 16 pi a 0011...011001... .......... U U U 8 8 4 +move 16 pi . 0011...011...... A+-DXWLdxI U U U 8 8 4 +move 16 pd d 0011...100000... .......... U U U 8 8 5 +move 16 pd a 0011...100001... .......... U U U 8 8 5 +move 16 pd . 0011...100...... A+-DXWLdxI U U U 8 8 5 +move 16 di d 0011...101000... .......... U U U 12 12 5 +move 16 di a 0011...101001... .......... U U U 12 12 5 +move 16 di . 0011...101...... A+-DXWLdxI U U U 12 12 5 +move 16 ix d 0011...110000... .......... U U U 14 14 7 +move 16 ix a 0011...110001... .......... U U U 14 14 7 +move 16 ix . 0011...110...... A+-DXWLdxI U U U 14 14 7 +move 16 aw d 0011000111000... .......... U U U 12 12 4 +move 16 aw a 0011000111001... .......... U U U 12 12 4 +move 16 aw . 0011000111...... A+-DXWLdxI U U U 12 12 4 +move 16 al d 0011001111000... .......... U U U 16 16 6 +move 16 al a 0011001111001... .......... U U U 16 16 6 +move 16 al . 0011001111...... A+-DXWLdxI U U U 16 16 6 +move 32 d d 0010...000000... .......... U U U 4 4 2 +move 32 d a 0010...000001... .......... U U U 4 4 2 +move 32 d . 0010...000...... A+-DXWLdxI U U U 4 4 2 +move 32 ai d 0010...010000... .......... U U U 12 12 4 +move 32 ai a 0010...010001... .......... U U U 12 12 4 +move 32 ai . 0010...010...... A+-DXWLdxI U U U 12 12 4 +move 32 pi d 0010...011000... .......... U U U 12 12 4 +move 32 pi a 0010...011001... .......... U U U 12 12 4 +move 32 pi . 0010...011...... A+-DXWLdxI U U U 12 12 4 +move 32 pd d 0010...100000... .......... U U U 12 14 5 +move 32 pd a 0010...100001... .......... U U U 12 14 5 +move 32 pd . 0010...100...... A+-DXWLdxI U U U 12 14 5 +move 32 di d 0010...101000... .......... U U U 16 16 5 +move 32 di a 0010...101001... .......... U U U 16 16 5 +move 32 di . 0010...101...... A+-DXWLdxI U U U 16 16 5 +move 32 ix d 0010...110000... .......... U U U 18 18 7 +move 32 ix a 0010...110001... .......... U U U 18 18 7 +move 32 ix . 0010...110...... A+-DXWLdxI U U U 18 18 7 +move 32 aw d 0010000111000... .......... U U U 16 16 4 +move 32 aw a 0010000111001... .......... U U U 16 16 4 +move 32 aw . 0010000111...... A+-DXWLdxI U U U 16 16 4 +move 32 al d 0010001111000... .......... U U U 20 20 6 +move 32 al a 0010001111001... .......... U U U 20 20 6 +move 32 al . 0010001111...... A+-DXWLdxI U U U 20 20 6 +movea 16 . d 0011...001000... .......... U U U 4 4 2 +movea 16 . a 0011...001001... .......... U U U 4 4 2 +movea 16 . . 0011...001...... A+-DXWLdxI U U U 4 4 2 +movea 32 . d 0010...001000... .......... U U U 4 4 2 +movea 32 . a 0010...001001... .......... U U U 4 4 2 +movea 32 . . 0010...001...... A+-DXWLdxI U U U 4 4 2 +move 16 frc d 0100001011000... .......... . U U . 4 4 +move 16 frc . 0100001011...... A+-DXWL... . U U . 8 4 +move 16 toc d 0100010011000... .......... U U U 12 12 4 +move 16 toc . 0100010011...... A+-DXWLdxI U U U 12 12 4 +move 16 frs d 0100000011000... .......... U S S 6 4 8 U only for 000 +move 16 frs . 0100000011...... A+-DXWL... U S S 8 8 8 U only for 000 +move 16 tos d 0100011011000... .......... S S S 12 12 8 +move 16 tos . 0100011011...... A+-DXWLdxI S S S 12 12 8 +move 32 fru . 0100111001101... .......... S S S 4 6 2 +move 32 tou . 0100111001100... .......... S S S 4 6 2 +movec 32 cr . 0100111001111010 .......... . S S . 12 6 +movec 32 rc . 0100111001111011 .......... . S S . 10 12 +movem 16 re pd 0100100010100... .......... U U U 8 8 4 +movem 16 re . 0100100010...... A..DXWL... U U U 8 8 4 +movem 32 re pd 0100100011100... .......... U U U 8 8 4 +movem 32 re . 0100100011...... A..DXWL... U U U 8 8 4 +movem 16 er pi 0100110010011... .......... U U U 12 12 8 +movem 16 er . 0100110010...... A..DXWLdx. U U U 12 12 8 +movem 32 er pi 0100110011011... .......... U U U 12 12 8 +movem 32 er . 0100110011...... A..DXWLdx. U U U 12 12 8 +movep 16 er . 0000...100001... .......... U U U 16 16 12 +movep 32 er . 0000...101001... .......... U U U 24 24 18 +movep 16 re . 0000...110001... .......... U U U 16 16 11 +movep 32 re . 0000...111001... .......... U U U 24 24 17 +moveq 32 . . 0111...0........ .......... U U U 4 4 2 +moves 8 . . 0000111000...... A+-DXWL... . S S . 14 5 +moves 16 . . 0000111001...... A+-DXWL... . S S . 14 5 +moves 32 . . 0000111010...... A+-DXWL... . S S . 16 5 +muls 16 . d 1100...111000... .......... U U U 54 32 27 +muls 16 . . 1100...111...... A+-DXWLdxI U U U 54 32 27 +mulu 16 . d 1100...011000... .......... U U U 54 30 27 +mulu 16 . . 1100...011...... A+-DXWLdxI U U U 54 30 27 +mull 32 . d 0100110000000... .......... . . U . . 43 +mull 32 . . 0100110000...... A+-DXWLdxI . . U . . 43 +nbcd 8 . d 0100100000000... .......... U U U 6 6 6 +nbcd 8 . . 0100100000...... A+-DXWL... U U U 8 8 6 +neg 8 . d 0100010000000... .......... U U U 4 4 2 +neg 8 . . 0100010000...... A+-DXWL... U U U 8 8 4 +neg 16 . d 0100010001000... .......... U U U 4 4 2 +neg 16 . . 0100010001...... A+-DXWL... U U U 8 8 4 +neg 32 . d 0100010010000... .......... U U U 6 6 2 +neg 32 . . 0100010010...... A+-DXWL... U U U 12 12 4 +negx 8 . d 0100000000000... .......... U U U 4 4 2 +negx 8 . . 0100000000...... A+-DXWL... U U U 8 8 4 +negx 16 . d 0100000001000... .......... U U U 4 4 2 +negx 16 . . 0100000001...... A+-DXWL... U U U 8 8 4 +negx 32 . d 0100000010000... .......... U U U 6 6 2 +negx 32 . . 0100000010...... A+-DXWL... U U U 12 12 4 +nop 0 . . 0100111001110001 .......... U U U 4 4 2 +not 8 . d 0100011000000... .......... U U U 4 4 2 +not 8 . . 0100011000...... A+-DXWL... U U U 8 8 4 +not 16 . d 0100011001000... .......... U U U 4 4 2 +not 16 . . 0100011001...... A+-DXWL... U U U 8 8 4 +not 32 . d 0100011010000... .......... U U U 6 6 2 +not 32 . . 0100011010...... A+-DXWL... U U U 12 12 4 +or 8 er d 1000...000000... .......... U U U 4 4 2 +or 8 er . 1000...000...... A+-DXWLdxI U U U 4 4 2 +or 16 er d 1000...001000... .......... U U U 4 4 2 +or 16 er . 1000...001...... A+-DXWLdxI U U U 4 4 2 +or 32 er d 1000...010000... .......... U U U 6 6 2 +or 32 er . 1000...010...... A+-DXWLdxI U U U 6 6 2 +or 8 re . 1000...100...... A+-DXWL... U U U 8 8 4 +or 16 re . 1000...101...... A+-DXWL... U U U 8 8 4 +or 32 re . 1000...110...... A+-DXWL... U U U 12 12 4 +ori 16 toc . 0000000000111100 .......... U U U 20 16 12 +ori 16 tos . 0000000001111100 .......... S S S 20 16 12 +ori 8 . d 0000000000000... .......... U U U 8 8 2 +ori 8 . . 0000000000...... A+-DXWL... U U U 12 12 4 +ori 16 . d 0000000001000... .......... U U U 8 8 2 +ori 16 . . 0000000001...... A+-DXWL... U U U 12 12 4 +ori 32 . d 0000000010000... .......... U U U 16 14 2 +ori 32 . . 0000000010...... A+-DXWL... U U U 20 20 4 +pack 16 rr . 1000...101000... .......... . . U . . 6 +pack 16 mm ax7 1000111101001... .......... . . U . . 13 +pack 16 mm ay7 1000...101001111 .......... . . U . . 13 +pack 16 mm axy7 1000111101001111 .......... . . U . . 13 +pack 16 mm . 1000...101001... .......... . . U . . 13 +pea 32 . . 0100100001...... A..DXWLdx. U U U 6 6 5 +reset 0 . . 0100111001110000 .......... S S S 0 0 0 +ror 8 s . 1110...000011... .......... U U U 6 6 8 +ror 16 s . 1110...001011... .......... U U U 6 6 8 +ror 32 s . 1110...010011... .......... U U U 8 8 8 +ror 8 r . 1110...000111... .......... U U U 6 6 8 +ror 16 r . 1110...001111... .......... U U U 6 6 8 +ror 32 r . 1110...010111... .......... U U U 8 8 8 +ror 16 . . 1110011011...... A+-DXWL... U U U 8 8 7 +rol 8 s . 1110...100011... .......... U U U 6 6 8 +rol 16 s . 1110...101011... .......... U U U 6 6 8 +rol 32 s . 1110...110011... .......... U U U 8 8 8 +rol 8 r . 1110...100111... .......... U U U 6 6 8 +rol 16 r . 1110...101111... .......... U U U 6 6 8 +rol 32 r . 1110...110111... .......... U U U 8 8 8 +rol 16 . . 1110011111...... A+-DXWL... U U U 8 8 7 +roxr 8 s . 1110...000010... .......... U U U 6 6 12 +roxr 16 s . 1110...001010... .......... U U U 6 6 12 +roxr 32 s . 1110...010010... .......... U U U 8 8 12 +roxr 8 r . 1110...000110... .......... U U U 6 6 12 +roxr 16 r . 1110...001110... .......... U U U 6 6 12 +roxr 32 r . 1110...010110... .......... U U U 8 8 12 +roxr 16 . . 1110010011...... A+-DXWL... U U U 8 8 5 +roxl 8 s . 1110...100010... .......... U U U 6 6 12 +roxl 16 s . 1110...101010... .......... U U U 6 6 12 +roxl 32 s . 1110...110010... .......... U U U 8 8 12 +roxl 8 r . 1110...100110... .......... U U U 6 6 12 +roxl 16 r . 1110...101110... .......... U U U 6 6 12 +roxl 32 r . 1110...110110... .......... U U U 8 8 12 +roxl 16 . . 1110010111...... A+-DXWL... U U U 8 8 5 +rtd 32 . . 0100111001110100 .......... . U U . 16 10 +rte 32 . . 0100111001110011 .......... S S S 20 24 20 bus fault not emulated +rtm 32 . . 000001101100.... .......... . . U . . 19 not properly emulated +rtr 32 . . 0100111001110111 .......... U U U 20 20 14 +rts 32 . . 0100111001110101 .......... U U U 16 16 10 +sbcd 8 rr . 1000...100000... .......... U U U 6 6 4 +sbcd 8 mm ax7 1000111100001... .......... U U U 18 18 16 +sbcd 8 mm ay7 1000...100001111 .......... U U U 18 18 16 +sbcd 8 mm axy7 1000111100001111 .......... U U U 18 18 16 +sbcd 8 mm . 1000...100001... .......... U U U 18 18 16 +st 8 . d 0101000011000... .......... U U U 6 4 4 +st 8 . . 0101000011...... A+-DXWL... U U U 8 8 6 +sf 8 . d 0101000111000... .......... U U U 4 4 4 +sf 8 . . 0101000111...... A+-DXWL... U U U 8 8 6 +scc 8 . d 0101....11000... .......... U U U 4 4 4 +scc 8 . . 0101....11...... A+-DXWL... U U U 8 8 6 +stop 0 . . 0100111001110010 .......... S S S 4 4 8 +sub 8 er d 1001...000000... .......... U U U 4 4 2 +sub 8 er . 1001...000...... A+-DXWLdxI U U U 4 4 2 +sub 16 er d 1001...001000... .......... U U U 4 4 2 +sub 16 er a 1001...001001... .......... U U U 4 4 2 +sub 16 er . 1001...001...... A+-DXWLdxI U U U 4 4 2 +sub 32 er d 1001...010000... .......... U U U 6 6 2 +sub 32 er a 1001...010001... .......... U U U 6 6 2 +sub 32 er . 1001...010...... A+-DXWLdxI U U U 6 6 2 +sub 8 re . 1001...100...... A+-DXWL... U U U 8 8 4 +sub 16 re . 1001...101...... A+-DXWL... U U U 8 8 4 +sub 32 re . 1001...110...... A+-DXWL... U U U 12 12 4 +suba 16 . d 1001...011000... .......... U U U 8 8 2 +suba 16 . a 1001...011001... .......... U U U 8 8 2 +suba 16 . . 1001...011...... A+-DXWLdxI U U U 8 8 2 +suba 32 . d 1001...111000... .......... U U U 6 6 2 +suba 32 . a 1001...111001... .......... U U U 6 6 2 +suba 32 . . 1001...111...... A+-DXWLdxI U U U 6 6 2 +subi 8 . d 0000010000000... .......... U U U 8 8 2 +subi 8 . . 0000010000...... A+-DXWL... U U U 12 12 4 +subi 16 . d 0000010001000... .......... U U U 8 8 2 +subi 16 . . 0000010001...... A+-DXWL... U U U 12 12 4 +subi 32 . d 0000010010000... .......... U U U 16 14 2 +subi 32 . . 0000010010...... A+-DXWL... U U U 20 20 4 +subq 8 . d 0101...100000... .......... U U U 4 4 2 +subq 8 . . 0101...100...... A+-DXWL... U U U 8 8 4 +subq 16 . d 0101...101000... .......... U U U 4 4 2 +subq 16 . a 0101...101001... .......... U U U 8 4 2 +subq 16 . . 0101...101...... A+-DXWL... U U U 8 8 4 +subq 32 . d 0101...110000... .......... U U U 8 8 2 +subq 32 . a 0101...110001... .......... U U U 8 8 2 +subq 32 . . 0101...110...... A+-DXWL... U U U 12 12 4 +subx 8 rr . 1001...100000... .......... U U U 4 4 2 +subx 16 rr . 1001...101000... .......... U U U 4 4 2 +subx 32 rr . 1001...110000... .......... U U U 8 6 2 +subx 8 mm ax7 1001111100001... .......... U U U 18 18 12 +subx 8 mm ay7 1001...100001111 .......... U U U 18 18 12 +subx 8 mm axy7 1001111100001111 .......... U U U 18 18 12 +subx 8 mm . 1001...100001... .......... U U U 18 18 12 +subx 16 mm . 1001...101001... .......... U U U 18 18 12 +subx 32 mm . 1001...110001... .......... U U U 30 30 12 +swap 32 . . 0100100001000... .......... U U U 4 4 4 +tas 8 . d 0100101011000... .......... U U U 4 4 4 +tas 8 . . 0100101011...... A+-DXWL... U U U 14 14 12 +trap 0 . . 010011100100.... .......... U U U 4 4 4 +trapt 0 . . 0101000011111100 .......... . . U . . 4 +trapt 16 . . 0101000011111010 .......... . . U . . 6 +trapt 32 . . 0101000011111011 .......... . . U . . 8 +trapf 0 . . 0101000111111100 .......... . . U . . 4 +trapf 16 . . 0101000111111010 .......... . . U . . 6 +trapf 32 . . 0101000111111011 .......... . . U . . 8 +trapcc 0 . . 0101....11111100 .......... . . U . . 4 +trapcc 16 . . 0101....11111010 .......... . . U . . 6 +trapcc 32 . . 0101....11111011 .......... . . U . . 8 +trapv 0 . . 0100111001110110 .......... U U U 4 4 4 +tst 8 . d 0100101000000... .......... U U U 4 4 2 +tst 8 . . 0100101000...... A+-DXWL... U U U 4 4 2 +tst 8 . pcdi 0100101000111010 .......... . . U . . 7 +tst 8 . pcix 0100101000111011 .......... . . U . . 9 +tst 8 . i 0100101000111100 .......... . . U . . 6 +tst 16 . d 0100101001000... .......... U U U 4 4 2 +tst 16 . a 0100101001001... .......... . . U . . 2 +tst 16 . . 0100101001...... A+-DXWL... U U U 4 4 2 +tst 16 . pcdi 0100101001111010 .......... . . U . . 7 +tst 16 . pcix 0100101001111011 .......... . . U . . 9 +tst 16 . i 0100101001111100 .......... . . U . . 6 +tst 32 . d 0100101010000... .......... U U U 4 4 2 +tst 32 . a 0100101010001... .......... . . U . . 2 +tst 32 . . 0100101010...... A+-DXWL... U U U 4 4 2 +tst 32 . pcdi 0100101010111010 .......... . . U . . 7 +tst 32 . pcix 0100101010111011 .......... . . U . . 9 +tst 32 . i 0100101010111100 .......... . . U . . 6 +unlk 32 . a7 0100111001011111 .......... U U U 12 12 6 +unlk 32 . . 0100111001011... .......... U U U 12 12 6 +unpk 16 rr . 1000...110000... .......... . . U . . 8 +unpk 16 mm ax7 1000111110001... .......... . . U . . 13 +unpk 16 mm ay7 1000...110001111 .......... . . U . . 13 +unpk 16 mm axy7 1000111110001111 .......... . . U . . 13 +unpk 16 mm . 1000...110001... .......... . . U . . 13 + + + +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +M68KMAKE_OPCODE_HANDLER_BODY + +M68KMAKE_OP(1010, 0, ., .) +{ + m68ki_exception_1010(); +} + + +M68KMAKE_OP(1111, 0, ., .) +{ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + + 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; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(M68KMAKE_GET_OPER_AY_16)); +} + + +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* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + M68KMAKE_GET_OPER_AY_32); +} + + +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_16()); +} + + +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(GET_MSB_8(src)) + res |= m68ki_shift_8_table[shift]; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +M68KMAKE_OP(asr, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(GET_MSB_16(src)) + res |= m68ki_shift_16_table[shift]; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +M68KMAKE_OP(asr, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + if(GET_MSB_32(src)) + res |= m68ki_shift_32_table[shift]; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +M68KMAKE_OP(asr, 8, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> 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); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_X = FLAG_C = src << shift; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + src &= m68ki_shift_8_table[shift + 1]; + FLAG_V = (!(src == 0 || (src == m68ki_shift_8_table[shift + 1] && shift < 8)))<<7; +} + + +M68KMAKE_OP(asl, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (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); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (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; + } + m68ki_exception_illegal(); +} + + +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; + } + m68ki_exception_illegal(); +} + + +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; + } + m68ki_exception_illegal(); +} + + +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, ., .) +{ + 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) ? MAKE_INT_16(dest1) : MASK_OUT_BELOW_16(*compare1) | dest1; + *compare2 = BIT_F(word2) ? 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); + + 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); + + 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); + + 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); + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + 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(); + uint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = M68KMAKE_GET_EA_AY_8; + uint lower_bound = m68ki_read_8(ea); + uint upper_bound = m68ki_read_8(ea + 1); + + if(!BIT_F(word2)) + compare = MAKE_INT_8(compare); + + FLAG_C = compare - lower_bound; + FLAG_Z = MASK_OUT_ABOVE_8(FLAG_C); + if(COND_CS()) + { + if(BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + + FLAG_C = upper_bound - compare; + FLAG_Z = MASK_OUT_ABOVE_8(FLAG_C); + 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(); + uint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = M68KMAKE_GET_EA_AY_16; + uint lower_bound = m68ki_read_16(ea); + uint upper_bound = m68ki_read_16(ea + 1); + + if(!BIT_F(word2)) + compare = MAKE_INT_16(compare); + + FLAG_C = compare - lower_bound; + FLAG_Z = MASK_OUT_ABOVE_16(FLAG_C); + FLAG_C = CFLAG_16(FLAG_C); + if(COND_CS()) + { + if(BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + + FLAG_C = upper_bound - compare; + FLAG_Z = MASK_OUT_ABOVE_16(FLAG_C); + FLAG_C = CFLAG_16(FLAG_C); + 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(); + uint compare = REG_DA[(word2 >> 12) & 15]; + uint ea = M68KMAKE_GET_EA_AY_32; + uint lower_bound = m68ki_read_32(ea); + uint upper_bound = m68ki_read_32(ea + 1); + + FLAG_C = compare - lower_bound; + FLAG_Z = MASK_OUT_ABOVE_32(FLAG_C); + FLAG_C = CFLAG_SUB_32(lower_bound, compare, FLAG_C); + if(COND_CS()) + { + if(BIT_B(word2)) + m68ki_exception_trap(EXCEPTION_CHK); + return; + } + + FLAG_C = upper_bound - compare; + FLAG_Z = MASK_OUT_ABOVE_32(FLAG_C); + FLAG_C = CFLAG_SUB_32(compare, upper_bound, FLAG_C); + 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; + + 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)))); + 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); + return; + } + REG_PC += 2; +} + + +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_16()); +} + + +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; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsr, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsr, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + *r_dst = res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsr, 8, r, .) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> 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); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src << shift; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(lsl, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (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); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (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_32(ea, res); + + 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_32(ea, res); + + 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_32(ea, res); + + 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; + 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 */ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + REG_CACR = REG_DA[(word2 >> 12) & 15]; + 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; + 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<> 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(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) + { + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* officially undefined */ +} + + +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) + { + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* officially undefined */ +} + + +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_16()); +} + + +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(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); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = src << (9-orig_shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ror, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_16(src, shift); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ror, 32, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint res = ROR_32(src, shift); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(ror, 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 = ROR_8(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_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); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = src << orig_shift; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(rol, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_16(src, shift); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> (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); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = src >> (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)) << 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); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxr, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), shift); + + FLAG_C = FLAG_X = res >> 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); + + res = ROR_33_64(res, shift); + + FLAG_C = FLAG_X = res >> 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)); + + *r_dst = res; + + FLAG_C = FLAG_X = (new_x_flag != 0)<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +M68KMAKE_OP(roxr, 8, r, .) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 9; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_9(src | (XFLAG_AS_1() << 8), shift); + + USE_CYCLES(orig_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); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +M68KMAKE_OP(roxl, 16, s, .) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), shift); + + FLAG_C = FLAG_X = res >> 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); + + res = ROL_33_64(res, shift); + + FLAG_C = FLAG_X = res >> 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)); + + *r_dst = res; + + FLAG_C = FLAG_X = (new_x_flag != 0)<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +M68KMAKE_OP(roxl, 8, r, .) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + + if(orig_shift != 0) + { + uint shift = orig_shift % 9; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_9(src | (XFLAG_AS_1() << 8), shift); + + USE_CYCLES(orig_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_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); + 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); + return; + } + /* Not handling bus fault (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); + 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); + return; + } + /* Not handling long or short bus fault */ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + 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(); + + 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_N = NFLAG_8(res); /* officially undefined */ + 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; + 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); + m68ki_remaining_cycles = 0; + 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; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(M68KMAKE_GET_OPER_AY_16)); +} + + +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* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - M68KMAKE_GET_OPER_AY_32); +} + + +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); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + 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)) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapt, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + 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)) + { + if(M68KMAKE_CC) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + REG_PC += 2; + return; + } + m68ki_exception_illegal(); +} + + +M68KMAKE_OP(trapcc, 32, ., .) +{ + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) + { + if(M68KMAKE_CC) + { + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ + return; + } + REG_PC += 4; + 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 ea = M68KMAKE_GET_EA_AY_8; + uint res = m68ki_read_8(ea); + + 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/src/m68kconf.h b/src/m68kconf.h new file mode 100644 index 0000000..a38613f --- /dev/null +++ b/src/m68kconf.h @@ -0,0 +1,194 @@ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + +#ifndef M68KCONF__HEADER +#define M68KCONF__HEADER + + +/* Configuration switches. + * Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks. + * OPT_SPECIFY_HANDLER causes the core to link directly to the function + * or macro you specify, rather than using callback functions whose pointer + * must be passed in using m68k_set_xxx_callback(). + */ +#define OPT_OFF 0 +#define OPT_ON 1 +#define OPT_SPECIFY_HANDLER 2 + + +/* ======================================================================== */ +/* ============================== MAME STUFF ============================== */ +/* ======================================================================== */ + +/* If you're compiling this for MAME, only change M68K_COMPILE_FOR_MAME + * to OPT_ON and use m68kmame.h to configure the 68k core. + */ +#ifndef M68K_COMPILE_FOR_MAME +#define M68K_COMPILE_FOR_MAME OPT_OFF +#endif /* M68K_COMPILE_FOR_MAME */ + +#if M68K_COMPILE_FOR_MAME == OPT_ON +#include "m68kmame.h" +#else + + + +/* ======================================================================== */ +/* ============================= CONFIGURATION ============================ */ +/* ======================================================================== */ + +/* Turn on if you want to use the following M68K variants */ +#define M68K_EMULATE_010 OPT_OFF +#define M68K_EMULATE_EC020 OPT_OFF +#define M68K_EMULATE_020 OPT_OFF + + +/* If on, the CPU will call m68k_read_immediate_xx() for immediate addressing + * and m68k_read_pcrelative_xx() for PC-relative addressing. + * If off, all read requests from the CPU will be redirected to m68k_read_xx() + */ +#define M68K_SEPARATE_READS OPT_OFF + + +/* If on, CPU will call the interrupt acknowledge callback when it services an + * interrupt. + * If off, all interrupts will be autovectored and all interrupt requests will + * auto-clear when the interrupt is serviced. + */ +//#define M68K_EMULATE_INT_ACK OPT_OFF +//#define M68K_INT_ACK_CALLBACK(A) your_int_ack_handler_function(A) + +//#ifdef __cplusplus +//extern "C" { +//#endif +int irq_ack_handler(int); +//#ifdef __cplusplus +//} +//#endif + +#define M68K_EMULATE_INT_ACK OPT_SPECIFY_HANDLER +#define M68K_INT_ACK_CALLBACK(A) irq_ack_handler(A) + + +/* If on, CPU will call the breakpoint acknowledge callback when it encounters + * a breakpoint instruction and it is running a 68010+. + */ +#define M68K_EMULATE_BKPT_ACK OPT_OFF +#define M68K_BKPT_ACK_CALLBACK() your_bkpt_ack_handler_function() + + +/* If on, the CPU will monitor the trace flags and take trace exceptions + */ +#define M68K_EMULATE_TRACE OPT_OFF + + +/* If on, CPU will call the output reset callback when it encounters a reset + * instruction. + */ +#define M68K_EMULATE_RESET OPT_OFF +#define M68K_RESET_CALLBACK() your_reset_handler_function() + + +/* If on, CPU will call the set fc callback on every memory access to + * differentiate between user/supervisor, program/data access like a real + * 68000 would. This should be enabled and the callback should be set if you + * want to properly emulate the m68010 or higher. (moves uses function codes + * to read/write data from different address spaces) + */ +#define M68K_EMULATE_FC OPT_OFF +#define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A) + + +/* If on, CPU will call the pc changed callback when it changes the PC by a + * large value. This allows host programs to be nicer when it comes to + * fetching immediate data and instructions on a banked memory system. + */ +#define M68K_MONITOR_PC OPT_OFF +#define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A) + + +/* If on, CPU will call the instruction hook callback before every + * instruction. + */ +#define M68K_INSTRUCTION_HOOK OPT_OFF +#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function() + + +/* If on, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ +#define M68K_EMULATE_PREFETCH OPT_OFF + + +/* If on, the CPU will generate address error exceptions if it tries to + * access a word or longword at an odd address. + * NOTE: Do not enable this! It is not working! + */ +#define M68K_EMULATE_ADDRESS_ERROR OPT_OFF + + +/* Turn on to enable logging of illegal instruction calls. + * M68K_LOG_FILEHANDLE must be #defined to a stdio file stream. + * Turn on M68K_LOG_1010_1111 to log all 1010 and 1111 calls. + */ +#define M68K_LOG_ENABLE OPT_OFF +#define M68K_LOG_1010_1111 OPT_OFF +#define M68K_LOG_FILEHANDLE some_file_handle + + +/* ----------------------------- COMPATIBILITY ---------------------------- */ + +/* The following options set optimizations that violate the current ANSI + * standard, but will be compliant under the forthcoming C9X standard. + */ + + +/* If on, the enulation core will use 64-bit integers to speed up some + * operations. +*/ +#define M68K_USE_64_BIT OPT_OFF + + +/* Set to your compiler's static inline keyword to enable it, or + * set it to blank to disable it. + * If you define INLINE in the makefile, it will override this value. + * NOTE: not enabling inline functions will SEVERELY slow down emulation. + */ +#ifndef INLINE +#define INLINE static __inline__ +#endif /* INLINE */ + + +/* If your environment requires special prefixes for system callback functions + * such as the argument to qsort(), then set them here or in the makefile. + */ +#ifndef DECL_SPEC +#define DECL_SPEC +#endif + +#endif /* M68K_COMPILE_FOR_MAME */ + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCONF__HEADER */ diff --git a/src/m68kcpu.c b/src/m68kcpu.c new file mode 100644 index 0000000..e979343 --- /dev/null +++ b/src/m68kcpu.c @@ -0,0 +1,894 @@ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ + +#if 0 +static const char* copyright_notice = +"MUSASHI\n" +"Version 3.3 (2001-01-29)\n" +"A portable Motorola M680x0 processor emulation engine.\n" +"Copyright 1998-2001 Karl Stenerud. All rights reserved.\n" +"\n" +"This code may be freely used for non-commercial purpooses as long as this\n" +"copyright notice remains unaltered in the source code and any binary files\n" +"containing this code in compiled form.\n" +"\n" +"All other lisencing terms must be negotiated with the author\n" +"(Karl Stenerud).\n" +"\n" +"The latest version of this code can be obtained at:\n" +"http://kstenerud.cjb.net\n" +; +#endif + + +/* ======================================================================== */ +/* ================================= NOTES ================================ */ +/* ======================================================================== */ + + + +/* ======================================================================== */ +/* ================================ INCLUDES ============================== */ +/* ======================================================================== */ + +#include "m68kops.h" +#include "m68kcpu.h" + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +int m68ki_initial_cycles; +int m68ki_remaining_cycles = 0; /* Number of clocks remaining */ +uint m68ki_tracing = 0; +uint m68ki_address_space; + +#ifdef M68K_LOG_ENABLE +char* m68ki_cpu_names[9] = +{ + "Invalid CPU", + "M68000", + "M68010", + "Invalid CPU", + "M68EC020" + "Invalid CPU", + "Invalid CPU", + "Invalid CPU", + "M68020" +}; +#endif /* M68K_LOG_ENABLE */ + +/* The CPU core */ +m68ki_cpu_core m68ki_cpu = {0}; + +#if M68K_EMULATE_ADDRESS_ERROR +jmp_buf m68ki_address_error_trap; +#endif /* M68K_EMULATE_ADDRESS_ERROR */ + +/* Used by shift & rotate instructions */ +uint8 m68ki_shift_8_table[65] = +{ + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +}; +uint16 m68ki_shift_16_table[65] = +{ + 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, + 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff +}; +uint m68ki_shift_32_table[65] = +{ + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, + 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, + 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, + 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff +}; + + +/* Number of clock cycles to use for exception processing. + * I used 4 for any vectors that are undocumented for processing times. + */ +uint8 m68ki_exception_cycle_table[3][256] = +{ + { /* 000 */ + 4, /* 0: Reset - Initial Stack Pointer */ + 4, /* 1: Reset - Initial Program Counter */ + 50, /* 2: Bus Error (unemulated) */ + 50, /* 3: Address Error (unemulated) */ + 34, /* 4: Illegal Instruction */ + 38, /* 5: Divide by Zero -- ASG: changed from 42 */ + 40, /* 6: CHK -- ASG: chanaged from 44 */ + 34, /* 7: TRAPV */ + 34, /* 8: Privilege Violation */ + 34, /* 9: Trace */ + 4, /* 10: 1010 */ + 4, /* 11: 1111 */ + 4, /* 12: RESERVED */ + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ + 4, /* 14: Format Error */ + 44, /* 15: Uninitialized Interrupt */ + 4, /* 16: RESERVED */ + 4, /* 17: RESERVED */ + 4, /* 18: RESERVED */ + 4, /* 19: RESERVED */ + 4, /* 20: RESERVED */ + 4, /* 21: RESERVED */ + 4, /* 22: RESERVED */ + 4, /* 23: RESERVED */ + 44, /* 24: Spurious Interrupt */ + 44, /* 25: Level 1 Interrupt Autovector */ + 44, /* 26: Level 2 Interrupt Autovector */ + 44, /* 27: Level 3 Interrupt Autovector */ + 44, /* 28: Level 4 Interrupt Autovector */ + 44, /* 29: Level 5 Interrupt Autovector */ + 44, /* 30: Level 6 Interrupt Autovector */ + 44, /* 31: Level 7 Interrupt Autovector */ + 34, /* 32: TRAP #0 -- ASG: chanaged from 38 */ + 34, /* 33: TRAP #1 */ + 34, /* 34: TRAP #2 */ + 34, /* 35: TRAP #3 */ + 34, /* 36: TRAP #4 */ + 34, /* 37: TRAP #5 */ + 34, /* 38: TRAP #6 */ + 34, /* 39: TRAP #7 */ + 34, /* 40: TRAP #8 */ + 34, /* 41: TRAP #9 */ + 34, /* 42: TRAP #10 */ + 34, /* 43: TRAP #11 */ + 34, /* 44: TRAP #12 */ + 34, /* 45: TRAP #13 */ + 34, /* 46: TRAP #14 */ + 34, /* 47: TRAP #15 */ + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ + 4, /* 49: FP Inexact Result (unemulated) */ + 4, /* 50: FP Divide by Zero (unemulated) */ + 4, /* 51: FP Underflow (unemulated) */ + 4, /* 52: FP Operand Error (unemulated) */ + 4, /* 53: FP Overflow (unemulated) */ + 4, /* 54: FP Signaling NAN (unemulated) */ + 4, /* 55: FP Unimplemented Data Type (unemulated) */ + 4, /* 56: MMU Configuration Error (unemulated) */ + 4, /* 57: MMU Illegal Operation Error (unemulated) */ + 4, /* 58: MMU Access Level Violation Error (unemulated) */ + 4, /* 59: RESERVED */ + 4, /* 60: RESERVED */ + 4, /* 61: RESERVED */ + 4, /* 62: RESERVED */ + 4, /* 63: RESERVED */ + /* 64-255: User Defined */ + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 + }, + { /* 010 */ + 4, /* 0: Reset - Initial Stack Pointer */ + 4, /* 1: Reset - Initial Program Counter */ + 126, /* 2: Bus Error (unemulated) */ + 126, /* 3: Address Error (unemulated) */ + 38, /* 4: Illegal Instruction */ + 44, /* 5: Divide by Zero */ + 44, /* 6: CHK */ + 34, /* 7: TRAPV */ + 38, /* 8: Privilege Violation */ + 38, /* 9: Trace */ + 4, /* 10: 1010 */ + 4, /* 11: 1111 */ + 4, /* 12: RESERVED */ + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ + 4, /* 14: Format Error */ + 44, /* 15: Uninitialized Interrupt */ + 4, /* 16: RESERVED */ + 4, /* 17: RESERVED */ + 4, /* 18: RESERVED */ + 4, /* 19: RESERVED */ + 4, /* 20: RESERVED */ + 4, /* 21: RESERVED */ + 4, /* 22: RESERVED */ + 4, /* 23: RESERVED */ + 46, /* 24: Spurious Interrupt */ + 46, /* 25: Level 1 Interrupt Autovector */ + 46, /* 26: Level 2 Interrupt Autovector */ + 46, /* 27: Level 3 Interrupt Autovector */ + 46, /* 28: Level 4 Interrupt Autovector */ + 46, /* 29: Level 5 Interrupt Autovector */ + 46, /* 30: Level 6 Interrupt Autovector */ + 46, /* 31: Level 7 Interrupt Autovector */ + 38, /* 32: TRAP #0 */ + 38, /* 33: TRAP #1 */ + 38, /* 34: TRAP #2 */ + 38, /* 35: TRAP #3 */ + 38, /* 36: TRAP #4 */ + 38, /* 37: TRAP #5 */ + 38, /* 38: TRAP #6 */ + 38, /* 39: TRAP #7 */ + 38, /* 40: TRAP #8 */ + 38, /* 41: TRAP #9 */ + 38, /* 42: TRAP #10 */ + 38, /* 43: TRAP #11 */ + 38, /* 44: TRAP #12 */ + 38, /* 45: TRAP #13 */ + 38, /* 46: TRAP #14 */ + 38, /* 47: TRAP #15 */ + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ + 4, /* 49: FP Inexact Result (unemulated) */ + 4, /* 50: FP Divide by Zero (unemulated) */ + 4, /* 51: FP Underflow (unemulated) */ + 4, /* 52: FP Operand Error (unemulated) */ + 4, /* 53: FP Overflow (unemulated) */ + 4, /* 54: FP Signaling NAN (unemulated) */ + 4, /* 55: FP Unimplemented Data Type (unemulated) */ + 4, /* 56: MMU Configuration Error (unemulated) */ + 4, /* 57: MMU Illegal Operation Error (unemulated) */ + 4, /* 58: MMU Access Level Violation Error (unemulated) */ + 4, /* 59: RESERVED */ + 4, /* 60: RESERVED */ + 4, /* 61: RESERVED */ + 4, /* 62: RESERVED */ + 4, /* 63: RESERVED */ + /* 64-255: User Defined */ + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 + }, + { /* 020 */ + 4, /* 0: Reset - Initial Stack Pointer */ + 4, /* 1: Reset - Initial Program Counter */ + 50, /* 2: Bus Error (unemulated) */ + 50, /* 3: Address Error (unemulated) */ + 20, /* 4: Illegal Instruction */ + 38, /* 5: Divide by Zero */ + 40, /* 6: CHK */ + 20, /* 7: TRAPV */ + 34, /* 8: Privilege Violation */ + 25, /* 9: Trace */ + 20, /* 10: 1010 */ + 20, /* 11: 1111 */ + 4, /* 12: RESERVED */ + 4, /* 13: Coprocessor Protocol Violation (unemulated) */ + 4, /* 14: Format Error */ + 30, /* 15: Uninitialized Interrupt */ + 4, /* 16: RESERVED */ + 4, /* 17: RESERVED */ + 4, /* 18: RESERVED */ + 4, /* 19: RESERVED */ + 4, /* 20: RESERVED */ + 4, /* 21: RESERVED */ + 4, /* 22: RESERVED */ + 4, /* 23: RESERVED */ + 30, /* 24: Spurious Interrupt */ + 30, /* 25: Level 1 Interrupt Autovector */ + 30, /* 26: Level 2 Interrupt Autovector */ + 30, /* 27: Level 3 Interrupt Autovector */ + 30, /* 28: Level 4 Interrupt Autovector */ + 30, /* 29: Level 5 Interrupt Autovector */ + 30, /* 30: Level 6 Interrupt Autovector */ + 30, /* 31: Level 7 Interrupt Autovector */ + 20, /* 32: TRAP #0 */ + 20, /* 33: TRAP #1 */ + 20, /* 34: TRAP #2 */ + 20, /* 35: TRAP #3 */ + 20, /* 36: TRAP #4 */ + 20, /* 37: TRAP #5 */ + 20, /* 38: TRAP #6 */ + 20, /* 39: TRAP #7 */ + 20, /* 40: TRAP #8 */ + 20, /* 41: TRAP #9 */ + 20, /* 42: TRAP #10 */ + 20, /* 43: TRAP #11 */ + 20, /* 44: TRAP #12 */ + 20, /* 45: TRAP #13 */ + 20, /* 46: TRAP #14 */ + 20, /* 47: TRAP #15 */ + 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ + 4, /* 49: FP Inexact Result (unemulated) */ + 4, /* 50: FP Divide by Zero (unemulated) */ + 4, /* 51: FP Underflow (unemulated) */ + 4, /* 52: FP Operand Error (unemulated) */ + 4, /* 53: FP Overflow (unemulated) */ + 4, /* 54: FP Signaling NAN (unemulated) */ + 4, /* 55: FP Unimplemented Data Type (unemulated) */ + 4, /* 56: MMU Configuration Error (unemulated) */ + 4, /* 57: MMU Illegal Operation Error (unemulated) */ + 4, /* 58: MMU Access Level Violation Error (unemulated) */ + 4, /* 59: RESERVED */ + 4, /* 60: RESERVED */ + 4, /* 61: RESERVED */ + 4, /* 62: RESERVED */ + 4, /* 63: RESERVED */ + /* 64-255: User Defined */ + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 + } +}; + +uint8 m68ki_ea_idx_cycle_table[64] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* ..01.000 no memory indirect, base NULL */ + 5, /* ..01..01 memory indirect, base NULL, outer NULL */ + 7, /* ..01..10 memory indirect, base NULL, outer 16 */ + 7, /* ..01..11 memory indirect, base NULL, outer 32 */ + 0, 5, 7, 7, 0, 5, 7, 7, 0, 5, 7, 7, + 2, /* ..10.000 no memory indirect, base 16 */ + 7, /* ..10..01 memory indirect, base 16, outer NULL */ + 9, /* ..10..10 memory indirect, base 16, outer 16 */ + 9, /* ..10..11 memory indirect, base 16, outer 32 */ + 0, 7, 9, 9, 0, 7, 9, 9, 0, 7, 9, 9, + 6, /* ..11.000 no memory indirect, base 32 */ + 11, /* ..11..01 memory indirect, base 32, outer NULL */ + 13, /* ..11..10 memory indirect, base 32, outer 16 */ + 13, /* ..11..11 memory indirect, base 32, outer 32 */ + 0, 11, 13, 13, 0, 11, 13, 13, 0, 11, 13, 13 +}; + + + +/* ======================================================================== */ +/* =============================== CALLBACKS ============================== */ +/* ======================================================================== */ + +/* Default callbacks used if the callback hasn't been set yet, or if the + * callback is set to NULL + */ + +/* Interrupt acknowledge */ +static int default_int_ack_callback_data; +static int default_int_ack_callback(int int_level) +{ + default_int_ack_callback_data = int_level; + CPU_INT_LEVEL = 0; + return M68K_INT_ACK_AUTOVECTOR; +} + +/* Breakpoint acknowledge */ +static unsigned int default_bkpt_ack_callback_data; +static void default_bkpt_ack_callback(unsigned int data) +{ + default_bkpt_ack_callback_data = data; +} + +/* Called when a reset instruction is executed */ +static void default_reset_instr_callback(void) +{ +} + +/* Called when the program counter changed by a large value */ +static unsigned int default_pc_changed_callback_data; +static void default_pc_changed_callback(unsigned int new_pc) +{ + default_pc_changed_callback_data = new_pc; +} + +/* Called every time there's bus activity (read/write to/from memory */ +static unsigned int default_set_fc_callback_data; +static void default_set_fc_callback(unsigned int new_fc) +{ + default_set_fc_callback_data = new_fc; +} + +/* Called every instruction cycle prior to execution */ +static void default_instr_hook_callback(void) +{ +} + + + +/* ======================================================================== */ +/* ================================= API ================================== */ +/* ======================================================================== */ + +/* 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; + + 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; + } + 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(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; +} + +void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data)) +{ + 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; +} + +void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc)) +{ + 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; +} + +void m68k_set_instr_hook_callback(void (*callback)(void)) +{ + CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback; +} + +#include +/* 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_FALSE = 2; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 3; + CYC_SHIFT = 1; + CYC_RESET = 132; + 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_FALSE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 3; + CYC_SHIFT = 1; + CYC_RESET = 130; + 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_FALSE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + 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_FALSE = 0; + CYC_MOVEM_W = 2; + CYC_MOVEM_L = 2; + CYC_SHIFT = 0; + CYC_RESET = 518; + return; + } +} + +/* Execute some instructions until we use up num_cycles clock cycles */ +/* ASG: removed per-instruction interrupt checks */ +int m68k_execute(int num_cycles) +{ + /* Make sure we're not stopped */ + if(!CPU_STOPPED) + { + /* Set our pool of clock cycles available */ + SET_CYCLES(num_cycles); + m68ki_initial_cycles = num_cycles; + + /* ASG: update cycles */ + USE_CYCLES(CPU_INT_CYCLES); + CPU_INT_CYCLES = 0; + + /* Return point if we had an address error */ + m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */ + + /* Main loop. Keep going until we run out of clock cycles */ + do + { + /* 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) */ + + /* Call external hook to peek at CPU */ + m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */ + + /* Record previous program counter */ + REG_PPC = REG_PC; + + /* 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); + + /* set previous PC to current PC for the next entry into the loop */ + REG_PPC = REG_PC; + + /* ASG: update cycles */ + USE_CYCLES(CPU_INT_CYCLES); + CPU_INT_CYCLES = 0; + + /* return how many clocks we used */ + return m68ki_initial_cycles - GET_CYCLES(); + } + + /* We get here if the CPU is stopped or halted */ + SET_CYCLES(0); + CPU_INT_CYCLES = 0; + + return num_cycles; +} + + +int m68k_cycles_run(void) +{ + return m68ki_initial_cycles - GET_CYCLES(); +} + +int m68k_cycles_remaining(void) +{ + return GET_CYCLES(); +} + +/* Change the timeslice */ +void m68k_modify_timeslice(int cycles) +{ + m68ki_initial_cycles += cycles; + ADD_CYCLES(cycles); +} + + +void m68k_end_timeslice(void) +{ + m68ki_initial_cycles = GET_CYCLES(); + SET_CYCLES(0); +} + + +/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */ +/* KS: Modified so that IPL* bits match with mask positions in the SR + * and cleaned out remenants of the interrupt controller. + */ +void m68k_set_irq(unsigned int int_level) +{ + 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_exception_interrupt(7); /* Edge triggered level 7 (NMI) */ + else + m68ki_check_interrupts(); /* Level triggered (IRQ) */ +} + + +/* Pulse the RESET line on the CPU */ +void m68k_pulse_reset(void) +{ + static uint emulation_initialized = 0; + + /* The first call to this function initializes the opcode handler jump table */ + if(!emulation_initialized) + { + m68ki_build_opcode_table(); + m68k_set_int_ack_callback(NULL); + m68k_set_bkpt_ack_callback(NULL); + m68k_set_reset_instr_callback(NULL); + m68k_set_pc_changed_callback(NULL); + m68k_set_fc_callback(NULL); + m68k_set_instr_hook_callback(NULL); + + emulation_initialized = 1; + } + + + if(CPU_TYPE == 0) /* KW 990319 */ + m68k_set_cpu_type(M68K_CPU_TYPE_68000); + + /* Clear all stop levels and eat up all remaining cycles */ + CPU_STOPPED = 0; + SET_CYCLES(0); + + /* Turn off tracing */ + FLAG_T1 = FLAG_T0 = 0; + m68ki_clear_trace(); + /* Interrupt mask to level 7 */ + FLAG_INT_MASK = 0x0700; + /* Reset VBR */ + REG_VBR = 0; + /* Go to supervisor mode */ + m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); + + /* Invalidate the prefetch queue */ +#if M68K_EMULATE_PREFETCH + /* 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); +} + +/* Pulse the HALT line on the CPU */ +void m68k_pulse_halt(void) +{ + 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); +} + +unsigned int m68k_get_context(void* dst) +{ + 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; +} + +void m68k_save_context( void (*save_value)(char*, unsigned int)) +{ + if(!save_value) + return; + + save_value("CPU_TYPE" , m68k_get_reg(NULL, M68K_REG_CPU_TYPE)); + save_value("D0" , REG_D[0]); + save_value("D1" , REG_D[1]); + save_value("D2" , REG_D[2]); + save_value("D3" , REG_D[3]); + save_value("D4" , REG_D[4]); + save_value("D5" , REG_D[5]); + save_value("D6" , REG_D[6]); + save_value("D7" , REG_D[7]); + save_value("A0" , REG_A[0]); + save_value("A1" , REG_A[1]); + save_value("A2" , REG_A[2]); + save_value("A3" , REG_A[3]); + save_value("A4" , REG_A[4]); + save_value("A5" , REG_A[5]); + save_value("A6" , REG_A[6]); + save_value("A7" , REG_A[7]); + save_value("PPC" , REG_PPC); + save_value("PC" , REG_PC); + save_value("USP" , REG_USP); + save_value("ISP" , REG_ISP); + save_value("MSP" , REG_MSP); + save_value("VBR" , REG_VBR); + save_value("SFC" , REG_SFC); + save_value("DFC" , REG_DFC); + save_value("CACR" , REG_CACR); + save_value("CAAR" , REG_CAAR); + save_value("SR" , m68ki_get_sr()); + save_value("INT_LEVEL" , CPU_INT_LEVEL); + save_value("INT_CYCLES", CPU_INT_CYCLES); + save_value("STOPPED" , (CPU_STOPPED & STOP_LEVEL_STOP) != 0); + save_value("HALTED" , (CPU_STOPPED & STOP_LEVEL_HALT) != 0); + save_value("PREF_ADDR" , CPU_PREF_ADDR); + save_value("PREF_DATA" , CPU_PREF_DATA); +} + +void m68k_load_context(unsigned int (*load_value)(char*)) +{ + unsigned int temp; + + m68k_set_cpu_type(load_value("CPU_TYPE")); + REG_PPC = load_value("PPC"); + REG_PC = load_value("PC"); + m68ki_jump(REG_PC); + CPU_INT_LEVEL = 0; + m68ki_set_sr_noint(load_value("SR")); + REG_D[0] = load_value("D0"); + REG_D[1] = load_value("D1"); + REG_D[2] = load_value("D2"); + REG_D[3] = load_value("D3"); + REG_D[4] = load_value("D4"); + REG_D[5] = load_value("D5"); + REG_D[6] = load_value("D6"); + REG_D[7] = load_value("D7"); + REG_A[0] = load_value("A0"); + REG_A[1] = load_value("A1"); + REG_A[2] = load_value("A2"); + REG_A[3] = load_value("A3"); + REG_A[4] = load_value("A4"); + REG_A[5] = load_value("A5"); + REG_A[6] = load_value("A6"); + REG_A[7] = load_value("A7"); + REG_USP = load_value("USP"); + REG_ISP = load_value("ISP"); + REG_MSP = load_value("MSP"); + REG_VBR = load_value("VBR"); + REG_SFC = load_value("SFC"); + REG_DFC = load_value("DFC"); + REG_CACR = load_value("CACR"); + REG_CAAR = load_value("CAAR"); + CPU_INT_LEVEL = load_value("INT_LEVEL"); + CPU_INT_CYCLES = load_value("INT_CYCLES"); + + CPU_STOPPED = 0; + temp = load_value("STOPPED"); + if(temp) CPU_STOPPED |= STOP_LEVEL_STOP; + temp = load_value("HALTED"); + if(temp) CPU_STOPPED |= STOP_LEVEL_HALT; + + CPU_PREF_ADDR = load_value("PREF_ADDR"); + CPU_PREF_DATA = load_value("PREF_DATA"); +} + + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ diff --git a/src/m68kcpu.h b/src/m68kcpu.h new file mode 100644 index 0000000..6ea7a57 --- /dev/null +++ b/src/m68kcpu.h @@ -0,0 +1,1838 @@ +#include +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + + +#ifndef M68KCPU__HEADER +#define M68KCPU__HEADER + +#include "m68k.h" +#include + +#if M68K_EMULATE_ADDRESS_ERROR +#include +#endif /* M68K_EMULATE_ADDRESS_ERROR */ + +/* ======================================================================== */ +/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */ +/* ======================================================================== */ + +/* Check for > 32bit sizes */ +#if UINT_MAX > 0xffffffff + #define M68K_INT_GT_32_BIT 1 +#endif + +/* Data types used in this emulation core */ +#undef sint8 +#undef sint16 +#undef sint32 +#undef sint64 +#undef uint8 +#undef uint16 +#undef uint32 +#undef uint64 +#undef sint +#undef uint + +#define sint8 signed char /* ASG: changed from char to signed char */ +#define sint16 signed short +#define sint32 signed long +#define uint8 unsigned char +#define uint16 unsigned short +#define uint32 unsigned long + +/* signed and unsigned int must be at least 32 bits wide */ +#define sint signed int +#define uint unsigned int + + +#if M68K_USE_64_BIT +#define sint64 signed long long +#define uint64 unsigned long long +#else +#define sint64 sint32 +#define uint64 uint32 +#endif /* M68K_USE_64_BIT */ + + + +/* Allow for architectures that don't have 8-bit sizes */ +#if UCHAR_MAX == 0xff + #define MAKE_INT_8(A) (sint8)(A) +#else + #undef sint8 + #define sint8 signed int + #undef uint8 + #define uint8 unsigned int + 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) +#else + #undef sint16 + #define sint16 signed int + #undef uint16 + #define uint16 unsigned int + 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 ULONG_MAX == 0xffffffff + #define MAKE_INT_32(A) (sint32)(A) +#else + #undef sint32 + #define sint32 signed int + #undef uint32 + #define uint32 unsigned int + INLINE sint MAKE_INT_32(uint value) + { + return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; + } +#endif /* ULONG_MAX == 0xffffffff */ + + + + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ +/* ======================================================================== */ + +/* Exception Vectors handled by emulation */ +#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ +#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ +#define EXCEPTION_ILLEGAL_INSTRUCTION 4 +#define EXCEPTION_ZERO_DIVIDE 5 +#define EXCEPTION_CHK 6 +#define EXCEPTION_TRAPV 7 +#define EXCEPTION_PRIVILEGE_VIOLATION 8 +#define EXCEPTION_TRACE 9 +#define EXCEPTION_1010 10 +#define EXCEPTION_1111 11 +#define EXCEPTION_FORMAT_ERROR 14 +#define EXCEPTION_UNINITIALIZED_INTERRUPT 15 +#define EXCEPTION_SPURIOUS_INTERRUPT 24 +#define EXCEPTION_INTERRUPT_AUTOVECTOR 24 +#define EXCEPTION_TRAP_BASE 32 + +/* Function codes set by CPU during data/address bus activity */ +#define FUNCTION_CODE_USER_DATA 1 +#define FUNCTION_CODE_USER_PROGRAM 2 +#define FUNCTION_CODE_SUPERVISOR_DATA 5 +#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 +#define FUNCTION_CODE_CPU_SPACE 7 + +/* CPU types for deciding what to emulate */ +#define CPU_TYPE_000 1 +#define CPU_TYPE_010 2 +#define CPU_TYPE_EC020 4 +#define CPU_TYPE_020 8 + +/* Different ways to stop the CPU */ +#define STOP_LEVEL_STOP 1 +#define STOP_LEVEL_HALT 2 + +#ifndef NULL +#define NULL ((void*)0) +#endif + +/* ======================================================================== */ +/* ================================ MACROS ================================ */ +/* ======================================================================== */ + + +/* ---------------------------- General Macros ---------------------------- */ + +/* Bit Isolation Macros */ +#define BIT_0(A) ((A) & 0x00000001) +#define BIT_1(A) ((A) & 0x00000002) +#define BIT_2(A) ((A) & 0x00000004) +#define BIT_3(A) ((A) & 0x00000008) +#define BIT_4(A) ((A) & 0x00000010) +#define BIT_5(A) ((A) & 0x00000020) +#define BIT_6(A) ((A) & 0x00000040) +#define BIT_7(A) ((A) & 0x00000080) +#define BIT_8(A) ((A) & 0x00000100) +#define BIT_9(A) ((A) & 0x00000200) +#define BIT_A(A) ((A) & 0x00000400) +#define BIT_B(A) ((A) & 0x00000800) +#define BIT_C(A) ((A) & 0x00001000) +#define BIT_D(A) ((A) & 0x00002000) +#define BIT_E(A) ((A) & 0x00004000) +#define BIT_F(A) ((A) & 0x00008000) +#define BIT_10(A) ((A) & 0x00010000) +#define BIT_11(A) ((A) & 0x00020000) +#define BIT_12(A) ((A) & 0x00040000) +#define BIT_13(A) ((A) & 0x00080000) +#define BIT_14(A) ((A) & 0x00100000) +#define BIT_15(A) ((A) & 0x00200000) +#define BIT_16(A) ((A) & 0x00400000) +#define BIT_17(A) ((A) & 0x00800000) +#define BIT_18(A) ((A) & 0x01000000) +#define BIT_19(A) ((A) & 0x02000000) +#define BIT_1A(A) ((A) & 0x04000000) +#define BIT_1B(A) ((A) & 0x08000000) +#define BIT_1C(A) ((A) & 0x10000000) +#define BIT_1D(A) ((A) & 0x20000000) +#define BIT_1E(A) ((A) & 0x40000000) +#define BIT_1F(A) ((A) & 0x80000000) + +/* Get the most significant bit for specific sizes */ +#define GET_MSB_8(A) ((A) & 0x80) +#define GET_MSB_9(A) ((A) & 0x100) +#define GET_MSB_16(A) ((A) & 0x8000) +#define GET_MSB_17(A) ((A) & 0x10000) +#define GET_MSB_32(A) ((A) & 0x80000000) +#if M68K_USE_64_BIT +#define GET_MSB_33(A) ((A) & 0x100000000) +#endif /* M68K_USE_64_BIT */ + +/* Isolate nibbles */ +#define LOW_NIBBLE(A) ((A) & 0x0f) +#define HIGH_NIBBLE(A) ((A) & 0xf0) + +/* These are used to isolate 8, 16, and 32 bit sizes */ +#define MASK_OUT_ABOVE_2(A) ((A) & 3) +#define MASK_OUT_ABOVE_8(A) ((A) & 0xff) +#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) +#define MASK_OUT_BELOW_2(A) ((A) & ~3) +#define MASK_OUT_BELOW_8(A) ((A) & ~0xff) +#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) + +/* No need to mask if we are 32 bit */ +#if M68K_INT_GT_32BIT || M68K_USE_64_BIT + #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 +#endif /* M68K_INT_GT_32BIT || M68K_USE_64_BIT */ + +/* Simulate address lines of 68k family */ +#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK) + + +/* Shift & Rotate Macros. */ +#define LSL(A, C) ((A) << (C)) +#define LSR(A, C) ((A) >> (C)) + +/* Some > 32-bit optimizations */ +#if M68K_INT_GT_32BIT + /* 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) +#endif /* M68K_INT_GT_32BIT */ + +#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))) +#endif /* M68K_USE_64_BIT */ + +#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) +#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) +#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) +#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) +#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) +#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) + +#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) +#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) +#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) +#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) +#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) +#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) + + + +/* ------------------------------ CPU Access ------------------------------ */ + +/* Access the CPU registers */ +#define CPU_TYPE m68ki_cpu.cpu_type + +#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ +#define REG_D m68ki_cpu.dar +#define REG_A (m68ki_cpu.dar+8) +#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] +#define REG_ISP m68ki_cpu.sp[4] +#define REG_MSP m68ki_cpu.sp[6] +#define REG_SP m68ki_cpu.dar[15] +#define REG_VBR m68ki_cpu.vbr +#define REG_SFC m68ki_cpu.sfc +#define REG_DFC m68ki_cpu.dfc +#define REG_CACR m68ki_cpu.cacr +#define REG_CAAR m68ki_cpu.caar +#define REG_IR m68ki_cpu.ir + +#define FLAG_T1 m68ki_cpu.t1_flag +#define FLAG_T0 m68ki_cpu.t0_flag +#define FLAG_S m68ki_cpu.s_flag +#define FLAG_M m68ki_cpu.m_flag +#define FLAG_X m68ki_cpu.x_flag +#define FLAG_N m68ki_cpu.n_flag +#define FLAG_Z m68ki_cpu.not_z_flag +#define FLAG_V m68ki_cpu.v_flag +#define FLAG_C m68ki_cpu.c_flag +#define FLAG_INT_MASK m68ki_cpu.int_mask + +#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */ +#define CPU_INT_CYCLES m68ki_cpu.int_cycles /* ASG */ +#define CPU_STOPPED m68ki_cpu.stopped +#define CPU_PREF_ADDR m68ki_cpu.pref_addr +#define CPU_PREF_DATA m68ki_cpu.pref_data +#define CPU_ADDRESS_MASK m68ki_cpu.address_mask +#define CPU_SR_MASK m68ki_cpu.sr_mask + +#define CYC_INSTRUCTION m68ki_cpu.cyc_instruction +#define CYC_EXCEPTION m68ki_cpu.cyc_exception +#define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b +#define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w +#define CYC_DBCC_F_NOEXP m68ki_cpu.cyc_dbcc_f_noexp +#define CYC_DBCC_F_EXP m68ki_cpu.cyc_dbcc_f_exp +#define CYC_SCC_R_FALSE m68ki_cpu.cyc_scc_r_false +#define CYC_MOVEM_W m68ki_cpu.cyc_movem_w +#define CYC_MOVEM_L m68ki_cpu.cyc_movem_l +#define CYC_SHIFT m68ki_cpu.cyc_shift +#define CYC_RESET m68ki_cpu.cyc_reset + + +#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback +#define CALLBACK_BKPT_ACK m68ki_cpu.bkpt_ack_callback +#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback +#define CALLBACK_PC_CHANGED m68ki_cpu.pc_changed_callback +#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback +#define CALLBACK_INSTR_HOOK m68ki_cpu.instr_hook_callback + + + +/* ----------------------------- Configuration ---------------------------- */ + +/* These defines are dependant on the configuration defines in m68kconf.h */ + +/* Disable certain comparisons if we're not using all CPU types */ +#if M68K_EMULATE_020 + #define CPU_TYPE_IS_020_PLUS(A) ((A) & CPU_TYPE_020) + #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 +#endif + +#if M68K_EMULATE_EC020 + #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) + #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) +#endif + +#if M68K_EMULATE_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)) + #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | 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) +#endif + +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 + #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) +#else + #define CPU_TYPE_IS_020_VARIANT(A) 0 +#endif + +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010 + #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000) +#else + #define CPU_TYPE_IS_000(A) 1 +#endif + + +#if !M68K_SEPARATE_READS +#define m68k_read_immediate_16(A) m68ki_read_program_16(A) +#define m68k_read_immediate_32(A) m68ki_read_program_32(A) + +#define m68k_read_pcrelative_8(A) m68ki_read_program_8(A) +#define m68k_read_pcrelative_16(A) m68ki_read_program_16(A) +#define m68k_read_pcrelative_32(A) m68ki_read_program_32(A) +#endif /* M68K_SEPARATE_READS */ + + +/* 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 +#else + /* 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 +#else + #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 +#else + #define m68ki_output_reset() +#endif /* M68K_EMULATE_RESET */ + +#if M68K_INSTRUCTION_HOOK + #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER + #define m68ki_instr_hook() M68K_INSTRUCTION_CALLBACK() + #else + #define m68ki_instr_hook() CALLBACK_INSTR_HOOK() + #endif +#else + #define m68ki_instr_hook() +#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 +#else + #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 +#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 +#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() +#else + #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 + extern jmp_buf m68ki_address_error_trap; + #define m68ki_set_address_error_trap() if(setjmp(m68ki_address_error_trap)) m68ki_exception_address_error(); + #define m68ki_check_address_error(A) if((A)&1) longjmp(m68ki_address_error_jump, 1); +#else + #define m68ki_set_address_error_trap() + #define m68ki_check_address_error(A) +#endif /* M68K_ADDRESS_ERROR */ + +/* Logging */ +#if M68K_LOG_ENABLE + #include + extern FILE* M68K_LOG_FILEHANDLE + extern char* 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 +#else + #define M68K_DO_LOG(A) + #define M68K_DO_LOG_EMU(A) +#endif + + + +/* -------------------------- EA / Operand Access ------------------------- */ + +/* + * The general instruction format follows this pattern: + * .... XXX. .... .YYY + * where XXX is register X and YYY is register Y + */ +/* Data Register Isolation */ +#define DX (REG_D[(REG_IR >> 9) & 7]) +#define DY (REG_D[REG_IR & 7]) +/* Address Register Isolation */ +#define AX (REG_A[(REG_IR >> 9) & 7]) +#define AY (REG_A[REG_IR & 7]) + + +/* Effective Address Calculations */ +#define EA_AY_AI_8() AY /* address register indirect */ +#define EA_AY_AI_16() EA_AY_AI_8() +#define EA_AY_AI_32() EA_AY_AI_8() +#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */ +#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */ +#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */ +#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */ +#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */ +#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */ +#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */ +#define EA_AY_DI_16() EA_AY_DI_8() +#define EA_AY_DI_32() EA_AY_DI_8() +#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */ +#define EA_AY_IX_16() EA_AY_IX_8() +#define EA_AY_IX_32() EA_AY_IX_8() + +#define EA_AX_AI_8() AX +#define EA_AX_AI_16() EA_AX_AI_8() +#define EA_AX_AI_32() EA_AX_AI_8() +#define EA_AX_PI_8() (AX++) +#define EA_AX_PI_16() ((AX+=2)-2) +#define EA_AX_PI_32() ((AX+=4)-4) +#define EA_AX_PD_8() (--AX) +#define EA_AX_PD_16() (AX-=2) +#define EA_AX_PD_32() (AX-=4) +#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16())) +#define EA_AX_DI_16() EA_AX_DI_8() +#define EA_AX_DI_32() EA_AX_DI_8() +#define EA_AX_IX_8() m68ki_get_ea_ix(AX) +#define EA_AX_IX_16() EA_AX_IX_8() +#define EA_AX_IX_32() EA_AX_IX_8() + +#define EA_A7_PI_8() ((REG_A[7]+=2)-2) +#define EA_A7_PD_8() (REG_A[7]-=2) + +#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */ +#define EA_AW_16() EA_AW_8() +#define EA_AW_32() EA_AW_8() +#define EA_AL_8() m68ki_read_imm_32() /* absolute long */ +#define EA_AL_16() EA_AL_8() +#define EA_AL_32() EA_AL_8() +#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */ +#define EA_PCDI_16() EA_PCDI_8() +#define EA_PCDI_32() EA_PCDI_8() +#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */ +#define EA_PCIX_16() EA_PCIX_8() +#define EA_PCIX_32() EA_PCIX_8() + + +#define OPER_I_8() m68ki_read_imm_8() +#define OPER_I_16() m68ki_read_imm_16() +#define OPER_I_32() m68ki_read_imm_32() + + + +/* --------------------------- Status Register ---------------------------- */ + +/* Flag Calculation Macros */ +#define CFLAG_8(A) (A) +#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) +#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) +#endif /* M68K_INT_GT_32_BIT */ + +#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) +#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) +#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) + +#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) +#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) +#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) + +#define NFLAG_8(A) (A) +#define NFLAG_16(A) ((A)>>8) +#define NFLAG_32(A) ((A)>>24) +#define NFLAG_64(A) ((A)>>56) + +#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) +#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) +#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) + + +/* Flag values */ +#define NFLAG_SET 0x80 +#define NFLAG_CLEAR 0 +#define CFLAG_SET 0x100 +#define CFLAG_CLEAR 0 +#define XFLAG_SET 0x100 +#define XFLAG_CLEAR 0 +#define VFLAG_SET 0x80 +#define VFLAG_CLEAR 0 +#define ZFLAG_SET 0 +#define ZFLAG_CLEAR 0xffffffff + +#define SFLAG_SET 4 +#define SFLAG_CLEAR 0 +#define MFLAG_SET 2 +#define MFLAG_CLEAR 0 + +/* Turn flag values into 1 or 0 */ +#define XFLAG_AS_1() ((FLAG_X>>8)&1) +#define NFLAG_AS_1() ((FLAG_N>>7)&1) +#define VFLAG_AS_1() ((FLAG_V>>7)&1) +#define ZFLAG_AS_1() (!FLAG_Z) +#define CFLAG_AS_1() ((FLAG_C>>8)&1) + + +/* Conditions */ +#define COND_CS() (FLAG_C&0x100) +#define COND_CC() (!COND_CS()) +#define COND_VS() (FLAG_V&0x80) +#define COND_VC() (!COND_VS()) +#define COND_NE() FLAG_Z +#define COND_EQ() (!COND_NE()) +#define COND_MI() (FLAG_N&0x80) +#define COND_PL() (!COND_MI()) +#define COND_LT() ((FLAG_N^FLAG_V)&0x80) +#define COND_GE() (!COND_LT()) +#define COND_HI() (COND_CC() && COND_NE()) +#define COND_LS() (COND_CS() || COND_EQ()) +#define COND_GT() (COND_GE() && COND_NE()) +#define COND_LE() (COND_LT() || COND_EQ()) + +/* Reversed conditions */ +#define COND_NOT_CS() COND_CC() +#define COND_NOT_CC() COND_CS() +#define COND_NOT_VS() COND_VC() +#define COND_NOT_VC() COND_VS() +#define COND_NOT_NE() COND_EQ() +#define COND_NOT_EQ() COND_NE() +#define COND_NOT_MI() COND_PL() +#define COND_NOT_PL() COND_MI() +#define COND_NOT_LT() COND_GE() +#define COND_NOT_GE() COND_LT() +#define COND_NOT_HI() COND_LS() +#define COND_NOT_LS() COND_HI() +#define COND_NOT_GT() COND_LE() +#define COND_NOT_LE() COND_GT() + +/* Not real conditions, but here for convenience */ +#define COND_XS() (FLAG_X&0x100) +#define COND_XC() (!COND_XS) + + +/* Get the condition code register */ +#define m68ki_get_ccr() ((COND_XS() >> 4) | \ + (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()) + + + +/* ---------------------------- Cycle Counting ---------------------------- */ + +#define ADD_CYCLES(A) m68ki_remaining_cycles += (A) +#define USE_CYCLES(A) m68ki_remaining_cycles -= (A) +#define SET_CYCLES(A) m68ki_remaining_cycles = A +#define GET_CYCLES() m68ki_remaining_cycles +#define USE_ALL_CYCLES() m68ki_remaining_cycles = 0 + + + +/* ----------------------------- Read / Write ----------------------------- */ + +/* Read from the current address space */ +#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space()) + +/* Write to the current data space */ +#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) + +/* map read immediate 8 to read immediate 16 */ +#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16()) + +/* Map PC-relative reads */ +#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A) +#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A) +#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) + +/* 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) + + + +/* ======================================================================== */ +/* =============================== PROTOTYPES ============================= */ +/* ======================================================================== */ + +typedef struct +{ + uint cpu_type; /* CPU Type: 68000, 68010, 68EC020, or 68020 */ + uint dar[16]; /* Data and Address Registers */ + 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 */ + 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 int_cycles; /* ASG: extra cycles from generated interrupts */ + 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 */ + + /* 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_false; + uint cyc_movem_w; + uint cyc_movem_l; + uint cyc_shift; + uint cyc_reset; + uint8* cyc_instruction; + 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 (*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)(void); /* Called every instruction cycle prior to execution */ + +} m68ki_cpu_core; + + +extern m68ki_cpu_core m68ki_cpu; +extern sint m68ki_remaining_cycles; +extern uint m68ki_tracing; +extern uint8 m68ki_shift_8_table[]; +extern uint16 m68ki_shift_16_table[]; +extern uint m68ki_shift_32_table[]; +extern uint8 m68ki_exception_cycle_table[][256]; +extern uint m68ki_address_space; +extern uint8 m68ki_ea_idx_cycle_table[]; + + +/* Read data immediately after the program counter */ +INLINE uint m68ki_read_imm_16(void); +INLINE uint m68ki_read_imm_32(void); + +/* Read data with specific function code */ +INLINE uint m68ki_read_8_fc (uint address, uint fc); +INLINE uint m68ki_read_16_fc (uint address, uint fc); +INLINE uint m68ki_read_32_fc (uint address, uint fc); + +/* Write data with specific function code */ +INLINE void m68ki_write_8_fc (uint address, uint fc, uint value); +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value); +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value); + +/* Indexed and PC-relative ea fetching */ +INLINE uint m68ki_get_ea_pcdi(void); +INLINE uint m68ki_get_ea_pcix(void); +INLINE uint m68ki_get_ea_ix(uint An); + +/* Operand fetching */ +INLINE uint OPER_AY_AI_8(void); +INLINE uint OPER_AY_AI_16(void); +INLINE uint OPER_AY_AI_32(void); +INLINE uint OPER_AY_PI_8(void); +INLINE uint OPER_AY_PI_16(void); +INLINE uint OPER_AY_PI_32(void); +INLINE uint OPER_AY_PD_8(void); +INLINE uint OPER_AY_PD_16(void); +INLINE uint OPER_AY_PD_32(void); +INLINE uint OPER_AY_DI_8(void); +INLINE uint OPER_AY_DI_16(void); +INLINE uint OPER_AY_DI_32(void); +INLINE uint OPER_AY_IX_8(void); +INLINE uint OPER_AY_IX_16(void); +INLINE uint OPER_AY_IX_32(void); + +INLINE uint OPER_AX_AI_8(void); +INLINE uint OPER_AX_AI_16(void); +INLINE uint OPER_AX_AI_32(void); +INLINE uint OPER_AX_PI_8(void); +INLINE uint OPER_AX_PI_16(void); +INLINE uint OPER_AX_PI_32(void); +INLINE uint OPER_AX_PD_8(void); +INLINE uint OPER_AX_PD_16(void); +INLINE uint OPER_AX_PD_32(void); +INLINE uint OPER_AX_DI_8(void); +INLINE uint OPER_AX_DI_16(void); +INLINE uint OPER_AX_DI_32(void); +INLINE uint OPER_AX_IX_8(void); +INLINE uint OPER_AX_IX_16(void); +INLINE uint OPER_AX_IX_32(void); + +INLINE uint OPER_A7_PI_8(void); +INLINE uint OPER_A7_PD_8(void); + +INLINE uint OPER_AW_8(void); +INLINE uint OPER_AW_16(void); +INLINE uint OPER_AW_32(void); +INLINE uint OPER_AL_8(void); +INLINE uint OPER_AL_16(void); +INLINE uint OPER_AL_32(void); +INLINE uint OPER_PCDI_8(void); +INLINE uint OPER_PCDI_16(void); +INLINE uint OPER_PCDI_32(void); +INLINE uint OPER_PCIX_8(void); +INLINE uint OPER_PCIX_16(void); +INLINE uint OPER_PCIX_32(void); + +/* Stack operations */ +INLINE void m68ki_push_16(uint value); +INLINE void m68ki_push_32(uint value); +INLINE uint m68ki_pull_16(void); +INLINE uint m68ki_pull_32(void); + +/* Program flow operations */ +INLINE void m68ki_jump(uint new_pc); +INLINE void m68ki_jump_vector(uint vector); +INLINE void m68ki_branch_8(uint offset); +INLINE void m68ki_branch_16(uint offset); +INLINE void m68ki_branch_32(uint offset); + +/* Status register operations. */ +INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ +INLINE void m68ki_set_sm_flag(uint value); /* only bits 1 and 2 of value should be set */ +INLINE void m68ki_set_ccr(uint value); /* set the condition code register */ +INLINE void m68ki_set_sr(uint value); /* set the status register */ +INLINE void m68ki_set_sr_noint(uint value); /* set the status register */ + +/* Exception processing */ +INLINE uint m68ki_init_exception(void); /* Initial exception processing */ + +INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */ +INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc); + +INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector); +INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector); +INLINE void m68ki_stack_frame_0010(uint sr, uint vector); +INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector); +INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc); +INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc); + +INLINE void m68ki_exception_trap(uint vector); +INLINE void m68ki_exception_trapN(uint vector); +INLINE void m68ki_exception_trace(void); +INLINE void m68ki_exception_privilege_violation(void); +INLINE void m68ki_exception_1010(void); +INLINE void m68ki_exception_1111(void); +INLINE void m68ki_exception_illegal(void); +INLINE void m68ki_exception_format_error(void); +INLINE void m68ki_exception_address_error(void); +INLINE void m68ki_exception_interrupt(uint int_level); +INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */ + +/* quick disassembly (used for logging) */ +char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type); + + +/* ======================================================================== */ +/* =========================== UTILITY FUNCTIONS ========================== */ +/* ======================================================================== */ + + +/* ---------------------------- Read Immediate ---------------------------- */ + +/* Handles all immediate reads, does address error check, function code setting, + * and prefetching if they are enabled in m68kconf.h + */ +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); /* auto-disable (see m68kcpu.h) */ +#if M68K_EMULATE_PREFETCH + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); + } + REG_PC += 2; + return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); +#else + REG_PC += 2; + return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2)); +#endif /* M68K_EMULATE_PREFETCH */ +} +INLINE uint m68ki_read_imm_32(void) +{ +#if M68K_EMULATE_PREFETCH + uint temp_val; + + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */ + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); + } + temp_val = CPU_PREF_DATA; + REG_PC += 2; + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); + } + REG_PC += 2; + + return temp_val; +#else + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */ + REG_PC += 4; + return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4)); +#endif /* M68K_EMULATE_PREFETCH */ +} + + + +/* ------------------------- Top level read/write ------------------------- */ + +/* Handles all memory accesses (except for immediate reads if they are + * configured to use separate functions in m68kconf.h). + * All memory accesses must go through these top level functions. + * These functions will also check for address error and set the function + * code if they are enabled in m68kconf.h. + */ +INLINE uint m68ki_read_8_fc(uint address, uint fc) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + return m68k_read_memory_8(ADDRESS_68K(address)); +} +INLINE uint m68ki_read_16_fc(uint address, uint fc) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ + return m68k_read_memory_16(ADDRESS_68K(address)); +} +INLINE uint m68ki_read_32_fc(uint address, uint fc) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ + return m68k_read_memory_32(ADDRESS_68K(address)); +} + +INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68k_write_memory_8(ADDRESS_68K(address), value); +} +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ + m68k_write_memory_16(ADDRESS_68K(address), value); +} +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value) +{ + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ + m68k_write_memory_32(ADDRESS_68K(address), value); +} + + + +/* --------------------- Effective Address Calculation -------------------- */ + +/* The program counter relative addressing modes cause operands to be + * retrieved from program space, not data space. + */ +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()); +} + + +INLINE uint m68ki_get_ea_pcix(void) +{ + m68ki_use_program_space(); /* auto-disable */ + return m68ki_get_ea_ix(REG_PC); +} + +/* Indexed addressing modes are encoded as follows: + * + * Base instruction format: + * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 + * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) + * + * Base instruction format for destination EA in move instructions: + * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 + * x x x x | BASE REG | 1 1 0 | X X X X X X (An) + * + * Brief extension format: + * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT + * + * Full extension format: + * F E D C B A 9 8 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS + * BASE DISPLACEMENT (0, 16, 32 bit) (bd) + * OUTER DISPLACEMENT (0, 16, 32 bit) (od) + * + * D/A: 0 = Dn, 1 = An (Xn) + * W/L: 0 = W (sign extend), 1 = L (.SIZE) + * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) + * BS: 0=add base reg, 1=suppress base reg (An suppressed) + * IS: 0=add index, 1=suppress index (Xn suppressed) + * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) + * + * IS I/IS Operation + * 0 000 No Memory Indirect + * 0 001 indir prex with null outer + * 0 010 indir prex with word outer + * 0 011 indir prex with long outer + * 0 100 reserved + * 0 101 indir postx with null outer + * 0 110 indir postx with word outer + * 0 111 indir postx with long outer + * 1 000 no memory indirect + * 1 001 mem indir with null outer + * 1 010 mem indir with word outer + * 1 011 mem indir with long outer + * 1 100-111 reserved + */ +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 */ + + 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); + } + + /* 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); + } + + /* Full extension format */ + + 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 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() : MAKE_INT_16(m68ki_read_imm_16()); + + /* 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() : 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; + + /* Preindex */ + return m68ki_read_32(An + bd + Xn) + od; +} + + +/* Fetch operands */ +INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); } + +INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);} +INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);} +INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);} + + + +/* ---------------------------- Stack Functions --------------------------- */ + +/* Push/pull data from the stack */ +INLINE void m68ki_push_16(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); + m68ki_write_16(REG_SP, value); +} + +INLINE void m68ki_push_32(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); + m68ki_write_32(REG_SP, value); +} + +INLINE uint m68ki_pull_16(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); + return m68ki_read_16(REG_SP-2); +} + +INLINE uint m68ki_pull_32(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); + return m68ki_read_32(REG_SP-4); +} + + +/* Increment/decrement the stack as if doing a push/pull but + * don't do any memory access. + */ +INLINE void m68ki_fake_push_16(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); +} + +INLINE void m68ki_fake_push_32(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); +} + +INLINE void m68ki_fake_pull_16(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); +} + +INLINE void m68ki_fake_pull_32(void) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); +} + + +/* ----------------------------- Program Flow ----------------------------- */ + +/* Jump to a new program location or vector. + * These functions will also call the pc_changed callback if it was enabled + * in m68kconf.h. + */ +INLINE void m68ki_jump(uint new_pc) +{ + REG_PC = new_pc; + m68ki_pc_changed(REG_PC); +} + +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); +} + + +/* Branch to a new memory location. + * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. + * So far I've found no problems with not calling pc_changed for 8 or 16 + * bit branches. + */ +INLINE void m68ki_branch_8(uint offset) +{ + REG_PC += MAKE_INT_8(offset); +} + +INLINE void m68ki_branch_16(uint offset) +{ + REG_PC += MAKE_INT_16(offset); +} + +INLINE void m68ki_branch_32(uint offset) +{ + REG_PC += offset; + m68ki_pc_changed(REG_PC); +} + + + +/* ---------------------------- Status Register --------------------------- */ + +/* Set the S flag and change the active stack pointer. + * Note that value MUST be 4 or 0. + */ +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)]; +} + +/* Set the S and M flags and change the active stack pointer. + * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M). + */ +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)]; +} + + +/* Set the condition code register */ +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; +} + +/* Set the status register but don't check for interrupts */ +INLINE void m68ki_set_sr_noint(uint value) +{ + /* 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); +} + +/* Set the status register and check for interrupts */ +INLINE void m68ki_set_sr(uint value) +{ + m68ki_set_sr_noint(value); + m68ki_check_interrupts(); +} + + +/* ------------------------- Exception Processing ------------------------- */ + +/* Initiate exception processing */ +INLINE uint m68ki_init_exception(void) +{ + /* 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); + + return sr; +} + +/* 3 word stack frame (68000 only) */ +INLINE void m68ki_stack_frame_3word(uint pc, uint sr) +{ + m68ki_push_32(pc); + m68ki_push_16(sr); +} + +/* Format 0 stack frame. + * This is the standard stack frame for 68010+. + */ +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); +} + +/* Format 1 stack frame (68020). + * For 68020, this is the 4 word throwaway frame. + */ +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); +} + +/* Format 2 stack frame. + * This is used only by 68020 for trap exceptions. + */ +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); +} + + +/* Bus error stack frame (68000 only). + */ +INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc) +{ + m68ki_push_32(pc); + m68ki_push_16(sr); + m68ki_push_16(REG_IR); + m68ki_push_32(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(((!write)<<4) | ((!instruction)<<3) | fc); +} + +/* Format 8 stack frame (68010). + * 68010 only. This is the 29 word bus/address error frame. + */ +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(); + + /* INSTRUCTION INPUT BUFFER */ + m68ki_push_16(0); + + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); + + /* DATA INPUT BUFFER */ + m68ki_push_16(0); + + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); + + /* DATA OUTPUT BUFFER */ + m68ki_push_16(0); + + /* UNUSED, RESERVED (not written) */ + m68ki_fake_push_16(); + + /* FAULT ADDRESS */ + m68ki_push_32(0); + + /* SPECIAL STATUS WORD */ + m68ki_push_16(0); + + /* 1000, VECTOR OFFSET */ + m68ki_push_16(0x8000 | (vector<<2)); + + /* PROGRAM COUNTER */ + m68ki_push_32(pc); + + /* STATUS REGISTER */ + m68ki_push_16(sr); +} + +/* Format A stack frame (short bus fault). + * This is used only by 68020 for bus fault and address error + * if the error happens at an instruction boundary. + * PC stacked is address of next instruction. + */ +void m68ki_stack_frame_1010(uint sr, uint vector, uint pc) +{ + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* DATA OUTPUT BUFFER (2 words) */ + m68ki_push_32(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* DATA CYCLE FAULT ADDRESS (2 words) */ + m68ki_push_32(0); + + /* INSTRUCTION PIPE STAGE B */ + m68ki_push_16(0); + + /* INSTRUCTION PIPE STAGE C */ + m68ki_push_16(0); + + /* SPECIAL STATUS REGISTER */ + m68ki_push_16(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* 1010, VECTOR OFFSET */ + m68ki_push_16(0xa000 | (vector<<2)); + + /* PROGRAM COUNTER */ + m68ki_push_32(pc); + + /* STATUS REGISTER */ + m68ki_push_16(sr); +} + +/* Format B stack frame (long bus fault). + * This is used only by 68020 for bus fault and address error + * if the error happens during instruction execution. + * PC stacked is address of instruction in progress. + */ +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); + + /* VERSION# (4 bits), INTERNAL INFORMATION */ + 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); + + /* INTERNAL REGISTERS (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); + + /* DATA OUTPUT BUFFER (2 words) */ + m68ki_push_32(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* DATA CYCLE FAULT ADDRESS (2 words) */ + m68ki_push_32(0); + + /* INSTRUCTION PIPE STAGE B */ + m68ki_push_16(0); + + /* INSTRUCTION PIPE STAGE C */ + m68ki_push_16(0); + + /* SPECIAL STATUS REGISTER */ + m68ki_push_16(0); + + /* INTERNAL REGISTER */ + m68ki_push_16(0); + + /* 1011, VECTOR OFFSET */ + m68ki_push_16(0xb000 | (vector<<2)); + + /* PROGRAM COUNTER */ + m68ki_push_32(pc); + + /* STATUS REGISTER */ + m68ki_push_16(sr); +} + + +/* Used for Group 2 exceptions. + * These stack a type 2 frame on the 020. + */ +INLINE void m68ki_exception_trap(uint vector) +{ + 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); + + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* Trap#n stacks a 0 frame but behaves like group2 otherwise */ +INLINE void m68ki_exception_trapN(uint vector) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC, sr, vector); + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* Exception for trace mode */ +INLINE void m68ki_exception_trace(void) +{ + uint sr = m68ki_init_exception(); + + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE); + else + m68ki_stack_frame_0010(sr, EXCEPTION_TRACE); + + m68ki_jump_vector(EXCEPTION_TRACE); + + /* Trace nullifies a STOP instruction */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); +} + +/* Exception for privilege violation */ +INLINE void m68ki_exception_privilege_violation(void) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC, 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]); +} + +/* Exception for A-Line instructions */ +INLINE void m68ki_exception_1010(void) +{ + 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)))); +#endif + + sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC-2, 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]); +} + +/* Exception for F-Line instructions */ +INLINE void m68ki_exception_1111(void) +{ + 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)))); +#endif + + sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC-2, 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]); +} + +/* Exception for illegal instructions */ +INLINE void m68ki_exception_illegal(void) +{ + 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)))); + + sr = m68ki_init_exception(); + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_ILLEGAL_INSTRUCTION); + m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for format errror in RTE */ +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); + + /* 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 */ +INLINE void m68ki_exception_address_error(void) +{ + /* Not emulated yet */ +} + + +/* Service an interrupt request and start exception processing */ +void m68ki_exception_interrupt(uint int_level) +{ + uint vector; + uint sr; + uint new_pc; + + /* Turn off the stopped state */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; + + /* If we are halted, don't do anything */ + if(CPU_STOPPED) + return; + + /* 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; + } + + /* 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; + + /* 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); + + /* 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); + + /* Defer cycle counting until later */ + CPU_INT_CYCLES += CYC_EXCEPTION[vector]; + +#if !M68K_EMULATE_INT_ACK + /* Automatically clear IRQ if we are not using an acknowledge scheme */ + CPU_INT_LEVEL = 0; +#endif /* M68K_EMULATE_INT_ACK */ +} + + +/* ASG: Check for interrupts */ +INLINE void m68ki_check_interrupts(void) +{ + if(CPU_INT_LEVEL > FLAG_INT_MASK) + m68ki_exception_interrupt(CPU_INT_LEVEL>>8); +} + + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCPU__HEADER */ diff --git a/src/m68kdasm.c b/src/m68kdasm.c new file mode 100644 index 0000000..7ded380 --- /dev/null +++ b/src/m68kdasm.c @@ -0,0 +1,3443 @@ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + +/* ======================================================================== */ +/* ================================ INCLUDES ============================== */ +/* ======================================================================== */ + +#include +#include +#include +#include "m68k.h" + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ +/* ======================================================================== */ + +/* unsigned int and int must be at least 32 bits wide */ +#undef uint +#define uint unsigned int + +/* Bit Isolation Functions */ +#define BIT_0(A) ((A) & 0x00000001) +#define BIT_1(A) ((A) & 0x00000002) +#define BIT_2(A) ((A) & 0x00000004) +#define BIT_3(A) ((A) & 0x00000008) +#define BIT_4(A) ((A) & 0x00000010) +#define BIT_5(A) ((A) & 0x00000020) +#define BIT_6(A) ((A) & 0x00000040) +#define BIT_7(A) ((A) & 0x00000080) +#define BIT_8(A) ((A) & 0x00000100) +#define BIT_9(A) ((A) & 0x00000200) +#define BIT_A(A) ((A) & 0x00000400) +#define BIT_B(A) ((A) & 0x00000800) +#define BIT_C(A) ((A) & 0x00001000) +#define BIT_D(A) ((A) & 0x00002000) +#define BIT_E(A) ((A) & 0x00004000) +#define BIT_F(A) ((A) & 0x00008000) +#define BIT_10(A) ((A) & 0x00010000) +#define BIT_11(A) ((A) & 0x00020000) +#define BIT_12(A) ((A) & 0x00040000) +#define BIT_13(A) ((A) & 0x00080000) +#define BIT_14(A) ((A) & 0x00100000) +#define BIT_15(A) ((A) & 0x00200000) +#define BIT_16(A) ((A) & 0x00400000) +#define BIT_17(A) ((A) & 0x00800000) +#define BIT_18(A) ((A) & 0x01000000) +#define BIT_19(A) ((A) & 0x02000000) +#define BIT_1A(A) ((A) & 0x04000000) +#define BIT_1B(A) ((A) & 0x08000000) +#define BIT_1C(A) ((A) & 0x10000000) +#define BIT_1D(A) ((A) & 0x20000000) +#define BIT_1E(A) ((A) & 0x40000000) +#define BIT_1F(A) ((A) & 0x80000000) + +/* These are the CPU types understood by this disassembler */ +#define TYPE_68000 1 +#define TYPE_68010 2 +#define TYPE_68020 4 +#define TYPE_68030 8 +#define TYPE_68040 16 + +#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 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 M68040_PLUS TYPE_68040 + + +/* Extension word formats */ +#define EXT_8BIT_DISPLACEMENT(A) ((A)&0xff) +#define EXT_FULL(A) BIT_8(A) +#define EXT_EFFECTIVE_ZERO(A) (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0) +#define EXT_BASE_REGISTER_PRESENT(A) (!BIT_7(A)) +#define EXT_INDEX_REGISTER_PRESENT(A) (!BIT_6(A)) +#define EXT_INDEX_REGISTER(A) (((A)>>12)&7) +#define EXT_INDEX_PRE_POST(A) (EXT_INDEX_PRESENT(A) && (A)&3) +#define EXT_INDEX_PRE(A) (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0) +#define EXT_INDEX_POST(A) (EXT_INDEX_PRESENT(A) && ((A)&7) > 4) +#define EXT_INDEX_SCALE(A) (((A)>>9)&3) +#define EXT_INDEX_LONG(A) BIT_B(A) +#define EXT_INDEX_AR(A) BIT_F(A) +#define EXT_BASE_DISPLACEMENT_PRESENT(A) (((A)&0x30) > 0x10) +#define EXT_BASE_DISPLACEMENT_WORD(A) (((A)&0x30) == 0x20) +#define EXT_BASE_DISPLACEMENT_LONG(A) (((A)&0x30) == 0x30) +#define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44) +#define EXT_OUTER_DISPLACEMENT_WORD(A) (((A)&3) == 2 && ((A)&0x47) < 0x44) +#define EXT_OUTER_DISPLACEMENT_LONG(A) (((A)&3) == 3 && ((A)&0x47) < 0x44) + + + +/* ======================================================================== */ +/* =============================== PROTOTYPES ============================= */ +/* ======================================================================== */ + +/* Read data at the PC and increment PC */ +uint read_imm_8(void); +uint read_imm_16(void); +uint read_imm_32(void); + +/* Read data at the PC but don't imcrement the PC */ +uint peek_imm_8(void); +uint peek_imm_16(void); +uint peek_imm_32(void); + +/* make signed integers 100% portably */ +static int make_int_8(int value); +static int make_int_16(int value); + +/* make a string of a hex value */ +static char* make_signed_hex_str_8(uint val); +static char* make_signed_hex_str_16(uint val); +static char* make_signed_hex_str_32(uint val); + +/* make string of ea mode */ +static char* get_ea_mode_str(uint instruction, uint size); + +char* get_ea_mode_str_8(uint instruction); +char* get_ea_mode_str_16(uint instruction); +char* get_ea_mode_str_32(uint instruction); + +/* make string of immediate value */ +static char* get_imm_str_s(uint size); +static char* get_imm_str_u(uint size); + +char* get_imm_str_s8(void); +char* get_imm_str_s16(void); +char* get_imm_str_s32(void); + +/* Stuff to build the opcode handler jump table */ +static void build_opcode_table(void); +static int valid_ea(uint opcode, uint mask); +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 */ +} opcode_struct; + + + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +/* Opcode handler jump table */ +static void (*g_instruction_table[0x10000])(void); +/* Flag if disassembler initialized */ +static int g_initialized = 0; + +/* Address mask to simulate address lines */ +static unsigned int g_address_mask = 0xffffffff; + +static char g_dasm_str[100]; /* string to hold disassembly */ +static char g_helper_str[100]; /* string to hold helpful info */ +static uint g_cpu_pc; /* program counter */ +static uint g_cpu_ir; /* instruction register */ +static uint g_cpu_type; + +/* used by ops like asr, ror, addq, etc */ +static uint g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; + +static 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 +}; + +static char* g_cc[16] = +{"t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"}; + +static char* 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 */ + "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ + "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ +}; + + +/* ======================================================================== */ +/* =========================== UTILITY FUNCTIONS ========================== */ +/* ======================================================================== */ + +#define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES) \ + if(!(g_cpu_type & ALLOWED_CPU_TYPES)) \ + { \ + d68000_illegal(); \ + return; \ + } + +#define read_imm_8() (m68k_read_disassembler_16(((g_cpu_pc+=2)-2)&g_address_mask)&0xff) +#define read_imm_16() m68k_read_disassembler_16(((g_cpu_pc+=2)-2)&g_address_mask) +#define read_imm_32() m68k_read_disassembler_32(((g_cpu_pc+=4)-4)&g_address_mask) + +#define peek_imm_8() (m68k_read_disassembler_16(g_cpu_pc & g_address_mask)&0xff) +#define peek_imm_16() m68k_read_disassembler_16(g_cpu_pc & g_address_mask) +#define peek_imm_32() m68k_read_disassembler_32(g_cpu_pc & g_address_mask) + +/* Fake a split interface */ +#define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0) +#define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1) +#define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2) + +#define get_imm_str_s8() get_imm_str_s(0) +#define get_imm_str_s16() get_imm_str_s(1) +#define get_imm_str_s32() get_imm_str_s(2) + +#define get_imm_str_u8() get_imm_str_u(0) +#define get_imm_str_u16() get_imm_str_u(1) +#define get_imm_str_u32() get_imm_str_u(2) + + +/* 100% portable signed int generators */ +static int make_int_8(int value) +{ + return (value & 0x80) ? value | ~0xff : value & 0xff; +} + +static int make_int_16(int value) +{ + return (value & 0x8000) ? value | ~0xffff : value & 0xffff; +} + + +/* Get string representation of hex values */ +static char* make_signed_hex_str_8(uint val) +{ + static char str[20]; + + val &= 0xff; + + if(val == 0x80) + sprintf(str, "-$80"); + else if(val & 0x80) + sprintf(str, "-$%x", (0-val) & 0x7f); + else + sprintf(str, "$%x", val & 0x7f); + + return str; +} + +static char* make_signed_hex_str_16(uint val) +{ + static char str[20]; + + val &= 0xffff; + + if(val == 0x8000) + sprintf(str, "-$8000"); + else if(val & 0x8000) + sprintf(str, "-$%x", (0-val) & 0x7fff); + else + sprintf(str, "$%x", val & 0x7fff); + + return str; +} + +static char* make_signed_hex_str_32(uint val) +{ + static char str[20]; + + val &= 0xffffffff; + + if(val == 0x80000000) + sprintf(str, "-$80000000"); + else if(val & 0x80000000) + sprintf(str, "-$%x", (0-val) & 0x7fffffff); + else + sprintf(str, "$%x", val & 0x7fffffff); + + 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* 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; +} + +/* 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; + + /* 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(); + + 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) + { + 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_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; + } + + 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; +} + + + +/* ======================================================================== */ +/* ========================= INSTRUCTION HANDLERS ========================= */ +/* ======================================================================== */ +/* Instruction handler function names follow this convention: + * + * d68000_NAME_EXTENSIONS(void) + * where NAME is the name of the opcode it handles and EXTENSIONS are any + * extensions for special instances of that opcode. + * + * Examples: + * d68000_add_er_8(): add opcode, from effective address to register, + * size = byte + * + * d68000_asr_s_8(): arithmetic shift right, static count, size = byte + * + * + * Common extensions: + * 8 : size = byte + * 16 : size = word + * 32 : size = long + * rr : register to register + * mm : memory to memory + * r : register + * s : static + * er : effective address -> register + * re : register -> effective address + * ea : using effective address mode of operation + * d : data register direct + * a : address register direct + * 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 + * al : absolute long + */ + +static void d68000_illegal(void) +{ + 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); +} + + +static void d68000_1111(void) +{ + 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); +} + + +static void d68000_abcd_mm(void) +{ + 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); +} + + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68000_andi_to_ccr(void) +{ + 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()); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_asr_ea(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_asl_ea(void) +{ + 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)); +} + +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())); +} + +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()); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68010_bkpt(void) +{ + 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]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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); +} + +static void d68020_bfclr(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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); +} + +static void d68020_bfexts(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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 D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); +} + +static void d68020_bfextu(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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 D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); +} + +static void d68020_bfffo(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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 D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); +} + +static void d68020_bfins(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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); +} + +static void d68020_bfset(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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); +} + +static void d68020_bftst(void) +{ + uint extension; + char offset[3]; + char width[3]; + + LIMIT_CPU_TYPES(M68020_PLUS); + + 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); +} + +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)); +} + +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())); +} + +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()); +} + +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)); +} + +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)); +} + +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)); +} + +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())); +} + +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 + peek_imm_32()); +} + +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)); +} + +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)); +} + +static void d68020_callm(void) +{ + 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)); +} + +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>>8)&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>>8)&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>>8)&7, get_ea_mode_str_32(g_cpu_ir)); +} + +static void d68020_cas2_16(void) +{ +/* CAS2 Dc1:Dc2,Du1:Dc2:(Rn1):(Rn2) +f e d c b a 9 8 7 6 5 4 3 2 1 0 + DARn1 0 0 0 Du1 0 0 0 Dc1 + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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; + } +} + +static void d68000_clr_8(void) +{ + 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)); +} + +static void d68000_clr_32(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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)); +} + +static void d68020_cmpi_pcdi_8(void) +{ + char* str; + LIMIT_CPU_TYPES(M68020_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(M68020_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; + LIMIT_CPU_TYPES(M68020_PLUS); + 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(M68020_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(M68020_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; + LIMIT_CPU_TYPES(M68020_PLUS); + 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(M68020_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(M68020_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); +} + +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); +} + +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); +} + +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(peek_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 += peek_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(peek_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()); +} + +static void d68020_cprestore(void) +{ + LIMIT_CPU_TYPES(M68020_PLUS); + 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); + 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); +} + +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); +} + +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); +} + +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); +} + +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; + } +} + +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())); +} + +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())); +} + +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); +} + +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); +} + +static void d68020_divl(void) +{ + 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); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68000_eori_to_ccr(void) +{ + 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()); +} + +static void d68000_exg_dd(void) +{ + 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); +} + +static void d68000_exg_da(void) +{ + 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); +} + +static void d68000_ext_32(void) +{ + 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); +} + +static void d68000_jmp(void) +{ + 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)); +} + +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); +} + +static void d68000_link_16(void) +{ + 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()); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_lsr_ea(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_lsl_ea(void) +{ + 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))); +} + +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))); +} + +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))); +} + +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); +} + +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); +} + +static void d68000_move_to_ccr(void) +{ + 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)); +} + +static void d68000_move_fr_sr(void) +{ + 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)); +} + +static void d68000_move_fr_usp(void) +{ + 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); +} + +static void d68010_movec(void) +{ + 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 = "?"; + } + + if(BIT_1(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; + + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1<<(15-i))) + { + first = i; + run_length = 0; + for(i++;i<8;i++) + if(data&(1<<(15-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; + for(i++;i<8;i++) + if(data&(1<<(7-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; + + buffer[0] = 0; + for(i=0;i<8;i++) + { + if(data&(1<<(15-i))) + { + first = i; + run_length = 0; + for(i++;i<8;i++) + if(data&(1<<(15-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; + for(i++;i<8;i++) + if(data&(1<<(7-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; + + 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; + for(i++;i<8;i++) + if(data&(1<<(i+8))) + 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; + + 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; + for(i++;i<8;i++) + if(data&(1<<(i+8))) + 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; + + 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; + for(i++;i<8;i++) + if(data&(1<<(i+8))) + 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; + + 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; + for(i++;i<8;i++) + if(data&(1<<(i+8))) + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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()); +} + +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); +} + +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()); +} + +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); +} + +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); +} + +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); +} + +static void d68020_mull(void) +{ + 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); +} + +static void d68000_nbcd(void) +{ + 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)); +} + +static void d68000_neg_16(void) +{ + 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)); +} + +static void d68000_negx_8(void) +{ + 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)); +} + +static void d68000_negx_32(void) +{ + 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"); +} + +static void d68000_not_8(void) +{ + 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)); +} + +static void d68000_not_32(void) +{ + 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); +} + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68000_ori_to_ccr(void) +{ + 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()); +} + +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()); +} + +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()); +} + +static void d68000_pea(void) +{ + sprintf(g_dasm_str, "pea %s", get_ea_mode_str_32(g_cpu_ir)); +} + +static void d68000_reset(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_ror_ea(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_rol_ea(void) +{ + 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); +} + +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); +} + + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_roxr_ea(void) +{ + 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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_roxl_ea(void) +{ + 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()); +} + +static void d68000_rte(void) +{ + sprintf(g_dasm_str, "rte"); +} + +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); +} + +static void d68000_rtr(void) +{ + sprintf(g_dasm_str, "rtr"); +} + +static void d68000_rts(void) +{ + sprintf(g_dasm_str, "rts"); +} + +static void d68000_sbcd_rr(void) +{ + 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); +} + +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)); +} + +static void d68000_stop(void) +{ + 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); +} + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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); +} + +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); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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)); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +static void d68000_swap(void) +{ + 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)); +} + +static void d68000_trap(void) +{ + 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]); +} + +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()); +} + +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()); +} + +static void d68000_trapv(void) +{ + sprintf(g_dasm_str, "trapv"); +} + +static void d68000_tst_8(void) +{ + 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)); +} + +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)); +} + +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)); +} + +static void d68000_tst_16(void) +{ + 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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68000_tst_32(void) +{ + 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)); +} + +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)); +} + +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)); +} + +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)); +} + +static void d68000_unlk(void) +{ + 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()); +} + +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()); +} + + + +/* ======================================================================== */ +/* ======================= INSTRUCTION TABLE BUILDER ====================== */ +/* ======================================================================== */ + +/* EA Masks: +800 = data register direct +400 = address register direct +200 = address register indirect +100 = ARI postincrement + 80 = ARI pre-decrement + 40 = ARI displacement + 20 = ARI index + 10 = absolute short + 8 = absolute long + 4 = immediate / sr + 2 = pc displacement + 1 = pc idx +*/ + +static 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}, + {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}, + {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}, + {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; + + 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; + + 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); + + 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; + uint opcode_info_length = 0; + + for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++) + opcode_info_length++; + + qsort((void *)g_opcode_info, opcode_info_length, sizeof(g_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 = g_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; + } + } + } + } +} + + + +/* ======================================================================== */ +/* ================================= API ================================== */ +/* ======================================================================== */ + +/* 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_68030: + g_cpu_type = TYPE_68030; + g_address_mask = 0xffffffff; + break; + case M68K_CPU_TYPE_68040: + 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_instruction_table[g_cpu_ir](); + sprintf(str_buff, "%s%s", g_dasm_str, g_helper_str); + return 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; +} + +/* 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; + } + + 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; + 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; + case M68K_CPU_TYPE_68EC020: + case M68K_CPU_TYPE_68020: + case M68K_CPU_TYPE_68030: + 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; + } + 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; +} + + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ diff --git a/src/m68kdasmAG.cpp b/src/m68kdasmAG.cpp new file mode 100644 index 0000000..b254b2d --- /dev/null +++ b/src/m68kdasmAG.cpp @@ -0,0 +1,2344 @@ +/* + * A MC68000/MC68010 disassembler + * + * Note: this is probably not the most efficient disassembler in the world :-) + * + * This code written by Aaron Giles (agiles@sirius.com) for the MAME project + * + */ + +#include +#include + +static char *ccodes[16] = { "T ", "F ", "HI", "LS", "CC", "CS", "NE", "EQ", "VC", "VS", "PL", "MI", "GE", "LT", "GT", "LE" }; + +#define PARAM_WORD(v) ((v) = *(unsigned short *)&p[0], p += 2) +#define PARAM_LONG(v) ((v) = (*(unsigned short *)&p[0] << 16) + *(unsigned short *)&p[2], p += 4) + +#ifdef LOGGING + +static char *MakeEA (int lo, char *pBase, int size, int *count) +{ + static char buffer[2][80]; + static int which; + + unsigned char *p = (unsigned char *)pBase; + char *buf = buffer[which]; + int reg = lo & 7; + unsigned long pm; + int temp; + + which ^= 1; + switch ((lo >> 3) & 7) + { + case 0: + sprintf (buf, "D%d", reg); + break; + case 1: + sprintf (buf, "A%d", reg); + break; + case 2: + sprintf (buf, "(A%d)", reg); + break; + case 3: + sprintf (buf, "(A%d)+", reg); + break; + case 4: + sprintf (buf, "-(A%d)", reg); + break; + case 5: + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buf, "(-$%X,A%d)", -(signed short)pm & 0xffff, reg); + else + sprintf (buf, "($%lX,A%d)", pm, reg); + break; + case 6: + PARAM_WORD (pm); + temp = pm & 0xff; + if (temp & 0x80) + sprintf (buf, "(-$%X,A%d,D%ld.%c)", -(signed char)temp & 0xff, reg, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + else + sprintf (buf, "($%X,A%d,D%ld.%c)", temp, reg, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + break; + case 7: + switch (reg) + { + case 0: + PARAM_WORD (pm); + sprintf (buf, "$%lX", pm); + break; + case 1: + PARAM_LONG (pm); + sprintf (buf, "$%lX", pm); + break; + case 2: + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buf, "(-$%X,PC)", -(signed short)pm & 0xffff); + else + sprintf (buf, "($%lX,PC)", pm); + break; + case 3: + PARAM_WORD (pm); + temp = pm & 0xff; + if (temp & 0x80) + sprintf (buf, "(-$%X,PC,D%ld.%c)", -(signed char)temp & 0xff, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + else + sprintf (buf, "($%X,PC,D%ld.%c)", temp, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + break; + case 4: + if (size == 1) + { + PARAM_WORD (pm); + temp = pm & 0xff; + sprintf (buf, "#$%X", temp); + } + else if (size == 2) + { + PARAM_WORD (pm); + sprintf (buf, "#$%lX", pm); + } + else + { + PARAM_LONG (pm); + sprintf (buf, "#$%lX", pm); + } + break; + } + break; + } + + *count = p - ((unsigned char*)pBase); + return buf; +} + +static char *MakeRegList (char *p, unsigned short pm) +{ + int start = -1, sep = 0; + int i; + + for (i = 0; i < 8; i++, pm >>= 1) + { + if ((pm & 1) && start == -1) + start = i; + else if (!(pm & 1) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "D%d", start); + else p += sprintf (p, "D%d-D%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "D7"); + else p += sprintf (p, "D%d-D7", start); + start = -1; + } + + for (i = 0; i < 8; i++, pm >>= 1) + { + if ((pm & 1) && start == -1) + start = i; + else if (!(pm & 1) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "A%d", start); + else p += sprintf (p, "A%d-A%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "A7"); + else p += sprintf (p, "A%d-A7", start); + } + + return p; +} + +static char *MakeRevRegList (char *p, unsigned short pm) +{ + int start = -1, sep = 0; + int i; + + for (i = 0; i < 8; i++, pm <<= 1) + { + if ((pm & 0x8000) && start == -1) + start = i; + else if (!(pm & 0x8000) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "D%d", start); + else p += sprintf (p, "D%d-D%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "D7"); + else p += sprintf (p, "D%d-D7", start); + start = -1; + } + + for (i = 0; i < 8; i++, pm <<= 1) + { + if ((pm & 0x8000) && start == -1) + start = i; + else if (!(pm & 0x8000) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "A%d", start); + else p += sprintf (p, "A%d-A%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "A7"); + else p += sprintf (p, "A%d-A7", start); + } + + return p; +} + + +int Dasm68000 (char *pBase, char *buffer, int pc) +{ + char *ea, *ea2, *p = pBase; + unsigned short op, lo, rhi, rlo; + unsigned long pm; + int count; + + PARAM_WORD(op); + + lo = op & 0x3f; + rhi = (op >> 9) & 7; + rlo = op & 7; + switch (op & 0xffc0) + { + case 0x0000: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ORI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ORI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0040: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ORI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ORI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0080: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ORI.L #$%lX,%s", pm, ea); + break; + case 0x0100: case 0x0300: case 0x0500: case 0x0700: case 0x0900: case 0x0b00: case 0x0d00: case 0x0f00: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.W ($%lX,A%d),D%d", pm, rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BTST D%d,%s", rhi, ea); + } + break; + case 0x0140: case 0x0340: case 0x0540: case 0x0740: case 0x0940: case 0x0b40: case 0x0d40: case 0x0f40: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.L ($%lX,A%d),D%d", pm, rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCHG D%d,%s", rhi, ea); + } + break; + case 0x0180: case 0x0380: case 0x0580: case 0x0780: case 0x0980: case 0x0b80: case 0x0d80: case 0x0f80: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.W D%d,($%lX,A%d)", rhi, pm, rlo); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCLR D%d,%s", rhi, ea); + } + break; + case 0x01c0: case 0x03c0: case 0x05c0: case 0x07c0: case 0x09c0: case 0x0bc0: case 0x0dc0: case 0x0fc0: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.L D%d,($%lX,A%d)", rhi, pm, rlo); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BSET D%d,%s", rhi, ea); + } + break; + case 0x0200: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ANDI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ANDI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0240: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ANDI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ANDI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0280: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ANDI.L #$%lX,%s", pm, ea); + break; + case 0x0400: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUBI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0440: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0480: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBI.L #$%lX,%s", pm, ea); + break; + case 0x0600: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADDI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0640: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0680: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDI.L #$%lX,%s", pm, ea); + break; + case 0x0800: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BTST #$%lX,%s", pm & 0xff, ea); + break; + case 0x0840: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCHG #$%lX,%s", pm & 0xff, ea); + break; + case 0x0880: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCLR #$%lX,%s", pm & 0xff, ea); + break; + case 0x08c0: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BSET #$%lX,%s", pm & 0xff, ea); + break; + case 0x0a00: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "EORI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "EORI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0a40: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "EORI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "EORI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0a80: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "EORI.L #$%lX,%s", pm, ea); + break; + case 0x0c00: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CMPI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0c40: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMPI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0c80: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMPI.L #$%lX,%s", pm, ea); + break; + case 0x0e00: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.B A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.B D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.B %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.B %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x0e40: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.W A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.W D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.W %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.W %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x0e80: + PARAM_WORD(pm); ea = MakeEA (lo, p, 4, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.L A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.L D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.L %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.L %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x1000: case 0x1080: case 0x10c0: case 0x1100: case 0x1140: case 0x1180: case 0x11c0: + case 0x1200: case 0x1280: case 0x12c0: case 0x1300: case 0x1340: case 0x1380: case 0x13c0: + case 0x1400: case 0x1480: case 0x14c0: case 0x1500: case 0x1540: case 0x1580: + case 0x1600: case 0x1680: case 0x16c0: case 0x1700: case 0x1740: case 0x1780: + case 0x1800: case 0x1880: case 0x18c0: case 0x1900: case 0x1940: case 0x1980: + case 0x1a00: case 0x1a80: case 0x1ac0: case 0x1b00: case 0x1b40: case 0x1b80: + case 0x1c00: case 0x1c80: case 0x1cc0: case 0x1d00: case 0x1d40: case 0x1d80: + case 0x1e00: case 0x1e80: case 0x1ec0: case 0x1f00: case 0x1f40: case 0x1f80: + ea = MakeEA (lo, p, 1, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 1, &count); p += count; + sprintf (buffer, "MOVE.B %s,%s", ea, ea2); + break; + case 0x2000: case 0x2080: case 0x20c0: case 0x2100: case 0x2140: case 0x2180: case 0x21c0: + case 0x2200: case 0x2280: case 0x22c0: case 0x2300: case 0x2340: case 0x2380: case 0x23c0: + case 0x2400: case 0x2480: case 0x24c0: case 0x2500: case 0x2540: case 0x2580: + case 0x2600: case 0x2680: case 0x26c0: case 0x2700: case 0x2740: case 0x2780: + case 0x2800: case 0x2880: case 0x28c0: case 0x2900: case 0x2940: case 0x2980: + case 0x2a00: case 0x2a80: case 0x2ac0: case 0x2b00: case 0x2b40: case 0x2b80: + case 0x2c00: case 0x2c80: case 0x2cc0: case 0x2d00: case 0x2d40: case 0x2d80: + case 0x2e00: case 0x2e80: case 0x2ec0: case 0x2f00: case 0x2f40: case 0x2f80: + ea = MakeEA (lo, p, 4, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 4, &count); p += count; + sprintf (buffer, "MOVE.L %s,%s", ea, ea2); + break; + case 0x2040: case 0x2240: case 0x2440: case 0x2640: case 0x2840: case 0x2a40: case 0x2c40: case 0x2e40: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "MOVEA.L %s,A%d", ea, rhi); + break; + case 0x3000: case 0x3080: case 0x30c0: case 0x3100: case 0x3140: case 0x3180: case 0x31c0: + case 0x3200: case 0x3280: case 0x32c0: case 0x3300: case 0x3340: case 0x3380: case 0x33c0: + case 0x3400: case 0x3480: case 0x34c0: case 0x3500: case 0x3540: case 0x3580: + case 0x3600: case 0x3680: case 0x36c0: case 0x3700: case 0x3740: case 0x3780: + case 0x3800: case 0x3880: case 0x38c0: case 0x3900: case 0x3940: case 0x3980: + case 0x3a00: case 0x3a80: case 0x3ac0: case 0x3b00: case 0x3b40: case 0x3b80: + case 0x3c00: case 0x3c80: case 0x3cc0: case 0x3d00: case 0x3d40: case 0x3d80: + case 0x3e00: case 0x3e80: case 0x3ec0: case 0x3f00: case 0x3f40: case 0x3f80: + ea = MakeEA (lo, p, 2, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 2, &count); p += count; + sprintf (buffer, "MOVE.W %s,%s", ea, ea2); + break; + case 0x3040: case 0x3240: case 0x3440: case 0x3640: case 0x3840: case 0x3a40: case 0x3c40: case 0x3e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVEA.W %s,A%d", ea, rhi); + break; + case 0x4000: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NEGX.B %s", ea); + break; + case 0x4040: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NEGX.W %s", ea); + break; + case 0x4080: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NEGX.L %s", ea); + break; + case 0x40c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE SR,%s", ea); + break; + case 0x4180: case 0x4380: case 0x4580: case 0x4780: case 0x4980: case 0x4b80: case 0x4d80: case 0x4f80: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CHK.W %s,D%d", ea, rhi); + break; + case 0x41c0: case 0x43c0: case 0x45c0: case 0x47c0: case 0x49c0: case 0x4bc0: case 0x4dc0: case 0x4fc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "LEA %s,A%d", ea, rhi); + break; + case 0x4200: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CLR.B %s", ea); + break; + case 0x4240: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CLR.W %s", ea); + break; + case 0x4280: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CLR.L %s", ea); + break; + case 0x42c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE CCR,%s", ea); + break; + case 0x4400: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NEG.B %s", ea); + break; + case 0x4440: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NEG.W %s", ea); + break; + case 0x4480: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NEG.L %s", ea); + break; + case 0x44c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE %s,CCR", ea); + break; + case 0x4600: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NOT.B %s", ea); + break; + case 0x4640: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NOT.W %s", ea); + break; + case 0x4680: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NOT.L %s", ea); + break; + case 0x46c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE %s,SR", ea); + break; + case 0x4800: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NBCD.B %s", ea); + break; + case 0x4840: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "SWAP D%d", rlo); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "PEA %s", ea); + } + break; + case 0x4880: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "EXT.W D%d", rlo); + else + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 2, &count); p += count; + b += sprintf (b, "MOVEM.W "); + if ((lo & 0x38) != 0x20) b = MakeRegList (b, pm); + else b = MakeRevRegList (b, pm); + sprintf (b, ",%s", ea); + } + break; + case 0x48c0: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "EXT.L D%d", rlo); + else + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 4, &count); p += count; + b += sprintf (b, "MOVEM.L "); + if ((lo & 0x38) != 0x20) b = MakeRegList (b, pm); + else b = MakeRevRegList (b, pm); + sprintf (b, ",%s", ea); + } + break; + case 0x4a00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "TST.B %s", ea); + break; + case 0x4a40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "TST.W %s", ea); + break; + case 0x4a80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "TST.L %s", ea); + break; + case 0x4ac0: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "TAS.B %s", ea); + break; + case 0x4c80: + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 2, &count); p += count; + b += sprintf (b, "MOVEM.W %s,", ea); + b = MakeRegList (b, pm); + } + break; + case 0x4cc0: + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 4, &count); p += count; + b += sprintf (b, "MOVEM.L %s,", ea); + b = MakeRegList (b, pm); + } + break; + case 0x4e40: + if ((lo & 30) == 0x00) + sprintf (buffer, "TRAP #$%X", lo & 15); + else if ((lo & 0x38) == 0x10) + { + PARAM_WORD (pm); + sprintf (buffer, "LINK A%d,#$%lX", rlo, pm); + } + else if ((lo & 0x38) == 0x18) + { + sprintf (buffer, "UNLK A%d", rlo); + } + else if ((lo & 0x38) == 0x20) + sprintf (buffer, "MOVE A%d,USP", rlo); + else if ((lo & 0x38) == 0x28) + sprintf (buffer, "MOVE USP,A%d", rlo); + else if (lo == 0x30) + sprintf (buffer, "RESET"); + else if (lo == 0x31) + sprintf (buffer, "NOP"); + else if (lo == 0x32) + sprintf (buffer, "STOP"); + else if (lo == 0x33) + sprintf (buffer, "RTE"); + else if (lo == 0x35) + sprintf (buffer, "RTS"); + else if (lo == 0x36) + sprintf (buffer, "TRAPV"); + else if (lo == 0x37) + sprintf (buffer, "RTR"); + else if (lo == 0x3a) + { + PARAM_WORD (pm); + switch (pm & 0xfff) + { + case 0x000: ea = "SFC"; break; + case 0x001: ea = "DFC"; break; + case 0x800: ea = "USP"; break; + case 0x801: ea = "VBR"; break; + default: ea = "???"; break; + } + if (pm & 0x8000) + sprintf (buffer, "MOVEC %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVEC %s,D%ld", ea, (pm >> 12) & 7); + } + else if (lo == 0x3b) + { + PARAM_WORD (pm); + switch (pm & 0xfff) + { + case 0x000: ea = "SFC"; break; + case 0x001: ea = "DFC"; break; + case 0x800: ea = "USP"; break; + case 0x801: ea = "VBR"; break; + default: ea = "???"; break; + } + if (pm & 0x8000) + sprintf (buffer, "MOVEC A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVEC D%ld,%s", (pm >> 12) & 7, ea); + } + else + sprintf (buffer, "DC.W $%X", op); + break; + case 0x4e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "JSR %s", ea); + break; + case 0x4ec0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "JMP %s", ea); + break; + case 0x5000: case 0x5200: case 0x5400: case 0x5600: case 0x5800: case 0x5a00: case 0x5c00: case 0x5e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADDQ.B #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5040: case 0x5240: case 0x5440: case 0x5640: case 0x5840: case 0x5a40: case 0x5c40: case 0x5e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDQ.W #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5080: case 0x5280: case 0x5480: case 0x5680: case 0x5880: case 0x5a80: case 0x5c80: case 0x5e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDQ.L #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x50c0: case 0x52c0: case 0x54c0: case 0x56c0: case 0x58c0: case 0x5ac0: case 0x5cc0: case 0x5ec0: + case 0x51c0: case 0x53c0: case 0x55c0: case 0x57c0: case 0x59c0: case 0x5bc0: case 0x5dc0: case 0x5fc0: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buffer, "DB%s D%d,*-$%X [%X]", ccodes[(op >> 8) & 15], rlo, (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "DB%s D%d,*+$%lX [%lX]", ccodes[(op >> 8) & 15], rlo, pm - 2, pc + pm + 2); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "S%s.B %s", ccodes[(op >> 8) & 15], ea); + } + break; + case 0x5100: case 0x5300: case 0x5500: case 0x5700: case 0x5900: case 0x5b00: case 0x5d00: case 0x5f00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUBQ.B #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5140: case 0x5340: case 0x5540: case 0x5740: case 0x5940: case 0x5b40: case 0x5d40: case 0x5f40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBQ.W #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5180: case 0x5380: case 0x5580: case 0x5780: case 0x5980: case 0x5b80: case 0x5d80: case 0x5f80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBQ.L #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x6000: case 0x6040: case 0x6080: case 0x60c0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "BRA *-$%X [%X]", (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "BRA *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "BRA.S *-$%X [%X]", (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "BRA.S *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + break; + case 0x6100: case 0x6140: case 0x6180: case 0x61c0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "BSR *-$%X [%X]", (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "BSR *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "BSR.S *-$%X [%X]", (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "BSR.S *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + break; + case 0x6200: case 0x6240: case 0x6280: case 0x62c0: case 0x6300: case 0x6340: case 0x6380: case 0x63c0: + case 0x6400: case 0x6440: case 0x6480: case 0x64c0: case 0x6500: case 0x6540: case 0x6580: case 0x65c0: + case 0x6600: case 0x6640: case 0x6680: case 0x66c0: case 0x6700: case 0x6740: case 0x6780: case 0x67c0: + case 0x6800: case 0x6840: case 0x6880: case 0x68c0: case 0x6900: case 0x6940: case 0x6980: case 0x69c0: + case 0x6a00: case 0x6a40: case 0x6a80: case 0x6ac0: case 0x6b00: case 0x6b40: case 0x6b80: case 0x6bc0: + case 0x6c00: case 0x6c40: case 0x6c80: case 0x6cc0: case 0x6d00: case 0x6d40: case 0x6d80: case 0x6dc0: + case 0x6e00: case 0x6e40: case 0x6e80: case 0x6ec0: case 0x6f00: case 0x6f40: case 0x6f80: case 0x6fc0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "B%s *-$%X [%X]", ccodes[(op >> 8) & 15], (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "B%s *+$%lX [%lX]", ccodes[(op >> 8) & 15], pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "B%s.S *-$%X [%X]", ccodes[(op >> 8) & 15], (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "B%s.S *+$%lX [%lX]", ccodes[(op >> 8) & 15], pm + 2, pc + pm + 2); + } + break; + case 0x7000: case 0x7040: case 0x7080: case 0x70c0: + case 0x7200: case 0x7240: case 0x7280: case 0x72c0: + case 0x7400: case 0x7440: case 0x7480: case 0x74c0: + case 0x7600: case 0x7640: case 0x7680: case 0x76c0: + case 0x7800: case 0x7840: case 0x7880: case 0x78c0: + case 0x7a00: case 0x7a40: case 0x7a80: case 0x7ac0: + case 0x7c00: case 0x7c40: case 0x7c80: case 0x7cc0: + case 0x7e00: case 0x7e40: case 0x7e80: case 0x7ec0: + pm = op & 0xff; + if (pm & 0x80) + sprintf (buffer, "MOVEQ #$-%X,D%d", -(signed char)pm, rhi); + else + sprintf (buffer, "MOVEQ #$%lX,D%d", pm, rhi); + break; + case 0x8000: case 0x8200: case 0x8400: case 0x8600: case 0x8800: case 0x8a00: case 0x8c00: case 0x8e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "OR.B %s,D%d", ea, rhi); + break; + case 0x8040: case 0x8240: case 0x8440: case 0x8640: case 0x8840: case 0x8a40: case 0x8c40: case 0x8e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "OR.W %s,D%d", ea, rhi); + break; + case 0x8080: case 0x8280: case 0x8480: case 0x8680: case 0x8880: case 0x8a80: case 0x8c80: case 0x8e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "OR.L %s,D%d", ea, rhi); + break; + case 0x80c0: case 0x82c0: case 0x84c0: case 0x86c0: case 0x88c0: case 0x8ac0: case 0x8cc0: case 0x8ec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "DIVU.W %s,D%d", ea, rhi); + break; + case 0x8100: case 0x8300: case 0x8500: case 0x8700: case 0x8900: case 0x8b00: case 0x8d00: case 0x8f00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "OR.B D%d,%s", rhi, ea); + break; + case 0x8140: case 0x8340: case 0x8540: case 0x8740: case 0x8940: case 0x8b40: case 0x8d40: case 0x8f40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "OR.W D%d,%s", rhi, ea); + break; + case 0x8180: case 0x8380: case 0x8580: case 0x8780: case 0x8980: case 0x8b80: case 0x8d80: case 0x8f80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "OR.L D%d,%s", rhi, ea); + break; + case 0x81c0: case 0x83c0: case 0x85c0: case 0x87c0: case 0x89c0: case 0x8bc0: case 0x8dc0: case 0x8fc0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "DIVS.W %s,D%d", ea, rhi); + break; + case 0x9000: case 0x9200: case 0x9400: case 0x9600: case 0x9800: case 0x9a00: case 0x9c00: case 0x9e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUB.B %s,D%d", ea, rhi); + break; + case 0x9040: case 0x9240: case 0x9440: case 0x9640: case 0x9840: case 0x9a40: case 0x9c40: case 0x9e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUB.W %s,D%d", ea, rhi); + break; + case 0x9080: case 0x9280: case 0x9480: case 0x9680: case 0x9880: case 0x9a80: case 0x9c80: case 0x9e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUB.L %s,D%d", ea, rhi); + break; + case 0x90c0: case 0x92c0: case 0x94c0: case 0x96c0: case 0x98c0: case 0x9ac0: case 0x9cc0: case 0x9ec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBA.W %s,A%d", ea, rhi); + break; + case 0x9100: case 0x9300: case 0x9500: case 0x9700: case 0x9900: case 0x9b00: case 0x9d00: case 0x9f00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1,&count); p += count; + sprintf (buffer, "SUB.B D%d,%s", rhi, ea); + } + break; + case 0x9140: case 0x9340: case 0x9540: case 0x9740: case 0x9940: case 0x9b40: case 0x9d40: case 0x9f40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.W -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.W D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUB.W D%d,%s", rhi, ea); + } + break; + case 0x9180: case 0x9380: case 0x9580: case 0x9780: case 0x9980: case 0x9b80: case 0x9d80: case 0x9f80: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.L -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.L D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUB.L D%d,%s", rhi, ea); + } + break; + case 0x91c0: case 0x93c0: case 0x95c0: case 0x97c0: case 0x99c0: case 0x9bc0: case 0x9dc0: case 0x9fc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBA.L %s,A%d", ea, rhi); + break; + case 0xb000: case 0xb200: case 0xb400: case 0xb600: case 0xb800: case 0xba00: case 0xbc00: case 0xbe00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CMP.B %s,D%d", ea, rhi); + break; + case 0xb040: case 0xb240: case 0xb440: case 0xb640: case 0xb840: case 0xba40: case 0xbc40: case 0xbe40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMP.W %s,D%d", ea, rhi); + break; + case 0xb080: case 0xb280: case 0xb480: case 0xb680: case 0xb880: case 0xba80: case 0xbc80: case 0xbe80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMP.L %s,D%d", ea, rhi); + break; + case 0xb0c0: case 0xb2c0: case 0xb4c0: case 0xb6c0: case 0xb8c0: case 0xbac0: case 0xbcc0: case 0xbec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMPA.W %s,A%d", ea, rhi); + break; + case 0xb100: case 0xb300: case 0xb500: case 0xb700: case 0xb900: case 0xbb00: case 0xbd00: case 0xbf00: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.B (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "EOR.B D%d,%s", rhi, ea); + } + break; + case 0xb140: case 0xb340: case 0xb540: case 0xb740: case 0xb940: case 0xbb40: case 0xbd40: case 0xbf40: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.W (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "EOR.W D%d,%s", rhi, ea); + } + break; + case 0xb180: case 0xb380: case 0xb580: case 0xb780: case 0xb980: case 0xbb80: case 0xbd80: case 0xbf80: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.L (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "EOR.L D%d,%s", rhi, ea); + } + break; + case 0xb1c0: case 0xb3c0: case 0xb5c0: case 0xb7c0: case 0xb9c0: case 0xbbc0: case 0xbdc0: case 0xbfc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMPA.L %s,A%d", ea, rhi); + break; + case 0xc000: case 0xc200: case 0xc400: case 0xc600: case 0xc800: case 0xca00: case 0xcc00: case 0xce00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "AND.B %s,D%d", ea, rhi); + break; + case 0xc040: case 0xc240: case 0xc440: case 0xc640: case 0xc840: case 0xca40: case 0xcc40: case 0xce40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "AND.W %s,D%d", ea, rhi); + break; + case 0xc080: case 0xc280: case 0xc480: case 0xc680: case 0xc880: case 0xca80: case 0xcc80: case 0xce80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "AND.L %s,D%d", ea, rhi); + break; + case 0xc0c0: case 0xc2c0: case 0xc4c0: case 0xc6c0: case 0xc8c0: case 0xcac0: case 0xccc0: case 0xcec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MULU.W %s,D%d", ea, rhi); + break; + case 0xc100: case 0xc300: case 0xc500: case 0xc700: case 0xc900: case 0xcb00: case 0xcd00: case 0xcf00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ABCD.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ABCD.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "AND.B D%d,%s", rhi, ea); + } + break; + case 0xc140: case 0xc340: case 0xc540: case 0xc740: case 0xc940: case 0xcb40: case 0xcd40: case 0xcf40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "EXG A%d,A%d", rhi, rlo); + else + sprintf (buffer, "EXG D%d,D%d", rhi, rlo); + } + else + { + ea = MakeEA (lo, p, 2,&count); p += count; + sprintf (buffer, "AND.W D%d,%s", rhi, ea); + } + break; + case 0xc180: case 0xc380: case 0xc580: case 0xc780: case 0xc980: case 0xcb80: case 0xcd80: case 0xcf80: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "EXG D%d,A%d", rhi, rlo); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "AND.L D%d,%s", rhi, ea); + } + break; + case 0xc1c0: case 0xc3c0: case 0xc5c0: case 0xc7c0: case 0xc9c0: case 0xcbc0: case 0xcdc0: case 0xcfc0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MULS.W %s,D%d", ea, rhi); + break; + case 0xd000: case 0xd200: case 0xd400: case 0xd600: case 0xd800: case 0xda00: case 0xdc00: case 0xde00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADD.B %s,D%d", ea, rhi); + break; + case 0xd040: case 0xd240: case 0xd440: case 0xd640: case 0xd840: case 0xda40: case 0xdc40: case 0xde40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADD.W %s,D%d", ea, rhi); + break; + case 0xd080: case 0xd280: case 0xd480: case 0xd680: case 0xd880: case 0xda80: case 0xdc80: case 0xde80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADD.L %s,D%d", ea, rhi); + break; + case 0xd0c0: case 0xd2c0: case 0xd4c0: case 0xd6c0: case 0xd8c0: case 0xdac0: case 0xdcc0: case 0xdec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDA.W %s,A%d", ea, rhi); + break; + case 0xd100: case 0xd300: case 0xd500: case 0xd700: case 0xd900: case 0xdb00: case 0xdd00: case 0xdf00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADD.B D%d,%s", rhi, ea); + } + break; + case 0xd140: case 0xd340: case 0xd540: case 0xd740: case 0xd940: case 0xdb40: case 0xdd40: case 0xdf40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.W -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.W D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADD.W D%d,%s", rhi, ea); + } + break; + case 0xd180: case 0xd380: case 0xd580: case 0xd780: case 0xd980: case 0xdb80: case 0xdd80: case 0xdf80: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.L -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.L D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 4,&count); p += count; + sprintf (buffer, "ADD.L D%d,%s", rhi, ea); + } + break; + case 0xd1c0: case 0xd3c0: case 0xd5c0: case 0xd7c0: case 0xd9c0: case 0xdbc0: case 0xddc0: case 0xdfc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDA.L %s,A%d", ea, rhi); + break; + case 0xe000: case 0xe200: case 0xe400: case 0xe600: case 0xe800: case 0xea00: case 0xec00: case 0xee00: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.B D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.B D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.B D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.B D%d,D%d", rhi, rlo); break; + } + break; + case 0xe040: case 0xe240: case 0xe440: case 0xe640: case 0xe840: case 0xea40: case 0xec40: case 0xee40: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.W D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.W D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.W D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.W D%d,D%d", rhi, rlo); break; + } + break; + case 0xe080: case 0xe280: case 0xe480: case 0xe680: case 0xe880: case 0xea80: case 0xec80: case 0xee80: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.L D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.L D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.L D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.L D%d,D%d", rhi, rlo); break; + } + break; + case 0xe0c0: case 0xe2c0: case 0xe4c0: case 0xe6c0: + case 0xe1c0: case 0xe3c0: case 0xe5c0: case 0xe7c0: + ea = MakeEA (lo, p, 4, &count); p += count; + switch ((op >> 8) & 7) + { + case 0: sprintf (buffer, "ASR.L #1,%s", ea); break; + case 1: sprintf (buffer, "ASL.L #1,%s", ea); break; + case 2: sprintf (buffer, "LSR.L #1,%s", ea); break; + case 3: sprintf (buffer, "LSL.L #1,%s", ea); break; + case 4: sprintf (buffer, "ROXR.L #1,%s", ea); break; + case 5: sprintf (buffer, "ROXL.L #1,%s", ea); break; + case 6: sprintf (buffer, "ROR.L #1,%s", ea); break; + case 7: sprintf (buffer, "ROL.L #1,%s", ea); break; + } + break; + case 0xe100: case 0xe300: case 0xe500: case 0xe700: case 0xe900: case 0xeb00: case 0xed00: case 0xef00: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.B D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.B D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.B D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.B D%d,D%d", rhi, rlo); break; + } + break; + case 0xe140: case 0xe340: case 0xe540: case 0xe740: case 0xe940: case 0xeb40: case 0xed40: case 0xef40: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.W D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.W D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.W D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.W D%d,D%d", rhi, rlo); break; + } + break; + case 0xe180: case 0xe380: case 0xe580: case 0xe780: case 0xe980: case 0xeb80: case 0xed80: case 0xef80: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.L D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.L D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.L D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.L D%d,D%d", rhi, rlo); break; + } + break; + default: + sprintf (buffer, "DC.W $%X", op); + break; + } + + return p - pBase; +} + +#else + +static char *MakeEA (int lo, char *pBase, int size, int *count) +{ + static char buffer[2][80]; + static int which; + + unsigned char *p = (unsigned char *)pBase; + char *buf = buffer[which]; + int reg = lo & 7; + unsigned long pm; + int temp; + + which ^= 1; + switch ((lo >> 3) & 7) + { + case 0: + sprintf (buf, "D%d", reg); + break; + case 1: + sprintf (buf, "A%d", reg); + break; + case 2: + sprintf (buf, "(A%d)", reg); + break; + case 3: + sprintf (buf, "(A%d)+", reg); + break; + case 4: + sprintf (buf, "-(A%d)", reg); + break; + case 5: + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buf, "(-$%X,A%d)", -(signed short)pm & 0xffff, reg); + else + sprintf (buf, "($%lX,A%d)", pm, reg); + break; + case 6: + PARAM_WORD (pm); + temp = pm & 0xff; + if (temp & 0x80) + sprintf (buf, "(-$%X,A%d,D%ld.%c)", -(signed char)temp & 0xff, reg, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + else + sprintf (buf, "($%X,A%d,D%ld.%c)", temp, reg, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + break; + case 7: + switch (reg) + { + case 0: + PARAM_WORD (pm); + sprintf (buf, "$%lX", pm); + break; + case 1: + PARAM_LONG (pm); + sprintf (buf, "$%lX", pm); + break; + case 2: + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buf, "(-$%X,PC)", -(signed short)pm & 0xffff); + else + sprintf (buf, "($%lX,PC)", pm); + break; + case 3: + PARAM_WORD (pm); + temp = pm & 0xff; + if (temp & 0x80) + sprintf (buf, "(-$%X,PC,D%ld.%c)", -(signed char)temp & 0xff, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + else + sprintf (buf, "($%X,PC,D%ld.%c)", temp, (pm >> 12) & 7, (pm & 800) ? 'L' : 'W'); + break; + case 4: + if (size == 1) + { + PARAM_WORD (pm); + temp = pm & 0xff; + sprintf (buf, "#$%X", temp); + } + else if (size == 2) + { + PARAM_WORD (pm); + sprintf (buf, "#$%lX", pm); + } + else + { + PARAM_LONG (pm); + sprintf (buf, "#$%lX", pm); + } + break; + } + break; + } + + *count = p - ((unsigned char*)pBase); + return buf; +} + +static char *MakeRegList (char *p, unsigned short pm) +{ + int start = -1, sep = 0; + int i; + + for (i = 0; i < 8; i++, pm >>= 1) + { + if ((pm & 1) && start == -1) + start = i; + else if (!(pm & 1) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "D%d", start); + else p += sprintf (p, "D%d-D%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "D7"); + else p += sprintf (p, "D%d-D7", start); + start = -1; + } + + for (i = 0; i < 8; i++, pm >>= 1) + { + if ((pm & 1) && start == -1) + start = i; + else if (!(pm & 1) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "A%d", start); + else p += sprintf (p, "A%d-A%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "A7"); + else p += sprintf (p, "A%d-A7", start); + } + + return p; +} + +static char *MakeRevRegList (char *p, unsigned short pm) +{ + int start = -1, sep = 0; + int i; + + for (i = 0; i < 8; i++, pm <<= 1) + { + if ((pm & 0x8000) && start == -1) + start = i; + else if (!(pm & 0x8000) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "D%d", start); + else p += sprintf (p, "D%d-D%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "D7"); + else p += sprintf (p, "D%d-D7", start); + start = -1; + } + + for (i = 0; i < 8; i++, pm <<= 1) + { + if ((pm & 0x8000) && start == -1) + start = i; + else if (!(pm & 0x8000) && start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == i - 1) p += sprintf (p, "A%d", start); + else p += sprintf (p, "A%d-A%d", start, i - 1); + start = -1; + } + } + if (start != -1) + { + if (sep++) p += sprintf (p, "/"); + if (start == 7) p += sprintf (p, "A7"); + else p += sprintf (p, "A%d-A7", start); + } + + return p; +} + + +int Dasm68000 (char *pBase, char *buffer, int pc) +{ + char *ea, *ea2, *p = pBase; + unsigned short op, lo, rhi, rlo; + unsigned long pm; + int count; + + PARAM_WORD(op); + + lo = op & 0x3f; + rhi = (op >> 9) & 7; + rlo = op & 7; + switch (op & 0xffc0) + { + case 0x0000: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ORI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ORI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0040: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ORI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ORI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0080: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ORI.L #$%lX,%s", pm, ea); + break; + case 0x0100: case 0x0300: case 0x0500: case 0x0700: case 0x0900: case 0x0b00: case 0x0d00: case 0x0f00: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.W ($%lX,A%d),D%d", pm, rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BTST D%d,%s", rhi, ea); + } + break; + case 0x0140: case 0x0340: case 0x0540: case 0x0740: case 0x0940: case 0x0b40: case 0x0d40: case 0x0f40: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.L ($%lX,A%d),D%d", pm, rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCHG D%d,%s", rhi, ea); + } + break; + case 0x0180: case 0x0380: case 0x0580: case 0x0780: case 0x0980: case 0x0b80: case 0x0d80: case 0x0f80: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.W D%d,($%lX,A%d)", rhi, pm, rlo); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCLR D%d,%s", rhi, ea); + } + break; + case 0x01c0: case 0x03c0: case 0x05c0: case 0x07c0: case 0x09c0: case 0x0bc0: case 0x0dc0: case 0x0fc0: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD(pm); + sprintf (buffer, "MOVEP.L D%d,($%lX,A%d)", rhi, pm, rlo); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BSET D%d,%s", rhi, ea); + } + break; + case 0x0200: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ANDI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ANDI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0240: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "ANDI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ANDI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0280: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ANDI.L #$%lX,%s", pm, ea); + break; + case 0x0400: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUBI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0440: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0480: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBI.L #$%lX,%s", pm, ea); + break; + case 0x0600: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADDI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0640: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0680: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDI.L #$%lX,%s", pm, ea); + break; + case 0x0800: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BTST #$%lX,%s", pm & 0xff, ea); + break; + case 0x0840: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCHG #$%lX,%s", pm & 0xff, ea); + break; + case 0x0880: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BCLR #$%lX,%s", pm & 0xff, ea); + break; + case 0x08c0: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "BSET #$%lX,%s", pm & 0xff, ea); + break; + case 0x0a00: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "EORI #$%lX,CCR", pm & 0xff); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "EORI.B #$%lX,%s", pm & 0xff, ea); + } + break; + case 0x0a40: + PARAM_WORD(pm); + if (lo == 0x3c) + sprintf (buffer, "EORI #$%lX,SR", pm & 0xffff); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "EORI.W #$%lX,%s", pm & 0xffff, ea); + } + break; + case 0x0a80: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "EORI.L #$%lX,%s", pm, ea); + break; + case 0x0c00: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CMPI.B #$%lX,%s", pm & 0xff, ea); + break; + case 0x0c40: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMPI.W #$%lX,%s", pm & 0xffff, ea); + break; + case 0x0c80: + PARAM_LONG(pm); ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMPI.L #$%lX,%s", pm, ea); + break; + case 0x0e00: + PARAM_WORD(pm); ea = MakeEA (lo, p, 1, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.B A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.B D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.B %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.B %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x0e40: + PARAM_WORD(pm); ea = MakeEA (lo, p, 2, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.W A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.W D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.W %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.W %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x0e80: + PARAM_WORD(pm); ea = MakeEA (lo, p, 4, &count); p += count; + if (pm & 0x0800) + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.L A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVES.L D%ld,%s", (pm >> 12) & 7, ea); + } + else + { + if (pm & 0x8000) + sprintf (buffer, "MOVES.L %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVES.L %s,D%ld", ea, (pm >> 12) & 7); + } + break; + case 0x1000: case 0x1080: case 0x10c0: case 0x1100: case 0x1140: case 0x1180: case 0x11c0: + case 0x1200: case 0x1280: case 0x12c0: case 0x1300: case 0x1340: case 0x1380: case 0x13c0: + case 0x1400: case 0x1480: case 0x14c0: case 0x1500: case 0x1540: case 0x1580: + case 0x1600: case 0x1680: case 0x16c0: case 0x1700: case 0x1740: case 0x1780: + case 0x1800: case 0x1880: case 0x18c0: case 0x1900: case 0x1940: case 0x1980: + case 0x1a00: case 0x1a80: case 0x1ac0: case 0x1b00: case 0x1b40: case 0x1b80: + case 0x1c00: case 0x1c80: case 0x1cc0: case 0x1d00: case 0x1d40: case 0x1d80: + case 0x1e00: case 0x1e80: case 0x1ec0: case 0x1f00: case 0x1f40: case 0x1f80: + ea = MakeEA (lo, p, 1, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 1, &count); p += count; + sprintf (buffer, "MOVE.B %s,%s", ea, ea2); + break; + case 0x2000: case 0x2080: case 0x20c0: case 0x2100: case 0x2140: case 0x2180: case 0x21c0: + case 0x2200: case 0x2280: case 0x22c0: case 0x2300: case 0x2340: case 0x2380: case 0x23c0: + case 0x2400: case 0x2480: case 0x24c0: case 0x2500: case 0x2540: case 0x2580: + case 0x2600: case 0x2680: case 0x26c0: case 0x2700: case 0x2740: case 0x2780: + case 0x2800: case 0x2880: case 0x28c0: case 0x2900: case 0x2940: case 0x2980: + case 0x2a00: case 0x2a80: case 0x2ac0: case 0x2b00: case 0x2b40: case 0x2b80: + case 0x2c00: case 0x2c80: case 0x2cc0: case 0x2d00: case 0x2d40: case 0x2d80: + case 0x2e00: case 0x2e80: case 0x2ec0: case 0x2f00: case 0x2f40: case 0x2f80: + ea = MakeEA (lo, p, 4, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 4, &count); p += count; + sprintf (buffer, "MOVE.L %s,%s", ea, ea2); + break; + case 0x2040: case 0x2240: case 0x2440: case 0x2640: case 0x2840: case 0x2a40: case 0x2c40: case 0x2e40: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "MOVEA.L %s,A%d", ea, rhi); + break; + case 0x3000: case 0x3080: case 0x30c0: case 0x3100: case 0x3140: case 0x3180: case 0x31c0: + case 0x3200: case 0x3280: case 0x32c0: case 0x3300: case 0x3340: case 0x3380: case 0x33c0: + case 0x3400: case 0x3480: case 0x34c0: case 0x3500: case 0x3540: case 0x3580: + case 0x3600: case 0x3680: case 0x36c0: case 0x3700: case 0x3740: case 0x3780: + case 0x3800: case 0x3880: case 0x38c0: case 0x3900: case 0x3940: case 0x3980: + case 0x3a00: case 0x3a80: case 0x3ac0: case 0x3b00: case 0x3b40: case 0x3b80: + case 0x3c00: case 0x3c80: case 0x3cc0: case 0x3d00: case 0x3d40: case 0x3d80: + case 0x3e00: case 0x3e80: case 0x3ec0: case 0x3f00: case 0x3f40: case 0x3f80: + ea = MakeEA (lo, p, 2, &count); p += count; ea2 = MakeEA (((op >> 9) & 0x07) + ((op >> 3) & 0x38), p, 2, &count); p += count; + sprintf (buffer, "MOVE.W %s,%s", ea, ea2); + break; + case 0x3040: case 0x3240: case 0x3440: case 0x3640: case 0x3840: case 0x3a40: case 0x3c40: case 0x3e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVEA.W %s,A%d", ea, rhi); + break; + case 0x4000: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NEGX.B %s", ea); + break; + case 0x4040: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NEGX.W %s", ea); + break; + case 0x4080: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NEGX.L %s", ea); + break; + case 0x40c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE SR,%s", ea); + break; + case 0x4180: case 0x4380: case 0x4580: case 0x4780: case 0x4980: case 0x4b80: case 0x4d80: case 0x4f80: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CHK.W %s,D%d", ea, rhi); + break; + case 0x41c0: case 0x43c0: case 0x45c0: case 0x47c0: case 0x49c0: case 0x4bc0: case 0x4dc0: case 0x4fc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "LEA %s,A%d", ea, rhi); + break; + case 0x4200: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CLR.B %s", ea); + break; + case 0x4240: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CLR.W %s", ea); + break; + case 0x4280: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CLR.L %s", ea); + break; + case 0x42c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE CCR,%s", ea); + break; + case 0x4400: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NEG.B %s", ea); + break; + case 0x4440: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NEG.W %s", ea); + break; + case 0x4480: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NEG.L %s", ea); + break; + case 0x44c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE %s,CCR", ea); + break; + case 0x4600: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NOT.B %s", ea); + break; + case 0x4640: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "NOT.W %s", ea); + break; + case 0x4680: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "NOT.L %s", ea); + break; + case 0x46c0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MOVE %s,SR", ea); + break; + case 0x4800: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "NBCD.B %s", ea); + break; + case 0x4840: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "SWAP D%d", rlo); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "PEA %s", ea); + } + break; + case 0x4880: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "EXT.W D%d", rlo); + else + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 2, &count); p += count; + b += sprintf (b, "MOVEM.W "); + if ((lo & 0x38) != 0x20) b = MakeRegList (b, pm); + else b = MakeRevRegList (b, pm); + sprintf (b, ",%s", ea); + } + break; + case 0x48c0: + if ((lo & 0x38) == 0x00) + sprintf (buffer, "EXT.L D%d", rlo); + else + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 4, &count); p += count; + b += sprintf (b, "MOVEM.L "); + if ((lo & 0x38) != 0x20) b = MakeRegList (b, pm); + else b = MakeRevRegList (b, pm); + sprintf (b, ",%s", ea); + } + break; + case 0x4a00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "TST.B %s", ea); + break; + case 0x4a40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "TST.W %s", ea); + break; + case 0x4a80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "TST.L %s", ea); + break; + case 0x4ac0: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "TAS.B %s", ea); + break; + case 0x4c80: + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 2, &count); p += count; + b += sprintf (b, "MOVEM.W %s,", ea); + b = MakeRegList (b, pm); + } + break; + case 0x4cc0: + { + char *b = buffer; + PARAM_WORD (pm); ea = MakeEA (lo, p, 4, &count); p += count; + b += sprintf (b, "MOVEM.L %s,", ea); + b = MakeRegList (b, pm); + } + break; + case 0x4e40: + if ((lo & 30) == 0x00) + sprintf (buffer, "TRAP #$%X", lo & 15); + else if ((lo & 0x38) == 0x10) + { + PARAM_WORD (pm); + sprintf (buffer, "LINK A%d,#$%lX", rlo, pm); + } + else if ((lo & 0x38) == 0x18) + { + sprintf (buffer, "UNLK A%d", rlo); + } + else if ((lo & 0x38) == 0x20) + sprintf (buffer, "MOVE A%d,USP", rlo); + else if ((lo & 0x38) == 0x28) + sprintf (buffer, "MOVE USP,A%d", rlo); + else if (lo == 0x30) + sprintf (buffer, "RESET"); + else if (lo == 0x31) + sprintf (buffer, "NOP"); + else if (lo == 0x32) + sprintf (buffer, "STOP"); + else if (lo == 0x33) + sprintf (buffer, "RTE"); + else if (lo == 0x35) + sprintf (buffer, "RTS"); + else if (lo == 0x36) + sprintf (buffer, "TRAPV"); + else if (lo == 0x37) + sprintf (buffer, "RTR"); + else if (lo == 0x3a) + { + PARAM_WORD (pm); + switch (pm & 0xfff) + { + case 0x000: ea = "SFC"; break; + case 0x001: ea = "DFC"; break; + case 0x800: ea = "USP"; break; + case 0x801: ea = "VBR"; break; + default: ea = "???"; break; + } + if (pm & 0x8000) + sprintf (buffer, "MOVEC %s,A%ld", ea, (pm >> 12) & 7); + else + sprintf (buffer, "MOVEC %s,D%ld", ea, (pm >> 12) & 7); + } + else if (lo == 0x3b) + { + PARAM_WORD (pm); + switch (pm & 0xfff) + { + case 0x000: ea = "SFC"; break; + case 0x001: ea = "DFC"; break; + case 0x800: ea = "USP"; break; + case 0x801: ea = "VBR"; break; + default: ea = "???"; break; + } + if (pm & 0x8000) + sprintf (buffer, "MOVEC A%ld,%s", (pm >> 12) & 7, ea); + else + sprintf (buffer, "MOVEC D%ld,%s", (pm >> 12) & 7, ea); + } + else + sprintf (buffer, "DC.W $%X", op); + break; + case 0x4e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "JSR %s", ea); + break; + case 0x4ec0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "JMP %s", ea); + break; + case 0x5000: case 0x5200: case 0x5400: case 0x5600: case 0x5800: case 0x5a00: case 0x5c00: case 0x5e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADDQ.B #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5040: case 0x5240: case 0x5440: case 0x5640: case 0x5840: case 0x5a40: case 0x5c40: case 0x5e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDQ.W #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5080: case 0x5280: case 0x5480: case 0x5680: case 0x5880: case 0x5a80: case 0x5c80: case 0x5e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDQ.L #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x50c0: case 0x52c0: case 0x54c0: case 0x56c0: case 0x58c0: case 0x5ac0: case 0x5cc0: case 0x5ec0: + case 0x51c0: case 0x53c0: case 0x55c0: case 0x57c0: case 0x59c0: case 0x5bc0: case 0x5dc0: case 0x5fc0: + if ((lo & 0x38) == 0x08) + { + PARAM_WORD (pm); + if (pm & 0x8000) + sprintf (buffer, "DB%s D%d,*-$%X [%X]", ccodes[(op >> 8) & 15], rlo, (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "DB%s D%d,*+$%lX [%lX]", ccodes[(op >> 8) & 15], rlo, pm - 2, pc + pm + 2); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "S%s.B %s", ccodes[(op >> 8) & 15], ea); + } + break; + case 0x5100: case 0x5300: case 0x5500: case 0x5700: case 0x5900: case 0x5b00: case 0x5d00: case 0x5f00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUBQ.B #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5140: case 0x5340: case 0x5540: case 0x5740: case 0x5940: case 0x5b40: case 0x5d40: case 0x5f40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBQ.W #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x5180: case 0x5380: case 0x5580: case 0x5780: case 0x5980: case 0x5b80: case 0x5d80: case 0x5f80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBQ.L #%d,%s", (rhi == 0) ? 8 : rhi, ea); + break; + case 0x6000: case 0x6040: case 0x6080: case 0x60c0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "BRA *-$%X [%X]", (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "BRA *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "BRA.S *-$%X [%X]", (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "BRA.S *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + break; + case 0x6100: case 0x6140: case 0x6180: case 0x61c0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "BSR *-$%X [%X]", (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "BSR *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "BSR.S *-$%X [%X]", (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "BSR.S *+$%lX [%lX]", pm + 2, pc + pm + 2); + } + break; + case 0x6200: case 0x6240: case 0x6280: case 0x62c0: case 0x6300: case 0x6340: case 0x6380: case 0x63c0: + case 0x6400: case 0x6440: case 0x6480: case 0x64c0: case 0x6500: case 0x6540: case 0x6580: case 0x65c0: + case 0x6600: case 0x6640: case 0x6680: case 0x66c0: case 0x6700: case 0x6740: case 0x6780: case 0x67c0: + case 0x6800: case 0x6840: case 0x6880: case 0x68c0: case 0x6900: case 0x6940: case 0x6980: case 0x69c0: + case 0x6a00: case 0x6a40: case 0x6a80: case 0x6ac0: case 0x6b00: case 0x6b40: case 0x6b80: case 0x6bc0: + case 0x6c00: case 0x6c40: case 0x6c80: case 0x6cc0: case 0x6d00: case 0x6d40: case 0x6d80: case 0x6dc0: + case 0x6e00: case 0x6e40: case 0x6e80: case 0x6ec0: case 0x6f00: case 0x6f40: case 0x6f80: case 0x6fc0: + pm = op & 0xff; + if (pm == 0) + { + PARAM_WORD(pm); + if (pm & 0x8000) + sprintf (buffer, "B%s *-$%X [%X]", ccodes[(op >> 8) & 15], (int)(-(signed short)pm) - 2, pc + (signed short)pm + 2); + else + sprintf (buffer, "B%s *+$%lX [%lX]", ccodes[(op >> 8) & 15], pm + 2, pc + pm + 2); + } + else + { + if (pm & 0x80) + sprintf (buffer, "B%s.S *-$%X [%X]", ccodes[(op >> 8) & 15], (int)(-(signed char)pm) - 2, pc + (signed char)pm + 2); + else + sprintf (buffer, "B%s.S *+$%lX [%lX]", ccodes[(op >> 8) & 15], pm + 2, pc + pm + 2); + } + break; + case 0x7000: case 0x7040: case 0x7080: case 0x70c0: + case 0x7200: case 0x7240: case 0x7280: case 0x72c0: + case 0x7400: case 0x7440: case 0x7480: case 0x74c0: + case 0x7600: case 0x7640: case 0x7680: case 0x76c0: + case 0x7800: case 0x7840: case 0x7880: case 0x78c0: + case 0x7a00: case 0x7a40: case 0x7a80: case 0x7ac0: + case 0x7c00: case 0x7c40: case 0x7c80: case 0x7cc0: + case 0x7e00: case 0x7e40: case 0x7e80: case 0x7ec0: + pm = op & 0xff; + if (pm & 0x80) + sprintf (buffer, "MOVEQ #$-%X,D%d", -(signed char)pm, rhi); + else + sprintf (buffer, "MOVEQ #$%lX,D%d", pm, rhi); + break; + case 0x8000: case 0x8200: case 0x8400: case 0x8600: case 0x8800: case 0x8a00: case 0x8c00: case 0x8e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "OR.B %s,D%d", ea, rhi); + break; + case 0x8040: case 0x8240: case 0x8440: case 0x8640: case 0x8840: case 0x8a40: case 0x8c40: case 0x8e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "OR.W %s,D%d", ea, rhi); + break; + case 0x8080: case 0x8280: case 0x8480: case 0x8680: case 0x8880: case 0x8a80: case 0x8c80: case 0x8e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "OR.L %s,D%d", ea, rhi); + break; + case 0x80c0: case 0x82c0: case 0x84c0: case 0x86c0: case 0x88c0: case 0x8ac0: case 0x8cc0: case 0x8ec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "DIVU.W %s,D%d", ea, rhi); + break; + case 0x8100: case 0x8300: case 0x8500: case 0x8700: case 0x8900: case 0x8b00: case 0x8d00: case 0x8f00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "OR.B D%d,%s", rhi, ea); + break; + case 0x8140: case 0x8340: case 0x8540: case 0x8740: case 0x8940: case 0x8b40: case 0x8d40: case 0x8f40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "OR.W D%d,%s", rhi, ea); + break; + case 0x8180: case 0x8380: case 0x8580: case 0x8780: case 0x8980: case 0x8b80: case 0x8d80: case 0x8f80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "OR.L D%d,%s", rhi, ea); + break; + case 0x81c0: case 0x83c0: case 0x85c0: case 0x87c0: case 0x89c0: case 0x8bc0: case 0x8dc0: case 0x8fc0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "DIVS.W %s,D%d", ea, rhi); + break; + case 0x9000: case 0x9200: case 0x9400: case 0x9600: case 0x9800: case 0x9a00: case 0x9c00: case 0x9e00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "SUB.B %s,D%d", ea, rhi); + break; + case 0x9040: case 0x9240: case 0x9440: case 0x9640: case 0x9840: case 0x9a40: case 0x9c40: case 0x9e40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUB.W %s,D%d", ea, rhi); + break; + case 0x9080: case 0x9280: case 0x9480: case 0x9680: case 0x9880: case 0x9a80: case 0x9c80: case 0x9e80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUB.L %s,D%d", ea, rhi); + break; + case 0x90c0: case 0x92c0: case 0x94c0: case 0x96c0: case 0x98c0: case 0x9ac0: case 0x9cc0: case 0x9ec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUBA.W %s,A%d", ea, rhi); + break; + case 0x9100: case 0x9300: case 0x9500: case 0x9700: case 0x9900: case 0x9b00: case 0x9d00: case 0x9f00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1,&count); p += count; + sprintf (buffer, "SUB.B D%d,%s", rhi, ea); + } + break; + case 0x9140: case 0x9340: case 0x9540: case 0x9740: case 0x9940: case 0x9b40: case 0x9d40: case 0x9f40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.W -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.W D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "SUB.W D%d,%s", rhi, ea); + } + break; + case 0x9180: case 0x9380: case 0x9580: case 0x9780: case 0x9980: case 0x9b80: case 0x9d80: case 0x9f80: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "SUBX.L -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "SUBX.L D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUB.L D%d,%s", rhi, ea); + } + break; + case 0x91c0: case 0x93c0: case 0x95c0: case 0x97c0: case 0x99c0: case 0x9bc0: case 0x9dc0: case 0x9fc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "SUBA.L %s,A%d", ea, rhi); + break; + case 0xb000: case 0xb200: case 0xb400: case 0xb600: case 0xb800: case 0xba00: case 0xbc00: case 0xbe00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "CMP.B %s,D%d", ea, rhi); + break; + case 0xb040: case 0xb240: case 0xb440: case 0xb640: case 0xb840: case 0xba40: case 0xbc40: case 0xbe40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMP.W %s,D%d", ea, rhi); + break; + case 0xb080: case 0xb280: case 0xb480: case 0xb680: case 0xb880: case 0xba80: case 0xbc80: case 0xbe80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMP.L %s,D%d", ea, rhi); + break; + case 0xb0c0: case 0xb2c0: case 0xb4c0: case 0xb6c0: case 0xb8c0: case 0xbac0: case 0xbcc0: case 0xbec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "CMPA.W %s,A%d", ea, rhi); + break; + case 0xb100: case 0xb300: case 0xb500: case 0xb700: case 0xb900: case 0xbb00: case 0xbd00: case 0xbf00: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.B (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "EOR.B D%d,%s", rhi, ea); + } + break; + case 0xb140: case 0xb340: case 0xb540: case 0xb740: case 0xb940: case 0xbb40: case 0xbd40: case 0xbf40: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.W (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "EOR.W D%d,%s", rhi, ea); + } + break; + case 0xb180: case 0xb380: case 0xb580: case 0xb780: case 0xb980: case 0xbb80: case 0xbd80: case 0xbf80: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "CMPM.L (A%d)+,(A%d)+", rlo, rhi); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "EOR.L D%d,%s", rhi, ea); + } + break; + case 0xb1c0: case 0xb3c0: case 0xb5c0: case 0xb7c0: case 0xb9c0: case 0xbbc0: case 0xbdc0: case 0xbfc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "CMPA.L %s,A%d", ea, rhi); + break; + case 0xc000: case 0xc200: case 0xc400: case 0xc600: case 0xc800: case 0xca00: case 0xcc00: case 0xce00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "AND.B %s,D%d", ea, rhi); + break; + case 0xc040: case 0xc240: case 0xc440: case 0xc640: case 0xc840: case 0xca40: case 0xcc40: case 0xce40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "AND.W %s,D%d", ea, rhi); + break; + case 0xc080: case 0xc280: case 0xc480: case 0xc680: case 0xc880: case 0xca80: case 0xcc80: case 0xce80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "AND.L %s,D%d", ea, rhi); + break; + case 0xc0c0: case 0xc2c0: case 0xc4c0: case 0xc6c0: case 0xc8c0: case 0xcac0: case 0xccc0: case 0xcec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MULU.W %s,D%d", ea, rhi); + break; + case 0xc100: case 0xc300: case 0xc500: case 0xc700: case 0xc900: case 0xcb00: case 0xcd00: case 0xcf00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ABCD.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ABCD.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "AND.B D%d,%s", rhi, ea); + } + break; + case 0xc140: case 0xc340: case 0xc540: case 0xc740: case 0xc940: case 0xcb40: case 0xcd40: case 0xcf40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "EXG A%d,A%d", rhi, rlo); + else + sprintf (buffer, "EXG D%d,D%d", rhi, rlo); + } + else + { + ea = MakeEA (lo, p, 2,&count); p += count; + sprintf (buffer, "AND.W D%d,%s", rhi, ea); + } + break; + case 0xc180: case 0xc380: case 0xc580: case 0xc780: case 0xc980: case 0xcb80: case 0xcd80: case 0xcf80: + if ((lo & 0x38) == 0x08) + sprintf (buffer, "EXG D%d,A%d", rhi, rlo); + else + { + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "AND.L D%d,%s", rhi, ea); + } + break; + case 0xc1c0: case 0xc3c0: case 0xc5c0: case 0xc7c0: case 0xc9c0: case 0xcbc0: case 0xcdc0: case 0xcfc0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "MULS.W %s,D%d", ea, rhi); + break; + case 0xd000: case 0xd200: case 0xd400: case 0xd600: case 0xd800: case 0xda00: case 0xdc00: case 0xde00: + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADD.B %s,D%d", ea, rhi); + break; + case 0xd040: case 0xd240: case 0xd440: case 0xd640: case 0xd840: case 0xda40: case 0xdc40: case 0xde40: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADD.W %s,D%d", ea, rhi); + break; + case 0xd080: case 0xd280: case 0xd480: case 0xd680: case 0xd880: case 0xda80: case 0xdc80: case 0xde80: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADD.L %s,D%d", ea, rhi); + break; + case 0xd0c0: case 0xd2c0: case 0xd4c0: case 0xd6c0: case 0xd8c0: case 0xdac0: case 0xdcc0: case 0xdec0: + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADDA.W %s,A%d", ea, rhi); + break; + case 0xd100: case 0xd300: case 0xd500: case 0xd700: case 0xd900: case 0xdb00: case 0xdd00: case 0xdf00: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.B -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.B D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 1, &count); p += count; + sprintf (buffer, "ADD.B D%d,%s", rhi, ea); + } + break; + case 0xd140: case 0xd340: case 0xd540: case 0xd740: case 0xd940: case 0xdb40: case 0xdd40: case 0xdf40: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.W -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.W D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 2, &count); p += count; + sprintf (buffer, "ADD.W D%d,%s", rhi, ea); + } + break; + case 0xd180: case 0xd380: case 0xd580: case 0xd780: case 0xd980: case 0xdb80: case 0xdd80: case 0xdf80: + if ((lo & 0x30) == 0) + { + if (lo & 0x08) + sprintf (buffer, "ADDX.L -(A%d),-(A%d)", rlo, rhi); + else + sprintf (buffer, "ADDX.L D%d,D%d", rlo, rhi); + } + else + { + ea = MakeEA (lo, p, 4,&count); p += count; + sprintf (buffer, "ADD.L D%d,%s", rhi, ea); + } + break; + case 0xd1c0: case 0xd3c0: case 0xd5c0: case 0xd7c0: case 0xd9c0: case 0xdbc0: case 0xddc0: case 0xdfc0: + ea = MakeEA (lo, p, 4, &count); p += count; + sprintf (buffer, "ADDA.L %s,A%d", ea, rhi); + break; + case 0xe000: case 0xe200: case 0xe400: case 0xe600: case 0xe800: case 0xea00: case 0xec00: case 0xee00: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.B D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.B D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.B D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.B D%d,D%d", rhi, rlo); break; + } + break; + case 0xe040: case 0xe240: case 0xe440: case 0xe640: case 0xe840: case 0xea40: case 0xec40: case 0xee40: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.W D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.W D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.W D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.W D%d,D%d", rhi, rlo); break; + } + break; + case 0xe080: case 0xe280: case 0xe480: case 0xe680: case 0xe880: case 0xea80: case 0xec80: case 0xee80: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROR.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASR.L D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSR.L D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXR.L D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROR.L D%d,D%d", rhi, rlo); break; + } + break; + case 0xe0c0: case 0xe2c0: case 0xe4c0: case 0xe6c0: + case 0xe1c0: case 0xe3c0: case 0xe5c0: case 0xe7c0: + ea = MakeEA (lo, p, 4, &count); p += count; + switch ((op >> 8) & 7) + { + case 0: sprintf (buffer, "ASR.L #1,%s", ea); break; + case 1: sprintf (buffer, "ASL.L #1,%s", ea); break; + case 2: sprintf (buffer, "LSR.L #1,%s", ea); break; + case 3: sprintf (buffer, "LSL.L #1,%s", ea); break; + case 4: sprintf (buffer, "ROXR.L #1,%s", ea); break; + case 5: sprintf (buffer, "ROXL.L #1,%s", ea); break; + case 6: sprintf (buffer, "ROR.L #1,%s", ea); break; + case 7: sprintf (buffer, "ROL.L #1,%s", ea); break; + } + break; + case 0xe100: case 0xe300: case 0xe500: case 0xe700: case 0xe900: case 0xeb00: case 0xed00: case 0xef00: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.B #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.B D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.B D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.B D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.B D%d,D%d", rhi, rlo); break; + } + break; + case 0xe140: case 0xe340: case 0xe540: case 0xe740: case 0xe940: case 0xeb40: case 0xed40: case 0xef40: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.W #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.W D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.W D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.W D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.W D%d,D%d", rhi, rlo); break; + } + break; + case 0xe180: case 0xe380: case 0xe580: case 0xe780: case 0xe980: case 0xeb80: case 0xed80: case 0xef80: + switch ((lo >> 3) & 7) + { + case 0: sprintf (buffer, "ASL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 1: sprintf (buffer, "LSL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 2: sprintf (buffer, "ROXL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 3: sprintf (buffer, "ROL.L #%d,D%d", (rhi == 0) ? 8 : rhi, rlo); break; + case 4: sprintf (buffer, "ASL.L D%d,D%d", rhi, rlo); break; + case 5: sprintf (buffer, "LSL.L D%d,D%d", rhi, rlo); break; + case 6: sprintf (buffer, "ROXL.L D%d,D%d", rhi, rlo); break; + case 7: sprintf (buffer, "ROL.L D%d,D%d", rhi, rlo); break; + } + break; + default: + sprintf (buffer, "DC.W $%X", op); + break; + } + + return p - pBase; +} + + + +#endif diff --git a/src/m68kmake.c b/src/m68kmake.c new file mode 100644 index 0000000..16ee266 --- /dev/null +++ b/src/m68kmake.c @@ -0,0 +1,1414 @@ +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.3 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright 1998-2001 Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other lisencing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + + +/* ======================================================================== */ +/* ============================ 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 + */ + + +char* g_version = "3.3"; + +/* ======================================================================== */ +/* =============================== INCLUDES =============================== */ +/* ======================================================================== */ + +#include +#include +#include +#include +#include + + + +/* ======================================================================== */ +/* ============================= CONFIGURATION ============================ */ +/* ======================================================================== */ + +#define MAX_PATH 1024 +#define MAX_DIR 1024 + +#define NUM_CPUS 3 /* 000, 010, 020 */ +#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" +#define FILENAME_OPS_AC "m68kopac.c" +#define FILENAME_OPS_DM "m68kopdm.c" +#define FILENAME_OPS_NZ "m68kopnz.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 ============================== */ +/* ======================================================================== */ + +#define CPU_TYPE_000 0 +#define CPU_TYPE_010 1 +#define CPU_TYPE_020 2 + +#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 int 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 int bits; /* Number of significant bits (used for sorting the table) */ + unsigned int op_mask; /* Mask to apply for matching an opcode to a handler */ + unsigned int 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 int cycles[NUM_CPUS]; /* cycles for 000, 010, 020 */ +} 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(char* fmt, ...); +void perror_exit(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_prototype(FILE* filep, char* base_name); +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(void); +void populate_table(void); +void read_insert(char* insert); + + + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +/* Name of the input file */ +char g_input_filename[MAX_PATH] = FILENAME_INPUT; + +/* File handles */ +FILE* g_input_file = NULL; +FILE* g_prototype_file = NULL; +FILE* g_table_file = NULL; +FILE* g_ops_ac_file = NULL; +FILE* g_ops_dm_file = NULL; +FILE* g_ops_nz_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; + +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 */ +}; + + +char* 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) */ +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 */ +int g_ea_cycle_table[13][NUM_CPUS][3] = +{/* 000 010 020 */ + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_AI */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI7 */ + {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD */ + {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD7 */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_DI */ + {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_IX */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}}, /* EA_MODE_AW */ + {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}}, /* EA_MODE_AL */ + {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_PCDI */ + {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_PCIX */ + {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}}, /* EA_MODE_I */ +}; + +/* Extra cycles for JMP instruction (000, 010) */ +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 */ + 8, /* 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) */ +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) */ +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) */ +int g_pea_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 */ + 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 MOVES instruction (010) */ +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) */ +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(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_ops_ac_file) fclose(g_ops_ac_file); + if(g_ops_dm_file) fclose(g_ops_dm_file); + if(g_ops_nz_file) fclose(g_ops_nz_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(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_ops_ac_file) fclose(g_ops_ac_file); + if(g_ops_dm_file) fclose(g_ops_dm_file); + if(g_ops_nz_file) fclose(g_ops_nz_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') + memcpy(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]; + } + 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->name != NULL;op++) + { + if( strcmp(name, op->name) == 0 && + (size == (int)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->name != NULL;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; + + 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"); + } + 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 prototype of an opcode handler function */ +void write_prototype(FILE* filep, char* base_name) +{ + fprintf(filep, "void %s(void);\n", base_name); +} + +/* Write the name of an opcode handler function */ +void write_function_name(FILE* filep, char* base_name) +{ + fprintf(filep, "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); + write_prototype(g_prototype_file, str); + 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(void) +{ + FILE* input_file = g_input_file; + FILE* output_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)); + + + output_file = g_ops_ac_file; + + 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); + + /* Change output files if we pass 'c' or 'n' */ + if(output_file == g_ops_ac_file && oper_name[0] > 'c') + output_file = g_ops_dm_file; + else if(output_file == g_ops_dm_file && oper_name[0] > 'm') + output_file = g_ops_nz_file; + + replace->length = 0; + + /* Generate opcode variants */ + if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0) + generate_opcode_cc_variants(output_file, body, replace, opinfo, 1); + else if(strcmp(opinfo->name, "dbcc") == 0) + generate_opcode_cc_variants(output_file, body, replace, opinfo, 2); + else if(strcmp(opinfo->name, "trapcc") == 0) + generate_opcode_cc_variants(output_file, body, replace, opinfo, 4); + else + generate_opcode_ea_variants(output_file, body, replace, opinfo); + } +} + + +/* 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("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("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] = (char)('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; + + /* 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[MAX_DIR] = ""; + char filename[MAX_PATH]; + /* 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_footer_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\t\tMusashi v%s 68000, 68010, 68EC020, 68020 emulator\n", g_version); + printf("\t\tCopyright 1998-2000 Karl Stenerud (karl@mame.net)\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); + + sprintf(filename, "%s%s", output_path, FILENAME_OPS_AC); + if((g_ops_ac_file = fopen(filename, "wt")) == NULL) + perror_exit("Unable to create ops ac file (%s)\n", filename); + + sprintf(filename, "%s%s", output_path, FILENAME_OPS_DM); + if((g_ops_dm_file = fopen(filename, "wt")) == NULL) + perror_exit("Unable to create ops dm file (%s)\n", filename); + + sprintf(filename, "%s%s", output_path, FILENAME_OPS_NZ); + if((g_ops_nz_file = fopen(filename, "wt")) == NULL) + perror_exit("Unable to create ops nz 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(temp_insert); + fprintf(g_table_file, "%s", temp_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(temp_insert); + fprintf(g_ops_ac_file, "%s\n\n", temp_insert); + fprintf(g_ops_dm_file, "%s\n\n", temp_insert); + fprintf(g_ops_nz_file, "%s\n\n", temp_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"); + + process_opcode_handlers(); + + 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"); + + print_opcode_output_table(g_table_file); + + fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert); + fprintf(g_table_file, "%s\n\n", table_footer_insert); + fprintf(g_ops_ac_file, "%s\n\n", ophandler_footer_insert); + fprintf(g_ops_dm_file, "%s\n\n", ophandler_footer_insert); + fprintf(g_ops_nz_file, "%s\n\n", ophandler_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_ops_ac_file); + fclose(g_ops_dm_file); + fclose(g_ops_nz_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/src/memory.cpp b/src/memory.cpp new file mode 100644 index 0000000..51d3f64 --- /dev/null +++ b/src/memory.cpp @@ -0,0 +1,184 @@ +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// + +#include "include/memory.h" + +typedef struct sMemBlockInfo +{ + void *ptr; + char *info; + UINT32 size; + struct sMemBlockInfo *next; + struct sMemBlockInfo *prev; +} sMemBlockInfo; + +sMemBlockInfo memoryInfo; +UINT32 memoryMaxAllocated; +UINT32 currentAllocatedMemory; +UINT32 maximumAllocatedMemory; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_addMemInfo(void *ptr, UINT32 size, char *info) +{ + sMemBlockInfo *alias; + + alias=&memoryInfo; + while (alias->next) alias=alias->next; + alias->next=(sMemBlockInfo*)malloc(sizeof(sMemBlockInfo)); + if (alias->next==NULL) + { + exit(0); + return; + } + alias->next->prev=alias; + alias=alias->next; + alias->next=NULL; + alias->size=size; + alias->ptr=ptr; + alias->info=info; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_init(void) +{ + memoryInfo.next=NULL; + memoryInfo.prev=NULL; + currentAllocatedMemory=0; + maximumAllocatedMemory=0; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void *memory_malloc(UINT32 size, char *info) +{ + void *ptr; + + ptr=(void*)malloc(size); + if (ptr==NULL) + { + return(NULL); + } + memory_addMemInfo(ptr,size,info); + currentAllocatedMemory+=size; + if (currentAllocatedMemory>maximumAllocatedMemory) + maximumAllocatedMemory=currentAllocatedMemory; + return(ptr); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_malloc_secure(void **new_ptr, UINT32 size, char *info) +{ + void *ptr; + + fprintf(log_get(),"memory: allocating %i bytes of memory for <%s>...",size,(info==NULL)?"unknown":info); + ptr=(void*)malloc(size); + if (ptr==NULL) + { + fprintf(log_get(),"failed\n"); + log_done(); + exit(0); + } + memory_addMemInfo(ptr,size,info); + currentAllocatedMemory+=size; + if (currentAllocatedMemory>maximumAllocatedMemory) + maximumAllocatedMemory=currentAllocatedMemory; + *new_ptr=ptr; + fprintf(log_get(),"ok\n"); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_memoryUsage(FILE *fp) +{ + sMemBlockInfo *alias; + UINT32 total=0; + + fprintf(fp,"Memory usage:\n"); + alias=&memoryInfo; + alias=alias->next; + while (alias) + { + fprintf(fp,"\t%16i bytes : <%s> (@ 0x%.8x)\n",alias->size,alias->info,alias->ptr); + total+=alias->size; + alias=alias->next; + } + fprintf(fp,"\n\t%16i bytes total(%i Mb)\n",total,(total>>20)); + fprintf(fp,"\n\t%16i bytes memory peak(%i Mb)\n",maximumAllocatedMemory,maximumAllocatedMemory>>20); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_done(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void memory_free(void *ptr) +{ + sMemBlockInfo *alias; + + alias=&memoryInfo; + alias=alias->next; + while (alias->ptr!=ptr) + alias=alias->next; + free(ptr); + currentAllocatedMemory-=alias->size; + alias->prev->next=alias->next; + if (alias->next!=NULL) + alias->next->prev=alias->prev; + free(alias); +} diff --git a/src/objectp.cpp b/src/objectp.cpp new file mode 100644 index 0000000..8b350cf --- /dev/null +++ b/src/objectp.cpp @@ -0,0 +1,785 @@ +// +// Object Processor +// + +#include +#include +#include +#include "jaguar.h" + + +//#define OP_DEBUG +//#define OP_DEBUG_BMP +//WTFITF???static int cnt = 0; +extern uint32 jaguar_mainRom_crc32; + +static uint8 * op_blend_y; +static uint8 * op_blend_cc; + +#define BLEND_Y(dst,src) op_blend_y[(((uint16)dst)<<8) | ((uint16)(src))] +#define BLEND_CC(dst,src) op_blend_cc[(((uint16)dst)<<8) | ((uint16)(src))] + + +static uint8 objectp_ram[0x40]; +uint8 objectp_running; + +uint8 objectp_stop_reading_list; + +#define OBJECT_TYPE_BITMAP 0 +#define OBJECT_TYPE_SCALE 1 +#define OBJECT_TYPE_GPU 2 +#define OBJECT_TYPE_BRANCH 3 +#define OBJECT_TYPE_STOP 4 +/* +#define OBJECT_TYPE_BITMAP 000 +#define OBJECT_TYPE_SCALE 001 +#define OBJECT_TYPE_GPU 010 +#define OBJECT_TYPE_BRANCH 011 +#define OBJECT_TYPE_STOP 100 +*/ + +#define CONDITION_EQUAL 0 +#define CONDITION_LESS_THAN 1 +#define CONDITION_GREATER_THAN 2 +#define CONDITION_OP_FLAG_SET 3 +#define CONDITION_SECOND_HALF_LINE 4 + +#define FLAGS_RELEASE 8 +#define FLAGS_TRANSPARENT 4 +#define FLAGS_READMODIFY 2 +#define FLAGS_HFLIP 1 + +static uint8 op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 }; +static uint32 op_bitmap_bit_size[8] = + { (uint32)(0.125*65536), (uint32)(0.25*65536), (uint32)(0.5*65536), (uint32)(1*65536), + (uint32)(2*65536), (uint32)(1*65536), (uint32)(1*65536), (uint32)(1*65536) }; +static uint32 op_pointer; +//WTFITF???static int cnt_bitmap = 0; + +// +// Object Processor bitmap processing +// + +void op_process_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, int render) +{ + uint8 bitdepth = (p1 >> 12) & 0x07; + int16 ypos = ((p0 >> 3) & 0x3FF) / 2; // ??? What if not interlaced (/2)? + int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels(); + int32 iwidth = ((p1 >> 28) & 0x3FF) * 4; + int32 dwidth = ((p1 >> 18) & 0x3FF) * 4; // ??? Should it be signed or unsigned ??? + int16 height = ((p0 >> 14) & 0x3FF) - 1; + uint32 link = ((p0 >> 24) & 0x7FFFF) << 3; + uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3; +#ifdef OP_DEBUG_BMP + uint32 firstPix = (p1 >> 49) & 0x3F; +#endif + uint8 flags = (p1 >> 45) & 0x0F; + uint8 idx = (p1 >> 38) & 0x7F; + uint32 pitch = (p1 >> 15) & 0x07; + int16 scanline_width = tom_getVideoModeWidth(); + uint8 * tom_ram_8 = tom_get_ram_pointer(); + uint8 * current_line_buffer = &tom_ram_8[0x1800]; + uint8 * paletteRam = &tom_ram_8[0x400]; + uint8 doom_hack = 0; + +//if (scanline == 200) +// fprintf(log_get(), "OP --> Current OPPtr: %08X, next: %08X, BMPPtr: %08X\n", op_pointer, link, ptr); + + op_pointer = link; + + if (!render || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0)) + return; + + if (iwidth == 0) + dwidth = iwidth = height; + + if (jaguar_mainRom_crc32 == 0x5e705756) // doom + { + if ((iwidth==160)&&(height==179)&&(xpos==-9)&&(ypos==24)) + { + doom_hack=1; + xpos=0; + } + } + // il y a un offset vertical de 20 pour un des bitmaps + // dans dinon olympics pour une raison encore inconnue + if (jaguar_mainRom_crc32==0x3c7bfda8) + { + if ((iwidth==220)&&(height==184)&&(ypos==0)) + { + ypos=20; + } + } + else + if (jaguar_mainRom_crc32==0x2f032271) + { + ypos+=8; + } + if (op_bitmap_bit_depth[bitdepth] == 24) + { + iwidth *= 2; + dwidth *= 2; + } + if (op_bitmap_bit_depth[bitdepth] == 8) + { + iwidth *= 2; + dwidth *= 2; + } + if (op_bitmap_bit_depth[bitdepth] == 4) + { + iwidth *= 2; + dwidth *= 2; + } + if (op_bitmap_bit_depth[bitdepth] == 2) + { + iwidth *= 2; + dwidth *= 2; + } + if (op_bitmap_bit_depth[bitdepth] == 1) + { + iwidth *= 2; + dwidth *= 2; + } + // Power Drive Rally (fixed size bitmaps have a 240 lines vertical offset) + // but could well be a modulo 240 + if (jaguar_mainRom_crc32==0x0ab88d90) + ypos %= 240; + +#ifdef OP_DEBUG_BMP + fprintf(log_get(),"bitmap %ix%i %ibpp at %i,%i firstpix=%i ptr=0x%.8x pitch %i hflipped=%s dwidth=%i (linked to 0x%.8x) Transluency=%s\n",iwidth,height,op_bitmap_bit_depth[bitdepth],xpos,ypos,firstPix,ptr,pitch,flags&FLAGS_HFLIP?"yes":"no",dwidth,op_pointer,(flags&FLAGS_READMODIFY)?"yes":"no"); +#endif + + if ((scanline < ypos) || (scanline > (ypos + height))) + return; + + // seek to the good bitmap scanline + // not sure for palettized modes + if (op_bitmap_bit_depth[bitdepth] > 8) + ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * (scanline - ypos); + else + ptr += dwidth * (scanline - ypos); + + if (xpos < 0) + { + iwidth += xpos; + ptr += (pitch * op_bitmap_bit_size[bitdepth] * (-xpos)) >> 16; + xpos = 0; + } + + if (iwidth <= 0) + { +#ifdef OP_DEBUG_BMP + fprintf(log_get(), "not rendering because iwidth <= 0\n"); +#endif + return; + } + + if (flags & FLAGS_HFLIP) + { + if ((xpos < 0) || ((xpos - iwidth) >= scanline_width)) + return; + + if ((xpos - iwidth) < 0) + iwidth = xpos; + } + else + { + if (((xpos + iwidth) < 0) || (xpos >= scanline_width)) + return; + + if ((xpos + iwidth) > scanline_width) + iwidth = scanline_width - xpos; + } + + current_line_buffer += xpos * 2; // 2 in 16 bpp modes (need to take the mode into account) + + // doom switches the resolution from 320 to 160 to double the display width + // this is not yet supported + if (doom_hack) + { + while (iwidth) + { + uint8 d0=jaguar_byte_read(ptr+0); + uint8 d1=jaguar_byte_read(ptr+1); + *current_line_buffer++=d0; + *current_line_buffer++=d1; + *current_line_buffer++=d0; + *current_line_buffer++=d1; + ptr+=2; + iwidth--; + } + return; + } + if (op_bitmap_bit_depth[bitdepth] == 1) + { + if (pitch == 1) + { +#include "fbmpop1.h" + } + else + { +#include "fbmpop1p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 2) + { + if (pitch == 1) + { +#include "fbmpop2.h" + } + else + { +#include "fbmpop2p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 4) + { + if (pitch == 1) + { +#include "fbmpop4.h" + } + else + { +#include "fbmpop4p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 8) + { + if (pitch == 1) + { +#include "fbmpop8.h" + } + else + { +#include "fbmpop8p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 16) + { + if (pitch == 1) + { +#include "fbmpop16.h" + } + else + { +#include "fbmpop16p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 24) + { + if (pitch == 1) + { +#include "fbmpop24.h" + } + else + { +#include "fbmpop24p.h" + } + } +} + +// +// Object Processor scaled bitmap processing +// + +void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, uint64 p2, int render) +{ +// if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0)) + + int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels(); + int16 ypos = ((p0 & 0x3FF8) >> 3) / 2; + uint16 iwidth = ((p1 >> 28) & 0x3FF) * 4; + int16 dwidth = ((p1 >> 18) & 0x3FF) * 4; // ??? Signed or unsigned ??? + int16 height = (p0 >> 14) & 0x3FF; // ??? Signed or unsigned ??? + uint32 link = ((p0 >> 24) & 0x7FFFF) << 3; + uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3; +//unused uint32 firstPix = (p1 >> 49) & 0x3F; + uint8 flags = (p1 >> 45) & 0x0F; + uint8 idx = (p1 >> 38) & 0x7F; + uint8 pitch = (p1 >> 15) & 0x07; + uint8 bitdepth = (p1 >> 12) & 0x07; + int16 scanline_width = tom_getVideoModeWidth(); + uint8 * tom_ram_8 = tom_get_ram_pointer(); + uint8 * current_line_buffer = &tom_ram_8[0x1800]; + uint32 vscale_fixed3p5 = ((p2 >> 8) & 0xFF); + uint32 hscale_fixed3p5 = (p2 & 0xFF); + float vscale = (float)vscale_fixed3p5 / 32.0f, hscale = (float)hscale_fixed3p5 / 32.0f; + + op_pointer = link; + + if (jaguar_mainRom_crc32==0x5a5b9c68) // atari karts + { + if (vscale == 0.0f) + vscale = 1.0f; + + if (ypos == 0) + ypos = scanline; + } +#ifdef OP_DEBUG_BMP + if (xpos == -3) + fprintf(log_get(), "[scanline %i] %ix%i scaled to %ix%i scale (%f, %f)%i bpp pitch %i at (%i,%i) @ 0x%.8x Transluency=%s\n", + scanline, iwidth,height, (int)(iwidth*hscale), (int)(height*vscale), hscale, vscale, + op_bitmap_bit_depth[bitdepth], pitch, xpos, ypos, ptr, (flags&FLAGS_READMODIFY) ? "yes" : "no"); +#endif + if (jaguar_mainRom_crc32==0x2f032271) + ypos += 8; + + if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0)) + return; + + if (op_bitmap_bit_depth[bitdepth]==8) + { + iwidth*=2; + dwidth*=2; + } + if (op_bitmap_bit_depth[bitdepth]==4) + { + iwidth*=2; + dwidth*=2; + } + if (op_bitmap_bit_depth[bitdepth]==2) + { + iwidth*=2; + dwidth*=2; + } + if (op_bitmap_bit_depth[bitdepth]==1) + { + iwidth*=2; + dwidth*=2; + } + + uint16 scaled_width = (uint16)((float)iwidth * hscale), + scaled_height = (uint16)((float)height * vscale); + + if (op_bitmap_bit_depth[bitdepth] == 4) // why ? + scaled_width *= 2; + + if (op_bitmap_bit_depth[bitdepth] == 2) // why ? + scaled_width *= 4; + + if (op_bitmap_bit_depth[bitdepth] == 1) // why ? + scaled_width *= 8; + + // seek to the good bitmap scanline + // not sure for palettized modes + if (op_bitmap_bit_depth[bitdepth] > 8) + ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * ((uint32)((scanline - ypos) / vscale)); + else + ptr += dwidth * ((uint32)((scanline - ypos) / vscale)); + + // visible ? + if ((scanline < ypos) || (scanline > (ypos+scaled_height)) || ((xpos+scaled_width) < 0) + || (xpos >= scanline_width)) + return; + + if (xpos < 0) + { + scaled_width += xpos; + ptr += (pitch * op_bitmap_bit_size[bitdepth] * ((uint32)((-xpos) / hscale))) >> 16; + xpos = 0; + } + + if (iwidth<=0) + return; + + if (flags&FLAGS_HFLIP) + { + if ((xpos<0)||((xpos-scaled_width)>=scanline_width)) + return; + + if ((xpos-scaled_width)<0) + scaled_width=xpos; + } + else + { + if (((xpos+scaled_width)<0)||(xpos>=scanline_width)) + return; + + if ((xpos+scaled_width)>scanline_width) + scaled_width=scanline_width-xpos; + } + + current_line_buffer += xpos * 2; + + int32 hscale_fixed = (int32)(65536.0f / hscale); + int32 cnt = 0; + + if (op_bitmap_bit_depth[bitdepth] == 1) + { + if (pitch == 1) + { +#include "zbmpop1.h" + } + else + { +#include "zbmpop1p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 2) + { + if (pitch == 1) + { +#include "zbmpop2.h" + } + else + { +#include "zbmpop2p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 4) + { + if (pitch == 1) + { +#include "zbmpop4.h" + } + else + { +#include "zbmpop4p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 8) + { + if (pitch == 1) + { +#include "zbmpop8.h" + } + else + { +#include "zbmpop8p.h" + } + } + else if (op_bitmap_bit_depth[bitdepth] == 16) + { + if (pitch == 1) + { +#include "zbmpop16.h" + } + else + { +#include "zbmpop16p.h" + } + } + else + fprintf(log_get(),"(unimplemented) %i bpp scaled bitmap\n",op_bitmap_bit_depth[bitdepth]); +} + +uint64 op_load_phrase(uint32 offset) +{ + offset &= ~0x07; // 8 byte alignment + return ((uint64)jaguar_long_read(offset) << 32) | (uint64)jaguar_long_read(offset+4); +} + +// +// Object Processor main list processing +// + +void op_process_list(int16 * backbuffer, int scanline, int render) +{ +// char * condition_to_str[8] = +// { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" }; +//WTFITF??? cnt_bitmap = 0; + + if (scanline < tom_get_vdb()) + return; + + if (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb()) + return; + + op_pointer = op_get_list_pointer(); + + objectp_stop_reading_list = 0; +//WTFITF??? cnt = 0; + +// if (op_pointer) fprintf(log_get()," new op list at 0x%.8x scanline %i\n",op_pointer,scanline); + while (op_pointer) + { + if (objectp_stop_reading_list) + return; + + uint64 p0 = op_load_phrase(op_pointer); + op_pointer += 8; +/*if (scanline == tom_get_vdb()) +{ +fprintf(log_get(), "%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF)); +if ((p0 & 0x07) == OBJECT_TYPE_BITMAP) +{ +fprintf(log_get(), " (BITMAP) "); +uint64 p1 = op_load_phrase(op_pointer); +fprintf(log_get(), "\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF)); + uint8 bitdepth = (p1 >> 12) & 0x07; + int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)? +// int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20); +int32 xpos = p1 & 0xFFF; +xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); + uint32 iwidth = ((p1 >> 28) & 0x3FF); + uint32 dwidth = ((p1 >> 18) & 0x3FF); // ??? Should it be signed or unsigned ??? + int16 height = ((p0 >> 14) & 0x3FF) - 1; + uint32 link = ((p0 >> 24) & 0x7FFFF) << 3; + uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3; + uint32 firstPix = (p1 >> 49) & 0x3F; + uint8 flags = (p1 >> 45) & 0x0F; + uint8 idx = (p1 >> 38) & 0x7F; + uint32 pitch = (p1 >> 15) & 0x07; +fprintf(log_get(), "[%u (%u) x %u @ %i, %u (%u bpp), l: %08X, p: %08X fp: %02X, fl:%02X, idx:%02X, pt:%02X]\n", iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, flags, idx, pitch); +uint8 * jaguar_mainRam = GetRamPtr(); +fprintf(log_get(), "[RAM] --> "); +for(int k=0; k<16; k++) + fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]); +fprintf(log_get(), "\n"); +} +if ((p0 & 0x07) == OBJECT_TYPE_SCALE) +{ +fprintf(log_get(), " (SCALED BITMAP)\n"); +} +if ((p0 & 0x07) == OBJECT_TYPE_GPU) +fprintf(log_get(), " (GPU)\n"); +if ((p0 & 0x07) == OBJECT_TYPE_BRANCH) +{ +fprintf(log_get(), " (BRANCH)\n"); +uint8 * jaguar_mainRam = GetRamPtr(); +fprintf(log_get(), "[RAM] --> "); +for(int k=0; k<8; k++) + fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]); +fprintf(log_get(), "\n"); +} +if ((p0 & 0x07) == OBJECT_TYPE_STOP) +fprintf(log_get(), " --> List end\n"); +}*/ + +// fprintf(log_get(),"0x%.8x type %i\n",op_pointer,((uint8)p0&0x07)); + switch ((uint8)p0 & 0x07) + { + case OBJECT_TYPE_BITMAP: + { + uint64 p1 = op_load_phrase(op_pointer); + op_pointer += 8; + op_process_bitmap(backbuffer, scanline, p0, p1, render); + break; + } + case OBJECT_TYPE_SCALE: + { + uint64 p1 = op_load_phrase(op_pointer); + op_pointer += 8; + uint64 p2 = op_load_phrase(op_pointer); + op_pointer += 8; + op_process_scaled_bitmap(backbuffer, scanline, p0, p1, p2, render); + break; + } + case OBJECT_TYPE_GPU: + { +//unused uint64 data = p0 >> 3; + op_set_current_object(p0); + gpu_set_irq_line(3, 1); + break; + } + case OBJECT_TYPE_BRANCH: + { + uint16 vcnt = (p0 >> 3) & 0x7FF; + uint8 cc = (p0 >> 14) & 0x03; + uint32 link = ((p0 >> 24) & 0x1FFFFF) << 3; + +// if ((vcnt!=507)&&(vcnt!=25)) +// fprintf(log_get(),"\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],vcnt>>1,link); + switch (cc) + { + case CONDITION_EQUAL: + if ((vcnt != 0x7FF) && (vcnt & 0x01)) + vcnt ^= 0x01; + if (((2 * tom_get_scanline()) == vcnt) || (vcnt == 0x7FF)) + op_pointer = link; + break; + case CONDITION_LESS_THAN: + if ((2 * tom_get_scanline()) < vcnt) + op_pointer = link; + break; + case CONDITION_GREATER_THAN: + if ((2 * tom_get_scanline()) > vcnt) + op_pointer = link; + break; + case CONDITION_OP_FLAG_SET: + if (op_get_status_register() & 0x01) + op_pointer = link; + break; + case CONDITION_SECOND_HALF_LINE: + fprintf(log_get(), "op: unexpected CONDITION_SECOND_HALF_LINE in BRANCH object\nop: shuting down\n"); + fclose(log_get()); + exit(0); + break; + default: + fprintf(log_get(),"op: unimplemented branch condition %i\n", cc); + } + break; + } + case OBJECT_TYPE_STOP: + { + // unsure + op_set_status_register(((p0>>3) & 0xFFFFFFFF)); + + if (p0 & 0x8) + { + tom_set_pending_object_int(); + if ((tom_irq_enabled(2)) && (jaguar_interrupt_handler_is_valid(64))) + { +// s68000interrupt(7,64); +// s68000flushInterrupts(); + m68k_set_irq(7); // Cause an NMI to occur... + } + } + + return; + break; + } + default: + fprintf(log_get(),"op: unknown object type %i\n", ((uint8)p0 & 0x07)); + return; + } + } +} + +// +// Object Processor initialization +// + +void op_init(void) +{ + memory_malloc_secure((void **)&op_blend_y, 0x10000, "Jaguar Object processor Y blend lookup table"); + memory_malloc_secure((void **)&op_blend_cc, 0x10000, "Jaguar Object processor C blend lookup table"); + + for(int i=0; i<256*256; i++) + { + int y = (i >> 8) & 0xFF; + int dy = (int8)(i & 0xFF); + y += dy; + if (y < 0) + y = 0; + else if (y > 0xFF) + y = 0xFF; + op_blend_y[i] = y; + } + + for(int i=0; i<256*256; i++) + { + int cl = (i >> 8) & 0xFF; + int dcl = (int8)(i & 0xFF); + cl += dcl; + if (cl < 0) + cl = 0; + else if (cl > 0xFF) + cl = 0xFF; + op_blend_cc[i] = cl; + } + op_reset(); +} + +// +// Object Processor reset +// + +void op_reset(void) +{ + memset(objectp_ram, 0x00, 0x40); + objectp_running = 0; +} + +void op_done(void) +{ +} + +void op_byte_write(uint32 offset, uint8 data) +{ + offset &= 0x3F; + objectp_ram[offset] = data; +} + +void op_word_write(uint32 offset, uint16 data) +{ + offset &= 0x3F; + objectp_ram[offset] = (data >> 8) & 0xFF; + objectp_ram[offset+1] = data & 0xFF; + +/*if (offset == 0x20) +fprintf(log_get(), "OP: Setting lo list pointer: %04X\n", data); +if (offset == 0x22) +fprintf(log_get(), "OP: Setting hi list pointer: %04X\n", data);//*/ +} + +// Memory range: F00010 - F00027 + +uint8 op_byte_read(uint32 offset) +{ + offset &= 0x3F; + return objectp_ram[offset]; +} + +uint16 op_word_read(uint32 offset) +{ + return (objectp_ram[offset & 0x3F] << 8) | objectp_ram[(offset+1) & 0x3F]; +} + +// F00010-F00017 R xxxxxxxx xxxxxxxx OB - current object code from the graphics processor +// F00020-F00023 W xxxxxxxx xxxxxxxx OLP - start of the object list +// F00026 W -------- -------x OBF - object processor flag + +uint32 op_get_list_pointer(void) +{ + // Note: This register is WORD swapped, hence the funky look of this... +/* uint32 ptr = objectp_ram[0x22]; + ptr <<= 8; + ptr |= objectp_ram[0x23]; + ptr <<= 8; + ptr |= objectp_ram[0x20]; + ptr <<= 8; + ptr |= objectp_ram[0x21]; +fprintf(log_get(), "OP: Getting list pointer: %08X\n", (unsigned int)ptr); + ptr &= ~0x07; + + return ptr;//*/ + return (objectp_ram[0x22] << 24) | (objectp_ram[0x23] << 16) | (objectp_ram[0x20] << 8) | objectp_ram[0x21]; +} + +uint32 op_get_status_register(void) +{ +/* uint32 ptr = objectp_ram[0x26]; + ptr <<= 8; + ptr |= objectp_ram[0x27]; + ptr <<= 8; + ptr |= objectp_ram[0x28]; + ptr <<= 8; + ptr |= objectp_ram[0x29]; + + return ptr;//*/ + return (objectp_ram[0x26] << 24) | (objectp_ram[0x27] << 16) | (objectp_ram[0x28] << 8) | objectp_ram[0x29]; +} + +void op_set_status_register(uint32 data) +{ + objectp_ram[0x26] = (data & 0xFF000000) >> 24; + objectp_ram[0x27] = (data & 0x00FF0000) >> 16; + objectp_ram[0x28] = (data & 0x0000FF00) >> 8; + objectp_ram[0x29] |= (data & 0xFE); +} + +void op_set_current_object(uint64 object) +{ +/* + 32 28 24 20 16 12 8 4 0 + +--------^---------^---------^--------^--------^--------^--------^--------+ +0 | object-data | + +-------------------------------------------------------------------------+ + + 64 60 56 52 48 44 40 36 32 + +--------^---------^---------^--------^--------^--------^--------^--------+ +1 | object-data | + +-------------------------------------------------------------------------+ +*/ + // Stored as least significant 32 bits first, ms32 last in big endian + objectp_ram[0x13] = object & 0xFF; object >>= 8; + objectp_ram[0x12] = object & 0xFF; object >>= 8; + objectp_ram[0x11] = object & 0xFF; object >>= 8; + objectp_ram[0x10] = object & 0xFF; object >>= 8; + + objectp_ram[0x17] = object & 0xFF; object >>= 8; + objectp_ram[0x16] = object & 0xFF; object >>= 8; + objectp_ram[0x15] = object & 0xFF; object >>= 8; + objectp_ram[0x14] = object & 0xFF; +} diff --git a/src/pcm.cpp b/src/pcm.cpp new file mode 100644 index 0000000..3592c1c --- /dev/null +++ b/src/pcm.cpp @@ -0,0 +1,236 @@ +#include "include/pcm.h" + +#define PCM_DUMP + +#define sample_rate 44100 +#define sample_bits 16 +#define buffer_size 4 +#define buffer_modulo (sample_rate * buffer_size) + +static int16 * pcm_left; +static int16 * pcm_right; +static uint32 pcm_left_pos; +static uint32 pcm_right_pos; +static uint32 pcm_left_playback_pos; +static uint32 pcm_right_playback_pos; +static FILE * fp_left; +static FILE * fp_right; +static uint32 pcm_sample_rate = sample_rate; +static uint32 pcm_inc = (pcm_sample_rate << 8) / sample_rate; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_set_sample_rate(int rate) +{ + pcm_sample_rate = rate; + pcm_inc = (pcm_sample_rate << 8) / sample_rate; +// fprintf(log_get(),"pcm: sample rate is %i hz, sample increment is %i (%f)\n",pcm_sample_rate,pcm_inc,((float)pcm_inc)/256.0f); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_updateOne(int channel, int16 *data, uint32 length) +{ + if (channel==0) + { + while (length) + { + *data++=pcm_left[(pcm_left_playback_pos>>8)%buffer_modulo]; + pcm_left_playback_pos+=pcm_inc; + length--; + } + } + else + { + while (length) + { + *data++=pcm_right[(pcm_right_playback_pos>>8)%buffer_modulo]; + pcm_right_playback_pos+=pcm_inc; + length--; + } + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_init(void) +{ + memory_malloc_secure((void**)&pcm_left,buffer_modulo*sizeof(int16),"Left dac buffer"); + memory_malloc_secure((void**)&pcm_right,buffer_modulo*sizeof(int16),"Right dac buffer"); + pcm_reset(); + fp_left=fopen("leftdac.raw","wb"); + fp_right=fopen("rightdac.raw","wb"); + +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_reset(void) +{ + pcm_left_pos=0; + pcm_right_pos=0; + pcm_left_playback_pos=0; + pcm_right_playback_pos=0; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_done(void) +{ + fclose(fp_left); + fclose(fp_right); + fprintf(log_get(), "PCM: Done.\n"); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_update(void) +{ +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_render_left_dac(void) +{ +#ifdef PCM_DUMP + fwrite(pcm_left,1,sample_rate*2,fp_left); +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_render_right_dac(void) +{ +#ifdef PCM_DUMP + fwrite(pcm_right,1,sample_rate*2,fp_right); +#endif +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_byte_write(uint32 offset, uint8 data) +{ +// fprintf(log_get(),"pcm: writing 0x%.2x at 0x%.8x\n",data,offset); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void pcm_word_write(uint32 offset, uint16 data) +{ + if (offset==2) + { + pcm_left[pcm_left_pos%buffer_modulo]=data; + pcm_left_pos++; + if ((pcm_left_pos%buffer_modulo)==0) + pcm_render_left_dac(); + } + else + if (offset==6) + { + pcm_right[pcm_right_pos%buffer_modulo]=data; + pcm_right_pos++; + if ((pcm_right_pos%buffer_modulo)==0) + pcm_render_right_dac(); + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 pcm_byte_read(uint32 offset) +{ +// fprintf(log_get(),"pcm: reading byte from 0x%.8x\n",offset); + return(0xff); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 pcm_word_read(uint32 offset) +{ +// fprintf(log_get(),"pcm: reading word from 0x%.8x\n",offset); + return(0xffff); +} diff --git a/src/tom.cpp b/src/tom.cpp new file mode 100644 index 0000000..4ef813b --- /dev/null +++ b/src/tom.cpp @@ -0,0 +1,1239 @@ +// +// TOM Processing +// +// by cal16 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Cleanups and endian wrongness amelioration by James L. Hammons +// Note: Endian wrongness probably stems from the MAME origins of this emu and +// the braindead way in which MAME handles memory. :-) +// +// Note: TOM has only a 16K memory space +// +// ------------------------------------------------------------ +// TOM REGISTERS (Mapped by Aaron Giles) +// ------------------------------------------------------------ +// F00000-F0FFFF R/W xxxxxxxx xxxxxxxx Internal Registers +// F00000 R/W -x-xx--- xxxxxxxx MEMCON1 - memory config reg 1 +// -x------ -------- (CPU32 - is the CPU 32bits?) +// ---xx--- -------- (IOSPEED - external I/O clock cycles) +// -------- x------- (FASTROM - reduces ROM clock cycles) +// -------- -xx----- (DRAMSPEED - sets RAM clock cycles) +// -------- ---xx--- (ROMSPEED - sets ROM clock cycles) +// -------- -----xx- (ROMWIDTH - sets width of ROM: 8,16,32,64 bits) +// -------- -------x (ROMHI - controls ROM mapping) +// F00002 R/W --xxxxxx xxxxxxxx MEMCON2 - memory config reg 2 +// --x----- -------- (HILO - image display bit order) +// ---x---- -------- (BIGEND - big endian addressing?) +// ----xxxx -------- (REFRATE - DRAM refresh rate) +// -------- xx------ (DWIDTH1 - DRAM1 width: 8,16,32,64 bits) +// -------- --xx---- (COLS1 - DRAM1 columns: 256,512,1024,2048) +// -------- ----xx-- (DWIDTH0 - DRAM0 width: 8,16,32,64 bits) +// -------- ------xx (COLS0 - DRAM0 columns: 256,512,1024,2048) +// F00004 R/W -----xxx xxxxxxxx HC - horizontal count +// -----x-- -------- (which half of the display) +// ------xx xxxxxxxx (10-bit counter) +// F00006 R/W ----xxxx xxxxxxxx VC - vertical count +// ----x--- -------- (which field is being generated) +// -----xxx xxxxxxxx (11-bit counter) +// F00008 R -----xxx xxxxxxxx LPH - light pen horizontal position +// F0000A R -----xxx xxxxxxxx LPV - light pen vertical position +// F00010-F00017 R xxxxxxxx xxxxxxxx OB - current object code from the graphics processor +// F00020-F00023 W xxxxxxxx xxxxxxxx OLP - start of the object list +// F00026 W -------- -------x OBF - object processor flag +// F00028 W ----xxxx xxxxxxxx VMODE - video mode +// W ----xxx- -------- (PWIDTH1-8 - width of pixel in video clock cycles) +// W -------x -------- (VARMOD - enable variable color resolution) +// W -------- x------- (BGEN - clear line buffere to BG color) +// W -------- -x------ (CSYNC - enable composite sync on VSYNC) +// W -------- --x----- (BINC - local border color if INCEN) +// W -------- ---x---- (INCEN - encrustation enable) +// W -------- ----x--- (GENLOCK - enable genlock) +// W -------- -----xx- (MODE - CRY16,RGB24,DIRECT16,RGB16) +// W -------- -------x (VIDEN - enables video) +// F0002A W xxxxxxxx xxxxxxxx BORD1 - border color (red/green) +// F0002C W -------- xxxxxxxx BORD2 - border color (blue) +// F0002E W ------xx xxxxxxxx HP - horizontal period +// F00030 W -----xxx xxxxxxxx HBB - horizontal blanking begin +// F00032 W -----xxx xxxxxxxx HBE - horizontal blanking end +// F00034 W -----xxx xxxxxxxx HSYNC - horizontal sync +// F00036 W ------xx xxxxxxxx HVS - horizontal vertical sync +// F00038 W -----xxx xxxxxxxx HDB1 - horizontal display begin 1 +// F0003A W -----xxx xxxxxxxx HDB2 - horizontal display begin 2 +// F0003C W -----xxx xxxxxxxx HDE - horizontal display end +// F0003E W -----xxx xxxxxxxx VP - vertical period +// F00040 W -----xxx xxxxxxxx VBB - vertical blanking begin +// F00042 W -----xxx xxxxxxxx VBE - vertical blanking end +// F00044 W -----xxx xxxxxxxx VS - vertical sync +// F00046 W -----xxx xxxxxxxx VDB - vertical display begin +// F00048 W -----xxx xxxxxxxx VDE - vertical display end +// F0004A W -----xxx xxxxxxxx VEB - vertical equalization begin +// F0004C W -----xxx xxxxxxxx VEE - vertical equalization end +// F0004E W -----xxx xxxxxxxx VI - vertical interrupt +// F00050 W xxxxxxxx xxxxxxxx PIT0 - programmable interrupt timer 0 +// F00052 W xxxxxxxx xxxxxxxx PIT1 - programmable interrupt timer 1 +// F00054 W ------xx xxxxxxxx HEQ - horizontal equalization end +// F00058 W xxxxxxxx xxxxxxxx BG - background color +// F000E0 R/W ---xxxxx ---xxxxx INT1 - CPU interrupt control register +// ---x---- -------- (C_JERCLR - clear pending Jerry ints) +// ----x--- -------- (C_PITCLR - clear pending PIT ints) +// -----x-- -------- (C_OPCLR - clear pending object processor ints) +// ------x- -------- (C_GPUCLR - clear pending graphics processor ints) +// -------x -------- (C_VIDCLR - clear pending video timebase ints) +// -------- ---x---- (C_JERENA - enable Jerry ints) +// -------- ----x--- (C_PITENA - enable PIT ints) +// -------- -----x-- (C_OPENA - enable object processor ints) +// -------- ------x- (C_GPUENA - enable graphics processor ints) +// -------- -------x (C_VIDENA - enable video timebase ints) +// F000E2 W -------- -------- INT2 - CPU interrupt resume register +// F00400-F005FF R/W xxxxxxxx xxxxxxxx CLUT - color lookup table A +// F00600-F007FF R/W xxxxxxxx xxxxxxxx CLUT - color lookup table B +// F00800-F00D9F R/W xxxxxxxx xxxxxxxx LBUF - line buffer A +// F01000-F0159F R/W xxxxxxxx xxxxxxxx LBUF - line buffer B +// F01800-F01D9F R/W xxxxxxxx xxxxxxxx LBUF - line buffer currently selected +// ------------------------------------------------------------ +// F02000-F021FF R/W xxxxxxxx xxxxxxxx GPU control registers +// F02100 R/W xxxxxxxx xxxxxxxx G_FLAGS - GPU flags register +// R/W x------- -------- (DMAEN - DMA enable) +// R/W -x------ -------- (REGPAGE - register page) +// W --x----- -------- (G_BLITCLR - clear blitter interrupt) +// W ---x---- -------- (G_OPCLR - clear object processor int) +// W ----x--- -------- (G_PITCLR - clear PIT interrupt) +// W -----x-- -------- (G_JERCLR - clear Jerry interrupt) +// W ------x- -------- (G_CPUCLR - clear CPU interrupt) +// R/W -------x -------- (G_BLITENA - enable blitter interrupt) +// R/W -------- x------- (G_OPENA - enable object processor int) +// R/W -------- -x------ (G_PITENA - enable PIT interrupt) +// R/W -------- --x----- (G_JERENA - enable Jerry interrupt) +// R/W -------- ---x---- (G_CPUENA - enable CPU interrupt) +// R/W -------- ----x--- (IMASK - interrupt mask) +// R/W -------- -----x-- (NEGA_FLAG - ALU negative) +// R/W -------- ------x- (CARRY_FLAG - ALU carry) +// R/W -------- -------x (ZERO_FLAG - ALU zero) +// F02104 W -------- ----xxxx G_MTXC - matrix control register +// W -------- ----x--- (MATCOL - column/row major) +// W -------- -----xxx (MATRIX3-15 - matrix width) +// F02108 W ----xxxx xxxxxx-- G_MTXA - matrix address register +// F0210C W -------- -----xxx G_END - data organization register +// W -------- -----x-- (BIG_INST - big endian instruction fetch) +// W -------- ------x- (BIG_PIX - big endian pixels) +// W -------- -------x (BIG_IO - big endian I/O) +// F02110 R/W xxxxxxxx xxxxxxxx G_PC - GPU program counter +// F02114 R/W xxxxxxxx xx-xxxxx G_CTRL - GPU control/status register +// R xxxx---- -------- (VERSION - GPU version code) +// R/W ----x--- -------- (BUS_HOG - hog the bus!) +// R/W -----x-- -------- (G_BLITLAT - blitter interrupt latch) +// R/W ------x- -------- (G_OPLAT - object processor int latch) +// R/W -------x -------- (G_PITLAT - PIT interrupt latch) +// R/W -------- x------- (G_JERLAT - Jerry interrupt latch) +// R/W -------- -x------ (G_CPULAT - CPU interrupt latch) +// R/W -------- ---x---- (SINGLE_GO - single step one instruction) +// R/W -------- ----x--- (SINGLE_STEP - single step mode) +// R/W -------- -----x-- (FORCEINT0 - cause interrupt 0 on GPU) +// R/W -------- ------x- (CPUINT - send GPU interrupt to CPU) +// R/W -------- -------x (GPUGO - enable GPU execution) +// F02118-F0211B R/W xxxxxxxx xxxxxxxx G_HIDATA - high data register +// F0211C-F0211F R xxxxxxxx xxxxxxxx G_REMAIN - divide unit remainder +// F0211C W -------- -------x G_DIVCTRL - divide unit control +// W -------- -------x (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide) +// ------------------------------------------------------------ + +#ifndef __PORT__ +#include +#endif +#include +#include "SDLptc.h" +#include "tom.h" +#include "gpu.h" +#include "objectp.h" +#include "cry2rgb.h" + + +extern uint32 jaguar_mainRom_crc32; + +//This can be defined in the makefile as well... +//#define TOM_DEBUG + +extern Console console; +extern Surface * surface; + +// This makes sense IFF it's being used in an endian friendly way. Currently, it's not. +//#define SWAP_32_ALL(A) ((SWAP_16(A>>16))|(SWAP_16(A<<16))) +//#define SWAP_32(A) ((A>>16)|(A<<16)) +//#define SWAP_16(A) ((A>>8)|(A<<8)) +// These are more endian friendly... +#define SET16(addr, val) tom_ram_8[addr] = ((val) & 0xFF00) >> 8, tom_ram_8[addr+1] = (val) & 0x00FF +#define GET16(addr) (tom_ram_8[addr] << 8) | tom_ram_8[addr+1] + +static uint8 * tom_ram_8; +// This is just braindead and wrong! +//static uint16 * tom_ram_16; +//static uint32 * tom_ram_32; + +/* +#define MEMCON1 tom_ram_16[0] +#define MEMCON2 tom_ram_16[1] +#define VMODE tom_ram_16[0x28>>1] +#define VBB tom_ram_16[0x40>>1] +#define VBE tom_ram_16[0x42>>1] +#define VDB tom_ram_16[0x46>>1] +#define VDE tom_ram_16[0x48>>1] + +#define BG tom_ram_16[0x58>>1] + +#define HBB tom_ram_16[0x30>>1] +#define HBE tom_ram_16[0x32>>1] +#define HDB tom_ram_16[0x38>>1] +#define HDE tom_ram_16[0x3C>>1] + +#define HP tom_ram_16[0x2E>>1] +#define VP tom_ram_16[0x3E>>1] +#define VS tom_ram_16[0x44>>1] + +#define BKGCOLOR tom_ram_16[0x58>>1] +*/ +#define MEMCON1 0x00 +#define MEMCON2 0x02 +#define VMODE 0x28 +#define HP 0x2E +#define HBB 0x30 +#define HBE 0x32 +#define HDB 0x38 +#define HDE 0x3C +#define VP 0x3E +#define VBB 0x40 +#define VBE 0x42 +#define VS 0x44 +#define VDB 0x46 +#define VDE 0x48 +#define BG 0x58 + + +uint32 tom_width, tom_height, tom_real_internal_width; + +static uint32 tom_timer_prescaler; +static uint32 tom_timer_divider; +static int32 tom_timer_counter; + +uint32 tom_scanline; +uint32 hblankWidthInPixels = 0; + +static char * videoMode_to_str[8] = + {"16 bpp CRY", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB", + "Mixed mode", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB"}; + +extern uint8 objectp_running; + +typedef void (render_xxx_scanline_fn)(int16 *); + +void tom_render_16bpp_cry_scanline(int16 * backbuffer); +void tom_render_24bpp_scanline(int16 * backbuffer); +void tom_render_16bpp_direct_scanline(int16 * backbuffer); +void tom_render_16bpp_rgb_scanline(int16 * backbuffer); +void tom_render_16bpp_cry_rgb_mix_scanline(int16 * backbuffer); + +void tom_render_16bpp_cry_stretch_scanline(int16 * backbuffer); +void tom_render_24bpp_stretch_scanline(int16 * backbuffer); +void tom_render_16bpp_direct_stretch_scanline(int16 * backbuffer); +void tom_render_16bpp_rgb_stretch_scanline(int16 * backbuffer); +void tom_render_16bpp_cry_rgb_mix_stretch_scanline(int16 * backbuffer); + +render_xxx_scanline_fn * scanline_render_normal[]= +{ + tom_render_16bpp_cry_scanline, + tom_render_24bpp_scanline, + tom_render_16bpp_direct_scanline, + tom_render_16bpp_rgb_scanline, + tom_render_16bpp_cry_rgb_mix_scanline, + tom_render_24bpp_scanline, + tom_render_16bpp_direct_scanline, + tom_render_16bpp_rgb_scanline, +}; +render_xxx_scanline_fn * scanline_render_stretch[]= +{ + tom_render_16bpp_cry_stretch_scanline, + tom_render_24bpp_stretch_scanline, + tom_render_16bpp_direct_stretch_scanline, + tom_render_16bpp_rgb_stretch_scanline, + tom_render_16bpp_cry_rgb_mix_stretch_scanline, + tom_render_24bpp_stretch_scanline, + tom_render_16bpp_direct_stretch_scanline, + tom_render_16bpp_rgb_stretch_scanline, +}; +render_xxx_scanline_fn * scanline_render[8]; + +uint16 tom_puck_int_pending; +uint16 tom_timer_int_pending; +uint16 tom_object_int_pending; +uint16 tom_gpu_int_pending; +uint16 tom_video_int_pending; + +uint16 * tom_cry_rgb_mix_lut; + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_calc_cry_rgb_mix_lut(void) +{ + uint32 chrm, chrl, y; + + memory_malloc_secure((void **)&tom_cry_rgb_mix_lut, 0x20000, "cry/rgb mixed mode lut"); + + for (uint32 i=0; i<0x10000; i++) + { + uint16 color=i; + + if (color & 0x01) + { + color >>= 1; + color = (color & 0x007C00) | ((color & 0x00003E0) >> 5) | ((color & 0x0000001F) << 5); + } + else + { + chrm = (color & 0xF000) >> 12; + chrl = (color & 0x0F00) >> 8; + y = (color & 0x00FF); + + uint16 red = ((((uint32)redcv[chrm][chrl]) * y) >> 11); + uint16 green = ((((uint32)greencv[chrm][chrl]) * y) >> 11); + uint16 blue = ((((uint32)bluecv[chrm][chrl]) * y) >> 11); + color = (red << 10) | (green << 5) | blue; + } + tom_cry_rgb_mix_lut[i] = color; + } +} + +void tom_set_pending_puck_int(void) +{ + tom_puck_int_pending = 1; +} + +void tom_set_pending_timer_int(void) +{ + tom_timer_int_pending = 1; +} + +void tom_set_pending_object_int(void) +{ + tom_object_int_pending = 1; +} + +void tom_set_pending_gpu_int(void) +{ + tom_gpu_int_pending = 1; +} + +void tom_set_pending_video_int(void) +{ + tom_video_int_pending = 1; +} + +uint8 * tom_get_ram_pointer(void) +{ + return tom_ram_8; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint8 tom_getVideoMode(void) +{ +// uint16 vmode = SWAP_16(VMODE); + uint16 vmode = GET16(VMODE); + return ((vmode >> 1) & 0x03) | ((vmode & 0x100) >> 6); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 tom_get_scanline(void) +{ + return tom_scanline; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 tom_get_hdb(void) +{ +// return SWAP_16(HDB); + return GET16(HDB); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint16 tom_get_vdb(void) +{ +// return SWAP_16(VBE); + return GET16(VBE); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_cry_rgb_mix_scanline(int16 * backbuffer) +{ + uint32 chrm, chrl, y; + + uint16 width = tom_width; + uint8 * current_line_buffer=(uint8 *)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color; + color = *current_line_buffer++; + color <<= 8; + color |= *current_line_buffer++; + *backbuffer++ = tom_cry_rgb_mix_lut[color]; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_cry_scanline(int16 *backbuffer) +{ + uint32 chrm, chrl, y; + + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color; + color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + + chrm = (color & 0xF000) >> 12; + chrl = (color & 0x0F00) >> 8; + y = (color & 0x00FF); + + uint16 red = ((((uint32)redcv[chrm][chrl])*y)>>11); + uint16 green = ((((uint32)greencv[chrm][chrl])*y)>>11); + uint16 blue = ((((uint32)bluecv[chrm][chrl])*y)>>11); + + + *backbuffer++=(red<<10)|(green<<5)|blue; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_24bpp_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 green=*current_line_buffer++; + uint16 red=*current_line_buffer++; + uint16 nc=*current_line_buffer++; + uint16 blue=*current_line_buffer++; + red>>=3; + green>>=3; + blue>>=3; + *backbuffer++=(red<<10)|(green<<5)|blue; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_direct_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + color>>=1; + *backbuffer++=color; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_rgb_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + color>>=1; + color=(color&0x007c00)|((color&0x00003e0)>>5)|((color&0x0000001f)<<5); + *backbuffer++=color; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_cry_rgb_mix_stretch_scanline(int16 *backbuffer) +{ + uint32 chrm, chrl, y; + + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color; + color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + *backbuffer++=tom_cry_rgb_mix_lut[color]; + current_line_buffer+=2; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_cry_stretch_scanline(int16 *backbuffer) +{ + uint32 chrm, chrl, y; + + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color; + color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + + chrm = (color & 0xF000) >> 12; + chrl = (color & 0x0F00) >> 8; + y = (color & 0x00FF); + + uint16 red = ((((uint32)redcv[chrm][chrl])*y)>>11); + uint16 green = ((((uint32)greencv[chrm][chrl])*y)>>11); + uint16 blue = ((((uint32)bluecv[chrm][chrl])*y)>>11); + + uint16 color2; + color2=*current_line_buffer++; + color2<<=8; + color2|=*current_line_buffer++; + + chrm = (color2 & 0xF000) >> 12; + chrl = (color2 & 0x0F00) >> 8; + y = (color2 & 0x00FF); + + uint16 red2 = ((((uint32)redcv[chrm][chrl])*y)>>11); + uint16 green2 = ((((uint32)greencv[chrm][chrl])*y)>>11); + uint16 blue2 = ((((uint32)bluecv[chrm][chrl])*y)>>11); + + red=(red+red2)>>1; + green=(green+green2)>>1; + blue=(blue+blue2)>>1; + + *backbuffer++=(red<<10)|(green<<5)|blue; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_24bpp_stretch_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 green=*current_line_buffer++; + uint16 red=*current_line_buffer++; + uint16 nc=*current_line_buffer++; + uint16 blue=*current_line_buffer++; + red>>=3; + green>>=3; + blue>>=3; + *backbuffer++=(red<<10)|(green<<5)|blue; + current_line_buffer+=4; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_direct_stretch_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color=*current_line_buffer++; + color<<=8; + color|=*current_line_buffer++; + color>>=1; + *backbuffer++=color; + current_line_buffer+=2; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer) +{ + uint16 width=tom_width; + uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + + while (width) + { + uint16 color1=*current_line_buffer++; + color1<<=8; + color1|=*current_line_buffer++; + color1>>=1; + uint16 color2=*current_line_buffer++; + color2<<=8; + color2|=*current_line_buffer++; + color2>>=1; + uint16 red=(((color1&0x7c00)>>10)+((color2&0x7c00)>>10))>>1; + uint16 green=(((color1&0x00003e0)>>5)+((color2&0x00003e0)>>5))>>1; + uint16 blue=(((color1&0x0000001f))+((color2&0x0000001f)))>>1; + + color1=(red<<10)|(blue<<5)|green; + *backbuffer++=color1; + width--; + } +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_exec_scanline(int16 * backbuffer, int32 scanline, int8 render) +{ + UINT16 bg = GET16(BG); + tom_scanline = scanline; + + jaguar_word_write(0xF00004, jaguar_word_read(0xF00004) + 1); + + if (render) + { + uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800]; + uint16 * current_line_buffer_16 = (uint16 *)current_line_buffer; + + for(int i=0; i> 9) & 0x07); + + uint32 width = 640; + switch (clock_cycles_per_pixel) + { + case 0: width = 640; break; + case 1: width = 640; break; + case 2: width = 448; break; + case 3: width = 320; break; + case 4: width = 256; break; + case 5: width = 256; break; + case 6: width = 256; break; + case 7: width = 320; break; +// default: fprintf(log_get(),"%i \n",clock_cycles_per_pixel); + } + + if (jaguar_mainRom_crc32 == 0x3c7bfda8) + { + if (width == 320) + width += 80; + if (width == 448) + width -= 16; + } + if (hdb == 123) + hblankWidthInPixels = 16; + else + hblankWidthInPixels = 0; + +// fprintf(log_get(),"hdb=%i hbe=%i\n",hdb,hbe); + return width; +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +uint32 tom_getVideoModeHeight(void) +{ +/* uint16 vmode = SWAP_16(VMODE); + uint16 vdb = SWAP_16(VDB); + uint16 vde = SWAP_16(VDE); + uint16 vbb = SWAP_16(VBB); + uint16 vbe = SWAP_16(VBE);*/ + uint16 vmode = GET16(VMODE); + uint16 vdb = GET16(VDB); + uint16 vde = GET16(VDE); + uint16 vbb = GET16(VBB); + uint16 vbe = GET16(VBE); + + if (vde == 65535) + vde = vbb; + + uint32 screen_height = (vde/*-vdb*/) >> 1; + return 227;//WAS:screen_height); +} +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// +// +// +// +// +// +// +////////////////////////////////////////////////////////////////////////////// +void tom_reset(void) +{ +// fprintf(log_get(),"tom_reset()\n"); + op_reset(); + blitter_reset(); + pcm_reset(); + + memset(tom_ram_8, 0x00, 0x4000); +// tom_ram_8[MEMCON1] = 0x18, tom_ram_8[MEMCON1+1] = 0x61; + SET16(MEMCON1, 0x1861); +// tom_ram_8[MEMCON2] = 0x00, tom_ram_8[MEMCON2+1] = 0x00; + SET16(MEMCON2, 0x0000); +// tom_ram_8[VMODE] = 0x06, tom_ram_8[VMODE+1] = 0xC1; + SET16(VMODE, 0x06C1); +// tom_ram_8[VP] = (523 & 0xFF00) >> 8, tom_ram_8[VP+1] = 523 & 0x00FF; // 525-2 + SET16(VP, 523); +// tom_ram_8[HP] = SWAP_16(844); + SET16(HP, 844); +// tom_ram_8[VS] = SWAP_16(523-6); + SET16(VS, 523 - 6); +// tom_ram_8[VBB] = SWAP_16(434); + SET16(VBB, 434); +// tom_ram_8[VBE] = SWAP_16(24); + SET16(VBE, 24); +// tom_ram_8[HBB] = SWAP_16(689+0x400); + SET16(HBB, 689 + 0x400); +// tom_ram_8[HBE] = SWAP_16(125); + SET16(HBE, 125); + +// tom_ram_8[VDE] = SWAP_16(65535); + SET16(VDE, 65535); +// tom_ram_8[VDB] = SWAP_16(28); + SET16(VDB, 28); +// tom_ram_8[HDB] = SWAP_16(166); + SET16(HDB, 166); +// tom_ram_8[HDE] = SWAP_16(65535); + SET16(HDE, 65535); + + tom_width = tom_real_internal_width = 0; + tom_height = 0; + tom_scanline = 0; + +// hblankWidthInPixels = (tom_ram_8[HDB] << 8) | tom_ram_8[HDB+1]; +// hblankWidthInPixels >>= 1; + hblankWidthInPixels = (GET16(HDB)) >> 1; + + tom_puck_int_pending = 0; + tom_timer_int_pending = 0; + tom_object_int_pending = 0; + tom_gpu_int_pending = 0; + tom_video_int_pending = 0; + + tom_timer_prescaler = 0; + tom_timer_divider = 0; + tom_timer_counter = 0; + memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render)); +} + +// +// TOM byte access (read) +// + +unsigned tom_byte_read(unsigned int offset) +{ + offset &= 0xFF3FFF; + +#ifdef TOM_DEBUG + fprintf(log_get(), "TOM: Reading byte at %06X\n", offset); +#endif + + if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + return gpu_byte_read(offset); + else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + return gpu_byte_read(offset); + else if ((offset >= 0xF00010) && (offset < 0xF00028)) + return op_byte_read(offset); + else if ((offset >= 0xF02200) && (offset < 0xF022A0)) + return blitter_byte_read(offset); + else if (offset == 0xF00050) + return tom_timer_prescaler >> 8; + else if (offset == 0xF00051) + return tom_timer_prescaler & 0xFF; + else if (offset == 0xF00052) + return tom_timer_divider >> 8; + else if (offset == 0xF00053) + return tom_timer_divider & 0xFF; + + return tom_ram_8[offset & 0x3FFF]; +} + +// +// TOM word access (read) +// + +unsigned tom_word_read(unsigned int offset) +{ + offset &= 0xFF3FFF; +#ifdef TOM_DEBUG + fprintf(log_get(), "TOM: Reading word at %06X\n", offset); +#endif + if (offset == 0xF000E0) + { + uint16 data = (tom_puck_int_pending << 4) | (tom_timer_int_pending << 3) + | (tom_object_int_pending << 2) | (tom_gpu_int_pending << 1) + | (tom_video_int_pending << 0); + //fprintf(log_get(),"tom: interrupt status is 0x%.4x \n",data); + return data; + } + else if (offset == 0xF00006) + return (tom_scanline << 1) + 1; + else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + return gpu_word_read(offset); + else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + return gpu_word_read(offset); + else if ((offset >= 0xF00010) && (offset < 0xF00028)) + return op_word_read(offset); + else if ((offset >= 0xF02200) && (offset < 0xF022A0)) + return blitter_word_read(offset); + else if (offset == 0xF00050) + return tom_timer_prescaler; + else if (offset == 0xF00052) + return tom_timer_divider; + + offset &= 0x3FFF; + +// uint16 data = tom_byte_read(offset); +// data <<= 8; +// data |= tom_byte_read(offset+1); + +// return data; + return (tom_byte_read(offset) << 8) | tom_byte_read(offset+1); +} + +// +// TOM byte access (write) +// + +void tom_byte_write(unsigned offset, unsigned data) +{ + offset &= 0xFF3FFF; + +#ifdef TOM_DEBUG + fprintf(log_get(), "TOM: Writing byte %02X at %06X\n", data, offset); +#endif + + if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + gpu_byte_write(offset, data); + return; + } + else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + gpu_byte_write(offset, data); + return; + } + else if ((offset >= 0xF00010) && (offset < 0xF00028)) + { + op_byte_write(offset, data); + return; + } + else if ((offset >= 0xF02200) && (offset < 0xF022A0)) + { + blitter_byte_write(offset, data); + return; + } + else if (offset == 0xF00050) + { + tom_timer_prescaler = (tom_timer_prescaler & 0x00FF) | (data << 8); + tom_reset_timer(); + return; + } + else if (offset == 0xF00051) + { + tom_timer_prescaler = (tom_timer_prescaler & 0xFF00) | data; + tom_reset_timer(); + return; + } + else if (offset == 0xF00052) + { + tom_timer_divider = (tom_timer_divider & 0x00FF) | (data << 8); + tom_reset_timer(); + return; + } + else if (offset == 0xF00053) + { + tom_timer_divider = (tom_timer_divider & 0xFF00) | data; + tom_reset_timer(); + return; + } + + tom_ram_8[offset & 0x3FFF] = data; +} + +// +// TOM word access (write) +// + +void tom_word_write(unsigned offset, unsigned data) +{ + offset &= 0xFF3FFF; + +#ifdef TOM_DEBUG + fprintf(log_get(), "TOM: Writing word %04X at %06X\n", data, offset); +#endif + + if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + { + gpu_word_write(offset, data); + return; + } + else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + { + gpu_word_write(offset, data); + return; + } + else if ((offset >= 0xF00000) && (offset < 0xF00002)) + { + tom_byte_write(offset, (data>>8)); + tom_byte_write(offset+1, (data&0xFF)); + } + else if ((offset >= 0xF00010) && (offset < 0xF00028)) + { + op_word_write(offset, data); + return; + } + else if (offset == 0xF00050) + { + tom_timer_prescaler = data; + tom_reset_timer(); + return; + } + else if (offset == 0xF00052) + { + tom_timer_divider = data; + tom_reset_timer(); + return; + } + else if (offset == 0xF000E0) + { + if (data & 0x0100) + tom_video_int_pending = 0; + if (data & 0x0200) + tom_gpu_int_pending = 0; + if (data & 0x0400) + tom_object_int_pending = 0; + if (data & 0x0800) + tom_timer_int_pending = 0; + if (data & 0x1000) + tom_puck_int_pending = 0; + } + else if ((offset >= 0xF02200) && (offset < 0xF022A0)) + { + blitter_word_write(offset, data); + return; + } + + offset &= 0x3FFF; + if (offset == 0x28) + objectp_running = 1; + + tom_byte_write(offset, data >> 8); + tom_byte_write(offset+1, data & 0xFF); + + // detect screen resolution changes + if ((offset >= 0x28) && (offset <= 0x4F)) + { + int width, height; + tom_real_internal_width = width = tom_getVideoModeWidth(); + height = tom_getVideoModeHeight(); + if (width == 640) + { + memcpy(scanline_render, scanline_render_stretch, sizeof(scanline_render)); + width = 320; + } + else + { + memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render)); + } + + + if ((width != tom_width) || (height != tom_height)) + { + ws_audio_done(); + + static char window_title[256]; + delete surface; + + tom_width = width; + tom_height = height; + Format format(16, 0x007C00, 0x00003E0, 0x0000001F); + surface = new Surface(tom_width, tom_height, format); + console.close(); + sprintf(window_title, "Virtual Jaguar (%ix%i)", tom_width, tom_height); + console.open(window_title, width, tom_height, format); + + ws_audio_init(); + ws_audio_reset(); + } + } +} + +int tom_irq_enabled(int irq) +{ + return jaguar_byte_read(0xF000E1) & (1 << irq); +} + +void tom_set_irq_latch(int irq, int enabled) +{ + tom_ram_8[0xE0] = (tom_ram_8[0xE0] & (~(1< 0) + { + tom_timer_counter -= cycles; + + if (tom_timer_counter <= 0) + { + tom_set_pending_timer_int(); + gpu_set_irq_line(2, 1); + if ((tom_irq_enabled(IRQ_TIMER)) && (jaguar_interrupt_handler_is_valid(64))) + { +// s68000interrupt(7, 64); +// s68000flushInterrupts(); + m68k_set_irq(7); // Cause a 68000 NMI... + } + tom_reset_timer(); + } + } +} + +void tom_done(void) +{ + fprintf(log_get(),"TOM: done() ...START\n"); + op_done(); + pcm_done(); +//This is killing the log for some reason, even though it doesn't do much of anything... +// blitter_done(); + fprintf(log_get(), "TOM: resolution %i x %i %s\n", tom_getVideoModeWidth(), tom_getVideoModeHeight(), + videoMode_to_str[tom_getVideoMode()]); +// fprintf(log_get(),"\ntom: object processor:\n"); +// fprintf(log_get(),"tom: pointer to object list: 0x%.8x\n",op_get_list_pointer()); +// fprintf(log_get(),"tom: INT1=0x%.2x%.2x\n",tom_byte_read(0xf000e0),tom_byte_read(0xf000e1)); + gpu_done(); + dsp_done(); + memory_free(tom_ram_8); + fprintf(log_get(),"TOM: done() ...END\n"); +} diff --git a/src/version.cpp b/src/version.cpp new file mode 100644 index 0000000..d00abdf --- /dev/null +++ b/src/version.cpp @@ -0,0 +1,18 @@ +// +// VERSION.CPP +// + +#include "version.h" + +void version_init(void) +{ +} + +void version_display(FILE * fp) +{ + fprintf(fp, "VirtualJaguar v1.0.1 (Last full build on %s %s)\n", __DATE__, __TIME__); +} + +void version_done(void) +{ +} diff --git a/tools/fix-unix.sh b/tools/fix-unix.sh new file mode 100644 index 0000000..4a1a732 --- /dev/null +++ b/tools/fix-unix.sh @@ -0,0 +1,21 @@ +#! /bin/sh +# +# Sets up the Allegro package for building under Unix, converting text +# files from CR/LF to LF format. + + +echo "Converting NeoPocott files to Unix format..." + +find . -type f "(" \ + -name "*.c*" -o -name "*.cfg" -o \ + -name "*.h" -o -name "*.s" -o \ + -name "*.txt" -o -name "*.asm" -o \ + -name "Makefile*" -o -name "readme.*" \ + ")" \ + -exec sh -c "echo {}; + mv {} _tmpfile; + tr -d \\\r < _tmpfile > {}; + touch -r _tmpfile {}; + rm _tmpfile" \; + +echo "Done!" -- 2.37.2