From fa566a2c8ec532eb5325b4d5a663fb2a7d72adc6 Mon Sep 17 00:00:00 2001 From: Neils Wagenaar Date: Mon, 11 Aug 2003 18:56:01 +0000 Subject: [PATCH] Virtual Jaguar 1.0.4 update (Shamus) --- INSTALL | 8 +- Makefile.win32 | 27 +- docs/README | 15 +- docs/TODO | 28 + docs/WHATSNEW | 62 +- eeproms/00000000.eep | Bin 128 -> 0 bytes eeproms/readme.txt | 1 + src/Jagem.cpp | 332 ----- src/blitter.cpp | 919 +++++++------- src/blitter2.cpp | 696 +++++++++++ src/dsp.cpp | 107 +- src/eeprom.cpp | 6 +- src/gpu.cpp | 2426 +++++++++++++------------------------ src/gpu2.cpp | 897 ++++++++++++++ src/gpu3.cpp | 762 ++++++++++++ src/gpu4.cpp | 1540 +++++++++++++++++++++++ src/include/SDLptc.h | 9 +- src/include/blitter2.h | 1 + src/include/blittertest.h | 0 src/include/cry2rgb.h | 123 +- src/include/dsp.h | 17 +- 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 | 15 +- src/include/gpu2.h | 122 ++ src/include/gpu3.h | 116 ++ src/include/gpuopcodes.h | 0 src/include/jaguar.h | 22 +- src/include/log.h | 19 +- src/include/m68kdasmAG.h | 1 - src/include/mamegpu.h | 781 ------------ src/include/objectp.h | 7 +- src/include/tom.h | 30 +- src/include/unzip.h | 135 +++ src/include/wavetable.h | 15 +- src/include/zbmpop16.h | 46 +- src/jagdasm.cpp | 57 +- src/jaguar.cpp | 803 ++++++------ src/jerry.cpp | 115 +- src/joystick.cpp | 80 +- src/log.cpp | 19 +- src/m68k.h | 5 +- src/m68kconf.h | 5 +- src/m68kdasmAG.cpp | 2344 ----------------------------------- src/memory.cpp | 12 +- src/objectp.cpp | 1435 +++++++++++++--------- src/pcm.cpp | 4 +- src/tom.cpp | 836 ++++++------- src/unzip.c | 868 +++++++++++++ src/version.cpp | 2 +- src/vj.cpp | 341 ++++++ 61 files changed, 8923 insertions(+), 9270 deletions(-) create mode 100644 docs/TODO delete mode 100644 eeproms/00000000.eep create mode 100644 eeproms/readme.txt delete mode 100644 src/Jagem.cpp create mode 100644 src/blitter2.cpp create mode 100644 src/gpu2.cpp create mode 100644 src/gpu3.cpp create mode 100644 src/gpu4.cpp create mode 100644 src/include/blitter2.h delete mode 100644 src/include/blittertest.h delete mode 100644 src/include/fbmpop1.h delete mode 100644 src/include/fbmpop16.h delete mode 100644 src/include/fbmpop16p.h delete mode 100644 src/include/fbmpop1p.h delete mode 100644 src/include/fbmpop2.h delete mode 100644 src/include/fbmpop24.h delete mode 100644 src/include/fbmpop24p.h delete mode 100644 src/include/fbmpop2p.h delete mode 100644 src/include/fbmpop4.h delete mode 100644 src/include/fbmpop4p.h delete mode 100644 src/include/fbmpop8.h delete mode 100644 src/include/fbmpop8p.h create mode 100644 src/include/gpu2.h create mode 100644 src/include/gpu3.h delete mode 100644 src/include/gpuopcodes.h delete mode 100644 src/include/m68kdasmAG.h delete mode 100644 src/include/mamegpu.h create mode 100644 src/include/unzip.h delete mode 100644 src/m68kdasmAG.cpp create mode 100644 src/unzip.c create mode 100644 src/vj.cpp diff --git a/INSTALL b/INSTALL index 28cd958..a1ef2ea 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,4 @@ -Virtual Jaguar v1.0.3 GCC/SDL release INSTALL +Virtual Jaguar v1.0.4 GCC/SDL release INSTALL --------------------------------------------- - Requirements : @@ -24,19 +24,19 @@ The .o's can be quite big and the binary is likely to be about a - 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 : +compile Virtual Jaguar v1.0.4 GCC/SDL release by doing the following : 1) Compile: make -f Makefile.win32 (for WIN32 systems with mingw) make -f Makefile.unix (for UN*X systems with gcc) -2) Optionally you can manually strip jag_em[.exe] to downsize the binary. +2) Optionally you can manually strip vj[.exe] to downsize the binary. If you don't have upx in your path somewhere, you can ignore the error message that make throws at you about not being able to find upx. -That's it! You're done! You can now start the emulator with ./jag_em[.exe]. +That's it! You're done! You can now start the emulator with ./vj. 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 diff --git a/Makefile.win32 b/Makefile.win32 index d1311b3..e83eb3f 100644 --- a/Makefile.win32 +++ b/Makefile.win32 @@ -3,20 +3,19 @@ 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` +# -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES # -fomit-frame-pointer `sdl-config --cflags` -DTOM_DEBUG LDFLAGS = $(CFLAGS) -TARGET = jag_em +TARGET = vj 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 \ @@ -32,12 +31,17 @@ OBJS = \ 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 + obj/blitter2.o \ + obj/vj.o \ + obj/unzip.o \ + obj/m68kcpu.o obj/m68kops.o obj/m68kopac.o obj/m68kopdm.o obj/m68kopnz.o \ + obj/m68kdasm.o +# obj/m68kdasmAG.o \ +# obj/gpu2.o \ -LIBS = `sdl-config --libs` -lstdc++ +LIBS = `sdl-config --libs` -lstdc++ -lz INCS = -I. -Isrc -Isrc/include `sdl-config --cflags` @@ -47,7 +51,7 @@ all: obj $(TARGET) clean: rm -rf obj - rm -f jag_em.exe + rm -f vj.exe obj: mkdir obj @@ -61,9 +65,9 @@ obj/%.o: src/%.c obj/%.o: src/%.cpp $(THECC) -c $< -o $@ -jag_em: $(OBJS) +vj: $(OBJS) $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) - upx -9 jag_em.exe +# upx -9 vj.exe # # Musashi specific stuffola @@ -84,6 +88,9 @@ obj/m68kopdm.o: obj/m68kmake.exe obj/m68kops.h obj/m68kopdm.c src/m68k.h src/m68 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/m68kdasm.o: src/m68kdasm.c src/m68k.h src/m68kconf.h + $(CC) $(CFLAGS) -Isrc -c src/m68kdasm.c -o obj/m68kdasm.o + obj/m68kops.h: obj/m68kmake.exe obj/m68kmake obj src/m68k_in.c diff --git a/docs/README b/docs/README index 7865403..163514b 100644 --- a/docs/README +++ b/docs/README @@ -58,12 +58,12 @@ 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 +./vj 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. +The context of ROMFILE is the filename of the an Atari Jaguar ROM dump (can be +either compressed or uncompressed). You can also use switches. By just typing +./vj 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 @@ -74,9 +74,9 @@ 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 C : Z or joystick button 3 Atari Button B : X or joystick button 2 -Atari Button C : C or joystick button 3 +Atari Button A : C or joystick button 1 Atari Buttons 1 - 10 : Keypad 0 - 9 (0 = 10) Atari Start/Pause : ENTER Atari Select : TAB @@ -84,6 +84,7 @@ Atari UP : UP or joystick UP Atari DOWN : DOWN or joystick DOWN Atari LEFT : LEFT or joystick LEFT Atari RIGHT : RIGHT or joystick RIGHT +Atari *, # are not mapped yet! 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 diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 0000000..aa9687d --- /dev/null +++ b/docs/TODO @@ -0,0 +1,28 @@ +Stuff to add/fix for the next release of Virtual Jaguar +------------------------------------------------------- + +- Would be nice to have a GUI for ROM selection, perhaps even for things + that are set on the command line. [Shamus] +- Would also be nice to be able to dynamically change the keybindings for + the various keys on the emulated Jaguar controller while inside the emulator. + [Shamus] +- DSP code needs to be rewritten. [Shamus] +- Code to stretch the display would be nice. [Shamus] +- Blitter needs fixing. [Shamus] +- We need a comprehensive way of determining what gets written where and + by whom (i.e., blitter wrote to range $F03000-$F03230) in order to figure + out the remaining problems with various ROMs. [Shamus] +- Sound needs a rewrite. With SDL, this shouldn't be much of a problem. + Of course, whoever does this should realize that the PCM outs are probably + not being used for a majority of the ROMs out there--according to the JTRM, + you're supposed to use the I2S interface to output sound since the PCM outs + aren't even physically hooked up in the console! [Shamus] +- There is a bug either with the GPU or the blitter (most likely the latter) + which causes the spinning "A"s in the BIOS startup code to be corrupted + when they are showing their backsides. [Shamus] +- Need to rewrite the main Jaguar execution loop to increment the VC by one + instead of by two, which is how the real Jaguar works. [Shamus] + +Stuff that was added/fixed +-------------------------- + diff --git a/docs/WHATSNEW b/docs/WHATSNEW index 89824e1..1930390 100644 --- a/docs/WHATSNEW +++ b/docs/WHATSNEW @@ -1,15 +1,68 @@ +Virtual Jaguar v1.0.4 GCC/SDL - source only release +--------------------------------------------------- + +* Lots of bugfixes. [Shamus] +* Jaguar BIOS now works properly and is used by default. BIOS failure was + due to a bug in the GPU (specifically in the SUBC and ADDC opcodes). To + override this behavior, use the -nobios switch. [Shamus] +* Rewrote the OP code--mostly because it was pissing me off. ;-) Not + to mention that it was almost completely unmaintainable in its former + state and was just plain wrong in its implementation in many places. + Because of this, some RMW effects that were missing from AvP are present + now and leftover crud in scaled bitmaps in Rayman is gone now. ;-) [Shamus] +* ZIP support! Now there is no longer any need to unzip ROMs (although if + you prefer to waste HD space, VJ will gladly accomodate you). The code to + support this is a pretty ugly hack, but it works and there are other fish + to fry at the moment. Also, ZLIB is now required to compile VJ. [Shamus] +* Support for PD ROMs. Currently the only one that works at all is JagMania, + though as the hardware emulation gets better more PD ROMs will begin to + work. [Shamus] +* Preliminary support for PAL Jaguar emulation. Default is NTSC. To use it, + use the -pal switch. [Shamus] +* Support for DSP activation. The DSP is now *off* by default, since it + doesn't work properly yet. Use the -dspon switch to force the DSP on. + [Shamus] +* Removed all hacks that were written to support a specific ROM from the OP + and GPU code (much more remains to be removed). Since the CRCs that were + calculated to support these hacks were done on byte swapped ROMs, they + weren't working anyway. Besides which, a hack means that you don't + understand the hardware properly and/or don't know how to write the code to + properly emulate the hardware. ;-) [Shamus] +* Renamed the executable from the ridiculously named jag_em to the more + sensibly named vj. Note that the Jag_em.cpp file has also been changed to + reflect this name change. [Shamus] +* Removed Aaron Giles 68K dissasembler in favor of the one included with the + Musashi core. It's there, why not use it? ;-) [Shamus] +* Reordered the order of A, B, and C buttons to more accurately reflect their + respective positions on a real Jaguar controller. Also fixed a small bug that + kept the number pad from reporting the right numbers to the emulator. :-) + [Shamus] +* Started to remove the !__PORT__ defintions from the source code. Since this + is supposed to be a portable emulator, we won't be using any MS specific + code anyway. [Shamus] +* Fixed some problems with the blitter when doing clipping and bit expansion. + Also fixed (reintroduced?) a bug that existed in the real blitter HW (the + YADD1 bit in A2--fixes Tempest 2000). [Shamus] +* Probably a bunch of other stuff that I've forgotten about. ;-) [Shamus] + +NOTE: Tested only on WIN32 platform! ;-) + + Virtual Jaguar v1.0.3 GCC/SDL - source only release ------------------------------------------------------- +--------------------------------------------------- * Converted GNU assembly in the GPU core to C code -- Rayman and - Alien vs Predator work again. :-) + Alien vs Predator work again. :-) [Shamus] * Removed closed source Starscream and replaced it with the open source - Musashi core. Because of this, VJ runs a little faster now. :-) -* Various cleanups to the source files (still lots of work to do!) + Musashi core. Because of this, VJ runs a little faster now. :-) [Shamus] +* Various cleanups to the source files (still lots of work to do!) [Shamus] NOTE: Tested only on WIN32 platform! + 1.0.1 - 1.0.2 - Unreleased, mostly for testing/finding bugs +----------------------------------------------------------- + Virtual Jaguar v1.0.0 GCC/SDL - initial source release ------------------------------------------------------ @@ -24,4 +77,5 @@ Virtual Jaguar v1.0.0 GCC/SDL - initial source release 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/eeproms/00000000.eep b/eeproms/00000000.eep deleted file mode 100644 index 00bc0474794e909101dcb2b0c7c809cfbe2bd665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128 LcmZQz7+3%R0Du4i diff --git a/eeproms/readme.txt b/eeproms/readme.txt new file mode 100644 index 0000000..4581bfe --- /dev/null +++ b/eeproms/readme.txt @@ -0,0 +1 @@ +Virtual Jaguar will create EEPROM images here. \ No newline at end of file diff --git a/src/Jagem.cpp b/src/Jagem.cpp deleted file mode 100644 index c03572c..0000000 --- a/src/Jagem.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// -// Virtual Jaguar Emulator -// -// by cal2 -// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons -// - -#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) {} - - 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/blitter.cpp b/src/blitter.cpp index 52a117a..e218345 100644 --- a/src/blitter.cpp +++ b/src/blitter.cpp @@ -3,39 +3,47 @@ // // by cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/fixes by James L. Hammons // -#define GEN_CODE +//#define GEN_CODE //#define LOG_BLITS -//#define USE_GENERIC_BLITTER +// Generic blitter it is, until all blitter bugs are squashed! +#define USE_GENERIC_BLITTER #include "jaguar.h" +#include "blitter2.h" // Testing purposes only! #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) +#define REG(A) (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \ + | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3]) +#define WREG(A,D) (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \ + blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF) int start_logging = 0; +// Blitter register RAM (most of it is hidden from the user) + static uint8 blitter_ram[0x100]; +// Blitter registers (offsets from F02200) + #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 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) // Fractional 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 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 fractional part for A2) +#define A2_STEP ((UINT32)0x34) // Integer part of the step (no fractional part for A2) #define COMMAND ((UINT32)0x38) #define PIXLINECOUNTER ((UINT32)0x3C) #define SRCDATA ((UINT32)0x40) @@ -56,36 +64,43 @@ static uint8 blitter_ram[0x100]; #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) +// Blitter command bits + +#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 UPDA1F (cmd & 0x00000100) +#define UPDA1 (cmd & 0x00000200) +#define UPDA2 (cmd & 0x00000400) + +#define DSTA2 (cmd & 0x00000800) + +#define Z_OP_INF (cmd & 0x00040000) +#define Z_OP_EQU (cmd & 0x00080000) +#define Z_OP_SUP (cmd & 0x00100000) + +#define LFU_NAN (cmd & 0x00200000) +#define LFU_NA (cmd & 0x00400000) +#define LFU_AN (cmd & 0x00800000) +#define LFU_A (cmd & 0x01000000) + +#define CMPDST (cmd & 0x02000000) +#define BCOMPEN (cmd & 0x04000000) +#define DCOMPEN (cmd & 0x08000000) + +#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 @@ -147,6 +162,8 @@ static uint8 blitter_ram[0x100]; // 16 bpp z data write #define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); } +//#define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); \ + WriteLog("16bpp z write --> "); } // z data write #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); @@ -169,7 +186,6 @@ static uint8 blitter_ram[0x100]; // 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)) : \ @@ -193,36 +209,51 @@ static uint8 blitter_ram[0x100]; // 16 bpp pixel write #define WRITE_PIXEL_16(a,d) { jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); } +//#define WRITE_PIXEL_16(a,d) { jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); \ + WriteLog("16bpp pixel write --> "); } +//This is where the bad YPOS values are being written... How to fix??? // 32 bpp pixel write #define WRITE_PIXEL_32(a,d) { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); } +//#define WRITE_PIXEL_32(a,d) { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); \ + WriteLog("32bpp pixel write --> "); } // pixel write #define WRITE_PIXEL(a,f,d) {\ switch ((f>>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 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 +// This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value +// of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is +// the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it +// as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to +// 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place +// being shifted to the right 3 places). 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 + 0, 0, 0, 0, // Note: This would really translate to 1, 1, 1, 1 + 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 * tom_ram_8; +//static uint8 * paletteRam; static uint8 src; static uint8 dst; static uint8 misc; @@ -256,26 +287,28 @@ 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 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 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 gd_ia, gd_ca; static int colour_index = 0; static int32 zadd; static uint32 z_i[4]; +static uint32 a1_clip_x, a1_clip_y; + static uint8 blitter_code_cache[4096]; static uint8 * blitter_ptr; uint8 blitter_working = 0; @@ -285,20 +318,20 @@ typedef void (blitter_fn)(void); typedef struct s_blitter_cache { uint32 hashcode; - uint8 *code; + uint8 * code; uint32 ready; uint8 used; - struct s_blitter_cache *next; - struct s_blitter_cache *prev; + struct s_blitter_cache * next; + struct s_blitter_cache * prev; } s_blitter_code_cache; -s_blitter_cache *blitter_cache[256]; +s_blitter_cache * blitter_cache[256]; -uint8 blitter_cache_init=0; -static uint8 BPP_LUT[8]={1,2,4,8,16,32,0,0}; +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; +FILE * blitters_code_fp; +FILE * blitters_code_init_fp; ////////////////////////////////////////////////////////////////////////////// // build C code for the specified blitter @@ -351,7 +384,7 @@ void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode) // 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); + 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 @@ -523,9 +556,9 @@ void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode) ////////////////////////////////////////////////////////////////////////////// void blitter_gen_start_of_function(void) { - *blitter_ptr++=0x55; // push ebp - *blitter_ptr++=0x8b; // mov ebp,esp - *blitter_ptr++=0xec; + *blitter_ptr++ = 0x55; // push ebp + *blitter_ptr++ = 0x8B; // mov ebp,esp + *blitter_ptr++ = 0xEC; } ////////////////////////////////////////////////////////////////////////////// // Generate a end of function in x86 assembly @@ -536,18 +569,12 @@ void blitter_gen_start_of_function(void) ////////////////////////////////////////////////////////////////////////////// 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 + *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<>24]; @@ -633,7 +659,7 @@ struct s_blitter_cache * blitter_in_cache(uint32 cmd) 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); + //WriteLog("warning: using generic blitter for blitter 0x%.8x\n",hashcode); #endif return(null); } @@ -647,29 +673,23 @@ struct s_blitter_cache * blitter_in_cache(uint32 cmd) // // ////////////////////////////////////////////////////////////////////////////// -uint32 blitter_execute_cached_code(struct s_blitter_cache *blitter) +uint32 blitter_execute_cached_code(struct s_blitter_cache * blitter) { - if ((blitter==null)||(blitter->ready==0)) + if ((blitter == null) || (blitter->ready == 0)) return 0; - blitter_fn *fn=(blitter_fn*)blitter->code; - blitter->used=1; + blitter_fn * fn = (blitter_fn *)blitter->code; + blitter->used = 1; (*fn)(); - return(1); + 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); +// WriteLog("adding blitter for hashcode 0x%.8x\n",hashcode); while (blitter_list->next) { @@ -688,17 +708,11 @@ void blitter_add(uint32 hashcode, uint8 *code) blitter_list->ready=1; blitter_list->used=0; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void blitter_list(void) { /* - fprintf(log_get(),"Used blitters list:\n"); + WriteLog("Used blitters list:\n"); for (int i=0;i<256;i++) { @@ -708,37 +722,35 @@ void blitter_list(void) { blitter_list=blitter_list->next; if (blitter_list->used) - fprintf(log_get(),"\t0%.8x\n",blitter_list->hashcode); + WriteLog("\t0%.8x\n",blitter_list->hashcode); } } */ } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// + // +// Generic blit handler // -////////////////////////////////////////////////////////////////////////////// + void blitter_generic(uint32 cmd) { - uint32 srcdata = 0; - uint32 srczdata = 0; - uint32 dstdata = 0; - uint32 dstzdata = 0; +//Testing only! +//uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0); + +/* uint32 srcdata = 0; + uint32 srczdata = 0; + uint32 dstdata = 0; + uint32 dstzdata = 0; uint32 writedata = 0; - uint32 inhibit = 0; + uint32 inhibit = 0;*/ + uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit; + while (outer_loop--) { - inner_loop=n_pixels; + inner_loop = n_pixels; while (inner_loop--) { - srcdata = 0; - srczdata = 0; - dstdata = 0; - dstzdata = 0; - writedata = 0; - inhibit = 0; + srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0; if (!DSTA2) { @@ -747,22 +759,15 @@ void blitter_generic(uint32 cmd) { srcdata = READ_PIXEL(a2, REG(A2_FLAGS)); if (SRCENZ) - { srczdata = READ_ZDATA(a2, REG(A2_FLAGS)); - } - else - if (cmd & 0x001c020) - { + else if (cmd & 0x0001C020) 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) - { + if (cmd & 0x0001C020) srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); - } } // load dst data and Z @@ -770,38 +775,27 @@ void blitter_generic(uint32 cmd) { 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 +/*This wasn't working... // 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) - ) + 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; + if (GOURZ) + srczdata = z_i[colour_index] >> 16; // apply z comparator if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; @@ -809,43 +803,80 @@ void blitter_generic(uint32 cmd) if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; // apply data comparator - if (DCOMPEN|BCOMPEN) +// Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!! +// Does BCOMPEN only work in 1 bpp mode??? + if (DCOMPEN | BCOMPEN) { if (!CMPDST) { +//WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit); // compare source pixel with pattern pixel - if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) - inhibit=1; +/* +Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001] + CMD -> src: SRCEN dst: misc: a1ctl: mode: ity: PATDSEL z-op: op: LFU_REPLACE ctrl: BCOMPEN + A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD + A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD + x/y: 0/20 +... +*/ +// AvP is still wrong, could be cuz it's doing A1 -> A2... + +// Src is the 1bpp bitmap... DST is the PATTERN!!! +// This seems to solve at least ONE of the problems with MC3D... +// Why should this be inverted??? +// Bcuz it is. This is supposed to be used only for a bit -> pixel expansion... +/* if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) +// if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit = 1;//*/ +/* uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07); + if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8) + inhibit = (srcdata == 0 ? 1: 0); +// inhibit = !srcdata; + else + WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/ +// What it boils down to is this: +// ***CHECK*** Hmm. Seems to cause Rayman to freeze. Investigate. +// This doesn't seem to be it. Hmm. +// It was a bug in the TOM read word code (reading VC) + if (srcdata == 0) + inhibit = 1;//*/ } else { // compare destination pixel with pattern pixel if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) - inhibit=1; +// if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit = 1; } - if (a1_phrase_mode||a2_phrase_mode) - inhibit=!inhibit; +// This is DEFINITELY WRONG + if (a1_phrase_mode || a2_phrase_mode) + inhibit = !inhibit; } - + + if (CLIPA1) + { + inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0 + && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1); + } + // 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); + writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode); } - else - if (INTADD) + 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); + 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 { @@ -854,58 +885,62 @@ void blitter_generic(uint32 cmd) 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) + 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) + if (ia & 0x80) ia = 0xFFFFFF00 | ia; intensity += ia; - if(intensity < 0) + if (intensity < 0) intensity = 0; - if(intensity > 0xFF) + if (intensity > 0xFF) intensity = 0xFF; writedata = (srcdata & 0xFF00) | intensity; } } else { - writedata=dstdata; - srczdata=dstzdata; + writedata = dstdata; + srczdata = dstzdata; } + if (/*a1_phrase_mode || */BKGWREN || !inhibit) { +// This is the sole source of the bogus YPOS values being written to the object list... !!! FIX !!! +/*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5) +{ + uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2); +// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) + if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) + WriteLog("32bpp pixel write: A1 Phrase mode --> "); +}//*/ // write to the destination WRITE_PIXEL(a1, REG(A1_FLAGS), writedata); - if (DSTWRZ) WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata); + if (DSTWRZ) + WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata); } } - else + else // if (DSTA2) { // 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) - { + else if (cmd & 0x0001C020) 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) - { + if (cmd & 0x001C020) srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); - } } // load dst data and Z @@ -913,26 +948,19 @@ void blitter_generic(uint32 cmd) { 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; + if (GOURZ) + srczdata = z_i[colour_index] >> 16; // apply z comparator if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; @@ -940,24 +968,51 @@ void blitter_generic(uint32 cmd) if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; // apply data comparator - if (DCOMPEN|BCOMPEN) +//NOTE: The bit comparator (BCOMPEN) is NOT the same at the 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; +// AvP: Numbers are correct, but sprites are not! +//This doesn't seem to be a problem... But could still be wrong... +/* if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) +// if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit = 1;//*/ +// This is probably not 100% correct... It works in the 1bpp case +// (in A1 <- A2 mode, that is...) +// AvP: This is causing blocks to be written instead of bit patterns... +// Works now... +// NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff! +/* uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07); + if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8) + inhibit = (srcdata == 0 ? 1: 0); + else + WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/ +// What it boils down to is this: +// ***CHECK*** Hmm. Seems to cause Rayman to freeze. Investigate. +// This doesn't seem to be it. Hmm. +// It was a bug in the TOM read word code (reading VC) + if (srcdata == 0) + inhibit = 1;//*/ } else { // compare destination pixel with pattern pixel if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) - inhibit=1; +// if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit = 1; } - if (a1_phrase_mode||a2_phrase_mode) - inhibit=!inhibit; + if (a1_phrase_mode || a2_phrase_mode) + inhibit =! inhibit; } + if (CLIPA1) + { + inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0 + && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1); + } + // compute the write data and store if (!inhibit) { @@ -966,17 +1021,16 @@ void blitter_generic(uint32 cmd) // use pattern data for write data writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode); } - else - if (INTADD) + 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); + 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 { @@ -989,37 +1043,45 @@ void blitter_generic(uint32 cmd) if (LFU_A) writedata |= srcdata & dstdata; } - if(GOURD) - writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); - if(SRCSHADE) + 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) + if (ia & 0x80) ia = 0xFFFFFF00 | ia; intensity += ia; - if(intensity < 0) + if (intensity < 0) intensity = 0; - if(intensity > 0xFF) + if (intensity > 0xFF) intensity = 0xFF; writedata = (srcdata & 0xFF00) | intensity; } } else { - writedata=dstdata; - srczdata=dstzdata; + writedata = dstdata; + srczdata = dstzdata; } if (/*a2_phrase_mode || */BKGWREN || !inhibit) { +/*if (logGo) +{ + uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1); +// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) + WriteLog("[%08X:%04X] ", offset, writedata); +}//*/ // 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; @@ -1027,24 +1089,24 @@ void blitter_generic(uint32 cmd) a2_y = (a2_y + a2_yadd) & a2_mask_y; if (GOURZ) - z_i[colour_index]+=zadd; + z_i[colour_index] += zadd; - if ((GOURD)||(SRCSHADE)) + if (GOURD || SRCSHADE) { gd_i[colour_index] += gd_ia; gd_c[colour_index] += gd_ca; } - if ((GOURD)||(SRCSHADE)||(GOURZ)) + if (GOURD || SRCSHADE || GOURZ) { - if(a1_phrase_mode) - colour_index=(colour_index+1)&0x3; + if (a1_phrase_mode) + colour_index = (colour_index + 1) & 0x03; } } - a1_x+=a1_step_x; - a1_y+=a1_step_y; - a2_x+=a2_step_x; - a2_y+=a2_step_y; + a1_x += a1_step_x; + a1_y += a1_step_y; + a2_x += a2_step_x; + a2_y += a2_step_y; /* if (a2_phrase_mode) { @@ -1058,17 +1120,11 @@ void blitter_generic(uint32 cmd) */ } // 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)); + 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; @@ -1098,28 +1154,29 @@ void blitter_blit(uint32 cmd) 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)]; +// a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)]; + UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; + a1_width = ((0x04 | m) << e) >> 2;//*/ 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); - - // +// a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)]; + m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F; + a2_width = ((0x04 | m) << e) >> 2;//*/ + a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF; + a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF; + + // Check for "use mask" flag 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; + // According to the official documentation, a hardware bug ties A2's yadd bit to A1's... + a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0); if (YSIGNSUB_A1) a1_yadd = -a1_yadd; @@ -1128,6 +1185,7 @@ void blitter_blit(uint32 cmd) switch (xadd_a1_control) { case XADDPHR: +// This is a documented Jaguar bug relating to phrase mode and truncation... Look into it! // add phrase offset to X and truncate a1_xadd = 1 << 16; a1_phrase_mode = 1; @@ -1149,12 +1207,6 @@ void blitter_blit(uint32 cmd) 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; @@ -1176,6 +1228,7 @@ void blitter_blit(uint32 cmd) // add zero (for those nice vertical lines) a2_xadd = 0; break; +//This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no? case XADDINC: // add the contents of the increment register // since there is no register for a2 we just add 1 @@ -1185,32 +1238,37 @@ void blitter_blit(uint32 cmd) if (XSIGNSUB_A2) a2_xadd = -a2_xadd; - // modify outer loop steps based on command + // Modify outer loop steps based on blitter 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); - } + if (UPDA1F) + a1_step_x = (REG(A1_FSTEP) & 0xFFFF), + a1_step_y = (REG(A1_FSTEP) >> 16); + + if (UPDA1) + a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16), + a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000)); + + if (UPDA2) + 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); + // Clipping... + + if (CLIPA1) + a1_clip_x = REG(A1_CLIP) & 0x7FFF, + a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF; + +// This phrase sizing is incorrect as well... !!! FIX !!! +// Err, this is pixel size... (and it's OK) + a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07); + a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07); // zbuffering if (GOURZ) @@ -1255,17 +1313,17 @@ void blitter_blit(uint32 cmd) } // fix for zoop! and syndicate - if ((jaguar_mainRom_crc32==0x501be17c)|| +/* 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 (a1_step_x < 0) + a1_step_x = (-n_pixels) * 65536; - if (a2_step_x<0) - a2_step_x=(-n_pixels)*65536;; + if (a2_step_x < 0) + a2_step_x = (-n_pixels) * 65536;; } else // fix for wolfenstein 3d @@ -1284,127 +1342,166 @@ void blitter_blit(uint32 cmd) // 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)); + WriteLog("Blit!\n"); + WriteLog(" cmd = 0x%.8x\n",cmd); + WriteLog(" a1_base = %08X\n", a1_addr); + WriteLog(" a1_pitch = %d\n", a1_pitch); + WriteLog(" a1_psize = %d\n", a1_psize); + WriteLog(" a1_width = %d\n", a1_width); + WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0); + WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0); + WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0); + WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0); + WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0); + WriteLog(" a1_zoffs = %i\n",a1_zoffs); + + WriteLog(" a2_base = %08X\n", a2_addr); + WriteLog(" a2_pitch = %d\n", a2_pitch); + WriteLog(" a2_psize = %d\n", a2_psize); + WriteLog(" a2_width = %d\n", a2_width); + WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0); + WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0); + WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0); + WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0); + WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0); + WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x); + WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y); + WriteLog(" a2_zoffs = %i\n",a2_zoffs); + + WriteLog(" count = %d x %d\n", n_pixels, n_lines); + + WriteLog(" command = %08X\n", cmd); + WriteLog(" dsten = %i\n",DSTEN); + WriteLog(" srcen = %i\n",SRCEN); + WriteLog(" patdsel = %i\n",PATDSEL); + WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA)); + WriteLog(" dcompen = %i\n",DCOMPEN); + WriteLog(" bcompen = %i\n",BCOMPEN); + WriteLog(" cmpdst = %i\n",CMPDST); + WriteLog(" GOURZ = %i\n",GOURZ); + WriteLog(" GOURD = %i\n",GOURD); + WriteLog(" SRCSHADE = %i\n",SRCSHADE); + WriteLog(" DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4)); } -*/ } + }//*/ #ifdef LOG_BLITS -// if (start_logging) + 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); + WriteLog("Blit!\n"); + WriteLog(" cmd = 0x%.8x\n",cmd); + WriteLog(" a1_base = %08X\n", a1_addr); + WriteLog(" a1_pitch = %d\n", a1_pitch); + WriteLog(" a1_psize = %d\n", a1_psize); + WriteLog(" a1_width = %d\n", a1_width); + WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0); + WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0); + WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0); + WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0); + WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0); + WriteLog(" a1_zoffs = %i\n",a1_zoffs); + + WriteLog(" a2_base = %08X\n", a2_addr); + WriteLog(" a2_pitch = %d\n", a2_pitch); + WriteLog(" a2_psize = %d\n", a2_psize); + WriteLog(" a2_width = %d\n", a2_width); + WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0); + WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0); + WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0); + WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0); + WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0); + WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x); + WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y); + WriteLog(" a2_zoffs = %i\n",a2_zoffs); + + WriteLog(" count = %d x %d\n", n_pixels, n_lines); + + WriteLog(" command = %08X\n", cmd); + WriteLog(" dsten = %i\n",DSTEN); + WriteLog(" srcen = %i\n",SRCEN); + WriteLog(" patdsel = %i\n",PATDSEL); + WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA)); + WriteLog(" dcompen = %i\n",DCOMPEN); + WriteLog(" bcompen = %i\n",BCOMPEN); + WriteLog(" cmpdst = %i\n",CMPDST); + WriteLog(" GOURZ = %i\n",GOURZ); + WriteLog(" GOURD = %i\n",GOURD); + WriteLog(" SRCSHADE= %i\n",SRCSHADE); } #endif +extern int blit_start_log; +extern int op_start_log; +if (blit_start_log) +{ + char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" }; + char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" }; + char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND", + "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" }; + uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03, + a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F, + zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F; + UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS); + uint32 p1 = a1f & 0x07, p2 = a2f & 0x07, + d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07, + zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07, + w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F, + ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F; + UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2; + UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2; + WriteLog("Blit! (%08X %s %08X) count: %d x %d, A1/2_FLAGS: %08X/%08X [cmd: %08X]\n", a1_addr, (mode&0x01 ? "->" : "<-"), a2_addr, n_pixels, n_lines, a1f, a2f, cmd); +// WriteLog(" CMD -> src: %d, dst: %d, misc: %d, a1ctl: %d, mode: %d, ity: %1X, z-op: %d, op: %1X, ctrl: %02X\n", src, dst, misc, a1ctl, mode, ity, zop, op, ctrl); + + WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : "")); + WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : "")); + WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : "")); + WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : "")); + WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : "")); + WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : "")); + WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : "")); + WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]); + WriteLog("ctrl: %s%s%s%s%s%s\n", (cmd & 0x02000000 ? "CMPDST " : ""), (cmd & 0x04000000 ? "BCOMPEN " : ""), (cmd & 0x08000000 ? "DCOMPEN " : ""), (cmd & 0x10000000 ? "BKGWREN " : ""), (cmd & 0x20000000 ? "BUSHI " : ""), (cmd & 0x40000000 ? "SRCSHADE" : "")); + + if (UPDA2) + { + WriteLog(" A2 step values: %d (X), %d (Y) [mask (%sused): %08X - %08X/%08X]\n", a2_step_x >> 16, a2_step_y >> 16, (a2f & 0x8000 ? "" : "un"), REG(A2_MASK), a2_mask_x, a2_mask_y); + } + + WriteLog(" A1 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p1, bppStr[d1], zo1, iw1, w1, ctrlStr[ac1&0x03], (ac1&0x04 ? "YADD1" : "YADD0"), (ac1&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac1&0x10 ? "YSIGNSUB" : "YSIGNADD")); + WriteLog(" A2 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p2, bppStr[d2], zo2, iw2, w2, ctrlStr[ac2&0x03], (ac2&0x04 ? "YADD1" : "YADD0"), (ac2&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac2&0x10 ? "YSIGNSUB" : "YSIGNADD")); + WriteLog(" x/y: %d/%d\n", a2_x >> 16, a2_y >> 16); +// blit_start_log = 0; +// op_start_log = 1; +} + 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) +/*if (blit_start_log) { - 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; -} + if (a1_addr == 0xF03000 && a2_addr == 0x004D58) + { + WriteLog("\nBytes at 004D58:\n"); + for(int i=0x004D58; i<0x004D58+(10*127*4); i++) + WriteLog("%02X ", jaguar_byte_read(i)); + WriteLog("\nBytes at F03000:\n"); + for(int i=0xF03000; i<0xF03000+(6*127*4); i++) + WriteLog("%02X ", jaguar_byte_read(i)); + WriteLog("\n\n"); + } +}//*/ -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; + blitter_working = 0; } uint32 blitter_long_read(uint32 offset) @@ -1436,8 +1533,8 @@ void blitter_init(void) blitter_reset(); #ifdef GEN_CODE - blitters_code_fp = fopen("include/blit_c.h","awrt"); - blitters_code_init_fp = fopen("include/blit_i.h","awrt"); + blitters_code_fp = fopen("include/blit_c.h", "awrt"); + blitters_code_init_fp = fopen("include/blit_i.h", "awrt"); #endif } @@ -1453,14 +1550,19 @@ void blitter_done(void) fclose(blitters_code_fp); fclose(blitters_code_init_fp); #endif - fprintf(log_get(), "BLIT: Done.\n"); + WriteLog("BLIT: Done.\n"); } void blitter_byte_write(uint32 offset, uint8 data) { +/*if (offset & 0xFF == 0x7B) +{ + WriteLog("--> Wrote to B_STOP: value -> %02X\n", data); +}*/ offset &= 0xFF; - if ((offset >= 0x7C) && (offset <= 0x9B)) +// if ((offset >= 0x7C) && (offset <= 0x9B)) + if ((offset >= 0x7C) && (offset <= 0x8B)) { switch (offset) { @@ -1481,8 +1583,11 @@ void blitter_byte_write(uint32 offset, uint8 data) case 0x88: break; case 0x89: blitter_ram[0x6F] = data; break; - case 0x9A: blitter_ram[0x46] = data; break; - case 0x9B: blitter_ram[0x47] = data; break; +//Mistyped? +// case 0x9A: blitter_ram[0x46] = data; break; +// case 0x9B: blitter_ram[0x47] = data; break; + case 0x8A: blitter_ram[0x46] = data; break; + case 0x8B: blitter_ram[0x47] = data; break; } } @@ -1495,25 +1600,21 @@ void blitter_word_write(uint32 offset, uint16 data) 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); - } + // I.e., the second write of 32-bit value--not convinced this is the best way to do this! + // But then again, according to the Jaguar docs, this is correct...! + blitter_blit(GET32(blitter_ram, 0x38)); +// Testing purposes only! +//This does the clipping correctly, but not the Gouraud shading... +// blitter2_exec(GET32(blitter_ram, 0x38)); } +//F02278,9,A,B uint8 blitter_byte_read(uint32 offset) { offset &= 0xFF; // status register - if (offset == (0x38+3)) + if (offset == (0x38 + 3)) return 0x01; // always idle return blitter_ram[offset]; @@ -1521,5 +1622,5 @@ uint8 blitter_byte_read(uint32 offset) uint16 blitter_word_read(uint32 offset) { - return (blitter_byte_read(offset) << 8) | blitter_byte_read(offset+1); + return ((uint16)blitter_byte_read(offset) << 8) | (uint16)blitter_byte_read(offset+1); } diff --git a/src/blitter2.cpp b/src/blitter2.cpp new file mode 100644 index 0000000..fa60c22 --- /dev/null +++ b/src/blitter2.cpp @@ -0,0 +1,696 @@ +//#include "stdafx.h" +#include "jaguar.h" +#include "blitter.h" +//#include "mem.h" +//#include "regs.h" + +//extern BYTE* MEM; + +// Stuff from the header file... + +typedef struct { + int srcen; + int srcenz; + int srcenx; + int dsten; + int dstenz; + int dstwrz; + int clip_a1; + int upda1f; + int upda1; + int upda2; + int dsta2; + int gourd; + int zbuff; + int topben; + int topnen; + int patdsel; + int adddsel; + int zmode; + int logic; + int cmpdst; + int bcompen; + int dcompen; + int bkgwren; + int srcshade; +} BLITCMD; + +typedef struct { + DWORD base; + DWORD pitch; + DWORD width; + DWORD depth; + DWORD z_offset; + signed int xadd; + signed int yadd; + WORD clip_x; + WORD clip_y; + unsigned int pixel_x; + unsigned int pixel_y; + signed int step_x; + signed int step_y; + unsigned int fstep_x; + unsigned int fstep_y; + signed int inc_x; + signed int inc_y; + DWORD pixelmode; + DWORD xsign; + DWORD ysign; +} BLIT_A1; + +typedef struct { + DWORD base; + DWORD pitch; + DWORD width; + DWORD depth; + DWORD z_offset; + DWORD mask_enable; + signed int xadd; + signed int yadd; + DWORD mask; + unsigned int pixel_x; + unsigned int pixel_y; + signed int step_x; + signed int step_y; + DWORD pixelmode; + DWORD xsign; + DWORD ysign; +} BLIT_A2; + +const DWORD bitdepth[8] = { 1,2,4,8,16,32,0,0 }; +const DWORD bitsize[8] = { 1,1,1,1,2,4,0,0 }; +const DWORD pitch[4] = { 8, 16, 32, 24 }; +const DWORD pixels_phrase[8] = {64,32,16,8,4,2,1,0}; + +const DWORD width_table[64] = { 1, 1, 1, 1, 2, 2, 3, 3, + 4, 4, 6, 6, 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, + 4096,5120,6144,7168,8192,10240,12288,14336, + 16384,20480,24576,28672,32768,40960,49152,57344 }; + +// + +// More stuff from REG.H + +// Blitter Registers + +#define A1_BASE jaguar_long_read(0xF02200) +#define A1_FLAGS jaguar_long_read(0xF02204) +#define A1_CLIP jaguar_long_read(0xF02208) +#define A1_CLIP_X jaguar_word_read(0xF0220A) +#define A1_CLIP_Y jaguar_word_read(0xF02208) +#define A1_PIXEL jaguar_long_read(0xF0220C) +#define A1_PIXEL_Y jaguar_word_read(0xF0220C) +#define A1_PIXEL_X jaguar_word_read(0xF0220E) +#define A1_STEP jaguar_long_read(0xF02210) +#define A1_STEP_Y jaguar_word_read(0xF02210) +#define A1_STEP_X jaguar_word_read(0xF02212) +#define A1_FSTEP jaguar_long_read(0xF02214) +#define A1_FSTEP_Y jaguar_word_read(0xF02214) +#define A1_FSTEP_X jaguar_word_read(0xF02216) +#define A1_FPIXEL jaguar_long_read(0xF02218) +#define A1_FPIXEL_Y jaguar_word_read(0xF02218) +#define A1_FPIXEL_X jaguar_word_read(0xF0221A) +#define A1_INC jaguar_long_read(0xF0221C) +#define A1_INC_Y jaguar_word_read(0xF0221C) +#define A1_INC_X jaguar_word_read(0xF0221E) +#define A1_FINC jaguar_long_read(0xF02220) +#define A1_FINC_Y jaguar_word_read(0xF02220) +#define A1_FINC_X jaguar_word_read(0xF02222) +#define A2_BASE jaguar_long_read(0xF02224) +#define A2_FLAGS jaguar_long_read(0xF02228) +#define A2_MASK jaguar_long_read(0xF0222C) +#define A2_MASK_Y jaguar_word_read(0xF0222C) +#define A2_MASK_X jaguar_word_read(0xF0222E) +#define A2_PIXEL jaguar_long_read(0xF02230) +#define A2_PIXEL_Y jaguar_word_read(0xF02230) +#define A2_PIXEL_X jaguar_word_read(0xF02232) +#define A2_STEP jaguar_long_read(0xF02234) +#define A2_STEP_Y jaguar_word_read(0xF02234) +#define A2_STEP_X jaguar_word_read(0xF02236) +#define B_CMD jaguar_long_read(0xF02238) +#define B_COUNT jaguar_long_read(0xF0223C) +#define B_COUNT_OUT jaguar_word_read(0xF0223C) +#define B_COUNT_IN jaguar_word_read(0xF0223E) +#define B_SRCD *(LONGLONG*)(MEM+0xF02240) +#define B_SRCD0 jaguar_long_read(0xF02240) +#define B_SRCD1 jaguar_long_read(0xF02244) +#define B_DSTD *(LONGLONG*)(MEM+0xF02248) +#define B_DSTD0 jaguar_long_read(0xF02248) +#define B_DSTD1 jaguar_long_read(0xF0224C) +#define B_DSTZ *(LONGLONG*)(MEM+0xF02250) +#define B_DSTZ0 jaguar_long_read(0xF02250) +#define B_DSTZ1 jaguar_long_read(0xF02254) +#define B_SRCZ *(LONGLONG*)(MEM+0xF02258) // Source Z Integer +#define B_SRCZ0 jaguar_long_read(0xF02258) +#define B_SRCZ1 jaguar_long_read(0xF0225C) +#define B_SRCZF *(LONGLONG*)(MEM+0xF02260) // Source Z Fraction +#define B_SRCZF0 jaguar_long_read(0xF02260) +#define B_SRCZF1 jaguar_long_read(0xF02264) +#define B_PATD *(LONGLONG*)(MEM+0xF02268) +#define B_PATD0 jaguar_long_read(0xF02268) +#define B_PATD1 jaguar_long_read(0xF0226C) +#define B_IINC jaguar_long_read(0xF02270) +#define B_IINC_I jaguar_word_read(0xF02270) +#define B_IINC_F jaguar_word_read(0xF02272) +#define B_ZINC jaguar_long_read(0xF02274) +#define B_ZINC_I jaguar_word_read(0xF02274) +#define B_ZINC_F jaguar_word_read(0xF02276) +#define B_STOP jaguar_long_read(0xF02278) +#define B_I3 jaguar_long_read(0xF0227C) +#define B_I3_I jaguar_word_read(0xF0227C) +#define B_I3_F jaguar_word_read(0xF0227E) +#define B_I2 jaguar_long_read(0xF02280) +#define B_I2_I jaguar_word_read(0xF02280) +#define B_I2_F jaguar_word_read(0xF02282) +#define B_I1 jaguar_long_read(0xF02284) +#define B_I1_I jaguar_word_read(0xF02284) +#define B_I1_F jaguar_word_read(0xF02286) +#define B_I0 jaguar_long_read(0xF02288) +#define B_I0_I jaguar_word_read(0xF02288) +#define B_I0_F jaguar_word_read(0xF0228A) +#define B_Z3 jaguar_long_read(0xF0228C) +#define B_Z3_I jaguar_word_read(0xF0228C) +#define B_Z3_F jaguar_word_read(0xF0228E) +#define B_Z2 jaguar_long_read(0xF02290) +#define B_Z2_I jaguar_word_read(0xF02290) +#define B_Z2_F jaguar_word_read(0xF02292) +#define B_Z1 jaguar_long_read(0xF02294) +#define B_Z1_I jaguar_word_read(0xF02294) +#define B_Z1_F jaguar_word_read(0xF02296) +#define B_Z0 jaguar_long_read(0xF02298) +#define B_Z0_I jaguar_word_read(0xF02298) +#define B_Z0_F jaguar_word_read(0xF0229A) + +//#define DWORDBIG(x) ((x>>16)&0xFFFF)|(x<<16) +#define DWORDBIG(x) x + +// + +//const pixels_per_phrase[8] = { 64, 32, 16, 8, 4, 2, 1, 0 }; + +void blitter2_exec(DWORD cmd) +{ + DWORD* src,* dst,* read; + DWORD a1_address, a2_address; + DWORD a1_bm,a2_bm; + DWORD* src_bm,* dst_bm; + BLITCMD bcmd; + BLIT_A1 a1; + BLIT_A2 a2; + memset(&a1,0,sizeof(BLIT_A1)); + memset(&a2,0,sizeof(BLIT_A2)); + memset(&bcmd,0,sizeof(BLITCMD)); + DWORD srcd = 0xF02240; + DWORD dstd = 0xF02248; + DWORD patd = 0xF02268; + + bcmd.srcen = (cmd & 0x1) ? 1 : 0; + bcmd.srcenz = (cmd & 0x2) ? 1 : 0; + bcmd.srcenx = (cmd & 0x4) ? 1 : 0; + bcmd.dsten = (cmd & 0x8) ? 1 : 0; + bcmd.dstenz = (cmd & 0x10) ? 1 : 0; + bcmd.dstwrz = (cmd & 0x20) ? 1 : 0; + bcmd.clip_a1 = (cmd & 0x40) ? 1 : 0; + bcmd.upda1f = (cmd & 0x100) ? 1 : 0; + bcmd.upda1 = (cmd & 0x200) ? 1 : 0; + bcmd.upda2 = (cmd & 0x400) ? 1 : 0; + bcmd.dsta2 = (cmd & 0x800) ? 1 : 0; + bcmd.gourd = (cmd & 0x1000) ? 1 : 0; + bcmd.patdsel = (cmd & 0x10000) ? 1 : 0; + bcmd.cmpdst = (cmd & 0x2000000) ? 1 : 0; + bcmd.bcompen = (cmd & 0x4000000) ? 1 : 0; + bcmd.dcompen = (cmd & 0x8000000) ? 1 : 0; + bcmd.bkgwren = (cmd & 0x10000000) ? 1 : 0; + bcmd.srcshade = (cmd & 0x40000000) ? 1 : 0; + bcmd.logic = (cmd >> 21) & 0xF; + bcmd.zmode = (cmd >> 18) & 0x7; + + DWORD outer_loop = B_COUNT_OUT; + DWORD inner_loop = B_COUNT_IN; + + a1.base = DWORDBIG(A1_BASE); + DWORD flags = DWORDBIG(A1_FLAGS); + a1.pitch = flags & 0x3; + a1.depth = (flags >> 3) & 0x7; + a1.z_offset = ((flags >> 6) & 0x7)*8; + a1.xadd = (short)((flags >> 16) & 0x3); + a1.pixel_x = A1_PIXEL_X << 16 | A1_FPIXEL_X; + a1.pixel_y = A1_PIXEL_Y << 16 | A1_FPIXEL_Y; + a1.step_x = (signed short)A1_STEP_X << 16; + a1.step_y = (signed short)A1_STEP_Y << 16; + a1.fstep_x = A1_FSTEP_X; + a1.fstep_y = A1_FSTEP_Y; + a1.inc_x = A1_INC_X << 16 | A1_FINC_X; + a1.inc_y = A1_INC_Y << 16 | A1_FINC_Y; + a1.clip_x = A1_CLIP_X & 0x7FFF; + a1.clip_y = A1_CLIP_Y & 0x7FFF; + a1.width = width_table[(flags >> 9) & 0x3F]; + + a1.yadd = (short)((flags >> 18) & 0x1); + a1.xsign = (flags >> 19) & 0x1; + a1.ysign = (flags >> 20) & 0x1; + if(a1.ysign) + a1.yadd = -a1.yadd; + a1.pixelmode = (flags >> 16) & 0x3; + + a2.base = DWORDBIG(A2_BASE); + flags = DWORDBIG(A2_FLAGS); + a2.pitch = flags & 0x3; + a2.z_offset = ((flags >> 6) & 0x7)*8; + a2.pixel_x = A2_PIXEL_X; + a2.pixel_y = A2_PIXEL_Y; + a2.step_x = (signed short)A2_STEP_X; + a2.step_y = (signed short)A2_STEP_Y; + a2.mask = DWORDBIG(A2_MASK); + a2.width = width_table[(flags >> 9) & 0x3F]; +// a2.yadd = (flags >> 18) & 0x1; + a2.yadd = a1.yadd; // Buggy blitter !!? YES! It is!!! + a2.pixelmode = (flags >> 16) & 0x3; + a2.xsign = (flags >> 19) & 0x1; + a2.ysign = (flags >> 20) & 0x1; + if(a2.ysign) + a2.yadd = -a2.yadd; + + if(bcmd.dsta2 == 0) { + dst = &a1_address; + src = &a2_address; + read = &a1_address; + dst_bm = &a1_bm; + src_bm = &a2_bm; + } else { + src = &a1_address; + dst = &a2_address; + read = &a2_address; + dst_bm = &a2_bm; + src_bm = &a1_bm; + } + if(!bcmd.srcen) { + src = &srcd; + } + if(bcmd.patdsel) { + src = &patd; + } + if(!bcmd.dsten) { + read = &dstd; + } + + int src_zoffset,dst_zoffset; + if(bcmd.dsta2) { + src_zoffset = a1.z_offset; + dst_zoffset = a2.z_offset; + } else { + src_zoffset = a2.z_offset; + dst_zoffset = a1.z_offset; + } + + unsigned int a1_x = a1.pixel_x; + unsigned int a1_y = a1.pixel_y; + unsigned int a2_x = a2.pixel_x; + unsigned int a2_y = a2.pixel_y; + int a1_size = pitch[a1.pitch]; + int a2_size = pitch[a2.pitch]; + //inner_loop = (inner_loop * bitdepth[a1.depth]) / 8; + + int a1_inc_x,a1_inc_y; + short a2_inc_x; + switch(a1.pixelmode) { + case 0:a1_inc_x = 1<<16; a1_inc_y = a1.yadd<<16; break; + case 1:a1_inc_x = 1<<16; a1_inc_y = a1.yadd<<16; break; + case 2:a1_inc_x = 0; a1_inc_y = a1.yadd<<16; break; + case 3:a1_inc_x = a1.inc_x; a1_inc_y = a1.inc_y; break; + } + if(a1.xsign) + a1_inc_x = -a1_inc_x; + switch(a2.pixelmode) { + case 0:a2_inc_x = 1;break; + case 1:a2_inc_x = 1;break; + case 2:a2_inc_x = 0;break; + case 3:a2_inc_x = 1;break; + } + if(a2.xsign) + a2_inc_x = -a2_inc_x; + + int gd_i[4]; + int gd_c[4]; + int gd_ia,gd_ca; + DWORD gouraud_add,gouraud_data; + WORD gint[4],gfrac[4]; + BYTE gcolour[4]; + gouraud_add = jaguar_long_read(0xF02270); + gcolour[3] = jaguar_byte_read(0xF02268); + gcolour[2] = jaguar_byte_read(0xF0226A); + gcolour[1] = jaguar_byte_read(0xF0226C); + gcolour[0] = jaguar_byte_read(0xF0226E); + gint[3] = jaguar_word_read(0xF0227C); + gint[2] = jaguar_word_read(0xF02280); + gint[1] = jaguar_word_read(0xF02284); + gint[0] = jaguar_word_read(0xF02288); + gfrac[3] = jaguar_word_read(0xF0227E); + gfrac[2] = jaguar_word_read(0xF02282); + gfrac[1] = jaguar_word_read(0xF02286); + gfrac[0] = jaguar_word_read(0xF0228A); + 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; + for(int v=0;v<4;v++) { + gd_i[v] = gint[v] & 0xFF; + //if(gd_i[v] & 0x80) + // gd_i[v] = 0xFF00 | gd_i[v]; + gd_i[v] = (gd_i[v] << 16) | gfrac[v]; + gd_c[v] = gcolour[v]<<4; + } + int colour_index = 0; + int pi=0; + switch(a1.depth) { + case 0:case 1:case 2:case 3: + for(DWORD j=0; j>16) * a1.width + (a1_x>>16))*bitdepth[a1.depth])/8); + a2_address = a2.base + (((a2_y * a2.width + a2_x)*bitdepth[a1.depth])/8); + src1 = jaguar_byte_read(*src); + dst1 = jaguar_byte_read(*dst); + dst_old = dst1; + //jaguar_long_read(*src+4,&src2); + if(!bcmd.patdsel) { + //jaguar_long_read(*dst+4,&dst2); + switch(bcmd.logic) + { + case 0:dst1 = 0;dst2 = 0;break; + case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break; + case 2:dst1 = !src1 & dst1; dst2 = !src2 & dst2;break; + case 3:dst1 = !src1; dst2 = !src2;break; + case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break; + case 5:dst1 = !dst1; dst2 = !dst2;break; + case 6:dst1 = !(src1 ^ dst1); dst2 = !(src2 ^ dst2);break; + case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break; + case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break; + case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break; + case 10:dst1 = dst1; dst2 = dst2;break; + case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break; + case 12:dst1 = src1; dst2 = src2;break; + case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break; + case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break; + case 15:dst1 = 0xFF; dst2 = 0xFF;break; + } + } else { + dst1 = src1; + //dst2 = src2; + } + if(bcmd.dcompen) { + BYTE pattern; + pattern = jaguar_byte_read(0xF02268); + if(!bcmd.cmpdst) { + if(src1 == !dst_old) + dst1 = dst_old; + } else { + if(dst1 == !dst_old) + dst1 = dst_old; + } + } + if(bcmd.clip_a1) { + if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) { + jaguar_byte_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } else { + jaguar_byte_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + a1_x += a1_inc_x; + a2_x += a2_inc_x; + a1_y += a1_inc_y; + a2_y += a2.yadd; + for(int v=0;v<4;v++) { + gd_i[v] += gd_ia; + gd_c[v] += gd_ca; + } + } + if(bcmd.upda1) { + a1_x += a1.step_x; + a1_y += a1.step_y; + } + if(bcmd.upda1f) { + a1_x += a1.fstep_x; + a1_y += a1.fstep_y; + } + if(bcmd.upda2) { + a2_x += a2.step_x; + a2_y += a2.step_y; + } + //a1_x = old_a1x; + //a2_x = old_a2x; + } + break; + case 4: + { + int zinc = jaguar_long_read(0xF02274); + INT32 compz[4]; + compz[0] = jaguar_long_read(0xF0228C); + compz[1] = jaguar_long_read(0xF02290); + compz[2] = jaguar_long_read(0xF02294); + compz[3] = jaguar_long_read(0xF02298); + for(DWORD j=0; j>16) * a1.width + ((a1_x>>16)&0xFFFFFFFC))*2*(a1_size/8)) + (((a1_x>>16)&0x3)*2); + a2_address = a2.base + ((a2_y * a2.width + (a2_x&0xFFFFFFFC))*2*(a2_size/8)) + ((a2_x&0x3)*2); + src1 = jaguar_word_read(*src); + dst1 = jaguar_word_read(*dst); + dst_old = dst1; + if(bcmd.srcenz) + srcz = jaguar_word_read(*src+src_zoffset); + else + srcz = compz[pi & 0x3] >> 16; + if(bcmd.dstenz) + dstz = jaguar_word_read(*dst+dst_zoffset); + + //jaguar_long_read(*src+4,&src2); + if(bcmd.patdsel) { +// dst1 = *(WORD*)(&MEM[0xF02268]); + dst1 = jaguar_word_read(0xF02268); + } else { + //jaguar_long_read(*dst+4,&dst2); + switch(bcmd.logic) + { + case 0:dst1 = 0;dst2 = 0;break; + case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break; + case 2:dst1 = !src1 & dst1; dst2 = !src2 & dst2;break; + case 3:dst1 = !src1; dst2 = !src2;break; + case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break; + case 5:dst1 = !dst1; dst2 = !dst2;break; + case 6:dst1 = (src1 ^ dst1); dst2 = !(src2 ^ dst2);break; + case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break; + case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break; + case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break; + case 10:dst1 = dst1; dst2 = dst2;break; + case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break; + case 12:dst1 = src1; dst2 = src2;break; + case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break; + case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break; + case 15:dst1 = 0xFFFFFFFF; dst2 = 0xFFFFFFFF;break; + } + } + if(bcmd.gourd) { + DWORD gdt = (gd_i[pi & 0x3] & 0xFFFFFF) | ((gd_c[pi & 0x3]>>4) << 24); + dst1 = gdt >> 16; + } + if(bcmd.srcshade) { + int intensity = src1 & 0xFF; + int ia = gd_ia >> 16; + if(ia & 0x80) + ia = 0xFFFFFF00 | ia; + intensity += ia; + if(intensity < 0) + intensity = 0; + if(intensity > 0xFF) + intensity = 0xFF; + dst1 = (src1 & 0xFF00) | intensity; + } + if(bcmd.dcompen) { + WORD pattern; + pattern = jaguar_word_read(0xF02268); + if(!bcmd.cmpdst) { + if(src1 == pattern)//dst_old) + dst1 = dst_old; + } else { + if(dst1 == pattern) + dst1 = dst_old; + } + } + if(bcmd.zmode > 0) { + bool zc = false; + switch(bcmd.zmode) { + case 1: zc = (srcz < dstz);break; + case 2: zc = (srcz == dstz);break; + case 3: zc = (srcz <= dstz);break; + case 4: zc = (srcz > dstz);break; + case 5: zc = (srcz != dstz);break; + case 6: zc = (srcz >= dstz);break; + } + if(zc == false) { + if(bcmd.clip_a1) { + if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) { + jaguar_word_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } else { + jaguar_word_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } else { + srcz = dstz; + } + } else { + if(bcmd.clip_a1) { + if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) { + jaguar_word_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } else { + jaguar_word_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } + if(bcmd.dstwrz) { + jaguar_word_write(*dst+dst_zoffset,srcz & 0xFFFF); + } + a1_x += a1_inc_x; + a2_x += a2_inc_x; + a1_y += a1_inc_y; + a2_y += a2.yadd; + gd_i[pi & 0x3] += gd_ia; + gd_c[pi & 0x3] += gd_ca; + if(gd_i[pi & 0x3] > 0xFFFFFF) + gd_i[pi & 0x3] = 0xFFFFFF; + if(gd_i[pi & 0x3] < 0) + gd_i[pi & 0x3] = 0; + compz[pi & 0x3] += zinc; + if(compz[pi & 0x3] > 0xFFFFFFFF) + compz[pi & 0x3] = 0xFFFFFFFF; + if(compz[pi & 0x3] < 0) + compz[pi & 0x3] = 0; + if(a1.pixelmode == 0) { + pi++; + } + } + if(bcmd.upda1) { + a1_x += a1.step_x; + a1_y += a1.step_y; + } + if(bcmd.upda1f) { + a1_x += a1.fstep_x; + a1_y += a1.fstep_y; + } + if(bcmd.upda2) { + a2_x += a2.step_x; + a2_y += a2.step_y; + } + } + break; + } + case 5: + for(DWORD j=0; j>16) * a1.width + (a1_x>>16))*bitdepth[a1.depth])/8); + a2_address = a2.base + (((a2_y * a2.width + a2_x)*bitdepth[a1.depth])/8); + src1 = jaguar_long_read(*src); + //jaguar_long_read(*src+4,&src2); + if(!bcmd.patdsel) { + dst1 = jaguar_long_read(*read); + //jaguar_long_read(*dst+4,&dst2); + switch(bcmd.logic) + { + case 0:dst1 = 0;dst2 = 0;break; + case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break; + case 2:dst1 = !src1 & dst1; dst2 = !src2 & dst2;break; + case 3:dst1 = !src1; dst2 = !src2;break; + case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break; + case 5:dst1 = !dst1; dst2 = !dst2;break; + case 6:dst1 = !(src1 ^ dst1); dst2 = !(src2 ^ dst2);break; + case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break; + case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break; + case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break; + case 10:dst1 = dst1; dst2 = dst2;break; + case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break; + case 12:dst1 = src1; dst2 = src2;break; + case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break; + case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break; + case 15:dst1 = 0xFFFFFFFF; dst2 = 0xFFFFFFFF;break; + } + } else { + dst1 = src1; + dst2 = src2; + } + if(bcmd.clip_a1) { + if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) { + jaguar_long_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + } else { + jaguar_long_write(*dst,dst1); + //jaguar_long_write(*dst+4,dst2); + } + a1_x += a1_inc_x; + a2_x += a2_inc_x; + a1_y += a1_inc_y; + a2_y += a2.yadd; + for(int v=0;v<4;v++) { + gd_i[v] += gd_ia; + gd_c[v] += gd_ca; + } + } + if(bcmd.upda1) { + a1_x += a1.step_x; + a1_y += a1.step_y; + } + if(bcmd.upda1f) { + a1_x += a1.fstep_x; + a1_y += a1.fstep_y; + } + if(bcmd.upda2) { + a2_x += a2.step_x; + a2_y += a2.step_y; + } + } + break; + default: + break; + } +/* A1_PIXEL_X = a1_x >> 16; + A1_PIXEL_Y = a1_y >> 16; + A1_FPIXEL_X = a1_x & 0xFFFF; + A1_FPIXEL_Y = a1_y & 0xFFFF; + A2_PIXEL_X = a2_x; + A2_PIXEL_Y = a2_y;*/ + jaguar_word_write(0xF0220E, a1_x >> 16); // A1_PIXEL_X = + jaguar_word_write(0xF0220C, a1_y >> 16); // A1_PIXEL_Y = + jaguar_word_write(0xF0221A, a1_x & 0xFFFF); // A1_FPIXEL_X = + jaguar_word_write(0xF02218, a1_y & 0xFFFF); // A1_FPIXEL_Y = + jaguar_word_write(0xF02232, a2_x); // A2_PIXEL_X = + jaguar_word_write(0xF02230, a2_y); // A2_PIXEL_Y = +} +/* +#define A1_PIXEL_Y jaguar_word_read(0xF0220C) +#define A1_PIXEL_X jaguar_word_read(0xF0220E) +#define A1_FPIXEL_Y jaguar_word_read(0xF02218) +#define A1_FPIXEL_X jaguar_word_read(0xF0221A) +#define A2_PIXEL_Y jaguar_word_read(0xF02230) +#define A2_PIXEL_X jaguar_word_read(0xF02232) +*/ diff --git a/src/dsp.cpp b/src/dsp.cpp index 294b73e..b1f54d4 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -152,7 +152,7 @@ char *dsp_opcode_str[64]= static uint16 *mirror_table; static uint8 *dsp_ram_8; -static uint32 dsp_pc; +uint32 dsp_pc; static uint32 dsp_acc; static uint32 dsp_remain; static uint32 dsp_modulo; @@ -160,7 +160,7 @@ static uint32 dsp_flags; static uint32 dsp_matrix_control; static uint32 dsp_pointer_to_matrix; static uint32 dsp_data_organization; -static uint32 dsp_control; +uint32 dsp_control; static uint32 dsp_div_control; static uint8 dsp_flag_z; static uint8 dsp_flag_n; @@ -270,10 +270,10 @@ unsigned dsp_byte_read(unsigned int offset) if (offset==0xF1CFE0) return(0xff); } - if ((offset>=dsp_work_ram_base)&&(offset=DSP_WORK_RAM_BASE)&&(offset=dsp_control_ram_base)&&(offset=DSP_CONTROL_RAM_BASE)&&(offset=dsp_work_ram_base)&&(offset=DSP_WORK_RAM_BASE)&&(offset=dsp_control_ram_base)&&(offset=DSP_CONTROL_RAM_BASE)&&(offset=dsp_work_ram_base)&&(offset=DSP_WORK_RAM_BASE)&&(offset=dsp_control_ram_base)&&(offset=DSP_CONTROL_RAM_BASE)&&(offset= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { - offset -= dsp_work_ram_base; + offset -= DSP_WORK_RAM_BASE; dsp_ram_8[offset] = data; if (dsp_in_exec == 0) { @@ -414,7 +414,7 @@ void dsp_byte_write(unsigned offset, unsigned data) } return; } - if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { uint32 reg = offset & 0x1C; int bytenum = offset & 0x03; @@ -438,21 +438,21 @@ 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)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { - offset -= dsp_work_ram_base; + 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); +// 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)) + else if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { if ((offset & 0x1C) == 0x1C) { @@ -479,16 +479,16 @@ 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)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { - offset -= dsp_work_ram_base; + 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)) + else if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { offset&=0x1f; switch (offset) @@ -577,7 +577,7 @@ void dsp_long_write(unsigned offset, unsigned data) jaguar_word_write(offset+2, data & 0xFFFF); } -uint8 * jaguar_rom_load(char * path, uint32 * romSize); +/*uint8 * jaguar_rom_load(char * path, uint32 * romSize); void dsp_load_bin_at(char * path, uint32 offset) { uint32 romSize; @@ -586,7 +586,7 @@ void dsp_load_bin_at(char * path, uint32 offset) rom = jaguar_rom_load(path, &romSize); for(uint32 i=0; i> 6) & 0x1f; + bits = (dsp_control >> 6) & 0x1F; bits |= (dsp_control >> 10) & 0x20; // get the interrupt mask - mask = (dsp_flags >> 4) & 0x1f; + 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(), "DSP: bits=%08X mask=%08X\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(), "\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++) @@ -802,22 +801,22 @@ void dsp_done(void) // // } static char buffer[512]; - j=dsp_work_ram_base; - for (int i=0;i<4096;i++) + j = DSP_WORK_RAM_BASE; +// for(int i=0; i<4096; i++) + while (j <= 0xF1BFFF) { - uint32 oldj=j; - j+=dasmjag(JAGUAR_DSP,buffer,j); -// fprintf(log_get(),"\t0x%.8x: %s\n",oldj,buffer); - } + uint32 oldj = j; + j += dasmjag(JAGUAR_DSP, buffer, j); + fprintf(log_get(), "\t%08X: %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); } @@ -1674,7 +1673,7 @@ static void dsp_opcode_pack(void) static void dsp_opcode_storeb(void) { - if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + if ((Rm >= DSP_WORK_RAM_BASE) && (Rm < (DSP_WORK_RAM_BASE+0x2000))) dsp_long_write(Rm,Rn&0xff); else jaguar_byte_write(Rm,Rn); @@ -1682,7 +1681,7 @@ static void dsp_opcode_storeb(void) static void dsp_opcode_storew(void) { - if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + if ((Rm >= DSP_WORK_RAM_BASE) && (Rm < (DSP_WORK_RAM_BASE+0x2000))) dsp_long_write(Rm,Rn&0xffff); else jaguar_word_write(Rm,Rn); @@ -1695,7 +1694,7 @@ static void dsp_opcode_store(void) static void dsp_opcode_loadb(void) { - if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + if ((Rm >= DSP_WORK_RAM_BASE) && (Rm < (DSP_WORK_RAM_BASE+0x2000))) Rn=dsp_long_read(Rm)&0xff; else Rn=jaguar_byte_read(Rm); @@ -1703,7 +1702,7 @@ static void dsp_opcode_loadb(void) static void dsp_opcode_loadw(void) { - if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000))) + if ((Rm >= DSP_WORK_RAM_BASE) && (Rm < (DSP_WORK_RAM_BASE+0x2000))) Rn=dsp_long_read(Rm)&0xffff; else Rn=jaguar_word_read(Rm); diff --git a/src/eeprom.cpp b/src/eeprom.cpp index 197d269..4a55ee0 100644 --- a/src/eeprom.cpp +++ b/src/eeprom.cpp @@ -12,6 +12,10 @@ static uint16 eeprom_ram[64]; +// +// Private function prototypes +// + void eeprom_set_di(uint32 state); void eeprom_set_cs(uint32 state); uint32 eeprom_get_do(void); @@ -47,7 +51,7 @@ 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; +extern char jaguar_boot_dir[1024]; void eeprom_init(void) diff --git a/src/gpu.cpp b/src/gpu.cpp index f9e505b..dd451be 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -7,9 +7,79 @@ // Note: Endian wrongness probably stems from the MAME origins of this emu and // the braindead way in which MAME handles memory. :-) // +// Problem with not booting the BIOS was the incorrect way that the +// SUBC instruction set the carry when the carry was set going in... +// Same problem with ADDC... +// #include "gpu.h" +// For GPU dissasembly... + +//#define GPU_DIS_ABS +//#define GPU_DIS_ADDC +//#define GPU_DIS_CMP +//#define GPU_DIS_CMPQ +//#define GPU_DIS_DIV +//#define GPU_DIS_JUMP +//#define GPU_DIS_JR +//#define GPU_DIS_ROR +//#define GPU_DIS_RORQ +//#define GPU_DIS_SH +//#define GPU_DIS_SHA +//#define GPU_DIS_SHARQ +//#define GPU_DIS_SHLQ +//#define GPU_DIS_SHRQ +//#define GPU_DIS_STORE14R +//#define GPU_DIS_STORE15R +//#define GPU_DIS_SUBC +/* +GPU opcodes use (BIOS flying ATARI logo): + add 357416 + addq 538030 + addqt 6999 + sub 116663 + subq 188059 + subqt 15086 + neg 36097 + and 233993 + or 109332 + xor 1384 + btst 111924 + bset 25029 + bclr 10551 + mult 28147 + imult 69148 ++ div 64102 ++ abs 159394 ++ shlq 194690 ++ shrq 292587 ++ sharq 192649 ++ rorq 58672 ++ cmp 244963 ++ cmpq 114834 + move 833472 + moveq 56427 + moveta 220814 + movefa 170678 + movei 152025 + loadw 108220 + load 430936 + storew 3036 + store 372490 + move_pc 2330 ++ jump 349134 ++ jr 529171 + mmult 64904 + nop 432179 +*/ + +// Private function prototypes + +void gpu_dump_disassembly(void); +void gpu_dump_registers(void); +void gpu_dump_memory(void); + #define CINT0FLAG 0x00200 #define CINT1FLAG 0x00400 #define CINT2FLAG 0x00800 @@ -18,6 +88,7 @@ #define CINT04FLAGS (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG) extern int start_logging; +extern int gpu_start_log; static void gpu_opcode_add(void); static void gpu_opcode_addc(void); @@ -86,22 +157,14 @@ 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 + 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])()= @@ -125,10 +188,6 @@ void (*gpu_opcode[64])()= }; 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; @@ -139,35 +198,32 @@ 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 uint8 gpu_flag_z, gpu_flag_n, gpu_flag_c; +static uint8 gpu_alternate_flag_z, gpu_alternate_flag_n, 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_instruction; 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 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 SET_FLAG_Z(r) (gpu_flag_z = ((r) == 0)); +#define SET_FLAG_N(r) (gpu_flag_n = (((UINT32)(r) >> 31) & 0x01)); -#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 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_Z (gpu_flag_z = 0) #define CLR_ZN (gpu_flag_z = gpu_flag_n = 0) @@ -180,16 +236,17 @@ static uint32 gpu_opcode_second_parameter; #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 }; +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)] +#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]= +char * gpu_opcode_str[64]= { "add", "addc", "addq", "addqt", "sub", "subc", "subq", "subqt", @@ -223,15 +280,15 @@ uint32 gpu_get_pc(void) return gpu_pc; } -void build_branch_condition_table(void) -{ #define ZFLAG 0x00001 #define CFLAG 0x00002 #define NFLAG 0x00004 - + +void build_branch_condition_table(void) +{ if (!branch_condition_table) { - branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(branch_condition_table[0])); + branch_condition_table = (uint8 *)malloc(32 * 8 * sizeof(branch_condition_table[0])); if (branch_condition_table) { @@ -265,9 +322,9 @@ void build_branch_condition_table(void) unsigned gpu_byte_read(unsigned int offset) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + 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)) + else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { uint32 data = gpu_long_read(offset & 0xFFFFFFFC); @@ -290,13 +347,13 @@ unsigned gpu_byte_read(unsigned int offset) unsigned gpu_word_read(unsigned int offset) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + 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)) + else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { // This looks and smells wrong... // But it *might* be OK... @@ -311,6 +368,10 @@ unsigned gpu_word_read(unsigned int offset) return data >> 16; } +//TEMP--Mirror of F03000? +if (offset >= 0xF0B000 && offset <= 0xF0BFFF) +WriteLog("[GPUR16] --> Possible GPU RAM mirror access!"); + return jaguar_word_read(offset); } @@ -321,13 +382,13 @@ unsigned gpu_word_read(unsigned int offset) unsigned gpu_long_read(unsigned int offset) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + 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)) + else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { offset &= 0x1F; switch (offset) @@ -362,6 +423,11 @@ unsigned gpu_long_read(unsigned int offset) } // to prevent any lock-ups } +//TEMP--Mirror of F03000? +if (offset >= 0xF0B000 && offset <= 0xF0BFFF) + WriteLog("[GPUR32] --> Possible GPU RAM mirror access!\n"); +/*if (offset >= 0xF1D000 && offset <= 0xF1DFFF) + WriteLog("[GPUR32] --> Reading from Wavetable ROM!\n");//*/ return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2); } @@ -372,7 +438,7 @@ unsigned gpu_long_read(unsigned int offset) void gpu_byte_write(unsigned offset, unsigned data) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE+0x1000)) { gpu_ram_8[offset & 0xFFF] = data; if (gpu_in_exec == 0) @@ -383,7 +449,7 @@ void gpu_byte_write(unsigned offset, unsigned data) } return; } - else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { uint32 reg = offset & 0x1C; int bytenum = offset & 0x03; @@ -400,7 +466,7 @@ void gpu_byte_write(unsigned offset, unsigned data) } return; } -// fprintf(log_get(),"gpu: writing %.2x at 0x%.8x\n",data,offset); +// WriteLog("gpu: writing %.2x at 0x%.8x\n",data,offset); jaguar_byte_write(offset, data); } @@ -411,8 +477,10 @@ void gpu_byte_write(unsigned offset, unsigned data) void gpu_word_write(unsigned offset, unsigned data) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE+0x1000)) { +//if (offset >= 0xF03000 && offset <= 0xF03003) +// WriteLog("--> GPU(16): Writing %04X at %08X ***\n", data, offset); gpu_ram_8[offset & 0xFFF] = (data>>8) & 0xFF; gpu_ram_8[(offset+1) & 0xFFF] = data & 0xFF; @@ -424,7 +492,7 @@ void gpu_word_write(unsigned offset, unsigned data) } return; } - if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + 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... { @@ -450,7 +518,16 @@ void gpu_word_write(unsigned offset, unsigned data) } return; } -// fprintf(log_get(),"gpu: writing %.4x at 0x%.8x\n",data,offset); + +// WriteLog("gpu: writing %.4x at 0x%.8x\n",data,offset); +//This is done by the blitter... +//if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) +// WriteLog("GPU(16): Writing %08X at %08X\n", data, offset); +//if ((offset >= 0x1FE020 && offset <= 0x1FE03F) || (offset >= 0x1FE820 && offset <= 0x1FE83F)) +// WriteLog("GPU(16): Writing %08X at %08X\n", data, offset); +//if (offset >= 0xF02200 && offset <= 0xF0229F) +// WriteLog("GPU(16): Writing to blitter --> %08X at %08X\n", data, offset); + jaguar_word_write(offset, data); } @@ -461,15 +538,28 @@ void gpu_word_write(unsigned offset, unsigned data) void gpu_long_write(unsigned offset, unsigned data) { - if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000)) + 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; +#ifdef GPU_DEBUG + if (offset & 0x03) + { + WriteLog("GPU: Someone is trying an unaligned write @ %08X [%08X]\n", offset, data) + gpu_dump_registers(); + } +#endif // #ifdef GPU_DEBUG +/*if (offset == 0xF03000) +{ + WriteLog("GPU Write [F03000]: %08X\n", data); +// data = 0x03D0DEAD; // Why isn't this there??? +// data = 0xABCDEFFF; // Why isn't this there??? +}//*/ + 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)) + else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { offset &= 0x1F; switch (offset) @@ -490,29 +580,31 @@ void gpu_long_write(unsigned offset, unsigned data) gpu_matrix_control = data; break; case 0x08: - gpu_pointer_to_matrix=data; + // Can only point to long aligned addresses + gpu_pointer_to_matrix = data & 0xFFFFFFFC; break; case 0x0C: - gpu_data_organization=data; + gpu_data_organization = data; break; case 0x10: - gpu_pc = data; /*fprintf(log_get(),"setting gpu pc to 0x%.8x\n",gpu_pc);*/ + gpu_pc = data; /*WriteLog("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 +// data &= (~0x07C0); // disable writes to irq pending + data &= (~0xF7C0); // Disable writes to INT_LAT0-4 & TOM version number /*if (GPU_RUNNING) { - fprintf(log_get(),"gpu pc is 0x%.8x\n",gpu_pc); + WriteLog("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"); +// WriteLog("GPU->CPU interrupt\n"); if (tom_irq_enabled(IRQ_GPU)) { if ((tom_irq_enabled(IRQ_GPU)) && (jaguar_interrupt_handler_is_valid(64))) @@ -539,7 +631,7 @@ void gpu_long_write(unsigned offset, unsigned data) // check for CPU->GPU interrupt if (data & 0x04) { - //fprintf(log_get(),"CPU->GPU interrupt\n"); + //WriteLog("CPU->GPU interrupt\n"); gpu_set_irq_line(0, 1); // s68000releaseTimeslice(); m68k_end_timeslice(); @@ -549,9 +641,10 @@ void gpu_long_write(unsigned offset, unsigned data) // single stepping if (data & 0x10) { - //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not "); + //WriteLog("asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not "); } - gpu_control = (gpu_control & 0x107C0) | (data & (~0x107C0)); +// gpu_control = (gpu_control & 0x107C0) | (data & (~0x107C0)); + gpu_control = (gpu_control & 0x1F7C0) | (data & (~0x1F7C0)); // if gpu wasn't running but is now running, execute a few cycles #ifndef GPU_SINGLE_STEPPING @@ -562,11 +655,13 @@ void gpu_long_write(unsigned offset, unsigned data) gpu_exec(1); #endif // #ifndef GPU_SINGLE_STEPPING #ifdef GPU_DEBUG -fprintf(log_get(), "Write to GPU CTRL: %08X ", data); +WriteLog("Write to GPU CTRL: %08X ", data); if (GPU_RUNNING) - fprintf(log_get(), "-- Starting to run at %08X...", gpu_pc); -fprintf(log_get(), "\n"); + WriteLog("-- Starting to run at %08X...", gpu_pc); +WriteLog("\n"); #endif // #ifdef GPU_DEBUG +//if (GPU_RUNNING) +// gpu_dump_disassembly(); break; } case 0x18: @@ -581,7 +676,15 @@ fprintf(log_get(), "\n"); } return; } -// fprintf(log_get(),"gpu: writing %.8x at 0x%.8x\n",data,offset); + +//This is done by the blitter... +//if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) +// WriteLog("GPU(32): Writing %08X at %08X\n", data, offset); +//if ((offset >= 0x1FE020 && offset <= 0x1FE03F) || (offset >= 0x1FE820 && offset <= 0x1FE83F)) +// WriteLog("GPU(32): Writing %08X at %08X\n", data, offset); +//if (offset >= 0xF02200 && offset <= 0xF0229F) +// WriteLog("GPU(32): Writing to blitter --> %08X at %08X\n", data, offset); + jaguar_word_write(offset, (data >> 16) & 0xFFFF); jaguar_word_write(offset+2, data & 0xFFFF); } @@ -591,14 +694,14 @@ 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); +// WriteLog("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); +// WriteLog("\tswitching to bank %i\n",bank?1:0); for(int i=0; i<32; i++) { temp = gpu_reg[i]; @@ -632,7 +735,7 @@ void gpu_update_register_banks(void) } // else // { -// fprintf(log_get(),"\tnot switching banks\n"); +// WriteLog("\tnot switching banks\n"); // } } @@ -661,11 +764,11 @@ void gpu_check_irqs(void) if (bits & 0x10) which = 4; if (bits & 0x20) which = 5; - if (gpu_flags & 0x8) + if (gpu_flags & 0x08) return; if (start_logging) - fprintf(log_get(),"gpu: generating irg %i\n",which); + WriteLog("GPU: generating irq %i\n", which); // set the interrupt flag gpu_flags |= 0x08; @@ -681,15 +784,14 @@ void gpu_check_irqs(void) // 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_pc = GPU_WORK_RAM_BASE + (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); + WriteLog("GPU: setting irg line %i\n", irqline); int mask = 0x40 << irqline; gpu_control &= ~mask; @@ -700,6 +802,10 @@ void gpu_set_irq_line(int irqline, int state) } } +//TEMPORARY: Testing only! +#include "gpu2.h" +#include "gpu3.h" + void gpu_init(void) { memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work ram"); @@ -712,6 +818,10 @@ void gpu_init(void) build_branch_condition_table(); gpu_reset(); + +//TEMPORARY: Testing only! + gpu2_init(); + gpu3_init(); } void gpu_reset(void) @@ -724,7 +834,7 @@ void gpu_reset(void) gpu_matrix_control = 0x00000000; gpu_pointer_to_matrix = 0x00000000; gpu_data_organization = 0xFFFFFFFF; - gpu_control = 0x00012800; + gpu_control = 0x00012800; // Correctly sets this a TOM Rev. 2 gpu_div_control = 0x00000000; gpu_in_exec = 0; @@ -739,9 +849,7 @@ void gpu_reset(void) // gpu_reg_bank_1 = gpu_reg; // gpu_reg_bank_0 = gpu_alternate_reg; - reset_flag_z(); - reset_flag_n(); - reset_flag_c(); + CLR_ZNC; gpu_alternate_flag_z = 0; gpu_alternate_flag_n = 0; @@ -761,11 +869,57 @@ void gpu_reset_stats(void) { for(uint32 i=0; i<64; i++) gpu_opcode_use[i] = 0; + WriteLog("--> GPU stats were reset!\n"); +} + +void gpu_dump_disassembly(void) +{ + char buffer[512]; + + WriteLog("\n---[GPU code at 00F03000]---------------------------\n"); + uint32 j = 0xF03000; + while (j <= 0xF03FFF) + { + uint32 oldj = j; + j += dasmjag(JAGUAR_GPU, buffer, j); + WriteLog("\t%08X: %s\n", oldj, buffer); + } +} + +void gpu_dump_registers(void) +{ + WriteLog("\n---[GPU flags: NCZ %d%d%d]-----------------------\n", gpu_flag_n, gpu_flag_c, gpu_flag_z); + WriteLog("\nRegisters bank 0\n"); + for(int j=0; j<8; j++) + { + WriteLog("\tr%2i = %08X r%2i = %08X r%2i = %08X r%2i = %08X\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]); + } + WriteLog("Registers bank 1\n"); + for(int j=0; j<8; j++) + { + WriteLog("\tr%2i = %08X r%2i = %08X r%2i = %08X r%2i = %08X\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]); + } +} + +void gpu_dump_memory(void) +{ + WriteLog("\n---[GPU data at 00F03000]---------------------------\n"); + for(int i=0; i<0xFFF; i+=4) + WriteLog("\t%08X: %02X %02X %02X %02X\n", 0xF03000+i, gpu_ram_8[i], + gpu_ram_8[i+1], gpu_ram_8[i+2], gpu_ram_8[i+3]); } void gpu_done(void) { - fprintf(log_get(), "GPU: stopped at PC=%08X (GPU %s running)\n", gpu_pc, GPU_RUNNING ? "was" : "wasn't"); + WriteLog("GPU: stopped at PC=%08X (GPU %s running)\n", (unsigned int)gpu_pc, GPU_RUNNING ? "was" : "wasn't"); // get the active interrupt bits int bits = (gpu_control >> 6) & 0x1F; @@ -776,52 +930,55 @@ void gpu_done(void) 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"); + WriteLog("GPU: ibits=0x%.8x imask=0x%.8x\n", bits, mask); +// WriteLog("\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", +// WriteLog("\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"); +// WriteLog("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", +// WriteLog("\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"); + WriteLog("\n---[GPU code at 00F03000]---------------------------\n"); static char buffer[512]; int j = 0xF03000; - for(int i=0; i<4096; i++) +// for(int i=0; i<4096; i++) + while (j <= 0xF03FFF) { uint32 oldj = j; j += dasmjag(JAGUAR_GPU, buffer, j); - fprintf(log_get(),"\t%08X: %s\n", oldj, buffer); - } + WriteLog("\t%08X: %s\n", oldj, buffer); + }//*/ - fprintf(log_get(), "---[GPU code at %08X]---------------------------\n", gpu_pc); +/* WriteLog("---[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); - } + WriteLog("\t%08X: %s\n", oldj, buffer); + }*/ - fprintf(log_get(), "gpu opcodes use:\n"); + WriteLog("\nGPU 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]); + WriteLog("\t%17s %lu\n", gpu_opcode_str[i], gpu_opcode_use[i]); } + WriteLog("\n"); + memory_free(gpu_ram_8); } @@ -829,6 +986,8 @@ void gpu_done(void) // Main GPU execution core // +static int testCount = 1; +static int len = 0; void gpu_exec(int32 cycles) { if (!GPU_RUNNING) @@ -852,17 +1011,136 @@ void gpu_exec(int32 cycles) gpu_flag_n = (gpu_flag_n ? 1 : 0); uint16 opcode = gpu_word_read(gpu_pc); -/*static char buffer[512]; -dasmjag(JAGUAR_GPU, buffer, gpu_pc); -fprintf(log_get(), "GPU: [%08X] %s\n", gpu_pc, buffer);*/ - uint32 index = opcode >> 10; + uint32 index = opcode >> 10; + gpu_instruction = opcode; // Added for GPU #3... gpu_opcode_first_parameter = (opcode >> 5) & 0x1F; gpu_opcode_second_parameter = opcode & 0x1F; +/*if (gpu_pc == 0xF03BE8) +WriteLog("Start of OP frame write...\n"); +if (gpu_pc == 0xF03EEE) +WriteLog("--> Writing BRANCH object ---\n"); +if (gpu_pc == 0xF03F62) +WriteLog("--> Writing BITMAP object ***\n");//*/ +/*if (gpu_pc == 0xF03546) +{ + WriteLog("\n--> GPU PC: F03546\n"); + gpu_dump_registers(); + gpu_dump_disassembly(); +}//*/ +/*if (gpu_pc == 0xF033F6) +{ + WriteLog("\n--> GPU PC: F033F6\n"); + gpu_dump_registers(); + gpu_dump_disassembly(); +}//*/ +/*if (gpu_pc == 0xF033CC) +{ + WriteLog("\n--> GPU PC: F033CC\n"); + gpu_dump_registers(); + gpu_dump_disassembly(); +}//*/ +/*if (gpu_pc == 0xF033D6) +{ + WriteLog("\n--> GPU PC: F033D6 (#%d)\n", testCount++); + gpu_dump_registers(); + gpu_dump_memory(); +}//*/ +/*if (gpu_pc == 0xF033D8) +{ + WriteLog("\n--> GPU PC: F033D8 (#%d)\n", testCount++); + gpu_dump_registers(); + gpu_dump_memory(); +}//*/ +/*if (gpu_pc == 0xF0358E) +{ + WriteLog("\n--> GPU PC: F0358E (#%d)\n", testCount++); + gpu_dump_registers(); + gpu_dump_memory(); +}//*/ +/*if (gpu_pc == 0xF034CA) +{ + WriteLog("\n--> GPU PC: F034CA (#%d)\n", testCount++); + gpu_dump_registers(); +}//*/ +/*if (gpu_pc == 0xF034CA) +{ + len = gpu_reg[1] + 4;//, r9save = gpu_reg[9]; + WriteLog("\nAbout to subtract [#%d] (R14=%08X, R15=%08X, R9=%08X):\n ", testCount++, gpu_reg[14], gpu_reg[15], gpu_reg[9]); + for(int i=0; i GPU PC: F035C8 (#%d)\n", testCount++); + gpu_dump_registers(); + gpu_dump_disassembly(); +}//*/ + +if (gpu_start_log) +{ + gpu_reset_stats(); +static char buffer[512]; +dasmjag(JAGUAR_GPU, buffer, gpu_pc); +WriteLog("GPU: [%08X] %s (RM=%08X, RN=%08X) -> ", gpu_pc, buffer, RM, RN); +}//*/ +//$E400 -> 1110 01 -> $39 -> 57 +//GPU #1 gpu_pc += 2; gpu_opcode[index](); +//GPU #2 +// gpu2_opcode[index](); +// gpu_pc += 2; +//GPU #3 (Doesn't show ATARI logo! #1 & #2 do...) +// gpu_pc += 2; +// gpu3_opcode[index](); + +// BIOS hacking +//GPU: [00F03548] jr nz,00F03560 (0xd561) (RM=00F03114, RN=00000004) -> --> JR: Branch taken. +/*static bool firstTime = true; +if (gpu_pc == 0xF03548 && firstTime) +{ + gpu_flag_z = 1; +// firstTime = false; + +//static char buffer[512]; +//int k=0xF03548; +//while (k<0xF0356C) +//{ +//int oldk = k; +//k += dasmjag(JAGUAR_GPU, buffer, k); +//WriteLog("GPU: [%08X] %s\n", oldk, buffer); +//} +// gpu_start_log = 1; +}//*/ +//GPU: [00F0354C] jump nz,(r29) (0xd3a1) (RM=00F03314, RN=00000004) -> (RM=00F03314, RN=00000004) +/*if (gpu_pc == 0xF0354C) + gpu_flag_z = 0;//, gpu_start_log = 1;//*/ + cycles -= gpu_opcode_cycles[index]; gpu_opcode_use[index]++; +if (gpu_start_log) + WriteLog("(RM=%08X, RN=%08X)\n", RM, RN);//*/ } gpu_in_exec--; @@ -872,61 +1150,137 @@ fprintf(log_get(), "GPU: [%08X] %s\n", gpu_pc, buffer);*/ // GPU opcodes // +/* +GPU opcodes use (offset punch--vertically below bad guy): + add 18686 + addq 32621 + sub 7483 + subq 10252 + and 21229 + or 15003 + btst 1822 + bset 2072 + mult 141 + div 2392 + shlq 13449 + shrq 10297 + sharq 11104 + cmp 6775 + cmpq 5944 + move 31259 + moveq 4473 + movei 23277 + loadb 46 + loadw 4201 + load 28580 + load_r14_indexed 1183 + load_r15_indexed 1125 + storew 178 + store 10144 + store_r14_indexed 320 + store_r15_indexed 1 + move_pc 1742 + jump 24467 + jr 18090 + nop 41362 +*/ + static void gpu_opcode_jump(void) { - uint32 delayed_pc = Rm; - uint32 jaguar_flags; - +#ifdef GPU_DIS_JUMP +char * condition[32] = +{ "T", "nz", "z", "???", "nc", "nc nz", "nc z", "???", "c", "c nz", + "c z", "???", "???", "???", "???", "???", "???", "???", "???", + "???", "nn", "nn nz", "nn z", "???", "n", "n nz", "n z", "???", + "???", "???", "???", "F" }; + WriteLog("%06X: JUMP %s, (R%02u) [NCZ:%u%u%u, R%02u=%08X] ", gpu_pc-2, condition[IMM_2], IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM); +#endif // normalize flags - gpu_flag_c = (gpu_flag_c ? 1 : 0); +/* 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_flag_n = (gpu_flag_n ? 1 : 0);*/ + // KLUDGE: Used by BRANCH_CONDITION + uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; - jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; - - if (branch_condition(imm_2)) + if (BRANCH_CONDITION(IMM_2)) { +#ifdef GPU_DIS_JUMP + WriteLog("Branched!\n"); +#endif +if (gpu_start_log) + WriteLog(" --> JUMP: Branch taken.\n"); + uint32 delayed_pc = RM; + gpu_exec(1); gpu_pc = delayed_pc; +/* uint16 opcode = gpu_word_read(gpu_pc); + gpu_opcode_first_parameter = (opcode >> 5) & 0x1F; + gpu_opcode_second_parameter = opcode & 0x1F; + + gpu_pc = delayed_pc; + gpu_opcode[opcode>>10]();//*/ } +#ifdef GPU_DIS_JUMP + else + WriteLog("Branch NOT taken.\n"); +#endif } 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; - +#ifdef GPU_DIS_JR +char * condition[32] = +{ "T", "nz", "z", "???", "nc", "nc nz", "nc z", "???", "c", "c nz", + "c z", "???", "???", "???", "???", "???", "???", "???", "???", + "???", "nn", "nn nz", "nn z", "???", "n", "n nz", "n z", "???", + "???", "???", "???", "F" }; + WriteLog("%06X: JR %s, %06X [NCZ:%u%u%u] ", gpu_pc-2, condition[IMM_2], gpu_pc+((IMM_1 & 0x10 ? 0xFFFFFFF0 | IMM_1 : IMM_1) * 2), gpu_flag_n, gpu_flag_c, gpu_flag_z); +#endif +/* if (CONDITION(jaguar.op & 31)) + { + INT32 r1 = (INT8)((jaguar.op >> 2) & 0xF8) >> 2; + UINT32 newpc = jaguar.PC + r1; + CALL_MAME_DEBUG; + jaguar.op = ROPCODE(jaguar.PC); + jaguar.PC = newpc; + (*jaguar.table[jaguar.op >> 10])(); + + jaguar_icount -= 3; // 3 wait states guaranteed + }*/ // 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; +/* gpu_flag_n = (gpu_flag_n ? 1 : 0); + gpu_flag_c = (gpu_flag_c ? 1 : 0); + gpu_flag_z = (gpu_flag_z ? 1 : 0);*/ + // KLUDGE: Used by BRANCH_CONDITION + uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; - if (branch_condition(imm_2)) + if (BRANCH_CONDITION(IMM_2)) { +#ifdef GPU_DIS_JR + WriteLog("Branched!\n"); +#endif +if (gpu_start_log) + WriteLog(" --> JR: Branch taken.\n"); + int32 offset = (IMM_1 & 0x10 ? 0xFFFFFFF0 | IMM_1 : IMM_1); // Sign extend IMM_1 + int32 delayed_pc = gpu_pc + (offset * 2); + gpu_exec(1); - gpu_pc=delayed_pc; + gpu_pc = delayed_pc; +/* uint16 opcode = gpu_word_read(gpu_pc); + gpu_opcode_first_parameter = (opcode >> 5) & 0x1F; + gpu_opcode_second_parameter = opcode & 0x1F; + + gpu_pc = delayed_pc; + gpu_opcode[opcode>>10]();//*/ } +#ifdef GPU_DIS_JR + else + WriteLog("Branch NOT taken.\n"); +#endif } 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]; @@ -934,69 +1288,16 @@ static void gpu_opcode_add(void) 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; -} -#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( - "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; + UINT32 res = RN + RM; + CLR_ZNC; SET_ZNC_ADD(RN, RM, res); + RN = res; } static void gpu_opcode_addc(void) { - uint32 _Rm=Rm; - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ +#ifdef GPU_DIS_ADDC + WriteLog("%06X: ADDC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif /* int dreg = jaguar.op & 31; UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31]; UINT32 r2 = jaguar.r[dreg]; @@ -1004,85 +1305,18 @@ static void gpu_opcode_addc(void) 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; -} -#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( - "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 - }; + UINT32 res = RN + RM + gpu_flag_c; + UINT32 carry = gpu_flag_c; +// SET_ZNC_ADD(RN, RM, res); //???BUG??? + SET_ZNC_ADD(RN + carry, RM, res); +// SET_ZNC_ADD(RN, RM + carry, res); + RN = res; +#ifdef GPU_DIS_ADDC + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #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]; @@ -1090,74 +1324,19 @@ static void gpu_opcode_addq(void) 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; -} -#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( - "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; + UINT32 r1 = gpu_convert_zero[IMM_1]; + UINT32 res = RN + r1; + CLR_ZNC; SET_ZNC_ADD(RN, r1, res); + RN = res; } static void gpu_opcode_addqt(void) { - Rn += gpu_convert_zero[imm_1]; + RN += gpu_convert_zero[IMM_1]; } static void gpu_opcode_sub(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]; @@ -1165,1590 +1344,681 @@ static void gpu_opcode_sub(void) UINT32 res = r2 - r1; jaguar.r[dreg] = res; CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/ - UINT32 res = Rn - Rm; - CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res); - Rn = res; - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + + UINT32 res = RN - RM; + SET_ZNC_SUB(RN, RM, res); + RN = res; } static void gpu_opcode_subc(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_SUB(r2,r1,res);*/ - UINT32 res = Rn - Rm - gpu_flag_c; - CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res); - Rn = res; - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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 - }; +#ifdef GPU_DIS_SUBC + WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif + UINT32 res = RN - RM - gpu_flag_c; + UINT32 borrow = gpu_flag_c; +// SET_ZNC_SUB(RN, RM, res); //???BUG??? YES!!! + SET_ZNC_SUB(RN - borrow, RM, res); + RN = res; +#ifdef GPU_DIS_SUBC + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #endif - Rn=res; } static void gpu_opcode_subq(void) { - uint32 _Rm=gpu_convert_zero[imm_1]; - uint32 _Rn=Rn; - 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_SUB(r2,r1,res);*/ - UINT32 r1 = gpu_convert_zero[imm_1]; - UINT32 res = Rn - r1; - CLR_ZNC; SET_ZNC_SUB(Rn, r1, res); - Rn = res; - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + UINT32 r1 = gpu_convert_zero[IMM_1]; + UINT32 res = RN - r1; + SET_ZNC_SUB(RN, r1, res); + RN = res; } static void gpu_opcode_subqt(void) { - Rn -= gpu_convert_zero[imm_1]; + RN -= gpu_convert_zero[IMM_1]; } static void gpu_opcode_cmp(void) { - uint32 _Rm=Rm; - uint32 _Rn=Rn; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31]; - UINT32 r2 = jaguar.r[jaguar.op & 31]; - UINT32 res = r2 - r1; - CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/ - UINT32 res = Rn - Rm; - CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#else - __asm - { - mov eax,_Rn - mov edx,_Rm - cmp eax,edx - setc [gpu_flag_c] - setz [gpu_flag_z] - sets [gpu_flag_n] - }; +#ifdef GPU_DIS_CMP + WriteLog("%06X: CMP R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif + UINT32 res = RN - RM; + SET_ZNC_SUB(RN, RM, res); +#ifdef GPU_DIS_CMP + WriteLog("[NCZ:%u%u%u]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z); #endif } static void gpu_opcode_cmpq(void) { +#ifdef GPU_DIS_CMPQ + WriteLog("%06X: CMPQ #%d, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, sqtable[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif 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__ -#ifndef USE_ASSEMBLY -{ -/* UINT32 r1 = (INT8)(jaguar.op >> 2) >> 3; - UINT32 r2 = jaguar.r[jaguar.op & 31]; - UINT32 res = r2 - r1; - CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/ - UINT32 r1 = sqtable[imm_1 & 0x1F]; // I like this better -> (INT8)(jaguar.op >> 2) >> 3; - UINT32 res = Rn - r1; - CLR_ZNC; SET_ZNC_SUB(Rn, r1, res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#else - __asm - { - mov eax,_Rn - mov edx,_Rm - cmp eax,edx - setc [gpu_flag_c] - setz [gpu_flag_z] - sets [gpu_flag_n] - }; + UINT32 r1 = sqtable[IMM_1 & 0x1F]; // I like this better -> (INT8)(jaguar.op >> 2) >> 3; + UINT32 res = RN - r1; + SET_ZNC_SUB(RN, r1, res); +#ifdef GPU_DIS_CMPQ + WriteLog("[NCZ:%u%u%u]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z); #endif } static void gpu_opcode_and(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.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = Rn & Rm; - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + RN = RN & RM; + SET_ZN(RN); } static void gpu_opcode_or(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 = r1 | r2; - jaguar.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = Rn | Rm; - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + RN = RN | RM; + SET_ZN(RN); } static void gpu_opcode_xor(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 = r1 ^ r2; - jaguar.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = Rn ^ Rm; - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + RN = RN ^ RM; + SET_ZN(RN); } static void gpu_opcode_not(void) { - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* int dreg = jaguar.op & 31; - UINT32 res = ~jaguar.r[dreg]; - jaguar.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = ~Rn; - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#else - __asm - { - mov eax,_Rn - not eax - setz [gpu_flag_z] - sets [gpu_flag_n] - mov res,eax - }; -#endif - Rn=res; + RN = ~RN; + SET_ZN(RN); } static void gpu_opcode_move_pc(void) { - Rn = gpu_pc-2; + // Should be previous PC--this might not always be previous instruction! + // Then again, this will point right at the *current* instruction, i.e., MOVE PC,R! + 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(); + RN = ((int32)RN < 0 ? 0 : (RN > 0xFF ? 0xFF : RN)); + SET_ZN(RN); } 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(); + RN = ((int32)RN < 0 ? 0 : (RN > 0xFFFF ? 0xFFFF : RN)); + SET_ZN(RN); } 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(); + RN = ((int32)RN < 0 ? 0 : (RN > 0xFFFFFF ? 0xFFFFFF : RN)); + SET_ZN(RN); } static void gpu_opcode_store_r14_indexed(void) { - gpu_long_write( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2),Rn); + 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); + 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); + RN = gpu_long_read(gpu_reg[14] + RM); } static void gpu_opcode_load_r15_ri(void) { - Rn=gpu_long_read(gpu_reg[15] + Rm); + RN = gpu_long_read(gpu_reg[15] + RM); } static void gpu_opcode_store_r14_ri(void) { - gpu_long_write(gpu_reg[14] + Rm,Rn); +#ifdef GPU_DIS_STORE14R + WriteLog("%06X: STORE R%02u, (R14+R%02u) [NCZ:%u%u%u, R%02u=%08X, R14+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[14]); +#endif + gpu_long_write(gpu_reg[14] + RM, RN); } static void gpu_opcode_store_r15_ri(void) { - gpu_long_write(gpu_reg[15] + Rm,Rn); +#ifdef GPU_DIS_STORE15R + WriteLog("%06X: STORE R%02u, (R15+R%02u) [NCZ:%u%u%u, R%02u=%08X, R15+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[15]); +#endif + gpu_long_write(gpu_reg[15] + RM, RN); } static void gpu_opcode_nop(void) { +#ifdef GPU_DIS_NOP + WriteLog("%06X: NOP [NCZ:%u%u%u]\n", gpu_pc-2, gpu_flag_n, gpu_flag_c, gpu_flag_z); +#endif } static void gpu_opcode_pack(void) { - uint32 _Rn=Rn; + uint32 val = 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); + if (RM == 0) // Pack + RN = ((val >> 10) & 0x0000F000) | ((val >> 5) & 0x00000F00) | (val & 0x000000FF); + else // Unpack + RN = ((val & 0x0000F000) << 10) | ((val & 0x00000F00) << 5) | (val & 0x000000FF); } static void gpu_opcode_storeb(void) { - if ((Rm >= 0xF03000) && (Rm < 0xF04000)) - gpu_long_write(Rm,Rn&0xff); +//Is this right??? +// Would appear to be so...! + if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) + gpu_long_write(RM, RN & 0xFF); else - jaguar_byte_write(Rm,Rn); + jaguar_byte_write(RM, RN); } static void gpu_opcode_storew(void) { - if ((Rm >= 0xF03000) && (Rm < 0xF04000)) - gpu_long_write(Rm,Rn&0xffff); + if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) + gpu_long_write(RM, RN & 0xFFFF); else - jaguar_word_write(Rm,Rn); + jaguar_word_write(RM, RN); } static void gpu_opcode_store(void) { - gpu_long_write(Rm,Rn); + 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); + gpu_long_write(RM + 0, 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; + if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) + RN = gpu_long_read(RM) & 0xFF; else - Rn=jaguar_byte_read(Rm); + RN = jaguar_byte_read(RM); } static void gpu_opcode_loadw(void) { - if ((Rm >= 0xF03000) && (Rm < 0xF04000)) - Rn=gpu_long_read(Rm)&0xffff; + if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) + RN = gpu_long_read(RM) & 0xFFFF; else - Rn=jaguar_word_read(Rm); + RN = jaguar_word_read(RM); } static void gpu_opcode_load(void) { - Rn = gpu_long_read(Rm); + 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); + gpu_hidata = gpu_long_read(RM + 0); + 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)); + 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)); + 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); + // This instruction is followed by 32-bit value in LSW / MSW format... + 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; + ALTERNATE_RN = RM; } static void gpu_opcode_movefa(void) { - Rn = alternate_Rm; + RN = ALTERNATE_RM; } static void gpu_opcode_move(void) { - Rn = Rm; + RN = RM; } static void gpu_opcode_moveq(void) { - Rn = imm_1; + RN = IMM_1; } static void gpu_opcode_resmac(void) { - Rn = gpu_acc; + RN = gpu_acc; } static void gpu_opcode_imult(void) { - uint32 res=Rn=((int16)Rn)*((int16)Rm); - set_flag_z(res); - set_flag_n(res); + RN = (int16)RN * (int16)RM; + SET_ZN(RN); } static void gpu_opcode_mult(void) { - uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn); - set_flag_z(res); - set_flag_n(res); + RN = (uint16)RM * (uint16)RN; + SET_ZN(RN); } static void gpu_opcode_bclr(void) { - uint32 _Rm=imm_1; - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* int dreg = jaguar.op & 31; - UINT32 r1 = (jaguar.op >> 5) & 31; - UINT32 r2 = jaguar.r[dreg]; - UINT32 res = r2 & ~(1 << r1); - jaguar.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = Rn & ~(1 << imm_1); - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + UINT32 res = RN & ~(1 << IMM_1); + RN = res; + SET_ZN(res); } static void gpu_opcode_btst(void) { - uint32 _Rm=imm_1; - uint32 _Rn=Rn; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* UINT32 r1 = (jaguar.op >> 5) & 31; - UINT32 r2 = jaguar.r[jaguar.op & 31]; - CLR_Z; jaguar.FLAGS |= (~r2 >> r1) & 1;*/ - CLR_Z; gpu_flag_z = (~Rn >> imm_1) & 1; - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#else - __asm - { - mov eax,_Rn - mov ecx,_Rm - bt eax,ecx - setnc [gpu_flag_z] - }; -#endif + gpu_flag_z = (~RN >> IMM_1) & 1; } static void gpu_opcode_bset(void) { - uint32 _Rm=imm_1; - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* int dreg = jaguar.op & 31; - UINT32 r1 = (jaguar.op >> 5) & 31; - UINT32 r2 = jaguar.r[dreg]; - UINT32 res = r2 | (1 << r1); - jaguar.r[dreg] = res; - CLR_ZN; SET_ZN(res);*/ - UINT32 res = Rn | (1 << imm_1); - Rn = res; - CLR_ZN; SET_ZN(res); - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + UINT32 res = RN | (1 << IMM_1); + RN = res; + SET_ZN(res); } static void gpu_opcode_imacn(void) { - uint32 res = ((int16)Rm) * ((int16)(Rn)); + 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); + uint32 _RM = RM; + uint32 res = RN = (((INT32)_RM >> 8) & 0xFF800000) | (_RM & 0x007FFFFF); + SET_ZN(res); } static void gpu_opcode_normi(void) { - uint32 _Rm = Rm; + uint32 _RM = RM; uint32 res = 0; - if (_Rm) + if (_RM) { - while ((_Rm & 0xFFC00000) == 0) + while ((_RM & 0xFFC00000) == 0) { - _Rm <<= 1; + _RM <<= 1; res--; } - while ((_Rm & 0xFF800000) != 0) + while ((_RM & 0xFF800000) != 0) { - _Rm >>= 1; + _RM >>= 1; res++; } } - Rn = res; - set_flag_z(res); - set_flag_n(res); + RN = res; + SET_ZN(res); } static void gpu_opcode_mmult(void) { - int count = gpu_matrix_control & 0x0F; - uint32 addr = gpu_pointer_to_matrix; // in the gpu ram + int count = gpu_matrix_control & 0x0F; // Matrix width + uint32 addr = gpu_pointer_to_matrix; // In the GPU's RAM int64 accum = 0; uint32 res; - if (!(gpu_matrix_control & 0x10)) + if (gpu_matrix_control & 0x10) // Column stepping { - for (int i = 0; i < count; i++) + for(int i=0; i>1)]>>16)&0xffff); + if (i & 0x01) + a = (int16)((gpu_alternate_reg[IMM_1 + (i >> 1)] >> 16) & 0xFFFF); else - a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff); + a = (int16)(gpu_alternate_reg[IMM_1 + (i >> 1)] & 0xFFFF); - int16 b=((int16)gpu_word_read(addr+2)); - accum += a*b; - addr += 4; + int16 b = ((int16)gpu_word_read(addr + 2)); + accum += a * b; + addr += 4 * count; } } - else + else // Row stepping { - for (int i = 0; i < count; i++) + for(int i=0; i>1)]>>16)&0xffff); + if (i & 0x01) + a = (int16)((gpu_alternate_reg[IMM_1 + (i >> 1)] >> 16) & 0xFFFF); else - a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff); + a = (int16)(gpu_alternate_reg[IMM_1 + (i >> 1)] & 0xFFFF); - int16 b=((int16)gpu_word_read(addr+2)); - accum += a*b; - addr += 4 * count; + int16 b = ((int16)gpu_word_read(addr + 2)); + accum += a * b; + addr += 4; } } - Rn = res = (int32)accum; - // carry flag to do - set_flag_z(res); - set_flag_n(res); + RN = res = (int32)accum; + // carry flag to do (out of the last add) + SET_ZN(res); } static void gpu_opcode_abs(void) { - uint32 _Rn=Rn; - uint32 res; - - if (_Rn==0x80000000) - { - set_flag_n(1); - } +#ifdef GPU_DIS_ABS + WriteLog("%06X: ABS R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif + gpu_flag_c = RN >> 31; + if (RN == 0x80000000) + //Is 0x80000000 a positive number? If so, then we need to set C to 0 as well! + gpu_flag_n = 1, gpu_flag_z = 0; else { - gpu_flag_c = ((_Rn&0x80000000)>>31); - res= Rn = (((int32)_Rn)<0) ? -_Rn : _Rn; - reset_flag_n(); - set_flag_z(res); + if (gpu_flag_c) + RN = -RN; + gpu_flag_n = 0; SET_FLAG_Z(RN); } +#ifdef GPU_DIS_ABS + WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif } -static void gpu_opcode_div(void) +static void gpu_opcode_div(void) // RN / RM { - uint32 _Rm=Rm; - uint32 _Rn=Rn; +#ifdef GPU_DIS_DIV + WriteLog("%06X: DIV R%02u, R%02u (%s) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, (gpu_div_control & 0x01 ? "16.16" : "32"), gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif +// NOTE: remainder is NOT calculated correctly here! +// The original tried to get it right by checking to see if the +// remainder was negative, but that's too late... +// The code there should do it now, but I'm not 100% sure... - if (_Rm) + if (RM) + { + if (gpu_div_control & 0x01) // 16.16 division + { + RN = ((UINT64)RN << 16) / RM; + gpu_remain = ((UINT64)RN << 16) % RM; + } + else + { + RN = RN / RM; + gpu_remain = RN % RM; + } + + if ((gpu_remain - RM) & 0x80000000) // If the result would have been negative... + gpu_remain -= RM; // Then make it negative! + } + else + RN = 0xFFFFFFFF; + +/* uint32 _RM=RM; + uint32 _RN=RN; + + if (_RM) { if (gpu_div_control & 1) { - gpu_remain = (((uint64)_Rn) << 16) % _Rm; + gpu_remain = (((uint64)_RN) << 16) % _RM; if (gpu_remain&0x80000000) - gpu_remain-=_Rm; - Rn = (((uint64)_Rn) << 16) / _Rm; + gpu_remain-=_RM; + RN = (((uint64)_RN) << 16) / _RM; } else { - gpu_remain = _Rn % _Rm; + gpu_remain = _RN % _RM; if (gpu_remain&0x80000000) - gpu_remain-=_Rm; - Rn/=_Rm; + gpu_remain-=_RM; + RN/=_RM; } } else - Rn=0xffffffff; + RN=0xffffffff;*/ +#ifdef GPU_DIS_DIV + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] Remainder: %08X\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN, gpu_remain); +#endif } static void gpu_opcode_imultn(void) { - uint32 res = (int32)((int16)Rn * (int16)Rm); + uint32 res = (int32)((int16)RN * (int16)RM); gpu_acc = (int32)res; - set_flag_z(res); - set_flag_n(res); + SET_FLAG_Z(res); + SET_FLAG_N(res); } static void gpu_opcode_neg(void) { - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -{ -/* int dreg = jaguar.op & 31; - UINT32 r2 = jaguar.r[dreg]; - UINT32 res = -r2; - jaguar.r[dreg] = res; - CLR_ZNC; SET_ZNC_SUB(0,r2,res);*/ - UINT32 res = -Rn; - CLR_ZNC; SET_ZNC_SUB(0, Rn, res); - Rn = res; - 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( - "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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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; + UINT32 res = -RN; + SET_ZNC_SUB(0, RN, res); + RN = res; } static void gpu_opcode_shlq(void) { - uint32 shift=(32-gpu_convert_zero[imm_1]); - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY /* int dreg = jaguar.op & 31; INT32 r1 = convert_zero[(jaguar.op >> 5) & 31]; UINT32 r2 = jaguar.r[dreg]; UINT32 res = r2 << (32 - r1); jaguar.r[dreg] = res; CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;*/ -{ - INT32 r1 = gpu_convert_zero[imm_1]; - UINT32 res = Rn << (32 - r1); - CLR_ZNC; SET_ZN(res); gpu_flag_c = (Rn >> 31) & 1; - Rn = res; - 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\ - 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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY - -#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 - } + +#ifdef GPU_DIS_SHLQ + WriteLog("%06X: SHLQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, 32 - IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif +// Was a bug here... +// (Look at Aaron's code: If r1 = 32, then 32 - 32 = 0 which is wrong!) + INT32 r1 = 32 - IMM_1; + UINT32 res = RN << r1; + SET_ZN(res); gpu_flag_c = (RN >> 31) & 1; + RN = res; +#ifdef GPU_DIS_SHLQ + WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); #endif - Rn=res; } static void gpu_opcode_shrq(void) { - uint32 shift=gpu_convert_zero[imm_1]; - uint32 _Rn=Rn; - - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY /* int dreg = jaguar.op & 31; INT32 r1 = convert_zero[(jaguar.op >> 5) & 31]; UINT32 r2 = jaguar.r[dreg]; UINT32 res = r2 >> r1; jaguar.r[dreg] = res; CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;*/ -{ - INT32 r1 = gpu_convert_zero[imm_1]; - UINT32 res = Rn >> r1; - CLR_ZNC; SET_ZN(res); gpu_flag_c = Rn & 1; - Rn = res; - 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 $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 // #ifdef __GCCWIN32__ -#endif // #ifndef USE_ASSEMBLY -#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 - } +#ifdef GPU_DIS_SHRQ + WriteLog("%06X: SHRQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif + INT32 r1 = gpu_convert_zero[IMM_1]; + UINT32 res = RN >> r1; + SET_ZN(res); gpu_flag_c = RN & 1; + RN = res; +#ifdef GPU_DIS_SHRQ + WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); #endif - Rn=res; } static void gpu_opcode_ror(void) { - uint32 shift=Rm; - uint32 _Rn=Rn; - uint32 res; -#ifdef __PORT__ -#ifndef USE_ASSEMBLY -//#ifndef __PORT__ // For testing... /* int dreg = jaguar.op & 31; UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31] & 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 = Rm & 0x1F; - UINT32 res = (Rn >> r1) | (Rn << (32 - r1)); - CLR_ZNC; SET_ZN(res); gpu_flag_c = (Rn >> 31) & 1; - Rn = res; - 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 - } +#ifdef GPU_DIS_ROR + WriteLog("%06X: ROR R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif + UINT32 r1 = RM & 0x1F; + UINT32 res = (RN >> r1) | (RN << (32 - r1)); + SET_ZN(res); gpu_flag_c = (RN >> 31) & 1; + RN = res; +#ifdef GPU_DIS_ROR + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #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; + +#ifdef GPU_DIS_RORQ + WriteLog("%06X: RORQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif + 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; + RN = res; + SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01; +#ifdef GPU_DIS_RORQ + WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif } -#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 +static void gpu_opcode_sha(void) +{ +/* int dreg = jaguar.op & 31; + INT32 r1 = (INT32)jaguar.r[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res; -#else - __asm + CLR_ZNC; + if (r1 < 0) { - 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 + res = (r1 <= -32) ? 0 : (r2 << -r1); + jaguar.FLAGS |= (r2 >> 30) & 2; } -#endif // #ifdef __PORT__ - Rn = res; -} + else + { + res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1); + jaguar.FLAGS |= (r2 << 1) & 2; + } + jaguar.r[dreg] = res; + SET_ZN(res);*/ -static void gpu_opcode_sha(void) -{ - int32 sRm=(int32)Rm; - uint32 _Rn=Rn; +#ifdef GPU_DIS_SHA + WriteLog("%06X: SHA R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif + UINT32 res; + + if ((INT32)RM < 0) + { + res = ((INT32)RM <= -32) ? 0 : (RN << -(INT32)RM); + gpu_flag_c = RN >> 31; + } + else + { + res = ((INT32)RM >= 32) ? ((INT32)RN >> 31) : ((INT32)RN >> (INT32)RM); + gpu_flag_c = RN & 0x01; + } + RN = res; + SET_ZN(res); +#ifdef GPU_DIS_SHA + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif - if (sRm<0) +/* int32 sRM=(int32)RM; + uint32 _RN=RN; + + if (sRM<0) { - uint32 shift=-sRm; + uint32 shift=-sRM; if (shift>=32) shift=32; - gpu_flag_c=(_Rn&0x80000000)>>31; + gpu_flag_c=(_RN&0x80000000)>>31; while (shift) { - _Rn<<=1; + _RN<<=1; shift--; } } else { - uint32 shift=sRm; + uint32 shift=sRM; if (shift>=32) shift=32; - gpu_flag_c=_Rn&0x1; + gpu_flag_c=_RN&0x1; while (shift) { - _Rn=((int32)_Rn)>>1; + _RN=((int32)_RN)>>1; shift--; } } - Rn=_Rn; - set_flag_z(_Rn); - set_flag_n(_Rn); + 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; +/* int dreg = jaguar.op & 31; + INT32 r1 = convert_zero[(jaguar.op >> 5) & 31]; + UINT32 r2 = jaguar.r[dreg]; + UINT32 res = (INT32)r2 >> r1; + jaguar.r[dreg] = res; + CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;*/ + +#ifdef GPU_DIS_SHARQ + WriteLog("%06X: SHARQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif + UINT32 res = (INT32)RN >> gpu_convert_zero[IMM_1]; + SET_ZN(res); gpu_flag_c = RN & 0x01; + RN = res; +#ifdef GPU_DIS_SHARQ + WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); +#endif - gpu_flag_c = (_Rn & 0x1); +//OLD: +/* uint32 shift = gpu_convert_zero[IMM_1]; + uint32 _RN = RN; + + gpu_flag_c = (_RN & 0x01); while (shift) { - _Rn=((int32)_Rn)>>1; + _RN = ((int32)_RN) >> 1; shift--; } - Rn=_Rn; - set_flag_z(_Rn); - set_flag_n(_Rn); + 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) +#ifdef GPU_DIS_SH + WriteLog("%06X: SH R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif + if (RM & 0x80000000) // Shift left { - uint32 shift=(-sRm); - if (shift>=32) shift=32; - gpu_flag_c=(_Rn&0x80000000)>>31; - while (shift) - { - _Rn<<=1; - shift--; - } + gpu_flag_c = RN >> 31; + RN = ((int32)RM <= -32 ? 0 : RN << -(int32)RM); } - else + else // Shift right { - uint32 shift=sRm; - if (shift>=32) shift=32; - gpu_flag_c=_Rn&0x1; - while (shift) - { - _Rn>>=1; - shift--; - } + gpu_flag_c = RN & 0x01; + RN = (RM >= 32 ? 0 : RN >> RM); } - Rn=_Rn; - set_flag_z(_Rn); - set_flag_n(_Rn); + SET_ZN(RN); +#ifdef GPU_DIS_SH + WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); +#endif } + +//Temporary: Testing only! +#include "gpu2.cpp" +#include "gpu3.cpp" diff --git a/src/gpu2.cpp b/src/gpu2.cpp new file mode 100644 index 0000000..9496b70 --- /dev/null +++ b/src/gpu2.cpp @@ -0,0 +1,897 @@ +// +// Alternate GPU core... Testing purposes only! +// + +//#include "gpu.h" + +// Random stuff from GPU.CPP + +/*static uint8 * gpu_ram_8; +extern 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, gpu_flag_n, gpu_flag_c; +static uint8 gpu_alternate_flag_z, gpu_alternate_flag_n, 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;*/ + +// + +const INT32 qtable[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 }; + +const 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 }; + +const UINT8 gpu_opcode_times[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, 6, 6, 4, 6, 6, 6, 1, 1, 1, + 1, 2, 2, 2, 1, 1,20, 3, 3, 1, 6, 6, 2, 2, 3, 3 }; + +UINT8 jump_condition[32][8]; + +void gpu2_init(void) +{ + memset(jump_condition, 0, 32 * 8 * sizeof(UINT8)); + + for(int j=0; j<32; j++) + { + for(int i=0; i<8; i++) + { + UINT8 r = 1; + if(j & 0x1) { + if(i & 0x1) + r = 0; + } + if(j & 0x2) { + if(!(i & 0x1)) + r = 0; + } + if(j & 0x4) { + if(i & (0x2 << (j >> 4))) + r = 0; + } + if(j & 0x8) { + if(!(i & (0x2 << (j >> 4)))) + r = 0; + } + jump_condition[j][i] = r; + } + } +} + +// case 22: // ABS +void opcode_abs(void) +{ + int d = RN; + if(d & 0x80000000) { + d = abs(d); + gpu_flag_c = 1; + } else { + gpu_flag_c = 0; + } + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = 0; +} + +// case 0: // ADD +void opcode_add(void) +{ + int s = RM; + int d = RN; + INT64 r = s + d; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 1: // ADDC +void opcode_addc(void) +{ + int s = RM; + int d = RN; + int c = gpu_flag_c; + INT64 r = s + d + c; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 2: // ADDQ +void opcode_addq(void) +{ + int s = qtable[IMM_1]; + int d = RN; + INT64 r = s + d; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 3: // ADDQT +void opcode_addqt(void) +{ + RN += qtable[IMM_1]; +} +// break; +// case 9: // AND +void opcode_and(void) +{ + RN &= RM; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 15: // BLCR +void opcode_bclr(void) +{ + RN &= ~(1 << IMM_1); + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 14: // BSET +void opcode_bset(void) +{ + RN |= 1 << IMM_1; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 13: // BTST +void opcode_btst(void) +{ + gpu_flag_z = RN & (1 << IMM_1) ? 0 : 1; +} +// break; +// case 30: // CMP +void opcode_cmp(void) +{ + int s = RM; + int d = RN; + gpu_flag_c = (unsigned int)d < (unsigned int)s; + d -= s; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 31: // CMPQ +void opcode_cmpq(void) +{ + int s = sqtable[IMM_1]; + int d = RN; + gpu_flag_c = (unsigned int)d < (unsigned int)s; + d -= s; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 21: // DIV +void opcode_div(void) +{ + if(RM != 0) { + if(gpu_div_control == 0) { + UINT32 q = RN; + UINT32 d = RM; + UINT32 r = q / d; + UINT32 r2 = q % d; + RN = r; + gpu_remain = r2; + } else { + UINT64 q = (UINT64)(RN)<<16; + UINT64 d = (UINT64)(RM); + UINT32 r = (UINT64)(q / d); + UINT32 r2 = (UINT64)(q % d); + RN = r; + gpu_remain = r2; + } + } +} +// break; +// case 20: // IMACN +void opcode_imacn(void) +{ + short s = RM; + short d = RN; + int r = s * d; + gpu_acc += r; +} +// break; +// case 17: // IMULT +void opcode_imult(void) +{ + short s = RM; + short d = RN; + int r = s * d; + RN = r; + gpu_flag_z = r == 0 ? 1 : 0; + gpu_flag_n = r & 0x80000000 ? 1 : 0; +} +// break; +// case 18: // IMULTN +void opcode_imultn(void) +{ + short s = RM; + short d = RN; + int r = s * d; + gpu_acc = r; + gpu_flag_z = r == 0 ? 1 : 0; + gpu_flag_n = r & 0x80000000 ? 1 : 0; +} +// break; +// case 53: // JR; +void opcode_jr(void) +{ + UINT32 dw = (gpu_flag_z & 0x1) | ((gpu_flag_n & 0x1) << 2) | ((gpu_flag_c & 0x1) << 1); + if (jump_condition[IMM_2][dw]) + { +if (gpu_start_log) + fprintf(log_get(), " --> JR: Branch taken. "); + signed int offset = IMM_1 & 0x10 ? (0xFFFFFFF0 | (IMM_1 & 0xF)) : (IMM_1 & 0xF); + UINT32 delayed_jump_address = gpu_pc + 2 + (offset * 2); +// delayed_jump = 1; + gpu_pc += 2; + gpu_exec(1); +// gpu_pc = delayed_jump_address; + gpu_pc = delayed_jump_address - 2; + } +} +// break; +// case 52: // JUMP +void opcode_jump(void) +{ + UINT32 dw = (gpu_flag_z & 0x1) | ((gpu_flag_n & 0x1) << 2) | ((gpu_flag_c & 0x1) << 1); + if (jump_condition[IMM_2][dw]) + { +if (gpu_start_log) + fprintf(log_get(), " --> JUMP: Branch taken. "); + UINT32 delayed_jump_address = RM & 0xFFFFFE; +// delayed_jump = 1; + gpu_pc += 2; + gpu_exec(1); +// gpu_pc = delayed_jump_address; + gpu_pc = delayed_jump_address - 2; + } +} +// break; +// case 41: // LOAD +void opcode_load(void) +{ + UINT32 address = RM; + if(address >= 0xF03000 && address < 0xF04000) { +// RN = _rotl(*(UINT32*)(&MEM[address]),16); + RN = gpu_long_read(address); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16); + RN = gpu_long_read(address-0x8000); + } else { +// RN = ReadMem32(address); + RN = jaguar_long_read(address); + } +} +// break; +// case 43: // LOAD (R14+m) +void opcode_load_r14_indexed(void) +{ + UINT32 address = gpu_reg[14] + (qtable[IMM_1] << 2); + if(address >= 0xF03000 && address < 0xF04000) { +// RN = _rotl(*(UINT32*)(&MEM[address]),16); + RN = gpu_long_read(address); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16); + RN = gpu_long_read(address-0x8000); + } else { +// RN = ReadMem32(address); + RN = jaguar_long_read(address); + } +} +// break; +// case 44: // LOAD (R15+m) +void opcode_load_r15_indexed(void) +{ + UINT32 address = gpu_reg[15] + (qtable[IMM_1] << 2); + if(address >= 0xF03000 && address < 0xF04000) { +// RN = _rotl(*(UINT32*)(&MEM[address]),16); + RN = gpu_long_read(address); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16); + RN = gpu_long_read(address-0x8000); + } else { +// RN = ReadMem32(address); + RN = jaguar_long_read(address); + } +} +// break; +// case 58: // LOAD (R14+Rm) +void opcode_load_r14_ri(void) +{ + UINT32 address = gpu_reg[14] + RM; + if(address >= 0xF03000 && address < 0xF04000) { +// RN = _rotl(*(UINT32*)(&MEM[address]),16); + RN = gpu_long_read(address); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16); + RN = gpu_long_read(address-0x8000); + } else { +// RN = ReadMem32(address); + RN = jaguar_long_read(address); + } +} +// break; +// case 59: // LOAD (R15+Rm) +void opcode_load_r15_ri(void) +{ + UINT32 address = gpu_reg[15] + RM; + if(address >= 0xF03000 && address < 0xF04000) { +// RN = _rotl(*(UINT32*)(&MEM[address]),16); + RN = gpu_long_read(address); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16); + RN = gpu_long_read(address-0x8000); + } else { +// RN = ReadMem32(address); + RN = jaguar_long_read(address); + } +} +// break; +// case 39: // LOADB +void opcode_loadb(void) +{ + if(RM >= 0xF03000 && RM < 0xF04000) { +// RN = ReadMem32(RM); + RN = gpu_long_read(RM); + } else { +// RN = ReadMem8(RM); + RN = jaguar_byte_read(RM); + } +} +// break; +// case 40: // LOADW +void opcode_loadw(void) +{ + if(RM >= 0xF03000 && RM < 0xF04000) { +// RN = ReadMem32(RM); + RN = gpu_long_read(RM); + } else { +// RN = ReadMem16(RM); + RN = jaguar_word_read(RM); + } +} +// break; +// case 42: // LOADP +void opcode_loadp(void) +{ + if(RM >= 0xF03000 && RM < 0xF04000) { +// RN = ReadMem32(RM); + RN = gpu_long_read(RM); + } else { +// RN = ReadMem32(RM); +// gpu_hidata = ReadMem32(RM+4); + RN = gpu_long_read(RM); + gpu_hidata = gpu_long_read(RM + 4); + } +} +// break; +// case 34: // MOVE +void opcode_move(void) +{ + RN = RM; +} +// break; +// case 51: // MOVE PC,Rn +void opcode_move_pc(void) +{ + RN = gpu_pc; +} +// break; +// case 37: // MOVEFA +void opcode_movefa(void) +{ + RN = gpu_alternate_reg[IMM_1]; +} +// break; +// case 38: // MOVEI +void opcode_movei(void) +{ + // This instruction is followed by 32-bit value in LSW / MSW format... +// RN = (uint32)gpu_word_read(gpu_pc) | ((uint32)gpu_word_read(gpu_pc + 2) << 16); +// gpu_pc += 4; +// RN = _rotl(*(UINT32*)(&MEM[address]),16); +// RN = *(UINT32*)(&MEM[gpu_pc+2]); + RN = _rotl(gpu_long_read(gpu_pc + 2), 16); + gpu_pc += 4; +} +// break; +// case 35: // MOVEQ +void opcode_moveq(void) +{ + RN = IMM_1; +} +// break; +// case 36: // MOVETA +void opcode_moveta(void) +{ + gpu_alternate_reg[IMM_2] = RM; +} +// break; +// case 55: // MTOI +void opcode_mtoi(void) +{ + int d = RN & 0x7FFFFF; + if(RN & 0x80000000) { + d |= 0xFF800000; + } + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 16: // MULT +void opcode_mult(void) +{ + unsigned short s = RM; + unsigned short d = RN; + int r = s * d; + RN = r; + gpu_flag_z = r == 0 ? 1 : 0; + gpu_flag_n = r & 0x80000000 ? 1 : 0; +} +// break; +// case 54: // MMULT +void opcode_mmult(void) +{ + int size = gpu_matrix_control & 0xF; + int address = gpu_pointer_to_matrix; + int add; + if (gpu_matrix_control & 0x10) + add = size * 4; + else + add = 4; + int result = 0; + for(int i=0; i>1)] >> 16; + else + r = (gpu_alternate_reg[IMM_1+(i>>1)] & 0xFFFF); + result += (int)(r * m); +/* int mult = r*m; + __asm { + mov eax,[result] + mov edx,[mult] + add eax,edx + setc [gpu_flag_c] + mov [result],eax + }*/ + + address += add; + } + RN = result; + gpu_flag_n = (result < 0) ? 1 : 0; + gpu_flag_z = (result == 0) ? 1 : 0; +} +// break; +// case 8: // NEG +void opcode_neg(void) +{ + int s = 0; + int d = RN; + gpu_flag_c = d - s < d; + d = s - d; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 57: // NOP +void opcode_nop(void) +{ +} +// break; +// case 56: // NORMI +void opcode_normi(void) +{ + /*unsigned int d = RN; + int r = 0; + while ((d & 0xffc00000) == 0) + { + d <<= 1; + r--; + } + while ((d & 0xff800000) != 0) + { + d >>= 1; + r++; + } + RN = r; + gpu_flag_z = r == 0 ? 1 : 0; + gpu_flag_n = r & 0x80000000 ? 1 : 0;*/ + RN = 0; +} +// break; +// case 12: // NOT +void opcode_not(void) +{ + int d = RN; + d ^= 0xFFFFFFFF; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 10: // OR +void opcode_or(void) +{ + int s = RM; + int d = RN; + d |= s; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 63: // PACK / UNPACK +void opcode_pack(void) +{ + if (IMM_1 == 0) + { + int c1 = (RN & 0x3C00000) >> 10; + int c2 = (RN & 0x1E000) >> 5; + int y = (RN & 0xFF); + RN = c1 | c2 | y; + } + else + { + int c1 = (RN & 0xF000) << 10; + int c2 = (RN & 0xF00) << 5; + int y = (RN & 0xFF); + RN = c1 | c2 | y; + } +} +// break; +// case 19: // RESMAC +void opcode_resmac(void) +{ + RN = gpu_acc; +} +// break; +// case 28: // ROR +void opcode_ror(void) +{ + unsigned int d = RN; + int shift = RM; + gpu_flag_c = d & 0x80000000 ? 1 : 0; + d = _rotr(d, shift); + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 29: // RORQ +void opcode_rorq(void) +{ + unsigned int d = RN; + int shift = qtable[IMM_1]; + gpu_flag_c = d & 0x80000000 ? 1 : 0; + d = _rotr(d, shift); + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 32: // SAT8 +void opcode_sat8(void) +{ + int d = RN; + if(d < 0) + d = 0; + if(d > 255) + d = 255; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = 0; +} +// break; +// case 33: // SAT16 +void opcode_sat16(void) +{ + int d = RN; + if(d < 0) + d = 0; + if(d > 65535) + d = 65535; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = 0; +} +// break; +// case 62: // SAT24 +void opcode_sat24(void) +{ + int d = RN; + if (d < 0) + d = 0; + if (d > 16777215) + d = 16777215; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = 0; +} +// break; +// case 23: // SH +void opcode_sh(void) +{ + int shift = RM; + if (shift & 0x80000000) + { + gpu_flag_c = RN & 0x80000000 ? 1 : 0; + UINT32 d = RN; + d <<= 0-shift; + RN = d; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; + } + else + { + gpu_flag_c = RN & 0x1 ? 1 : 0; + UINT32 d = RN; + d >>= shift; + RN = d; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; + } +} +// break; +// case 26: // SHA +void opcode_sha(void) +{ + int shift = RM; + if(shift & 0x80000000) { + gpu_flag_c = RN & 0x80000000 ? 1 : 0; + INT32 d = RN; + d <<= 0-shift; + RN = d; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; + } else { + gpu_flag_c = RN & 0x1 ? 1 : 0; + INT32 d = RN; + d >>= shift; + RN = d; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; + } +} +// break; +// case 27: // SHARQ +void opcode_sharq(void) +{ + INT32 d = RN; + int shift = qtable[IMM_1]; + gpu_flag_c = d & 0x1 ? 1 : 0; + d >>= shift; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 24: // SHLQ +void opcode_shlq(void) +{ + UINT32 d = RN; + int shift = 32 - IMM_1; + gpu_flag_c = d & 0x80000000 ? 1 : 0; + d <<= shift; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; + // case 25: // SHRQ +void opcode_shrq(void) +{ + UINT32 d = RN; + int shift = qtable[IMM_1]; + gpu_flag_c = d & 0x1 ? 1 : 0; + d >>= shift; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} +// break; +// case 47: // STORE +void opcode_store(void) +{ + UINT32 address = RM; + if(address >= 0xF03000 && address < 0xF04000) { +// *(UINT32*)(&MEM[address]) = _rotl(RN,16); + gpu_long_write(address, RN); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16); + gpu_long_write(address-0x8000, RN); + } else { +// WriteMem32(address,RN); + jaguar_long_write(address, RN); + } +} +// break; +// case 49: // STORE (R14+m) +void opcode_store_r14_indexed(void) +{ + UINT32 address = gpu_reg[14] + (qtable[IMM_1] << 2); + if(address >= 0xF03000 && address < 0xF04000) { +// *(UINT32*)(&MEM[address]) = _rotl(RN,16); + gpu_long_write(address, RN); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16); + gpu_long_write(address-0x8000, RN); + } else { +// WriteMem32(address,RN); + jaguar_long_write(address, RN); + } +} +// break; +// case 50: // STORE (R15+m) +void opcode_store_r15_indexed(void) +{ + UINT32 address = gpu_reg[15] + (qtable[IMM_1] << 2); + if(address >= 0xF03000 && address < 0xF04000) { +// *(UINT32*)(&MEM[address]) = _rotl(RN,16); + gpu_long_write(address, RN); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16); + gpu_long_write(address-0x8000, RN); + } else { +// WriteMem32(address,RN); + jaguar_long_write(address, RN); + } +} +// break; +// case 60: // STORE (R14+Rm) +void opcode_store_r14_ri(void) +{ + UINT32 address = gpu_reg[14] + RM; + if(address >= 0xF03000 && address < 0xF04000) { +// *(UINT32*)(&MEM[address]) = _rotl(RN,16); + gpu_long_write(address, RN); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16); + gpu_long_write(address-0x8000, RN); + } else { +// WriteMem32(address,RN); + jaguar_long_write(address, RN); + } +} +// break; +// case 61: // STORE (R15+Rm) +void opcode_store_r15_ri(void) +{ + UINT32 address = gpu_reg[15] + RM; + if(address >= 0xF03000 && address < 0xF04000) { +// *(UINT32*)(&MEM[address]) = _rotl(RN,16); + gpu_long_write(address, RN); + } else if(address >= 0xF0B000 && address < 0xF0C000) { +// *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16); + gpu_long_write(address-0x8000, RN); + } else { +// WriteMem32(address,RN); + jaguar_long_write(address, RN); + } +} +// break; +// case 45: // STOREB +void opcode_storeb(void) +{ + if(RM>0xF03000 && RM<0xF04000) { +// WriteMem32(RM,RN); + gpu_long_write(RM, RN); + } else { +// WriteMem8(RM,(UINT8)RN); + jaguar_byte_write(RM, (UINT8)RN); + } +} +// break; +// case 46: // STOREW +void opcode_storew(void) +{ + if(RM>0xF03000 && RM<0xF04000) { +// WriteMem32(RM,RN); + gpu_long_write(RM, RN); + } else { +// WriteMem16(RM,(WORD)RN); + jaguar_word_write(RM, (UINT16)RN); + } +} +// break; +// case 48: // STOREP +void opcode_storep(void) +{ + if (RM>0xF03000 && RM<0xF04000) + { +// WriteMem32(RM,RN); + gpu_long_write(RM, RN); + } + else + { +// WriteMem32(RM,RN); +// WriteMem32(RM+4,gpu_hidata); + jaguar_long_write(RM, RN); + jaguar_long_write(RM + 4, gpu_hidata); + } +} +// break; +// case 4: // SUB +void opcode_sub(void) +{ + int s = RM; + int d = RN; + INT64 r = d - s; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 5: // SUBC +void opcode_subc(void) +{ + int s = RM; + int d = RN; + int c = gpu_flag_c; + INT64 r = d - s - c; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 6: // SUBQ +void opcode_subq(void) +{ + int s = qtable[IMM_1]; + int d = RN; + INT64 r = d - s; + gpu_flag_c = r & 0x100000000 ? 1 : 0; + RN = r; + gpu_flag_z = RN == 0 ? 1 : 0; + gpu_flag_n = RN & 0x80000000 ? 1 : 0; +} +// break; +// case 7: // SUBQT +void opcode_subqt(void) +{ + RN -= qtable[IMM_1]; +} +// break; +// case 11: // XOR +void opcode_xor(void) +{ + int s = RM; + int d = RN; + d ^= s; + RN = d; + gpu_flag_z = d == 0 ? 1 : 0; + gpu_flag_n = d & 0x80000000 ? 1 : 0; +} diff --git a/src/gpu3.cpp b/src/gpu3.cpp new file mode 100644 index 0000000..c7a9065 --- /dev/null +++ b/src/gpu3.cpp @@ -0,0 +1,762 @@ +// +// Aaron Giles GPU core +// + +static UINT8 * condition_table = NULL; +static UINT16 * mirror_table = NULL; +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 }; + +// Initialization + +void gpu3_init(void) +{ + 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); + + /* allocate the condition table */ + 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; + } +} + +/*################################################################################################### +** OPCODES +**#################################################################################################*/ + +void abs_rn(void) +{ + int dreg = IMM_2; + UINT32 res = gpu_reg[dreg]; + CLR_ZNC; + if (res & 0x80000000) + { + gpu_reg[dreg] = res = -res; + gpu_flag_c = 1; + } + SET_Z(res); +} + +void add_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + 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 = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + 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_ADD(r2,r1,res);*/ +} + +void addqt_n_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 + r1; + gpu_reg[dreg] = res; +} + +void and_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = IMM_1; + 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 = IMM_2; + UINT32 r1 = IMM_1; + 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 = IMM_1; + UINT32 r2 = gpu_reg[IMM_2]; + CLR_Z; gpu_flag_z = (~r2 >> r1) & 1; +} + +void cmp_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[IMM_2]; + UINT32 res = r2 - r1; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void cmpq_n_rn(void) +{ + UINT32 r1 = (INT8)(gpu_instruction >> 2) >> 3; + UINT32 r2 = gpu_reg[IMM_2]; + UINT32 res = r2 - r1; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void div_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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[IMM_1]; + UINT32 r2 = gpu_reg[IMM_2]; + gpu_acc += (INT64)((INT16)r1 * (INT16)r2); +// logerror("Unexpected IMACN instruction!\n"); +} + +void imult_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (INT16)r1 * (INT16)r2; + gpu_acc = (INT32)res; + CLR_ZN; SET_ZN(res); + +// gpu_instruction = ROPCODE(gpu_pc); + gpu_instruction = gpu_word_read(gpu_pc); + while ((gpu_instruction >> 10) == 20) + { + r1 = gpu_reg[IMM_1]; + r2 = gpu_reg[IMM_2]; + gpu_acc += (INT64)((INT16)r1 * (INT16)r2); + gpu_pc += 2; +// gpu_instruction = ROPCODE(gpu_pc); + gpu_instruction = gpu_word_read(gpu_pc); + } + if ((gpu_instruction >> 10) == 19) + { + gpu_pc += 2; + gpu_reg[IMM_2] = (UINT32)gpu_acc; + } +} + +void jr_cc_n(void) +{ +// if (CONDITION(IMM_2)) + uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; + if (BRANCH_CONDITION(IMM_2)) + { + INT32 r1 = (INT8)((gpu_instruction >> 2) & 0xf8) >> 2; + UINT32 newpc = gpu_pc + r1; +/* CALL_MAME_DEBUG; + gpu_instruction = ROPCODE(gpu_pc); + gpu_pc = newpc; + (*jaguar.table[gpu_instruction >> 10])(); + + jaguar_icount -= 3; // 3 wait states guaranteed*/ + gpu_exec(1); + gpu_pc = newpc; + } +} + +void jump_cc_rn(void) +{ +// if (CONDITION(IMM_2)) + uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; + if (BRANCH_CONDITION(IMM_2)) + { + UINT8 reg = IMM_1; + + // special kludge for risky code in the cojag DSP interrupt handlers +/* UINT32 newpc = (jaguar_icount == bankswitch_icount) ? gpu_alternate_reg[reg] : gpu_reg[reg]; + CALL_MAME_DEBUG; + gpu_instruction = ROPCODE(gpu_pc); + gpu_pc = newpc; + (*jaguar.table[gpu_instruction >> 10])(); + + jaguar_icount -= 3; // 3 wait states guaranteed*/ + UINT32 newpc = gpu_reg[reg]; + gpu_exec(1); + gpu_pc = newpc; + } +} + +void load_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// gpu_reg[IMM_2] = READLONG(r1); + gpu_reg[IMM_2] = gpu_long_read(r1); +} + +void load_r14n_rn(void) +{ + UINT32 r1 = convert_zero[IMM_1]; +// gpu_reg[IMM_2] = READLONG(gpu_reg[14] + 4 * r1); + gpu_reg[IMM_2] = gpu_long_read(gpu_reg[14] + 4 * r1); +} + +void load_r15n_rn(void) +{ + UINT32 r1 = convert_zero[IMM_1]; +// gpu_reg[IMM_2] = READLONG(gpu_reg[15] + 4 * r1); + gpu_reg[IMM_2] = gpu_long_read(gpu_reg[15] + 4 * r1); +} + +void load_r14rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// gpu_reg[IMM_2] = READLONG(gpu_reg[14] + r1); + gpu_reg[IMM_2] = gpu_long_read(gpu_reg[14] + r1); +} + +void load_r15rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// gpu_reg[IMM_2] = READLONG(gpu_reg[15] + r1); + gpu_reg[IMM_2] = gpu_long_read(gpu_reg[15] + r1); +} + +void loadb_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// gpu_reg[IMM_2] = READBYTE(r1); + gpu_reg[IMM_2] = gpu_byte_read(r1); +} + +void loadw_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// gpu_reg[IMM_2] = READWORD(r1); + gpu_reg[IMM_2] = gpu_word_read(r1); +} + +void loadp_rn_rn(void) /* GPU only */ +{ + UINT32 r1 = gpu_reg[IMM_1]; + // Is this a bug? I'm sure he meant to read DWORDs here, not just WORDs... +// gpu_hidata = READWORD(r1); +// gpu_reg[IMM_2] = READWORD(r1+4); + gpu_hidata = gpu_long_read(r1); + gpu_reg[IMM_2] = gpu_long_read(r1+4); +} + +void mirror_rn(void) /* DSP only */ +{ +/* int dreg = IMM_2; + 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 = IMM_1; + int dreg = IMM_2; + 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)READWORD(addr); + 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)READWORD(addr); + 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[IMM_2] = gpu_reg[IMM_1]; +} + +void move_pc_rn(void) +{ +// gpu_reg[IMM_2] = jaguar.ppc; + gpu_reg[IMM_2] = gpu_pc - 2; +} + +void movefa_rn_rn(void) +{ + gpu_reg[IMM_2] = gpu_alternate_reg[IMM_1]; +} + +void movei_n_rn(void) +{ +// UINT32 res = ROPCODE(gpu_pc) | (ROPCODE(gpu_pc + 2) << 16); + UINT32 res = gpu_word_read(gpu_pc) | (gpu_word_read(gpu_pc + 2) << 16); + gpu_pc += 4; + gpu_reg[IMM_2] = res; +} + +void moveq_n_rn(void) +{ + gpu_reg[IMM_2] = IMM_1; +} + +void moveta_rn_rn(void) +{ + gpu_alternate_reg[IMM_2] = gpu_reg[IMM_1]; +} + +void mtoi_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; + gpu_reg[IMM_2] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff); +} + +void mult_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + 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[IMM_1]; + UINT32 res = 0; + while ((r1 & 0xffc00000) == 0) + { + r1 <<= 1; + res--; + } + while ((r1 & 0xff800000) != 0) + { + r1 >>= 1; + res++; + } + gpu_reg[IMM_2] = res; + CLR_ZN; SET_ZN(res); +} + +void not_rn(void) +{ + int dreg = IMM_2; + UINT32 res = ~gpu_reg[dreg]; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} + +void or_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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[IMM_2] = (UINT32)gpu_acc; +} + +void ror_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1] & 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 >> 31) & 0x01; +} + +void rorq_n_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + 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 >> 31) & 0x01; +} + +void sat8_rn(void) /* GPU only */ +{ + int dreg = IMM_2; + 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 = IMM_2; + 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 = IMM_2; + 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 = IMM_2; + 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 = IMM_2; + 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 = IMM_2; + INT32 r1 = (INT32)gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res; + + CLR_ZNC; + if (r1 < 0) + { + res = (r1 <= -32) ? 0 : (r2 << -r1); + gpu_flag_c = (r2 >> 31) & 0x01; + } + else + { + res = (r1 >= 32) ? 0 : (r2 >> r1); + gpu_flag_c = r2 & 0x01; + } + gpu_reg[dreg] = res; + SET_ZN(res); +} + +void sha_rn_rn(void) +{ + int dreg = IMM_2; + INT32 r1 = (INT32)gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res; + + CLR_ZNC; + if (r1 < 0) + { + res = (r1 <= -32) ? 0 : (r2 << -r1); + gpu_flag_c = (r2 >> 31) & 0x01; + } + else + { + res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1); +// jaguar.FLAGS |= (r2 << 1) & 2; + gpu_flag_c = r2 & 0x01; + } + gpu_reg[dreg] = res; + SET_ZN(res); +} + +void sharq_n_rn(void) +{ + int dreg = IMM_2; + INT32 r1 = convert_zero[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = (INT32)r2 >> r1; + gpu_reg[dreg] = res; +// CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2; + CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01; +} + +void shlq_n_rn(void) +{ + int dreg = IMM_2; + INT32 r1 = convert_zero[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 << (32 - r1); + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01; +} + +void shrq_n_rn(void) +{ + int dreg = IMM_2; + INT32 r1 = convert_zero[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 >> r1; + gpu_reg[dreg] = res; +// CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2; + CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01; +} + +void store_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITELONG(r1, gpu_reg[IMM_2]); + gpu_long_write(r1, gpu_reg[IMM_2]); +} + +void store_rn_r14n(void) +{ + UINT32 r1 = convert_zero[IMM_1]; +// WRITELONG(gpu_reg[14] + r1 * 4, gpu_reg[IMM_2]); + gpu_long_write(gpu_reg[14] + r1 * 4, gpu_reg[IMM_2]); +} + +void store_rn_r15n(void) +{ + UINT32 r1 = convert_zero[IMM_1]; +// WRITELONG(gpu_reg[15] + r1 * 4, gpu_reg[IMM_2]); + gpu_long_write(gpu_reg[15] + r1 * 4, gpu_reg[IMM_2]); +} + +void store_rn_r14rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITELONG(gpu_reg[14] + r1, gpu_reg[IMM_2]); + gpu_long_write(gpu_reg[14] + r1, gpu_reg[IMM_2]); +} + +void store_rn_r15rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITELONG(gpu_reg[15] + r1, gpu_reg[IMM_2]); + gpu_long_write(gpu_reg[15] + r1, gpu_reg[IMM_2]); +} + +void storeb_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITEBYTE(r1, gpu_reg[IMM_2]); + gpu_byte_write(r1, gpu_reg[IMM_2]); +} + +void storew_rn_rn(void) +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITEWORD(r1, gpu_reg[IMM_2]); + gpu_word_write(r1, gpu_reg[IMM_2]); +} + +void storep_rn_rn(void) /* GPU only */ +{ + UINT32 r1 = gpu_reg[IMM_1]; +// WRITELONG(r1, gpu_hidata); +// WRITELONG(r1+4, gpu_reg[IMM_2]); + gpu_long_write(r1, gpu_hidata); + gpu_long_write(r1+4, gpu_reg[IMM_2]); +} + +void sub_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1; + gpu_reg[dreg] = res; + CLR_ZNC; SET_ZNC_SUB(r2,r1,res); +} + +void subc_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + 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 = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + 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 = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + 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 = IMM_2; + UINT32 r1 = convert_zero[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r2 - r1; + gpu_reg[dreg] = res; +} + +void xor_rn_rn(void) +{ + int dreg = IMM_2; + UINT32 r1 = gpu_reg[IMM_1]; + UINT32 r2 = gpu_reg[dreg]; + UINT32 res = r1 ^ r2; + gpu_reg[dreg] = res; + CLR_ZN; SET_ZN(res); +} diff --git a/src/gpu4.cpp b/src/gpu4.cpp new file mode 100644 index 0000000..d8daa08 --- /dev/null +++ b/src/gpu4.cpp @@ -0,0 +1,1540 @@ +#include "core.h" + +//#define DEBUG_GPU + +#define J_ALWAYS 0x00 +#define J_NZ 0x01 +#define J_Z 0x02 +#define J_NC 0x04 +#define J_NC_NZ 0x05 +#define J_NC_Z 0x06 +#define J_C 0x08 +#define J_C_NZ 0x09 +#define J_C_Z 0x0A +#define J_NN 0x14 +#define J_NN_NZ 0x15 +#define J_NN_Z 0x16 +#define J_N 0x18 +#define J_N_NZ 0x19 +#define J_N_Z 0x1A +#define J_NEVER 0x1F + + // Opcode Function Prototypes + + void G_ADD( void ); void G_ADDC( void ); + void G_ADDQ( void ); void G_ADDQT( void ); + void G_SUB( void ); void G_SUBC( void ); + void G_SUBQ( void ); void G_SUBQT( void ); + void G_NEG( void ); void G_AND( void ); + void G_OR( void ); void G_XOR( void ); + void G_NOT( void ); void G_BTST( void ); + void G_BSET( void ); void G_BCLR( void ); + void G_MULT( void ); void G_IMULT( void ); + void G_IMULTN( void ); void G_RESMAC( void ); + void G_IMACN( void ); void G_DIV( void ); + void G_ABS( void ); void G_SH( void ); + void G_SHLQ( void ); void G_SHRQ( void ); + void G_SHA( void ); void G_SHARQ( void ); + void G_ROR( void ); void G_RORQ( void ); + void G_CMP( void ); void G_CMPQ( void ); + void G_SAT8( void ); void G_SAT16( void ); + void G_MOVE( void ); void G_MOVEQ( void ); + void G_MOVETA( void ); void G_MOVEFA( void ); + void G_MOVEI( void ); void G_LOADB( void ); + void G_LOADW( void ); void G_LOAD( void ); + void G_LOADP( void ); void G_STORE_14I( void ); + void G_LOAD_14I( void ); void G_LOAD_15I( void ); + void G_STOREB( void ); void G_STOREW( void ); + void G_STORE( void ); void G_STOREP( void ); + void G_STORE_15I( void ); void G_MOVE_PC( void ); + void G_JUMP( void ); void G_JR( void ); + void G_MMULT( void ); void G_MTOI( void ); + void G_NORMI( void ); void G_NOP( void ); + void G_LOAD_14R( void ); void G_LOAD_15R( void ); + void G_STORE_14R( void ); void G_STORE_15R( void ); + void G_SAT24( void ); void G_PACK_UNPACK( void ); + + // Other Prototypes + + unsigned mem_readword( unsigned ); + unsigned mem_readbyte( unsigned ); + void mem_writeword( unsigned, unsigned ); + void mem_writebyte( unsigned, unsigned ); + + // CPU Cycles for Each GPU Opcode + + byte gpuCycles[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, 0, 6, 6, 2, 2, 3, 3 + + }; + + // GPU Opcode Function Table + + void (*gpuOp[64])()= { + G_ADD, G_ADDC, G_ADDQ, G_ADDQT, + G_SUB, G_SUBC, G_SUBQ, G_SUBQT, + G_NEG, G_AND, G_OR, G_XOR, + G_NOT, G_BTST, G_BSET, G_BCLR, + G_MULT, G_IMULT, G_IMULTN, G_RESMAC, + G_IMACN, G_DIV, G_ABS, G_SH, + G_SHLQ, G_SHRQ, G_SHA, G_SHARQ, + G_ROR, G_RORQ, G_CMP, G_CMPQ, + G_SAT8, G_SAT16, G_MOVE, G_MOVEQ, + G_MOVETA, G_MOVEFA, G_MOVEI, G_LOADB, + G_LOADW, G_LOAD, G_LOADP, G_LOAD_14I, + G_LOAD_15I, G_STOREB, G_STOREW, G_STORE, + G_STOREP, G_STORE_14I, G_STORE_15I, G_MOVE_PC, + G_JUMP, G_JR, G_MMULT, G_MTOI, + G_NORMI, G_NOP, G_LOAD_14R, G_LOAD_15R, + G_STORE_14R, G_STORE_15R, G_SAT24, G_PACK_UNPACK + }; + + GPUSTATE gst; // GPU State Information + dword GincPC; // PC Increment Flag + dword GjmpPC; // PC Jump gdstination + dword Gbranch; // Branch Flag + +#ifdef DEBUG_GPU + FILE *oo; +#endif +/* + sdword arb[32]; // GPU Active Register Bank + sdword srb[32]; // GPU Secondary Register Bank + dword acc; // Accumulator + dword pc; // Program Counter + dword src; // Source Register + dword dst; // Destination Register + BOOL z; // Zero Flag + BOOL n; // Negative Flag + BOOL c; // Carry Flag + dword ctrl; // GPU Control Word (0xF02114 RW) + BOOL div16; // 16.16 Division Flag (0xF0211C WO) + dword divrem; // Division Remainder (0xF0211C RO) +*/ + + dword gpc; // Program Counter + dword gsrc; // Instruction Word Source + dword gdst; // Instruction Word Destination + BOOL gz; // Zero Flag + BOOL gn; // Negative Flag + BOOL gc; // Carry Flag + + + // GPU Processor Emulation + + DWORD gpu_exec( LPVOID lpParam ) + { + dword iw; // Instruction Word + +#ifdef DEBUG_GPU + oo = fopen( "gpudbg.out", "w" ); + + { + FILE *f; + int i; + + f = fopen( "gpudump.bin", "wb" ); + for( i = 0x3000; i < 0x4000; i += 2 ) // Dump GPU RAM + { + fwrite( &st.tom[i+1], 1, 1, f ); + fwrite( &st.tom[i], 1, 1, f ); + } + fclose( f ); + } +#endif + + // Counter = InterruptPeriod; + + while( gst.gpuActive ) + { + if( gst.step ) // While Single Step Enabled + { + while( !gst.stepgo ) ; // Wait Until StepGo Issued + printf( " GPU Released for One Instruction (SINGLE STEP)\n" ); + } + + iw = mem_readword( gpc ); // Get Instruction Word + gsrc = (iw & 0x03E0) >> 5; // Get Source + gdst = (iw & 0x001F); // Get Destination + + gpuOp[iw >> 10](); // Jump to and Execute Opcode Routine + +#ifdef DEBUG_GPU + fflush( oo ); +#endif + + // Counter -= Cycles[Opcode]; + + // if( Counter <= 0 ) + // { + // /* Check for Interrupts and do Other Cyclic tasks here + // Counter += InterruptPeriod + // } + + switch( Gbranch ) // Increment Program Counter + { + case 2: // Next Instruction is the Branch Address + Gbranch = 0; + gpc = GjmpPC; + break; + + // A Branch Address was Stored in the Branch Program Counter. + // The Next Instruction is a PC + 4 (Case 0 is Executed). + // The Next Instruction is at the Branch Program Counter + + case 1: + Gbranch = 2; + case 0: // Normal Execution + switch( GincPC ) + { + case 1: // Opcode Used a 32-Bit Word + gpc += 6; + GincPC = 0; + break; + case 0: // Normal Execution + gpc += 2; + break; + } + break; + } + + if( gst.step ) // If Single Step Mode Enabled + { + gst.stepgo = 0; // Reset StepGo Flag + printf( " GPU Paused Until New SINGLE_GO (SINGLE STEP)\n" ); + } + } + + #ifdef DEBUG_GPU + fclose( oo ); + #endif + + return( TRUE ); + } + + void G_ABS( void ) + { + if( gst.arb[gdst] == 0x80000000 ) + gn = 1; + else + if( gst.arb[gdst] < 0 ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + neg eax + mov [ecx*4+gst.arb],eax + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = 0; + gc = 1; + } + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ABS R%i\t\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_ADD( void ) + { + __asm { + mov ecx,[gsrc] + mov edx,[ecx*4+gst.arb] + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + add eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc addend + mov ecx,0 + addend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ADD R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_ADDC( void ) + { + __asm { + clc + mov ecx,[gc] + jcxz addc + stc + addc: + mov ecx,[gsrc] + mov edx,[ecx*4+gst.arb] + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + adc eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc addcend + mov ecx,0 + addcend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ADDC R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_ADDQ( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + add eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc addqend + mov ecx,0 + addqend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ADDQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_ADDQT( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + add eax,edx + mov [ecx*4+gst.arb],eax + }; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ADDQT 0x%02X,R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_AND( void ) + { + gst.arb[gdst] &= gst.arb[gsrc]; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X AND R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_BCLR( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + btr eax,edx + mov [ecx*4+gst.arb],eax + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X BCLR 0x%04X,R%i\t\t\t " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gz, gn, gc ); + #endif + } + + void G_BSET( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + bts eax,edx + mov [ecx*4+gst.arb],eax + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X BSET 0x%04X,R%i\t\t\t " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gz, gn, gc ); + #endif + } + + void G_BTST( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov ecx,[gsrc] + bt eax,ecx + mov ecx,1 + jc btstend + mov ecx,0 + btstend: + mov [gz],ecx + }; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X BTST 0x%04X,R%i\t\t\t " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gz, gn, gc ); + #endif + } + + void G_CMP( void ) + { + sdword tmpW; + + __asm { + mov ecx,[gsrc] + mov edx,[ecx*4+gst.arb] + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + sub eax,edx + lahf + mov [tmpW],eax + }; + + gc = (tmpW & 0x0100) ? 1 : 0; + gz = (tmpW & 0x4000) ? 1 : 0; + gn = (tmpW & 0x8000) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X CMP R%i,R%i\t\t " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gz, gn, gc ); + #endif + } + + void G_CMPQ( void ) + { + sdword tmpW; + + __asm { + mov edx,[gsrc] + bt edx,4 + jnc cmpq + bts edx,31 + cmpq: + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + sub eax,edx + lahf + mov [tmpW],eax + }; + + gc = (tmpW & 0x0100) ? 1 : 0; + gz = (tmpW & 0x4000) ? 1 : 0; + gn = (tmpW & 0x8000) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X CMPQ 0x%02X,R%i\t\t " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gz, gn, gc ); + #endif*/ + } + + void G_DIV( void ) + { + if( gst.div16 ) + printf( "GPU DIVIDE 16.16 REQUIRED !!!!\n" ); + else + { + (dword)gst.arb[gdst] = (dword)gst.arb[gdst] / + (dword)gst.arb[gsrc]; + + gst.divrem = (dword)gst.arb[gdst] % (dword)gst.arb[gsrc]; + } + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X DIV R%i,R%i\t\tR%02i = 0x%08X ", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_IMACN( void ) + { + // Like IMULT but product is added to the previous arithmetic operation. + // Intended to be used after IMULTN. + + gst.acc += (sdword)((sword)gst.arb[gsrc] * + (sword)gst.arb[gdst] ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X IMACN R%i,R%i\t\tACC = 0x%08X\n", + gpc, gsrc, gdst, gst.acc ); + #endif + } + + void G_IMULT( void ) + { + gst.arb[gdst] = (sdword)((sword)gst.arb[gsrc] * + (sword)gst.arb[gdst] ); + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X IMULT R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_IMULTN( void ) + { + // Like IMULT but result not written back to gst.arb[gdst] + // but to an accumulator. Used as first part of multiply/accumulate group. + + gst.acc = (sdword)((sword)gst.arb[gsrc] * + (sword)gst.arb[gdst] ); + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X IMULTN R%i,R%i\t\tACC = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gst.acc, + gz, gn, gc ); + #endif + } + + void G_JR( void ) + { + if( gsrc >= 16 ) // Set Jump Direction + gsrc -= 32; + + GjmpPC = (gpc + 2) + (gsrc * 2); + + switch( gdst ) + { + case 0x00: // No Conditions + Gbranch = 1; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR 0x%08X\n", gpc, GjmpPC ); + #endif + break; + + case 0x01: // NE - Not Equal + if( !gz ) // Zero Flag Unset + Gbranch = 1; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR NE,0x%08X\n",gpc, GjmpPC ); + #endif + break; + + case 0x02: // EQ - Equal + if( gz) // Zero Flag Set + Gbranch = 1; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR EQ,0x%08X\n", gpc, GjmpPC ); + #endif + break; + + case 0x04: // Flag Selected Cleared to Jump + if( !gc ) Gbranch = 1; else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR CC,0x%08X\n", gpc, GjmpPC ); + #endif + break; + + case 0x08: // Flag Selected Set to Jump + if( gc ) Gbranch = 1; else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR CS,0x%08X\n", gpc, GjmpPC ); + #endif + break; + + case 0x14: + if( !gn ) Gbranch = 1; else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR NN,0x%08X\n", gpc, GjmpPC ); + #endif + break; + + case 0x18: + if( gn ) Gbranch = 1; else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JR N,0x%08X\n", gpc, GjmpPC ); + #endif + break; + + default: + #ifdef DEBUG_GPU + fprintf( oo, "Unknown JR Condition at 0x%08X\n", gpc ); + #endif + break; + + } + } + + void G_JUMP( void ) + { + GjmpPC = gst.arb[gsrc]; + + switch( gdst ) + { + case J_ALWAYS: + Gbranch = 1; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP (R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NZ: + if( !gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NZ,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_Z: + if( gz) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP Z,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NC: + if( !gc ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NC,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NC_NZ: + if( !gc && !gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NC_NZ,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NC_Z: + if( !gc && gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NC_Z,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_C: + if( gc ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP C,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_C_NZ: + if( gc && !gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP C_NZ,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_C_Z: + if( gc && gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP C_Z,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NN: + if( !gn ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NN,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NN_NZ: + if( !gn && !gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NN_NZ,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NN_Z: + if( !gn && gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NN_Z,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_N: + if( gn ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP N,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_N_NZ: + if( gn && !gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP N_NZ,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_N_Z: + if( gn && gz ) Gbranch = 1; + else Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP N_Z,(R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + case J_NEVER: + Gbranch = 0; + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X JUMP NEVER (R%02i) DEST = 0x%08X\n", + gpc, gsrc, GjmpPC ); + #endif + break; + + default: + #ifdef DEBUG_GPU + fprintf( oo, "Unknown JUMP Condition\n" ); + #endif + break; + } + } + + void G_LOAD( void ) + { + gst.arb[gdst] = mem_readword( gst.arb[gsrc] ) << 16; + gst.arb[gdst] |= mem_readword( gst.arb[gsrc] + 2 ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOAD (R%i),R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOAD_14I( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0E] + (gsrc * 4); + gst.arb[gdst] = mem_readword( tmpW ) << 16; + gst.arb[gdst] |= mem_readword( tmpW + 2 ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOAD (R14+%02i),R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOAD_15I( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0F] + (gsrc * 4); + gst.arb[gdst] = mem_readword( tmpW ) << 16; + gst.arb[gdst] |= mem_readword( tmpW + 2 ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOAD (R15+%02i),R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOAD_14R( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0E] + gst.arb[gsrc]; + gst.arb[gdst] = mem_readword( tmpW ) << 16; + gst.arb[gdst] |= mem_readword( tmpW + 2 ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOAD (R14+R%i),R%i\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOAD_15R( void ) + { + sdword tmpW; + + // NOTE: Manual seems to indicate that this opcode + // uses Register 14 as the base offset address. + + tmpW = gst.arb[0x0E] + gst.arb[gsrc]; + gst.arb[gdst] = mem_readword( tmpW ) << 16; + gst.arb[gdst] |= mem_readword( tmpW + 2 ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOAD (R15+R%i),R%i\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOADB( void ) + { + if( gst.arb[gsrc] >= 0xF03000 && gst.arb[gsrc] < 0xF04000 ) + { + gst.arb[gdst] = mem_readword( gst.arb[gsrc] ) << 16; + gst.arb[gdst] |= mem_readword( gst.arb[gsrc] + 2 ); + } + else + gst.arb[gdst] = mem_readbyte( gst.arb[gsrc] ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOADB (R%i),R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOADW( void ) + { + if( gst.arb[gsrc] >= 0xF03000 && gst.arb[gsrc] < 0xF04000 ) + { + gst.arb[gdst] = mem_readword( gst.arb[gsrc] ) << 16; + gst.arb[gdst] |= mem_readword( gst.arb[gsrc] + 2 ); + } + else + gst.arb[gdst] = mem_readword( gst.arb[gsrc] ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X LOADW (R%i),R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_LOADP( void ) + {/* + phr.hi = mem_readword( tolp ) << 16; + phr.hi |= mem_readword( tolp + 0x02 ); + phr.lo = mem_readword( tolp + 0x04 ) << 16; + phr.lo |= mem_readword( tolp + 0x06 ); +*/ + #ifdef DEBUG_GPU + fprintf( oo, "GPU - Unimplemented Opcode (LOADP)\n" ); + #endif + + gst.gpuActive = FALSE; + } + + void G_MMULT( void ) + { + #ifdef DEBUG_GPU + fprintf( oo, "GPU - Unimplemented Opcode (MMULT)\n" ); + #endif + gst.gpuActive = FALSE; + } + + void G_MOVE( void ) + { + gst.arb[gdst] = gst.arb[gsrc]; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVE R%i,R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_MOVE_PC( void ) + { + gst.arb[gdst] = gpc; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVE PC,R%i\t\tR%02i = 0x%08X\n", + gpc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_MOVEFA( void ) + { + gst.arb[gdst] = gst.srb[gsrc]; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVEFA R%i,R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_MOVEI( void ) + { + gst.arb[gdst] = mem_readword(gpc + 2); + gst.arb[gdst] |= mem_readword(gpc + 4) << 16; + + GincPC = 1; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVEI 0x%08X,R%i\tR%02i = 0x%08X\n", + gpc, gst.arb[gdst], gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_MOVEQ( void ) + { + gst.arb[gdst] = gsrc; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVEQ 0x%02X,R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_MOVETA( void ) + { + gst.srb[gdst] = gst.arb[gsrc]; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MOVETA R%i,R%i\t\tR%02i = 0x%08X(0)\n", + gpc, gsrc, gdst, gdst, gst.srb[gdst] ); + #endif + } + + void G_MTOI( void ) + { + #ifdef DEBUG_GPU + fprintf( oo, "GPU - Unimplemented Opcode (MTOI)\n" ); + #endif + gst.gpuActive = FALSE; + } + + void G_MULT( void ) + { + gst.arb[gdst] = (sdword)((word)gst.arb[gsrc] * + (word)gst.arb[gdst] ); + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X MULT R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_NEG( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + neg eax + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc negend + mov ecx,0 + negend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X NEG R%i\t\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_NOP( void ) + { + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X NOP\n", gpc ); + #endif + } + + void G_NORMI( void ) + { + #ifdef DEBUG_GPU + fprintf( oo, "GPU - Unimplemented Opcode (NORMI)\n" ); + #endif + gst.gpuActive = FALSE; + } + + void G_NOT( void ) // Fix donated by YaK + { + gst.arb[gdst] = gst.arb[gdst] ^ 0xFFFFFFFF; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X NOT R%i\t\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_OR( void ) + { + gst.arb[gdst] |= gst.arb[gsrc]; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X OR R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_PACK_UNPACK( void ) + { + dword tmpW; + + tmpW = gst.arb[gdst]; + + if( gsrc ) // UNPACK + { + gst.arb[gdst] = (tmpW & 0x000000FF); + gst.arb[gdst] |= (tmpW & 0x00000F00) << 5; + gst.arb[gdst] |= (tmpW & 0x0000F000) << 10; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X UNPACK R%i\t\t\tR%02i = 0x%08X\n", + gpc, gdst, gdst, gst.arb[gdst] ); + #endif + } + else // PACK + { + gst.arb[gdst] = (tmpW & 0x000000FF); + gst.arb[gdst] |= (tmpW & 0x0001E000) >> 5; + gst.arb[gdst] |= (tmpW & 0x03C00000) >> 10; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X PACK R%i\t\t\tR%02i = 0x%08X\n", + gpc, gdst, gdst, gst.arb[gdst] ); + #endif + } + } + + void G_RESMAC( void ) + { + // Write result register to Register Rn + // Used as last part of multiply/accumulate group. + + gst.arb[gdst] = gst.acc; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X RESMAC R%i\t\tR%02X = 0x%08X\n", + gpc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_ROR( void ) + { + gc = (gst.arb[gdst] >> 31) & 0x01; + + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + mov ecx,[edx*4+gst.arb] + and ecx,0x1F + ror eax,cl + mov ecx,[gdst] + mov [ecx*4+gst.arb],eax + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X ROR R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_RORQ( void ) + { + sdword tmpW; + + gc = (gst.arb[gdst] >> 31) & 0x01; + tmpW = gst.arb[gdst]; + + __asm { + mov eax,[tmpW] + mov ecx,[gsrc] + ror eax,cl + mov [tmpW],eax + }; + + gst.arb[gdst] = tmpW; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X RORQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_SAT8( void ) + { + if( gst.arb[gdst] < 0 ) gst.arb[gdst] =0x00000000; + if( gst.arb[gdst] > 255 ) gst.arb[gdst] =0x000000FF; + + gn = 0; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SAT8 R%02i\t\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_SAT16( void ) + { + if( gst.arb[gdst] < 0 ) gst.arb[gdst] =0x00000000; + if( gst.arb[gdst] > 65535 ) gst.arb[gdst] =0x0000FFFF; + + gn = 0; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SAT16 R%02i\t\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_SAT24( void ) + { + if( gst.arb[gdst] < 0 ) gst.arb[gdst] =0x00000000; + if( gst.arb[gdst] > 16777215 ) gst.arb[gdst] =0x00FFFFFF; + + gn = 0; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SAT24 R%02i\t\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_SH( void ) + { + sdword tmpW; + + // NOTE: Watch the values here carefully + + if( gst.arb[gsrc] >= 0 ) // Shift Right + { + gc = gst.arb[gdst] & 0x01; + tmpW = gst.arb[gsrc]; + __asm { + mov edx,[gdst] + mov eax,[edx*4+gst.arb] + mov ecx,[tmpW] + shr eax,cl + mov [edx*4+gst.arb],eax + }; + } + else // Shift Left + { + gc = (gst.arb[gdst] >> 31) & 0x01; + // Fix donated by YaK + tmpW = (0xFFFFFFFF - gst.arb[gsrc]) + 1; + __asm { + mov edx,[gdst] + mov eax,[edx*4+gst.arb] + mov ecx,[tmpW] + shl eax,cl + mov [edx*4+gst.arb],eax + }; + } + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SH R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif*/ + } + + void G_SHA( void ) + { + sdword tmpW; + + // NOTE: Watch the values here carefully + + if( gst.arb[gsrc] >= 0 ) // Shift Right + { + gc = gst.arb[gdst] & 0x01; + tmpW = gst.arb[gsrc]; + __asm { + mov edx,[gdst] + mov eax,[edx*4+gst.arb] + mov ecx,[tmpW] + sar eax,cl + mov [edx*4+gst.arb],eax + }; + } + else // Shift Left + { + gc = (gst.arb[gdst] >> 31) & 0x01; + // Fix donated by YaK + tmpW = (0xFFFFFFFF - gst.arb[gsrc]) + 1; + __asm { + mov edx,[gdst] + mov eax,[edx*4+gst.arb] + mov ecx,[tmpW] + shl eax,cl + mov [edx*4+gst.arb],eax + }; + } + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SHA R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif*/ + } + + void G_SHARQ( void ) + { + sdword tmpW; + + gc = (gst.arb[gdst] & 0x01); + tmpW = gst.arb[gdst]; + + __asm { + mov eax,[tmpW] + mov ecx,[gsrc] + sar eax,cl + mov [tmpW],eax + }; + + gst.arb[gdst] = tmpW; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SHARQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_SHLQ( void ) + { + gc = (gst.arb[gdst] >> 31) & 0x01; + gst.arb[gdst] <<= (32 - gsrc); + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SHLQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_SHRQ( void ) + { + gc = gst.arb[gdst] & 0x01; + gst.arb[gdst] >>= (32 - gsrc); + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SHRQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_STORE( void ) + { + mem_writeword( gst.arb[gsrc], (gst.arb[gdst] >> 16) ); + mem_writeword( gst.arb[gsrc] + 2, (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STORE R%i,(R%i)\t\tgdst = 0x%08X\n", + gpc, gdst, gsrc, gst.arb[gsrc] ); + #endif + } + + void G_STORE_14I( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0E] + (gsrc * 4); + + mem_writeword( tmpW, (gst.arb[gdst] >> 16) ); + mem_writeword( tmpW + 2, (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STORE R%i,(R14+%02i)\t\tgdst = 0x%08X\n", + gpc, gsrc, gdst, tmpW ); + #endif + } + + void G_STORE_15I( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0F] + (gsrc * 4); + + mem_writeword( tmpW, (gst.arb[gdst] >> 16) ); + mem_writeword( tmpW + 2, (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STORE R%i,(R15+%02i)\t\tgdst = 0x%08X\n", + gpc, gsrc, gdst, tmpW ); + #endif + } + + void G_STORE_14R( void ) + { + sdword tmpW; + + tmpW = gst.arb[0x0E] + gst.arb[gsrc]; + mem_writeword( tmpW, (gst.arb[gdst] >> 16) ); + mem_writeword( tmpW + 2, (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STORE R%i,(R14+R%i)\tgdst = 0x%08X\n", + gpc, gdst, gsrc, tmpW ); + #endif + } + + void G_STORE_15R( void ) + { + sdword tmpW; + + // NOTE: Manual seems to indicate that this opcode + // uses Register 14 as the base offset address. + + tmpW = gst.arb[0x0E] + gst.arb[gsrc]; + mem_writeword( tmpW, (gst.arb[gdst] >> 16) ); + mem_writeword( tmpW + 2, (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STORE R%i,(R14+R%i)\tgdst = 0x%08X\n", + gpc, gdst, gsrc, tmpW ); + #endif + } + + void G_STOREB( void ) + { + if( gst.arb[gsrc] >= 0xF03000 && gst.arb[gsrc] < 0xF04000 ) + { + mem_writeword( gst.arb[gsrc], (gst.arb[gdst] >> 16) ); + mem_writeword( gst.arb[gsrc] + 2, (gst.arb[gdst] & 0xFFFF) ); + } + else + mem_writebyte( gst.arb[gsrc], (gst.arb[gdst] & 0xFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STOREB R%i,(R%i)\tgdst = 0x%08X\n", + gpc, gdst, gsrc, gsrc ); + #endif + } + + void G_STOREW( void ) + { + if( gst.arb[gsrc] >= 0xF03000 && gst.arb[gsrc] < 0xF04000 ) + { + mem_writeword( gst.arb[gsrc], (gst.arb[gdst] >> 16) ); + mem_writeword( gst.arb[gsrc] + 2, (gst.arb[gdst] & 0xFFFF) ); + } + else + mem_writeword( gst.arb[gsrc], (gst.arb[gdst] & 0xFFFF) ); + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X STOREW R%i,(R%i)\tgdst = 0x%08X\n", + gpc, gdst, gsrc, gsrc ); + #endif + } + + void G_STOREP( void ) + { + #ifdef DEBUG_GPU + fprintf( oo, "GPU - Unimplemented Opcode (STOREP)\n" ); + #endif + gst.gpuActive = FALSE; + } + + void G_SUB( void ) + { + __asm { + mov ecx,[gsrc] + mov edx,[ecx*4+gst.arb] + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + sub eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc subend + mov ecx,0 + subend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SUB R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } + + void G_SUBC( void ) + { + __asm { + clc + mov ecx,[gc] + jcxz subc + stc + subc: + mov ecx,[gsrc] + mov edx,[ecx*4+gst.arb] + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + sbb eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc subcend + mov ecx,0 + subcend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SUBC R%i,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_SUBQ( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + sub eax,edx + mov [ecx*4+gst.arb],eax + mov ecx,1 + jc subqend + mov ecx,0 + subqend: + mov [gc],ecx + }; + + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SUBQ 0x%02X,R%i\t\tR%02i = 0x%08X " + "Z:%i N:%i C:%i\n", gpc, gsrc, gdst, gdst, + gst.arb[gdst], gz, gn, gc ); + #endif + } + + void G_SUBQT( void ) + { + __asm { + mov ecx,[gdst] + mov eax,[ecx*4+gst.arb] + mov edx,[gsrc] + sub eax,edx + mov [ecx*4+gst.arb],eax + }; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X SUBQT 0x%02X,R%i\t\tR%02i = 0x%08X\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst] ); + #endif + } + + void G_XOR( void ) + { + gst.arb[gdst] ^= gst.arb[gsrc]; + gz = (gst.arb[gdst] == 0) ? 1 : 0; + gn = (gst.arb[gdst] < 0) ? 1 : 0; + + #ifdef DEBUG_GPU + fprintf( oo, "0x%06X XOR R%i,R%i\t\tR%02i = 0x%08X Z:%i N:%i C:%i\n", + gpc, gsrc, gdst, gdst, gst.arb[gdst], + gz, gn, gc ); + #endif + } diff --git a/src/include/SDLptc.h b/src/include/SDLptc.h index 0827956..c7f366b 100644 --- a/src/include/SDLptc.h +++ b/src/include/SDLptc.h @@ -10,17 +10,10 @@ #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 { @@ -256,4 +249,4 @@ class Console: public Surface int nJoystick; }; -#endif // #ifndef __SDLPTC_H__ +#endif // __SDLPTC_H__ diff --git a/src/include/blitter2.h b/src/include/blitter2.h new file mode 100644 index 0000000..d8317ff --- /dev/null +++ b/src/include/blitter2.h @@ -0,0 +1 @@ +void blitter2_exec(DWORD cmd); diff --git a/src/include/blittertest.h b/src/include/blittertest.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/include/cry2rgb.h b/src/include/cry2rgb.h index 06ea79e..abf0cdd 100644 --- a/src/include/cry2rgb.h +++ b/src/include/cry2rgb.h @@ -1,74 +1,71 @@ -//////////////////////////////////////////////////////////////////////////////// +// // Red Color Values for CrY<->RGB Color Conversion -//////////////////////////////////////////////////////////////////////////////// - - uint8 redcv[16][16] = { +// +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 - }; + { 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] = { +// +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 - }; + { 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] = { +// +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 - }; + { 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/dsp.h b/src/include/dsp.h index 403fa42..8c6c35d 100644 --- a/src/include/dsp.h +++ b/src/include/dsp.h @@ -1,21 +1,12 @@ -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// +// DSP.H #ifndef __DSP_H__ #define __DSP_H__ #include "jaguar.h" -#define dsp_control_ram_base 0x00f1a100 -#define dsp_work_ram_base 0x00f1b000 +#define DSP_CONTROL_RAM_BASE 0x00F1A100 +#define DSP_WORK_RAM_BASE 0x00F1B000 void dsp_init(void); void dsp_reset(void); @@ -33,4 +24,4 @@ void dsp_long_write(unsigned offset, unsigned data); void dsp_check_if_i2s_interrupt_needed(void); void dsp_releaseTimeslice(void); -#endif +#endif // #ifndef __DSP_H__ diff --git a/src/include/fbmpop1.h b/src/include/fbmpop1.h deleted file mode 100644 index 4629dba..0000000 --- a/src/include/fbmpop1.h +++ /dev/null @@ -1,145 +0,0 @@ - - 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 deleted file mode 100644 index 4b20593..0000000 --- a/src/include/fbmpop16.h +++ /dev/null @@ -1,146 +0,0 @@ - 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 deleted file mode 100644 index 2fe7c30..0000000 --- a/src/include/fbmpop16p.h +++ /dev/null @@ -1,131 +0,0 @@ - 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 deleted file mode 100644 index eaed31d..0000000 --- a/src/include/fbmpop1p.h +++ /dev/null @@ -1,170 +0,0 @@ - - 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 deleted file mode 100644 index ec08851..0000000 --- a/src/include/fbmpop2.h +++ /dev/null @@ -1,268 +0,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; - 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 deleted file mode 100644 index c1ccbb2..0000000 --- a/src/include/fbmpop24.h +++ /dev/null @@ -1,74 +0,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; - 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 deleted file mode 100644 index 7d02948..0000000 --- a/src/include/fbmpop24p.h +++ /dev/null @@ -1,99 +0,0 @@ - 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 deleted file mode 100644 index 07c28f8..0000000 --- a/src/include/fbmpop2p.h +++ /dev/null @@ -1,317 +0,0 @@ - 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 deleted file mode 100644 index e53e6b1..0000000 --- a/src/include/fbmpop4.h +++ /dev/null @@ -1,178 +0,0 @@ - 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 deleted file mode 100644 index ec2091d..0000000 --- a/src/include/fbmpop4p.h +++ /dev/null @@ -1,221 +0,0 @@ - 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 deleted file mode 100644 index af8a715..0000000 --- a/src/include/fbmpop8.h +++ /dev/null @@ -1,104 +0,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]); - } - 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 deleted file mode 100644 index 4fff541..0000000 --- a/src/include/fbmpop8p.h +++ /dev/null @@ -1,129 +0,0 @@ - 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 index 7ac8f95..68761e0 100644 --- a/src/include/gpu.h +++ b/src/include/gpu.h @@ -1,21 +1,14 @@ -////////////////////////////////////////////////////////////////////////////// // -////////////////////////////////////////////////////////////////////////////// +// GPU.H: Header file // -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// #ifndef __GPU_H__ #define __GPU_H__ #include "jaguar.h" -#define gpu_control_ram_base 0x00f02100 -#define gpu_work_ram_base 0x00f03000 +#define GPU_CONTROL_RAM_BASE 0x00F02100 +#define GPU_WORK_RAM_BASE 0x00F03000 void gpu_init(void); void gpu_reset(void); @@ -35,4 +28,4 @@ void gpu_releaseTimeslice(void); void gpu_reset_stats(void); uint32 gpu_read_pc(void); -#endif +#endif // #ifndef __GPU_H__ diff --git a/src/include/gpu2.h b/src/include/gpu2.h new file mode 100644 index 0000000..276f55b --- /dev/null +++ b/src/include/gpu2.h @@ -0,0 +1,122 @@ +//void gpu2_exec(int); +void gpu2_init(void); +//void gpu2_interrupt(int); +//void gpu2_set_regbank(int); +//int gpu2_get_regbank(void); + +/*typedef struct { + signed int r0[32]; + signed int r1[32]; + UINT8 z; + UINT8 n; + UINT8 c; + UINT8 flags; + UINT32 pc; + UINT32 remain; + int acc; + UINT32 hidata; + UINT32 matrix_address; + UINT32 matrix_size; + UINT32 irq_enable[6]; + UINT32 irq_active[6]; + UINT32 active; + UINT32 imask; + UINT32 regbank; + UINT32 bcmd; + signed int* reg; + signed int* alt; + UINT32 r; + UINT32 divide; + UINT32 single_step; + UINT32 interrupt_stack[8]; + int i_pointer; +} GPUSTATE;*/ + +//extern GPUSTATE gpustate; + +//extern void (* gpu2_opcode[64])(); + +void opcode_add(void); +void opcode_addc(void); +void opcode_addq(void); +void opcode_addqt(void); +void opcode_sub(void); +void opcode_subc(void); +void opcode_subq(void); +void opcode_subqt(void); +void opcode_neg(void); +void opcode_and(void); +void opcode_or(void); +void opcode_xor(void); +void opcode_not(void); +void opcode_btst(void); +void opcode_bset(void); +void opcode_bclr(void); +void opcode_mult(void); +void opcode_imult(void); +void opcode_imultn(void); +void opcode_resmac(void); +void opcode_imacn(void); +void opcode_div(void); +void opcode_abs(void); +void opcode_sh(void); +void opcode_shlq(void); +void opcode_shrq(void); +void opcode_sha(void); +void opcode_sharq(void); +void opcode_ror(void); +void opcode_rorq(void); +void opcode_cmp(void); +void opcode_cmpq(void); +void opcode_sat8(void); +void opcode_sat16(void); +void opcode_move(void); +void opcode_moveq(void); +void opcode_moveta(void); +void opcode_movefa(void); +void opcode_movei(void); +void opcode_loadb(void); +void opcode_loadw(void); +void opcode_load(void); +void opcode_loadp(void); +void opcode_load_r14_indexed(void); +void opcode_load_r15_indexed(void); +void opcode_storeb(void); +void opcode_storew(void); +void opcode_store(void); +void opcode_storep(void); +void opcode_store_r14_indexed(void); +void opcode_store_r15_indexed(void); +void opcode_move_pc(void); +void opcode_jump(void); +void opcode_jr(void); +void opcode_mmult(void); +void opcode_mtoi(void); +void opcode_normi(void); +void opcode_nop(void); +void opcode_load_r14_ri(void); +void opcode_load_r15_ri(void); +void opcode_store_r14_ri(void); +void opcode_store_r15_ri(void); +void opcode_sat24(void); +void opcode_pack(void); + +void (* gpu2_opcode[64])()= +{ + opcode_add, opcode_addc, opcode_addq, opcode_addqt, + opcode_sub, opcode_subc, opcode_subq, opcode_subqt, + opcode_neg, opcode_and, opcode_or, opcode_xor, + opcode_not, opcode_btst, opcode_bset, opcode_bclr, + opcode_mult, opcode_imult, opcode_imultn, opcode_resmac, + opcode_imacn, opcode_div, opcode_abs, opcode_sh, + opcode_shlq, opcode_shrq, opcode_sha, opcode_sharq, + opcode_ror, opcode_rorq, opcode_cmp, opcode_cmpq, + opcode_sat8, opcode_sat16, opcode_move, opcode_moveq, + opcode_moveta, opcode_movefa, opcode_movei, opcode_loadb, + opcode_loadw, opcode_load, opcode_loadp, opcode_load_r14_indexed, + opcode_load_r15_indexed, opcode_storeb, opcode_storew, opcode_store, + opcode_storep, opcode_store_r14_indexed, opcode_store_r15_indexed, opcode_move_pc, + opcode_jump, opcode_jr, opcode_mmult, opcode_mtoi, + opcode_normi, opcode_nop, opcode_load_r14_ri, opcode_load_r15_ri, + opcode_store_r14_ri, opcode_store_r15_ri, opcode_sat24, opcode_pack, +}; diff --git a/src/include/gpu3.h b/src/include/gpu3.h new file mode 100644 index 0000000..b5bfffc --- /dev/null +++ b/src/include/gpu3.h @@ -0,0 +1,116 @@ +void gpu3_init(void); + +/*################################################################################################### +** FUNCTION TABLES +**#################################################################################################*/ + +void abs_rn(void); +void add_rn_rn(void); +void addc_rn_rn(void); +void addq_n_rn(void); +void addqmod_n_rn(void); /* DSP only */ +void addqt_n_rn(void); +void and_rn_rn(void); +void bclr_n_rn(void); +void bset_n_rn(void); +void btst_n_rn(void); +void cmp_rn_rn(void); +void cmpq_n_rn(void); +void div_rn_rn(void); +void illegal(void); +void imacn_rn_rn(void); +void imult_rn_rn(void); +void imultn_rn_rn(void); +void jr_cc_n(void); +void jump_cc_rn(void); +void load_rn_rn(void); +void load_r14n_rn(void); +void load_r15n_rn(void); +void load_r14rn_rn(void); +void load_r15rn_rn(void); +void loadb_rn_rn(void); +void loadw_rn_rn(void); +void loadp_rn_rn(void); /* GPU only */ +void mirror_rn(void); /* DSP only */ +void mmult_rn_rn(void); +void move_rn_rn(void); +void move_pc_rn(void); +void movefa_rn_rn(void); +void movei_n_rn(void); +void moveq_n_rn(void); +void moveta_rn_rn(void); +void mtoi_rn_rn(void); +void mult_rn_rn(void); +void neg_rn(void); +void nop(void); +void normi_rn_rn(void); +void not_rn(void); +void or_rn_rn(void); +void pack_rn(void); /* GPU only */ +void resmac_rn(void); +void ror_rn_rn(void); +void rorq_n_rn(void); +void sat8_rn(void); /* GPU only */ +void sat16_rn(void); /* GPU only */ +void sat16s_rn(void); /* DSP only */ +void sat24_rn(void); /* GPU only */ +void sat32s_rn(void); /* DSP only */ +void sh_rn_rn(void); +void sha_rn_rn(void); +void sharq_n_rn(void); +void shlq_n_rn(void); +void shrq_n_rn(void); +void store_rn_rn(void); +void store_rn_r14n(void); +void store_rn_r15n(void); +void store_rn_r14rn(void); +void store_rn_r15rn(void); +void storeb_rn_rn(void); +void storew_rn_rn(void); +void storep_rn_rn(void); /* GPU only */ +void sub_rn_rn(void); +void subc_rn_rn(void); +void subq_n_rn(void); +void subqmod_n_rn(void); /* DSP only */ +void subqt_n_rn(void); +void xor_rn_rn(void); + +void (* gpu3_opcode[64])(void) = +{ + /* 00-03 */ add_rn_rn, addc_rn_rn, addq_n_rn, addqt_n_rn, + /* 04-07 */ sub_rn_rn, subc_rn_rn, subq_n_rn, subqt_n_rn, + /* 08-11 */ neg_rn, and_rn_rn, or_rn_rn, xor_rn_rn, + /* 12-15 */ not_rn, btst_n_rn, bset_n_rn, bclr_n_rn, + /* 16-19 */ mult_rn_rn, imult_rn_rn, imultn_rn_rn, resmac_rn, + /* 20-23 */ imacn_rn_rn, div_rn_rn, abs_rn, sh_rn_rn, + /* 24-27 */ shlq_n_rn, shrq_n_rn, sha_rn_rn, sharq_n_rn, + /* 28-31 */ ror_rn_rn, rorq_n_rn, cmp_rn_rn, cmpq_n_rn, + /* 32-35 */ sat8_rn, sat16_rn, move_rn_rn, moveq_n_rn, + /* 36-39 */ moveta_rn_rn, movefa_rn_rn, movei_n_rn, loadb_rn_rn, + /* 40-43 */ loadw_rn_rn, load_rn_rn, loadp_rn_rn, load_r14n_rn, + /* 44-47 */ load_r15n_rn, storeb_rn_rn, storew_rn_rn, store_rn_rn, + /* 48-51 */ storep_rn_rn, store_rn_r14n, store_rn_r15n, move_pc_rn, + /* 52-55 */ jump_cc_rn, jr_cc_n, mmult_rn_rn, mtoi_rn_rn, + /* 56-59 */ normi_rn_rn, nop, load_r14rn_rn, load_r15rn_rn, + /* 60-63 */ store_rn_r14rn, store_rn_r15rn, sat24_rn, pack_rn +}; + +void (* dsp3_opcode[64])(void) = +{ + /* 00-03 */ add_rn_rn, addc_rn_rn, addq_n_rn, addqt_n_rn, + /* 04-07 */ sub_rn_rn, subc_rn_rn, subq_n_rn, subqt_n_rn, + /* 08-11 */ neg_rn, and_rn_rn, or_rn_rn, xor_rn_rn, + /* 12-15 */ not_rn, btst_n_rn, bset_n_rn, bclr_n_rn, + /* 16-19 */ mult_rn_rn, imult_rn_rn, imultn_rn_rn, resmac_rn, + /* 20-23 */ imacn_rn_rn, div_rn_rn, abs_rn, sh_rn_rn, + /* 24-27 */ shlq_n_rn, shrq_n_rn, sha_rn_rn, sharq_n_rn, + /* 28-31 */ ror_rn_rn, rorq_n_rn, cmp_rn_rn, cmpq_n_rn, + /* 32-35 */ subqmod_n_rn, sat16s_rn, move_rn_rn, moveq_n_rn, + /* 36-39 */ moveta_rn_rn, movefa_rn_rn, movei_n_rn, loadb_rn_rn, + /* 40-43 */ loadw_rn_rn, load_rn_rn, sat32s_rn, load_r14n_rn, + /* 44-47 */ load_r15n_rn, storeb_rn_rn, storew_rn_rn, store_rn_rn, + /* 48-51 */ mirror_rn, store_rn_r14n, store_rn_r15n, move_pc_rn, + /* 52-55 */ jump_cc_rn, jr_cc_n, mmult_rn_rn, mtoi_rn_rn, + /* 56-59 */ normi_rn_rn, nop, load_r14rn_rn, load_r15rn_rn, + /* 60-63 */ store_rn_r14rn, store_rn_r15rn, illegal, addqmod_n_rn +}; diff --git a/src/include/gpuopcodes.h b/src/include/gpuopcodes.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/include/jaguar.h b/src/include/jaguar.h index aeb449d..ef3ea8e 100644 --- a/src/include/jaguar.h +++ b/src/include/jaguar.h @@ -5,8 +5,7 @@ #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 "m68k.h" #include "tom.h" #include "jerry.h" #include "gpu.h" @@ -28,15 +27,15 @@ 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 +//#ifdef __PORT__ +//void jaguar_init(const char * filename); +//#else void jaguar_init(void); -#endif // #ifdef __PORT__ +//#endif // #ifdef __PORT__ void jaguar_reset(void); void jaguar_reset_handler(void); void jaguar_done(void); -void jaguar_exec(int16 * backbuffer, uint8 render); +void jaguar_exec(int16 * backbuffer, bool render); unsigned jaguar_byte_read(unsigned int offset); unsigned jaguar_word_read(unsigned int offset); unsigned jaguar_long_read(unsigned int offset); @@ -46,6 +45,15 @@ void jaguar_long_write(unsigned offset, unsigned data); uint32 jaguar_interrupt_handler_is_valid(uint32 i); void jaguar_dasm(uint32 offset, uint32 qt); +// Some handy macros to help converting native endian to big endian (jaguar native) +// & vice versa + +#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 +#define GET32(r, a) ((r[a] << 24) | (r[a+1] << 16) | (r[a+2] << 8) | r[a+3]) +#define SET16(r, a, v) r[a] = ((v) & 0xFF00) >> 8, r[a+1] = (v) & 0xFF +#define GET16(r, a) ((r[a] << 8) | r[a+1]) + //Temp debug stuff void DumpMainMemory(void); diff --git a/src/include/log.h b/src/include/log.h index 107774e..d1a034f 100644 --- a/src/include/log.h +++ b/src/include/log.h @@ -1,22 +1,25 @@ -////////////////////////////////////////////////////////////////////////////// // -////////////////////////////////////////////////////////////////////////////// +// LOG.H // -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// #ifndef __LOG_H__ #define __LOG_H__ #include #include +#include + +#ifdef __cplusplus +extern "C" { +#endif int log_init(char *); FILE *log_get(void); void log_done(void); +void WriteLog(const char * text, ...); +#ifdef __cplusplus +} #endif + +#endif // __LOG_H__ diff --git a/src/include/m68kdasmAG.h b/src/include/m68kdasmAG.h deleted file mode 100644 index 0f46c36..0000000 --- a/src/include/m68kdasmAG.h +++ /dev/null @@ -1 +0,0 @@ -int Dasm68000(char * pBase, char * buffer, int pc); diff --git a/src/include/mamegpu.h b/src/include/mamegpu.h deleted file mode 100644 index 99c64cb..0000000 --- a/src/include/mamegpu.h +++ /dev/null @@ -1,781 +0,0 @@ -#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/objectp.h b/src/include/objectp.h index 835c0e2..956e5b2 100644 --- a/src/include/objectp.h +++ b/src/include/objectp.h @@ -11,10 +11,13 @@ 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_process_list(int16 * backbuffer, int scanline, bool render); void op_set_status_register(uint32 data); uint32 op_get_status_register(void); void op_set_current_object(uint64 object); +// Replacement functions -#endif +void OPProcessList(int scanline, bool render); + +#endif // __OBJECTP_H__ diff --git a/src/include/tom.h b/src/include/tom.h index 3ed0ccd..0aff74b 100644 --- a/src/include/tom.h +++ b/src/include/tom.h @@ -1,13 +1,6 @@ -////////////////////////////////////////////////////////////////////////////// // -////////////////////////////////////////////////////////////////////////////// +// TOM Header file // -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// #ifndef __TOM_H__ #define __TOM_H__ @@ -21,7 +14,6 @@ #define VIDEO_MODE_16BPP_DIRECT 2 #define VIDEO_MODE_16BPP_RGB 3 - extern uint32 tom_width; extern uint32 tom_height; @@ -32,19 +24,18 @@ 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); +void tom_exec_scanline(int16 * backbuffer, int32 scanline, bool render); uint32 tom_getVideoModeWidth(void); uint32 tom_getVideoModeHeight(void); uint8 tom_getVideoMode(void); -uint8 *tom_get_ram_pointer(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 -////////////////////////////////////////////////////////////////////////////// +// Interrupts + #define IRQ_VBLANK 0 #define IRQ_GPU 1 #define IRQ_HBLANK 2 @@ -52,10 +43,10 @@ uint32 tom_getHBlankWidthInPixels(void); #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); +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); @@ -63,5 +54,4 @@ void tom_set_pending_gpu_int(void); void tom_set_pending_video_int(void); void tom_reset_timer(void); - -#endif +#endif // __TOM_H__ diff --git a/src/include/unzip.h b/src/include/unzip.h new file mode 100644 index 0000000..16654ca --- /dev/null +++ b/src/include/unzip.h @@ -0,0 +1,135 @@ +#ifndef __UNZIP_H__ +#define __UNZIP_H__ + +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************************** + * Support for retrieving files from zipfiles + ***************************************************************************/ + +struct zipent +{ + UINT32 cent_file_header_sig; + UINT8 version_made_by; + UINT8 host_os; + UINT8 version_needed_to_extract; + UINT8 os_needed_to_extract; + UINT16 general_purpose_bit_flag; + UINT16 compression_method; + UINT16 last_mod_file_time; + UINT16 last_mod_file_date; + UINT32 crc32; + UINT32 compressed_size; + UINT32 uncompressed_size; + UINT16 filename_length; + UINT16 extra_field_length; + UINT16 file_comment_length; + UINT16 disk_number_start; + UINT16 internal_file_attrib; + UINT32 external_file_attrib; + UINT32 offset_lcl_hdr_frm_frst_disk; + char * name; /* 0 terminated */ +}; + +typedef struct _ZIP +{ + char * zip; /* zip name */ + FILE * fp; /* zip handler */ + int pathtype, pathindex; /* additional path info */ + long length; /* length of zip file */ + char * ecd; /* end_of_cent_dir data */ + unsigned ecd_length; /* end_of_cent_dir length */ + char * cd; /* cent_dir data */ + unsigned cd_pos; /* position in cent_dir */ + struct zipent ent; /* buffer for readzip */ + /* end_of_cent_dir */ + UINT32 end_of_cent_dir_sig; + UINT16 number_of_this_disk; + UINT16 number_of_disk_start_cent_dir; + UINT16 total_entries_cent_dir_this_disk; + UINT16 total_entries_cent_dir; + UINT32 size_of_cent_dir; + UINT32 offset_to_start_of_cent_dir; + UINT16 zipfile_comment_length; + char * zipfile_comment; /* pointer in ecd */ +} ZIP; + +/* Opens a zip stream for reading + return: + !=0 success, zip stream + ==0 error +*/ +ZIP * openzip(int pathtype, int pathindex, const char * path); + +/* Closes a zip stream */ +void closezip(ZIP * zip); + +/* Reads the current entry from a zip stream + in: + zip opened zip + return: + !=0 success + ==0 error +*/ +struct zipent * readzip(ZIP * zip); + +/* Suspend access to a zip file (release file handler) + in: + zip opened zip + note: + A suspended zip is automatically reopened at first call of + readuncompressd() or readcompressed() functions +*/ +void suspendzip(ZIP * zip); + +/* Resets a zip stream to the first entry + in: + zip opened zip + note: + ZIP file must be opened and not suspended +*/ +void rewindzip(ZIP * zip); + +/* Read compressed data from a zip entry + in: + zip opened zip + ent entry to read + out: + data buffer for data, ent.compressed_size UINT8s allocated by the caller + return: + ==0 success + <0 error +*/ +int readcompresszip(ZIP * zip, struct zipent * ent, char * data); + +/* Read decompressed data from a zip entry + in: + zip zip stream open + ent entry to read + out: + data buffer for data, ent.uncompressed_size UINT8s allocated by the caller + return: + ==0 success + <0 error +*/ +int readuncompresszip(ZIP * zip, struct zipent * ent, char * data); + +/* public functions */ +int /* error */ load_zipped_file(int pathtype, int pathindex, const char * zipfile, const char * filename, + unsigned char ** buf, uint32 * length); + +void unzip_cache_clear(void); + +/* public globals */ +extern int gUnzipQuiet; /* flag controls error messages */ + +#ifdef __cplusplus +} +#endif + +#endif // __UNZIP_H__ diff --git a/src/include/wavetable.h b/src/include/wavetable.h index 8faffb9..085a158 100644 --- a/src/include/wavetable.h +++ b/src/include/wavetable.h @@ -1,4 +1,15 @@ -const unsigned char wave_table[4096] = { +// +// Jaguar Wavetable ROM +// +// In a real Jaguar, these are 16-bit values that are sign-extended to 32 bits. +// Each entry has 128 values (e.g., SINE goes from F1D200-F1D3FF) +// + +// NOTE: This can probably be converted to 32-bit table, since I don't think +// that unaligned access is allowed... + +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, @@ -255,4 +266,4 @@ const unsigned char wave_table[4096] = { 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/zbmpop16.h b/src/include/zbmpop16.h index 9238d6f..4d54a51 100644 --- a/src/include/zbmpop16.h +++ b/src/include/zbmpop16.h @@ -1,22 +1,22 @@ - if (flags&FLAGS_READMODIFY) + if (flags & FLAGS_READMODIFY) { - if (flags&FLAGS_HFLIP) + if (flags & FLAGS_HFLIP) { - if (flags&FLAGS_TRANSPARENT) + 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); + 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)); + *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; + current_line_buffer -= 2; + cnt += hscale_fixed; scaled_width--; } } @@ -24,8 +24,8 @@ { 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)); + *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--; } @@ -98,21 +98,21 @@ } else { - if (flags&FLAGS_TRANSPARENT) + 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); + 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); + *current_line_buffer++ = c >> 8; + *current_line_buffer++ = c & 0xFF; } else - current_line_buffer+=2; - cnt+=hscale_fixed; + current_line_buffer += 2; + cnt += hscale_fixed; scaled_width--; } } @@ -120,9 +120,9 @@ { 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; + *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/jagdasm.cpp b/src/jagdasm.cpp index 45ec567..fb0652c 100644 --- a/src/jagdasm.cpp +++ b/src/jagdasm.cpp @@ -1,11 +1,11 @@ -#include "include/jaguar.h" +#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] = +char * condition[32] = { "", "nz,", @@ -15,6 +15,7 @@ char *condition[32] = "nc nz,", "nc z,", "???,", + "c,", "c nz,", "c z,", @@ -32,6 +33,7 @@ char *condition[32] = "nn nz,", "nn z,", "???,", + "n,", "n nz,", "n z,", @@ -44,17 +46,19 @@ char *condition[32] = -char *signed_16bit(INT16 val) +char * signed_16bit(INT16 val) { static char temp[10]; + if (val < 0) - sprintf(temp, "-$%x", -val); + sprintf(temp, "-$%X", -val); else - sprintf(temp, "$%x", val); + sprintf(temp, "$%X", val); + return temp; } -unsigned dasmjag(int dsp_type, char *buffer, unsigned pc) +unsigned dasmjag(int dsp_type, char * buffer, unsigned pc) { int op = ROPCODE(pc); int reg1 = (op >> 5) & 31; @@ -64,22 +68,22 @@ unsigned dasmjag(int dsp_type, char *buffer, unsigned pc) 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 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 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 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; @@ -88,14 +92,14 @@ unsigned dasmjag(int dsp_type, char *buffer, unsigned pc) 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 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 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 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 @@ -155,6 +159,7 @@ unsigned dasmjag(int dsp_type, char *buffer, unsigned pc) sprintf(buffer, "addqmod $%x,r%d", convert_zero[reg1], reg2); break; } - sprintf(buffer,"%s (0x%.4x)",buffer,op); + sprintf(buffer,"%s (%04X)", buffer, op); + return size; } diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 74c1de4..749601b 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -9,45 +9,32 @@ // #include "jaguar.h" -#include "m68kdasmAG.h" -#include "crc32.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 +#define CPU_DEBUG +#define JAGUAR_WIP_RELEASE +#define JAGUAR_REAL_SPEED +//Do this in makefile??? Yes! Could, but it's easier to define here... +//#define LOG_UNMAPPED_MEMORY_ACCESSES // -// Function Prototypes +// Private 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); +void M68K_show_context(void); +// These values are overridden by command line switches... -#ifdef SOUND_OUTPUT -int dsp_enabled = 1; -#else -int dsp_enabled = 0; -#endif +bool dsp_enabled = false; +bool jaguar_use_bios = true; // Default is now to USE the BIOS 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; @@ -56,10 +43,32 @@ 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; +/*static*/ uint8 * jaguar_mainRam = NULL; +/*static*/ uint8 * jaguar_bootRom = NULL; +/*static*/ uint8 * jaguar_mainRom = NULL; + + +// +// Callback function to detect illegal instructions +// +void M68KInstructionHook(void) +{ + uint32 m68kPC = m68k_get_reg(NULL, M68K_REG_PC); + + if (!m68k_is_valid_instruction(jaguar_word_read(m68kPC), M68K_CPU_TYPE_68000)) + { + WriteLog("\nEncountered illegal instruction at %08X!!!\n\nAborting!\n", m68kPC); + uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7); + WriteLog("M68K: Top of stack: %08X. Stack trace:\n", jaguar_long_read(topOfStack)); + for(int i=0; i<10; i++) + WriteLog("%06X: %08X\n", topOfStack - (i * 4), jaguar_long_read(topOfStack - (i * 4))); + WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled"); + M68K_show_context(); + log_done(); + exit(0); + } +} // // Musashi 68000 read/write/IRQ functions @@ -69,7 +78,9 @@ int irq_ack_handler(int level) { int vector = M68K_INT_ACK_AUTOVECTOR; - if (level = 7) + // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work OK... + + if (level == 7) { m68k_set_irq(0); // Clear the IRQ... vector = 64; // Set user interrupt #0 @@ -78,12 +89,9 @@ int irq_ack_handler(int level) 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); +//WriteLog( "[RM8] Addr: %08X\n", address); unsigned int retVal = 0; if ((address >= 0x000000) && (address <= 0x3FFFFF)) @@ -104,9 +112,36 @@ unsigned int m68k_read_memory_8(unsigned int address) return retVal; } +void gpu_dump_disassembly(void); +void gpu_dump_registers(void); + unsigned int m68k_read_memory_16(unsigned int address) { -//fprintf(log_get(), "[RM16] Addr: %08X\n", address); +//WriteLog( "[RM16] Addr: %08X\n", address); +/*if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005FBA) +// for(int i=0; i<10000; i++) + WriteLog("[M68K] In routine #6!\n");//*/ +//if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00006696) // GPU Program #4 +//if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005B3C) // GPU Program #2 +/*if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005BA8) // GPU Program #3 +{ + WriteLog("[M68K] About to run GPU! (Addr:%08X, data:%04X)\n", address, tom_word_read(address)); + gpu_dump_registers(); + gpu_dump_disassembly(); +// for(int i=0; i<10000; i++) +// WriteLog( "[M68K] About to run GPU!\n"); +}//*/ +//WriteLog( "[WM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value); +/*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x00006696 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x000066A8) +{ + if (address == 0x000066A0) + { + gpu_dump_registers(); + gpu_dump_disassembly(); + } + for(int i=0; i<10000; i++) + WriteLog( "[M68K] About to run GPU! (Addr:%08X, data:%04X)\n", address, tom_word_read(address)); +}//*/ unsigned int retVal = 0; if ((address >= 0x000000) && (address <= 0x3FFFFE)) @@ -123,7 +158,7 @@ unsigned int m68k_read_memory_16(unsigned int address) retVal = jerry_word_read(address); else //{ -//fprintf(log_get(), "[RM16] Unknown address: %08X\n", address); +//WriteLog( "[RM16] Unknown address: %08X\n", address); retVal = jaguar_unknown_readword(address); //} @@ -132,13 +167,15 @@ unsigned int m68k_read_memory_16(unsigned int address) unsigned int m68k_read_memory_32(unsigned int address) { -//fprintf(log_get(), "--> [RM32]\n"); +//WriteLog( "--> [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 >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F)) +// WriteLog("M68K: Writing %02X at %08X\n", value, address); +//WriteLog( "[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)) @@ -153,7 +190,29 @@ void m68k_write_memory_8(unsigned int address, unsigned int 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); +extern int dsp_pc;//, dsp_control; +if (address == 0xF1A116 && (value & 0x01)) +{ + WriteLog(" M68K(16): DSP is GO! (DSP_PC: %08X)\n\n", dsp_pc); + +/* static char buffer[512]; + uint32 j = 0xF1B000; + while (j <= 0xF1BFFF) + { + uint32 oldj = j; + j += dasmjag(JAGUAR_DSP, buffer, j); + WriteLog( "\t%08X: %s\n", oldj, buffer); + } + WriteLog( "\n");//*/ +} +//else +// WriteLog("M68K(16): DSP halted... (Old value: %08X)\n", dsp_control); + +//if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F)) +// WriteLog("M68K: Writing %04X at %08X\n", value, address); +//WriteLog( "[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value); +//if (address >= 0xF02200 && address <= 0xF0229F) +// WriteLog("M68K: Writing to blitter --> %04X at %08X\n", value, address); if ((address >= 0x000000) && (address <= 0x3FFFFE)) { jaguar_mainRam[address] = value >> 8; @@ -171,19 +230,19 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) void m68k_write_memory_32(unsigned int address, unsigned int value) { -//fprintf(log_get(), "--> [WM32]\n"); +extern int dsp_pc;//, dsp_control; +if (address == 0xF1A114 && (value & 0x01)) + WriteLog("M68K(32): DSP is GO! (DSP_PC: %08X)\n", dsp_pc); +//else +// WriteLog("M68K(32): DSP halted... (Old value: %08X)\n", dsp_control); + +//WriteLog( "--> [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); @@ -191,57 +250,6 @@ uint32 jaguar_get_handler(uint32 i) 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); @@ -250,49 +258,36 @@ uint32 jaguar_interrupt_handler_is_valid(uint32 i) else return 0; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void s68000show_context(void) + +void M68K_show_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]); + WriteLog( "\t68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC)); 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]); + WriteLog( "\tD%i = %08X\n", i-M68K_REG_D0, m68k_get_reg(NULL, (m68k_register_t)i)); + WriteLog( "\n"); 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)); + WriteLog( "\tA%i = %08X\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i)); - fprintf(log_get(), "68k dasm\n"); + WriteLog( "68K disasm\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"); +// jaguar_dasm(0x5000, 0x14414); + WriteLog( "..................\n"); if (tom_irq_enabled(IRQ_VBLANK)) { - fprintf(log_get(), "vblank int: enabled\n"); + WriteLog( "vblank int: enabled\n"); jaguar_dasm(jaguar_get_handler(64), 0x200); } else - fprintf(log_get(), "vblank int: disabled\n"); - fprintf(log_get(), "..................\n"); + WriteLog( "vblank int: disabled\n"); + WriteLog( "..................\n"); for(int i=0; i<256; i++) - fprintf(log_get(), "handler %03i at $%08X\n", i, jaguar_get_handler(i)); + WriteLog( "handler %03i at $%08X\n", i, (unsigned int)jaguar_get_handler(i)); } -// Starscream crap ripped out... - // // Unknown read/write byte/word routines // @@ -300,21 +295,21 @@ void s68000show_context(void) 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)); + WriteLog( "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)); + WriteLog( "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)); + WriteLog( "jaguar: unknown byte read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC)); #endif return 0xFF; } @@ -322,195 +317,251 @@ unsigned jaguar_unknown_readbyte(unsigned address) 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)); + WriteLog( "Jaguar: Unknown word read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC)); #endif return 0xFFFF; } // -// Jaguar ROM loading +// Disassemble M68K instructions at the given offset // -uint8 * jaguar_rom_load(char * path, uint32 * romSize) +unsigned int m68k_read_disassembler_8(unsigned int address) { - __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); + return m68k_read_memory_8(address); +} - /* 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; +unsigned int m68k_read_disassembler_16(unsigned int address) +{ + return m68k_read_memory_16(address); } -// -// Load a ROM at a specific address -// +unsigned int m68k_read_disassembler_32(unsigned int address) +{ + return m68k_read_memory_32(address); +} -void jaguar_rom_load_to(uint8 * rom, char * path, uint32 * romSize) +void jaguar_dasm(uint32 offset, uint32 qt) { - __int64 filepos; +#ifdef CPU_DEBUG + static char buffer[2048];//, mem[64]; + int pc = offset, oldpc; - fprintf(log_get(), "jaguar: loading %s...", path); - FILE * fp = fopen(path, "rb"); - if (fp == NULL) + for(uint32 i=0; i= 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) { - while (size > 0) +//TEMP--Mirror of F03000? +/*if (offset >= 0xF0B000 && offset <= 0xF0BFFF) +WriteLog( "[JWR16] --> Possible GPU RAM mirror access! [%08X]\n", 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)) { - uint8 tmp = rom[0]; - rom[0] = rom[1]; - rom[1] = tmp; - rom += 2; - size -= 2; + 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)) +//{ +//WriteLog("Reading from JERRY offset %08X...\n", offset); + return jerry_word_read(offset); +//} -// -// Disassemble instructions at the given offset -// + return jaguar_unknown_readword(offset); +} -void jaguar_dasm(uint32 offset, uint32 qt) +void jaguar_byte_write(unsigned offset, unsigned data) { -#ifdef CPU_DEBUG - static char buffer[2048], mem[64]; - int pc = offset, oldpc; - - for(int i=0; i= 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); } -// -// Jaguar cartridge ROM loading -// - -void jaguar_load_cart(char * path, uint8 * mem, uint32 offs, uint32 boot, uint32 header) +void jaguar_word_write(unsigned offset, unsigned data) { - uint32 romsize; +extern int dsp_pc;//, dsp_control; +if (offset == 0xF1A116 && (data & 0x01)) + WriteLog(" JagWW: DSP is GO! (DSP_PC: %08X)\n", dsp_pc); +//else +// WriteLog("JagWW: DSP halted... (Old value: %08X)\n", dsp_control); + +//extern int blit_start_log; +//if (blit_start_log) +/*{ + if (offset == 0x0674DE) + WriteLog( "[JWW16] Bad write starting @ 0674DE! [%04X]\n", data); +}//*/ +//TEMP--Mirror of F03000? +//if (offset >= 0xF0B000 && offset <= 0xF0BFFF) +//WriteLog( "[JWW16] --> Possible GPU RAM mirror access! [%08X]", offset); +//if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) +// WriteLog("JagWW: Writing %04X at %08X\n", data, offset); + 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); +} - jaguar_rom_load_to(mem+offs-header, path, &romsize); -// Is there a need for this? The answer is !!! NO !!! -// jaguar_byte_swap(mem+offs, romsize); - jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romsize); - fprintf(log_get(), "CRC: %08X\n", jaguar_mainRom_crc32); +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); +} -// Brain dead endian dependent crap -// *((uint32 *)&jaguar_mainRam[4]) = boot; -// This is how it *should* have been done... - SET32(jaguar_mainRam, 4, boot); -// Same as above... -// jaguar_dasm((boot>>16) | (boot<<16), 32*4); - jaguar_dasm(boot, 32*4); +void jaguar_long_write(unsigned offset, unsigned data) +{ +extern int dsp_pc;//, dsp_control; +if (offset == 0xF1A114 && (data & 0x01)) + WriteLog("JagLW: DSP is GO! (DSP_PC: %08X)\n", dsp_pc); +//else +// WriteLog("JagLW: DSP halted... (Old value: %08X)\n", dsp_control); + +//extern int effect_start; +// $10, $0C, $0A, $09 too much, $08 too little... +//if (effect_start && offset == 0xF03000) data = (data & 0xFFFF0000) | (((data & 0xFFFF) + 0x0008) & 0xFFFF); +//Doesn't work--offsets horizontally if (effect_start && offset == 0xF03004) data -= (0x300 * 8); // one line is $300 +//if (effect_start && offset == 0xF03000) data = 0x00000000; // Let's try making the top/bottom *always* 0! +//Interesting: it seems to pin half of the screen down (but too low)... +//Definitely the fine scroll offsets (for left side of screen)... + +//if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) +// WriteLog("JagLW: Writing %08X at %08X\n", data, offset); + jaguar_word_write(offset, data >> 16); + jaguar_word_write(offset+2, data & 0xFFFF); } // // Jaguar initialization // -#ifdef __PORT__ -void jaguar_init(const char * filename) -#else +//void jaguar_init(const char * filename) void jaguar_init(void) -#endif { - uint32 romsize; +// 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"); + memory_malloc_secure((void **)&jaguar_mainRam, 0x400000, "Jaguar 68K CPU RAM"); + memory_malloc_secure((void **)&jaguar_bootRom, 0x040000, "Jaguar 68K CPU BIOS ROM"); + memory_malloc_secure((void **)&jaguar_mainRom, 0x600000, "Jaguar 68K CPU ROM"); memset(jaguar_mainRam, 0x00, 0x400000); +// memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs... + memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s... - 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); +// jaguar_rom_load_to(jaguar_bootRom, jaguar_bootRom_path, &romsize); +// memcpy(jaguar_mainRam, jaguar_bootRom, 8); +// 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"); - }//*/ - +// strcpy(romLoadDialog_filePath, filename); +// jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0); if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756) || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0x2630cbc4)) - dsp_enabled = 1; + dsp_enabled = true; if ((jaguar_mainRom_crc32 == 0x6e90989f) || (jaguar_mainRom_crc32 == 0xfc8f0dcd) || (jaguar_mainRom_crc32 == 0x2a512a83) || (jaguar_mainRom_crc32 == 0x41307601) @@ -519,13 +570,13 @@ void jaguar_init(void) if (jaguar_mainRom_crc32 == 0x7ae20823) { - dsp_enabled = 1; + dsp_enabled = true; 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; + dsp_enabled = true; gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); } @@ -539,28 +590,28 @@ void jaguar_init(void) } if (jaguar_mainRom_crc32 == 0xdcb0197a) { - dsp_enabled = 0; // dsp not needed + dsp_enabled = false; // 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; + dsp_enabled = true; if (jaguar_mainRom_crc32 == 0x5e705756) { gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); - dsp_enabled = 1; + dsp_enabled = true; } 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; + dsp_enabled = true; } if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed)) { gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); - dsp_enabled = 1; + dsp_enabled = true; } if (jaguar_mainRom_crc32 == 0x6e90989f) gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60); @@ -572,7 +623,7 @@ void jaguar_init(void) if (jaguar_mainRom_crc32 == 0x8483392b) { - dsp_enabled = 1; + dsp_enabled = true; } #else // #ifdef JAGUAR_WIP_RELEASE @@ -608,7 +659,7 @@ void jaguar_init(void) if (jaguar_mainRom_crc32==0xe21d0e2f) { - dsp_enabled=1; + dsp_enabled=true; gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); } @@ -623,19 +674,19 @@ void jaguar_init(void) // 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 + dsp_enabled=true; // 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; + dsp_enabled=true; // 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; + dsp_enabled=true; } // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0); if (jaguar_mainRom_crc32==0x2630cbc4) @@ -643,7 +694,7 @@ void jaguar_init(void) // 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; + dsp_enabled=true; } // 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); @@ -651,7 +702,7 @@ void jaguar_init(void) { gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); // dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); - dsp_enabled=1; + dsp_enabled=true; } // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pitfall - The Mayan Adventure.JAG",jaguar_mainRom,0x0000, 0x20000080,0); if (jaguar_mainRom_crc32==0x6e90989f) @@ -668,7 +719,7 @@ void jaguar_init(void) // 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; + dsp_enabled=true; } // cpu/dsp/gpu synchronization problems @@ -689,7 +740,7 @@ void jaguar_init(void) // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Burnout.JAG",jaguar_mainRom,0x0000, 0x20000080,0); if (jaguar_mainRom_crc32==0x20ae75f4) { - dsp_enabled=1; + dsp_enabled=true; gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); } @@ -697,14 +748,14 @@ void jaguar_init(void) // 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; + dsp_enabled=true; } // 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; + dsp_enabled=true; gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); } // not working at all @@ -712,19 +763,19 @@ void jaguar_init(void) if (jaguar_mainRom_crc32==0x6f57dcd2) { gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); - dsp_enabled=0; + dsp_enabled=false; } jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0); if (jaguar_mainRom_crc32==0x6a7c7430) { - dsp_enabled=1; + dsp_enabled=true; } if (jaguar_mainRom_crc32==0x2f032271) { - dsp_enabled=1; + dsp_enabled=true; dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60); } @@ -752,14 +803,7 @@ void jaguar_init(void) #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(); @@ -768,144 +812,19 @@ void jaguar_init(void) 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 CPU_DEBUG +// for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++) +// WriteLog("\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i)); + uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7); + WriteLog("M68K: Top of stack: %08X. Stack trace:\n", jaguar_long_read(topOfStack)); + for(int i=0; i<10; i++) + WriteLog("%06X: %08X\n", topOfStack - (i * 4), jaguar_long_read(topOfStack - (i * 4))); +// WriteLog("Jaguar: CD BIOS version %04X\n", jaguar_word_read(0x3004)); + WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled"); + M68K_show_context(); +//#endif #ifdef SOUND_OUTPUT ws_audio_done(); #endif @@ -913,16 +832,31 @@ void jaguar_done(void) 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"); + if (jaguar_use_bios) + memcpy(jaguar_mainRam, jaguar_bootRom, 8); + else + { + SET32(jaguar_mainRam, 4, 0x00802000); + // Handle PD stuff... + // This should definitely go elsewhere (like in the cart load section)! + if (jaguar_mainRom[0] == 0x60 && jaguar_mainRom[1] == 0x1A) + { + uint32 runAddress = GET32(jaguar_mainRom, 0x2A); + uint32 progLength = GET32(jaguar_mainRom, 0x02); + WriteLog("Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength); + memcpy(jaguar_mainRam + runAddress, jaguar_mainRom + 0x2E, progLength); + SET32(jaguar_mainRam, 4, runAddress); + } + } + +// WriteLog("jaguar_reset():\n"); #ifdef SOUND_OUTPUT ws_audio_reset(); #endif @@ -932,16 +866,15 @@ void jaguar_reset(void) 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)); + WriteLog( "\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) +void jaguar_exec(int16 * backbuffer, bool render) { uint32 i, vblank_duration = tom_get_vdb(); @@ -965,11 +898,11 @@ void jaguar_exec(int16 * backbuffer, uint8 render) if (invalid_instruction_address != 0x80000000) cd_bios_process(invalid_instruction_address);*/ m68k_execute(m68k_cycles_per_scanline); - // No CD handling... Hmm... + // No CD handling... !!! FIX !!! cd_bios_exec(i); tom_pit_exec(m68k_cycles_per_scanline); - tom_exec_scanline(backbuffer, i, 0); + tom_exec_scanline(backbuffer, i, false); jerry_pit_exec(m68k_cycles_per_scanline); jerry_i2s_exec(m68k_cycles_per_scanline); gpu_exec(gpu_cycles_per_scanline); @@ -983,7 +916,7 @@ void jaguar_exec(int16 * backbuffer, uint8 render) if (invalid_instruction_address != 0x80000000) cd_bios_process(invalid_instruction_address);*/ m68k_execute(m68k_cycles_per_scanline); - // No CD handling... Hmm... + // No CD handling... !!! FIX !!! cd_bios_exec(i); tom_pit_exec(m68k_cycles_per_scanline); jerry_pit_exec(m68k_cycles_per_scanline); @@ -1009,10 +942,6 @@ void DumpMainMemory(void) return; fwrite(jaguar_mainRam, 1, 0x400000, fp); -// for(int i=0; i<0x400000; i++) -// fprintf(fp, "%c", jaguar_mainRam[i]); -// fputc(jaguar_mainRam[i], fp); - fclose(fp); } diff --git a/src/jerry.cpp b/src/jerry.cpp index 8b97e86..1aff37f 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -147,11 +147,7 @@ //#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; @@ -177,7 +173,7 @@ void jerry_i2s_exec(uint32 cycles) 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); + //WriteLog("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; @@ -186,14 +182,14 @@ void jerry_i2s_exec(uint32 cycles) { // 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); + //WriteLog("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"); + //WriteLog("i2s: reseting\n"); jerry_i2s_interrupt_divide = 8; jerry_i2s_interrupt_timer = -1; } @@ -206,7 +202,7 @@ void jerry_reset_timer_1(void) 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); +// WriteLog("jerry: reseting timer 1 to 0x%.8x (%i)\n",jerry_timer_1_counter,jerry_timer_1_counter); } void jerry_reset_timer_2(void) @@ -220,7 +216,7 @@ void jerry_reset_timer_2(void) 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); +// WriteLog("jerry: reseting timer 2 to 0x%.8x (%i)\n",jerry_timer_2_counter,jerry_timer_2_counter); } void jerry_pit_exec(uint32 cycles) @@ -244,54 +240,31 @@ void jerry_pit_exec(uint32 cycles) } } -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; - - // use real wave table dump -// JLH: Looks like this WT dump is in the wrong endian (For the Jaguar, that is)... -// memcpy(jerry_wave_rom, wave_table, 0x1000); - - // reverse byte ordering -// JLH: 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); - }*/ -// Why the need for an extra buffer to hold it, when it already exists in the form of wave_table??? -// Also, there was a memory leak, since it was never deallocated... (jerry_wave_rom) - - // Copy it to DSP RAM -//WAS: memcpy(&jerry_ram_8[0xD000], jerry_wave_rom, 0x1000); - memcpy(&jerry_ram_8[0xD000], wave_table, 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(); +//This should be handled with the cart initialization... +// eeprom_init(); + memory_malloc_secure((void **)&jerry_ram_8, 0x10000, "JERRY RAM/ROM"); + memcpy(&jerry_ram_8[0xD000], wave_table, 0x1000); + +/*for(int i=0; i<0x1000; i++) + WriteLog("WT byte, JERRY byte: %02X, %02X\n", wave_table[i], jerry_ram_8[0xD000+i]);//*/ } void jerry_reset(void) { - //fprintf(log_get(),"jerry_reset()\n"); + //WriteLog("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) + memset(jerry_ram_8, 0x00, 0xD000); // Don't clear out the Wavetable ROM...! + 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; @@ -303,7 +276,7 @@ void jerry_reset(void) void jerry_done(void) { - //fprintf(log_get(),"jerry_done()\n"); + //WriteLog("jerry_done()\n"); memory_free(jerry_ram_8); clock_done(); anajoy_done(); @@ -318,13 +291,13 @@ void jerry_done(void) unsigned jerry_byte_read(unsigned int offset) { #ifdef JERRY_DEBUG - fprintf(log_get(),"jerry: reading byte at 0x%.6x\n",offset); + WriteLog("JERRY: Reading byte at %06X\n", offset); #endif - if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) return dsp_byte_read(offset); - else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) return dsp_byte_read(offset); - else if ((offset >= 0xF10000) && (offset <= 0xF10007)) + else if (offset >= 0xF10000 && offset <= 0xF10007) { switch(offset & 0x07) { @@ -346,15 +319,15 @@ unsigned jerry_byte_read(unsigned int offset) return jerry_timer_2_divider & 0xFF; } } - else if ((offset >= 0xF10010) && (offset <= 0xf10015)) + else if (offset >= 0xF10010 && offset <= 0xf10015) return clock_byte_read(offset); - else if ((offset >= 0xF17C00) && (offset <= 0xF17C01)) + else if (offset >= 0xF17C00 && offset <= 0xF17C01) return anajoy_byte_read(offset); - else if ((offset >= 0xF14000) && (offset <= 0xF14003)) + else if (offset >= 0xF14000 && offset <= 0xF14003) { return joystick_byte_read(offset) | eeprom_byte_read(offset); } - else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF)) + else if (offset >= 0xF14000 && offset <= 0xF1A0FF) return eeprom_byte_read(offset); return jerry_ram_8[offset & 0xFFFF]; @@ -367,12 +340,12 @@ unsigned jerry_byte_read(unsigned int offset) unsigned jerry_word_read(unsigned int offset) { #ifdef JERRY_DEBUG - fprintf(log_get(),"jerry: reading word at 0x%.6x\n",offset); + WriteLog("JERRY: Reading word at %06X\n", offset); #endif - if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) return dsp_word_read(offset); - else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) return dsp_word_read(offset); else if ((offset >= 0xF10000) && (offset <= 0xF10007)) { @@ -397,7 +370,7 @@ unsigned jerry_word_read(unsigned int offset) return anajoy_word_read(offset); else if (offset == 0xF14000) { - //fprintf(log_get(),"reading 0x%.4x from 0xf14000\n"); + //WriteLog("reading 0x%.4x from 0xf14000\n"); return (joystick_word_read(offset) & 0xFFFE) | eeprom_word_read(offset); } else if ((offset >= 0xF14002) && (offset < 0xF14003)) @@ -410,10 +383,10 @@ unsigned jerry_word_read(unsigned int offset) if (offset==0x4002) return(0xffff);*/ -/* uint16 data = jerry_ram_8[offset+0]; - data <<= 8; - data |= jerry_ram_8[offset+1]; - return data;*/ +/*if (offset >= 0xF1D000) + WriteLog("JERRY: Reading word at %08X [%04X]...\n", offset, ((uint16)jerry_ram_8[(offset+0)&0xFFFF] << 8) | jerry_ram_8[(offset+1)&0xFFFF]);//*/ + + offset &= 0xFFFF; // Prevent crashing...! return ((uint16)jerry_ram_8[offset+0] << 8) | jerry_ram_8[offset+1]; } @@ -424,21 +397,21 @@ unsigned jerry_word_read(unsigned int offset) void jerry_byte_write(unsigned offset, unsigned data) { #ifdef JERRY_DEBUG - fprintf(log_get(),"jerry: writing byte %.2x at 0x%.6x\n",data,offset); + WriteLog("jerry: writing byte %.2x at 0x%.6x\n",data,offset); #endif - if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { dsp_byte_write(offset, data); return; } - else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { dsp_byte_write(offset, data); return; } else if ((offset >= 0xF1A152) && (offset <= 0xF1A153)) { -// fprintf(log_get(),"i2s: writing 0x%.2x to SCLK\n",data); +// WriteLog("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 @@ -488,6 +461,10 @@ void jerry_byte_write(unsigned offset, unsigned data) return; } +//Need to protect write attempts to Wavetable ROM (F1D000-FFF) + if (offset >= 0xF1D000 && offset <= 0xF1DFFF) + return; + jerry_ram_8[offset & 0xFFFF] = data; } @@ -498,22 +475,22 @@ void jerry_byte_write(unsigned offset, unsigned data) void jerry_word_write(unsigned offset, unsigned data) { #ifdef JERRY_DEBUG - fprintf(log_get(), "JERRY: Writing word %04X at %06X\n", data, offset); + WriteLog( "JERRY: Writing word %04X at %06X\n", data, offset); #endif - if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) { dsp_word_write(offset, data); return; } - else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) { dsp_word_write(offset, data); return; } else if (offset == 0xF1A152) { -// fprintf(log_get(),"i2s: writing 0x%.4x to SCLK\n",data); +// WriteLog("i2s: writing 0x%.4x to SCLK\n",data); jerry_i2s_interrupt_divide = data & 0xFF; jerry_i2s_interrupt_timer = -1; jerry_i2s_exec(0); @@ -568,6 +545,10 @@ void jerry_word_write(unsigned offset, unsigned data) return; } +//Need to protect write attempts to Wavetable ROM (F1D000-FFF) + if (offset >= 0xF1D000 && offset <= 0xF1DFFF) + 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 index b764bdd..07135cc 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -3,13 +3,13 @@ // // by cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/fixes by James L. Hammons // -#ifndef __PORT__ -#include "include/stdafx.h" -#include -#endif +//#ifndef __PORT__ +//#include "include/stdafx.h" +//#include +//#endif #include #include #include "SDLptc.h" @@ -21,10 +21,10 @@ void main_screen_switch(void); #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_s 4 +#define BUTTON_7 5 +#define BUTTON_4 6 +#define BUTTON_1 7 #define BUTTON_0 8 #define BUTTON_8 9 #define BUTTON_5 10 @@ -44,9 +44,16 @@ void main_screen_switch(void); static uint8 joystick_ram[4]; static uint8 joypad_0_buttons[21]; static uint8 joypad_1_buttons[21]; -extern uint8 finished; +extern bool finished; extern int start_logging; - +int gpu_start_log = 0; +int op_start_log = 0; +int blit_start_log = 0; +int effect_start = 0; +bool interactiveMode = false; +bool iLeft, iRight, iToggle = false; +bool keyHeld1 = false, keyHeld2 = false, keyHeld3 = false; +int objectPtr = 0; void joystick_init(void) { @@ -60,6 +67,10 @@ void joystick_exec(void) memset(joypad_0_buttons, 0, 21); memset(joypad_1_buttons, 0, 21); + gpu_start_log = 0; // Only log while key down! + effect_start = 0; + blit_start_log = 0; + iLeft = iRight = false; if ((keystate[SDLK_LALT]) & (keystate[SDLK_RETURN])) main_screen_switch(); @@ -70,9 +81,10 @@ void joystick_exec(void) 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; + // The buttons are labelled C,B,A on the controller (going from left to right) + if (keystate[SDLK_z]) joypad_0_buttons[BUTTON_C] = 0x01; if (keystate[SDLK_x]) joypad_0_buttons[BUTTON_B] = 0x01; - if (keystate[SDLK_c]) joypad_0_buttons[BUTTON_C] = 0x01; + if (keystate[SDLK_c]) joypad_0_buttons[BUTTON_A] = 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]) @@ -82,6 +94,41 @@ void joystick_exec(void) // if (keystate[SDLK_u]) jaguar_long_write(0xf1c384,jaguar_long_read(0xf1c384)+1); if (keystate[SDLK_d]) DumpMainMemory(); + if (keystate[SDLK_l]) + gpu_start_log = 1; + if (keystate[SDLK_o]) + op_start_log = 1; + if (keystate[SDLK_b]) + blit_start_log = 1; + if (keystate[SDLK_1]) + effect_start = 1; + + if (keystate[SDLK_i]) + interactiveMode = true; + + if (keystate[SDLK_8] && interactiveMode) + { + if (!keyHeld1) + objectPtr--, keyHeld1 = true; + } + else + keyHeld1 = false; + + if (keystate[SDLK_0] && interactiveMode) + { + if (!keyHeld2) + objectPtr++, keyHeld2 = true; + } + else + keyHeld2 = false; + + if (keystate[SDLK_9] && interactiveMode) + { + if (!keyHeld3) + iToggle = !iToggle, keyHeld3 = true; + } + else + keyHeld3 = false; if (keystate[SDLK_KP0]) joypad_0_buttons[BUTTON_0] = 0x01; if (keystate[SDLK_KP1]) joypad_0_buttons[BUTTON_1] = 0x01; @@ -95,7 +142,7 @@ void joystick_exec(void) if (keystate[SDLK_KP9]) joypad_0_buttons[BUTTON_9] = 0x01; if (keystate[SDLK_ESCAPE]) - finished = 1; + finished = true; /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com */ /* Joystick support */ @@ -152,6 +199,7 @@ void joystick_word_write(uint32 offset, uint16 data) uint8 joystick_byte_read(uint32 offset) { + extern bool hardwareTypeNTSC; offset &= 0x03; if (offset == 0) @@ -160,6 +208,7 @@ uint8 joystick_byte_read(uint32 offset) int pad0Index = joystick_ram[1] & 0x0F; int pad1Index = (joystick_ram[1] >> 4) & 0x0F; +// This is bad--we're assuming that a bit is set in the last case if (!(pad0Index & 0x01)) pad0Index = 0; else if (!(pad0Index & 0x02)) @@ -191,7 +240,8 @@ uint8 joystick_byte_read(uint32 offset) } else if (offset == 3) { - uint8 data = ((1 << 5) | (1 << 4) | 0x0F); +// uint8 data = ((1 << 5) | (1 << 4) | 0x0F); + uint8 data = 0x2F | (hardwareTypeNTSC ? 0x10 : 0x00); int pad0Index = joystick_ram[1] & 0x0F; //unused int pad1Index = (joystick_ram[1] >> 4) & 0x0F; diff --git a/src/log.cpp b/src/log.cpp index f748183..1730251 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -3,7 +3,7 @@ // // by cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/new stuff by James L. Hammons // #include "log.h" @@ -13,8 +13,10 @@ FILE * log_stream = NULL; int log_init(char * path) { log_stream = fopen(path, "wrt"); + if (log_stream == NULL) return 0; + return 1; } @@ -27,3 +29,18 @@ void log_done(void) { fclose(log_stream); } + +// +// This logger is used mainly to ensure that text gets written to the log file +// even if the program crashes. The performance hit is acceptable in this case! +// + +void WriteLog(const char * text, ...) +{ + va_list arg; + + va_start(arg, text); + vfprintf(log_stream, text, arg); + va_end(arg); + fflush(log_stream); // Make sure that text is written! +} diff --git a/src/m68k.h b/src/m68k.h index 4f4379b..b94eeae 100644 --- a/src/m68k.h +++ b/src/m68k.h @@ -162,7 +162,10 @@ 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); +unsigned int m68k_read_disassembler_32 (unsigned int address);//*/ +/*#define m68k_read_disassembler_8 m68k_read_memory_8 +#define m68k_read_disassembler_16 m68k_read_memory_16 +#define m68k_read_disassembler_32 m68k_read_memory_32//*/ /* Write to anywhere */ void m68k_write_memory_8(unsigned int address, unsigned int value); diff --git a/src/m68kconf.h b/src/m68kconf.h index 56402bf..5b750a7 100644 --- a/src/m68kconf.h +++ b/src/m68kconf.h @@ -130,8 +130,11 @@ int irq_ack_handler(int); /* If on, CPU will call the instruction hook callback before every * instruction. */ +void M68KInstructionHook(void); #define M68K_INSTRUCTION_HOOK OPT_OFF -#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function() +//#define M68K_INSTRUCTION_HOOK OPT_SPECIFY_HANDLER +//#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function() +#define M68K_INSTRUCTION_CALLBACK() M68KInstructionHook() /* If on, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ diff --git a/src/m68kdasmAG.cpp b/src/m68kdasmAG.cpp deleted file mode 100644 index 6b1ea91..0000000 --- a/src/m68kdasmAG.cpp +++ /dev/null @@ -1,2344 +0,0 @@ -/* - * 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/memory.cpp b/src/memory.cpp index 39376ca..f5bb2ff 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -73,11 +73,11 @@ 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); + WriteLog("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"); + WriteLog("Failed!\n"); log_done(); exit(0); } @@ -86,7 +86,7 @@ void memory_malloc_secure(void ** new_ptr, UINT32 size, char * info) if (currentAllocatedMemory > maximumAllocatedMemory) maximumAllocatedMemory = currentAllocatedMemory; *new_ptr = ptr; - fprintf(log_get(), "ok\n"); + WriteLog("OK\n"); } void memory_memoryUsage(FILE * fp) @@ -99,12 +99,12 @@ void memory_memoryUsage(FILE * fp) alias = alias->next; while (alias) { - fprintf(fp, "\t%16i bytes : <%s> (@ 0x%.8x)\n", alias->size, alias->info, alias->ptr); + fprintf(fp, "\t%16i bytes: <%s> (@ %08X)\n", (int)alias->size, alias->info, (unsigned int)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); + fprintf(fp, "\n\t%16i bytes total(%i Mb)\n", (int)total, (int)(total >> 20)); + fprintf(fp, "\n\t%16i bytes memory peak(%i Mb)\n", (int)maximumAllocatedMemory, (int)(maximumAllocatedMemory >> 20)); } void memory_done(void) diff --git a/src/objectp.cpp b/src/objectp.cpp index 792a850..4934892 100644 --- a/src/objectp.cpp +++ b/src/objectp.cpp @@ -3,7 +3,7 @@ // // by cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/fixes/rewrites by James L. Hammons // #include @@ -13,345 +13,941 @@ //#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 BLEND_Y(dst, src) op_blend_y[(((uint16)dst<<8)) | ((uint16)(src))] +#define BLEND_CR(dst, src) op_blend_cr[(((uint16)dst)<<8) | ((uint16)(src))] +//Delete this once we're rid of zbmpop*.h... +#define BLEND_CC(dst, src) op_blend_cr[(((uint16)dst)<<8) | ((uint16)(src))] + +#define OBJECT_TYPE_BITMAP 0 // 000 +#define OBJECT_TYPE_SCALE 1 // 001 +#define OBJECT_TYPE_GPU 2 // 010 +#define OBJECT_TYPE_BRANCH 3 // 011 +#define OBJECT_TYPE_STOP 4 // 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 +//Delete this once we're rid of zbmpop*.h... #define FLAGS_RELEASE 8 #define FLAGS_TRANSPARENT 4 #define FLAGS_READMODIFY 2 #define FLAGS_HFLIP 1 +#define OPFLAG_RELEASE 8 // Bus release bit +#define OPFLAG_TRANS 4 // Transparency bit +#define OPFLAG_RMW 2 // Read-Modify-Write bit +#define OPFLAG_REFLECT 1 // Horizontal mirror bit + +// Private function prototypes + +void OPProcessFixedBitmap(int scanline, uint64 p0, uint64 p1, bool render); +void OPProcessScaledBitmap(int scanline, uint64 p0, uint64 p1, uint64 p2, bool render); + +// External global variables + +extern uint32 jaguar_mainRom_crc32; + +// Local global variables + +static uint8 * op_blend_y; +static uint8 * op_blend_cr; +// There may be a problem with this "RAM" overlapping some of the +// regular TOM RAM... +static uint8 objectp_ram[0x40]; // This is based at $F00000 +uint8 objectp_running; +bool objectp_stop_reading_list; + 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 +// Object Processor initialization // +void op_init(void) +{ + // Blend tables (64K each) + memory_malloc_secure((void **)&op_blend_y, 0x10000, "Jaguar Object processor Y blend lookup table"); + memory_malloc_secure((void **)&op_blend_cr, 0x10000, "Jaguar Object processor CR blend lookup table"); + + // Here we calculate the saturating blend of a signed 4-bit value and an + // existing Cyan/Red value as well as a signed 8-bit value and an existing intensity... + // Note: CRY is 4 bits Cyan, 4 bits Red, 16 bits intensitY + for(int i=0; i<256*256; i++) + { + int y = (i >> 8) & 0xFF; + int dy = (INT8)i; // Sign extend the Y index + int c1 = (i >> 8) & 0x0F; + int dc1 = (INT8)(i << 4) >> 4; // Sign extend the R index + int c2 = (i >> 12) & 0x0F; + int dc2 = (INT8)(i & 0xF0) >> 4; // Sign extend the C index + + y += dy; + if (y < 0) + y = 0; + else if (y > 0xFF) + y = 0xFF; + op_blend_y[i] = y; + + c1 += dc1; + if (c1 < 0) + c1 = 0; + else if (c1 > 0x0F) + c1 = 0x0F; + c2 += dc2; + + if (c2 < 0) + c2 = 0; + else if (c2 > 0x0F) + c2 = 0x0F; + op_blend_cr[i] = (c2 << 4) | c1; + } + + op_reset(); +} -void op_process_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, int render) +// +// Object Processor reset +// +void op_reset(void) { - 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; + memset(objectp_ram, 0x00, 0x40); + objectp_running = 0; +} -//if (scanline == 200) -// fprintf(log_get(), "OP --> Current OPPtr: %08X, next: %08X, BMPPtr: %08X\n", op_pointer, link, ptr); +void op_done(void) +{ +} - op_pointer = link; +// +// Object Processor memory access +// Memory range: F00010 (F00008?) - F00027 +// +void op_byte_write(uint32 offset, uint8 data) +{ + offset &= 0x3F; + objectp_ram[offset] = data; +} - if (!render || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0)) - return; +void op_word_write(uint32 offset, uint16 data) +{ + offset &= 0x3F; +// objectp_ram[offset] = (data >> 8) & 0xFF; +// objectp_ram[offset+1] = data & 0xFF; + SET16(objectp_ram, offset, data); - if (iwidth == 0) - dwidth = iwidth = height; +/*if (offset == 0x20) +WriteLog("OP: Setting lo list pointer: %04X\n", data); +if (offset == 0x22) +WriteLog("OP: Setting hi list pointer: %04X\n", data);//*/ +} - 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; +uint8 op_byte_read(uint32 offset) +{ + offset &= 0x3F; + return objectp_ram[offset]; +} -#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 +uint16 op_word_read(uint32 offset) +{ +// return (objectp_ram[offset & 0x3F] << 8) | objectp_ram[(offset+1) & 0x3F]; + offset &= 0x3F; + return GET16(objectp_ram, offset); +} - if ((scanline < ypos) || (scanline > (ypos + height))) - return; +// 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 - // 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); +uint32 op_get_list_pointer(void) +{ + // Note: This register is LO / HI WORD, hence the funky look of this... +// return (objectp_ram[0x22] << 24) | (objectp_ram[0x23] << 16) | (objectp_ram[0x20] << 8) | objectp_ram[0x21]; + return GET16(objectp_ram, 0x20) | (GET16(objectp_ram, 0x22) << 16); +} - if (xpos < 0) - { - iwidth += xpos; - ptr += (pitch * op_bitmap_bit_size[bitdepth] * (-xpos)) >> 16; - xpos = 0; - } +// This is WRONG, since the OBF is only 16 bits wide!!! [FIXED] - if (iwidth <= 0) - { -#ifdef OP_DEBUG_BMP - fprintf(log_get(), "not rendering because iwidth <= 0\n"); -#endif +uint32 op_get_status_register(void) +{ +// return (objectp_ram[0x26] << 24) | (objectp_ram[0x27] << 16) | (objectp_ram[0x28] << 8) | objectp_ram[0x29]; +// return GET32(objectp_ram, 0x26); + return GET16(objectp_ram, 0x26); +} + +// This is WRONG, since the OBF is only 16 bits wide!!! [FIXED] + +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);*/ + objectp_ram[0x26] = (data & 0x0000FF00) >> 8; + objectp_ram[0x27] |= (data & 0xFE); +} + +void op_set_current_object(uint64 object) +{ +//Not sure this is right... Wouldn't it just be stored 64 bit BE? + // 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; +} + +uint64 op_load_phrase(uint32 offset) +{ + offset &= ~0x07; // 8 byte alignment + return ((uint64)jaguar_long_read(offset) << 32) | (uint64)jaguar_long_read(offset+4); +} + +// +// OP replacement functions +// + +void OPStorePhrase(uint32 offset, uint64 p) +{ + offset &= ~0x07; // 8 byte alignment + jaguar_long_write(offset, p >> 32); + jaguar_long_write(offset + 4, p & 0xFFFFFFFF); +} + +// +// *** NEW *** +// Object Processor main routine +// +void OPProcessList(int scanline, bool render) +{ +extern int op_start_log; +// char * condition_to_str[8] = +// { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" }; + +// If jaguar_exec() is working right, we should *never* have to check for this +// condition... + if (scanline < tom_get_vdb()) 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 (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb()) + return; - if ((xpos + iwidth) > scanline_width) - iwidth = scanline_width - xpos; - } + op_pointer = op_get_list_pointer(); - current_line_buffer += xpos * 2; // 2 in 16 bpp modes (need to take the mode into account) + objectp_stop_reading_list = false; - // doom switches the resolution from 320 to 160 to double the display width - // this is not yet supported - if (doom_hack) +// *** BEGIN OP PROCESSOR TESTING ONLY *** +extern bool interactiveMode; +extern bool iToggle; +extern int objectPtr; +bool inhibit; +int bitmapCounter = 0; +// *** END OP PROCESSOR TESTING ONLY *** + +// if (op_pointer) WriteLog(" new op list at 0x%.8x scanline %i\n",op_pointer,scanline); + while (op_pointer) { - while (iwidth) +// *** BEGIN OP PROCESSOR TESTING ONLY *** +if (interactiveMode && bitmapCounter == objectPtr) + inhibit = iToggle; +else + inhibit = false; +// *** END OP PROCESSOR TESTING ONLY *** + if (objectp_stop_reading_list) + return; + + uint64 p0 = op_load_phrase(op_pointer); + op_pointer += 8; +if (scanline == tom_get_vdb() && op_start_log) +{ +WriteLog("%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF)); +if ((p0 & 0x07) == OBJECT_TYPE_BITMAP) +{ +WriteLog(" (BITMAP) "); +uint64 p1 = op_load_phrase(op_pointer); +WriteLog("\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 = p1 & 0xFFF; +xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); + uint32 iwidth = ((p1 >> 28) & 0x3FF); + uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned! + uint16 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; +WriteLog("\n [%u (%u) x %u @ %i, %u (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", + iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&FLAGS_HFLIP ? "REFLECT " : ""), (flags&FLAGS_READMODIFY ? "RMW " : ""), (flags&FLAGS_TRANSPARENT ? "TRANS " : ""), (flags&FLAGS_RELEASE ? "RELEASE" : ""), idx, pitch); +} +if ((p0 & 0x07) == OBJECT_TYPE_SCALE) +{ +WriteLog(" (SCALED BITMAP)"); +uint64 p1 = op_load_phrase(op_pointer), p2 = op_load_phrase(op_pointer+8); +WriteLog("\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 = p1 & 0xFFF; +xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); + uint32 iwidth = ((p1 >> 28) & 0x3FF); + uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned! + uint16 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; +WriteLog("\n [%u (%u) x %u @ %i, %u (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", + iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&FLAGS_HFLIP ? "REFLECT " : ""), (flags&FLAGS_READMODIFY ? "RMW " : ""), (flags&FLAGS_TRANSPARENT ? "TRANS " : ""), (flags&FLAGS_RELEASE ? "RELEASE" : ""), idx, pitch); + uint32 hscale = p2 & 0xFF; + uint32 vscale = (p2 >> 8) & 0xFF; + uint32 remainder = (p2 >> 16) & 0xFF; +WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder); +} +if ((p0 & 0x07) == OBJECT_TYPE_GPU) +WriteLog(" (GPU)\n"); +if ((p0 & 0x07) == OBJECT_TYPE_BRANCH) +{ +WriteLog(" (BRANCH)\n"); +uint8 * jaguar_mainRam = GetRamPtr(); +WriteLog("[RAM] --> "); +for(int k=0; k<8; k++) + WriteLog("%02X ", jaguar_mainRam[op_pointer-8 + k]); +WriteLog("\n"); +} +if ((p0 & 0x07) == OBJECT_TYPE_STOP) +WriteLog(" --> List end\n"); +}//*/ + +// WriteLog("%08X type %i\n", op_pointer, (uint8)p0 & 0x07); + switch ((uint8)p0 & 0x07) { - 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) + case OBJECT_TYPE_BITMAP: { -#include "fbmpop1.h" + // Would *not* be /2 if interlaced...! + uint16 ypos = ((p0 >> 3) & 0x3FF) / 2; +// This is only theory implied by Rayman...! +// It seems that if the YPOS is zero, then bump the YPOS value so that it coincides with +// the VDB value. With interlacing, this would be slightly more tricky. +// There's probably another bit somewhere that enables this mode--but so far, doesn't seem +// to affect any other game in a negative way (that I've seen). +// Either that, or it's an undocumented bug... + if (ypos == 0) + ypos = tom_word_read(0xF00046) / 2; // Get the VDB value + uint32 height = (p0 & 0xFFC000) >> 14; + uint32 oldOPP = op_pointer - 8; +// *** BEGIN OP PROCESSOR TESTING ONLY *** +if (inhibit && op_start_log) + WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!!\n"); +bitmapCounter++; +if (!inhibit) // For OP testing only! +// *** END OP PROCESSOR TESTING ONLY *** + if (scanline >= ypos && height > 0) + { + uint64 p1 = op_load_phrase(op_pointer); + op_pointer += 8; +//WriteLog("OP: Writing scanline %d with ypos == %d...\n", scanline, ypos); +//WriteLog("--> Writing %u BPP bitmap...\n", op_bitmap_bit_depth[(p1 >> 12) & 0x07]); + OPProcessFixedBitmap(scanline, p0, p1, render); + + // OP write-backs + +//???Does this really happen??? Doesn't seem to work if you do this...! +// uint32 link = (p0 & 0x7FFFF000000) >> 21; +// SET16(objectp_ram, 0x20, link & 0xFFFF); // OLP +// SET16(objectp_ram, 0x22, link >> 16); +/* uint32 height = (p0 & 0xFFC000) >> 14; + if (height - 1 > 0) + height--;*/ + // NOTE: Would subtract 2 if in interlaced mode...! +// uint64 height = ((p0 & 0xFFC000) - 0x4000) & 0xFFC000; +// if (height) + height--; + + uint64 data = (p0 & 0xFFFFF80000000000) >> 40; + uint64 dwidth = (p1 & 0xFFC0000) >> 15; + data += dwidth; + + p0 &= ~0xFFFFF80000FFC000; // Mask out old data... + p0 |= (uint64)height << 14; + p0 |= data << 40; + OPStorePhrase(oldOPP, p0); + } + op_pointer = (p0 & 0x000007FFFF000000) >> 21; + break; } - else + case OBJECT_TYPE_SCALE: { -#include "fbmpop1p.h" + // Would *not* be /2 if interlaced...! + uint16 ypos = ((p0 >> 3) & 0x3FF) / 2; +// This is only theory implied by Rayman...! +// It seems that if the YPOS is zero, then bump the YPOS value so that it coincides with +// the VDB value. With interlacing, this would be slightly more tricky. +// There's probably another bit somewhere that enables this mode--but so far, doesn't seem +// to affect any other game in a negative way (that I've seen). +// Either that, or it's an undocumented bug... + if (ypos == 0) + ypos = tom_word_read(0xF00046) / 2; // Get the VDB value + uint32 height = (p0 & 0xFFC000) >> 14; + uint32 oldOPP = op_pointer - 8; +// *** BEGIN OP PROCESSOR TESTING ONLY *** +if (inhibit && op_start_log) + WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!!\n"); +bitmapCounter++; +if (!inhibit) // For OP testing only! +// *** END OP PROCESSOR TESTING ONLY *** + if (scanline >= ypos && height > 0) + { + uint64 p1 = op_load_phrase(op_pointer); + op_pointer += 8; + uint64 p2 = op_load_phrase(op_pointer); + op_pointer += 8; +//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, scanline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + OPProcessScaledBitmap(scanline, p0, p1, p2, render); + + // OP write-backs + +//???Does this really happen??? Doesn't seem to work if you do this...! +// uint32 link = (p0 & 0x7FFFF000000) >> 21; +// SET16(objectp_ram, 0x20, link & 0xFFFF); // OLP +// SET16(objectp_ram, 0x22, link >> 16); +/* uint32 height = (p0 & 0xFFC000) >> 14; + if (height - 1 > 0) + height--;*/ + // NOTE: Would subtract 2 if in interlaced mode...! +// uint64 height = ((p0 & 0xFFC000) - 0x4000) & 0xFFC000; + + uint8 remainder = p2 >> 16, vscale = p2 >> 8; + if (vscale == 0) + vscale = 0x20; // OP bug??? + + remainder -= 0x20; // 1.0f in [3.5] fixed point format + if (remainder & 0x80) // I.e., it's negative + { + uint64 data = (p0 & 0xFFFFF80000000000) >> 40; + uint64 dwidth = (p1 & 0xFFC0000) >> 15; + + while (remainder & 0x80) + { + remainder += vscale; + if (height) + height--; + + data += dwidth; + } + p0 &= ~0xFFFFF80000FFC000; // Mask out old data... + p0 |= (uint64)height << 14; + p0 |= data << 40; + OPStorePhrase(oldOPP, p0); + } + +//WriteLog(" [%08X%08X -> ", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + p2 &= ~0x0000000000FF0000; + p2 |= (uint64)remainder << 16; +//WriteLog("%08X%08X]\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + OPStorePhrase(oldOPP+16, p2); +//remainder = (uint8)(p2 >> 16), vscale = (uint8)(p2 >> 8); +//WriteLog(" [after]: rem=%02X, vscale=%02X\n", remainder, vscale); + } + op_pointer = (p0 & 0x000007FFFF000000) >> 21; + break; } - } - else if (op_bitmap_bit_depth[bitdepth] == 2) - { - if (pitch == 1) + case OBJECT_TYPE_GPU: { -#include "fbmpop2.h" + op_set_current_object(p0); + gpu_set_irq_line(3, 1); + break; } - else + case OBJECT_TYPE_BRANCH: { -#include "fbmpop2p.h" + uint16 ypos = (p0 >> 3) & 0x7FF; + uint8 cc = (p0 >> 14) & 0x03; + uint32 link = (p0 >> 21) & 0x3FFFF8; + +// if ((ypos!=507)&&(ypos!=25)) +// WriteLog("\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],ypos>>1,link); + switch (cc) + { + case CONDITION_EQUAL: + if (ypos != 0x7FF && (ypos & 0x01)) + ypos ^= 0x01; + if ((2 * tom_get_scanline()) == ypos || ypos == 0x7FF) + op_pointer = link; + break; + case CONDITION_LESS_THAN: + if ((2 * tom_get_scanline()) < ypos) + op_pointer = link; + break; + case CONDITION_GREATER_THAN: + if ((2 * tom_get_scanline()) > ypos) + op_pointer = link; + break; + case CONDITION_OP_FLAG_SET: + if (op_get_status_register() & 0x01) + op_pointer = link; + break; + case CONDITION_SECOND_HALF_LINE: + // This basically means branch if bit 10 of HC is set + WriteLog("OP: Unexpected CONDITION_SECOND_HALF_LINE in BRANCH object\nop: shuting down\n"); + fclose(log_get()); + exit(0); + break; + default: + WriteLog("OP: Unimplemented branch condition %i\n", cc); + } + break; } - } - else if (op_bitmap_bit_depth[bitdepth] == 4) - { - if (pitch == 1) + case OBJECT_TYPE_STOP: { -#include "fbmpop4.h" +//op_start_log = 0; + // unsure +//WriteLog("OP: --> STOP\n"); + 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)) + m68k_set_irq(7); // Cause an NMI to occur... + } + + return; + break; } - else - { -#include "fbmpop4p.h" + default: + WriteLog("op: unknown object type %i\n", ((uint8)p0 & 0x07)); + return; } } - else if (op_bitmap_bit_depth[bitdepth] == 8) +} + +// +// *** NEW *** +// Store fixed size bitmap in line buffer +// + +// Interesting thing about Rayman: There seems to be a transparent bitmap (1/8/16 bpp--which?) +// being rendered under his feet--doesn't align when walking... Check it out! + +void OPProcessFixedBitmap(int scanline, uint64 p0, uint64 p1, bool render) +{ +// Need to make sure that when writing that it stays within the line buffer... +// LBUF ($F01800 - $F01D9E) 360 x 32-bit RAM + uint8 depth = (p1 >> 12) & 0x07; // Color depth of image +//Why is HBlankWidthInPixels subtracted from this??? +// int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels(); + int32 xpos = ((int16)((p1 << 4) & 0xFFFF)) >> 4;// Image xpos in LBUF + uint32 iwidth = (p1 >> 28) & 0x3FF; // Image width in *phrases* + uint32 data = (p0 >> 40) & 0xFFFFF8; // Pixel data address +#ifdef OP_DEBUG_BMP +// Prolly should use this... Though not sure exactly how. + uint32 firstPix = (p1 >> 49) & 0x3F; +#endif +// We can ignore the RELEASE (high order) bit for now--probably forever...! +// uint8 flags = (p1 >> 45) & 0x0F; // REFLECT, RMW, TRANS, RELEASE +//Optimize: break these out to their own BOOL values + uint8 flags = (p1 >> 45) & 0x07; // REFLECT (0), RMW (1), TRANS (2) +// "For images with 1 to 4 bits/pixel the top 7 to 4 bits of the index +// provide the most significant bits of the palette address." + uint8 index = (p1 >> 37) & 0xFE; // CLUT index offset (upper pix, 1-4 bpp) + uint32 pitch = (p1 >> 15) & 0x07; // Phrase pitch + +// int16 scanlineWidth = tom_getVideoModeWidth(); + uint8 * tom_ram_8 = tom_get_ram_pointer(); + uint8 * paletteRAM = &tom_ram_8[0x400]; + // This is OK as long as it's used correctly: For 16-bit RAM to RAM direct copies--NOT + // for use when using endian-corrected data (i.e., any of the *_word_read functions!) + uint16 * paletteRAM16 = (uint16 *)paletteRAM; + +// WriteLog("bitmap %ix? %ibpp at %i,? firstpix=? data=0x%.8x pitch %i hflipped=%s dwidth=? (linked to ?) RMW=%s Tranparent=%s\n", +// iwidth, op_bitmap_bit_depth[bitdepth], xpos, ptr, pitch, (flags&FLAGS_HFLIP ? "yes" : "no"), (flags&FLAGS_READMODIFY ? "yes" : "no"), (flags&FLAGS_TRANSPARENT ? "yes" : "no")); + +// Is it OK to have a 0 for the data width??? (i.e., undocumented?) +// Seems to be... Seems that dwidth *can* be zero (i.e., reuse same line) as well. +// Pitch == 0 is OK too... +// if (!render || op_pointer == 0 || dwidth == 0 || ptr == 0 || pitch == 0) +//I'm not convinced that we need to concern ourselves with data & op_pointer here either! + if (!render || iwidth == 0) // || data == 0 || op_pointer == 0) + return; + +//#define OP_DEBUG_BMP +//#ifdef OP_DEBUG_BMP +// WriteLog("bitmap %ix%i %ibpp at %i,%i firstpix=%i data=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 + + int32 phraseWidthToPixels[8] = { 64, 32, 16, 8, 4, 2, 0, 0 }; + int32 leftMargin = xpos, rightMargin = (xpos + (phraseWidthToPixels[depth] * iwidth)) - 1; + uint32 clippedWidth = 0, phraseClippedWidth = 0;//, phrasePixel = 0; + bool in24BPPMode = (((GET16(tom_ram_8, 0x0028) >> 1) & 0x03) == 1 ? true : false); // VMODE + // Not sure if this is Jaguar Two only location or what... + // From the docs, it is... If we want to limit here we should think of something else. +// int32 limit = GET16(tom_ram_8, 0x0008); // LIMIT + int32 limit = 720; + int32 lbufWidth = (!in24BPPMode ? limit - 1 : (limit / 2) - 1); // Zero based limit... + + // If the image is completely to the left or right of the line buffer, then bail. +//If in REFLECT mode, then these values are swapped! !!! FIX !!! [DONE] +//There are four possibilities: +// 1. image sits on left edge and no REFLECT; starts out of bounds but ends in bounds. +// 2. image sits on left edge and REFLECT; starts in bounds but ends out of bounds. +// 3. image sits on right edge and REFLECT; starts out of bounds but ends in bounds. +// 4. image sits on right edge and no REFLECT; starts in bounds but ends out of bounds. +//Numbers 2 & 4 can be caught by checking the LBUF clip while in the inner loop, +// numbers 1 & 3 are of concern. +// This *indirectly* handles only cases 2 & 4! And is WRONG is REFLECT is set...! +// if (rightMargin < 0 || leftMargin > lbufWidth) + +// It might be easier to swap these (if REFLECTed) and just use XPOS down below... +// That way, you could simply set XPOS to leftMargin if !REFLECT and to rightMargin otherwise. +// Still have to be careful with the DATA and IWIDTH values though... + + if ((!(flags & OPFLAG_REFLECT) && (rightMargin < 0 || leftMargin > lbufWidth)) + || ((flags & OPFLAG_REFLECT) && (leftMargin < 0 || rightMargin > lbufWidth))) + return; + + // Otherwise, find the clip limits and clip the phrase as well... + // NOTE: I'm fudging here by letting the actual blit overstep the bounds of the + // line buffer, but it shouldn't matter since there are two unused line + // buffers below and nothing above and I'll at most write 8 bytes outside + // the line buffer... I could use a fractional clip begin/end value, but + // this makes the blit a *lot* more hairy. I might fix this in the future + // if it becomes necessary. (JLH) + // Probably wouldn't be *that* hairy. Just use a delta that tells the inner loop + // which pixel in the phrase is being written, and quit when either end of phrases + // is reached or line buffer extents are surpassed. + +//This stuff is probably wrong as well... !!! FIX !!! +//The strange thing is that it seems to work, but that's no guarantee that it's bulletproof! +//Yup. Seems that JagMania doesn't work correctly with this... +//Dunno if this is the problem, but Atari Karts is showing *some* of the road now... + if (leftMargin < 0) + clippedWidth = 0 - leftMargin, + phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth], + leftMargin = 0 - (clippedWidth % phraseWidthToPixels[depth]); +// leftMargin = 0; + + if (rightMargin > lbufWidth) + clippedWidth = rightMargin - lbufWidth, + phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth], + rightMargin = lbufWidth + (clippedWidth % phraseWidthToPixels[depth]); +// rightMargin = lbufWidth; + + // If the image is sitting on the line buffer left or right edge, we need to compensate + // by decreasing the image phrase width accordingly. + iwidth -= phraseClippedWidth; + + // Also, if we're clipping the phrase we need to make sure we're in the correct part of + // the pixel data. + data += phraseClippedWidth * (pitch << 3); + + // NOTE: When the bitmap is in REFLECT mode, the XPOS marks the *right* side of the + // bitmap! This makes clipping & etc. MUCH, much easier...! + uint32 lbufAddress = 0x1800 + (!in24BPPMode ? leftMargin * 2 : leftMargin * 4); + uint8 * currentLineBuffer = &tom_ram_8[lbufAddress]; + + // Render. + +// Hmm. We check above for 24 BPP mode, but don't do anything about it below... +// If we *were* in 24 BPP mode, how would you convert CRY to RGB24? Seems to me +// that if you're in CRY mode then you wouldn't be able to use 24 BPP bitmaps +// anyway. + + if (depth == 0) // 1 BPP { - if (pitch == 1) +// uint32 paletteIndex = index << 1; + // The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 5) | 0x02; + + while (iwidth--) { -#include "fbmpop8.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<64; i++) + { + uint8 bit = pixels >> 63; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--this *won't* work... + if ((flags & OPFLAG_TRANS) && bit == 0) + ; // Do nothing... + else + { + if (!(flags & OPFLAG_RMW)) +//Optimize: Set palleteRAM16 to beginning of palette RAM + index*2 and use only [bit] as index... + *(uint16 *)currentLineBuffer = paletteRAM16[index | bit]; + else + *currentLineBuffer = + BLEND_CR(*currentLineBuffer, paletteRAM[(index | bit) << 1]), + *(currentLineBuffer + 1) = + BLEND_Y(*(currentLineBuffer + 1), paletteRAM[((index | bit) << 1) + 1]); + } + + currentLineBuffer += lbufDelta; + pixels <<= 1; + } } - else + } + else if (depth == 1) // 2 BPP + { + index &= 0xFC; // Top six bits form CLUT index + // The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 5) | 0x02; + + while (iwidth--) { -#include "fbmpop8p.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<32; i++) + { + uint8 bits = pixels >> 62; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--this *won't* work... + if ((flags & OPFLAG_TRANS) && bits == 0) + ; // Do nothing... + else + { + if (!(flags & OPFLAG_RMW)) + *(uint16 *)currentLineBuffer = paletteRAM16[index | bits]; + else + *currentLineBuffer = + BLEND_CR(*currentLineBuffer, paletteRAM[(index | bits) << 1]), + *(currentLineBuffer + 1) = + BLEND_Y(*(currentLineBuffer + 1), paletteRAM[((index | bits) << 1) + 1]); + } + + currentLineBuffer += lbufDelta; + pixels <<= 2; + } } } - else if (op_bitmap_bit_depth[bitdepth] == 16) + else if (depth == 2) // 4 BPP { - if (pitch == 1) + index &= 0xF0; // Top four bits form CLUT index + // The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 5) | 0x02; + + while (iwidth--) { -#include "fbmpop16.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<16; i++) + { + uint8 bits = pixels >> 60; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--this *won't* work... + if ((flags & OPFLAG_TRANS) && bits == 0) + ; // Do nothing... + else + { + if (!(flags & OPFLAG_RMW)) + *(uint16 *)currentLineBuffer = paletteRAM16[index | bits]; + else + *currentLineBuffer = + BLEND_CR(*currentLineBuffer, paletteRAM[(index | bits) << 1]), + *(currentLineBuffer + 1) = + BLEND_Y(*(currentLineBuffer + 1), paletteRAM[((index | bits) << 1) + 1]); + } + + currentLineBuffer += lbufDelta; + pixels <<= 4; + } } - else + } + else if (depth == 3) // 8 BPP + { + // The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 5) | 0x02; + + while (iwidth--) { -#include "fbmpop16p.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<8; i++) + { + uint8 bits = pixels >> 56; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--this *won't* work... + if ((flags & OPFLAG_TRANS) && bits == 0) + ; // Do nothing... + else + { + if (!(flags & OPFLAG_RMW)) + *(uint16 *)currentLineBuffer = paletteRAM16[bits]; + else + *currentLineBuffer = + BLEND_CR(*currentLineBuffer, paletteRAM[bits << 1]), + *(currentLineBuffer + 1) = + BLEND_Y(*(currentLineBuffer + 1), paletteRAM[(bits << 1) + 1]); + } + + currentLineBuffer += lbufDelta; + pixels <<= 8; + } } } - else if (op_bitmap_bit_depth[bitdepth] == 24) + else if (depth == 4) // 16 BPP { - if (pitch == 1) + // The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 5) | 0x02; + + while (iwidth--) { -#include "fbmpop24.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<4; i++) + { + uint8 bitsHi = pixels >> 56, bitsLo = pixels >> 48; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--it *won't* work... + if ((flags & OPFLAG_TRANS) && (bitsLo | bitsHi) == 0) + ; // Do nothing... + else + { + if (!(flags & OPFLAG_RMW)) + *currentLineBuffer = bitsHi, + *(currentLineBuffer + 1) = bitsLo; + else + *currentLineBuffer = + BLEND_CR(*currentLineBuffer, bitsHi), + *(currentLineBuffer + 1) = + BLEND_Y(*(currentLineBuffer + 1), bitsLo); + } + + currentLineBuffer += lbufDelta; + pixels <<= 16; + } } - else + } + else if (depth == 5) // 24 BPP + { +WriteLog("OP: Writing 24 BPP bitmap!\n"); + // Not sure, but I think RMW only works with 16 BPP and below, and only in CRY mode... + // The LSB is OPFLAG_REFLECT, so sign extend it and or 4 into it. + int32 lbufDelta = ((int8)((flags << 7) & 0xFF) >> 4) | 0x04; + + while (iwidth--) { -#include "fbmpop24p.h" + // Fetch phrase... + uint64 pixels = ((uint64)jaguar_long_read(data) << 32) | jaguar_long_read(data + 4); + data += pitch << 3; // Multiply pitch * 8 (optimize: precompute this value) + + for(int i=0; i<2; i++) + { + uint8 bits3 = pixels >> 56, bits2 = pixels >> 48, + bits1 = pixels >> 40, bits0 = pixels >> 32; +// Seems to me that both of these are in the same endian, so we could cast it as +// uint16 * and do straight across copies (what about 24 bpp? Treat it differently...) +// This only works for the palettized modes (1 - 8 BPP), since we actually have to +// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?) +// No, it isn't because we read the memory in an endian safe way--it *won't* work... + if ((flags & OPFLAG_TRANS) && (bits3 | bits2 | bits1 | bits0) == 0) + ; // Do nothing... + else + *currentLineBuffer = bits3, + *(currentLineBuffer + 1) = bits2, + *(currentLineBuffer + 2) = bits1, + *(currentLineBuffer + 3) = bits0; + + currentLineBuffer += lbufDelta; + pixels <<= 32; + } } } } // -// Object Processor scaled bitmap processing +// *** NEW *** +// Store scaled bitmap in line buffer // - -void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, uint64 p2, int render) +void OPProcessScaledBitmap(int scanline, uint64 p0, uint64 p1, uint64 p2, bool 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 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; + uint16 dwidth = ((p1 >> 18) & 0x3FF) * 4; // Unsigned! +// uint16 height = (p0 >> 14) & 0x3FF; // Unsigned! +// uint32 link = ((p0 >> 24) & 0x7FFFF) << 3; + uint32 ptr = (p0 >> 40) & 0xFFFFF8; //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; + uint32 vscale_fixed3p5 = (p2 >> 8) & 0xFF; + uint32 hscale_fixed3p5 = p2 & 0xFF; + float vscale = (float)vscale_fixed3p5 / 32.0f, hscale = (float)hscale_fixed3p5 / 32.0f; - if (jaguar_mainRom_crc32==0x5a5b9c68) // atari karts +//No hacks! +/* 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", + WriteLog("[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; +//No hacks! +/* if (jaguar_mainRom_crc32==0x2f032271) + ypos += 8;*/ - if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0)) + if (!render || 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; - } + if (bitdepth <= 3) // 1, 2, 4, 8 BPP + iwidth *= 2, dwidth *= 2; - uint16 scaled_width = (uint16)((float)iwidth * hscale), - scaled_height = (uint16)((float)height * vscale); + uint16 scaled_width = (uint16)((float)iwidth * hscale); if (op_bitmap_bit_depth[bitdepth] == 4) // why ? scaled_width *= 2; @@ -362,18 +958,12 @@ void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint6 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)) +/* if ((scanline < ypos) || (scanline > (ypos + scaled_height)) || ((xpos + scaled_width) < 0) + || (xpos >= scanline_width))*/ + if ((xpos + scaled_width) < 0 || xpos >= scanline_width) return; - + if (xpos < 0) { scaled_width += xpos; @@ -381,24 +971,24 @@ void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint6 xpos = 0; } - if (iwidth<=0) + if (iwidth <= 0) return; - if (flags&FLAGS_HFLIP) + if (flags & FLAGS_HFLIP) { - if ((xpos<0)||((xpos-scaled_width)>=scanline_width)) + if (xpos < 0 || (xpos-scaled_width) >= scanline_width) return; - if ((xpos-scaled_width)<0) - scaled_width=xpos; + if ((xpos - scaled_width) < 0) + scaled_width = xpos; } else { - if (((xpos+scaled_width)<0)||(xpos>=scanline_width)) + if ((xpos + scaled_width) < 0 || xpos >= scanline_width) return; - if ((xpos+scaled_width)>scanline_width) - scaled_width=scanline_width-xpos; + if ((xpos + scaled_width) > scanline_width) + scaled_width = scanline_width-xpos; } current_line_buffer += xpos * 2; @@ -462,326 +1052,5 @@ void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint6 } } 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; + WriteLog("(unimplemented) %i bpp scaled bitmap\n",op_bitmap_bit_depth[bitdepth]); } diff --git a/src/pcm.cpp b/src/pcm.cpp index ad49706..846dfc9 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -60,8 +60,8 @@ void pcm_updateOne(int channel, int16 * data, uint32 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"); + 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(); #ifdef PCM_DUMP fp_left = fopen("leftdac.raw", "wb"); diff --git a/src/tom.cpp b/src/tom.cpp index c98916a..3cfd290 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -43,7 +43,7 @@ // 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------- (BGEN - clear line buffer to BG color) // W -------- -x------ (CSYNC - enable composite sync on VSYNC) // W -------- --x----- (BINC - local border color if INCEN) // W -------- ---x---- (INCEN - encrustation enable) @@ -136,10 +136,114 @@ // F0211C W -------- -------x G_DIVCTRL - divide unit control // W -------- -------x (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide) // ------------------------------------------------------------ +// BLITTER REGISTERS +// ------------------------------------------------------------ +// F02200-F022FF R/W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx Blitter registers +// F02200 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_BASE - A1 base register +// F02204 W -------- ---xxxxx -xxxxxxx xxxxx-xx A1_FLAGS - A1 flags register +// W -------- ---x---- -------- -------- (YSIGNSUB - invert sign of Y delta) +// W -------- ----x--- -------- -------- (XSIGNSUB - invert sign of X delta) +// W -------- -----x-- -------- -------- (Y add control) +// W -------- ------xx -------- -------- (X add control) +// W -------- -------- -xxxxxx- -------- (width in 6-bit floating point) +// W -------- -------- -------x xx------ (ZOFFS1-6 - Z data offset) +// W -------- -------- -------- --xxx--- (PIXEL - pixel size) +// W -------- -------- -------- ------xx (PITCH1-4 - data phrase pitch) +// F02208 W -xxxxxxx xxxxxxxx -xxxxxxx xxxxxxxx A1_CLIP - A1 clipping size +// W -xxxxxxx xxxxxxxx -------- -------- (height) +// W -------- -------- -xxxxxxx xxxxxxxx (width) +// F0220C R/W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_PIXEL - A1 pixel pointer +// R/W xxxxxxxx xxxxxxxx -------- -------- (Y pixel value) +// R/W -------- -------- xxxxxxxx xxxxxxxx (X pixel value) +// F02210 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_STEP - A1 step value +// W xxxxxxxx xxxxxxxx -------- -------- (Y step value) +// W -------- -------- xxxxxxxx xxxxxxxx (X step value) +// F02214 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_FSTEP - A1 step fraction value +// W xxxxxxxx xxxxxxxx -------- -------- (Y step fraction value) +// W -------- -------- xxxxxxxx xxxxxxxx (X step fraction value) +// F02218 R/W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_FPIXEL - A1 pixel pointer fraction +// R/W xxxxxxxx xxxxxxxx -------- -------- (Y pixel fraction value) +// R/W -------- -------- xxxxxxxx xxxxxxxx (X pixel fraction value) +// F0221C W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_INC - A1 increment +// W xxxxxxxx xxxxxxxx -------- -------- (Y increment) +// W -------- -------- xxxxxxxx xxxxxxxx (X increment) +// F02220 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A1_FINC - A1 increment fraction +// W xxxxxxxx xxxxxxxx -------- -------- (Y increment fraction) +// W -------- -------- xxxxxxxx xxxxxxxx (X increment fraction) +// F02224 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A2_BASE - A2 base register +// F02228 W -------- ---xxxxx -xxxxxxx xxxxx-xx A2_FLAGS - A2 flags register +// W -------- ---x---- -------- -------- (YSIGNSUB - invert sign of Y delta) +// W -------- ----x--- -------- -------- (XSIGNSUB - invert sign of X delta) +// W -------- -----x-- -------- -------- (Y add control) +// W -------- ------xx -------- -------- (X add control) +// W -------- -------- -xxxxxx- -------- (width in 6-bit floating point) +// W -------- -------- -------x xx------ (ZOFFS1-6 - Z data offset) +// W -------- -------- -------- --xxx--- (PIXEL - pixel size) +// W -------- -------- -------- ------xx (PITCH1-4 - data phrase pitch) +// F0222C W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A2_MASK - A2 window mask +// F02230 R/W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A2_PIXEL - A2 pixel pointer +// R/W xxxxxxxx xxxxxxxx -------- -------- (Y pixel value) +// R/W -------- -------- xxxxxxxx xxxxxxxx (X pixel value) +// F02234 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx A2_STEP - A2 step value +// W xxxxxxxx xxxxxxxx -------- -------- (Y step value) +// W -------- -------- xxxxxxxx xxxxxxxx (X step value) +// F02238 W -xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_CMD - command register +// W -x------ -------- -------- -------- (SRCSHADE - modify source intensity) +// W --x----- -------- -------- -------- (BUSHI - hi priority bus) +// W ---x---- -------- -------- -------- (BKGWREN - writeback destination) +// W ----x--- -------- -------- -------- (DCOMPEN - write inhibit from data comparator) +// W -----x-- -------- -------- -------- (BCOMPEN - write inhibit from bit coparator) +// W ------x- -------- -------- -------- (CMPDST - compare dest instead of src) +// W -------x xxx----- -------- -------- (logical operation) +// W -------- ---xxx-- -------- -------- (ZMODE - Z comparator mode) +// W -------- ------x- -------- -------- (ADDDSEL - select sum of src & dst) +// W -------- -------x -------- -------- (PATDSEL - select pattern data) +// W -------- -------- x------- -------- (TOPNEN - enable carry into top intensity nibble) +// W -------- -------- -x------ -------- (TOPBEN - enable carry into top intensity byte) +// W -------- -------- --x----- -------- (ZBUFF - enable Z updates in inner loop) +// W -------- -------- ---x---- -------- (GOURD - enable gouraud shading in inner loop) +// W -------- -------- ----x--- -------- (DSTA2 - reverses A2/A1 roles) +// W -------- -------- -----x-- -------- (UPDA2 - add A2 step to A2 in outer loop) +// W -------- -------- ------x- -------- (UPDA1 - add A1 step to A1 in outer loop) +// W -------- -------- -------x -------- (UPDA1F - add A1 fraction step to A1 in outer loop) +// W -------- -------- -------- x------- (diagnostic use) +// W -------- -------- -------- -x------ (CLIP_A1 - clip A1 to window) +// W -------- -------- -------- --x----- (DSTWRZ - enable dest Z write in inner loop) +// W -------- -------- -------- ---x---- (DSTENZ - enable dest Z read in inner loop) +// W -------- -------- -------- ----x--- (DSTEN - enables dest data read in inner loop) +// W -------- -------- -------- -----x-- (SRCENX - enable extra src read at start of inner) +// W -------- -------- -------- ------x- (SRCENZ - enables source Z read in inner loop) +// W -------- -------- -------- -------x (SRCEN - enables source data read in inner loop) +// F02238 R xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_CMD - status register +// R xxxxxxxx xxxxxxxx -------- -------- (inner count) +// R -------- -------- xxxxxxxx xxxxxx-- (diagnostics) +// R -------- -------- -------- ------x- (STOPPED - when stopped in collision detect) +// R -------- -------- -------- -------x (IDLE - when idle) +// F0223C W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_COUNT - counters register +// W xxxxxxxx xxxxxxxx -------- -------- (outer loop count) +// W -------- -------- xxxxxxxx xxxxxxxx (inner loop count) +// F02240-F02247 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_SRCD - source data register +// F02248-F0224F W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_DSTD - destination data register +// F02250-F02257 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_DSTZ - destination Z register +// F02258-F0225F W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_SRCZ1 - source Z register 1 +// F02260-F02267 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_SRCZ2 - source Z register 2 +// F02268-F0226F W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_PATD - pattern data register +// F02270 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_IINC - intensity increment +// F02274 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_ZINC - Z increment +// F02278 W -------- -------- -------- -----xxx B_STOP - collision control +// W -------- -------- -------- -----x-- (STOPEN - enable blitter collision stops) +// W -------- -------- -------- ------x- (ABORT - abort after stop) +// W -------- -------- -------- -------x (RESUME - resume after stop) +// F0227C W -------- xxxxxxxx xxxxxxxx xxxxxxxx B_I3 - intensity 3 +// F02280 W -------- xxxxxxxx xxxxxxxx xxxxxxxx B_I2 - intensity 2 +// F02284 W -------- xxxxxxxx xxxxxxxx xxxxxxxx B_I1 - intensity 1 +// F02288 W -------- xxxxxxxx xxxxxxxx xxxxxxxx B_I0 - intensity 0 +// F0228C W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_Z3 - Z3 +// F02290 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_Z2 - Z2 +// F02294 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_Z1 - Z1 +// F02298 W xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx B_Z0 - Z0 +// ------------------------------------------------------------ -#ifndef __PORT__ -#include -#endif #include #include "SDLptc.h" #include "tom.h" @@ -147,59 +251,23 @@ #include "objectp.h" #include "cry2rgb.h" +// TOM registers (offset from $F00000) -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 HC 0x04 #define VMODE 0x28 -#define HP 0x2E +#define MODE 0x0006 // Line buffer to video generator mode +#define BGEN 0x0080 // Background enable (CRY & RGB16 only) +#define VARMOD 0x0100 // Mixed CRY/RGB16 mode +#define PWIDTH 0x0E00 // Pixel width in video clock cycles +#define HP 0x2E // Values range from 1 - 1024 (value written + 1) #define HBB 0x30 #define HBE 0x32 -#define HDB 0x38 +#define HDB1 0x38 +#define HDB2 0x3A #define HDE 0x3C -#define VP 0x3E +#define VP 0x3E // Value ranges from 1 - 2048 (value written + 1) #define VBB 0x40 #define VBE 0x42 #define VS 0x44 @@ -207,24 +275,37 @@ static uint8 * tom_ram_8; #define VDE 0x48 #define BG 0x58 +//This can be defined in the makefile as well... +//(It's easier to do it here...) +//#define TOM_DEBUG -uint32 tom_width, tom_height, tom_real_internal_width; +extern uint32 jaguar_mainRom_crc32; +extern Console console; +extern Surface * surface; +extern uint8 objectp_running; +static uint8 * tom_ram_8; +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; +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; 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; + { "16 bpp CRY", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB", + "Mixed mode", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB" }; typedef void (render_xxx_scanline_fn)(int16 *); +// Private function prototypes + void tom_render_16bpp_cry_scanline(int16 * backbuffer); void tom_render_24bpp_scanline(int16 * backbuffer); void tom_render_16bpp_direct_scanline(int16 * backbuffer); @@ -248,6 +329,7 @@ render_xxx_scanline_fn * scanline_render_normal[]= tom_render_16bpp_direct_scanline, tom_render_16bpp_rgb_scanline, }; + render_xxx_scanline_fn * scanline_render_stretch[]= { tom_render_16bpp_cry_stretch_scanline, @@ -259,35 +341,17 @@ render_xxx_scanline_fn * scanline_render_stretch[]= 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; +render_xxx_scanline_fn * scanline_render[8]; -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"); + memory_malloc_secure((void **)&tom_cry_rgb_mix_lut, 2 * 0x10000, "CRY/RGB mixed mode LUT"); for (uint32 i=0; i<0x10000; i++) { - uint16 color=i; + uint16 color = i; if (color & 0x01) { @@ -296,13 +360,12 @@ void tom_calc_cry_rgb_mix_lut(void) } 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); + uint32 chrm = (color & 0xF000) >> 12, + chrl = (color & 0x0F00) >> 8, + y = color & 0x00FF; + uint16 red = (((uint32)redcv[chrm][chrl]) * y) >> 11, + green = (((uint32)greencv[chrm][chrl]) * y) >> 11, + blue = (((uint32)bluecv[chrm][chrl]) * y) >> 11; color = (red << 10) | (green << 5) | blue; } tom_cry_rgb_mix_lut[i] = color; @@ -338,224 +401,130 @@ 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 vmode = GET16(tom_ram_8, VMODE); + return ((vmode & VARMOD) >> 6) | ((vmode & MODE) >> 1); } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// uint16 tom_get_scanline(void) { return tom_scanline; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// -uint16 tom_get_hdb(void) + +/*uint16 tom_get_hdb(void) { -// return SWAP_16(HDB); - return GET16(HDB); -} -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + return GET16(tom_ram_8, HDB); +}*/ + uint16 tom_get_vdb(void) { -// return SWAP_16(VBE); - return GET16(VBE); + return GET16(tom_ram_8, VBE); } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// 16 BPP CRY/RGB mixed mode rendering // -////////////////////////////////////////////////////////////////////////////// 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]; + uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800]; while (width) { - uint16 color; - color = *current_line_buffer++; - color <<= 8; + uint16 color = (*current_line_buffer++) << 8; color |= *current_line_buffer++; *backbuffer++ = tom_cry_rgb_mix_lut[color]; width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// 16 BPP CRY mode rendering // -////////////////////////////////////////////////////////////////////////////// -void tom_render_16bpp_cry_scanline(int16 *backbuffer) +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]; - 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++; + uint16 color = (*current_line_buffer++) << 8; + color |= *current_line_buffer++; - chrm = (color & 0xF000) >> 12; - chrl = (color & 0x0F00) >> 8; - y = (color & 0x00FF); + uint32 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 red = (((uint32)redcv[chrm][chrl]) * y) >> 11, + green = (((uint32)greencv[chrm][chrl]) * y) >> 11, + blue = (((uint32)bluecv[chrm][chrl]) * y) >> 11; - *backbuffer++=(red<<10)|(green<<5)|blue; + *backbuffer++ = (red << 10) | (green << 5) | blue; width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// 24 BPP mode rendering // -////////////////////////////////////////////////////////////////////////////// -void tom_render_24bpp_scanline(int16 *backbuffer) +void tom_render_24bpp_scanline(int16 * backbuffer) { - uint16 width=tom_width; - uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + 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; + uint16 green = (*current_line_buffer++) >> 3; + uint16 red = (*current_line_buffer++) >> 3; + current_line_buffer++; + uint16 blue = (*current_line_buffer++) >> 3; + *backbuffer++ = (red << 10) | (green << 5) | blue; width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// 16 BPP direct mode rendering // -////////////////////////////////////////////////////////////////////////////// -void tom_render_16bpp_direct_scanline(int16 *backbuffer) +void tom_render_16bpp_direct_scanline(int16 * backbuffer) { - uint16 width=tom_width; - uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + 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; + uint16 color = (*current_line_buffer++) << 8; + color |= *current_line_buffer++; + *backbuffer++ = color >> 1; width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// 16 BPP RGB mode rendering // -////////////////////////////////////////////////////////////////////////////// -void tom_render_16bpp_rgb_scanline(int16 *backbuffer) +void tom_render_16bpp_rgb_scanline(int16 * backbuffer) { - uint16 width=tom_width; - uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800]; + 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; + uint16 color = (*current_line_buffer++) << 8; + color = (color | *current_line_buffer++) >> 1; + color = (color&0x7C00) | ((color&0x03E0) >> 5) | ((color&0x001F) << 5); + *backbuffer++ = color; width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + +// This stuff may just go away by itself, especially if we do some +// good old OpenGL goodness... + 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]; @@ -570,16 +539,7 @@ void tom_render_16bpp_cry_rgb_mix_stretch_scanline(int16 *backbuffer) width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void tom_render_16bpp_cry_stretch_scanline(int16 *backbuffer) { uint32 chrm, chrl, y; @@ -623,16 +583,7 @@ void tom_render_16bpp_cry_stretch_scanline(int16 *backbuffer) width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void tom_render_24bpp_stretch_scanline(int16 *backbuffer) { uint16 width=tom_width; @@ -642,7 +593,7 @@ void tom_render_24bpp_stretch_scanline(int16 *backbuffer) { uint16 green=*current_line_buffer++; uint16 red=*current_line_buffer++; - uint16 nc=*current_line_buffer++; + /*uint16 nc=*/current_line_buffer++; uint16 blue=*current_line_buffer++; red>>=3; green>>=3; @@ -652,16 +603,7 @@ void tom_render_24bpp_stretch_scanline(int16 *backbuffer) width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void tom_render_16bpp_direct_stretch_scanline(int16 *backbuffer) { uint16 width=tom_width; @@ -678,16 +620,7 @@ void tom_render_16bpp_direct_stretch_scanline(int16 *backbuffer) width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer) { uint16 width=tom_width; @@ -712,99 +645,80 @@ void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer) width--; } } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// Process a single scanline // -////////////////////////////////////////////////////////////////////////////// -void tom_exec_scanline(int16 * backbuffer, int32 scanline, int8 render) +void tom_exec_scanline(int16 * backbuffer, int32 scanline, bool render) { - UINT16 bg = GET16(BG); tom_scanline = scanline; - jaguar_word_write(0xF00004, jaguar_word_read(0xF00004) + 1); + // Increment the horizontal count (why?) + SET16(tom_ram_8, HC, GET16(tom_ram_8, HC) + 1); if (render) { uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800]; - uint16 * current_line_buffer_16 = (uint16 *)current_line_buffer; + uint8 bgHI = tom_ram_8[BG], bgLO = tom_ram_8[BG+1]; - for(int i=0; i> 9) & 0x07); + int clock_cycles_per_pixel = (vmode & PWIDTH) >> 9; uint32 width = 640; switch (clock_cycles_per_pixel) @@ -817,108 +731,84 @@ uint32 tom_getVideoModeWidth(void) 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); +// default: WriteLog("%i \n",clock_cycles_per_pixel); } - if (jaguar_mainRom_crc32 == 0x3c7bfda8) +/* if (jaguar_mainRom_crc32 == 0x3c7bfda8) // Kludge for what??? { if (width == 320) width += 80; if (width == 448) width -= 16; - } - if (hdb == 123) + }//*/ + + if (hdb1 == 123) hblankWidthInPixels = 16; else hblankWidthInPixels = 0; -// fprintf(log_get(),"hdb=%i hbe=%i\n",hdb,hbe); +// WriteLog("hdb1=%i hbe=%i\n",hdb1,hbe); return width; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// -// -// -////////////////////////////////////////////////////////////////////////////// + +// *** SPECULATION *** +// It might work better to virtualize the height settings, i.e., set the vertical +// height at 240 lines and clip using the VDB and VDE/VP registers... +// Same with the 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; +// uint16 vmode = GET16(tom_ram_8, VMODE); +// uint16 vbe = GET16(tom_ram_8, VBE); +// uint16 vbb = GET16(tom_ram_8, VBB); + uint16 vdb = GET16(tom_ram_8, VDB); + uint16 vde = GET16(tom_ram_8, VDE); + uint16 vp = GET16(tom_ram_8, VP); - uint32 screen_height = (vde/*-vdb*/) >> 1; - return 227;//WAS:screen_height); +/* if (vde == 0xFFFF) + vde = vbb;//*/ + +// return 227;//WAS:(vde/*-vdb*/) >> 1; + // The video mode height probably works this way: + // VC counts from 0 to VP. VDB starts the OP. Either when + // VDE is reached or VP, the OP is stopped. Let's try it... + // Also note that we're conveniently ignoring interlaced display modes...! + return ((vde > vp ? vp : vde) - vdb) >> 1; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -// + // +// TOM reset code +// NOTE: Should set up PAL values here when in PAL mode (use BIOS to find default values) +// for when user starts with -nobios -pal flags... // -////////////////////////////////////////////////////////////////////////////// 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); + SET16(tom_ram_8, MEMCON1, 0x1861); + SET16(tom_ram_8, MEMCON2, 0x0000); + SET16(tom_ram_8, VMODE, 0x06C1); + SET16(tom_ram_8, VP, 523); + SET16(tom_ram_8, HP, 844); + SET16(tom_ram_8, VS, 523 - 6); + SET16(tom_ram_8, VBB, 434); + SET16(tom_ram_8, VBE, 24); + SET16(tom_ram_8, HBB, 689 + 0x400); + SET16(tom_ram_8, HBE, 125); + + SET16(tom_ram_8, VDE, 2047);//65535); + SET16(tom_ram_8, VDB, 28); + SET16(tom_ram_8, HDB1, 166); + SET16(tom_ram_8, HDE, 2047);//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; + + hblankWidthInPixels = GET16(tom_ram_8, HDB1) >> 1; tom_puck_int_pending = 0; tom_timer_int_pending = 0; @@ -938,15 +828,19 @@ void tom_reset(void) unsigned tom_byte_read(unsigned int offset) { +//???Is this needed??? +// It seems so. Perhaps it's the +$8000 offset being written to (32-bit interface)? +// However, the 32-bit interface is WRITE ONLY, so that can't be it... +// Also, the 68K CANNOT make use of the 32-bit interface, since its bus width is only 16-bits... offset &= 0xFF3FFF; #ifdef TOM_DEBUG - fprintf(log_get(), "TOM: Reading byte at %06X\n", offset); + WriteLog("TOM: Reading byte at %06X\n", offset); #endif - if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + 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)) + 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); @@ -970,23 +864,28 @@ unsigned tom_byte_read(unsigned int offset) unsigned tom_word_read(unsigned int offset) { +//???Is this needed??? offset &= 0xFF3FFF; #ifdef TOM_DEBUG - fprintf(log_get(), "TOM: Reading word at %06X\n", offset); + WriteLog("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); + //WriteLog("tom: interrupt status is 0x%.4x \n",data); return data; } - else if (offset == 0xF00006) + else if (offset == 0xF00006) // VC + // What if we're in interlaced mode? + // According to docs, in non-interlace mode VC is ALWAYS even... +// return (tom_scanline << 1);// + 1; +//But it's causing Rayman to be fucked up... Why??? return (tom_scanline << 1) + 1; - else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + 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)) + 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); @@ -998,12 +897,6 @@ unsigned tom_word_read(unsigned int offset) 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); } @@ -1013,18 +906,20 @@ unsigned tom_word_read(unsigned int offset) void tom_byte_write(unsigned offset, unsigned data) { +//???Is this needed??? +// Perhaps on the writes--32-bit writes that is! And masked with FF7FFF... offset &= 0xFF3FFF; #ifdef TOM_DEBUG - fprintf(log_get(), "TOM: Writing byte %02X at %06X\n", data, offset); + WriteLog("TOM: Writing byte %02X at %06X\n", data, offset); #endif - if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + 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)) + else if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE+0x1000)) { gpu_byte_write(offset, data); return; @@ -1063,6 +958,12 @@ void tom_byte_write(unsigned offset, unsigned data) tom_reset_timer(); return; } + else if (offset >= 0xF00400 && offset <= 0xF007FF) // CLUT (A & B) + { + // Writing to one CLUT writes to the other + offset &= 0x5FF; // Mask out $F00600 (restrict to $F00400-5FF) + tom_ram_8[offset] = data, tom_ram_8[offset + 0x200] = data; + } tom_ram_8[offset & 0x3FFF] = data; } @@ -1073,26 +974,27 @@ void tom_byte_write(unsigned offset, unsigned data) void tom_word_write(unsigned offset, unsigned data) { +//???Is this needed??? offset &= 0xFF3FFF; #ifdef TOM_DEBUG - fprintf(log_get(), "TOM: Writing word %04X at %06X\n", data, offset); + WriteLog("TOM: Writing word %04X at %06X\n", data, offset); #endif - if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20)) + 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)) + 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)); + tom_byte_write(offset, data >> 8); + tom_byte_write(offset+1, data & 0xFF); } else if ((offset >= 0xF00010) && (offset < 0xF00028)) { @@ -1124,35 +1026,59 @@ void tom_word_write(unsigned offset, unsigned data) if (data & 0x1000) tom_puck_int_pending = 0; } - else if ((offset >= 0xF02200) && (offset < 0xF022A0)) + else if ((offset >= 0xF02200) && (offset <= 0xF0229F)) { blitter_word_write(offset, data); return; } + else if (offset >= 0xF00400 && offset <= 0xF007FE) // CLUT (A & B) + { + // Writing to one CLUT writes to the other + offset &= 0x5FF; // Mask out $F00600 (restrict to $F00400-5FF) +// Watch out for unaligned writes here! (Not fixed yet) + SET16(tom_ram_8, offset, data), SET16(tom_ram_8, offset + 0x200, data); + } offset &= 0x3FFF; - if (offset == 0x28) + if (offset == 0x28) // VMODE (Why? Why not OBF?) objectp_running = 1; + if (offset >= 0x30 && offset <= 0x4E) + data &= 0x07FF; // These are (mostly) 11-bit registers + if (offset == 0x2E || offset == 0x36 || offset == 0x54) + data &= 0x03FF; // These are all 10-bit registers + tom_byte_write(offset, data >> 8); - tom_byte_write(offset+1, data & 0xFF); + 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 (offset == VDB) + WriteLog("TOM: Vertical Display Begin written: %04X\n", data); +if (offset == VDE) + WriteLog("TOM: Vertical Display End written: %04X\n", data); +if (offset == VP) + WriteLog("TOM: Vertical Period written: %04X (%sinterlaced)\n", data, (data & 0x01 ? "non-" : "")); +if (offset == HDB1) + WriteLog("TOM: Horizontal Display Begin 1 written: %04X\n", data); +if (offset == HDE) + WriteLog("TOM: Horizontal Display End written: %04X\n", data); +if (offset == HP) + WriteLog("TOM: Horizontal Period written: %04X\n", data); +if (offset == VMODE) + WriteLog("TOM: Video Mode written: %04X\n", data); + + uint32 width = tom_getVideoModeWidth(), height = tom_getVideoModeHeight(); + tom_real_internal_width = width; + 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)) { @@ -1161,12 +1087,11 @@ void tom_word_write(unsigned offset, unsigned data) static char window_title[256]; delete surface; - tom_width = width; - tom_height = height; + 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); + sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)tom_width, (int)tom_height); console.open(window_title, width, tom_height, format); ws_audio_init(); @@ -1196,7 +1121,7 @@ void tom_reset_timer(void) tom_timer_counter = 0; else tom_timer_counter = (1 + tom_timer_prescaler) * (1 + tom_timer_divider); -// fprintf(log_get(),"tom: reseting timer to 0x%.8x (%i)\n",tom_timer_counter,tom_timer_counter); +// WriteLog("tom: reseting timer to 0x%.8x (%i)\n",tom_timer_counter,tom_timer_counter); } void tom_pit_exec(uint32 cycles) @@ -1210,30 +1135,9 @@ void tom_pit_exec(uint32 cycles) 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/unzip.c b/src/unzip.c new file mode 100644 index 0000000..364f7c0 --- /dev/null +++ b/src/unzip.c @@ -0,0 +1,868 @@ +// +// ZIP file support (mostly ripped from MAME) +// +// Added by James L. Hammons +// + +#include "unzip.h" +//#include "driver.h" +#include "log.h" + +#include +#include +#include +#include +#include + +/* public globals */ +int gUnzipQuiet = 0; /* flag controls error messages */ + + +#define ERROR_CORRUPT "The zipfile seems to be corrupt, please check it" +#define ERROR_FILESYSTEM "Your filesystem seems to be corrupt, please check it" +#define ERROR_UNSUPPORTED "The format of this zipfile is not supported, please recompress it" + +#define INFLATE_INPUT_BUFFER_MAX 16384 +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +/* Print a error message */ +void errormsg(const char * extmsg, const char * usermsg, const char * zipname) +{ + /* Output to the user with no internal detail */ + if (!gUnzipQuiet) + printf("Error in zipfile %s\n%s\n", zipname, usermsg); + /* Output to log file with all informations */ + WriteLog("Error in zipfile %s: %s\n", zipname, extmsg); +} + +/* ------------------------------------------------------------------------- + Unzip support + ------------------------------------------------------------------------- */ + +/* Use these to avoid structure padding and byte-ordering problems */ +static UINT16 read_word (char *buf) { + unsigned char *ubuf = (unsigned char *) buf; + + return ((UINT16)ubuf[1] << 8) | (UINT16)ubuf[0]; +} + +/* Use these to avoid structure padding and byte-ordering problems */ +static UINT32 read_dword (char *buf) { + unsigned char *ubuf = (unsigned char *) buf; + + return ((UINT32)ubuf[3] << 24) | ((UINT32)ubuf[2] << 16) | ((UINT32)ubuf[1] << 8) | (UINT32)ubuf[0]; +} + +/* Locate end-of-central-dir sig in buffer and return offset + out: + *offset offset of cent dir start in buffer + return: + ==0 not found + !=0 found, *offset valid +*/ +static int ecd_find_sig (char *buffer, int buflen, int *offset) +{ + static char ecdsig[] = { 'P', 'K', 0x05, 0x06 }; + int i; + for (i=buflen-22; i>=0; i--) { + if (memcmp(buffer+i, ecdsig, 4) == 0) { + *offset = i; + return 1; + } + } + return 0; +} + +/* Read ecd data in zip structure + in: + zip->fp, zip->length zip file + out: + zip->ecd, zip->ecd_length ecd data +*/ +static int ecd_read(ZIP * zip) +{ + char * buf; + int buf_length = 1024; /* initial buffer length */ + + while (1) + { + int offset; + + if (buf_length > zip->length) + buf_length = zip->length; + + if (fseek(zip->fp, zip->length - buf_length, SEEK_SET) != 0) + { + return -1; + } + + /* allocate buffer */ + buf = (char *)malloc(buf_length); + if (!buf) + { + return -1; + } + + if (fread(buf, 1, buf_length, zip->fp) != buf_length) + { + free(buf); + return -1; + } + + if (ecd_find_sig(buf, buf_length, &offset)) { + zip->ecd_length = buf_length - offset; + + zip->ecd = (char*)malloc( zip->ecd_length ); + if (!zip->ecd) { + free(buf); + return -1; + } + + memcpy(zip->ecd, buf + offset, zip->ecd_length); + + free(buf); + return 0; + } + + free(buf); + + if (buf_length < zip->length) { + /* double buffer */ + buf_length = 2*buf_length; + + WriteLog("Retry reading of zip ecd for %d bytes\n",buf_length); + + } else { + return -1; + } + } +} + +/* offsets in end of central directory structure */ +#define ZIPESIG 0x00 +#define ZIPEDSK 0x04 +#define ZIPECEN 0x06 +#define ZIPENUM 0x08 +#define ZIPECENN 0x0a +#define ZIPECSZ 0x0c +#define ZIPEOFST 0x10 +#define ZIPECOML 0x14 +#define ZIPECOM 0x16 + +/* offsets in central directory entry structure */ +#define ZIPCENSIG 0x0 +#define ZIPCVER 0x4 +#define ZIPCOS 0x5 +#define ZIPCVXT 0x6 +#define ZIPCEXOS 0x7 +#define ZIPCFLG 0x8 +#define ZIPCMTHD 0xa +#define ZIPCTIM 0xc +#define ZIPCDAT 0xe +#define ZIPCCRC 0x10 +#define ZIPCSIZ 0x14 +#define ZIPCUNC 0x18 +#define ZIPCFNL 0x1c +#define ZIPCXTL 0x1e +#define ZIPCCML 0x20 +#define ZIPDSK 0x22 +#define ZIPINT 0x24 +#define ZIPEXT 0x26 +#define ZIPOFST 0x2a +#define ZIPCFN 0x2e + +/* offsets in local file header structure */ +#define ZIPLOCSIG 0x00 +#define ZIPVER 0x04 +#define ZIPGENFLG 0x06 +#define ZIPMTHD 0x08 +#define ZIPTIME 0x0a +#define ZIPDATE 0x0c +#define ZIPCRC 0x0e +#define ZIPSIZE 0x12 +#define ZIPUNCMP 0x16 +#define ZIPFNLN 0x1a +#define ZIPXTRALN 0x1c +#define ZIPNAME 0x1e + +// +// Opens a zip stream for reading +// return: +// !=0 success, zip stream +// ==0 error +// +ZIP * openzip(int pathtype, int pathindex, const char * zipfile) +{ + /* allocate */ + ZIP * zip = (ZIP *)malloc(sizeof(ZIP)); + if (!zip) + { + return 0; + } + + /* open */ + zip->fp = fopen(zipfile, "rb"); + if (!zip->fp) + { + errormsg("Opening for reading", ERROR_FILESYSTEM, zipfile); + free(zip); + return 0; + } + + /* go to end */ + if (fseek(zip->fp, 0L, SEEK_END) != 0) + { + errormsg ("Seeking to end", ERROR_FILESYSTEM, zipfile); + fclose(zip->fp); + free(zip); + return 0; + } + + /* get length */ + zip->length = ftell(zip->fp); + if (zip->length < 0) + { + errormsg("Get file size", ERROR_FILESYSTEM, zipfile); + fclose(zip->fp); + free(zip); + return 0; + } + if (zip->length == 0) + { + errormsg ("Empty file", ERROR_CORRUPT, zipfile); + fclose(zip->fp); + free(zip); + return 0; + } + + /* read ecd data */ + if (ecd_read(zip) != 0) + { + errormsg("Reading ECD (end of central directory)", ERROR_CORRUPT, zipfile); + fclose(zip->fp); + free(zip); + return 0; + } + + /* compile ecd info */ + zip->end_of_cent_dir_sig = read_dword (zip->ecd+ZIPESIG); + zip->number_of_this_disk = read_word (zip->ecd+ZIPEDSK); + zip->number_of_disk_start_cent_dir = read_word (zip->ecd+ZIPECEN); + zip->total_entries_cent_dir_this_disk = read_word (zip->ecd+ZIPENUM); + zip->total_entries_cent_dir = read_word (zip->ecd+ZIPECENN); + zip->size_of_cent_dir = read_dword (zip->ecd+ZIPECSZ); + zip->offset_to_start_of_cent_dir = read_dword (zip->ecd+ZIPEOFST); + zip->zipfile_comment_length = read_word (zip->ecd+ZIPECOML); + zip->zipfile_comment = zip->ecd+ZIPECOM; + + /* verify that we can work with this zipfile (no disk spanning allowed) */ + if ((zip->number_of_this_disk != zip->number_of_disk_start_cent_dir) || + (zip->total_entries_cent_dir_this_disk != zip->total_entries_cent_dir) || + (zip->total_entries_cent_dir < 1)) + { + errormsg("Cannot span disks", ERROR_UNSUPPORTED, zipfile); + free(zip->ecd); + fclose(zip->fp); + free(zip); + return 0; + } + + if (fseek(zip->fp, zip->offset_to_start_of_cent_dir, SEEK_SET) != 0) + { + errormsg("Seeking to central directory", ERROR_CORRUPT, zipfile); + free(zip->ecd); + fclose(zip->fp); + free(zip); + return 0; + } + + /* read from start of central directory */ + zip->cd = (char *)malloc(zip->size_of_cent_dir); + if (!zip->cd) + { + free(zip->ecd); + fclose(zip->fp); + free(zip); + return 0; + } + + if (fread(zip->cd, 1, zip->size_of_cent_dir, zip->fp) != zip->size_of_cent_dir) + { + errormsg("Reading central directory", ERROR_CORRUPT, zipfile); + free(zip->cd); + free(zip->ecd); + fclose(zip->fp); + free(zip); + return 0; + } + + /* reset ent */ + zip->ent.name = 0; + + /* rewind */ + zip->cd_pos = 0; + + /* file name */ + zip->zip = (char*)malloc(strlen(zipfile)+1); + if (!zip->zip) + { + free(zip->cd); + free(zip->ecd); + fclose(zip->fp); + free(zip); + return 0; + } + strcpy(zip->zip, zipfile); + zip->pathtype = pathtype; + zip->pathindex = pathindex; + + return zip; +} + +/* Reads the current entry from a zip stream + in: + zip opened zip + return: + !=0 success + ==0 error +*/ +struct zipent* readzip(ZIP* zip) { + + /* end of directory */ + if (zip->cd_pos >= zip->size_of_cent_dir) + return 0; + + /* compile zipent info */ + zip->ent.cent_file_header_sig = read_dword (zip->cd+zip->cd_pos+ZIPCENSIG); + zip->ent.version_made_by = *(zip->cd+zip->cd_pos+ZIPCVER); + zip->ent.host_os = *(zip->cd+zip->cd_pos+ZIPCOS); + zip->ent.version_needed_to_extract = *(zip->cd+zip->cd_pos+ZIPCVXT); + zip->ent.os_needed_to_extract = *(zip->cd+zip->cd_pos+ZIPCEXOS); + zip->ent.general_purpose_bit_flag = read_word (zip->cd+zip->cd_pos+ZIPCFLG); + zip->ent.compression_method = read_word (zip->cd+zip->cd_pos+ZIPCMTHD); + zip->ent.last_mod_file_time = read_word (zip->cd+zip->cd_pos+ZIPCTIM); + zip->ent.last_mod_file_date = read_word (zip->cd+zip->cd_pos+ZIPCDAT); + zip->ent.crc32 = read_dword (zip->cd+zip->cd_pos+ZIPCCRC); + zip->ent.compressed_size = read_dword (zip->cd+zip->cd_pos+ZIPCSIZ); + zip->ent.uncompressed_size = read_dword (zip->cd+zip->cd_pos+ZIPCUNC); + zip->ent.filename_length = read_word (zip->cd+zip->cd_pos+ZIPCFNL); + zip->ent.extra_field_length = read_word (zip->cd+zip->cd_pos+ZIPCXTL); + zip->ent.file_comment_length = read_word (zip->cd+zip->cd_pos+ZIPCCML); + zip->ent.disk_number_start = read_word (zip->cd+zip->cd_pos+ZIPDSK); + zip->ent.internal_file_attrib = read_word (zip->cd+zip->cd_pos+ZIPINT); + zip->ent.external_file_attrib = read_dword (zip->cd+zip->cd_pos+ZIPEXT); + zip->ent.offset_lcl_hdr_frm_frst_disk = read_dword (zip->cd+zip->cd_pos+ZIPOFST); + + /* check to see if filename length is illegally long (past the size of this directory + entry) */ + if (zip->cd_pos + ZIPCFN + zip->ent.filename_length > zip->size_of_cent_dir) + { + errormsg("Invalid filename length in directory", ERROR_CORRUPT,zip->zip); + return 0; + } + + /* copy filename */ + free(zip->ent.name); + zip->ent.name = (char*)malloc(zip->ent.filename_length + 1); + memcpy(zip->ent.name, zip->cd+zip->cd_pos+ZIPCFN, zip->ent.filename_length); + zip->ent.name[zip->ent.filename_length] = 0; + + /* skip to next entry in central dir */ + zip->cd_pos += ZIPCFN + zip->ent.filename_length + zip->ent.extra_field_length + zip->ent.file_comment_length; + + return &zip->ent; +} + +/* Closes a zip stream */ +void closezip(ZIP * zip) +{ + /* release all */ + free(zip->ent.name); + free(zip->cd); + free(zip->ecd); + /* only if not suspended */ + if (zip->fp) + fclose(zip->fp); + free(zip->zip); + free(zip); +} + +/* Suspend access to a zip file (release file handler) + in: + zip opened zip + note: + A suspended zip is automatically reopened at first call of + readuncompressd() or readcompressed() functions +*/ +void suspendzip(ZIP * zip) +{ + if (zip->fp) + { + fclose(zip->fp); + zip->fp = 0; + } +} + +/* Revive a suspended zip file (reopen file handler) + in: + zip suspended zip + return: + zip success + ==0 error (zip must be closed with closezip) +*/ +static ZIP * revivezip(ZIP * zip) +{ + if (!zip->fp) + { + zip->fp = fopen(zip->zip, "rb"); + if (!zip->fp) + return 0; + } + + return zip; +} + +/* Reset a zip stream to the first entry + in: + zip opened zip + note: + ZIP file must be opened and not suspended +*/ +void rewindzip(ZIP * zip) +{ + zip->cd_pos = 0; +} + +// +// Seek zip->fp to compressed data +// return: +// ==0 success +// <0 error +// +int seekcompresszip(ZIP * zip, struct zipent * ent) +{ + char buf[ZIPNAME]; + long offset; + + if (!zip->fp) + { + if (!revivezip(zip)) + return -1; + } + + if (fseek(zip->fp, ent->offset_lcl_hdr_frm_frst_disk, SEEK_SET) != 0) + { + errormsg("Seeking to header", ERROR_CORRUPT, zip->zip); + return -1; + } + + if (fread(buf, 1, ZIPNAME, zip->fp) != ZIPNAME) + { + errormsg("Reading header", ERROR_CORRUPT, zip->zip); + return -1; + } + + { + UINT16 filename_length = read_word(buf+ZIPFNLN); + UINT16 extra_field_length = read_word(buf+ZIPXTRALN); + + // calculate offset to data and fseek() there + offset = ent->offset_lcl_hdr_frm_frst_disk + ZIPNAME + filename_length + extra_field_length; + + if (fseek(zip->fp, offset, SEEK_SET) != 0) + { + errormsg("Seeking to compressed data", ERROR_CORRUPT, zip->zip); + return -1; + } + + } + + return 0; +} + +// +// Inflate a file +// in: +// in_file stream to inflate +// in_size size of the compressed data to read +// out: +// out_size size of decompressed data +// out_data buffer for decompressed data +// return: +// ==0 ok +// +// 990525 rewritten for use with zlib MLR +// +static int inflate_file(FILE * in_file, unsigned in_size, unsigned char * out_data, unsigned out_size) +{ + int err; + unsigned char * in_buffer; + z_stream d_stream; // decompression stream + + d_stream.zalloc = 0; + d_stream.zfree = 0; + d_stream.opaque = 0; + + d_stream.next_in = 0; + d_stream.avail_in = 0; + d_stream.next_out = out_data; + d_stream.avail_out = out_size; + + err = inflateInit2(&d_stream, -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + */ + if (err != Z_OK) + { + WriteLog("inflateInit error: %d\n", err); + return -1; + } + + in_buffer = (unsigned char*)malloc(INFLATE_INPUT_BUFFER_MAX+1); + if (!in_buffer) + return -1; + + for (;;) + { + if (in_size <= 0) + { + WriteLog("inflate error: compressed size too small\n"); + free (in_buffer); + return -1; + } + d_stream.next_in = in_buffer; + d_stream.avail_in = fread(in_buffer, 1, MIN(in_size, INFLATE_INPUT_BUFFER_MAX), in_file); + in_size -= d_stream.avail_in; + if (in_size == 0) + d_stream.avail_in++; /* add dummy byte at end of compressed data */ + + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err != Z_OK) + { + WriteLog("inflate error: %d\n", err); + free (in_buffer); + return -1; + } + } + + err = inflateEnd(&d_stream); + if (err != Z_OK) + { + WriteLog("inflateEnd error: %d\n", err); + free (in_buffer); + return -1; + } + + free (in_buffer); + + if ((d_stream.avail_out > 0) || (in_size > 0)) + { + WriteLog("zip size mismatch. %i\n", in_size); + return -1; + } + + return 0; +} + +// +// Read compressed data +// out: +// data compressed data read +// return: +// ==0 success +// <0 error +// +int readcompresszip(ZIP * zip, struct zipent * ent, char * data) +{ + int err = seekcompresszip(zip, ent); + if (err != 0) + return err; + + if (fread(data, 1, ent->compressed_size, zip->fp) != ent->compressed_size) + { + errormsg("Reading compressed data", ERROR_CORRUPT, zip->zip); + return -1; + } + + return 0; +} + +// +// Read UNcompressed data +// out: +// data UNcompressed data +// return: +// ==0 success +// <0 error +// +int readuncompresszip(ZIP * zip, struct zipent * ent, char * data) +{ + if (ent->compression_method == 0x0000) + { + /* file is not compressed, simply stored */ + + /* check if size are equal */ + if (ent->compressed_size != ent->uncompressed_size) + { + errormsg("Wrong uncompressed size in store compression", ERROR_CORRUPT,zip->zip); + return -3; + } + + return readcompresszip(zip, ent, data); + } + else if (ent->compression_method == 0x0008) + { + /* file is compressed using "Deflate" method */ + if (ent->version_needed_to_extract > 0x14) + { + errormsg("Version too new", ERROR_UNSUPPORTED, zip->zip); + return -2; + } + + if (ent->os_needed_to_extract != 0x00) + { + errormsg("OS not supported", ERROR_UNSUPPORTED, zip->zip); + return -2; + } + + if (ent->disk_number_start != zip->number_of_this_disk) + { + errormsg("Cannot span disks", ERROR_UNSUPPORTED, zip->zip); + return -2; + } + + /* read compressed data */ + if (seekcompresszip(zip, ent) != 0) + { + return -1; + } + + /* configure inflate */ + if (inflate_file(zip->fp, ent->compressed_size, (unsigned char *)data, ent->uncompressed_size)) + { + errormsg("Inflating compressed data", ERROR_CORRUPT, zip->zip); + return -3; + } + + return 0; + } + else + { + errormsg("Compression method unsupported", ERROR_UNSUPPORTED, zip->zip); + return -2; + } +} + +/* ------------------------------------------------------------------------- + Zip cache support + ------------------------------------------------------------------------- */ + +/* Use the zip cache */ +// No, don't +//#define ZIP_CACHE + +#ifdef ZIP_CACHE + +/* ZIP cache entries */ +#define ZIP_CACHE_MAX 5 + +/* ZIP cache buffer LRU ( Last Recently Used ) + zip_cache_map[0] is the newer + zip_cache_map[ZIP_CACHE_MAX-1] is the older +*/ +static ZIP* zip_cache_map[ZIP_CACHE_MAX]; + +static ZIP* cache_openzip(int pathtype, int pathindex, const char* zipfile) { + ZIP* zip; + unsigned i; + + /* search in the cache buffer */ + for(i=0;ipathtype == pathtype && zip_cache_map[i]->pathindex == pathindex && strcmp(zip_cache_map[i]->zip,zipfile)==0) { + /* found */ + unsigned j; + +/* + WriteLog("Zip cache HIT for %s\n", zipfile); +*/ + + /* reset the zip directory */ + rewindzip( zip_cache_map[i] ); + + /* store */ + zip = zip_cache_map[i]; + + /* shift */ + for(j=i;j>0;--j) + zip_cache_map[j] = zip_cache_map[j-1]; + + /* set the first entry */ + zip_cache_map[0] = zip; + + return zip_cache_map[0]; + } + } + /* not found */ + +/* + WriteLog("Zip cache FAIL for %s\n", zipfile); +*/ + + /* open the zip */ + zip = openzip( pathtype, pathindex, zipfile ); + if (!zip) + return 0; + + /* close the oldest entry */ + if (zip_cache_map[ZIP_CACHE_MAX-1]) { + /* close last zip */ + closezip(zip_cache_map[ZIP_CACHE_MAX-1]); + /* reset the entry */ + zip_cache_map[ZIP_CACHE_MAX-1] = 0; + } + + /* shift */ + for(i=ZIP_CACHE_MAX-1;i>0;--i) + zip_cache_map[i] = zip_cache_map[i-1]; + + /* set the first entry */ + zip_cache_map[0] = zip; + + return zip_cache_map[0]; +} + +static void cache_closezip(ZIP* zip) { + unsigned i; + + /* search in the cache buffer */ + for(i=0;i Comparing filenames: [%s] <-> [%s]\n", s1, s2); + + // This assumes that s1 is longer than s2... Might not be! !!! FIX !!! + while (*s1 && toupper(*s1) == toupper(*s2)) + { + s1++; + s2++; + } + + return !*s1 && !*s2; +} + +// +// Pass the path to the zipfile and the name of the file within the zipfile. +// buf will be set to point to the uncompressed image of that zipped file. +// length will be set to the length of the uncompressed data. +// +int load_zipped_file(int pathtype, int pathindex, const char * zipfile, const char * filename, unsigned char ** buf, uint32 * length) +{ + ZIP * zip; + struct zipent * ent; + + zip = cache_openzip(pathtype, pathindex, zipfile); + if (!zip) + return -1; + + while (readzip(zip)) + { + /* NS981003: support for "load by CRC" */ + char crc[9]; + + ent = &(zip->ent); + sprintf(crc, "%08x", (unsigned int)ent->crc32); + + if (filename == NULL || equal_filename(ent->name, filename) + || (ent->crc32 && !strcmp(crc, filename))) + { + *length = ent->uncompressed_size; + + if (readuncompresszip(zip, ent, (char *)*buf) != 0) + { + cache_closezip(zip); + return -1; + } + + cache_suspendzip(zip); + return 0; + } + } + + cache_suspendzip(zip); + return -1; +} diff --git a/src/version.cpp b/src/version.cpp index a62ec53..64e2623 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -14,7 +14,7 @@ void version_init(void) void version_display(FILE * fp) { - fprintf(fp, "VirtualJaguar v1.0.3 (Last full build on %s %s)\n", __DATE__, __TIME__); + fprintf(fp, "VirtualJaguar v1.0.4 (Last full build on %s %s)\n", __DATE__, __TIME__); } void version_done(void) diff --git a/src/vj.cpp b/src/vj.cpp new file mode 100644 index 0000000..9d28b92 --- /dev/null +++ b/src/vj.cpp @@ -0,0 +1,341 @@ +// +// Virtual Jaguar Emulator +// +// by cal2 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Cleanups/fixes by James L. Hammons +// + +// Added by SDLEMU (http://sdlemu.ngemu.com) +// Added for GCC UNIX compatibility +#ifdef __GCCUNIX__ +#include +#endif // __GCCUNIX__ + +#include +#include +#include "SDLptc.h" +#include "jaguar.h" +#include "crc32.h" +#include "unzip.h" + +// Uncomment this for speed control +//#define SPEED_CONTROL + +// +// Private function prototypes +// + +uint32 JaguarLoadROM(uint8 *, char *); +void JaguarLoadCart(uint8 *, char *); + +// +// Various paths +// + +//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/"; +char jaguar_boot_dir[1024]; +//static char romLoadDialog_filePath[1024]; + + +Console console; +Surface * surface; +Format format(16, 0x007C00, 0x00003E0, 0x0000001F); +bool finished = false; +bool fullscreen = false; +bool hardwareTypeNTSC = true; // Set to false for PAL + +// +// External variables +// + +extern bool jaguar_use_bios; +extern bool dsp_enabled; +extern uint8 * jaguar_mainRam; +extern uint8 * jaguar_bootRom; +extern uint8 * jaguar_mainRom; + + +void main_screen_switch(void) +{ + fullscreen = !fullscreen; + if (fullscreen) + console.option("fullscreen output"); + else + console.option("windowed output"); + console.close(); + console.open("Virtual Jaguar", tom_width, tom_height, format); +} + +// 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 = 0; // Default: Show every frame + int32 nFrame = 0; // No. of Frame + int32 nJoyport = 0; // Joystick port + + printf("Virtual Jaguar/SDL v1.0.4 (GCC/SDL Port)\n"); + printf("Based upon Virtual Jaguar core v1.0.0 by cal2 of 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"); + + console.option("windowed output"); + + // BIOS is now ON by default--use the -nobios switch to turn it off! + jaguar_use_bios = true; + bool haveCart = false; // Assume there is no cartridge...! + + // Checking the switches ;) + + for(int i=1; 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 + } + + if (!strcmp(argv[i], "-nobios")) + jaguar_use_bios = false; + + if (!strcmp(argv[i], "-dspon")) + dsp_enabled = 1; + + if (!strcmp(argv[i], "-pal")) + hardwareTypeNTSC = false; + + if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "-?")) + { + printf("Usage: \n\n"); + printf("vj [romfile] [switches]\n"); + printf(" -? or -help : Display usage and 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"); + printf(" -nobios : Boot cart without using Jaguar BIOS ROM \n"); + printf(" -dspon : Force VJ to use the DSP \n"); + printf(" -pal : Force VJ to PAL mode (default is NTSC) \n"); + printf("\nInvoking Virtual Jagaur with no ROM file will cause it to boot up\n"); + printf("with the Jaguar BIOS.\n"); + return true; + } + } + + getcwd(jaguar_boot_dir, 1024); + log_init("vj.log"); + memory_init(); + version_init(); + version_display(log_get()); + jaguar_init(); + + // Get the BIOS ROM + if (jaguar_use_bios) + JaguarLoadROM(jaguar_bootRom, jaguar_bootRom_path); + + SET32(jaguar_mainRam, 0, 0x00200000); // Set top of stack... + + // Get the cartridge ROM (if passed in) + if (haveCart) + { + JaguarLoadCart(jaguar_mainRom, argv[1]); + eeprom_init(); + } + + 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 + surface = new Surface(tom_getVideoModeWidth(), tom_getVideoModeHeight(), format); + + // 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 keyboard...\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 3l337 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) {} + + jaguar_done(); + version_done(); + memory_done(); + log_done(); + console.close(); // Close SDL items as last! + + return 0; +} + +// +// Generic ROM loading +// +uint32 JaguarLoadROM(uint8 * rom, char * path) +{ + uint32 romSize; + + WriteLog("JagEm: Loading %s...", path); + + char * ext = strrchr(path, '.'); + if (strcmpi(ext, ".zip") == 0) + { + // Handle ZIP file loading here... + WriteLog("(ZIPped)..."); + + if (load_zipped_file(0, 0, path, NULL, &rom, &romSize) == -1) + { + WriteLog("Failed!\n"); + log_done(); + exit(0); + } + } + else + { + FILE * fp = fopen(path, "rb"); + + if (fp == NULL) + { + WriteLog("Failed!\n"); + log_done(); + exit(0); + } + + fseek(fp, 0, SEEK_END); + romSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + fread(rom, 1, romSize, fp); + fclose(fp); + } + + WriteLog("OK (%i bytes)\n", romSize); + return romSize; +} + +// +// Jaguar cartridge ROM loading +// +void JaguarLoadCart(uint8 * mem, char * path) +{ + uint32 romsize = JaguarLoadROM(mem, path); + jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romsize); + WriteLog( "CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); +} -- 2.37.2