-Virtual Jaguar v1.0.3 GCC/SDL release INSTALL
+Virtual Jaguar v1.0.4 GCC/SDL release INSTALL
---------------------------------------------
- Requirements :
- 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
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 \
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`
clean:
rm -rf obj
- rm -f jag_em.exe
+ rm -f vj.exe
obj:
mkdir obj
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
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
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
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
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
--- /dev/null
+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
+--------------------------
+
+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
------------------------------------------------------
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
--- /dev/null
+Virtual Jaguar will create EEPROM images here.
\ No newline at end of file
+++ /dev/null
-//
-// 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 <mmsystem.h>
-#include <direct.h>
-#endif // #ifndef __PORT__
-#include <time.h>
-
-/* Added by SDLEMU (http://sdlemu.ngemu.com) */
-/* Added for GCC UNIX compatibility */
-#ifdef __GCCUNIX__
-#include <unistd.h>
-#endif // #ifdef __GCCUNIX__
-
-#include <SDL.h>
-#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 <romfile> [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<argc || argv[i]!=NULL); i++)
- {
- if (!strcmp(argv[i], "-fullscreen"))
- console.option("fullscreen output");
-
- if (!strcmp(argv[i], "-window"))
- console.option("windowed output");
-
- if (!strcmp(argv[i], "-joystick"))
- console.option("joystick enabled");
-
- if (!strcmp(argv[i], "-joyport"))
- {
- nJoyport = atoi(argv[++i]) + 1;
- if (nJoyport > 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; i<nCount-1; i++)
- jaguar_exec(backbuffer, 0);
-#endif
- /* Setting up new backbuffer with new pixels and data */
- jaguar_exec(backbuffer, 1);
- totalFrames++;
-
- /* Simple frameskip */
- if (nFrame == nFrameskip)
- {
- int32 * vs = (int32 *)surface->lock();
- 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;i<nCount-1;i++)
- jaguar_exec(backbuffer,0);
-#endif
- jaguar_exec(backbuffer,1);
- totalFrames++;
-
- int32 *vs = (int32 *)surface->lock();
- 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
-
//
// 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)
#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
// 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);
// 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)) : \
// 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;
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;
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
// 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
//////////////////////////////////////////////////////////////////////////////
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
//////////////////////////////////////////////////////////////////////////////
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<<B);
#define HASHCODE_BIT_TEST(B) (hashcode&(1<<B))
HASHCODE_BIT(a1_phrase_mode, 28);
HASHCODE_BIT(a2_phrase_mode, 29);
-
return(hashcode);
}
//////////////////////////////////////////////////////////////////////////////
uint32 i;
uint32 hashcode=blitter_calc_hashcode(cmd);
#ifdef LOG_BLITS
- fprintf(log_get(),"blitter: hashcode= 0x%.8x\n",hashcode);
+ WriteLog("blitter: hashcode= 0x%.8x\n",hashcode);
#endif
struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24];
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);
}
//
//
//////////////////////////////////////////////////////////////////////////////
-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)
{
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++)
{
{
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)
{
{
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
{
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;
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
{
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
{
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;
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)
{
// 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
{
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;
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)
{
*/ }
// 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;
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;
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;
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;
// 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
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)
}
// 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
// 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)
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
}
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)
{
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;
}
}
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];
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);
}
--- /dev/null
+//#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<outer_loop; j++) {
+ int old_a1x = a1_x;
+ int old_a2x = a2_x;
+ for(DWORD i=0; i<(inner_loop*bitdepth[a1.depth]); i+=bitdepth[a1.depth]) {
+ BYTE src1,src2=0;
+ BYTE dst1,dst2;
+ BYTE dst_old;
+ a1_address = a1.base + ((((a1_y>>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<outer_loop; j++) {
+ for(DWORD i=0; i<inner_loop*2; i+=2) {
+ WORD src1,src2;
+ WORD dst1,dst2;
+ WORD dst_old;
+ WORD srcz,dstz;
+ a1_address = a1.base + (((a1_y>>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<outer_loop; j++) {
+ for(DWORD i=0; i<(inner_loop*bitdepth[a1.depth])/8; i+=bitsize[a1.depth]) {
+ DWORD src1,src2=0;
+ DWORD dst1,dst2;
+ a1_address = a1.base + ((((a1_y>>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)
+*/
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;
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;
if (offset==0xF1CFE0)
return(0xff);
}
- if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
- return(dsp_ram_8[offset-dsp_work_ram_base]);
+ if ((offset>=DSP_WORK_RAM_BASE)&&(offset<DSP_WORK_RAM_BASE+0x2000))
+ return(dsp_ram_8[offset-DSP_WORK_RAM_BASE]);
- 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 data=dsp_long_read(offset&0xfffffffc);
if (offset==0xF1B1C2) return(0);
}
- 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;
uint16 data=(((uint16)dsp_ram_8[offset])<<8)|((uint16)dsp_ram_8[offset+1]);
return(data);
}
- 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 data;
{
offset&=0xFFFFFFFC;
- 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;
uint32 data= (((uint32)dsp_ram_8[offset] )<<24)|
(((uint32)dsp_ram_8[offset+1])<<16)|
(((uint32)dsp_ram_8[offset+2])<<8 )|
( (uint32)dsp_ram_8[offset+3]);
return(data);
}
- if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
+ if ((offset>=DSP_CONTROL_RAM_BASE)&&(offset<DSP_CONTROL_RAM_BASE+0x20))
{
offset&=0x1f;
switch (offset)
void dsp_byte_write(unsigned offset, unsigned data)
{
- 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;
if (dsp_in_exec == 0)
{
}
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;
{
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)
{
{
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)
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;
rom = jaguar_rom_load(path, &romSize);
for(uint32 i=0; i<romSize; i++)
jaguar_byte_write(offset+i, rom[i]);
-}
+}//*/
static int go = 0;
void dsp_update_register_banks(void)
// movei #service_address,r30 ; pointer to ISR entry
// jump (r30) ; jump to ISR
// nop
- dsp_pc = dsp_work_ram_base;
+ dsp_pc = DSP_WORK_RAM_BASE;
dsp_pc += which * 0x10;
dsp_reg[30]=dsp_pc;
}
void dsp_init(void)
{
- memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "dsp work ram");
- memory_malloc_secure((void **)&dsp_reg, 32*sizeof(int32), "dsp bank 0 regs");
- memory_malloc_secure((void **)&dsp_alternate_reg, 32*sizeof(int32), "dsp bank 1 regs");
-
+ memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "DSP work RAM");
+ memory_malloc_secure((void **)&dsp_reg, 32*sizeof(int32), "DSP bank 0 regs");
+ memory_malloc_secure((void **)&dsp_alternate_reg, 32*sizeof(int32), "DSP bank 1 regs");
+
dsp_build_branch_condition_table();
dsp_reset();
}
void dsp_done(void)
{
int i, j;
- fprintf(log_get(),"dsp: stopped at pc=0x%.8x dsp_modulo=0x%.8x(dsp %s running)\n",dsp_pc,dsp_modulo,dsp_running?"was":"wasn't");
- fprintf(log_get(),"dsp: %sin interrupt handler\n",(dsp_flags & 0x8)?"":"not ");
+ fprintf(log_get(), "DSP: Stopped at PC=%08X dsp_modulo=%08X(dsp %s running)\n", dsp_pc, dsp_modulo, dsp_running ? "was" : "wasn't");
+ fprintf(log_get(), "DSP: %sin interrupt handler\n", (dsp_flags & 0x8) ? "" : "not ");
int bits, mask;
// get the active interrupt bits
- bits = (dsp_control >> 6) & 0x1f;
+ bits = (dsp_control >> 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++)
//
// }
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);
}
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);
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);
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);
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);
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);
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)
// 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
#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);
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])()=
};
static uint8 * gpu_ram_8;
-//static uint16 *gpu_ram_16;
-//static uint32 *gpu_ram_32;
-
-
static uint32 gpu_pc;
static uint32 gpu_acc;
static uint32 gpu_remain;
static uint32 gpu_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)
#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",
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)
{
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);
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...
return data >> 16;
}
+//TEMP--Mirror of F03000?
+if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
+WriteLog("[GPUR16] --> Possible GPU RAM mirror access!");
+
return jaguar_word_read(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)
}
// 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);
}
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)
}
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;
}
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);
}
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;
}
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...
{
}
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);
}
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)
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)))
// 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();
// 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
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:
}
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);
}
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];
}
// else
// {
-// fprintf(log_get(),"\tnot switching banks\n");
+// WriteLog("\tnot switching banks\n");
// }
}
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;
// 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;
}
}
+//TEMPORARY: Testing only!
+#include "gpu2.h"
+#include "gpu3.h"
+
void gpu_init(void)
{
memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work ram");
build_branch_condition_table();
gpu_reset();
+
+//TEMPORARY: Testing only!
+ gpu2_init();
+ gpu3_init();
}
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;
// 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;
{
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;
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);
}
// Main GPU execution core
//
+static int testCount = 1;
+static int len = 0;
void gpu_exec(int32 cycles)
{
if (!GPU_RUNNING)
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<len; i+=4)
+ WriteLog(" %08X", gpu_long_read(gpu_reg[15]+i));
+ WriteLog("\n ");
+ for(int i=0; i<len; i+=4)
+ WriteLog(" %08X", gpu_long_read(gpu_reg[14]+i));
+ WriteLog("\n\n");
+}
+if (gpu_pc == 0xF034DE)
+{
+ WriteLog("\nSubtracted! (R14=%08X, R15=%08X):\n ", gpu_reg[14], gpu_reg[15]);
+ for(int i=0; i<len; i+=4)
+ WriteLog(" %08X", gpu_long_read(gpu_reg[15]+i));
+ WriteLog("\n ");
+ for(int i=0; i<len; i+=4)
+ WriteLog(" %08X", gpu_long_read(gpu_reg[14]+i));
+ WriteLog("\n ");
+ for(int i=0; i<len; i+=4)
+ WriteLog(" --------");
+ WriteLog("\n ");
+ for(int i=0; i<len; i+=4)
+ WriteLog(" %08X", gpu_long_read(gpu_reg[9]+4+i));
+ WriteLog("\n\n");
+}//*/
+/*if (gpu_pc == 0xF035C8)
+{
+ WriteLog("\n--> 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--;
// 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];
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];
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];
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];
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<count; i++)
{
int16 a;
- if (i&0x01)
- a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (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<count; i++)
{
int16 a;
- if (i&0x01)
- a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (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"
--- /dev/null
+//
+// 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<size; i++)
+ {
+ short m, r;
+// m = ReadMem16(address+2);
+ m = gpu_word_read(address + 2);
+ if (i & 0x1)
+ r = gpu_alternate_reg[IMM_1+(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;
+}
--- /dev/null
+//
+// 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);
+}
--- /dev/null
+#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
+ }
#define __SDLPTC_H__
#include "SDL.h"
-#ifdef __PORT__
#include <string.h>
#include <stdlib.h>
-#endif // #ifdef __PORT__
-
#include "types.h"
-#ifndef __PORT__
-#define randomize() srand(time(NULL))
-#define random(max) (rand() % (max))
-#endif // #ifndef __PORT__
class Error
{
int nJoystick;
};
-#endif // #ifndef __SDLPTC_H__
+#endif // __SDLPTC_H__
--- /dev/null
+void blitter2_exec(DWORD cmd);
-////////////////////////////////////////////////////////////////////////////////
+//
// 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
+};
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+// 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);
void dsp_check_if_i2s_interrupt_needed(void);
void dsp_releaseTimeslice(void);
-#endif
+#endif // #ifndef __DSP_H__
+++ /dev/null
-
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
+++ /dev/null
-
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
+++ /dev/null
- 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--;
- }
- }
- }
-//////////////////////////////////////////////////////////////////////////////
//
-//////////////////////////////////////////////////////////////////////////////
+// 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);
void gpu_reset_stats(void);
uint32 gpu_read_pc(void);
-#endif
+#endif // #ifndef __GPU_H__
--- /dev/null
+//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,
+};
--- /dev/null
+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
+};
#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"
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);
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);
-//////////////////////////////////////////////////////////////////////////////
//
-//////////////////////////////////////////////////////////////////////////////
+// LOG.H
//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
#ifndef __LOG_H__
#define __LOG_H__
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
+
+#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__
+++ /dev/null
-int Dasm68000(char * pBase, char * buffer, int pc);
+++ /dev/null
-#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);
-}
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__
-//////////////////////////////////////////////////////////////////////////////
//
-//////////////////////////////////////////////////////////////////////////////
+// TOM Header file
//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
#ifndef __TOM_H__
#define __TOM_H__
#define VIDEO_MODE_16BPP_DIRECT 2
#define VIDEO_MODE_16BPP_RGB 3
-
extern uint32 tom_width;
extern uint32 tom_height;
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
#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);
void tom_set_pending_video_int(void);
void tom_reset_timer(void);
-
-#endif
+#endif // __TOM_H__
--- /dev/null
+#ifndef __UNZIP_H__
+#define __UNZIP_H__
+
+#include "types.h"
+#include <stdio.h>
+
+#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__
-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,
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,
- };
+};
- 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--;
}
}
{
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--;
}
}
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--;
}
}
{
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--;
}
}
-#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,",
"nc nz,",
"nc z,",
"???,",
+
"c,",
"c nz,",
"c z,",
"nn nz,",
"nn z,",
"???,",
+
"n,",
"n nz,",
"n z,",
-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;
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;
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
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;
}
//
#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;
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
{
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
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))
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))
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);
//}
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))
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;
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);
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);
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
//
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;
}
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<qt; i++)
{
- fprintf(log_get(), "failed\n");
- log_done();
- exit(0);
- return;
- }
- fseek(fp, 0, SEEK_END);
+ oldpc = pc;
+// for(int j=0; j<64; j++)
+// mem[j^0x01] = jaguar_byte_read(pc + j);
- /* Added by SDLEMU (http://sdlemu.ngemu.com) */
- /* Added for GCC UNIX compatibility */
-#ifdef __GCCUNIX__
- fgetpos(fp, (fpos_t *)&filepos);
-#else
- fgetpos(fp, &filepos);
+// pc += Dasm68000((char *)mem, buffer, 0);
+ pc += m68k_disassemble(buffer, pc, M68K_CPU_TYPE_68000);
+ WriteLog("%08X: %s\n", oldpc, buffer);
+ }
#endif
-
- *romSize = (int)filepos;
- fseek(fp, 0, SEEK_SET);
- fread(rom, 1, *romSize, fp);
- fclose(fp);
- fprintf(log_get(), "ok (%i bytes)\n", *romSize);
}
-//
-// Byte swap a region of memory
-//
+unsigned jaguar_byte_read(unsigned int offset)
+{
+ uint8 data = 0x00;
-/*void jaguar_byte_swap(uint8 * rom, uint32 size)
+ 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)
{
- 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<qt; i++)
+ offset &= 0xFFFFFF;
+ if (offset < 0x400000)
{
- oldpc = pc;
- for(int j=0; j<64; j++)
- mem[j^0x01] = jaguar_byte_read(pc + j);
-
- pc += Dasm68000((char *)mem, buffer, 0);
- fprintf(log_get(), "%08X: %s\n", oldpc, buffer);
+// jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data;
+ jaguar_mainRam[offset & 0x3FFFFF] = data;
+ return;
}
-#endif
+// 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);
}
-//
-// 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)
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);
}
}
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);
if (jaguar_mainRom_crc32 == 0x8483392b)
{
- dsp_enabled = 1;
+ dsp_enabled = true;
}
#else // #ifdef JAGUAR_WIP_RELEASE
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);
}
// 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)
// 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);
{
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)
// 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
// 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);
}
// 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
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);
}
#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();
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
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
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();
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);
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);
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);
}
//#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;
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;
{
// 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;
}
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)
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)
}
}
-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;
void jerry_done(void)
{
- //fprintf(log_get(),"jerry_done()\n");
+ //WriteLog("jerry_done()\n");
memory_free(jerry_ram_8);
clock_done();
anajoy_done();
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)
{
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];
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))
{
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))
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];
}
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
return;
}
+//Need to protect write attempts to Wavetable ROM (F1D000-FFF)
+ if (offset >= 0xF1D000 && offset <= 0xF1DFFF)
+ return;
+
jerry_ram_8[offset & 0xFFFF] = 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);
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;
}
//
// 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 <mmsystem.h>
-#endif
+//#ifndef __PORT__
+//#include "include/stdafx.h"
+//#include <mmsystem.h>
+//#endif
#include <time.h>
#include <SDL.h>
#include "SDLptc.h"
#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
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)
{
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();
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])
// 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;
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 */
uint8 joystick_byte_read(uint32 offset)
{
+ extern bool hardwareTypeNTSC;
offset &= 0x03;
if (offset == 0)
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))
}
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;
//
// 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"
int log_init(char * path)
{
log_stream = fopen(path, "wrt");
+
if (log_stream == NULL)
return 0;
+
return 1;
}
{
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!
+}
/* 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);
/* 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 */
+++ /dev/null
-/*
- * 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 <string.h>
-#include <stdio.h>
-
-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
{
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);
}
if (currentAllocatedMemory > maximumAllocatedMemory)
maximumAllocatedMemory = currentAllocatedMemory;
*new_ptr = ptr;
- fprintf(log_get(), "ok\n");
+ WriteLog("OK\n");
}
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)
//
// 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 <stdio.h>
//#define OP_DEBUG
//#define OP_DEBUG_BMP
-//WTFITF???static int cnt = 0;
-extern uint32 jaguar_mainRom_crc32;
-
-static uint8 * op_blend_y;
-static uint8 * op_blend_cc;
-
-#define BLEND_Y(dst,src) op_blend_y[(((uint16)dst)<<8) | ((uint16)(src))]
-#define BLEND_CC(dst,src) op_blend_cc[(((uint16)dst)<<8) | ((uint16)(src))]
-
-static uint8 objectp_ram[0x40];
-uint8 objectp_running;
-uint8 objectp_stop_reading_list;
-
-#define OBJECT_TYPE_BITMAP 0
-#define OBJECT_TYPE_SCALE 1
-#define OBJECT_TYPE_GPU 2
-#define OBJECT_TYPE_BRANCH 3
-#define OBJECT_TYPE_STOP 4
-/*
-#define OBJECT_TYPE_BITMAP 000
-#define OBJECT_TYPE_SCALE 001
-#define OBJECT_TYPE_GPU 010
-#define OBJECT_TYPE_BRANCH 011
-#define OBJECT_TYPE_STOP 100
-*/
-
-#define CONDITION_EQUAL 0
-#define CONDITION_LESS_THAN 1
-#define CONDITION_GREATER_THAN 2
-#define CONDITION_OP_FLAG_SET 3
+#define 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;
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;
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;
}
}
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]);
}
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");
// 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)
// 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 <windows.h>
-#endif
#include <SDL.h>
#include "SDLptc.h"
#include "tom.h"
#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
#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);
tom_render_16bpp_direct_scanline,
tom_render_16bpp_rgb_scanline,
};
+
render_xxx_scanline_fn * scanline_render_stretch[]=
{
tom_render_16bpp_cry_stretch_scanline,
tom_render_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)
{
}
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;
{
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];
width--;
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
void tom_render_16bpp_cry_stretch_scanline(int16 *backbuffer)
{
uint32 chrm, chrl, y;
width--;
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
void tom_render_24bpp_stretch_scanline(int16 *backbuffer)
{
uint16 width=tom_width;
{
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;
width--;
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
void tom_render_16bpp_direct_stretch_scanline(int16 *backbuffer)
{
uint16 width=tom_width;
width--;
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer)
{
uint16 width=tom_width;
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<tom_real_internal_width; i++)
- *current_line_buffer_16++ = bg;
+ // Clear line buffer with BG
+ if (GET16(tom_ram_8, VMODE) & BGEN) // && (CRY or RGB16)...
+ for(uint32 i=0; i<tom_real_internal_width; i++)
+ *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
- op_process_list(backbuffer, scanline, render);
+// op_process_list(backbuffer, scanline, render);
+ OPProcessList(scanline, render);
- (scanline_render[tom_getVideoMode()])(backbuffer);
+ scanline_render[tom_getVideoMode()](backbuffer);
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
+
//
+// TOM initialization
//
-//////////////////////////////////////////////////////////////////////////////
void tom_init(void)
{
op_init();
blitter_init();
pcm_init();
-// fprintf(log_get(),"tom_init()\n");
- memory_malloc_secure((void **)&tom_ram_8, 0x4000, "tom ram");
-// tom_ram_16 = (uint16 *)tom_ram_8;
-// tom_ram_32 = (uint32 *)tom_ram_8;
+ memory_malloc_secure((void **)&tom_ram_8, 0x4000, "TOM RAM");
tom_reset();
+ // Setup the non-stretchy scanline rendering...
memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render));
tom_calc_cry_rgb_mix_lut();
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
+void tom_done(void)
+{
+ op_done();
+ pcm_done();
+ blitter_done();
+ WriteLog("TOM: Resolution %i x %i %s\n", tom_getVideoModeWidth(), tom_getVideoModeHeight(),
+ videoMode_to_str[tom_getVideoMode()]);
+// WriteLog("\ntom: object processor:\n");
+// WriteLog("tom: pointer to object list: 0x%.8x\n",op_get_list_pointer());
+// WriteLog("tom: INT1=0x%.2x%.2x\n",tom_byte_read(0xf000e0),tom_byte_read(0xf000e1));
+ gpu_done();
+ dsp_done();
+ memory_free(tom_ram_8);
+}
+
uint32 tom_getHBlankWidthInPixels(void)
{
return hblankWidthInPixels;
}
-//////////////////////////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-//
-//
-//
-//////////////////////////////////////////////////////////////////////////////
+
uint32 tom_getVideoModeWidth(void)
{
- static uint16 onetime = 1;
+// static uint16 onetime = 1;
-/* uint16 vmode = SWAP_16(VMODE);
- uint16 hdb = SWAP_16(HDB);
- uint16 hde = SWAP_16(HDE);
- uint16 hbb = SWAP_16(HBB);
- uint16 hbe = SWAP_16(HBE);*/
- uint16 vmode = GET16(VMODE);
- uint16 hdb = GET16(HDB);
- uint16 hde = GET16(HDE);
- uint16 hbb = GET16(HBB);
- uint16 hbe = GET16(HBE);
+ uint16 vmode = GET16(tom_ram_8, VMODE);
+ uint16 hdb1 = GET16(tom_ram_8, HDB1);
+// uint16 hde = GET16(tom_ram_8, HDE);
+// uint16 hbb = GET16(tom_ram_8, HBB);
+// uint16 hbe = GET16(tom_ram_8, HBE);
- int clock_cycles_per_pixel = ((vmode >> 9) & 0x07);
+ int clock_cycles_per_pixel = (vmode & PWIDTH) >> 9;
uint32 width = 640;
switch (clock_cycles_per_pixel)
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;
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);
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);
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);
}
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;
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;
}
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))
{
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))
{
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();
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)
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");
-}
--- /dev/null
+//
+// ZIP file support (mostly ripped from MAME)
+//
+// Added by James L. Hammons
+//
+
+#include "unzip.h"
+//#include "driver.h"
+#include "log.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <zlib.h>
+
+/* 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;i<ZIP_CACHE_MAX;++i) {
+ if (zip_cache_map[i] && zip_cache_map[i]->pathtype == 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<ZIP_CACHE_MAX;++i) {
+ if (zip_cache_map[i]==zip) {
+ /* close zip */
+ closezip(zip);
+
+ /* reset cache entry */
+ zip_cache_map[i] = 0;
+ return;
+
+ }
+ }
+ /* not found */
+
+ /* close zip */
+ closezip(zip);
+}
+
+/* CK980415 added to allow osd code to clear zip cache for auditing--each time
+ the user opens up an audit for a game we should reread the zip */
+void unzip_cache_clear()
+{
+ unsigned i;
+
+ /* search in the cache buffer for any zip info and clear it */
+ for(i=0;i<ZIP_CACHE_MAX;++i) {
+ if (zip_cache_map[i] != NULL) {
+ /* close zip */
+ closezip(zip_cache_map[i]);
+
+ /* reset cache entry */
+ zip_cache_map[i] = 0;
+/* return; */
+
+ }
+ }
+}
+
+#define cache_suspendzip(a) suspendzip(a)
+
+#else
+
+#define cache_openzip(a,b,c) openzip(a,b,c)
+#define cache_closezip(a) closezip(a)
+#define cache_suspendzip(a) closezip(a)
+
+#define unzip_cache_clear()
+
+#endif
+
+/* -------------------------------------------------------------------------
+ Backward MAME compatibility
+ ------------------------------------------------------------------------- */
+
+//
+// Compare two filenames
+// NOTE: Don't check directory in zip and ignore case
+//
+static int equal_filename(const char * zipfile, const char * file)
+{
+// const char * s1 = file;
+ // start comparison after last / also...!
+ const char * s1 = strrchr(file, '/');
+ if (s1)
+ s1++;
+ else
+ s1 = file;
+ // start comparison after last /
+ const char * s2 = strrchr(zipfile, '/');
+ if (s2)
+ s2++;
+ else
+ s2 = zipfile;
+//WriteLog("--> 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;
+}
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)
--- /dev/null
+//
+// 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 <unistd.h>
+#endif // __GCCUNIX__
+
+#include <time.h>
+#include <SDL.h>
+#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<argc || argv[i]!=NULL; i++)
+ {
+ // This would be the most likely place to do the cart loading...
+ if (argv[i][0] != '-')
+ haveCart = true; // It looks like we have a cartridge!
+
+ if (!strcmp(argv[i], "-fullscreen"))
+ {
+ fullscreen = true;
+ console.option("fullscreen output");
+ }
+
+ if (!strcmp(argv[i], "-window"))
+ console.option("windowed output");
+
+ if (!strcmp(argv[i], "-joystick"))
+ console.option("joystick enabled");
+
+ if (!strcmp(argv[i], "-joyport"))
+ {
+ nJoyport = atoi(argv[++i]) + 1;
+ if (nJoyport > 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; i<nCount-1; i++)
+ jaguar_exec(backbuffer, false);
+#endif
+ // Setting up new backbuffer with new pixels and data
+ jaguar_exec(backbuffer, true);
+ totalFrames++;
+
+ // Simple frameskip
+ if (nFrame == nFrameskip)
+ {
+ int32 * vs = (int32 *)surface->lock();
+ 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);
+}