From 2b23b5cbaf15bccc2aae0ff3ee91cedd26f101bd Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 17 Dec 2012 20:59:21 -0500 Subject: Switch to the more complete Snes9x 1.53 documentation. --- source/doc/porting.txt | 725 ------------ source/docs/changes.txt | 2459 +++++++++++++++++++++++++++++++++++++++ source/docs/control-inputs.txt | 68 ++ source/docs/controls.txt | 97 ++ source/docs/gpl-2.0.txt | 339 ++++++ source/docs/lgpl-2.1.txt | 504 ++++++++ source/docs/porting.html | 371 ++++++ source/docs/portsofsnes9x.txt | 118 ++ source/docs/snapshots.txt | 84 ++ source/docs/snes9x-license.txt | 174 +++ source/docs/snes9x.conf.default | 238 ++++ 11 files changed, 4452 insertions(+), 725 deletions(-) delete mode 100644 source/doc/porting.txt create mode 100644 source/docs/changes.txt create mode 100644 source/docs/control-inputs.txt create mode 100644 source/docs/controls.txt create mode 100644 source/docs/gpl-2.0.txt create mode 100644 source/docs/lgpl-2.1.txt create mode 100644 source/docs/porting.html create mode 100644 source/docs/portsofsnes9x.txt create mode 100644 source/docs/snapshots.txt create mode 100644 source/docs/snes9x-license.txt create mode 100644 source/docs/snes9x.conf.default (limited to 'source') diff --git a/source/doc/porting.txt b/source/doc/porting.txt deleted file mode 100644 index 3d28eec..0000000 --- a/source/doc/porting.txt +++ /dev/null @@ -1,725 +0,0 @@ - How to Port Snes9x to a New Platform - ==================================== - -Version: 1.01 -Date: 23-December-1998 - -(c) Copyright 1998 Gary Henderson (gary@daniver.demon.co.uk) - -Introduction -============ - -This is brief description of the steps involved in porting Snes9x, the Super -Nintendo Entertainment System emulator, to new hardware which is at least -similar to Workstation or PC. It describes what code you have to write and -what functions exist that you can make use of. It also gives some insights as -to how Snes9x actually works, although that will be subject of another -document yet to be written. - -Host System Requirements -======================== - -A C++ compiler, so you can compile the emulator! Snes9x really isn't written -in C++, it just uses the C++ compiler as a 'better C' compiler to get inline -functions and so on. With some modification, it could be converted to be -compiled with an ordinary C compiler. Snes9x isn't very C type safe and -will probably not work on a system who's integers are less than 32-bits wide -without lots of editing. - -If the host system uses a CPU that implements the i386 instruction set then -you will also want to use the three assembler CPU cores, although I recently -scrapped the SPC700 assembler code (too many bugs) and replaced it with -compiler generated assembler code that I haven't got around to optimising -yet. The 65c816 and SPC700 code needs to be assembled using the GNU -assembler that comes with gcc and the Super FX code assembled with NASM -v0.97 or higher. gcc is available from lots of sites. NASM is available from -http://www.cryogen.com/Nasm - -A fast CPU. SNES emulation is very compute intensive: two, or sometimes three -CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor -with real-time sample decompression, filter and echo effects, two custom -graphics processor chips that can produce transparency, scaling, rotation -and window effects in 32768 colors, and finally hardware DMA all take their -toll on the host CPU. - -Lots of RAM. The SNES itself has 128k work RAM, 64k V-RAM and 64k sound CPU -RAM. If a Super FX game is being emulated, that usually comes with another -64k inside the game pack. Snes9x itself needs 4Mb to load SNES ROM images -into (or 6Mb if I ever figure out the SNES memory map of the 48Mbit ROM -images out there), 256k to cache decompressed sound samples in, 512k to -cache converted SNES tiles in, and another 64k for S-RAM emulation. And -that's not counting a few large lookup tables that the graphics code needs -for speeding up transparency effects plus few other tables used by the ZSNES -Super FX code. It all adds up to 7Mb (ish). Add to that RAM needed to -store the actual emulator code and RAM required by the host operating system -and any other process that is running; that's lots of RAM. Well, it is if -your host system only has a few mega-bytes of RAM available. - -An 8-bit, 256 color (one byte per pixel) or deeper display, at least 256x239 -pixels in resolution, or 512x478 if you're going to support the SNES' -hi-res. background screen modes. Ideally, a 16-bit, 65536 color screen mode -is required if you want to support transparency at speed, as that is what the -code renders internally. Any other format screen, with transparency enabled, -will require picture format conversion before you can place the rendered -SNES image on to the screen. - -Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound -data to the host computer's sound hardware. The DOS port uses interrupts -from the sound card to know when more sound data is required, most other -ports have to periodically poll the host sound hardware to see if more data -is required; if it is then the SNES sound mixing code provided by Snes9x is -called to fill an area of system memory with ready mixed SNES sound data, -which then can be passed on to the host sound hardware. Sound data is -generated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for -16-bit data. Stereo sound data generates twice as many samples, with each -channel's samples interleaved, first left's then right's. - -For the user to be able to control and play SNES games, some form of input -device is required, a joystick or keyboard, for example. The real SNES can -have 2 eight-button digital joy-pads connected to it or 5 joy-pads when an -optional multi-player adaptor was purchased, although most games only require -a single joy-pad. Access to all eight buttons and the direction pad, of -course, are usually required by most games. Snes9x does emulate the -multi-player adaptor hardware, if you were wondering, but its still up to -you to provide the emulation of the individual joy-pads. - -The SNES also had a mouse and light gun available as optional extras, -Snes9x can emulate both of these using some form of pointing device, -usually the host system's mouse. - -If an accurate, constant SNES play rate is required, then a real-time timer -will be needed that can time intervals of 16.7ms (NTSC frame time) or 20ms -(PAL frame time). - -Some SNES game packs contained a small amount of extra RAM and a battery so -ROMs could save a player's progress through a game for games that takes many -hours to play from start to finish. Snes9x simulates this S-RAM by saving -the contents of the area of memory normally occupied by the S-RAM into file -then automatically restoring it again the next time the user plays the same -game. If the hardware you're porting to doesn't have a hard disk available -then you could be in trouble. - -Snes9x also implements freeze-game files which can record the state of the -SNES hardware and RAM at a particular point in time and can restore it to -that exact state at a later date - the result is that users can save a game -at any point, not just at save-game or password points provided by the -original game coders. Each freeze file is over 400k in size. To help save -disk space, Snes9x can be compiled with zlib, which is used to compress the -freeze files, reducing the size to typically below 100k. Download zlib from -its homepage at http://www.cdrom.com/pub/infozip/zlib/, compile Snes9x with -ZLIB defined and link with zlib. zlib is also used to load any compressed -ROM images Snes9x my encounter, compressed with gzip or compress. - -Porting -======= - -In theory you will only need to edit port.h, then in a separate file write -all the initialisation code and interface routines that Snes9x expects the -you to implement. You, no doubt, will discover otherwise.... - -There are several compile-time only options available: - -DEBUGGER --------- - -Enables extra code to assist me in debugging SNES ROMs. The debugger has only -ever been a quick-hack by me and user-interface to debugger facilities is -virtually non-existent. Most of the debugger information is output via -stdout and enabling the compile-time options slows the whole emulator down -slightly. However, the debugger options available are very powerful; you -could use it to help get your port working. You probably still want to ship -the finished version with the debugger disabled, it will only confuse -non-technical users. - -VAR_CYCLES ----------- - -I recommend you define this. The main CPU in the SNES actually varies in -speed depending on what area of memory its accessing and the ROM access -speed of the game pack; defining VAR_CYCLES causes Snes9x to emulate this, -using a good approximation, rather than fixed cycle length as ZSNES does. The -resultant code is slightly slower. Leaving it undefined results in many more -emulation timing errors appearing while playing games. - -CPU_SHUTDOWN and SPC700_SHUTDOWN --------------------------------- - -Again I recommend defining both of these. They are both speed up hacks. -When defined, Snes9x starts watching for when either the main or sound CPUs -are in simply loops waiting for a known event to happen - like the end of -the current scan-line, and interrupt or a sound timer to reach a particular -value. If Snes9x spots either CPU in such a loop it uses its insider -knowledge to simply skip the emulation of that CPU's instructions until the -event happens. It can be a big win with lots of SNES games. - -I'm constantly amazed at the ingenuity of some programmers who are able to -produce complex code to do simple things: some ROM's wait loops are so -complex Snes9x fails to spot the CPU is in such a loop and the shutdown -speed up hacks don't work. - -You might be wondering why VAR_CYCLES, and the two SHUTDOWN options have to -be enabled with defines, well, in the past they sometimes introduced -problems with some ROMs, so I kept them as options. I think I've fixed all -the problems now, but you never know... - -SPC700_C --------- - -Define this if you are using the C/C++ version of the SPC700 CPU core. It -enables a ROM compatibility feature that executes SPC700 instructions during -SNES DMA, it allows several games to start that would otherwise lock up and -fixes music pauses when ROMs do lots of DMA, usually when switching between -game screens. - -ZLIB ----- - -Define this if you have the zlib library available and you want it to -compress freeze-game files to save disk space. The library is also used to -support compressed ROM images. - -NO_INLINE_SET_GET ------------------ - -Define this to stop several of the memory access routines from being -defined in-line. Whether the C++ compiler actually in-lines when this symbol -is not defined is up to the compiler itself. In-lines functions can speed up -the C++ CPU emulations on some architectures at the cost of increased code -size. Try fiddling with this option once you've got port working to see if -it helps the speed of your port. - -EXECUTE_SUPERFX_PER_LINE and ZSNES_FX -------------------------------------- - -Define these if you're going to be using the ZSNES Super FX i386 assembler -code, otherwise leave them both undefined. In theory, -EXECUTE_SUPERFX_PER_LINE can also be defined when using the C++ Super FX -emulation code, but the code is still buggy and enabling the option -introduces more problems than it fixes. Any takers for fixing the C++ code? - -JOYSTICK_SUPPORT, SIDEWINDER_SUPPORT and GRIP_SUPPORT ------------------------------------------------------ - -These options enable support for various input devices in the UNIX and MS-DOS -port code. They're only of interest if you're able to use the existing UNIX -or MS-DOS port specific code. - -port.h -====== - -If the byte ordering of the target system is least significant byte first, -make sure LSB_FIRST is defined in this header, otherwise, make sure its not -defined. - -If you're going to support 16-bit screen rendering (required if you want -transparency effects) and your system doesn't use RGB 565 - 5 bits for red, -6 bits for green and 5 bits for blue - then you'll need make sure RGB555, -BGR565 or BGR555 is defined instead. You might want to take a look at the -*_LOW_BIT_MASKs, *_HI_BIT_MASKs and BUILD_PIXEL macros to make sure they're -correct, because I've only every tested the RGB565 version, though the Mac -port uses the RGB555 option. If your system is 24 or 32-bit only, then -don't define anything; instead write a conversion routine that will take a -complete rendered 16-bit SNES screen in RGB565 format and convert to the -format required to be displayed on your hardware. - -port.h also typedefs some types, uint8 for an unsigned, 8-bit quantity, -uint16 for an unsigned, 16-bit quantity, uint32 for a 32-bit, unsigned -quantity and bool8 for a true/false type. Signed versions are also -typedef'ed. - -The CHECK_SOUND macro can be defined to invoke some code that polls the -host system's sound hardware to see if it can accept any more sound data. -Snes9x makes calls to this macro several times when it is rendering the SNES -screen, during large SNES DMAs and after every emulated CPU instruction. - -Since this CHECK_SOUND macro is invoked often, the code should only take a -very small amount of time to execute or it will slow down the emulator's -performance. The Linux and UNIX ports use a system timer and set a variable -when it has expired; the CHECK_SOUND only has to check to see if the -variable is set. On the MS-DOS and Mac ports, the sound hardware is not -polled at all, instead it is driven by interrupts or callbacks and the -CHECK_SOUND macro is defined to be empty. - -Initialisation Code -------------------- - -This is what the Linux, UNIX and MS-DOS ports do, I suspect your code -might be similar: - -- The Settings structure is initialised to some sensible default values - - check the main function in unix.cpp for the values it uses. - -- The command line is parsed, options specified override default values in - the Settings structure and specify a ROM image filename that the user - wants loaded. Your port could load user preferences from a file or some - other source at this point. Most values, with a little care, can be changed - via a GUI once the emulator is running. - -- Some Settings structure value validation takes place, for example if - transparency effects are requested the code also makes sure 16-bit - screen rendering is turned on as well. - -- Memory.Init() and S9xInitAPU() are called, checking neither failed. The - only reason they would fail is if memory allocation failed. - -- Memory.LoadROM (filename) is called to load the specified ROM image into - memory. If that worked Memory.LoadSRAM (sram_filename) is called to load - the ROM's S-RAM file, if one exists. The all current ports base the - sram_filename on the filename of the ROM image, changing the file's - extension (the .smc or whatever bit) and changing the directory where its - located - you won't be able to save S-RAM files onto a CD if that's where - the ROM image is located! - - If your port has a GUI, you can delay this step until the user picks an - image to load. - - SNES roms images come in all shapes and sizes, some with headers, some - without, some have been mangled by the copier device in one of two ways, and - some split into several pieces; plus the SNES itself has several different - memory map models. The code tries to auto-detect all these various types, - but sometimes the SNES ROM header information has been manually edited by - someone at some stage and the code guesses wrong. To help it out it these - situations, the Settings structure contains several options to force a - particular ROM image format; these values must be initialised prior to each - call to Memory.LoadROM(filename). - -- The Linux and UNIX ports now do some more operating system initialisation - ready for a system timer to be started. - -- The host display hardware is now initialised. The actual screen depth and - resolution should be picked based on the user preferences if possible. - The X Window System port can't control the screen depth or resolution, if - the user requests transparency effects but the display hardware is only - set to 8-bit, it has to invoke an extra step of converting the 16-bit SNES - rendered screen to a fixed palette 8-bit display just before the SNES - screen is copied to the display hardware. - - The GFX.Screen pointer needs to be initialised to point to an array of - uint8 for 8-bit screen rendering or uint16 for 16-bit rendering, cast to - an array of uint8. The array needs to be at least 256x239 bytes or shorts - in size for lo-res only support (Settings.SupportHiRes = FALSE) or - 512x478 for lo-res and hi-res support. If transparency effects are - required, the GFX.SubScreen array also needs to be initialised to another - identically sized array of the same type, otherwise it can be just - initialised to NULL. - - The GFX.Pitch variable needs to be set to the number of bytes on each line - of the arrays, e.g. 256 for lo-res only support, up to 1024 for 16-bit - hi-res support. If GFX.Screen is pointing into an existing array, one - created by the library function rather than just calling malloc or new, - then set GFX.Pitch to the number of bytes per line of that array, - including any padding the library function may have added. - - If the target hardware supports fast access to video RAM, the screen is in - 16-bit format supported by the SNES rendering code and you can double - buffer the display, you might want to point GFX.Screen directly at the - video buffer RAM. You will need to recompute the GFX.Delta value every - time you change the GFX.Screen value to double-buffer the rendering and - display. - -- A call to S9xGraphicsInit() is made; make sure all your graphics rendering - options are setup correctly by now. If later, you want to change some - settings, for example 16-bit to 8-bit rendering, call S9xGraphicsDeinit() - first, change your settings, GFX.Screen and GFX.SubScreen arrays, etc., - then call S9xGraphicsInit() again. - -- S9xInitSound(int playbackrate, bool8 stereo, int sound_buffer_size) - is now called, which in turn will call your S9xOpenSoundDevice function - - see below. - -- The display is switched to graphics mode using a call to S9xGraphicsMode(). - -- The system timer is started; its used for keeping the emulator speed - relatively constant on the MS-DOS port and noting when the sound hardware - sound should be able to accept more sound data on the Linux and UNIX ports. - -- A main loop is entered which is just a loop constantly calling - S9xMainLoop() then polling the operating system for any pending events - such as key presses and releases, joystick updates, mouse position - updates, GUI user interaction, etc. - - Pause functionality can be implemented by skipping the call to S9xMainLoop - and muting the sound output by calling S9xSetSoundMute (TRUE). - - Don't enter the main loop until a SNES ROM image has been loaded, or at - least skip calling S9xMainLoop inside the loop until one is and make sure - S9xReset is called instead before entering the main loop. The Mac port - implements this technique by starting in pause mode and refusing to unpause - until a ROM image is loaded. - - S9xMainLoop processes SNES CPU emulation, SNES screen rendering, DMA and - H-DMA emulation, until emulated scan-line 0 is reached, then it returns. - Now is your chance to process any system events pending, scan the - keyboard, read joystick values, etc. - - If DEBUGGER compile-time support is enabled and the CPU emulation has hit - a break point or single-stepping is switched on, or the DEBUG_MODE_FLAG is - set in the CPU.Flags variable, then the S9xMainLoop routine returns early, - allowing you to act on the event in some way. The Linux, DOS and UNIX ports - respond to the DEBUG_MODE_FLAG being set by calling S9xDoDebug(), which in - turn outputs the current instruction and loops reading commands from stdin - and outputting debug information, currently via stdout. The debugger - desperately needs rewriting to support a GUI interface, more descriptive - commands and better error handling; maybe one day... - -Existing Interface Routines ---------------------------- - -These are routines already written that you will either need to call or -might find useful. - --> bool8 Memory.Init () - -Allocates and initialises several major lumps of memory, for example -the SNES ROM and RAM arrays, tile cache arrays, etc. Returns FALSE if -memory allocation fails. - --> void Memory.Deinit () - -Undoes the memory allocations made by Memory.Init. - --> bool8 S9xGraphicsInit () - -Allocated and initialises several lookup tables used to speed up SNES -graphics rendering. Call after you have initialised the GFX.Screen, -GFX.SubScreen and GFX.Pitch values. If Settings.Transparency is false it -does not allocate tables used to speed up transparency effects. If you -want to provide the user with option to turn the effects on and off during -game play, make sure Settings.Transparency is true when this function is -called, it can later be set to FALSE. - -Returns FALSE if memory allocation fails. - --> void S9xGraphicsDeinit () - -Undoes the memory allocations made by S9xGraphicsInit. - --> bool8 S9xInitAPU () - -Allocates and initialises several arrays used by the sound CPU and sound -generation code. - --> void S9xDeinitAPU () - -Undoes the allocations made by S9xInitAPU. - --> bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size) - -Does more sound code initialisation and opens the host system's sound hardware -by calling the S9xOpenSoundDevice function provided by you. - --> void S9xReset () - -Resets the SNES emulated hardware back to the state it was in at 'switch-on' -except the S-RAM area is presevered. The effect is it resets the current game -back to the start. This function is automatically called by Memory.LoROM. - --> bool8 Memory.LoadROM (const char *filename) - -Attempts to load the specified ROM image filename into the emulated ROM area. -There are many different SNES ROM image formats and the code attempts to -auto-detect as many different types as it can and in a vast majority of the -cases gets it right. However, some ROM images have been edited by someone at -some stage or have been mangled by the ROM copier that produced them and -LoadROM needs help. Inparticular, it can't auto-detect the odd way in which -some Super FX games have been mangled and needs to be told, via -Settings.Interleaved2, that the ROM image is in that format, or that -odd-sized ROM images have a 512 byte copier header. - -There are several other ROM image options in the Settings structure; -allow the user to set them before calling LoadROM, or make sure they all -reset to default values before each call to LoadROM. - --> bool8 Memory.LoadSRAM (const char *filename) - -Call this routine to load the associated S-RAM save file (if any). The -filename should be based on the ROM image name to allow easy linkage. -The current ports change the directory and the filename extension of the ROM -filename to derive the S-RAM filename. - --> bool8 Memory.SaveSRAM (const char *filename) - -Call this routine to save the emulated S-RAM area into a file so it can -be restored again the next time the user wants to play the game. Remember -to call this when just before the emulator exits or when the user has been -playing a game and is about to load another one. - --> void S9xMainLoop() - -The emulator main loop. Call this from your own main loop that calls this -function (if a ROM image is loaded and the game is not paused), processes -any pending host system events, then goes back around the loop again until -the emulator exits. - -S9xMainLoop normally returns control to your main loop once every emulated -frame, when it reaches the start of scan-line zero. However, the routine -can return more often if the DEBUGGER compile-time flag is defined and the -CPU has hit a break point, or the DEBUG_MODE_FLAG bit is set in CPU.Flags -or instruction single-stepping is enabled. - --> void S9xMixSamples (uint8 *buffer, int sample_count) - -Call this routine from your host sound hardware handling code to fill the -specified buffer with ready mixed SNES sound data. If 16-bit sound mode is -choosen, then the buffer will be filled with an array of sample_count int16, -otherwise an array of sample_count uint8. If stereo sound generation is -selected the buffer is filled with the same number of samples, but in pairs, -first a left channel sample followed by the right channel sample. - -There is a limit on how much data S9xMixSamples can deal with in one go and -hence a limit on the sample_count value; the limit is the value of the -MAX_BUFFER_SIZE symbol, normally 4096 bytes. - --> bool8 S9xSetSoundMute (bool8 mute) - -Call with a TRUE parmeter to prevent S9xMixSamples from processing SNES -sample data and instead just filling the return buffer with silent sound -data. Useful if your sound system is interrupt or callback driven and the -game has been paused either directly or indirectly because the user -interacting with the emulator's user interface in some way. - --> bool8 S9xFreezeGame (const char *filename) - -Call this routine to record the current SNES hardware state into a file, -the file can be loaded back using S9xUnfreezeGame at a later date effectively -restoring the current game to exact same spot. Call this routine while -you're processing any pending system events when S9xMainLoop has returned -control to you in your main loop. - --> bool8 S9xUnfreezeGame (const char *filename) - -Restore the SNES hardware back to the exactly the state it was in when -S9xFreezeGame was used to generate the file specified. You have to arrange -the correct ROM is already loaded using Memory.LoadROM, an easy way to -arrange this is to base freeze-game filenames on the ROM image name. The -Linux, UNIX and DOS ports load freeze-game files when the user presses a -function key, with the names romfilename.000 for F1, romfilename.001 for F2, -etc. Games are frozen in the first place when the user presses Shift-function -key. You could choose some other scheme. - --> void S9xNextController () - -The real SNES allows several different types of devices to be plugged into -the game controller ports. The devices Snes9x emulates are a joy-pad, -multi-player adaptor (allowing a further 4 joy-pads to be plugged in), -a 2-button mouse and a light gun known as the SuperScope. - -Each call to S9xNextController will step the current emulated device on to -the next device in the sequence multi-player, joy-pad, mouse on port 1, -mouse on port 2, light gun then back to multi-player again. Defines -allocating a number of each device type are in snes9x.h. The currently -selected device is stored in IPPU.Controller if you want to give some -feedback to the user. The initial value of IPPU.Controller (set when -S9xReset is called) is obtained from Settings.ControllerOption based on -currently enabled options. - -Some ROMs object to certain non-joy-pad devices being plugged into the real -SNES while they are running, all Super FX games should only allow joy-pads to -be plugged in because the Super FX chip and any other device would overload -the SNES power supply. Tetris and Dr. Mario also objects for reasons best -known to itself. For this reason there are switches in the Settings -structure to enable and display the emulation of the various devices. - -const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte) - -const char *S9xProActionReplayToRaw (const char *code, uint32 &address, - uint8 &byte) - -const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, - uint8 &num_bytes, uint8 bytes[3]) - -void S9xApplyCheats (bool8 apply) - -void S9xRemoveCheats () - -void S9xAddCheat (uint32 address, bool8 cpu_address, bool8 sram, uint8 num_bytes, - uint8 byte1, uint8 byte2, uint8 byte3) - -void S9xDeleteCheats () - -void S9xDoDebug () - -Interface Routines You Need to Implement ----------------------------------------- - -bool8 S9xOpenSnapshotFile (const char *base, bool8 read_only, STREAM *file) -*************************************************************************** -void S9xCloseSnapshotFile (STREAM file) -*************************************** - -Routines to open and close freeze-game files. STREAM is defined as a -gzFile if ZLIB is defined else its defined as FILE *. The read_only parameter -is set to TRUE when reading a freeze-game file and FALSE when writing a -freeze-game file. - -void S9xExit () -*************** - -Called when some fatal error situation arises or when the 'q' debugger -command is used. The Mac port just beeps and drops back to the GUI when -S9xExit is called, the MS-DOS, Linux and Solaris ports all call exit () to -terminate the emulator process. - -void S9xParseArg (char **argv, int &index, int argc) -**************************************************** - -void S9xExtraUsage () -********************* - -If you're going to be using the simple command line parser, when it -encounters an unknown option it calls S9xUsage which is supposed to report -all options the generic parse knows about (I haven't been keeping it up to -date of late). S9xUsage then, in turn calls S9xExtraUsage which you -implement to report any port-specific options available. - -void S9xGraphicsMode () -*********************** -void S9xTextMode () -******************* - -The SNES debugger calls these routines to switch from a graphics screen -mode used to display the SNES game to a debugger screen used to display -debugger output. If the SNES screen can be displayed at the same time as -a text display, as would be the case when the host system implements a -graphical window system, or you're not going to support the SNES debugger, -then these routines should do nothing. - -On the X Window System UNIX/Linux port, these routines do nothing where as -on the MS-DOS port they switch between a graphics screen mode and a text-only -screen mode. - -bool8 S9xInitUpdate () -********************** - -Called just before Snes9x starts to render a SNES screen. The Windows port -uses this call to lock Direct X screen area to allow exclusive access; on -other existing ports its implemented as an empty function. - -bool8 S9xDeinitDisplay (int width, int height, bool8 sixteen_bit) -***************************************************************** - -Called once a complete SNES screen has been rendered into the GFX.Screen -memory buffer, now is your chance to copy the SNES rendered screen to the -host computer's screen memory. The problem is that you have to cope with -different sized SNES rendered screens. Width is always 256, unless you're -supporting SNES hi-res. screen modes (Settings.SupportHiRes is TRUE), in -which case it can be 256 or 512. The height parameter can be either 224 or -239 if you're only supporting SNES lo-res. screen modes, or 224, 239, 448 or -478 if hi-res. SNES screen modes are being supported. - -All current ports support scaling the SNES screen to fill the host system's -screen, the many ports even supports interpolation - blending the colours of -adjacent pixels to help hide the fact they've been scaled - and scan-line -simulation - slightly darkening every other horizontal line. - -Don't forget that if you're just placing the SNES image centerally in the -screen then you might need to clear areas of the screen if the SNES image -changes size between calls to S9xDeinitDisplay. The MS-DOS and UNIX ports -currently don't do this which results in junk being left on the screen if -the ROM changes SNES screen modes. - -The sixteen_bit is just a copy of the Settings.SixteenBit setting and if -TRUE indicates a 16-bit SNES screen image has been rendered, 8-bit otherwise. - -void S9xMessage (int type, int number, const char *message) -*********************************************************** - -I've started work on converting all the old printfs into calls to this -routine. When Snes9x wants to display an error, information or warning -message, it calls this routine. Check in messages.h for the types and -individual message numbers that Snes9x currently passes as parameters. - -The idea is display the message string so the user can see it, but you -choose not to display anything at all, or change the message based on the -message number or message type. - -Eventually all debug output will also go via this function, trace information -already does. - -bool8 S9xOpenSoundDevice(int mode, bool8 stereo, int buffer_size) -***************************************************************** - -S9xInitSound calls this function to actually open the host operating system's -sound device, or initialise the sound card in MS-DOS port. - -The mode parameter is the value passed in on the command line with the -r -command line flag, assuming you're using the Snes9x parser. Its meant to -indicate what playback the sound hardware should be set to, value 1 to 7. -I think the real SNES sound chip playback rate is 30kHz, but such high -playback rates take a lot of native CPU power to emulate. The default -playback rate is 22kHz for the MS-DOS and UNIX ports. - -The stereo flag indicates if the user wants stereo sound. Again, stereo -sound takes more CPU to power to emulate compared to mono sound. - -The buffer_size value indicates what sample buffer size the user wants, -usually zero, meaning you should pick the value best suited to the current -playback rate. Sound data is normally passed to the sound hardware in -blocks, the smaller the block the less latency between the SNES game playing -a sound and it being heard by the user. But if you pick a too smaller value, -and you're having to periodically poll the operating system to see if it can -accept more sound data, then the sound output will break up because other -actions such as rendering the SNES screen can prevent you from polling the -hardware often enough and the operating system runs out of sound data to -play. - -The MS-DOS port uses a buffer size of 128 samples since the sound card -sends an interrupt when more data is required which is acted upon promptly, -where as the Linux and Solaris ports use a buffer size of 512 samples or -more depending on the playback rate. Stereo and 16-bit sound both double the -actual size of the buffer in bytes. - -uint32 S9xReadJoypad (int which1_0_to_4) -**************************************** - -This function is called to return a bit-wise mask of the state of one of the -five emulated SNES controllers. Return 0 if you're not supporting controllers -past a certain number or return the mask representing the current state of -the controller number passed as a parameter or'ed with 0x80000000. - -Symbolic constants are defined in snes9x.h indicating the bit positions of -the various SNES buttons and direction indicators; they're all in the form -SNES_X_MASK where X is the SNES controller button name. - -The MS-DOS and X Window System ports record what keys are currently pressed -and use that to build up a mask, the Windows port polls the operating system -when S9xReadJoypad is called to find out what keys are pressed. All ports -also implement host joysticks and joy-pads via this interface. - -bool8 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons) -******************************************************************************* - -Used by Snes9x to get the current position of the host pointing device, -usually a mouse, used to emulated the SNES mouse. Snes9x converts the x and -y values to delta values required by the SNES mouse, so the actual x and y -values are unimportant, only the change in value since the last call to -this function is used. - -Graphical windowing systems normally restrict the movement of the pointer on -the screen, if you're porting to such an environment you might want to make -a note of the change in position in the mouse since the last time you asked -the operating system the mouse position, add this change in value to some -saved x and y value, the reposition the pointer back to the centre of the -SNES display window. The saved x and y values will be the values returned -by this function. - -The buttons return value is a bit-wise mask of the two SNES mouse buttons, -bit 0 for button 1 (left) and bit 1 for button 2 (right). - -bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons) -***************************************************************** - -void S9xSetPalette () -********************* - -void S9xSyncSpeed () -S9xUnixProcessSound -void _makepath(char *, char const *, char const *, char const *, char const *) -void _splitpath(char const *, char *, char *, char *, char *) - - -Sound Generation ----------------- - -Settings --------- diff --git a/source/docs/changes.txt b/source/docs/changes.txt new file mode 100644 index 0000000..0f1027f --- /dev/null +++ b/source/docs/changes.txt @@ -0,0 +1,2459 @@ +Snes9x 1.53 + +- Rebuilt IRQ handling. (zones) +- Improved overall timings, now Snes9x can handle events in + a opcode a little. (zones) +- Improved screen interlace and sprite interlace supports. (OV2, zones) +- Fixed Hi-Res pixel plotter. (BearOso, zones, OV2) +- Fixed C4 for Mega Man X2's "weapon get" screen. (Jonas Quinn) +- Fixed Super Buster Bros. graphics after reset. (Jonas Quinn) +- Improved SA-1 support. (zones) +- Added SA-1 CC2 support. (Jonas Quinn, byuu) +- Fixed SA-1 NMI override mode. (zones) +- Fixed Dual Orb 2 sound glitch. (byuu) +- New APU timing hack, fixes various games that exhibit + problems with Blargg's SNES_SPC library. (OV2) +- Fixed the problem that echo buffer breaks IPL ROM. (zones, OV2) +- Fixed movie snapshot unfreeze inconsistency. (gocha) +- Faster config file saving. (OV2) +- Fixed BlockInvalidVRAMAccess config file option. + (windows port, unix port and gtk legacy config) (Jonas Quinn) +- Remove POSIX dup and access calls, and rename qword to + fix compilation with Cell SDK. (BearOso) +- Fixed PS3 version save state crash by using heap + allocation for soundsnapshot. (danieldematteis) +- Fixed crash relating to double-closed descriptor. (BearOso) +- Removed CPUShutdown speedhack, DisableHDMA and + DisableIRQ options. (zones) +- Removed remaining outdated asm code. (zones) +- JMA 64 bit support. (kode54, Nach, friedrich.goepel) +- GTK+, Win32, Mac: Added optional Hi-Res blending. (BearOso, OV2, zones) +- GTK+, Win32: Support for bsnes-style XML shaders. (BearOso, OV2) +- Win32: Full unicode support. (OV2) +- Win32: Restored OpenGL mode. (OV2) +- Win32: x64 version. (OV2) +- Win32: HLSL shader support. (mudlord) +- Win32: Win7 jumplist synchronizes with recent roms list. (OV2) +- Win32: Updated menu structure. (OV2) +- Win32: Drag&Drop support for ROMs. (gocha, OV2) +- Win32: Reworked movie-recording with size selection. (gocha, OV2) +- Win32: Restored SPC save option. (OV2) +- Win32: Fixed vsync in DirectDraw. (OV2) +- Win32: Improved window position saving. (OV2) +- Win32: Restored compile with DEBUGGER. (gocha) +- Win32: Fixed various edge-case errors and/or possible + leaks. (Brian Friesen) +- Win32: Config file option to always center image. (OV2) +- Win32: Fixed "Turbo Down mode" hotkey assignment. (gocha) +- Win32: Added and fixed Autofire for D-pad. (gocha) +- Win32: Fixed aggressive soundsync wait. (OV2) +- Win32: Added window size presets. (OV2) +- Mac : Added pause and frame advance functions. (zones) +- Mac : Now you can choose any folder for saving files. (zones) +- Mac : Updated Music Box (mostly internally). (zones) +- Mac : Fixed gliches in open/save dialogs on 10.6. (zones) +- Mac : Fixed display configuration in windowed mode. (zones) +- Unix : Fixed segfault and hang-up with -DNOSOUND. (zones) +- GTK+ : Added ability to set specific folders for SRAM, + patches, snapshots, etc. (BearOso) +- GTK+ : Fixed many permissions issues with config folders. (BearOso) +- GTK+ : Updated compatibility with latest GTK+ and + GtkBuilder. Added experimental support for GTK+ 3.x. (BearOso) +- GTK+ : Updated software output to use cairo and added the + ability to use bilinear-filtering with it. (BearOso) +- GTK+ : Fixed issues where cheats wouldn't stay enabled. (BearOso) +- GTK+ : Fixed focus issue when there is no window manager. (BearOso) +- GTK+ : Fixed X Visual incompatibilities and expose + problems in the Xv and OpenGL outputs. (BearOso) +- GTK+ : Fixed vsync with new X Server and NVIDIA drivers. (BearOso) +- GTK+ : Added "Reduce input lag" option to OpenGL output. (BearOso) +- GTK+ : Added a visual indication of the expected video + refresh rate for the currently selected sound input rate. (BearOso) + +Snes9x 1.52 +- IMPORTANT NOTICE: The structure of savestates (also known + as snapshots / freeze files) is incompatible with older + versions! Snes9x 1.52 cannot read the savestates created + by 1.51 or older. (zones) +- Highly acculate SPC700 and S-DSP emulation. (Blargg) +- Replaced APU emulation cores (SPC700 and S-DSP) with + ones provided by Blargg's SNES_SPC library. This renders + savestates incompatible with older versions. (BearOso, zones) +- SPC7110 emulation. (byuu, neviksti) +- Merged bsnes' SPC7110 emulation code. Note that the .rtc + file of Far East of Eden Zero is incompatible with older + versions. (zones) +- Removed graphics pack support. It's no more necessary. (zones) +- Replaced S-RTC emulation code with bsnes' one to keep the + good compatibility of .rtc files between the two + emulators. As a result, Daikaijuu Monogatari 2 now + outputs the .rtc file, and its .srm file is incompatible + with older versions. (zones) +- Added savestate supports for DSP-2, DSP-4, ST-010 and + OBC1. (zones) +- Added UPS support. (byuu) +- Fixed DSP-4 AI problem. (Jonas Quinn) +- Fixed invalid memory accesses in C4 and OBC1 codes. (zones) +- Fixed invalid memory accesses in BSX codes. My mistake. (zones) +- Fixed the read value of $213e, $4210 and $4211. (zones) +- Fixed the writing of word values at the memory boundary. (zones) +- Fixed the bug that the unnecessary SA-1 emulation + continues once any SA-1 games are launched. (zones) +- Removed old color blending codes. (zones) +- Removed too-old Snes96 and ZSNES snapshot support. (zones) +- Updated command-line options. (zones) +- Code cleaning. (zones) +- GTK+ : Added a port of Snes9x to the GTK+ toolkit. (BearOso) +- Unix : Reconstructed and simplified all the contents. + Some features have been removed to be simple, and many + options have changed. GTK+ port is recommended for most + of Linux users. (zones) +- Win32: Now uses snes9x.conf to prevent problems with + modified meaning of settings. (OV2) +- Win32: Removed broken OpenGL mode. (OV2) +- Win32: Removed support for 8bit output. (OV2) +- Win32: Reworked settings dialogues to accomodate the + new APU core and display settings. (OV2) +- Win32: Updated defaults to use D3D and XA2 (better + Vista and Win7 support). (OV2) +- Win32: Direct3D and XAudio2 support. (OV2) +- Win32: Added Blargg's ntsc filter (three presets). (OV2) +- Mac : Fixed corrupted screenshot on Intel Mac. (zones) +- Mac : Fixed sudden abort in QuickTime movie export on + Intel Mac. (zones) +- Mac : Changed sound settings for the new APU core. (zones) +- Mac : Changed the default folder which Snes9x looks for + to 'Application Support' folder. (zones) +- Mac : Changed folder names: 'IPSs' -> 'Patches', + 'BIOSs' -> 'BIOSes'. (zones) +- Mac : Added Blargg's ntsc filter. (zones) +- Mac : Internal changes for Leopard and Snow Leopard. (zones) + +Snes9x 1.51 +- Added DSP1 and SuperFX savestate support. (nitsuja) +- Added screen state GFX to save states. (optional) (nitsuja) +- Fixed desync when loading inconsistent state in playback. (nitsuja) +- When playback reaches a movie's end, recording continues + instead of the movie suddenly closing. (after recording) (nitsuja) +- can now record resets and mouse/superscope/justifier(s) (nitsuja) +- Added same-line-comment support for config files. (nitsuja) +- input display for all controllers (including peripherals) (nitsuja) +- Win32: Now uses .cfg file instead of Windows registry. (nitsuja) +- Win32: open ROM dialog bugfixes and speedup and facelift (nitsuja) +- Win32: option to use standard file open dialog for ROMs (nitsuja) +- Win32: maintain aspect ratio and bilinear filter stretch (nitsuja) +- Win32: optional removal of the dreaded "black bar" (nitsuja) +- Win32: Added EPX,EPX2,EPX3,HQ2X,HQ3X,TV3X,DM3X filters. (nitsuja) +- Win32: Added hires support for Interlace and TV Mode. (nitsuja) +- Win32: text removed from .avi output (optional) (nitsuja) +- Win32: better directory management, customizeable (nitsuja) +- Win32: Screenshot support is back. (nitsuja) +- Win32: Netplay is back (but still not very good). (nitsuja) +- Win32: Made OpenGL Bi-linear an advanced .cfg option. (nitsuja) +- Win32: cheat search improvements (address, watch, SuperFX)(nitsuja) +- Win32: Added non-modal ("active") cheat search option. (nitsuja) +- Win32: new hotkey-config dialog and configurable hotkeys (nitsuja) +- Win32: Fixed joystick config in input dialog. (nitsuja) +- Win32: Fixed hires and extended height .avi output. (nitsuja) +- Win32: various small GUI improvements (nitsuja) +- Win32: Netplay fixes. (nitsuja) +- "Fake Mute" desync workaround option for movies, until + all ports have deterministic sound. (Bisqwit, nitsuja) +- Fix for save state blocks > 999999 bytes. (Bisqwit) +- C4 games now save C4 data in save states. (DeHackEd) +- Unix: Framework for high-speed seeking. Specify a frame + number in a movie, and the emulator will run at + maximum speed to that frame. Untested. (DeHackEd) +- X11: Support for window exposure. When a window is + damaged due to overlay, being iconified, etc. it will + be repainted correctly. (DeHackEd) +- Unix: parameter: -autodemo loads a movie for + playback on startup. Only the x11 code handles this + right now. (DeHackEd) +- Unix: parameter: -oldturbo, the turbo button renders all + frames when fast-forwarding. (DeHackEd) +- Unix: parameter: -upanddown, override U+D and + L+R protection. (DeHackEd) +- Unix: parameter: -mute, currently linux only, blocks out + audio output from your speakers while still emulating + sound. Not fully tested. (DeHackEd) +- Unix: parameter: -maxframes during movie + playback, snes9x will exit when the target is hit. (DeHackEd) +- Unix: parameter: -keypress shows to stderr and on-screen + the currently pressed buttons on joypad 1. (DeHackEd) +- Unix: Stream dumping (NOT COMPLETE). With -dumpstreams, + raw video and raw audio are dumped to videostream%d.dat + and audiostream%d.dat, where %d increments on each CPU + reset, starting at zero. (DeHackEd) +- Unix: Non-blocking sound on Linux. It makes seeking nicer.(DeHackEd) +- Unix: Configurable sound device. (pierredavidbelanger) +- configure.in now requires a sufficiently new version of + autoconf. (anomie) +- Fixed slow versions of branch opcodes. (anomie) +- Fixed the mosaic offset bug. (anomie) +- No sorting by priority in C4 command 00 00. MegaMan X2 + can go behind the legs of the intro stage boss. (anomie) +- New RTO discovery, fixes Super Conflict: The Mideast + title screen. (anomie, byuu) +- A 1->0 transition on $2100.7 causes OAM Address Reset. (anomie, byuu) +- The final HDMA Indirect Address load is only weird + on the last channel of the scanline. + Touge Densetsu Saisoku Battle problem solved. (anomie, byuu) +- Fixed BGnVOFS bug. Only HOFS needs ~&7 update. (byuu) +- Fixed superfluous VIRQ triggers. (zones) +- Fixed missing IRQ trigger just after the previous one. (zones) +- Fixed missing IRQ while writing to $4200. (zones) +- Fixed IRQ timing after WRAM refresh. (zones) +- Fixed NMA timing after DMA transfer. (zones) +- Fixed superfluous auto-joypad-reading. (zones) +- Fixed missing WRAM refresh during DMA transfer. (zones) +- Fixed DMA so that HDMA and any HC triggered events can + run during DMA transfer. (zones) +- Roughly fixed the case that HDMA and DMA use the same + channel at the same time. HDMA kills DMA. Thanks byuu. (zones) +- Changed initial DMA registers values. (zones) +- Slightly modified APU execute timings. (zones) +- Fixed APU I/O registers to get/set the proper value. (zones) +- Blocked invalid VRAM writings, though you can turn off + this option due to Snes9x's inaccurate timings. (zones) +- Omitted SPCTOOL, no one uses it. (zones) +- Added Sufami Turbo support. (zones) +- Added Same Game add-on cart support. (zones) +- Fixed HiROM SRAM and DSP1-4 memory maps a little. (zones) +- Improved mirroring. (Nach, grinvader, byuu) +- CRC32 on BS dumps now follows uCONSRT standard. (Nach) +- BS dumps now always run in NTSC mode. (Nach) +- Unknown regions (generally betas) default to NTSC. (Nach) +- Now support NSRT headers for setting up controllers. (Nach, nitsuja) +- Unix: Fixed command line help output. (Nach) +- Unix: Sound now defaults to 32KHz, Stereo, Interpolation + so Snes9x finally sounds like a real SNES by default. (Nach) +- Win32: Saner defaults for movie record. (Nach) +- Unix: Fixed crashing with mouse or super scope. (Nach) +- Removed some weird code which was crashing Korean + League and its varients. (Nach) +- Win32: Can now compile with MinGW. (Jonas Quinn, Nach) +- Win32: Can now cross compile Snes9xw. (Nach) +- Unix: SSnes9x compiles again. (Nach) +- Win32: ZSNES C4 and SuperFX compiles once again. (Jonas Quinn) +- Unix: Netplay Fixes. (Nach) +- Unix: Netplay Improvements. (Fabianx) + +Snes9x 1.5 +- Pseudo-hires rendering flush, Old 2xsai endian fix (anomie) +- Added 'oops' auto-snapshot support (anomie) +- Fixed usage messages (Unix) (anomie) +- Old split-ROM-in-zip bugfix (anomie) +- ./configure fix for detecting libpng (anomie) +- Fix "no PNG support" error message (anomie) +- Anomie's control remapping patch (anomie) +- Support for IPS patches in the zip file (anomie) +- OBC1 savestate fix (Overload) +- Fix turbo frameskip, X11 keyboard auto-repeat, VRAM reads (anomie) +- Add some missing ifdefs (UNZIP_SUPPORT and ZLIB), + from AaronOneal (anomie) +- Config file for Unix/X11 and Unix/SVGA (anomie) +- CPU instruction fixes (mostly emulation mode & timing) (anomie) +- Mode 7 fixes (anomie) +- Rewrote the renderer. Enjoy! (anomie) +- Correct-ish memmap boundary testing. (anomie) +- Add support for saner directory structures under Unix (anomie) +- Unix: Fixed detection of newer libpng (spotted by vapier) (PBortas) +- Added 4-point gaussian interpolation and proper envelopes + many thanks to Brad Martin and TRAC. (zones) +- Fixed several sound problems. (zones) +- Fixed the memory access problem in C++ Super FX core. (zones) +- Speed adjustment of C++ Super FX emulation. (zones) +- Various timing fixes: NMI, IRQ, WRAM refresh, + cycles per line, HBlank start, etc. + Many thanks to byuu for much information. (zones) +- Removed some game specific hacks. (zones) +- Added partial Satellaview (BS) emulation. (Dreamer Nom, zones) +- Added the Katakana font for onscreen messages. (107) +- Updated JMA to v1 (Nach) +- Unix: Fixed JMA options in config (Nach) +- Unix: Removed --with(out)-asmcpu option in config + because the i386 assembler CPU core is out of date. (zones) +- Unix: Changed the default settings in config. (zones) +- Updated porting.html (porting.txt) in sync with 1.5. (zones) +- Fixed buffer over/under flow due to incorrect logical + operator in S-RTC code (byuu) +- Fixed HDMA flags bug. (byuu, anomie) +- Fixed bugs causing crashing in Unix. (Nach) +- Ported Snes9x to AMD64. (John Weidman, Nach, zones) +- Completed DSP-1 code. (Andreas Naive, Overload, Nach) +- Updated DSP-3 code. (Nach, z80 gaiden) +- Updated DSP-4 code. (Dreamer Nom, Nach, z80 gaiden) +- Overhauled BS detection. (Nach) +- Improved Unix portability. (Nach, zones) +- Fixed infiniti loop and invalid read bug in + C++ C4 core. (Nach) + + +Snes9x 1.43 +- Win32: Disabled Netplay (funkyass) +- Win32: Various fixes, including ROM dialog (funkyass) +- Win32: New Input Config Dialog (funkyass) +- Win32: added .avi output feature (blip) +- Win32: fixed frame timings >100ms, added frame advance (blip) +- Rewrote Unfreeze, renamed it S9xUnfreezeFromStream, + failing to load a freeze file no longer resets emulation (blip) +- Fixed Unfreeze to restore IPPU.HDMA properly (blip) +- Rewrote OBC1 code to match the real chip (Overload) +- More updates the to DSP-1 code, fixes to projection (Overload, Andreas Naive) +- Unix/X11: Rewrote keyboard setup code (Bisqwit) +- Added movie recording+rerecording support (blip, Bisqwit) +- Added -hidemenu CLI switch (funkyass) +- fixed broken Win32 filters (lantus) +- Added internal support for emulating the new-style SNES (MKendora) +- Cleaned up many quirks of the cheat search engine (MKendora, Don Vincenzo) +- Fix mosaic in hires SNES modes (Tokimeki Memorial) (MKendora, zones) +- Rewrote Legend's hack, added another game to it (MKendora) +- Optimized the Open ROM dialog (MKendora) +- Rewrote the Seta DSP map (The Dumper, MKendora) +- Began string isolation for the UI, eases translation (funkyass) +- added -nopatch -nocheat, and -cheat CLI items (MKendora) +- fixed a UI typo (funkyass) +- fixed several C core stack ops in emulation mode (MKendora) +- split emulation mode ops from native mode ops (MKendora) +- Seta special chip emulation enhancements (Feather, The Dumper, Overload, MKendora) +- code tweaks to the ST010 (Nach, pagefault) +- fix some C/asm quirks and HDMA quirks (all my fault) (MKendora) +- several timing hacks to fix games (lantus) +- improved checksumming for odd mirrorings (MKendora) +- Snes9x uses a standard zlib instead of a packaged one (PBortas) +- Exhaust Heat 2 and regional ports are playable (Feather, The Dumper, Overload, MKendora) +- Game Doctor dumps that are 24 Mbit are now supported by + a force option (MKendora, Nach) +- SuperFx interleave format is now considered deprecated. + Support will be removed in future versions (Team decision) +- made SuperFx interleave detection a compile option (MKendora) +- added memory maps for slotted games (MKendora) +- fixed a typo in the usage messages (MKendora) +- fixed the bug that had nuked optimizations (The Dumper) +- restored full speed optimizations in release builds (funkyass) +- Added non-speed-hack version of color subtraction. (zones) +- OpenGL info message font fix (zones) +- APU timer fix (zones, Nach) +- Fixed mouse offset in resized X11 window. (PhaethonH) +- Fixed a (presumably) long-standing bug: Mode 6's BG is + depth 4, not depth 8! (anomie) +- Unix: unmap all joystick buttons before applying -joymapX (anomie) +- Win32: added a define to disable pausing when focus is + lost, NOPAUSE (funkyass) +- Win32: Changed the default for Auto-save SRAM to 15 sec (funkyass) +- Dreamcast: Added SH4 assembler (PBortas, Marcus Comstedt, Per Hedbor) +- C90 and aclocal 1.8 warning fixes (thanks Ville Skytt) (PBortas) +- Unix: AMD64 compilation fixes. (PBortas) +- Added support for NSRT Team's JMA format (Nach, NSRT Team, funkyass) +- Unix: Loading a zip file on binaries without zip support + will give an appropriate error message (Nach) +- Unix: Added install target with proper --prefix handling. (PBortas) + + +Snes9x 1.42 +- Added 8-bit rendering filters (funkyass) +- Added Sanity Checks for the Display Dialog (funkyass) +- New Layout for the Joypad Dialog, (funkyass) +- Fixed that anoying Joypad dialog bug. Now check to see + if the axis exists before asking for the info form it (funkyass) +- Added full POV support. (funkyass) +- Fixed sram sizes for SuperFx games (Nach, MKendora) +- Stopped saving sram for games with no battery (Nach, Mkendora) +- Killed the gray line and slightly optimized Win32 GL (MKendora) +- stack wrapping fix in C core (MKendora) +- removed some dead hacks (Oda Nobunaga and Dezaemon) (MKendora) +- fixed some DMA and HDMA modes (anomie, MKendora) +- improved HDMA timing (anomie) +- cleaned up load and deinterleave code (MKendora) +- removed old UI DLL (MKendora) +- new cheat dialogs (MKendora) +- started Unicode preparation in Win32 UI (MKendora) +- Implement odd sprite sizes, sprite priority rotation. (anomie) +- RTO code that hopefully works. MK's #define is + "MK_DEBUG_RTO" to try to debug the RTO code. (anomie) +- SDD1 decompression support for Linux. Also added a new + command line option -sdd1-pack. (anomie) +- Added correct VRAM read logic. #define CORRECT_VRAM_READS + if you want it. (anomie) +- removed the non-VAR_CYCLES path (MKendora) +- changed access timing map to be address-based. (MKendora, anomie) +- DSP-1 updates (Overload, Andreas Naive) +- S-DD1 decompression support (Andreas Naive) +- optimized S-DD1 code (anomie) +- S-DD1 can use packs or decompression (MKendora) +- More work on Exhaust Heat 2 (MKendora, Overload, The Dumper) +- separated ROM detection from file reading (lantus) +- fixed a mirroring bug in LoROMs (MKendora) +- cleaned up some mapping issues (MKendora) +- ST018 games now boot before locking up (Mkendora, Overload) +- SA-1 state was not completely reset, crashed Marvelous (zones) +- Removed sample caching. It caused problems, and was not + noticably faster. (MKendora) +- Fixed interlace without breaking the displays for MK (anomie) +- Fixed a PPU OpenBus hack (anomie) +- Moved SPC7110 and S-DD1 regs to speed up the general case + of reading the $4xxx registers (MKendora) +- altered Hi/Lo ROM detection to fix a few misdetects. (MKendora) +- Implemented RTO flags. With MK's implementation of $213F's + interlace bit, we now pass the SNES Test Cart's + Electronics Test (anomie) +- Fix sprite windowing bug (anomie) +- Way back in 1.40 MK changed the Windows port to default + to a plain old joypad instead of the MP5. And then we + removed the hacks for games that dislike the MP5. So + we need to change the defaults elsewhere too... (anomie) +- cleaned up the hacks section somewhat (MKendora) +- removed some interleave hacks (MKendora) +- fixed a bug in KartContents (MKendora) +- transparency fix for Jurassic Park (lantus) +- A hidden Win32 feature (MKendora) +- Kludged Mark Davis until I get stable APU timing (MKendora) +- Win32 renders overscan always, fixes some jumpy games (MKendora, lantus) +- Fixed an FMOD bug (MKendora) +- cosmetic tweaks (Everyone) +- Fixed 2 special chip bugs in the C core (zones) +- Added some sanity fixes to the C core, fixes MLBPA + Baseball for C core users (zones) +- updated zlib source (includes 1.1.4-1 patch) (MKendora) +- compiler warning fixes (PBortas) +- Updated the SuperFx asm core (pagefault) +- Kludged Unix compilation to produce working SuperFx (PBortas) + with the asm core. +- Kludged VC to deal with optimization weirdness (MKendora) +- Hacked Robocop vs. Terminator using Daffy Duck hack. Stops + flashing. (MKendora) +- Added some defines to the asm core (MKendora) +- Added possibility to take screenshots on Unix (PBortas) +- Initialize the C SuperFx core better (PBortas) +- Kludge a Japanese golf game until the APU timing is fixed (MKendora) + + +Snes9x 1.41-1 + +- Oops, in the asm CPU core i was stomping on %eax too + early, so register $4210 wasn't getting set properly. (anomie) + + +Snes9x 1.41 + +- Win32 controllers now stay the same between games (MKendora) +- Win 32 Open ROM dialog fixes (MKendora) +- Win32 Display dialog fixes (funkyass) +- Win32 OpenGL ratio tweaking. (Reduces the gray line) (kode54) +- Fixed Win32 superscope for those having issues (MKendora) +- Generic accuracy fix in main SUperscope emulation (MKendora) +- sprite bug fixed (gah! How'd we miss that) (anomie) +- SPC saving compatibility fix (Caz and zones) +- Window clipping update (anomie) +- Mode 7 clipping fix (TRAC) +- latching fix (anomie) +- BS BIOS checksum and mapping fix (MKendora) +- Working Uniracers hack (dma.cpp) (anomie) +- HDMA Indirect Address fix for Romancing Saga 2 (anomie) +- Better savestate hack, does it break anything? (anomie) +- C4 C core fixes. Mostly Trapezoid (thanks Nach), + some s/short/int16/, some indentation. (anomie) +- Damn, but the indentation in ppu.cpp was screwed up. + Killed some dead code too (twas commented forevermore). (anomie) +- fixed a potential crash in S-DD1 logging (MKendora) +- Improved accuracy of Hi/LoROM detection (~500 ROM test) (MKendora) +- Hack for Moryou Senki Madara 2, don't call + SelectTileRenderer from DrawOBJS if BGMode is 5 or 6. A + real fix requires at least rewriting SelectTileRenderer, + or inlining a special version in DrawOBJS. (anomie) +- DMA traces: add additional address info to reads too. (anomie) +- Killed the old Borland Joypad dialog (funkyass) +- Fixed issues with Dezaemon and CT, maybe others (anomie, MKendora) +- Changed the internal snapshot key from \ to VK_F12 (funkyass) + Fixes issues with non-US keyboard layouts. +- Fixed OAM reset to not occur during forced blank. (anomie) +- Killed some dead OAM reset code that doesn't need saving. (anomie) +- Unix/X11: Fixed screen jumping. CT enables overscan mid- + frame for only one frame, and we now update the rendered + screen height accordingly. Other ports are still broken. (anomie) +- Unix/X11: Fixed possible TV mode crash. (anomie) +- Fixed OAM reset timing (beginning of V-Blank rather than + end) for R-TYPE 3 (J). (anomie) +- Unix/X11: Fixed OpenGL target (PBortas) +- Unix/OSS: Fixed big endian sound (PBortas/ernstp) +- Tweaked the About Dialog so its read-only and no scroll (funkyass) + + +Snes9x 1.40 + +- cleaned up a sound skipping code issue. Same as the + RTC issue (lantus) +- re-fixed the invalid BRR header behavior twice (Lord Nightmare, FatlXception, Mkendora) +- More BS mapping fixes. (The Dumper, MKendora) +- Fixed Ranma Bun no 1 - Chonai Gekitou Hen (J) and + Street Combat (U). Interlace is not supported in the + non-Hi-res modes, as far as I can tell. (MKendora) +- Also fixes Maka Maka (J). Frank Yang's report, and + anomie's code both provided clues to this one. +- Removed special casing on setting 5c77 version to one. + This seems to be true for U and J units always. I need + it checked out on PAL... (neviksti) +- Using SNEeSe's values for 5c78 and 5A22. Note we know + that the 5c78 version can also be 1 or 2, instead of 3. (TRAC, neviksti) +- Added turbo buttons. Credit/blame for the design goes + to slack, Nave, Gogo, and myself. (MKendora) +- fixed a bug in turbo (slack, MKendora) +- Tried merging the behavior of Old $4200 with new $4200 (MKendora) +- Made $4200's return value match what VSMC Explorer + showed on Fancia's SNES (MKendora) +- Fixed a matrix multiplcation bug in ZSNES state loads (MKendora) +- Fixed Dezaemon and Ys3 mode 7 (lantus) +- Fixed H-DMA modes 5-7. Thanks to The Dumper for the + extra motivation needed. GunForce and Genocide 2 work. (The Dumper, MKendora) +- Fixed BG3 Priority. I'm stupid. anomie had fixed it, + but lantus fixed it again, because I didn't use it. (anomie, lantus) +- Added a Star Fox 2 hack, and an interleave skip (The Dumper, lantus, MKendora) +- Cleared BS setting on load (lantus) +- Fix for Mode 7 priorities. fixes F-1 Grand Prix (all 3) (anomie) +- JANJYU GAKUEN 2 needs Multi-tap 5 off. (Frank Yang, MKendora) +- HONKAKUHA IGO GOSEI: No multi-tap 5, allow mouse (lantus, MKendora) +- Added a few missed conditional compiles (Nach) +- disabled multitap 5 by default, added menu to enable (MKendora) +- special thanks to anomie and lantus. One of them is + responsible for a bug fix I forgot already. (anomie, lantus) +- Removed several Multitap5 disable hacks. (MKendora) +- Added an SPC dumping upgrade from kode54 (kode54) +- cleaned up some resource leaks (MKendora) +- I forgot this since 1.39mk, but SPC700 flag fixes (anomie) +- Mode 7 interpolation screen flip fix (anomie) +- Updated SPC7110 code a bit, for compatibility (Daniel, anomie) +- Changed RTC saving. (Byte exact to old format on Win32) + The submitted patch for "safety" doubled the file size, + so I had to write it in explicitly little-endian. (MKendora) +- Removed the old hidden cursor (MKendora) +- Applied a WAI correction from anomie. (anomie) +- Added a patch for Pseudo hi-res (anomie) +- Hacked around Word writes to $7F:FFFF. Thanks to lantus + and The Dumper for verification. (MKendora) +- PPC compile fix? and debugger reversion (anomie) +- Set defaults differently to improve sound quality. (MKendora) +- Clear Force load settings after Init (lantus) +- Made menu reset a soft reset. Fixed BL Sound Test & more (CaitSith2) +- Fixed word writes to block bounds in asm core. (MKendora) +- redone version of my bounds fix, only this one WORKS! (TRAC) +- Thanks to TRAC for the AT&T syntax refresher! (TRAC) +- Fixed screen saver disable (kode54) +- Fixed OAM and sprite priority in the asm core (anomie) +- Proper Interlace fix for mid-frame changes (anomie) +- Fixed OpenGL to accomodate previous patch (MKendora) +- Ported the "Settings" dialog to VC (MKendora) +- Fixed ROM Info bugs (_pentium_five, MKendora) +- Fixed non-stretched interlacing, but it's s.l.o.w. (anomie) +- Superscope and Mouse need to be enabled by the menu. (MKendora) +- Fixed HiROM sram reads in asm and C cores (anomie, MKendora) +- Added Company 48 to the list. Thanks to _pentium_five_ (StatMat) +- Set Super Drift Out's S-ram correctly. (Snes9xppSE Team) +- Fixed NTSC timing. Helps ToP Intro greatly (kode54) +- Added several entries to the company list, from uCON64 (Nach) +- Lots more companies (StatMat, Nach) +- Fixed Win32 Superscope support (NT kernel only?) (MKendora) +- Added ZSNES OBC1 code ported from asm to C (sanmaiwashi) +- Implemented Justifier emulation (neviksti, MKendora) +- Fixed Rudora no Hihou's clip window bug (anomie) +- Fixed Flintstones sprite issue (lantus) +- Fixed sram mappings for Big Sky Troopers and + Taikyoku - IGO Goliath. Both map in bank F0 (MKendora) +- Fixed a possible crash when switching audio settings (MKendora) +- Added per-pack gfx pack configuration (MKendora) +- Fixed glitches in DSP-1 games (Flintstones fix) (lantus) +- Added delay to Superscope latching. Fixes X-Zone. (neviksti, MKendora, zones) +- Added DSP-2 support (Overload, The Dumper, Lord Nightmare, + MKendora, neviksti) +- Fixed Super Bases Loaded 2 (and J/K ports) DSP-1 seems + to ignore the A15 line in LoROM maps (MKendora) +- Corrected $4200 again (The Dumper) +- Corrected $2100, $2102, and $2102 read behavior (anomie) +- Fixed Cancel on the Sound Options dialog. (MKendora) +- Fixed the sound options dialog (Thanks, Quattro) (MKendora) +- updated DSP-1 support to match chip better (Overload, neviksti, The Dumper) +- added a few Ops to the DSP-4 routine (Nothing plays yet) (neviksti, The Dumper, Overload, MKendora) +- added screenshot support (anomie, sanmaiwashi) +- stubbed the ST010 chip in Exhaust Heat 2 (Overload, MKendora) +- hacked around War 2410's lockup (pagefault, _Demo_, MKendora) +- updated tests for type 1 ROMs (based on reset vector) (MKendora) +- Emulation mode CPU fix (The Dumper) +- Open Bus fixes (anomie) +- Better Expansion port emulation (anomie) +- More Open Bus fixes (Overload, anomie) +- HDMA fixes (fix colors only in Full Throttle Racing) (anomie) +- Migrated DKJM2 onto the Tales map (MKendora) +- Tried to remove Dragon Knight 4 hack (LoROM sram fix) (MKendora) +- Fixed ROM Mirroring for LoROMs (<= 32 Mbit) (MKendora, TRAC) +- blocked wram to wram DMAs (neviksti) +- fixed HiROM mirroring, too. Thanks TRAC! (MKendora, TRAC) +- fixed C core RMW and Push ops to write in the correct + order, fixes Michael Jordan gfx. (anomie, Overload, MKendora) +- set RDIO to start as 0xFF, fixes SuperFx games. (anomie, Overload) +- New connect dialog (funkyass) +- better conditional compile of FMOD (funkyass) +- fixed screenshot code when libpng is not used (funkyass) +- added portability fixes (zones) +- fixed asm Pushes (anomie) +- fixed asm LoROM s-ram decode (MKendora) +- migrated DEZAEMON to standard LoROM map (MKendora) +- fixed the Madara 2 OpenGL bug (key found in Rudra) (MKendora) +- fixed asm RMW instructions (MKendora) +- fixed ADC opcode (The Dumper) +- added DSP-2 Op09 (The Dumper) +- updated C4 C code (anomie) +- updated C4 asm code (Nach) +- Keep OpenGL in ratio (kode54) +- Replaced many more Borland dialogs (funkyass, MKendora, Nach) +- Added CRC32 to displayed ROM Info (Nach, MKendora) +- Fix cheat support (The Dumper) +- improved DMA timing (MKendora, Overload, The Dumper) +- Fixed Mode 7 math, removed Dezaemon, Gaia, Ys 3 hacks (TRAC, MKendora) +- Mode 7 flip fix (TRAC) +- Multiple safety and initialization fixes (zones) +- Platform safety fixes (PBortas) +- Memmap cleanups (MKendora) +- More preliminary work on special chips (The Dumper, Overload, MKendora) +- Added color coding (MKendora) +- Another HDMA fix (anomie) +- added another known hack to the hacked games list (Nach) +- ToP memmap changes (MKendora) +- Checksum calculation changes (MKendora) +- Special cased a few games for OAM issues (MKendora) +- Reverted OAM reset to 1.39 timing (MKendora) +- Reworked vram wrapping (zones, Mkendora) +- Fixed $4210 and Super Professional Baseball 2 (Overload, MKendora) +- Fixed APU RAM init (Overload, MKendora) +- More support for Exhaust Heat 2 (not playable) (The Dumper, Overload, neviksti) +- removed some debris from save states (MKendora) +- fixed? Doom's save state bug (MKendora) +- simple overdump detection warning (MKendora) + + +1.39mk3b + +- Fixed the RTC detection. FINALLY done correctly (lantus, MKendora) + + +1.39mk3a + +- neatened up the company table. (MKendora) +- fixed a mistake in the ROM Info box (MKendora) +- Added a Calulcated Size field to ROM INfo. (MKendora) +- Added 3 more companies to the ROM Info table (MKendora) +- Fixed BS detection (The Dumper) +- Added a Legend-specific hack to get sound. I remembered + it being mentioned in the changelog. (Gary Henderson) +- Unbroke the Star Ocean special cases (Trigger of Time, MKendora) +- Company 255 is not Hudson-ZFE detects all Hudson games + without it, except a corrupt dump (StatMat, MKendora) +- fixed a bug in the redone detection for the SPC7110 (CaitSith2) +- 44Khz sound should be 44.1Kz. Changed, though you'll + need to re-set 44.1Khz to make it take effect. Not sure + if this affects non-Windows ports. (MKendora) +- Added 32Khz playback (MKendora) +- Inproved BS ROM mapping (_Demo_, The Dumper, MKendora) + + +1.39mk3 + +- Honkaku Syogi Fuunji Ryuou (J) fixed (force no multitap) (Frank Yang) + Also Fixed Super Castles (j). + Also fixed a bunch more. This dude e-mailed like 100 bugs + to my hosts, some already fixed in Snes9x1.39mk2, but + about 7 were clearly multi-tap5. +- also fixed Dekitate High School. Error was in Japanese (Frank Yang, Tomato) +- fixed 2 memory leaks (Aaron) +- Dai Kaiju Monogotari 2 works as a 40 Mbit ROM. (MKendora, The Dumper) +- Fixed the Flashback bug. Lots of info led to this. (neviksti, MKendora) + Thanks neviksti, The Dumper, TRAC, and FatlXception + for clarifying the behavior. +- Fixed Sailor Moon Fuwa Fuwa Panic 2 to work with (neviksti, MKendora) + previous fix. It's a total hack, but it should sound + just like the old Snes9x did. neviksti strikes again! +- Dirty hack to make 3 games deinterleave properly: (MKendora) + Wizardry 4, Mark Davis, and Honkakuha Igo Gosei(FX) + all work as well as the deinterleaved counterparts. + (The last is a hacked game, and you should get the + non-FX version) +- Fixed Seima Jyuden Beasts and Blades. Another Multitap, (Frank Yang) + but for some reason, the hack requires the C cpu core. + Thanks to Tomato for taking a stab at the error message, + as well. It was too vague to be of use, he said. I + just tried it because it worked on other games. +- Res Arcana fixed. Another Frank Yang report, another J (Frank Yang, MKendora) + error, but I can read kana well enough with a table! +- Removed a Terranigma specific hack. Not sure, but the (anomie) + new behavior might have fixed Tin-Tin in Tibet's colors. +- Dirty hack to work around a dirty hack. Both Yoshi's (MKendora) + Island (E) dumps should work now +- Added the JumboLoROM memory map, Extends LoROM support (The Dumper, neviksti, MKendora) + to 48+ Megabits. +- added an EXTBG fix, since iirc, TRAC is using it as well (anomie) + Does it actually fix anything? +- Fixed crash in DSP Op06 (The Dumper) +- Fixed a GUI error on my part (Trigger of Time) +- Cleaned up some of the SPC7110 detection/size code. (MKendora) +- Merged in XBox port changes to SPC7110 code (lantus) +- Added a call to Memory.Deinit when exiting. (lantus, MKendora) +- Many memory leaks fixed while chatting with lantus (lantus, MKendora) +- Fixed that stubborn open/close leak (lantus) + + +1.39mk2 + +- hacked in Shien's Revenge (anomie) +- fixed Orge Battle's green lines. (CPU source for DMA) (anomie) + - Looks interesting, and might apply to other DMA cases? +- maybe "fixed" DKC's barrels? by treating $2001 + as unmapped. The game worked before with a hack. (MKendora) +- optimized SPC7110 slightly by removing extra setup work (MKendora) +- Fixed DBZ 3 (Korean). S. Korea is, in fact, NTSC. (MKendora) +- Fixed a hard-coded value in the SPC7110 (MKendora) +- Added a Win port ROM Info dialog (MKendora) + - some companies aren't in the table I used. + If you encounter an Unimplemented company, + report it the the Snes9x development forum, with + the correct company and the number. + + +1.39mk +- SPC7110 support based on Dark Force's docs. (Dark Force, zsKnight, + The Dumper, MKendora) + Trust me when I say those guys deserve the credit more + than me. From what I'm told, Dark Force is the man + behind most of the reverse engineering, but they all + did a much harder bunch of work than I did following + their specs. It's plain and simple that these three + are the masterminds behind all SPC7110 support. + + Dark Force for reverse engineering the chip (Extremely tough work!) + zsKnight for the original core, and probably other things + The Dumper for dumping the packs and doing hardware tests. + + Also thanks to CaitSith2 for numerous bug reports + and a lot of bug fixes. + +- Theme Park hack removed, fixed via PPU latching (anomie, MKendora, TRAC) +- WWF Wrestlemania hack removed (anomie, TRAC) +- Strike Gunner hack fixed (anomie, MKendora, TRAC) +- FF:MQ text fixed. May help other sprite issues. (TRAC) +- Umi Hara Kawa Se timing corrected. (anomie) +- S-DD1 packs load by the same rules as ZSNES (MKendora) +- SPC7110 code builds in linux (Lord Nightmare, zinx) +- Added The Dumper's DSP-1 updates (The Dumper) +- SPC7110 is correctly displayed on load, RTC also noted. (MKendora) +- Fixed a potential graphics problem (TRAC) + no known games fixed, but who knows? +- Fixed Ballz3D (pagefault) +- Re-fixed Ballz3D, via DSP op 0F (The Dumper) +- included some of anomie's fixes. Many caused me grief, + so only Marko's Magic Football is intentionally fixed. (anomie) +- finished zsnes save support, though I don't know how + well it will work with SPC7110 games (MKendora) +- Added a new soundux.cpp again to fix some noise. + (Fixes the GW "fart track") (Lord Nightmare, info from Anti-Res) +- Added 3 cache modes for SPC7110 games (MKendora) +- Added new BRR decoder. Requires sample caching + and the Anti-Res decoder be disabled. (FatlXception, port by Lord Nightmare) +- Added CaitSith2's RTC debugger. define RTC_DEBUGGER in + project settings to enable it. (CaitSith2) +- SPC7110 per-game cumulative logging (MKendora) +- other fixes that I've forgotten (sanma iwashi, TRAC, anomie, ????) + +- "I'm not worthy" thanks to the original SPC7110 crew (DF, zsKnight, and the Dumper) +- Thanks again to the same people, because they deserve it! +- thanks to The Dumper, Dejap, TRAC, and all the ZSNES crew for technical assistance +- Thanks to most of the Snes9x mods for testing (no thanks to you, Raptor ;) +- and thanks to TRAC and #mkendora for letting me vent at you. + +1.39 +- Added SDD-1 unknown graphics data logging at the dumper's request. A bit late + but might help with Street Fighter 2 Alpha's data dumping. Creates a + romname.dat file in the freeze file folder. +- Implemented 16-bit texture support for OpenGL modes in Windows and Linux. + Had to support a new pixel format type to do it - RGB5551 (one bit of alpha) + which caused me some major problems - black was no longer always pixel value + zero! +- Removed the Bump map OpenGL mode from the Windows port (didn't look so good + anyway and was slow). +- Added a hidden novelty OpenGL mode (clue: a keyboard shortcut activates it) +- Reverted back to FMod version 3.20 after reports that version 3.33 broke + AD3 support. +- Implemented a better work-around for the broken select system call in the + Linux kernel - the original work-around was long-winded and stopped working + when I implemented OpenGL support under Linux. +- Added the same speed-up hack to the OpenGL code that the Glide code already + supported. Basically, if your OpenGL implementation supports 16-bit textures + then OpenGL mode should be as fast, or faster than the 3dfx Glide mode. +- Hopefully fixed Glide support. +- Reverted back to the original colour blending code. The newer code, although + more accurate in most cases, had too many glitches and was slower. +- Included multiple Japanese games fixes from Iswashi San. +- Fixed a timing problem caused by a speed up hack that was affecting Top Gear + 300. No the game still isn't playable yet, but I noticed the problem while + investigating the DSP-4 chip used by the game. +1.38 +- Added support for Star Ocean and Street Fighter 2 Alpha decompressed graphics + packs from dejap. Used a binary chop search rather than a linear search to + locate correct decompressed graphics more quickly - should help emulation + speed during later stages of the game. +- Included OpenGL support into the Linux port and speeded up the Windows OpenGL + implementation slightly. The real speed up would occur if I could figure out + how/if 16-bit textures are supported in OpenGL because at the moment the + 16-bit software rendered SNES image must be converted to 24-bit before being + uploaded as a texture... +- Included the latest ZSNES DSP-1 code. Now Pilotwings, SD Racer and Suzuka 8 + Hours are playable. Aim For The Ace, Super Air Diver 1 & 2 and Syutoko Battle 94 + are also playable, but with bugs. Thanks to zsKnight, _demo_, et al for all + their hard work. +- Another Daffy Duck: Marvin Missions screen flicker problem worked around - + writing to the IRQ enable register shouldn't clear any pending IRQs, but + Sieken 3 seems to require this or else the game hangs. Special-cased Daffy + Duck for now. +- An NMI emulation bug was triggering a Panic Bomberman World game bug, + crashing it. Basically, if a game enables NMIs after the normal trigger + point, the NMI should not trigger if the game has already read the NMI clear + register. +- Panic Bomberman World requires SPC700 memory to be initialised to zero on + reset otherwise the game hangs when a tune finishes and another one should + start. +- Added mouse pointer auto-hide to the Windows port. Much better than the turn + the mouse pointer into a black dot method I was using before. +- Included the latest ZSNES Super FX code. Not sure if it fixes actually fixes + any games. +- Added an offset hack for Strike Gunner to get the scrolling ground layer + to line up correctly - another offset-per-tile bug hacked around for now. +- Arrr! Left in some debugging code in the last release that prevented all + games that need the slower SPC700 timing from working. Removed it. +- Hmm. The broken cut-scenes in Deep Space 9 seem to indicate that I haven't + got the emulated clock speed of the 65c816 CPU correct yet. And not by a + little bit - a 9% too slow error. Hacked special timing for the game for now. +- Added triple-buffering to Windows port - enabling double-buffering actually + enables triple-buffering if you have enough free video RAM, defaulting to + double-buffering if you don't. +- Fixed another crash bug in the interpolated mode 7 code - if no scaling + was being used (either up or down) and screen repeat was enabled and the + screen was flipped horizontally, the routine would crash Snes9x. Was causing + Snes9x to crash during rock monster boss stage of Castlevania 4. +- Oops. Got the initialisation of the default SNES screen width and height + round the wrong way - could cause a X Windows System error message on the + UNIX port after loading a ZSNES freeze file. +- Included the unofficial Windows port emulation fixes for several games including + Kentouou World championship and TKO Super Championship. +- Included Iwashi San's improved Anti Res. sound sample decoding routine and + updated the C version to match. +- Included Anti Res. improved sample decompression code he sent me ages ago, + but for some reason I didn't include. Sorry. This version seems good enough + to leave enabled all the time. +1.37 +- Added fix for Captain America's corrupt graphics - a ROM bug causes it to + read from what I thought should be an unmapped memory area, but it expects + the value returned to be zero. +- Added code to support games that switch to the hi-res. SNES screen mode part + way down the screen while using the 3dfx bi-linear filter mode. The code + basically has to back out of the speed up hack it was using when the game + switches resolutions. +- Fixed support for games that have mixed lo-res. (256x224), medium res. + (512x224) and hi-res. (512x448) all on the same screen - corrects the display + of Majin Tensei 2. +- Added support for games that use sub-screen addition to the back-drop layer + while displaying hi-res. graphics - something I thought the SNES couldn't do + but the game Marvelous uses this. +- Reworked the UNIX/Linux output image handling code: the image doesn't always + have to be scaled when hi-res. support is enabled, the PutImage operation + only updates the area of the screen it has to, the SNES image is now always + centred in the window/full-screen area and if the SNES image changes size + between frames, the old screen areas are now correctly cleared. +- Fixed the corrupt graphics problem during the battle scene of Last Bible 3 - + it requires that previously unknown DMA mode 5 should just act the same as + DMA mode 1. +- Fixed a nasty bug when H-IRQs were being reused on the same scanline - a logic + bug could cause H-DMA processing for that line to be skipped. Was causing + the bridge and the start banners to be the wrong colours in Top Gear 2. +- Added Kreed's display processing modes to the Linux port, including his new + asm version of the Super2xSaI mode and the new software bi-linear filtering + mode. +- Think I might have figured out the odd Mode 7 glitch problems the games + Illusion and Gaia and Chase HQ were having. My original fix was to mod the + centre X & Y values with 1024, but looks like the true fix is to mod + X + horizontal offset and Y + vertical offset with 1024 when screen wrapping + is enabled. +- Disabled H-DMA'ing into V-RAM via registers 2118/2119. The game Hook + deliberately does this causing graphic corruption while dialog boxes are + displayed. Maybe the real SNES disallowed this and it was left in the game by + mistake? Not sure what effect the game was trying to produce because + disabling the emulation of this feature doesn't seem to affect the game at + all, other than stopping the corruption. + + Also fixes graphics junk problem on first screen of Bugs Bunny. +- Added a 'region-free' timing hack for Power Rangers Fight - without it the + NTSC version was displaying badly glitching graphics; I'd already fixed the + PAL version. +- Added true priority-per-pixel mode 7 support (the previous support was just + a hack to get the colours correct) - level 2 of Contra 3 used this feature. +- The Japanese, German, French and Spanish version of Illusion of Gaia needs the + slow SPC700 timing. +- Deleted the Breath of Fire 2 S-RAM hack for the hacker intro version - + according to reports it was causing problems for the non-hacked version. +- Legend, the PAL version, never sets the sound master volume control - Snes9x + was defaulting this to off, I guess the real SNES must default it to full + volume; changed Snes9x. The NTSC version of Legend does set the master + volume level, but sets it to off just after the title screen. Hmm. The -nmv + command-line switch allows you to hear sound in this version. +- Panic Bomber World was tripping an SA-1 emulation bug - the WAI instruction + emulation code was setting the 'waiting for interrupt' flag on the wrong CPU + causing the main SNES to skip an instruction when the next interrupt occurred. +- Panic Bomber World, Bomberman 4 and UFO Kamen Yakisoban all need the slower + SPC700 timing. +- Oops! The Super Formation Soccer 95 fix was causing Aero 2 to lock up. This + means I have no no idea what value the DMA in progress register should + represent. I've hacked it and made it toggle between 0 and $ff on each read + which gets both games working, for now... +- The ROM de-interleaving code always assumed the blocks were rearranged based + on a power of two, but Francois found a copy of Soldiers of Fortune where + this was not the case. Corrected the code. +1.36 +- Finally worked out why the menu items weren't being highlighted in several + ROMs, including Battletoads, U.N. Squadron and All Japan Pro Wrestling. + Two problems: its seems the SNES does halve the colour value result when + blending colours when only the fixed colour addition/subtraction is enabled, + but doesn't halve the result when sub-screen is being blended and its a clear + part of the sub-screen. The second problem was that I had an optimisation + that prevented the time consuming colour blending code from being called if + the colour being added/subtracted was black - adding zero to a number doesn't + affect the result, but not performing the side-effect of halving the result + does affect the final value... +- Super Formation Soccer 95 requires that the DMA enabled register doesn't + always return zero, otherwise the game locks up. +- Thanks to several people reporting a screen flickering problem in the + pseudo 3-d section of Jurassic Park 2 I've fixed a nasty problem in H-IRQ + handling code which could cause double-triggers or skip IRQs altogether. + With this fix I can now remove the special hacks for Ninja Warriors Again, + Chuck Rock and F-1 Grand Prix. +- More games needing the slow SPC700 timing: + Zennihon Puroresu 2, Soulblazer and Robotrek. +- The CPU idle time skipping code was skipping cycles during a software delay + loop in Itchy and Scratchy, causing screen flicker. +- Looks like reading the value of register $2137 shouldn't clear a pending + IRQ - was causing screen flicker on Yoshi's Island. +- Actraiser 1 & 2 both need the slow SPC700 timing. +- Terranigma reads a sound channel's current sample output value and waits for + it to be zero before preceeding. I forgot to always return zero when a + channel was silent. This mistake was causing the game to lock up. + + Itchy and Scratchy and was causing the music to stop and samples to be cut + short in the Mario Early Years series. +- Added a hack for Secret of the Evermore - at several points in the game, just + as the plane is about to land, it reads from unknown registers $4000 and + $4001 and, if it doesn't get the value its looking for, the game hangs or + displays corrupt graphics. +- Silva Saga 2 was accidentally triggering a colour blending hack I put in + place Kirby Dreamland 3 and Kirby Superstar. +- The ZSNES freeze-file loading code could leave a file open if the file wasn't + a valid ZSNES freeze file. +- Super Punch-out requires certain DMA registers to be updated after the DMA + completes. Snes9x used to do that, but I must have accidentally left the code + commented out whilst investigating a different problem in another game. +1.35 +- Added a recently played game list to the Windows port File menu so you can + quickly load up your favourite games. +- Included IPS patching support based on code from Neill Corlett - just rename + the patch file to match your ROM image name but with a .ips extension and + copy it into your ROM or freeze-file folder. +- Added John Weidman's and Darkforce's S-RTC, (Real Time Clock) emulation code. + The only game that seems to use it is Dai Kaijyu Monogatari II. +- Included code from Nose000 for games with 128Kbytes of S-RAM. Now + Sound Novel-Tcool, Thoroughbred Breeder 3, RPG-Tcool 2 and Dezaemon are + supported. +- The Windows port now has an option to make the 'turbo speed' button a toggle + button. +- The optimised fixed colour addition/subtraction code was ignoring the colour + window. Thanks to John Weidman for pointing this out. +- Added mode 7 and hi-res. hack for Dezaemon from Nose000 - the mode 7 hack + looks interesting (to me); I wonder if some other games would benefit? +- Both Tales of Phantasia and Star Ocean need custom sound CPU timing. Hmm. + That's 4 ROMs now, there will be more... That means I still haven't + discovered all the major SNES timing quirks. :-( +- Windows port now has an option to save the S-RAM data at any time. +- Windows port saving SPC dumps now auto-increments the filename. +- Added work-around for a Super Robot Wars Ex ROM bug - the game was checking + the wrong PPU register for end of h-blank. The game must have only worked by + chance rather than by design on a real SNES. +1.34 +- Corrected the colour addition/subtraction and halve the result code not to + halve the result when only the fixed colour is used, i.e. the sub-screen is + clear. Discovered and fixed this awhile ago, but I accidentally reintroduced + the bug when adding some optimisations a few versions back. +- Finally cleared the last of the offset per tile background mode bugs. There + was something odd about the tile at the left-hand edge of the screen that I + couldn't figure out - well now I have. Yoshi's Island level 6 boss screen, + Mario RPG mine cart screen and Jim Power title screen now all display + correctly. +- Made reading blank areas of the SNES memory map return the middle byte of + the address - fixes Home Alone which tries to execute code in an empty part + of its memory map but only works because the real SNES seems to return the + middle byte of the address - $60 in this case, which corresponds to the + ReTurn from Subroutine instruction. +- Added auto-cycle skipping disable for Earth Worm Jim 2 and several other + games that spool sample data using H-DMA as the sample is being played. + Improves some sound effects in these games. +- Fixed joy-pad routines to only report up or left if down or right are also + pressed respectively. Works around a game bug in Empire Strikes Back in the + asteroid stage where the game crashes if both left and right are pressed - + something impossible to do on the original SNES game-pad. +- Added custom SPC700 timing for Rendering Ranger R2 - the game now works with + full sound. No idea why it needs custom SPC700 timing. +- The ROM type detection was broken for Treasure Hunter G and Test Drive 2 - + fixed the code so type 2 ROMs can be LoROM. +- Adjusted the main CPU cycles per scan-line from 341 to 342 to give an exact + match for the timing required for Earth Worm Jim 2. All EWJ2 needs now + for perfect sound emulation is a method of synchronising the emulation + speed to the host hardware's sound card playback rate, oh, and a fast CPU! + The Linux port already has this but seems to be broken because games + play at double-speed when this option is enabled. +- Some SPC700 code in Earth Worm Jim 2 seemed to prove that I had guessed the + clock speed of the SPC700 sound CPU incorrectly - out by almost a factor of + two, in fact. Changed the relative emulated clock speed of SPC700. Now + Chrono Trigger doesn't lock up at certain points anymore, the special SPC700 + timing for games written by the Human Software company isn't required and + you can hear some more of the sound samples in Earth Worm Jim 2, etc. +- H-IRQ triggering code was broken - if a ROM turned on H-IRQ but later turned + it off, Snes9x could continued to generate H-IRQs, crashing some games. +- Added a generic test for Human Entertainment games - they need special + sound CPU timing to work. Gets Taekwon-Do working. +- Disabled offset-per-tile mode for Theme Park; the world map screen is corrupt + with it enabled. +- Yet more changes to the offset-per-tile backgrounds modes 2 and 4. Added + 64 tile wide screen support for Mario RPG's mine cart ride and fixed multiple + bugs with the handling of horizontal offset-per-tile used in Chrono Trigger's + fade in of the space ship. +- New feature: Snes9x can now load ZSNES freeze state files! Just copy them + into the freeze file folder and Snes9x will load them when you load a freeze + file, but only if the corresponding native format Snes9x freeze file doesn't + exist. +- Added memory map hack for Batman - Revenge of the Joker: its ROM header block + is in the wrong location and Snes9x incorrectly detected its ROM type. +- Fixed an off-by-one-pixel clip window 2 bug when the window was set to clip + outside the window area; clip window 1 was already correct. Removed the bright + line bug at the left edge when the combat screen is appearing in Starfox and + the clip problem when text boxes zoom-out in Yoshi's Island. +- Jim Power's title screen seems to prove that the per-tile offset data on + mode 2 isn't ignored for the left most tile as I originally thought. + Modified the code. +- The recent timing changes highlighted another problem with Daffy Duck - + changed IRQ enable register to only clear pending IRQs if one has been pending + for several microseconds. +- Speeded up the sprite data register handling slightly. +- Finally got Aero the AcroBat 2 working, after many hours of investigation, + spread over several years - literally! Two problems. The SNES doesn't seem + to consider scan-line line zero to be part of the v-blank period even though + the line is never drawn and V-IRQs at the start of the scan-line have to be + delayed until a few microseconds into the line - Traverse: Starlight & Prairie + required this as well, so I removed the original, Traverse specific hack. + There's a problem with the in-game music that I'll investigate at a later + date. + - The in-game music problem just required ENVX emulation to be switched on, + off by default on the Linux port, on by default on the Windows port. +- Fixed the mode 7 corruption problem on the title screen of Chase HQ using the + same trick as Illusion of Gaia - i.e. mod the mode 7 centre X & Y values with + 1024. +- Fixed another crash bug in the interpolated mode 7 code - a portion of + the code was ignoring the screen flip value and the fact that X render + direction reversed if the screen was flipped horizontally. Was causing a + crash on the whale boss screen of Kirby Superstar. +- Mortal Kombat 3 now auto-adjusts emulated cycles per scan-line work-around + a speech sample being cut short. +- Added sample data register reading support to the sound DSP - somehow I + seem to have missed implementing this. Not sure if any ROM actually reads + the value. +- Followed Sumire Kinoshita's suggestion and stopped clearing the ENDX flags + when the value is read, against my better judgement, and it does actually + improve speech samples in several games. Ooops! The Mortal Kombat series, + Magical Drop 2 and Metal Combat are the ones I've discovered so far. +- WWF Arcade now auto-adjusts the cycles per scan-line value to work-around + a sound sample repeat problem. +- Hmm. There's something about offset-per-tile mode I don't understand - WWF + Wrestlemania Arcade is getting corrupt graphics; not sure what effect the + ROM is trying to produce. Disabled offset-per-tile mode for the game for now. +- Fixed Street Racer player 1 wobble problem during the soccer game by auto- + adjusting the cycles per scan-line value slightly. +- Made Power Rangers Fight auto-adjust emulated cycles per scan-line to work + around a slight timing problem that causes an NMI to corrupt register + values that an IRQ handler is trying to update. Without it the scrolling + back-drop and fighter graphics are corrupt. +- Illusion of Gaia seems to need the mode 7 centre X & Y values to be mod 1024 + if the screen repeat flag is set. Fixes the island fly-over bug right at + the end of the intro but breaks a few other games. Hmm. Made it auto-switch + on for this game only. +- Added memory map support for Radical Dreamers. Thanks to satellite hut master + for the information. +- Made updates to the top bit of the sprite write address register be ignored + unless the low byte had been written to first. A ROM coding bug in + James Pond II requires this, otherwise it writes a junk byte value into the + main character's X position and Robocod wobbles around all over the place. +- Reverted back to pre 1.31 way of initialising unknown register values - + Rock and Roll Racing was reading a junk register value and using the value + to set up DMA, which in turn was causing corruption on the player select + screen. +- Added Star Ocean memory map - thanks zsKnight! The original ROM I was testing + was corrupt, no wonder I couldn't figure out the memory map myself! The game + still isn't playable, though, due to missing S-DD1 graphics decompression + (+ encryption?) emulation. +- Started to dump some compressed data values from Street Fighter 2 Alpha in + the hope that one day someone will be able to crack the S-DD1's compression + algorithm. +1.33a +- C4 emulation wasn't being automatically enabled for Rockman X2 / X3 - the + Japanese versions of Megaman X2 / X3. +- Fixed the Super FX plot table pointer that I accidentally broke while saving + 1Mb of workspace RAM - it was stopping all Super FX games from working. +1.33 +- Noticed another problem with the CPU_SHUTDOWN code - Chrono Trigger locked + up during the intro but only when using the asm code CPU core. Found the + algorithm difference between the code and made the CPU match what the C + version was doing. Still not sure why it caused a problem in the first place. +- Changed colour subtraction code to use Lindsey Dubb's newer version he sent + me some time ago but I 'forgot' to include. I say forgot, but I really put + off including it because, although it improves most games that use the + effect, it does result in one or two slight visual glitches. +- Hacked in zsKnight's C4 emulation asm code - now both Megaman X2 and X3 are + playable. Still got to complete the reverse engineering of the i386 asm code + to C so other, non-Intel ports can have C4 emulation. +- Shuffled the keyboard mapping a bit on the Linux port so now Tab key acts as + an emulation speed turbo button, `, # and ~ act as superscope turbo and + / acts as the superscope pause button. +- Fixed asm CPU_SHUTDOWN code that I accidentally broke while trying to + optimise it! Thanks to all the people who noticed Snes9x's frame skipping + had changed between releases. Frames rates should be improved again for more + than 50% of games. +- Re-enabled in-lining of the C SNES memory access routines, improves frame + rate by one or two on slower machines. +- Optimised the asm 65c816 addressing mode emulation code a little. +- Included some code changes making life easier for the Mac porter, John Stiles. +- Added memory map support for Sufami Turbo using information supplied by + Nose0000. No idea if it works because I don't have the ROM. +- Spent a few minutes trying to figure out the Star Ocean memory map so at + least the sound effects could be heard. But gave up after a couple of hours + due to laziness. If anyone knows the memory map details, let me know please! +1.32a +- The delay loading of the OpenGL DLLs on the Windows port was causing the + OpenGL initialisation code to fail. Reverted back to normal DDL loading but + with the side effect that Windows 95 users must visit the Microsoft web site + and download the OpenGL add-on before Snes9x will work for them. +- Corrected the OpenGL bump-map display option - my attempt to get the + bi-linear OpenGL display option to work with Voodoo card's limited texture + size had broken the bump-map mode. +1.32 +- Changed the Windows port to delay load the two OpenGL DLLs, so now they're + only loaded if you switch to OpenGL mode. The original version of Windows 95 + didn't include the OpenGL DDLs, so Snes9x wouldn't even start on that + platform; now it should. +- Added yet another sound buffer option to the Windows port - this time the + block size of sound data to mix. Some DirectSound sound card drivers only + report the play position moving in steps rather than continuous amounts and + Snes9x's default mix block size turned out to be smaller than this step + value on several cards. + Snes9x couldn't work out out where the true play position was accurately + enough resulting in broken, noisy sound output. +- Modified the Windows frame timer code to use semaphores rather than events - + they should make Snes9x more reliable at not missing frame sync pulses when + Windows is busy doing background tasks. +- Added SA-1 shutdown code - basically, Snes9x now stops emulating SA-1 CPU + instructions when the SA-1 enters an idle loop waiting for the main SNES + CPU to give it something to do. All SA-1 run much faster and smoother now. +- Added multi-axis joystick/game controller support to the Windows port and + tweaked the dead-zone threshold position a little. +- It looks like the SNES PPU was designed to support 128K of V-RAM but only + 64K was fitted; Snes9x wasn't wrapping all V-RAM address to stay within the + 64K limit causing a corrupt title screen on ReX Ronan - there will be others. +- Added amend functionality to the Windows Cheat Entry dialog and added extra + text boxes for direct address and cheat value input rather than only being + able to type in a Game Genie or Pro-Action Reply code. +- BS Suttehakkun2 was crashing just before start of play - the ROM was + performing a junk DMA that was corrupting RAM, crashing the game when it + went searching for a particular value. +- F-1 Grand Prix requires IRQ triggering when IRQ scan-line register set to + current scan line, but Chuck Rock objects. Hmm. Chuck Rock seems to indicate + the CPU emulation is running too fast, but I can't see where the mistake is. + Special-cased Chuck Rock for now. +- Optimised SNES DMA handling slightly - copying data to SNES V-RAM is now + significantly faster. +- Windows Cheat search dialog was ignoring data type parameter in various + places which was causing problems when larger numbers were being searched + for. +- Forced unknown PPU register reads to always return 0 - a coding bug in + Equinox shows that this is required. An earlier fix didn't work. +- Puya Puya 2 & remix were objecting to an NMI being triggered when enabling + NMIs after scan-line 226, but Ys 5 seems to require this. Hmm. Added a hack + to support both games. +1.31 +- Snes9x DirectSound code modified - the mixing block size is now always 10ms + for Windows 95/98/2000 and 20ms for NT 4.x, now there should be no need to + enable Sync Sound when a large sound buffer is required (helps emulation + speed). The maximum sound buffer length values have been updated to reflect + the smaller mixing block size. +- Changed the DirectSound code back to use an offset from the play position + as the place to write new sample data into the sound buffer - on NT 4.x the + write position seems to vary randomly rather than being a fixed distance + in front of the play position as documented. Now I know why I used the play + position originally! +- Changed the DirectSound code to fill the sound buffer at the write position + supplied by DirectSound, rather than just before the current play position - + should help reduce latency. +- Added an auto-detect method for interleaved mode 2 Super FX ROM images - + well, not really auto-detect: if the game crashes and its a Super FX game, + Snes9x assumes its in interleaved mode 2, de-mangles the ROM image and tries + to run the game again. +- Had to update the Snes9x Windows registry version number as the additional + diagonal settings make old registry settings incompatible. +- Added diagonal keyboard controls to the Windows port, as requested by + several users. +- Changed PPU code to return zero when reading non-existent registers - the + game Equinox relies on this due to an original game coding bug. +- Included FMOD sound driver support to Windows port - people experiencing + broken sound or delayed sound, etc, might want to give it a try. +- Tales of Phantasia - un-interleaved format ROM memory map changes to match + odd ZSNES format, now the hacked ROM works. +- Changed NMI again. Made reading or writing to PPU register 0x4210 + clear NMI pending flag again, without this Super Tennis does not work. +- Changed NMI timing back to be the same as several versions ago and just + special cased Cacoma Knight instead - although kept the code to prevent + the re-triggering of an NNI more than once in the same frame. +1.30 +- Forgot to force GUI surface to be displayed when some dialogs where popped + up - problem only happened on full-screen mode with triple or double + buffering enabled, or when using 3dfx mode. It appeared as if Snes9x had + locked up, but pressing Esc would pop down the hidden dialog. +- Added a couple of options to the Settings dialog. Now its possible to + disable S-RAM auto-save which was causing Snes9x to write to the hard disk + every 30 seconds on some games, causing the occasional skipped frame. +- Fixed Reset option which was accidentally broken when Netplay support was + added. +- Added support for Dirt Racer - it leaves the Super FX chip running all the + time, so the default CPU emulation method never allocated any time to other + CPUs and the emulation seemed to lock up. +- NMI timing changed again. Now an NMI can only be triggered once per + frame and enabling an NMI after the normal trigger scan line triggers + an NMI immediately. This fixes display glitches in Ys 5, Stargate and + Daffy Duck. +- Fixed the WAI instruction to only 'wake up' once an actual NMI has + triggered, rather than just waking up when it should have triggered. + This fixes Battletoads, broken since version 1.29(ish). +- Changed NMI again. Made reading or writing to PPU register 0x4210 not + clear NMI pending flag. Seems to allow all the NMI timing sensitive ROMs + I had on my list to now work without any special hacks. Illusion of + Gaia now works again. +- Another NMI fix - cleared the CPU pending NMI flag at start of frame; + Battletoads intro was crashing without this. A long DMA was stopping the + SNES CPU so it couldn't and shouldn't respond to the NMI signal from the PPU. +- Fixed Netplay problem when game didn't have any S-RAM and Sync Using Reset + was being used. An error dialog was displayed and the client would disconnect + from the server. +1.30b#1 +- The Windows auto-frame skip code was broken - badly. It didn't re-sync a + timer value with timer events being generated, causing Snes9x to deliberately + stop and wait for an event when it didn't need to, slowing down the overall + emulation speed and increasing the number of frames skipped. +- Improved the Windows cheat search dialog - its now possible to compare + against a value and more comparison functions are available. +- Finally worked out why Voodoo 3 support was so buggy in Snes9x - the Voodoo 3 + card generates a WM_DISPLAYCHANGE message when switching to Voodoo mode (the + Voodoo 1 and 2 cards don't); Snes9x thought that some other application had + changed the screen depth or resolution and tried to adjust its window to + match - triggering another WM_DISPLAYCHANGE message. No idea how the code + worked at all; it must have been only by chance and very dependant on the + driver version you were using! +- Implemented Netplay on the Windows port - but its buggy as hell. I seem to + be having major Windows multi-threading problems. Comments I've seen seem to + suggest that Windows 95/98 don't implement true multi-threading; hmm... +- Not happy with the current Netplay, so I scrapped it and tried again; + the protocol is much improved and not using select to control game timing + seems to have removed lots of the threading-type problems I was having. +- Attempted to switch to just using Borland's C++ Builder to build the Windows + port - and failed, again. Although C++ Builder can build Snes9x from sources, + it can't then link in the asm CPU cores. I had hoped Borland might have + fixed this with their latest release - they haven't. +- Several attempts to get Anti Resonance's super-fast sound CPU and sound DSP + code working in Snes9x, but all failed. Part of the problem was his code was + written using TASM and the object files it generated would only work under + Windows - but all my SNES debugging code was in the Linux port. Anti' fixed + that, and I then had some success getting his code working, but its just too + unstable at the moment for a main-stream release. +- Included an option to use Anti Resonance's alternate sample decoding routine; + it can approximate the wind and noise sound effects heard in several Square + Soft games. +- Thanks to Lindsey Dubb for the mode 7 bi-linear filtering code - it + generates a nice smooth image when a game scales the screen using the SNES' + mode 7, but you'll a fast machine if you don't want the frame rate to drop. +- Thanks again to Lindsey Dubb, he improved the colour addition/subtraction + subtraction routines - they are just a little slower but now mostly perform + full 15-bit precision addition and subtraction rather than the previous + 13-bits of precision. Many more colour shades can be seen - look at the + improved shading on the Mario Kart or F-Zero track for example. +- Added a reverse stereo option, for people with sound cards that swap the two + channels. +- Added a sound config dialog to the Windows port - now you can access extra + sound options that have always been there, but just no GUI interface to + access them. +- Fixed the 32-bit windowed support on the Windows port. +- Adjusted the NMI timing by a few microseconds to get Metal Warriors working + again. +- Added a few more sound playback rate choices. Most modern sound cards allow + any value to be used from a large range, rather than just a select few, may + be I ought to add text field so you could just type a value in? +- Used Factory Setup 4 to build a new installer package for the Windows port - + just shipping a zip file was confusing novice users and many (mostly AOL + users) seemed to have an odd program mapped to .zip files, further confusing + the issue. +1.29 +- Disabled the SPC700 noise feature simulation used by Chrono Trigger and + Final Fantasy 3 until I work out why its being triggered by sound effects + that don't use it. +- Rewrote/reorganised the DirectX and 3D/fx handling code, now both are never + enabled at the same time in Snes9X. It might fix the crashing problems some + Window port users are seeing. Changing between DirectX and Voodoo 3D/fx + modes now requires Snes9X to be restarted. +- Tracked down and fixed the Chrono Trigger black screen problem on the Windows + port: a rogue asm instruction was left in by mistake after some code edits - + it was only by chance that the code worked on the Linux port. +- Added some SNES debug options to the Windows port, but disabled by default, + on the shipped version. +- Clicking on the column headings in the OpenROM dialog in the Windows port + now sorts by that column; plus added some slight screen update optimisations. +- Added an optimisation to graphics rendering: don't add or subtract + sub-screen from background layers, or clear the sub-screen, if SNES fixed + colour is black and no background layers are enabled on sub-screen, even if + ROM tries to enable translucency effects for every background layer. + Discovered Sonic was doing this, there will be others. +- Forgot to enable auto S-RAM save on Windows port, oops! +1.28 +- Warning dialog added to the Windows port - if a ROM is loaded from a + read-only directory, e.g. a CD, and the freeze file folder is set to be the + same as the ROM image folder, then a warning is displayed when the game first + starts. +- The Windows port now supports 5 joy-pads - Snes9x always did support 5 but + the Windows port lacked the GUI option to enable and configure it. +- Added an about dialog to the Windows port. +- The Windows port now has a simple settings dialog, only one option so far - + changing the freeze file and S-RAM save directory; much better than having to + use regedit at least. +- Added a new cheat search dialog, you can use it to find where games are + storing life counters, health levels, etc. and then add cheats that stop the + values from changing. +- Added a cheat code entry dialog to the Windows port; now Game Genie, + Pro-Action Replay and Gold Finger codes can be graphically entered and + edited. +- Added a master cheat codes on/off toggle, available from the Cheats menu + on the Windows port. +- Extended the number of cheats per game from 10 to 75. +- Changed cheat code to reapply cheat every emulated frame so if RAM is being + patched the cheat value is continuously applied. +- Wrote some new cheat search code, the code won't be useful until I get around + to writing a cheat search dialog. +- Added automatic cheat code loading and saving using the same file format as + ZSNES. +- Rewrote large parts of the Snes9x cheat handling code ready for adding + cheat dialogs to the Windows port. +1.27 +- Added a flag to only enable SPC700 noise 'feature' when Chrono Trigger or + Final Fantasy 3 are loaded - the conditions that I thought were necessary to + trigger the feature where sometimes being met by other games. +- Added a simulation of the SPC700 noise 'feature' where some games, notably + Chrono Trigger and Final Fantasy 3, play samples that deliberately overrun + outside a 16-bit value, the SPC700 sound DSP then for some reason starts to + generate a type of noise sound which the games use to generate wind and + swish type sound effects. Thanks to ZSNES for some of the information. +- Fixed another sound interpolation problem, thanks to Mikael Bouillot - + the initial value of the sample byte being played was not being set correctly + when processing fractional offsets. +- Added auto S-RAM save option; S-RAM is automatically written to a .srm file + a few seconds (30 by default) after a ROM writes to it - useful for people + who were playing games long into to night, only to lose their progress + after a power cut or machine crash. +- NMI delay code changed again - the fix for Cacoma Knight was breaking + Tuff E Nuff; it would seem delaying NMI until the start of h-blank to too + long, added a cycle counter instead. +- Fixed yet another clip window bug - clip window was being incorrectly set + at no range if colour window was enabled but background layer clip window + was disabled (meaning layer should not be clipped). + Fixes the sunken ship level on FF5. +- Worked out (by example) how to add keyboard accelerators to the Windows port, + now toggling full screen using ALT+Return works. +- Added mouse-warp to the Windows port so the the cursor doesn't wonder off the + Window while SNES mouse emulation is enabled. +- Improved 3dfx support on Windows port - load dialog doesn't drop out of + bi-linear mode and underlying window zooms to full-screen so its easy to find + and click on the menu bar with the mouse. +- Added Mouse and Superscope SNES emulation support to the Windows port, use + '7' on the keyboard to select. +- Windows cursor now hidden unless super scope emulation is enabled. +- Windows port now has command line parsing - cheapo way of adding Game Genie, + Pro Action Replay cheat codes, disabling sound CPU emulation for the + corrupt copy of Star Fox 2, etc. Also allows ROM images to be dropped onto + the Snes9x icon. +- Cacoma Knight seems to provide proof that Snes9x triggers the SNES + non-maskable interrupt (NMI) too early. Changed interrupt to trigger at the + start of the next horizontal blank period. Will have to watch for it + causing problems for other ROMs. +- Added a translucency hack - when a ROM tries to create a stipple background + pattern by enabling pseudo hi-res. and not enabling a background layer on + one of the screens, Snes9x changes the effect to use transparency effects + instead (the real SNES can't do transparency effects with pseudo hi-res. + enabled). Now the water in Kirby 3 is translucent. +- SA-1 CPU reset bug fixed, now Jumpin' Derby boots and plays but with major + graphics problems. +- Fixed nasty asm SA-1 custom hardware read/write bug that was causing the + course map not to be displayed on Augusta Masters and Pebble Beach. +- Added SA-1 character conversion DMA support for all SNES depths, now + Augusta Masters and Pebble Beach work. +- Merged in minor code changes for Linux running on the Alpha processor. Thanks + to Sadruddin Rejeb for the changes. +- Added four more auto-multi-player-adaptor-emulation-off presets based on + code from Mystagogus. +- Added DirectX3D output image processing support to the Windows port... and + removed it again because it causes my desktop machine to lock up. Back to + the drawing board... +1.26 +- Fixed memory leak that crept in when SA-1 support was added when loading a + game freeze file. +- Added SPC dumping option based on code from Cyber Warrior X that he sent me + ages ago but I've just found again while looking for something else! +- Merged in most of the Amiga PPC port source code changes into the main + source code tree. +- Keying on a sound channel seems to clear its last-sound-sample-block-just- + played flag. Chaos Engine/Soldiers of Fortune needs this. +- Add multi-thread support to the UNIX ports for sound playing - required in + the Linux port to work around a Sound Blaster Live driver bug and useful if + you have multiple CPUs in your machine to help spread the emulation workload. +1.25 +- Added BS 24Mbit ROM memory map, for Derby Stallion 96 and Sound Novel-TCool. + No idea if it works. Thanks to Nose0000 for the info and code. +- Corrected unzip code not to loop forever if an encrypted zip file is loaded - + an error is generated instead. +- Changed relative SPC700 cycle length for Mortal Kombat 3 to fix sample + repeat problems - I wish I knew exactly how fast the SPC700 is clocked. + Maybe I should write a test ROM and run it on a real SNES? +1.24 +- 3dfx speed hack back again, only disabled when Seiken 3 is loaded. +- Some minor SA-1 speed ups added - the SA-1 instruction skipping code will + have to wait until I have more time. +1.23 +- Corrected a SA-1 reset bug that reset the SA-1 RAM bank pointer back to block + zero but didn't clear the RAM bank register. Was causing Kirby 3 to crash. +- Fixed a wave clipping problem with interpolated sound that was causing noise + on sound output when certain sound samples were played. +- Fixed a bug in the sync-sound code that could overrun the sound buffer by a + few bytes causing clicks on the sound output. +- The sound sample repeat bug that has plagued Snes9x ever since is was called + Snes96 finally bit the dust - Snes9x continued to play sample loops + even if the game dynamically updated the sample not to loop. Fixes the + stutter in the Mortal Kombat series and improves the sound from several games + that download sound samples in real-time as they are played. +- Rewrote the code the handled the SPC700's 64 byte shadow RAM area to fix a + possible sample corruption problem with ROMs that stored samples that + cross the 64 byte start area. +- Added code to allow ROMs to change the sample being played the next time the + channel loops or is keyed on - not sure if it fixes anything but seems more + correct. +- Added a zero-frequency fix to the stereo sound mixing code that I'd already + added to the mono code some time ago. +- Changed the code to set the end-of-sample flag just before the last block is + played, rather than just after. Seems to help improve the sound on some + games. +- Sound sample start code now doesn't reset the channel's envelope volume level + to zero before starting the sample - helps reduce the clicks being heard when + a channel envelope volume level hadn't reached zero before being keyed on + again. +- Changed initialisation of sample-end-register to 0 rather than 255 - seems + more logical now I've thought about it. Not sure if it helps anything. +1.22 +- Finally fixed the corrupt copy of Donkey Kong Country not working problem - + Snes9x thought the ROM used the same memory map as Street Fighter Alpha 2. +- Added explode, un-shrink and un-reduce decompression modes support to the + unzip code. +- Fixed offset per tile bug that crept in after me trying to fix the Starfox + on-tilt bug. +- Made some fixes to the C Super FX emulation code, enough to get most 'FX + games playable on the Mac port. +1.21 +- Finally worked out how character DMA worked on the SA-1 and implemented a + hacky, slow version, but its enough to get the level up screens displaying + correctly on Mario RPG. +- Incorporated ZSNES' new optimised Super FX asm code - had to track down and + fix a nasty memory overwrite bug in the code first to get it to work. +- Changed sample mixing code to not automatically wrap offsets to + keep inside the sound buffer, external port code is now expected to do that. + Helped me fix a problem in the Windows port that prevented very large sound + buffers from working, which are required for some badly written sound card + drivers. +- Corrected a bug in the SA-1 C code where incorrect processor emulation + functions where called if the code was compiled with in-lining turned off. +- Fixed crash bug in Super Mario RPG on the level up screen - forgot to mask + the enable bit from the RAM bank register. Thanks to Christian Wolf for + sending me a freeze file which made it easy to find the problem. +- Fixed a lockup bug in the window clipping code, if the ROM ever turned off + the sub-screen completely the clipping code would enter an infinite loop. + Fixes The Cartoon Addams. +- Made the Daffy Duck NMI fix only enable when Daffy Duck is loaded - fix was + causing problems for Breath Of Fire 1 and 2. +1.20 +- Windows port no longer sets DirectSound to exclusive mode, so its now + possible to hear sound output from Windows apps while Snes9x has focus. +- Fixed the freeze file loading and saving on the Windows port. +- More GUI settings are saved in the registry on the Windows port now. +- Added 3D/FX image scaling/filtering support to the Windows port. +- Added the TV mode from the Mac/Linux ports to the Windows port. +- Incorporated Kreed's new output image routines into the Windows port that + fixes RGB555 display colour problems. Many thanks to Kreed. +- New auto-frame rate timing code on the Windows port, stops the silly speed + up problems when the old code tried to 'catch up' after the emulator had + been paused. +- Increased the DirectSound secondary buffer length on the Windows port to + hopefully fix all the static/broken sound output problems some people were + experiencing. +- Altered the ZSNES Super FX asm code so the Windows port could use it - all + previous versions of the Windows port were shipped using the C Super FX + emulation code which is a lot slower. +- Implemented interpolated and sync-sound options on the Windows port. +- Added an image stretch option to the Windows port - stretches the SNES image + to fill the whole screen or the Window. Looks really good on my TNT card + since that chips seems to filter the image as it scales it. +- Implemented Windowed mode on the Windows port. +- Added special SPC700 cycle timing for Empire Strikes Back. +- Fixed the missing polygon problem for Super FX games - thanks to zsknight + for the information. +- Implemented SA-1 support required for Mario RPG, Kirby Superstar, + Paradius 3, etc. but since only a good image of Mario RPG exists, I could + only test that game. +- Fixed a graphics clip window bug: inverting the area of a clip area that + only consisted of empty bands should become the full width of the screen; + Mario Kart's rear-view mirror display needs it. +- Fixed mode 7 render code to use correct z-buffer when rendering onto the + sub-screen. Fixes Final Fantasy V title screen. +- Added horizontal offset per tile support in the offset per tile modes 2 + and 6, and switchable horizontal/vertical offset in mode 4. Fixes Chrono + Trigger in several places and Mario All Stars title screens. +- Changed SPC700 relative cycle length to 14, needed for Stunt Car Racer. +- Enabled immediate triggering of NMI if NMI enable flag set while scan-line + was on first line of v-blank. Needed to fix a background jitter bug in + Daffy Duck: The Marvin Missions. +- Altered ROM load code to ignore corrupt ROM map type byte in ROM header, + preventing the code erroneously detecting what it thinks are interleaved + ROMs. Fixes EEK! The cat, Formation Soccer, the corrupt copy of Donkey + Kong Country, ... +- Disabled IRQ re-triggering if V-IRQ registers set to the current line. Fixes + Chuck Rock. +- Fixed missing sprites in Andre Agassi Tennis - writing to low byte only of + the sprite write address register seems to also clear the hi-byte. +1.19 +- Games written by the Japanese software company Human seem to need special + SPC700 sound CPU timing, so the ROM load and reset routines now check the + software author company and adjust the CPU cycle length accordingly. + It gets Clock Tower, Super Fire Pro-wrestling Premium, etc working. +- Added ROM check sum calculation and testing code - Snes9x can now detect + pure, corrupt or hacked ROMs. +- Noticed a fast way to implement the SNES 4096 colour mode, so I implemented + it. Now the colours in ActRaiser 2 look correct. +- Corrected a noise frequency error thanks to information from Takehiro. +- Added a 'start in full screen mode' flag to the Linux port. +- While debugging the new graphics code I thought of a fast way to implement + the SNES direct colour mode, tried it out and now the colours in Actraiser 2 + are correct. +- Blast, forgot about the colour window and fixed colour effects. The separate + sub-screen is back again, but all the other graphics speed ups are there. +- Now I've got a z-buffer I keep finding other ways to optimise the SNES + graphics rendering - no need for a separate sub-screen, no need to clear + the sub-screen to the fixed colour, no need to waste CPU time on translucency + effects on hidden pixels, no need to completely clear the main-screen to the + back drop colour, etc., etc. +- Implemented a software z-buffer and changed the SNES graphics rendering to + use it (required change for future 3D card support). Finally fixes the + sprite-to-sprite priority bug that some games suffer from. Also a big speed + increasing for some games (10 fps+), others are slight losers. +- Added code to skip the rendering of completely transparent graphic tiles + rather than comparing each pixel to see if it is transparent; helps the + frame rate a bit on some games. +- Added a fixed for Tetris & Dr. Mario - the game didn't like a multi-player 5 + adaptor plugged in to the real SNES when being played, so turned off the + adaptor emulation for this game. +- Added hack for Final Fantasy II - if sync sound isn't on, make attack rate of + 1ms actually 0ms (old v1.16 behaviour). Causes a slight click but its better + than samples being cut short. +- Fixed a clip window area invert bug if the colour window was enabled on + on one window and the other window was being used to clip a background layer. + Fixes the finial (I hope) display problem with Gun Hazard. +- Added code to intersect the clip window areas if both a colour window and + a background layer clip window were enabled at the same time. Required by + Gun Hazard. +- Forgot to mark graphic clip windows as needing recomputing when the master + colour window inside/outside/on/off/main-screen/sub-screen PPU register was + updated. Was causing display problems for Gun Hazard. +- Internal H-DMA execution accelerator pointer variables where not always + being recomputed when started H-DMA part way into a frame. Was causing + display problems for Gun Hazard. +- Made H-DMA continue for one extra scan-line to fix a disappearing monster + problem in Dragon Quest 5. Thanks to Alex Jackson for the bug report. +- Zoop seems to require volume envelope height reading by the sound CPU to + always return 0 when the channel is in gain mode. +- The sound code was ignoring updates to the ADSR volume envelope rates while + one was in progress. Fixed that and now the bird song at the start of + Chrono Trigger sounds correct. +- Had to disable the CPU shutdown code for loops reading the horizontal beam + position, it was causing problems for Star Fox. Still no polygons though. +- Oops, sound DSP noise output was broken - accidentally deleted an important + line while removing debug code ready for the last release. +- Added initial 3Dfx support to the Linux port - basically using the Voodoo + card as a bi-linear filtering, scaling blitter. Actually slightly slower than + TV mode, for non-scrolling images due to poor texture upload speeds to the + card, but the full-screen feature is nice and the speed doesn't drop as more + of the screen changes. +1.18 +- Implemented a sync-sound mode where sound data gets generated in sync with + SPC700 instructions being executed. Finally the sound Williams Arcade + classics can be heard. Also helps slight sound timing problems in many other + games but doesn't fix Mortal Kombat 2 like I thought it would - its + sound routine programmers must have been on drugs or something! +- Added interpolated sound - gives low frequency sounds much more bass similar + to a real SNES especially with the playback rate ramped up to 44KHz. +- Added on-screen messages as various emulation options are toggled on and off + using the in-game keys. +- Fixed a PPU register read bug with the sprite register write position. Thanks + to Takehiro TOMINAGA for the bug report. +- Altered the auto-frame skip timing code to only wait and re-sync to the end + of frame when frames haven't been skipped. Again thanks to Takehiro. +- Speeded up the colour addition and subtraction code using ideas from + Takehiro. +1.17 +- Linux and UNIX sound code now driven directly from signal timer handler + rather than the timer handler just setting a flag which had to be polled in + the main emulation code. Slightly faster execution. +- Fixed the crash bug in the ZSNES Super FX asm code with Vortex - the game's + polygons still aren't visible though. +- Implemented bent-line increase and exponential decay and sustain volume + envelopes - they should match, or at least be very similar to the real SNES + sound DSP chip now. +- It would seem ROMs can key on sound channels even if the channel hasn't + been keyed-off, Pac-In-Time requires it. Changed code to allow it. +- Quick mod to ZSNES Super FX code to get Winter Gold working - it was already + working with the C Super FX code. +- Added emulation of the extra 1/2 scan-line per frame on PAL and NTSC - + should help improve music speed emulation. +- Worked around the click sound heard when ROMs use 0 volume envelope attack + rate. +- Removed the 'check for IRQ already happened' H-IRQ position register setting + code - it was causing problems for Ninja Warriors and was not required by + F1 Grand Prix. +- Fixed a bug in the new sound code - the sustain part of the + attack-decay-sustain-release volume envelope was being skipped if the + sustain level wasn't at 100%. The fix has helped some music notes from + being cut off early in a few games. +- Added fix to Pro Action Reply support (again). Thanks to Paul Shoener III for + the original fix and Gil Pedersen for reminding me to apply it! +- Finally fixed the Tales of Phantasia 'bum note' problem! The ROM set its + sample directory to the upper-most page and I forget to code for the hidden + 64 bytes of RAM, that appear when the boot ROM is switched off, when fetching + sample addresses. +- Adjusted the relative cycle length between the 65c816 and the SPC700 slightly + to get Terranigma working again. +- Oops, the emulated joypads 3 and 4 via the emulated Multi-player 5 interface + weren't working. Thanks to Steffen Schwenke for the bug report. +- Optimised the echo sound code - by-passed the the FIR filter code if only + a pass-through FIR filter was defined by the ROM. +- Modified V and H-IRQ register changing code to trigger an IRQ immediately if + V-IRQ is enabled and the scan-lines match and either H-IRQ is not enabled or + the electron beam position has already gone past the trigger point. Fixes + the screen flicker in F1 Grand Prix. +- Modified the priority-per-pixel mode 7 code to use BG#1's clipping data if + the top bit of the mode 7 pixel is set. Fixes initial track drive-through + display in F1 Grand Prix. +- Modified the sprite priority levels for the priority-per-pixel mode 7 + display. Now the car can be seen in F1 Grand Prix. +- Wrote a sound DSP register recording scheme which 'plays back' the register + changes in sync with the sound generation code. I'm bit disappointed, it + only improves the sound in a very few games... Scrapped the code, it actually + causes more problems than it fixes. Oh, well, another 3 weeks work wasted... +- Fixed a SPC700 wake up problem for Lufia I - made the SPC700 also wake up + when the 65c816 read from one of the four comm ports. +- Included lots of sound code speed ups and sound quality improvements + from Takehiro TOMINAGA - many thanks go to him. +1.16 +- Fixed a case where the -forcelorom option didn't work - the case was + required for Formation Soccer which claims in its ROM header to use the + same memory map as Super FX ROM, it doesn't. +- Pulled apart a real SNES using a crowbar (great fun), just to look at what + speed the SPC700 is actually clocked at for more accurate relative emulation + speed. +- Implemented SPC700 cycle counting in the hope the improved timing would fix + Tales'; no such luck but at least the -ratio option is obsolete now. +- Implemented executing SPC700 instructions during DMA, fixes BSZelda and + Goal lock up at start and music pausing briefly when ROMs do lots of DMA, + usually between game screens. +- Scrapped the i386 asm SPC700 code - it was the cause of the music not + restarting after a battle in Chrono Trigger and FF3 and I didn't realise + because the bug had already occurred in the test freeze-file I had. + Thanks to John Stiles for pointing out that the Mac port didn't have the + missing music problem. +- Fixed RGB subtraction bug on displays with only 5 bits for green, e.g. RGB555 + displays. The GREEN_HI_BIT variable was always set to a value for 6 bit + green displays. +- Added the SA-1 memory map, still a long way to go before any SA-1 game will + run. +1.15 +- Jumped versions to keep in sync with the DOS port release. +1.14 +- Improved 8-bit sound generation slightly, but it still sounds very poor + compared to 16-bit sound. +1.13 +- Implemented the Tales of Phantasia memory map using the information supplied + by zsKnight. Had to also implement a de-interleave routine to work around + a ROM feature and Snes9x CPU instruction fetching implementation detail. +- Added a frames-per-second on-screen display option. +- Fixed the final glitch bug with the Mario Kart track display - the byte code + for the termination of the DSP1 raster command wasn't been recognised. +- Disabled a NMI/DMA hack for Rise of the Robots, was causing problems for + Mario Kart and 'Robots wasn't working correctly anyway. +- Optimised the mode 7 rendering a little. +- Changed tile rendering code to use offsets into screen buffer rather than + direct pointers ready for z-buffer implementation. +1.12 +- Changed V-blank NMI to occur immediately after a WAI instruction, Toy Story + required this. +- Fixed reading of H-DMA line counter register, Top Gear 3000 needed this. +- Ripped off large parts of ZSNES's DSP1 code (with _Demo_'s and zsKnight's + approval). Now Mario Kart works almost 100%. +- Added a check to see if a vertical scan-line IRQ register change will cause + a H-IRQ later on the current scan-line. Pilot Wings needed this. +- Fixed possible crash bug in clip window code when both windows had two + spans. Could actually cause Chrono Trigger to crash the emulator. +- Fixed a lock-up problem with the C Super FX code, Star Fox and executing + a few 'FX instructions per scan-line (required for Winter Gold). +1.11 +- Partially fixed the DOS netplay server - the server timer is running too + slowly and it doesn't deal with disconnects correctly yet. +- Corrected the sound echo delay - it was varying with the sound playback + rate chosen by the user - it shouldn't have been. +- Implemented DOS netplay code - DOS server code still not working though. +- Removed all floating point calculations from the sound generation code. +- Fiddled with the pitch modulation code - my guess is the output of a + channel that is used to modulate the frequency of another channel is + automatically muted by the SPC700 chip. Just a guess, but the wind from + FF3 sounds 'better' but far from perfect. +- Optimised the tile palette index calculation. +- Optimised the planar to chunky tile conversion code. +- Fixed X11 port to always scale SNES image if hi-res. only (no interpolation) + support is enabled. +- Added zipped ROM image support using Gilles Vollant unzip code and + some code that Ivar (Lestat) sent me a long time ago. +- 65c816 asm RTI instruction was destroying the program bank in emulation mode, + the C code was already correct. Caused C64E to break. +1.10 +- Finished NetPlay v1 - allows up to five networked machines to play + multi-player SNES games, one player on each machine. +- Switchable full-screen mode added to Linux X11 port, some code and ideas + nicked from Maciej Babinski's original Snes9x XFree86 DGA Linux port, the + UAE Amiga emulator, plus lots of my own code. +1.08 +- Bug fixes to C Super FX emulation - now Winter Gold works correctly again. +1.07 +- More DSP1 work. Mario Kart is now playable! The character projection code + is still broken so the opponents and obstacles aren't always positioned + correctly on screen and you keep bumping into them, but I can still keep + coming first! +- Started work on NetPlay support. +- Decreased sound card DMA buffer size on DOS port to improve sound generation + and sound CPU synchronisation in some games. +- Included Linux joystick driver patches from Vojtech Pavlik so the port can + use the new v1.x joystick drivers, again written by Vojtech Pavlik. Allows + use of Micro$oft Sidewinder pads, NES and SNES pads, PlayStation pads, + Gamepad Pros, etc. +- Added halve-the-result colour subtraction. +1.06 +- Extended code to allow support for multiple 16-bit screen formats, + switchable at run-time, rather just supporting one, selectable at compile + time. +- Added XFree86 DGA Linux port - code from Maciej Babinski. +- More fixes to the X11 image format conversion and setup code. +- The asm SetByte routine wasn't wrapping writes to S-RAM correctly, allowing + some ROMs to think they were running on a copier and put up an error + screen. Thanks to Nu of #rom for the report. +- Added 'TV-Mode' support (interpolation and scan-lines) to the DOS and + UNIX ports from code based on John Stiles work. +- Added v-sync option to the DOS port. +- Added fix to Pro Action Reply support, thanks to Paul Shoener III. +- Added ggi support (untested) to Linux port using patches from + Alexander Larsson (alla@lysator.liu.se). +- Added 16 to 24/32 bit image conversion routines to the UNIX X11 code. +- The SPC700 OR1 instruction was broken. Thanks to Pyrgopolinices for the + report. +- DOS port was having trouble splitting and joining path names - caused + problems when specifying the full path name of a ROM when the ROM image + was on another drive. +- If a ROM reset the sound DSP and then turned on echo effects but kept + the same echo delay setting, then the echo effects could not be heard. + Thanks to madec@mclink.it for the bug report and freeze file that made it + easy to find the problem. +- DOS port was always using stereo sound setting, if sound card + supported it, regardless of the user preference. +- Linux port X11 port could crash if window was resized while transparency + effects were enabled. +- The colour subtraction accelerator look-up table was slightly wrong, causing + one bit of red, green blue values to 'spill' into the next field. +- Allowed colour window to cut a hole in the main-screen and show the sub- + screen underneath. The effect is used by Illusion of Gaia. +- Added support for colour subtraction, with the halve-the-result flag + set. +- Included DSP1 code from _Demo_. Now you can see the track in Mario Kart and + the ground in Pilot Wings - still can't play the games though due to other + missing commands. +- Added an NMI hack to work around a code bug in Battle Toads: BATTLEMANIACS, + its only by chance that the game works on a real SNES - And disabled it + again because it causes problems for Chrono Trigger. +- A frame skip of zero was actually still skipping one frame. Thanks to + Marius Fodor for the info. +- And yet more X-OR window bug fixes - now the effects during some of the more + 'posh' spells look correct in Chrono Trigger. +- Yet another window area inversion bug - off by one pixel on right-hand edge. +- Forgot to put dummy start and end points for XOR window combination modes - + now Uniracers looks correct and Sailor Moon looks like it does on a real + SNES. +- Window clip code was using wrong index into a 2-dimensional array when + the whole of the main or sub-screens were clipped. +1.05 +- The master volume disable code was looking that the wrong variable! +- Fixed crash bug in newer sound code if a ROM tried to start a sample + playing who's data went past the end of SPC700 memory. (Cannon Fodder) +1.04 +- Fixed DSP1 ROM header detection bug. +- More DSP1 work; still nothing works, although I know the multiply command + is correct because I've compared the results against a real DSP1. +1.03 +- Oops, the multi-player 5 disable code change broke the multi-player 5 being + the default controller. +- Implemented the colour window on the main screen - now Zelda's oval zoom + window displays correctly and Krusty's Super Fun House clips the left-most + 8 pixels as it does on the real SNES. +- TERRANIGMA didn't like me returning a random value when it attempted to + read a channel's the current sample byte. +- Hacked in initial support for mode 7 priority-per-pixel - the priority bit + doesn't actually change the priority of the pixel but the two games that I + know of that use the feature look OK. (Winter Extreme Skiing and the + intro of Tiny Toons Adventures). +- Colour addition/subtraction code now uses RGB565 rather than RGB555 + calculations - helps a little with the loss of the bottom bit of SNES + colour data. +- DSP1 emulation started - nothing works yet. +1.02 +- Switched to adding back drop colour rather than fixed colour when + sub-screen addition is enabled but there's nothing on the sub-screen. + Uniracers seems to need it. - DISABLED it again. Causes problems for + other ROMs and Uniracers itself on later screens. +- Fixed XOR window logic combination mode and area inversion code, now + Uniracers works correctly. +- Oops, if colour window and half colour addition/subtraction were both + switched on, area outside colour window was still being halved, it shouldn't. + Hacky fix at the moment until I implement the correct fix. +- Fixed several bugs with the mosaic effect and 16x16 tiles and a few + possible background scroll offset bugs and the mosaic effect. +- Optimised the sound sample generation code for cases when the SNES + sample playback frequency was higher than the sound card playback rate. +- Fixed possible click sound when a sample was first started to be played. +1.01 +- Corrected scan-line count for PAL games - should be 312 lines verses 262 for + NTSC. Was causing slow music on PAL games. +- Added error correction code to the SPC700 timer update code - the + SPC700 timers are updated using the emulated h-blank handler which is + called every emulated 63.6 microseconds (15.720KHz) but the SPC700 timers + need to be updated at multiples of 8KHz, hence the error. Was causing + music to be played slightly too fast. +- Switched back to using C SPC700 code - the old SPC700 asm code was lacking + several optimisations that the C version had. It also had multiple + speed hack cycle skipping bugs. Plus I hadn't even finished optimising + all the code from the last time I converted the C compiler output. +- Optimised SPC700 memory access routines a little. +- Disabled code that prevented ROMs updating SPC700 timer values while the + timer was running - it seems like it is allowed, even though docs on the + 'net I've seen say its not. +1.0 +- Fixed SuperScope support. +- Added hi-res. option to my DOS port. +- Fixed 4, 6, and 8 button standard PC joystick support. +- Changed some types the source code was using BYTE -> uint8, WORD -> uint16, + DWORD -> uint32 and BOOL -> bool8, types were clashing Windows typedefs + but sizes didn't always match. +0.99 +- 8-bit double height and/or width tile rendering was missing every other + group of 4 pixels - screen pointer advance count was wrong. +- Asm SPC700 emulation was ignoring the Shutdown flag - the result is its + not possible to turn off cycle skipping for the SPC700 emulation. +0.98 +- CPU to ROM address decoding code rewritten - used by Game Genie cheat codes, + orginal code might have been the cause of some Game Genie codes not working. +- Started to remove printf calls and replace them with calls to S9xMessage, + port code can then dicide what to do with message. +0.97 +- Re-enabled decompressed sample caching, still has a possible click problem + but the sound code is a lot faster with it enabled. Added command line option + to disable it if required. +- Added '7' key support to rotate through available controller options, in + the order multi-player5, mouse on #1, mouse on #2, superscope, + standard controller and then back to multi-player5. +- Hi-res. (512x448) support fixed. +- Mouse support completed - Lemmings 2 and Mario Paint working a treat. +- More colour window fixes. +- Fixed freeze game problem when ZSNES SuperFX code is being used - + ZSNES 'FX state was not being saved and restored. +- ZSNES SuperFX asm emulation code plugged in to Snes9x. +0.96 +- Looks like if the colour window is not enabled at all and the colour + window selector is defined to only allow colour effects inside the colour + window, then no effects should be visible. +- Offset-per-tile rendering code didn't support width 64 screen size, which + Chrono Trigger used on its title screen. +- Contra 3 seems to prove that defining the clip window area to be 'outside' + a window that covers the whole screen is not an area with no range. + - No it doesn't. It proves that I shouldn't have initialised the right + window edges to 255! Contra 3 enables clipping windows without first + defining their range. +- Debug frame advance feature was being prevented from forcing the next + frame to be rendered by SyncSpeed which was being called after the + debugger returned to the main loop. +- H-DMA code was allowing ROMs to manually start H-DMA during the v-blank + period, ROMs shouldn't be allowed to do this. +- Asm code would not push the correct CPU status onto the emulated stack if + returning from an NMI immediately triggered an IRQ - fixes Mortal Kombat 1 + and War of the Gems. +- 'd' dump memory debug command was not preserving the CYCLES count. +- C versions of SNES memory access code had same problem as asm code on the DOS + port except it didn't cause a crash just ROMs failed to work correctly. +- Asm i386 code was using signed compares to check for special case memory + areas - it was causing crash problems on the DOS port which was sometimes + returning valid address values with the top bit set - i.e. they seemed + like negative values! +- Changed event reschedule code to always allow h-blank start events, used to + disable them during v-blank period. +- Added code to HDMA when end of visible lines reached. +- Changed register 4212 code not to always return h-blank when in v-blank. +- Clipping fixed colour addition to background area was off by one pixel on + the right-hand edge. +- HDMA: Finally worked out how the real SNES operates when ROMs manual + start H-DMA during the frame - ROMs must set up the H-DMA line count + and address values before H-DMA is started. +- Fixed the asm code to remove all hard-wired structure offsets - one offset + into the IPPU structure was wrong in the code because the structure had + changed size. +- Added colour window support and allowed graphic window settings to be + different on the main screen and sub screen, just like a real SNES. +- SuperFX LJMP instruction had bank and address values swapped. +- Fixed possible memory overwrite problem because OBJList array was one + element too short. +- Added AND multi-graphic window combo support. +- ROM image memory allocation allocates an extra 32K of RAM, then moves the + pointer forward by that amount - stops the SuperFX emulation from accessing + unallocated memory, possibly causing a crash. +- SuperFX emulation now stores sign and zero flags in separate variables so + the MERGE instruction can set flags correctly. +- Added 65c816 instruction skipping to i386 asm code when 65c816 waiting in + a simple loop for some 'event' to happen e.g. end of frame NMI. +- Finally fixed the APU instruction skipping problem with the i386 asm + code when the WAI instruction is used - caused slow music on some ROMs. +- Offset-per-tile modes don't seem to support screen size - Mario All Stars + Super Mario 2 requires this on title screen. Doesn't seem to effect + Tetris Attack or Puzzle Bobble. +- Changed SNES select and start keys from shift and control to space and + enter - allows shift-fn key to save game positions without the SNES ROM + also getting a select joypad button press. +- Multiplayer5 support for controllers 3+ was broken for ROMs that used + automatic hardware joypad reading rather than reading joypads serially. +- ResetPPU was not clearing tile caches and marking OBJ as need recomputing. +- Cached OBJ positions and sizes were not being recomputed if ROM changed + global OBJ sizes during frame. +- Fixed brightness multiplication problem on 16-bit code for green. +- SPC700 emulation now uses one variable to store ZERO and NEGATIVE flags. +- SPC700 emulation now only increments PC once at end of instruction. +- New ROM type and interleaved detection code. +- Reading sound DSP register ENDX also clears the value. The docs on the + 'net said that only writing to the register cleared its value. Fixes + sound in Zoop. +- Fixed mode 4 colour palette problem on background #2 in tile-based graphics + code. +- Fixed graphics mode 4, offset-per-tile support. Only one set of offset data + that is switchable between horizontal and vertical, unlike modes 2 and 6 + which allow separate horizontal and vertical offsets per tile. +- Modified the APU timer code again, if the timer is enabled, a write to the + timer target register is only allowed if a value hasn't been written yet. + Fixed Donkey Kong Country 1 and Earth Worm Jim 1 & 2. +- Attack rate of 0ms changed from 1ms back to 0ms because of a group of ROMs + that change from attack mode to decay mode in real-time. Will change back + when I've added better SPC700 CPU and sound generation sync code. +- Added support for ROMs set a new sound timer value while the timer is + enabled (EWJ 1 & 2). +- Added support for ROMs that read the sound envelope height (MK1, MK2, etc). +- ROMs writing to the H-DMA enable register during visible scan-lines were + restarting H-DMA for that frame causing random screen effect corruption. +- Echo feedback seems to be after the FIR filter, not before as a diagram I've + seen suggests. +- Sound pitch modulation added. +- Memory access routines changed to pass a single 24-bit address rather than + the previous separate 8-bit bank and 16-bit address parameters. +0.3 +- Updates to A-Bus address during a frame must not update H-DMA address. + Fixes Actraiser 2 and Pacman 2. +- Removed sound volume mangling - with echo support enabled it doesn't seem to + be required. +- Attack rate of 0ms changed to 1ms to help prevent click sound with sudden + start of a sample playing. +- Sample caching of samples that looped using part of the original sample + created a click on the sound output. Caching disabled for the moment. Would + require 512K of cache RAM to fix sample caching. +- Colour addition/subtraction support added - but still a little buggy in + places and very slow. +- 16-bit colour support added. +- Sustain sound volume was not being set if a sample using ADSR was started + with both the attack rate and decay rate set to zero - resulted in missing + sound samples on with some games. +- Sound echo support added. +- Sound channel mixing code was not completely clearing a channel's sound + buffer when a channel finished playing a sample. +- Sound mixing code rewritten to use one buffer, rather than writing each + channel into a separate buffer then combining them into one buffer. +- Memory access routines rewritten to use an 8K block lookup table rather than + dedicated code for each ROM memory map - it was getting difficult to support + the new types of SNES ROM memory maps becoming apparent. +- Sound sample decoding wasn't decoding sound samples correctly if a + previously cached sample was only partially overwritten by the ROM as + opposed to being completely replaced. +- Sound sample decoding wasn't clipping generated sample values correctly. +- Changed H-DMA to start in the current frame only if enable register is + written to during v-blank, h-blank or while the screen is blanked. +- The SPC700 seems to start executing instructions before the 65c816 - + shorter reset pulse? (NO - forgot the SPC700 executes instructions while DMA + is taking place). +- ROMs that reset the H-IRQ position so another IRQ would be triggered on the + same scan-line where not supported - Super Off-Road: The Baj needs it. +- $4212 bit 7 needs to go high at the end of h-blank at line 224 not at the + start of h-blank - Bubsy needs it. +- Sample decoding routine could write to memory outside sample cache area if + address of block to decode was greater than $0x10000 - 9. +- Walking mario can be seen on map screen of MarioWorld - needed sprite + priority rotation working. ROM sets bit 7 of $2103 then sets rotation in + $2102. Reset rotation at start of v-blank not at end. +0.24 +- Fixed reading of DMA register values - now Ms Pacman works. +- Saved sprite memory address being restored on the wrong scan-line - caused + corrupt sprites on at least one game (GANBARE GOEMON 2). +- Screen colour palette not being updated if ROM only wrote to low byte of + palette register. +- Possible memory corruption fixed if a ROM tried to write to an invalid + sprite address via PPU registers. +- X11 port support quick load and save by pressing function keys to load or + shift + function keys to save. +0.23 +- Added option to disable graphic window effects - T2: The Arcade Game doesn't + seem to like them. +- Mode 7 "outside screen area" register interpretation fixed - now the + Actraiser map screen looks a lot better. +- Old DMA code hack for Battle Toads: Double Dragon removed as it was no + longer required and it was causing problems for Ys III. +- Lowered max volume level of 16-bit sound mixing code to help with sound + clipping problems is lots of SNES sound channels are playing. +0.22 +- Crash bug fixed in mode 7 graphics windows code +0.21 +- Fixed a noise channel volume bug - noise waveform was getting clipped. +- Fixed 24bit X Window System server support on the Solaris port. +- Sprites in priority level 1 on mode 7 were being drawn incorrectly behind + graphics screen. +- BG 3 priority 1 tiles sometimes not drawn dependent on the $2105 bit 3 + setting. +- Added graphic window support the tile redraw code. +- Added mosaic support to tile redraw code. +- Tile redraw code was drawing one line too many on screen-splits. +- Tile-based redraw code made more intelligent about when a background should + be displayed or not. +- Added wrap within bank support to large DMAs just to support Rock 'n' Roll + racing. +0.20 +- DMA routines added lots of special cases and removed most calls to GetByte, + using a pointer instead. +- Multiple using PPU registers is now only computed when first byte of result + is actually read. +- Sound enabled by default if compiled without DEBUGGER defined. +- Tile redraw method made the default. +- Fixed CPU_SHUTDOWN so SPC700 continues to execute even if main CPU is + "skipping" cycles waiting for an event to happen. +- More command line options added. +- Default cycles-per-scan-line to execute lowered to 90% from 100%. +- +/- keys now work even if auto-frame rate adjust was enabled. +- SPC700 emulation partially rewritten in assembler. +- Asm 65c816 code change to use same speed up techniques as the C++ code. +- Minor speed tweaks to the sound decoding and mixing code. +- C++ SPC700 emulation changed to use same method as 65c816 emulation for + computing and storing emulated CPU flags. +- Mode 7 code rewritten and several scrolling offset bugs fixed. +- Lo-ROM S-RAM memory map bug fixed - now Uniracers works. +- Multiple speed ups and changes to the tile and line-based redraw code. +- Tile and line redraw code changed to cache converted tiles between frames. +- Variable cycle length timing made compile-tile switchable. +- C++ 65c816 emulation changed to use several opcode jump tables to avoid + a register size comparison test on most emulated instructions. +- C++ 65c816 emulation changed how is computes and stores emulated CPU flags. +- Fixed high frequency sound playback bug - the sample rate calculation was + blowing the range of an unsigned long. +- Fixed V-RAM reading so DKC3, Addams Family, Aladdin and Pacman all work. +- Fixed sound code so ROMs can change from ADSR mode to decrease mode - fixes + lots of ROMs. +0.12 released +- Added dynamic speed regulation. +- TCALL vector calculation change from n to 15 - n. +- Fixed crash bug if ROM writes to sound DSP register numbers greater than + 127. +- Fixed DOS memory locked for interrupt code. +- Added long name versions of command line switches. +- Added command line switch for SPC700_SHUTDOWN code and WAI cycle skipping + code. +0.1 released +- All DOS memory is now locked from being swapped. +- Fixed DOS port keyboard polling code - could get confused if a keyboard + interrupt happened while keys were being checked. +- SPC700 ADC instruction never cleared Overflow or Carry flags! +- Changed selection of playback speeds for Solaris port. +- Sample caching code was broken - cached samples were never used. +- Added code speed ups for ROMs that use a lot of DMA to VRAM. +- More cpu code asm speed up. +- Fixed 16x16 size tiles on tile-based redraw code. +- Fixed sound gain-mode increase and decrease volume envelopes. +- Added code to support ROMs that reuse sprites in the same frame. +- Fixed processing of negative volume levels. +- Fixed SPC700 EOR1 instruction. +- Added SPC700 shutdown code to stop executing SPC700 instructions if in + a tight loop waiting for a timer or for the 65C816 to respond. +- DOS playback rate was being forced to 16KHz by Allegro - fixed. +- Fixed bug in SPC700 MOV1 C,bit, address. +- Fixed a off-by-one loop sample pointer bug in MixSamples. +- Added command line flags for cached-tile based drawing and sub-screen + background layers priority swapping. +- NOPE, got encoding of the OR1/EOR1,AND1 range of correct originally - + got duff information from an "SPC700" programmer. +- More SPC700 fixes: got the encoding of the OR1/EOR1,AND1 range of + instructions wrong - I guessed wrong originally. +- Sample looping bug fix on mono sound mixing code. +- Sound pitch value no-longer clipped to 14 bits - apparently FF3 needs this. +- Followed Paradox's suggestion and changed graphics code to place sub-screen + background layers below main-screen background layers. Helps lots of games + that use sub-screen addition/subtraction - now you don't have to toggle + background layers on and off so often just to see hidden text, characters, + or maps, etc. Made it switchable. + Acts as a good intermediate solution until sub-screen addition/subtraction + is actually implemented. +- Modified sound skipper code to return random values when ROM is stuck + waiting for the SPC700 CPU to respond - helps several ROMs that previously + don't work with the currently selection of APU skippers. +- Improved sound mixing code so volume is not attenuated so much, giving + better results on 8bit sound cards. +- Changed the frequency at which the joystick polling routine is called - now + called every-other frame rather than every 3rd frame. +- Recompiled Linux and DOS ports with the Pentium optimising version of gcc - + gives a few percent speed increase. +- Changed V-RAM increment count from 64 to 128 - apparently Final Fantasy 3 + needs this as well. +- Fixed sprite priority bug with Mode 7 - apparently Final Fantasy 3 needs + this. +- Fixed a screen clipping problem with the S-VGA mode. +- Fixed bug that had crept in with -m 2 S-VGA mode (Linux version). +- Fixed S-VGA Linux version with sound enabled. +- The SPC700 ADC (X),(Y) instruction was broken - with all these SPC700 fixes + now many more ROMs work with sound enabled. +- The SPC700 Pop PSW instruction was not resetting the direct page location. +- The SPC700 instruction MOV A,[DP+X] was incorrectly doing a MOV A,DP+X. +- Got the SPC700 SETx and CLRx instruction encoding swapped around. +- Fixed #define problem that was stopping DOS snapshot saving from working. +0.72 released +- Fixed the DOS filename handling - old Unix code was screwing up with ROM + filenames that contained backslashes (\) - the ROM would load but S-RAM + loading and saving would fail and the default filename for snapshots + wouldn't work. +- This time really fixed Allegro library keyboard handling (DOS port); it + was missing key some presses/releases (was stopping Chrono Trigger + Left + Right + A button combo from working). +- Added code to automatically remove headers off S-RAM save files with + 512 byte headers. +- 32Mbit ROMs in interleaved format are now automatically detected and + converted. +- Added -ss 3 sound skip method support to the asm version - now NBA Live '96 + works again. +- Added support for multi-part ROM images. +0.71 released +- Made libgz.so statically linked (again) on Linux port - sorry. +- Made writing to $4200 also clear any pending IRQs. This finally allows + Battle Toads: Double Dragon, Spawn and Sieken 3 all the work with the same + IRQ logic (but Sieken 3 still gets stuck in sound download code). +- Fixed a H-DMA wobble bug - some frames could randomly miss a line of + H-DMA causing the F-Zero screen to wobble, and slight text character + corruption on games like DKC3. +- Interleaved format ROM images are now swapped in-place, without the need + for a temp 4Mb buffer (saves lots of disk swapping on a 16Mb Windows 95 + machine). +0.7 released +- Fixed Allegro library keyboard handling (DOS port); it was missing key + some presses/releases. +- DOS port had a different MAX_PATH value which moved the location of the + SRAM size variable when using the asm CPU emulation core. This, in turn, + caused the SRAM emulation to fail on the DOS port. Donkey Kong County 2 & 3 + were reporting a ROM copier was connected to the SNES and refused to run. +- Fixed assembler version of XCE - it was always leaving the carry flag + clear - caused Killer Instinct and Super Punchout to think a ROM + copier was fitted to the SNES and they all refused to run. +- Fixed assembler versions of MVN/MVP - they weren't setting the data bank + register to the destination bank of the instruction. +- Fixed joystick detection on MS-DOS port - a single 2 or 4 button joystick in + port 1 was being ignored if a second joystick was not present in port 2. +- Fixed an uninitialised variable in graphics code - was causing random + missing scan lines on Mode 7 screens. +- Joysticks now scanned every 3rd frame (joystick scanning is slow in the PC). +- Double-whoops, Metriod 3 had stopped working in v0.6 - fixed it + (memory map bug). +- Made bit 6 of $4211 set if v-counter == v-timer-position. +- Made reading of $4200 read $4212 instead. +- Adjusted DMA timing to always access ROM memory at slow speed - this seems + to fix Battle Toads. +- Added code to automatically clear pending IRQs when the horizontal line + is no longer equal to the horizontal timer line - this fixes Seiken 3, it + now just gets stuck in the sound CPU wait code - oh well. +- Moved NMI back to its original pre-0.65 behaviour, now Puzzle Bobble works. +- More graphics speed ups - the code to render background tiles with their + priority bits set is only called if there are actual priority-bit tiles. +- Changed default frame skip rate from 1 to 2 - its seems most people don't + bother to read the docs, so I thought I'll help them out a bit! +- Speeded up Mode 7 graphics on games like F-Zero that rewrite the matrix + registers on each scan line using H-DMA. +- Reorganised the graphics code and did a slight speed up - graphics code + will be the next thing to rewrite in assembler. +- Rewrote CPU core in assembler for Intel platforms - gives a very noticeable + speed increase. +- Fixed several problems with the APU sound CPU emulation - its now getting + stable enough to try and implement sound. +- Fixed bug that caused 1 byte of S-RAM to be emulated when ROM didn't + expect any - it was enough to stop Street Fighter 2 and others from + working - thanks Lord ESNES. +- The TXS and TCS instructions shouldn't set the Z and N flags. +- Looks like MVP/MVN instructions should ignore accumulator size - change + code to always use all 16 bits and exit with accumulator set to 0xffff. +- Whoops, accidently left some test code in which was causing the V-BLANK + flag, bit 8 in register $4212, to be miss-calculated. +- Fixed palette in mode 0. +- Speeded up graphics drawing a little by skipping groups of 4 pixels that + were all transparent. +0.65 released +- S-VGA and MS-DOS ports now have a VGA mode command line flag. +- Improved the fading code - should be much more smooth now. +- Fixed second joy-pad support and re-mapped keys and joysticks to actually + make a match between what my docs said and a real SNES (SNES docs I'd + seen were wrong!). +- Fixed a bug in Relative Long CPU addressing mode. +- Ported Snes96 to MS-DOS. +- Snapshot loading and saving no longer uses external gzip binary. +- Added support for registers at $21c2 and $21c3. +- Made reading the software latch for the horizontal and vertical counters also + clear any pending IRQ. +- Added sprite priority rotation. +- Rewrote parts of the graphics routines to fix a sprite-to-sprite priority + bug. +- NMI flag changed again - now back to being reset by reading $4210 but + actual NMI is delayed. +- Made mode 7 background colour 0 transparent - this fixed several sprite + priority problems a few games where having. +- Finally worked out how sprite "Object Name Select" works and emulated it - + this fixes many (if not all) of the corrupted sprites some games + experienced. +- Delayed NMI activation for one instruction to give time for loops that + wait for bit 7 of $4210 to go high. +- Special-cased line count of 128 on H-DMA to mean repeat previous data with + a line count of 128 and not just terminate H-DMA on that channel. +- APU sound CPU emulation added - just need to debug the thing. +- Fixed Overflow flag setting in ADC and SBC instructions - it was never + being set. +- Rewrote how CPU instructions are fetched and how values are pushed and pulled + from the stack - it gave a very large increase in emulation speed. +- H-DMA was being started one scan-line too late. +- Added CG-RAM reading support. +- Added "Full Graphic" V-RAM reading. +- Speeded up C version of CPU emulation quite a bit - could speed it up a + little more before rewriting in assembler. +- Fixed bugs in 16x16 tile drawing on 2bit and 8bit deep screens. +0.6 released +- Speeded up 16x16 tile background rendering by removing a temp tile buffer + it was using. The speed up also fixed a vertical scroll bug. +- Fixed slight window clipping on 16x16 tile backgrounds. +- Added automatic PAL/NTSC mode switching. +- Fixed background and sprites so only visible if on main-screen or + on sub-screen under correct circumstance. +- Fixed lockup bug in DMA. +- Stopped NMI flag from being reset by reading $4210 - was causing a couple + of games to get stuck. +- Whoops, got horizontal and vertical Mode 7 flip bits around the wrong way! +- Fixed MIT shared memory pixmap support for X11 version (it was always turned + off). +- Fixed minor bug - first sprite in priority group was drawn twice. Didn't + cause any visual bugs, it just slowed down redrawing a little. +- Fixed DMA bug - transfer byte count should be 0 after DMA has finished. +- Fixed a scaling bug if width < height. +- Interleaved ROM image support added. +- 16bit and 24bit X11 server support added - with scaling. +- Added window scaling on X11 version. +- Partial clip windows added - the only window overlap option implemented at + the moment is OR, it seems it good enough for all the ROMs I've tested + it with. +- Partial Mosaic effect added (pixels only growing vertically). +- Missing Mode 7 "outside screen area" option added. +- Fixed mode 7 screen wrap "outside screen area" option. +- Used new event processing to finally fix H-IRQ so it triggers at the + correct position on the scan line. +- New event processing added. +- Linux version now statically links libgz.so (sorry). +0.5 released +- Linux S-VGA version changed from using a 320x240 ModeX screen (slow) to a + 256x256 chunky screen (faster) - thanks to Phillip Ezolt (pe28+@andrew.cmu.edu) + for information on how to do this. +- Mode 7 screen flipping added. +- Included Snes97's CPU emulation code into Snes96. Didn't fix any bugs but + slowed down the emulation some what and I couldn't compile it optimised + because it was so large - so I removed it again. +- Added a few extra features available via the keyboard. +- Fixed a H-DMA transfer mode - bad documentation. +- Fixed H-DMA indirect addressing (it was using the wrong CPU memory bank). +- The Linux slow down bug is my crappy laptop enabling battery saving features ! +- Changed graphics code to perform true line-by-line screen updates. +- Fixed sprite drawing bugs. +- Ported Snes97's graphics code to Snes96. +- Fixed memory map for HiROM save RAM area. +- Fixed HiROM memory map - now Killer Instinct and Donkey Kong County work ! +- OK the slow down bug is just actually my laptop trying to save battery + power by slowing the CPU clock! +- The Linux slow down bug shows itself on DOS emulators running under DOSEMU + so it must be a kernel problem (or feature). +- Fixed H-DMA (again) to be complete emulation - all I need now is line-by-line + screen update... +- Fixed DMA to not copy too many bytes if byte count was not a multiple of + the transfer mode quantity (caused corruption on Super Mario World map screen). +- Changed mapping of keyboard to joy-pad buttons and added additional + direction keys for joy-pad one so player one's right hand doesn't have to + obscure player two's keyboard joy-pad buttons. +- Changed joystick button layout to match SNES if using a 6 button joy-pad. +- Changed snapshot format so I can easily use libgz on Linux. +- Added few speed up tweaks that will be lost again when I add line-by-line + screen update. +- First visible scan-line changed from 8 to 1 to match with new docs. +- New SNES information source found; fixed partial H-DMA emulation to include + indirect addressing support. +- Snapshot files are now compressed. +- Compressed ROM images now supported on Linux. +- Snapshot loading and saving added. +- Joystick support for Linux added. One 2, 4 or 6 button joystick, or two 2 + button joysticks supported (PC hardware limitation). +- SVGA full screen support added for Linux. Still has the X11 slow down bug so + can't blame the X11 server any more! Must be a kernel bug or a very odd + emulator bug. +- Added emulation of two joy-pads on the PC/Sun keyboard. +- Removed -i command line flag as it is no longer used. -h value range has also + changed: now 1 - 100 (percentage). +- Actuate cycle counting rather than instruction counting now added including + fast and slow ROM timing - should give much better timing information when + line-by-line screen update added. +- Bug fixed old-style joy-pad access used by some ROMs - Mario All Stars still + gives problems if enabled and I don't know why; but at least Super Bomberman + now works ! +- Looks like if both horizontal and vertical IRQ are enabled then IRQ should + only be triggered once per frame and not once per scan line - looking at the + IRQ handler of a couple of ROMs seems to confirm this. +- Added initial cycle counting - not accurate enough for some ROMs though. +- Finally worked out how the odd VRAM address increments should work but only + found one ROM, so far, that actually uses it. +- Debugged the odd slow down problem with the Linux port - it seems to be a + bug in the X Window System server - starve the X server of keyboard presses + or mouse clicks or movement and the X server slows down, slowing down the + emulator with it ! +0.4 released +- Fixed sprite vertical clipping at top of screen. +- No need to invert the Mode 7 transformation matrix before use - the + ROM coder already had to! +- Fixed Mode 7 scrolling offset when using special effects. +- Added Mode 7 rotation, enlargement and reduction emulation. +- DMA shouldn't zero the byte count value after a DMA has completed. +- Added DMA reading (Addams Family was using it) +- Fixed V-RAM read function - returned data should lag behind the V-RAM + address by one byte/word. +- Added mode 7 graphics only. +0.3 released +- Speeded up the main CPU loop a bit. +- Add more command line options: + -f (default 1) + -i (default 32768) + -h (default 45, some games allow a lower + setting resulting in a increased + emulated frame rate) + -t enable CPU tracing + -ss (default 0, more methods to be added) + -H disable H-DMA emulation + -F Force Hi-ROM memory map +- Modified planar to chunky conversion to use look up tables. +- But now Mario All Stars won't start. Made emulation of $4016 optional with + -o command line switch. +- Thanks to Carlos (calb) of ESNES fame, I've added correct $4016 & $4017 + joy-pad register processing - now several more ROMs will start once a + button is pressed and can be controlled. +- DMA wasn't updating DMA registers with the final CPU address used after the + DMA had completed (caused sprite and background corruption with some ROMs). + Still suspect another DMA side effect isn't being emulated correctly though. +- Fixed setting of CPU overflow flag in ADC and SBC instructions in decimal + mode. +- Fixed MVP/MVN CPU instructions to leave X and Y values correct at end of + loop - several more ROMs now work. Still don't know if MVP/MVN instructions + should ignore the accumulator size flag or not. +- Rewrote background drawing code - gives a large increase in speed. +- Flag to only update X Windows colour palette when necessary was missing a + case - caused some ROMs to start with a black screen. +- Code to only update background tiles when changed wasn't working so I + disabled it. +- CPU WAI instruction needed to trigger on hardware IRQ even when interrupt + enable flag was false. +- DMA was not transferring 65536 bytes when byte count was 0. +- Fixed matrix 16bit x 8bit multiplication (old debug code was causing junk + value to be returned). +- Fixed Makefile so version.h header file change recompiles file that shows + version number in window title. +- Added more reporting of used but unimplemented missing hardware features to + debug command. +- New ROM loading code from Jerremy included, can now cope with ROM images + with no 512 byte header. +- Speeded up emulated memory access a little bit. +0.2 released +- Added matrix 16bit x 8bit multiplication for Super Off-Road Racer. +- Added initial H-DMA emulation - visual effects using it will not be seen + correctly until screen is updated line-by-line rather than the whole screen + at end-of-frame. +- Fixed horizontal sprite clipping (vertical clipping still has a problem). +- Integrated large sprite bug fixes and new background drawing code from + Jerremy. +- Fixed large size per-sprite flag; always stayed true after sprite size was + changed to large. +- Rewrote the planar to chunky pixel conversion routines (still need more + work). +- Made registers $4016 & $4017 always return $ff - lots of ROMs that previously + wouldn't go beyond the title screen thought old-style joy-pads were + connected and were waiting for the user to press a button on them. +- Frame skip rate now set to 1 instead of 5 on my P166 laptop! +- Fixed NMI v-blank flag being incorrect set, caused some ROMs to lock. +- X keyboard autorepeat now switched off when emulator has keyboard focus. +- Added number key options to toggle backgrounds 1 to 4 and objs (sprites) on + and off. +- Fixed sprite clipping problems at edge of left hand side of screen. +- Corrected Hi-ROM memory map (I think) (no I didn't) +- Fixed most of the sprite-to-sprite priority problems. +- Added sprite debug command, 'S'. +- Added a debug command to show what missing hardware features a ROM was using. +- Added horizontal and vertical beam position IRQ - horizontal always triggers + at start of line at the moment. +- Fixed SBC instruction to set carry flag the correct way around. +Initial release 0.1 +- Ported Windows 95 version of Snes96 to Linux on a PC and Solaris on a + SparcStation. +- Corrected work RAM memory map. diff --git a/source/docs/control-inputs.txt b/source/docs/control-inputs.txt new file mode 100644 index 0000000..4faddc3 --- /dev/null +++ b/source/docs/control-inputs.txt @@ -0,0 +1,68 @@ +Control input names are completely defined by the individual ports. This +document is intended to collect the rules for all ports. + +The various meta-characters in the rules are: + # - A number. The range is detemined by the context + ## - A two-digit number (i.e. with leading zeros) + [...] - Something optional + (...) - For grouping with | + | - "or", choose one of the options. + <...> - A named field + {...} - A list of possible values. Multiple values may be used, but they + must be in the order listed and joined with +-signs. + "" - 'ditto', used to indicate the same list as the above line. + +================================================================================ +Unix +================================================================================ + +Input names: + Jxx:Axis# Axis # on joystick xx. Axis0 may be + Up/Down, and Axis1 Left/Right. + Jxx:B# Button # on joystick xx. + + Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+B# Used with the 'JSx Meta#' port + Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+Axis# command. + + Jxx:X+B# Used to 'define' this key for all + Jxx:X+Axis# combinations of JS Meta. + +Port-specific Commands: + JSx Meta# Used to specify modifier keys (i.e. Shift, Control) to + affect the specified joystick. For example, you could + map J00:B20 to "JS0 Meta1", then map J00:B0 to "Joypad1 + A" and J00:M1+B0 to "Joypad1 Turbo A". '#' may range + from 1-8. + + Jsx ToggleMeta# Like the above, but toggles the meta-state each time + the button is pressed. + +================================================================================ +Unix/X11 +================================================================================ + +Keyboard Input: + + Note that only one keyboard (K00) is currently supported. If you know how + to support multiple keyboards (and can test it!), feel free to fix x11.cpp + and delete this note. + + Keyboard modifiers are S=Shift, C=Control, A=Alt, M=Meta. Combine them in + order, i.e. all 4 would be "SCAM". + + Kxx: Key names are as recognized by XStringToKeysym. + Kxx:+ Note however that keys are mapped by keycode, + so for example on a standard qwerty keyboard + "K00:colon" and "K00:semicolon" are identical. + +Pointer Input: + + Note that only one mouse (M00) is currently supported. If you know how to + support multiple pointing devices (and can test it!), feel free to fix + x11.cpp and delete this note. + + Mxx:Pointer Map the mouse pointer. If someone has a mouse + Mxx:Pointer# device with multiple pointers, fix x11.cpp to + report that and you can use the second syntax. + + Mxx:B# Mouse buttons. diff --git a/source/docs/controls.txt b/source/docs/controls.txt new file mode 100644 index 0000000..703cd33 --- /dev/null +++ b/source/docs/controls.txt @@ -0,0 +1,97 @@ +This lists the available commands, excluding the ones you get back from +S9xGetAllSnes9xCommands(). The various meta-characters are: + # - A number. The range is detemined by the context + ## - A two-digit number (i.e. with leading zeros) + [...] - Something optional + (...) - For grouping with | + | - "or", choose one of the options. + <...> - A named field + {...} - A list of possible values. Multiple values may be used, but they + must be in the order listed and joined with +-signs. + "" - 'ditto', used to indicate the same list as the above line. + +Speeds are: Var, Slow, Med, and Fast. 'Var' starts slow and speeds up as the +button is held. + +Axes are: Left/Right, Right/Left, Up/Down, Down/Up, Y/A, A/Y, X/B, B/X, L/R, +and R/L. Negative is listed first (i.e. "Y/A" means negative deflection is +towards Y, while "A/Y" means negative deflection is towards A). + +AxisToPointer, ButtonToPointer, and AxisToButtons allow for translating +between different input types. There are 8 'pointers' with IDs +PseudoPointerBase+0 to PseudoPointerBase+7, and 256 'buttons' with IDs +PseudoButtonBase+0 to PseudoButtonBase+255. So for example, +"AxisToButtons 0/255 T=50%" would take the axis data, and do +S9xReportButton(PseudoButtonBase+0,1) when said axis goes past 50% in the +negative direction and S9xReportButton(PseudoButtonBase+255,1) when it goes +over 50% deflection in the positive direction. Similarly, it will do +S9xReportButton(...,0) when the deflection drops under 50% in either +direction. "ButtonToPointer 1u Slow" would move the pointer with ID +PseudoPointerBase+0 up one pixel per frame as long as the button is pressed +(reporting this change at the end of each frame). + +--------------- +Button Commands +--------------- + +Joypad# {Up, Down, Left, Right, A, B, X, Y, L, R, Start, Select} +Joypad# Turbo "" +Joypad# Sticky "" +Joypad# StickyTurbo "" +Joypad# ToggleTurbo "" +Joypad# ToggleSticky "" +Joypad# ToggleStickyTurbo "" + +Mouse# (L|R|LR) + +Superscope AimOffscreen +Superscope {Fire, Cursor, ToggleTurbo, Pause} +Superscope AimOffscreen "" + +Justifier# AimOffscreen +Justifier# {Trigger, Start} +Justifier# AimOffscreen "" + +ButtonToPointer #[u|d][l|r] ; NOTE: "# " is invalid + +------------- +Axis Commands +------------- + +Joypad# Axis T=#% ; T = 0.1 to 100 by tenths +AxisToButtons #/# T=#% ; neg then pos, range 0-255, T as above +AxisToPointer #(h|v) [-] ; NOTE: '-' inverts the axis + +---------------- +Pointer Commands +---------------- + +Pointer {Mouse1, Mouse2, Superscope, Justifier1, Justifier2} + +------ +Multis +------ + +Multis are a type of button command. The basic format of a multi is "{...}", +where the '...' consists of 1 or more valid non-multi button command +strings. The braces are literal, not metacharacters. Subcommands separated +by commas are executed one after the next. Semicolons skip one frame before +continuing subcommand execution. Semicolons may be repeated. When the multi +button is pressed, each subcommand is 'pressed', and when the multi button +is released each subcommand is 'released'. + +There are also press-only multis, defined as "+{...}". These act just like +regular multis, with two differences: the multi is only run when you press +the button (release isignored), and each subcommand must be prefixed with +'+' or '-' to indicate whether the the subcommand should be pressed or +released. + +For example: {Joypad1 A,Joypad2 A;Joypad3 A;;;;;QuickSave000} + This presses (or releases) A on pads 1 and 2, then waits one frame, then + presses A on pad 3, then waits 5 frames, then saves to snapshot 0 (on press + only). + +You may access the multi number in the returned s9xcommand_t structure as +cmd.button.multi_idx. This may be used to assign the same multi to multiple +buttons: + MULTI# ; NOTE: that's a literal octothorpe diff --git a/source/docs/gpl-2.0.txt b/source/docs/gpl-2.0.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/source/docs/gpl-2.0.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/source/docs/lgpl-2.1.txt b/source/docs/lgpl-2.1.txt new file mode 100644 index 0000000..602bfc9 --- /dev/null +++ b/source/docs/lgpl-2.1.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/source/docs/porting.html b/source/docs/porting.html new file mode 100644 index 0000000..a2d3d49 --- /dev/null +++ b/source/docs/porting.html @@ -0,0 +1,371 @@ + + + + + + + + Porting Snes9x + + +

How to Port Snes9x to a New Platform

+
+ Version: 1.53
+ (c) Copyright 1998 Gary Henderson +
+

Introduction

+

+ This is brief description of the steps to port Snes9x to the new platform. It describes what code you have to write and what functions exist that you can make use of. It also gives some insights as to how Snes9x actually works, although that will be subject of another document yet to be written. +

+

System Requirements

+

+ A C++ compiler. For the most part Snes9x really isn't written in C++, it just uses the C++ compiler as a “better C” compiler to get inline functions and so on. GCC is good for compiling Snes9x (http://gcc.gnu.org/). +

+

+ A fast CPU. SNES emulation is very compute intensive; two, or sometimes three CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor with real-time sample decompression, filter and echo effects, two custom graphics processor chips that can produce transparency, scaling, rotation and window effects in 32768 colors, and finally hardware DMA all take their toll on the host CPU. +

+

+ Enough RAM. Snes9x uses 8MB to load SNES ROM images and several MB for emulating sound, graphics, custom chips, and so on. +

+

+ A 16-bit color (two bytes per pixel) or deeper display, at least 512*478 pixels in resolution. Pixel format conversion may be required before you place the rendered SNES screen on to the display. +

+

+ Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound data to the host sound system. Some ports can use interrupts or callbacks from the sound system to know when more sound data is required, most other ports have to periodically poll the host sound system to see if more data is required; if it is then the sound mixing code is called to fill the sound buffer with SNES sound data, which then can be passed on to the host sound system. Sound data is generated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for 16-bit data. Stereo sound data generates twice as many samples, with each channel's samples interleaved, first left's then right's. +

+

+ For the user to be able to control and play SNES games, some form of input device is required, a joypad or keyboard, for example. The real SNES can have 2 eight-button digital joypads connected to it or 5 joypads when an optional multi-player adaptor is connected, although most games only require a single joypad. Access to all eight buttons and the direction pad, of course, are usually required by most games. Snes9x does emulate the multi-player adaptor hardware, if you were wondering, but its still up to you to provide the emulation of the individual joypads. +

+

+ The real SNES also has a SNES mouse, Super Scope and Justifier (light-gun) available as optional extras. Snes9x can emulate all of these using some form of pointing device, usually the host system's mouse. +

+

+ Some SNES game cartridges contains a small amount of extra RAM and a battery, so ROMs could save a player's progress through a game for games that takes many hours to play from start to finish. Snes9x simulates this S-RAM by saving the contents of the area of memory occupied by the S-RAM into a file then automatically restoring it again the next time the user plays the same game. If the hardware you're porting to doesn't have a storage media available then you could be in trouble. +

+

+ Snes9x also implements freeze-game files which can record the state of the SNES hardware and RAM at a particular point in time and can restore it to that exact state at a later date - the result is that users can save a game at any point, not just at save-game or password points provided by the original game coders. Each freeze file is over 400k in size. To help save disk space, Snes9x can be compiled with zlib (http://www.zlib.net/), which is used to GZIP compress the freeze files, reducing the size to typically below 100k. zlib is also used to load GZIP or ZIP compressed ROM images. Additionally, Snes9x supports JMA archives compressed with NSRT (http://nsrt.edgeemu.com/). +

+

Compile-Time Options

+

DEBUGGER

+

+ Enables extra code to assist you in debugging SNES ROMs. The debugger has only ever been a quick-hack and user-interface to debugger facilities is virtually non-existent. Most of the debugger information is output via stdout and enabling the debugger slows the whole emulator down slightly. However, the debugger options available are very powerful; you could use it to help get your port working. You probably still want to ship the finished version with the debugger disabled, it will only confuse non-technical users. +

+

RIGHTSHIFT_IS_SAR

+

+ Define this if your compiler uses shift right arithmetic for signed values. For example, GCC and Visual C++ use shift right arithmetic. +

+

ZLIB / UNZIP_SUPPORT / JMA_SUPPORT

+

+ Define these if you want to support GZIP/ZIP/JMA compressed ROM images and GZIP compressed freeze-game files. +

+

USE_OPENGL

+

+ Define this and set Settings.OpenGLEnable to true, then you'll get the rendered SNES image as one OpenGL texture. +

+

Typical Options Common for Most Platforms

+

+ ZLIB
+ UNZIP_SUPPORT
+ JMA_SUPPORT
+ RIGHTSHIFT_IS_SAR
+

+

Editing port.h

+

+ You may need to edit port.h to fit Snes9x to your system. +

+

+ If the byte ordering of your system is least significant byte first, make sure LSB_FIRST is defined, otherwise make sure it's not defined. +

+

+ You'll need to make sure what pixel format your system uses for 16-bit colors (RGB565, RGB555, BGR565 or BGR555), and if it's not RGB565, define PIXEL_FORMAT to it so that Snes9x will use it to render the SNES screen. For example, Windows uses RGB565, Mac OS X uses RGB555. If your system supports more than one pixel format, you can define GFX_MULTI_FORMAT and change Snes9x's pixel format dynamically by calling S9xSetRenderPixelFormat function. If your system is 24 or 32-bit only, then don't define anything; instead write a conversion routine that will take a complete rendered 16-bit SNES screen in RGB565 format and convert to the format required to be displayed on your system. +

+

+ port.h also typedefs some types; uint8 for an unsigned 8-bit quantity, uint16 for an unsigned 16-bit quantity, uint32 for a 32-bit unsigned quantity and bool8 for a true/false type. Signed versions are also typedef'ed. +

+

Controllers Management

+

+ Read controls.h, crosshair.h, controls.txt and control-inputs.txt for details. This section is the minimal explanation to get the SNES controls workable. +

+

+ The real SNES allows several different types of devices to be plugged into the game controller ports. The devices Snes9x emulates are a joypad, multi-player adaptor known as the Multi Player 5 or Multi Tap (allowing a further 4 joypads to be plugged in), a 2-button mouse, a light gun known as the Super Scope, and a light gun known as the Justifier. +

+

+ In your initialization code, call S9xUnmapAllControl function. +

+

+ Map any IDs to each SNES controller's buttons and pointers. (ID 249-255 are reserved). +

+

+ Typically, use S9xMapPointer function for the pointer of the SNES mouse, Super Scope and Justifier, S9xMapButton function for other buttons. Set poll to false for the joypad buttons, true for the other buttons and pointers. +

+

+ S9xMapButton(k1P_A_Button, s9xcommand_t cmd = S9xGetCommandT("Joypad1 A"), false); +

+

+ In your main emulation loop, after S9xMainLoop function is called, check your system's keyboard/joypad, and call S9xReportButton function to report the states of the SNES joypad buttons to Snes9x. +

+

+ void MyMainLoop (void)
+ {
+     S9xMainLoop();
+     MyReportButttons();
+ }
+

+

+ void MyReportButtons (void)
+ {
+     S9xReportButton(k1P_A_Button, (key_is_pressed ? true : false));
+ }
+

+

+ Prepare your S9xPollButton and S9xPollPointer function to reply Snes9x's request for other buttons/cursors states. +

+

+ Call S9xSetController function. It connects each input device to each SNES input port.
+ Here's typical controller settings that is used by the real SNES games: +

+

Joypad
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
+

+

Mouse (port 1)
+ S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0);
+ S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
+

+

Mouse (port 2)
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0);
+

+

Super Scope
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0);
+

+

Multi Player 5
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_MP5, 1, 2, 3, 4);
+

+

Justifier
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0);
+

+

Justifier (2 players)
+ S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
+ S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0);
+

+

Existing Interface Functions

+

bool8 Memory.Init (void)

+

+ Allocates and initializes several major lumps of memory, for example the SNES ROM and RAM arrays, tile cache arrays, etc. Returns false if memory allocation fails. +

+

void Memory.Deinit (void)

+

+ Deallocates the memory allocations made by Memory.Init function. +

+

bool8 S9xGraphicsInit (void)

+

+ Allocates and initializes several lookup tables used to speed up SNES graphics rendering. Call after you have initialized the GFX.Screen and GFX.Pitch values. Returns false if memory allocation fails. +

+

void S9xGraphicsDeinit (void)

+

+ Deallocates the memory allocations made by S9xGraphicsInit function. +

+

bool8 S9xInitAPU (void)

+

+ Allocates and initializes several arrays used by the sound CPU and sound generation code. Returns false if memory allocation fails. +

+

void S9xDeinitAPU (void)

+

+ Deallocates the allocations made by S9xInitAPU function. +

+

bool8 S9xInitSound (int buffer_ms, int lag_ms)

+

+ Allocates memory for mixing and queueing SNES sound data, does more sound code initialization and opens the host system's sound device by calling S9xOpenSoundDevice, a function you must provide. Before calling this function you must set up Settings.SoundSync, Settings.SixteenBitSound, Settings.SoundPlaybackRate, Settings.SoundInputRate (see section below) and Settings.Stereo.
+ buffer_ms, given in milliseconds, is the memory buffer size for queueing sound data. lag_ms is allowable latency between when a sample is queued and when it is pulled in S9xMixSamples. Set lag_ms to zero if you have your own latency handling code in your port. +

+

void S9xReset (void)

+

+ Resets the SNES emulated hardware back to the state it was in at “switch-on” except the S-RAM area is preserved (“hardware reset”). The effect is it resets the current game back to the start. This function is automatically called by Memory.LoadROM function. +

+

void S9xSoftReset (void)

+

+ Similar to S9xReset function, but “software reset” as you press the SNES reset button. +

+

bool8 Memory.LoadROM (const char *filepath)

+

+ Attempts to load the specified ROM image filename into the emulated ROM area. There are many different SNES ROM image formats and the code attempts to auto-detect as many different types as it can and in a vast majority of the cases gets it right.
+ There are several ROM image options in the Settingsstructure; allow the user to set them before calling Memory.LoadROM function, or make sure they are all reset to default values before each call to Memory.LoadROM function. See Settings.ForceXXX in snes9x.h. +

+

bool8 Memory.LoadMultiCart (const char *cartApath, const char *cartBpath)

+

+ Attempts to load multiple ROM images into the emulated ROM area, for the multiple cartridge systems such as Sufami Turbo, Same Game, etc. +

+

bool8 Memory.LoadSRAM (const char *filepath)

+

+ Call this function to load the associated S-RAM save file (if any). The filename should be based on the ROM image name to allow easy linkage. The current ports change the directory and the filename extension of the ROM filename to derive the S-RAM filename. +

+

bool8 Memory.SaveSRAM (const char *filepath)

+

+ Call this function to save the emulated S-RAM area into a file so it can be restored again the next time the user wants to play the game. Remember to call this when just before the emulator exits or when the user has been playing a game and is about to load another one. +

+

void S9xMainLoop (void)

+

+ The emulator main loop. Call this from your own main loop that calls this function (if a ROM image is loaded and the game is not paused), processes any pending host system events, then goes back around the loop again until the emulator exits. S9xMainLoop function normally returns control to your main loop once every emulated frame, when it reaches the start of scan-line zero. However it may take a few frames when a huge memory transfer is being emulated. The function can return more often if the DEBUGGER compile-time flag is defined and the CPU has hit a break point, or the DEBUG_MODE_FLAG bit is set in CPU.Flags or instruction single-stepping is enabled. +

+

void S9xMixSamples (uint8 *buffer, int sample_count)

+

+ Call this function from your host sound system handling code to fill buffer with ready-mixed SNES sound data. If 16-bit sound mode is chosen, then the buffer will be filled with an array of sample_count int16, otherwise an array of sample_count uint8. If stereo sound generation is selected the buffer is filled with the same number of samples, but in pairs, first a left channel sample followed by the right channel sample.
+ If there are less queued samples than you request by sample_count, the function fills buffer with silent sound data and returns false. To avoid this shortage of queued samples, request larger buffer size when calling S9xInitSound, and handle sound latency safely. +

+

int S9xGetSampleCount (void)

+

+ Returns the number of sound samples available in the buffer for your configured playback settings. +

+

void S9xSetSamplesAvailableCallback (void (*) samples_available (void *), void *data)

+

+ Call this function to set up a callback that is run when sound samples are made available. samples_available is a function you provide that returns void and takes a pointer as an argument. data is a pointer that you may wish to pass to your callback or can be NULL. If you choose to provide a callback, you must call the provided S9xFinalizeSamples function inside it to actually buffer the samples. If you are using a callback-oriented sound API, it is recommended to set up a function that locks a common mutex during the calls to S9xFinalizeSamples and S9xMixSamples to prevent them from running at the same time and corrupting the sound buffer.
+ If you wish to disable a callback you have set up or need to temporarily shut down your sound system, you may pass NULL for both arguments to revert to the built-in version. +

+

bool8 S9xSyncSound (void)

+

+ Call this function to synchronize the sound buffers to the game state. If Snes9x is generating too much sound data, or a buffer-overrun is likely, this function will return false. In this case, you may wish to wait until your host sound system uses the available samples, and S9xSyncSound returns true before continuing to execute S9xMainLoop. +

+

bool8 S9xSetSoundMute (bool8 mute)

+

+ Call with a true parameter to prevent S9xMixSamples function from processing SNES sample data and instead just filling the return buffer with silent sound data. Useful if your sound system is interrupt or callback driven and the game has been paused either directly or indirectly because the user interacting with the emulator's user interface in some way. +

+

bool8 S9xFreezeGame (const char *filepath)

+

+ Call this function to record the current SNES hardware state into a file, the file can be loaded back using S9xUnfreezeGame function at a later date effectively restoring the current game to exact same spot. Call this function while you're processing any pending system events when S9xMainLoop function has returned control to you in your main loop. +

+

bool8 S9xUnfreezeGame (const char *filepath)

+

+ Restore the SNES hardware back to the exactly the state it was in when S9xFreezeGame function was used to generate the file specified. You have to arrange the correct ROM is already loaded using Memory.LoadROM function, an easy way to arrange this is to base freeze-game filenames on the ROM image name. The UNIX/Linux ports load freeze-game files when the user presses a function key, with the names romfilename.000 for F1, romfilename.001 for F2, etc. Games are frozen in the first place when the user presses Shift-function key. You could choose some other scheme. +

+

void S9xDumpSPCSnapshot (void)

+

+ Call this funtion to make a so-called SPC file, a snapshot of SNES sound state. Actual dump occurs at the first key-on event after this function is called. +

+

void S9xSetInfoString (const char *string)

+

+ Call this function if you want to show a message onto the SNES screen. +

+

Other Available Functions

+

+ See movie.h and movie.cpp to support the Snes9x movie feature.
+ See cheats.h, cheats.cpp and cheats2.cpp to support the cheat feature. +

+

Interface Functions You Need to Implement

+

bool8 S9xOpenSnapshotFile (const char *filepath, bool8 read_only, STREAM *file)

+

+ This function opens a freeze-game file. STREAM is defined as a gzFile if ZLIB is defined else it's defined as FILE *. The read_only parameter is set to true when reading a freeze-game file and false when writing a freeze-game file. Open the file filepath and return its pointer file. +

+

void S9xCloseSnapshotFile (STREAM file)

+

+ This function closes the freeze-game file opened by S9xOpenSnapshotFile function. +

+

void S9xExit (void)

+

+ Called when some fatal error situation arises or when the “q” debugger command is used. +

+

bool8 S9xInitUpdate (void)

+

+ Called just before Snes9x begins to render an SNES screen. Use this function if you should prepare before drawing, otherwise let it empty. +

+

bool8 S9xDeinitUpdate (int width, int height)

+

+ Called once a complete SNES screen has been rendered into the GFX.Screen memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478. +

+

void S9xMessage (int type, int number, const char *message)

+

+ When Snes9x wants to display an error, information or warning message, it calls this function. Check in messages.h for the types and individual message numbers that Snes9x currently passes as parameters.
+ The idea is display the message string so the user can see it, but you choose not to display anything at all, or change the message based on the message number or message type.
+ Eventually all debug output will also go via this function, trace information already does. +

+

bool8 S9xOpenSoundDevice (void)

+

+ S9xInitSound function calls this function to actually open the host sound device. +

+

const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype)

+

+ When Snes9x needs to know the name of the cheat/IPS file and so on, this function is called. Check extension and dirtype, and return the appropriate filename. The current ports return the ROM file path with the given extension. +

+

const char *S9xGetFilenameInc (const char *extension, enum s9x_getdirtype dirtype)

+

+ Almost the same as S9xGetFilename function, but used for saving SPC files etc. So you have to take care not to delete the previously saved file, by increasing the number of the filename; romname.000.spc, romname.001.spc, ... +

+

const char *S9xGetDirectory (enum s9x_getdirtype dirtype)

+

+ Called when Snes9x wants to know the directory dirtype. +

+

const char *S9xChooseFilename (bool8 read_only)

+

+ If your port can match Snes9x's built-in LoadFreezeFile/SaveFreezeFile command (see controls.cpp), you may choose to use this function. Otherwise return NULL. +

+

const char *S9xChooseMovieFilename (bool8 read_only)

+

+ If your port can match Snes9x's built-in BeginRecordingMovie/LoadMovie command (see controls.cpp), you may choose to use this function. Otherwise return NULL. +

+

const char *S9xBasename (const char *path)

+

+ Called when Snes9x wants to know the name of the ROM image. Typically, extract the filename from path and return it. +

+

void S9xAutoSaveSRAM (void)

+

+ If Settings.AutoSaveDelay is not zero, Snes9x calls this function when the contents of the S-RAM has been changed. Typically, call Memory.SaveSRAM function from this function. +

+

void S9xToggleSoundChannel (int c)

+

+ If your port can match Snes9x's built-in SoundChannelXXX command (see controls.cpp), you may choose to use this function. Otherwise return NULL. Basically, turn on/off the sound channel c (0-7), and turn on all channels if c is 8. +

+

void S9xSetPalette (void)

+

+ Called when the SNES color palette has changed. Use this function if your system should change its color palette to match the SNES's. Otherwise let it empty. +

+

void S9xSyncSpeed (void)

+

+ Called at the end of S9xMainLoop function, when emulating one frame has been done. You should adjust the frame rate in this function. +

+

Global Variables

+

uint16 *GFX.Screen

+

+ A uint16 array pointer to (at least) 2*512*478 bytes buffer where Snes9x puts the rendered SNES screen. However, if your port will not support hires mode (Settings.SupportHiRes = false), then a 2*256*239 bytes buffer is allowed. You should allocate the space by yourself. As well you can change the GFX.Screen value after S9xDeinitUpdate function is called so that double-buffering will be easy. +

+

uint32 GFX.Pitch

+

+ Bytes per line (not pixels per line) of the GFX.Screen buffer. Typically set it to 1024. When the SNES screen is 256 pixels width and Settings.OpenGLEnable is false, last half 512 bytes per line are unused. When Settings.OpenGLEnable is true, GFX.Pitch is ignored. +

+

Settings structure

+

+ There are various switches in the Settings structure. See snes9x.h for details. At least the settings below are required for good emulation. +

+

+ memset(&Settings, 0, sizeof(Settings));
+ Settings.MouseMaster = true;
+ Settings.SuperScopeMaster = true;
+ Settings.JustifierMaster = true;
+ Settings.MultiPlayer5Master = true;
+ Settings.FrameTimePAL = 20000;
+ Settings.FrameTimeNTSC = 16667;
+ Settings.SixteenBitSound = true;
+ Settings.Stereo = true;
+ Settings.SoundPlaybackRate = 32000;
+ Settings.SoundInputRate = 32000;
+ Settings.SupportHiRes = true;
+ Settings.Transparency = true;
+ Settings.AutoDisplayMessages = true;
+ Settings.InitialInfoStringTimeout = 120;
+ Settings.HDMATimingHack = 100;
+ Settings.BlockInvalidVRAMAccessMaster = true; +

+

Settings.SoundInputRate

+

+ Adjusts the sound rate through resampling. For every Settings.SoundInputRate samples generated by the SNES, Settings.SoundPlaybackRate samples will be produced.
+ The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure Settings.SoundInputRate to suit their own systems. Setting Settings.SoundInputRate to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the S9xSyncSound function can eliminate sound discontinuity. +

+
+ Updated most recently by: 2011/1/16 zones +
+ + diff --git a/source/docs/portsofsnes9x.txt b/source/docs/portsofsnes9x.txt new file mode 100644 index 0000000..d05365c --- /dev/null +++ b/source/docs/portsofsnes9x.txt @@ -0,0 +1,118 @@ +These are all the known ports of Snes9X to other consoles/handhelds/etc as of +2011/04/24. They are all supported and welcomed on the official Snes9X site. + +**If you know of anyone who is currently working on a port of Snes9X, or if you +have some interest in making a port, please have them go to the Snes9X forums +(http://www.snes9x.com/phpbb2/) and have them register an account there. After +that, speak to Ryan and/or Jerremy so you can be let into the devs area and the +git so you can have access to the most current code, collaborate with the other +developers, make the port officialized, etc.** + +Ports and how to get them running are as follows: + +*PSP Version of Snes9X* +Name: Snes9X Euphoria +Latest version: R5 Beta +Homepage/forum: http://www.retroemu.com/forum/ +Maintainer: Zack + +HOW TO GET IT RUNNING: +*DISCLAIMER* You will have to do some Googling, including but not limited to: +* Downgrading/upgrading your firmware +* Checking if your PSP-2000 series can use Pandora's Battery +* Checking if your PSP-3000 series can use the DaveeFTW Downgrader +* Creating Pandora's Battery +* Finding the hacks, HENs, CFWs, etc and how to use/install them + +1. Make sure your PSP is hackable in some way. This means: +* PSP-1000 series and certain PSP-2000 series can use Pandora Battery +* PSP-2000 series that can't use Pandora Battery, most PSP-3000 series, and PSP +Gos are hackable via other means (DaveeFTW Downgrader, etc) + +2. Make sure your PSP has custom firmware or a HEN that's useable (you'll have +to upgrade/downgrade the firmware as necessary). (Hint: I personally prefer +5.50 GEN-D3 on the Pandora-able PSPs; 6.20 or 6.35 PRO-B4 or better on the +non-Pandora-able PSPs.) + +3. When that’s done, be sure to put the Snes9X Euphoria folder in /PSP/GAME on +your PSP’s memory stick (PSP-1000/2000/3000 series) or internal memory +(PSP Go). Be sure to copy the ROMs into the roms folder, saves (*.srm, etc) +into the saves folder, and cheats into the cheats folder. + +*Wii/Gamecube version of Snes9X* +Name: Snes9X GX +Latest Version: 4.2.7 +Homepage/forum: http://code.google.com/p/snes9x-gx +Maintainer: Tantric + +HOW TO GET IT RUNNING: +*DISCLAIMER* You will have to do some Googling, including but not limited to: +* Finding the latest Homebrew Channel, Snes9X GX Channel, and/or IOS58 +installers and installing them +* Finding a modchip for your GameCube and installing it + +Wii: You will need the latest Homebrew Channel installed on your Wii. After +that, copy and paste the apps folder onto the root of your SD card; same goes +for the snes9xgx folder. After that, copy over any ROMs you have to the +\snes9xgx\roms folder, save files (*.srm, etc) to the \snes9xgx\saves folder, +and cheats to the \snes9xgx\cheats folder. + +In addition, there appears to be a channel for Snes9X GX; you will need the +Homebrew Channel installed and you MUST be on System Menu 4.3 so you can be on +IOS58 (or use the IOS58 installer). After that, you should be able to run the +installer from the Homebrew Channel, and you'll be good to go! + +Gamecube: You might need a modchip. + +*Android and iOS (Apple iPhone/iPod Touch) version of Snes9X* +Name: Snes9X EX +Latest Version: 1.3.23 +Homepage/forum: http://www.explusalpha.com/home/snes9x-ex +Maintainer: Rakashazi (on the Snes9X forums) + +HOW TO GET IT RUNNING: +*DISCLAIMER* You will have to do some Googling, including but not limited to: +* iOS (iPhone/iPod Touch) ONLY!!!: Jailbreaking your firmware + +Android: It appears you can just download from the Android app-store thingy and +run it from there :) Be sure to copy over your ROMs, saves, etc though. + +iOS: You’ll have to jailbreak your firmware and install the Cydia app +installer. Then you’ll have to install the BigBoss repository within Cydia and +search for Snes9X EX; you may also want to search for the sshd and all needed +stuff for that, as it’s the only way you can put the ROMs, saves, etc onto your +iPhone/iPod Touch. After that you should be able to download and run from there +:) + +*PS3 version of Snes9X* +Name: Snes9X PS3 +Latest Version: 4.4.9 +Homepage/forum: https://code.google.com/p/snes9x-ps3/ (although for some +reason, you may have to Google for the latest version) +Maintainer: Squarepusher + +HOW TO GET IT RUNNING: +*DISCLAIMER* You will have to do some Googling, including but not limited to: +* Finding a HEN/Jailbreaker/CFW/etc onto your PS3 and installing it +* (if necessary) Downgrading/Upgrading your PS3's firmware + +You’ll have to install a HEN/Jailbreaker/CFW/etc on your PS3 (you might have to +upgrade or downgrade your PS3’s firmware as needed). After that, it should be +as simple as copy the emulator, ROMs, saves, etc over to the PS3 and it should +work :) + +*X-Box Version of Snes9X* +Name: Snes9xbox +Latest Version: V2 (V3 should be out soon) +Homepage/forum: http://forums.xbox-scene.com/index.php?showforum=96 + +HOW TO GET IT RUNNING: +*DISCLAIMER* You will need to do some Googling, including but not limited to: +* Finding a softmod (hack) or a modchip and installing/using it +* Finding a replacement dashboard such as XBMC + +Really, it's not hard. Read the readme, and use a softmod or modchip and a +replacement dashboard. After that's installed, it should be as simple as +copying over the emulator, ROMs, saves, etc to the X-Box and it should work. + +Updated most recently by: 2011/4/24 adventure_of_link \ No newline at end of file diff --git a/source/docs/snapshots.txt b/source/docs/snapshots.txt new file mode 100644 index 0000000..ef0d1fd --- /dev/null +++ b/source/docs/snapshots.txt @@ -0,0 +1,84 @@ +***** Important notice ******************************************************** + This document describes the snapshot file format for Snes9x 1.52 and later, + not compatible with 1.51. +******************************************************************************* + + Snes9x snapshot file format: (may be gzip-compressed) + + Begins with fixed length signature, consisting of a string, ':', a 4-digit + decimal version, and a '\n'. + +#!s9xsnp:0006 <-- '\n' after the 6 + + Then we have various blocks. The block format is: 3-character block name, + ':', 6-digit length, ':', then the data. Blocks are written in a defined + order. Structs are written packed with their members in a defined order, in + big-endian order where applicable. + +NAM:000019:Chrono Trigger.zip + + Currently defined blocks (in order) are: + + Essential parts: + NAM - ROM filename, from Memory.ROMFilename. 0-terminated string. + CPU - struct SCPUState, CPU internal state variables. + REG - struct SRegisters, emulated CPU registers. + PPU - struct SPPU, PPU internal variables. Note that IPPU is never saved. + DMA - struct SDMA, DMA/HDMA state variables. + VRA - Memory.VRAM, 0x10000 bytes. + RAM - Memory.RAM, 0x20000 bytes (WRAM). + SRA - Memory.SRAM, 0x20000 bytes. + FIL - Memory.FillRAM, 0x8000 bytes (register backing store). + SND - All of sound emulated registers and state valiables. + CTL - struct SControlSnapshot, controller emulation. + TIM - struct STimings, variables about timings between emulated events. + + Optional parts: + SFX - struct FxRegs_s, Super FX. + SA1 - struct SSA1, SA1 internal state variables. + SAR - struct SSA1Registers, SA1 emulated registers. + DP1 - struct SDSP1, DSP-1. + DP2 - struct SDSP2, DSP-2. + DP4 - struct SDSP4, DSP-4. + CX4 - Memory.C4RAM, 0x2000 bytes. + ST0 - struct SST010, ST-010. + OBC - struct SOBC1, OBC1 internal state variables. + OBM - Memory.OBC1RAM, 0x2000 byts. + S71 - struct SSPC7110Snapshot, SPC7110. + SRT - struct SSRTCSnapshot, S-RTC internal state variables. + CLK - struct SRTCData, S-RTC emulated registers. + BSX - struct SBSX, BS-X. + SHO - rendered SNES screen. + MOV - struct SnapshotMovieInfo. + MID - Some block of data the movie subsystem. + +================== + +Without changing the snapshot version number: +--------------------------------------------- + +Blocks may be safely added at the END of the file, as anything after the last +block is ignored. Blocks may not be moved or removed. + +Blocks may not decrease in size. Say you decrease from 10 bytes to 5. Then +later you increase back to 8. The only way you could safely do this is if +bytes 5-7 still mean the same thing they meant when the block was 10 bytes +long. + +Blocks may increase in size as you wish, as long as you can handle old +savestates with the old shorter size. + +Struct members may not change in interpretation. New struct members may be +added (at the END!) only if you can cope with them being binary-0 in older +savestates. Struct members may not be removed or changed in size/type. + +With changing the snapshot version number: +------------------------------------------ + +Blocks may be added, moved, or removed at will. + +Blocks may decrease in size. + +Struct members may be added, moved, or deleted, and their +interpretations/types may be changed. Use the 'debuted_in' and 'deleted_in' +fields to indicate when the new member debuted or the old member went away. diff --git a/source/docs/snes9x-license.txt b/source/docs/snes9x-license.txt new file mode 100644 index 0000000..19d5fd6 --- /dev/null +++ b/source/docs/snes9x-license.txt @@ -0,0 +1,174 @@ + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2004 Matthew Kendora + + (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) + + (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) + + (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), + Kris Bleakley (codeviolation@hotmail.com) + + (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), + Nach (n-a-c-h@users.sourceforge.net), + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2006 - 2007 nitsuja + + (c) Copyright 2009 - 2011 BearOso, + OV2 + + + BS-X C emulator code + (c) Copyright 2005 - 2006 Dreamer Nom, + zones + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), + Nach, + zsKnight (zsknight@zsnes.com) + + C4 C++ code + (c) Copyright 2003 - 2006 Brad Jorsch, + Nach + + DSP-1 emulator code + (c) Copyright 1998 - 2006 _Demo_, + Andreas Naive (andreasnaive@gmail.com), + Gary Henderson, + Ivar (ivar@snes9x.com), + John Weidman, + Kris Bleakley, + Matthew Kendora, + Nach, + neviksti (neviksti@hotmail.com) + + DSP-2 emulator code + (c) Copyright 2003 John Weidman, + Kris Bleakley, + Lord Nightmare (lord_nightmare@users.sourceforge.net), + Matthew Kendora, + neviksti + + DSP-3 emulator code + (c) Copyright 2003 - 2006 John Weidman, + Kris Bleakley, + Lancer, + z80 gaiden + + DSP-4 emulator code + (c) Copyright 2004 - 2006 Dreamer Nom, + John Weidman, + Kris Bleakley, + Nach, + z80 gaiden + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, + pagefault (pagefault@zsnes.com), + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code used in 1.39-1.51 + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, + John Weidman, + Dark Force + + SPC7110 and RTC C++ emulator code used in 1.52+ + (c) Copyright 2009 byuu, + neviksti + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive, + John Weidman + + S-RTC C emulator code + (c) Copyright 2001 - 2006 byuu, + John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, + John Weidman, + Kris Bleakley, + Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 _Demo_, + pagefault, + zsKnight + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, + Gary Henderson, + John Weidman + + Sound emulator code used in 1.5-1.51 + (c) Copyright 1998 - 2003 Brad Martin + (c) Copyright 1998 - 2006 Charles Bilyue' + + Sound emulator code used in 1.52+ + (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + 2xSaI filter + (c) Copyright 1999 - 2001 Derek Liauw Kie Fa + + HQ2x, HQ3x, HQ4x filters + (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) + + NTSC filter + (c) Copyright 2006 - 2007 Shay Green + + GTK+ GUI code + (c) Copyright 2004 - 2011 BearOso + + Win32 GUI code + (c) Copyright 2003 - 2006 blip, + funkyass, + Matthew Kendora, + Nach, + nitsuja + (c) Copyright 2009 - 2011 OV2 + + Mac OS GUI code + (c) Copyright 1998 - 2001 John Stiles + (c) Copyright 2001 - 2011 zones + + + Specific ports contains the works of other authors. See headers in + individual files. + + + Snes9x homepage: http://www.snes9x.com/ + + Permission to use, copy, modify and/or distribute Snes9x in both binary + and source form, for non-commercial purposes, is hereby granted without + fee, providing that this license information and copyright notice appear + with all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software or it's derivatives. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes, + but is not limited to, charging money for Snes9x or software derived from + Snes9x, including Snes9x or derivatives in commercial game bundles, and/or + using Snes9x as a promotion for your commercial product. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. diff --git a/source/docs/snes9x.conf.default b/source/docs/snes9x.conf.default new file mode 100644 index 0000000..4f36d25 --- /dev/null +++ b/source/docs/snes9x.conf.default @@ -0,0 +1,238 @@ +#----------------------------------------- +# snes9x.conf : Snes9x Configuration file +#----------------------------------------- + +[ROM] +# Filename = +LoROM = FALSE +HiROM = FALSE +PAL = FALSE +NTSC = FALSE +# Header = TRUE/FALSE to ForceHeader or ForceNoHeader +# Interleaved = TRUE/FALSE to ForceInterleaved or ForceNoInterleaved +Interleaved2 = FALSE +InterleaveGD24 = FALSE +Cheat = FALSE +Patch = TRUE + +[Sound] +Sync = FALSE +16BitSound = TRUE +Stereo = TRUE +ReverseStereo = FALSE +Rate = 32000 +InputRate = 32000 +Mute = FALSE + +[Display] +HiRes = TRUE +Transparency = TRUE +GraphicWindows = TRUE +DisplayFrameRate = FALSE +DisplayWatchedAddresses = FALSE +DisplayInput = FALSE +DisplayFrameCount = FALSE +MessagesInImage = TRUE +MessageDisplayTime = 120 + +[Settings] +BSXBootup = FALSE +# FrameTime = +FrameSkip = Auto +TurboMode = FALSE +TurboFrameSkip = 15 +MovieTruncateAtEnd = FALSE +MovieNotifyIgnored = FALSE +WrongMovieStateProtection = TRUE +StretchScreenshots = 1 +SnapshotScreenshots = TRUE +DontSaveOopsSnapshot = FALSE +AutoSaveDelay = 0 + +[Controls] +MouseMaster = TRUE +SuperscopeMaster = TRUE +JustifierMaster = TRUE +MP5Master = TRUE +AllowLeftRight = FALSE +Port1 = pad1 +Port2 = none +Mouse1Crosshair = 1 White/Black +Mouse2Crosshair = 1 White/Black +SuperscopeCrosshair = 2 White/Black +Justifier1Crosshair = 4 Blue/Black +Justifier2Crosshair = 4 MagicPink/Black + +[Hack] +EnableGameSpecificHacks = TRUE +AllowInvalidVRAMAccess = FALSE +SpeedHacks = FALSE +HDMATiming = 100 + +[Netplay] +Enable = FALSE +Port = 6096 +Server = "" + +[DEBUG] +Debugger = FALSE +Trace = FALSE + +[Unix] +# BaseDir = ~/.snes9x +# SnapshotFilename = +# PlayMovieFilename = +# RecordMovieFilename = +EnableGamePad = TRUE +PadDevice1 = (null) +PadDevice2 = (null) +PadDevice3 = (null) +PadDevice4 = (null) +PadDevice5 = (null) +PadDevice6 = (null) +PadDevice7 = (null) +PadDevice8 = (null) +ThreadSound = FALSE +SoundBufferSize = 100 +SoundFragmentSize = 2048 +# SoundDevice = +ClearAllControls = FALSE + +[Unix/X11] +SetKeyRepeat = TRUE +VideoMode = 1 + +[Unix/X11 Controls] +J00:Axis1 = Joypad1 Axis Up/Down T=50% +J00:Axis0 = Joypad1 Axis Left/Right T=50% +J00:B1 = Joypad1 A +J00:B2 = Joypad1 B +J00:B0 = Joypad1 X +J00:B3 = Joypad1 Y +J00:B6 = Joypad1 L +J00:B7 = Joypad1 R +J00:B8 = Joypad1 Select +J00:B11 = Joypad1 Start +K00:u = Joypad1 Up +K00:Up = Joypad1 Up +K00:j = Joypad1 Down +K00:n = Joypad1 Down +K00:Down = Joypad1 Down +K00:h = Joypad1 Left +K00:Left = Joypad1 Left +K00:k = Joypad1 Right +K00:Right = Joypad1 Right +K00:d = Joypad1 A +K00:S+d = Joypad1 ToggleTurbo A +K00:C+d = Joypad1 ToggleSticky A +K00:c = Joypad1 B +K00:S+c = Joypad1 ToggleTurbo B +K00:C+c = Joypad1 ToggleSticky B +K00:s = Joypad1 X +K00:S+s = Joypad1 ToggleTurbo X +K00:C+s = Joypad1 ToggleSticky X +K00:x = Joypad1 Y +K00:S+x = Joypad1 ToggleTurbo Y +K00:C+x = Joypad1 ToggleSticky Y +K00:a = Joypad1 L +K00:v = Joypad1 L +K00:S+a = Joypad1 ToggleTurbo L +K00:S+v = Joypad1 ToggleTurbo L +K00:C+a = Joypad1 ToggleSticky L +K00:C+v = Joypad1 ToggleSticky L +K00:z = Joypad1 R +K00:S+z = Joypad1 ToggleTurbo R +K00:C+z = Joypad1 ToggleSticky R +K00:space = Joypad1 Select +K00:Return = Joypad1 Start +K00:KP_Up = Joypad2 Up +K00:KP_Down = Joypad2 Down +K00:KP_Left = Joypad2 Left +K00:KP_Right = Joypad2 Right +K00:Prior = Joypad2 A +K00:Next = Joypad2 B +K00:Home = Joypad2 X +K00:End = Joypad2 Y +K00:Insert = Joypad2 L +K00:Delete = Joypad2 R +K00:KP_Add = Joypad2 Select +K00:KP_Enter = Joypad2 Start +K00:Escape = ExitEmu +K00:Pause = Pause +K00:Scroll_Lock = Pause +K00:CS+Escape = Reset +K00:S+Escape = SoftReset +K00:F12 = SaveFreezeFile +K00:A+F3 = SaveFreezeFile +K00:C+F3 = SaveFreezeFile +K00:F11 = LoadFreezeFile +K00:A+F2 = LoadFreezeFile +K00:C+F2 = LoadFreezeFile +K00:S+F1 = QuickSave000 +K00:S+F2 = QuickSave001 +K00:S+F3 = QuickSave002 +K00:S+F4 = QuickSave003 +K00:S+F5 = QuickSave004 +K00:S+F6 = QuickSave005 +K00:S+F7 = QuickSave006 +K00:S+F8 = QuickSave007 +K00:S+F9 = QuickSave008 +K00:F1 = QuickLoad000 +K00:F2 = QuickLoad001 +K00:F3 = QuickLoad002 +K00:F4 = QuickLoad003 +K00:F5 = QuickLoad004 +K00:F6 = QuickLoad005 +K00:F7 = QuickLoad006 +K00:F8 = QuickLoad007 +K00:F9 = QuickLoad008 +K00:F10 = LoadOopsFile +K00:A+F1 = SaveSPC +K00:C+F1 = SaveSPC +K00:Print = Screenshot +K00:S+1 = BeginRecordingMovie +K00:S+2 = EndRecordingMovie +K00:S+3 = LoadMovie +K00:Tab = EmuTurbo +K00:S+Tab = ToggleEmuTurbo +K00:equal = IncFrameRate +K00:minus = DecFrameRate +K00:S+equal = IncFrameTime +K00:S+minus = DecFrameTime +K00:A+equal = IncEmuTurbo +K00:A+minus = DecEmuTurbo +K00:C+equal = IncTurboSpeed +K00:C+minus = DecTurboSpeed +K00:6 = SwapJoypads +K00:A+F4 = SoundChannel0 +K00:C+F4 = SoundChannel0 +K00:A+F5 = SoundChannel1 +K00:C+F5 = SoundChannel1 +K00:A+F6 = SoundChannel2 +K00:C+F6 = SoundChannel2 +K00:A+F7 = SoundChannel3 +K00:C+F7 = SoundChannel3 +K00:A+F8 = SoundChannel4 +K00:C+F8 = SoundChannel4 +K00:A+F9 = SoundChannel5 +K00:C+F9 = SoundChannel5 +K00:A+F10 = SoundChannel6 +K00:C+F10 = SoundChannel6 +K00:A+F11 = SoundChannel7 +K00:C+F11 = SoundChannel7 +K00:A+F12 = SoundChannelsOn +K00:C+F12 = SoundChannelsOn +K00:1 = ToggleBG0 +K00:2 = ToggleBG1 +K00:3 = ToggleBG2 +K00:4 = ToggleBG3 +K00:5 = ToggleSprites +K00:9 = ToggleTransparency +K00:BackSpace = ClipWindows +K00:A+Escape = Debugger +M00:Pointer = Pointer Mouse1+Superscope+Justifier1 +M00:B0 = {Mouse1 L,Superscope Fire,Justifier1 Trigger} +M00:B2 = {Mouse1 R,Superscope Cursor,Justifier1 Start} +M00:B1 = {Justifier1 AimOffscreen Trigger,Superscope AimOffscreen} +K00:grave = Superscope ToggleTurbo +K00:slash = Superscope Pause -- cgit v1.2.3 From 83b449ed11a4a0fd7b97f02f4d3d0a03419a6804 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 17 Dec 2012 21:05:08 -0500 Subject: Remove more build stuff. --- source/autom4te.cache/output.0 | 0 source/autom4te.cache/requests | 67 ------------------------------------------ source/autom4te.cache/traces.0 | 0 3 files changed, 67 deletions(-) delete mode 100644 source/autom4te.cache/output.0 delete mode 100644 source/autom4te.cache/requests delete mode 100644 source/autom4te.cache/traces.0 (limited to 'source') diff --git a/source/autom4te.cache/output.0 b/source/autom4te.cache/output.0 deleted file mode 100644 index e69de29..0000000 diff --git a/source/autom4te.cache/requests b/source/autom4te.cache/requests deleted file mode 100644 index bec4e12..0000000 --- a/source/autom4te.cache/requests +++ /dev/null @@ -1,67 +0,0 @@ -# This file was generated by Autom4te Tue Dec 22 07:01:21 UTC 2009. -# It contains the lists of macros which have been traced. -# It can be safely removed. - -@request = ( - bless( [ - '0', - 1, - [ - '/usr/share/autoconf' - ], - [ - '/usr/share/autoconf/autoconf/autoconf.m4f', - 'Makefile.in' - ], - { - '_LT_AC_TAGCONFIG' => 1, - 'AM_PROG_F77_C_O' => 1, - 'AC_INIT' => 1, - 'm4_pattern_forbid' => 1, - '_AM_COND_IF' => 1, - 'AC_CANONICAL_TARGET' => 1, - 'AC_SUBST' => 1, - 'AC_CONFIG_LIBOBJ_DIR' => 1, - 'AC_FC_SRCEXT' => 1, - 'AC_CANONICAL_HOST' => 1, - 'AC_PROG_LIBTOOL' => 1, - 'AM_INIT_AUTOMAKE' => 1, - 'AC_CONFIG_SUBDIRS' => 1, - 'AM_AUTOMAKE_VERSION' => 1, - 'LT_CONFIG_LTDL_DIR' => 1, - 'AC_REQUIRE_AUX_FILE' => 1, - 'AC_CONFIG_LINKS' => 1, - 'm4_sinclude' => 1, - 'LT_SUPPORTED_TAG' => 1, - 'AM_MAINTAINER_MODE' => 1, - 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1, - '_m4_warn' => 1, - 'AM_PROG_CXX_C_O' => 1, - '_AM_COND_ENDIF' => 1, - 'AM_ENABLE_MULTILIB' => 1, - 'AM_SILENT_RULES' => 1, - 'AC_CONFIG_FILES' => 1, - 'include' => 1, - 'LT_INIT' => 1, - 'AM_GNU_GETTEXT' => 1, - 'AC_LIBSOURCE' => 1, - 'AM_PROG_FC_C_O' => 1, - 'AC_CANONICAL_BUILD' => 1, - 'AC_FC_FREEFORM' => 1, - 'AH_OUTPUT' => 1, - '_AM_SUBST_NOTMAKE' => 1, - 'AC_CONFIG_AUX_DIR' => 1, - 'sinclude' => 1, - 'm4_pattern_allow' => 1, - 'AM_PROG_CC_C_O' => 1, - 'AC_CANONICAL_SYSTEM' => 1, - 'AM_CONDITIONAL' => 1, - 'AC_CONFIG_HEADERS' => 1, - 'AC_DEFINE_TRACE_LITERAL' => 1, - 'm4_include' => 1, - '_AM_COND_ELSE' => 1, - 'AC_SUBST_TRACE' => 1 - } - ], 'Autom4te::Request' ) - ); - diff --git a/source/autom4te.cache/traces.0 b/source/autom4te.cache/traces.0 deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3 From b935574e53ce56cc89691bfaff1905b0d1207739 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 17 Dec 2012 22:42:09 -0500 Subject: Remove more unneeded files. --- source/snes9x.cpp | 808 --------------------------------------------------- source/sound.cpp | 279 ------------------ source/spc.cpp | 133 --------- source/spccycles.cpp | 110 ------- source/spctool.cpp | 201 ------------- 5 files changed, 1531 deletions(-) delete mode 100644 source/snes9x.cpp delete mode 100644 source/sound.cpp delete mode 100644 source/spc.cpp delete mode 100644 source/spccycles.cpp delete mode 100644 source/spctool.cpp (limited to 'source') diff --git a/source/snes9x.cpp b/source/snes9x.cpp deleted file mode 100644 index fd0ee0e..0000000 --- a/source/snes9x.cpp +++ /dev/null @@ -1,808 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ -#include -#include -#ifdef HAVE_STRINGS_H -#include -#endif - -#include "snes9x.h" -#include "memmap.h" -#include "display.h" -#include "cheats.h" - -#ifdef DEBUGGER -extern FILE *trace; -#endif - -void S9xUsage () -{ - S9xMessage (S9X_INFO, S9X_USAGE, "snes9x: S9xUsage: snes9x \n\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "Where can be:\n"); - - S9xMessage (S9X_INFO, S9X_USAGE, "\ --cycles or -h Percentage of CPU cycles to execute every scan line (default 90)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --frameskip or -f Screen update frame skip rate (default 2)\n"); - S9xExtraUsage (); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --hirom or -fh or -hr Force Hi-ROM memory map, useful for hacked ROM images.\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --lorom or -fl or -lr Force Lo-ROM memory map, useful for hacked ROM images.\n"); - //FIXME: -old bsolete? - S9xMessage (S9X_INFO, S9X_USAGE, "\ --old or -o Enable old-style SNES joypad emulation\n"); - //FIXME: -noold obsolete? - S9xMessage (S9X_INFO, S9X_USAGE, "\ --noold or -no Disbale old-style SNES joypad emulation\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --soundskip or -ss Sound CPU skip-waiting method, 0 - 3 (default 0)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --sound or -s Enable digital sound output (default: enabled)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nosound or -ns Disable digital sound output\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --soundquality or -r Sound sample playback rate/quality, 0-7 (default 4)\n"); - -#ifdef __sgi -/* BS: changed the sample rate values to match the IRIX options */ - S9xMessage (S9X_INFO, S9X_USAGE, "\ - 0 - off, 1 - 8192, 2 - 11025, 3 - 16000,\n\ - 4 - 22050 (default), 5 - 32000, 6 - 44100,\n\ - 7 - 48000\n"); -#else - S9xMessage (S9X_INFO, S9X_USAGE, "\ - 0 - off, 1 - 8192, 2 - 11025, 3 - 16500,\n\ - 4 - 22050 (default), 5 - 29300, 6 - 36600,\n\ - 7 - 44000\n"); -#endif - - S9xMessage (S9X_INFO, S9X_USAGE, "\ --stereo Enable stereo sound (default: mono sound)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --mono Enable mono sound (default: mono sound)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --buffersize or -B Sound playback buffer size (default auto for playback rate)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nospeedhacks or -N Disable some internal speed ups that break a few ROMs\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --speedhacks or -SH Enable some internal speed ups that break a few ROMs\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --loadsnapshot or -l \n\ - Load saved game position snapshot file & required ROM\n\ - image.\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --swapjoypads or -s Swap joypad 1 and 2 around\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --pal or -p Fool ROM into thinking that this is a PAL SNES system\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --ntsc or -n Fool ROM into thinking that this is a NTCS SNES system\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --interleaved or -i ROM image is in interleaved format.\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --interleaved2 or -i2 ROM image is in interleaved 2 format\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --interleavedgd24 or -gd24 ROM image is in Game Doctor 24 Mbit format\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nohdma or -H Disable H-DMA emulation (default: enabled)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --hdma or -NH Enable H-DMA emulation (default: enabled)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --layering or -L Swap some background priority levels - helps some games\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --graphicwindows Enable graphic window effects (default: enabled)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nographicwindows or -nw Disable graphic window effects (default: enabled)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nopatch Disable IPS autopatching\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nocheat Disable the cheat system\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --cheat Enables the cheat system\n"); -#ifdef DEBUGGER - S9xMessage (S9X_INFO, S9X_USAGE, "\ --noirq or -I Disable processor IRQ (for debugging)\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --debug or -d Enter debug mode once ROM has loaded\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --trace or -t Trace CPU instructions to file (WARNING: file gets very large!)\n"); -#endif - -#ifdef JOYSTICK_SUPPORT -#ifdef __linux - S9xMessage (S9X_INFO, S9X_USAGE, "\ --joydevX /dev/jsY Use joystick device /dev/jsY for emulation of gamepad X\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --joymapX 0 1 2 3 4 5 6 7 Joystick buttons which should be assigned to gamepad X - A B X Y TL TR Start and Select\n"); -#else - S9xMessage (S9X_INFO, S9X_USAGE, "\ --four or -4 Single standard PC joystick has four buttons\n"); - S9xMessage (S9X_INFO, S9X_USAGE, "\ --six or -6 Single standard PC joystick has six buttons\n"); -#endif - S9xMessage (S9X_INFO, S9X_USAGE, "\ --nojoy or -j Disable joystick support\n"); -#endif - - S9xMessage (S9X_INFO, S9X_USAGE, "\ -\nROM image needs to be in Super MagiCom (*.smc), Super FamiCom (*.sfc),\n\ -*.fig, or split (*.1, *.2, or sf32527a, sf32527b, etc) format and can be\n\ -compressed with gzip or compress.\n"); - - exit (1); -} - -#ifdef STORM -extern int dofps; -extern int hicolor; -extern int secondjoy; -extern int minimal; -int prelude=0; -extern int unit; -#endif - -char *S9xParseArgs (char **argv, int argc) -{ - char *rom_filename = NULL; - - for (int i = 1; i < argc; i++) - { - if (*argv[i] == '-') - { - if (strcasecmp (argv [i], "--selftest") == 0) - { - // FIXME: Probable missuse of S9X_USAGE - // FIXME: Actual tests. But at least this checks for coredumps. - S9xMessage (S9X_INFO, S9X_USAGE, "Running selftest ..."); - S9xMessage (S9X_INFO, S9X_USAGE, "snes9x started:\t[OK]"); - S9xMessage (S9X_INFO, S9X_USAGE, "All tests ok."); - exit(0); - } - if (strcasecmp (argv [i], "-so") == 0 || - strcasecmp (argv [i], "-sound") == 0) - { - Settings.NextAPUEnabled = TRUE; - } - else if (strcasecmp (argv [i], "-ns") == 0 || - strcasecmp (argv [i], "-nosound") == 0) - { - Settings.NextAPUEnabled = FALSE; - } - else if (strcasecmp (argv [i], "-soundskip") == 0 || - strcasecmp (argv [i], "-sk") == 0) - { - if (i + 1 < argc) - Settings.SoundSkipMethod = atoi (argv [++i]); - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-ra") == 0 || - strcasecmp (argv [i], "-ratio") == 0) - { - if ((i + 1) < argc) - { - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-h") == 0 || - strcasecmp (argv [i], "-cycles") == 0) - { - if (i + 1 < argc) - { - int p = atoi (argv [++i]); - if (p > 0 && p < 200) - Settings.CyclesPercentage = p; - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-nh") == 0 || - strcasecmp (argv [i], "-nohdma") == 0) - { - Settings.DisableHDMA = TRUE; - } - else if (strcasecmp (argv [i], "-ha") == 0 || - strcasecmp (argv [i], "-hdma") == 0) - { - Settings.DisableHDMA = FALSE; - } - else if (strcasecmp (argv [i], "-n") == 0 || - strcasecmp (argv [i], "-nospeedhacks") == 0) - { - Settings.ShutdownMaster = FALSE; - } - else if (strcasecmp (argv [i], "-sh") == 0 || - strcasecmp (argv [i], "-speedhacks") == 0) - { - Settings.ShutdownMaster = TRUE; - } - else if (strcasecmp (argv [i], "-p") == 0 || - strcasecmp (argv [i], "-pal") == 0) - { - Settings.ForcePAL = TRUE; - } - else if (strcasecmp (argv [i], "-n") == 0 || - strcasecmp (argv [i], "-ntsc") == 0) - { - Settings.ForceNTSC = TRUE; - } - else if (strcasecmp (argv [i], "-f") == 0 || - strcasecmp (argv [i], "-frameskip") == 0) - { - if (i + 1 < argc) - Settings.SkipFrames = atoi (argv [++i]) + 1; - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-fh") == 0 || - strcasecmp (argv [i], "-hr") == 0 || - strcasecmp (argv [i], "-hirom") == 0) - Settings.ForceHiROM = TRUE; - else if (strcasecmp (argv [i], "-fl") == 0 || - strcasecmp (argv [i], "-lr") == 0 || - strcasecmp (argv [i], "-lorom") == 0) - Settings.ForceLoROM = TRUE; - else if (strcasecmp (argv [i], "-hd") == 0 || - strcasecmp (argv [i], "-header") == 0 || - strcasecmp (argv [i], "-he") == 0) - { - Settings.ForceHeader = TRUE; - } - else if (strcasecmp (argv [i], "-nhd") == 0 || - strcasecmp (argv [i], "-noheader") == 0) - { - Settings.ForceNoHeader = TRUE; - } - else if (strcasecmp (argv [i], "-bs") == 0) - { - Settings.BS = TRUE; - } -#ifdef DEBUGGER - else if (strcasecmp (argv [i], "-d") == 0 || - strcasecmp (argv [i], "-debug") == 0) - { - CPU.Flags |= DEBUG_MODE_FLAG; - } - else if (strcasecmp (argv [i], "-t") == 0 || - strcasecmp (argv [i], "-trace") == 0) - { - trace = fopen ("trace.log", "wb"); - CPU.Flags |= TRACE_FLAG; - } -#endif - else if (strcasecmp (argv [i], "-L") == 0 || - strcasecmp (argv [i], "-layering") == 0) - Settings.BGLayering = TRUE; - else if (strcasecmp (argv [i], "-nl") == 0 || - strcasecmp (argv [i], "-nolayering") == 0) - Settings.BGLayering = FALSE; - else if (strcasecmp (argv [i], "-O") == 0 || - strcasecmp (argv [i], "-tileredraw") == 0) - { - } - else if (strcasecmp (argv [i], "-no") == 0 || - strcasecmp (argv [i], "-lineredraw") == 0) - { - } - else if (strcasecmp (argv [i], "-tr") == 0 || - strcasecmp (argv [i], "-transparency") == 0) - { - Settings.ForceTransparency = TRUE; - Settings.ForceNoTransparency = FALSE; - } - else if (strcasecmp (argv [i], "-nt") == 0 || - strcasecmp (argv [i], "-notransparency") == 0) - { - Settings.ForceNoTransparency = TRUE; - Settings.ForceTransparency = FALSE; - } - else if (strcasecmp (argv [i], "-hi") == 0 || - strcasecmp (argv [i], "-hires") == 0) - { - Settings.SupportHiRes = TRUE; - } - else if (strcasecmp (argv [i], "-16") == 0 || - strcasecmp (argv [i], "-sixteen") == 0) - { - Settings.SixteenBit = TRUE; - } - else if (strcasecmp (argv [i], "-displayframerate") == 0 || - strcasecmp (argv [i], "-dfr") == 0) - { - Settings.DisplayFrameRate = TRUE; - } - else if (strcasecmp (argv [i], "-s") == 0 || - strcasecmp (argv [i], "-swapjoypads") == 0 || - strcasecmp (argv [i], "-sw") == 0) - Settings.SwapJoypads = TRUE; - else if (strcasecmp (argv [i], "-i") == 0 || - strcasecmp (argv [i], "-interleaved") == 0) - Settings.ForceInterleaved = TRUE; - else if (strcasecmp (argv [i], "-i2") == 0 || - strcasecmp (argv [i], "-interleaved2") == 0) - Settings.ForceInterleaved2=TRUE; - else if (strcasecmp (argv [i], "-gd24") == 0 || - strcasecmp (argv [i], "-interleavedgd24") == 0) - Settings.ForceInterleaveGD24 = TRUE; - else if (strcasecmp (argv [i], "-ni") == 0 || - strcasecmp (argv [i], "-nointerleave") == 0) - Settings.ForceNotInterleaved = TRUE; - else if (strcasecmp (argv [i], "-noirq") == 0) - Settings.DisableIRQ = TRUE; - else if (strcasecmp (argv [i], "-nw") == 0 || - strcasecmp (argv [i], "-nowindows") == 0) - { - Settings.DisableGraphicWindows = TRUE; - } - else if (strcasecmp (argv [i], "-nopatch") == 0) - { - Settings.NoPatch=TRUE; - } - else if (strcasecmp (argv [i], "-nocheat") == 0) - { - Settings.ApplyCheats=FALSE; - } - else if (strcasecmp (argv [i], "-cheat") == 0) - { - Settings.ApplyCheats=TRUE; - } - else if (strcasecmp (argv [i], "-windows") == 0) - { - Settings.DisableGraphicWindows = FALSE; - } - else if (strcasecmp (argv [i], "-aidoshm") == 0) - { - if (i + 1 < argc) - { - Settings.AIDOShmId = atoi (argv [++i]); - fprintf(stderr, "Snes9X running in AIDO mode. shmid: %d\n", - Settings.AIDOShmId); - } else - S9xUsage (); - } -#ifdef DEBUG_MAXCOUNT - else if (strcasecmp (argv [i], "-maxcount") == 0) - { - if (i + 1 < argc) - { - Settings.MaxCount = atol (argv [++i]); - fprintf(stderr, "Running for a maximum of %d loops.\n", - Settings.MaxCount); - } else - S9xUsage (); - } -#endif - else if (strcasecmp (argv [i], "-im7") == 0) - { - Settings.Mode7Interpolate = TRUE; - } - else if (strcasecmp (argv [i], "-gg") == 0 || - strcasecmp (argv [i], "-gamegenie") == 0) - { - if (i + 1 < argc) - { - uint32 address; - uint8 byte; - const char *error; - if ((error = S9xGameGenieToRaw (argv [++i], address, byte)) == NULL) - S9xAddCheat (TRUE, FALSE, address, byte); - else - S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, - error); - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-ar") == 0 || - strcasecmp (argv [i], "-actionreplay") == 0) - { - if (i + 1 < argc) - { - uint32 address; - uint8 byte; - const char *error; - if ((error = S9xProActionReplayToRaw (argv [++i], address, byte)) == NULL) - S9xAddCheat (TRUE, FALSE, address, byte); - else - S9xMessage (S9X_ERROR, S9X_ACTION_REPLY_CODE_ERROR, - error); - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-gf") == 0 || - strcasecmp (argv [i], "-goldfinger") == 0) - { - if (i + 1 < argc) - { - uint32 address; - uint8 bytes [3]; - bool8 sram; - uint8 num_bytes; - const char *error; - if ((error = S9xGoldFingerToRaw (argv [++i], address, sram, - num_bytes, bytes)) == NULL) - { - for (int c = 0; c < num_bytes; c++) - S9xAddCheat (TRUE, FALSE, address + c, bytes [c]); - } - else - S9xMessage (S9X_ERROR, S9X_GOLD_FINGER_CODE_ERROR, - error); - } - else - S9xUsage (); - } - else if (strcasecmp (argv[i], "-ft") == 0 || - strcasecmp (argv [i], "-frametime") == 0) - { - if (i + 1 < argc) - { - double ft; - if (sscanf (argv [++i], "%lf", &ft) == 1) - { -#ifdef __WIN32__ - Settings.FrameTimePAL = (int32) (ft * 1000); - Settings.FrameTimeNTSC = (int32) (ft * 1000); -#else - Settings.FrameTimePAL = (int32) ft; - Settings.FrameTimeNTSC = (int32) ft; -#endif - - } - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-e") == 0 || - strcasecmp (argv [i], "-echo") == 0) - Settings.DisableSoundEcho = FALSE; - else if (strcasecmp (argv [i], "-ne") == 0 || - strcasecmp (argv [i], "-noecho") == 0) - Settings.DisableSoundEcho = TRUE; - else if (strcasecmp (argv [i], "-r") == 0 || - strcasecmp (argv [i], "-soundquality") == 0 || - strcasecmp (argv [i], "-sq") == 0) - { - if (i + 1 < argc) - Settings.SoundPlaybackRate = atoi (argv [++i]) & 7; - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-stereo") == 0 || - strcasecmp (argv [i], "-st") == 0) - { - Settings.Stereo = TRUE; - Settings.APUEnabled = TRUE; - Settings.NextAPUEnabled = TRUE; - } - else if (strcasecmp (argv [i], "-mono") == 0) - { - Settings.Stereo = FALSE; - Settings.NextAPUEnabled = TRUE; - } - else if (strcasecmp (argv [i], "-envx") == 0 || - strcasecmp (argv [i], "-ex") == 0) - { - Settings.SoundEnvelopeHeightReading = TRUE; - } - else if (strcasecmp (argv [i], "-nosamplecaching") == 0 || - strcasecmp (argv [i], "-nsc") == 0 || - strcasecmp (argv [i], "-nc") == 0) - { - Settings.DisableSampleCaching = TRUE; - } - else if (strcasecmp (argv [i], "-nomastervolume") == 0 || - strcasecmp (argv [i], "-nmv") == 0) - { - Settings.DisableMasterVolume = TRUE; - } - else if (strcasecmp (argv [i], "-soundsync") == 0 || - strcasecmp (argv [i], "-sy") == 0) - { - Settings.SoundSync = TRUE; - Settings.SoundEnvelopeHeightReading = TRUE; - Settings.InterpolatedSound = TRUE; - } - else if (strcasecmp (argv [i], "-soundsync2") == 0 || - strcasecmp (argv [i], "-sy2") == 0) - { - Settings.SoundSync = 2; - Settings.SoundEnvelopeHeightReading = TRUE; - Settings.InterpolatedSound = TRUE; - } - else if (strcasecmp (argv [i], "-interpolatedsound") == 0 || - strcasecmp (argv [i], "-is") == 0) - { - Settings.InterpolatedSound = TRUE; - } -#ifdef USE_THREADS - else if (strcasecmp (argv [i], "-threadsound") == 0 || - strcasecmp (argv [i], "-ts") == 0) - { - Settings.ThreadSound = TRUE; - } -#endif - else if (strcasecmp (argv [i], "-alt") == 0 || - strcasecmp (argv [i], "-altsampledecode") == 0) - { - Settings.AltSampleDecode = 1; - } - else if (strcasecmp (argv [i], "-fix") == 0) - { - Settings.FixFrequency = 1; - } - else if (strcasecmp (argv [i], "-nosuperfx") == 0 || - strcasecmp (argv [i], "-nosfx") == 0) - Settings.ForceNoSuperFX = TRUE; - else if (strcasecmp (argv [i], "-superfx") == 0 || - strcasecmp (argv [i], "-sfx") == 0) - Settings.ForceSuperFX = TRUE; - else if (strcasecmp (argv [i], "-dsp1") == 0) - Settings.ForceDSP1 = TRUE; - else if (strcasecmp (argv [i], "-nodsp1") == 0) - Settings.ForceNoDSP1 = TRUE; - else if (strcasecmp (argv [i], "-nomultiplayer5") == 0 || - strcasecmp (argv [i], "-nmp") == 0) - Settings.MultiPlayer5 = FALSE; - else if (strcasecmp (argv [i], "-multiplayer5") == 0 || - strcasecmp (argv [i], "-mp") == 0) - { - Settings.MultiPlayer5 = TRUE; - Settings.ControllerOption = SNES_MULTIPLAYER5; - } - else if (strcasecmp (argv [i], "-mouse") == 0 || - strcasecmp (argv [i], "-mo") == 0) - { - Settings.ControllerOption = SNES_MOUSE_SWAPPED; - Settings.Mouse = TRUE; - } - else if (strcasecmp (argv [i], "-nomouse") == 0 || - strcasecmp (argv [i], "-nm") == 0) - { - Settings.Mouse = FALSE; - } - else if (strcasecmp (argv [i], "-superscope") == 0 || - strcasecmp (argv [i], "-ss") == 0) - { - Settings.SuperScope = TRUE; - Settings.ControllerOption = SNES_SUPERSCOPE; - } - else if (strcasecmp (argv [i], "-nosuperscope") == 0 || - strcasecmp (argv [i], "-nss") == 0) - { - Settings.SuperScope = FALSE; - } -#ifdef NETPLAY_SUPPORT - else if (strcasecmp (argv [i], "-port") == 0 || - strcasecmp (argv [i], "-po") == 0) - { - if (i + 1 < argc) - { - Settings.NetPlay = TRUE; - Settings.Port = -atoi (argv [++i]); - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-server") == 0 || - strcasecmp (argv [i], "-srv") == 0) - { - if (i + 1 < argc) - { - Settings.NetPlay = TRUE; - strncpy (Settings.ServerName, argv [++i], 127); - Settings.ServerName [127] = 0; - } - else - S9xUsage (); - } - else if (strcasecmp (argv [i], "-net") == 0) - { - Settings.NetPlay = TRUE; - } -#endif -#ifdef STORM - else if (strcasecmp(argv[i],"-nosecondjoy")==0){secondjoy=0;} - else if (strcasecmp(argv[i],"-showfps")==0){dofps=1;} - else if (strcasecmp(argv[i],"-hicolor")==0){hicolor=1;} - else if (strcasecmp(argv[i],"-minimal")==0){minimal=1;printf("Keyboard with exception of ESC switched off!\n");} - else if (strcasecmp(argv[i],"-ahiunit")==0) - { - if (i+1 -#include -#include -#include -#include -#include -#include - -#define EQ == -#define MINBUFFLEN 10000 - -#include -#include -#include -#include -#include - -#include "snes9x.h" -#include "soundux.h" - -extern SoundStatus so; - -extern int AudioOpen(unsigned long freq, unsigned long bufsize, unsigned long bitrate, unsigned long stereo); -extern void AudioClose(void); - -extern int OpenPrelude(ULONG Type, ULONG DefaultFreq, ULONG MinBuffSize); -extern void ClosePrelude(void); - -extern int SoundSignal; -unsigned long DoubleBuffer; -//extern struct AHISampleInfo Sample0; -//extern struct AHISampleInfo Sample1; -//extern unsigned long BufferSize; - -struct Library *AHIPPCBase; -struct Library *AHIBase; -struct MsgPort *AHImp=NULL; -struct AHIRequest *AHIio=NULL; -BYTE AHIDevice=-1; - -struct AHIData *AHIData; - -unsigned long Frequency = 0; -//unsigned long BufferSize = 0; -unsigned long BitRate = 0; -unsigned long Stereo = 0; -//unsigned long AHIError = 9; - -BYTE InternSignal=-1; - -int mixsamples; -extern int prelude; - -#define REALSIZE (BitRate*Stereo) - -struct AHIAudioModeRequester *req=NULL; -struct AHIAudioCtrl *actrl=NULL; - -ULONG BufferLen=NULL; - - -/* this really should be dynamically allocated... */ -#undef MAX_BUFFER_SIZE -#define MAX_BUFFER_SIZE 65536 -#define MIN_BUFFER_SIZE 65536 - -#define MODE_MONO 0 -#define MODE_STEREO 1 - -#define QUAL_8BIT 8 -#define QUAL_16BIT 16 - - -int test=0; -int test2=0; - -int AudioOpen(unsigned long freq, unsigned long minbufsize, unsigned long bitrate, unsigned long stereo) -{ - ULONG Type; - - Frequency = freq; - - so.playback_rate = Frequency; - - if(stereo) so.stereo = TRUE; - else so.stereo = FALSE; - - switch(bitrate) - { - case 8: - so.sixteen_bit = FALSE; - BitRate=1; - if(stereo) - { - Stereo=2; - Type = AHIST_S8S; - } - else - { - Stereo=1; - Type = AHIST_M8S; - } - - break; - - default: //defaulting to 16bit, because it means it won't crash atleast - case QUAL_16BIT: - so.sixteen_bit = TRUE; - BitRate=2; - if(stereo) - { - Stereo=2; - Type = AHIST_S16S; - } - else - { - Stereo=1; - Type = AHIST_M16S; - } - break; - } - - if(prelude) prelude = OpenPrelude(Type, freq, minbufsize); - - - if(prelude) return 1; else printf("Defaulting to AHI...\n"); - - /* only 1 channel right? */ - /* NOTE: The buffersize will not always be what you requested - * it finds the minimun AHI requires and then rounds it up to - * nearest 32 bytes. Check AHIData->BufferSize or Samples[n].something_Length - */ - if(AHIData = OpenAHI(1, Type, AHI_INVALID_ID, AHI_DEFAULT_FREQ, 0, minbufsize)) - { - printf("AHI opened\n"); - printf("BuffSize %d\n", AHIData->BufferSize); - } - else - { - printf("AHI failed to open: %d\n", AHIData); - return 0; - } - - so.buffer_size = AHIData->BufferSize; // in bytes - if (so.buffer_size > MAX_BUFFER_SIZE) so.buffer_size = MAX_BUFFER_SIZE; - - /* Lots of useful fields in the AHIData struct, have a look */ - AHIBase = AHIData->AHIBase; - actrl = AHIData->AudioCtrl; - Frequency = AHIData->MixingFreq; - - printf("signal %ld\n", AHIData->SoundFuncSignal); - - Wait(AHIData->SoundFuncSignal); - - /* I don't think it should start playing until there is something - * In the buffer, however to set off the SoundFunc it should - * probably go through the buffer at least once, just silently. - */ - AHI_SetFreq(0, Frequency, actrl, AHISF_IMM); - - Wait(AHIData->SoundFuncSignal); - - AHI_SetVol(0, 0x10000, 0x8000, actrl, AHISF_IMM); - - mixsamples=AHIData->BufferSamples; - - SoundSignal = AHIData->SoundFuncSignal; - - return 1; -} - -void AudioClose( void ) -{ - if(prelude) ClosePrelude(); - else ;//CloseAHI(AHIData); -} - - -#include - -extern int main(int argc, char **argv); - -void wbmain(struct WBStartup * argmsg) -{ - char argv[1][]={"WarpSNES"}; - int argc=1; - main(argc,(char **)argv); -} - - diff --git a/source/spc.cpp b/source/spc.cpp deleted file mode 100644 index c12c831..0000000 --- a/source/spc.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ -void S9xSPCDump (const char *filename) -{ - FILE *fs; - - bool8 read_only = FALSE; - char def [PATH_MAX]; - char title [PATH_MAX]; - char drive [_MAX_DRIVE]; - char dir [_MAX_DIR]; - char ext [_MAX_EXT]; - - S9xSetSoundMute (TRUE); - -#if 0 - _splitpath (Memory.ROMFilename, drive, dir, def, ext); - strcat (def, ".spc"); - sprintf (title, "%s SPC filename", - read_only ? "Select load" : "Choose save"); - const char *filename; - - filename = S9xSelectFilename (def, ".", "spc", title); -#endif - - fs = fopen (filename, "wb"); - fputs ("SNES-SPC700 Sound File Data 0.10", fs); - fseek (fs, 37, SEEK_SET); - fwrite (&APURegisters.PC, 2, 1, fs); - - fputc (APURegisters.YA.B.A, fs); - fputc (APURegisters.X, fs); - fputc (APURegisters.YA.B.Y, fs); - fputc (APURegisters.P, fs); - fputc (APURegisters.S - 0x100, fs); // ??? - fseek (fs, 256, SEEK_SET); - - fwrite (IAPU.RAM, 1, 65536, fs); - - fwrite (APU.DSP, 1, 192, fs); - fwrite (APU.ExtraRAM, 1, 64, fs); - - fclose (fs); - - S9xSetSoundMute (FALSE); -} - diff --git a/source/spccycles.cpp b/source/spccycles.cpp deleted file mode 100644 index 3cb572e..0000000 --- a/source/spccycles.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ - -static uint8 spc700cycles [256] = -{ - /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ - /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, - /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, - /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, - /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, - /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, - /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, - /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, - /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, - /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, - /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, - /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, - /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, - /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, - /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, - /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, - /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 -}; - diff --git a/source/spctool.cpp b/source/spctool.cpp deleted file mode 100644 index 011498c..0000000 --- a/source/spctool.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ -#include "snes9x.h" -#include "spctool/dsp.h" -#include "spctool/spc700.h" -#include "spctool/soundmod.h" -#include "apu.h" - -bool8 S9xOpenSoundDevice (int, bool8, int); - -void S9xSetPlaybackRate (uint32 rate) -{ - DOpt SmpOpt; - - SmpOpt.Smp8bit=false; - SmpOpt.SmpMono=false; - SmpOpt.IntType=IntC; - SmpOpt.OldBRE=false; - SmpOpt.MixRout=1; - SetSPUOpt (rate, SmpOpt); - -// so.playback_rate = playback_rate; -// so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate)); - } - -bool8 S9xSetSoundMute (bool8 mute) -{ - return (TRUE); -} - -START_EXTERN_C -bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size) -{ - if (!(mode & 7)) - return (TRUE); - - S9xSetSoundMute (TRUE); - if (!S9xOpenSoundDevice (mode, stereo, buffer_size)) - { - S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED, - "Sound device open failed"); - return (FALSE); - } - return (TRUE); -} - -void TraceSPC (unsigned char *PC, unsigned short YA, unsigned char X, - SPCFlags PS, unsigned char *SP) -{ - APURegisters.YA.W = YA; - APURegisters.X = X; - APURegisters.S = SP - IAPU.RAM; - IAPU.PC = PC; - IAPU._Carry = PS.C; - IAPU._Zero = !PS.Z | (PS.N << 7); - IAPU._Overflow = PS.V; - APURegisters.P = *(uint8 *) &PS; - S9xTraceAPU (); -} - -bool8 S9xInitAPU () -{ - void *SPCBase; //Base pointer and aligned pointer to SPC RAM - - SPCBase=malloc(131072); //Allocate memory for SPC RAM - memset(SPCBase, 0, 131072); - - IAPU.RAM=(uint8 *) InitSPU(SPCBase); //Initialize SPU w/ ptr to SPC RAM (Call only once) - - S9xSetPlaybackRate (22050); - ResetSPU(20); //Reset SPU with pre-amp level of 30 -// _SetSPCDbg(TraceSPC); //Install debug handler - return (TRUE); -} - -void S9xResetAPU () -{ - ResetSPU(20); - IAPU.RAM [0xf1] = 0x80; - _FixSPC (0xffc0, 0, 0, 0, 0, 0xff); -// FixDSP (); -} - -extern "C" void EDSP (uint8 *, int32); - -void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset) -{ -// _EmuDSP (buffer + byte_offset, sample_count / 2); - - EDSP (buffer + byte_offset, sample_count / 2); -#if 0 -for (int i = 0; i < 32; i++) -printf ("%02x,", *(buffer + byte_offset + i)); -printf ("\n"); -#endif -} -END_EXTERN_C - -void S9xFixSoundAfterSnapshotLoad () -{ -} - -void S9xSetSoundControl (int) -{ -} - -#ifdef DEBUGGER -START_EXTERN_C -void S9xDeinitAPU () -{ -} - -END_EXTERN_C -#endif - -- cgit v1.2.3 From 8951fdff1aada126257e07699ea6f132cb8d2e65 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 18 Dec 2012 00:02:49 -0500 Subject: Remove various explicit delays and reduce screen tearing when drawing emulated screens. --- source/nds/entry.cpp | 17 ++++++----------- source/nds/gui.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 19 deletions(-) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index d3dbae3..c14902c 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -172,12 +172,7 @@ bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/) break; } - -// memcpy(up_screen_addr, GFX.Screen, 256*192*2); -// memcpy(down_screen_addr, GFX.Screen+256*192*2, 256*(224-192)*2); - - ds2_flipScreen(UP_SCREEN, 0); -// ds2_flipScreen(DOWN_SCREEN, 0); + ds2_flipScreen(UP_SCREEN, 1); // synchronise to vblank to avoid tearing return (TRUE); } @@ -454,12 +449,12 @@ int load_gamepak(char* file) CPU.Flags = 0; S9xReset (); - mdelay(50); + // mdelay(50); // Delete this delay if (!Memory.LoadROM (file)) return -1; Memory.LoadSRAM (S9xGetFilename (".srm")); - mdelay(50); + // mdelay(50); // Delete this delay //S9xLoadCheatFile (S9xGetFilename (".cht")); S9xCheat_Disable(); @@ -507,7 +502,7 @@ int load_gamepak(char* file) } */ - mdelay(50); + // mdelay(50); // Delete this delay if (!Settings.APUEnabled) S9xSetSoundMute (FALSE); @@ -602,7 +597,7 @@ int sfc_main (int argc, char **argv) if (Settings.Paused) { S9xSetSoundMute (TRUE); - mdelay(50); + // mdelay(50); // Delete this delay unsigned short screen[256*192]; copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192); @@ -996,7 +991,7 @@ const unsigned int keymap[12] = { unsigned int S9xReadJoypad (int which1) { - struct key_buf inputdata; + struct key_buf inputdata; ds2_getrawInput(&inputdata); if(inputdata.key & KEY_TOUCH) //Active menu diff --git a/source/nds/gui.c b/source/nds/gui.c index f8cd03b..99ea7b0 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1650,7 +1650,7 @@ unsigned int frame_interval; --------------------------------------------------------*/ u32 menu(u16 *screen) { - mdelay(50); + mdelay(50); // to prevent the touch key from being applied too soon? gui_action_type gui_action; u32 i; u32 repeat; @@ -2059,7 +2059,7 @@ u32 menu(u16 *screen) reorder_latest_file(); save_game_config_file(); - mdelay(500); + // mdelay(500); // Delete this delay } } } @@ -2842,7 +2842,7 @@ u32 menu(u16 *screen) draw_string_vcenter(up_screen_addr, 0, 80, 256, COLOR_WHITE, msg[MSG_NON_LOAD_GAME]); ds2_flipScreen(UP_SCREEN, 1); - mdelay(500); + // mdelay(500); // Delete this delay } } @@ -2894,7 +2894,7 @@ u32 menu(u16 *screen) } save_emu_config_file(); - mdelay(500); + // mdelay(500); // Delete this delay } } @@ -3617,7 +3617,7 @@ u32 menu(u16 *screen) //----------------------------------------------------------------------------// // Menu Start ds2_setCPUclocklevel(0); - mdelay(200); + // mdelay(200); // Delete this delay ds2_setBacklight(3); @@ -3647,7 +3647,7 @@ u32 menu(u16 *screen) choose_menu(&main_menu); // Menu loop - mdelay(200); + // mdelay(50); // Delete this delay, shortened from 200 while(repeat) { @@ -4133,9 +4133,9 @@ u32 menu(u16 *screen) save_game_config_file(); } save_emu_config_file(); - mdelay(100); + // mdelay(100); // Delete this delay set_cpu_clock(clock_speed_number); - mdelay(200); + // mdelay(200); // Delete this delay ds2_clearScreen(DOWN_SCREEN, 0); ds2_flipScreen(DOWN_SCREEN, 1); -- cgit v1.2.3 From 286bfd58050a13e2e0e30bb35a7a1d189ec7edd1 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 18 Dec 2012 00:40:18 -0500 Subject: Sync sound. In addition to having less sound skipping going on, certain platformer games (I'm looking at you, Super Mario World) are helped by having more synchronised controls. In other words, synchronising the audio also synchronises the controls a bit more. --- source/nds/entry.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index c14902c..24c0e03 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -385,6 +385,7 @@ void init_sfc_setting(void) Settings.NetPlay = FALSE; Settings.ServerName [0] = 0; Settings.ThreadSound = FALSE; + Settings.SoundSync = TRUE; Settings.AutoSaveDelay = 0; #ifdef _NETPLAY_SUPPORT Settings.Port = NP_DEFAULT_PORT; -- cgit v1.2.3 From e708c127fa51beab567a9ce0e3ab53b58c997773 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 18 Dec 2012 22:53:49 -0500 Subject: Un-inline a bunch of stuff. With the MIPS instruction cache, this means that two consecutive SNES CPU instructions using e.g. the same addressing style or the same opcode have a chance that the second one will use the first one's code and that it will be cached. --- source/apumem.h | 8 +- source/cpuaddr.h | 44 ++++---- source/cpumacro.h | 124 +++++++++++------------ source/getset.h | 14 +-- source/memmap.cpp | 7 +- source/ppu.cpp | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++- source/ppu.h | 293 ++---------------------------------------------------- source/sa1cpu.cpp | 63 ++++++++++++ source/tile.cpp | 48 ++++----- 9 files changed, 481 insertions(+), 405 deletions(-) (limited to 'source') diff --git a/source/apumem.h b/source/apumem.h index 8f6dfa4..573b52c 100644 --- a/source/apumem.h +++ b/source/apumem.h @@ -95,7 +95,7 @@ extern uint8 W4; extern uint8 APUROM[64]; END_EXTERN_C -INLINE uint8 S9xAPUGetByteZ (uint8 Address) +uint8 S9xAPUGetByteZ (uint8 Address) { if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) { @@ -127,7 +127,7 @@ INLINE uint8 S9xAPUGetByteZ (uint8 Address) return (IAPU.DirectPage [Address]); } -INLINE void S9xAPUSetByteZ (uint8 byte, uint8 Address) +void S9xAPUSetByteZ (uint8 byte, uint8 Address) { if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) { @@ -156,7 +156,7 @@ INLINE void S9xAPUSetByteZ (uint8 byte, uint8 Address) IAPU.DirectPage [Address] = byte; } -INLINE uint8 S9xAPUGetByte (uint32 Address) +uint8 S9xAPUGetByte (uint32 Address) { Address &= 0xffff; @@ -189,7 +189,7 @@ INLINE uint8 S9xAPUGetByte (uint32 Address) return (IAPU.RAM [Address]); } -INLINE void S9xAPUSetByte (uint8 byte, uint32 Address) +void S9xAPUSetByte (uint8 byte, uint32 Address) { Address &= 0xffff; diff --git a/source/cpuaddr.h b/source/cpuaddr.h index a4c0ff4..76344db 100644 --- a/source/cpuaddr.h +++ b/source/cpuaddr.h @@ -100,19 +100,19 @@ typedef enum { JUMP = 4 } AccessMode; -STATIC inline void Immediate8 (AccessMode a) +void Immediate8 (AccessMode a) { OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; CPU.PC++; } -STATIC inline void Immediate16 (AccessMode a) +void Immediate16 (AccessMode a) { OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; CPU.PC += 2; } -STATIC inline void Relative (AccessMode a) +void Relative (AccessMode a) { Int8 = *CPU.PC++; #ifndef SA1_OPCODES @@ -121,7 +121,7 @@ STATIC inline void Relative (AccessMode a) OpAddress = ((int) (CPU.PC - CPU.PCBase) + Int8) & 0xffff; } -STATIC inline void RelativeLong (AccessMode a) +void RelativeLong (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = *(uint16 *) CPU.PC; @@ -136,7 +136,7 @@ STATIC inline void RelativeLong (AccessMode a) OpAddress &= 0xffff; } -STATIC inline void AbsoluteIndexedIndirect (AccessMode a) +void AbsoluteIndexedIndirect (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = (Registers.X.W + *(uint16 *) CPU.PC) & 0xffff; @@ -152,7 +152,7 @@ STATIC inline void AbsoluteIndexedIndirect (AccessMode a) if(a&READ) OpenBus = (uint8)(OpAddress>>8); } -STATIC inline void AbsoluteIndirectLong (AccessMode a) +void AbsoluteIndirectLong (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = *(uint16 *) CPU.PC; @@ -172,7 +172,7 @@ STATIC inline void AbsoluteIndirectLong (AccessMode a) } } -STATIC inline void AbsoluteIndirect (AccessMode a) +void AbsoluteIndirect (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = *(uint16 *) CPU.PC; @@ -190,7 +190,7 @@ STATIC inline void AbsoluteIndirect (AccessMode a) OpAddress += ICPU.ShiftedPB; } -STATIC inline void Absolute (AccessMode a) +void Absolute (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = *(uint16 *) CPU.PC + ICPU.ShiftedDB; @@ -204,7 +204,7 @@ STATIC inline void Absolute (AccessMode a) #endif } -STATIC inline void AbsoluteLong (AccessMode a) +void AbsoluteLong (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = (*(uint32 *) CPU.PC) & 0xffffff; @@ -218,7 +218,7 @@ STATIC inline void AbsoluteLong (AccessMode a) #endif } -STATIC inline void Direct(AccessMode a) +void Direct(AccessMode a) { if(a&READ) OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; @@ -228,7 +228,7 @@ STATIC inline void Direct(AccessMode a) // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } -STATIC inline void DirectIndirectIndexed (AccessMode a) +void DirectIndirectIndexed (AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; @@ -245,7 +245,7 @@ STATIC inline void DirectIndirectIndexed (AccessMode a) // XXX: else Add one cycle if crosses page boundary } -STATIC inline void DirectIndirectIndexedLong (AccessMode a) +void DirectIndirectIndexedLong (AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; @@ -261,7 +261,7 @@ STATIC inline void DirectIndirectIndexedLong (AccessMode a) // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } -STATIC inline void DirectIndexedIndirect(AccessMode a) +void DirectIndexedIndirect(AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff; @@ -281,7 +281,7 @@ STATIC inline void DirectIndexedIndirect(AccessMode a) #endif } -STATIC inline void DirectIndexedX (AccessMode a) +void DirectIndexedX (AccessMode a) { if(a&READ) OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W); @@ -299,7 +299,7 @@ STATIC inline void DirectIndexedX (AccessMode a) #endif } -STATIC inline void DirectIndexedY (AccessMode a) +void DirectIndexedY (AccessMode a) { if(a&READ) OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W + Registers.Y.W); @@ -316,7 +316,7 @@ STATIC inline void DirectIndexedY (AccessMode a) #endif } -STATIC inline void AbsoluteIndexedX (AccessMode a) +void AbsoluteIndexedX (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W; @@ -333,7 +333,7 @@ STATIC inline void AbsoluteIndexedX (AccessMode a) // XXX: else is cross page boundary add one cycle } -STATIC inline void AbsoluteIndexedY (AccessMode a) +void AbsoluteIndexedY (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W; @@ -350,7 +350,7 @@ STATIC inline void AbsoluteIndexedY (AccessMode a) // XXX: else is cross page boundary add one cycle } -STATIC inline void AbsoluteLongIndexedX (AccessMode a) +void AbsoluteLongIndexedX (AccessMode a) { #ifdef FAST_LSB_WORD_ACCESS OpAddress = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff; @@ -364,7 +364,7 @@ STATIC inline void AbsoluteLongIndexedX (AccessMode a) #endif } -STATIC inline void DirectIndirect (AccessMode a) +void DirectIndirect (AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; @@ -378,7 +378,7 @@ STATIC inline void DirectIndirect (AccessMode a) // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } -STATIC inline void DirectIndirectLong (AccessMode a) +void DirectIndirectLong (AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; @@ -393,7 +393,7 @@ STATIC inline void DirectIndirectLong (AccessMode a) // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } -STATIC inline void StackRelative (AccessMode a) +void StackRelative (AccessMode a) { if(a&READ) OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; @@ -403,7 +403,7 @@ STATIC inline void StackRelative (AccessMode a) #endif } -STATIC inline void StackRelativeIndirectIndexed (AccessMode a) +void StackRelativeIndirectIndexed (AccessMode a) { OpenBus = *CPU.PC; OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; diff --git a/source/cpumacro.h b/source/cpumacro.h index d97aa53..5b4e15b 100644 --- a/source/cpumacro.h +++ b/source/cpumacro.h @@ -90,19 +90,19 @@ #ifndef _CPUMACRO_H_ #define _CPUMACRO_H_ -STATIC inline void SetZN16 (uint16 Work) +void SetZN16 (uint16 Work) { ICPU._Zero = Work != 0; ICPU._Negative = (uint8) (Work >> 8); } -STATIC inline void SetZN8 (uint8 Work) +void SetZN8 (uint8 Work) { ICPU._Zero = Work; ICPU._Negative = Work; } -STATIC inline void ADC8 () +void ADC8 () { Work8 = S9xGetByte (OpAddress); @@ -159,7 +159,7 @@ STATIC inline void ADC8 () } } -STATIC inline void ADC16 () +void ADC16 () { Work16 = S9xGetWord (OpAddress); @@ -235,19 +235,19 @@ STATIC inline void ADC16 () } } -STATIC inline void AND16 () +void AND16 () { Registers.A.W &= S9xGetWord (OpAddress); SetZN16 (Registers.A.W); } -STATIC inline void AND8 () +void AND8 () { Registers.AL &= S9xGetByte (OpAddress); SetZN8 (Registers.AL); } -STATIC inline void A_ASL16 () +void A_ASL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -257,7 +257,7 @@ STATIC inline void A_ASL16 () SetZN16 (Registers.A.W); } -STATIC inline void A_ASL8 () +void A_ASL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -267,7 +267,7 @@ STATIC inline void A_ASL8 () SetZN8 (Registers.AL); } -STATIC inline void ASL16 () +void ASL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -281,7 +281,7 @@ STATIC inline void ASL16 () SetZN16 (Work16); } -STATIC inline void ASL8 () +void ASL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -293,7 +293,7 @@ STATIC inline void ASL8 () SetZN8 (Work8); } -STATIC inline void BIT16 () +void BIT16 () { Work16 = S9xGetWord (OpAddress); ICPU._Overflow = (Work16 & 0x4000) != 0; @@ -301,7 +301,7 @@ STATIC inline void BIT16 () ICPU._Zero = (Work16 & Registers.A.W) != 0; } -STATIC inline void BIT8 () +void BIT8 () { Work8 = S9xGetByte (OpAddress); ICPU._Overflow = (Work8 & 0x40) != 0; @@ -309,7 +309,7 @@ STATIC inline void BIT8 () ICPU._Zero = Work8 & Registers.AL; } -STATIC inline void CMP16 () +void CMP16 () { Int32 = (long) Registers.A.W - (long) S9xGetWord (OpAddress); @@ -317,7 +317,7 @@ STATIC inline void CMP16 () SetZN16 ((uint16) Int32); } -STATIC inline void CMP8 () +void CMP8 () { Int16 = (short) Registers.AL - (short) S9xGetByte (OpAddress); @@ -325,7 +325,7 @@ STATIC inline void CMP8 () SetZN8 ((uint8) Int16); } -STATIC inline void CMX16 () +void CMX16 () { Int32 = (long) Registers.X.W - (long) S9xGetWord (OpAddress); @@ -333,7 +333,7 @@ STATIC inline void CMX16 () SetZN16 ((uint16) Int32); } -STATIC inline void CMX8 () +void CMX8 () { Int16 = (short) Registers.XL - (short) S9xGetByte (OpAddress); @@ -341,7 +341,7 @@ STATIC inline void CMX8 () SetZN8 ((uint8) Int16); } -STATIC inline void CMY16 () +void CMY16 () { Int32 = (long) Registers.Y.W - (long) S9xGetWord (OpAddress); @@ -349,7 +349,7 @@ STATIC inline void CMY16 () SetZN16 ((uint16) Int32); } -STATIC inline void CMY8 () +void CMY8 () { Int16 = (short) Registers.YL - (short) S9xGetByte (OpAddress); @@ -357,7 +357,7 @@ STATIC inline void CMY8 () SetZN8 ((uint8) Int16); } -STATIC inline void A_DEC16 () +void A_DEC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -370,7 +370,7 @@ STATIC inline void A_DEC16 () SetZN16 (Registers.A.W); } -STATIC inline void A_DEC8 () +void A_DEC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -383,7 +383,7 @@ STATIC inline void A_DEC8 () SetZN8 (Registers.AL); } -STATIC inline void DEC16 () +void DEC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -399,7 +399,7 @@ STATIC inline void DEC16 () SetZN16 (Work16); } -STATIC inline void DEC8 () +void DEC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -413,19 +413,19 @@ STATIC inline void DEC8 () SetZN8 (Work8); } -STATIC inline void EOR16 () +void EOR16 () { Registers.A.W ^= S9xGetWord (OpAddress); SetZN16 (Registers.A.W); } -STATIC inline void EOR8 () +void EOR8 () { Registers.AL ^= S9xGetByte (OpAddress); SetZN8 (Registers.AL); } -STATIC inline void A_INC16 () +void A_INC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -438,7 +438,7 @@ STATIC inline void A_INC16 () SetZN16 (Registers.A.W); } -STATIC inline void A_INC8 () +void A_INC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -451,7 +451,7 @@ STATIC inline void A_INC8 () SetZN8 (Registers.AL); } -STATIC inline void INC16 () +void INC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -467,7 +467,7 @@ STATIC inline void INC16 () SetZN16 (Work16); } -STATIC inline void INC8 () +void INC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -481,43 +481,43 @@ STATIC inline void INC8 () SetZN8 (Work8); } -STATIC inline void LDA16 () +void LDA16 () { Registers.A.W = S9xGetWord (OpAddress); SetZN16 (Registers.A.W); } -STATIC inline void LDA8 () +void LDA8 () { Registers.AL = S9xGetByte (OpAddress); SetZN8 (Registers.AL); } -STATIC inline void LDX16 () +void LDX16 () { Registers.X.W = S9xGetWord (OpAddress); SetZN16 (Registers.X.W); } -STATIC inline void LDX8 () +void LDX8 () { Registers.XL = S9xGetByte (OpAddress); SetZN8 (Registers.XL); } -STATIC inline void LDY16 () +void LDY16 () { Registers.Y.W = S9xGetWord (OpAddress); SetZN16 (Registers.Y.W); } -STATIC inline void LDY8 () +void LDY8 () { Registers.YL = S9xGetByte (OpAddress); SetZN8 (Registers.YL); } -STATIC inline void A_LSR16 () +void A_LSR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -527,7 +527,7 @@ STATIC inline void A_LSR16 () SetZN16 (Registers.A.W); } -STATIC inline void A_LSR8 () +void A_LSR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -537,7 +537,7 @@ STATIC inline void A_LSR8 () SetZN8 (Registers.AL); } -STATIC inline void LSR16 () +void LSR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -551,7 +551,7 @@ STATIC inline void LSR16 () SetZN16 (Work16); } -STATIC inline void LSR8 () +void LSR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -563,19 +563,19 @@ STATIC inline void LSR8 () SetZN8 (Work8); } -STATIC inline void ORA16 () +void ORA16 () { Registers.A.W |= S9xGetWord (OpAddress); SetZN16 (Registers.A.W); } -STATIC inline void ORA8 () +void ORA8 () { Registers.AL |= S9xGetByte (OpAddress); SetZN8 (Registers.AL); } -STATIC inline void A_ROL16 () +void A_ROL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -586,7 +586,7 @@ STATIC inline void A_ROL16 () SetZN16 ((uint16) Work32); } -STATIC inline void A_ROL8 () +void A_ROL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -599,7 +599,7 @@ STATIC inline void A_ROL8 () SetZN8 ((uint8) Work16); } -STATIC inline void ROL16 () +void ROL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -614,7 +614,7 @@ STATIC inline void ROL16 () SetZN16 ((uint16) Work32); } -STATIC inline void ROL8 () +void ROL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -627,7 +627,7 @@ STATIC inline void ROL8 () SetZN8 ((uint8) Work16); } -STATIC inline void A_ROR16 () +void A_ROR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -640,7 +640,7 @@ STATIC inline void A_ROR16 () SetZN16 ((uint16) Work32); } -STATIC inline void A_ROR8 () +void A_ROR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -652,7 +652,7 @@ STATIC inline void A_ROR8 () SetZN8 ((uint8) Work16); } -STATIC inline void ROR16 () +void ROR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -667,7 +667,7 @@ STATIC inline void ROR16 () SetZN16 ((uint16) Work32); } -STATIC inline void ROR8 () +void ROR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -680,7 +680,7 @@ STATIC inline void ROR8 () SetZN8 ((uint8) Work16); } -STATIC inline void SBC16 () +void SBC16 () { Work16 = S9xGetWord (OpAddress); @@ -750,7 +750,7 @@ STATIC inline void SBC16 () } } -STATIC inline void SBC8 () +void SBC8 () { Work8 = S9xGetByte (OpAddress); if (CheckDecimal ()) @@ -801,47 +801,47 @@ STATIC inline void SBC8 () } } -STATIC inline void STA16 () +void STA16 () { S9xSetWord (Registers.A.W, OpAddress); } -STATIC inline void STA8 () +void STA8 () { S9xSetByte (Registers.AL, OpAddress); } -STATIC inline void STX16 () +void STX16 () { S9xSetWord (Registers.X.W, OpAddress); } -STATIC inline void STX8 () +void STX8 () { S9xSetByte (Registers.XL, OpAddress); } -STATIC inline void STY16 () +void STY16 () { S9xSetWord (Registers.Y.W, OpAddress); } -STATIC inline void STY8 () +void STY8 () { S9xSetByte (Registers.YL, OpAddress); } -STATIC inline void STZ16 () +void STZ16 () { S9xSetWord (0, OpAddress); } -STATIC inline void STZ8 () +void STZ8 () { S9xSetByte (0, OpAddress); } -STATIC inline void TSB16 () +void TSB16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -854,7 +854,7 @@ STATIC inline void TSB16 () S9xSetByte (Work16&0xFF, OpAddress); } -STATIC inline void TSB8 () +void TSB8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -865,7 +865,7 @@ STATIC inline void TSB8 () S9xSetByte (Work8, OpAddress); } -STATIC inline void TRB16 () +void TRB16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -878,7 +878,7 @@ STATIC inline void TRB16 () S9xSetByte (Work16&0xFF, OpAddress); } -STATIC inline void TRB8 () +void TRB8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; diff --git a/source/getset.h b/source/getset.h index 2368ac2..f04bf95 100644 --- a/source/getset.h +++ b/source/getset.h @@ -103,7 +103,7 @@ extern "C" extern uint8 OpenBus; } -INLINE uint8 S9xGetByte (uint32 Address) +uint8 S9xGetByte (uint32 Address) { int block; uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; @@ -197,7 +197,7 @@ INLINE uint8 S9xGetByte (uint32 Address) } } -INLINE uint16 S9xGetWord (uint32 Address) +uint16 S9xGetWord (uint32 Address) { if ((Address & 0x0fff) == 0x0fff) { @@ -320,7 +320,7 @@ INLINE uint16 S9xGetWord (uint32 Address) } } -INLINE void S9xSetByte (uint8 Byte, uint32 Address) +void S9xSetByte (uint8 Byte, uint32 Address) { #if defined(CPU_SHUTDOWN) CPU.WaitAddress = NULL; @@ -436,7 +436,7 @@ INLINE void S9xSetByte (uint8 Byte, uint32 Address) } } -INLINE void S9xSetWord (uint16 Word, uint32 Address) +void S9xSetWord (uint16 Word, uint32 Address) { if((Address & 0x0FFF)==0x0FFF) { @@ -594,7 +594,7 @@ INLINE void S9xSetWord (uint16 Word, uint32 Address) } } -INLINE uint8 *GetBasePointer (uint32 Address) +uint8 *GetBasePointer (uint32 Address) { uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; if (GetAddress >= (uint8 *) CMemory::MAP_LAST) @@ -660,7 +660,7 @@ INLINE uint8 *GetBasePointer (uint32 Address) } } -INLINE uint8 *S9xGetMemPointer (uint32 Address) +uint8 *S9xGetMemPointer (uint32 Address) { uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; if (GetAddress >= (uint8 *) CMemory::MAP_LAST) @@ -714,7 +714,7 @@ INLINE uint8 *S9xGetMemPointer (uint32 Address) } } -INLINE void S9xSetPCBase (uint32 Address) +void S9xSetPCBase (uint32 Address) { int block; uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; diff --git a/source/memmap.cpp b/source/memmap.cpp index 65b8739..e378601 100644 --- a/source/memmap.cpp +++ b/source/memmap.cpp @@ -146,7 +146,7 @@ int is_bsx(unsigned char *); int bs_name(unsigned char *); int check_char(unsigned); void S9xDeinterleaveType2 (bool8 reset=TRUE); -inline uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32 = 0xFFFFFFFF); +uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32 = 0xFFFFFFFF); extern char *rom_filename; @@ -395,10 +395,11 @@ char *CMemory::Safe (const char *s) /**********************************************************************************************/ /* Init() */ -/* This function allocates all the memory needed by the emulator */ +/* This function allocates and zeroes all the memory needed by the emulator */ /**********************************************************************************************/ bool8 CMemory::Init () { + // memset? Really? We could just memcpy after the first allocation... [Neb] RAM = (uint8 *) malloc (0x20000); SRAM = (uint8 *) malloc (0x20000); VRAM = (uint8 *) malloc (0x10000); @@ -1213,7 +1214,7 @@ void S9xDeinterleaveType2 (bool8 reset) } //CRC32 for char arrays -inline uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32) +uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32) { for (register uint32 i = 0; i < size; i++) { diff --git a/source/ppu.cpp b/source/ppu.cpp index fc0bd51..389bdd2 100644 --- a/source/ppu.cpp +++ b/source/ppu.cpp @@ -117,7 +117,7 @@ uint8 in_bit=0; extern uint8 *HDMAMemPointers [8]; -static inline void S9xLatchCounters (bool force) +void S9xLatchCounters (bool force) { if(!force && !(Memory.FillRAM[0x4213] & 0x80)) return; @@ -3297,3 +3297,286 @@ printf ("%06x: %d\n", t, FxEmulate (2000000)); } #endif +// Register reads and writes... + +uint8 REGISTER_4212() +{ + GetBank = 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) + GetBank = 1; + + GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) + GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */ + + return (GetBank); +} + +void FLUSH_REDRAW () +{ + if (IPPU.PreviousLine != IPPU.CurrentLine) + S9xUpdateScreen (); +} + +void REGISTER_2104 (uint8 byte) +{ + if (PPU.OAMAddr & 0x100) + { + int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1); + if (byte != PPU.OAMData [addr]){ + FLUSH_REDRAW (); + PPU.OAMData [addr] = byte; + IPPU.OBJChanged = TRUE; + + // X position high bit, and sprite size (x4) + struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4]; + + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1]; + pObj++->Size = byte & 2; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1]; + pObj++->Size = byte & 8; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1]; + pObj++->Size = byte & 32; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1]; + pObj->Size = byte & 128; + } + PPU.OAMFlip ^= 1; + if(!(PPU.OAMFlip & 1)){ + ++PPU.OAMAddr; + PPU.OAMAddr &= 0x1ff; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } else { + if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; + } + } else if(!(PPU.OAMFlip & 1)){ + PPU.OAMWriteRegister &= 0xff00; + PPU.OAMWriteRegister |= byte; + PPU.OAMFlip |= 1; + if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; + } else { + PPU.OAMWriteRegister &= 0x00ff; + uint8 lowbyte = (uint8)(PPU.OAMWriteRegister); + uint8 highbyte = byte; + PPU.OAMWriteRegister |= byte << 8; + + int addr = (PPU.OAMAddr << 1); + + if (lowbyte != PPU.OAMData [addr] || + highbyte != PPU.OAMData [addr+1]) + { + FLUSH_REDRAW (); + PPU.OAMData [addr] = lowbyte; + PPU.OAMData [addr+1] = highbyte; + IPPU.OBJChanged = TRUE; + if (addr & 2) + { + // Tile + PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff; + + // priority, h and v flip. + PPU.OBJ[addr].Palette = (highbyte >> 1) & 7; + PPU.OBJ[addr].Priority = (highbyte >> 4) & 3; + PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1; + PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1; + } + else + { + // X position (low) + PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00; + PPU.OBJ[addr].HPos |= lowbyte; + + // Sprite Y position + PPU.OBJ[addr].VPos = highbyte; + } + } + PPU.OAMFlip &= ~1; + ++PPU.OAMAddr; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } + + Memory.FillRAM [0x2104] = byte; +} + +void REGISTER_2118 (uint8 Byte) +{ + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + } + else + { + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + } + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + { +#ifdef DEBUGGER + if (Settings.TraceVRAM && !CPU.InDMA) + { + printf ("VRAM write byte: $%04X (%d,%d)\n", PPU.VMA.Address, + Memory.FillRAM[0x2115] & 3, + (Memory.FillRAM [0x2115] & 0x0c) >> 2); + } +#endif + PPU.VMA.Address += PPU.VMA.Increment; + } +// Memory.FillRAM [0x2118] = Byte; +} + +void REGISTER_2118_tile (uint8 Byte) +{ + uint32 address; + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2118] = Byte; +} + +void REGISTER_2118_linear (uint8 Byte) +{ + uint32 address; + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2118] = Byte; +} + +void REGISTER_2119 (uint8 Byte) +{ + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + } + else + { + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + } + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + { +#ifdef DEBUGGER + if (Settings.TraceVRAM && !CPU.InDMA) + { + printf ("VRAM write word: $%04X (%d,%d)\n", PPU.VMA.Address, + Memory.FillRAM[0x2115] & 3, + (Memory.FillRAM [0x2115] & 0x0c) >> 2); + } +#endif + PPU.VMA.Address += PPU.VMA.Increment; + } +// Memory.FillRAM [0x2119] = Byte; +} + +void REGISTER_2119_tile (uint8 Byte) +{ + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2119] = Byte; +} + +void REGISTER_2119_linear (uint8 Byte) +{ + uint32 address; + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2119] = Byte; +} + +void REGISTER_2122(uint8 Byte) +{ + // CG-RAM (palette) write + + if (PPU.CGFLIP) + { + if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) + { + if (Settings.SixteenBit) + FLUSH_REDRAW (); + PPU.CGDATA[PPU.CGADD] &= 0x00FF; + PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; + IPPU.ColorsChanged = TRUE; + if (Settings.SixteenBit) + { + IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + } + PPU.CGADD++; + } + else + { + if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) + { + if (Settings.SixteenBit) + FLUSH_REDRAW (); + PPU.CGDATA[PPU.CGADD] &= 0x7F00; + PPU.CGDATA[PPU.CGADD] |= Byte; + IPPU.ColorsChanged = TRUE; + if (Settings.SixteenBit) + { + IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + } + } + PPU.CGFLIP ^= 1; +// Memory.FillRAM [0x2122] = Byte; +} + +void REGISTER_2180(uint8 Byte) +{ + Memory.RAM[PPU.WRAM++] = Byte; + PPU.WRAM &= 0x1FFFF; + Memory.FillRAM [0x2180] = Byte; +} diff --git a/source/ppu.h b/source/ppu.h index 99dde34..5a889ef 100644 --- a/source/ppu.h +++ b/source/ppu.h @@ -342,288 +342,17 @@ END_EXTERN_C #define MAX_5C78_VERSION 0x03 #define MAX_5A22_VERSION 0x02 -STATIC inline uint8 REGISTER_4212() -{ - GetBank = 0; - if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && - CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) - GetBank = 1; - - GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; - if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) - GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */ - - return (GetBank); -} - -STATIC inline void FLUSH_REDRAW () -{ - if (IPPU.PreviousLine != IPPU.CurrentLine) - S9xUpdateScreen (); -} - -STATIC inline void REGISTER_2104 (uint8 byte) -{ - if (PPU.OAMAddr & 0x100) - { - int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1); - if (byte != PPU.OAMData [addr]){ - FLUSH_REDRAW (); - PPU.OAMData [addr] = byte; - IPPU.OBJChanged = TRUE; - - // X position high bit, and sprite size (x4) - struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4]; - - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1]; - pObj++->Size = byte & 2; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1]; - pObj++->Size = byte & 8; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1]; - pObj++->Size = byte & 32; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1]; - pObj->Size = byte & 128; - } - PPU.OAMFlip ^= 1; - if(!(PPU.OAMFlip & 1)){ - ++PPU.OAMAddr; - PPU.OAMAddr &= 0x1ff; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } else { - if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; - } - } else if(!(PPU.OAMFlip & 1)){ - PPU.OAMWriteRegister &= 0xff00; - PPU.OAMWriteRegister |= byte; - PPU.OAMFlip |= 1; - if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; - } else { - PPU.OAMWriteRegister &= 0x00ff; - uint8 lowbyte = (uint8)(PPU.OAMWriteRegister); - uint8 highbyte = byte; - PPU.OAMWriteRegister |= byte << 8; - - int addr = (PPU.OAMAddr << 1); - - if (lowbyte != PPU.OAMData [addr] || - highbyte != PPU.OAMData [addr+1]) - { - FLUSH_REDRAW (); - PPU.OAMData [addr] = lowbyte; - PPU.OAMData [addr+1] = highbyte; - IPPU.OBJChanged = TRUE; - if (addr & 2) - { - // Tile - PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff; - - // priority, h and v flip. - PPU.OBJ[addr].Palette = (highbyte >> 1) & 7; - PPU.OBJ[addr].Priority = (highbyte >> 4) & 3; - PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1; - PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1; - } - else - { - // X position (low) - PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00; - PPU.OBJ[addr].HPos |= lowbyte; - - // Sprite Y position - PPU.OBJ[addr].VPos = highbyte; - } - } - PPU.OAMFlip &= ~1; - ++PPU.OAMAddr; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } - - Memory.FillRAM [0x2104] = byte; -} - -STATIC inline void REGISTER_2118 (uint8 Byte) -{ - uint32 address; - if (PPU.VMA.FullGraphicCount) - { - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; - Memory.VRAM [address] = Byte; - } - else - { - Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; - } - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - { -#ifdef DEBUGGER - if (Settings.TraceVRAM && !CPU.InDMA) - { - printf ("VRAM write byte: $%04X (%d,%d)\n", PPU.VMA.Address, - Memory.FillRAM[0x2115] & 3, - (Memory.FillRAM [0x2115] & 0x0c) >> 2); - } -#endif - PPU.VMA.Address += PPU.VMA.Increment; - } -// Memory.FillRAM [0x2118] = Byte; -} - -STATIC inline void REGISTER_2118_tile (uint8 Byte) -{ - uint32 address; - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; - Memory.VRAM [address] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2118] = Byte; -} - -STATIC inline void REGISTER_2118_linear (uint8 Byte) -{ - uint32 address; - Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2118] = Byte; -} - -STATIC inline void REGISTER_2119 (uint8 Byte) -{ - uint32 address; - if (PPU.VMA.FullGraphicCount) - { - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; - Memory.VRAM [address] = Byte; - } - else - { - Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; - } - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - { -#ifdef DEBUGGER - if (Settings.TraceVRAM && !CPU.InDMA) - { - printf ("VRAM write word: $%04X (%d,%d)\n", PPU.VMA.Address, - Memory.FillRAM[0x2115] & 3, - (Memory.FillRAM [0x2115] & 0x0c) >> 2); - } -#endif - PPU.VMA.Address += PPU.VMA.Increment; - } -// Memory.FillRAM [0x2119] = Byte; -} - -STATIC inline void REGISTER_2119_tile (uint8 Byte) -{ - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; - Memory.VRAM [address] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2119] = Byte; -} - -STATIC inline void REGISTER_2119_linear (uint8 Byte) -{ - uint32 address; - Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2119] = Byte; -} - -STATIC inline void REGISTER_2122(uint8 Byte) -{ - // CG-RAM (palette) write - - if (PPU.CGFLIP) - { - if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) - { - if (Settings.SixteenBit) - FLUSH_REDRAW (); - PPU.CGDATA[PPU.CGADD] &= 0x00FF; - PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; - IPPU.ColorsChanged = TRUE; - if (Settings.SixteenBit) - { - IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; - IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; - IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], - IPPU.Green [PPU.CGADD], - IPPU.Blue [PPU.CGADD]); - } - } - PPU.CGADD++; - } - else - { - if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) - { - if (Settings.SixteenBit) - FLUSH_REDRAW (); - PPU.CGDATA[PPU.CGADD] &= 0x7F00; - PPU.CGDATA[PPU.CGADD] |= Byte; - IPPU.ColorsChanged = TRUE; - if (Settings.SixteenBit) - { - IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; - IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; - IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], - IPPU.Green [PPU.CGADD], - IPPU.Blue [PPU.CGADD]); - } - } - } - PPU.CGFLIP ^= 1; -// Memory.FillRAM [0x2122] = Byte; -} - -STATIC inline void REGISTER_2180(uint8 Byte) -{ - Memory.RAM[PPU.WRAM++] = Byte; - PPU.WRAM &= 0x1FFFF; - Memory.FillRAM [0x2180] = Byte; -} - +extern uint8 REGISTER_4212(); +extern void FLUSH_REDRAW (); +extern void REGISTER_2104 (uint8 byte); +extern void REGISTER_2118 (uint8 Byte); +extern void REGISTER_2118_tile (uint8 Byte); +extern void REGISTER_2118_linear (uint8 Byte); +extern void REGISTER_2119 (uint8 Byte); +extern void REGISTER_2119_tile (uint8 Byte); +extern void REGISTER_2119_linear (uint8 Byte); +extern void REGISTER_2122(uint8 Byte); +extern void REGISTER_2180(uint8 Byte); //Platform specific input functions used by PPU.CPP void JustifierButtons(uint32&); diff --git a/source/sa1cpu.cpp b/source/sa1cpu.cpp index 1532f57..655fa5c 100644 --- a/source/sa1cpu.cpp +++ b/source/sa1cpu.cpp @@ -134,6 +134,69 @@ #define StackRelative SA1StackRelative #define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed +#define SetZN16 SA1SetZN16 +#define SetZN8 SA1SetZN8 +#define ADC8 SA1ADC8 +#define ADC16 SA1ADC16 +#define AND16 SA1AND16 +#define AND8 SA1AND8 +#define A_ASL16 SA1A_ASL16 +#define A_ASL8 SA1A_ASL8 +#define ASL16 SA1ASL16 +#define ASL8 SA1ASL8 +#define BIT16 SA1BIT16 +#define BIT8 SA1BIT8 +#define CMP16 SA1CMP16 +#define CMP8 SA1CMP8 +#define CMX16 SA1CMX16 +#define CMX8 SA1CMX8 +#define CMY16 SA1CMY16 +#define CMY8 SA1CMY8 +#define A_DEC16 SA1A_DEC16 +#define A_DEC8 SA1A_DEC8 +#define DEC16 SA1DEC16 +#define DEC8 SA1DEC8 +#define EOR16 SA1EOR16 +#define EOR8 SA1EOR8 +#define A_INC16 SA1A_INC16 +#define A_INC8 SA1A_INC8 +#define INC16 SA1INC16 +#define INC8 SA1INC8 +#define LDA16 SA1LDA16 +#define LDA8 SA1LDA8 +#define LDX16 SA1LDX16 +#define LDX8 SA1LDX8 +#define LDY16 SA1LDY16 +#define LDY8 SA1LDY8 +#define A_LSR16 SA1A_LSR16 +#define A_LSR8 SA1A_LSR8 +#define LSR16 SA1LSR16 +#define LSR8 SA1LSR8 +#define ORA16 SA1ORA16 +#define ORA8 SA1ORA8 +#define A_ROL16 SA1A_ROL16 +#define A_ROL8 SA1A_ROL8 +#define ROL16 SA1ROL16 +#define ROL8 SA1ROL8 +#define A_ROR16 SA1A_ROR16 +#define A_ROR8 SA1A_ROR8 +#define ROR16 SA1ROR16 +#define ROR8 SA1ROR8 +#define SBC16 SA1SBC16 +#define SBC8 SA1SBC8 +#define STA16 SA1STA16 +#define STA8 SA1STA8 +#define STX16 SA1STX16 +#define STX8 SA1STX8 +#define STY16 SA1STY16 +#define STY8 SA1STY8 +#define STZ16 SA1STZ16 +#define STZ8 SA1STZ8 +#define TSB16 SA1TSB16 +#define TSB8 SA1TSB8 +#define TRB16 SA1TRB16 +#define TRB8 SA1TRB8 + //#undef CPU_SHUTDOWN #undef VAR_CYCLES #define SA1_OPCODES diff --git a/source/tile.cpp b/source/tile.cpp index 27e61f0..d4cdcbf 100644 --- a/source/tile.cpp +++ b/source/tile.cpp @@ -216,7 +216,7 @@ uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) return (non_zero ? TRUE : BLANK_TILE); } -inline void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -236,7 +236,7 @@ inline void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -256,7 +256,7 @@ inline void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -276,7 +276,7 @@ inline void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -296,7 +296,7 @@ inline void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -318,7 +318,7 @@ inline void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -417,7 +417,7 @@ void DrawLargePixel (uint32 Tile, uint32 Offset, RENDER_TILE_LARGE (((uint8) GFX.ScreenColors [pixel]), PLOT_PIXEL) } -inline void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -437,7 +437,7 @@ inline void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -457,7 +457,7 @@ inline void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -477,7 +477,7 @@ inline void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -497,7 +497,7 @@ inline void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -519,7 +519,7 @@ inline void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -614,7 +614,7 @@ void DrawLargePixel16 (uint32 Tile, uint32 Offset, RENDER_TILE_LARGE (GFX.ScreenColors [pixel], PLOT_PIXEL) } -inline void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -646,7 +646,7 @@ inline void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -678,7 +678,7 @@ inline void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -710,7 +710,7 @@ inline void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -742,7 +742,7 @@ inline void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -774,7 +774,7 @@ inline void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -806,7 +806,7 @@ inline void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -838,7 +838,7 @@ inline void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -951,7 +951,7 @@ void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) } -inline void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -977,7 +977,7 @@ inline void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -1003,7 +1003,7 @@ inline void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; @@ -1029,7 +1029,7 @@ inline void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -inline void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels) +void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels) { uint32 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; -- cgit v1.2.3 From 6bab708c22e3c310d10a8f110161bf1691d01240 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 00:28:32 -0500 Subject: Delete offsets.cpp, which is for a standalone tool that is unrelated to the emulator. --- source/memmap.cpp | 1 - source/offsets.cpp | 421 ----------------------------------------------------- 2 files changed, 422 deletions(-) delete mode 100644 source/offsets.cpp (limited to 'source') diff --git a/source/memmap.cpp b/source/memmap.cpp index e378601..04bc621 100644 --- a/source/memmap.cpp +++ b/source/memmap.cpp @@ -399,7 +399,6 @@ char *CMemory::Safe (const char *s) /**********************************************************************************************/ bool8 CMemory::Init () { - // memset? Really? We could just memcpy after the first allocation... [Neb] RAM = (uint8 *) malloc (0x20000); SRAM = (uint8 *) malloc (0x20000); VRAM = (uint8 *) malloc (0x10000); diff --git a/source/offsets.cpp b/source/offsets.cpp deleted file mode 100644 index 3438488..0000000 --- a/source/offsets.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ - -#include "snes9x.h" -#include "65c816.h" -#include "memmap.h" -#include "ppu.h" -#include "apu.h" -#include "cpuexec.h" -#include "sa1.h" - -#ifndef S9xSTREAM -#define S9xSTREAM stdout -#endif - -#define OFFSET(N,F) \ -fprintf (S9xSTREAM, "#define " #N " CPU + %d\n", (int) &((struct SCPUState *) 0)->F); -#define OFFSET2(N,F) \ -fprintf (S9xSTREAM, "#define " #N " Registers + %d\n", (int) &((struct SRegisters *) 0)->F); -#define OFFSET3(F) \ -fprintf (S9xSTREAM, "#define " #F " Memory + %d\n", (int) &((class CMemory *) 0)->F); -#define OFFSET4(N,F) \ -fprintf (S9xSTREAM, "#define " #N " APU + %d\n", (int) &((struct SAPU *) 0)->F); -#define OFFSET5(N,F) \ -fprintf (S9xSTREAM, "#define " #N " IAPU + %d\n", (int) &((struct SIAPU *) 0)->F); -#define OFFSET6(N,F) \ -fprintf (S9xSTREAM, "#define " #N " ICPU + %d\n", (int) &((struct SICPU *) 0)->F); -#define OFFSET7(N,F) \ -fprintf (S9xSTREAM, "#define " #N " Settings + %d\n", (int) &((struct SSettings *) 0)->F); -#define OFFSET8(N, F) \ -fprintf (S9xSTREAM, "#define " #N " APURegisters + %d\n", (int) &((struct SAPURegisters *) 0)->F); - -#define OFFSET9(N, F) \ -fprintf (S9xSTREAM, "#define " #N " PPU + %d\n", (int) &((struct SPPU *) 0)->F); -#define OFFSET10(N, F) \ -fprintf (S9xSTREAM, "#define " #N " IPPU + %d\n", (int) &((struct InternalPPU *) 0)->F); -#define OFFSET11(N, F) \ -fprintf (S9xSTREAM, "#define " #N " SA1 + %d\n", (int) &((struct SSA1 *) 0)->F); -#define OFFSET12(N, F) \ -fprintf (S9xSTREAM, "#define " #N " SA1Registers + %d\n", (int) &((struct SSA1Registers *) 0)->F); - -int main (int /*argc*/, char ** /*argv*/) -{ - OFFSET(Flags,Flags) - OFFSET(BranchSkip,BranchSkip) - OFFSET(NMIActive,NMIActive) - OFFSET(IRQActive,IRQActive) - OFFSET(WaitingForInterrupt,WaitingForInterrupt) - OFFSET(InDMA,InDMA) - OFFSET(WhichEvent,WhichEvent) - OFFSET(PCS,PC) - OFFSET(PCBase,PCBase) - OFFSET(PCAtOpcodeStart,PCAtOpcodeStart) - OFFSET(WaitAddress,WaitAddress) - OFFSET(WaitCounter,WaitCounter) - OFFSET(Cycles,Cycles) - OFFSET(NextEvent,NextEvent) - OFFSET(V_Counter,V_Counter) - OFFSET(MemSpeed,MemSpeed) - OFFSET(MemSpeedx2,MemSpeedx2) - OFFSET(FastROMSpeed,FastROMSpeed) - OFFSET(AutoSaveTimer,AutoSaveTimer) - OFFSET(SRAMModified,SRAMModified) - OFFSET(NMITriggerPoint,NMITriggerPoint) - OFFSET(TriedInterleavedMode2,TriedInterleavedMode2) - OFFSET(BRKTriggered,BRKTriggered) - OFFSET(NMICycleCount,NMICycleCount) - OFFSET(IRQCycleCount,IRQCycleCount) - - OFFSET2(PB,PB) - OFFSET2(DB,DB) - OFFSET2(PP,P.W) - OFFSET2(PL,P.W) - fprintf (S9xSTREAM, "#define PH PL + 1\n"); - OFFSET2(AA,A.W) - OFFSET2(AL,A.W) - fprintf (S9xSTREAM, "#define AH AL + 1\n"); - OFFSET2(DD,D.W) - OFFSET2(DL,D.W) - fprintf (S9xSTREAM, "#define DH DL + 1\n"); - OFFSET2(SS,S.W) - OFFSET2(SL,S.W) - fprintf (S9xSTREAM, "#define SH SL + 1\n"); - OFFSET2(XX,X.W) - OFFSET2(XL,X.W) - fprintf (S9xSTREAM, "#define XH XL + 1\n"); - OFFSET2(YY,Y.W) - OFFSET2(YL,Y.W) - fprintf (S9xSTREAM, "#define YH YL + 1\n"); - OFFSET2(PCR, PC) - - OFFSET3(RAM) - OFFSET3(ROM) - OFFSET3(VRAM) - OFFSET3(SRAM) - OFFSET3(BWRAM) - OFFSET3(FillRAM) - OFFSET3(C4RAM) - OFFSET3(HiROM) - OFFSET3(LoROM) - OFFSET3(SRAMMask) - OFFSET3(SRAMSize) - OFFSET3(Map) - OFFSET3(WriteMap) - OFFSET3(MemorySpeed) - OFFSET3(BlockIsRAM) - OFFSET3(BlockIsROM) - OFFSET3(ROMFilename) - - OFFSET5(APUPCS,PC) - OFFSET5(APURAM,RAM) - OFFSET5(APUExecuting,APUExecuting) - OFFSET5(APUDirectPage,DirectPage) - OFFSET5(APUBit,Bit) - OFFSET5(APUAddress,Address) - OFFSET5(APUWaitAddress1,WaitAddress1) - OFFSET5(APUWaitAddress2,WaitAddress2) - OFFSET5(APUWaitCounter,WaitCounter) - OFFSET5(APUShadowRAM,ShadowRAM) - OFFSET5(APUCachedSamples,CachedSamples) - OFFSET5(APU_Carry,_Carry) - OFFSET5(APU_Zero,_Zero) - OFFSET5(APU_Overflow,_Overflow) - OFFSET5(APUTimerErrorCounter,TimerErrorCounter) - - OFFSET4(APUCycles,Cycles) - OFFSET4(APUShowROM,ShowROM) - OFFSET4(APUFlags,Flags) - OFFSET4(APUKeyedChannels,KeyedChannels) - OFFSET4(APUOutPorts,OutPorts) - OFFSET4(APUDSP,DSP) - OFFSET4(APUExtraRAM,ExtraRAM) - OFFSET4(APUTimer,Timer) - OFFSET4(APUTimerTarget,TimerTarget) - OFFSET4(APUTimerEnabled,TimerEnabled) - OFFSET4(TimerValueWritten,TimerValueWritten) - - OFFSET6(CPUSpeed,Speed) - OFFSET6(CPUOpcodes,S9xOpcodes) - OFFSET6(_Carry,_Carry) - OFFSET6(_Zero,_Zero) - OFFSET6(_Negative,_Negative) - OFFSET6(_Overflow,_Overflow) - OFFSET6(ShiftedDB,ShiftedDB) - OFFSET6(ShiftedPB,ShiftedPB) - OFFSET6(CPUExecuting,CPUExecuting) - OFFSET6(Scanline,Scanline) - OFFSET6(Frame,Frame) - - OFFSET7(APUEnabled,APUEnabled) - OFFSET7(Shutdown,Shutdown) - OFFSET7(SoundSkipMethod,SoundSkipMethod) - OFFSET7(H_Max,H_Max) - OFFSET7(HBlankStart,HBlankStart) - OFFSET7(CyclesPercentage,CyclesPercentage) - OFFSET7(DisableIRQ,DisableIRQ) - OFFSET7(Paused,Paused) - OFFSET7(PAL,PAL) - OFFSET7(SoundSync,SoundSync) - OFFSET7(SA1Enabled,SA1) - OFFSET7(SuperFXEnabled,SuperFX) - - OFFSET8(ApuP,P) - OFFSET8(ApuYA,YA.W) - OFFSET8(ApuA,YA.B.A) - OFFSET8(ApuY,YA.B.Y) - OFFSET8(ApuX,X) - OFFSET8(ApuS,S) - OFFSET8(ApuPC,PC) - OFFSET8(APUPCR,PC) - - OFFSET9(BGMode,BGMode) - OFFSET9(BG3Priority,BG3Priority) - OFFSET9(Brightness,Brightness) - OFFSET9(GHight,VMA.High) - OFFSET9(GInc,VMA.Increment) - OFFSET9(GAddress,VMA.Address) - OFFSET9(GMask1,VMA.Mask1) - OFFSET9(GFullGraphicCount,VMA.FullGraphicCount) - OFFSET9(GShift,VMA.Shift) - OFFSET9(CGFLIP,CGFLIP) - OFFSET9(CGDATA,CGDATA) - OFFSET9(FirstSprite,FirstSprite) - OFFSET9(LastSprite,LastSprite) - OFFSET9(OBJ,OBJ) - OFFSET9(OAMPriorityRotation,OAMPriorityRotation) - OFFSET9(OAMAddr,OAMAddr) - OFFSET9(OAMFlip,OAMFlip) - OFFSET9(OAMTileAddress,OAMTileAddress) - OFFSET9(IRQVBeamPos,IRQVBeamPos) - OFFSET9(IRQHBeamPos,IRQHBeamPos) - OFFSET9(VBeamPosLatched,VBeamPosLatched) - OFFSET9(HBeamPosLatched,HBeamPosLatched) - OFFSET9(HBeamFlip,HBeamFlip) - OFFSET9(VBeamFlip,VBeamFlip) - OFFSET9(HVBeamCounterLatched,HVBeamCounterLatched) - OFFSET9(MatrixA,MatrixA) - OFFSET9(MatrixB,MatrixB) - OFFSET9(MatrixC,MatrixC) - OFFSET9(MatrixD,MatrixD) - OFFSET9(CentreX,CentreX) - OFFSET9(CentreY,CentreY) - OFFSET9(Joypad1ButtonReadPos,Joypad1ButtonReadPos) - OFFSET9(Joypad2ButtonReadPos,Joypad2ButtonReadPos) - OFFSET9(CGADD,CGADD) - OFFSET9(FixedColourGreen,FixedColourGreen) - OFFSET9(FixedColourRed,FixedColourRed) - OFFSET9(FixedColourBlue,FixedColourBlue) - OFFSET9(SavedOAMAddr,SavedOAMAddr) - OFFSET9(ScreenHeight,ScreenHeight) - OFFSET9(WRAM,WRAM) - OFFSET9(BG_Forced,BG_Forced) - OFFSET9(ForcedBlanking,ForcedBlanking) - OFFSET9(OBJThroughMain,OBJThroughMain) - OFFSET9(OBJThroughSub,OBJThroughSub) - OFFSET9(OBJSizeSelect,OBJSizeSelect) - OFFSET9(OBJNameBase,OBJNameBase) - OFFSET9(OAMReadFlip,OAMReadFlip) - OFFSET9(OAMData,OAMData) - OFFSET9(VTimerEnabled,VTimerEnabled) - OFFSET9(HTimerEnabled,HTimerEnabled) - OFFSET9(HTimerPosition,HTimerPosition) - OFFSET9(Mosaic,Mosaic) - OFFSET9(BGMosaic,BGMosaic) - OFFSET9(Mode7HFlip,Mode7HFlip) - OFFSET9(Mode7VFlip,Mode7VFlip) - OFFSET9(Mode7Repeat,Mode7Repeat) - OFFSET9(Window1Left,Window1Left) - OFFSET9(Window1Right,Window1Right) - OFFSET9(Window2Left,Window2Left) - OFFSET9(Window2Right,Window2Right) - OFFSET9(ClipWindowOverlapLogic,ClipWindowOverlapLogic) - OFFSET9(ClipWindow1Enable,ClipWindow1Enable) - OFFSET9(ClipWindow2Enable,ClipWindow2Enable) - OFFSET9(ClipWindow1Inside,ClipWindow1Inside) - OFFSET9(ClipWindow2Inside,ClipWindow2Inside) - OFFSET9(RecomputeClipWindows,RecomputeClipWindows) - OFFSET9(CGFLIPRead,CGFLIPRead) - OFFSET9(OBJNameSelect,OBJNameSelect) - OFFSET9(Need16x8Mulitply,Need16x8Mulitply) - OFFSET9(Joypad3ButtonReadPos,Joypad3ButtonReadPos) - OFFSET9(MouseSpeed,MouseSpeed) - OFFSET9(RangeTimeOver,RangeTimeOver) - - OFFSET10(ColorsChanged,ColorsChanged) - OFFSET10(HDMA,HDMA) - OFFSET10(HDMAStarted,HDMAStarted) - OFFSET10(MaxBrightness,MaxBrightness) - OFFSET10(LatchedBlanking,LatchedBlanking) - OFFSET10(OBJChanged,OBJChanged) - OFFSET10(RenderThisFrame,RenderThisFrame) - OFFSET10(SkippedFrames,SkippedFrames) - OFFSET10(FrameSkip,FrameSkip) - OFFSET10(TileCache,TileCache) - OFFSET10(TileCached,TileCached) -#ifdef CORRECT_VRAM_READS - OFFSET10(VRAMReadBuffer,VRAMReadBuffer) -#else - OFFSET10(FirstVRAMRead,FirstVRAMRead) -#endif - OFFSET10(Interlace,Interlace) - OFFSET10(DoubleWidthPixels,DoubleWidthPixels) - OFFSET10(RenderedScreenHeight,RenderedScreenHeight) - OFFSET10(RenderedScreenWidth,RenderedScreenWidth) - OFFSET10(Red,Red) - OFFSET10(Green,Green) - OFFSET10(Blue,Blue) - OFFSET10(XB,XB) - OFFSET10(ScreenColors,ScreenColors) - OFFSET10(PreviousLine,PreviousLine) - OFFSET10(CurrentLine,CurrentLine) - OFFSET10(Joypads,Joypads) - OFFSET10(SuperScope,SuperScope) - OFFSET10(Mouse,Mouse) - OFFSET10(PrevMouseX,PrevMouseX) - OFFSET10(PrevMouseY,PrevMouseY) - OFFSET10(Clip,Clip) - - OFFSET11(SA1Opcodes,S9xOpcodes) - OFFSET11(SA1_Carry,_Carry) - OFFSET11(SA1_Zero,_Zero) - OFFSET11(SA1_Negative,_Negative) - OFFSET11(SA1_Overflow,_Overflow) - OFFSET11(SA1CPUExecuting,CPUExecuting) - OFFSET11(SA1ShiftedPB,ShiftedPB) - OFFSET11(SA1ShiftedDB,ShiftedDB) - OFFSET11(SA1Flags,Flags) - OFFSET11(SA1Executing,Executing) - OFFSET11(SA1NMIActive,NMIActive) - OFFSET11(SA1IRQActive,IRQActive) - OFFSET11(SA1WaitingForInterrupt,WaitingForInterrupt) - OFFSET11(SA1PCS,PC) - OFFSET11(SA1PCBase,PCBase) - OFFSET11(SA1PCAtOpcodeStart,PCAtOpcodeStart) - OFFSET11(SA1WaitAddress,WaitAddress) - OFFSET11(SA1WaitCounter,WaitCounter) - OFFSET11(SA1WaitByteAddress1,WaitByteAddress1) - OFFSET11(SA1WaitByteAddress2,WaitByteAddress2) - OFFSET11(SA1BWRAM,BWRAM) - OFFSET11(SA1Map,Map) - OFFSET11(SA1WriteMap,WriteMap) - OFFSET11(SA1op1,op1) - OFFSET11(SA1op2,op2) - OFFSET11(SA1arithmetic_op,arithmetic_op) - OFFSET11(SA1sum,sum) - OFFSET11(SA1overflow,overflow) - OFFSET11(VirtualBitmapFormat,VirtualBitmapFormat) - OFFSET11(SA1_in_char_dma,in_char_dma) - OFFSET11(SA1variable_bit_pos,variable_bit_pos) - - OFFSET12(SA1PB,PB) - OFFSET12(SA1DB,DB) - OFFSET12(SA1PP,P.W) - OFFSET12(SA1PL,P.W) - fprintf (S9xSTREAM, "#define SA1PH SA1PL + 1\n"); - OFFSET12(SA1AA,A.W) - OFFSET12(SA1AL,A.W) - fprintf (S9xSTREAM, "#define SA1AH SA1AL + 1\n"); - OFFSET12(SA1DD,D.W) - OFFSET12(SA1DL,D.W) - fprintf (S9xSTREAM, "#define SA1DH SA1DL + 1\n"); - OFFSET12(SA1SS,S.W) - OFFSET12(SA1SL,S.W) - fprintf (S9xSTREAM, "#define SA1SH SA1SL + 1\n"); - OFFSET12(SA1XX,X.W) - OFFSET12(SA1XL,X.W) - fprintf (S9xSTREAM, "#define SA1XH SA1XL + 1\n"); - OFFSET12(SA1YY,Y.W) - OFFSET12(SA1YL,Y.W) - fprintf (S9xSTREAM, "#define SA1YH SA1YL + 1\n"); - OFFSET12(SA1PCR, PC) - - return (0); -} - -- cgit v1.2.3 From 65b56543ab4bab2307fe3b29a15f43caaa88dfa1 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 01:30:30 -0500 Subject: Raise the CPU's clock speed to 396 MHz while loading ROMs. Also raise the CPU's clock speed to 396 MHz by default, instead of 360 MHz, when emulating a ROM. --- source/nds/gui.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 99ea7b0..07f59d0 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1721,7 +1721,7 @@ u32 menu(u16 *screen) game_config.clock_speed_number = clock_speed_number; reorder_latest_file(); - //S9xAutoSaveSRAM (); + S9xAutoSaveSRAM (); save_game_config_file(); } save_emu_config_file(); @@ -1734,7 +1734,7 @@ u32 menu(u16 *screen) if(gamepak_name[0] != 0) { - //S9xAutoSaveSRAM (); + S9xAutoSaveSRAM (); save_game_config_file(); } @@ -1748,7 +1748,10 @@ u32 menu(u16 *screen) draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]); ds2_flipScreen(DOWN_SCREEN, 2); - if(load_gamepak(line_buffer) == -1) + ds2_setCPUclocklevel(13); + int load_result = load_gamepak(&line_buffer); + ds2_setCPUclocklevel(0); + if(load_result == -1) { first_load = 1; gamepak_name[0] = '\0'; @@ -1812,8 +1815,12 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]); ds2_flipScreen(DOWN_SCREEN, 2); - - if(load_gamepak(args[1]) == -1) + + ds2_setCPUclocklevel(13); + int load_result = load_gamepak(args[1]); + ds2_setCPUclocklevel(0); + + if(load_result == -1) { first_load = 1; gamepak_name[0] = '\0'; @@ -3495,7 +3502,7 @@ u32 menu(u16 *screen) if(gamepak_name[0] != 0) { - //S9xAutoSaveSRAM (); + S9xAutoSaveSRAM (); save_game_config_file(); } @@ -3511,7 +3518,12 @@ u32 menu(u16 *screen) *ext_pos= '/'; ext_pos = emu_config.latest_file[current_option_num -1]; - if(load_gamepak(ext_pos) == -1) { + + ds2_setCPUclocklevel(13); + int load_result = load_gamepak(ext_pos); + ds2_setCPUclocklevel(0); + + if(load_result == -1) { first_load = 1; return; } @@ -4129,7 +4141,7 @@ u32 menu(u16 *screen) game_config.clock_speed_number = clock_speed_number; reorder_latest_file(); - //S9xAutoSaveSRAM (); + S9xAutoSaveSRAM (); save_game_config_file(); } save_emu_config_file(); @@ -4308,7 +4320,7 @@ void init_game_config(void) { u32 i; - game_config.clock_speed_number = 2; //360MHz + game_config.clock_speed_number = 5; // 396 MHz by default clock_speed_number = 2; game_config.graphic = 0; -- cgit v1.2.3 From dd06ba36fff3fad1eea457026c21f49a01c78604 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 01:37:10 -0500 Subject: Default to Graphics Mode 3, which displays the correct SNES aspect ratio at the cost of some lines at the top and bottom. --- source/nds/gui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 07f59d0..4c0a9d7 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -4321,8 +4321,8 @@ void init_game_config(void) u32 i; game_config.clock_speed_number = 5; // 396 MHz by default - clock_speed_number = 2; - game_config.graphic = 0; + clock_speed_number = 5; + game_config.graphic = 3; // By default, have a good-looking aspect ratio game_config.gamepad_config_menu = BUTTON_ID_TOUCH; memcpy(game_config.gamepad_config_map, gamepad_config_map_init, sizeof(gamepad_config_map_init)); -- cgit v1.2.3 From eee0a7ecdaa08f15ebeb7821d6e805234dc78c33 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 03:10:55 -0500 Subject: Change the English labels so they're more descriptive. Really set the default CPU frequency to the highest. --- source/nds/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 4c0a9d7..af04c74 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -266,7 +266,7 @@ u32 game_enable_audio = 1; /****************************************************************************** ******************************************************************************/ static u32 menu_cheat_page = 0; -static u32 clock_speed_number = 2; +static u32 clock_speed_number = 5; u32 gamepad_config_menu; /****************************************************************************** -- cgit v1.2.3 From 973cd8d5e37dba2e15de3d3fd1965d2fbfc2cdab Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 18:38:04 -0500 Subject: EN: Link the French translation to the interface. FR: Ajout de la traduction française à l'interface. EN: * bdf_font.c: Add support for having a main font, [0], of more than 128 characters. Refactor character width checks into a new function, BDF_width16_ucs. * bdf_font.h, draw.h, gui.c: Use UTF-8 for all strings to allow more translations. Use BDF_width16_ucs where possible. FR: * bdf_font.c: Prendre en charge une police principale, [0], de plus de 128 caractères. Diriger les vérifications de la largeur d'un caractère vers une nouvelle routine, BDF_width16_ucs. * bdf_font.h, draw.h, gui.c: Utiliser le codage UTF-8 pour toutes les chaînes pour permettre d'autres traductions. Utiliser BDF_width16_ucs là où c'est possible. --- source/font/Pictochat-16.bdf | 2682 ++++++++++++++++++++++++++++++++++++++++++ source/font/README.txt | 40 + source/nds/bdf_font.c | 300 ++--- source/nds/draw.h | 118 +- source/nds/gui.c | 38 +- source/nds/message.h | 2 +- 6 files changed, 2962 insertions(+), 218 deletions(-) create mode 100644 source/font/Pictochat-16.bdf create mode 100644 source/font/README.txt (limited to 'source') diff --git a/source/font/Pictochat-16.bdf b/source/font/Pictochat-16.bdf new file mode 100644 index 0000000..9749a85 --- /dev/null +++ b/source/font/Pictochat-16.bdf @@ -0,0 +1,2682 @@ +STARTFONT 2.1 +FONT -FontForge-Pictochat-Book-R-Normal--16-150-75-75-P-53-ISO10646-1 +SIZE 15 75 75 +FONTBOUNDINGBOX 9 13 0 -1 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +STARTPROPERTIES 37 +FAMILY_NAME "Pictochat" +WEIGHT_NAME "Book" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 16 +POINT_SIZE 150 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "P" +AVERAGE_WIDTH 53 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONTNAME_REGISTRY "" +CHARSET_COLLECTIONS "ISO10646-1" +FONT_NAME "Pictochat" +FACE_NAME "Pictochat Regular" +FONT_VERSION "1.0" +FONT_ASCENT 13 +FONT_DESCENT 3 +UNDERLINE_POSITION 2 +UNDERLINE_THICKNESS 1 +X_HEIGHT 5 +CAP_HEIGHT 8 +RAW_ASCENT 799 +RAW_DESCENT 200 +NORM_SPACE 2 +RELATIVE_WEIGHT 40 +RELATIVE_SETWIDTH 50 +SUPERSCRIPT_X 0 +SUPERSCRIPT_Y 8 +SUPERSCRIPT_SIZE 8 +SUBSCRIPT_X 0 +SUBSCRIPT_Y 0 +SUBSCRIPT_SIZE 8 +AVG_LOWERCASE_WIDTH 55 +AVG_UPPERCASE_WIDTH 56 +ENDPROPERTIES +CHARS 176 +STARTCHAR space +ENCODING 32 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 9 0 0 +BITMAP +80 +80 +80 +80 +80 +80 +00 +80 +80 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 3 0 6 +BITMAP +28 +50 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 9 0 0 +BITMAP +14 +14 +7E +28 +28 +28 +FC +50 +50 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +70 +A8 +A0 +70 +28 +A8 +70 +20 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 9 0 0 +BITMAP +44 +A4 +A8 +48 +10 +24 +2A +4A +44 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 437 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +20 +50 +50 +50 +20 +54 +88 +88 +74 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 1 2 1 7 +BITMAP +80 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +20 +40 +40 +80 +80 +80 +40 +40 +20 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +80 +40 +40 +20 +20 +20 +40 +40 +80 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 7 0 1 +BITMAP +10 +92 +54 +38 +54 +92 +10 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 5 0 2 +BITMAP +20 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 2 2 0 -1 +BITMAP +40 +80 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 1 0 4 +BITMAP +F8 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 1 1 0 0 +BITMAP +80 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +20 +20 +20 +40 +40 +40 +80 +80 +80 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +88 +98 +98 +A8 +C8 +C8 +88 +70 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 2 9 0 0 +BITMAP +C0 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +08 +08 +08 +70 +80 +80 +80 +F8 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +08 +08 +08 +70 +08 +08 +08 +F0 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 437 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +88 +88 +88 +88 +88 +7C +08 +08 +08 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F8 +80 +80 +80 +F0 +08 +08 +08 +F0 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +80 +80 +80 +F0 +88 +88 +88 +70 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F8 +08 +08 +10 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +88 +88 +88 +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +88 +88 +88 +78 +08 +08 +08 +70 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 5 0 2 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 2 6 0 1 +BITMAP +40 +00 +00 +00 +40 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 5 0 2 +BITMAP +20 +40 +80 +40 +20 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 3 0 3 +BITMAP +F8 +00 +F8 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 5 0 2 +BITMAP +80 +40 +20 +40 +80 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +E0 +10 +10 +20 +40 +40 +00 +40 +40 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 9 0 0 +BITMAP +38 +44 +9A +AA +AA +AA +9C +40 +3C +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +88 +88 +88 +F0 +88 +88 +88 +F0 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +78 +80 +80 +80 +80 +80 +80 +80 +78 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +88 +88 +88 +88 +88 +88 +88 +F0 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +F0 +80 +80 +80 +F0 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +F0 +80 +80 +80 +F0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +78 +80 +80 +80 +B8 +88 +88 +88 +70 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +88 +88 +F8 +88 +88 +88 +88 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 9 0 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +10 +10 +10 +10 +10 +10 +10 +10 +E0 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +90 +90 +A0 +C0 +A0 +90 +90 +88 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +D8 +D8 +A8 +A8 +88 +88 +88 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +C8 +C8 +A8 +A8 +98 +98 +88 +88 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +88 +88 +88 +F0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 10 0 -1 +BITMAP +70 +88 +88 +88 +88 +88 +88 +A8 +70 +18 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F0 +88 +88 +88 +F0 +90 +90 +88 +88 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +70 +80 +80 +80 +60 +10 +10 +10 +E0 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +88 +50 +50 +50 +50 +20 +20 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +A8 +A8 +A8 +A8 +50 +50 +50 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +50 +50 +20 +50 +50 +88 +88 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +50 +50 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +F0 +10 +20 +20 +60 +40 +40 +80 +F0 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +E0 +80 +80 +80 +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +80 +80 +80 +40 +40 +40 +20 +20 +20 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +E0 +20 +20 +20 +20 +20 +20 +20 +E0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 2 0 7 +BITMAP +40 +A0 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 1 0 0 +BITMAP +F8 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 2 2 0 7 +BITMAP +80 +40 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +80 +80 +80 +F0 +88 +88 +88 +88 +F0 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +80 +80 +80 +80 +78 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +08 +08 +08 +78 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +F8 +80 +80 +78 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +30 +40 +40 +F0 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +78 +88 +88 +88 +78 +08 +F0 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +80 +80 +80 +F0 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 8 0 0 +BITMAP +80 +00 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 -1 +BITMAP +20 +00 +20 +20 +20 +20 +20 +20 +C0 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +80 +80 +80 +90 +A0 +C0 +A0 +90 +90 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 2 9 0 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +40 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 6 0 0 +BITMAP +FC +92 +92 +92 +92 +92 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F0 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +F0 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +78 +88 +88 +88 +78 +08 +08 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 6 0 0 +BITMAP +B0 +C0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 6 0 0 +BITMAP +70 +80 +60 +10 +10 +E0 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +40 +F0 +40 +40 +40 +40 +30 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +88 +50 +50 +20 +20 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +A8 +A8 +A8 +50 +50 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +88 +50 +20 +20 +50 +88 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +88 +88 +50 +50 +20 +20 +C0 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +10 +20 +40 +80 +F8 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +30 +40 +40 +40 +80 +40 +40 +40 +30 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 1 9 1 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +C0 +20 +20 +20 +10 +20 +20 +20 +C0 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 625 0 +DWIDTH 10 0 +BBX 9 2 0 4 +BITMAP +7880 +8700 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 9 0 0 +BITMAP +80 +80 +00 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 437 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +10 +78 +94 +A0 +A0 +A0 +C4 +78 +40 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +30 +48 +40 +20 +F8 +20 +40 +80 +F8 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +88 +88 +50 +50 +F8 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 125 0 +DWIDTH 2 0 +BBX 1 9 0 0 +BITMAP +80 +80 +80 +80 +00 +80 +80 +80 +80 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 625 0 +DWIDTH 10 0 +BBX 9 9 0 0 +BITMAP +3E00 +4100 +9C80 +A280 +A080 +A280 +9C80 +4100 +3E00 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 625 0 +DWIDTH 10 0 +BBX 9 9 0 0 +BITMAP +3E00 +4100 +BC80 +A280 +BC80 +A480 +A280 +4100 +3E00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 3 0 6 +BITMAP +40 +A0 +40 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 7 0 1 +BITMAP +20 +20 +F8 +20 +20 +00 +F8 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 187 0 +DWIDTH 3 0 +BBX 2 2 0 7 +BITMAP +40 +80 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 2 2 1 3 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +20 +20 +00 +20 +20 +40 +80 +80 +70 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +20 +10 +00 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +20 +40 +00 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 12 0 0 +BITMAP +20 +50 +00 +20 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +28 +50 +00 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +50 +00 +20 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 12 0 0 +BITMAP +20 +50 +20 +00 +20 +50 +50 +50 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 10 0 -1 +BITMAP +70 +80 +80 +80 +80 +80 +80 +70 +20 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 1000 0 +DWIDTH 5 0 +BBX 4 11 0 0 +BITMAP +40 +20 +00 +F0 +80 +80 +F0 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 1000 0 +DWIDTH 5 0 +BBX 4 11 0 0 +BITMAP +20 +40 +00 +F0 +80 +80 +F0 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 1000 0 +DWIDTH 5 0 +BBX 4 11 0 0 +BITMAP +20 +50 +00 +F0 +80 +80 +F0 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 1000 0 +DWIDTH 5 0 +BBX 4 10 0 0 +BITMAP +50 +00 +F0 +80 +80 +F0 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 2 11 0 0 +BITMAP +80 +40 +00 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 2 11 1 0 +BITMAP +40 +80 +00 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 11 0 0 +BITMAP +40 +A0 +00 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 10 0 0 +BITMAP +A0 +00 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +28 +50 +00 +88 +C8 +C8 +A8 +A8 +98 +98 +88 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +40 +20 +00 +70 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +10 +20 +00 +70 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +20 +50 +00 +70 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +28 +50 +00 +70 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +50 +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 5 0 2 +BITMAP +88 +50 +20 +50 +88 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +40 +20 +00 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +10 +20 +00 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 11 0 0 +BITMAP +20 +50 +00 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 10 0 0 +BITMAP +50 +00 +88 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +80 +80 +F0 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +70 +88 +88 +B0 +88 +88 +88 +B0 +80 +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +10 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +10 +20 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +50 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +28 +50 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +50 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 10 0 0 +BITMAP +20 +50 +20 +00 +F0 +08 +78 +88 +88 +78 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 7 0 -1 +BITMAP +70 +80 +80 +80 +70 +20 +40 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +40 +20 +00 +70 +88 +F8 +80 +80 +78 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +10 +20 +00 +70 +88 +F8 +80 +80 +78 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +50 +00 +70 +88 +F8 +80 +80 +78 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +50 +00 +70 +88 +F8 +80 +80 +78 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 2 9 0 0 +BITMAP +80 +40 +00 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 2 9 1 0 +BITMAP +40 +80 +00 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 9 0 0 +BITMAP +40 +A0 +00 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 250 0 +DWIDTH 4 0 +BBX 3 8 0 0 +BITMAP +A0 +00 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +28 +50 +00 +F0 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +40 +20 +00 +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +10 +20 +00 +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +50 +00 +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +28 +50 +00 +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +50 +00 +70 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 5 0 2 +BITMAP +20 +00 +F8 +00 +20 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +40 +20 +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +10 +20 +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +50 +00 +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +50 +00 +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 10 0 -1 +BITMAP +10 +20 +00 +88 +88 +50 +50 +20 +20 +C0 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 -1 +BITMAP +80 +80 +F0 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 -1 +BITMAP +50 +00 +88 +88 +50 +50 +20 +20 +C0 +ENDCHAR +STARTCHAR OE +ENCODING 338 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 9 0 0 +BITMAP +6E +90 +90 +90 +9E +90 +90 +90 +6E +ENDCHAR +STARTCHAR oe +ENCODING 339 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 7 6 0 0 +BITMAP +6C +92 +9E +90 +90 +6E +ENDCHAR +STARTCHAR quotedblleft +ENCODING 8220 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 2 0 7 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR quotedblright +ENCODING 8221 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 2 0 7 +BITMAP +50 +A0 +ENDCHAR +STARTCHAR bullet +ENCODING 8226 +SWIDTH 312 0 +DWIDTH 5 0 +BBX 4 4 0 2 +BITMAP +60 +F0 +F0 +60 +ENDCHAR +STARTCHAR ellipsis +ENCODING 8230 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 5 1 0 0 +BITMAP +A8 +ENDCHAR +STARTCHAR Euro +ENCODING 8364 +SWIDTH 437 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +18 +24 +40 +F0 +40 +F0 +40 +24 +18 +ENDCHAR +STARTCHAR trademark +ENCODING 8482 +SWIDTH 625 0 +DWIDTH 10 0 +BBX 9 4 0 5 +BITMAP +E880 +4D80 +4A80 +4880 +ENDCHAR +STARTCHAR arrowleft +ENCODING 8592 +SWIDTH 625 0 +DWIDTH 10 0 +BBX 9 5 0 2 +BITMAP +2000 +4000 +FF80 +4000 +2000 +ENDCHAR +STARTCHAR arrowup +ENCODING 8593 +SWIDTH 375 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +70 +A8 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR arrowright +ENCODING 8594 +SWIDTH 1000 0 +DWIDTH 10 0 +BBX 9 5 0 2 +BITMAP +0200 +0100 +FF80 +0100 +0200 +ENDCHAR +STARTCHAR arrowdown +ENCODING 8595 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +20 +20 +20 +20 +20 +A8 +70 +20 +ENDCHAR +ENDFONT diff --git a/source/font/README.txt b/source/font/README.txt new file mode 100644 index 0000000..c417cb8 --- /dev/null +++ b/source/font/README.txt @@ -0,0 +1,40 @@ +In this directory, you will find the source file for the main font used by +CATSFC. It's an Adobe BDF file, which is fed into the emulator when running +in "font dump" mode to produce a more efficient representation in an "ODF" +format. The font is based on the one used by Pictochat, with a few more +characters that Pictochat does not have (but no Japanese characters). + +You can edit the font in an application that reads BDF bitmap fonts, such as +FontForge. Open the font in the application then export it again as BDF. +One case where you would want to do this is to add new glyphs to support a +new language. + +To include the more efficient representation (ODF) in CATSFC/system after +editing the BDF file: + + 1. If your font added characters beyond U+2193 DOWNWARDS ARROW, adjust the + maximum codepoint in source/nds/bdf_font.c, after the first instance of + > #ifndef HAVE_ODF + 2. In source/nds/bdf_font.c, + > #define DUMP_ODF + and + > // #define HAVE_ODF + This will make the plugin read the BDF source and write an ODF file. + 3. make + 4. Copy the new plugin to your card, under /_dstwoplug. + 5. Copy the .bdf file to your card, under /CATSFC/system, as Pictochat-16.bdf. + 6. Run the plugin on the Supercard DSTWO. It will briefly load, then display + "Font library initialisation error -1, press any key to exit". This is + because it tries to load the Chinese font's source, Song.bdf, which you + don't have. Regardless, it does dump an ODF file for Pictochat-16.bdf. + 7. Copy the .odf font somewhere on your hard drive if you want to keep a copy + of it. Delete the .bdf file from your card. + 8. Reverse the changes made in step 2. + 9. make +10. Copy the new plugin to your card, under /_dstwoplug. + +And you can use your new font! + +Finally, you may want to send your .bdf source file to a CATSFC developer +or commit it to a fork on Github, for inclusion in the plugin. You may also +want to send your changes to CATSFC/system/language.msg for the same reason. \ No newline at end of file diff --git a/source/nds/bdf_font.c b/source/nds/bdf_font.c index 5da57e3..b1e7ccd 100644 --- a/source/nds/bdf_font.c +++ b/source/nds/bdf_font.c @@ -27,13 +27,13 @@ #include "gui.h" -#define BDF_VERDANA "SYSTEM/verdana.bdf" +#define BDF_PICTOCHAT "SYSTEM/Pictochat-16.bdf" #define BDF_SONG "SYSTEM/song.bdf" -#define ODF_VERDANA "SYSTEM/verdana.odf" +#define ODF_PICTOCHAT "SYSTEM/Pictochat-16.odf" #define ODF_SONG "SYSTEM/song.odf" -#define HAVE_ODF -//#define DUMP_ODF +#define HAVE_ODF // Define this if you have generated Pictochat-16.odf [Neb] +// #define DUMP_ODF // Define this if you want to regenerate Pictochat-16.odf [Neb] #define BDF_LIB_NUM 2 #define ODF_VERSION "1.0" @@ -49,21 +49,24 @@ static u32 fonts_max_height; static u32 bitmap_code(unsigned char *code, unsigned char *bitmap) { unsigned char *map; - u32 a, b, len; + u8 a, b; + u32 len; len= 0; map= (unsigned char*)bitmap; while(*map) { - //character to number, we assume the character can convert to number! + // One hex character represents the state of 4 successive pixels if(*map != 0x0A) { - if(*map <= 0x39) a= *map - 0x30; - else a= *map - 0x37; + if (*map <= '9') a= *map - '0'; + else if (*map <= 'F') a= *map - 'A' + 10; + else if (*map <= 'f') a= *map - 'a' + 10; map++; - if(*map <= 0x39) b= *map - 0x30; - else b= *map - 0x37; + if (*map <= '9') b= *map - '0'; + else if (*map <= 'F') b= *map - 'A' + 10; + else if (*map <= 'f') b= *map - 'a' + 10; *code++ = (a << 4) | b; len++; @@ -108,7 +111,7 @@ static u32 hatoi(char *string) /* * example * -* STARTCHAR 2264 +* STARTCHAR * ENCODING 8804 * SWIDTH 840 0 * DWIDTH 14 0 @@ -202,8 +205,17 @@ static int parse_bdf(char *filename, u32 start, u32 span, struct bdflibinfo *bdf pt += 6; ret= atoi(pt); - bdflibinfop -> start= start; - bdflibinfop -> span= span; + if (method == 1) + bdflibinfop -> start= start; + switch (method) { + case 0: + default: + bdflibinfop -> span= span + start; + break; + case 1: + bdflibinfop -> span= span; + break; + } //construct bdf font information bdffontp= (struct bdffont*)malloc(span * sizeof(struct bdffont)); @@ -241,14 +253,7 @@ static int parse_bdf(char *filename, u32 start, u32 span, struct bdflibinfo *bdf } if(!(strncasecmp(string, "STARTCHAR ", 10))) { - i= hatoi(pt +10); - if(i < start) continue; - else if(i < end) break; - else //Not found the start - { - ret= -7; - goto parse_bdf_error; - } + break; } } @@ -266,7 +271,7 @@ static int parse_bdf(char *filename, u32 start, u32 span, struct bdflibinfo *bdf pt= string + 9; index= atoi(pt); - if(index >= end) break; + if(index < start || index >= end) break; if(method == 0) i= index; else if(method == 1) i= index-start; @@ -534,15 +539,15 @@ int BDF_font_init(void) fonts_max_height= 0; #ifndef HAVE_ODF - sprintf(tmp_path, "%s/%s", main_path, BDF_VERDANA); - err= parse_bdf(tmp_path, 0, 128, &bdflib_info[0], 0); + sprintf(tmp_path, "%s/%s", main_path, BDF_PICTOCHAT); + err= parse_bdf(tmp_path, 32 /* from SPACE */, 8564 /* to one past the last character, "DOWNWARDS ARROW" */, &bdflib_info[0], 1); if(err < 0) { printf("BDF 0 initial error: %d\n", err); return -1; } #else - sprintf(tmp_path, "%s/%s", main_path, ODF_VERDANA); + sprintf(tmp_path, "%s/%s", main_path, ODF_PICTOCHAT); err= init_from_odf(tmp_path, &bdflib_info[0]); if(err < 0) { @@ -556,7 +561,7 @@ int BDF_font_init(void) fonts_max_height = bdflib_info[0].height; #ifdef DUMP_ODF - sprintf(tmp_path, "%s/%s", main_path, BDF_VERDANA); + sprintf(tmp_path, "%s/%s", main_path, BDF_PICTOCHAT); err= dump2odf(tmp_path, &bdflib_info[0]); if(err < 0) { @@ -613,7 +618,7 @@ void BDF_font_release(void) } } -/*----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- //16-bit color // Unicode Character // back is background, 0x8000 is transparence, other are visable colors @@ -626,26 +631,25 @@ u32 BDF_render16_ucs(void* screen_address, u32 screen_w, u32 v_align, u32 back, unsigned char cc; struct bdffont *bdffontp; - if(ch < 128) - { - bdffontp= bdflib_info[0].fonts; - fonts_height= bdflib_info[0].height; - } - else if(bdflib_info[1].fonts != NULL) - { - k= bdflib_info[1].start; - m= k + bdflib_info[1].span; - if(ch >= k && ch < m) - { + int font_num; + bool found = 0; + for (font_num = 0; font_num < BDF_LIB_NUM && !found; font_num++) { + if(bdflib_info[font_num].fonts != NULL) + { + k = bdflib_info[font_num].start; + if (ch < k) + continue; + m = k + bdflib_info[font_num].span; + if (ch >= m) + continue; ch -= k; - bdffontp= bdflib_info[1].fonts; - fonts_height= bdflib_info[0].height; - } - else - return 8; - } - else - return 8; + bdffontp= bdflib_info[font_num].fonts; + fonts_height= bdflib_info[font_num].height; + found = 1; + } + } + if (!found) + return 8; // the width of an undefined character, not an error code width= bdffontp[ch].dwidth >> 16; ret= width; @@ -715,6 +719,27 @@ u32 BDF_render16_ucs(void* screen_address, u32 screen_w, u32 v_align, u32 back, return ret; } +/* Returns the width, in pixels, of a character given its UCS-16 codepoint. */ +u32 BDF_width16_ucs(u16 ch) +{ + u32 k, ret; + + int font_num; + for (font_num = 0; font_num < BDF_LIB_NUM; font_num++) { + if(bdflib_info[font_num].fonts != NULL) + { + k = bdflib_info[font_num].start; + if (ch < k) + continue; + if (ch > k + bdflib_info[font_num].span) + continue; + ch -= k; + return bdflib_info[font_num].fonts[ch].dwidth >> 16; + } + } + return 8; // the width of an undefined character, not an error code +} + /*----------------------------------------------------------------------------- //16-bit color // ASCII Character @@ -837,101 +862,101 @@ void BDF_render_string(void* screen_address, u32 x, u32 y, u32 back, u32 front, /*----------------------------------------------------------------------------- ------------------------------------------------------------------------------*/ -char* utf8decode(char *utf8, u16 *ucs) -{ - unsigned char c = *utf8++; - unsigned long code; - int tail = 0; - - if ((c <= 0x7f) || (c >= 0xc2)) { - /* Start of new character. */ - if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ - code = c; - } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ - tail = 1; - code = c & 0x1f; - } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ - tail = 2; - code = c & 0x0f; - } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ - tail = 3; - code = c & 0x07; - } else { - /* Invalid size. */ - code = 0; - } - - while (tail-- && ((c = *utf8++) != 0)) { - if ((c & 0xc0) == 0x80) { - /* Valid continuation character. */ - code = (code << 6) | (c & 0x3f); - - } else { - /* Invalid continuation char */ - code = 0xfffd; - utf8--; - break; - } - } - } else { - /* Invalid UTF-8 char */ - code = 0; - } - /* currently we don't support chars above U-FFFF */ - *ucs = (code < 0x10000) ? code : 0; - return utf8; -} - -static u8 utf8_ucs2(const char *utf8, u16 *ucs) +char* utf8decode(char *utf8, u16 *ucs) +{ + unsigned char c = *utf8++; + unsigned long code; + int tail = 0; + + if ((c <= 0x7f) || (c >= 0xc2)) { + /* Start of new character. */ + if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ + code = c; + } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ + tail = 1; + code = c & 0x1f; + } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ + tail = 2; + code = c & 0x0f; + } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ + tail = 3; + code = c & 0x07; + } else { + /* Invalid size. */ + code = 0; + } + + while (tail-- && ((c = *utf8++) != 0)) { + if ((c & 0xc0) == 0x80) { + /* Valid continuation character. */ + code = (code << 6) | (c & 0x3f); + + } else { + /* Invalid continuation char */ + code = 0xfffd; + utf8--; + break; + } + } + } else { + /* Invalid UTF-8 char */ + code = 0; + } + /* currently we don't support chars above U-FFFF */ + *ucs = (code < 0x10000) ? code : 0; + return utf8; +} + +static u8 utf8_ucs2(const char *utf8, u16 *ucs) { char *pt = (char*)utf8; - - while(*pt !='\0') - { - pt = utf8decode(pt, ucs++); - } - *ucs = '\0'; - return 0; -} - -static u32 ucslen(const u16 *ucs) -{ + + while(*pt !='\0') + { + pt = utf8decode(pt, ucs++); + } + *ucs = '\0'; + return 0; +} + +static u32 ucslen(const u16 *ucs) +{ u32 len = 0; - - while(ucs[len] != '\0') - len++; - return len; + + while(ucs[len] != '\0') + len++; + return len; } unsigned char* skip_utf8_unit(unsigned char* utf8, unsigned int num) { while(num--) { - unsigned char c = *utf8++; - int tail = 0; - if ((c <= 0x7f) || (c >= 0xc2)) { - /* Start of new character. */ - if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ - } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ - tail = 1; - } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ - tail = 2; - } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ - tail = 3; - } else { /* Invalid size. */ - } - - while (tail-- && ((c = *utf8++) != 0)) { - if ((c & 0xc0) != 0x80) { - /* Invalid continuation char */ - utf8--; - break; - } - } + unsigned char c = *utf8++; + int tail = 0; + if ((c <= 0x7f) || (c >= 0xc2)) { + /* Start of new character. */ + if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ + } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ + tail = 1; + } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ + tail = 2; + } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ + tail = 3; + } else { /* Invalid size. */ + } + + while (tail-- && ((c = *utf8++) != 0)) { + if ((c & 0xc0) != 0x80) { + /* Invalid continuation char */ + utf8--; + break; + } + } } } - /* currently we don't support chars above U-FFFF */ + /* currently we don't support chars above U-FFFF */ return utf8; } @@ -971,10 +996,9 @@ void BDF_render_mix(void* screen_address, u32 screen_w, u32 x, u32 y, u32 v_alig continue; } - if(unicode < 128) - cmp = bdf_fontp[0][unicode].dwidth>>16; - else if(unicode >= start && unicode < end) - cmp = bdf_fontp[1][unicode -start].dwidth>>16; + /* If the text would go beyond the end of the line, go back to the + * start instead. */ + cmp = BDF_width16_ucs(unicode); if((screenp+cmp) >= line_start) { @@ -1074,10 +1098,7 @@ u32 BDF_cut_unicode(u16 *unicodes, u32 len, u32 width, u32 direction) while(len > 0) { unicode= unicodes[i]; - if(unicode < 128) - xw += bdf_fontp[0][unicode].dwidth>>16; - else if(unicode >= start && unicode < end) - xw += bdf_fontp[1][unicode -start].dwidth>>16; + xw += BDF_width16_ucs(unicode); if(xw >= width) break; i += direction; @@ -1096,10 +1117,7 @@ u32 BDF_cut_unicode(u16 *unicodes, u32 len, u32 width, u32 direction) while(len-- > 0) { unicode= unicodes[i]; - if(unicode < 128) - xw += bdf_fontp[0][unicode].dwidth>>16; - else if(unicode >= start && unicode < end) - xw += bdf_fontp[1][unicode -start].dwidth>>16; + xw += BDF_width16_ucs(unicode); i += direction; } diff --git a/source/nds/draw.h b/source/nds/draw.h index 3bdf5be..f40aa23 100644 --- a/source/nds/draw.h +++ b/source/nds/draw.h @@ -17,8 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __DRAW_H__ -#define __DRAW_H__ +#ifndef __DRAW_H__ +#define __DRAW_H__ #include "ds2_types.h" #include "ds2io.h" @@ -27,12 +27,12 @@ #define NDS_SCREEN_WIDTH 256 #define NDS_SCREEN_HEIGHT 192 #define NDS_SCREEN_SIZE (NDS_SCREEN_WIDTH*NDS_SCREEN_HEIGHT) - -#define COLOR16(red, green, blue) ((blue << 10) | (green << 5) | red) -#define GET_R16(color) (color & 0x1f) -#define GET_G16(color) ((color >> 5) & 0x1f) -#define GET_B16(color) ((color >> 10)& 0x1f) -#define COLOR32(red, green, blue) (0xff000000 | ((blue & 0xff) << 16) | ((green & 0xff) << 8) | (red & 0xff)) + +#define COLOR16(red, green, blue) ((blue << 10) | (green << 5) | red) +#define GET_R16(color) (color & 0x1f) +#define GET_G16(color) ((color >> 5) & 0x1f) +#define GET_B16(color) ((color >> 10)& 0x1f) +#define COLOR32(red, green, blue) (0xff000000 | ((blue & 0xff) << 16) | ((green & 0xff) << 8) | (red & 0xff)) #define RGB24_15(pixel) ((((*pixel) & 0xF8) << 7) |\ (((*(pixel+1)) & 0xF8) << 2) |\ @@ -44,36 +44,36 @@ #define PRINT_STRING(screen, str, fg_color, x, y) \ - BDF_render_string(screen, x, y, COLOR_TRANS, fg_color, str) \ + BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, COLOR_TRANS, fg_color, str) \ #define PRINT_STRING_SHADOW(screen, str, fg_color, x, y) \ - BDF_render_string(screen, x+1, y+1, 0, 0, str); \ - BDF_render_string(screen, x, y, 0, 0, str) \ + BDF_render_mix(screen, SCREEN_WIDTH, x+1, y+1, 0, 0, 0, str); \ + BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, 0, 0, str) \ #define PRINT_STRING_BG(screen, str, fg_color, bg_color, x, y) \ - BDF_render_string(screen, x, y, bg_color, fg_color, str) \ + BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, bg_color, fg_color, str) \ + +// #define PRINT_STRING_BG_UTF8(screen, utf8, fg_color, bg_color, x, y) \ +// BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, bg_color, fg_color, utf8) \ -#define PRINT_STRING_BG_UTF8(screen, utf8, fg_color, bg_color, x, y) \ - BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, bg_color, fg_color, utf8) \ - //colors -#define COLOR_TRANS COLOR16(31, 31, 63) -#define COLOR_WHITE COLOR16(31, 31, 31) -#define COLOR_BLACK COLOR16( 0, 0, 0) -#define COLOR_TEXT COLOR16(31, 31, 31) -#define COLOR_PROGRESS_TEXT COLOR16( 0, 0, 0) -#define COLOR_PROGRESS_BAR COLOR16(15, 15, 15) -#define COLOR_ERROR COLOR16(31, 0, 0) -#define COLOR_BG COLOR16(2, 4, 10) -#define COLOR_BG32 COLOR32(2*8, 4*8, 10*8) -#define COLOR_ROM_INFO COLOR16(22, 18, 26) -#define COLOR_ACTIVE_ITEM COLOR16(31, 31, 31) -#define COLOR_INACTIVE_ITEM COLOR16(13, 20, 18) -#define COLOR_HELP_TEXT COLOR16(16, 20, 24) -#define COLOR_DIALOG COLOR16(31, 31, 31) -#define COLOR_DIALOG_SHADOW COLOR16( 0, 2, 8) -#define COLOR_FRAME COLOR16( 0, 0, 0) +#define COLOR_TRANS COLOR16(31, 31, 63) +#define COLOR_WHITE COLOR16(31, 31, 31) +#define COLOR_BLACK COLOR16( 0, 0, 0) +#define COLOR_TEXT COLOR16(31, 31, 31) +#define COLOR_PROGRESS_TEXT COLOR16( 0, 0, 0) +#define COLOR_PROGRESS_BAR COLOR16(15, 15, 15) +#define COLOR_ERROR COLOR16(31, 0, 0) +#define COLOR_BG COLOR16(2, 4, 10) +#define COLOR_BG32 COLOR32(2*8, 4*8, 10*8) +#define COLOR_ROM_INFO COLOR16(22, 18, 26) +#define COLOR_ACTIVE_ITEM COLOR16(31, 31, 31) +#define COLOR_INACTIVE_ITEM COLOR16(13, 20, 18) +#define COLOR_HELP_TEXT COLOR16(16, 20, 24) +#define COLOR_DIALOG COLOR16(31, 31, 31) +#define COLOR_DIALOG_SHADOW COLOR16( 0, 2, 8) +#define COLOR_FRAME COLOR16( 0, 0, 0) #define COLOR_YESNO_TEXT COLOR16( 0, 0, 0) #define COLOR_GREEN COLOR16( 0, 31, 0 ) #define COLOR_GREEN1 COLOR16( 0, 24, 0 ) @@ -81,14 +81,14 @@ #define COLOR_GREEN3 COLOR16( 0, 12, 0 ) #define COLOR_GREEN4 COLOR16( 0, 6, 0 ) #define COLOR_RED COLOR16( 31, 0, 0 ) -#define COLOR_MSSG COLOR16( 16, 8, 29) -/****************************************************************************** - * +#define COLOR_MSSG COLOR16( 16, 8, 29) +/****************************************************************************** + * ******************************************************************************/ #ifdef __cplusplus extern "C" { #endif - + struct background{ char bgname[128]; char bgbuffer[256*192*2]; @@ -151,17 +151,17 @@ extern struct gui_iconlist gui_icon_list[]; #define ICON_CHTFILE gui_icon_list[38] #define ICON_MSG gui_icon_list[39] #define ICON_BUTTON gui_icon_list[40] - -/****************************************************************************** - * - ******************************************************************************/ + +/****************************************************************************** + * + ******************************************************************************/ extern void print_string_center(void* screen_addr, u32 sy, u32 color, u32 bg_color, char *str); -extern void print_string_shadow_center(void* screen_addr, u32 sy, u32 color, char *str); -extern void hline(u32 sx, u32 ex, u32 y, u32 color); -extern void hline_alpha(u32 sx, u32 ex, u32 y, u32 color, u32 alpha); -extern void vline(u32 x, u32 sy, u32 ey, u32 color); -extern void vline_alpha(u32 x, u32 sy, u32 ey, u32 color, u32 alpha); -extern void drawbox(void* screen_address, u32 sx, u32 sy, u32 ex, u32 ey, u32 color); +extern void print_string_shadow_center(void* screen_addr, u32 sy, u32 color, char *str); +extern void hline(u32 sx, u32 ex, u32 y, u32 color); +extern void hline_alpha(u32 sx, u32 ex, u32 y, u32 color, u32 alpha); +extern void vline(u32 x, u32 sy, u32 ey, u32 color); +extern void vline_alpha(u32 x, u32 sy, u32 ey, u32 color, u32 alpha); +extern void drawbox(void* screen_address, u32 sx, u32 sy, u32 ex, u32 ey, u32 color); extern void drawboxfill(void* screen_address, u32 sx, u32 sy, u32 ex, u32 ey, u32 color); extern void draw_selitem(void* screen_address, u32 x, u32 y, u32 color, u32 active); extern void draw_message(void* screen_address, u16 *screen_bg, u32 sx, u32 sy, u32 ex, u32 ey, @@ -173,19 +173,19 @@ extern void draw_string_vcenter(void* screen_address, u32 sx, u32 sy, u32 width, extern u32 draw_hscroll_init(void* screen_address, u32 sx, u32 sy, u32 width, u32 color_bg, u32 color_fg, char *string); extern u32 draw_hscroll(u32 index, s32 scroll_val); -extern void draw_hscroll_over(u32 index); -extern void boxfill_alpha(u32 sx, u32 sy, u32 ex, u32 ey, u32 color, u32 alpha); -extern void init_progress(enum SCREEN_ID screen, u32 total, char *text); -extern void update_progress(void); -extern void show_progress(char *text); -extern void scrollbar(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 all, u32 view, u32 now); +extern void draw_hscroll_over(u32 index); +extern void boxfill_alpha(u32 sx, u32 sy, u32 ex, u32 ey, u32 color, u32 alpha); +extern void init_progress(enum SCREEN_ID screen, u32 total, char *text); +extern void update_progress(void); +extern void show_progress(char *text); +extern void scrollbar(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 all, u32 view, u32 now); extern u32 yesno_dialog(char *text); -extern u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no); -extern void msg_screen_init(const char *title); -extern void msg_screen_draw(); -extern void msg_printf(const char *text, ...); -extern void msg_screen_clear(void); -extern void msg_set_text_color(u32 color); +extern u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no); +extern void msg_screen_init(const char *title); +extern void msg_screen_draw(); +extern void msg_printf(const char *text, ...); +extern void msg_screen_clear(void); +extern void msg_set_text_color(u32 color); extern int icon_init(u32 language_id); extern int gui_change_icon(u32 language_id); @@ -203,5 +203,5 @@ extern void blit_to_screen(void* screen_addr, u16 *src, u32 w, u32 h, u32 dest_x } #endif -#endif //__DRAW_H__ - +#endif //__DRAW_H__ + diff --git a/source/nds/gui.c b/source/nds/gui.c index af04c74..b1b9ce5 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -40,10 +40,11 @@ char rom_path[MAX_PATH]; char gamepak_name[MAX_PATH]; char gcheat_filename[MAX_PATH]; -char *lang[2] = +char *lang[3] = { "English", // 0 "简体中文", // 1 + "Français", // 2 }; /****************************************************************************** @@ -1937,7 +1938,7 @@ u32 menu(u16 *screen) else color= COLOR_INACTIVE_ITEM; - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27); } int slot_index; @@ -1948,7 +1949,7 @@ u32 menu(u16 *screen) slot_index= get_savestate_slot(); sprintf(line_buffer, "%d", (slot_index+2) > SAVE_STATE_SLOT_NUM ? SAVE_STATE_SLOT_NUM : (slot_index+2)); - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 146, 40 + 0*27); + PRINT_STRING_BG(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 146, 40 + 0*27); if(current_option_num == 1) selected = slot_index+1; @@ -2006,7 +2007,7 @@ u32 menu(u16 *screen) else color= COLOR_INACTIVE_ITEM; - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27); } if(current_option_num == 2) @@ -2578,7 +2579,7 @@ u32 menu(u16 *screen) pt = strrchr(tmp_buf, ')'); strcat(line_buffer, pt); - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 40 + display_option-> line_number*27); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 40 + display_option-> line_number*27); } void dynamic_cheat_menu_end() @@ -2801,7 +2802,7 @@ u32 menu(u16 *screen) mm = *(display_option->current_option); sprintf(line_buffer, *(display_option->display_string), str[mm]); - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 27, + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 27, 38 + (display_option-> line_number)*32); } @@ -2913,7 +2914,7 @@ u32 menu(u16 *screen) strcpy(line_buffer, *(display_option->display_string)); line_num= display_option-> line_number; - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 27, + PRINT_STRING_BG(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 27, 40 + (display_option->line_number)*27); num_byte = freespace; @@ -2945,7 +2946,7 @@ u32 menu(u16 *screen) strcat(line_buffer, ".0 GB"); } - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 147, + PRINT_STRING_BG(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 147, 40 + (display_option->line_number)*27); } @@ -2965,7 +2966,7 @@ u32 menu(u16 *screen) char *enable_disable_options[] = { (char*)&msg[MSG_EN_DIS_ABLE_0], (char*)&msg[MSG_EN_DIS_ABLE_1] }; - char *language_options[] = { (char*)&lang[0], (char*)&lang[1] }; + char *language_options[] = { (char*) &lang[0], (char*) &lang[1], (char*) &lang[2] }; char *keyremap_options[] = {(char*)&msg[MSG_KEY_MAP_NONE], (char*)&msg[MSG_KEY_MAP_A], (char*)&msg[MSG_KEY_MAP_B], (char*)&msg[MSG_KEY_MAP_SL], (char*)&msg[MSG_KEY_MAP_ST], (char*)&msg[MSG_KEY_MAP_RT], @@ -3124,7 +3125,7 @@ u32 menu(u16 *screen) /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[MSG_SUB_MENU_42], &clock_speed_number, 6, NULL, 1), /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], language_options, - &emu_config.language, 2, NULL, ACTION_TYPE, 2), + &emu_config.language, 3 /* number of possibilities */, NULL, ACTION_TYPE, 2), /* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_SUB_MENU_43], NULL, &desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3), @@ -3582,7 +3583,7 @@ u32 menu(u16 *screen) else color= COLOR_INACTIVE_ITEM; - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 37 + line_num*32); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 37 + line_num*32); } void game_fastforward() @@ -3758,7 +3759,7 @@ u32 menu(u16 *screen) else color= COLOR_INACTIVE_ITEM; - PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + i*27); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + i*27); } } } @@ -4204,6 +4205,7 @@ int load_language_msg(char *filename, u32 language) switch(language) { case ENGLISH: + default: strcpy(start, "STARTENGLISH"); strcpy(end, "ENDENGLISH"); cmplen= 12; @@ -4213,10 +4215,10 @@ int load_language_msg(char *filename, u32 language) strcpy(end, "ENDCHINESESIM"); cmplen= 15; break; - default: - strcpy(start, "STARTENGLISH"); - strcpy(end, "ENDENGLISH"); - cmplen= 12; + case FRENCH: + strcpy(start, "STARTFRENCH"); + strcpy(end, "ENDFRENCH"); + cmplen= 11; break; } //find the start flag @@ -4898,7 +4900,9 @@ void gui_init(u32 lang_id) flag = load_font(); if(0 != flag) { - err_msg(DOWN_SCREEN, "initial font library error, press any key to exit\n"); + char message[128]; + sprintf(message, "Font library initialisation error %d, press any key to exit\n", flag); + err_msg(DOWN_SCREEN, message); goto gui_init_err; } diff --git a/source/nds/message.h b/source/nds/message.h index fc6bd33..9292d3f 100644 --- a/source/nds/message.h +++ b/source/nds/message.h @@ -165,7 +165,7 @@ enum MSG enum LANGUAGE{ ENGLISH, CHINESE_SIMPLIFIED, - CHINESE_TRADITIONAL + FRENCH }; char *msg[MSG_END+1]; -- cgit v1.2.3 From 100c3bd9e9f9e7fc809434706ddcc2fde96143af Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 18:49:13 -0500 Subject: Make it easier to add new translations to the menu. * source/nds/gui.c: Calculate the number of options based on the array size of language_otions. --- source/nds/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index b1b9ce5..3201665 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -3125,7 +3125,7 @@ u32 menu(u16 *screen) /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[MSG_SUB_MENU_42], &clock_speed_number, 6, NULL, 1), /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], language_options, - &emu_config.language, 3 /* number of possibilities */, NULL, ACTION_TYPE, 2), + &emu_config.language, sizeof(language_options) / sizeof(language_options[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2), /* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_SUB_MENU_43], NULL, &desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3), -- cgit v1.2.3 From ea02ffdf427925058138853a04658e7f3fa0f416 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 19 Dec 2012 19:03:38 -0500 Subject: Widen the space in the font a bit to better match the Pictochat font. --- source/font/Pictochat-16.bdf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/font/Pictochat-16.bdf b/source/font/Pictochat-16.bdf index 9749a85..06117a2 100644 --- a/source/font/Pictochat-16.bdf +++ b/source/font/Pictochat-16.bdf @@ -45,8 +45,8 @@ ENDPROPERTIES CHARS 176 STARTCHAR space ENCODING 32 -SWIDTH 125 0 -DWIDTH 2 0 +SWIDTH 187 0 +DWIDTH 3 0 BBX 1 1 0 0 BITMAP 00 -- cgit v1.2.3 From 80858801300a2f48ad250721a79ebc7b1b0aba92 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 20 Dec 2012 18:10:38 -0500 Subject: Remove the SNES Open Bus behaviour by default. Also simplify translation again. SNES Open Bus is a quirk of the memory subsystem that allow reads of invalid addresses to return the last byte read from memory. However, it is seldom needed by a game, and it costs 1 to 3 MIPS instructions per SNES instruction to emulate. If you need SNES Open Bus, you can remove -DNO_OPEN_BUS from the Makefile. --- source/cpuaddr.h | 80 ++++++++++++++---- source/cpuops.cpp | 36 +++++++- source/getset.h | 31 +++++-- source/globals.cpp | 4 +- source/memmap.h | 9 +- source/nds/gui.c | 8 +- source/nds/message.h | 2 + source/ppu.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++-------- source/ppu.h | 2 + source/sa1.cpp | 9 ++ 10 files changed, 343 insertions(+), 64 deletions(-) (limited to 'source') diff --git a/source/cpuaddr.h b/source/cpuaddr.h index 76344db..4f5febf 100644 --- a/source/cpuaddr.h +++ b/source/cpuaddr.h @@ -146,10 +146,14 @@ void AbsoluteIndexedIndirect (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif +#ifndef NO_OPEN_BUS OpenBus = *(CPU.PC + 1); +#endif CPU.PC += 2; OpAddress = S9xGetWord (ICPU.ShiftedPB + OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif } void AbsoluteIndirectLong (AccessMode a) @@ -163,13 +167,19 @@ void AbsoluteIndirectLong (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif +#ifndef NO_OPEN_BUS OpenBus = *(CPU.PC + 1); +#endif CPU.PC += 2; +#ifndef NO_OPEN_BUS if(a&READ) { OpAddress = S9xGetWord (OpAddress) | ((OpenBus=S9xGetByte (OpAddress + 2)) << 16); } else { +#endif OpAddress = S9xGetWord (OpAddress) | (S9xGetByte (OpAddress + 2) << 16); +#ifndef NO_OPEN_BUS } +#endif } void AbsoluteIndirect (AccessMode a) @@ -183,10 +193,14 @@ void AbsoluteIndirect (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif +#ifndef NO_OPEN_BUS OpenBus = *(CPU.PC + 1); +#endif CPU.PC += 2; OpAddress = S9xGetWord (OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif OpAddress += ICPU.ShiftedPB; } @@ -197,7 +211,9 @@ void Absolute (AccessMode a) #else OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB; #endif +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); +#endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; @@ -211,7 +227,9 @@ void AbsoluteLong (AccessMode a) #else OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16); #endif +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+2); +#endif CPU.PC += 3; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; @@ -220,7 +238,9 @@ void AbsoluteLong (AccessMode a) void Direct(AccessMode a) { +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; @@ -230,14 +250,18 @@ void Direct(AccessMode a) void DirectIndirectIndexed (AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif OpAddress = S9xGetWord (OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif OpAddress += ICPU.ShiftedDB + Registers.Y.W; // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; @@ -247,30 +271,40 @@ void DirectIndirectIndexed (AccessMode a) void DirectIndirectIndexedLong (AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif +#ifndef NO_OPEN_BUS if(a&READ){ OpAddress = S9xGetWord (OpAddress) + ((OpenBus = S9xGetByte (OpAddress + 2)) << 16) + Registers.Y.W; } else { +#endif OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16) + Registers.Y.W; +#ifndef NO_OPEN_BUS } +#endif // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } void DirectIndexedIndirect(AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif OpAddress = S9xGetWord (OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif OpAddress += ICPU.ShiftedDB; #ifndef SA1_OPCODES @@ -283,36 +317,34 @@ void DirectIndexedIndirect(AccessMode a) void DirectIndexedX (AccessMode a) { +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W); OpAddress &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; -#endif - -#ifndef SA1_OPCODES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; // if (Registers.DL != 0) // CPU.Cycles += TWO_CYCLES; // else - CPU.Cycles += ONE_CYCLE; +// CPU.Cycles += ONE_CYCLE; #endif } void DirectIndexedY (AccessMode a) { +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W + Registers.Y.W); OpAddress &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; -#endif - -#ifndef SA1_OPCODES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; // if (Registers.DL != 0) // CPU.Cycles += TWO_CYCLES; // else - CPU.Cycles += ONE_CYCLE; +// CPU.Cycles += ONE_CYCLE; #endif } @@ -324,7 +356,9 @@ void AbsoluteIndexedX (AccessMode a) OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + Registers.X.W; #endif +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); +#endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; @@ -341,7 +375,9 @@ void AbsoluteIndexedY (AccessMode a) OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + Registers.Y.W; #endif +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); +#endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; @@ -357,7 +393,9 @@ void AbsoluteLongIndexedX (AccessMode a) #else OpAddress = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff; #endif +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+2); +#endif CPU.PC += 3; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; @@ -366,13 +404,17 @@ void AbsoluteLongIndexedX (AccessMode a) void DirectIndirect (AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif OpAddress = S9xGetWord (OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif OpAddress += ICPU.ShiftedDB; // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; @@ -380,39 +422,49 @@ void DirectIndirect (AccessMode a) void DirectIndirectLong (AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif +#ifndef NO_OPEN_BUS if(a&READ){ OpAddress = S9xGetWord (OpAddress) + ((OpenBus=S9xGetByte (OpAddress + 2)) << 16); } else { +#endif OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16); +#ifndef NO_OPEN_BUS } +#endif // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; } void StackRelative (AccessMode a) { +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } void StackRelativeIndirectIndexed (AccessMode a) { +#ifndef NO_OPEN_BUS OpenBus = *CPU.PC; +#endif OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif OpAddress = S9xGetWord (OpAddress); +#ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(OpAddress>>8); +#endif OpAddress = (OpAddress + ICPU.ShiftedDB + Registers.Y.W) & 0xffffff; } diff --git a/source/cpuops.cpp b/source/cpuops.cpp index c5adc67..967ca9f 100644 --- a/source/cpuops.cpp +++ b/source/cpuops.cpp @@ -3556,7 +3556,9 @@ static void Op00 (void) PushW (CPU.PC - CPU.PCBase + 1); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3572,7 +3574,9 @@ static void Op00 (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3607,7 +3611,9 @@ void S9xOpcode_IRQ (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3632,7 +3638,9 @@ void S9xOpcode_IRQ (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3669,7 +3677,9 @@ void S9xOpcode_NMI (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3694,7 +3704,9 @@ void S9xOpcode_NMI (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3730,7 +3742,9 @@ static void Op02 (void) PushW (CPU.PC - CPU.PCBase + 1); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3746,7 +3760,9 @@ static void Op02 (void) PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); PushB (Registers.PL); +#ifndef NO_OPEN_BUS OpenBus = Registers.PL; +#endif ClearDecimal (); SetIRQ (); @@ -3905,7 +3921,10 @@ static void Op54X1 (void) Registers.DB = *CPU.PC++; ICPU.ShiftedDB = Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; +#ifndef NO_OPEN_BUS + OpenBus = +#endif + SrcBank = *CPU.PC++; S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), ICPU.ShiftedDB + Registers.Y.W); @@ -3927,7 +3946,10 @@ static void Op54X0 (void) Registers.DB = *CPU.PC++; ICPU.ShiftedDB = Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; +#ifndef NO_OPEN_BUS + OpenBus = +#endif + SrcBank = *CPU.PC++; S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), ICPU.ShiftedDB + Registers.Y.W); @@ -3948,7 +3970,10 @@ static void Op44X1 (void) #endif Registers.DB = *CPU.PC++; ICPU.ShiftedDB = Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; +#ifndef NO_OPEN_BUS + OpenBus = +#endif + SrcBank = *CPU.PC++; S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), ICPU.ShiftedDB + Registers.Y.W); @@ -3968,7 +3993,10 @@ static void Op44X0 (void) #endif Registers.DB = *CPU.PC++; ICPU.ShiftedDB = Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; +#ifndef NO_OPEN_BUS + OpenBus = +#endif + SrcBank = *CPU.PC++; S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), ICPU.ShiftedDB + Registers.Y.W); diff --git a/source/getset.h b/source/getset.h index f04bf95..9b94b22 100644 --- a/source/getset.h +++ b/source/getset.h @@ -98,10 +98,12 @@ #include "obc1.h" #include "seta.h" +#ifndef NO_OPEN_BUS extern "C" { extern uint8 OpenBus; } +#endif uint8 S9xGetByte (uint32 Address) { @@ -178,8 +180,11 @@ uint8 S9xGetByte (uint32 Address) #ifdef DEBUGGER printf ("DEBUG R(B) %06x\n", Address); #endif - return OpenBus; - +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif default: @@ -193,7 +198,11 @@ uint8 S9xGetByte (uint32 Address) #ifdef DEBUGGER printf ("R(B) %06x\n", Address); #endif +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } } @@ -201,8 +210,13 @@ uint16 S9xGetWord (uint32 Address) { if ((Address & 0x0fff) == 0x0fff) { - OpenBus=S9xGetByte (Address); +#ifndef NO_OPEN_BUS + OpenBus = S9xGetByte (Address); return (OpenBus | (S9xGetByte (Address + 1) << 8)); +#else + uint8 Split = S9xGetByte (Address); + return (Split | (S9xGetByte (Address + 1) << 8)); +#endif } int block; uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; @@ -302,8 +316,11 @@ uint16 S9xGetWord (uint32 Address) #ifdef DEBUGGER printf ("DEBUG R(W) %06x\n", Address); #endif - return (OpenBus | (OpenBus<<8)); - +#ifndef NO_OPEN_BUS + return (OpenBus | (OpenBus<<8)); +#else + return 0; // Arbitrarily chosen value [Neb] +#endif default: case CMemory::MAP_NONE: @@ -316,7 +333,11 @@ uint16 S9xGetWord (uint32 Address) #ifdef DEBUGGER printf ("R(W) %06x\n", Address); #endif +#ifndef NO_OPEN_BUS return (OpenBus | (OpenBus<<8)); +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } } diff --git a/source/globals.cpp b/source/globals.cpp index 0103f7e..f00a621 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -157,7 +157,9 @@ uint32 Work32 = 0; signed char Int8 = 0; short Int16 = 0; long Int32 = 0; -unsigned char OpenBus = 0; +#ifndef NO_OPEN_BUS +uint8 OpenBus = 0; +#endif END_EXTERN_C diff --git a/source/memmap.h b/source/memmap.h index 58f0c9f..f838065 100644 --- a/source/memmap.h +++ b/source/memmap.h @@ -276,7 +276,7 @@ bool8 LoadZip(const char* zipname, END_EXTERN_C extern "C" { -void S9xAutoSaveSRAM (); + void S9xAutoSaveSRAM (); } #ifdef NO_INLINE_SET_GET @@ -288,9 +288,12 @@ void S9xSetPCBase (uint32 Address); uint8 *S9xGetMemPointer (uint32 Address); uint8 *GetBasePointer (uint32 Address); -extern "C"{ -extern uint8 OpenBus; +#ifndef NO_OPEN_BUS +extern "C" { + extern uint8 OpenBus; } +#endif + #else #define INLINE inline #include "getset.h" diff --git a/source/nds/gui.c b/source/nds/gui.c index 3201665..61a3b58 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -40,6 +40,8 @@ char rom_path[MAX_PATH]; char gamepak_name[MAX_PATH]; char gcheat_filename[MAX_PATH]; +// If adding a language, make sure you update the size of the array in +// message.h too. char *lang[3] = { "English", // 0 @@ -2966,8 +2968,6 @@ u32 menu(u16 *screen) char *enable_disable_options[] = { (char*)&msg[MSG_EN_DIS_ABLE_0], (char*)&msg[MSG_EN_DIS_ABLE_1] }; - char *language_options[] = { (char*) &lang[0], (char*) &lang[1], (char*) &lang[2] }; - char *keyremap_options[] = {(char*)&msg[MSG_KEY_MAP_NONE], (char*)&msg[MSG_KEY_MAP_A], (char*)&msg[MSG_KEY_MAP_B], (char*)&msg[MSG_KEY_MAP_SL], (char*)&msg[MSG_KEY_MAP_ST], (char*)&msg[MSG_KEY_MAP_RT], (char*)&msg[MSG_KEY_MAP_LF], (char*)&msg[MSG_KEY_MAP_UP], (char*)&msg[MSG_KEY_MAP_DW], @@ -3124,8 +3124,8 @@ u32 menu(u16 *screen) //CPU speed /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[MSG_SUB_MENU_42], &clock_speed_number, 6, NULL, 1), - /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], language_options, - &emu_config.language, sizeof(language_options) / sizeof(language_options[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2), + /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], lang, + &emu_config.language, sizeof(lang) / sizeof(lang[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2), /* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_SUB_MENU_43], NULL, &desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3), diff --git a/source/nds/message.h b/source/nds/message.h index 9292d3f..4a0acd2 100644 --- a/source/nds/message.h +++ b/source/nds/message.h @@ -168,6 +168,8 @@ enum LANGUAGE{ FRENCH }; +extern char* lang[3]; // Allocated in gui.c, needs to match the languages ^ + char *msg[MSG_END+1]; char msg_data[16 * 1024]; diff --git a/source/ppu.cpp b/source/ppu.cpp index 389bdd2..8ba7a5f 100644 --- a/source/ppu.cpp +++ b/source/ppu.cpp @@ -1071,10 +1071,17 @@ void S9xSetPPU (uint8 Byte, uint16 Address) /******************************************************************************/ uint8 S9xGetPPU (uint16 Address) { +#ifndef NO_OPEN_BUS uint8 byte = OpenBus; - +#else + uint8 byte = 0; // Arbitrarily chosen value [Neb] +#endif if(Address<0x2100)//not a real PPU reg +#ifndef NO_OPEN_BUS return OpenBus; //treat as unmapped memory returning last byte on the bus +#else + return 0; // Arbitrarily chosen value [Neb] +#endif if (Address <= 0x2190) { switch (Address) @@ -1086,18 +1093,34 @@ uint8 S9xGetPPU (uint16 Address) #ifdef DEBUGGER missing.oam_address_read = 1; #endif - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2104: case 0x2105: case 0x2106: +#ifndef NO_OPEN_BUS return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2107: +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2108: case 0x2109: case 0x210a: +#ifndef NO_OPEN_BUS return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x210b: case 0x210c: case 0x210d: @@ -1107,8 +1130,14 @@ uint8 S9xGetPPU (uint16 Address) case 0x2111: case 0x2112: case 0x2113: - missing.bg_offset_read = 1; - return OpenBus; +#ifdef DEBUGGER + missing.bg_offset_read = 1; +#endif +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2114: #ifdef DEBUGGER @@ -1116,15 +1145,27 @@ uint8 S9xGetPPU (uint16 Address) #endif case 0x2115: case 0x2116: - return PPU.OpenBus1; +#ifndef NO_OPEN_BUS + return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2117: - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2118: case 0x2119: case 0x211a: - return PPU.OpenBus1; +#ifndef NO_OPEN_BUS + return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x211b: case 0x211c: @@ -1135,25 +1176,45 @@ uint8 S9xGetPPU (uint16 Address) #ifdef DEBUGGER missing.matrix_read = 1; #endif - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2121: case 0x2122: case 0x2123: - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2124: case 0x2125: case 0x2126: - return PPU.OpenBus1; +#ifndef NO_OPEN_BUS + return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2127: - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2128: case 0x2129: case 0x212a: - return PPU.OpenBus1; +#ifndef NO_OPEN_BUS + return PPU.OpenBus1; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x212b: case 0x212c: @@ -1164,7 +1225,11 @@ uint8 S9xGetPPU (uint16 Address) case 0x2131: case 0x2132: case 0x2133: - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2134: case 0x2135: @@ -1182,10 +1247,18 @@ uint8 S9xGetPPU (uint16 Address) #ifdef DEBUGGER missing.matrix_multiply = 1; #endif - return (PPU.OpenBus1 = Memory.FillRAM[Address]); + return ( +#ifndef NO_OPEN_BUS + PPU.OpenBus1 = +#endif + Memory.FillRAM[Address]); case 0x2137: S9xLatchCounters(0); +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2138: // Read OAM (sprite) control data @@ -1230,7 +1303,11 @@ uint8 S9xGetPPU (uint16 Address) #ifdef DEBUGGER missing.oam_read = 1; #endif - return (PPU.OpenBus1 = byte); + return ( +#ifndef NO_OPEN_BUS + PPU.OpenBus1 = +#endif + byte); case 0x2139: // Read vram low byte @@ -1275,7 +1352,9 @@ uint8 S9xGetPPU (uint16 Address) IPPU.FirstVRAMRead = FALSE; } #endif +#ifndef NO_OPEN_BUS PPU.OpenBus1 = byte; +#endif break; case 0x213A: // Read vram high byte @@ -1319,7 +1398,9 @@ uint8 S9xGetPPU (uint16 Address) IPPU.FirstVRAMRead = FALSE; } #endif +#ifndef NO_OPEN_BUS PPU.OpenBus1 = byte; +#endif break; case 0x213B: @@ -1333,7 +1414,11 @@ uint8 S9xGetPPU (uint16 Address) byte = PPU.CGDATA [PPU.CGADD] & 0xff; PPU.CGFLIPRead ^= 1; - return (PPU.OpenBus2 = byte); + return ( +#ifndef NO_OPEN_BUS + PPU.OpenBus2 = +#endif + byte); case 0x213C: // Horizontal counter value 0-339 @@ -1341,10 +1426,19 @@ uint8 S9xGetPPU (uint16 Address) missing.h_counter_read = 1; #endif if (PPU.HBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01); + byte = +#ifndef NO_OPEN_BUS + (PPU.OpenBus2 & 0xfe) +#else + 0 // Arbitrarily chosen value [Neb] +#endif + | ((PPU.HBeamPosLatched >> 8) & 0x01); + else byte = (uint8)PPU.HBeamPosLatched; +#ifndef NO_OPEN_BUS PPU.OpenBus2 = byte; +#endif PPU.HBeamFlip ^= 1; break; @@ -1354,10 +1448,18 @@ uint8 S9xGetPPU (uint16 Address) missing.v_counter_read = 1; #endif if (PPU.VBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01); + byte = +#ifndef NO_OPEN_BUS + (PPU.OpenBus2 & 0xfe) +#else + 0 // Arbitrarily chosen value [Neb] +#endif + | ((PPU.VBeamPosLatched >> 8) & 0x01); else byte = (uint8)PPU.VBeamPosLatched; +#ifndef NO_OPEN_BUS PPU.OpenBus2 = byte; +#endif PPU.VBeamFlip ^= 1; break; @@ -1366,14 +1468,22 @@ uint8 S9xGetPPU (uint16 Address) FLUSH_REDRAW (); //so far, 5c77 version is always 1. - return (PPU.OpenBus1 = (Model->_5C77 | PPU.RangeTimeOver)); + return ( +#ifndef NO_OPEN_BUS + PPU.OpenBus1 = +#endif + (Model->_5C77 | PPU.RangeTimeOver)); case 0x213F: // NTSC/PAL and which field flags PPU.VBeamFlip = PPU.HBeamFlip = 0; //neviksti found a 2 and a 3 here. SNEeSe uses a 3. //XXX: field flags not emulated - return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)| Model->_5C78) | (~PPU.OpenBus2 & 0x20); + return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)| Model->_5C78) +#ifndef NO_OPEN_BUS + | (~PPU.OpenBus2 & 0x20) +#endif + ; case 0x2140: case 0x2141: case 0x2142: case 0x2143: case 0x2144: case 0x2145: case 0x2146: case 0x2147: @@ -1403,7 +1513,7 @@ uint8 S9xGetPPU (uint16 Address) { #ifdef CPU_SHUTDOWN // CPU.WaitAddress = CPU.PCAtOpcodeStart; -#endif +#endif if (SNESGameFixes.APU_OutPorts_ReturnValueFix && Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter) { @@ -1457,10 +1567,18 @@ uint8 S9xGetPPU (uint16 Address) case 0x2181: case 0x2182: case 0x2183: - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif - default: - return OpenBus; + default: +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } } else @@ -1474,15 +1592,23 @@ uint8 S9xGetPPU (uint16 Address) { case 0x21c2: if(Model->_5C77 ==2) - return (0x20); + return (0x20); // fprintf(stderr, "Read from $21c2!\n"); - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x21c3: - if(Model->_5C77 ==2) + if(Model->_5C77 ==2) return (0); // fprintf(stderr, "Read from $21c3!\n"); - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x2800: // For Dai Kaijyu Monogatari II if (Settings.SRTC) @@ -1498,12 +1624,20 @@ uint8 S9xGetPPU (uint16 Address) S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); } #endif - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } } if (!Settings.SuperFX) - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif #ifdef ZSNES_FX if (Address < 0x3040) byte = S9xSuperFXReadReg (Address); @@ -2165,7 +2299,11 @@ uint8 S9xGetCPU (uint16 Address) S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); } #endif - return OpenBus; +#ifndef NO_OPEN_BUS + return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } // return (Memory.FillRAM [Address]); @@ -2189,7 +2327,11 @@ uint8 S9xGetCPU (uint16 Address) case 0x420d: case 0x420e: case 0x420f: +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif case 0x4210: #ifdef CPU_SHUTDOWN @@ -2198,7 +2340,11 @@ uint8 S9xGetCPU (uint16 Address) byte = Memory.FillRAM[0x4210]; Memory.FillRAM[0x4210] = Model->_5A22; //SNEeSe returns 2 for 5A22 version. - return ((byte&0x80)|(OpenBus&0x70)|Model->_5A22); + return ((byte&0x80) +#ifndef NO_OPEN_BUS + |(OpenBus&0x70) +#endif + |Model->_5A22); case 0x4211: byte = (CPU.IRQActive & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) ? 0x80 : 0; @@ -2207,7 +2353,9 @@ uint8 S9xGetCPU (uint16 Address) CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); // Maybe? Register Scan indicated open bus... +#ifndef NO_OPEN_BUS byte |= OpenBus&0x3f; +#endif return (byte); @@ -2216,7 +2364,11 @@ uint8 S9xGetCPU (uint16 Address) #ifdef CPU_SHUTDOWN CPU.WaitAddress = CPU.PCAtOpcodeStart; #endif - return (REGISTER_4212()|(OpenBus&0x3E)); + return (REGISTER_4212() +#ifndef NO_OPEN_BUS + |(OpenBus&0x3E) +#endif + ); case 0x4213: // I/O port input - returns 0 wherever $4201 is 0, and 1 elsewhere @@ -2401,7 +2553,11 @@ uint8 S9xGetCPU (uint16 Address) return Memory.FillRAM[Address]; } +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } // return (Memory.FillRAM[Address]); } @@ -2469,8 +2625,10 @@ void S9xResetPPU () PPU.OAMPriorityRotation = 0; PPU.OAMWriteRegister = 0; PPU.RangeTimeOver = 0; +#ifndef NO_OPEN_BUS PPU.OpenBus1 = 0; PPU.OpenBus2 = 0; +#endif PPU.OAMFlip = 0; PPU.OAMTileAddress = 0; @@ -2665,8 +2823,10 @@ void S9xSoftResetPPU () PPU.OAMPriorityRotation = 0; PPU.OAMWriteRegister = 0; PPU.RangeTimeOver = 0; +#ifndef NO_OPEN_BUS PPU.OpenBus1 = 0; PPU.OpenBus2 = 0; +#endif PPU.OAMFlip = 0; PPU.OAMTileAddress = 0; diff --git a/source/ppu.h b/source/ppu.h index 5a889ef..6daf473 100644 --- a/source/ppu.h +++ b/source/ppu.h @@ -266,8 +266,10 @@ struct SPPU { // XXX Do these need to be added to snapshot.cpp? uint16 OAMWriteRegister; uint8 BGnxOFSbyte; +#ifndef NO_OPEN_BUS uint8 OpenBus1; uint8 OpenBus2; +#endif }; #define CLIP_OR 0 diff --git a/source/sa1.cpp b/source/sa1.cpp index 39b08bb..eb10d33 100644 --- a/source/sa1.cpp +++ b/source/sa1.cpp @@ -228,14 +228,23 @@ uint8 S9xSA1GetByte (uint32 address) #ifdef DEBUGGER // printf ("R(B) %06x\n", address); #endif +#ifndef NO_OPEN_BUS return OpenBus; +#else + return 0; // Arbitrarily chosen value [Neb] +#endif } } uint16 S9xSA1GetWord (uint32 address) { +#ifndef NO_OPEN_BUS OpenBus = S9xSA1GetByte (address); return (OpenBus | (S9xSA1GetByte (address + 1) << 8)); +#else + uint8 Split = S9xSA1GetByte (address); + return (Split | (S9xSA1GetByte (address + 1) << 8)); +#endif } void S9xSA1SetByte (uint8 byte, uint32 address) -- cgit v1.2.3 From 8a4343ff8e4114f19f034130a4b841a6b9a98217 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 20 Dec 2012 19:34:51 -0500 Subject: Bump the version number for NDSSFC. * gui.c: #define NDSSFC_VERSION "1.08". --- source/nds/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 61a3b58..64953be 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -54,7 +54,7 @@ char *lang[3] = ******************************************************************************/ #define SUBMENU_ROW_NUM 6 -#define NDSSFC_VERSION "1.07" +#define NDSSFC_VERSION "1.08" #define SAVE_STATE_SLOT_NUM 10 -- cgit v1.2.3 From 712c249e8c2b614555a6492b520244fe12cd1910 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 20 Dec 2012 23:52:09 -0500 Subject: Simplify the GUI code. * gui.c: Simplify row and column checks when handling touch events. * draw.c, err_msg: Use ConsoleInit instead of a custom drawstring function when an initialisation error that is NOT related to DS2 I/O occurs. This allows \r\n to work. * gui.c, initialisation: Remove the Engrish in the "initial error" messages. Make them appear in English and French. Unfortunately, the console doesn't support Chinese characters, and I don't know Chinese. --- source/nds/draw.c | 54 +------------- source/nds/gui.c | 219 ++++++++++++++++++------------------------------------ 2 files changed, 74 insertions(+), 199 deletions(-) (limited to 'source') diff --git a/source/nds/draw.c b/source/nds/draw.c index 6223c6e..b6c3f9b 100644 --- a/source/nds/draw.c +++ b/source/nds/draw.c @@ -1273,57 +1273,11 @@ void show_log(void* screen_addr) } /*************************************************************/ -extern const unsigned char font_map[128][8]; - -//font size 8*8 -static inline void drawfont(unsigned short *addr, unsigned short f_color, unsigned short b_color, unsigned char ch) -{ - unsigned char *dot_map; - unsigned int j, k; - unsigned char dot; - unsigned short *dst; - - dot_map = (unsigned char*)font_map[ch&0x7F]; - - for(j= 0; j < 8; j++) - { - dot = *dot_map++; - dst = addr + j*SCREEN_WIDTH; - for(k = 0; k < 8; k++) - *dst++ = (dot & (0x80>>k)) ? f_color : b_color; - } -} - -static void drawstring(unsigned int x, unsigned int y, enum SCREEN_ID screen, char *string, - unsigned short f_color, unsigned short b_color) -{ - unsigned short *scr_addr, *dst; - - if(screen & UP_MASK) - scr_addr = up_screen_addr; - else - scr_addr = down_screen_addr; - - if(x>= 32 || y>= 24) return; - - while(*string) - { - dst = scr_addr + (y*8)*SCREEN_WIDTH + x*8; - drawfont(dst, f_color, b_color, *string++); - - x += 1; - if(x>= 32) - { - x = 0; - y+= 1; - if(y >= 24) break; - } - } -} - void err_msg(enum SCREEN_ID screen, char *msg) { - drawstring(0, 0, screen, msg, COLOR16(16, 16, 16), COLOR16(0, 0, 0)); + // A wild console appeared! + ConsoleInit(RGB15(31, 31, 31), RGB15(0, 0, 0), UP_SCREEN, 512); + printf(msg); } /* @@ -1372,5 +1326,3 @@ void blit_to_screen(void* screen_addr, u16 *src, u32 w, u32 h, u32 dest_x, u32 d *dst++ = *src++; } } - - diff --git a/source/nds/gui.c b/source/nds/gui.c index 64953be..f2d9af6 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -403,13 +403,14 @@ static int sort_function(const void *dest_str_ptr, const void *src_str_ptr) char *dest_str = *((char **)dest_str_ptr); char *src_str = *((char **)src_str_ptr); + // For files and directories, . and .. sort first. if(src_str[0] == '.') return 1; if(dest_str[0] == '.') return -1; - return strcasecmp(dest_str, src_str); + return strcasecmp(dest_str, src_str); } static int my_array_partion(void *array, int left, int right) @@ -464,9 +465,9 @@ static void strupr(char *str) } } -//****************************************************************************** +// ****************************************************************************** // get file list -//****************************************************************************** +// ****************************************************************************** #define FILE_LIST_MAX 512 #define DIR_LIST_MAX 64 #define NAME_MEM_SIZE (320*64) @@ -628,7 +629,7 @@ static int load_file_list(struct FILE_LIST_INFO *filelist_infop) strcpy(current_dir_name, filelist_infop -> current_path); - //* path formate should be: "fat:/" or "fat:/dir0" or "fat:", not "fat:/dir0/" + // path formate should be: "fat:/" or "fat:/dir0" or "fat:", not "fat:/dir0/" current_dir = opendir(current_dir_name); //Open directory faiure if(current_dir == NULL) { @@ -792,31 +793,23 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) { case CURSOR_TOUCH: ds2_getrawInput(&inputdata); - if(inputdata.y <= 33) + // ___ 33 This screen has 6 possible rows. Touches + // ___ 60 above or below these are ignored. + // . . . (+27) + // ___ 192 + if(inputdata.y <= 33 || inputdata.y > 192) break; - else if(inputdata.y <= 60) - mod = 0; - else if(inputdata.y <= 87) - mod = 1; - else if(inputdata.y <= 114) - mod = 2; - else if(inputdata.y <= 141) - mod = 3; - else if(inputdata.y <= 168) - mod = 4; - else if(inputdata.y <= 192) - mod = 5; else - break; - + mod = (inputdata.y - 33) / 27; + if(selected_item_on_list - selected_item_on_screen + mod >= total_items_num) break; - + selected_item_on_list = selected_item_on_list - selected_item_on_screen + mod; - + if(selected_item_on_list + 1 <= num_files) { - //The ".." directory + //The ".." directory is the parent if(!strcasecmp(file_list[selected_item_on_list], "..")) { char *ext_pos; @@ -852,7 +845,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) case CURSOR_UP: redraw = 1; if(selected_item_on_screen > 0) - { + { //Not the first item on list selected_item_on_list -= 1; //Selected item on screen center @@ -2868,7 +2861,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_EMU_VERSION0]); - sprintf(line_buffer, "%s %s", msg[MSG_EMU_VERSION1], NDSSFC_VERSION); + sprintf(line_buffer, "%s %s", msg[MSG_EMU_VERSION1], NDSSFC_VERSION); draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, line_buffer); ds2_flipScreen(DOWN_SCREEN, 2); @@ -3461,7 +3454,7 @@ u32 menu(u16 *screen) { draw_hscroll_over(current_option_num-1); ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/'); - draw_hscroll_init(down_screen_addr, 26, 35 + (current_option_num-1)*27, 200, + draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200, COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1); } @@ -3780,26 +3773,13 @@ u32 menu(u16 *screen) /* Main menu */ if(current_menu == &main_menu) { - if(inputdata.x <= 86 && inputdata.y <= 80) - current_option_num = 0; - else if(inputdata.x <= 172 && inputdata.y <= 80) - current_option_num = 1; - else if(inputdata.x <= 256 && inputdata.y <= 80) - current_option_num = 2; - else if(inputdata.x <= 86 && inputdata.y <= 160) - current_option_num = 3; - else if(inputdata.x <= 172 && inputdata.y <= 160) - current_option_num = 4; - else if(inputdata.x <= 256 && inputdata.y <= 160) - current_option_num = 5; - else if(inputdata.x <= 86 && inputdata.y <= 192) - current_option_num = 6; - else if(inputdata.x <= 172 && inputdata.y <= 192) - current_option_num = 7; - else if(inputdata.x <= 256 && inputdata.y <= 192) - current_option_num = 8; - else - break; + // 0 86 172 256 + // _____ _____ _____ 0 + // |0VID_|1SAV_|2CHT_| 80 + // |3TLS_|4OPT_|5EXI_| 160 + // |6NEW_|7RET_|8RST_| 192 + + current_option_num = (inputdata.y / 80) * 3 + (inputdata.x / 86); current_option = current_menu->options + current_option_num; if(current_option -> option_type & HIDEN_TYPE) @@ -3818,31 +3798,22 @@ u32 menu(u16 *screen) && current_menu != (main_menu.options +6)->sub_menu && current_menu != ((main_menu.options +6)->sub_menu->options + 2)->sub_menu) { - if(inputdata.y <= 33) + if (inputdata.y <= 33 || inputdata.y > 192) break; - else if(inputdata.y <= 60) - current_option_num = 1; - else if(inputdata.y <= 87) - current_option_num = 2; - else if(inputdata.y <= 114) - current_option_num = 3; - else if(inputdata.y <= 141) - current_option_num = 4; - else if(inputdata.y <= 168) - current_option_num = 5; - else if(inputdata.y <= 192) - current_option_num = 6; - else - break; - + // ___ 33 This screen has 6 possible rows. Touches + // ___ 60 above or below these are ignored. + // . . . (+27) + // ___ 192 + current_option_num = (inputdata.y - 33) / 27; + current_option = current_menu->options + current_option_num; - + if(current_option -> option_type & HIDEN_TYPE) break; - + if(!current_option) break; - + if(current_menu->key_function) { gui_action = CURSOR_RIGHT; @@ -3885,33 +3856,16 @@ u32 menu(u16 *screen) u32 current_option_val = *(current_option->current_option); u32 old_option_val = current_option_val; - if(inputdata.x <= 25) - break; - else if(inputdata.x <= 45) - current_option_val = 0; - else if(inputdata.x <= 65) - current_option_val = 1; - else if(inputdata.x <= 86) - current_option_val = 2; - else if(inputdata.x <= 107) - current_option_val = 3; - else if(inputdata.x <= 128) - current_option_val = 4; - else if(inputdata.x <= 149) - current_option_val = 5; - else if(inputdata.x <= 170) - current_option_val = 6; - else if(inputdata.x <= 191) - current_option_val = 7; - else if(inputdata.x <= 212) - current_option_val = 8; - else if(inputdata.x <= 233) - current_option_val = 9; - else + if(inputdata.x <= 23 || inputdata.x > 233) break; - + // | | | | | | | | | | | + // 23 44 65 86 ... (+21) 233 + // This row has 10 cells for save states, each 21 + // pixels wide. + current_option_val = (inputdata.x - 23) / 21; + *(current_option->current_option) = current_option_val; - + if(current_option_val == old_option_val) { gui_action = CURSOR_SELECT; @@ -3952,33 +3906,16 @@ u32 menu(u16 *screen) u32 current_option_val = *(current_option->current_option); u32 old_option_val = current_option_val; - if(inputdata.x <= 25) - break; - else if(inputdata.x <= 45) - current_option_val = 0; - else if(inputdata.x <= 65) - current_option_val = 1; - else if(inputdata.x <= 86) - current_option_val = 2; - else if(inputdata.x <= 107) - current_option_val = 3; - else if(inputdata.x <= 128) - current_option_val = 4; - else if(inputdata.x <= 149) - current_option_val = 5; - else if(inputdata.x <= 170) - current_option_val = 6; - else if(inputdata.x <= 191) - current_option_val = 7; - else if(inputdata.x <= 212) - current_option_val = 8; - else if(inputdata.x <= 233) - current_option_val = 9; - else + if(inputdata.x <= 23 || inputdata.x > 233) break; - + // | | | | | | | | | | | + // 23 44 65 86 ... (+21) 233 + // This row has 10 cells for save states, each 21 + // pixels wide. + current_option_val = (inputdata.x - 23) / 21; + *(current_option->current_option) = current_option_val; - + if(current_option_val == old_option_val) { gui_action = CURSOR_SELECT; @@ -4004,25 +3941,16 @@ u32 menu(u16 *screen) || current_menu == (main_menu.options + 6)->sub_menu || current_menu == ((main_menu.options +6)->sub_menu->options + 2)->sub_menu) { - if(inputdata.y <= 33) + if (inputdata.y <= 33 || inputdata.y > 192) break; - else if(inputdata.y <= 60) - current_option_num = 1; - else if(inputdata.y <= 87) - current_option_num = 2; - else if(inputdata.y <= 114) - current_option_num = 3; - else if(inputdata.y <= 141) - current_option_num = 4; - else if(inputdata.y <= 168) - current_option_num = 5; - else if(inputdata.y <= 192) - current_option_num = 6; - else - break; - + // ___ 33 This screen has 6 possible rows. Touches + // ___ 60 above or below these are ignored. + // . . . (+27) The row between 33 and 60 is [1], though! + // ___ 192 + current_option_num = (inputdata.y - 33) / 27 + 1; + current_option = current_menu->options + current_option_num; - + if(current_option -> option_type & HIDEN_TYPE) break; else if(current_option->option_type & ACTION_TYPE) @@ -4150,12 +4078,9 @@ u32 menu(u16 *screen) set_cpu_clock(clock_speed_number); // mdelay(200); // Delete this delay - ds2_clearScreen(DOWN_SCREEN, 0); - ds2_flipScreen(DOWN_SCREEN, 1); - ds2_clearScreen(UP_SCREEN, 0); - ds2_flipScreen(UP_SCREEN, 1); - ds2_clearScreen(UP_SCREEN, 0); - ds2_flipScreen(UP_SCREEN, 1); + ds2_clearScreen(DUAL_SCREEN, 0); + ds2_flipScreen(DUAL_SCREEN, 1); + ds2_flipScreen(UP_SCREEN, 1); // Flip again because otherwise it flickers ds2_setBacklight(2); //save game config @@ -4855,7 +4780,7 @@ void gui_init(u32 lang_id) { int flag; - ds2_setCPUclocklevel(11); + ds2_setCPUclocklevel(13); // Crank it up. When the menu starts, -> 0. printf_clock(); //Find the "CATSFC" system directory @@ -4876,11 +4801,11 @@ void gui_init(u32 lang_id) strcpy(main_path, "fat:"); if(search_dir("CATSFC", main_path) == 0) { - printf("Dirctory find: %s\n", main_path); + printf("Found CATSFC directory\r\nDossier CATSFC trouve\r\n\r\n%s\r\n", main_path); } else { - err_msg(DOWN_SCREEN, "Can't fine CATSFC directory, press any key to exit\n"); + err_msg(DOWN_SCREEN, "/CATSFC: Directory missing\r\nPress any key to return to\r\nthe menu\r\n\r\n/CATSFC: Dossier manquant\r\nAppuyer sur une touche pour\r\nretourner au menu"); goto gui_init_err; } } @@ -4892,7 +4817,7 @@ void gui_init(u32 lang_id) flag = icon_init(lang_id); if(0 != flag) { - err_msg(DOWN_SCREEN, "some icon can't open when initial GUI, press any key to exit\n"); + err_msg(DOWN_SCREEN, "Some icons are missing\r\nLoad them onto your card\r\nPress any key to return to\r\nthe menu\r\n\r\nDes icones sont manquantes\r\nChargez-les sur votre carte\r\nAppuyer sur une touche pour\r\nretourner au menu"); goto gui_init_err; } @@ -4900,8 +4825,8 @@ void gui_init(u32 lang_id) flag = load_font(); if(0 != flag) { - char message[128]; - sprintf(message, "Font library initialisation error %d, press any key to exit\n", flag); + char message[512]; + sprintf(message, "Font library initialisation\r\nerror (%d)\r\nPress any key to return to\r\nthe menu\r\n\r\nErreur d'initalisation de la\r\npolice de caracteres (%d)\r\nAppuyer sur une touche pour\r\nretourner au menu", flag, flag); err_msg(DOWN_SCREEN, message); goto gui_init_err; } @@ -4912,13 +4837,14 @@ void gui_init(u32 lang_id) flag = load_language_msg(LANGUAGE_PACK, lang_id); if(0 != flag) { - err_msg(DOWN_SCREEN, "initial language package error, press any key to exit\n"); + char message[512]; + sprintf(message, "Language pack initialisation\r\nerror (%d)\r\nPress any key to return to\r\nthe menu\r\n\r\nErreur d'initalisation du\r\npack de langue (%d)\r\nAppuyer sur une touche pour\r\nretourner au menu", flag, flag); + err_msg(DOWN_SCREEN, message); goto gui_init_err; } initial_path_config(); - return; gui_init_err: @@ -4927,6 +4853,3 @@ gui_init_err: quit(); while(1); } - - - -- cgit v1.2.3 From 5585c035fbec86ee4bec79865357479142e94b9f Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Fri, 21 Dec 2012 00:05:07 -0500 Subject: Fix an off-by-one in the previous commit's touch handling code. --- source/nds/gui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index f2d9af6..2f9e1d2 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -3802,9 +3802,9 @@ u32 menu(u16 *screen) break; // ___ 33 This screen has 6 possible rows. Touches // ___ 60 above or below these are ignored. - // . . . (+27) + // . . . (+27) The row between 33 and 60 is [1], though! // ___ 192 - current_option_num = (inputdata.y - 33) / 27; + current_option_num = (inputdata.y - 33) / 27 + 1; current_option = current_menu->options + current_option_num; -- cgit v1.2.3 From 3972512b2a5c25236ea3ba586621dba6e5b56361 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Fri, 21 Dec 2012 01:44:57 -0500 Subject: Looks like only having 'lang' crashes the options dialog. Restore the array of pointers. --- source/nds/gui.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 2f9e1d2..bf85b67 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -49,6 +49,8 @@ char *lang[3] = "Français", // 2 }; +char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lang[2] }; + /****************************************************************************** * Macro definition ******************************************************************************/ @@ -3117,8 +3119,8 @@ u32 menu(u16 *screen) //CPU speed /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[MSG_SUB_MENU_42], &clock_speed_number, 6, NULL, 1), - /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], lang, - &emu_config.language, sizeof(lang) / sizeof(lang[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2), + /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], language_options, + &emu_config.language, sizeof(language_options) / sizeof(language_options[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2), /* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_SUB_MENU_43], NULL, &desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3), -- cgit v1.2.3 From a0d0c5e7a5bdc396b4c370a750273b6e3b963bb0 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Fri, 21 Dec 2012 03:50:10 -0500 Subject: Eliminate the latency of button press recognition, which was bad enough to lose keys entirely sometimes, and could otherwise delay a button press or release by 200 ms. This was the entire reason I created the fork, and I finally did it! It syncs the controls every scanline of a frame, which costs about 60,000 MIPS instructions per frame to deal with. Luckily, the processor runs at 396 MHz, which means the cost of checking the controls is 1% of the CPU's power. --- source/cpuexec.cpp | 14 ++++++++++++++ source/nds/ds2_main.c | 52 +++++++++++++++++++++++++-------------------------- source/nds/entry.cpp | 10 ++++++---- source/nds/gui.c | 1 + source/ppu.cpp | 35 +++++++++++++++++++++++++++++++++- source/ppu.h | 3 +++ 6 files changed, 83 insertions(+), 32 deletions(-) (limited to 'source') diff --git a/source/cpuexec.cpp b/source/cpuexec.cpp index 21b1574..5fb79e5 100644 --- a/source/cpuexec.cpp +++ b/source/cpuexec.cpp @@ -105,6 +105,10 @@ #include "sa1.h" #include "spc7110.h" +#ifdef SYNC_JOYPAD_AT_HBLANK +#include "display.h" +#endif + extern void S9xProcessSound (unsigned int); void S9xMainLoop (void) @@ -226,6 +230,16 @@ void S9xDoHBlankProcessing () switch (CPU.WhichEvent) { case HBLANK_START_EVENT: +#ifdef SYNC_JOYPAD_AT_HBLANK + // Re-get the controls every hblank. A resolution algorithm in + // ppu.cpp will determine with greater accuracy whether a key was + // pressed or released during the frame. + uint32 i; + for (i = 0; i < 5; i++) + { + IPPU.JoypadsAtHBlanks [i][CPU.V_Counter] = S9xReadJoypad (i); + } +#endif if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); diff --git a/source/nds/ds2_main.c b/source/nds/ds2_main.c index 710215b..2d73313 100644 --- a/source/nds/ds2_main.c +++ b/source/nds/ds2_main.c @@ -15,19 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "console.h" -#include "fs_api.h" + */ + +#include +#include "console.h" +#include "fs_api.h" #include "ds2io.h" #include "ds2_timer.h" #include "ds2_malloc.h" - -#define BLACK_COLOR RGB15(0, 0, 0) -#define WHITE_COLOR RGB15(31, 31, 31) - -extern int sfc_main (int argc, char **argv); + +#define BLACK_COLOR RGB15(0, 0, 0) +#define WHITE_COLOR RGB15(31, 31, 31) + +extern int sfc_main (int argc, char **argv); #if 0 void ddump_mem(unsigned char* addr, unsigned int len) @@ -42,24 +42,22 @@ void ddump_mem(unsigned char* addr, unsigned int len) } #endif +void ds2_main(void) +{ + int err; +ds2_setCPUclocklevel(13); + //Initial video and audio and other input and output + err = ds2io_initb(512, 22050, 0, 0); + if(err) goto _failure; - -void ds2_main(void) -{ - int err; -ds2_setCPUclocklevel(13); - //Initial video and audio and other input and output - err = ds2io_initb(512, 22050, 0, 0); - if(err) goto _failure; + //Initial file system + err = fat_init(); + if(err) goto _failure; - //Initial file system - err = fat_init(); - if(err) goto _failure; + //go to user main funtion + sfc_main (0, 0); - //go to user main funtion - sfc_main (0, 0); - _failure: - ds2_plug_exit(); -} - + ds2_plug_exit(); +} + diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 24c0e03..467461b 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -90,6 +90,7 @@ void S9xParseDisplayArg (char **argv, int &ind, int) void S9xExit () { + ds2_setCPUclocklevel(13); // Crank it up to exit quickly if(Settings.SPC7110) (*CleanUp7110)(); @@ -382,15 +383,15 @@ void init_sfc_setting(void) Settings.SixteenBit = TRUE; Settings.SupportHiRes = FALSE; - Settings.NetPlay = FALSE; - Settings.ServerName [0] = 0; Settings.ThreadSound = FALSE; Settings.SoundSync = TRUE; Settings.AutoSaveDelay = 0; #ifdef _NETPLAY_SUPPORT + Settings.NetPlay = FALSE; + Settings.ServerName [0] = 0; Settings.Port = NP_DEFAULT_PORT; #endif - Settings.ApplyCheats =FALSE; + Settings.ApplyCheats = FALSE; Settings.TurboMode = FALSE; Settings.TurboSkipFrames = 40; Settings.StretchScreenshots = 1; @@ -1009,7 +1010,8 @@ unsigned int S9xReadJoypad (int which1) key |= (inputdata.key & (1< 679, though.) --- source/cheats.cpp | 35 ++- source/cheats.h | 40 ++-- source/cheats2.cpp | 2 - source/gfx.cpp | 3 +- source/nds/bdf_font.c | 1 + source/nds/cheats3.cpp | 206 ------------------ source/nds/draw.c | 1 + source/nds/entry.cpp | 9 +- source/nds/gcheat.c | 574 ++++++++----------------------------------------- source/nds/gcheat.h | 47 +--- source/nds/gui.c | 93 ++++---- source/nds/gui.h | 72 +++---- 12 files changed, 203 insertions(+), 880 deletions(-) delete mode 100644 source/nds/cheats3.cpp (limited to 'source') diff --git a/source/cheats.cpp b/source/cheats.cpp index 922e08d..dc388d2 100644 --- a/source/cheats.cpp +++ b/source/cheats.cpp @@ -104,20 +104,20 @@ static bool8 S9xAllHex (const char *code, int len) return (TRUE); } -const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte) +const char *S9xProActionReplayToRaw (const char *code, uint32 *address, uint8 *byte) { uint32 data = 0; if (strlen (code) != 8 || !S9xAllHex (code, 8) || sscanf (code, "%x", &data) != 1) return ("Invalid Pro Action Replay code - should be 8 hex digits in length."); - address = data >> 8; - byte = (uint8) data; + *address = data >> 8; + *byte = (uint8) data; return (NULL); } -const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, - uint8 &num_bytes, uint8 bytes[3]) +const char *S9xGoldFingerToRaw (const char *code, uint32 *address, bool8 *sram, + uint8 *num_bytes, uint8 bytes[3]) { char tmp [15]; if (strlen (code) != 14) @@ -125,7 +125,7 @@ const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, strncpy (tmp, code, 5); tmp [5] = 0; - if (sscanf (tmp, "%x", &address) != 1) + if (sscanf (tmp, "%x", address) != 1) return ("Invalid Gold Finger code."); int i; @@ -138,12 +138,12 @@ const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, break; bytes [i] = (uint8) byte; } - num_bytes = i; - sram = code [13] == '1'; + *num_bytes = i; + *sram = code [13] == '1'; return (NULL); } -const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte) +const char *S9xGameGenieToRaw (const char *code, uint32 *address, uint8 *byte) { char new_code [12]; @@ -176,15 +176,14 @@ const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte) } uint32 data = 0; sscanf (new_code, "%x", &data); - byte = (uint8)(data >> 24); - address = data & 0xffffff; - address = ((address & 0x003c00) << 10) + - ((address & 0x00003c) << 14) + - ((address & 0xf00000) >> 8) + - ((address & 0x000003) << 10) + - ((address & 0x00c000) >> 6) + - ((address & 0x0f0000) >> 12) + - ((address & 0x0003c0) >> 6); + *byte = (uint8)(data >> 24); + *address = ((data & 0x003c00) << 10) + + ((data & 0x00003c) << 14) + + ((data & 0xf00000) >> 8) + + ((data & 0x000003) << 10) + + ((data & 0x00c000) >> 6) + + ((data & 0x0f0000) >> 12) + + ((data & 0x0003c0) >> 6); return (NULL); } diff --git a/source/cheats.h b/source/cheats.h index c8bd716..bb2646f 100644 --- a/source/cheats.h +++ b/source/cheats.h @@ -93,21 +93,17 @@ extern "C" { #endif -#define MAX_SFCCHEAT_NAME 24 -#define MAX_CHEATS_T 200 +#define MAX_SFCCHEAT_NAME 48 +#define MAX_CHEATS_T 800 struct SCheat { uint32 address; uint8 byte; uint8 saved_byte; - bool8 enabled; + // bool8 enabled; + uint32 enabled; // THIS IS A TOTAL HACK FOR THE NDSSFC GUI, YOU HAVE BEEN WARNED [Neb] bool8 saved; - uint8 total_part; - uint8 part_id; - uint8 part_len; - uint8 cheat_type; - uint32 name_id; char name[MAX_SFCCHEAT_NAME]; }; @@ -140,10 +136,10 @@ typedef enum void S9xInitCheatData (); -const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte); -const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte); -const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, - uint8 &num_bytes, uint8 bytes[3]); +const char *S9xGameGenieToRaw (const char *code, uint32 *address, uint8 *byte); +const char *S9xProActionReplayToRaw (const char *code, uint32 *address, uint8 *byte); +const char *S9xGoldFingerToRaw (const char *code, uint32 *address, bool8 *sram, + uint8 *num_bytes, uint8 bytes[3]); void S9xApplyCheats (); void S9xApplyCheat (uint32 which1); void S9xRemoveCheats (); @@ -158,25 +154,13 @@ void S9xDeleteCheat (uint32 which1); bool8 S9xLoadCheatFile (const char *filename); bool8 S9xSaveCheatFile (const char *filename); -void S9xStartCheatSearch (SCheatData *); -void S9xSearchForChange (SCheatData *, S9xCheatComparisonType cmp, +void S9xStartCheatSearch (struct SCheatData *cheats); +void S9xSearchForChange (struct SCheatData *cheats, S9xCheatComparisonType cmp, S9xCheatDataSize size, bool8 is_signed, bool8 update); -void S9xSearchForValue (SCheatData *, S9xCheatComparisonType cmp, +void S9xSearchForValue (struct SCheatData *cheats, S9xCheatComparisonType cmp, S9xCheatDataSize size, uint32 value, bool8 is_signed, bool8 update); -void S9xOutputCheatSearchResults (SCheatData *); - - -int S9xAddCheat_ex (unsigned int address, unsigned char* cheat_dat, unsigned int cheat_dat_len, - unsigned int cheat_cell_num, unsigned int part_id, unsigned int str_num); -void S9xAddCheat_ov(unsigned int cheat_cell_num, unsigned int total_part); -unsigned int S9xGetCheat_nameid(unsigned int start, unsigned int part); -void S9xCheat_switch(unsigned int start, unsigned int sub_part, unsigned int enable); -void S9xApplyCheats_ex(void); -void S9xCheat_Disable(void); -void S9xCheat_Enable(void); - -void S9x_dumpcheat(unsigned int id); +void S9xOutputCheatSearchResults (struct SCheatData *cheats); #ifdef __cplusplus } diff --git a/source/cheats2.cpp b/source/cheats2.cpp index 346a9b1..1423637 100644 --- a/source/cheats2.cpp +++ b/source/cheats2.cpp @@ -277,5 +277,3 @@ bool8 S9xSaveCheatFile (const char *filename) fclose (fs); return (TRUE); } - - diff --git a/source/gfx.cpp b/source/gfx.cpp index 14e28a5..16d006e 100644 --- a/source/gfx.cpp +++ b/source/gfx.cpp @@ -771,8 +771,7 @@ void S9xEndScreenRefresh () Settings.SixteenBit); } - //S9xApplyCheats (); - S9xApplyCheats_ex (); + S9xApplyCheats (); #ifdef DEBUGGER if (CPU.Flags & FRAME_ADVANCE_FLAG) { diff --git a/source/nds/bdf_font.c b/source/nds/bdf_font.c index b1e7ccd..773403a 100644 --- a/source/nds/bdf_font.c +++ b/source/nds/bdf_font.c @@ -18,6 +18,7 @@ */ //v1.1 +#include "port.h" #include #include "ds2_types.h" #include "ds2_malloc.h" diff --git a/source/nds/cheats3.cpp b/source/nds/cheats3.cpp deleted file mode 100644 index bdb5545..0000000 --- a/source/nds/cheats3.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* cheats3.cpp - * - * Copyright (C) 2010 dking - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licens e as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "snes9x.h" -#include "cheats.h" -#include "memmap.h" -#include "gcheat.h" - -extern SCheatData Cheat; - -int S9xAddCheat_ex (unsigned int address, unsigned char* cheat_dat, unsigned int cheat_dat_len, - unsigned int cheat_cell_num, unsigned int part_id, unsigned int str_num) -{ - if(cheat_cell_num < MAX_CHEATS_T) - { - Cheat.c[cheat_cell_num].address = address; - Cheat.c[cheat_cell_num].enabled = FALSE; - - if(cheat_dat_len > 1) - memcpy(Cheat.c[cheat_cell_num].name, cheat_dat, cheat_dat_len); - else - Cheat.c[cheat_cell_num].byte = cheat_dat[0]; - - Cheat.c[cheat_cell_num].total_part = 0; //default are sub-part - Cheat.c[cheat_cell_num].part_id = part_id; - Cheat.c[cheat_cell_num].part_len = cheat_dat_len; - Cheat.c[cheat_cell_num].cheat_type = 0; //default are sub-part - Cheat.c[cheat_cell_num].name_id = str_num; - - return 0; - } - - return -1; -} - -void S9xAddCheat_ov(unsigned int cheat_cell_num, unsigned int total_part) -{ - if(cheat_cell_num < MAX_CHEATS_T) - { - Cheat.c[cheat_cell_num].total_part = total_part; //default are sub-part - Cheat.c[cheat_cell_num].cheat_type = 0x80; - } -} - -static unsigned int S9xGetSub_id(unsigned int start, unsigned int sub_part) -{ - unsigned int i, m, n; - - if(0 == sub_part) - return start; - - if((start+1) >= g_cheat_cell_num) - return start; - - m = 0; - for(i= start; i < g_cheat_cell_num; ) - { - n = Cheat.c[i].total_part; - i += n; - m += 1; - if(m == sub_part) break; - } - - return i; -} - -unsigned int S9xGetCheat_nameid(unsigned int start, unsigned int part) -{ -#if 0 - unsigned int m, n, i; - unsigned int ret; - unsigned int cell_num; - - cell_num = g_cheat_cell_num; - - ret = Cheat.c[start].name_id; - if((start+1) >= cell_num) - return ret; - - m = 0; - for(i = start; i < cell_num; ) { - if(m == part) break; - n = Cheat.c[i].total_part; - i += n; - m += 1; - } - - if(i < cell_num) - ret = Cheat.c[i].name_id; - - return ret; -#else - unsigned int i; - - i = S9xGetSub_id(start, part); - return Cheat.c[i].name_id; -#endif -} - -void S9xCheat_switch(unsigned int start, unsigned int sub_part, unsigned int enable) -{ - unsigned int i, m, n; - - if((start+1) >= g_cheat_cell_num) - return; - - i = S9xGetSub_id(start, sub_part); - m = Cheat.c[i].total_part; - for(n = 0; n < m; n++) - Cheat.c[i+n].enabled = enable; -} - -static inline void S9xApplyCheat_ex(unsigned int start, unsigned int num) -{ - unsigned int i, m; - unsigned int address, len; - - for(i = 0; i < num; i++) - { - address = Cheat.c[start+i].address; - len = Cheat.c[start+i].part_len; - - int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; - unsigned char *ptr = Memory.Map [block]; - - if(1 == len) - { - if (ptr >= (uint8 *) CMemory::MAP_LAST) - *(ptr + (address & 0xffff)) = Cheat.c[start+i].byte; - else - S9xSetByte (Cheat.c[start+i].byte, address); - } - else - { - for(m= 0; m < len; m++) - { - if (ptr >= (uint8 *) CMemory::MAP_LAST) - *(ptr + (address & 0xffff)) = Cheat.c[start+i].name[m]; - else - S9xSetByte (Cheat.c[start+i].name[m], address); - } - } - } -} - -void S9xApplyCheats_ex(void) -{ - unsigned int i, m, n; - - if (Settings.ApplyCheats) - { - for(i= 0; i < g_cheat_cell_num; i++) - { - m = Cheat.c[i].total_part; - if(Cheat.c[i].enabled) - S9xApplyCheat_ex(i, m); - i += m; - } - } -} - -#if 1 -extern "C" void dump_mem(unsigned char* addr, unsigned int len); - -void S9x_dumpcheat(unsigned int id) -{ - cprintf("\nid %d------------\n", id); - cprintf("total %d; part %d\n", Cheat.c[id].total_part, Cheat.c[id].part_id); - cprintf("address: %08x; data: %d\n", Cheat.c[id].address, Cheat.c[id].part_len); - if(Cheat.c[id].part_len == 1) - cprintf("data: %02x\n", Cheat.c[id].byte); - else - dump_mem((unsigned char*)Cheat.c[id].name, Cheat.c[id].part_len); - cprintf(" ------\n"); -} -#endif - -void S9xCheat_Disable(void) -{ - Settings.ApplyCheats = FALSE; -} - -void S9xCheat_Enable(void) -{ - Settings.ApplyCheats = TRUE; -} - diff --git a/source/nds/draw.c b/source/nds/draw.c index b6c3f9b..9d1b8ec 100644 --- a/source/nds/draw.c +++ b/source/nds/draw.c @@ -22,6 +22,7 @@ * draw.cpp * basic program to draw some graphic ******************************************************************************/ +#include "port.h" #include #include #include "ds2_malloc.h" diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 467461b..ea5f6ce 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -97,7 +97,8 @@ void S9xExit () S9xSetSoundMute (TRUE); S9xDeinitDisplay (); Memory.SaveSRAM (S9xGetFilename (".srm")); - S9xSaveCheatFile (S9xGetFilename (".cht")); + // S9xSaveCheatFile (S9xGetFilename (".chb")); // cheat binary file + // Do this when loading a cheat file! Memory.Deinit (); S9xDeinitAPU (); @@ -258,7 +259,6 @@ const char *S9xGetSnapshotDirectory () return ((const char*)DEFAULT_RTS_DIR); } - const char *S9xGetFilename (const char *ex) { static char filename [PATH_MAX + 1]; @@ -391,7 +391,7 @@ void init_sfc_setting(void) Settings.ServerName [0] = 0; Settings.Port = NP_DEFAULT_PORT; #endif - Settings.ApplyCheats = FALSE; + Settings.ApplyCheats = TRUE; Settings.TurboMode = FALSE; Settings.TurboSkipFrames = 40; Settings.StretchScreenshots = 1; @@ -457,8 +457,7 @@ int load_gamepak(char* file) Memory.LoadSRAM (S9xGetFilename (".srm")); // mdelay(50); // Delete this delay - //S9xLoadCheatFile (S9xGetFilename (".cht")); - S9xCheat_Disable(); + S9xLoadCheatFile (S9xGetFilename (".chb")); // cheat binary file, as opposed to text #ifdef _NETPLAY_SUPPORT if (strlen (Settings.ServerName) == 0) diff --git a/source/nds/gcheat.c b/source/nds/gcheat.c index 062ce9d..648bfda 100644 --- a/source/nds/gcheat.c +++ b/source/nds/gcheat.c @@ -1,9 +1,9 @@ /* gcheat.c * - * Copyright (C) 2010 dking + * Copyright (C) 2012 GBAtemp user Nebuleon. * * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licens e as + * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * @@ -17,511 +17,111 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "port.h" #include "string.h" #include "fs_api.h" #include "ds2_malloc.h" #include "gcheat.h" #include "charsets.h" +#include "cheats.h" -#define MAX_SFCCHEAT_NAME 24 +extern struct SCheatData Cheat; - -//GCHEAT_STRUCT gcheat[MAX_CHEATS]; -unsigned int g_cheat_cell_num; -unsigned int g_cheat_num; - -#define SKIP_SPACE(pt) while(' ' == *pt) pt++ - -static unsigned char* check_is_cht(unsigned char *str) -{ - unsigned char *pt, *pt1; - - if(*str == '\0') return NULL; - - pt = str; - while(*pt == ' ') pt++; //Skip leading space - if(*pt != '[') return NULL; //valid entry should be:[string] - - pt1 = strrchr(str, ']'); - if(pt1 == NULL) return NULL; - - while(*(--pt1) == ' '); - *(pt1+1) = '\0'; //Cut trailing space between string and ']' - - while(*(++pt) == ' '); //Cut space between '[' and string - - return pt; -} - -static unsigned int sscanf_hex_value(unsigned char* str, unsigned int *value) -{ - unsigned char *pt; - unsigned int tmp; - unsigned char ch; - unsigned int len; - - pt = str; - len = 0; - tmp = 0; - while(*pt && len < 8) - { - ch = *pt; - if(ch >= 'a' && ch <= 'f') ch = ch - 'a' + 0xa; - else if(ch >= 'A' && ch <= 'F') ch = ch - 'A' + 0xa; - else if(ch >= '0' && ch <= '9') ch = ch - '0'; - else if(ch == ' ') continue; - else break; - - tmp = (tmp << 4) | ch; - pt++; - len += 1; - } - - *value = tmp; - return len; -} - -/* -* Convert the src string to UTF8 coding dst string, and cut to length -*/ -int string2utf8(unsigned char *src, unsigned char* dst, unsigned int length) +// Reads a cheat text file in BSNES's format. +int NDSSFCLoadCheatFile(const char* filename) { - unsigned char *pt; - unsigned char ch; - unsigned short ucode; - unsigned int type; - unsigned int len; + FILE* fp = fopen(filename, "r"); + if (fp == NULL) + return -1; - len = 0; - type = 0; - pt = src; - while(*pt) + S9xDeleteCheats(); + + // The construction is "a","b","c" . + // a is ignored. In BSNES, it decides whether the code is enabled. + // b is a series of codes separated by +. Each of the codes is in the form + // accepted by the Game Genie, Pro Action Replay, or the GoldFinger. + // c is the cheat's description. + char line[256], code[24]; + char *description, *codes_ptr; + uint32 address; + uint8 byte; + uint8 bytes [3]; + bool8 sram; + uint8 num_bytes; + + while (fgets(line, sizeof(line), fp)) { - pt = utf8decode(pt, &ucode); - if(ucode < 0x4e00) { - if(ucode == 0 || ucode > 0x7F) { - type = 1; - break; - } - } else if(ucode > 0x9FCF) { - type = 1; - break; + char* ptr = &line[0]; + // Ignore a. + while (*ptr && *ptr != ',') + ptr++; + // If there was no comma, declare a bad file. + if (*ptr == '\0') { + fclose(fp); + return -2; } - else - len++; - - if(len >= 3) break; //There is enough UTF8, so it is, to save time(>_*) - } + *ptr++; // Past the comma + + if (*ptr && *ptr == '"') + ptr++; // Starting quote of b. + codes_ptr = ptr; // Save this for later. + while (*ptr && *ptr != ',') + ptr++; + // If there was no comma, declare a bad file. + if (*ptr == '\0') { + fclose(fp); + return -2; + } + *ptr++; // Past the comma + *(ptr - 1) = '\0'; // End the codes there + + uint32 i = 0; + description = ptr; // Skip starting " in description + while (*description && *description == '"') + description++; + ptr = description; + while (*ptr && !(*ptr == '\r' || *ptr == '\n' || *ptr == '"') && i < MAX_SFCCHEAT_NAME - 1) { + ptr++; // Remove trailing newline/quote in description + i++; // Clip the cheat name to MAX_SFCCHEAT_NAME chars + } + *ptr = '\0'; - if(type == 0) //UTF8 - { - while(*src) - { - ch = *src++; - *dst++ = ch; + uint32 n = 0, c; + // n is the number of cheat codes. Beware of MAX_CHEATS_T. - if(ch < 0x80) { - if(length > 1) length -= 1; - else break; - } else if (ch < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ - if(length > 2) length -= 2; - else break; - *dst++ = *src++; - } else if (ch < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ - if(length > 3) length -= 3; - else break; - *dst++ = *src++; - *dst++ = *src++; - } else if (ch < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ - if(length > 4) length -= 4; - else break; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - } else { - break; + // List of cheat codes having the same description. + ptr = codes_ptr; + while (*ptr && !(*ptr == ',' || *ptr == '"')) { + if (n >= MAX_CHEATS_T) { + fclose(fp); + return 0; } - } - *dst = '\0'; - } - else //assume it is GBK code - { - //GBK to UTF8 - while(*src) - { - ch = *src; - if(ch < 0x80) - { - if(length > 1) length -= 1; - else break; - - *dst++= ch; - src ++; + i = 0; + while (*ptr && *ptr != '+' && i < sizeof(code) - 1) + code[i++] = *ptr++; + code[i] = '\0'; + if (!S9xGameGenieToRaw (code, &address, &byte)) { + S9xAddCheat (FALSE, TRUE, address, byte); + strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); + } + else if (!S9xProActionReplayToRaw (code, &address, &byte)) { + S9xAddCheat (FALSE, TRUE, address, byte); + strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); } - else + else if (!S9xGoldFingerToRaw (code, &address, &sram, &num_bytes, bytes)) { - ucode = charsets_gbk_to_ucs(src); - - if (ucode < 0x800) //2 bytes - { - if(length > 2) length -= 2; - else break; - - *dst++ = 0xC0 | ((ucode >> 6) & 0x1F); - *dst++ = 0x80 | (ucode & 0x3F); - } - else //3 bytes - { - if(length > 3) length -= 3; - else break; - - *dst++ = 0xE0 | (ucode >> 12); - *dst++ = 0x80 | ((ucode >>6) & 0x3F); - *dst++ = 0x80 | (ucode & 0x3F); + for (c = 0; c < num_bytes; c++) { + S9xAddCheat (FALSE, TRUE, address + c, bytes[c]); + strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, 22); } - - src += 2; } - } - *dst = '\0'; - } - - return 0; -} - -int load_cheatname(const char* filename, unsigned int string_num, unsigned int string_len, MSG_TABLE* mssg_table) -{ - FILE *fp; - unsigned char current_line[256]; - unsigned char current_line_tmp[256]; - int len, m; - unsigned char** indexp; - unsigned char* msg; - unsigned char* pt; - - mssg_table->msg_index = (unsigned char**)malloc(string_num*4); - if(NULL == mssg_table->msg_index) - return -1; - - string_len = string_len + string_len/2; - mssg_table->msg_pool = (unsigned char*)malloc((string_len+31)&(~31)); - if(NULL == mssg_table->msg_pool) { - free((void*)mssg_table->msg_index); - return -1; - } - - fp = fopen(filename, "r"); - if(fp == NULL) { - free((void*)mssg_table->msg_index); - free((void*)mssg_table->msg_pool); - return -1; - } - - len = 0; - m= 0; - indexp = mssg_table->msg_index; - msg = mssg_table->msg_pool; - while(fgets(current_line, 256, fp)) - { - unsigned int str_len; - - if((pt = check_is_cht(current_line)) != NULL) - { - if(!strcasecmp(pt, "gameinfo")) - continue; - - string2utf8(pt, current_line_tmp, 255); - - str_len = strlen(current_line_tmp); - strncpy(msg+len, current_line_tmp, str_len); - - indexp[m++] = msg+len; - len += str_len; - msg[len] = '\0'; - len += 1; - - if(len >= string_len) break; - if(m >= string_num) break; - - while(fgets(current_line, 256, fp)) - { - str_len = strlen(current_line); - if(str_len < 4) break; - - if((pt = strchr(current_line, '=')) == NULL) //valid cheat item - break; - - *pt = '\0'; - pt = current_line; - - string2utf8(pt, current_line_tmp, 255); - - str_len = strlen(current_line_tmp); - strncpy(msg+len, current_line_tmp, str_len); - - indexp[m++] = msg+len; - len += str_len; - msg[len] = '\0'; - len += 1; - - if(len >= string_len) break; - if(m >= string_num) break; + else { + fclose(fp); + return -3; // Bad cheat format } - - if(len >= string_len) break; - if(m >= string_num) break; - } - } - - mssg_table -> msg_num = m; - fclose(fp); - -#if 0 -cprintf("string_len %d; len %d\n", string_len, len); -for(m= 0; m msg_num; m++) -{ -cprintf("msg%d:%s\n", m, indexp[m]); -} -#endif - - return 0; -} - -#define MAX_CHEAT_DATE_LEN (MAX_SFCCHEAT_NAME/2) //other part hold the saved data - -/* -* Load cheat file -*/ -int load_cheatfile(const char* filename, unsigned int *string_num, unsigned int *string_len, - GCHEAT_STRUCT *gcheat) -{ - FILE *cheats_file; - unsigned char current_line[256]; - unsigned char current_line_tmp[256]; - unsigned int current_line_len; - unsigned char *pt; - int gcheat_num; - - unsigned int str_num; - unsigned int str_len; - unsigned int cheat_cell_num; - int flag; - - cheats_file = fopen(filename, "r"); - if(NULL == cheats_file) - return -1; - g_cheat_cell_num = 0; - g_cheat_num = 0; - cheat_cell_num = 0; - gcheat_num = 0; - str_num = 0; - str_len = 0; - flag = 0; - - while(fgets(current_line, 256, cheats_file)) - { - if((pt = check_is_cht(current_line)) == NULL) //Check valid cht cheat - continue; - - if(!strcasecmp(pt, "gameinfo")) //maybe file end - continue; - - gcheat[gcheat_num].name_id = str_num; - gcheat[gcheat_num].item_id = cheat_cell_num; - gcheat[gcheat_num].item_num = 0; - - string2utf8(pt, current_line_tmp, CHEAT_NAME_LENGTH); - strcpy(gcheat[gcheat_num].name_shot, current_line_tmp); //store a cut name shot - //Initialize other parameter of gcheat - gcheat[gcheat_num].active = 0; - gcheat[gcheat_num].sub_active = 0; - - current_line_len = strlen(pt); - str_len += current_line_len +1; - str_num++; - - //Cheat items - while(fgets(current_line, 256, cheats_file) != NULL) - { - if(strlen(current_line) < 4) - break; - - if((pt = strchr(current_line, '=')) == NULL) //No valid content - break; - - //one sub item each pass - unsigned int first_part; //first part of a cheat item - unsigned int first_part_id; - unsigned int sub_part_id; - unsigned int hex_len; - - unsigned int cheat_addr; - unsigned char cheat_dat[MAX_CHEAT_DATE_LEN]; - unsigned int cheat_dat_len; - unsigned int str_num_saved; - - str_num_saved = str_num; - str_len += pt - current_line +1; - str_num++; - - first_part = 1; - first_part_id = cheat_cell_num; - sub_part_id = 0; - - //skip name part - pt += 1; - current_line_len = strlen(pt); - - //data part - while(1) - { - //fill current_line buffer as full as possible - if(current_line_len < (MAX_CHEAT_DATE_LEN*3+8)) - { //the data length can fill a cheat cell - if(NULL == strchr(pt, 0x0A)) { //this line not end - memmove(current_line, pt, current_line_len+1); - fgets(current_line+current_line_len, 256-current_line_len, cheats_file); - pt = current_line; - current_line_len = strlen(pt); - } - } -#if 0 -cprintf("------\n"); -cprintf("new %d:[%s]\n", current_line_len, pt); -dump_mem(pt, strlen(pt)); -cprintf("\n------\n"); -#endif - //get address - if(first_part) - { - hex_len = sscanf_hex_value(pt, &cheat_addr); - if(0 == hex_len) { - goto load_cheatfile_error; - } - - pt += hex_len; - current_line_len -= hex_len +1; - // strict to follow the formate - if(',' != *pt++ || '\0' == *pt || 0x0D == *pt || 0x0A == *pt) { - goto load_cheatfile_error; - } - - if(cheat_addr < 0x10000) - cheat_addr |= 0x7e0000; - else { - cheat_addr &= 0xffff; - cheat_addr |= 0x7f0000; - } - } - - //get data - unsigned int tmp, m; - - m = 0; - cheat_dat_len = 0; - while(m++ < MAX_CHEAT_DATE_LEN) - { - hex_len = sscanf_hex_value(pt, &tmp); - if(0 == hex_len) break; - - cheat_dat[cheat_dat_len++] = (unsigned char)tmp; - - pt += hex_len; - current_line_len -= hex_len +1; - if(',' == *pt) pt++; - } - - //In first part, get data error - if(0 == cheat_dat_len) { - if(0 == sub_part_id) - goto load_cheatfile_error; - } - else { - //record data - flag = S9xAddCheat_ex(cheat_addr, cheat_dat, cheat_dat_len, cheat_cell_num++, sub_part_id++, str_num_saved); - if(0 != flag) { - cheat_cell_num -= sub_part_id; - break; - } - } - - if(0 == *pt || 0x0D == *pt || 0x0A == *pt) break; //a line over - - first_part = 0; - if(';' == *pt) first_part = 1, pt += 1; //other address of the cheat cell - else cheat_addr += cheat_dat_len; //more data - } //data part - - //have no enough cheat_cell struct to store cheat - if(0 != flag) break; - - S9xAddCheat_ov(first_part_id, sub_part_id); - gcheat[gcheat_num].item_num += 1; - } //Cheat items - - if(0 != flag) break; - - gcheat_num += 1; - if(gcheat_num >= MAX_CHEATS) - break; - } - - g_cheat_cell_num = cheat_cell_num; - g_cheat_num = gcheat_num; - *string_num = str_num; - *string_len = str_len; - fclose(cheats_file); - -#if 0 -cprintf("g_cheat_num %d; g_cheat_cell_num %d\n", g_cheat_num, g_cheat_cell_num); - -int i; -for(i= 0; i < g_cheat_cell_num; i++) -S9x_dumpcheat(i); - -for(i= 0; i < g_cheat_num; i++) -{ - cprintf("cheat %d\n", i); - cprintf("item num %d; item id %d\n", gcheat[i].item_num, gcheat[i].item_id); -} -#endif - - return 0; - -load_cheatfile_error: - fclose(cheats_file); - return -1; -} - -void gcheat_Managment(GCHEAT_STRUCT *gcheat) -{ - unsigned int i, enable, m, en_flag; - unsigned int active, item_id, sub_active, item_num; - - //no cheat - if(0 == g_cheat_num || 0 == g_cheat_cell_num) { - S9xCheat_Disable(); - return; - } - - enable = 0; - for(i = 0; i < g_cheat_num; i++) - { - active = gcheat[i].active & 0x1; - item_id = gcheat[i].item_id; - item_num = gcheat[i].item_num; - sub_active = gcheat[i].sub_active; - - for(m = 0; m < item_num; m++) - { - en_flag = sub_active == m ? active : 0; - S9xCheat_switch(item_id, m, en_flag); } - - if(active) enable = 1; } - if(enable) - S9xCheat_Enable(); + fclose(fp); + return 0; } - diff --git a/source/nds/gcheat.h b/source/nds/gcheat.h index e5131f6..3c9e440 100644 --- a/source/nds/gcheat.h +++ b/source/nds/gcheat.h @@ -15,51 +15,24 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GCHEAT_H__ -#define __GCHEAT_H__ + */ + +#ifndef __GCHEAT_H__ +#define __GCHEAT_H__ #ifdef __cplusplus extern "C" { #endif - -#define CHEAT_NAME_LENGTH (32) -#define MAX_CHEATS_PAGE 10 -#define CHEATS_PER_PAGE 4 -#define MAX_CHEATS (MAX_CHEATS_PAGE * CHEATS_PER_PAGE) -//Support EMU Cheat(emulator cheat) code -typedef struct -{ - u32 name_id; //name ID in another table - u32 active; //status - u16 item_num; //sub-item number - u16 sub_active; - u32 item_id; //There is another struct array to store the cheat data - char name_shot[CHEAT_NAME_LENGTH]; - u32 reserved; -} GCHEAT_STRUCT; +#include "cheats.h" -typedef struct -{ - unsigned char** msg_index; - unsigned char* msg_pool; - unsigned int msg_num; -} MSG_TABLE; - -extern GCHEAT_STRUCT gcheat[MAX_CHEATS]; -extern unsigned int g_cheat_cell_num; -extern unsigned int g_cheat_num; +#define CHEATS_PER_PAGE 4 +#define MAX_CHEATS_PAGE (MAX_CHEATS_T / CHEATS_PER_PAGE) -extern int load_cheatfile(const char* filename, unsigned int *string_num, - unsigned int *string_len, GCHEAT_STRUCT *gcheat); -extern int load_cheatname(const char* filename, unsigned int string_num, - unsigned int string_len, MSG_TABLE* mssg_table); -extern void gcheat_Managment(GCHEAT_STRUCT *gcheat); +extern int NDSSFCLoadCheatFile(const char* filename); #ifdef __cplusplus } #endif - -#endif //__GCHEAT_H__ + +#endif //__GCHEAT_H__ diff --git a/source/nds/gui.c b/source/nds/gui.c index 4a04efc..84f522f 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -23,6 +23,7 @@ #include #include +#include "port.h" #include "ds2_types.h" #include "ds2io.h" #include "ds2_malloc.h" @@ -35,6 +36,8 @@ #include "bitmap.h" #include "gcheat.h" +extern struct SCheatData Cheat; + char main_path[MAX_PATH]; char rom_path[MAX_PATH]; char gamepak_name[MAX_PATH]; @@ -69,7 +72,7 @@ char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lan EMU_CONFIG emu_config; //game configure file's header -#define GAME_CONFIG_HEADER "GSFC1.0" +#define GAME_CONFIG_HEADER "GSFC1.1" // 1.1 removed cheat names #define GAME_CONFIG_HEADER_SIZE 7 GAME_CONFIG game_config; @@ -110,7 +113,7 @@ static unsigned int savestate_index; NULL, \ &cheat_format_ptr[number], \ enable_disable_options, \ - &(game_config.cheats_flag[number].active), \ + &(Cheat.c[number].enabled), \ 2, \ NULL, \ line_number, \ @@ -1656,8 +1659,8 @@ u32 menu(u16 *screen) u32 first_load = 0; char tmp_filename[MAX_FILE]; char line_buffer[512]; - char cheat_format_str[MAX_CHEATS][41*4]; - char *cheat_format_ptr[MAX_CHEATS]; + char cheat_format_str[MAX_CHEATS_T][41*4]; + char *cheat_format_ptr[MAX_CHEATS_T]; MENU_TYPE *current_menu; MENU_OPTION_TYPE *current_option; @@ -2214,19 +2217,18 @@ u32 menu(u16 *screen) unsigned char **dynamic_cheat_pt = NULL; unsigned int dynamic_cheat_active; int dynamic_cheat_scroll_value= 0; - MSG_TABLE cheat_msg= {NULL, NULL}; void cheat_menu_init() { - for(i = 0; i < MAX_CHEATS; i++) + for(i = 0; i < MAX_CHEATS_T; i++) { - if(i >= g_cheat_num) + if(i >= Cheat.num_cheats) { sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_NON_LOAD], i); } else { - sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, game_config.cheats_flag[i].name_shot); + sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, Cheat.c[i].name); } cheat_format_ptr[i]= cheat_format_str[i]; @@ -2237,13 +2239,11 @@ u32 menu(u16 *screen) void cheat_menu_end() { - if(!first_load) - gcheat_Managment(game_config.cheats_flag); } void dynamic_cheat_key() { - unsigned int m, n; + unsigned int m, n; switch(gui_action) { @@ -2455,11 +2455,12 @@ u32 menu(u16 *screen) unsigned int nums; nums = (CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1; - if(gui_action == CURSOR_SELECT && nums < g_cheat_num) + if(gui_action == CURSOR_SELECT && nums < Cheat.num_cheats) { unsigned int m; - nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num; + // nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num; + // REVISIT [Neb] if(dynamic_cheat_options) { @@ -2497,7 +2498,8 @@ u32 menu(u16 *screen) dynamic_cheat_options[0].action_function = NULL; dynamic_cheat_options[0].passive_function = NULL; dynamic_cheat_options[0].sub_menu = &cheats_menu; - dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id); + // dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id); + // REVISIT [Neb] dynamic_cheat_options[0].options = NULL; dynamic_cheat_options[0].current_option = NULL; dynamic_cheat_options[0].num_options = 0; @@ -2505,13 +2507,15 @@ u32 menu(u16 *screen) dynamic_cheat_options[0].line_number = 0; dynamic_cheat_options[0].option_type = SUBMENU_TYPE; - m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id; + // m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id; + // REVISIT [Neb] for(i= 0; i < nums; i++) { dynamic_cheat_options[i+1].action_function = dynamic_cheat_action; dynamic_cheat_options[i+1].passive_function = NULL; dynamic_cheat_options[i+1].sub_menu = NULL; - dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num)); + // dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num)); + // REVISIT [Neb] dynamic_cheat_options[i+1].options = NULL; dynamic_cheat_options[i+1].current_option = NULL; dynamic_cheat_options[i+1].num_options = 2; @@ -2520,10 +2524,11 @@ u32 menu(u16 *screen) dynamic_cheat_options[i+1].option_type = ACTION_TYPE; } - dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + - current_option_num -1].active & 0x1; - dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + - current_option_num -1].sub_active << 16; + // dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + + // current_option_num -1].active & 0x1; + // dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + + // current_option_num -1].sub_active << 16; + // REVISIT [Neb] //Initial srollable options int k; @@ -2585,7 +2590,8 @@ u32 menu(u16 *screen) unsigned int m, k; m = cheats_menu.focus_option-1; - game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + m].sub_active = dynamic_cheat_active >> 16; + // game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + m].sub_active = dynamic_cheat_active >> 16; + // REVISIT [Neb] k = SUBMENU_ROW_NUM +1; for(m= 0; m>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif + (*op)(Addr); } -void AbsoluteIndirectLong (AccessMode a) +static void AbsoluteIndirectLong (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = *(uint16 *) CPU.PC; + Addr = *(uint16 *) CPU.PC; #else - OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8); #endif #ifndef SA1_OPCODES @@ -173,21 +199,23 @@ void AbsoluteIndirectLong (AccessMode a) CPU.PC += 2; #ifndef NO_OPEN_BUS if(a&READ) { - OpAddress = S9xGetWord (OpAddress) | ((OpenBus=S9xGetByte (OpAddress + 2)) << 16); + Addr = S9xGetWord (Addr) | ((OpenBus=S9xGetByte (Addr + 2)) << 16); } else { #endif - OpAddress = S9xGetWord (OpAddress) | (S9xGetByte (OpAddress + 2) << 16); + Addr = S9xGetWord (Addr) | (S9xGetByte (Addr + 2) << 16); #ifndef NO_OPEN_BUS } #endif + (*op)(Addr); } -void AbsoluteIndirect (AccessMode a) +static void AbsoluteIndirect (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = *(uint16 *) CPU.PC; + Addr = *(uint16 *) CPU.PC; #else - OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8); #endif #ifndef SA1_OPCODES @@ -197,19 +225,21 @@ void AbsoluteIndirect (AccessMode a) OpenBus = *(CPU.PC + 1); #endif CPU.PC += 2; - OpAddress = S9xGetWord (OpAddress); + Addr = S9xGetWord (Addr); #ifndef NO_OPEN_BUS - if(a&READ) OpenBus = (uint8)(OpAddress>>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - OpAddress += ICPU.ShiftedPB; + Addr += ICPU.ShiftedPB; + (*op)(Addr); } -void Absolute (AccessMode a) +static void Absolute (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = *(uint16 *) CPU.PC + ICPU.ShiftedDB; + Addr = *(uint16 *) CPU.PC + ICPU.ShiftedDB; #else - OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB; + Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB; #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); @@ -218,14 +248,16 @@ void Absolute (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif + (*op)(Addr); } -void AbsoluteLong (AccessMode a) +static void AbsoluteLong (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = (*(uint32 *) CPU.PC) & 0xffffff; + Addr = (*(uint32 *) CPU.PC) & 0xffffff; #else - OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16); #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+2); @@ -234,78 +266,82 @@ void AbsoluteLong (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif + (*op)(Addr); } -void Direct(AccessMode a) +static void Direct(AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -void DirectIndirectIndexed (AccessMode a) +static void DirectIndirectIndexed (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - OpAddress = S9xGetWord (OpAddress); + Addr = S9xGetWord (Addr); #ifndef NO_OPEN_BUS - if(a&READ) OpenBus = (uint8)(OpAddress>>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - OpAddress += ICPU.ShiftedDB + Registers.Y.W; + Addr += ICPU.ShiftedDB + Registers.Y.W; // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; // XXX: always add one if STA // XXX: else Add one cycle if crosses page boundary + (*op)(Addr); } -void DirectIndirectIndexedLong (AccessMode a) +static void DirectIndirectIndexedLong (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif #ifndef NO_OPEN_BUS if(a&READ){ - OpAddress = S9xGetWord (OpAddress) + ((OpenBus = S9xGetByte (OpAddress + 2)) << 16) + Registers.Y.W; + Addr = S9xGetWord (Addr) + ((OpenBus = S9xGetByte (Addr + 2)) << 16) + Registers.Y.W; } else { #endif - OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16) + Registers.Y.W; + Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16) + Registers.Y.W; #ifndef NO_OPEN_BUS } #endif // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -void DirectIndexedIndirect(AccessMode a) +static void DirectIndexedIndirect(AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - OpAddress = S9xGetWord (OpAddress); + Addr = S9xGetWord (Addr); #ifndef NO_OPEN_BUS - if(a&READ) OpenBus = (uint8)(OpAddress>>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - OpAddress += ICPU.ShiftedDB; + Addr += ICPU.ShiftedDB; #ifndef SA1_OPCODES // if (Registers.DL != 0) @@ -313,15 +349,16 @@ void DirectIndexedIndirect(AccessMode a) // else CPU.Cycles += ONE_CYCLE; #endif + (*op)(Addr); } -void DirectIndexedX (AccessMode a) +static void DirectIndexedX (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W); - OpAddress &= CheckEmulation() ? 0xff : 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W); + Addr &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; @@ -330,15 +367,16 @@ void DirectIndexedX (AccessMode a) // else // CPU.Cycles += ONE_CYCLE; #endif + (*op)(Addr); } -void DirectIndexedY (AccessMode a) +static void DirectIndexedY (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W + Registers.Y.W); - OpAddress &= CheckEmulation() ? 0xff : 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W + Registers.Y.W); + Addr &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; // if (Registers.DL != 0) @@ -346,14 +384,16 @@ void DirectIndexedY (AccessMode a) // else // CPU.Cycles += ONE_CYCLE; #endif + (*op)(Addr); } -void AbsoluteIndexedX (AccessMode a) +static void AbsoluteIndexedX (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W; + Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W; #else - OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + + Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + Registers.X.W; #endif #ifndef NO_OPEN_BUS @@ -365,14 +405,16 @@ void AbsoluteIndexedX (AccessMode a) #endif // XXX: always add one cycle for ROL, LSR, etc // XXX: else is cross page boundary add one cycle + (*op)(Addr); } -void AbsoluteIndexedY (AccessMode a) +static void AbsoluteIndexedY (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W; + Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W; #else - OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + + Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + Registers.Y.W; #endif #ifndef NO_OPEN_BUS @@ -384,14 +426,16 @@ void AbsoluteIndexedY (AccessMode a) #endif // XXX: always add cycle for STA // XXX: else is cross page boundary add one cycle + (*op)(Addr); } -void AbsoluteLongIndexedX (AccessMode a) +static void AbsoluteLongIndexedX (AccessMode a, InternalOp op) { + long Addr; #ifdef FAST_LSB_WORD_ACCESS - OpAddress = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff; + Addr = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff; #else - OpAddress = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff; + Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff; #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+2); @@ -400,73 +444,78 @@ void AbsoluteLongIndexedX (AccessMode a) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif + (*op)(Addr); } -void DirectIndirect (AccessMode a) +static void DirectIndirect (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - OpAddress = S9xGetWord (OpAddress); + Addr = S9xGetWord (Addr); #ifndef NO_OPEN_BUS - if(a&READ) OpenBus = (uint8)(OpAddress>>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - OpAddress += ICPU.ShiftedDB; + Addr += ICPU.ShiftedDB; // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -void DirectIndirectLong (AccessMode a) +static void DirectIndirectLong (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif #ifndef NO_OPEN_BUS if(a&READ){ - OpAddress = S9xGetWord (OpAddress) + ((OpenBus=S9xGetByte (OpAddress + 2)) << 16); + Addr = S9xGetWord (Addr) + ((OpenBus=S9xGetByte (Addr + 2)) << 16); } else { #endif - OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16); + Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16); #ifndef NO_OPEN_BUS } #endif // if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -void StackRelative (AccessMode a) +static void StackRelative (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif + (*op)(Addr); } -void StackRelativeIndirectIndexed (AccessMode a) +static void StackRelativeIndirectIndexed (AccessMode a, InternalOp op) { #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff; + long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif - OpAddress = S9xGetWord (OpAddress); + Addr = S9xGetWord (Addr); #ifndef NO_OPEN_BUS - if(a&READ) OpenBus = (uint8)(OpAddress>>8); + if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - OpAddress = (OpAddress + ICPU.ShiftedDB + + Addr = (Addr + ICPU.ShiftedDB + Registers.Y.W) & 0xffffff; + (*op)(Addr); } #endif diff --git a/source/cpumacro.h b/source/cpumacro.h index 5b4e15b..335576a 100644 --- a/source/cpumacro.h +++ b/source/cpumacro.h @@ -90,21 +90,21 @@ #ifndef _CPUMACRO_H_ #define _CPUMACRO_H_ -void SetZN16 (uint16 Work) +static void SetZN16 (uint16 Work) { ICPU._Zero = Work != 0; ICPU._Negative = (uint8) (Work >> 8); } -void SetZN8 (uint8 Work) +static void SetZN8 (uint8 Work) { ICPU._Zero = Work; ICPU._Negative = Work; } -void ADC8 () +static void ADC8 (long Addr) { - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); if (CheckDecimal ()) { @@ -159,9 +159,9 @@ void ADC8 () } } -void ADC16 () +static void ADC16 (long Addr) { - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); if (CheckDecimal ()) { @@ -235,19 +235,19 @@ void ADC16 () } } -void AND16 () +static void AND16 (long Addr) { - Registers.A.W &= S9xGetWord (OpAddress); + Registers.A.W &= S9xGetWord (Addr); SetZN16 (Registers.A.W); } -void AND8 () +static void AND8 (long Addr) { - Registers.AL &= S9xGetByte (OpAddress); + Registers.AL &= S9xGetByte (Addr); SetZN8 (Registers.AL); } -void A_ASL16 () +static inline void A_ASL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -257,7 +257,7 @@ void A_ASL16 () SetZN16 (Registers.A.W); } -void A_ASL8 () +static inline void A_ASL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -267,97 +267,97 @@ void A_ASL8 () SetZN8 (Registers.AL); } -void ASL16 () +static void ASL16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); ICPU._Carry = (Work16 & 0x8000) != 0; Work16 <<= 1; - //S9xSetWord (Work16, OpAddress); - S9xSetByte(Work16>>8, OpAddress+1); - S9xSetByte(Work16&0xFF, OpAddress); + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16>>8, Addr+1); + S9xSetByte(Work16&0xFF, Addr); SetZN16 (Work16); } -void ASL8 () +static void ASL8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); ICPU._Carry = (Work8 & 0x80) != 0; Work8 <<= 1; - S9xSetByte (Work8, OpAddress); + S9xSetByte (Work8, Addr); SetZN8 (Work8); } -void BIT16 () +static void BIT16 (long Addr) { - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); ICPU._Overflow = (Work16 & 0x4000) != 0; ICPU._Negative = (uint8) (Work16 >> 8); ICPU._Zero = (Work16 & Registers.A.W) != 0; } -void BIT8 () +static void BIT8 (long Addr) { - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); ICPU._Overflow = (Work8 & 0x40) != 0; ICPU._Negative = Work8; ICPU._Zero = Work8 & Registers.AL; } -void CMP16 () +static void CMP16 (long Addr) { Int32 = (long) Registers.A.W - - (long) S9xGetWord (OpAddress); + (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); } -void CMP8 () +static void CMP8 (long Addr) { Int16 = (short) Registers.AL - - (short) S9xGetByte (OpAddress); + (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); } -void CMX16 () +static void CMX16 (long Addr) { Int32 = (long) Registers.X.W - - (long) S9xGetWord (OpAddress); + (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); } -void CMX8 () +static void CMX8 (long Addr) { Int16 = (short) Registers.XL - - (short) S9xGetByte (OpAddress); + (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); } -void CMY16 () +static void CMY16 (long Addr) { Int32 = (long) Registers.Y.W - - (long) S9xGetWord (OpAddress); + (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); } -void CMY8 () +static void CMY8 (long Addr) { Int16 = (short) Registers.YL - - (short) S9xGetByte (OpAddress); + (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); } -void A_DEC16 () +static inline void A_DEC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -370,7 +370,7 @@ void A_DEC16 () SetZN16 (Registers.A.W); } -void A_DEC8 () +static inline void A_DEC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -383,7 +383,7 @@ void A_DEC8 () SetZN8 (Registers.AL); } -void DEC16 () +static void DEC16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -392,14 +392,14 @@ void DEC16 () CPU.WaitAddress = NULL; #endif - Work16 = S9xGetWord (OpAddress) - 1; - //S9xSetWord (Work16, OpAddress); - S9xSetByte (Work16>>8, OpAddress+1); - S9xSetByte (Work16&0xFF, OpAddress); + Work16 = S9xGetWord (Addr) - 1; + //S9xSetWord (Work16, Addr); + S9xSetByte (Work16>>8, Addr+1); + S9xSetByte (Work16&0xFF, Addr); SetZN16 (Work16); } -void DEC8 () +static void DEC8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -408,24 +408,24 @@ void DEC8 () CPU.WaitAddress = NULL; #endif - Work8 = S9xGetByte (OpAddress) - 1; - S9xSetByte (Work8, OpAddress); + Work8 = S9xGetByte (Addr) - 1; + S9xSetByte (Work8, Addr); SetZN8 (Work8); } -void EOR16 () +static void EOR16 (long Addr) { - Registers.A.W ^= S9xGetWord (OpAddress); + Registers.A.W ^= S9xGetWord (Addr); SetZN16 (Registers.A.W); } -void EOR8 () +static void EOR8 (long Addr) { - Registers.AL ^= S9xGetByte (OpAddress); + Registers.AL ^= S9xGetByte (Addr); SetZN8 (Registers.AL); } -void A_INC16 () +static inline void A_INC16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -438,7 +438,7 @@ void A_INC16 () SetZN16 (Registers.A.W); } -void A_INC8 () +static inline void A_INC8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -451,7 +451,7 @@ void A_INC8 () SetZN8 (Registers.AL); } -void INC16 () +static void INC16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -460,14 +460,14 @@ void INC16 () CPU.WaitAddress = NULL; #endif - Work16 = S9xGetWord (OpAddress) + 1; - //S9xSetWord (Work16, OpAddress); - S9xSetByte (Work16>>8, OpAddress+1); - S9xSetByte (Work16&0xFF, OpAddress); + Work16 = S9xGetWord (Addr) + 1; + //S9xSetWord (Work16, Addr); + S9xSetByte (Work16>>8, Addr+1); + S9xSetByte (Work16&0xFF, Addr); SetZN16 (Work16); } -void INC8 () +static void INC8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -476,48 +476,48 @@ void INC8 () CPU.WaitAddress = NULL; #endif - Work8 = S9xGetByte (OpAddress) + 1; - S9xSetByte (Work8, OpAddress); + Work8 = S9xGetByte (Addr) + 1; + S9xSetByte (Work8, Addr); SetZN8 (Work8); } -void LDA16 () +static void LDA16 (long Addr) { - Registers.A.W = S9xGetWord (OpAddress); + Registers.A.W = S9xGetWord (Addr); SetZN16 (Registers.A.W); } -void LDA8 () +static void LDA8 (long Addr) { - Registers.AL = S9xGetByte (OpAddress); + Registers.AL = S9xGetByte (Addr); SetZN8 (Registers.AL); } -void LDX16 () +static void LDX16 (long Addr) { - Registers.X.W = S9xGetWord (OpAddress); + Registers.X.W = S9xGetWord (Addr); SetZN16 (Registers.X.W); } -void LDX8 () +static void LDX8 (long Addr) { - Registers.XL = S9xGetByte (OpAddress); + Registers.XL = S9xGetByte (Addr); SetZN8 (Registers.XL); } -void LDY16 () +static void LDY16 (long Addr) { - Registers.Y.W = S9xGetWord (OpAddress); + Registers.Y.W = S9xGetWord (Addr); SetZN16 (Registers.Y.W); } -void LDY8 () +static void LDY8 (long Addr) { - Registers.YL = S9xGetByte (OpAddress); + Registers.YL = S9xGetByte (Addr); SetZN8 (Registers.YL); } -void A_LSR16 () +static inline void A_LSR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -527,7 +527,7 @@ void A_LSR16 () SetZN16 (Registers.A.W); } -void A_LSR8 () +static inline void A_LSR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -537,45 +537,45 @@ void A_LSR8 () SetZN8 (Registers.AL); } -void LSR16 () +static void LSR16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); ICPU._Carry = Work16 & 1; Work16 >>= 1; - //S9xSetWord (Work16, OpAddress); - S9xSetByte (Work16>>8, OpAddress+1); - S9xSetByte (Work16&0xFF, OpAddress); + //S9xSetWord (Work16, Addr); + S9xSetByte (Work16>>8, Addr+1); + S9xSetByte (Work16&0xFF, Addr); SetZN16 (Work16); } -void LSR8 () +static void LSR8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); ICPU._Carry = Work8 & 1; Work8 >>= 1; - S9xSetByte (Work8, OpAddress); + S9xSetByte (Work8, Addr); SetZN8 (Work8); } -void ORA16 () +static void ORA16 (long Addr) { - Registers.A.W |= S9xGetWord (OpAddress); + Registers.A.W |= S9xGetWord (Addr); SetZN16 (Registers.A.W); } -void ORA8 () +static void ORA8 (long Addr) { - Registers.AL |= S9xGetByte (OpAddress); + Registers.AL |= S9xGetByte (Addr); SetZN8 (Registers.AL); } -void A_ROL16 () +static inline void A_ROL16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -586,7 +586,7 @@ void A_ROL16 () SetZN16 ((uint16) Work32); } -void A_ROL8 () +static inline void A_ROL8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -599,35 +599,35 @@ void A_ROL8 () SetZN8 ((uint8) Work16); } -void ROL16 () +static void ROL16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = S9xGetWord (OpAddress); + Work32 = S9xGetWord (Addr); Work32 <<= 1; Work32 |= CheckCarry(); ICPU._Carry = Work32 >= 0x10000; - //S9xSetWord ((uint16) Work32, OpAddress); - S9xSetByte((Work32>>8)&0xFF, OpAddress+1); - S9xSetByte(Work32&0xFF, OpAddress); + //S9xSetWord ((uint16) Work32, Addr); + S9xSetByte((Work32>>8)&0xFF, Addr+1); + S9xSetByte(Work32&0xFF, Addr); SetZN16 ((uint16) Work32); } -void ROL8 () +static void ROL8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetByte (OpAddress); + Work16 = S9xGetByte (Addr); Work16 <<= 1; Work16 |= CheckCarry (); ICPU._Carry = Work16 >= 0x100; - S9xSetByte ((uint8) Work16, OpAddress); + S9xSetByte ((uint8) Work16, Addr); SetZN8 ((uint8) Work16); } -void A_ROR16 () +static inline void A_ROR16 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -640,7 +640,7 @@ void A_ROR16 () SetZN16 ((uint16) Work32); } -void A_ROR8 () +static inline void A_ROR8 () { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -652,37 +652,37 @@ void A_ROR8 () SetZN8 ((uint8) Work16); } -void ROR16 () +static void ROR16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = S9xGetWord (OpAddress); + Work32 = S9xGetWord (Addr); Work32 |= (int) CheckCarry() << 16; ICPU._Carry = (uint8) (Work32 & 1); Work32 >>= 1; - //S9xSetWord ((uint16) Work32, OpAddress); - S9xSetByte ( (Work32>>8)&0x00FF, OpAddress+1); - S9xSetByte (Work32&0x00FF, OpAddress); + //S9xSetWord ((uint16) Work32, Addr); + S9xSetByte ( (Work32>>8)&0x00FF, Addr+1); + S9xSetByte (Work32&0x00FF, Addr); SetZN16 ((uint16) Work32); } -void ROR8 () +static void ROR8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetByte (OpAddress); + Work16 = S9xGetByte (Addr); Work16 |= (int) CheckCarry () << 8; ICPU._Carry = (uint8) (Work16 & 1); Work16 >>= 1; - S9xSetByte ((uint8) Work16, OpAddress); + S9xSetByte ((uint8) Work16, Addr); SetZN8 ((uint8) Work16); } -void SBC16 () +static void SBC16 (long Addr) { - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); if (CheckDecimal ()) { @@ -750,9 +750,9 @@ void SBC16 () } } -void SBC8 () +static void SBC8 (long Addr) { - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); if (CheckDecimal ()) { A1 = (Registers.A.W) & 0xF; @@ -801,92 +801,92 @@ void SBC8 () } } -void STA16 () +static void STA16 (long Addr) { - S9xSetWord (Registers.A.W, OpAddress); + S9xSetWord (Registers.A.W, Addr); } -void STA8 () +static void STA8 (long Addr) { - S9xSetByte (Registers.AL, OpAddress); + S9xSetByte (Registers.AL, Addr); } -void STX16 () +static void STX16 (long Addr) { - S9xSetWord (Registers.X.W, OpAddress); + S9xSetWord (Registers.X.W, Addr); } -void STX8 () +static void STX8 (long Addr) { - S9xSetByte (Registers.XL, OpAddress); + S9xSetByte (Registers.XL, Addr); } -void STY16 () +static void STY16 (long Addr) { - S9xSetWord (Registers.Y.W, OpAddress); + S9xSetWord (Registers.Y.W, Addr); } -void STY8 () +static void STY8 (long Addr) { - S9xSetByte (Registers.YL, OpAddress); + S9xSetByte (Registers.YL, Addr); } -void STZ16 () +static void STZ16 (long Addr) { - S9xSetWord (0, OpAddress); + S9xSetWord (0, Addr); } -void STZ8 () +static void STZ8 (long Addr) { - S9xSetByte (0, OpAddress); + S9xSetByte (0, Addr); } -void TSB16 () +static void TSB16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); ICPU._Zero = (Work16 & Registers.A.W) != 0; Work16 |= Registers.A.W; - //S9xSetWord (Work16, OpAddress); - S9xSetByte (Work16>>8, OpAddress+1); - S9xSetByte (Work16&0xFF, OpAddress); + //S9xSetWord (Work16, Addr); + S9xSetByte (Work16>>8, Addr+1); + S9xSetByte (Work16&0xFF, Addr); } -void TSB8 () +static void TSB8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); ICPU._Zero = Work8 & Registers.AL; Work8 |= Registers.AL; - S9xSetByte (Work8, OpAddress); + S9xSetByte (Work8, Addr); } -void TRB16 () +static void TRB16 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (OpAddress); + Work16 = S9xGetWord (Addr); ICPU._Zero = (Work16 & Registers.A.W) != 0; Work16 &= ~Registers.A.W; - //S9xSetWord (Work16, OpAddress); - S9xSetByte (Work16>>8, OpAddress+1); - S9xSetByte (Work16&0xFF, OpAddress); + //S9xSetWord (Work16, Addr); + S9xSetByte (Work16>>8, Addr+1); + S9xSetByte (Work16&0xFF, Addr); } -void TRB8 () +static void TRB8 (long Addr) { #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (OpAddress); + Work8 = S9xGetByte (Addr); ICPU._Zero = Work8 & Registers.AL; Work8 &= ~Registers.AL; - S9xSetByte (Work8, OpAddress); + S9xSetByte (Work8, Addr); } #endif diff --git a/source/cpuops.cpp b/source/cpuops.cpp index 967ca9f..33a2005 100644 --- a/source/cpuops.cpp +++ b/source/cpuops.cpp @@ -119,185 +119,161 @@ END_EXTERN_C #include "cpumacro.h" #include "apu.h" +// For use with the opcodes whose functions here examine the OpAddress. +static void OpAddressPassthrough (long Addr) +{ + OpAddress = Addr; +} + /* ADC *************************************************************************************** */ static void Op69M1 (void) { - Immediate8 (READ); - ADC8 (); + Immediate8 (READ, ADC8); } static void Op69M0 (void) { - Immediate16 (READ); - ADC16 (); + Immediate16 (READ, ADC16); } static void Op65M1 (void) { - Direct (READ); - ADC8 (); + Direct (READ, ADC8); } static void Op65M0 (void) { - Direct (READ); - ADC16 (); + Direct (READ, ADC16); } static void Op75M1 (void) { - DirectIndexedX (READ); - ADC8 (); + DirectIndexedX (READ, ADC8); } static void Op75M0 (void) { - DirectIndexedX (READ); - ADC16 (); + DirectIndexedX (READ, ADC16); } static void Op72M1 (void) { - DirectIndirect (READ); - ADC8 (); + DirectIndirect (READ, ADC8); } static void Op72M0 (void) { - DirectIndirect (READ); - ADC16 (); + DirectIndirect (READ, ADC16); } static void Op61M1 (void) { - DirectIndexedIndirect (READ); - ADC8 (); + DirectIndexedIndirect (READ, ADC8); } static void Op61M0 (void) { - DirectIndexedIndirect (READ); - ADC16 (); + DirectIndexedIndirect (READ, ADC16); } static void Op71M1 (void) { - DirectIndirectIndexed (READ); - ADC8 (); + DirectIndirectIndexed (READ, ADC8); } static void Op71M0 (void) { - DirectIndirectIndexed (READ); - ADC16 (); + DirectIndirectIndexed (READ, ADC16); } static void Op67M1 (void) { - DirectIndirectLong (READ); - ADC8 (); + DirectIndirectLong (READ, ADC8); } static void Op67M0 (void) { - DirectIndirectLong (READ); - ADC16 (); + DirectIndirectLong (READ, ADC16); } static void Op77M1 (void) { - DirectIndirectIndexedLong (READ); - ADC8 (); + DirectIndirectIndexedLong (READ, ADC8); } static void Op77M0 (void) { - DirectIndirectIndexedLong (READ); - ADC16 (); + DirectIndirectIndexedLong (READ, ADC16); } static void Op6DM1 (void) { - Absolute (READ); - ADC8 (); + Absolute (READ, ADC8); } static void Op6DM0 (void) { - Absolute (READ); - ADC16 (); + Absolute (READ, ADC16); } static void Op7DM1 (void) { - AbsoluteIndexedX (READ); - ADC8 (); + AbsoluteIndexedX (READ, ADC8); } static void Op7DM0 (void) { - AbsoluteIndexedX (READ); - ADC16 (); + AbsoluteIndexedX (READ, ADC16); } static void Op79M1 (void) { - AbsoluteIndexedY (READ); - ADC8 (); + AbsoluteIndexedY (READ, ADC8); } static void Op79M0 (void) { - AbsoluteIndexedY (READ); - ADC16 (); + AbsoluteIndexedY (READ, ADC16); } static void Op6FM1 (void) { - AbsoluteLong (READ); - ADC8 (); + AbsoluteLong (READ, ADC8); } static void Op6FM0 (void) { - AbsoluteLong (READ); - ADC16 (); + AbsoluteLong (READ, ADC16); } static void Op7FM1 (void) { - AbsoluteLongIndexedX (READ); - ADC8 (); + AbsoluteLongIndexedX (READ, ADC8); } static void Op7FM0 (void) { - AbsoluteLongIndexedX (READ); - ADC16 (); + AbsoluteLongIndexedX (READ, ADC16); } static void Op63M1 (void) { - StackRelative (READ); - ADC8 (); + StackRelative (READ, ADC8); } static void Op63M0 (void) { - StackRelative (READ); - ADC16 (); + StackRelative (READ, ADC16); } static void Op73M1 (void) { - StackRelativeIndirectIndexed (READ); - ADC8 (); + StackRelativeIndirectIndexed (READ, ADC8); } static void Op73M0 (void) { - StackRelativeIndirectIndexed (READ); - ADC16 (); + StackRelativeIndirectIndexed (READ, ADC16); } /**********************************************************************************************/ @@ -328,170 +304,142 @@ static void Op29M0 (void) static void Op25M1 (void) { - Direct (READ); - AND8 (); + Direct (READ, AND8); } static void Op25M0 (void) { - Direct (READ); - AND16 (); + Direct (READ, AND16); } static void Op35M1 (void) { - DirectIndexedX (READ); - AND8 (); + DirectIndexedX (READ, AND8); } static void Op35M0 (void) { - DirectIndexedX (READ); - AND16 (); + DirectIndexedX (READ, AND16); } static void Op32M1 (void) { - DirectIndirect (READ); - AND8 (); + DirectIndirect (READ, AND8); } static void Op32M0 (void) { - DirectIndirect (READ); - AND16 (); + DirectIndirect (READ, AND16); } static void Op21M1 (void) { - DirectIndexedIndirect (READ); - AND8 (); + DirectIndexedIndirect (READ, AND8); } static void Op21M0 (void) { - DirectIndexedIndirect (READ); - AND16 (); + DirectIndexedIndirect (READ, AND16); } static void Op31M1 (void) { - DirectIndirectIndexed (READ); - AND8 (); + DirectIndirectIndexed (READ, AND8); } static void Op31M0 (void) { - DirectIndirectIndexed (READ); - AND16 (); + DirectIndirectIndexed (READ, AND16); } static void Op27M1 (void) { - DirectIndirectLong (READ); - AND8 (); + DirectIndirectLong (READ, AND8); } static void Op27M0 (void) { - DirectIndirectLong (READ); - AND16 (); + DirectIndirectLong (READ, AND16); } static void Op37M1 (void) { - DirectIndirectIndexedLong (READ); - AND8 (); + DirectIndirectIndexedLong (READ, AND8); } static void Op37M0 (void) { - DirectIndirectIndexedLong (READ); - AND16 (); + DirectIndirectIndexedLong (READ, AND16); } static void Op2DM1 (void) { - Absolute (READ); - AND8 (); + Absolute (READ, AND8); } static void Op2DM0 (void) { - Absolute (READ); - AND16 (); + Absolute (READ, AND16); } static void Op3DM1 (void) { - AbsoluteIndexedX (READ); - AND8 (); + AbsoluteIndexedX (READ, AND8); } static void Op3DM0 (void) { - AbsoluteIndexedX (READ); - AND16 (); + AbsoluteIndexedX (READ, AND16); } static void Op39M1 (void) { - AbsoluteIndexedY (READ); - AND8 (); + AbsoluteIndexedY (READ, AND8); } static void Op39M0 (void) { - AbsoluteIndexedY (READ); - AND16 (); + AbsoluteIndexedY (READ, AND16); } static void Op2FM1 (void) { - AbsoluteLong (READ); - AND8 (); + AbsoluteLong (READ, AND8); } static void Op2FM0 (void) { - AbsoluteLong (READ); - AND16 (); + AbsoluteLong (READ, AND16); } static void Op3FM1 (void) { - AbsoluteLongIndexedX (READ); - AND8 (); + AbsoluteLongIndexedX (READ, AND8); } static void Op3FM0 (void) { - AbsoluteLongIndexedX (READ); - AND16 (); + AbsoluteLongIndexedX (READ, AND16); } static void Op23M1 (void) { - StackRelative (READ); - AND8 (); + StackRelative (READ, AND8); } static void Op23M0 (void) { - StackRelative (READ); - AND16 (); + StackRelative (READ, AND16); } static void Op33M1 (void) { - StackRelativeIndirectIndexed (READ); - AND8 (); + StackRelativeIndirectIndexed (READ, AND8); } static void Op33M0 (void) { - StackRelativeIndirectIndexed (READ); - AND16 (); + StackRelativeIndirectIndexed (READ, AND16); } /**********************************************************************************************/ @@ -508,50 +456,42 @@ static void Op0AM0 (void) static void Op06M1 (void) { - Direct (MODIFY); - ASL8 (); + Direct (MODIFY, ASL8); } static void Op06M0 (void) { - Direct (MODIFY); - ASL16 (); + Direct (MODIFY, ASL16); } static void Op16M1 (void) { - DirectIndexedX (MODIFY); - ASL8 (); + DirectIndexedX (MODIFY, ASL8); } static void Op16M0 (void) { - DirectIndexedX (MODIFY); - ASL16 (); + DirectIndexedX (MODIFY, ASL16); } static void Op0EM1 (void) { - Absolute (MODIFY); - ASL8 (); + Absolute (MODIFY, ASL8); } static void Op0EM0 (void) { - Absolute (MODIFY); - ASL16 (); + Absolute (MODIFY, ASL16); } static void Op1EM1 (void) { - AbsoluteIndexedX (MODIFY); - ASL8 (); + AbsoluteIndexedX (MODIFY, ASL8); } static void Op1EM0 (void) { - AbsoluteIndexedX (MODIFY); - ASL16 (); + AbsoluteIndexedX (MODIFY, ASL16); } /**********************************************************************************************/ @@ -579,50 +519,42 @@ static void Op89M0 (void) static void Op24M1 (void) { - Direct (READ); - BIT8 (); + Direct (READ, BIT8); } static void Op24M0 (void) { - Direct (READ); - BIT16 (); + Direct (READ, BIT16); } static void Op34M1 (void) { - DirectIndexedX (READ); - BIT8 (); + DirectIndexedX (READ, BIT8); } static void Op34M0 (void) { - DirectIndexedX (READ); - BIT16 (); + DirectIndexedX (READ, BIT16); } static void Op2CM1 (void) { - Absolute (READ); - BIT8 (); + Absolute (READ, BIT8); } static void Op2CM0 (void) { - Absolute (READ); - BIT16 (); + Absolute (READ, BIT16); } static void Op3CM1 (void) { - AbsoluteIndexedX (READ); - BIT8 (); + AbsoluteIndexedX (READ, BIT8); } static void Op3CM0 (void) { - AbsoluteIndexedX (READ); - BIT16 (); + AbsoluteIndexedX (READ, BIT16); } /**********************************************************************************************/ @@ -655,170 +587,142 @@ static void OpC9M0 (void) static void OpC5M1 (void) { - Direct (READ); - CMP8 (); + Direct (READ, CMP8); } static void OpC5M0 (void) { - Direct (READ); - CMP16 (); + Direct (READ, CMP16); } static void OpD5M1 (void) { - DirectIndexedX (READ); - CMP8 (); + DirectIndexedX (READ, CMP8); } static void OpD5M0 (void) { - DirectIndexedX (READ); - CMP16 (); + DirectIndexedX (READ, CMP16); } static void OpD2M1 (void) { - DirectIndirect (READ); - CMP8 (); + DirectIndirect (READ, CMP8); } static void OpD2M0 (void) { - DirectIndirect (READ); - CMP16 (); + DirectIndirect (READ, CMP16); } static void OpC1M1 (void) { - DirectIndexedIndirect (READ); - CMP8 (); + DirectIndexedIndirect (READ, CMP8); } static void OpC1M0 (void) { - DirectIndexedIndirect (READ); - CMP16 (); + DirectIndexedIndirect (READ, CMP16); } static void OpD1M1 (void) { - DirectIndirectIndexed (READ); - CMP8 (); + DirectIndirectIndexed (READ, CMP8); } static void OpD1M0 (void) { - DirectIndirectIndexed (READ); - CMP16 (); + DirectIndirectIndexed (READ, CMP16); } static void OpC7M1 (void) { - DirectIndirectLong (READ); - CMP8 (); + DirectIndirectLong (READ, CMP8); } static void OpC7M0 (void) { - DirectIndirectLong (READ); - CMP16 (); + DirectIndirectLong (READ, CMP16); } static void OpD7M1 (void) { - DirectIndirectIndexedLong (READ); - CMP8 (); + DirectIndirectIndexedLong (READ, CMP8); } static void OpD7M0 (void) { - DirectIndirectIndexedLong (READ); - CMP16 (); + DirectIndirectIndexedLong (READ, CMP16); } static void OpCDM1 (void) { - Absolute (READ); - CMP8 (); + Absolute (READ, CMP8); } static void OpCDM0 (void) { - Absolute (READ); - CMP16 (); + Absolute (READ, CMP16); } static void OpDDM1 (void) { - AbsoluteIndexedX (READ); - CMP8 (); + AbsoluteIndexedX (READ, CMP8); } static void OpDDM0 (void) { - AbsoluteIndexedX (READ); - CMP16 (); + AbsoluteIndexedX (READ, CMP16); } static void OpD9M1 (void) { - AbsoluteIndexedY (READ); - CMP8 (); + AbsoluteIndexedY (READ, CMP8); } static void OpD9M0 (void) { - AbsoluteIndexedY (READ); - CMP16 (); + AbsoluteIndexedY (READ, CMP16); } static void OpCFM1 (void) { - AbsoluteLong (READ); - CMP8 (); + AbsoluteLong (READ, CMP8); } static void OpCFM0 (void) { - AbsoluteLong (READ); - CMP16 (); + AbsoluteLong (READ, CMP16); } static void OpDFM1 (void) { - AbsoluteLongIndexedX (READ); - CMP8 (); + AbsoluteLongIndexedX (READ, CMP8); } static void OpDFM0 (void) { - AbsoluteLongIndexedX (READ); - CMP16 (); + AbsoluteLongIndexedX (READ, CMP16); } static void OpC3M1 (void) { - StackRelative (READ); - CMP8 (); + StackRelative (READ, CMP8); } static void OpC3M0 (void) { - StackRelative (READ); - CMP16 (); + StackRelative (READ, CMP16); } static void OpD3M1 (void) { - StackRelativeIndirectIndexed (READ); - CMP8 (); + StackRelativeIndirectIndexed (READ, CMP8); } static void OpD3M0 (void) { - StackRelativeIndirectIndexed (READ); - CMP16 (); + StackRelativeIndirectIndexed (READ, CMP16); } /**********************************************************************************************/ @@ -852,26 +756,22 @@ static void OpE0X0 (void) static void OpE4X1 (void) { - Direct (READ); - CMX8 (); + Direct (READ, CMX8); } static void OpE4X0 (void) { - Direct (READ); - CMX16 (); + Direct (READ, CMX16); } static void OpECX1 (void) { - Absolute (READ); - CMX8 (); + Absolute (READ, CMX8); } static void OpECX0 (void) { - Absolute (READ); - CMX16 (); + Absolute (READ, CMX16); } /**********************************************************************************************/ @@ -905,26 +805,22 @@ static void OpC0X0 (void) static void OpC4X1 (void) { - Direct (READ); - CMY8 (); + Direct (READ, CMY8); } static void OpC4X0 (void) { - Direct (READ); - CMY16 (); + Direct (READ, CMY16); } static void OpCCX1 (void) { - Absolute (READ); - CMY8 (); + Absolute (READ, CMY8); } static void OpCCX0 (void) { - Absolute (READ); - CMY16 (); + Absolute (READ, CMY16); } /**********************************************************************************************/ @@ -942,50 +838,42 @@ static void Op3AM0 (void) static void OpC6M1 (void) { - Direct (MODIFY); - DEC8 (); + Direct (MODIFY, DEC8); } static void OpC6M0 (void) { - Direct (MODIFY); - DEC16 (); + Direct (MODIFY, DEC16); } static void OpD6M1 (void) { - DirectIndexedX (MODIFY); - DEC8 (); + DirectIndexedX (MODIFY, DEC8); } static void OpD6M0 (void) { - DirectIndexedX (MODIFY); - DEC16 (); + DirectIndexedX (MODIFY, DEC16); } static void OpCEM1 (void) { - Absolute (MODIFY); - DEC8 (); + Absolute (MODIFY, DEC8); } static void OpCEM0 (void) { - Absolute (MODIFY); - DEC16 (); + Absolute (MODIFY, DEC16); } static void OpDEM1 (void) { - AbsoluteIndexedX (MODIFY); - DEC8 (); + AbsoluteIndexedX (MODIFY, DEC8); } static void OpDEM0 (void) { - AbsoluteIndexedX (MODIFY); - DEC16 (); + AbsoluteIndexedX (MODIFY, DEC16); } /**********************************************************************************************/ @@ -1016,170 +904,142 @@ static void Op49M0 (void) static void Op45M1 (void) { - Direct (READ); - EOR8 (); + Direct (READ, EOR8); } static void Op45M0 (void) { - Direct (READ); - EOR16 (); + Direct (READ, EOR16); } static void Op55M1 (void) { - DirectIndexedX (READ); - EOR8 (); + DirectIndexedX (READ, EOR8); } static void Op55M0 (void) { - DirectIndexedX (READ); - EOR16 (); + DirectIndexedX (READ, EOR16); } static void Op52M1 (void) { - DirectIndirect (READ); - EOR8 (); + DirectIndirect (READ, EOR8); } static void Op52M0 (void) { - DirectIndirect (READ); - EOR16 (); + DirectIndirect (READ, EOR16); } static void Op41M1 (void) { - DirectIndexedIndirect (READ); - EOR8 (); + DirectIndexedIndirect (READ, EOR8); } static void Op41M0 (void) { - DirectIndexedIndirect (READ); - EOR16 (); + DirectIndexedIndirect (READ, EOR16); } static void Op51M1 (void) { - DirectIndirectIndexed (READ); - EOR8 (); + DirectIndirectIndexed (READ, EOR8); } static void Op51M0 (void) { - DirectIndirectIndexed (READ); - EOR16 (); + DirectIndirectIndexed (READ, EOR16); } static void Op47M1 (void) { - DirectIndirectLong (READ); - EOR8 (); + DirectIndirectLong (READ, EOR8); } static void Op47M0 (void) { - DirectIndirectLong (READ); - EOR16 (); + DirectIndirectLong (READ, EOR16); } static void Op57M1 (void) { - DirectIndirectIndexedLong (READ); - EOR8 (); + DirectIndirectIndexedLong (READ, EOR8); } static void Op57M0 (void) { - DirectIndirectIndexedLong (READ); - EOR16 (); + DirectIndirectIndexedLong (READ, EOR16); } static void Op4DM1 (void) { - Absolute (READ); - EOR8 (); + Absolute (READ, EOR8); } static void Op4DM0 (void) { - Absolute (READ); - EOR16 (); + Absolute (READ, EOR16); } static void Op5DM1 (void) { - AbsoluteIndexedX (READ); - EOR8 (); + AbsoluteIndexedX (READ, EOR8); } static void Op5DM0 (void) { - AbsoluteIndexedX (READ); - EOR16 (); + AbsoluteIndexedX (READ, EOR16); } static void Op59M1 (void) { - AbsoluteIndexedY (READ); - EOR8 (); + AbsoluteIndexedY (READ, EOR8); } static void Op59M0 (void) { - AbsoluteIndexedY (READ); - EOR16 (); + AbsoluteIndexedY (READ, EOR16); } static void Op4FM1 (void) { - AbsoluteLong (READ); - EOR8 (); + AbsoluteLong (READ, EOR8); } static void Op4FM0 (void) { - AbsoluteLong (READ); - EOR16 (); + AbsoluteLong (READ, EOR16); } static void Op5FM1 (void) { - AbsoluteLongIndexedX (READ); - EOR8 (); + AbsoluteLongIndexedX (READ, EOR8); } static void Op5FM0 (void) { - AbsoluteLongIndexedX (READ); - EOR16 (); + AbsoluteLongIndexedX (READ, EOR16); } static void Op43M1 (void) { - StackRelative (READ); - EOR8 (); + StackRelative (READ, EOR8); } static void Op43M0 (void) { - StackRelative (READ); - EOR16 (); + StackRelative (READ, EOR16); } static void Op53M1 (void) { - StackRelativeIndirectIndexed (READ); - EOR8 (); + StackRelativeIndirectIndexed (READ, EOR8); } static void Op53M0 (void) { - StackRelativeIndirectIndexed (READ); - EOR16 (); + StackRelativeIndirectIndexed (READ, EOR16); } /**********************************************************************************************/ @@ -1197,50 +1057,42 @@ static void Op1AM0 (void) static void OpE6M1 (void) { - Direct (MODIFY); - INC8 (); + Direct (MODIFY, INC8); } static void OpE6M0 (void) { - Direct (MODIFY); - INC16 (); + Direct (MODIFY, INC16); } static void OpF6M1 (void) { - DirectIndexedX (MODIFY); - INC8 (); + DirectIndexedX (MODIFY, INC8); } static void OpF6M0 (void) { - DirectIndexedX (MODIFY); - INC16 (); + DirectIndexedX (MODIFY, INC16); } static void OpEEM1 (void) { - Absolute (MODIFY); - INC8 (); + Absolute (MODIFY, INC8); } static void OpEEM0 (void) { - Absolute (MODIFY); - INC16 (); + Absolute (MODIFY, INC16); } static void OpFEM1 (void) { - AbsoluteIndexedX (MODIFY); - INC8 (); + AbsoluteIndexedX (MODIFY, INC8); } static void OpFEM0 (void) { - AbsoluteIndexedX (MODIFY); - INC16 (); + AbsoluteIndexedX (MODIFY, INC16); } /**********************************************************************************************/ @@ -1271,170 +1123,142 @@ static void OpA9M0 (void) static void OpA5M1 (void) { - Direct (READ); - LDA8 (); + Direct (READ, LDA8); } static void OpA5M0 (void) { - Direct (READ); - LDA16 (); + Direct (READ, LDA16); } static void OpB5M1 (void) { - DirectIndexedX (READ); - LDA8 (); + DirectIndexedX (READ, LDA8); } static void OpB5M0 (void) { - DirectIndexedX (READ); - LDA16 (); + DirectIndexedX (READ, LDA16); } static void OpB2M1 (void) { - DirectIndirect (READ); - LDA8 (); + DirectIndirect (READ, LDA8); } static void OpB2M0 (void) { - DirectIndirect (READ); - LDA16 (); + DirectIndirect (READ, LDA16); } static void OpA1M1 (void) { - DirectIndexedIndirect (READ); - LDA8 (); + DirectIndexedIndirect (READ, LDA8); } static void OpA1M0 (void) { - DirectIndexedIndirect (READ); - LDA16 (); + DirectIndexedIndirect (READ, LDA16); } static void OpB1M1 (void) { - DirectIndirectIndexed (READ); - LDA8 (); + DirectIndirectIndexed (READ, LDA8); } static void OpB1M0 (void) { - DirectIndirectIndexed (READ); - LDA16 (); + DirectIndirectIndexed (READ, LDA16); } static void OpA7M1 (void) { - DirectIndirectLong (READ); - LDA8 (); + DirectIndirectLong (READ, LDA8); } static void OpA7M0 (void) { - DirectIndirectLong (READ); - LDA16 (); + DirectIndirectLong (READ, LDA16); } static void OpB7M1 (void) { - DirectIndirectIndexedLong (READ); - LDA8 (); + DirectIndirectIndexedLong (READ, LDA8); } static void OpB7M0 (void) { - DirectIndirectIndexedLong (READ); - LDA16 (); + DirectIndirectIndexedLong (READ, LDA16); } static void OpADM1 (void) { - Absolute (READ); - LDA8 (); + Absolute (READ, LDA8); } static void OpADM0 (void) { - Absolute (READ); - LDA16 (); + Absolute (READ, LDA16); } static void OpBDM1 (void) { - AbsoluteIndexedX (READ); - LDA8 (); + AbsoluteIndexedX (READ, LDA8); } static void OpBDM0 (void) { - AbsoluteIndexedX (READ); - LDA16 (); + AbsoluteIndexedX (READ, LDA16); } static void OpB9M1 (void) { - AbsoluteIndexedY (READ); - LDA8 (); + AbsoluteIndexedY (READ, LDA8); } static void OpB9M0 (void) { - AbsoluteIndexedY (READ); - LDA16 (); + AbsoluteIndexedY (READ, LDA16); } static void OpAFM1 (void) { - AbsoluteLong (READ); - LDA8 (); + AbsoluteLong (READ, LDA8); } static void OpAFM0 (void) { - AbsoluteLong (READ); - LDA16 (); + AbsoluteLong (READ, LDA16); } static void OpBFM1 (void) { - AbsoluteLongIndexedX (READ); - LDA8 (); + AbsoluteLongIndexedX (READ, LDA8); } static void OpBFM0 (void) { - AbsoluteLongIndexedX (READ); - LDA16 (); + AbsoluteLongIndexedX (READ, LDA16); } static void OpA3M1 (void) { - StackRelative (READ); - LDA8 (); + StackRelative (READ, LDA8); } static void OpA3M0 (void) { - StackRelative (READ); - LDA16 (); + StackRelative (READ, LDA16); } static void OpB3M1 (void) { - StackRelativeIndirectIndexed (READ); - LDA8 (); + StackRelativeIndirectIndexed (READ, LDA8); } static void OpB3M0 (void) { - StackRelativeIndirectIndexed (READ); - LDA16 (); + StackRelativeIndirectIndexed (READ, LDA16); } /**********************************************************************************************/ @@ -1465,50 +1289,42 @@ static void OpA2X0 (void) static void OpA6X1 (void) { - Direct (READ); - LDX8 (); + Direct (READ, LDX8); } static void OpA6X0 (void) { - Direct (READ); - LDX16 (); + Direct (READ, LDX16); } static void OpB6X1 (void) { - DirectIndexedY (READ); - LDX8 (); + DirectIndexedY (READ, LDX8); } static void OpB6X0 (void) { - DirectIndexedY (READ); - LDX16 (); + DirectIndexedY (READ, LDX16); } static void OpAEX1 (void) { - Absolute (READ); - LDX8 (); + Absolute (READ, LDX8); } static void OpAEX0 (void) { - Absolute (READ); - LDX16 (); + Absolute (READ, LDX16); } static void OpBEX1 (void) { - AbsoluteIndexedY (READ); - LDX8 (); + AbsoluteIndexedY (READ, LDX8); } static void OpBEX0 (void) { - AbsoluteIndexedY (READ); - LDX16 (); + AbsoluteIndexedY (READ, LDX16); } /**********************************************************************************************/ @@ -1539,50 +1355,42 @@ static void OpA0X0 (void) static void OpA4X1 (void) { - Direct (READ); - LDY8 (); + Direct (READ, LDY8); } static void OpA4X0 (void) { - Direct (READ); - LDY16 (); + Direct (READ, LDY16); } static void OpB4X1 (void) { - DirectIndexedX (READ); - LDY8 (); + DirectIndexedX (READ, LDY8); } static void OpB4X0 (void) { - DirectIndexedX (READ); - LDY16 (); + DirectIndexedX (READ, LDY16); } static void OpACX1 (void) { - Absolute (READ); - LDY8 (); + Absolute (READ, LDY8); } static void OpACX0 (void) { - Absolute (READ); - LDY16 (); + Absolute (READ, LDY16); } static void OpBCX1 (void) { - AbsoluteIndexedX (READ); - LDY8 (); + AbsoluteIndexedX (READ, LDY8); } static void OpBCX0 (void) { - AbsoluteIndexedX (READ); - LDY16 (); + AbsoluteIndexedX (READ, LDY16); } /**********************************************************************************************/ @@ -1599,50 +1407,42 @@ static void Op4AM0 (void) static void Op46M1 (void) { - Direct (MODIFY); - LSR8 (); + Direct (MODIFY, LSR8); } static void Op46M0 (void) { - Direct (MODIFY); - LSR16 (); + Direct (MODIFY, LSR16); } static void Op56M1 (void) { - DirectIndexedX (MODIFY); - LSR8 (); + DirectIndexedX (MODIFY, LSR8); } static void Op56M0 (void) { - DirectIndexedX (MODIFY); - LSR16 (); + DirectIndexedX (MODIFY, LSR16); } static void Op4EM1 (void) { - Absolute (MODIFY); - LSR8 (); + Absolute (MODIFY, LSR8); } static void Op4EM0 (void) { - Absolute (MODIFY); - LSR16 (); + Absolute (MODIFY, LSR16); } static void Op5EM1 (void) { - AbsoluteIndexedX (MODIFY); - LSR8 (); + AbsoluteIndexedX (MODIFY, LSR8); } static void Op5EM0 (void) { - AbsoluteIndexedX (MODIFY); - LSR16 (); + AbsoluteIndexedX (MODIFY, LSR16); } /**********************************************************************************************/ @@ -1673,170 +1473,142 @@ static void Op09M0 (void) static void Op05M1 (void) { - Direct (READ); - ORA8 (); + Direct (READ, ORA8); } static void Op05M0 (void) { - Direct (READ); - ORA16 (); + Direct (READ, ORA16); } static void Op15M1 (void) { - DirectIndexedX (READ); - ORA8 (); + DirectIndexedX (READ, ORA8); } static void Op15M0 (void) { - DirectIndexedX (READ); - ORA16 (); + DirectIndexedX (READ, ORA16); } static void Op12M1 (void) { - DirectIndirect (READ); - ORA8 (); + DirectIndirect (READ, ORA8); } static void Op12M0 (void) { - DirectIndirect (READ); - ORA16 (); + DirectIndirect (READ, ORA16); } static void Op01M1 (void) { - DirectIndexedIndirect (READ); - ORA8 (); + DirectIndexedIndirect (READ, ORA8); } static void Op01M0 (void) { - DirectIndexedIndirect (READ); - ORA16 (); + DirectIndexedIndirect (READ, ORA16); } static void Op11M1 (void) { - DirectIndirectIndexed (READ); - ORA8 (); + DirectIndirectIndexed (READ, ORA8); } static void Op11M0 (void) { - DirectIndirectIndexed (READ); - ORA16 (); + DirectIndirectIndexed (READ, ORA16); } static void Op07M1 (void) { - DirectIndirectLong (READ); - ORA8 (); + DirectIndirectLong (READ, ORA8); } static void Op07M0 (void) { - DirectIndirectLong (READ); - ORA16 (); + DirectIndirectLong (READ, ORA16); } static void Op17M1 (void) { - DirectIndirectIndexedLong (READ); - ORA8 (); + DirectIndirectIndexedLong (READ, ORA8); } static void Op17M0 (void) { - DirectIndirectIndexedLong (READ); - ORA16 (); + DirectIndirectIndexedLong (READ, ORA16); } static void Op0DM1 (void) { - Absolute (READ); - ORA8 (); + Absolute (READ, ORA8); } static void Op0DM0 (void) { - Absolute (READ); - ORA16 (); + Absolute (READ, ORA16); } static void Op1DM1 (void) { - AbsoluteIndexedX (READ); - ORA8 (); + AbsoluteIndexedX (READ, ORA8); } static void Op1DM0 (void) { - AbsoluteIndexedX (READ); - ORA16 (); + AbsoluteIndexedX (READ, ORA16); } static void Op19M1 (void) { - AbsoluteIndexedY (READ); - ORA8 (); + AbsoluteIndexedY (READ, ORA8); } static void Op19M0 (void) { - AbsoluteIndexedY (READ); - ORA16 (); + AbsoluteIndexedY (READ, ORA16); } static void Op0FM1 (void) { - AbsoluteLong (READ); - ORA8 (); + AbsoluteLong (READ, ORA8); } static void Op0FM0 (void) { - AbsoluteLong (READ); - ORA16 (); + AbsoluteLong (READ, ORA16); } static void Op1FM1 (void) { - AbsoluteLongIndexedX (READ); - ORA8 (); + AbsoluteLongIndexedX (READ, ORA8); } static void Op1FM0 (void) { - AbsoluteLongIndexedX (READ); - ORA16 (); + AbsoluteLongIndexedX (READ, ORA16); } static void Op03M1 (void) { - StackRelative (READ); - ORA8 (); + StackRelative (READ, ORA8); } static void Op03M0 (void) { - StackRelative (READ); - ORA16 (); + StackRelative (READ, ORA16); } static void Op13M1 (void) { - StackRelativeIndirectIndexed (READ); - ORA8 (); + StackRelativeIndirectIndexed (READ, ORA8); } static void Op13M0 (void) { - StackRelativeIndirectIndexed (READ); - ORA16 (); + StackRelativeIndirectIndexed (READ, ORA16); } /**********************************************************************************************/ @@ -1854,50 +1626,42 @@ static void Op2AM0 (void) static void Op26M1 (void) { - Direct (MODIFY); - ROL8 (); + Direct (MODIFY, ROL8); } static void Op26M0 (void) { - Direct (MODIFY); - ROL16 (); + Direct (MODIFY, ROL16); } static void Op36M1 (void) { - DirectIndexedX (MODIFY); - ROL8 (); + DirectIndexedX (MODIFY, ROL8); } static void Op36M0 (void) { - DirectIndexedX (MODIFY); - ROL16 (); + DirectIndexedX (MODIFY, ROL16); } static void Op2EM1 (void) { - Absolute (MODIFY); - ROL8 (); + Absolute (MODIFY, ROL8); } static void Op2EM0 (void) { - Absolute (MODIFY); - ROL16 (); + Absolute (MODIFY, ROL16); } static void Op3EM1 (void) { - AbsoluteIndexedX (MODIFY); - ROL8 (); + AbsoluteIndexedX (MODIFY, ROL8); } static void Op3EM0 (void) { - AbsoluteIndexedX (MODIFY); - ROL16 (); + AbsoluteIndexedX (MODIFY, ROL16); } /**********************************************************************************************/ @@ -1914,276 +1678,231 @@ static void Op6AM0 (void) static void Op66M1 (void) { - Direct (MODIFY); - ROR8 (); + Direct (MODIFY, ROR8); } static void Op66M0 (void) { - Direct (MODIFY); - ROR16 (); + Direct (MODIFY, ROR16); } static void Op76M1 (void) { - DirectIndexedX (MODIFY); - ROR8 (); + DirectIndexedX (MODIFY, ROR8); } static void Op76M0 (void) { - DirectIndexedX (MODIFY); - ROR16 (); + DirectIndexedX (MODIFY, ROR16); } static void Op6EM1 (void) { - Absolute (MODIFY); - ROR8 (); + Absolute (MODIFY, ROR8); } static void Op6EM0 (void) { - Absolute (MODIFY); - ROR16 (); + Absolute (MODIFY, ROR16); } static void Op7EM1 (void) { - AbsoluteIndexedX (MODIFY); - ROR8 (); + AbsoluteIndexedX (MODIFY, ROR8); } static void Op7EM0 (void) { - AbsoluteIndexedX (MODIFY); - ROR16 (); + AbsoluteIndexedX (MODIFY, ROR16); } /**********************************************************************************************/ /* SBC *************************************************************************************** */ static void OpE9M1 (void) { - Immediate8 (READ); - SBC8 (); + Immediate8 (READ, SBC8); } static void OpE9M0 (void) { - Immediate16 (READ); - SBC16 (); + Immediate16 (READ, SBC16); } static void OpE5M1 (void) { - Direct (READ); - SBC8 (); + Direct (READ, SBC8); } static void OpE5M0 (void) { - Direct (READ); - SBC16 (); + Direct (READ, SBC16); } static void OpF5M1 (void) { - DirectIndexedX (READ); - SBC8 (); + DirectIndexedX (READ, SBC8); } static void OpF5M0 (void) { - DirectIndexedX (READ); - SBC16 (); + DirectIndexedX (READ, SBC16); } static void OpF2M1 (void) { - DirectIndirect (READ); - SBC8 (); + DirectIndirect (READ, SBC8); } static void OpF2M0 (void) { - DirectIndirect (READ); - SBC16 (); + DirectIndirect (READ, SBC16); } static void OpE1M1 (void) { - DirectIndexedIndirect (READ); - SBC8 (); + DirectIndexedIndirect (READ, SBC8); } static void OpE1M0 (void) { - DirectIndexedIndirect (READ); - SBC16 (); + DirectIndexedIndirect (READ, SBC16); } static void OpF1M1 (void) { - DirectIndirectIndexed (READ); - SBC8 (); + DirectIndirectIndexed (READ, SBC8); } static void OpF1M0 (void) { - DirectIndirectIndexed (READ); - SBC16 (); + DirectIndirectIndexed (READ, SBC16); } static void OpE7M1 (void) { - DirectIndirectLong (READ); - SBC8 (); + DirectIndirectLong (READ, SBC8); } static void OpE7M0 (void) { - DirectIndirectLong (READ); - SBC16 (); + DirectIndirectLong (READ, SBC16); } static void OpF7M1 (void) { - DirectIndirectIndexedLong (READ); - SBC8 (); + DirectIndirectIndexedLong (READ, SBC8); } static void OpF7M0 (void) { - DirectIndirectIndexedLong (READ); - SBC16 (); + DirectIndirectIndexedLong (READ, SBC16); } static void OpEDM1 (void) { - Absolute (READ); - SBC8 (); + Absolute (READ, SBC8); } static void OpEDM0 (void) { - Absolute (READ); - SBC16 (); + Absolute (READ, SBC16); } static void OpFDM1 (void) { - AbsoluteIndexedX (READ); - SBC8 (); + AbsoluteIndexedX (READ, SBC8); } static void OpFDM0 (void) { - AbsoluteIndexedX (READ); - SBC16 (); + AbsoluteIndexedX (READ, SBC16); } static void OpF9M1 (void) { - AbsoluteIndexedY (READ); - SBC8 (); + AbsoluteIndexedY (READ, SBC8); } static void OpF9M0 (void) { - AbsoluteIndexedY (READ); - SBC16 (); + AbsoluteIndexedY (READ, SBC16); } static void OpEFM1 (void) { - AbsoluteLong (READ); - SBC8 (); + AbsoluteLong (READ, SBC8); } static void OpEFM0 (void) { - AbsoluteLong (READ); - SBC16 (); + AbsoluteLong (READ, SBC16); } static void OpFFM1 (void) { - AbsoluteLongIndexedX (READ); - SBC8 (); + AbsoluteLongIndexedX (READ, SBC8); } static void OpFFM0 (void) { - AbsoluteLongIndexedX (READ); - SBC16 (); + AbsoluteLongIndexedX (READ, SBC16); } static void OpE3M1 (void) { - StackRelative (READ); - SBC8 (); + StackRelative (READ, SBC8); } static void OpE3M0 (void) { - StackRelative (READ); - SBC16 (); + StackRelative (READ, SBC16); } static void OpF3M1 (void) { - StackRelativeIndirectIndexed (READ); - SBC8 (); + StackRelativeIndirectIndexed (READ, SBC8); } static void OpF3M0 (void) { - StackRelativeIndirectIndexed (READ); - SBC16 (); + StackRelativeIndirectIndexed (READ, SBC16); } /**********************************************************************************************/ /* STA *************************************************************************************** */ static void Op85M1 (void) { - Direct (WRITE); - STA8 (); + Direct (WRITE, STA8); } static void Op85M0 (void) { - Direct (WRITE); - STA16 (); + Direct (WRITE, STA16); } static void Op95M1 (void) { - DirectIndexedX (WRITE); - STA8 (); + DirectIndexedX (WRITE, STA8); } static void Op95M0 (void) { - DirectIndexedX (WRITE); - STA16 (); + DirectIndexedX (WRITE, STA16); } static void Op92M1 (void) { - DirectIndirect (WRITE); - STA8 (); + DirectIndirect (WRITE, STA8); } static void Op92M0 (void) { - DirectIndirect (WRITE); - STA16 (); + DirectIndirect (WRITE, STA16); } static void Op81M1 (void) { - DirectIndexedIndirect (WRITE); - STA8 (); + DirectIndexedIndirect (WRITE, STA8); #ifdef noVAR_CYCLES if (CheckIndex ()) CPU.Cycles += ONE_CYCLE; @@ -2192,8 +1911,7 @@ static void Op81M1 (void) static void Op81M0 (void) { - DirectIndexedIndirect (WRITE); - STA16 (); + DirectIndexedIndirect (WRITE, STA16); #ifdef noVAR_CYCLES if (CheckIndex ()) CPU.Cycles += ONE_CYCLE; @@ -2202,248 +1920,208 @@ static void Op81M0 (void) static void Op91M1 (void) { - DirectIndirectIndexed (WRITE); - STA8 (); + DirectIndirectIndexed (WRITE, STA8); } static void Op91M0 (void) { - DirectIndirectIndexed (WRITE); - STA16 (); + DirectIndirectIndexed (WRITE, STA16); } static void Op87M1 (void) { - DirectIndirectLong (WRITE); - STA8 (); + DirectIndirectLong (WRITE, STA8); } static void Op87M0 (void) { - DirectIndirectLong (WRITE); - STA16 (); + DirectIndirectLong (WRITE, STA16); } static void Op97M1 (void) { - DirectIndirectIndexedLong (WRITE); - STA8 (); + DirectIndirectIndexedLong (WRITE, STA8); } static void Op97M0 (void) { - DirectIndirectIndexedLong (WRITE); - STA16 (); + DirectIndirectIndexedLong (WRITE, STA16); } static void Op8DM1 (void) { - Absolute (WRITE); - STA8 (); + Absolute (WRITE, STA8); } static void Op8DM0 (void) { - Absolute (WRITE); - STA16 (); + Absolute (WRITE, STA16); } static void Op9DM1 (void) { - AbsoluteIndexedX (WRITE); - STA8 (); + AbsoluteIndexedX (WRITE, STA8); } static void Op9DM0 (void) { - AbsoluteIndexedX (WRITE); - STA16 (); + AbsoluteIndexedX (WRITE, STA16); } static void Op99M1 (void) { - AbsoluteIndexedY (WRITE); - STA8 (); + AbsoluteIndexedY (WRITE, STA8); } static void Op99M0 (void) { - AbsoluteIndexedY (WRITE); - STA16 (); + AbsoluteIndexedY (WRITE, STA16); } static void Op8FM1 (void) { - AbsoluteLong (WRITE); - STA8 (); + AbsoluteLong (WRITE, STA8); } static void Op8FM0 (void) { - AbsoluteLong (WRITE); - STA16 (); + AbsoluteLong (WRITE, STA16); } static void Op9FM1 (void) { - AbsoluteLongIndexedX (WRITE); - STA8 (); + AbsoluteLongIndexedX (WRITE, STA8); } static void Op9FM0 (void) { - AbsoluteLongIndexedX (WRITE); - STA16 (); + AbsoluteLongIndexedX (WRITE, STA16); } static void Op83M1 (void) { - StackRelative (WRITE); - STA8 (); + StackRelative (WRITE, STA8); } static void Op83M0 (void) { - StackRelative (WRITE); - STA16 (); + StackRelative (WRITE, STA16); } static void Op93M1 (void) { - StackRelativeIndirectIndexed (WRITE); - STA8 (); + StackRelativeIndirectIndexed (WRITE, STA8); } static void Op93M0 (void) { - StackRelativeIndirectIndexed (WRITE); - STA16 (); + StackRelativeIndirectIndexed (WRITE, STA16); } /**********************************************************************************************/ /* STX *************************************************************************************** */ static void Op86X1 (void) { - Direct (WRITE); - STX8 (); + Direct (WRITE, STX8); } static void Op86X0 (void) { - Direct (WRITE); - STX16 (); + Direct (WRITE, STX16); } static void Op96X1 (void) { - DirectIndexedY (WRITE); - STX8 (); + DirectIndexedY (WRITE, STX8); } static void Op96X0 (void) { - DirectIndexedY (WRITE); - STX16 (); + DirectIndexedY (WRITE, STX16); } static void Op8EX1 (void) { - Absolute (WRITE); - STX8 (); + Absolute (WRITE, STX8); } static void Op8EX0 (void) { - Absolute (WRITE); - STX16 (); + Absolute (WRITE, STX16); } /**********************************************************************************************/ /* STY *************************************************************************************** */ static void Op84X1 (void) { - Direct (WRITE); - STY8 (); + Direct (WRITE, STY8); } static void Op84X0 (void) { - Direct (WRITE); - STY16 (); + Direct (WRITE, STY16); } static void Op94X1 (void) { - DirectIndexedX (WRITE); - STY8 (); + DirectIndexedX (WRITE, STY8); } static void Op94X0 (void) { - DirectIndexedX (WRITE); - STY16 (); + DirectIndexedX (WRITE, STY16); } static void Op8CX1 (void) { - Absolute (WRITE); - STY8 (); + Absolute (WRITE, STY8); } static void Op8CX0 (void) { - Absolute (WRITE); - STY16 (); + Absolute (WRITE, STY16); } /**********************************************************************************************/ /* STZ *************************************************************************************** */ static void Op64M1 (void) { - Direct (WRITE); - STZ8 (); + Direct (WRITE, STZ8); } static void Op64M0 (void) { - Direct (WRITE); - STZ16 (); + Direct (WRITE, STZ16); } static void Op74M1 (void) { - DirectIndexedX (WRITE); - STZ8 (); + DirectIndexedX (WRITE, STZ8); } static void Op74M0 (void) { - DirectIndexedX (WRITE); - STZ16 (); + DirectIndexedX (WRITE, STZ16); } static void Op9CM1 (void) { - Absolute (WRITE); - STZ8 (); + Absolute (WRITE, STZ8); } static void Op9CM0 (void) { - Absolute (WRITE); - STZ16 (); + Absolute (WRITE, STZ16); } static void Op9EM1 (void) { - AbsoluteIndexedX (WRITE); - STZ8 (); + AbsoluteIndexedX (WRITE, STZ8); } static void Op9EM0 (void) { - AbsoluteIndexedX (WRITE); - STZ16 (); + AbsoluteIndexedX (WRITE, STZ16); } /**********************************************************************************************/ @@ -2451,52 +2129,44 @@ static void Op9EM0 (void) /* TRB *************************************************************************************** */ static void Op14M1 (void) { - Direct (MODIFY); - TRB8 (); + Direct (MODIFY, TRB8); } static void Op14M0 (void) { - Direct (MODIFY); - TRB16 (); + Direct (MODIFY, TRB16); } static void Op1CM1 (void) { - Absolute (MODIFY); - TRB8 (); + Absolute (MODIFY, TRB8); } static void Op1CM0 (void) { - Absolute (MODIFY); - TRB16 (); + Absolute (MODIFY, TRB16); } /**********************************************************************************************/ /* TSB *************************************************************************************** */ static void Op04M1 (void) { - Direct (MODIFY); - TSB8 (); + Direct (MODIFY, TSB8); } static void Op04M0 (void) { - Direct (MODIFY); - TSB16 (); + Direct (MODIFY, TSB16); } static void Op0CM1 (void) { - Absolute (MODIFY); - TSB8 (); + Absolute (MODIFY, TSB8); } static void Op0CM0 (void) { - Absolute (MODIFY); - TSB16 (); + Absolute (MODIFY, TSB16); } /**********************************************************************************************/ @@ -2608,7 +2278,7 @@ inline void CPUShutdown() /* BCC */ static void Op90 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck0 (); if (!CheckCarry ()) { @@ -2616,14 +2286,14 @@ static void Op90 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - CPUShutdown (); + CPUShutdown(); } } /* BCS */ static void OpB0 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck0 (); if (CheckCarry ()) { @@ -2638,7 +2308,7 @@ static void OpB0 (void) /* BEQ */ static void OpF0 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck2 (); if (CheckZero ()) { @@ -2653,7 +2323,7 @@ static void OpF0 (void) /* BMI */ static void Op30 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck1 (); if (CheckNegative ()) { @@ -2668,7 +2338,7 @@ static void Op30 (void) /* BNE */ static void OpD0 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck1 (); if (!CheckZero ()) { @@ -2684,7 +2354,7 @@ static void OpD0 (void) /* BPL */ static void Op10 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck1 (); if (!CheckNegative ()) { @@ -2699,7 +2369,7 @@ static void Op10 (void) /* BRA */ static void Op80 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -2710,7 +2380,7 @@ static void Op80 (void) /* BVC */ static void Op50 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck0 (); if (!CheckOverflow ()) { @@ -2725,7 +2395,7 @@ static void Op50 (void) /* BVS */ static void Op70 (void) { - Relative (JUMP); + Relative (JUMP, OpAddressPassthrough); BranchCheck0 (); if (CheckOverflow ()) { @@ -2928,39 +2598,39 @@ static void OpEA (void) //PEA NL static void OpF4E1 (void) { - Absolute (NONE); + Absolute (NONE, OpAddressPassthrough); PushWENew ((unsigned short)OpAddress); } static void OpF4 (void) { - Absolute (NONE); + Absolute (NONE, OpAddressPassthrough); PushW ((unsigned short)OpAddress); } //PEI NL static void OpD4E1 (void) { - DirectIndirect (NONE); + DirectIndirect (NONE, OpAddressPassthrough); PushWENew ((unsigned short)OpAddress); } static void OpD4 (void) { - DirectIndirect (NONE); + DirectIndirect (NONE, OpAddressPassthrough); PushW ((unsigned short)OpAddress); } //PER NL static void Op62E1 (void) { - RelativeLong (NONE); + RelativeLong (NONE, OpAddressPassthrough); PushWENew ((unsigned short)OpAddress); } static void Op62 (void) { - RelativeLong (NONE); + RelativeLong (NONE, OpAddressPassthrough); PushW ((unsigned short)OpAddress); } @@ -3593,7 +3263,7 @@ static void Op00 (void) /* BRL ************************************************************************************** */ static void Op82 (void) { - RelativeLong (JUMP); + RelativeLong (JUMP, OpAddressPassthrough); S9xSetPCBase (ICPU.ShiftedPB + OpAddress); } /**********************************************************************************************/ @@ -3779,7 +3449,7 @@ static void Op02 (void) /* JML *************************************************************************************** */ static void OpDC (void) { - AbsoluteIndirectLong (JUMP); + AbsoluteIndirectLong (JUMP, OpAddressPassthrough); Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); @@ -3790,7 +3460,7 @@ static void OpDC (void) static void Op5C (void) { - AbsoluteLong (JUMP); + AbsoluteLong (JUMP, OpAddressPassthrough); Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); @@ -3800,7 +3470,7 @@ static void Op5C (void) /* JMP *************************************************************************************** */ static void Op4C (void) { - Absolute (JUMP); + Absolute (JUMP, OpAddressPassthrough); S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); #if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES) CPUShutdown (); @@ -3809,13 +3479,13 @@ static void Op4C (void) static void Op6C (void) { - AbsoluteIndirect (JUMP); + AbsoluteIndirect (JUMP, OpAddressPassthrough); S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); } static void Op7C (void) { - AbsoluteIndexedIndirect (JUMP); + AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); S9xSetPCBase (ICPU.ShiftedPB + OpAddress); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; @@ -3826,7 +3496,7 @@ static void Op7C (void) /* JSL/RTL *********************************************************************************** */ static void Op22E1 (void) { - AbsoluteLong (JUMP); + AbsoluteLong (JUMP, OpAddressPassthrough); PushB (Registers.PB); PushWENew (CPU.PC - CPU.PCBase - 1); Registers.PB = (uint8) (OpAddress >> 16); @@ -3836,7 +3506,7 @@ static void Op22E1 (void) static void Op22 (void) { - AbsoluteLong (JUMP); + AbsoluteLong (JUMP, OpAddressPassthrough); PushB (Registers.PB); PushW (CPU.PC - CPU.PCBase - 1); Registers.PB = (uint8) (OpAddress >> 16); @@ -3870,7 +3540,7 @@ static void Op6B (void) /* JSR/RTS *********************************************************************************** */ static void Op20 (void) { - Absolute (JUMP); + Absolute (JUMP, OpAddressPassthrough); PushW (CPU.PC - CPU.PCBase - 1); S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); #ifndef SA1_OPCODES @@ -3881,7 +3551,7 @@ static void Op20 (void) //JSR a,x static void OpFCE1 (void) { - AbsoluteIndexedIndirect (JUMP); + AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); PushWENew (CPU.PC - CPU.PCBase - 1); S9xSetPCBase (ICPU.ShiftedPB + OpAddress); #ifndef SA1_OPCODES @@ -3891,7 +3561,7 @@ static void OpFCE1 (void) static void OpFC (void) { - AbsoluteIndexedIndirect (JUMP); + AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); PushW (CPU.PC - CPU.PCBase - 1); S9xSetPCBase (ICPU.ShiftedPB + OpAddress); #ifndef SA1_OPCODES @@ -4093,7 +3763,6 @@ static void Op40 (void) missing.emulate6502 = 1; } S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); - if (CheckIndex ()) { Registers.XH = 0; @@ -4126,9 +3795,7 @@ static void OpCB (void) SA1.Executing = FALSE; do { - APU_EXECUTE1 (); - } while (APU.Cycles < SA1.NextEvent); - SA1.Executing = TRUE; + APU_EXECUTE1 (, } while (APU.Cycles < SA1.NextEvent, SA1.Executing = TRUE; } } #endif -- cgit v1.2.3 From 7a6ffe8a1e241f4308be9867990563a06a335b86 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Sun, 23 Dec 2012 18:03:54 -0500 Subject: Screen tearing-related fix. --- source/nds/gui.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 4a04efc..d818602 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -4083,6 +4083,7 @@ u32 menu(u16 *screen) ds2_clearScreen(DUAL_SCREEN, 0); ds2_flipScreen(DUAL_SCREEN, 1); + copy_screen(up_screen_addr, (void*) screen, 0, 0, 256, 192); ds2_flipScreen(UP_SCREEN, 1); // Flip again because otherwise it flickers ds2_setBacklight(2); -- cgit v1.2.3 From bb39cc82364ea00324a054ba0970bdc07ecfdeec Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Sun, 23 Dec 2012 20:51:14 -0500 Subject: Correctly handle multi-part codes, for all cheat types (GG, PAR, GF). They are currently loaded as multiple codes, however. --- source/cheats2.cpp | 6 ++++-- source/nds/gcheat.c | 12 +++++++----- source/nds/gui.c | 13 ++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) (limited to 'source') diff --git a/source/cheats2.cpp b/source/cheats2.cpp index 1423637..8d81d6d 100644 --- a/source/cheats2.cpp +++ b/source/cheats2.cpp @@ -105,17 +105,19 @@ void S9xInitCheatData () void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, uint8 byte) { - if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat. c [0])) + if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat.c [0])) { Cheat.c [Cheat.num_cheats].address = address; Cheat.c [Cheat.num_cheats].byte = byte; - Cheat.c [Cheat.num_cheats].enabled = TRUE; + Cheat.c [Cheat.num_cheats].enabled = enable; if (save_current_value) { Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByte (address); Cheat.c [Cheat.num_cheats].saved = TRUE; } Cheat.num_cheats++; + if (enable) + S9xApplyCheat(Cheat.num_cheats - 1); } } diff --git a/source/nds/gcheat.c b/source/nds/gcheat.c index 648bfda..e3d0e8d 100644 --- a/source/nds/gcheat.c +++ b/source/nds/gcheat.c @@ -72,8 +72,8 @@ int NDSSFCLoadCheatFile(const char* filename) fclose(fp); return -2; } + *ptr = '\0'; // End the codes there *ptr++; // Past the comma - *(ptr - 1) = '\0'; // End the codes there uint32 i = 0; description = ptr; // Skip starting " in description @@ -86,19 +86,21 @@ int NDSSFCLoadCheatFile(const char* filename) } *ptr = '\0'; - uint32 n = 0, c; + uint32 c; // n is the number of cheat codes. Beware of MAX_CHEATS_T. // List of cheat codes having the same description. ptr = codes_ptr; while (*ptr && !(*ptr == ',' || *ptr == '"')) { - if (n >= MAX_CHEATS_T) { + if (Cheat.num_cheats >= MAX_CHEATS_T) { fclose(fp); return 0; } i = 0; - while (*ptr && *ptr != '+' && i < sizeof(code) - 1) + while (*ptr && !(*ptr == '+' || *ptr == ',' || *ptr == '"') && i < sizeof(code) - 1) code[i++] = *ptr++; + if (*ptr) + ptr++; // Go past the + , or " code[i] = '\0'; if (!S9xGameGenieToRaw (code, &address, &byte)) { S9xAddCheat (FALSE, TRUE, address, byte); @@ -112,7 +114,7 @@ int NDSSFCLoadCheatFile(const char* filename) { for (c = 0; c < num_bytes; c++) { S9xAddCheat (FALSE, TRUE, address + c, bytes[c]); - strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, 22); + strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); } } else { diff --git a/source/nds/gui.c b/source/nds/gui.c index 84f522f..1b265b6 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -2618,10 +2618,12 @@ u32 menu(u16 *screen) if(load_file(file_ext, tmp_filename, DEFAULT_CHEAT_DIR) != -1) { - strcpy(line_buffer, DEFAULT_CHEAT_DIR); - strcat(line_buffer, "/"); - strcat(line_buffer, tmp_filename); + sprintf(line_buffer, "%s/%s", DEFAULT_CHEAT_DIR, tmp_filename); flag = NDSSFCLoadCheatFile(line_buffer); + + strcpy(line_buffer, (char *) S9xGetFilename (".chb")); + S9xSaveCheatFile (line_buffer); // cheat binary + if(0 != flag) { //load cheat file failure S9xDeleteCheats(); @@ -2630,12 +2632,9 @@ u32 menu(u16 *screen) return; } - strcpy(line_buffer, (char *) S9xGetFilename (".chb")); - - S9xSaveCheatFile (line_buffer); // cheat binary - menu_cheat_page = 0; cheat_menu_init(); + } } -- cgit v1.2.3 From f843d68bb65f8a532b365efc5cbdf5be65c5f517 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 24 Dec 2012 01:15:41 -0500 Subject: Make the GUI accept and save Snes9x's cheat file format. Improve support for saving the values present in ROM/RAM before a cheat is applied. Beautify the cheat selection menu, making it more tabular. --- source/cheats2.cpp | 29 +++++---- source/nds/gcheat.c | 6 +- source/nds/gui.c | 171 ++++++++++++++-------------------------------------- 3 files changed, 65 insertions(+), 141 deletions(-) (limited to 'source') diff --git a/source/cheats2.cpp b/source/cheats2.cpp index 8d81d6d..e5a7b0f 100644 --- a/source/cheats2.cpp +++ b/source/cheats2.cpp @@ -171,6 +171,8 @@ void S9xRemoveCheat (uint32 which1) *(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte; else S9xSetByte (Cheat.c [which1].saved_byte, address); + // Unsave the address for the next call to S9xRemoveCheat. + Cheat.c [which1].saved = FALSE; } } @@ -213,20 +215,24 @@ bool8 S9xLoadCheatFile (const char *filename) Cheat.num_cheats = 0; FILE *fs = fopen (filename, "rb"); - uint8 data [28]; + uint8 data [8 + MAX_SFCCHEAT_NAME]; if (!fs) return (FALSE); - while (fread ((void *) data, 1, 28, fs) == 28) + while (fread ((void *) data, 1, 8 + MAX_SFCCHEAT_NAME, fs) == 8 + MAX_SFCCHEAT_NAME) { + if (data[6] != 254 || data[7] != 252) { + fclose (fs); + return (FALSE); + } Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0; Cheat.c [Cheat.num_cheats].byte = data [1]; Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16); Cheat.c [Cheat.num_cheats].saved_byte = data [5]; Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0; - memmove (Cheat.c [Cheat.num_cheats].name, &data [8], 20); - Cheat.c [Cheat.num_cheats++].name [20] = 0; + memcpy (Cheat.c [Cheat.num_cheats].name, &data [8], MAX_SFCCHEAT_NAME - 1); + Cheat.c [Cheat.num_cheats++].name [MAX_SFCCHEAT_NAME - 1] = 0; } fclose (fs); @@ -242,7 +248,7 @@ bool8 S9xSaveCheatFile (const char *filename) } FILE *fs = fopen (filename, "wb"); - uint8 data [28]; + uint8 data [8 + MAX_SFCCHEAT_NAME]; if (!fs) return (FALSE); @@ -250,12 +256,9 @@ bool8 S9xSaveCheatFile (const char *filename) uint32 i; for (i = 0; i < Cheat.num_cheats; i++) { - memset (data, 0, 28); - if (i == 0) - { - data [6] = 254; - data [7] = 252; - } + memset (data, 0, 8 + MAX_SFCCHEAT_NAME); + data [6] = 254; + data [7] = 252; if (!Cheat.c [i].enabled) data [0] |= 4; @@ -268,8 +271,8 @@ bool8 S9xSaveCheatFile (const char *filename) data [4] = (uint8) (Cheat.c [i].address >> 16); data [5] = Cheat.c [i].saved_byte; - memmove (&data [8], Cheat.c [i].name, 19); - if (fwrite (data, 28, 1, fs) != 1) + memcpy (&data [8], Cheat.c [i].name, MAX_SFCCHEAT_NAME - 1); + if (fwrite (data, 8 + MAX_SFCCHEAT_NAME, 1, fs) != 1) { fclose (fs); return (FALSE); diff --git a/source/nds/gcheat.c b/source/nds/gcheat.c index e3d0e8d..d0ada43 100644 --- a/source/nds/gcheat.c +++ b/source/nds/gcheat.c @@ -103,17 +103,17 @@ int NDSSFCLoadCheatFile(const char* filename) ptr++; // Go past the + , or " code[i] = '\0'; if (!S9xGameGenieToRaw (code, &address, &byte)) { - S9xAddCheat (FALSE, TRUE, address, byte); + S9xAddCheat (FALSE, FALSE, address, byte); strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); } else if (!S9xProActionReplayToRaw (code, &address, &byte)) { - S9xAddCheat (FALSE, TRUE, address, byte); + S9xAddCheat (FALSE, FALSE, address, byte); strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); } else if (!S9xGoldFingerToRaw (code, &address, &sram, &num_bytes, bytes)) { for (c = 0; c < num_bytes; c++) { - S9xAddCheat (FALSE, TRUE, address + c, bytes[c]); + S9xAddCheat (FALSE, FALSE, address + c, bytes[c]); strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME); } } diff --git a/source/nds/gui.c b/source/nds/gui.c index 1b265b6..a8152c4 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -111,7 +111,7 @@ static unsigned int savestate_index; action_function, \ passive_function, \ NULL, \ - &cheat_format_ptr[number], \ + &cheat_data_ptr[number], \ enable_disable_options, \ &(Cheat.c[number].enabled), \ 2, \ @@ -1659,8 +1659,9 @@ u32 menu(u16 *screen) u32 first_load = 0; char tmp_filename[MAX_FILE]; char line_buffer[512]; - char cheat_format_str[MAX_CHEATS_T][41*4]; - char *cheat_format_ptr[MAX_CHEATS_T]; + char cheat_data_str[MAX_CHEATS_T][5]; + // ^ Holds the index inside Cheat, as a number in an ASCIIZ string + char* cheat_data_ptr[MAX_CHEATS_T]; MENU_TYPE *current_menu; MENU_OPTION_TYPE *current_option; @@ -2222,16 +2223,8 @@ u32 menu(u16 *screen) { for(i = 0; i < MAX_CHEATS_T; i++) { - if(i >= Cheat.num_cheats) - { - sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_NON_LOAD], i); - } - else - { - sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, Cheat.c[i].name); - } - - cheat_format_ptr[i]= cheat_format_str[i]; + sprintf(cheat_data_str[i], "%d", i); + cheat_data_ptr[i] = &cheat_data_str[i][0]; } reload_cheats_page(); @@ -2239,6 +2232,17 @@ u32 menu(u16 *screen) void cheat_menu_end() { + // Honour current cheat selections. + uint32 i; + for (i = 0; i < Cheat.num_cheats; i++) { + if (Cheat.c[i].enabled) + S9xApplyCheat(i); + else + S9xRemoveCheat(i); + } + // Save current cheat selections to the cheat binary file. + strcpy(line_buffer, (char *) S9xGetFilename (".chb")); + S9xSaveCheatFile (line_buffer); // cheat binary } void dynamic_cheat_key() @@ -2452,102 +2456,13 @@ u32 menu(u16 *screen) void cheat_option_action() { - unsigned int nums; - - nums = (CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1; - if(gui_action == CURSOR_SELECT && nums < Cheat.num_cheats) - { - unsigned int m; - - // nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num; - // REVISIT [Neb] - - if(dynamic_cheat_options) - { - free((void*)dynamic_cheat_options); - dynamic_cheat_options = NULL; - } - - if(dynamic_cheat_menu) - { - free((void*)dynamic_cheat_menu); - dynamic_cheat_menu = NULL; - } - - dynamic_cheat_options = (MENU_OPTION_TYPE*)malloc(sizeof(MENU_OPTION_TYPE)*(nums+1)); - if(dynamic_cheat_options == NULL) return; - - dynamic_cheat_menu = (MENU_TYPE*)malloc(sizeof(MENU_TYPE)); - if(dynamic_cheat_menu == NULL) - { - free((void*)dynamic_cheat_options); - dynamic_cheat_options = NULL; - return; - } - - //menu - dynamic_cheat_menu->init_function = NULL; - dynamic_cheat_menu->passive_function = dynamic_cheat_menu_passive; - dynamic_cheat_menu->key_function = dynamic_cheat_key; - dynamic_cheat_menu->end_function = dynamic_cheat_menu_end; - dynamic_cheat_menu->options = dynamic_cheat_options; - dynamic_cheat_menu->num_options = nums+1; - dynamic_cheat_menu->focus_option = 0; - dynamic_cheat_menu->screen_focus = 0; - //back option - dynamic_cheat_options[0].action_function = NULL; - dynamic_cheat_options[0].passive_function = NULL; - dynamic_cheat_options[0].sub_menu = &cheats_menu; - // dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id); - // REVISIT [Neb] - dynamic_cheat_options[0].options = NULL; - dynamic_cheat_options[0].current_option = NULL; - dynamic_cheat_options[0].num_options = 0; - dynamic_cheat_options[0].help_string = NULL; - dynamic_cheat_options[0].line_number = 0; - dynamic_cheat_options[0].option_type = SUBMENU_TYPE; - - // m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id; - // REVISIT [Neb] - for(i= 0; i < nums; i++) - { - dynamic_cheat_options[i+1].action_function = dynamic_cheat_action; - dynamic_cheat_options[i+1].passive_function = NULL; - dynamic_cheat_options[i+1].sub_menu = NULL; - // dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num)); - // REVISIT [Neb] - dynamic_cheat_options[i+1].options = NULL; - dynamic_cheat_options[i+1].current_option = NULL; - dynamic_cheat_options[i+1].num_options = 2; - dynamic_cheat_options[i+1].help_string = NULL; - dynamic_cheat_options[i+1].line_number = i+1; - dynamic_cheat_options[i+1].option_type = ACTION_TYPE; - } - - // dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + - // current_option_num -1].active & 0x1; - // dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + - // current_option_num -1].sub_active << 16; - // REVISIT [Neb] - - //Initial srollable options - int k; - - draw_hscroll_init(down_screen_addr, 50, 9, 180, COLOR_TRANS, - COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string); - - if(nums>5) nums = SUBMENU_ROW_NUM; - for(k= 0; k < nums; k++) - { - draw_hscroll_init(down_screen_addr, 23, 40 + k*27, 200, - COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[k+1].display_string); - } - dynamic_cheat_scroll_value= 0; - - choose_menu(dynamic_cheat_menu); - } } +#define CHEAT_NUMBER_X 26 +#define CHEAT_DESC_X 52 +#define CHEAT_DESC_SX 163 +#define CHEAT_ACTIVE_X 225 + void cheat_option_passive() { unsigned short color; @@ -2562,27 +2477,33 @@ u32 menu(u16 *screen) //sprintf("%A") will have problem ? strcpy(tmp_buf, *(display_option->display_string)); - pt = strrchr(tmp_buf, ':'); - if(pt != NULL) - sprintf(pt+1, "%s", *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)]))); + // This is the number of the cheat to display - strcpy(line_buffer, tmp_buf); - pt = strrchr(line_buffer, ')'); - *pt = '\0'; - pt = strchr(line_buffer, '('); + int i = atoi(tmp_buf); - len = BDF_cut_string(pt+1, 0, 2); - if(len > 90) - { - len = BDF_cut_string(pt+1, 90, 1); - *(pt+1+len) = '\0'; - strcat(line_buffer, "..."); - } + sprintf(line_buffer, "%d.", i + 1); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_NUMBER_X, 40 + display_option-> line_number*27); - pt = strrchr(tmp_buf, ')'); - strcat(line_buffer, pt); + if (i >= Cheat.num_cheats) { + PRINT_STRING_BG(down_screen_addr, msg[MSG_CHEAT_MENU_NON_LOAD], color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27); + } + else { + strcpy(line_buffer, Cheat.c[i].name); + len = BDF_cut_string(line_buffer, 0, 2); + if(len > CHEAT_DESC_SX) + { + len = BDF_cut_string(line_buffer, CHEAT_DESC_SX, 1); + line_buffer[len] = '\0'; + strcat(line_buffer, "..."); + } + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27); - PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 40 + display_option-> line_number*27); + if (Cheat.c[i].enabled) + strcpy(line_buffer, "+"); + else + strcpy(line_buffer, "-"); + PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_ACTIVE_X, 40 + display_option-> line_number*27); + } } void dynamic_cheat_menu_end() @@ -3578,7 +3499,7 @@ u32 menu(u16 *screen) { for(i = 0; i < CHEATS_PER_PAGE; i++) { - cheats_options[i+1].display_string = &cheat_format_ptr[(CHEATS_PER_PAGE * menu_cheat_page) + i]; + cheats_options[i+1].display_string = &cheat_data_ptr[(CHEATS_PER_PAGE * menu_cheat_page) + i]; cheats_options[i+1].current_option = &(Cheat.c[(CHEATS_PER_PAGE * menu_cheat_page) + i].enabled); } } -- cgit v1.2.3 From e7ce8dd66c19de431fb347a0f3cd0ea867a802ce Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 24 Dec 2012 02:15:42 -0500 Subject: Bump to v. 1.09. Update the readme for cheats. Update the github link in source.txt. --- source/nds/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 979d99c..772775b 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -59,7 +59,7 @@ char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lan ******************************************************************************/ #define SUBMENU_ROW_NUM 6 -#define NDSSFC_VERSION "1.08" +#define NDSSFC_VERSION "1.09" #define SAVE_STATE_SLOT_NUM 10 -- cgit v1.2.3 From f29c76dc58689fe55f4ece494a0d3d44c831203f Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 24 Dec 2012 03:53:20 -0500 Subject: End the use of global variables for CPU emulation. This creates fewer memory store instructions in many SNES, SA1 and APU opcodes. Fix the APU half-carry bug, which may be audible. globals.cpp: Get rid of A1, A2, A3, A4, W1, W2, W3, W4, Int8, Int16, Int32, Work8, Work16, Work32, Ans8, Ans16, Ans32. --- source/cpuaddr.h | 2 +- source/cpumacro.h | 128 +++++++++++++++--------------- source/cpuops.cpp | 32 +++----- source/globals.cpp | 2 + source/spc700.cpp | 229 +++++++++++++++++++++++++---------------------------- 5 files changed, 187 insertions(+), 206 deletions(-) (limited to 'source') diff --git a/source/cpuaddr.h b/source/cpuaddr.h index 84ee45b..09f5788 100644 --- a/source/cpuaddr.h +++ b/source/cpuaddr.h @@ -134,7 +134,7 @@ static void Immediate16 (AccessMode a, InternalOp op) static void Relative (AccessMode a, InternalOp op) { - Int8 = *CPU.PC++; + int8 Int8 = *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif diff --git a/source/cpumacro.h b/source/cpumacro.h index 335576a..1bd5d2f 100644 --- a/source/cpumacro.h +++ b/source/cpumacro.h @@ -104,14 +104,14 @@ static void SetZN8 (uint8 Work) static void ADC8 (long Addr) { - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); if (CheckDecimal ()) { - A1 = (Registers.A.W) & 0xF; - A2 = (Registers.A.W >> 4) & 0xF; - W1 = Work8 & 0xF; - W2 = (Work8 >> 4) & 0xF; + uint8 A1 = (Registers.A.W) & 0xF; + uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 W1 = Work8 & 0xF; + uint8 W2 = (Work8 >> 4) & 0xF; A1 += W1 + CheckCarry(); if (A1 > 9) @@ -133,7 +133,7 @@ static void ADC8 (long Addr) ClearCarry (); } - Ans8 = (A2 << 4) | A1; + int8 Ans8 = (A2 << 4) | A1; if (~(Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80) SetOverflow(); @@ -144,7 +144,7 @@ static void ADC8 (long Addr) } else { - Ans16 = Registers.AL + Work8 + CheckCarry(); + int16 Ans16 = Registers.AL + Work8 + CheckCarry(); ICPU._Carry = Ans16 >= 0x100; @@ -161,18 +161,18 @@ static void ADC8 (long Addr) static void ADC16 (long Addr) { - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); if (CheckDecimal ()) { - A1 = (Registers.A.W) & 0xF; - A2 = (Registers.A.W >> 4) & 0xF; - A3 = (Registers.A.W >> 8) & 0xF; - A4 = (Registers.A.W >> 12) & 0xF; - W1 = Work16 & 0xF; - W2 = (Work16 >> 4) & 0xF; - W3 = (Work16 >> 8) & 0xF; - W4 = (Work16 >> 12) & 0xF; + uint8 A1 = (Registers.A.W) & 0xF; + uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 A3 = (Registers.A.W >> 8) & 0xF; + uint8 A4 = (Registers.A.W >> 12) & 0xF; + uint8 W1 = Work16 & 0xF; + uint8 W2 = (Work16 >> 4) & 0xF; + uint8 W3 = (Work16 >> 8) & 0xF; + uint8 W4 = (Work16 >> 12) & 0xF; A1 += W1 + CheckCarry (); if (A1 > 9) @@ -210,7 +210,7 @@ static void ADC16 (long Addr) ClearCarry (); } - Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); if (~(Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000) SetOverflow(); @@ -221,7 +221,7 @@ static void ADC16 (long Addr) } else { - Ans32 = Registers.A.W + Work16 + CheckCarry(); + uint32 Ans32 = Registers.A.W + Work16 + CheckCarry(); ICPU._Carry = Ans32 >= 0x10000; @@ -272,7 +272,7 @@ static void ASL16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); ICPU._Carry = (Work16 & 0x8000) != 0; Work16 <<= 1; //S9xSetWord (Work16, Addr); @@ -286,7 +286,7 @@ static void ASL8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); ICPU._Carry = (Work8 & 0x80) != 0; Work8 <<= 1; S9xSetByte (Work8, Addr); @@ -295,7 +295,7 @@ static void ASL8 (long Addr) static void BIT16 (long Addr) { - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); ICPU._Overflow = (Work16 & 0x4000) != 0; ICPU._Negative = (uint8) (Work16 >> 8); ICPU._Zero = (Work16 & Registers.A.W) != 0; @@ -303,7 +303,7 @@ static void BIT16 (long Addr) static void BIT8 (long Addr) { - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); ICPU._Overflow = (Work8 & 0x40) != 0; ICPU._Negative = Work8; ICPU._Zero = Work8 & Registers.AL; @@ -311,7 +311,7 @@ static void BIT8 (long Addr) static void CMP16 (long Addr) { - Int32 = (long) Registers.A.W - + int32 Int32 = (long) Registers.A.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -319,7 +319,7 @@ static void CMP16 (long Addr) static void CMP8 (long Addr) { - Int16 = (short) Registers.AL - + int16 Int16 = (short) Registers.AL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -327,7 +327,7 @@ static void CMP8 (long Addr) static void CMX16 (long Addr) { - Int32 = (long) Registers.X.W - + int32 Int32 = (long) Registers.X.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -335,7 +335,7 @@ static void CMX16 (long Addr) static void CMX8 (long Addr) { - Int16 = (short) Registers.XL - + int16 Int16 = (short) Registers.XL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -343,7 +343,7 @@ static void CMX8 (long Addr) static void CMY16 (long Addr) { - Int32 = (long) Registers.Y.W - + int32 Int32 = (long) Registers.Y.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -351,7 +351,7 @@ static void CMY16 (long Addr) static void CMY8 (long Addr) { - Int16 = (short) Registers.YL - + int16 Int16 = (short) Registers.YL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -392,7 +392,7 @@ static void DEC16 (long Addr) CPU.WaitAddress = NULL; #endif - Work16 = S9xGetWord (Addr) - 1; + uint16 Work16 = S9xGetWord (Addr) - 1; //S9xSetWord (Work16, Addr); S9xSetByte (Work16>>8, Addr+1); S9xSetByte (Work16&0xFF, Addr); @@ -408,7 +408,7 @@ static void DEC8 (long Addr) CPU.WaitAddress = NULL; #endif - Work8 = S9xGetByte (Addr) - 1; + uint8 Work8 = S9xGetByte (Addr) - 1; S9xSetByte (Work8, Addr); SetZN8 (Work8); } @@ -460,7 +460,7 @@ static void INC16 (long Addr) CPU.WaitAddress = NULL; #endif - Work16 = S9xGetWord (Addr) + 1; + uint16 Work16 = S9xGetWord (Addr) + 1; //S9xSetWord (Work16, Addr); S9xSetByte (Work16>>8, Addr+1); S9xSetByte (Work16&0xFF, Addr); @@ -476,7 +476,7 @@ static void INC8 (long Addr) CPU.WaitAddress = NULL; #endif - Work8 = S9xGetByte (Addr) + 1; + uint8 Work8 = S9xGetByte (Addr) + 1; S9xSetByte (Work8, Addr); SetZN8 (Work8); } @@ -542,7 +542,7 @@ static void LSR16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); ICPU._Carry = Work16 & 1; Work16 >>= 1; //S9xSetWord (Work16, Addr); @@ -556,7 +556,7 @@ static void LSR8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); ICPU._Carry = Work8 & 1; Work8 >>= 1; S9xSetByte (Work8, Addr); @@ -580,7 +580,7 @@ static inline void A_ROL16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = (Registers.A.W << 1) | CheckCarry(); + uint32 Work32 = (Registers.A.W << 1) | CheckCarry(); ICPU._Carry = Work32 >= 0x10000; Registers.A.W = (uint16) Work32; SetZN16 ((uint16) Work32); @@ -591,7 +591,7 @@ static inline void A_ROL8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = Registers.AL; + uint16 Work16 = Registers.AL; Work16 <<= 1; Work16 |= CheckCarry(); ICPU._Carry = Work16 >= 0x100; @@ -604,7 +604,7 @@ static void ROL16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = S9xGetWord (Addr); + uint32 Work32 = S9xGetWord (Addr); Work32 <<= 1; Work32 |= CheckCarry(); ICPU._Carry = Work32 >= 0x10000; @@ -619,7 +619,7 @@ static void ROL8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetByte (Addr); + uint16 Work16 = S9xGetByte (Addr); Work16 <<= 1; Work16 |= CheckCarry (); ICPU._Carry = Work16 >= 0x100; @@ -632,7 +632,7 @@ static inline void A_ROR16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = Registers.A.W; + uint32 Work32 = Registers.A.W; Work32 |= (int) CheckCarry() << 16; ICPU._Carry = (uint8) (Work32 & 1); Work32 >>= 1; @@ -645,7 +645,7 @@ static inline void A_ROR8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = Registers.AL | ((uint16) CheckCarry() << 8); + uint16 Work16 = Registers.AL | ((uint16) CheckCarry() << 8); ICPU._Carry = (uint8) Work16 & 1; Work16 >>= 1; Registers.AL = (uint8) Work16; @@ -657,7 +657,7 @@ static void ROR16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work32 = S9xGetWord (Addr); + uint32 Work32 = S9xGetWord (Addr); Work32 |= (int) CheckCarry() << 16; ICPU._Carry = (uint8) (Work32 & 1); Work32 >>= 1; @@ -672,7 +672,7 @@ static void ROR8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetByte (Addr); + uint16 Work16 = S9xGetByte (Addr); Work16 |= (int) CheckCarry () << 8; ICPU._Carry = (uint8) (Work16 & 1); Work16 >>= 1; @@ -682,18 +682,18 @@ static void ROR8 (long Addr) static void SBC16 (long Addr) { - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); if (CheckDecimal ()) { - A1 = (Registers.A.W) & 0xF; - A2 = (Registers.A.W >> 4) & 0xF; - A3 = (Registers.A.W >> 8) & 0xF; - A4 = (Registers.A.W >> 12) & 0xF; - W1 = Work16 & 0xF; - W2 = (Work16 >> 4) & 0xF; - W3 = (Work16 >> 8) & 0xF; - W4 = (Work16 >> 12) & 0xF; + uint8 A1 = (Registers.A.W) & 0xF; + uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 A3 = (Registers.A.W >> 8) & 0xF; + uint8 A4 = (Registers.A.W >> 12) & 0xF; + uint8 W1 = Work16 & 0xF; + uint8 W2 = (Work16 >> 4) & 0xF; + uint8 W3 = (Work16 >> 8) & 0xF; + uint8 W4 = (Work16 >> 12) & 0xF; A1 -= W1 + !CheckCarry (); A2 -= W2; @@ -724,7 +724,7 @@ static void SBC16 (long Addr) SetCarry (); } - Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); if ((Registers.A.W ^ Work16) & (Registers.A.W ^ Ans16) & 0x8000) SetOverflow(); @@ -736,7 +736,7 @@ static void SBC16 (long Addr) else { - Int32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; + int32 Int32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; ICPU._Carry = Int32 >= 0; @@ -752,13 +752,13 @@ static void SBC16 (long Addr) static void SBC8 (long Addr) { - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); if (CheckDecimal ()) { - A1 = (Registers.A.W) & 0xF; - A2 = (Registers.A.W >> 4) & 0xF; - W1 = Work8 & 0xF; - W2 = (Work8 >> 4) & 0xF; + uint8 A1 = (Registers.A.W) & 0xF; + uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 W1 = Work8 & 0xF; + uint8 W2 = (Work8 >> 4) & 0xF; A1 -= W1 + !CheckCarry (); A2 -= W2; @@ -777,7 +777,7 @@ static void SBC8 (long Addr) SetCarry (); } - Ans8 = (A2 << 4) | A1; + uint8 Ans8 = (A2 << 4) | A1; if ((Registers.AL ^ Work8) & (Registers.AL ^ Ans8) & 0x80) SetOverflow (); @@ -788,7 +788,7 @@ static void SBC8 (long Addr) } else { - Int16 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1; + int16 Int16 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1; ICPU._Carry = Int16 >= 0; if ((Registers.AL ^ Work8) & @@ -846,7 +846,7 @@ static void TSB16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); ICPU._Zero = (Work16 & Registers.A.W) != 0; Work16 |= Registers.A.W; //S9xSetWord (Work16, Addr); @@ -859,7 +859,7 @@ static void TSB8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); ICPU._Zero = Work8 & Registers.AL; Work8 |= Registers.AL; S9xSetByte (Work8, Addr); @@ -870,7 +870,7 @@ static void TRB16 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work16 = S9xGetWord (Addr); + uint16 Work16 = S9xGetWord (Addr); ICPU._Zero = (Work16 & Registers.A.W) != 0; Work16 &= ~Registers.A.W; //S9xSetWord (Work16, Addr); @@ -883,7 +883,7 @@ static void TRB8 (long Addr) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Work8 = S9xGetByte (Addr); + uint8 Work8 = S9xGetByte (Addr); ICPU._Zero = Work8 & Registers.AL; Work8 &= ~Registers.AL; S9xSetByte (Work8, Addr); diff --git a/source/cpuops.cpp b/source/cpuops.cpp index 33a2005..719465e 100644 --- a/source/cpuops.cpp +++ b/source/cpuops.cpp @@ -100,19 +100,6 @@ #include "sa1.h" #include "spc7110.h" -START_EXTERN_C -extern uint8 A1, A2, A3, A4, W1, W2, W3, W4; -extern uint8 Ans8; -extern uint16 Ans16; -extern uint32 Ans32; -extern uint8 Work8; -extern uint16 Work16; -extern uint32 Work32; -extern signed char Int8; -extern short Int16; -extern long Int32; -END_EXTERN_C - #include "cpuexec.h" #include "cpuaddr.h" #include "cpuops.h" @@ -561,7 +548,7 @@ static void Op3CM0 (void) /* CMP *************************************************************************************** */ static void OpC9M1 (void) { - Int32 = (int) Registers.AL - (int) *CPU.PC++; + int32 Int32 = (int) Registers.AL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -571,6 +558,7 @@ static void OpC9M1 (void) static void OpC9M0 (void) { + int32 Int32; #ifdef FAST_LSB_WORD_ACCESS Int32 = (long) Registers.A.W - (long) *(uint16 *) CPU.PC; #else @@ -730,7 +718,7 @@ static void OpD3M0 (void) /* CMX *************************************************************************************** */ static void OpE0X1 (void) { - Int32 = (int) Registers.XL - (int) *CPU.PC++; + int32 Int32 = (int) Registers.XL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -740,6 +728,7 @@ static void OpE0X1 (void) static void OpE0X0 (void) { + int32 Int32; #ifdef FAST_LSB_WORD_ACCESS Int32 = (long) Registers.X.W - (long) *(uint16 *) CPU.PC; #else @@ -779,7 +768,7 @@ static void OpECX0 (void) /* CMY *************************************************************************************** */ static void OpC0X1 (void) { - Int32 = (int) Registers.YL - (int) *CPU.PC++; + int32 Int32 = (int) Registers.YL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -789,6 +778,7 @@ static void OpC0X1 (void) static void OpC0X0 (void) { + int32 Int32; #ifdef FAST_LSB_WORD_ACCESS Int32 = (long) Registers.Y.W - (long) *(uint16 *) CPU.PC; #else @@ -3188,8 +3178,8 @@ static void OpFB (void) CPU.Cycles += ONE_CYCLE; #endif - A1 = ICPU._Carry; - A2 = Registers.PH; + uint8 A1 = ICPU._Carry; + uint8 A2 = Registers.PH; ICPU._Carry = A2 & 1; Registers.PH = A1; @@ -3682,7 +3672,7 @@ static void Op44X0 (void) /* REP/SEP *********************************************************************************** */ static void OpC2 (void) { - Work8 = ~*CPU.PC++; + uint8 Work8 = ~*CPU.PC++; Registers.PL &= Work8; ICPU._Carry &= Work8; ICPU._Overflow &= (Work8 >> 6); @@ -3708,7 +3698,7 @@ static void OpC2 (void) static void OpE2 (void) { - Work8 = *CPU.PC++; + uint8 Work8 = *CPU.PC++; Registers.PL |= Work8; ICPU._Carry |= Work8 & 1; ICPU._Overflow |= (Work8 >> 6) & 1; @@ -3735,7 +3725,7 @@ static void OpE2 (void) /* XBA *************************************************************************************** */ static void OpEB (void) { - Work8 = Registers.AL; + uint8 Work8 = Registers.AL; Registers.AL = Registers.AH; Registers.AH = Work8; diff --git a/source/globals.cpp b/source/globals.cpp index f00a621..ca2b12b 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -147,6 +147,7 @@ CMemory Memory; struct SSNESGameFixes SNESGameFixes; +#if 0 uint8 A1 = 0, A2 = 0, A3 = 0, A4 = 0, W1 = 0, W2 = 0, W3 = 0, W4 = 0; uint8 Ans8 = 0; uint16 Ans16 = 0; @@ -157,6 +158,7 @@ uint32 Work32 = 0; signed char Int8 = 0; short Int16 = 0; long Int32 = 0; +#endif #ifndef NO_OPEN_BUS uint8 OpenBus = 0; #endif diff --git a/source/spc700.cpp b/source/spc700.cpp index fe13ae8..1cd27d3 100644 --- a/source/spc700.cpp +++ b/source/spc700.cpp @@ -107,19 +107,6 @@ void S9xAPUSetByte (uint8, uint32 address); #include "apumem.h" #endif -START_EXTERN_C -extern uint8 Work8; -extern uint16 Work16; -extern uint32 Work32; -extern signed char Int8; -extern short Int16; -extern long Int32; -extern short Int16; -extern uint8 W1; -extern uint8 W2; - -END_EXTERN_C - #define OP1 (*(IAPU.PC + 1)) #define OP2 (*(IAPU.PC + 2)) @@ -179,7 +166,7 @@ void STOP (char *s) // XXX: HalfCarry - BJ fixed? #define SBC(a,b)\ -Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\ +int16 Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\ IAPU._Carry = Int16 >= 0;\ if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\ APUSetOverflow ();\ @@ -192,21 +179,22 @@ if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\ APUSetZN8 ((uint8) Int16); // XXX: HalfCarry - BJ fixed? +// XXX: HalfCarry used Int16 before; trying to fix it with Work16 [Neb] #define ADC(a,b)\ -Work16 = (a) + (b) + APUCheckCarry();\ +uint16 Work16 = (a) + (b) + APUCheckCarry();\ IAPU._Carry = Work16 >= 0x100; \ if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\ APUSetOverflow ();\ else \ APUClearOverflow (); \ APUClearHalfCarry ();\ -if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\ +if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\ APUSetHalfCarry ();\ (a) = (uint8) Work16;\ APUSetZN8 ((uint8) Work16); #define CMP(a,b)\ -Int16 = (short) (a) - (short) (b);\ +int16 Int16 = (short) (a) - (short) (b);\ IAPU._Carry = Int16 >= 0;\ APUSetZN8 ((uint8) Int16); @@ -219,12 +207,12 @@ APUSetZN8 ((uint8) Int16); (b) >>= 1;\ APUSetZN8 (b); #define ROL(b)\ - Work16 = ((b) << 1) | APUCheckCarry (); \ + uint16 Work16 = ((b) << 1) | APUCheckCarry (); \ IAPU._Carry = Work16 >= 0x100; \ (b) = (uint8) Work16; \ APUSetZN8 (b); #define ROR(b)\ - Work16 = (b) | ((uint16) APUCheckCarry () << 8); \ + uint16 Work16 = (b) | ((uint16) APUCheckCarry () << 8); \ IAPU._Carry = (uint8) Work16 & 1; \ Work16 >>= 1; \ (b) = (uint8) Work16; \ @@ -256,12 +244,12 @@ APUSetZN8 ((uint8) Int16); #endif #define Relative()\ - Int8 = OP1;\ - Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8; + int8 Int8 = OP1;\ + int16 Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8; #define Relative2()\ - Int8 = OP2;\ - Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8; + int8 Int8 = OP2;\ + int16 Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8; #ifdef FAST_LSB_WORD_ACCESS #define IndexedXIndirect()\ @@ -355,7 +343,7 @@ void Apu3F () // CALL absolute void Apu4F () // PCALL $XX { - Work8 = OP1; + uint8 Work8 = OP1; PushW (IAPU.PC + 2 - IAPU.RAM); IAPU.PC = IAPU.RAM + 0xff00 + Work8; } @@ -449,7 +437,7 @@ void ApuF2 () } #define BBS(b) \ -Work8 = OP1; \ +uint8 Work8 = OP1; \ Relative2 (); \ if (S9xAPUGetByteZ (Work8) & (1 << (b))) \ { \ @@ -500,7 +488,7 @@ void ApuE3 () } #define BBC(b) \ -Work8 = OP1; \ +uint8 Work8 = OP1; \ Relative2 (); \ if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \ { \ @@ -595,7 +583,7 @@ void Apu08 () void Apu09 () { // OR dp(dest),dp(src) - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); Work8 |= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -640,7 +628,7 @@ void Apu17 () void Apu18 () { // OR dp,#00 - Work8 = OP1; + uint8 Work8 = OP1; Work8 |= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -650,7 +638,7 @@ void Apu18 () void Apu19 () { // OR (X),(Y) - Work8 = S9xAPUGetByteZ (APURegisters.X) | S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) | S9xAPUGetByteZ (APURegisters.YA.B.Y); APUSetZN8 (Work8); S9xAPUSetByteZ (Work8, APURegisters.X); IAPU.PC++; @@ -758,7 +746,7 @@ void ApuEA () void Apu0B () { // ASL dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); ASL (Work8); S9xAPUSetByteZ (Work8, OP1); IAPU.PC += 2; @@ -768,7 +756,7 @@ void Apu0C () { // ASL abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ASL (Work8); S9xAPUSetByte (Work8, IAPU.Address); IAPU.PC += 3; @@ -777,7 +765,7 @@ void Apu0C () void Apu1B () { // ASL dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); ASL (Work8); S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); IAPU.PC += 2; @@ -856,7 +844,7 @@ void Apu0E () { // TSET1 abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); S9xAPUSetByte (Work8 | APURegisters.YA.B.A, IAPU.Address); Work8 &= APURegisters.YA.B.A; APUSetZN8 (Work8); @@ -867,7 +855,7 @@ void Apu4E () { // TCLR1 abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); S9xAPUSetByte (Work8 & ~APURegisters.YA.B.A, IAPU.Address); Work8 &= APURegisters.YA.B.A; APUSetZN8 (Work8); @@ -1050,7 +1038,7 @@ void Apu40 () void Apu1A () { // DECW dp - Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); Work16--; S9xAPUSetByteZ ((uint8) Work16, OP1); S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); @@ -1061,8 +1049,8 @@ void Apu1A () void Apu5A () { // CMPW YA,dp - Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - Int32 = (long) APURegisters.YA.W - (long) Work16; + uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + int32 Int32 = (long) APURegisters.YA.W - (long) Work16; IAPU._Carry = Int32 >= 0; APUSetZN16 ((uint16) Int32); IAPU.PC += 2; @@ -1071,7 +1059,7 @@ void Apu5A () void Apu3A () { // INCW dp - Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); Work16++; S9xAPUSetByteZ ((uint8) Work16, OP1); S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); @@ -1083,8 +1071,8 @@ void Apu3A () void Apu7A () { // ADDW YA,dp - Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - Work32 = (uint32) APURegisters.YA.W + Work16; + uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + uint32 Work32 = (uint32) APURegisters.YA.W + Work16; IAPU._Carry = Work32 >= 0x10000; if (~(APURegisters.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) APUSetOverflow (); @@ -1100,11 +1088,12 @@ void Apu7A () // XXX: BJ: i think the old HalfCarry behavior was wrong... // XXX: Or is it between bits 7 and 8 for ADDW/SUBW? +// XXX: Used Work32 instead of Int32 before. Fixed? [Neb] void Apu9A () { // SUBW YA,dp - Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - Int32 = (long) APURegisters.YA.W - (long) Work16; + uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + int32 Int32 = (long) APURegisters.YA.W - (long) Work16; APUClearHalfCarry (); IAPU._Carry = Int32 >= 0; if (((APURegisters.YA.W ^ Work16) & 0x8000) && @@ -1116,7 +1105,7 @@ void Apu9A () ((APURegisters.YA.W ^ (uint16) Int32) & 0x0080)) APUSetHalfCarry (); APUSetHalfCarry (); - if((APURegisters.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) + if((APURegisters.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) APUClearHalfCarry (); APURegisters.YA.W = (uint16) Int32; APUSetZN16 (APURegisters.YA.W); @@ -1143,7 +1132,7 @@ void ApuDA () void Apu64 () { // CMP A,dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1152,7 +1141,7 @@ void Apu65 () { // CMP A,abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -1160,7 +1149,7 @@ void Apu65 () void Apu66 () { // CMP A,(X) - Work8 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); CMP (APURegisters.YA.B.A, Work8); IAPU.PC++; } @@ -1169,7 +1158,7 @@ void Apu67 () { // CMP A,(dp+X) IndexedXIndirect (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1177,7 +1166,7 @@ void Apu67 () void Apu68 () { // CMP A,#00 - Work8 = OP1; + uint8 Work8 = OP1; CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1185,8 +1174,8 @@ void Apu68 () void Apu69 () { // CMP dp(dest), dp(src) - W1 = S9xAPUGetByteZ (OP1); - Work8 = S9xAPUGetByteZ (OP2); + uint8 W1 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP2); CMP (Work8, W1); IAPU.PC += 3; } @@ -1194,7 +1183,7 @@ void Apu69 () void Apu74 () { // CMP A, dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1203,7 +1192,7 @@ void Apu75 () { // CMP A,abs+X AbsoluteX (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -1212,7 +1201,7 @@ void Apu76 () { // CMP A, abs+Y AbsoluteY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -1221,7 +1210,7 @@ void Apu77 () { // CMP A,(dp)+Y IndirectIndexedY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1229,8 +1218,8 @@ void Apu77 () void Apu78 () { // CMP dp,#00 - Work8 = OP1; - W1 = S9xAPUGetByteZ (OP2); + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ (OP2); CMP (W1, Work8); IAPU.PC += 3; } @@ -1238,8 +1227,8 @@ void Apu78 () void Apu79 () { // CMP (X),(Y) - W1 = S9xAPUGetByteZ (APURegisters.X); - Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); CMP (W1, Work8); IAPU.PC++; } @@ -1248,7 +1237,7 @@ void Apu1E () { // CMP X,abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.X, Work8); IAPU.PC += 3; } @@ -1256,7 +1245,7 @@ void Apu1E () void Apu3E () { // CMP X,dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); CMP (APURegisters.X, Work8); IAPU.PC += 2; } @@ -1272,7 +1261,7 @@ void Apu5E () { // CMP Y,abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); CMP (APURegisters.YA.B.Y, Work8); IAPU.PC += 3; } @@ -1280,7 +1269,7 @@ void Apu5E () void Apu7E () { // CMP Y,dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); CMP (APURegisters.YA.B.Y, Work8); IAPU.PC += 2; } @@ -1288,7 +1277,7 @@ void Apu7E () void ApuAD () { // CMP Y,#00 - Work8 = OP1; + uint8 Work8 = OP1; CMP (APURegisters.YA.B.Y, Work8); IAPU.PC += 2; } @@ -1378,7 +1367,7 @@ void Apu28 () void Apu29 () { // AND dp(dest),dp(src) - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); Work8 &= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -1423,7 +1412,7 @@ void Apu37 () void Apu38 () { // AND dp,#00 - Work8 = OP1; + uint8 Work8 = OP1; Work8 &= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -1433,7 +1422,7 @@ void Apu38 () void Apu39 () { // AND (X),(Y) - Work8 = S9xAPUGetByteZ (APURegisters.X) & S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) & S9xAPUGetByteZ (APURegisters.YA.B.Y); APUSetZN8 (Work8); S9xAPUSetByteZ (Work8, APURegisters.X); IAPU.PC++; @@ -1442,7 +1431,7 @@ void Apu39 () void Apu2B () { // ROL dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); ROL (Work8); S9xAPUSetByteZ (Work8, OP1); IAPU.PC += 2; @@ -1452,7 +1441,7 @@ void Apu2C () { // ROL abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ROL (Work8); S9xAPUSetByte (Work8, IAPU.Address); IAPU.PC += 3; @@ -1461,7 +1450,7 @@ void Apu2C () void Apu3B () { // ROL dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); ROL (Work8); S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); IAPU.PC += 2; @@ -1477,7 +1466,7 @@ void Apu3C () void Apu2E () { // CBNE dp,rel - Work8 = OP1; + uint8 Work8 = OP1; Relative2 (); if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A) @@ -1493,7 +1482,7 @@ void Apu2E () void ApuDE () { // CBNE dp+X,rel - Work8 = OP1 + APURegisters.X; + uint8 Work8 = OP1 + APURegisters.X; Relative2 (); if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A) @@ -1561,7 +1550,7 @@ void ApuDC () void ApuAB () { // INC dp - Work8 = S9xAPUGetByteZ (OP1) + 1; + uint8 Work8 = S9xAPUGetByteZ (OP1) + 1; S9xAPUSetByteZ (Work8, OP1); APUSetZN8 (Work8); @@ -1576,7 +1565,7 @@ void ApuAC () { // INC abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address) + 1; + uint8 Work8 = S9xAPUGetByte (IAPU.Address) + 1; S9xAPUSetByte (Work8, IAPU.Address); APUSetZN8 (Work8); @@ -1590,7 +1579,7 @@ void ApuAC () void ApuBB () { // INC dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) + 1; + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) + 1; S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); APUSetZN8 (Work8); @@ -1617,7 +1606,7 @@ void ApuBC () void Apu8B () { // DEC dp - Work8 = S9xAPUGetByteZ (OP1) - 1; + uint8 Work8 = S9xAPUGetByteZ (OP1) - 1; S9xAPUSetByteZ (Work8, OP1); APUSetZN8 (Work8); @@ -1632,7 +1621,7 @@ void Apu8C () { // DEC abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address) - 1; + uint8 Work8 = S9xAPUGetByte (IAPU.Address) - 1; S9xAPUSetByte (Work8, IAPU.Address); APUSetZN8 (Work8); @@ -1646,7 +1635,7 @@ void Apu8C () void Apu9B () { // DEC dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) - 1; + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) - 1; S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); APUSetZN8 (Work8); @@ -1715,7 +1704,7 @@ void Apu48 () void Apu49 () { // EOR dp(dest),dp(src) - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); Work8 ^= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -1760,7 +1749,7 @@ void Apu57 () void Apu58 () { // EOR dp,#00 - Work8 = OP1; + uint8 Work8 = OP1; Work8 ^= S9xAPUGetByteZ (OP2); S9xAPUSetByteZ (Work8, OP2); APUSetZN8 (Work8); @@ -1770,7 +1759,7 @@ void Apu58 () void Apu59 () { // EOR (X),(Y) - Work8 = S9xAPUGetByteZ (APURegisters.X) ^ S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) ^ S9xAPUGetByteZ (APURegisters.YA.B.Y); APUSetZN8 (Work8); S9xAPUSetByteZ (Work8, APURegisters.X); IAPU.PC++; @@ -1779,7 +1768,7 @@ void Apu59 () void Apu4B () { // LSR dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); LSR (Work8); S9xAPUSetByteZ (Work8, OP1); IAPU.PC += 2; @@ -1789,7 +1778,7 @@ void Apu4C () { // LSR abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); LSR (Work8); S9xAPUSetByte (Work8, IAPU.Address); IAPU.PC += 3; @@ -1798,7 +1787,7 @@ void Apu4C () void Apu5B () { // LSR dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); LSR (Work8); S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); IAPU.PC += 2; @@ -1861,7 +1850,7 @@ void ApuBD () void Apu6B () { // ROR dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); ROR (Work8); S9xAPUSetByteZ (Work8, OP1); IAPU.PC += 2; @@ -1871,7 +1860,7 @@ void Apu6C () { // ROR abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ROR (Work8); S9xAPUSetByte (Work8, IAPU.Address); IAPU.PC += 3; @@ -1880,7 +1869,7 @@ void Apu6C () void Apu7B () { // ROR dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); ROR (Work8); S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); IAPU.PC += 2; @@ -1896,9 +1885,9 @@ void Apu7C () void Apu6E () { // DBNZ dp,rel - Work8 = OP1; + uint8 Work8 = OP1; Relative2 (); - W1 = S9xAPUGetByteZ (Work8) - 1; + uint8 W1 = S9xAPUGetByteZ (Work8) - 1; S9xAPUSetByteZ (W1, Work8); if (W1 != 0) { @@ -1943,7 +1932,7 @@ void Apu7F () void Apu84 () { // ADC A,dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1952,7 +1941,7 @@ void Apu85 () { // ADC A, abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -1960,7 +1949,7 @@ void Apu85 () void Apu86 () { // ADC A,(X) - Work8 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); ADC (APURegisters.YA.B.A, Work8); IAPU.PC++; } @@ -1969,7 +1958,7 @@ void Apu87 () { // ADC A,(dp+X) IndexedXIndirect (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1977,7 +1966,7 @@ void Apu87 () void Apu88 () { // ADC A,#00 - Work8 = OP1; + uint8 Work8 = OP1; ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -1985,8 +1974,8 @@ void Apu88 () void Apu89 () { // ADC dp(dest),dp(src) - Work8 = S9xAPUGetByteZ (OP1); - W1 = S9xAPUGetByteZ (OP2); + uint8 Work8 = S9xAPUGetByteZ (OP1); + uint8 W1 = S9xAPUGetByteZ (OP2); ADC (W1, Work8); S9xAPUSetByteZ (W1, OP2); IAPU.PC += 3; @@ -1995,7 +1984,7 @@ void Apu89 () void Apu94 () { // ADC A,dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2004,7 +1993,7 @@ void Apu95 () { // ADC A, abs+X AbsoluteX (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -2013,7 +2002,7 @@ void Apu96 () { // ADC A, abs+Y AbsoluteY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -2022,7 +2011,7 @@ void Apu97 () { // ADC A, (dp)+Y IndirectIndexedY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); ADC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2030,8 +2019,8 @@ void Apu97 () void Apu98 () { // ADC dp,#00 - Work8 = OP1; - W1 = S9xAPUGetByteZ (OP2); + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ (OP2); ADC (W1, Work8); S9xAPUSetByteZ (W1, OP2); IAPU.PC += 3; @@ -2040,8 +2029,8 @@ void Apu98 () void Apu99 () { // ADC (X),(Y) - W1 = S9xAPUGetByteZ (APURegisters.X); - Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); ADC (W1, Work8); S9xAPUSetByteZ (W1, APURegisters.X); IAPU.PC++; @@ -2058,7 +2047,7 @@ void Apu8D () void Apu8F () { // MOV dp,#00 - Work8 = OP1; + uint8 Work8 = OP1; S9xAPUSetByteZ (Work8, OP2); IAPU.PC += 3; } @@ -2075,7 +2064,7 @@ void Apu9E () else { APUClearOverflow (); - Work8 = APURegisters.YA.W / APURegisters.X; + uint8 Work8 = APURegisters.YA.W / APURegisters.X; APURegisters.YA.B.Y = APURegisters.YA.W % APURegisters.X; APURegisters.YA.B.A = Work8; } @@ -2096,7 +2085,7 @@ void Apu9F () void ApuA4 () { // SBC A, dp - Work8 = S9xAPUGetByteZ (OP1); + uint8 Work8 = S9xAPUGetByteZ (OP1); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2105,7 +2094,7 @@ void ApuA5 () { // SBC A, abs Absolute (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -2113,7 +2102,7 @@ void ApuA5 () void ApuA6 () { // SBC A, (X) - Work8 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); SBC (APURegisters.YA.B.A, Work8); IAPU.PC++; } @@ -2122,7 +2111,7 @@ void ApuA7 () { // SBC A,(dp+X) IndexedXIndirect (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2130,7 +2119,7 @@ void ApuA7 () void ApuA8 () { // SBC A,#00 - Work8 = OP1; + uint8 Work8 = OP1; SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2138,8 +2127,8 @@ void ApuA8 () void ApuA9 () { // SBC dp(dest), dp(src) - Work8 = S9xAPUGetByteZ (OP1); - W1 = S9xAPUGetByteZ (OP2); + uint8 Work8 = S9xAPUGetByteZ (OP1); + uint8 W1 = S9xAPUGetByteZ (OP2); SBC (W1, Work8); S9xAPUSetByteZ (W1, OP2); IAPU.PC += 3; @@ -2148,7 +2137,7 @@ void ApuA9 () void ApuB4 () { // SBC A, dp+X - Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2157,7 +2146,7 @@ void ApuB5 () { // SBC A,abs+X AbsoluteX (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -2166,7 +2155,7 @@ void ApuB6 () { // SBC A,abs+Y AbsoluteY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 3; } @@ -2175,7 +2164,7 @@ void ApuB7 () { // SBC A,(dp)+Y IndirectIndexedY (); - Work8 = S9xAPUGetByte (IAPU.Address); + uint8 Work8 = S9xAPUGetByte (IAPU.Address); SBC (APURegisters.YA.B.A, Work8); IAPU.PC += 2; } @@ -2183,8 +2172,8 @@ void ApuB7 () void ApuB8 () { // SBC dp,#00 - Work8 = OP1; - W1 = S9xAPUGetByteZ (OP2); + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ (OP2); SBC (W1, Work8); S9xAPUSetByteZ (W1, OP2); IAPU.PC += 3; @@ -2193,8 +2182,8 @@ void ApuB8 () void ApuB9 () { // SBC (X),(Y) - W1 = S9xAPUGetByteZ (APURegisters.X); - Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); SBC (W1, Work8); S9xAPUSetByteZ (W1, APURegisters.X); IAPU.PC++; -- cgit v1.2.3 From 1fd0171c5fd17cd48f6ef4104600c6f05b4e3004 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Mon, 24 Dec 2012 04:01:50 -0500 Subject: Bump version number to 1.10 for the APU half-carry bug and optimisations. --- source/nds/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 772775b..91e1aa3 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -59,7 +59,7 @@ char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lan ******************************************************************************/ #define SUBMENU_ROW_NUM 6 -#define NDSSFC_VERSION "1.09" +#define NDSSFC_VERSION "1.10" #define SAVE_STATE_SLOT_NUM 10 -- cgit v1.2.3 From 7f0e1fee814df6c44ced04246f511b0f91787673 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 25 Dec 2012 03:18:36 -0500 Subject: Wait for keys to be released after the yes/no dialog for deleting saved states, instead of delaying. --- source/nds/gui.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/nds/gui.c b/source/nds/gui.c index 91e1aa3..964944b 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -2170,6 +2170,7 @@ u32 menu(u16 *screen) { if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)")) { + wait_Allkey_release(0); for(i= 0; i < SAVE_STATE_SLOT_NUM; i++) { get_savestate_filename(i, tmp_filename); @@ -2198,8 +2199,10 @@ u32 menu(u16 *screen) sprintf(line_buffer, msg[MSG_DELETTE_SINGLE_SAVESTATE_WARING], delette_savestate_num); draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, line_buffer); - if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)")) + if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)")) { + wait_Allkey_release(0); clear_savestate_slot(delette_savestate_num); +} } else { @@ -2740,6 +2743,7 @@ u32 menu(u16 *screen) if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes", "No")) { + wait_Allkey_release(0); draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_DEFAULT_LOADING]); ds2_flipScreen(DOWN_SCREEN, 2); @@ -2803,11 +2807,10 @@ u32 menu(u16 *screen) ds2_clearScreen(UP_SCREEN, 0); draw_string_vcenter(up_screen_addr, 0, 80, 256, COLOR_WHITE, msg[MSG_NON_LOAD_GAME]); ds2_flipScreen(UP_SCREEN, 1); - mdelay(10); //FIXME: Stranger? } save_emu_config_file(); - // mdelay(500); // Delete this delay + wait_Allkey_release(0); } } @@ -3556,6 +3559,11 @@ u32 menu(u16 *screen) } else { + /* + * It's pretty complicated. These two flips are needed because, + * otherwise, the menu freezes if S9xAutoSaveSRAM was called after + * loading from a save state. + */ ds2_flipScreen(UP_SCREEN, 1); ds2_flipScreen(UP_SCREEN, 1); } @@ -3563,7 +3571,6 @@ u32 menu(u16 *screen) choose_menu(&main_menu); // Menu loop - // mdelay(50); // Delete this delay, shortened from 200 while(repeat) { -- cgit v1.2.3 From 9c1742f6cb2043d0ed6a61ab6de3bef0aad6dc56 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 25 Dec 2012 16:00:34 -0500 Subject: Universally use update method 2 for the lower screen and 0 for the upper screen. Method 1 causes problems after about 15 minutes; despite the double-buffering, screen updates start to tear in the middle consistently. --- source/nds/draw.c | 8 ++++---- source/nds/entry.cpp | 6 ++++-- source/nds/gui.c | 27 +++++++++------------------ 3 files changed, 17 insertions(+), 24 deletions(-) (limited to 'source') diff --git a/source/nds/draw.c b/source/nds/draw.c index 9d1b8ec..2a9e440 100644 --- a/source/nds/draw.c +++ b/source/nds/draw.c @@ -811,7 +811,7 @@ u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no) // draw_string_vcenter(screen_address, i+1, sy+1, box_width, COLOR_WHITE, no); draw_string_vcenter((unsigned short*)screen_addr, 138, 130, 58, COLOR_WHITE, no); - ds2_flipScreen(screen, 1); + ds2_flipScreen(screen, 2); gui_action_type gui_action = CURSOR_NONE; while((gui_action != CURSOR_SELECT) && (gui_action != CURSOR_BACK)) @@ -860,7 +860,7 @@ void init_progress(enum SCREEN_ID screen, u32 total, char *text) drawboxfill((unsigned short*)screen_addr, progress_sx, progress_sy, progress_ex, progress_ey, COLOR16(15, 15, 15)); - ds2_flipScreen(_progress_screen_id, 1); + ds2_flipScreen(_progress_screen_id, 2); } // update progress bar @@ -883,7 +883,7 @@ void update_progress(void) drawboxfill(screen_addr, progress_sx, progress_sy, progress_sx+width, progress_ey, COLOR16(30, 19, 7)); - ds2_flipScreen(_progress_screen_id, 1); + ds2_flipScreen(_progress_screen_id, 2); } // display progress string @@ -908,7 +908,7 @@ void show_progress(char *text) // if (text[0] != '\0') // print_string_center(progress_sy - 21, COLOR_PROGRESS_TEXT, COLOR_DIALOG, text); - ds2_flipScreen(_progress_screen_id, 1); + ds2_flipScreen(_progress_screen_id, 2); // OSTimeDly(progress_wait); mdelay(500); diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index ea5f6ce..ce8d732 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -174,7 +174,10 @@ bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/) break; } - ds2_flipScreen(UP_SCREEN, 1); // synchronise to vblank to avoid tearing + ds2_flipScreen(UP_SCREEN, 0); + // A problem with update method 1 (wait, double buffer) means that, after + // about 15 minutes of play time, the screen starts to half-redraw every + // frame. With update method 0, this is mitigated. (Method 2 is too slow.) return (TRUE); } @@ -598,7 +601,6 @@ int sfc_main (int argc, char **argv) if (Settings.Paused) { S9xSetSoundMute (TRUE); - // mdelay(50); // Delete this delay unsigned short screen[256*192]; copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192); diff --git a/source/nds/gui.c b/source/nds/gui.c index 964944b..3438f62 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1114,7 +1114,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) } redraw = 0; - ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer + ds2_flipScreen(DOWN_SCREEN, 2); } //end if(0 != redraw) else if(0 != redraw) { unsigned int m, n; @@ -1142,7 +1142,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) } draw_hscroll(m+1, redraw); - ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer + ds2_flipScreen(DOWN_SCREEN, 2); redraw = 0; } @@ -1162,7 +1162,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) { if(draw_hscroll(0, 1) <= 1) path_scroll = 0x8000; //scroll left } - ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer + ds2_flipScreen(DOWN_SCREEN, 2); } mdelay(50); //about 50ms @@ -1176,7 +1176,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) manage_filelist_info(&filelist_info, -1); ds2_clearScreen(DOWN_SCREEN, COLOR_BLACK); - ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer + ds2_flipScreen(DOWN_SCREEN, 2); return return_value; } @@ -3991,22 +3991,14 @@ u32 menu(u16 *screen) save_game_config_file(); } save_emu_config_file(); - // mdelay(100); // Delete this delay set_cpu_clock(clock_speed_number); - // mdelay(200); // Delete this delay - ds2_clearScreen(DUAL_SCREEN, 0); - ds2_flipScreen(DUAL_SCREEN, 1); + ds2_clearScreen(DOWN_SCREEN, 0); + ds2_flipScreen(DOWN_SCREEN, 1); copy_screen(up_screen_addr, (void*) screen, 0, 0, 256, 192); - ds2_flipScreen(UP_SCREEN, 1); // Flip again because otherwise it flickers + ds2_flipScreen(UP_SCREEN, 0); ds2_setBacklight(2); -//save game config -// save_game_config_file(); -// save_emu_config_file(); - - -// ds2_setCPUclocklevel(12); wait_Allkey_release(0); return return_value; @@ -4722,7 +4714,7 @@ void gui_init(u32 lang_id) } show_log(down_screen_addr); - ds2_flipScreen(DOWN_SCREEN, 1); + ds2_flipScreen(DOWN_SCREEN, 2); flag = icon_init(lang_id); if(0 != flag) @@ -4758,8 +4750,7 @@ void gui_init(u32 lang_id) return; gui_init_err: - ds2_flipScreen(DOWN_SCREEN, 1); + ds2_flipScreen(DOWN_SCREEN, 2); wait_Anykey_press(0); quit(); - while(1); } -- cgit v1.2.3 From 139c793b584a76acd42d72ec019d2cabab7d3ee7 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Tue, 25 Dec 2012 22:44:39 -0500 Subject: Smoother sound. Raise the sound sampling frequency to 48000 Hz. --- source/nds/ds2_main.c | 5 +++-- source/nds/ds2sound.h | 24 ++++++++++++++++++++++++ source/nds/entry.cpp | 24 ++++++------------------ 3 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 source/nds/ds2sound.h (limited to 'source') diff --git a/source/nds/ds2_main.c b/source/nds/ds2_main.c index 2d73313..7229727 100644 --- a/source/nds/ds2_main.c +++ b/source/nds/ds2_main.c @@ -23,6 +23,7 @@ #include "ds2io.h" #include "ds2_timer.h" #include "ds2_malloc.h" +#include "ds2sound.h" #define BLACK_COLOR RGB15(0, 0, 0) #define WHITE_COLOR RGB15(31, 31, 31) @@ -45,9 +46,9 @@ void ddump_mem(unsigned char* addr, unsigned int len) void ds2_main(void) { int err; -ds2_setCPUclocklevel(13); + ds2_setCPUclocklevel(13); //Initial video and audio and other input and output - err = ds2io_initb(512, 22050, 0, 0); + err = ds2io_initb(DS2_BUFFER_SIZE, SND_SAMPLE_RATE, 0, 0); if(err) goto _failure; //Initial file system diff --git a/source/nds/ds2sound.h b/source/nds/ds2sound.h new file mode 100644 index 0000000..cf37f6f --- /dev/null +++ b/source/nds/ds2sound.h @@ -0,0 +1,24 @@ +// The sound buffer sizes used on the DS2's side, for each value of +// Settings.SoundPlaybackRate. +#define DS2_BUFFER_SIZE_1 256 +#define DS2_BUFFER_SIZE_2 256 +#define DS2_BUFFER_SIZE_3 256 +#define DS2_BUFFER_SIZE_4 512 +#define DS2_BUFFER_SIZE_5 512 +#define DS2_BUFFER_SIZE_6 1024 +#define DS2_BUFFER_SIZE_7 1024 + +// The sampling rate for the sound, in Hz, for each value of +// Settings.SoundPlaybackRate. +#define SND_SAMPLE_RATE_1 8000 +#define SND_SAMPLE_RATE_2 11025 +#define SND_SAMPLE_RATE_3 16000 +#define SND_SAMPLE_RATE_4 22050 +#define SND_SAMPLE_RATE_5 32000 +#define SND_SAMPLE_RATE_6 44100 +#define SND_SAMPLE_RATE_7 48000 + +// Settings in use. The number should match in all three settings. +#define DS2_BUFFER_SIZE DS2_BUFFER_SIZE_7 +#define SND_SAMPLE_RATE SND_SAMPLE_RATE_7 +#define SNES9X_SRATE_ID 7 diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index ce8d732..a8e2217 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -20,6 +20,7 @@ #include "draw.h" #include "gui.h" +#include "ds2sound.h" void S9xProcessSound (unsigned int); @@ -359,9 +360,9 @@ void init_sfc_setting(void) Settings.JoystickEnabled = FALSE; #endif - Settings.SoundPlaybackRate = 4; //2 = 11025, 4 = 22050, 6 = 44100 + Settings.SoundPlaybackRate = SNES9X_SRATE_ID; // -> ds2sound.h for defs Settings.Stereo = TRUE; - Settings.SoundBufferSize = 0; + Settings.SoundBufferSize = DS2_BUFFER_SIZE; Settings.CyclesPercentage = 100; Settings.DisableSoundEcho = FALSE; //sound settings @@ -767,28 +768,15 @@ void S9xSyncSpeed () #endif } -/* -* Open sound device -*/ -static int Rates[8] = -{ - 0, 8000, 11025, 16000, 22050, 32000, 44100, 48000 -}; - -static int BufferSizes [8] = -{ - 0, 256, 256, 256, 512, 512, 1024, 1024 -}; - bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size) { so.sixteen_bit = TRUE; so.stereo = stereo; - so.playback_rate = Rates[mode & 0x07]; + so.playback_rate = SND_SAMPLE_RATE; S9xSetPlaybackRate (so.playback_rate); if (buffer_size == 0) - buffer_size = BufferSizes [mode & 7]; + buffer_size = DS2_BUFFER_SIZE; if (buffer_size > MAX_BUFFER_SIZE / 4) buffer_size = MAX_BUFFER_SIZE / 4; @@ -936,7 +924,7 @@ void S9xProcessSound (unsigned int) // block_generate_sound = FALSE; unsigned short *dst_pt = audiobuff; - unsigned short *dst_pt1 = dst_pt + 512; + unsigned short *dst_pt1 = dst_pt + DS2_BUFFER_SIZE; /* Feed the samples to the soundcard until nothing is left */ for(;;) -- cgit v1.2.3 From e5869adc4469115c7eac9abf70145fc178e017de Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 26 Dec 2012 14:42:02 -0500 Subject: Merge Registers structures into their respective CPUs to avoid additional memory addresses being loaded every opcode. --- source/65c816.h | 34 ++-- source/apu.cpp | 12 +- source/apu.h | 15 +- source/cpu.cpp | 20 +- source/cpuaddr.h | 60 +++--- source/cpuexec.cpp | 12 +- source/cpuexec.h | 13 +- source/cpumacro.h | 236 +++++++++++----------- source/cpuops.cpp | 550 +++++++++++++++++++++++++------------------------- source/globals.cpp | 10 +- source/sa1.cpp | 26 +-- source/sa1.h | 30 +-- source/sa1cpu.cpp | 1 - source/snaporig.cpp | 12 +- source/snapshot.cpp | 78 +++---- source/spc700.cpp | 572 ++++++++++++++++++++++++++-------------------------- source/spc700.h | 32 ++- 17 files changed, 852 insertions(+), 861 deletions(-) (limited to 'source') diff --git a/source/65c816.h b/source/65c816.h index a82de8d..04b591c 100644 --- a/source/65c816.h +++ b/source/65c816.h @@ -117,14 +117,14 @@ #define SetCarry() (ICPU._Carry = 1) #define SetZero() (ICPU._Zero = 0) #define ClearZero() (ICPU._Zero = 1) -#define SetIRQ() (Registers.PL |= IRQ) -#define ClearIRQ() (Registers.PL &= ~IRQ) -#define SetDecimal() (Registers.PL |= Decimal) -#define ClearDecimal() (Registers.PL &= ~Decimal) -#define SetIndex() (Registers.PL |= IndexFlag) -#define ClearIndex() (Registers.PL &= ~IndexFlag) -#define SetMemory() (Registers.PL |= MemoryFlag) -#define ClearMemory() (Registers.PL &= ~MemoryFlag) +#define SetIRQ() (ICPU.Registers.PL |= IRQ) +#define ClearIRQ() (ICPU.Registers.PL &= ~IRQ) +#define SetDecimal() (ICPU.Registers.PL |= Decimal) +#define ClearDecimal() (ICPU.Registers.PL &= ~Decimal) +#define SetIndex() (ICPU.Registers.PL |= IndexFlag) +#define ClearIndex() (ICPU.Registers.PL &= ~IndexFlag) +#define SetMemory() (ICPU.Registers.PL |= MemoryFlag) +#define ClearMemory() (ICPU.Registers.PL &= ~MemoryFlag) #define SetOverflow() (ICPU._Overflow = 1) #define ClearOverflow() (ICPU._Overflow = 0) #define SetNegative() (ICPU._Negative = 0x80) @@ -132,17 +132,17 @@ #define CheckZero() (ICPU._Zero == 0) #define CheckCarry() (ICPU._Carry) -#define CheckIRQ() (Registers.PL & IRQ) -#define CheckDecimal() (Registers.PL & Decimal) -#define CheckIndex() (Registers.PL & IndexFlag) -#define CheckMemory() (Registers.PL & MemoryFlag) +#define CheckIRQ() (ICPU.Registers.PL & IRQ) +#define CheckDecimal() (ICPU.Registers.PL & Decimal) +#define CheckIndex() (ICPU.Registers.PL & IndexFlag) +#define CheckMemory() (ICPU.Registers.PL & MemoryFlag) #define CheckOverflow() (ICPU._Overflow) #define CheckNegative() (ICPU._Negative & 0x80) -#define CheckEmulation() (Registers.P.W & Emulation) +#define CheckEmulation() (ICPU.Registers.P.W & Emulation) -#define ClearFlags(f) (Registers.P.W &= ~(f)) -#define SetFlags(f) (Registers.P.W |= (f)) -#define CheckFlag(f) (Registers.PL & (f)) +#define ClearFlags(f) (ICPU.Registers.P.W &= ~(f)) +#define SetFlags(f) (ICPU.Registers.P.W |= (f)) +#define CheckFlag(f) (ICPU.Registers.PL & (f)) typedef union { @@ -166,7 +166,5 @@ struct SRegisters{ uint16 PC; }; -EXTERN_C struct SRegisters Registers; - #endif diff --git a/source/apu.cpp b/source/apu.cpp index 3abb669..3c1a5d3 100644 --- a/source/apu.cpp +++ b/source/apu.cpp @@ -181,12 +181,12 @@ void S9xResetAPU () memmove (APU.ExtraRAM, APUROM, sizeof (APUROM)); IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8); APU.Cycles = 0; - APURegisters.YA.W = 0; - APURegisters.X = 0; - APURegisters.S = 0xff; - APURegisters.P = 0; + IAPU.Registers.YA.W = 0; + IAPU.Registers.X = 0; + IAPU.Registers.S = 0xff; + IAPU.Registers.P = 0; S9xAPUUnpackStatus (); - APURegisters.PC = 0; + IAPU.Registers.PC = 0; IAPU.APUExecuting = Settings.APUEnabled; #ifdef SPC700_SHUTDOWN IAPU.WaitAddress1 = NULL; @@ -419,7 +419,7 @@ void S9xSetAPUDSP (uint8 byte) { if (byte & ~spc_is_dumping_temp) { - APURegisters.PC = IAPU.PC - IAPU.RAM; + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; S9xAPUPackStatus(); S9xSPCDump (S9xGetFilenameInc (".spc")); spc_is_dumping = 0; diff --git a/source/apu.h b/source/apu.h index 0a64e34..67b2525 100644 --- a/source/apu.h +++ b/source/apu.h @@ -95,6 +95,7 @@ struct SIAPU { uint8 *PC; + struct SAPURegisters Registers; uint8 *RAM; uint8 *DirectPage; bool8 APUExecuting; @@ -136,15 +137,15 @@ extern int spc_is_dumping_temp; extern uint8 spc_dump_dsp[0x100]; STATIC inline void S9xAPUUnpackStatus() { - IAPU._Zero = ((APURegisters.P & Zero) == 0) | (APURegisters.P & Negative); - IAPU._Carry = (APURegisters.P & Carry); - IAPU._Overflow = (APURegisters.P & Overflow) >> 6; + IAPU._Zero = ((IAPU.Registers.P & Zero) == 0) | (IAPU.Registers.P & Negative); + IAPU._Carry = (IAPU.Registers.P & Carry); + IAPU._Overflow = (IAPU.Registers.P & Overflow) >> 6; } STATIC inline void S9xAPUPackStatus() { - APURegisters.P &= ~(Zero | Negative | Carry | Overflow); - APURegisters.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) | + IAPU.Registers.P &= ~(Zero | Negative | Carry | Overflow); + IAPU.Registers.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) | (IAPU._Zero & 0x80) | (IAPU._Overflow << 6); } @@ -162,8 +163,8 @@ void S9xSetAPUTimer (uint16 Address, uint8 byte); bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size); void S9xOpenCloseSoundTracingFile (bool8); void S9xPrintAPUState (); -extern int32 S9xAPUCycles [256]; // Scaled cycle lengths -extern int32 S9xAPUCycleLengths [256]; // Raw data. +extern uint16 S9xAPUCycles [256]; // Scaled cycle lengths +extern uint16 S9xAPUCycleLengths [256]; // Raw data. extern void (*S9xApuOpcodes [256]) (void); END_EXTERN_C diff --git a/source/cpu.cpp b/source/cpu.cpp index 80e387f..d6e8f53 100644 --- a/source/cpu.cpp +++ b/source/cpu.cpp @@ -117,15 +117,15 @@ void S9xResetSuperFX () void S9xResetCPU () { - Registers.PB = 0; - Registers.PC = S9xGetWord (0xFFFC); - Registers.D.W = 0; - Registers.DB = 0; - Registers.SH = 1; - Registers.SL = 0xFF; - Registers.XH = 0; - Registers.YH = 0; - Registers.P.W = 0; + ICPU.Registers.PB = 0; + ICPU.Registers.PC = S9xGetWord (0xFFFC); + ICPU.Registers.D.W = 0; + ICPU.Registers.DB = 0; + ICPU.Registers.SH = 1; + ICPU.Registers.SL = 0xFF; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + ICPU.Registers.P.W = 0; ICPU.ShiftedPB = 0; ICPU.ShiftedDB = 0; @@ -157,7 +157,7 @@ void S9xResetCPU () //CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded CPU.NMICycleCount = 0; CPU.IRQCycleCount = 0; - S9xSetPCBase (Registers.PC); + S9xSetPCBase (ICPU.Registers.PC); ICPU.S9xOpcodes = S9xOpcodesE1; ICPU.CPUExecuting = TRUE; diff --git a/source/cpuaddr.h b/source/cpuaddr.h index 09f5788..34fb41b 100644 --- a/source/cpuaddr.h +++ b/source/cpuaddr.h @@ -163,9 +163,9 @@ static void AbsoluteIndexedIndirect (AccessMode a, InternalOp op) { long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = (Registers.X.W + *(uint16 *) CPU.PC) & 0xffff; + Addr = (ICPU.Registers.X.W + *(uint16 *) CPU.PC) & 0xffff; #else - Addr = (Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff; + Addr = (ICPU.Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff; #endif #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; @@ -274,11 +274,11 @@ static void Direct(AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif -// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; +// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; (*op)(Addr); } @@ -287,7 +287,7 @@ static void DirectIndirectIndexed (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif @@ -296,9 +296,9 @@ static void DirectIndirectIndexed (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS if(a&READ) OpenBus = (uint8)(Addr>>8); #endif - Addr += ICPU.ShiftedDB + Registers.Y.W; + Addr += ICPU.ShiftedDB + ICPU.Registers.Y.W; -// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; +// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; // XXX: always add one if STA // XXX: else Add one cycle if crosses page boundary (*op)(Addr); @@ -309,21 +309,21 @@ static void DirectIndirectIndexedLong (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif #ifndef NO_OPEN_BUS if(a&READ){ - Addr = S9xGetWord (Addr) + ((OpenBus = S9xGetByte (Addr + 2)) << 16) + Registers.Y.W; + Addr = S9xGetWord (Addr) + ((OpenBus = S9xGetByte (Addr + 2)) << 16) + ICPU.Registers.Y.W; } else { #endif - Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16) + Registers.Y.W; + Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16) + ICPU.Registers.Y.W; #ifndef NO_OPEN_BUS } #endif -// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; +// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; (*op)(Addr); } @@ -332,7 +332,7 @@ static void DirectIndexedIndirect(AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif @@ -344,7 +344,7 @@ static void DirectIndexedIndirect(AccessMode a, InternalOp op) Addr += ICPU.ShiftedDB; #ifndef SA1_OPCODES -// if (Registers.DL != 0) +// if (ICPU.Registers.DL != 0) // CPU.Cycles += TWO_CYCLES; // else CPU.Cycles += ONE_CYCLE; @@ -357,12 +357,12 @@ static void DirectIndexedX (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W); + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W); Addr &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (Registers.DL != 0) +// if (ICPU.Registers.DL != 0) // CPU.Cycles += TWO_CYCLES; // else // CPU.Cycles += ONE_CYCLE; @@ -375,11 +375,11 @@ static void DirectIndexedY (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W + Registers.Y.W); + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.Y.W); Addr &= CheckEmulation() ? 0xff : 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (Registers.DL != 0) +// if (ICPU.Registers.DL != 0) // CPU.Cycles += TWO_CYCLES; // else // CPU.Cycles += ONE_CYCLE; @@ -391,10 +391,10 @@ static void AbsoluteIndexedX (AccessMode a, InternalOp op) { long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W; + Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + ICPU.Registers.X.W; #else Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + - Registers.X.W; + ICPU.Registers.X.W; #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); @@ -412,10 +412,10 @@ static void AbsoluteIndexedY (AccessMode a, InternalOp op) { long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W; + Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + ICPU.Registers.Y.W; #else Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + - Registers.Y.W; + ICPU.Registers.Y.W; #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+1); @@ -433,9 +433,9 @@ static void AbsoluteLongIndexedX (AccessMode a, InternalOp op) { long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff; + Addr = (*(uint32 *) CPU.PC + ICPU.Registers.X.W) & 0xffffff; #else - Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff; + Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + ICPU.Registers.X.W) & 0xffffff; #endif #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *(CPU.PC+2); @@ -452,7 +452,7 @@ static void DirectIndirect (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif @@ -462,7 +462,7 @@ static void DirectIndirect (AccessMode a, InternalOp op) #endif Addr += ICPU.ShiftedDB; -// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; +// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; (*op)(Addr); } @@ -471,7 +471,7 @@ static void DirectIndirectLong (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif @@ -484,7 +484,7 @@ static void DirectIndirectLong (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS } #endif -// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE; +// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; (*op)(Addr); } @@ -493,7 +493,7 @@ static void StackRelative (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS if(a&READ) OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif @@ -505,7 +505,7 @@ static void StackRelativeIndirectIndexed (AccessMode a, InternalOp op) #ifndef NO_OPEN_BUS OpenBus = *CPU.PC; #endif - long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff; + long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif @@ -514,7 +514,7 @@ static void StackRelativeIndirectIndexed (AccessMode a, InternalOp op) if(a&READ) OpenBus = (uint8)(Addr>>8); #endif Addr = (Addr + ICPU.ShiftedDB + - Registers.Y.W) & 0xffffff; + ICPU.Registers.Y.W) & 0xffffff; (*op)(Addr); } #endif diff --git a/source/cpuexec.cpp b/source/cpuexec.cpp index 5fb79e5..66bb8da 100644 --- a/source/cpuexec.cpp +++ b/source/cpuexec.cpp @@ -171,9 +171,9 @@ void S9xMainLoop (void) DO_HBLANK_CHECK(); } - Registers.PC = CPU.PC - CPU.PCBase; + ICPU.Registers.PC = CPU.PC - CPU.PCBase; S9xPackStatus (); - APURegisters.PC = IAPU.PC - IAPU.RAM; + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; S9xAPUPackStatus (); if (CPU.Flags & SCAN_KEYS_FLAG) { @@ -235,10 +235,10 @@ void S9xDoHBlankProcessing () // ppu.cpp will determine with greater accuracy whether a key was // pressed or released during the frame. uint32 i; - for (i = 0; i < 5; i++) - { - IPPU.JoypadsAtHBlanks [i][CPU.V_Counter] = S9xReadJoypad (i); - } + for (i = 0; i < 5; i++) + { + IPPU.JoypadsAtHBlanks [i][CPU.V_Counter] = S9xReadJoypad (i); + } #endif if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); diff --git a/source/cpuexec.h b/source/cpuexec.h index 9a26081..a094220 100644 --- a/source/cpuexec.h +++ b/source/cpuexec.h @@ -109,6 +109,7 @@ struct SICPU { uint8 *Speed; struct SOpcodes *S9xOpcodes; + struct SRegisters Registers; uint8 _Carry; uint8 _Zero; uint8 _Negative; @@ -140,16 +141,16 @@ END_EXTERN_C STATIC inline void S9xUnpackStatus() { - ICPU._Zero = (Registers.PL & Zero) == 0; - ICPU._Negative = (Registers.PL & Negative); - ICPU._Carry = (Registers.PL & Carry); - ICPU._Overflow = (Registers.PL & Overflow) >> 6; + ICPU._Zero = (ICPU.Registers.PL & Zero) == 0; + ICPU._Negative = (ICPU.Registers.PL & Negative); + ICPU._Carry = (ICPU.Registers.PL & Carry); + ICPU._Overflow = (ICPU.Registers.PL & Overflow) >> 6; } STATIC inline void S9xPackStatus() { - Registers.PL &= ~(Zero | Negative | Carry | Overflow); - Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | + ICPU.Registers.PL &= ~(Zero | Negative | Carry | Overflow); + ICPU.Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | (ICPU._Negative & 0x80) | (ICPU._Overflow << 6); } diff --git a/source/cpumacro.h b/source/cpumacro.h index 1bd5d2f..c70c2ba 100644 --- a/source/cpumacro.h +++ b/source/cpumacro.h @@ -108,8 +108,8 @@ static void ADC8 (long Addr) if (CheckDecimal ()) { - uint8 A1 = (Registers.A.W) & 0xF; - uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; uint8 W1 = Work8 & 0xF; uint8 W2 = (Work8 >> 4) & 0xF; @@ -134,27 +134,27 @@ static void ADC8 (long Addr) } int8 Ans8 = (A2 << 4) | A1; - if (~(Registers.AL ^ Work8) & + if (~(ICPU.Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80) SetOverflow(); else ClearOverflow(); - Registers.AL = Ans8; - SetZN8 (Registers.AL); + ICPU.Registers.AL = Ans8; + SetZN8 (ICPU.Registers.AL); } else { - int16 Ans16 = Registers.AL + Work8 + CheckCarry(); + int16 Ans16 = ICPU.Registers.AL + Work8 + CheckCarry(); ICPU._Carry = Ans16 >= 0x100; - if (~(Registers.AL ^ Work8) & + if (~(ICPU.Registers.AL ^ Work8) & (Work8 ^ (uint8) Ans16) & 0x80) SetOverflow(); else ClearOverflow(); - Registers.AL = (uint8) Ans16; - SetZN8 (Registers.AL); + ICPU.Registers.AL = (uint8) Ans16; + SetZN8 (ICPU.Registers.AL); } } @@ -165,10 +165,10 @@ static void ADC16 (long Addr) if (CheckDecimal ()) { - uint8 A1 = (Registers.A.W) & 0xF; - uint8 A2 = (Registers.A.W >> 4) & 0xF; - uint8 A3 = (Registers.A.W >> 8) & 0xF; - uint8 A4 = (Registers.A.W >> 12) & 0xF; + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; + uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; uint8 W1 = Work16 & 0xF; uint8 W2 = (Work16 >> 4) & 0xF; uint8 W3 = (Work16 >> 8) & 0xF; @@ -211,40 +211,40 @@ static void ADC16 (long Addr) } uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); - if (~(Registers.A.W ^ Work16) & + if (~(ICPU.Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000) SetOverflow(); else ClearOverflow(); - Registers.A.W = Ans16; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = Ans16; + SetZN16 (ICPU.Registers.A.W); } else { - uint32 Ans32 = Registers.A.W + Work16 + CheckCarry(); + uint32 Ans32 = ICPU.Registers.A.W + Work16 + CheckCarry(); ICPU._Carry = Ans32 >= 0x10000; - if (~(Registers.A.W ^ Work16) & + if (~(ICPU.Registers.A.W ^ Work16) & (Work16 ^ (uint16) Ans32) & 0x8000) SetOverflow(); else ClearOverflow(); - Registers.A.W = (uint16) Ans32; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = (uint16) Ans32; + SetZN16 (ICPU.Registers.A.W); } } static void AND16 (long Addr) { - Registers.A.W &= S9xGetWord (Addr); - SetZN16 (Registers.A.W); + ICPU.Registers.A.W &= S9xGetWord (Addr); + SetZN16 (ICPU.Registers.A.W); } static void AND8 (long Addr) { - Registers.AL &= S9xGetByte (Addr); - SetZN8 (Registers.AL); + ICPU.Registers.AL &= S9xGetByte (Addr); + SetZN8 (ICPU.Registers.AL); } static inline void A_ASL16 () @@ -252,9 +252,9 @@ static inline void A_ASL16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = (Registers.AH & 0x80) != 0; - Registers.A.W <<= 1; - SetZN16 (Registers.A.W); + ICPU._Carry = (ICPU.Registers.AH & 0x80) != 0; + ICPU.Registers.A.W <<= 1; + SetZN16 (ICPU.Registers.A.W); } static inline void A_ASL8 () @@ -262,9 +262,9 @@ static inline void A_ASL8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = (Registers.AL & 0x80) != 0; - Registers.AL <<= 1; - SetZN8 (Registers.AL); + ICPU._Carry = (ICPU.Registers.AL & 0x80) != 0; + ICPU.Registers.AL <<= 1; + SetZN8 (ICPU.Registers.AL); } static void ASL16 (long Addr) @@ -298,7 +298,7 @@ static void BIT16 (long Addr) uint16 Work16 = S9xGetWord (Addr); ICPU._Overflow = (Work16 & 0x4000) != 0; ICPU._Negative = (uint8) (Work16 >> 8); - ICPU._Zero = (Work16 & Registers.A.W) != 0; + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; } static void BIT8 (long Addr) @@ -306,12 +306,12 @@ static void BIT8 (long Addr) uint8 Work8 = S9xGetByte (Addr); ICPU._Overflow = (Work8 & 0x40) != 0; ICPU._Negative = Work8; - ICPU._Zero = Work8 & Registers.AL; + ICPU._Zero = Work8 & ICPU.Registers.AL; } static void CMP16 (long Addr) { - int32 Int32 = (long) Registers.A.W - + int32 Int32 = (long) ICPU.Registers.A.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -319,7 +319,7 @@ static void CMP16 (long Addr) static void CMP8 (long Addr) { - int16 Int16 = (short) Registers.AL - + int16 Int16 = (short) ICPU.Registers.AL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -327,7 +327,7 @@ static void CMP8 (long Addr) static void CMX16 (long Addr) { - int32 Int32 = (long) Registers.X.W - + int32 Int32 = (long) ICPU.Registers.X.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -335,7 +335,7 @@ static void CMX16 (long Addr) static void CMX8 (long Addr) { - int16 Int16 = (short) Registers.XL - + int16 Int16 = (short) ICPU.Registers.XL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -343,7 +343,7 @@ static void CMX8 (long Addr) static void CMY16 (long Addr) { - int32 Int32 = (long) Registers.Y.W - + int32 Int32 = (long) ICPU.Registers.Y.W - (long) S9xGetWord (Addr); ICPU._Carry = Int32 >= 0; SetZN16 ((uint16) Int32); @@ -351,7 +351,7 @@ static void CMY16 (long Addr) static void CMY8 (long Addr) { - int16 Int16 = (short) Registers.YL - + int16 Int16 = (short) ICPU.Registers.YL - (short) S9xGetByte (Addr); ICPU._Carry = Int16 >= 0; SetZN8 ((uint8) Int16); @@ -366,8 +366,8 @@ static inline void A_DEC16 () CPU.WaitAddress = NULL; #endif - Registers.A.W--; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W--; + SetZN16 (ICPU.Registers.A.W); } static inline void A_DEC8 () @@ -379,8 +379,8 @@ static inline void A_DEC8 () CPU.WaitAddress = NULL; #endif - Registers.AL--; - SetZN8 (Registers.AL); + ICPU.Registers.AL--; + SetZN8 (ICPU.Registers.AL); } static void DEC16 (long Addr) @@ -415,14 +415,14 @@ static void DEC8 (long Addr) static void EOR16 (long Addr) { - Registers.A.W ^= S9xGetWord (Addr); - SetZN16 (Registers.A.W); + ICPU.Registers.A.W ^= S9xGetWord (Addr); + SetZN16 (ICPU.Registers.A.W); } static void EOR8 (long Addr) { - Registers.AL ^= S9xGetByte (Addr); - SetZN8 (Registers.AL); + ICPU.Registers.AL ^= S9xGetByte (Addr); + SetZN8 (ICPU.Registers.AL); } static inline void A_INC16 () @@ -434,8 +434,8 @@ static inline void A_INC16 () CPU.WaitAddress = NULL; #endif - Registers.A.W++; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W++; + SetZN16 (ICPU.Registers.A.W); } static inline void A_INC8 () @@ -447,8 +447,8 @@ static inline void A_INC8 () CPU.WaitAddress = NULL; #endif - Registers.AL++; - SetZN8 (Registers.AL); + ICPU.Registers.AL++; + SetZN8 (ICPU.Registers.AL); } static void INC16 (long Addr) @@ -483,38 +483,38 @@ static void INC8 (long Addr) static void LDA16 (long Addr) { - Registers.A.W = S9xGetWord (Addr); - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = S9xGetWord (Addr); + SetZN16 (ICPU.Registers.A.W); } static void LDA8 (long Addr) { - Registers.AL = S9xGetByte (Addr); - SetZN8 (Registers.AL); + ICPU.Registers.AL = S9xGetByte (Addr); + SetZN8 (ICPU.Registers.AL); } static void LDX16 (long Addr) { - Registers.X.W = S9xGetWord (Addr); - SetZN16 (Registers.X.W); + ICPU.Registers.X.W = S9xGetWord (Addr); + SetZN16 (ICPU.Registers.X.W); } static void LDX8 (long Addr) { - Registers.XL = S9xGetByte (Addr); - SetZN8 (Registers.XL); + ICPU.Registers.XL = S9xGetByte (Addr); + SetZN8 (ICPU.Registers.XL); } static void LDY16 (long Addr) { - Registers.Y.W = S9xGetWord (Addr); - SetZN16 (Registers.Y.W); + ICPU.Registers.Y.W = S9xGetWord (Addr); + SetZN16 (ICPU.Registers.Y.W); } static void LDY8 (long Addr) { - Registers.YL = S9xGetByte (Addr); - SetZN8 (Registers.YL); + ICPU.Registers.YL = S9xGetByte (Addr); + SetZN8 (ICPU.Registers.YL); } static inline void A_LSR16 () @@ -522,9 +522,9 @@ static inline void A_LSR16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = Registers.AL & 1; - Registers.A.W >>= 1; - SetZN16 (Registers.A.W); + ICPU._Carry = ICPU.Registers.AL & 1; + ICPU.Registers.A.W >>= 1; + SetZN16 (ICPU.Registers.A.W); } static inline void A_LSR8 () @@ -532,9 +532,9 @@ static inline void A_LSR8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = Registers.AL & 1; - Registers.AL >>= 1; - SetZN8 (Registers.AL); + ICPU._Carry = ICPU.Registers.AL & 1; + ICPU.Registers.AL >>= 1; + SetZN8 (ICPU.Registers.AL); } static void LSR16 (long Addr) @@ -565,14 +565,14 @@ static void LSR8 (long Addr) static void ORA16 (long Addr) { - Registers.A.W |= S9xGetWord (Addr); - SetZN16 (Registers.A.W); + ICPU.Registers.A.W |= S9xGetWord (Addr); + SetZN16 (ICPU.Registers.A.W); } static void ORA8 (long Addr) { - Registers.AL |= S9xGetByte (Addr); - SetZN8 (Registers.AL); + ICPU.Registers.AL |= S9xGetByte (Addr); + SetZN8 (ICPU.Registers.AL); } static inline void A_ROL16 () @@ -580,9 +580,9 @@ static inline void A_ROL16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - uint32 Work32 = (Registers.A.W << 1) | CheckCarry(); + uint32 Work32 = (ICPU.Registers.A.W << 1) | CheckCarry(); ICPU._Carry = Work32 >= 0x10000; - Registers.A.W = (uint16) Work32; + ICPU.Registers.A.W = (uint16) Work32; SetZN16 ((uint16) Work32); } @@ -591,11 +591,11 @@ static inline void A_ROL8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - uint16 Work16 = Registers.AL; + uint16 Work16 = ICPU.Registers.AL; Work16 <<= 1; Work16 |= CheckCarry(); ICPU._Carry = Work16 >= 0x100; - Registers.AL = (uint8) Work16; + ICPU.Registers.AL = (uint8) Work16; SetZN8 ((uint8) Work16); } @@ -632,11 +632,11 @@ static inline void A_ROR16 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - uint32 Work32 = Registers.A.W; + uint32 Work32 = ICPU.Registers.A.W; Work32 |= (int) CheckCarry() << 16; ICPU._Carry = (uint8) (Work32 & 1); Work32 >>= 1; - Registers.A.W = (uint16) Work32; + ICPU.Registers.A.W = (uint16) Work32; SetZN16 ((uint16) Work32); } @@ -645,10 +645,10 @@ static inline void A_ROR8 () #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - uint16 Work16 = Registers.AL | ((uint16) CheckCarry() << 8); + uint16 Work16 = ICPU.Registers.AL | ((uint16) CheckCarry() << 8); ICPU._Carry = (uint8) Work16 & 1; Work16 >>= 1; - Registers.AL = (uint8) Work16; + ICPU.Registers.AL = (uint8) Work16; SetZN8 ((uint8) Work16); } @@ -686,10 +686,10 @@ static void SBC16 (long Addr) if (CheckDecimal ()) { - uint8 A1 = (Registers.A.W) & 0xF; - uint8 A2 = (Registers.A.W >> 4) & 0xF; - uint8 A3 = (Registers.A.W >> 8) & 0xF; - uint8 A4 = (Registers.A.W >> 12) & 0xF; + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; + uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; uint8 W1 = Work16 & 0xF; uint8 W2 = (Work16 >> 4) & 0xF; uint8 W3 = (Work16 >> 8) & 0xF; @@ -725,28 +725,28 @@ static void SBC16 (long Addr) } uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); - if ((Registers.A.W ^ Work16) & - (Registers.A.W ^ Ans16) & 0x8000) + if ((ICPU.Registers.A.W ^ Work16) & + (ICPU.Registers.A.W ^ Ans16) & 0x8000) SetOverflow(); else ClearOverflow(); - Registers.A.W = Ans16; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = Ans16; + SetZN16 (ICPU.Registers.A.W); } else { - int32 Int32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; + int32 Int32 = (long) ICPU.Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; ICPU._Carry = Int32 >= 0; - if ((Registers.A.W ^ Work16) & - (Registers.A.W ^ (uint16) Int32) & 0x8000) + if ((ICPU.Registers.A.W ^ Work16) & + (ICPU.Registers.A.W ^ (uint16) Int32) & 0x8000) SetOverflow(); else ClearOverflow (); - Registers.A.W = (uint16) Int32; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = (uint16) Int32; + SetZN16 (ICPU.Registers.A.W); } } @@ -755,8 +755,8 @@ static void SBC8 (long Addr) uint8 Work8 = S9xGetByte (Addr); if (CheckDecimal ()) { - uint8 A1 = (Registers.A.W) & 0xF; - uint8 A2 = (Registers.A.W >> 4) & 0xF; + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; uint8 W1 = Work8 & 0xF; uint8 W2 = (Work8 >> 4) & 0xF; @@ -778,57 +778,57 @@ static void SBC8 (long Addr) } uint8 Ans8 = (A2 << 4) | A1; - if ((Registers.AL ^ Work8) & - (Registers.AL ^ Ans8) & 0x80) + if ((ICPU.Registers.AL ^ Work8) & + (ICPU.Registers.AL ^ Ans8) & 0x80) SetOverflow (); else ClearOverflow (); - Registers.AL = Ans8; - SetZN8 (Registers.AL); + ICPU.Registers.AL = Ans8; + SetZN8 (ICPU.Registers.AL); } else { - int16 Int16 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1; + int16 Int16 = (short) ICPU.Registers.AL - (short) Work8 + (short) CheckCarry() - 1; ICPU._Carry = Int16 >= 0; - if ((Registers.AL ^ Work8) & - (Registers.AL ^ (uint8) Int16) & 0x80) + if ((ICPU.Registers.AL ^ Work8) & + (ICPU.Registers.AL ^ (uint8) Int16) & 0x80) SetOverflow (); else ClearOverflow (); - Registers.AL = (uint8) Int16; - SetZN8 (Registers.AL); + ICPU.Registers.AL = (uint8) Int16; + SetZN8 (ICPU.Registers.AL); } } static void STA16 (long Addr) { - S9xSetWord (Registers.A.W, Addr); + S9xSetWord (ICPU.Registers.A.W, Addr); } static void STA8 (long Addr) { - S9xSetByte (Registers.AL, Addr); + S9xSetByte (ICPU.Registers.AL, Addr); } static void STX16 (long Addr) { - S9xSetWord (Registers.X.W, Addr); + S9xSetWord (ICPU.Registers.X.W, Addr); } static void STX8 (long Addr) { - S9xSetByte (Registers.XL, Addr); + S9xSetByte (ICPU.Registers.XL, Addr); } static void STY16 (long Addr) { - S9xSetWord (Registers.Y.W, Addr); + S9xSetWord (ICPU.Registers.Y.W, Addr); } static void STY8 (long Addr) { - S9xSetByte (Registers.YL, Addr); + S9xSetByte (ICPU.Registers.YL, Addr); } static void STZ16 (long Addr) @@ -847,8 +847,8 @@ static void TSB16 (long Addr) CPU.Cycles += ONE_CYCLE; #endif uint16 Work16 = S9xGetWord (Addr); - ICPU._Zero = (Work16 & Registers.A.W) != 0; - Work16 |= Registers.A.W; + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; + Work16 |= ICPU.Registers.A.W; //S9xSetWord (Work16, Addr); S9xSetByte (Work16>>8, Addr+1); S9xSetByte (Work16&0xFF, Addr); @@ -860,8 +860,8 @@ static void TSB8 (long Addr) CPU.Cycles += ONE_CYCLE; #endif uint8 Work8 = S9xGetByte (Addr); - ICPU._Zero = Work8 & Registers.AL; - Work8 |= Registers.AL; + ICPU._Zero = Work8 & ICPU.Registers.AL; + Work8 |= ICPU.Registers.AL; S9xSetByte (Work8, Addr); } @@ -871,8 +871,8 @@ static void TRB16 (long Addr) CPU.Cycles += ONE_CYCLE; #endif uint16 Work16 = S9xGetWord (Addr); - ICPU._Zero = (Work16 & Registers.A.W) != 0; - Work16 &= ~Registers.A.W; + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; + Work16 &= ~ICPU.Registers.A.W; //S9xSetWord (Work16, Addr); S9xSetByte (Work16>>8, Addr+1); S9xSetByte (Work16&0xFF, Addr); @@ -884,8 +884,8 @@ static void TRB8 (long Addr) CPU.Cycles += ONE_CYCLE; #endif uint8 Work8 = S9xGetByte (Addr); - ICPU._Zero = Work8 & Registers.AL; - Work8 &= ~Registers.AL; + ICPU._Zero = Work8 & ICPU.Registers.AL; + Work8 &= ~ICPU.Registers.AL; S9xSetByte (Work8, Addr); } #endif diff --git a/source/cpuops.cpp b/source/cpuops.cpp index 719465e..4ddcb6b 100644 --- a/source/cpuops.cpp +++ b/source/cpuops.cpp @@ -268,25 +268,25 @@ static void Op73M0 (void) /* AND *************************************************************************************** */ static void Op29M1 (void) { - Registers.AL &= *CPU.PC++; + ICPU.Registers.AL &= *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void Op29M0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.A.W &= *(uint16 *) CPU.PC; + ICPU.Registers.A.W &= *(uint16 *) CPU.PC; #else - Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.A.W); + SetZN16 (ICPU.Registers.A.W); } static void Op25M1 (void) @@ -485,7 +485,7 @@ static void Op1EM0 (void) /* BIT *************************************************************************************** */ static void Op89M1 (void) { - ICPU._Zero = Registers.AL & *CPU.PC++; + ICPU._Zero = ICPU.Registers.AL & *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif @@ -494,9 +494,9 @@ static void Op89M1 (void) static void Op89M0 (void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU._Zero = (Registers.A.W & *(uint16 *) CPU.PC) != 0; + ICPU._Zero = (ICPU.Registers.A.W & *(uint16 *) CPU.PC) != 0; #else - ICPU._Zero = (Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0; + ICPU._Zero = (ICPU.Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0; #endif #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; @@ -548,7 +548,7 @@ static void Op3CM0 (void) /* CMP *************************************************************************************** */ static void OpC9M1 (void) { - int32 Int32 = (int) Registers.AL - (int) *CPU.PC++; + int32 Int32 = (int) ICPU.Registers.AL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -560,9 +560,9 @@ static void OpC9M0 (void) { int32 Int32; #ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) Registers.A.W - (long) *(uint16 *) CPU.PC; + Int32 = (long) ICPU.Registers.A.W - (long) *(uint16 *) CPU.PC; #else - Int32 = (long) Registers.A.W - + Int32 = (long) ICPU.Registers.A.W - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); #endif ICPU._Carry = Int32 >= 0; @@ -718,7 +718,7 @@ static void OpD3M0 (void) /* CMX *************************************************************************************** */ static void OpE0X1 (void) { - int32 Int32 = (int) Registers.XL - (int) *CPU.PC++; + int32 Int32 = (int) ICPU.Registers.XL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -730,9 +730,9 @@ static void OpE0X0 (void) { int32 Int32; #ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) Registers.X.W - (long) *(uint16 *) CPU.PC; + Int32 = (long) ICPU.Registers.X.W - (long) *(uint16 *) CPU.PC; #else - Int32 = (long) Registers.X.W - + Int32 = (long) ICPU.Registers.X.W - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); #endif ICPU._Carry = Int32 >= 0; @@ -768,7 +768,7 @@ static void OpECX0 (void) /* CMY *************************************************************************************** */ static void OpC0X1 (void) { - int32 Int32 = (int) Registers.YL - (int) *CPU.PC++; + int32 Int32 = (int) ICPU.Registers.YL - (int) *CPU.PC++; ICPU._Carry = Int32 >= 0; SetZN8 ((uint8) Int32); #ifndef SA1_OPCODES @@ -780,9 +780,9 @@ static void OpC0X0 (void) { int32 Int32; #ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) Registers.Y.W - (long) *(uint16 *) CPU.PC; + Int32 = (long) ICPU.Registers.Y.W - (long) *(uint16 *) CPU.PC; #else - Int32 = (long) Registers.Y.W - + Int32 = (long) ICPU.Registers.Y.W - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); #endif ICPU._Carry = Int32 >= 0; @@ -871,25 +871,25 @@ static void OpDEM0 (void) /* EOR *************************************************************************************** */ static void Op49M1 (void) { - Registers.AL ^= *CPU.PC++; + ICPU.Registers.AL ^= *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void Op49M0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.A.W ^= *(uint16 *) CPU.PC; + ICPU.Registers.A.W ^= *(uint16 *) CPU.PC; #else - Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.A.W); + SetZN16 (ICPU.Registers.A.W); } static void Op45M1 (void) @@ -1089,26 +1089,26 @@ static void OpFEM0 (void) /* LDA *************************************************************************************** */ static void OpA9M1 (void) { - Registers.AL = *CPU.PC++; + ICPU.Registers.AL = *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void OpA9M0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.A.W = *(uint16 *) CPU.PC; + ICPU.Registers.A.W = *(uint16 *) CPU.PC; #else - Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.A.W); + SetZN16 (ICPU.Registers.A.W); } static void OpA5M1 (void) @@ -1256,25 +1256,25 @@ static void OpB3M0 (void) /* LDX *************************************************************************************** */ static void OpA2X1 (void) { - Registers.XL = *CPU.PC++; + ICPU.Registers.XL = *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.XL); + SetZN8 (ICPU.Registers.XL); } static void OpA2X0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.X.W = *(uint16 *) CPU.PC; + ICPU.Registers.X.W = *(uint16 *) CPU.PC; #else - Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.X.W); + SetZN16 (ICPU.Registers.X.W); } static void OpA6X1 (void) @@ -1321,26 +1321,26 @@ static void OpBEX0 (void) /* LDY *************************************************************************************** */ static void OpA0X1 (void) { - Registers.YL = *CPU.PC++; + ICPU.Registers.YL = *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.YL); + SetZN8 (ICPU.Registers.YL); } static void OpA0X0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.Y.W = *(uint16 *) CPU.PC; + ICPU.Registers.Y.W = *(uint16 *) CPU.PC; #else - Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.Y.W); + SetZN16 (ICPU.Registers.Y.W); } static void OpA4X1 (void) @@ -1440,25 +1440,25 @@ static void Op5EM0 (void) /* ORA *************************************************************************************** */ static void Op09M1 (void) { - Registers.AL |= *CPU.PC++; + ICPU.Registers.AL |= *CPU.PC++; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void Op09M0 (void) { #ifdef FAST_LSB_WORD_ACCESS - Registers.A.W |= *(uint16 *) CPU.PC; + ICPU.Registers.A.W |= *(uint16 *) CPU.PC; #else - Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8); #endif CPU.PC += 2; #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (Registers.A.W); + SetZN16 (ICPU.Registers.A.W); } static void Op05M1 (void) @@ -2447,8 +2447,8 @@ static void OpCAX1 (void) CPU.WaitAddress = NULL; #endif - Registers.XL--; - SetZN8 (Registers.XL); + ICPU.Registers.XL--; + SetZN8 (ICPU.Registers.XL); } static void OpCAX0 (void) @@ -2460,8 +2460,8 @@ static void OpCAX0 (void) CPU.WaitAddress = NULL; #endif - Registers.X.W--; - SetZN16 (Registers.X.W); + ICPU.Registers.X.W--; + SetZN16 (ICPU.Registers.X.W); } static void Op88X1 (void) @@ -2473,8 +2473,8 @@ static void Op88X1 (void) CPU.WaitAddress = NULL; #endif - Registers.YL--; - SetZN8 (Registers.YL); + ICPU.Registers.YL--; + SetZN8 (ICPU.Registers.YL); } static void Op88X0 (void) @@ -2486,8 +2486,8 @@ static void Op88X0 (void) CPU.WaitAddress = NULL; #endif - Registers.Y.W--; - SetZN16 (Registers.Y.W); + ICPU.Registers.Y.W--; + SetZN16 (ICPU.Registers.Y.W); } /**********************************************************************************************/ @@ -2501,8 +2501,8 @@ static void OpE8X1 (void) CPU.WaitAddress = NULL; #endif - Registers.XL++; - SetZN8 (Registers.XL); + ICPU.Registers.XL++; + SetZN8 (ICPU.Registers.XL); } static void OpE8X0 (void) @@ -2514,8 +2514,8 @@ static void OpE8X0 (void) CPU.WaitAddress = NULL; #endif - Registers.X.W++; - SetZN16 (Registers.X.W); + ICPU.Registers.X.W++; + SetZN16 (ICPU.Registers.X.W); } static void OpC8X1 (void) @@ -2527,8 +2527,8 @@ static void OpC8X1 (void) CPU.WaitAddress = NULL; #endif - Registers.YL++; - SetZN8 (Registers.YL); + ICPU.Registers.YL++; + SetZN8 (ICPU.Registers.YL); } static void OpC8X0 (void) @@ -2540,8 +2540,8 @@ static void OpC8X0 (void) CPU.WaitAddress = NULL; #endif - Registers.Y.W++; - SetZN16 (Registers.Y.W); + ICPU.Registers.Y.W++; + SetZN16 (ICPU.Registers.Y.W); } /**********************************************************************************************/ @@ -2558,32 +2558,32 @@ static void OpEA (void) /* PUSH Instructions ************************************************************************* */ /* #define PushW(w) \ - * S9xSetWord (w, Registers.S.W - 1);\ - * Registers.S.W -= 2; + * S9xSetWord (w, ICPU.Registers.S.W - 1);\ + * ICPU.Registers.S.W -= 2; */ #define PushB(b)\ - S9xSetByte (b, Registers.S.W--); + S9xSetByte (b, ICPU.Registers.S.W--); #define PushBE(b)\ - S9xSetByte (b, Registers.S.W--);\ - Registers.SH=0x01; + S9xSetByte (b, ICPU.Registers.S.W--);\ + ICPU.Registers.SH=0x01; #define PushW(w) \ - S9xSetByte ((w)>>8, Registers.S.W);\ - S9xSetByte ((w)&0xff, (Registers.S.W - 1)&0xFFFF);\ - Registers.S.W -= 2; + S9xSetByte ((w)>>8, ICPU.Registers.S.W);\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W - 1)&0xFFFF);\ + ICPU.Registers.S.W -= 2; #define PushWE(w) \ - S9xSetByte ((w)>>8, Registers.S.W--);\ - Registers.SH=0x01;\ - S9xSetByte ((w)&0xff, (Registers.S.W--)&0xFFFF);\ - Registers.SH = 0x01; + S9xSetByte ((w)>>8, ICPU.Registers.S.W--);\ + ICPU.Registers.SH=0x01;\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ + ICPU.Registers.SH = 0x01; #define PushWENew(w) \ - S9xSetByte ((w)>>8, Registers.S.W--);\ - S9xSetByte ((w)&0xff, (Registers.S.W--)&0xFFFF);\ - Registers.SH = 0x01; + S9xSetByte ((w)>>8, ICPU.Registers.S.W--);\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ + ICPU.Registers.SH = 0x01; //PEA NL static void OpF4E1 (void) @@ -2628,7 +2628,7 @@ static void Op62 (void) //PHA static void Op48E1 (void) { - PushBE (Registers.AL); + PushBE (ICPU.Registers.AL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2636,7 +2636,7 @@ static void Op48E1 (void) static void Op48M1 (void) { - PushB (Registers.AL); + PushB (ICPU.Registers.AL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2644,7 +2644,7 @@ static void Op48M1 (void) static void Op48M0 (void) { - PushW (Registers.A.W); + PushW (ICPU.Registers.A.W); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2653,14 +2653,14 @@ static void Op48M0 (void) //PHB static void Op8BE1 (void) { - PushBE (Registers.DB); + PushBE (ICPU.Registers.DB); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif } static void Op8B (void) { - PushB (Registers.DB); + PushB (ICPU.Registers.DB); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2669,7 +2669,7 @@ static void Op8B (void) //PHD NL static void Op0BE1 (void) { - PushWENew (Registers.D.W); + PushWENew (ICPU.Registers.D.W); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2677,7 +2677,7 @@ static void Op0BE1 (void) static void Op0B (void) { - PushW (Registers.D.W); + PushW (ICPU.Registers.D.W); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2686,7 +2686,7 @@ static void Op0B (void) //PHK static void Op4BE1 (void) { - PushBE (Registers.PB); + PushBE (ICPU.Registers.PB); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2694,7 +2694,7 @@ static void Op4BE1 (void) static void Op4B (void) { - PushB (Registers.PB); + PushB (ICPU.Registers.PB); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2704,7 +2704,7 @@ static void Op4B (void) static void Op08E1 (void) { S9xPackStatus (); - PushBE (Registers.PL); + PushBE (ICPU.Registers.PL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2713,7 +2713,7 @@ static void Op08E1 (void) static void Op08 (void) { S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2722,7 +2722,7 @@ static void Op08 (void) //PHX static void OpDAE1 (void) { - PushBE (Registers.XL); + PushBE (ICPU.Registers.XL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2730,7 +2730,7 @@ static void OpDAE1 (void) static void OpDAX1 (void) { - PushB (Registers.XL); + PushB (ICPU.Registers.XL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2738,7 +2738,7 @@ static void OpDAX1 (void) static void OpDAX0 (void) { - PushW (Registers.X.W); + PushW (ICPU.Registers.X.W); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2747,7 +2747,7 @@ static void OpDAX0 (void) //PHY static void Op5AE1 (void) { - PushBE (Registers.YL); + PushBE (ICPU.Registers.YL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2755,7 +2755,7 @@ static void Op5AE1 (void) static void Op5AX1 (void) { - PushB (Registers.YL); + PushB (ICPU.Registers.YL); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2763,7 +2763,7 @@ static void Op5AX1 (void) static void Op5AX0 (void) { - PushW (Registers.Y.W); + PushW (ICPU.Registers.Y.W); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif @@ -2772,32 +2772,32 @@ static void Op5AX0 (void) /* PULL Instructions ************************************************************************* */ #define PullW(w) \ - w = S9xGetByte (++Registers.S.W); \ - w |= (S9xGetByte (++Registers.S.W)<<8); + w = S9xGetByte (++ICPU.Registers.S.W); \ + w |= (S9xGetByte (++ICPU.Registers.S.W)<<8); -/* w = S9xGetWord (Registers.S.W + 1); \ - Registers.S.W += 2; +/* w = S9xGetWord (ICPU.Registers.S.W + 1); \ + ICPU.Registers.S.W += 2; */ #define PullB(b)\ - b = S9xGetByte (++Registers.S.W); + b = S9xGetByte (++ICPU.Registers.S.W); #define PullBE(b)\ - Registers.S.W++;\ - Registers.SH=0x01;\ - b = S9xGetByte (Registers.S.W); + ICPU.Registers.S.W++;\ + ICPU.Registers.SH=0x01;\ + b = S9xGetByte (ICPU.Registers.S.W); #define PullWE(w) \ - Registers.S.W++;\ - Registers.SH=0x01;\ - w = S9xGetByte (Registers.S.W); \ - Registers.S.W++; \ - Registers.SH=0x01;\ - w |= (S9xGetByte (Registers.S.W)<<8); + ICPU.Registers.S.W++;\ + ICPU.Registers.SH=0x01;\ + w = S9xGetByte (ICPU.Registers.S.W); \ + ICPU.Registers.S.W++; \ + ICPU.Registers.SH=0x01;\ + w |= (S9xGetByte (ICPU.Registers.S.W)<<8); #define PullWENew(w) \ PullW(w);\ - Registers.SH=0x01; + ICPU.Registers.SH=0x01; //PLA static void Op68E1 (void) @@ -2805,8 +2805,8 @@ static void Op68E1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullBE (Registers.AL); - SetZN8 (Registers.AL); + PullBE (ICPU.Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void Op68M1 (void) @@ -2814,8 +2814,8 @@ static void Op68M1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullB (Registers.AL); - SetZN8 (Registers.AL); + PullB (ICPU.Registers.AL); + SetZN8 (ICPU.Registers.AL); } static void Op68M0 (void) @@ -2823,8 +2823,8 @@ static void Op68M0 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullW (Registers.A.W); - SetZN16 (Registers.A.W); + PullW (ICPU.Registers.A.W); + SetZN16 (ICPU.Registers.A.W); } //PLB @@ -2833,9 +2833,9 @@ static void OpABE1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullBE (Registers.DB); - SetZN8 (Registers.DB); - ICPU.ShiftedDB = Registers.DB << 16; + PullBE (ICPU.Registers.DB); + SetZN8 (ICPU.Registers.DB); + ICPU.ShiftedDB = ICPU.Registers.DB << 16; } static void OpAB (void) @@ -2843,9 +2843,9 @@ static void OpAB (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullB (Registers.DB); - SetZN8 (Registers.DB); - ICPU.ShiftedDB = Registers.DB << 16; + PullB (ICPU.Registers.DB); + SetZN8 (ICPU.Registers.DB); + ICPU.ShiftedDB = ICPU.Registers.DB << 16; } /* PHP */ @@ -2855,8 +2855,8 @@ static void Op2BE1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullWENew (Registers.D.W); - SetZN16 (Registers.D.W); + PullWENew (ICPU.Registers.D.W); + SetZN16 (ICPU.Registers.D.W); } static void Op2B (void) @@ -2864,8 +2864,8 @@ static void Op2B (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullW (Registers.D.W); - SetZN16 (Registers.D.W); + PullW (ICPU.Registers.D.W); + SetZN16 (ICPU.Registers.D.W); } /* PLP */ @@ -2874,13 +2874,13 @@ static void Op28E1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullBE (Registers.PL); + PullBE (ICPU.Registers.PL); S9xUnpackStatus (); if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } S9xFixCycles(); /* CHECK_FOR_IRQ();*/ @@ -2891,13 +2891,13 @@ static void Op28 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullB (Registers.PL); + PullB (ICPU.Registers.PL); S9xUnpackStatus (); if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } S9xFixCycles(); /* CHECK_FOR_IRQ();*/ @@ -2909,8 +2909,8 @@ static void OpFAE1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullBE (Registers.XL); - SetZN8 (Registers.XL); + PullBE (ICPU.Registers.XL); + SetZN8 (ICPU.Registers.XL); } static void OpFAX1 (void) @@ -2918,8 +2918,8 @@ static void OpFAX1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullB (Registers.XL); - SetZN8 (Registers.XL); + PullB (ICPU.Registers.XL); + SetZN8 (ICPU.Registers.XL); } static void OpFAX0 (void) @@ -2927,8 +2927,8 @@ static void OpFAX0 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullW (Registers.X.W); - SetZN16 (Registers.X.W); + PullW (ICPU.Registers.X.W); + SetZN16 (ICPU.Registers.X.W); } //PLY @@ -2937,8 +2937,8 @@ static void Op7AE1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullBE (Registers.YL); - SetZN8 (Registers.YL); + PullBE (ICPU.Registers.YL); + SetZN8 (ICPU.Registers.YL); } static void Op7AX1 (void) @@ -2946,8 +2946,8 @@ static void Op7AX1 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullB (Registers.YL); - SetZN8 (Registers.YL); + PullB (ICPU.Registers.YL); + SetZN8 (ICPU.Registers.YL); } static void Op7AX0 (void) @@ -2955,8 +2955,8 @@ static void Op7AX0 (void) #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif - PullW (Registers.Y.W); - SetZN16 (Registers.Y.W); + PullW (ICPU.Registers.Y.W); + SetZN16 (ICPU.Registers.Y.W); } /**********************************************************************************************/ @@ -2998,8 +2998,8 @@ static void OpAAX1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.XL = Registers.AL; - SetZN8 (Registers.XL); + ICPU.Registers.XL = ICPU.Registers.AL; + SetZN8 (ICPU.Registers.XL); } /* TAX16 */ @@ -3008,8 +3008,8 @@ static void OpAAX0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.X.W = Registers.A.W; - SetZN16 (Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.A.W; + SetZN16 (ICPU.Registers.X.W); } /* TAY8 */ @@ -3018,8 +3018,8 @@ static void OpA8X1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.YL = Registers.AL; - SetZN8 (Registers.YL); + ICPU.Registers.YL = ICPU.Registers.AL; + SetZN8 (ICPU.Registers.YL); } /* TAY16 */ @@ -3028,8 +3028,8 @@ static void OpA8X0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.Y.W = Registers.A.W; - SetZN16 (Registers.Y.W); + ICPU.Registers.Y.W = ICPU.Registers.A.W; + SetZN16 (ICPU.Registers.Y.W); } static void Op5B (void) @@ -3037,8 +3037,8 @@ static void Op5B (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.D.W = Registers.A.W; - SetZN16 (Registers.D.W); + ICPU.Registers.D.W = ICPU.Registers.A.W; + SetZN16 (ICPU.Registers.D.W); } static void Op1B (void) @@ -3046,9 +3046,9 @@ static void Op1B (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.S.W = Registers.A.W; + ICPU.Registers.S.W = ICPU.Registers.A.W; if (CheckEmulation()) - Registers.SH = 1; + ICPU.Registers.SH = 1; } static void Op7B (void) @@ -3056,8 +3056,8 @@ static void Op7B (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.A.W = Registers.D.W; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.D.W; + SetZN16 (ICPU.Registers.A.W); } static void Op3B (void) @@ -3065,8 +3065,8 @@ static void Op3B (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.A.W = Registers.S.W; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.S.W; + SetZN16 (ICPU.Registers.A.W); } static void OpBAX1 (void) @@ -3074,8 +3074,8 @@ static void OpBAX1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.XL = Registers.SL; - SetZN8 (Registers.XL); + ICPU.Registers.XL = ICPU.Registers.SL; + SetZN8 (ICPU.Registers.XL); } static void OpBAX0 (void) @@ -3083,8 +3083,8 @@ static void OpBAX0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.X.W = Registers.S.W; - SetZN16 (Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.S.W; + SetZN16 (ICPU.Registers.X.W); } static void Op8AM1 (void) @@ -3092,8 +3092,8 @@ static void Op8AM1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.AL = Registers.XL; - SetZN8 (Registers.AL); + ICPU.Registers.AL = ICPU.Registers.XL; + SetZN8 (ICPU.Registers.AL); } static void Op8AM0 (void) @@ -3101,8 +3101,8 @@ static void Op8AM0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.A.W = Registers.X.W; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.X.W; + SetZN16 (ICPU.Registers.A.W); } static void Op9A (void) @@ -3110,9 +3110,9 @@ static void Op9A (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.S.W = Registers.X.W; + ICPU.Registers.S.W = ICPU.Registers.X.W; if (CheckEmulation()) - Registers.SH = 1; + ICPU.Registers.SH = 1; } static void Op9BX1 (void) @@ -3120,8 +3120,8 @@ static void Op9BX1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.YL = Registers.XL; - SetZN8 (Registers.YL); + ICPU.Registers.YL = ICPU.Registers.XL; + SetZN8 (ICPU.Registers.YL); } static void Op9BX0 (void) @@ -3129,8 +3129,8 @@ static void Op9BX0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.Y.W = Registers.X.W; - SetZN16 (Registers.Y.W); + ICPU.Registers.Y.W = ICPU.Registers.X.W; + SetZN16 (ICPU.Registers.Y.W); } static void Op98M1 (void) @@ -3138,8 +3138,8 @@ static void Op98M1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.AL = Registers.YL; - SetZN8 (Registers.AL); + ICPU.Registers.AL = ICPU.Registers.YL; + SetZN8 (ICPU.Registers.AL); } static void Op98M0 (void) @@ -3147,8 +3147,8 @@ static void Op98M0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.A.W = Registers.Y.W; - SetZN16 (Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.Y.W; + SetZN16 (ICPU.Registers.A.W); } static void OpBBX1 (void) @@ -3156,8 +3156,8 @@ static void OpBBX1 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.XL = Registers.YL; - SetZN8 (Registers.XL); + ICPU.Registers.XL = ICPU.Registers.YL; + SetZN8 (ICPU.Registers.XL); } static void OpBBX0 (void) @@ -3165,8 +3165,8 @@ static void OpBBX0 (void) #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE; #endif - Registers.X.W = Registers.Y.W; - SetZN16 (Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.Y.W; + SetZN16 (ICPU.Registers.X.W); } /**********************************************************************************************/ @@ -3179,20 +3179,20 @@ static void OpFB (void) #endif uint8 A1 = ICPU._Carry; - uint8 A2 = Registers.PH; + uint8 A2 = ICPU.Registers.PH; ICPU._Carry = A2 & 1; - Registers.PH = A1; + ICPU.Registers.PH = A1; if (CheckEmulation()) { SetFlags (MemoryFlag | IndexFlag); - Registers.SH = 1; + ICPU.Registers.SH = 1; missing.emulate6502 = 1; } if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } S9xFixCycles(); } @@ -3212,17 +3212,17 @@ static void Op00 (void) if (!CheckEmulation()) { - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushW (CPU.PC - CPU.PCBase + 1); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; S9xSetPCBase (S9xGetWord (0xFFE6)); #ifndef SA1_OPCODES @@ -3233,14 +3233,14 @@ static void Op00 (void) { PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; S9xSetPCBase (S9xGetWord (0xFFFE)); #ifndef SA1_OPCODES @@ -3267,17 +3267,17 @@ void S9xOpcode_IRQ (void) #endif if (!CheckEmulation()) { - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES S9xSA1SetPCBase (Memory.FillRAM [0x2207] | @@ -3297,14 +3297,14 @@ void S9xOpcode_IRQ (void) { PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES S9xSA1SetPCBase (Memory.FillRAM [0x2207] | @@ -3333,17 +3333,17 @@ void S9xOpcode_NMI (void) #endif if (!CheckEmulation()) { - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES S9xSA1SetPCBase (Memory.FillRAM [0x2205] | @@ -3363,14 +3363,14 @@ void S9xOpcode_NMI (void) { PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES S9xSA1SetPCBase (Memory.FillRAM [0x2205] | @@ -3398,17 +3398,17 @@ static void Op02 (void) #endif if (!CheckEmulation()) { - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushW (CPU.PC - CPU.PCBase + 1); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; S9xSetPCBase (S9xGetWord (0xFFE4)); #ifndef SA1_OPCODES @@ -3419,14 +3419,14 @@ static void Op02 (void) { PushW (CPU.PC - CPU.PCBase); S9xPackStatus (); - PushB (Registers.PL); + PushB (ICPU.Registers.PL); #ifndef NO_OPEN_BUS - OpenBus = Registers.PL; + OpenBus = ICPU.Registers.PL; #endif ClearDecimal (); SetIRQ (); - Registers.PB = 0; + ICPU.Registers.PB = 0; ICPU.ShiftedPB = 0; S9xSetPCBase (S9xGetWord (0xFFF4)); #ifndef SA1_OPCODES @@ -3440,7 +3440,7 @@ static void Op02 (void) static void OpDC (void) { AbsoluteIndirectLong (JUMP, OpAddressPassthrough); - Registers.PB = (uint8) (OpAddress >> 16); + ICPU.Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); #ifndef SA1_OPCODES @@ -3451,7 +3451,7 @@ static void OpDC (void) static void Op5C (void) { AbsoluteLong (JUMP, OpAddressPassthrough); - Registers.PB = (uint8) (OpAddress >> 16); + ICPU.Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); } @@ -3487,9 +3487,9 @@ static void Op7C (void) static void Op22E1 (void) { AbsoluteLong (JUMP, OpAddressPassthrough); - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushWENew (CPU.PC - CPU.PCBase - 1); - Registers.PB = (uint8) (OpAddress >> 16); + ICPU.Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); } @@ -3497,19 +3497,19 @@ static void Op22E1 (void) static void Op22 (void) { AbsoluteLong (JUMP, OpAddressPassthrough); - PushB (Registers.PB); + PushB (ICPU.Registers.PB); PushW (CPU.PC - CPU.PCBase - 1); - Registers.PB = (uint8) (OpAddress >> 16); + ICPU.Registers.PB = (uint8) (OpAddress >> 16); ICPU.ShiftedPB = OpAddress & 0xff0000; S9xSetPCBase (OpAddress); } static void Op6BE1 (void) { - PullWENew (Registers.PC); - PullB (Registers.PB); - ICPU.ShiftedPB = Registers.PB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff)); + PullWENew (ICPU.Registers.PC); + PullB (ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif @@ -3517,10 +3517,10 @@ static void Op6BE1 (void) static void Op6B (void) { - PullW (Registers.PC); - PullB (Registers.PB); - ICPU.ShiftedPB = Registers.PB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff)); + PullW (ICPU.Registers.PC); + PullB (ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif @@ -3561,8 +3561,8 @@ static void OpFC (void) static void Op60 (void) { - PullW (Registers.PC); - S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff)); + PullW (ICPU.Registers.PC); + S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES CPU.Cycles += ONE_CYCLE * 3; #endif @@ -3579,20 +3579,20 @@ static void Op54X1 (void) CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = Registers.DB << 16; + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; #ifndef NO_OPEN_BUS OpenBus = #endif SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), - ICPU.ShiftedDB + Registers.Y.W); + S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - Registers.XL++; - Registers.YL++; - Registers.A.W--; - if (Registers.A.W != 0xffff) + ICPU.Registers.XL++; + ICPU.Registers.YL++; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) CPU.PC -= 3; } @@ -3604,20 +3604,20 @@ static void Op54X0 (void) CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = Registers.DB << 16; + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; #ifndef NO_OPEN_BUS OpenBus = #endif SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), - ICPU.ShiftedDB + Registers.Y.W); + S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - Registers.X.W++; - Registers.Y.W++; - Registers.A.W--; - if (Registers.A.W != 0xffff) + ICPU.Registers.X.W++; + ICPU.Registers.Y.W++; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) CPU.PC -= 3; } @@ -3628,19 +3628,19 @@ static void Op44X1 (void) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = Registers.DB << 16; + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; #ifndef NO_OPEN_BUS OpenBus = #endif SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), - ICPU.ShiftedDB + Registers.Y.W); + S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - Registers.XL--; - Registers.YL--; - Registers.A.W--; - if (Registers.A.W != 0xffff) + ICPU.Registers.XL--; + ICPU.Registers.YL--; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) CPU.PC -= 3; } @@ -3651,19 +3651,19 @@ static void Op44X0 (void) #ifndef SA1_OPCODES CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = Registers.DB << 16; + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; #ifndef NO_OPEN_BUS OpenBus = #endif SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), - ICPU.ShiftedDB + Registers.Y.W); + S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - Registers.X.W--; - Registers.Y.W--; - Registers.A.W--; - if (Registers.A.W != 0xffff) + ICPU.Registers.X.W--; + ICPU.Registers.Y.W--; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) CPU.PC -= 3; } @@ -3673,7 +3673,7 @@ static void Op44X0 (void) static void OpC2 (void) { uint8 Work8 = ~*CPU.PC++; - Registers.PL &= Work8; + ICPU.Registers.PL &= Work8; ICPU._Carry &= Work8; ICPU._Overflow &= (Work8 >> 6); ICPU._Negative &= Work8; @@ -3689,8 +3689,8 @@ static void OpC2 (void) } if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } S9xFixCycles(); /* CHECK_FOR_IRQ(); */ @@ -3699,7 +3699,7 @@ static void OpC2 (void) static void OpE2 (void) { uint8 Work8 = *CPU.PC++; - Registers.PL |= Work8; + ICPU.Registers.PL |= Work8; ICPU._Carry |= Work8 & 1; ICPU._Overflow |= (Work8 >> 6) & 1; ICPU._Negative |= Work8; @@ -3715,8 +3715,8 @@ static void OpE2 (void) } if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } S9xFixCycles(); } @@ -3725,11 +3725,11 @@ static void OpE2 (void) /* XBA *************************************************************************************** */ static void OpEB (void) { - uint8 Work8 = Registers.AL; - Registers.AL = Registers.AH; - Registers.AH = Work8; + uint8 Work8 = ICPU.Registers.AL; + ICPU.Registers.AL = ICPU.Registers.AH; + ICPU.Registers.AH = Work8; - SetZN8 (Registers.AL); + SetZN8 (ICPU.Registers.AL); #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; #endif @@ -3739,24 +3739,24 @@ static void OpEB (void) /* RTI *************************************************************************************** */ static void Op40 (void) { - PullB (Registers.PL); + PullB (ICPU.Registers.PL); S9xUnpackStatus (); - PullW (Registers.PC); + PullW (ICPU.Registers.PC); if (!CheckEmulation()) { - PullB (Registers.PB); - ICPU.ShiftedPB = Registers.PB << 16; + PullB (ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; } else { SetFlags (MemoryFlag | IndexFlag); missing.emulate6502 = 1; } - S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); if (CheckIndex ()) { - Registers.XH = 0; - Registers.YH = 0; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; } #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; diff --git a/source/globals.cpp b/source/globals.cpp index ca2b12b..adb9ab4 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -113,20 +113,14 @@ struct SICPU ICPU; struct SCPUState CPU; -struct SRegisters Registers; - struct SAPU APU; struct SIAPU IAPU; -struct SAPURegisters APURegisters; - struct SSettings Settings; struct SDSP1 DSP1; -struct SSA1Registers SA1Registers; - struct SSA1 SA1; SSoundData SoundData; @@ -361,7 +355,7 @@ struct SNetPlay NetPlay; #endif // Raw SPC700 instruction cycle lengths -int32 S9xAPUCycleLengths [256] = +uint16 S9xAPUCycleLengths [256] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, @@ -384,7 +378,7 @@ int32 S9xAPUCycleLengths [256] = // Actual data used by CPU emulation, will be scaled by APUReset routine // to be relative to the 65c816 instruction lengths. -int32 S9xAPUCycles [256] = +uint16 S9xAPUCycles [256] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, diff --git a/source/sa1.cpp b/source/sa1.cpp index eb10d33..1f6b13f 100644 --- a/source/sa1.cpp +++ b/source/sa1.cpp @@ -122,16 +122,16 @@ void S9xSA1Init () void S9xSA1Reset () { - SA1Registers.PB = 0; - SA1Registers.PC = Memory.FillRAM [0x2203] | + SA1.Registers.PB = 0; + SA1.Registers.PC = Memory.FillRAM [0x2203] | (Memory.FillRAM [0x2204] << 8); - SA1Registers.D.W = 0; - SA1Registers.DB = 0; - SA1Registers.SH = 1; - SA1Registers.SL = 0xFF; - SA1Registers.XH = 0; - SA1Registers.YH = 0; - SA1Registers.P.W = 0; + SA1.Registers.D.W = 0; + SA1.Registers.DB = 0; + SA1.Registers.SH = 1; + SA1.Registers.SL = 0xFF; + SA1.Registers.XH = 0; + SA1.Registers.YH = 0; + SA1.Registers.P.W = 0; SA1.ShiftedPB = 0; SA1.ShiftedDB = 0; @@ -141,7 +141,7 @@ void S9xSA1Reset () SA1.WaitingForInterrupt = FALSE; SA1.PC = NULL; SA1.PCBase = NULL; - S9xSA1SetPCBase (SA1Registers.PC); + S9xSA1SetPCBase (SA1.Registers.PC); SA1.S9xOpcodes = S9xSA1OpcodesM1X1; S9xSA1UnpackStatus(); @@ -181,10 +181,10 @@ void S9xSA1SetBWRAMMemMap (uint8 val) void S9xFixSA1AfterSnapshotLoad () { - SA1.ShiftedPB = (uint32) SA1Registers.PB << 16; - SA1.ShiftedDB = (uint32) SA1Registers.DB << 16; + SA1.ShiftedPB = (uint32) SA1.Registers.PB << 16; + SA1.ShiftedDB = (uint32) SA1.Registers.DB << 16; - S9xSA1SetPCBase (SA1.ShiftedPB + SA1Registers.PC); + S9xSA1SetPCBase (SA1.ShiftedPB + SA1.Registers.PC); S9xSA1UnpackStatus (); S9xSA1FixCycles (); SA1.VirtualBitmapFormat = (Memory.FillRAM [0x223f] & 0x80) ? 2 : 4; diff --git a/source/sa1.h b/source/sa1.h index 21353d5..708fb68 100644 --- a/source/sa1.h +++ b/source/sa1.h @@ -141,21 +141,22 @@ struct SSA1 { uint8 VirtualBitmapFormat; bool8 in_char_dma; uint8 variable_bit_pos; + struct SSA1Registers Registers; }; #define SA1CheckZero() (SA1._Zero == 0) #define SA1CheckCarry() (SA1._Carry) -#define SA1CheckIRQ() (SA1Registers.PL & IRQ) -#define SA1CheckDecimal() (SA1Registers.PL & Decimal) -#define SA1CheckIndex() (SA1Registers.PL & IndexFlag) -#define SA1CheckMemory() (SA1Registers.PL & MemoryFlag) +#define SA1CheckIRQ() (SA1.Registers.PL & IRQ) +#define SA1CheckDecimal() (SA1.Registers.PL & Decimal) +#define SA1CheckIndex() (SA1.Registers.PL & IndexFlag) +#define SA1CheckMemory() (SA1.Registers.PL & MemoryFlag) #define SA1CheckOverflow() (SA1._Overflow) #define SA1CheckNegative() (SA1._Negative & 0x80) -#define SA1CheckEmulation() (SA1Registers.P.W & Emulation) +#define SA1CheckEmulation() (SA1.Registers.P.W & Emulation) -#define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f)) -#define SA1SetFlags(f) (SA1Registers.P.W |= (f)) -#define SA1CheckFlag(f) (SA1Registers.PL & (f)) +#define SA1ClearFlags(f) (SA1.Registers.P.W &= ~(f)) +#define SA1SetFlags(f) (SA1.Registers.P.W |= (f)) +#define SA1CheckFlag(f) (SA1.Registers.PL & (f)) START_EXTERN_C @@ -171,7 +172,6 @@ extern struct SOpcodes S9xSA1OpcodesM1X1 [256]; extern struct SOpcodes S9xSA1OpcodesM1X0 [256]; extern struct SOpcodes S9xSA1OpcodesM0X1 [256]; extern struct SOpcodes S9xSA1OpcodesM0X0 [256]; -extern struct SSA1Registers SA1Registers; extern struct SSA1 SA1; void S9xSA1MainLoop (); @@ -186,16 +186,16 @@ END_EXTERN_C STATIC inline void S9xSA1UnpackStatus() { - SA1._Zero = (SA1Registers.PL & Zero) == 0; - SA1._Negative = (SA1Registers.PL & Negative); - SA1._Carry = (SA1Registers.PL & Carry); - SA1._Overflow = (SA1Registers.PL & Overflow) >> 6; + SA1._Zero = (SA1.Registers.PL & Zero) == 0; + SA1._Negative = (SA1.Registers.PL & Negative); + SA1._Carry = (SA1.Registers.PL & Carry); + SA1._Overflow = (SA1.Registers.PL & Overflow) >> 6; } STATIC inline void S9xSA1PackStatus() { - SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow); - SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | + SA1.Registers.PL &= ~(Zero | Negative | Carry | Overflow); + SA1.Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | (SA1._Negative & 0x80) | (SA1._Overflow << 6); } diff --git a/source/sa1cpu.cpp b/source/sa1cpu.cpp index 655fa5c..5382528 100644 --- a/source/sa1cpu.cpp +++ b/source/sa1cpu.cpp @@ -95,7 +95,6 @@ #include "sa1.h" #define CPU SA1 #define ICPU SA1 -#define Registers SA1Registers #define S9xGetByte S9xSA1GetByte #define S9xGetWord S9xSA1GetWord #define S9xSetByte S9xSA1SetByte diff --git a/source/snaporig.cpp b/source/snaporig.cpp index 090c378..219f67f 100644 --- a/source/snaporig.cpp +++ b/source/snaporig.cpp @@ -230,7 +230,7 @@ static int ReadOrigSnapshot (STREAM snap) if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS) return (result); - Registers = *(struct SRegisters *) &OrigRegisters; + ICPU.Registers = *(struct SRegisters *) &OrigRegisters; if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS) return (result); @@ -379,7 +379,7 @@ static int ReadOrigSnapshot (STREAM snap) if ((result = ReadBlock ("ARE:", &OrigAPURegisters, sizeof (OrigAPURegisters), snap)) != SUCCESS) return (result); - APURegisters = *(struct SAPURegisters *) &OrigAPURegisters; + IAPU.Registers = *(struct SAPURegisters *) &OrigAPURegisters; if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("SOU:", &OrigSoundData, @@ -437,7 +437,7 @@ static int ReadOrigSnapshot (STREAM snap) } S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + APURegisters.PC; + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; @@ -453,9 +453,9 @@ static int ReadOrigSnapshot (STREAM snap) S9xSetSoundMute (TRUE); } S9xFixSoundAfterSnapshotLoad (); - ICPU.ShiftedPB = Registers.PB << 16; - ICPU.ShiftedDB = Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); S9xUnpackStatus (); S9xFixCycles (); S9xReschedule (); diff --git a/source/snapshot.cpp b/source/snapshot.cpp index fda8d62..8dd7f8c 100644 --- a/source/snapshot.cpp +++ b/source/snapshot.cpp @@ -658,7 +658,7 @@ void S9xFreezeToStream (STREAM stream) Memory.ROMFilename, 0); WRITE_STREAM (buffer, strlen (buffer) + 1, stream); FreezeStruct (stream, "CPU", &CPU, SnapCPU, COUNT (SnapCPU)); - FreezeStruct (stream, "REG", &Registers, SnapRegisters, COUNT (SnapRegisters)); + FreezeStruct (stream, "REG", &ICPU.Registers, SnapRegisters, COUNT (SnapRegisters)); FreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU)); FreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA)); @@ -671,7 +671,7 @@ void S9xFreezeToStream (STREAM stream) { // APU FreezeStruct (stream, "APU", &APU, SnapAPU, COUNT (SnapAPU)); - FreezeStruct (stream, "ARE", &APURegisters, SnapAPURegisters, + FreezeStruct (stream, "ARE", &IAPU.Registers, SnapAPURegisters, COUNT (SnapAPURegisters)); FreezeBlock (stream, "ARA", IAPU.RAM, 0x10000); FreezeStruct (stream, "SOU", &SoundData, SnapSoundData, @@ -679,10 +679,10 @@ void S9xFreezeToStream (STREAM stream) } if (Settings.SA1) { - SA1Registers.PC = SA1.PC - SA1.PCBase; + SA1.Registers.PC = SA1.PC - SA1.PCBase; S9xSA1PackStatus (); FreezeStruct (stream, "SA1", &SA1, SnapSA1, COUNT (SnapSA1)); - FreezeStruct (stream, "SAR", &SA1Registers, SnapSA1Registers, + FreezeStruct (stream, "SAR", &SA1.Registers, SnapSA1Registers, COUNT (SnapSA1Registers)); } @@ -841,7 +841,7 @@ int S9xUnfreezeFromStream (STREAM stream) S9xSetSoundMute (TRUE); UnfreezeStructFromCopy (&CPU, SnapCPU, COUNT (SnapCPU), local_cpu); - UnfreezeStructFromCopy (&Registers, SnapRegisters, COUNT (SnapRegisters), local_registers); + UnfreezeStructFromCopy (&ICPU.Registers, SnapRegisters, COUNT (SnapRegisters), local_registers); UnfreezeStructFromCopy (&PPU, SnapPPU, COUNT (SnapPPU), local_ppu); UnfreezeStructFromCopy (DMA, SnapDMA, COUNT (SnapDMA), local_dma); memcpy (Memory.VRAM, local_vram, 0x10000); @@ -851,14 +851,14 @@ int S9xUnfreezeFromStream (STREAM stream) if(local_apu) { UnfreezeStructFromCopy (&APU, SnapAPU, COUNT (SnapAPU), local_apu); - UnfreezeStructFromCopy (&APURegisters, SnapAPURegisters, COUNT (SnapAPURegisters), local_apu_registers); + UnfreezeStructFromCopy (&IAPU.Registers, SnapAPURegisters, COUNT (SnapAPURegisters), local_apu_registers); memcpy (IAPU.RAM, local_apu_ram, 0x10000); UnfreezeStructFromCopy (&SoundData, SnapSoundData, COUNT (SnapSoundData), local_apu_sounddata); } if(local_sa1) { UnfreezeStructFromCopy (&SA1, SnapSA1, COUNT (SnapSA1), local_sa1); - UnfreezeStructFromCopy (&SA1Registers, SnapSA1Registers, COUNT (SnapSA1Registers), local_sa1_registers); + UnfreezeStructFromCopy (&SA1.Registers, SnapSA1Registers, COUNT (SnapSA1Registers), local_sa1_registers); } if(local_spc) { @@ -882,7 +882,7 @@ int S9xUnfreezeFromStream (STREAM stream) if (local_apu) { S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + APURegisters.PC; + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; @@ -921,9 +921,9 @@ int S9xUnfreezeFromStream (STREAM stream) Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]=0xFF; } - ICPU.ShiftedPB = Registers.PB << 16; - ICPU.ShiftedDB = Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); S9xUnpackStatus (); S9xFixCycles (); // S9xReschedule (); // <-- this causes desync when recording or playing movies @@ -1390,15 +1390,15 @@ bool8 S9xUnfreezeZSNES (const char *filename) // 34 bcycpl cycles per scanline // 35 cycphb cyclers per hblank - Registers.A.W = READ_WORD (&t [41]); - Registers.DB = t [43]; - Registers.PB = t [44]; - Registers.S.W = READ_WORD (&t [45]); - Registers.D.W = READ_WORD (&t [47]); - Registers.X.W = READ_WORD (&t [49]); - Registers.Y.W = READ_WORD (&t [51]); - Registers.P.W = READ_WORD (&t [53]); - Registers.PC = READ_WORD (&t [55]); + ICPU.Registers.A.W = READ_WORD (&t [41]); + ICPU.Registers.DB = t [43]; + ICPU.Registers.PB = t [44]; + ICPU.Registers.S.W = READ_WORD (&t [45]); + ICPU.Registers.D.W = READ_WORD (&t [47]); + ICPU.Registers.X.W = READ_WORD (&t [49]); + ICPU.Registers.Y.W = READ_WORD (&t [51]); + ICPU.Registers.P.W = READ_WORD (&t [53]); + ICPU.Registers.PC = READ_WORD (&t [55]); fread ((char*)t, 1, 8, fs); fread ((char*)t, 1, 3019, fs); @@ -1552,12 +1552,12 @@ bool8 S9xUnfreezeZSNES (const char *filename) // SNES SPC700 state and internal ZSNES SPC700 emulation state fread ((char*)t, 1, 304, fs); - APURegisters.PC = READ_DWORD (&t [0]); - APURegisters.YA.B.A = t [4]; - APURegisters.X = t [8]; - APURegisters.YA.B.Y = t [12]; - APURegisters.P = t [16]; - APURegisters.S = t [24]; + IAPU.Registers.PC = READ_DWORD (&t [0]); + IAPU.Registers.YA.B.A = t [4]; + IAPU.Registers.X = t [8]; + IAPU.Registers.YA.B.Y = t [12]; + IAPU.Registers.P = t [16]; + IAPU.Registers.S = t [24]; APU.Cycles = READ_DWORD (&t [32]); APU.ShowROM = (IAPU.RAM [0xf1] & 0x80) != 0; @@ -1606,7 +1606,7 @@ bool8 S9xUnfreezeZSNES (const char *filename) IAPU.RAM [0xf2] = saved; S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + APURegisters.PC; + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; @@ -1642,15 +1642,15 @@ bool8 S9xUnfreezeZSNES (const char *filename) S9xSetSA1 (t [36], 0x2201); S9xSetSA1 (t [41], 0x2209); - SA1Registers.A.W = READ_DWORD (&t [592]); - SA1Registers.X.W = READ_DWORD (&t [596]); - SA1Registers.Y.W = READ_DWORD (&t [600]); - SA1Registers.D.W = READ_DWORD (&t [604]); - SA1Registers.DB = t [608]; - SA1Registers.PB = t [612]; - SA1Registers.S.W = READ_DWORD (&t [616]); - SA1Registers.PC = READ_DWORD (&t [636]); - SA1Registers.P.W = t [620] | (t [624] << 8); + SA1.Registers.A.W = READ_DWORD (&t [592]); + SA1.Registers.X.W = READ_DWORD (&t [596]); + SA1.Registers.Y.W = READ_DWORD (&t [600]); + SA1.Registers.D.W = READ_DWORD (&t [604]); + SA1.Registers.DB = t [608]; + SA1.Registers.PB = t [612]; + SA1.Registers.S.W = READ_DWORD (&t [616]); + SA1.Registers.PC = READ_DWORD (&t [636]); + SA1.Registers.P.W = t [620] | (t [624] << 8); memmove (&Memory.FillRAM [0x3000], t + 692, 2 * 1024); @@ -1806,9 +1806,9 @@ fread(&temp, 1, 4, fs); IPPU.RenderThisFrame = FALSE; S9xFixSoundAfterSnapshotLoad (); - ICPU.ShiftedPB = Registers.PB << 16; - ICPU.ShiftedDB = Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); S9xUnpackStatus (); S9xFixCycles (); S9xReschedule (); diff --git a/source/spc700.cpp b/source/spc700.cpp index 1cd27d3..69ed120 100644 --- a/source/spc700.cpp +++ b/source/spc700.cpp @@ -219,28 +219,28 @@ APUSetZN8 ((uint8) Int16); APUSetZN8 (b); #define Push(b)\ - *(IAPU.RAM + 0x100 + APURegisters.S) = b;\ - APURegisters.S--; + *(IAPU.RAM + 0x100 + IAPU.Registers.S) = b;\ + IAPU.Registers.S--; #define Pop(b)\ - APURegisters.S++;\ - (b) = *(IAPU.RAM + 0x100 + APURegisters.S); + IAPU.Registers.S++;\ + (b) = *(IAPU.RAM + 0x100 + IAPU.Registers.S); #ifdef FAST_LSB_WORD_ACCESS #define PushW(w)\ - *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S) = w;\ - APURegisters.S -= 2; + *(uint16 *) (IAPU.RAM + 0xff + IAPU.Registers.S) = w;\ + IAPU.Registers.S -= 2; #define PopW(w)\ - APURegisters.S += 2;\ - w = *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S); + IAPU.Registers.S += 2;\ + w = *(uint16 *) (IAPU.RAM + 0xff + IAPU.Registers.S); #else #define PushW(w)\ - *(IAPU.RAM + 0xff + APURegisters.S) = w;\ - *(IAPU.RAM + 0x100 + APURegisters.S) = (w >> 8);\ - APURegisters.S -= 2; + *(IAPU.RAM + 0xff + IAPU.Registers.S) = w;\ + *(IAPU.RAM + 0x100 + IAPU.Registers.S) = (w >> 8);\ + IAPU.Registers.S -= 2; #define PopW(w)\ - APURegisters.S += 2; \ - (w) = *(IAPU.RAM + 0xff + APURegisters.S) + (*(IAPU.RAM + 0x100 + APURegisters.S) << 8); + IAPU.Registers.S += 2; \ + (w) = *(IAPU.RAM + 0xff + IAPU.Registers.S) + (*(IAPU.RAM + 0x100 + IAPU.Registers.S) << 8); #endif #define Relative()\ @@ -253,16 +253,16 @@ APUSetZN8 ((uint8) Int16); #ifdef FAST_LSB_WORD_ACCESS #define IndexedXIndirect()\ - IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff)); + IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + IAPU.Registers.X) & 0xff)); #define Absolute()\ IAPU.Address = *(uint16 *) (IAPU.PC + 1); #define AbsoluteX()\ - IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.X; + IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.Registers.X; #define AbsoluteY()\ - IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.YA.B.Y; + IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.Registers.YA.B.Y; #define MemBit()\ IAPU.Address = *(uint16 *) (IAPU.PC + 1);\ @@ -270,19 +270,19 @@ APUSetZN8 ((uint8) Int16); IAPU.Address &= 0x1fff; #define IndirectIndexedY()\ - IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + APURegisters.YA.B.Y; + IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + IAPU.Registers.YA.B.Y; #else #define IndexedXIndirect()\ - IAPU.Address = *(IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff)) + \ - (*(IAPU.DirectPage + ((OP1 + APURegisters.X + 1) & 0xff)) << 8); + IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.Registers.X) & 0xff)) + \ + (*(IAPU.DirectPage + ((OP1 + IAPU.Registers.X + 1) & 0xff)) << 8); #define Absolute()\ IAPU.Address = OP1 + (OP2 << 8); #define AbsoluteX()\ - IAPU.Address = OP1 + (OP2 << 8) + APURegisters.X; + IAPU.Address = OP1 + (OP2 << 8) + IAPU.Registers.X; #define AbsoluteY()\ - IAPU.Address = OP1 + (OP2 << 8) + APURegisters.YA.B.Y; + IAPU.Address = OP1 + (OP2 << 8) + IAPU.Registers.YA.B.Y; #define MemBit()\ IAPU.Address = OP1 + (OP2 << 8);\ @@ -292,7 +292,7 @@ APUSetZN8 ((uint8) Int16); #define IndirectIndexedY()\ IAPU.Address = *(IAPU.DirectPage + OP1) + \ (*(IAPU.DirectPage + OP1 + 1) << 8) + \ - APURegisters.YA.B.Y; + IAPU.Registers.YA.B.Y; #endif void Apu00 () @@ -541,8 +541,8 @@ void ApuF3 () void Apu04 () { // OR A,dp - APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -550,16 +550,16 @@ void Apu05 () { // OR A,abs Absolute (); - APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu06 () { // OR A,(X) - APURegisters.YA.B.A |= S9xAPUGetByteZ (APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -567,16 +567,16 @@ void Apu07 () { // OR A,(dp+X) IndexedXIndirect (); - APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu08 () { // OR A,#00 - APURegisters.YA.B.A |= OP1; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= OP1; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -593,8 +593,8 @@ void Apu09 () void Apu14 () { // OR A,dp+X - APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1 + APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -602,8 +602,8 @@ void Apu15 () { // OR A,abs+X AbsoluteX (); - APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -611,8 +611,8 @@ void Apu16 () { // OR A,abs+Y AbsoluteY (); - APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -620,8 +620,8 @@ void Apu17 () { // OR A,(dp)+Y IndirectIndexedY (); - APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -638,9 +638,9 @@ void Apu18 () void Apu19 () { // OR (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) | S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) | S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, APURegisters.X); + S9xAPUSetByteZ (Work8, IAPU.Registers.X); IAPU.PC++; } @@ -765,16 +765,16 @@ void Apu0C () void Apu1B () { // ASL dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); ASL (Work8); - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu1C () { // ASL A - ASL (APURegisters.YA.B.A); + ASL (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -782,35 +782,35 @@ void Apu0D () { // PUSH PSW S9xAPUPackStatus (); - Push (APURegisters.P); + Push (IAPU.Registers.P); IAPU.PC++; } void Apu2D () { // PUSH A - Push (APURegisters.YA.B.A); + Push (IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu4D () { // PUSH X - Push (APURegisters.X); + Push (IAPU.Registers.X); IAPU.PC++; } void Apu6D () { // PUSH Y - Push (APURegisters.YA.B.Y); + Push (IAPU.Registers.YA.B.Y); IAPU.PC++; } void Apu8E () { // POP PSW - Pop (APURegisters.P); + Pop (IAPU.Registers.P); S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; @@ -822,21 +822,21 @@ void Apu8E () void ApuAE () { // POP A - Pop (APURegisters.YA.B.A); + Pop (IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuCE () { // POP X - Pop (APURegisters.X); + Pop (IAPU.Registers.X); IAPU.PC++; } void ApuEE () { // POP Y - Pop (APURegisters.YA.B.Y); + Pop (IAPU.Registers.YA.B.Y); IAPU.PC++; } @@ -845,8 +845,8 @@ void Apu0E () // TSET1 abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - S9xAPUSetByte (Work8 | APURegisters.YA.B.A, IAPU.Address); - Work8 &= APURegisters.YA.B.A; + S9xAPUSetByte (Work8 | IAPU.Registers.YA.B.A, IAPU.Address); + Work8 &= IAPU.Registers.YA.B.A; APUSetZN8 (Work8); IAPU.PC += 3; } @@ -856,8 +856,8 @@ void Apu4E () // TCLR1 abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - S9xAPUSetByte (Work8 & ~APURegisters.YA.B.A, IAPU.Address); - Work8 &= APURegisters.YA.B.A; + S9xAPUSetByte (Work8 & ~IAPU.Registers.YA.B.A, IAPU.Address); + Work8 &= IAPU.Registers.YA.B.A; APUSetZN8 (Work8); IAPU.PC += 3; } @@ -871,7 +871,7 @@ void Apu0F () #else PushW (IAPU.PC + 1 - IAPU.RAM); S9xAPUPackStatus (); - Push (APURegisters.P); + Push (IAPU.Registers.P); APUSetBreak (); APUClearInterrupt (); // XXX:Where is the BRK vector ??? @@ -1050,7 +1050,7 @@ void Apu5A () { // CMPW YA,dp uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - int32 Int32 = (long) APURegisters.YA.W - (long) Work16; + int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; IAPU._Carry = Int32 >= 0; APUSetZN16 ((uint16) Int32); IAPU.PC += 2; @@ -1072,17 +1072,17 @@ void Apu7A () { // ADDW YA,dp uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - uint32 Work32 = (uint32) APURegisters.YA.W + Work16; + uint32 Work32 = (uint32) IAPU.Registers.YA.W + Work16; IAPU._Carry = Work32 >= 0x10000; - if (~(APURegisters.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) + if (~(IAPU.Registers.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) APUSetOverflow (); else APUClearOverflow (); APUClearHalfCarry (); - if((APURegisters.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) + if((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) APUSetHalfCarry (); - APURegisters.YA.W = (uint16) Work32; - APUSetZN16 (APURegisters.YA.W); + IAPU.Registers.YA.W = (uint16) Work32; + APUSetZN16 (IAPU.Registers.YA.W); IAPU.PC += 2; } @@ -1093,39 +1093,39 @@ void Apu9A () { // SUBW YA,dp uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - int32 Int32 = (long) APURegisters.YA.W - (long) Work16; + int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; APUClearHalfCarry (); IAPU._Carry = Int32 >= 0; - if (((APURegisters.YA.W ^ Work16) & 0x8000) && - ((APURegisters.YA.W ^ (uint16) Int32) & 0x8000)) + if (((IAPU.Registers.YA.W ^ Work16) & 0x8000) && + ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x8000)) APUSetOverflow (); else APUClearOverflow (); - if (((APURegisters.YA.W ^ Work16) & 0x0080) && - ((APURegisters.YA.W ^ (uint16) Int32) & 0x0080)) + if (((IAPU.Registers.YA.W ^ Work16) & 0x0080) && + ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x0080)) APUSetHalfCarry (); APUSetHalfCarry (); - if((APURegisters.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) + if((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) APUClearHalfCarry (); - APURegisters.YA.W = (uint16) Int32; - APUSetZN16 (APURegisters.YA.W); + IAPU.Registers.YA.W = (uint16) Int32; + APUSetZN16 (IAPU.Registers.YA.W); IAPU.PC += 2; } void ApuBA () { // MOVW YA,dp - APURegisters.YA.B.A = S9xAPUGetByteZ (OP1); - APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1 + 1); - APUSetZN16 (APURegisters.YA.W); + IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1); + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1 + 1); + APUSetZN16 (IAPU.Registers.YA.W); IAPU.PC += 2; } void ApuDA () { // MOVW dp,YA - S9xAPUSetByteZ (APURegisters.YA.B.A, OP1); - S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1 + 1); + S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1); + S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1 + 1); IAPU.PC += 2; } @@ -1133,7 +1133,7 @@ void Apu64 () { // CMP A,dp uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1142,15 +1142,15 @@ void Apu65 () // CMP A,abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu66 () { // CMP A,(X) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); - CMP (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } @@ -1159,7 +1159,7 @@ void Apu67 () // CMP A,(dp+X) IndexedXIndirect (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1167,7 +1167,7 @@ void Apu68 () { // CMP A,#00 uint8 Work8 = OP1; - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1183,8 +1183,8 @@ void Apu69 () void Apu74 () { // CMP A, dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); - CMP (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1193,7 +1193,7 @@ void Apu75 () // CMP A,abs+X AbsoluteX (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -1202,7 +1202,7 @@ void Apu76 () // CMP A, abs+Y AbsoluteY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -1211,7 +1211,7 @@ void Apu77 () // CMP A,(dp)+Y IndirectIndexedY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.A, Work8); + CMP (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1227,8 +1227,8 @@ void Apu78 () void Apu79 () { // CMP (X),(Y) - uint8 W1 = S9xAPUGetByteZ (APURegisters.X); - uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); CMP (W1, Work8); IAPU.PC++; } @@ -1238,7 +1238,7 @@ void Apu1E () // CMP X,abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.X, Work8); + CMP (IAPU.Registers.X, Work8); IAPU.PC += 3; } @@ -1246,14 +1246,14 @@ void Apu3E () { // CMP X,dp uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (APURegisters.X, Work8); + CMP (IAPU.Registers.X, Work8); IAPU.PC += 2; } void ApuC8 () { // CMP X,#00 - CMP (APURegisters.X, OP1); + CMP (IAPU.Registers.X, OP1); IAPU.PC += 2; } @@ -1262,7 +1262,7 @@ void Apu5E () // CMP Y,abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (APURegisters.YA.B.Y, Work8); + CMP (IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 3; } @@ -1270,7 +1270,7 @@ void Apu7E () { // CMP Y,dp uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (APURegisters.YA.B.Y, Work8); + CMP (IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 2; } @@ -1278,7 +1278,7 @@ void ApuAD () { // CMP Y,#00 uint8 Work8 = OP1; - CMP (APURegisters.YA.B.Y, Work8); + CMP (IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 2; } @@ -1286,8 +1286,8 @@ void Apu1F () { // JMP (abs+X) Absolute (); - IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + APURegisters.X) + - (S9xAPUGetByte (IAPU.Address + APURegisters.X + 1) << 8); + IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.Registers.X) + + (S9xAPUGetByte (IAPU.Address + IAPU.Registers.X + 1) << 8); // XXX: HERE: // APU.Flags |= TRACE_FLAG; } @@ -1325,8 +1325,8 @@ void ApuE0 () void Apu24 () { // AND A,dp - APURegisters.YA.B.A &= S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1334,16 +1334,16 @@ void Apu25 () { // AND A,abs Absolute (); - APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu26 () { // AND A,(X) - APURegisters.YA.B.A &= S9xAPUGetByteZ (APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -1351,16 +1351,16 @@ void Apu27 () { // AND A,(dp+X) IndexedXIndirect (); - APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu28 () { // AND A,#00 - APURegisters.YA.B.A &= OP1; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= OP1; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1377,8 +1377,8 @@ void Apu29 () void Apu34 () { // AND A,dp+X - APURegisters.YA.B.A &= S9xAPUGetByteZ (OP1 + APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1386,8 +1386,8 @@ void Apu35 () { // AND A,abs+X AbsoluteX (); - APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -1395,8 +1395,8 @@ void Apu36 () { // AND A,abs+Y AbsoluteY (); - APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -1404,8 +1404,8 @@ void Apu37 () { // AND A,(dp)+Y IndirectIndexedY (); - APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1422,9 +1422,9 @@ void Apu38 () void Apu39 () { // AND (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) & S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) & S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, APURegisters.X); + S9xAPUSetByteZ (Work8, IAPU.Registers.X); IAPU.PC++; } @@ -1450,16 +1450,16 @@ void Apu2C () void Apu3B () { // ROL dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); ROL (Work8); - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu3C () { // ROL A - ROL (APURegisters.YA.B.A); + ROL (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -1469,7 +1469,7 @@ void Apu2E () uint8 Work8 = OP1; Relative2 (); - if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A) + if (S9xAPUGetByteZ (Work8) != IAPU.Registers.YA.B.A) { IAPU.PC = IAPU.RAM + (uint16) Int16; APU.Cycles += IAPU.TwoCycles; @@ -1482,10 +1482,10 @@ void Apu2E () void ApuDE () { // CBNE dp+X,rel - uint8 Work8 = OP1 + APURegisters.X; + uint8 Work8 = OP1 + IAPU.Registers.X; Relative2 (); - if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A) + if (S9xAPUGetByteZ (Work8) != IAPU.Registers.YA.B.A) { IAPU.PC = IAPU.RAM + (uint16) Int16; APU.Cycles += IAPU.TwoCycles; @@ -1498,8 +1498,8 @@ void ApuDE () void Apu3D () { // INC X - APURegisters.X++; - APUSetZN8 (APURegisters.X); + IAPU.Registers.X++; + APUSetZN8 (IAPU.Registers.X); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1511,8 +1511,8 @@ void Apu3D () void ApuFC () { // INC Y - APURegisters.YA.B.Y++; - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y++; + APUSetZN8 (IAPU.Registers.YA.B.Y); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1524,8 +1524,8 @@ void ApuFC () void Apu1D () { // DEC X - APURegisters.X--; - APUSetZN8 (APURegisters.X); + IAPU.Registers.X--; + APUSetZN8 (IAPU.Registers.X); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1537,8 +1537,8 @@ void Apu1D () void ApuDC () { // DEC Y - APURegisters.YA.B.Y--; - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y--; + APUSetZN8 (IAPU.Registers.YA.B.Y); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1579,8 +1579,8 @@ void ApuAC () void ApuBB () { // INC dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) + 1; - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X) + 1; + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); APUSetZN8 (Work8); #ifdef SPC700_SHUTDOWN @@ -1593,8 +1593,8 @@ void ApuBB () void ApuBC () { // INC A - APURegisters.YA.B.A++; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A++; + APUSetZN8 (IAPU.Registers.YA.B.A); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1635,8 +1635,8 @@ void Apu8C () void Apu9B () { // DEC dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) - 1; - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X) - 1; + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); APUSetZN8 (Work8); #ifdef SPC700_SHUTDOWN @@ -1649,8 +1649,8 @@ void Apu9B () void Apu9C () { // DEC A - APURegisters.YA.B.A--; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A--; + APUSetZN8 (IAPU.Registers.YA.B.A); #ifdef SPC700_SHUTDOWN IAPU.WaitCounter++; @@ -1662,8 +1662,8 @@ void Apu9C () void Apu44 () { // EOR A,dp - APURegisters.YA.B.A ^= S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1671,16 +1671,16 @@ void Apu45 () { // EOR A,abs Absolute (); - APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu46 () { // EOR A,(X) - APURegisters.YA.B.A ^= S9xAPUGetByteZ (APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -1688,16 +1688,16 @@ void Apu47 () { // EOR A,(dp+X) IndexedXIndirect (); - APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu48 () { // EOR A,#00 - APURegisters.YA.B.A ^= OP1; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= OP1; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1714,8 +1714,8 @@ void Apu49 () void Apu54 () { // EOR A,dp+X - APURegisters.YA.B.A ^= S9xAPUGetByteZ (OP1 + APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1723,8 +1723,8 @@ void Apu55 () { // EOR A,abs+X AbsoluteX (); - APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -1732,8 +1732,8 @@ void Apu56 () { // EOR A,abs+Y AbsoluteY (); - APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -1741,8 +1741,8 @@ void Apu57 () { // EOR A,(dp)+Y IndirectIndexedY (); - APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -1759,9 +1759,9 @@ void Apu58 () void Apu59 () { // EOR (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X) ^ S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) ^ S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, APURegisters.X); + S9xAPUSetByteZ (Work8, IAPU.Registers.X); IAPU.PC++; } @@ -1787,63 +1787,63 @@ void Apu4C () void Apu5B () { // LSR dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); LSR (Work8); - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu5C () { // LSR A - LSR (APURegisters.YA.B.A); + LSR (IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu7D () { // MOV A,X - APURegisters.YA.B.A = APURegisters.X; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = IAPU.Registers.X; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuDD () { // MOV A,Y - APURegisters.YA.B.A = APURegisters.YA.B.Y; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = IAPU.Registers.YA.B.Y; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu5D () { // MOV X,A - APURegisters.X = APURegisters.YA.B.A; - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = IAPU.Registers.YA.B.A; + APUSetZN8 (IAPU.Registers.X); IAPU.PC++; } void ApuFD () { // MOV Y,A - APURegisters.YA.B.Y = APURegisters.YA.B.A; - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y = IAPU.Registers.YA.B.A; + APUSetZN8 (IAPU.Registers.YA.B.Y); IAPU.PC++; } void Apu9D () { //MOV X,SP - APURegisters.X = APURegisters.S; - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = IAPU.Registers.S; + APUSetZN8 (IAPU.Registers.X); IAPU.PC++; } void ApuBD () { // MOV SP,X - APURegisters.S = APURegisters.X; + IAPU.Registers.S = IAPU.Registers.X; IAPU.PC++; } @@ -1869,16 +1869,16 @@ void Apu6C () void Apu7B () { // ROR dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); ROR (Work8); - S9xAPUSetByteZ (Work8, OP1 + APURegisters.X); + S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu7C () { // ROR A - ROR (APURegisters.YA.B.A); + ROR (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -1902,8 +1902,8 @@ void ApuFE () { // DBNZ Y,rel Relative (); - APURegisters.YA.B.Y--; - if (APURegisters.YA.B.Y != 0) + IAPU.Registers.YA.B.Y--; + if (IAPU.Registers.YA.B.Y != 0) { IAPU.PC = IAPU.RAM + (uint16) Int16; APU.Cycles += IAPU.TwoCycles; @@ -1915,25 +1915,25 @@ void ApuFE () void Apu6F () { // RET - PopW (APURegisters.PC); - IAPU.PC = IAPU.RAM + APURegisters.PC; + PopW (IAPU.Registers.PC); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } void Apu7F () { // RETI // STOP ("RETI"); - Pop (APURegisters.P); + Pop (IAPU.Registers.P); S9xAPUUnpackStatus (); - PopW (APURegisters.PC); - IAPU.PC = IAPU.RAM + APURegisters.PC; + PopW (IAPU.Registers.PC); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } void Apu84 () { // ADC A,dp uint8 Work8 = S9xAPUGetByteZ (OP1); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1942,15 +1942,15 @@ void Apu85 () // ADC A, abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu86 () { // ADC A,(X) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); - ADC (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } @@ -1959,7 +1959,7 @@ void Apu87 () // ADC A,(dp+X) IndexedXIndirect (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1967,7 +1967,7 @@ void Apu88 () { // ADC A,#00 uint8 Work8 = OP1; - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1984,8 +1984,8 @@ void Apu89 () void Apu94 () { // ADC A,dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); - ADC (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -1994,7 +1994,7 @@ void Apu95 () // ADC A, abs+X AbsoluteX (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -2003,7 +2003,7 @@ void Apu96 () // ADC A, abs+Y AbsoluteY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -2012,7 +2012,7 @@ void Apu97 () // ADC A, (dp)+Y IndirectIndexedY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (APURegisters.YA.B.A, Work8); + ADC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2029,18 +2029,18 @@ void Apu98 () void Apu99 () { // ADC (X),(Y) - uint8 W1 = S9xAPUGetByteZ (APURegisters.X); - uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); ADC (W1, Work8); - S9xAPUSetByteZ (W1, APURegisters.X); + S9xAPUSetByteZ (W1, IAPU.Registers.X); IAPU.PC++; } void Apu8D () { // MOV Y,#00 - APURegisters.YA.B.Y = OP1; - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y = OP1; + APUSetZN8 (IAPU.Registers.YA.B.Y); IAPU.PC += 2; } @@ -2055,30 +2055,30 @@ void Apu8F () void Apu9E () { // DIV YA,X - if (APURegisters.X == 0) + if (IAPU.Registers.X == 0) { APUSetOverflow (); - APURegisters.YA.B.Y = 0xff; - APURegisters.YA.B.A = 0xff; + IAPU.Registers.YA.B.Y = 0xff; + IAPU.Registers.YA.B.A = 0xff; } else { APUClearOverflow (); - uint8 Work8 = APURegisters.YA.W / APURegisters.X; - APURegisters.YA.B.Y = APURegisters.YA.W % APURegisters.X; - APURegisters.YA.B.A = Work8; + uint8 Work8 = IAPU.Registers.YA.W / IAPU.Registers.X; + IAPU.Registers.YA.B.Y = IAPU.Registers.YA.W % IAPU.Registers.X; + IAPU.Registers.YA.B.A = Work8; } // XXX How should Overflow, Half Carry, Zero and Negative flags be set?? - // APUSetZN16 (APURegisters.YA.W); - APUSetZN8 (APURegisters.YA.B.A); + // APUSetZN16 (IAPU.Registers.YA.W); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu9F () { // XCN A - APURegisters.YA.B.A = (APURegisters.YA.B.A >> 4) | (APURegisters.YA.B.A << 4); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = (IAPU.Registers.YA.B.A >> 4) | (IAPU.Registers.YA.B.A << 4); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -2086,7 +2086,7 @@ void ApuA4 () { // SBC A, dp uint8 Work8 = S9xAPUGetByteZ (OP1); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2095,15 +2095,15 @@ void ApuA5 () // SBC A, abs Absolute (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void ApuA6 () { // SBC A, (X) - uint8 Work8 = S9xAPUGetByteZ (APURegisters.X); - SBC (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } @@ -2112,7 +2112,7 @@ void ApuA7 () // SBC A,(dp+X) IndexedXIndirect (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2120,7 +2120,7 @@ void ApuA8 () { // SBC A,#00 uint8 Work8 = OP1; - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2137,8 +2137,8 @@ void ApuA9 () void ApuB4 () { // SBC A, dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X); - SBC (APURegisters.YA.B.A, Work8); + uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2147,7 +2147,7 @@ void ApuB5 () // SBC A,abs+X AbsoluteX (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -2156,7 +2156,7 @@ void ApuB6 () // SBC A,abs+Y AbsoluteY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } @@ -2165,7 +2165,7 @@ void ApuB7 () // SBC A,(dp)+Y IndirectIndexedY (); uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (APURegisters.YA.B.A, Work8); + SBC (IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } @@ -2182,42 +2182,42 @@ void ApuB8 () void ApuB9 () { // SBC (X),(Y) - uint8 W1 = S9xAPUGetByteZ (APURegisters.X); - uint8 Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y); + uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); SBC (W1, Work8); - S9xAPUSetByteZ (W1, APURegisters.X); + S9xAPUSetByteZ (W1, IAPU.Registers.X); IAPU.PC++; } void ApuAF () { // MOV (X)+, A - S9xAPUSetByteZ (APURegisters.YA.B.A, APURegisters.X++); + S9xAPUSetByteZ (IAPU.Registers.YA.B.A, IAPU.Registers.X++); IAPU.PC++; } void ApuBE () { // DAS - if ((APURegisters.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) + if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) { - APURegisters.YA.B.A -= 6; + IAPU.Registers.YA.B.A -= 6; } - if (APURegisters.YA.B.A > 0x9f || !IAPU._Carry) + if (IAPU.Registers.YA.B.A > 0x9f || !IAPU._Carry) { - APURegisters.YA.B.A -= 0x60; + IAPU.Registers.YA.B.A -= 0x60; APUClearCarry (); } else { APUSetCarry (); } - APUSetZN8 (APURegisters.YA.B.A); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuBF () { // MOV A,(X)+ - APURegisters.YA.B.A = S9xAPUGetByteZ (APURegisters.X++); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByteZ (IAPU.Registers.X++); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -2238,7 +2238,7 @@ void ApuA0 () void ApuC4 () { // MOV dp,A - S9xAPUSetByteZ (APURegisters.YA.B.A, OP1); + S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1); IAPU.PC += 2; } @@ -2246,14 +2246,14 @@ void ApuC5 () { // MOV abs,A Absolute (); - S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } void ApuC6 () { // MOV (X), A - S9xAPUSetByteZ (APURegisters.YA.B.A, APURegisters.X); + S9xAPUSetByteZ (IAPU.Registers.YA.B.A, IAPU.Registers.X); IAPU.PC++; } @@ -2261,7 +2261,7 @@ void ApuC7 () { // MOV (dp+X),A IndexedXIndirect (); - S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 2; } @@ -2269,14 +2269,14 @@ void ApuC9 () { // MOV abs,X Absolute (); - S9xAPUSetByte (APURegisters.X, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.X, IAPU.Address); IAPU.PC += 3; } void ApuCB () { // MOV dp,Y - S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1); + S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1); IAPU.PC += 2; } @@ -2284,30 +2284,30 @@ void ApuCC () { // MOV abs,Y Absolute (); - S9xAPUSetByte (APURegisters.YA.B.Y, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.Y, IAPU.Address); IAPU.PC += 3; } void ApuCD () { // MOV X,#00 - APURegisters.X = OP1; - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = OP1; + APUSetZN8 (IAPU.Registers.X); IAPU.PC += 2; } void ApuCF () { // MUL YA - APURegisters.YA.W = (uint16) APURegisters.YA.B.A * APURegisters.YA.B.Y; - APUSetZN16 (APURegisters.YA.W); + IAPU.Registers.YA.W = (uint16) IAPU.Registers.YA.B.A * IAPU.Registers.YA.B.Y; + APUSetZN16 (IAPU.Registers.YA.W); IAPU.PC++; } void ApuD4 () { // MOV dp+X, A - S9xAPUSetByteZ (APURegisters.YA.B.A, OP1 + APURegisters.X); + S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1 + IAPU.Registers.X); IAPU.PC += 2; } @@ -2315,7 +2315,7 @@ void ApuD5 () { // MOV abs+X,A AbsoluteX (); - S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } @@ -2323,7 +2323,7 @@ void ApuD6 () { // MOV abs+Y,A AbsoluteY (); - S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } @@ -2331,56 +2331,56 @@ void ApuD7 () { // MOV (dp)+Y,A IndirectIndexedY (); - S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address); + S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 2; } void ApuD8 () { // MOV dp,X - S9xAPUSetByteZ (APURegisters.X, OP1); + S9xAPUSetByteZ (IAPU.Registers.X, OP1); IAPU.PC += 2; } void ApuD9 () { // MOV dp+Y,X - S9xAPUSetByteZ (APURegisters.X, OP1 + APURegisters.YA.B.Y); + S9xAPUSetByteZ (IAPU.Registers.X, OP1 + IAPU.Registers.YA.B.Y); IAPU.PC += 2; } void ApuDB () { // MOV dp+X,Y - S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1 + APURegisters.X); + S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void ApuDF () { // DAA - if ((APURegisters.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) + if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) { - if(APURegisters.YA.B.A > 0xf0) APUSetCarry (); - APURegisters.YA.B.A += 6; + if(IAPU.Registers.YA.B.A > 0xf0) APUSetCarry (); + IAPU.Registers.YA.B.A += 6; //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc... } //else { APUClearHalfCarry (); } ditto as above - if (APURegisters.YA.B.A > 0x9f || IAPU._Carry) + if (IAPU.Registers.YA.B.A > 0x9f || IAPU._Carry) { - APURegisters.YA.B.A += 0x60; + IAPU.Registers.YA.B.A += 0x60; APUSetCarry (); } else { APUClearCarry (); } - APUSetZN8 (APURegisters.YA.B.A); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuE4 () { // MOV A, dp - APURegisters.YA.B.A = S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -2388,16 +2388,16 @@ void ApuE5 () { // MOV A,abs Absolute (); - APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } void ApuE6 () { // MOV A,(X) - APURegisters.YA.B.A = S9xAPUGetByteZ (APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByteZ (IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC++; } @@ -2405,16 +2405,16 @@ void ApuE7 () { // MOV A,(dp+X) IndexedXIndirect (); - APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuE8 () { // MOV A,#00 - APURegisters.YA.B.A = OP1; - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = OP1; + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -2422,16 +2422,16 @@ void ApuE9 () { // MOV X, abs Absolute (); - APURegisters.X = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.X); IAPU.PC += 3; } void ApuEB () { // MOV Y,dp - APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.YA.B.Y); IAPU.PC += 2; } @@ -2439,16 +2439,16 @@ void ApuEC () { // MOV Y,abs Absolute (); - APURegisters.YA.B.Y = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.Y); IAPU.PC += 3; } void ApuF4 () { // MOV A, dp+X - APURegisters.YA.B.A = S9xAPUGetByteZ (OP1 + APURegisters.X); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } @@ -2456,8 +2456,8 @@ void ApuF5 () { // MOV A, abs+X AbsoluteX (); - APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -2465,8 +2465,8 @@ void ApuF6 () { // MOV A, abs+Y AbsoluteY (); - APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 3; } @@ -2474,24 +2474,24 @@ void ApuF7 () { // MOV A, (dp)+Y IndirectIndexedY (); - APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (APURegisters.YA.B.A); + IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuF8 () { // MOV X,dp - APURegisters.X = S9xAPUGetByteZ (OP1); - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.Registers.X); IAPU.PC += 2; } void ApuF9 () { // MOV X,dp+Y - APURegisters.X = S9xAPUGetByteZ (OP1 + APURegisters.YA.B.Y); - APUSetZN8 (APURegisters.X); + IAPU.Registers.X = S9xAPUGetByteZ (OP1 + IAPU.Registers.YA.B.Y); + APUSetZN8 (IAPU.Registers.X); IAPU.PC += 2; } @@ -2505,8 +2505,8 @@ void ApuFA () void ApuFB () { // MOV Y,dp+X - APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1 + APURegisters.X); - APUSetZN8 (APURegisters.YA.B.Y); + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); + APUSetZN8 (IAPU.Registers.YA.B.Y); IAPU.PC += 2; } diff --git a/source/spc700.h b/source/spc700.h index 3d09fee..abb413e 100644 --- a/source/spc700.h +++ b/source/spc700.h @@ -107,29 +107,29 @@ #define APUClearCarry() (IAPU._Carry = 0) #define APUSetCarry() (IAPU._Carry = 1) -#define APUSetInterrupt() (APURegisters.P |= Interrupt) -#define APUClearInterrupt() (APURegisters.P &= ~Interrupt) -#define APUSetHalfCarry() (APURegisters.P |= HalfCarry) -#define APUClearHalfCarry() (APURegisters.P &= ~HalfCarry) -#define APUSetBreak() (APURegisters.P |= BreakFlag) -#define APUClearBreak() (APURegisters.P &= ~BreakFlag) -#define APUSetDirectPage() (APURegisters.P |= DirectPageFlag) -#define APUClearDirectPage() (APURegisters.P &= ~DirectPageFlag) +#define APUSetInterrupt() (IAPU.Registers.P |= Interrupt) +#define APUClearInterrupt() (IAPU.Registers.P &= ~Interrupt) +#define APUSetHalfCarry() (IAPU.Registers.P |= HalfCarry) +#define APUClearHalfCarry() (IAPU.Registers.P &= ~HalfCarry) +#define APUSetBreak() (IAPU.Registers.P |= BreakFlag) +#define APUClearBreak() (IAPU.Registers.P &= ~BreakFlag) +#define APUSetDirectPage() (IAPU.Registers.P |= DirectPageFlag) +#define APUClearDirectPage() (IAPU.Registers.P &= ~DirectPageFlag) #define APUSetOverflow() (IAPU._Overflow = 1) #define APUClearOverflow() (IAPU._Overflow = 0) #define APUCheckZero() (IAPU._Zero == 0) #define APUCheckCarry() (IAPU._Carry) -#define APUCheckInterrupt() (APURegisters.P & Interrupt) -#define APUCheckHalfCarry() (APURegisters.P & HalfCarry) -#define APUCheckBreak() (APURegisters.P & BreakFlag) -#define APUCheckDirectPage() (APURegisters.P & DirectPageFlag) +#define APUCheckInterrupt() (IAPU.Registers.P & Interrupt) +#define APUCheckHalfCarry() (IAPU.Registers.P & HalfCarry) +#define APUCheckBreak() (IAPU.Registers.P & BreakFlag) +#define APUCheckDirectPage() (IAPU.Registers.P & DirectPageFlag) #define APUCheckOverflow() (IAPU._Overflow) #define APUCheckNegative() (IAPU._Zero & 0x80) -#define APUClearFlags(f) (APURegisters.P &= ~(f)) -#define APUSetFlags(f) (APURegisters.P |= (f)) -#define APUCheckFlag(f) (APURegisters.P & (f)) +#define APUClearFlags(f) (IAPU.Registers.P &= ~(f)) +#define APUSetFlags(f) (IAPU.Registers.P |= (f)) +#define APUCheckFlag(f) (IAPU.Registers.P & (f)) typedef union { @@ -149,8 +149,6 @@ struct SAPURegisters{ uint16 PC; }; -EXTERN_C struct SAPURegisters APURegisters; - // Needed by ILLUSION OF GAIA //#define ONE_APU_CYCLE 14 #define ONE_APU_CYCLE 21 -- cgit v1.2.3 From 0f60f047f5146c76a73c8a299b4405929bf3909f Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Wed, 26 Dec 2012 15:40:35 -0500 Subject: Add the update methods for the upper and lower screen into defines. --- source/nds/entry.cpp | 6 +++--- source/nds/gui.c | 48 ++++++++++++++++++++++++------------------------ source/nds/gui.h | 6 +++++- 3 files changed, 32 insertions(+), 28 deletions(-) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index a8e2217..9d0f0bc 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -175,7 +175,7 @@ bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/) break; } - ds2_flipScreen(UP_SCREEN, 0); + ds2_flipScreen(UP_SCREEN, UP_SCREEN_UPDATE_METHOD); // A problem with update method 1 (wait, double buffer) means that, after // about 15 minutes of play time, the screen starts to half-redraw every // frame. With update method 0, this is mitigated. (Method 2 is too slow.) @@ -586,9 +586,9 @@ int sfc_main (int argc, char **argv) { if (!Settings.Paused #ifdef DEBUGGER - || (CPU.Flags & (DEBUG_MODE_FLAG | SINGLE_STEP_FLAG)) + || (CPU.Flags & (DEBUG_MODE_FLAG | SINGLE_STEP_FLAG) #endif - ) + ) S9xMainLoop (); diff --git a/source/nds/gui.c b/source/nds/gui.c index 3438f62..9aa16bb 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1114,7 +1114,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) } redraw = 0; - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); } //end if(0 != redraw) else if(0 != redraw) { unsigned int m, n; @@ -1142,7 +1142,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) } draw_hscroll(m+1, redraw); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); redraw = 0; } @@ -1162,7 +1162,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) { if(draw_hscroll(0, 1) <= 1) path_scroll = 0x8000; //scroll left } - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); } mdelay(50); //about 50ms @@ -1176,7 +1176,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name) manage_filelist_info(&filelist_info, -1); ds2_clearScreen(DOWN_SCREEN, COLOR_BLACK); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); return return_value; } @@ -1233,7 +1233,7 @@ u32 play_screen_snapshot(void) { draw_message(down_screen_addr, screenp, 28, 31, 227, 165, color_bg); draw_string_vcenter(down_screen_addr, 36, 55, 190, COLOR_MSSG, msg[MSG_NO_SLIDE]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); if(screenp) free((void*)screenp); //construct filelist_info struct @@ -1260,7 +1260,7 @@ u32 play_screen_snapshot(void) draw_string_vcenter(down_screen_addr, 36, 115, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE4]); draw_string_vcenter(down_screen_addr, 36, 130, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE5]); draw_string_vcenter(down_screen_addr, 36, 145, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE6]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); repeat= 1; i= 0; @@ -1749,7 +1749,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); ds2_setCPUclocklevel(13); int load_result = load_gamepak(&line_buffer); @@ -1817,7 +1817,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); ds2_setCPUclocklevel(13); int load_result = load_gamepak(args[1]); @@ -2047,7 +2047,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, NULL, 28, 31, 227, 165, 0); draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_SAVESTATE_DOING]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); int flag = save_state(tmp_filename, (void*)screen); //clear message @@ -2063,7 +2063,7 @@ u32 menu(u16 *screen) savestate_index = slot_index; } - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); //save game config reorder_latest_file(); @@ -2100,7 +2100,7 @@ u32 menu(u16 *screen) { draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_SAVESTATE_FILE_BAD]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); wait_Allkey_release(0); if(gui_action == CURSOR_SELECT) @@ -2186,7 +2186,7 @@ u32 menu(u16 *screen) { draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_DELETTE_SAVESTATE_NOTHING]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); mdelay(500); } } @@ -2207,7 +2207,7 @@ u32 menu(u16 *screen) else { draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_DELETTE_SAVESTATE_NOTHING]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); mdelay(500); } } @@ -2578,18 +2578,18 @@ u32 menu(u16 *screen) if(!first_load) { draw_string_vcenter(down_screen_addr, 36, 70, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); if(save_ss_bmp(screen)) draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT_COMPLETE]); else draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT_FAILURE]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); mdelay(500); } else { draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVESTATE_SLOT_EMPTY]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); mdelay(500); } } @@ -2746,7 +2746,7 @@ u32 menu(u16 *screen) wait_Allkey_release(0); draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_DEFAULT_LOADING]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); sprintf(line_buffer, "%s/%s", main_path, EMU_CONFIG_FILENAME); remove(line_buffer); @@ -2777,7 +2777,7 @@ u32 menu(u16 *screen) draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_EMU_VERSION0]); sprintf(line_buffer, "%s %s", msg[MSG_EMU_VERSION1], NDSSFC_VERSION); draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, line_buffer); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); wait_Anykey_press(0); } @@ -2797,7 +2797,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color); draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE]); draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE_WAITING]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); load_language_msg(LANGUAGE_PACK, emu_config.language); gui_change_icon(emu_config.language); @@ -3405,7 +3405,7 @@ u32 menu(u16 *screen) draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, 0); draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); if(gamepak_name[0] != 0) { @@ -3977,7 +3977,7 @@ u32 menu(u16 *screen) break; } // end swith - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); } // end while destroy_dynamic_cheats(); if(bg_screenp != NULL) free((void*)bg_screenp); @@ -3996,7 +3996,7 @@ u32 menu(u16 *screen) ds2_clearScreen(DOWN_SCREEN, 0); ds2_flipScreen(DOWN_SCREEN, 1); copy_screen(up_screen_addr, (void*) screen, 0, 0, 256, 192); - ds2_flipScreen(UP_SCREEN, 0); + ds2_flipScreen(UP_SCREEN, UP_SCREEN_UPDATE_METHOD); ds2_setBacklight(2); wait_Allkey_release(0); @@ -4714,7 +4714,7 @@ void gui_init(u32 lang_id) } show_log(down_screen_addr); - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); flag = icon_init(lang_id); if(0 != flag) @@ -4750,7 +4750,7 @@ void gui_init(u32 lang_id) return; gui_init_err: - ds2_flipScreen(DOWN_SCREEN, 2); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); wait_Anykey_press(0); quit(); } diff --git a/source/nds/gui.h b/source/nds/gui.h index 3b222d1..9ebaf26 100644 --- a/source/nds/gui.h +++ b/source/nds/gui.h @@ -24,6 +24,9 @@ #include "fs_api.h" #include "gcheat.h" +#define UP_SCREEN_UPDATE_METHOD 0 +#define DOWN_SCREEN_UPDATE_METHOD 2 + #define MAX_GAMEPAD_MAP 16 #ifdef __cplusplus @@ -96,7 +99,8 @@ extern char rom_path[MAX_PATH]; extern u32 game_enable_audio; /****************************************************************************** - ******************************************************************************/ extern char g_default_rom_dir[MAX_PATH]; + ******************************************************************************/ +extern char g_default_rom_dir[MAX_PATH]; extern char DEFAULT_RTS_DIR[MAX_PATH]; extern char DEFAULT_CFG_DIR[MAX_PATH]; extern char DEFAULT_SS_DIR[MAX_PATH]; -- cgit v1.2.3 From 6b36e79013d4c9273a96a9783a2bccdb516f174a Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 27 Dec 2012 18:02:03 -0500 Subject: Speed up rendering by an unknown amount. gfx.cpp, others: Avoid always checking for Settings.SixteenBit if FOREVER_16_BIT is defined. port.h: Define FOREVER_16_BIT below PIXEL_FORMAT. --- source/gfx.cpp | 148 ++++++++++++++++----- source/globals.cpp | 1 - source/nds/entry.cpp | 6 + source/port.h | 4 + source/ppu.cpp | 369 ++++++++++++--------------------------------------- source/snes9x.h | 2 + source/tile.cpp | 90 +++++++------ 7 files changed, 256 insertions(+), 364 deletions(-) (limited to 'source') diff --git a/source/gfx.cpp b/source/gfx.cpp index 16d006e..5e6c650 100644 --- a/source/gfx.cpp +++ b/source/gfx.cpp @@ -167,6 +167,7 @@ extern uint8 Mode7Depths [2]; #define BLACK BUILD_PIXEL(0,0,0) +#ifndef FOREVER_16_BIT void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount); void DrawClippedTile (uint32 Tile, uint32 Offset, @@ -185,6 +186,7 @@ void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset, void DrawLargePixel (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount); +#endif void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount); @@ -365,7 +367,9 @@ bool8 S9xGraphicsInit () GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; GFX.ZPitch = GFX.Pitch; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) +#endif GFX.ZPitch >>= 1; GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; @@ -374,13 +378,17 @@ bool8 S9xGraphicsInit () PPU.BG_Forced = 0; IPPU.OBJChanged = TRUE; +#ifndef FOREVER_16_BIT if (Settings.Transparency) Settings.SixteenBit = TRUE; +#endif IPPU.DirectColourMapsNeedRebuild = TRUE; GFX.PixSize = 1; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif DrawTilePtr = DrawTile16; DrawClippedTilePtr = DrawClippedTile16; DrawLargePixelPtr = DrawLargePixel16; @@ -388,6 +396,7 @@ bool8 S9xGraphicsInit () DrawHiResClippedTilePtr = DrawClippedTile16; GFX.PPL = GFX.Pitch >> 1; GFX.PPLx2 = GFX.Pitch; +#ifndef FOREVER_16_BIT } else { @@ -399,10 +408,13 @@ bool8 S9xGraphicsInit () GFX.PPL = GFX.Pitch; GFX.PPLx2 = GFX.Pitch * 2; } +#endif S9xFixColourBrightness (); +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) return (FALSE); @@ -549,6 +561,7 @@ bool8 S9xGraphicsInit () } } } +#ifndef FOREVER_16_BIT } else { @@ -556,6 +569,7 @@ bool8 S9xGraphicsInit () GFX.ZERO_OR_X2 = NULL; GFX.ZERO = NULL; } +#endif return (TRUE); } @@ -634,20 +648,28 @@ void S9xStartScreenRefresh () IPPU.DoubleHeightPixels = TRUE; GFX.Pitch2 = GFX.RealPitch; GFX.Pitch = GFX.RealPitch * 2; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) +#endif GFX.PPL = GFX.PPLx2 = GFX.RealPitch; +#ifndef FOREVER_16_BIT else GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1; +#endif } else { IPPU.RenderedScreenHeight = PPU.ScreenHeight; GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; IPPU.DoubleHeightPixels = FALSE; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) +#endif GFX.PPL = GFX.Pitch >> 1; +#ifndef FOREVER_16_BIT else GFX.PPL = GFX.Pitch; +#endif GFX.PPLx2 = GFX.PPL << 1; } } @@ -661,7 +683,9 @@ void S9xStartScreenRefresh () GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 1; GFX.ZPitch = GFX.RealPitch; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) +#endif GFX.ZPitch >>= 1; } } @@ -731,9 +755,10 @@ void S9xEndScreenRefresh () FLUSH_REDRAW (); if (IPPU.ColorsChanged) { - uint32 saved = PPU.CGDATA[0]; + uint32 saved = PPU.CGDATA[0]; +#ifndef FOREVER_16_BIT if (!Settings.SixteenBit) - { + { // Hack for Super Mario World - to get its sky blue // (It uses Fixed colour addition on the backdrop colour) if (!(Memory.FillRAM [0x2131] & 0x80) && (Memory.FillRAM[0x2131] & 0x20) && @@ -742,7 +767,8 @@ void S9xEndScreenRefresh () PPU.CGDATA[0] = PPU.FixedColourRed | (PPU.FixedColourGreen << 5) | (PPU.FixedColourBlue << 10); } - } + } +#endif IPPU.ColorsChanged = FALSE; PPU.CGDATA[0] = saved; } @@ -768,7 +794,12 @@ void S9xEndScreenRefresh () } #endif S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, - Settings.SixteenBit); +#ifndef FOREVER_16_BIT + Settings.SixteenBit +#else + TRUE +#endif + ); } S9xApplyCheats (); @@ -1083,7 +1114,7 @@ void S9xSetupOBJ () IPPU.OBJChanged = FALSE; } -void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0) +static void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0) { #ifdef MK_DEBUG_RTO if(Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY); @@ -1158,45 +1189,56 @@ if(Settings.BGLayering) { OnMain = FALSE; GFX.PixSize = 2; if (IPPU.DoubleHeightPixels) - { +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif DrawTilePtr = DrawTile16x2x2; DrawClippedTilePtr = DrawClippedTile16x2x2; +#ifndef FOREVER_16_BIT } else { DrawTilePtr = DrawTilex2x2; DrawClippedTilePtr = DrawClippedTilex2x2; } +#endif } else { +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif DrawTilePtr = DrawTile16x2; DrawClippedTilePtr = DrawClippedTile16x2; +#ifndef FOREVER_16_BIT } else { DrawTilePtr = DrawTilex2; DrawClippedTilePtr = DrawClippedTilex2; } +#endif } } else { +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif DrawTilePtr = DrawTile16; DrawClippedTilePtr = DrawClippedTile16; +#ifndef FOREVER_16_BIT } else { DrawTilePtr = DrawTile; DrawClippedTilePtr = DrawClippedTile; } +#endif } } GFX.Z1 = D + 2; @@ -1294,7 +1336,7 @@ if(Settings.BGLayering) { #endif } -void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +static void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) { CHECK_SOUND(); @@ -1522,7 +1564,7 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) } } -void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +static void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) { CHECK_SOUND(); @@ -1859,7 +1901,7 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) } } -void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) +static void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) { CHECK_SOUND(); @@ -2190,7 +2232,7 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) } -void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) { GFX.PixSize = 1; @@ -2687,17 +2729,17 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) } \ } -void DrawBGMode7Background (uint8 *Screen, int bg) +static void DrawBGMode7Background (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask)) } -void DrawBGMode7Background16 (uint8 *Screen, int bg) +static void DrawBGMode7Background16 (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]); } -void DrawBGMode7Background16Add (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -2708,7 +2750,7 @@ void DrawBGMode7Background16Add (uint8 *Screen, int bg) GFX.ScreenColors [b & GFX.Mode7Mask]); } -void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -2719,7 +2761,7 @@ void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) GFX.ScreenColors [b & GFX.Mode7Mask]); } -void DrawBGMode7Background16Sub (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -2730,7 +2772,7 @@ void DrawBGMode7Background16Sub (uint8 *Screen, int bg) GFX.ScreenColors [b & GFX.Mode7Mask]); } -void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -3123,12 +3165,12 @@ STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) return x+y; } -void DrawBGMode7Background16_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16_i (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7_i (uint16, theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); } -void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -3139,7 +3181,7 @@ void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); } -void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -3150,7 +3192,7 @@ void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); } -void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -3161,7 +3203,7 @@ void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); } -void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg) { RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? @@ -3206,7 +3248,7 @@ TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \ HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ ~TWO_LOW_BITS_MASK ) >> 2); -void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) +static void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) { bool8 BG0; bool8 BG1; @@ -3236,9 +3278,10 @@ void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) } sub |= force_no_add; - - if (PPU.BGMode <= 1) - { + + switch (PPU.BGMode) { + case 0: + case 1: if (OB) { SelectTileRenderer (sub || !SUB_OR_ADD(4)); @@ -3265,9 +3308,12 @@ void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) SelectTileRenderer (sub || !SUB_OR_ADD(3)); DrawBackground (PPU.BGMode, 3, D + 2, D + 5); } - } - else if (PPU.BGMode != 7) - { + break; + case 2: + case 3: + case 4: + case 5: + case 6: if (OB) { SelectTileRenderer (sub || !SUB_OR_ADD(4)); @@ -3278,14 +3324,13 @@ void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) SelectTileRenderer (sub || !SUB_OR_ADD(0)); DrawBackground (PPU.BGMode, 0, D + 5, D + 13); } - if (PPU.BGMode != 6 && BG1) + if (BG1 && PPU.BGMode != 6) { SelectTileRenderer (sub || !SUB_OR_ADD(1)); DrawBackground (PPU.BGMode, 1, D + 2, D + 9); } - } - else - { + break; + case 7: if (OB) { SelectTileRenderer (sub || !SUB_OR_ADD(4)); @@ -3356,7 +3401,10 @@ void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) } } } - } + break; + default: + break; + } } #include "font.h" @@ -3365,8 +3413,10 @@ void DisplayChar (uint8 *Screen, uint8 c) { int line = (((c & 0x7f) - 32) >> 4) * font_height; int offset = (((c & 0x7f) - 32) & 15) * font_width; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif int h, w; uint16 *s = (uint16 *) Screen; for (h = 0; h < font_height; h++, line++, @@ -3396,6 +3446,7 @@ void DisplayChar (uint8 *Screen, uint8 c) *s = BLACK; } } +#ifndef FOREVER_16_BIT } else { @@ -3416,6 +3467,7 @@ void DisplayChar (uint8 *Screen, uint8 c) } } } +#endif } static void S9xDisplayFrameRate () @@ -3432,8 +3484,12 @@ static void S9xDisplayFrameRate () for (i = 0; i < len; i++) { DisplayChar (Screen, string [i]); +#ifndef FOREVER_16_BIT Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : (font_width - 1); +#else + Screen += (font_width - 1) * sizeof (uint16); +#endif } } @@ -3450,9 +3506,13 @@ static void S9xDisplayString (const char *string) { if (char_count >= max_chars || string [i] < 32) { +#ifndef FOREVER_16_BIT Screen -= Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) * max_chars : (font_width - 1) * max_chars; +#else + Screen -= (font_width - 1) * max_chars * sizeof (uint16); +#endif Screen += font_height * GFX.Pitch; if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight) break; @@ -3461,8 +3521,12 @@ static void S9xDisplayString (const char *string) if (string [i] < 32) continue; DisplayChar (Screen, string [i]); +#ifndef FOREVER_16_BIT Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : (font_width - 1); +#else + Screen += (font_width - 1) * sizeof (uint16); +#endif } } @@ -3528,8 +3592,10 @@ void S9xUpdateScreen () { // The game has switched from lo-res to hi-res mode part way down // the screen. Scale any existing lo-res pixels on screen +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif for (register uint32 y = 0; y < starty; y++) { register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; @@ -3538,6 +3604,7 @@ void S9xUpdateScreen () for (register int x = 255; x >= 0; x--, p--, q -= 2) *q = *(q + 1) = *p; } +#ifndef FOREVER_16_BIT } else { @@ -3549,6 +3616,7 @@ void S9xUpdateScreen () *q = *(q + 1) = *p; } } +#endif IPPU.DoubleWidthPixels = TRUE; } // BJ: And we have to change the height if Interlace gets set, @@ -3561,10 +3629,14 @@ void S9xUpdateScreen () IPPU.DoubleHeightPixels = TRUE; GFX.Pitch2 = GFX.RealPitch; GFX.Pitch = GFX.RealPitch * 2; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) +#endif GFX.PPL = GFX.PPLx2 = GFX.RealPitch; +#ifndef FOREVER_16_BIT else GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1; +#endif // The game has switched from non-interlaced to interlaced mode // part way down the screen. Scale everything. @@ -3582,7 +3654,11 @@ void S9xUpdateScreen () uint32 black = BLACK | (BLACK << 16); - if (Settings.Transparency && Settings.SixteenBit) + if (Settings.Transparency +#ifndef FOREVER_16_BIT + && Settings.SixteenBit +#endif + ) { if (GFX.Pseudo) { @@ -3993,8 +4069,10 @@ void S9xUpdateScreen () { // Mixure of background modes used on screen - scale width // of all non-mode 5 and 6 pixels. +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif for (register uint32 y = starty; y <= endy; y++) { register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; @@ -4002,6 +4080,7 @@ void S9xUpdateScreen () for (register int x = 255; x >= 0; x--, p--, q -= 2) *q = *(q + 1) = *p; } +#ifndef FOREVER_16_BIT } else { @@ -4013,6 +4092,7 @@ void S9xUpdateScreen () *q = *(q + 1) = *p; } } +#endif } // Double the height of the pixels just drawn diff --git a/source/globals.cpp b/source/globals.cpp index adb9ab4..c804318 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -228,7 +228,6 @@ uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0; uint32 current_graphic_format = RGB565; #endif -uint8 GetBank = 0; struct SCheatData Cheat; volatile SoundStatus so; diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 9d0f0bc..1589c21 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -384,7 +384,9 @@ void init_sfc_setting(void) Settings.ControllerOption = SNES_JOYPAD; Settings.Transparency = TRUE; +#ifndef FOREVER_16_BIT Settings.SixteenBit = TRUE; +#endif Settings.SupportHiRes = FALSE; Settings.ThreadSound = FALSE; @@ -792,6 +794,7 @@ bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size) void S9xGenerateSound () { +#if 0 int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far; @@ -853,10 +856,12 @@ void S9xGenerateSound () S9xProcessSound (0); pending_signal = FALSE; } +#endif } void S9xProcessSound (unsigned int) { +#if 0 unsigned short *audiobuff; if (!Settings.APUEnabled || so.mute_sound ) @@ -957,6 +962,7 @@ void S9xProcessSound (unsigned int) } so.samples_mixed_so_far -= sample_count; +#endif } void Init_Timer (void) diff --git a/source/port.h b/source/port.h index ac241b6..5b94d06 100644 --- a/source/port.h +++ b/source/port.h @@ -112,6 +112,10 @@ /* #define PIXEL_FORMAT RGB565 */ #define PIXEL_FORMAT BGR555 +#define FOREVER_16_BIT +// The above is used to disable the 16-bit graphics mode checks sprinkled +// throughout the code, if the pixel format is always 16-bit. + // #define GFX_MULTI_FORMAT #if defined(TARGET_OS_MAC) && TARGET_OS_MAC diff --git a/source/ppu.cpp b/source/ppu.cpp index 5c7d690..def55e9 100644 --- a/source/ppu.cpp +++ b/source/ppu.cpp @@ -204,8 +204,10 @@ void S9xUpdateHTimer () void S9xFixColourBrightness () { IPPU.XB = mul_brightness [PPU.Brightness]; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif for (int i = 0; i < 256; i++) { IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f]; @@ -214,7 +216,9 @@ void S9xFixColourBrightness () IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.Red [i], IPPU.Green [i], IPPU.Blue [i]); } +#ifndef FOREVER_16_BIT } +#endif } /******************************************************************************/ @@ -472,8 +476,6 @@ void S9xSetPPU (uint8 Byte, uint16 Address) PPU.VMA.Increment = 32; break; case 2: - PPU.VMA.Increment = 128; - break; case 3: PPU.VMA.Increment = 128; break; @@ -882,28 +884,20 @@ void S9xSetPPU (uint8 Byte, uint16 Address) case 0x2135: case 0x2136: // Matrix 16bit x 8bit multiply result (read-only) - return; - case 0x2137: // Software latch for horizontal and vertical timers (read-only) - return; case 0x2138: // OAM read data (read-only) - return; case 0x2139: case 0x213a: // VRAM read data (read-only) - return; case 0x213b: // CG-RAM read data (read-only) - return; case 0x213c: case 0x213d: // Horizontal and vertical (low/high) read counter (read-only) - return; case 0x213e: // PPU status (time over and range over) - return; case 0x213f: // NTSC/PAL select and field (read-only) return; @@ -969,7 +963,7 @@ void S9xSetPPU (uint8 Byte, uint16 Address) if (Address == 0x2801 && Settings.SRTC) S9xSetSRTC (Byte, Address); else - if (Address < 0x3000 || Address >= 0x3000 + 768) + if (Address < 0x3000 || Address >= 0x3300) { #ifdef DEBUGGER missing.unknownppu_write = Address; @@ -1010,39 +1004,27 @@ void S9xSetPPU (uint8 Byte, uint16 Address) break; case 0x3031: - Memory.FillRAM [Address] = Byte; - break; case 0x3033: + case 0x3037: + case 0x3039: + case 0x303a: + case 0x303f: Memory.FillRAM [Address] = Byte; break; case 0x3034: - Memory.FillRAM [Address] = Byte & 0x7f; - break; case 0x3036: Memory.FillRAM [Address] = Byte & 0x7f; break; - case 0x3037: - Memory.FillRAM [Address] = Byte; - break; case 0x3038: Memory.FillRAM [Address] = Byte; fx_dirtySCBR(); break; - case 0x3039: - Memory.FillRAM [Address] = Byte; - break; - case 0x303a: - Memory.FillRAM [Address] = Byte; - break; case 0x303b: break; case 0x303c: Memory.FillRAM [Address] = Byte; fx_updateRamBank(Byte); break; - case 0x303f: - Memory.FillRAM [Address] = Byte; - break; case 0x301f: Memory.FillRAM [Address] = Byte; Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G; @@ -1185,6 +1167,16 @@ uint8 S9xGetPPU (uint16 Address) case 0x2121: case 0x2122: case 0x2123: + case 0x2127: + case 0x212b: + case 0x212c: + case 0x212d: + case 0x212e: + case 0x212f: + case 0x2130: + case 0x2131: + case 0x2132: + case 0x2133: #ifndef NO_OPEN_BUS return OpenBus; #else @@ -1194,19 +1186,6 @@ uint8 S9xGetPPU (uint16 Address) case 0x2124: case 0x2125: case 0x2126: -#ifndef NO_OPEN_BUS - return PPU.OpenBus1; -#else - return 0; // Arbitrarily chosen value [Neb] -#endif - - case 0x2127: -#ifndef NO_OPEN_BUS - return OpenBus; -#else - return 0; // Arbitrarily chosen value [Neb] -#endif - case 0x2128: case 0x2129: case 0x212a: @@ -1216,21 +1195,6 @@ uint8 S9xGetPPU (uint16 Address) return 0; // Arbitrarily chosen value [Neb] #endif - case 0x212b: - case 0x212c: - case 0x212d: - case 0x212e: - case 0x212f: - case 0x2130: - case 0x2131: - case 0x2132: - case 0x2133: -#ifndef NO_OPEN_BUS - return OpenBus; -#else - return 0; // Arbitrarily chosen value [Neb] -#endif - case 0x2134: case 0x2135: case 0x2136: @@ -1528,13 +1492,11 @@ uint8 S9xGetPPU (uint16 Address) { case 0: case 1: + case 3: CPU.BranchSkip = TRUE; break; case 2: break; - case 3: - CPU.BranchSkip = TRUE; - break; } if ((Address & 3) < 2) { @@ -1567,12 +1529,6 @@ uint8 S9xGetPPU (uint16 Address) case 0x2181: case 0x2182: case 0x2183: -#ifndef NO_OPEN_BUS - return OpenBus; -#else - return 0; // Arbitrarily chosen value [Neb] -#endif - default: #ifndef NO_OPEN_BUS return OpenBus; @@ -1938,7 +1894,6 @@ void S9xSetCPU (uint8 byte, uint16 Address) case 0x4216: case 0x4217: // Multiply product (read-only) - return; case 0x4218: case 0x4219: case 0x421a: @@ -2382,7 +2337,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4217: // Multiplcation result (for multiply) or remainder of // divison. - return (Memory.FillRAM[Address]); case 0x4218: case 0x4219: case 0x421a: @@ -2392,7 +2346,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x421e: case 0x421f: // Joypads 1-4 button and direction state. - return (Memory.FillRAM [Address]); case 0x4300: case 0x4310: @@ -2403,7 +2356,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4360: case 0x4370: // DMA direction, address type, fixed flag, - return (Memory.FillRAM[Address]); case 0x4301: case 0x4311: @@ -2413,7 +2365,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4351: case 0x4361: case 0x4371: - return (Memory.FillRAM[Address]); case 0x4302: case 0x4312: @@ -2423,7 +2374,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4352: case 0x4362: case 0x4372: - return (Memory.FillRAM[Address]); case 0x4303: case 0x4313: @@ -2433,7 +2383,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4353: case 0x4363: case 0x4373: - return (Memory.FillRAM[Address]); case 0x4304: case 0x4314: @@ -2443,7 +2392,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4354: case 0x4364: case 0x4374: - return (Memory.FillRAM[Address]); case 0x4305: case 0x4315: @@ -2453,7 +2401,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4355: case 0x4365: case 0x4375: - return (Memory.FillRAM[Address]); case 0x4306: case 0x4316: @@ -2463,17 +2410,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4356: case 0x4366: case 0x4376: - return (Memory.FillRAM[Address]); - - case 0x4307: - case 0x4317: - case 0x4327: - case 0x4337: - case 0x4347: - case 0x4357: - case 0x4367: - case 0x4377: - return (DMA[(Address >> 4) & 7].IndirectBank); case 0x4308: case 0x4318: @@ -2483,7 +2419,6 @@ uint8 S9xGetCPU (uint16 Address) case 0x4358: case 0x4368: case 0x4378: - return (Memory.FillRAM[Address]); case 0x4309: case 0x4319: @@ -2495,6 +2430,16 @@ uint8 S9xGetCPU (uint16 Address) case 0x4379: return (Memory.FillRAM[Address]); + case 0x4307: + case 0x4317: + case 0x4327: + case 0x4337: + case 0x4347: + case 0x4357: + case 0x4367: + case 0x4377: + return (DMA[(Address >> 4) & 7].IndirectBank); + case 0x430A: case 0x431A: case 0x432A: @@ -2562,7 +2507,7 @@ uint8 S9xGetCPU (uint16 Address) // return (Memory.FillRAM[Address]); } -void S9xResetPPU () +static void CommonPPUReset () { PPU.BGMode = 0; PPU.BG3Priority = 0; @@ -2570,6 +2515,7 @@ void S9xResetPPU () PPU.VMA.High = 0; PPU.VMA.Increment = 1; PPU.VMA.Address = 0; + PPU.VMA.FullGraphicCount = 0; PPU.VMA.Shift = 0; @@ -2593,13 +2539,11 @@ void S9xResetPPU () PPU.ClipCounts[4] = 0; PPU.ClipCounts[5] = 0; PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; - PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; - PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; - PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; - PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; + PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; + PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; PPU.CGFLIP = 0; - int c; + uint16 c; for (c = 0; c < 256; c++) { IPPU.Red [c] = (c & 7) << 2; @@ -2644,9 +2588,6 @@ void S9xResetPPU () PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; PPU.CentreX = PPU.CentreY = 0; - PPU.Joypad1ButtonReadPos = 0; - PPU.Joypad2ButtonReadPos = 0; - PPU.Joypad3ButtonReadPos = 0; PPU.CGADD = 0; PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; @@ -2668,9 +2609,9 @@ void S9xResetPPU () PPU.VTimerEnabled = FALSE; PPU.HTimerEnabled = FALSE; PPU.HTimerPosition = Settings.H_Max + 1; + PPU.Mosaic = 0; - PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE; - PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; + PPU.BGMosaic [0] = PPU.BGMosaic [1] = PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; PPU.Mode7HFlip = FALSE; PPU.Mode7VFlip = FALSE; PPU.Mode7Repeat = 0; @@ -2679,6 +2620,7 @@ void S9xResetPPU () PPU.Window2Left = 1; PPU.Window2Right = 0; PPU.RecomputeClipWindows = TRUE; + PPU.CGFLIPRead = 0; PPU.Need16x8Mulitply = FALSE; PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; @@ -2696,6 +2638,7 @@ void S9xResetPPU () IPPU.DisplayedRenderedFrameCount = 0; IPPU.SkippedFrames = 0; IPPU.FrameSkip = 0; + ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); @@ -2711,16 +2654,11 @@ void S9xResetPPU () IPPU.RenderedScreenWidth = SNES_WIDTH; IPPU.RenderedScreenHeight = SNES_HEIGHT; IPPU.XB = NULL; + for (c = 0; c < 256; c++) IPPU.ScreenColors [c] = c; S9xFixColourBrightness (); IPPU.PreviousLine = IPPU.CurrentLine = 0; - IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; - IPPU.Joypads[3] = IPPU.Joypads[4] = 0; - IPPU.SuperScope = 0; - IPPU.Mouse[0] = IPPU.Mouse[1] = 0; - IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; - IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; if (Settings.ControllerOption == 0) IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; @@ -2736,7 +2674,31 @@ void S9xResetPPU () S9xProcessMouse (0); S9xProcessMouse (1); } - for (c = 0; c < 0x8000; c += 0x100) + + ZeroMemory (&Memory.FillRAM [0x2100], 0x100); + ZeroMemory (&Memory.FillRAM [0x4200], 0x100); + ZeroMemory (&Memory.FillRAM [0x4000], 0x100); + // For BS Suttehakkun 2... + ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); + + Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF; +} + +void S9xResetPPU () +{ + CommonPPUReset (); + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + + IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; + IPPU.Joypads[3] = IPPU.Joypads[4] = 0; + IPPU.SuperScope = 0; + IPPU.Mouse[0] = IPPU.Mouse[1] = 0; + IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; + IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; + + for (uint16 c = 0; c < 0x8000; c += 0x100) { if ( !Settings.SuperFX ) { @@ -2750,168 +2712,15 @@ void S9xResetPPU () memset (&Memory.FillRAM [c], c >> 8, 0x100); } } - - ZeroMemory (&Memory.FillRAM [0x2100], 0x100); - ZeroMemory (&Memory.FillRAM [0x4200], 0x100); - ZeroMemory (&Memory.FillRAM [0x4000], 0x100); - // For BS Suttehakkun 2... - ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); - - Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF; } void S9xSoftResetPPU () { - PPU.BGMode = 0; - PPU.BG3Priority = 0; - PPU.Brightness = 0; - PPU.VMA.High = 0; - PPU.VMA.Increment = 1; - PPU.VMA.Address = 0; - PPU.VMA.FullGraphicCount = 0; - PPU.VMA.Shift = 0; - - for (uint8 B = 0; B != 4; B++) - { - PPU.BG[B].SCBase = 0; - PPU.BG[B].VOffset = 0; - PPU.BG[B].HOffset = 0; - PPU.BG[B].BGSize = 0; - PPU.BG[B].NameBase = 0; - PPU.BG[B].SCSize = 0; - - PPU.ClipCounts[B] = 0; - PPU.ClipWindowOverlapLogic [B] = CLIP_OR; - PPU.ClipWindow1Enable[B] = FALSE; - PPU.ClipWindow2Enable[B] = FALSE; - PPU.ClipWindow1Inside[B] = TRUE; - PPU.ClipWindow2Inside[B] = TRUE; - } - - PPU.ClipCounts[4] = 0; - PPU.ClipCounts[5] = 0; - PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; - PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; - PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; - PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; - PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; - - PPU.CGFLIP = 0; - int c; - for (c = 0; c < 256; c++) - { - IPPU.Red [c] = (c & 7) << 2; - IPPU.Green [c] = ((c >> 3) & 7) << 2; - IPPU.Blue [c] = ((c >> 6) & 2) << 3; - PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) | - (IPPU.Blue [c] << 10); - } - - PPU.FirstSprite = 0; - PPU.LastSprite = 127; - for (int Sprite = 0; Sprite < 128; Sprite++) - { - PPU.OBJ[Sprite].HPos = 0; - PPU.OBJ[Sprite].VPos = 0; - PPU.OBJ[Sprite].VFlip = 0; - PPU.OBJ[Sprite].HFlip = 0; - PPU.OBJ[Sprite].Priority = 0; - PPU.OBJ[Sprite].Palette = 0; - PPU.OBJ[Sprite].Name = 0; - PPU.OBJ[Sprite].Size = 0; - } - PPU.OAMPriorityRotation = 0; - PPU.OAMWriteRegister = 0; - PPU.RangeTimeOver = 0; -#ifndef NO_OPEN_BUS - PPU.OpenBus1 = 0; - PPU.OpenBus2 = 0; -#endif - - PPU.OAMFlip = 0; - PPU.OAMTileAddress = 0; - PPU.OAMAddr = 0; - PPU.IRQVBeamPos = 0; - PPU.IRQHBeamPos = 0; - PPU.VBeamPosLatched = 0; - PPU.HBeamPosLatched = 0; - - PPU.HBeamFlip = 0; - PPU.VBeamFlip = 0; - PPU.HVBeamCounterLatched = 0; - - PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; - PPU.CentreX = PPU.CentreY = 0; + CommonPPUReset (); // PPU.Joypad1ButtonReadPos = 0; // PPU.Joypad2ButtonReadPos = 0; // PPU.Joypad3ButtonReadPos = 0; - PPU.CGADD = 0; - PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; - PPU.SavedOAMAddr = 0; - PPU.ScreenHeight = SNES_HEIGHT; - PPU.WRAM = 0; - PPU.BG_Forced = 0; - PPU.ForcedBlanking = TRUE; - PPU.OBJThroughMain = FALSE; - PPU.OBJThroughSub = FALSE; - PPU.OBJSizeSelect = 0; - PPU.OBJNameSelect = 0; - PPU.OBJNameBase = 0; - PPU.OBJAddition = FALSE; - PPU.OAMReadFlip = 0; - PPU.BGnxOFSbyte = 0; - ZeroMemory (PPU.OAMData, 512 + 32); - - PPU.VTimerEnabled = FALSE; - PPU.HTimerEnabled = FALSE; - PPU.HTimerPosition = Settings.H_Max + 1; - PPU.Mosaic = 0; - PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE; - PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; - PPU.Mode7HFlip = FALSE; - PPU.Mode7VFlip = FALSE; - PPU.Mode7Repeat = 0; - PPU.Window1Left = 1; - PPU.Window1Right = 0; - PPU.Window2Left = 1; - PPU.Window2Right = 0; - PPU.RecomputeClipWindows = TRUE; - PPU.CGFLIPRead = 0; - PPU.Need16x8Mulitply = FALSE; - PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; - IPPU.ColorsChanged = TRUE; - IPPU.HDMA = 0; - IPPU.HDMAStarted = FALSE; - IPPU.MaxBrightness = 0; - IPPU.LatchedBlanking = 0; - IPPU.OBJChanged = TRUE; - IPPU.RenderThisFrame = TRUE; - IPPU.DirectColourMapsNeedRebuild = TRUE; - IPPU.FrameCount = 0; - IPPU.RenderedFramesCount = 0; - IPPU.DisplayedRenderedFrameCount = 0; - IPPU.SkippedFrames = 0; - IPPU.FrameSkip = 0; - ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); -#ifdef CORRECT_VRAM_READS - IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? -#else - IPPU.FirstVRAMRead = FALSE; -#endif - IPPU.Interlace = FALSE; - IPPU.InterlaceSprites = FALSE; - IPPU.DoubleWidthPixels = FALSE; - IPPU.DoubleHeightPixels = FALSE; - IPPU.RenderedScreenWidth = SNES_WIDTH; - IPPU.RenderedScreenHeight = SNES_HEIGHT; - IPPU.XB = NULL; - for (c = 0; c < 256; c++) - IPPU.ScreenColors [c] = c; - S9xFixColourBrightness (); - IPPU.PreviousLine = IPPU.CurrentLine = 0; // IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; // IPPU.Joypads[3] = IPPU.Joypads[4] = 0; // IPPU.SuperScope = 0; @@ -2919,30 +2728,8 @@ void S9xSoftResetPPU () // IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; // IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; - if (Settings.ControllerOption == 0) - IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; - else - IPPU.Controller = Settings.ControllerOption - 1; - S9xNextController (); - - for (c = 0; c < 2; c++) - memset (&IPPU.Clip [c], 0, sizeof (struct ClipData)); - - if (Settings.MouseMaster) - { - S9xProcessMouse (0); - S9xProcessMouse (1); - } - for (c = 0; c < 0x8000; c += 0x100) + for (uint16 c = 0; c < 0x8000; c += 0x100) memset (&Memory.FillRAM [c], c >> 8, 0x100); - - ZeroMemory (&Memory.FillRAM [0x2100], 0x100); - ZeroMemory (&Memory.FillRAM [0x4200], 0x100); - ZeroMemory (&Memory.FillRAM [0x4000], 0x100); - // For BS Suttehakkun 2... - ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); - - Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF; } void S9xProcessMouse (int which1) @@ -3494,7 +3281,7 @@ printf ("%06x: %d\n", t, FxEmulate (2000000)); uint8 REGISTER_4212() { - GetBank = 0; + uint8 GetBank = 0; if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) GetBank = 1; @@ -3508,8 +3295,8 @@ uint8 REGISTER_4212() void FLUSH_REDRAW () { - if (IPPU.PreviousLine != IPPU.CurrentLine) - S9xUpdateScreen (); + if (IPPU.PreviousLine != IPPU.CurrentLine) + S9xUpdateScreen (); } void REGISTER_2104 (uint8 byte) @@ -3728,19 +3515,25 @@ void REGISTER_2122(uint8 Byte) { if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) { +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) - FLUSH_REDRAW (); +#endif + FLUSH_REDRAW (); PPU.CGDATA[PPU.CGADD] &= 0x00FF; PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; IPPU.ColorsChanged = TRUE; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], IPPU.Green [PPU.CGADD], IPPU.Blue [PPU.CGADD]); +#ifndef FOREVER_16_BIT } +#endif } PPU.CGADD++; } @@ -3748,19 +3541,25 @@ void REGISTER_2122(uint8 Byte) { if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) { +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) - FLUSH_REDRAW (); +#endif + FLUSH_REDRAW (); PPU.CGDATA[PPU.CGADD] &= 0x7F00; PPU.CGDATA[PPU.CGADD] |= Byte; IPPU.ColorsChanged = TRUE; +#ifndef FOREVER_16_BIT if (Settings.SixteenBit) { +#endif IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], IPPU.Green [PPU.CGADD], IPPU.Blue [PPU.CGADD]); +#ifndef FOREVER_16_BIT } +#endif } } PPU.CGFLIP ^= 1; diff --git a/source/snes9x.h b/source/snes9x.h index 61281aa..e9ed479 100644 --- a/source/snes9x.h +++ b/source/snes9x.h @@ -342,7 +342,9 @@ struct SSettings{ bool8 FixFrequency; /* Graphics options */ +#ifndef FOREVER_16_BIT bool8 SixteenBit; +#endif bool8 Transparency; bool8 SupportHiRes; bool8 Mode7Interpolate; diff --git a/source/tile.cpp b/source/tile.cpp index d4cdcbf..7e996a9 100644 --- a/source/tile.cpp +++ b/source/tile.cpp @@ -97,7 +97,7 @@ extern uint32 HeadMask [4]; extern uint32 TailMask [5]; -uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) +static uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) { register uint8 *tp = &Memory.VRAM[TileAddr]; uint32 *p = (uint32 *) pCache; @@ -215,8 +215,10 @@ uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) } return (non_zero ? TRUE : BLANK_TILE); } +#define PLOT_PIXEL(screen, pixel) (pixel) -void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) +#ifndef FOREVER_16_BIT +static void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -236,7 +238,7 @@ void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -256,7 +258,7 @@ void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -276,7 +278,7 @@ void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -296,7 +298,7 @@ void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -318,7 +320,7 @@ void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) { uint8 Pixel; uint8 *Screen = GFX.S + Offset; @@ -412,14 +414,14 @@ void DrawLargePixel (uint32 Tile, uint32 Offset, register uint8 *sp = GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; uint8 pixel; -#define PLOT_PIXEL(screen, pixel) (pixel) RENDER_TILE_LARGE (((uint8) GFX.ScreenColors [pixel]), PLOT_PIXEL) } +#endif -void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -437,9 +439,9 @@ void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -457,9 +459,9 @@ void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -477,9 +479,9 @@ void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -497,9 +499,9 @@ void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -519,9 +521,9 @@ void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.DB + Offset; @@ -614,9 +616,9 @@ void DrawLargePixel16 (uint32 Tile, uint32 Offset, RENDER_TILE_LARGE (GFX.ScreenColors [pixel], PLOT_PIXEL) } -void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -646,9 +648,9 @@ void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -678,9 +680,9 @@ void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -710,9 +712,9 @@ void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -742,9 +744,9 @@ void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -774,9 +776,9 @@ void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -806,9 +808,9 @@ void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -838,9 +840,9 @@ void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -951,9 +953,9 @@ void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) } -void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -977,9 +979,9 @@ void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -1003,9 +1005,9 @@ void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; @@ -1029,9 +1031,9 @@ void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) #undef FN } -void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels) +static void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels) { - uint32 Pixel; + uint8 Pixel; uint16 *Screen = (uint16 *) GFX.S + Offset; uint8 *Depth = GFX.ZBuffer + Offset; uint8 *SubDepth = GFX.SubZBuffer + Offset; -- cgit v1.2.3 From 963c3459e51264ccf0cc501a41e45de6e71eeea3 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 27 Dec 2012 18:10:31 -0500 Subject: Accidentally committed the previous revision with sound functions emptied. --- source/nds/entry.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 1589c21..b4467a1 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -794,7 +794,6 @@ bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size) void S9xGenerateSound () { -#if 0 int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far; @@ -856,12 +855,10 @@ void S9xGenerateSound () S9xProcessSound (0); pending_signal = FALSE; } -#endif } void S9xProcessSound (unsigned int) { -#if 0 unsigned short *audiobuff; if (!Settings.APUEnabled || so.mute_sound ) @@ -962,7 +959,6 @@ void S9xProcessSound (unsigned int) } so.samples_mixed_so_far -= sample_count; -#endif } void Init_Timer (void) -- cgit v1.2.3 From c8935c352c119025d130e8146c276845828075dd Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 27 Dec 2012 18:46:37 -0500 Subject: Make cleanly without -DCPU_SHUTDOWN. --- source/cpuops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/cpuops.cpp b/source/cpuops.cpp index 4ddcb6b..b01bce5 100644 --- a/source/cpuops.cpp +++ b/source/cpuops.cpp @@ -3822,9 +3822,9 @@ static void OpCB (void) { #ifndef SA1_OPCODES CPU.Cycles += TWO_CYCLES; -#endif #endif } +#endif } #endif // SA1_OPCODES } -- cgit v1.2.3 From 09b5fdb86139e6356ddd0dcb80fb9f16d9b94640 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 27 Dec 2012 18:51:20 -0500 Subject: Revert "Switch to the more complete Snes9x 1.53 documentation." It doesn't match the version used in NDSSFC, and I failed to port to 1.53 anyway. This reverts commit 2b23b5cbaf15bccc2aae0ff3ee91cedd26f101bd. --- source/doc/porting.txt | 725 ++++++++++++ source/docs/changes.txt | 2459 --------------------------------------- source/docs/control-inputs.txt | 68 -- source/docs/controls.txt | 97 -- source/docs/gpl-2.0.txt | 339 ------ source/docs/lgpl-2.1.txt | 504 -------- source/docs/porting.html | 371 ------ source/docs/portsofsnes9x.txt | 118 -- source/docs/snapshots.txt | 84 -- source/docs/snes9x-license.txt | 174 --- source/docs/snes9x.conf.default | 238 ---- 11 files changed, 725 insertions(+), 4452 deletions(-) create mode 100644 source/doc/porting.txt delete mode 100644 source/docs/changes.txt delete mode 100644 source/docs/control-inputs.txt delete mode 100644 source/docs/controls.txt delete mode 100644 source/docs/gpl-2.0.txt delete mode 100644 source/docs/lgpl-2.1.txt delete mode 100644 source/docs/porting.html delete mode 100644 source/docs/portsofsnes9x.txt delete mode 100644 source/docs/snapshots.txt delete mode 100644 source/docs/snes9x-license.txt delete mode 100644 source/docs/snes9x.conf.default (limited to 'source') diff --git a/source/doc/porting.txt b/source/doc/porting.txt new file mode 100644 index 0000000..3d28eec --- /dev/null +++ b/source/doc/porting.txt @@ -0,0 +1,725 @@ + How to Port Snes9x to a New Platform + ==================================== + +Version: 1.01 +Date: 23-December-1998 + +(c) Copyright 1998 Gary Henderson (gary@daniver.demon.co.uk) + +Introduction +============ + +This is brief description of the steps involved in porting Snes9x, the Super +Nintendo Entertainment System emulator, to new hardware which is at least +similar to Workstation or PC. It describes what code you have to write and +what functions exist that you can make use of. It also gives some insights as +to how Snes9x actually works, although that will be subject of another +document yet to be written. + +Host System Requirements +======================== + +A C++ compiler, so you can compile the emulator! Snes9x really isn't written +in C++, it just uses the C++ compiler as a 'better C' compiler to get inline +functions and so on. With some modification, it could be converted to be +compiled with an ordinary C compiler. Snes9x isn't very C type safe and +will probably not work on a system who's integers are less than 32-bits wide +without lots of editing. + +If the host system uses a CPU that implements the i386 instruction set then +you will also want to use the three assembler CPU cores, although I recently +scrapped the SPC700 assembler code (too many bugs) and replaced it with +compiler generated assembler code that I haven't got around to optimising +yet. The 65c816 and SPC700 code needs to be assembled using the GNU +assembler that comes with gcc and the Super FX code assembled with NASM +v0.97 or higher. gcc is available from lots of sites. NASM is available from +http://www.cryogen.com/Nasm + +A fast CPU. SNES emulation is very compute intensive: two, or sometimes three +CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor +with real-time sample decompression, filter and echo effects, two custom +graphics processor chips that can produce transparency, scaling, rotation +and window effects in 32768 colors, and finally hardware DMA all take their +toll on the host CPU. + +Lots of RAM. The SNES itself has 128k work RAM, 64k V-RAM and 64k sound CPU +RAM. If a Super FX game is being emulated, that usually comes with another +64k inside the game pack. Snes9x itself needs 4Mb to load SNES ROM images +into (or 6Mb if I ever figure out the SNES memory map of the 48Mbit ROM +images out there), 256k to cache decompressed sound samples in, 512k to +cache converted SNES tiles in, and another 64k for S-RAM emulation. And +that's not counting a few large lookup tables that the graphics code needs +for speeding up transparency effects plus few other tables used by the ZSNES +Super FX code. It all adds up to 7Mb (ish). Add to that RAM needed to +store the actual emulator code and RAM required by the host operating system +and any other process that is running; that's lots of RAM. Well, it is if +your host system only has a few mega-bytes of RAM available. + +An 8-bit, 256 color (one byte per pixel) or deeper display, at least 256x239 +pixels in resolution, or 512x478 if you're going to support the SNES' +hi-res. background screen modes. Ideally, a 16-bit, 65536 color screen mode +is required if you want to support transparency at speed, as that is what the +code renders internally. Any other format screen, with transparency enabled, +will require picture format conversion before you can place the rendered +SNES image on to the screen. + +Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound +data to the host computer's sound hardware. The DOS port uses interrupts +from the sound card to know when more sound data is required, most other +ports have to periodically poll the host sound hardware to see if more data +is required; if it is then the SNES sound mixing code provided by Snes9x is +called to fill an area of system memory with ready mixed SNES sound data, +which then can be passed on to the host sound hardware. Sound data is +generated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for +16-bit data. Stereo sound data generates twice as many samples, with each +channel's samples interleaved, first left's then right's. + +For the user to be able to control and play SNES games, some form of input +device is required, a joystick or keyboard, for example. The real SNES can +have 2 eight-button digital joy-pads connected to it or 5 joy-pads when an +optional multi-player adaptor was purchased, although most games only require +a single joy-pad. Access to all eight buttons and the direction pad, of +course, are usually required by most games. Snes9x does emulate the +multi-player adaptor hardware, if you were wondering, but its still up to +you to provide the emulation of the individual joy-pads. + +The SNES also had a mouse and light gun available as optional extras, +Snes9x can emulate both of these using some form of pointing device, +usually the host system's mouse. + +If an accurate, constant SNES play rate is required, then a real-time timer +will be needed that can time intervals of 16.7ms (NTSC frame time) or 20ms +(PAL frame time). + +Some SNES game packs contained a small amount of extra RAM and a battery so +ROMs could save a player's progress through a game for games that takes many +hours to play from start to finish. Snes9x simulates this S-RAM by saving +the contents of the area of memory normally occupied by the S-RAM into file +then automatically restoring it again the next time the user plays the same +game. If the hardware you're porting to doesn't have a hard disk available +then you could be in trouble. + +Snes9x also implements freeze-game files which can record the state of the +SNES hardware and RAM at a particular point in time and can restore it to +that exact state at a later date - the result is that users can save a game +at any point, not just at save-game or password points provided by the +original game coders. Each freeze file is over 400k in size. To help save +disk space, Snes9x can be compiled with zlib, which is used to compress the +freeze files, reducing the size to typically below 100k. Download zlib from +its homepage at http://www.cdrom.com/pub/infozip/zlib/, compile Snes9x with +ZLIB defined and link with zlib. zlib is also used to load any compressed +ROM images Snes9x my encounter, compressed with gzip or compress. + +Porting +======= + +In theory you will only need to edit port.h, then in a separate file write +all the initialisation code and interface routines that Snes9x expects the +you to implement. You, no doubt, will discover otherwise.... + +There are several compile-time only options available: + +DEBUGGER +-------- + +Enables extra code to assist me in debugging SNES ROMs. The debugger has only +ever been a quick-hack by me and user-interface to debugger facilities is +virtually non-existent. Most of the debugger information is output via +stdout and enabling the compile-time options slows the whole emulator down +slightly. However, the debugger options available are very powerful; you +could use it to help get your port working. You probably still want to ship +the finished version with the debugger disabled, it will only confuse +non-technical users. + +VAR_CYCLES +---------- + +I recommend you define this. The main CPU in the SNES actually varies in +speed depending on what area of memory its accessing and the ROM access +speed of the game pack; defining VAR_CYCLES causes Snes9x to emulate this, +using a good approximation, rather than fixed cycle length as ZSNES does. The +resultant code is slightly slower. Leaving it undefined results in many more +emulation timing errors appearing while playing games. + +CPU_SHUTDOWN and SPC700_SHUTDOWN +-------------------------------- + +Again I recommend defining both of these. They are both speed up hacks. +When defined, Snes9x starts watching for when either the main or sound CPUs +are in simply loops waiting for a known event to happen - like the end of +the current scan-line, and interrupt or a sound timer to reach a particular +value. If Snes9x spots either CPU in such a loop it uses its insider +knowledge to simply skip the emulation of that CPU's instructions until the +event happens. It can be a big win with lots of SNES games. + +I'm constantly amazed at the ingenuity of some programmers who are able to +produce complex code to do simple things: some ROM's wait loops are so +complex Snes9x fails to spot the CPU is in such a loop and the shutdown +speed up hacks don't work. + +You might be wondering why VAR_CYCLES, and the two SHUTDOWN options have to +be enabled with defines, well, in the past they sometimes introduced +problems with some ROMs, so I kept them as options. I think I've fixed all +the problems now, but you never know... + +SPC700_C +-------- + +Define this if you are using the C/C++ version of the SPC700 CPU core. It +enables a ROM compatibility feature that executes SPC700 instructions during +SNES DMA, it allows several games to start that would otherwise lock up and +fixes music pauses when ROMs do lots of DMA, usually when switching between +game screens. + +ZLIB +---- + +Define this if you have the zlib library available and you want it to +compress freeze-game files to save disk space. The library is also used to +support compressed ROM images. + +NO_INLINE_SET_GET +----------------- + +Define this to stop several of the memory access routines from being +defined in-line. Whether the C++ compiler actually in-lines when this symbol +is not defined is up to the compiler itself. In-lines functions can speed up +the C++ CPU emulations on some architectures at the cost of increased code +size. Try fiddling with this option once you've got port working to see if +it helps the speed of your port. + +EXECUTE_SUPERFX_PER_LINE and ZSNES_FX +------------------------------------- + +Define these if you're going to be using the ZSNES Super FX i386 assembler +code, otherwise leave them both undefined. In theory, +EXECUTE_SUPERFX_PER_LINE can also be defined when using the C++ Super FX +emulation code, but the code is still buggy and enabling the option +introduces more problems than it fixes. Any takers for fixing the C++ code? + +JOYSTICK_SUPPORT, SIDEWINDER_SUPPORT and GRIP_SUPPORT +----------------------------------------------------- + +These options enable support for various input devices in the UNIX and MS-DOS +port code. They're only of interest if you're able to use the existing UNIX +or MS-DOS port specific code. + +port.h +====== + +If the byte ordering of the target system is least significant byte first, +make sure LSB_FIRST is defined in this header, otherwise, make sure its not +defined. + +If you're going to support 16-bit screen rendering (required if you want +transparency effects) and your system doesn't use RGB 565 - 5 bits for red, +6 bits for green and 5 bits for blue - then you'll need make sure RGB555, +BGR565 or BGR555 is defined instead. You might want to take a look at the +*_LOW_BIT_MASKs, *_HI_BIT_MASKs and BUILD_PIXEL macros to make sure they're +correct, because I've only every tested the RGB565 version, though the Mac +port uses the RGB555 option. If your system is 24 or 32-bit only, then +don't define anything; instead write a conversion routine that will take a +complete rendered 16-bit SNES screen in RGB565 format and convert to the +format required to be displayed on your hardware. + +port.h also typedefs some types, uint8 for an unsigned, 8-bit quantity, +uint16 for an unsigned, 16-bit quantity, uint32 for a 32-bit, unsigned +quantity and bool8 for a true/false type. Signed versions are also +typedef'ed. + +The CHECK_SOUND macro can be defined to invoke some code that polls the +host system's sound hardware to see if it can accept any more sound data. +Snes9x makes calls to this macro several times when it is rendering the SNES +screen, during large SNES DMAs and after every emulated CPU instruction. + +Since this CHECK_SOUND macro is invoked often, the code should only take a +very small amount of time to execute or it will slow down the emulator's +performance. The Linux and UNIX ports use a system timer and set a variable +when it has expired; the CHECK_SOUND only has to check to see if the +variable is set. On the MS-DOS and Mac ports, the sound hardware is not +polled at all, instead it is driven by interrupts or callbacks and the +CHECK_SOUND macro is defined to be empty. + +Initialisation Code +------------------- + +This is what the Linux, UNIX and MS-DOS ports do, I suspect your code +might be similar: + +- The Settings structure is initialised to some sensible default values - + check the main function in unix.cpp for the values it uses. + +- The command line is parsed, options specified override default values in + the Settings structure and specify a ROM image filename that the user + wants loaded. Your port could load user preferences from a file or some + other source at this point. Most values, with a little care, can be changed + via a GUI once the emulator is running. + +- Some Settings structure value validation takes place, for example if + transparency effects are requested the code also makes sure 16-bit + screen rendering is turned on as well. + +- Memory.Init() and S9xInitAPU() are called, checking neither failed. The + only reason they would fail is if memory allocation failed. + +- Memory.LoadROM (filename) is called to load the specified ROM image into + memory. If that worked Memory.LoadSRAM (sram_filename) is called to load + the ROM's S-RAM file, if one exists. The all current ports base the + sram_filename on the filename of the ROM image, changing the file's + extension (the .smc or whatever bit) and changing the directory where its + located - you won't be able to save S-RAM files onto a CD if that's where + the ROM image is located! + + If your port has a GUI, you can delay this step until the user picks an + image to load. + + SNES roms images come in all shapes and sizes, some with headers, some + without, some have been mangled by the copier device in one of two ways, and + some split into several pieces; plus the SNES itself has several different + memory map models. The code tries to auto-detect all these various types, + but sometimes the SNES ROM header information has been manually edited by + someone at some stage and the code guesses wrong. To help it out it these + situations, the Settings structure contains several options to force a + particular ROM image format; these values must be initialised prior to each + call to Memory.LoadROM(filename). + +- The Linux and UNIX ports now do some more operating system initialisation + ready for a system timer to be started. + +- The host display hardware is now initialised. The actual screen depth and + resolution should be picked based on the user preferences if possible. + The X Window System port can't control the screen depth or resolution, if + the user requests transparency effects but the display hardware is only + set to 8-bit, it has to invoke an extra step of converting the 16-bit SNES + rendered screen to a fixed palette 8-bit display just before the SNES + screen is copied to the display hardware. + + The GFX.Screen pointer needs to be initialised to point to an array of + uint8 for 8-bit screen rendering or uint16 for 16-bit rendering, cast to + an array of uint8. The array needs to be at least 256x239 bytes or shorts + in size for lo-res only support (Settings.SupportHiRes = FALSE) or + 512x478 for lo-res and hi-res support. If transparency effects are + required, the GFX.SubScreen array also needs to be initialised to another + identically sized array of the same type, otherwise it can be just + initialised to NULL. + + The GFX.Pitch variable needs to be set to the number of bytes on each line + of the arrays, e.g. 256 for lo-res only support, up to 1024 for 16-bit + hi-res support. If GFX.Screen is pointing into an existing array, one + created by the library function rather than just calling malloc or new, + then set GFX.Pitch to the number of bytes per line of that array, + including any padding the library function may have added. + + If the target hardware supports fast access to video RAM, the screen is in + 16-bit format supported by the SNES rendering code and you can double + buffer the display, you might want to point GFX.Screen directly at the + video buffer RAM. You will need to recompute the GFX.Delta value every + time you change the GFX.Screen value to double-buffer the rendering and + display. + +- A call to S9xGraphicsInit() is made; make sure all your graphics rendering + options are setup correctly by now. If later, you want to change some + settings, for example 16-bit to 8-bit rendering, call S9xGraphicsDeinit() + first, change your settings, GFX.Screen and GFX.SubScreen arrays, etc., + then call S9xGraphicsInit() again. + +- S9xInitSound(int playbackrate, bool8 stereo, int sound_buffer_size) + is now called, which in turn will call your S9xOpenSoundDevice function - + see below. + +- The display is switched to graphics mode using a call to S9xGraphicsMode(). + +- The system timer is started; its used for keeping the emulator speed + relatively constant on the MS-DOS port and noting when the sound hardware + sound should be able to accept more sound data on the Linux and UNIX ports. + +- A main loop is entered which is just a loop constantly calling + S9xMainLoop() then polling the operating system for any pending events + such as key presses and releases, joystick updates, mouse position + updates, GUI user interaction, etc. + + Pause functionality can be implemented by skipping the call to S9xMainLoop + and muting the sound output by calling S9xSetSoundMute (TRUE). + + Don't enter the main loop until a SNES ROM image has been loaded, or at + least skip calling S9xMainLoop inside the loop until one is and make sure + S9xReset is called instead before entering the main loop. The Mac port + implements this technique by starting in pause mode and refusing to unpause + until a ROM image is loaded. + + S9xMainLoop processes SNES CPU emulation, SNES screen rendering, DMA and + H-DMA emulation, until emulated scan-line 0 is reached, then it returns. + Now is your chance to process any system events pending, scan the + keyboard, read joystick values, etc. + + If DEBUGGER compile-time support is enabled and the CPU emulation has hit + a break point or single-stepping is switched on, or the DEBUG_MODE_FLAG is + set in the CPU.Flags variable, then the S9xMainLoop routine returns early, + allowing you to act on the event in some way. The Linux, DOS and UNIX ports + respond to the DEBUG_MODE_FLAG being set by calling S9xDoDebug(), which in + turn outputs the current instruction and loops reading commands from stdin + and outputting debug information, currently via stdout. The debugger + desperately needs rewriting to support a GUI interface, more descriptive + commands and better error handling; maybe one day... + +Existing Interface Routines +--------------------------- + +These are routines already written that you will either need to call or +might find useful. + +-> bool8 Memory.Init () + +Allocates and initialises several major lumps of memory, for example +the SNES ROM and RAM arrays, tile cache arrays, etc. Returns FALSE if +memory allocation fails. + +-> void Memory.Deinit () + +Undoes the memory allocations made by Memory.Init. + +-> bool8 S9xGraphicsInit () + +Allocated and initialises several lookup tables used to speed up SNES +graphics rendering. Call after you have initialised the GFX.Screen, +GFX.SubScreen and GFX.Pitch values. If Settings.Transparency is false it +does not allocate tables used to speed up transparency effects. If you +want to provide the user with option to turn the effects on and off during +game play, make sure Settings.Transparency is true when this function is +called, it can later be set to FALSE. + +Returns FALSE if memory allocation fails. + +-> void S9xGraphicsDeinit () + +Undoes the memory allocations made by S9xGraphicsInit. + +-> bool8 S9xInitAPU () + +Allocates and initialises several arrays used by the sound CPU and sound +generation code. + +-> void S9xDeinitAPU () + +Undoes the allocations made by S9xInitAPU. + +-> bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size) + +Does more sound code initialisation and opens the host system's sound hardware +by calling the S9xOpenSoundDevice function provided by you. + +-> void S9xReset () + +Resets the SNES emulated hardware back to the state it was in at 'switch-on' +except the S-RAM area is presevered. The effect is it resets the current game +back to the start. This function is automatically called by Memory.LoROM. + +-> bool8 Memory.LoadROM (const char *filename) + +Attempts to load the specified ROM image filename into the emulated ROM area. +There are many different SNES ROM image formats and the code attempts to +auto-detect as many different types as it can and in a vast majority of the +cases gets it right. However, some ROM images have been edited by someone at +some stage or have been mangled by the ROM copier that produced them and +LoadROM needs help. Inparticular, it can't auto-detect the odd way in which +some Super FX games have been mangled and needs to be told, via +Settings.Interleaved2, that the ROM image is in that format, or that +odd-sized ROM images have a 512 byte copier header. + +There are several other ROM image options in the Settings structure; +allow the user to set them before calling LoadROM, or make sure they all +reset to default values before each call to LoadROM. + +-> bool8 Memory.LoadSRAM (const char *filename) + +Call this routine to load the associated S-RAM save file (if any). The +filename should be based on the ROM image name to allow easy linkage. +The current ports change the directory and the filename extension of the ROM +filename to derive the S-RAM filename. + +-> bool8 Memory.SaveSRAM (const char *filename) + +Call this routine to save the emulated S-RAM area into a file so it can +be restored again the next time the user wants to play the game. Remember +to call this when just before the emulator exits or when the user has been +playing a game and is about to load another one. + +-> void S9xMainLoop() + +The emulator main loop. Call this from your own main loop that calls this +function (if a ROM image is loaded and the game is not paused), processes +any pending host system events, then goes back around the loop again until +the emulator exits. + +S9xMainLoop normally returns control to your main loop once every emulated +frame, when it reaches the start of scan-line zero. However, the routine +can return more often if the DEBUGGER compile-time flag is defined and the +CPU has hit a break point, or the DEBUG_MODE_FLAG bit is set in CPU.Flags +or instruction single-stepping is enabled. + +-> void S9xMixSamples (uint8 *buffer, int sample_count) + +Call this routine from your host sound hardware handling code to fill the +specified buffer with ready mixed SNES sound data. If 16-bit sound mode is +choosen, then the buffer will be filled with an array of sample_count int16, +otherwise an array of sample_count uint8. If stereo sound generation is +selected the buffer is filled with the same number of samples, but in pairs, +first a left channel sample followed by the right channel sample. + +There is a limit on how much data S9xMixSamples can deal with in one go and +hence a limit on the sample_count value; the limit is the value of the +MAX_BUFFER_SIZE symbol, normally 4096 bytes. + +-> bool8 S9xSetSoundMute (bool8 mute) + +Call with a TRUE parmeter to prevent S9xMixSamples from processing SNES +sample data and instead just filling the return buffer with silent sound +data. Useful if your sound system is interrupt or callback driven and the +game has been paused either directly or indirectly because the user +interacting with the emulator's user interface in some way. + +-> bool8 S9xFreezeGame (const char *filename) + +Call this routine to record the current SNES hardware state into a file, +the file can be loaded back using S9xUnfreezeGame at a later date effectively +restoring the current game to exact same spot. Call this routine while +you're processing any pending system events when S9xMainLoop has returned +control to you in your main loop. + +-> bool8 S9xUnfreezeGame (const char *filename) + +Restore the SNES hardware back to the exactly the state it was in when +S9xFreezeGame was used to generate the file specified. You have to arrange +the correct ROM is already loaded using Memory.LoadROM, an easy way to +arrange this is to base freeze-game filenames on the ROM image name. The +Linux, UNIX and DOS ports load freeze-game files when the user presses a +function key, with the names romfilename.000 for F1, romfilename.001 for F2, +etc. Games are frozen in the first place when the user presses Shift-function +key. You could choose some other scheme. + +-> void S9xNextController () + +The real SNES allows several different types of devices to be plugged into +the game controller ports. The devices Snes9x emulates are a joy-pad, +multi-player adaptor (allowing a further 4 joy-pads to be plugged in), +a 2-button mouse and a light gun known as the SuperScope. + +Each call to S9xNextController will step the current emulated device on to +the next device in the sequence multi-player, joy-pad, mouse on port 1, +mouse on port 2, light gun then back to multi-player again. Defines +allocating a number of each device type are in snes9x.h. The currently +selected device is stored in IPPU.Controller if you want to give some +feedback to the user. The initial value of IPPU.Controller (set when +S9xReset is called) is obtained from Settings.ControllerOption based on +currently enabled options. + +Some ROMs object to certain non-joy-pad devices being plugged into the real +SNES while they are running, all Super FX games should only allow joy-pads to +be plugged in because the Super FX chip and any other device would overload +the SNES power supply. Tetris and Dr. Mario also objects for reasons best +known to itself. For this reason there are switches in the Settings +structure to enable and display the emulation of the various devices. + +const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte) + +const char *S9xProActionReplayToRaw (const char *code, uint32 &address, + uint8 &byte) + +const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, + uint8 &num_bytes, uint8 bytes[3]) + +void S9xApplyCheats (bool8 apply) + +void S9xRemoveCheats () + +void S9xAddCheat (uint32 address, bool8 cpu_address, bool8 sram, uint8 num_bytes, + uint8 byte1, uint8 byte2, uint8 byte3) + +void S9xDeleteCheats () + +void S9xDoDebug () + +Interface Routines You Need to Implement +---------------------------------------- + +bool8 S9xOpenSnapshotFile (const char *base, bool8 read_only, STREAM *file) +*************************************************************************** +void S9xCloseSnapshotFile (STREAM file) +*************************************** + +Routines to open and close freeze-game files. STREAM is defined as a +gzFile if ZLIB is defined else its defined as FILE *. The read_only parameter +is set to TRUE when reading a freeze-game file and FALSE when writing a +freeze-game file. + +void S9xExit () +*************** + +Called when some fatal error situation arises or when the 'q' debugger +command is used. The Mac port just beeps and drops back to the GUI when +S9xExit is called, the MS-DOS, Linux and Solaris ports all call exit () to +terminate the emulator process. + +void S9xParseArg (char **argv, int &index, int argc) +**************************************************** + +void S9xExtraUsage () +********************* + +If you're going to be using the simple command line parser, when it +encounters an unknown option it calls S9xUsage which is supposed to report +all options the generic parse knows about (I haven't been keeping it up to +date of late). S9xUsage then, in turn calls S9xExtraUsage which you +implement to report any port-specific options available. + +void S9xGraphicsMode () +*********************** +void S9xTextMode () +******************* + +The SNES debugger calls these routines to switch from a graphics screen +mode used to display the SNES game to a debugger screen used to display +debugger output. If the SNES screen can be displayed at the same time as +a text display, as would be the case when the host system implements a +graphical window system, or you're not going to support the SNES debugger, +then these routines should do nothing. + +On the X Window System UNIX/Linux port, these routines do nothing where as +on the MS-DOS port they switch between a graphics screen mode and a text-only +screen mode. + +bool8 S9xInitUpdate () +********************** + +Called just before Snes9x starts to render a SNES screen. The Windows port +uses this call to lock Direct X screen area to allow exclusive access; on +other existing ports its implemented as an empty function. + +bool8 S9xDeinitDisplay (int width, int height, bool8 sixteen_bit) +***************************************************************** + +Called once a complete SNES screen has been rendered into the GFX.Screen +memory buffer, now is your chance to copy the SNES rendered screen to the +host computer's screen memory. The problem is that you have to cope with +different sized SNES rendered screens. Width is always 256, unless you're +supporting SNES hi-res. screen modes (Settings.SupportHiRes is TRUE), in +which case it can be 256 or 512. The height parameter can be either 224 or +239 if you're only supporting SNES lo-res. screen modes, or 224, 239, 448 or +478 if hi-res. SNES screen modes are being supported. + +All current ports support scaling the SNES screen to fill the host system's +screen, the many ports even supports interpolation - blending the colours of +adjacent pixels to help hide the fact they've been scaled - and scan-line +simulation - slightly darkening every other horizontal line. + +Don't forget that if you're just placing the SNES image centerally in the +screen then you might need to clear areas of the screen if the SNES image +changes size between calls to S9xDeinitDisplay. The MS-DOS and UNIX ports +currently don't do this which results in junk being left on the screen if +the ROM changes SNES screen modes. + +The sixteen_bit is just a copy of the Settings.SixteenBit setting and if +TRUE indicates a 16-bit SNES screen image has been rendered, 8-bit otherwise. + +void S9xMessage (int type, int number, const char *message) +*********************************************************** + +I've started work on converting all the old printfs into calls to this +routine. When Snes9x wants to display an error, information or warning +message, it calls this routine. Check in messages.h for the types and +individual message numbers that Snes9x currently passes as parameters. + +The idea is display the message string so the user can see it, but you +choose not to display anything at all, or change the message based on the +message number or message type. + +Eventually all debug output will also go via this function, trace information +already does. + +bool8 S9xOpenSoundDevice(int mode, bool8 stereo, int buffer_size) +***************************************************************** + +S9xInitSound calls this function to actually open the host operating system's +sound device, or initialise the sound card in MS-DOS port. + +The mode parameter is the value passed in on the command line with the -r +command line flag, assuming you're using the Snes9x parser. Its meant to +indicate what playback the sound hardware should be set to, value 1 to 7. +I think the real SNES sound chip playback rate is 30kHz, but such high +playback rates take a lot of native CPU power to emulate. The default +playback rate is 22kHz for the MS-DOS and UNIX ports. + +The stereo flag indicates if the user wants stereo sound. Again, stereo +sound takes more CPU to power to emulate compared to mono sound. + +The buffer_size value indicates what sample buffer size the user wants, +usually zero, meaning you should pick the value best suited to the current +playback rate. Sound data is normally passed to the sound hardware in +blocks, the smaller the block the less latency between the SNES game playing +a sound and it being heard by the user. But if you pick a too smaller value, +and you're having to periodically poll the operating system to see if it can +accept more sound data, then the sound output will break up because other +actions such as rendering the SNES screen can prevent you from polling the +hardware often enough and the operating system runs out of sound data to +play. + +The MS-DOS port uses a buffer size of 128 samples since the sound card +sends an interrupt when more data is required which is acted upon promptly, +where as the Linux and Solaris ports use a buffer size of 512 samples or +more depending on the playback rate. Stereo and 16-bit sound both double the +actual size of the buffer in bytes. + +uint32 S9xReadJoypad (int which1_0_to_4) +**************************************** + +This function is called to return a bit-wise mask of the state of one of the +five emulated SNES controllers. Return 0 if you're not supporting controllers +past a certain number or return the mask representing the current state of +the controller number passed as a parameter or'ed with 0x80000000. + +Symbolic constants are defined in snes9x.h indicating the bit positions of +the various SNES buttons and direction indicators; they're all in the form +SNES_X_MASK where X is the SNES controller button name. + +The MS-DOS and X Window System ports record what keys are currently pressed +and use that to build up a mask, the Windows port polls the operating system +when S9xReadJoypad is called to find out what keys are pressed. All ports +also implement host joysticks and joy-pads via this interface. + +bool8 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons) +******************************************************************************* + +Used by Snes9x to get the current position of the host pointing device, +usually a mouse, used to emulated the SNES mouse. Snes9x converts the x and +y values to delta values required by the SNES mouse, so the actual x and y +values are unimportant, only the change in value since the last call to +this function is used. + +Graphical windowing systems normally restrict the movement of the pointer on +the screen, if you're porting to such an environment you might want to make +a note of the change in position in the mouse since the last time you asked +the operating system the mouse position, add this change in value to some +saved x and y value, the reposition the pointer back to the centre of the +SNES display window. The saved x and y values will be the values returned +by this function. + +The buttons return value is a bit-wise mask of the two SNES mouse buttons, +bit 0 for button 1 (left) and bit 1 for button 2 (right). + +bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons) +***************************************************************** + +void S9xSetPalette () +********************* + +void S9xSyncSpeed () +S9xUnixProcessSound +void _makepath(char *, char const *, char const *, char const *, char const *) +void _splitpath(char const *, char *, char *, char *, char *) + + +Sound Generation +---------------- + +Settings +-------- diff --git a/source/docs/changes.txt b/source/docs/changes.txt deleted file mode 100644 index 0f1027f..0000000 --- a/source/docs/changes.txt +++ /dev/null @@ -1,2459 +0,0 @@ -Snes9x 1.53 - -- Rebuilt IRQ handling. (zones) -- Improved overall timings, now Snes9x can handle events in - a opcode a little. (zones) -- Improved screen interlace and sprite interlace supports. (OV2, zones) -- Fixed Hi-Res pixel plotter. (BearOso, zones, OV2) -- Fixed C4 for Mega Man X2's "weapon get" screen. (Jonas Quinn) -- Fixed Super Buster Bros. graphics after reset. (Jonas Quinn) -- Improved SA-1 support. (zones) -- Added SA-1 CC2 support. (Jonas Quinn, byuu) -- Fixed SA-1 NMI override mode. (zones) -- Fixed Dual Orb 2 sound glitch. (byuu) -- New APU timing hack, fixes various games that exhibit - problems with Blargg's SNES_SPC library. (OV2) -- Fixed the problem that echo buffer breaks IPL ROM. (zones, OV2) -- Fixed movie snapshot unfreeze inconsistency. (gocha) -- Faster config file saving. (OV2) -- Fixed BlockInvalidVRAMAccess config file option. - (windows port, unix port and gtk legacy config) (Jonas Quinn) -- Remove POSIX dup and access calls, and rename qword to - fix compilation with Cell SDK. (BearOso) -- Fixed PS3 version save state crash by using heap - allocation for soundsnapshot. (danieldematteis) -- Fixed crash relating to double-closed descriptor. (BearOso) -- Removed CPUShutdown speedhack, DisableHDMA and - DisableIRQ options. (zones) -- Removed remaining outdated asm code. (zones) -- JMA 64 bit support. (kode54, Nach, friedrich.goepel) -- GTK+, Win32, Mac: Added optional Hi-Res blending. (BearOso, OV2, zones) -- GTK+, Win32: Support for bsnes-style XML shaders. (BearOso, OV2) -- Win32: Full unicode support. (OV2) -- Win32: Restored OpenGL mode. (OV2) -- Win32: x64 version. (OV2) -- Win32: HLSL shader support. (mudlord) -- Win32: Win7 jumplist synchronizes with recent roms list. (OV2) -- Win32: Updated menu structure. (OV2) -- Win32: Drag&Drop support for ROMs. (gocha, OV2) -- Win32: Reworked movie-recording with size selection. (gocha, OV2) -- Win32: Restored SPC save option. (OV2) -- Win32: Fixed vsync in DirectDraw. (OV2) -- Win32: Improved window position saving. (OV2) -- Win32: Restored compile with DEBUGGER. (gocha) -- Win32: Fixed various edge-case errors and/or possible - leaks. (Brian Friesen) -- Win32: Config file option to always center image. (OV2) -- Win32: Fixed "Turbo Down mode" hotkey assignment. (gocha) -- Win32: Added and fixed Autofire for D-pad. (gocha) -- Win32: Fixed aggressive soundsync wait. (OV2) -- Win32: Added window size presets. (OV2) -- Mac : Added pause and frame advance functions. (zones) -- Mac : Now you can choose any folder for saving files. (zones) -- Mac : Updated Music Box (mostly internally). (zones) -- Mac : Fixed gliches in open/save dialogs on 10.6. (zones) -- Mac : Fixed display configuration in windowed mode. (zones) -- Unix : Fixed segfault and hang-up with -DNOSOUND. (zones) -- GTK+ : Added ability to set specific folders for SRAM, - patches, snapshots, etc. (BearOso) -- GTK+ : Fixed many permissions issues with config folders. (BearOso) -- GTK+ : Updated compatibility with latest GTK+ and - GtkBuilder. Added experimental support for GTK+ 3.x. (BearOso) -- GTK+ : Updated software output to use cairo and added the - ability to use bilinear-filtering with it. (BearOso) -- GTK+ : Fixed issues where cheats wouldn't stay enabled. (BearOso) -- GTK+ : Fixed focus issue when there is no window manager. (BearOso) -- GTK+ : Fixed X Visual incompatibilities and expose - problems in the Xv and OpenGL outputs. (BearOso) -- GTK+ : Fixed vsync with new X Server and NVIDIA drivers. (BearOso) -- GTK+ : Added "Reduce input lag" option to OpenGL output. (BearOso) -- GTK+ : Added a visual indication of the expected video - refresh rate for the currently selected sound input rate. (BearOso) - -Snes9x 1.52 -- IMPORTANT NOTICE: The structure of savestates (also known - as snapshots / freeze files) is incompatible with older - versions! Snes9x 1.52 cannot read the savestates created - by 1.51 or older. (zones) -- Highly acculate SPC700 and S-DSP emulation. (Blargg) -- Replaced APU emulation cores (SPC700 and S-DSP) with - ones provided by Blargg's SNES_SPC library. This renders - savestates incompatible with older versions. (BearOso, zones) -- SPC7110 emulation. (byuu, neviksti) -- Merged bsnes' SPC7110 emulation code. Note that the .rtc - file of Far East of Eden Zero is incompatible with older - versions. (zones) -- Removed graphics pack support. It's no more necessary. (zones) -- Replaced S-RTC emulation code with bsnes' one to keep the - good compatibility of .rtc files between the two - emulators. As a result, Daikaijuu Monogatari 2 now - outputs the .rtc file, and its .srm file is incompatible - with older versions. (zones) -- Added savestate supports for DSP-2, DSP-4, ST-010 and - OBC1. (zones) -- Added UPS support. (byuu) -- Fixed DSP-4 AI problem. (Jonas Quinn) -- Fixed invalid memory accesses in C4 and OBC1 codes. (zones) -- Fixed invalid memory accesses in BSX codes. My mistake. (zones) -- Fixed the read value of $213e, $4210 and $4211. (zones) -- Fixed the writing of word values at the memory boundary. (zones) -- Fixed the bug that the unnecessary SA-1 emulation - continues once any SA-1 games are launched. (zones) -- Removed old color blending codes. (zones) -- Removed too-old Snes96 and ZSNES snapshot support. (zones) -- Updated command-line options. (zones) -- Code cleaning. (zones) -- GTK+ : Added a port of Snes9x to the GTK+ toolkit. (BearOso) -- Unix : Reconstructed and simplified all the contents. - Some features have been removed to be simple, and many - options have changed. GTK+ port is recommended for most - of Linux users. (zones) -- Win32: Now uses snes9x.conf to prevent problems with - modified meaning of settings. (OV2) -- Win32: Removed broken OpenGL mode. (OV2) -- Win32: Removed support for 8bit output. (OV2) -- Win32: Reworked settings dialogues to accomodate the - new APU core and display settings. (OV2) -- Win32: Updated defaults to use D3D and XA2 (better - Vista and Win7 support). (OV2) -- Win32: Direct3D and XAudio2 support. (OV2) -- Win32: Added Blargg's ntsc filter (three presets). (OV2) -- Mac : Fixed corrupted screenshot on Intel Mac. (zones) -- Mac : Fixed sudden abort in QuickTime movie export on - Intel Mac. (zones) -- Mac : Changed sound settings for the new APU core. (zones) -- Mac : Changed the default folder which Snes9x looks for - to 'Application Support' folder. (zones) -- Mac : Changed folder names: 'IPSs' -> 'Patches', - 'BIOSs' -> 'BIOSes'. (zones) -- Mac : Added Blargg's ntsc filter. (zones) -- Mac : Internal changes for Leopard and Snow Leopard. (zones) - -Snes9x 1.51 -- Added DSP1 and SuperFX savestate support. (nitsuja) -- Added screen state GFX to save states. (optional) (nitsuja) -- Fixed desync when loading inconsistent state in playback. (nitsuja) -- When playback reaches a movie's end, recording continues - instead of the movie suddenly closing. (after recording) (nitsuja) -- can now record resets and mouse/superscope/justifier(s) (nitsuja) -- Added same-line-comment support for config files. (nitsuja) -- input display for all controllers (including peripherals) (nitsuja) -- Win32: Now uses .cfg file instead of Windows registry. (nitsuja) -- Win32: open ROM dialog bugfixes and speedup and facelift (nitsuja) -- Win32: option to use standard file open dialog for ROMs (nitsuja) -- Win32: maintain aspect ratio and bilinear filter stretch (nitsuja) -- Win32: optional removal of the dreaded "black bar" (nitsuja) -- Win32: Added EPX,EPX2,EPX3,HQ2X,HQ3X,TV3X,DM3X filters. (nitsuja) -- Win32: Added hires support for Interlace and TV Mode. (nitsuja) -- Win32: text removed from .avi output (optional) (nitsuja) -- Win32: better directory management, customizeable (nitsuja) -- Win32: Screenshot support is back. (nitsuja) -- Win32: Netplay is back (but still not very good). (nitsuja) -- Win32: Made OpenGL Bi-linear an advanced .cfg option. (nitsuja) -- Win32: cheat search improvements (address, watch, SuperFX)(nitsuja) -- Win32: Added non-modal ("active") cheat search option. (nitsuja) -- Win32: new hotkey-config dialog and configurable hotkeys (nitsuja) -- Win32: Fixed joystick config in input dialog. (nitsuja) -- Win32: Fixed hires and extended height .avi output. (nitsuja) -- Win32: various small GUI improvements (nitsuja) -- Win32: Netplay fixes. (nitsuja) -- "Fake Mute" desync workaround option for movies, until - all ports have deterministic sound. (Bisqwit, nitsuja) -- Fix for save state blocks > 999999 bytes. (Bisqwit) -- C4 games now save C4 data in save states. (DeHackEd) -- Unix: Framework for high-speed seeking. Specify a frame - number in a movie, and the emulator will run at - maximum speed to that frame. Untested. (DeHackEd) -- X11: Support for window exposure. When a window is - damaged due to overlay, being iconified, etc. it will - be repainted correctly. (DeHackEd) -- Unix: parameter: -autodemo loads a movie for - playback on startup. Only the x11 code handles this - right now. (DeHackEd) -- Unix: parameter: -oldturbo, the turbo button renders all - frames when fast-forwarding. (DeHackEd) -- Unix: parameter: -upanddown, override U+D and - L+R protection. (DeHackEd) -- Unix: parameter: -mute, currently linux only, blocks out - audio output from your speakers while still emulating - sound. Not fully tested. (DeHackEd) -- Unix: parameter: -maxframes during movie - playback, snes9x will exit when the target is hit. (DeHackEd) -- Unix: parameter: -keypress shows to stderr and on-screen - the currently pressed buttons on joypad 1. (DeHackEd) -- Unix: Stream dumping (NOT COMPLETE). With -dumpstreams, - raw video and raw audio are dumped to videostream%d.dat - and audiostream%d.dat, where %d increments on each CPU - reset, starting at zero. (DeHackEd) -- Unix: Non-blocking sound on Linux. It makes seeking nicer.(DeHackEd) -- Unix: Configurable sound device. (pierredavidbelanger) -- configure.in now requires a sufficiently new version of - autoconf. (anomie) -- Fixed slow versions of branch opcodes. (anomie) -- Fixed the mosaic offset bug. (anomie) -- No sorting by priority in C4 command 00 00. MegaMan X2 - can go behind the legs of the intro stage boss. (anomie) -- New RTO discovery, fixes Super Conflict: The Mideast - title screen. (anomie, byuu) -- A 1->0 transition on $2100.7 causes OAM Address Reset. (anomie, byuu) -- The final HDMA Indirect Address load is only weird - on the last channel of the scanline. - Touge Densetsu Saisoku Battle problem solved. (anomie, byuu) -- Fixed BGnVOFS bug. Only HOFS needs ~&7 update. (byuu) -- Fixed superfluous VIRQ triggers. (zones) -- Fixed missing IRQ trigger just after the previous one. (zones) -- Fixed missing IRQ while writing to $4200. (zones) -- Fixed IRQ timing after WRAM refresh. (zones) -- Fixed NMA timing after DMA transfer. (zones) -- Fixed superfluous auto-joypad-reading. (zones) -- Fixed missing WRAM refresh during DMA transfer. (zones) -- Fixed DMA so that HDMA and any HC triggered events can - run during DMA transfer. (zones) -- Roughly fixed the case that HDMA and DMA use the same - channel at the same time. HDMA kills DMA. Thanks byuu. (zones) -- Changed initial DMA registers values. (zones) -- Slightly modified APU execute timings. (zones) -- Fixed APU I/O registers to get/set the proper value. (zones) -- Blocked invalid VRAM writings, though you can turn off - this option due to Snes9x's inaccurate timings. (zones) -- Omitted SPCTOOL, no one uses it. (zones) -- Added Sufami Turbo support. (zones) -- Added Same Game add-on cart support. (zones) -- Fixed HiROM SRAM and DSP1-4 memory maps a little. (zones) -- Improved mirroring. (Nach, grinvader, byuu) -- CRC32 on BS dumps now follows uCONSRT standard. (Nach) -- BS dumps now always run in NTSC mode. (Nach) -- Unknown regions (generally betas) default to NTSC. (Nach) -- Now support NSRT headers for setting up controllers. (Nach, nitsuja) -- Unix: Fixed command line help output. (Nach) -- Unix: Sound now defaults to 32KHz, Stereo, Interpolation - so Snes9x finally sounds like a real SNES by default. (Nach) -- Win32: Saner defaults for movie record. (Nach) -- Unix: Fixed crashing with mouse or super scope. (Nach) -- Removed some weird code which was crashing Korean - League and its varients. (Nach) -- Win32: Can now compile with MinGW. (Jonas Quinn, Nach) -- Win32: Can now cross compile Snes9xw. (Nach) -- Unix: SSnes9x compiles again. (Nach) -- Win32: ZSNES C4 and SuperFX compiles once again. (Jonas Quinn) -- Unix: Netplay Fixes. (Nach) -- Unix: Netplay Improvements. (Fabianx) - -Snes9x 1.5 -- Pseudo-hires rendering flush, Old 2xsai endian fix (anomie) -- Added 'oops' auto-snapshot support (anomie) -- Fixed usage messages (Unix) (anomie) -- Old split-ROM-in-zip bugfix (anomie) -- ./configure fix for detecting libpng (anomie) -- Fix "no PNG support" error message (anomie) -- Anomie's control remapping patch (anomie) -- Support for IPS patches in the zip file (anomie) -- OBC1 savestate fix (Overload) -- Fix turbo frameskip, X11 keyboard auto-repeat, VRAM reads (anomie) -- Add some missing ifdefs (UNZIP_SUPPORT and ZLIB), - from AaronOneal (anomie) -- Config file for Unix/X11 and Unix/SVGA (anomie) -- CPU instruction fixes (mostly emulation mode & timing) (anomie) -- Mode 7 fixes (anomie) -- Rewrote the renderer. Enjoy! (anomie) -- Correct-ish memmap boundary testing. (anomie) -- Add support for saner directory structures under Unix (anomie) -- Unix: Fixed detection of newer libpng (spotted by vapier) (PBortas) -- Added 4-point gaussian interpolation and proper envelopes - many thanks to Brad Martin and TRAC. (zones) -- Fixed several sound problems. (zones) -- Fixed the memory access problem in C++ Super FX core. (zones) -- Speed adjustment of C++ Super FX emulation. (zones) -- Various timing fixes: NMI, IRQ, WRAM refresh, - cycles per line, HBlank start, etc. - Many thanks to byuu for much information. (zones) -- Removed some game specific hacks. (zones) -- Added partial Satellaview (BS) emulation. (Dreamer Nom, zones) -- Added the Katakana font for onscreen messages. (107) -- Updated JMA to v1 (Nach) -- Unix: Fixed JMA options in config (Nach) -- Unix: Removed --with(out)-asmcpu option in config - because the i386 assembler CPU core is out of date. (zones) -- Unix: Changed the default settings in config. (zones) -- Updated porting.html (porting.txt) in sync with 1.5. (zones) -- Fixed buffer over/under flow due to incorrect logical - operator in S-RTC code (byuu) -- Fixed HDMA flags bug. (byuu, anomie) -- Fixed bugs causing crashing in Unix. (Nach) -- Ported Snes9x to AMD64. (John Weidman, Nach, zones) -- Completed DSP-1 code. (Andreas Naive, Overload, Nach) -- Updated DSP-3 code. (Nach, z80 gaiden) -- Updated DSP-4 code. (Dreamer Nom, Nach, z80 gaiden) -- Overhauled BS detection. (Nach) -- Improved Unix portability. (Nach, zones) -- Fixed infiniti loop and invalid read bug in - C++ C4 core. (Nach) - - -Snes9x 1.43 -- Win32: Disabled Netplay (funkyass) -- Win32: Various fixes, including ROM dialog (funkyass) -- Win32: New Input Config Dialog (funkyass) -- Win32: added .avi output feature (blip) -- Win32: fixed frame timings >100ms, added frame advance (blip) -- Rewrote Unfreeze, renamed it S9xUnfreezeFromStream, - failing to load a freeze file no longer resets emulation (blip) -- Fixed Unfreeze to restore IPPU.HDMA properly (blip) -- Rewrote OBC1 code to match the real chip (Overload) -- More updates the to DSP-1 code, fixes to projection (Overload, Andreas Naive) -- Unix/X11: Rewrote keyboard setup code (Bisqwit) -- Added movie recording+rerecording support (blip, Bisqwit) -- Added -hidemenu CLI switch (funkyass) -- fixed broken Win32 filters (lantus) -- Added internal support for emulating the new-style SNES (MKendora) -- Cleaned up many quirks of the cheat search engine (MKendora, Don Vincenzo) -- Fix mosaic in hires SNES modes (Tokimeki Memorial) (MKendora, zones) -- Rewrote Legend's hack, added another game to it (MKendora) -- Optimized the Open ROM dialog (MKendora) -- Rewrote the Seta DSP map (The Dumper, MKendora) -- Began string isolation for the UI, eases translation (funkyass) -- added -nopatch -nocheat, and -cheat CLI items (MKendora) -- fixed a UI typo (funkyass) -- fixed several C core stack ops in emulation mode (MKendora) -- split emulation mode ops from native mode ops (MKendora) -- Seta special chip emulation enhancements (Feather, The Dumper, Overload, MKendora) -- code tweaks to the ST010 (Nach, pagefault) -- fix some C/asm quirks and HDMA quirks (all my fault) (MKendora) -- several timing hacks to fix games (lantus) -- improved checksumming for odd mirrorings (MKendora) -- Snes9x uses a standard zlib instead of a packaged one (PBortas) -- Exhaust Heat 2 and regional ports are playable (Feather, The Dumper, Overload, MKendora) -- Game Doctor dumps that are 24 Mbit are now supported by - a force option (MKendora, Nach) -- SuperFx interleave format is now considered deprecated. - Support will be removed in future versions (Team decision) -- made SuperFx interleave detection a compile option (MKendora) -- added memory maps for slotted games (MKendora) -- fixed a typo in the usage messages (MKendora) -- fixed the bug that had nuked optimizations (The Dumper) -- restored full speed optimizations in release builds (funkyass) -- Added non-speed-hack version of color subtraction. (zones) -- OpenGL info message font fix (zones) -- APU timer fix (zones, Nach) -- Fixed mouse offset in resized X11 window. (PhaethonH) -- Fixed a (presumably) long-standing bug: Mode 6's BG is - depth 4, not depth 8! (anomie) -- Unix: unmap all joystick buttons before applying -joymapX (anomie) -- Win32: added a define to disable pausing when focus is - lost, NOPAUSE (funkyass) -- Win32: Changed the default for Auto-save SRAM to 15 sec (funkyass) -- Dreamcast: Added SH4 assembler (PBortas, Marcus Comstedt, Per Hedbor) -- C90 and aclocal 1.8 warning fixes (thanks Ville Skytt) (PBortas) -- Unix: AMD64 compilation fixes. (PBortas) -- Added support for NSRT Team's JMA format (Nach, NSRT Team, funkyass) -- Unix: Loading a zip file on binaries without zip support - will give an appropriate error message (Nach) -- Unix: Added install target with proper --prefix handling. (PBortas) - - -Snes9x 1.42 -- Added 8-bit rendering filters (funkyass) -- Added Sanity Checks for the Display Dialog (funkyass) -- New Layout for the Joypad Dialog, (funkyass) -- Fixed that anoying Joypad dialog bug. Now check to see - if the axis exists before asking for the info form it (funkyass) -- Added full POV support. (funkyass) -- Fixed sram sizes for SuperFx games (Nach, MKendora) -- Stopped saving sram for games with no battery (Nach, Mkendora) -- Killed the gray line and slightly optimized Win32 GL (MKendora) -- stack wrapping fix in C core (MKendora) -- removed some dead hacks (Oda Nobunaga and Dezaemon) (MKendora) -- fixed some DMA and HDMA modes (anomie, MKendora) -- improved HDMA timing (anomie) -- cleaned up load and deinterleave code (MKendora) -- removed old UI DLL (MKendora) -- new cheat dialogs (MKendora) -- started Unicode preparation in Win32 UI (MKendora) -- Implement odd sprite sizes, sprite priority rotation. (anomie) -- RTO code that hopefully works. MK's #define is - "MK_DEBUG_RTO" to try to debug the RTO code. (anomie) -- SDD1 decompression support for Linux. Also added a new - command line option -sdd1-pack. (anomie) -- Added correct VRAM read logic. #define CORRECT_VRAM_READS - if you want it. (anomie) -- removed the non-VAR_CYCLES path (MKendora) -- changed access timing map to be address-based. (MKendora, anomie) -- DSP-1 updates (Overload, Andreas Naive) -- S-DD1 decompression support (Andreas Naive) -- optimized S-DD1 code (anomie) -- S-DD1 can use packs or decompression (MKendora) -- More work on Exhaust Heat 2 (MKendora, Overload, The Dumper) -- separated ROM detection from file reading (lantus) -- fixed a mirroring bug in LoROMs (MKendora) -- cleaned up some mapping issues (MKendora) -- ST018 games now boot before locking up (Mkendora, Overload) -- SA-1 state was not completely reset, crashed Marvelous (zones) -- Removed sample caching. It caused problems, and was not - noticably faster. (MKendora) -- Fixed interlace without breaking the displays for MK (anomie) -- Fixed a PPU OpenBus hack (anomie) -- Moved SPC7110 and S-DD1 regs to speed up the general case - of reading the $4xxx registers (MKendora) -- altered Hi/Lo ROM detection to fix a few misdetects. (MKendora) -- Implemented RTO flags. With MK's implementation of $213F's - interlace bit, we now pass the SNES Test Cart's - Electronics Test (anomie) -- Fix sprite windowing bug (anomie) -- Way back in 1.40 MK changed the Windows port to default - to a plain old joypad instead of the MP5. And then we - removed the hacks for games that dislike the MP5. So - we need to change the defaults elsewhere too... (anomie) -- cleaned up the hacks section somewhat (MKendora) -- removed some interleave hacks (MKendora) -- fixed a bug in KartContents (MKendora) -- transparency fix for Jurassic Park (lantus) -- A hidden Win32 feature (MKendora) -- Kludged Mark Davis until I get stable APU timing (MKendora) -- Win32 renders overscan always, fixes some jumpy games (MKendora, lantus) -- Fixed an FMOD bug (MKendora) -- cosmetic tweaks (Everyone) -- Fixed 2 special chip bugs in the C core (zones) -- Added some sanity fixes to the C core, fixes MLBPA - Baseball for C core users (zones) -- updated zlib source (includes 1.1.4-1 patch) (MKendora) -- compiler warning fixes (PBortas) -- Updated the SuperFx asm core (pagefault) -- Kludged Unix compilation to produce working SuperFx (PBortas) - with the asm core. -- Kludged VC to deal with optimization weirdness (MKendora) -- Hacked Robocop vs. Terminator using Daffy Duck hack. Stops - flashing. (MKendora) -- Added some defines to the asm core (MKendora) -- Added possibility to take screenshots on Unix (PBortas) -- Initialize the C SuperFx core better (PBortas) -- Kludge a Japanese golf game until the APU timing is fixed (MKendora) - - -Snes9x 1.41-1 - -- Oops, in the asm CPU core i was stomping on %eax too - early, so register $4210 wasn't getting set properly. (anomie) - - -Snes9x 1.41 - -- Win32 controllers now stay the same between games (MKendora) -- Win 32 Open ROM dialog fixes (MKendora) -- Win32 Display dialog fixes (funkyass) -- Win32 OpenGL ratio tweaking. (Reduces the gray line) (kode54) -- Fixed Win32 superscope for those having issues (MKendora) -- Generic accuracy fix in main SUperscope emulation (MKendora) -- sprite bug fixed (gah! How'd we miss that) (anomie) -- SPC saving compatibility fix (Caz and zones) -- Window clipping update (anomie) -- Mode 7 clipping fix (TRAC) -- latching fix (anomie) -- BS BIOS checksum and mapping fix (MKendora) -- Working Uniracers hack (dma.cpp) (anomie) -- HDMA Indirect Address fix for Romancing Saga 2 (anomie) -- Better savestate hack, does it break anything? (anomie) -- C4 C core fixes. Mostly Trapezoid (thanks Nach), - some s/short/int16/, some indentation. (anomie) -- Damn, but the indentation in ppu.cpp was screwed up. - Killed some dead code too (twas commented forevermore). (anomie) -- fixed a potential crash in S-DD1 logging (MKendora) -- Improved accuracy of Hi/LoROM detection (~500 ROM test) (MKendora) -- Hack for Moryou Senki Madara 2, don't call - SelectTileRenderer from DrawOBJS if BGMode is 5 or 6. A - real fix requires at least rewriting SelectTileRenderer, - or inlining a special version in DrawOBJS. (anomie) -- DMA traces: add additional address info to reads too. (anomie) -- Killed the old Borland Joypad dialog (funkyass) -- Fixed issues with Dezaemon and CT, maybe others (anomie, MKendora) -- Changed the internal snapshot key from \ to VK_F12 (funkyass) - Fixes issues with non-US keyboard layouts. -- Fixed OAM reset to not occur during forced blank. (anomie) -- Killed some dead OAM reset code that doesn't need saving. (anomie) -- Unix/X11: Fixed screen jumping. CT enables overscan mid- - frame for only one frame, and we now update the rendered - screen height accordingly. Other ports are still broken. (anomie) -- Unix/X11: Fixed possible TV mode crash. (anomie) -- Fixed OAM reset timing (beginning of V-Blank rather than - end) for R-TYPE 3 (J). (anomie) -- Unix/X11: Fixed OpenGL target (PBortas) -- Unix/OSS: Fixed big endian sound (PBortas/ernstp) -- Tweaked the About Dialog so its read-only and no scroll (funkyass) - - -Snes9x 1.40 - -- cleaned up a sound skipping code issue. Same as the - RTC issue (lantus) -- re-fixed the invalid BRR header behavior twice (Lord Nightmare, FatlXception, Mkendora) -- More BS mapping fixes. (The Dumper, MKendora) -- Fixed Ranma Bun no 1 - Chonai Gekitou Hen (J) and - Street Combat (U). Interlace is not supported in the - non-Hi-res modes, as far as I can tell. (MKendora) -- Also fixes Maka Maka (J). Frank Yang's report, and - anomie's code both provided clues to this one. -- Removed special casing on setting 5c77 version to one. - This seems to be true for U and J units always. I need - it checked out on PAL... (neviksti) -- Using SNEeSe's values for 5c78 and 5A22. Note we know - that the 5c78 version can also be 1 or 2, instead of 3. (TRAC, neviksti) -- Added turbo buttons. Credit/blame for the design goes - to slack, Nave, Gogo, and myself. (MKendora) -- fixed a bug in turbo (slack, MKendora) -- Tried merging the behavior of Old $4200 with new $4200 (MKendora) -- Made $4200's return value match what VSMC Explorer - showed on Fancia's SNES (MKendora) -- Fixed a matrix multiplcation bug in ZSNES state loads (MKendora) -- Fixed Dezaemon and Ys3 mode 7 (lantus) -- Fixed H-DMA modes 5-7. Thanks to The Dumper for the - extra motivation needed. GunForce and Genocide 2 work. (The Dumper, MKendora) -- Fixed BG3 Priority. I'm stupid. anomie had fixed it, - but lantus fixed it again, because I didn't use it. (anomie, lantus) -- Added a Star Fox 2 hack, and an interleave skip (The Dumper, lantus, MKendora) -- Cleared BS setting on load (lantus) -- Fix for Mode 7 priorities. fixes F-1 Grand Prix (all 3) (anomie) -- JANJYU GAKUEN 2 needs Multi-tap 5 off. (Frank Yang, MKendora) -- HONKAKUHA IGO GOSEI: No multi-tap 5, allow mouse (lantus, MKendora) -- Added a few missed conditional compiles (Nach) -- disabled multitap 5 by default, added menu to enable (MKendora) -- special thanks to anomie and lantus. One of them is - responsible for a bug fix I forgot already. (anomie, lantus) -- Removed several Multitap5 disable hacks. (MKendora) -- Added an SPC dumping upgrade from kode54 (kode54) -- cleaned up some resource leaks (MKendora) -- I forgot this since 1.39mk, but SPC700 flag fixes (anomie) -- Mode 7 interpolation screen flip fix (anomie) -- Updated SPC7110 code a bit, for compatibility (Daniel, anomie) -- Changed RTC saving. (Byte exact to old format on Win32) - The submitted patch for "safety" doubled the file size, - so I had to write it in explicitly little-endian. (MKendora) -- Removed the old hidden cursor (MKendora) -- Applied a WAI correction from anomie. (anomie) -- Added a patch for Pseudo hi-res (anomie) -- Hacked around Word writes to $7F:FFFF. Thanks to lantus - and The Dumper for verification. (MKendora) -- PPC compile fix? and debugger reversion (anomie) -- Set defaults differently to improve sound quality. (MKendora) -- Clear Force load settings after Init (lantus) -- Made menu reset a soft reset. Fixed BL Sound Test & more (CaitSith2) -- Fixed word writes to block bounds in asm core. (MKendora) -- redone version of my bounds fix, only this one WORKS! (TRAC) -- Thanks to TRAC for the AT&T syntax refresher! (TRAC) -- Fixed screen saver disable (kode54) -- Fixed OAM and sprite priority in the asm core (anomie) -- Proper Interlace fix for mid-frame changes (anomie) -- Fixed OpenGL to accomodate previous patch (MKendora) -- Ported the "Settings" dialog to VC (MKendora) -- Fixed ROM Info bugs (_pentium_five, MKendora) -- Fixed non-stretched interlacing, but it's s.l.o.w. (anomie) -- Superscope and Mouse need to be enabled by the menu. (MKendora) -- Fixed HiROM sram reads in asm and C cores (anomie, MKendora) -- Added Company 48 to the list. Thanks to _pentium_five_ (StatMat) -- Set Super Drift Out's S-ram correctly. (Snes9xppSE Team) -- Fixed NTSC timing. Helps ToP Intro greatly (kode54) -- Added several entries to the company list, from uCON64 (Nach) -- Lots more companies (StatMat, Nach) -- Fixed Win32 Superscope support (NT kernel only?) (MKendora) -- Added ZSNES OBC1 code ported from asm to C (sanmaiwashi) -- Implemented Justifier emulation (neviksti, MKendora) -- Fixed Rudora no Hihou's clip window bug (anomie) -- Fixed Flintstones sprite issue (lantus) -- Fixed sram mappings for Big Sky Troopers and - Taikyoku - IGO Goliath. Both map in bank F0 (MKendora) -- Fixed a possible crash when switching audio settings (MKendora) -- Added per-pack gfx pack configuration (MKendora) -- Fixed glitches in DSP-1 games (Flintstones fix) (lantus) -- Added delay to Superscope latching. Fixes X-Zone. (neviksti, MKendora, zones) -- Added DSP-2 support (Overload, The Dumper, Lord Nightmare, - MKendora, neviksti) -- Fixed Super Bases Loaded 2 (and J/K ports) DSP-1 seems - to ignore the A15 line in LoROM maps (MKendora) -- Corrected $4200 again (The Dumper) -- Corrected $2100, $2102, and $2102 read behavior (anomie) -- Fixed Cancel on the Sound Options dialog. (MKendora) -- Fixed the sound options dialog (Thanks, Quattro) (MKendora) -- updated DSP-1 support to match chip better (Overload, neviksti, The Dumper) -- added a few Ops to the DSP-4 routine (Nothing plays yet) (neviksti, The Dumper, Overload, MKendora) -- added screenshot support (anomie, sanmaiwashi) -- stubbed the ST010 chip in Exhaust Heat 2 (Overload, MKendora) -- hacked around War 2410's lockup (pagefault, _Demo_, MKendora) -- updated tests for type 1 ROMs (based on reset vector) (MKendora) -- Emulation mode CPU fix (The Dumper) -- Open Bus fixes (anomie) -- Better Expansion port emulation (anomie) -- More Open Bus fixes (Overload, anomie) -- HDMA fixes (fix colors only in Full Throttle Racing) (anomie) -- Migrated DKJM2 onto the Tales map (MKendora) -- Tried to remove Dragon Knight 4 hack (LoROM sram fix) (MKendora) -- Fixed ROM Mirroring for LoROMs (<= 32 Mbit) (MKendora, TRAC) -- blocked wram to wram DMAs (neviksti) -- fixed HiROM mirroring, too. Thanks TRAC! (MKendora, TRAC) -- fixed C core RMW and Push ops to write in the correct - order, fixes Michael Jordan gfx. (anomie, Overload, MKendora) -- set RDIO to start as 0xFF, fixes SuperFx games. (anomie, Overload) -- New connect dialog (funkyass) -- better conditional compile of FMOD (funkyass) -- fixed screenshot code when libpng is not used (funkyass) -- added portability fixes (zones) -- fixed asm Pushes (anomie) -- fixed asm LoROM s-ram decode (MKendora) -- migrated DEZAEMON to standard LoROM map (MKendora) -- fixed the Madara 2 OpenGL bug (key found in Rudra) (MKendora) -- fixed asm RMW instructions (MKendora) -- fixed ADC opcode (The Dumper) -- added DSP-2 Op09 (The Dumper) -- updated C4 C code (anomie) -- updated C4 asm code (Nach) -- Keep OpenGL in ratio (kode54) -- Replaced many more Borland dialogs (funkyass, MKendora, Nach) -- Added CRC32 to displayed ROM Info (Nach, MKendora) -- Fix cheat support (The Dumper) -- improved DMA timing (MKendora, Overload, The Dumper) -- Fixed Mode 7 math, removed Dezaemon, Gaia, Ys 3 hacks (TRAC, MKendora) -- Mode 7 flip fix (TRAC) -- Multiple safety and initialization fixes (zones) -- Platform safety fixes (PBortas) -- Memmap cleanups (MKendora) -- More preliminary work on special chips (The Dumper, Overload, MKendora) -- Added color coding (MKendora) -- Another HDMA fix (anomie) -- added another known hack to the hacked games list (Nach) -- ToP memmap changes (MKendora) -- Checksum calculation changes (MKendora) -- Special cased a few games for OAM issues (MKendora) -- Reverted OAM reset to 1.39 timing (MKendora) -- Reworked vram wrapping (zones, Mkendora) -- Fixed $4210 and Super Professional Baseball 2 (Overload, MKendora) -- Fixed APU RAM init (Overload, MKendora) -- More support for Exhaust Heat 2 (not playable) (The Dumper, Overload, neviksti) -- removed some debris from save states (MKendora) -- fixed? Doom's save state bug (MKendora) -- simple overdump detection warning (MKendora) - - -1.39mk3b - -- Fixed the RTC detection. FINALLY done correctly (lantus, MKendora) - - -1.39mk3a - -- neatened up the company table. (MKendora) -- fixed a mistake in the ROM Info box (MKendora) -- Added a Calulcated Size field to ROM INfo. (MKendora) -- Added 3 more companies to the ROM Info table (MKendora) -- Fixed BS detection (The Dumper) -- Added a Legend-specific hack to get sound. I remembered - it being mentioned in the changelog. (Gary Henderson) -- Unbroke the Star Ocean special cases (Trigger of Time, MKendora) -- Company 255 is not Hudson-ZFE detects all Hudson games - without it, except a corrupt dump (StatMat, MKendora) -- fixed a bug in the redone detection for the SPC7110 (CaitSith2) -- 44Khz sound should be 44.1Kz. Changed, though you'll - need to re-set 44.1Khz to make it take effect. Not sure - if this affects non-Windows ports. (MKendora) -- Added 32Khz playback (MKendora) -- Inproved BS ROM mapping (_Demo_, The Dumper, MKendora) - - -1.39mk3 - -- Honkaku Syogi Fuunji Ryuou (J) fixed (force no multitap) (Frank Yang) - Also Fixed Super Castles (j). - Also fixed a bunch more. This dude e-mailed like 100 bugs - to my hosts, some already fixed in Snes9x1.39mk2, but - about 7 were clearly multi-tap5. -- also fixed Dekitate High School. Error was in Japanese (Frank Yang, Tomato) -- fixed 2 memory leaks (Aaron) -- Dai Kaiju Monogotari 2 works as a 40 Mbit ROM. (MKendora, The Dumper) -- Fixed the Flashback bug. Lots of info led to this. (neviksti, MKendora) - Thanks neviksti, The Dumper, TRAC, and FatlXception - for clarifying the behavior. -- Fixed Sailor Moon Fuwa Fuwa Panic 2 to work with (neviksti, MKendora) - previous fix. It's a total hack, but it should sound - just like the old Snes9x did. neviksti strikes again! -- Dirty hack to make 3 games deinterleave properly: (MKendora) - Wizardry 4, Mark Davis, and Honkakuha Igo Gosei(FX) - all work as well as the deinterleaved counterparts. - (The last is a hacked game, and you should get the - non-FX version) -- Fixed Seima Jyuden Beasts and Blades. Another Multitap, (Frank Yang) - but for some reason, the hack requires the C cpu core. - Thanks to Tomato for taking a stab at the error message, - as well. It was too vague to be of use, he said. I - just tried it because it worked on other games. -- Res Arcana fixed. Another Frank Yang report, another J (Frank Yang, MKendora) - error, but I can read kana well enough with a table! -- Removed a Terranigma specific hack. Not sure, but the (anomie) - new behavior might have fixed Tin-Tin in Tibet's colors. -- Dirty hack to work around a dirty hack. Both Yoshi's (MKendora) - Island (E) dumps should work now -- Added the JumboLoROM memory map, Extends LoROM support (The Dumper, neviksti, MKendora) - to 48+ Megabits. -- added an EXTBG fix, since iirc, TRAC is using it as well (anomie) - Does it actually fix anything? -- Fixed crash in DSP Op06 (The Dumper) -- Fixed a GUI error on my part (Trigger of Time) -- Cleaned up some of the SPC7110 detection/size code. (MKendora) -- Merged in XBox port changes to SPC7110 code (lantus) -- Added a call to Memory.Deinit when exiting. (lantus, MKendora) -- Many memory leaks fixed while chatting with lantus (lantus, MKendora) -- Fixed that stubborn open/close leak (lantus) - - -1.39mk2 - -- hacked in Shien's Revenge (anomie) -- fixed Orge Battle's green lines. (CPU source for DMA) (anomie) - - Looks interesting, and might apply to other DMA cases? -- maybe "fixed" DKC's barrels? by treating $2001 - as unmapped. The game worked before with a hack. (MKendora) -- optimized SPC7110 slightly by removing extra setup work (MKendora) -- Fixed DBZ 3 (Korean). S. Korea is, in fact, NTSC. (MKendora) -- Fixed a hard-coded value in the SPC7110 (MKendora) -- Added a Win port ROM Info dialog (MKendora) - - some companies aren't in the table I used. - If you encounter an Unimplemented company, - report it the the Snes9x development forum, with - the correct company and the number. - - -1.39mk -- SPC7110 support based on Dark Force's docs. (Dark Force, zsKnight, - The Dumper, MKendora) - Trust me when I say those guys deserve the credit more - than me. From what I'm told, Dark Force is the man - behind most of the reverse engineering, but they all - did a much harder bunch of work than I did following - their specs. It's plain and simple that these three - are the masterminds behind all SPC7110 support. - - Dark Force for reverse engineering the chip (Extremely tough work!) - zsKnight for the original core, and probably other things - The Dumper for dumping the packs and doing hardware tests. - - Also thanks to CaitSith2 for numerous bug reports - and a lot of bug fixes. - -- Theme Park hack removed, fixed via PPU latching (anomie, MKendora, TRAC) -- WWF Wrestlemania hack removed (anomie, TRAC) -- Strike Gunner hack fixed (anomie, MKendora, TRAC) -- FF:MQ text fixed. May help other sprite issues. (TRAC) -- Umi Hara Kawa Se timing corrected. (anomie) -- S-DD1 packs load by the same rules as ZSNES (MKendora) -- SPC7110 code builds in linux (Lord Nightmare, zinx) -- Added The Dumper's DSP-1 updates (The Dumper) -- SPC7110 is correctly displayed on load, RTC also noted. (MKendora) -- Fixed a potential graphics problem (TRAC) - no known games fixed, but who knows? -- Fixed Ballz3D (pagefault) -- Re-fixed Ballz3D, via DSP op 0F (The Dumper) -- included some of anomie's fixes. Many caused me grief, - so only Marko's Magic Football is intentionally fixed. (anomie) -- finished zsnes save support, though I don't know how - well it will work with SPC7110 games (MKendora) -- Added a new soundux.cpp again to fix some noise. - (Fixes the GW "fart track") (Lord Nightmare, info from Anti-Res) -- Added 3 cache modes for SPC7110 games (MKendora) -- Added new BRR decoder. Requires sample caching - and the Anti-Res decoder be disabled. (FatlXception, port by Lord Nightmare) -- Added CaitSith2's RTC debugger. define RTC_DEBUGGER in - project settings to enable it. (CaitSith2) -- SPC7110 per-game cumulative logging (MKendora) -- other fixes that I've forgotten (sanma iwashi, TRAC, anomie, ????) - -- "I'm not worthy" thanks to the original SPC7110 crew (DF, zsKnight, and the Dumper) -- Thanks again to the same people, because they deserve it! -- thanks to The Dumper, Dejap, TRAC, and all the ZSNES crew for technical assistance -- Thanks to most of the Snes9x mods for testing (no thanks to you, Raptor ;) -- and thanks to TRAC and #mkendora for letting me vent at you. - -1.39 -- Added SDD-1 unknown graphics data logging at the dumper's request. A bit late - but might help with Street Fighter 2 Alpha's data dumping. Creates a - romname.dat file in the freeze file folder. -- Implemented 16-bit texture support for OpenGL modes in Windows and Linux. - Had to support a new pixel format type to do it - RGB5551 (one bit of alpha) - which caused me some major problems - black was no longer always pixel value - zero! -- Removed the Bump map OpenGL mode from the Windows port (didn't look so good - anyway and was slow). -- Added a hidden novelty OpenGL mode (clue: a keyboard shortcut activates it) -- Reverted back to FMod version 3.20 after reports that version 3.33 broke - AD3 support. -- Implemented a better work-around for the broken select system call in the - Linux kernel - the original work-around was long-winded and stopped working - when I implemented OpenGL support under Linux. -- Added the same speed-up hack to the OpenGL code that the Glide code already - supported. Basically, if your OpenGL implementation supports 16-bit textures - then OpenGL mode should be as fast, or faster than the 3dfx Glide mode. -- Hopefully fixed Glide support. -- Reverted back to the original colour blending code. The newer code, although - more accurate in most cases, had too many glitches and was slower. -- Included multiple Japanese games fixes from Iswashi San. -- Fixed a timing problem caused by a speed up hack that was affecting Top Gear - 300. No the game still isn't playable yet, but I noticed the problem while - investigating the DSP-4 chip used by the game. -1.38 -- Added support for Star Ocean and Street Fighter 2 Alpha decompressed graphics - packs from dejap. Used a binary chop search rather than a linear search to - locate correct decompressed graphics more quickly - should help emulation - speed during later stages of the game. -- Included OpenGL support into the Linux port and speeded up the Windows OpenGL - implementation slightly. The real speed up would occur if I could figure out - how/if 16-bit textures are supported in OpenGL because at the moment the - 16-bit software rendered SNES image must be converted to 24-bit before being - uploaded as a texture... -- Included the latest ZSNES DSP-1 code. Now Pilotwings, SD Racer and Suzuka 8 - Hours are playable. Aim For The Ace, Super Air Diver 1 & 2 and Syutoko Battle 94 - are also playable, but with bugs. Thanks to zsKnight, _demo_, et al for all - their hard work. -- Another Daffy Duck: Marvin Missions screen flicker problem worked around - - writing to the IRQ enable register shouldn't clear any pending IRQs, but - Sieken 3 seems to require this or else the game hangs. Special-cased Daffy - Duck for now. -- An NMI emulation bug was triggering a Panic Bomberman World game bug, - crashing it. Basically, if a game enables NMIs after the normal trigger - point, the NMI should not trigger if the game has already read the NMI clear - register. -- Panic Bomberman World requires SPC700 memory to be initialised to zero on - reset otherwise the game hangs when a tune finishes and another one should - start. -- Added mouse pointer auto-hide to the Windows port. Much better than the turn - the mouse pointer into a black dot method I was using before. -- Included the latest ZSNES Super FX code. Not sure if it fixes actually fixes - any games. -- Added an offset hack for Strike Gunner to get the scrolling ground layer - to line up correctly - another offset-per-tile bug hacked around for now. -- Arrr! Left in some debugging code in the last release that prevented all - games that need the slower SPC700 timing from working. Removed it. -- Hmm. The broken cut-scenes in Deep Space 9 seem to indicate that I haven't - got the emulated clock speed of the 65c816 CPU correct yet. And not by a - little bit - a 9% too slow error. Hacked special timing for the game for now. -- Added triple-buffering to Windows port - enabling double-buffering actually - enables triple-buffering if you have enough free video RAM, defaulting to - double-buffering if you don't. -- Fixed another crash bug in the interpolated mode 7 code - if no scaling - was being used (either up or down) and screen repeat was enabled and the - screen was flipped horizontally, the routine would crash Snes9x. Was causing - Snes9x to crash during rock monster boss stage of Castlevania 4. -- Oops. Got the initialisation of the default SNES screen width and height - round the wrong way - could cause a X Windows System error message on the - UNIX port after loading a ZSNES freeze file. -- Included the unofficial Windows port emulation fixes for several games including - Kentouou World championship and TKO Super Championship. -- Included Iwashi San's improved Anti Res. sound sample decoding routine and - updated the C version to match. -- Included Anti Res. improved sample decompression code he sent me ages ago, - but for some reason I didn't include. Sorry. This version seems good enough - to leave enabled all the time. -1.37 -- Added fix for Captain America's corrupt graphics - a ROM bug causes it to - read from what I thought should be an unmapped memory area, but it expects - the value returned to be zero. -- Added code to support games that switch to the hi-res. SNES screen mode part - way down the screen while using the 3dfx bi-linear filter mode. The code - basically has to back out of the speed up hack it was using when the game - switches resolutions. -- Fixed support for games that have mixed lo-res. (256x224), medium res. - (512x224) and hi-res. (512x448) all on the same screen - corrects the display - of Majin Tensei 2. -- Added support for games that use sub-screen addition to the back-drop layer - while displaying hi-res. graphics - something I thought the SNES couldn't do - but the game Marvelous uses this. -- Reworked the UNIX/Linux output image handling code: the image doesn't always - have to be scaled when hi-res. support is enabled, the PutImage operation - only updates the area of the screen it has to, the SNES image is now always - centred in the window/full-screen area and if the SNES image changes size - between frames, the old screen areas are now correctly cleared. -- Fixed the corrupt graphics problem during the battle scene of Last Bible 3 - - it requires that previously unknown DMA mode 5 should just act the same as - DMA mode 1. -- Fixed a nasty bug when H-IRQs were being reused on the same scanline - a logic - bug could cause H-DMA processing for that line to be skipped. Was causing - the bridge and the start banners to be the wrong colours in Top Gear 2. -- Added Kreed's display processing modes to the Linux port, including his new - asm version of the Super2xSaI mode and the new software bi-linear filtering - mode. -- Think I might have figured out the odd Mode 7 glitch problems the games - Illusion and Gaia and Chase HQ were having. My original fix was to mod the - centre X & Y values with 1024, but looks like the true fix is to mod - X + horizontal offset and Y + vertical offset with 1024 when screen wrapping - is enabled. -- Disabled H-DMA'ing into V-RAM via registers 2118/2119. The game Hook - deliberately does this causing graphic corruption while dialog boxes are - displayed. Maybe the real SNES disallowed this and it was left in the game by - mistake? Not sure what effect the game was trying to produce because - disabling the emulation of this feature doesn't seem to affect the game at - all, other than stopping the corruption. - + Also fixes graphics junk problem on first screen of Bugs Bunny. -- Added a 'region-free' timing hack for Power Rangers Fight - without it the - NTSC version was displaying badly glitching graphics; I'd already fixed the - PAL version. -- Added true priority-per-pixel mode 7 support (the previous support was just - a hack to get the colours correct) - level 2 of Contra 3 used this feature. -- The Japanese, German, French and Spanish version of Illusion of Gaia needs the - slow SPC700 timing. -- Deleted the Breath of Fire 2 S-RAM hack for the hacker intro version - - according to reports it was causing problems for the non-hacked version. -- Legend, the PAL version, never sets the sound master volume control - Snes9x - was defaulting this to off, I guess the real SNES must default it to full - volume; changed Snes9x. The NTSC version of Legend does set the master - volume level, but sets it to off just after the title screen. Hmm. The -nmv - command-line switch allows you to hear sound in this version. -- Panic Bomber World was tripping an SA-1 emulation bug - the WAI instruction - emulation code was setting the 'waiting for interrupt' flag on the wrong CPU - causing the main SNES to skip an instruction when the next interrupt occurred. -- Panic Bomber World, Bomberman 4 and UFO Kamen Yakisoban all need the slower - SPC700 timing. -- Oops! The Super Formation Soccer 95 fix was causing Aero 2 to lock up. This - means I have no no idea what value the DMA in progress register should - represent. I've hacked it and made it toggle between 0 and $ff on each read - which gets both games working, for now... -- The ROM de-interleaving code always assumed the blocks were rearranged based - on a power of two, but Francois found a copy of Soldiers of Fortune where - this was not the case. Corrected the code. -1.36 -- Finally worked out why the menu items weren't being highlighted in several - ROMs, including Battletoads, U.N. Squadron and All Japan Pro Wrestling. - Two problems: its seems the SNES does halve the colour value result when - blending colours when only the fixed colour addition/subtraction is enabled, - but doesn't halve the result when sub-screen is being blended and its a clear - part of the sub-screen. The second problem was that I had an optimisation - that prevented the time consuming colour blending code from being called if - the colour being added/subtracted was black - adding zero to a number doesn't - affect the result, but not performing the side-effect of halving the result - does affect the final value... -- Super Formation Soccer 95 requires that the DMA enabled register doesn't - always return zero, otherwise the game locks up. -- Thanks to several people reporting a screen flickering problem in the - pseudo 3-d section of Jurassic Park 2 I've fixed a nasty problem in H-IRQ - handling code which could cause double-triggers or skip IRQs altogether. - With this fix I can now remove the special hacks for Ninja Warriors Again, - Chuck Rock and F-1 Grand Prix. -- More games needing the slow SPC700 timing: - Zennihon Puroresu 2, Soulblazer and Robotrek. -- The CPU idle time skipping code was skipping cycles during a software delay - loop in Itchy and Scratchy, causing screen flicker. -- Looks like reading the value of register $2137 shouldn't clear a pending - IRQ - was causing screen flicker on Yoshi's Island. -- Actraiser 1 & 2 both need the slow SPC700 timing. -- Terranigma reads a sound channel's current sample output value and waits for - it to be zero before preceeding. I forgot to always return zero when a - channel was silent. This mistake was causing the game to lock up. - + Itchy and Scratchy and was causing the music to stop and samples to be cut - short in the Mario Early Years series. -- Added a hack for Secret of the Evermore - at several points in the game, just - as the plane is about to land, it reads from unknown registers $4000 and - $4001 and, if it doesn't get the value its looking for, the game hangs or - displays corrupt graphics. -- Silva Saga 2 was accidentally triggering a colour blending hack I put in - place Kirby Dreamland 3 and Kirby Superstar. -- The ZSNES freeze-file loading code could leave a file open if the file wasn't - a valid ZSNES freeze file. -- Super Punch-out requires certain DMA registers to be updated after the DMA - completes. Snes9x used to do that, but I must have accidentally left the code - commented out whilst investigating a different problem in another game. -1.35 -- Added a recently played game list to the Windows port File menu so you can - quickly load up your favourite games. -- Included IPS patching support based on code from Neill Corlett - just rename - the patch file to match your ROM image name but with a .ips extension and - copy it into your ROM or freeze-file folder. -- Added John Weidman's and Darkforce's S-RTC, (Real Time Clock) emulation code. - The only game that seems to use it is Dai Kaijyu Monogatari II. -- Included code from Nose000 for games with 128Kbytes of S-RAM. Now - Sound Novel-Tcool, Thoroughbred Breeder 3, RPG-Tcool 2 and Dezaemon are - supported. -- The Windows port now has an option to make the 'turbo speed' button a toggle - button. -- The optimised fixed colour addition/subtraction code was ignoring the colour - window. Thanks to John Weidman for pointing this out. -- Added mode 7 and hi-res. hack for Dezaemon from Nose000 - the mode 7 hack - looks interesting (to me); I wonder if some other games would benefit? -- Both Tales of Phantasia and Star Ocean need custom sound CPU timing. Hmm. - That's 4 ROMs now, there will be more... That means I still haven't - discovered all the major SNES timing quirks. :-( -- Windows port now has an option to save the S-RAM data at any time. -- Windows port saving SPC dumps now auto-increments the filename. -- Added work-around for a Super Robot Wars Ex ROM bug - the game was checking - the wrong PPU register for end of h-blank. The game must have only worked by - chance rather than by design on a real SNES. -1.34 -- Corrected the colour addition/subtraction and halve the result code not to - halve the result when only the fixed colour is used, i.e. the sub-screen is - clear. Discovered and fixed this awhile ago, but I accidentally reintroduced - the bug when adding some optimisations a few versions back. -- Finally cleared the last of the offset per tile background mode bugs. There - was something odd about the tile at the left-hand edge of the screen that I - couldn't figure out - well now I have. Yoshi's Island level 6 boss screen, - Mario RPG mine cart screen and Jim Power title screen now all display - correctly. -- Made reading blank areas of the SNES memory map return the middle byte of - the address - fixes Home Alone which tries to execute code in an empty part - of its memory map but only works because the real SNES seems to return the - middle byte of the address - $60 in this case, which corresponds to the - ReTurn from Subroutine instruction. -- Added auto-cycle skipping disable for Earth Worm Jim 2 and several other - games that spool sample data using H-DMA as the sample is being played. - Improves some sound effects in these games. -- Fixed joy-pad routines to only report up or left if down or right are also - pressed respectively. Works around a game bug in Empire Strikes Back in the - asteroid stage where the game crashes if both left and right are pressed - - something impossible to do on the original SNES game-pad. -- Added custom SPC700 timing for Rendering Ranger R2 - the game now works with - full sound. No idea why it needs custom SPC700 timing. -- The ROM type detection was broken for Treasure Hunter G and Test Drive 2 - - fixed the code so type 2 ROMs can be LoROM. -- Adjusted the main CPU cycles per scan-line from 341 to 342 to give an exact - match for the timing required for Earth Worm Jim 2. All EWJ2 needs now - for perfect sound emulation is a method of synchronising the emulation - speed to the host hardware's sound card playback rate, oh, and a fast CPU! - The Linux port already has this but seems to be broken because games - play at double-speed when this option is enabled. -- Some SPC700 code in Earth Worm Jim 2 seemed to prove that I had guessed the - clock speed of the SPC700 sound CPU incorrectly - out by almost a factor of - two, in fact. Changed the relative emulated clock speed of SPC700. Now - Chrono Trigger doesn't lock up at certain points anymore, the special SPC700 - timing for games written by the Human Software company isn't required and - you can hear some more of the sound samples in Earth Worm Jim 2, etc. -- H-IRQ triggering code was broken - if a ROM turned on H-IRQ but later turned - it off, Snes9x could continued to generate H-IRQs, crashing some games. -- Added a generic test for Human Entertainment games - they need special - sound CPU timing to work. Gets Taekwon-Do working. -- Disabled offset-per-tile mode for Theme Park; the world map screen is corrupt - with it enabled. -- Yet more changes to the offset-per-tile backgrounds modes 2 and 4. Added - 64 tile wide screen support for Mario RPG's mine cart ride and fixed multiple - bugs with the handling of horizontal offset-per-tile used in Chrono Trigger's - fade in of the space ship. -- New feature: Snes9x can now load ZSNES freeze state files! Just copy them - into the freeze file folder and Snes9x will load them when you load a freeze - file, but only if the corresponding native format Snes9x freeze file doesn't - exist. -- Added memory map hack for Batman - Revenge of the Joker: its ROM header block - is in the wrong location and Snes9x incorrectly detected its ROM type. -- Fixed an off-by-one-pixel clip window 2 bug when the window was set to clip - outside the window area; clip window 1 was already correct. Removed the bright - line bug at the left edge when the combat screen is appearing in Starfox and - the clip problem when text boxes zoom-out in Yoshi's Island. -- Jim Power's title screen seems to prove that the per-tile offset data on - mode 2 isn't ignored for the left most tile as I originally thought. - Modified the code. -- The recent timing changes highlighted another problem with Daffy Duck - - changed IRQ enable register to only clear pending IRQs if one has been pending - for several microseconds. -- Speeded up the sprite data register handling slightly. -- Finally got Aero the AcroBat 2 working, after many hours of investigation, - spread over several years - literally! Two problems. The SNES doesn't seem - to consider scan-line line zero to be part of the v-blank period even though - the line is never drawn and V-IRQs at the start of the scan-line have to be - delayed until a few microseconds into the line - Traverse: Starlight & Prairie - required this as well, so I removed the original, Traverse specific hack. - There's a problem with the in-game music that I'll investigate at a later - date. - - The in-game music problem just required ENVX emulation to be switched on, - off by default on the Linux port, on by default on the Windows port. -- Fixed the mode 7 corruption problem on the title screen of Chase HQ using the - same trick as Illusion of Gaia - i.e. mod the mode 7 centre X & Y values with - 1024. -- Fixed another crash bug in the interpolated mode 7 code - a portion of - the code was ignoring the screen flip value and the fact that X render - direction reversed if the screen was flipped horizontally. Was causing a - crash on the whale boss screen of Kirby Superstar. -- Mortal Kombat 3 now auto-adjusts emulated cycles per scan-line work-around - a speech sample being cut short. -- Added sample data register reading support to the sound DSP - somehow I - seem to have missed implementing this. Not sure if any ROM actually reads - the value. -- Followed Sumire Kinoshita's suggestion and stopped clearing the ENDX flags - when the value is read, against my better judgement, and it does actually - improve speech samples in several games. Ooops! The Mortal Kombat series, - Magical Drop 2 and Metal Combat are the ones I've discovered so far. -- WWF Arcade now auto-adjusts the cycles per scan-line value to work-around - a sound sample repeat problem. -- Hmm. There's something about offset-per-tile mode I don't understand - WWF - Wrestlemania Arcade is getting corrupt graphics; not sure what effect the - ROM is trying to produce. Disabled offset-per-tile mode for the game for now. -- Fixed Street Racer player 1 wobble problem during the soccer game by auto- - adjusting the cycles per scan-line value slightly. -- Made Power Rangers Fight auto-adjust emulated cycles per scan-line to work - around a slight timing problem that causes an NMI to corrupt register - values that an IRQ handler is trying to update. Without it the scrolling - back-drop and fighter graphics are corrupt. -- Illusion of Gaia seems to need the mode 7 centre X & Y values to be mod 1024 - if the screen repeat flag is set. Fixes the island fly-over bug right at - the end of the intro but breaks a few other games. Hmm. Made it auto-switch - on for this game only. -- Added memory map support for Radical Dreamers. Thanks to satellite hut master - for the information. -- Made updates to the top bit of the sprite write address register be ignored - unless the low byte had been written to first. A ROM coding bug in - James Pond II requires this, otherwise it writes a junk byte value into the - main character's X position and Robocod wobbles around all over the place. -- Reverted back to pre 1.31 way of initialising unknown register values - - Rock and Roll Racing was reading a junk register value and using the value - to set up DMA, which in turn was causing corruption on the player select - screen. -- Added Star Ocean memory map - thanks zsKnight! The original ROM I was testing - was corrupt, no wonder I couldn't figure out the memory map myself! The game - still isn't playable, though, due to missing S-DD1 graphics decompression - (+ encryption?) emulation. -- Started to dump some compressed data values from Street Fighter 2 Alpha in - the hope that one day someone will be able to crack the S-DD1's compression - algorithm. -1.33a -- C4 emulation wasn't being automatically enabled for Rockman X2 / X3 - the - Japanese versions of Megaman X2 / X3. -- Fixed the Super FX plot table pointer that I accidentally broke while saving - 1Mb of workspace RAM - it was stopping all Super FX games from working. -1.33 -- Noticed another problem with the CPU_SHUTDOWN code - Chrono Trigger locked - up during the intro but only when using the asm code CPU core. Found the - algorithm difference between the code and made the CPU match what the C - version was doing. Still not sure why it caused a problem in the first place. -- Changed colour subtraction code to use Lindsey Dubb's newer version he sent - me some time ago but I 'forgot' to include. I say forgot, but I really put - off including it because, although it improves most games that use the - effect, it does result in one or two slight visual glitches. -- Hacked in zsKnight's C4 emulation asm code - now both Megaman X2 and X3 are - playable. Still got to complete the reverse engineering of the i386 asm code - to C so other, non-Intel ports can have C4 emulation. -- Shuffled the keyboard mapping a bit on the Linux port so now Tab key acts as - an emulation speed turbo button, `, # and ~ act as superscope turbo and - / acts as the superscope pause button. -- Fixed asm CPU_SHUTDOWN code that I accidentally broke while trying to - optimise it! Thanks to all the people who noticed Snes9x's frame skipping - had changed between releases. Frames rates should be improved again for more - than 50% of games. -- Re-enabled in-lining of the C SNES memory access routines, improves frame - rate by one or two on slower machines. -- Optimised the asm 65c816 addressing mode emulation code a little. -- Included some code changes making life easier for the Mac porter, John Stiles. -- Added memory map support for Sufami Turbo using information supplied by - Nose0000. No idea if it works because I don't have the ROM. -- Spent a few minutes trying to figure out the Star Ocean memory map so at - least the sound effects could be heard. But gave up after a couple of hours - due to laziness. If anyone knows the memory map details, let me know please! -1.32a -- The delay loading of the OpenGL DLLs on the Windows port was causing the - OpenGL initialisation code to fail. Reverted back to normal DDL loading but - with the side effect that Windows 95 users must visit the Microsoft web site - and download the OpenGL add-on before Snes9x will work for them. -- Corrected the OpenGL bump-map display option - my attempt to get the - bi-linear OpenGL display option to work with Voodoo card's limited texture - size had broken the bump-map mode. -1.32 -- Changed the Windows port to delay load the two OpenGL DLLs, so now they're - only loaded if you switch to OpenGL mode. The original version of Windows 95 - didn't include the OpenGL DDLs, so Snes9x wouldn't even start on that - platform; now it should. -- Added yet another sound buffer option to the Windows port - this time the - block size of sound data to mix. Some DirectSound sound card drivers only - report the play position moving in steps rather than continuous amounts and - Snes9x's default mix block size turned out to be smaller than this step - value on several cards. - Snes9x couldn't work out out where the true play position was accurately - enough resulting in broken, noisy sound output. -- Modified the Windows frame timer code to use semaphores rather than events - - they should make Snes9x more reliable at not missing frame sync pulses when - Windows is busy doing background tasks. -- Added SA-1 shutdown code - basically, Snes9x now stops emulating SA-1 CPU - instructions when the SA-1 enters an idle loop waiting for the main SNES - CPU to give it something to do. All SA-1 run much faster and smoother now. -- Added multi-axis joystick/game controller support to the Windows port and - tweaked the dead-zone threshold position a little. -- It looks like the SNES PPU was designed to support 128K of V-RAM but only - 64K was fitted; Snes9x wasn't wrapping all V-RAM address to stay within the - 64K limit causing a corrupt title screen on ReX Ronan - there will be others. -- Added amend functionality to the Windows Cheat Entry dialog and added extra - text boxes for direct address and cheat value input rather than only being - able to type in a Game Genie or Pro-Action Reply code. -- BS Suttehakkun2 was crashing just before start of play - the ROM was - performing a junk DMA that was corrupting RAM, crashing the game when it - went searching for a particular value. -- F-1 Grand Prix requires IRQ triggering when IRQ scan-line register set to - current scan line, but Chuck Rock objects. Hmm. Chuck Rock seems to indicate - the CPU emulation is running too fast, but I can't see where the mistake is. - Special-cased Chuck Rock for now. -- Optimised SNES DMA handling slightly - copying data to SNES V-RAM is now - significantly faster. -- Windows Cheat search dialog was ignoring data type parameter in various - places which was causing problems when larger numbers were being searched - for. -- Forced unknown PPU register reads to always return 0 - a coding bug in - Equinox shows that this is required. An earlier fix didn't work. -- Puya Puya 2 & remix were objecting to an NMI being triggered when enabling - NMIs after scan-line 226, but Ys 5 seems to require this. Hmm. Added a hack - to support both games. -1.31 -- Snes9x DirectSound code modified - the mixing block size is now always 10ms - for Windows 95/98/2000 and 20ms for NT 4.x, now there should be no need to - enable Sync Sound when a large sound buffer is required (helps emulation - speed). The maximum sound buffer length values have been updated to reflect - the smaller mixing block size. -- Changed the DirectSound code back to use an offset from the play position - as the place to write new sample data into the sound buffer - on NT 4.x the - write position seems to vary randomly rather than being a fixed distance - in front of the play position as documented. Now I know why I used the play - position originally! -- Changed the DirectSound code to fill the sound buffer at the write position - supplied by DirectSound, rather than just before the current play position - - should help reduce latency. -- Added an auto-detect method for interleaved mode 2 Super FX ROM images - - well, not really auto-detect: if the game crashes and its a Super FX game, - Snes9x assumes its in interleaved mode 2, de-mangles the ROM image and tries - to run the game again. -- Had to update the Snes9x Windows registry version number as the additional - diagonal settings make old registry settings incompatible. -- Added diagonal keyboard controls to the Windows port, as requested by - several users. -- Changed PPU code to return zero when reading non-existent registers - the - game Equinox relies on this due to an original game coding bug. -- Included FMOD sound driver support to Windows port - people experiencing - broken sound or delayed sound, etc, might want to give it a try. -- Tales of Phantasia - un-interleaved format ROM memory map changes to match - odd ZSNES format, now the hacked ROM works. -- Changed NMI again. Made reading or writing to PPU register 0x4210 - clear NMI pending flag again, without this Super Tennis does not work. -- Changed NMI timing back to be the same as several versions ago and just - special cased Cacoma Knight instead - although kept the code to prevent - the re-triggering of an NNI more than once in the same frame. -1.30 -- Forgot to force GUI surface to be displayed when some dialogs where popped - up - problem only happened on full-screen mode with triple or double - buffering enabled, or when using 3dfx mode. It appeared as if Snes9x had - locked up, but pressing Esc would pop down the hidden dialog. -- Added a couple of options to the Settings dialog. Now its possible to - disable S-RAM auto-save which was causing Snes9x to write to the hard disk - every 30 seconds on some games, causing the occasional skipped frame. -- Fixed Reset option which was accidentally broken when Netplay support was - added. -- Added support for Dirt Racer - it leaves the Super FX chip running all the - time, so the default CPU emulation method never allocated any time to other - CPUs and the emulation seemed to lock up. -- NMI timing changed again. Now an NMI can only be triggered once per - frame and enabling an NMI after the normal trigger scan line triggers - an NMI immediately. This fixes display glitches in Ys 5, Stargate and - Daffy Duck. -- Fixed the WAI instruction to only 'wake up' once an actual NMI has - triggered, rather than just waking up when it should have triggered. - This fixes Battletoads, broken since version 1.29(ish). -- Changed NMI again. Made reading or writing to PPU register 0x4210 not - clear NMI pending flag. Seems to allow all the NMI timing sensitive ROMs - I had on my list to now work without any special hacks. Illusion of - Gaia now works again. -- Another NMI fix - cleared the CPU pending NMI flag at start of frame; - Battletoads intro was crashing without this. A long DMA was stopping the - SNES CPU so it couldn't and shouldn't respond to the NMI signal from the PPU. -- Fixed Netplay problem when game didn't have any S-RAM and Sync Using Reset - was being used. An error dialog was displayed and the client would disconnect - from the server. -1.30b#1 -- The Windows auto-frame skip code was broken - badly. It didn't re-sync a - timer value with timer events being generated, causing Snes9x to deliberately - stop and wait for an event when it didn't need to, slowing down the overall - emulation speed and increasing the number of frames skipped. -- Improved the Windows cheat search dialog - its now possible to compare - against a value and more comparison functions are available. -- Finally worked out why Voodoo 3 support was so buggy in Snes9x - the Voodoo 3 - card generates a WM_DISPLAYCHANGE message when switching to Voodoo mode (the - Voodoo 1 and 2 cards don't); Snes9x thought that some other application had - changed the screen depth or resolution and tried to adjust its window to - match - triggering another WM_DISPLAYCHANGE message. No idea how the code - worked at all; it must have been only by chance and very dependant on the - driver version you were using! -- Implemented Netplay on the Windows port - but its buggy as hell. I seem to - be having major Windows multi-threading problems. Comments I've seen seem to - suggest that Windows 95/98 don't implement true multi-threading; hmm... -- Not happy with the current Netplay, so I scrapped it and tried again; - the protocol is much improved and not using select to control game timing - seems to have removed lots of the threading-type problems I was having. -- Attempted to switch to just using Borland's C++ Builder to build the Windows - port - and failed, again. Although C++ Builder can build Snes9x from sources, - it can't then link in the asm CPU cores. I had hoped Borland might have - fixed this with their latest release - they haven't. -- Several attempts to get Anti Resonance's super-fast sound CPU and sound DSP - code working in Snes9x, but all failed. Part of the problem was his code was - written using TASM and the object files it generated would only work under - Windows - but all my SNES debugging code was in the Linux port. Anti' fixed - that, and I then had some success getting his code working, but its just too - unstable at the moment for a main-stream release. -- Included an option to use Anti Resonance's alternate sample decoding routine; - it can approximate the wind and noise sound effects heard in several Square - Soft games. -- Thanks to Lindsey Dubb for the mode 7 bi-linear filtering code - it - generates a nice smooth image when a game scales the screen using the SNES' - mode 7, but you'll a fast machine if you don't want the frame rate to drop. -- Thanks again to Lindsey Dubb, he improved the colour addition/subtraction - subtraction routines - they are just a little slower but now mostly perform - full 15-bit precision addition and subtraction rather than the previous - 13-bits of precision. Many more colour shades can be seen - look at the - improved shading on the Mario Kart or F-Zero track for example. -- Added a reverse stereo option, for people with sound cards that swap the two - channels. -- Added a sound config dialog to the Windows port - now you can access extra - sound options that have always been there, but just no GUI interface to - access them. -- Fixed the 32-bit windowed support on the Windows port. -- Adjusted the NMI timing by a few microseconds to get Metal Warriors working - again. -- Added a few more sound playback rate choices. Most modern sound cards allow - any value to be used from a large range, rather than just a select few, may - be I ought to add text field so you could just type a value in? -- Used Factory Setup 4 to build a new installer package for the Windows port - - just shipping a zip file was confusing novice users and many (mostly AOL - users) seemed to have an odd program mapped to .zip files, further confusing - the issue. -1.29 -- Disabled the SPC700 noise feature simulation used by Chrono Trigger and - Final Fantasy 3 until I work out why its being triggered by sound effects - that don't use it. -- Rewrote/reorganised the DirectX and 3D/fx handling code, now both are never - enabled at the same time in Snes9X. It might fix the crashing problems some - Window port users are seeing. Changing between DirectX and Voodoo 3D/fx - modes now requires Snes9X to be restarted. -- Tracked down and fixed the Chrono Trigger black screen problem on the Windows - port: a rogue asm instruction was left in by mistake after some code edits - - it was only by chance that the code worked on the Linux port. -- Added some SNES debug options to the Windows port, but disabled by default, - on the shipped version. -- Clicking on the column headings in the OpenROM dialog in the Windows port - now sorts by that column; plus added some slight screen update optimisations. -- Added an optimisation to graphics rendering: don't add or subtract - sub-screen from background layers, or clear the sub-screen, if SNES fixed - colour is black and no background layers are enabled on sub-screen, even if - ROM tries to enable translucency effects for every background layer. - Discovered Sonic was doing this, there will be others. -- Forgot to enable auto S-RAM save on Windows port, oops! -1.28 -- Warning dialog added to the Windows port - if a ROM is loaded from a - read-only directory, e.g. a CD, and the freeze file folder is set to be the - same as the ROM image folder, then a warning is displayed when the game first - starts. -- The Windows port now supports 5 joy-pads - Snes9x always did support 5 but - the Windows port lacked the GUI option to enable and configure it. -- Added an about dialog to the Windows port. -- The Windows port now has a simple settings dialog, only one option so far - - changing the freeze file and S-RAM save directory; much better than having to - use regedit at least. -- Added a new cheat search dialog, you can use it to find where games are - storing life counters, health levels, etc. and then add cheats that stop the - values from changing. -- Added a cheat code entry dialog to the Windows port; now Game Genie, - Pro-Action Replay and Gold Finger codes can be graphically entered and - edited. -- Added a master cheat codes on/off toggle, available from the Cheats menu - on the Windows port. -- Extended the number of cheats per game from 10 to 75. -- Changed cheat code to reapply cheat every emulated frame so if RAM is being - patched the cheat value is continuously applied. -- Wrote some new cheat search code, the code won't be useful until I get around - to writing a cheat search dialog. -- Added automatic cheat code loading and saving using the same file format as - ZSNES. -- Rewrote large parts of the Snes9x cheat handling code ready for adding - cheat dialogs to the Windows port. -1.27 -- Added a flag to only enable SPC700 noise 'feature' when Chrono Trigger or - Final Fantasy 3 are loaded - the conditions that I thought were necessary to - trigger the feature where sometimes being met by other games. -- Added a simulation of the SPC700 noise 'feature' where some games, notably - Chrono Trigger and Final Fantasy 3, play samples that deliberately overrun - outside a 16-bit value, the SPC700 sound DSP then for some reason starts to - generate a type of noise sound which the games use to generate wind and - swish type sound effects. Thanks to ZSNES for some of the information. -- Fixed another sound interpolation problem, thanks to Mikael Bouillot - - the initial value of the sample byte being played was not being set correctly - when processing fractional offsets. -- Added auto S-RAM save option; S-RAM is automatically written to a .srm file - a few seconds (30 by default) after a ROM writes to it - useful for people - who were playing games long into to night, only to lose their progress - after a power cut or machine crash. -- NMI delay code changed again - the fix for Cacoma Knight was breaking - Tuff E Nuff; it would seem delaying NMI until the start of h-blank to too - long, added a cycle counter instead. -- Fixed yet another clip window bug - clip window was being incorrectly set - at no range if colour window was enabled but background layer clip window - was disabled (meaning layer should not be clipped). - Fixes the sunken ship level on FF5. -- Worked out (by example) how to add keyboard accelerators to the Windows port, - now toggling full screen using ALT+Return works. -- Added mouse-warp to the Windows port so the the cursor doesn't wonder off the - Window while SNES mouse emulation is enabled. -- Improved 3dfx support on Windows port - load dialog doesn't drop out of - bi-linear mode and underlying window zooms to full-screen so its easy to find - and click on the menu bar with the mouse. -- Added Mouse and Superscope SNES emulation support to the Windows port, use - '7' on the keyboard to select. -- Windows cursor now hidden unless super scope emulation is enabled. -- Windows port now has command line parsing - cheapo way of adding Game Genie, - Pro Action Replay cheat codes, disabling sound CPU emulation for the - corrupt copy of Star Fox 2, etc. Also allows ROM images to be dropped onto - the Snes9x icon. -- Cacoma Knight seems to provide proof that Snes9x triggers the SNES - non-maskable interrupt (NMI) too early. Changed interrupt to trigger at the - start of the next horizontal blank period. Will have to watch for it - causing problems for other ROMs. -- Added a translucency hack - when a ROM tries to create a stipple background - pattern by enabling pseudo hi-res. and not enabling a background layer on - one of the screens, Snes9x changes the effect to use transparency effects - instead (the real SNES can't do transparency effects with pseudo hi-res. - enabled). Now the water in Kirby 3 is translucent. -- SA-1 CPU reset bug fixed, now Jumpin' Derby boots and plays but with major - graphics problems. -- Fixed nasty asm SA-1 custom hardware read/write bug that was causing the - course map not to be displayed on Augusta Masters and Pebble Beach. -- Added SA-1 character conversion DMA support for all SNES depths, now - Augusta Masters and Pebble Beach work. -- Merged in minor code changes for Linux running on the Alpha processor. Thanks - to Sadruddin Rejeb for the changes. -- Added four more auto-multi-player-adaptor-emulation-off presets based on - code from Mystagogus. -- Added DirectX3D output image processing support to the Windows port... and - removed it again because it causes my desktop machine to lock up. Back to - the drawing board... -1.26 -- Fixed memory leak that crept in when SA-1 support was added when loading a - game freeze file. -- Added SPC dumping option based on code from Cyber Warrior X that he sent me - ages ago but I've just found again while looking for something else! -- Merged in most of the Amiga PPC port source code changes into the main - source code tree. -- Keying on a sound channel seems to clear its last-sound-sample-block-just- - played flag. Chaos Engine/Soldiers of Fortune needs this. -- Add multi-thread support to the UNIX ports for sound playing - required in - the Linux port to work around a Sound Blaster Live driver bug and useful if - you have multiple CPUs in your machine to help spread the emulation workload. -1.25 -- Added BS 24Mbit ROM memory map, for Derby Stallion 96 and Sound Novel-TCool. - No idea if it works. Thanks to Nose0000 for the info and code. -- Corrected unzip code not to loop forever if an encrypted zip file is loaded - - an error is generated instead. -- Changed relative SPC700 cycle length for Mortal Kombat 3 to fix sample - repeat problems - I wish I knew exactly how fast the SPC700 is clocked. - Maybe I should write a test ROM and run it on a real SNES? -1.24 -- 3dfx speed hack back again, only disabled when Seiken 3 is loaded. -- Some minor SA-1 speed ups added - the SA-1 instruction skipping code will - have to wait until I have more time. -1.23 -- Corrected a SA-1 reset bug that reset the SA-1 RAM bank pointer back to block - zero but didn't clear the RAM bank register. Was causing Kirby 3 to crash. -- Fixed a wave clipping problem with interpolated sound that was causing noise - on sound output when certain sound samples were played. -- Fixed a bug in the sync-sound code that could overrun the sound buffer by a - few bytes causing clicks on the sound output. -- The sound sample repeat bug that has plagued Snes9x ever since is was called - Snes96 finally bit the dust - Snes9x continued to play sample loops - even if the game dynamically updated the sample not to loop. Fixes the - stutter in the Mortal Kombat series and improves the sound from several games - that download sound samples in real-time as they are played. -- Rewrote the code the handled the SPC700's 64 byte shadow RAM area to fix a - possible sample corruption problem with ROMs that stored samples that - cross the 64 byte start area. -- Added code to allow ROMs to change the sample being played the next time the - channel loops or is keyed on - not sure if it fixes anything but seems more - correct. -- Added a zero-frequency fix to the stereo sound mixing code that I'd already - added to the mono code some time ago. -- Changed the code to set the end-of-sample flag just before the last block is - played, rather than just after. Seems to help improve the sound on some - games. -- Sound sample start code now doesn't reset the channel's envelope volume level - to zero before starting the sample - helps reduce the clicks being heard when - a channel envelope volume level hadn't reached zero before being keyed on - again. -- Changed initialisation of sample-end-register to 0 rather than 255 - seems - more logical now I've thought about it. Not sure if it helps anything. -1.22 -- Finally fixed the corrupt copy of Donkey Kong Country not working problem - - Snes9x thought the ROM used the same memory map as Street Fighter Alpha 2. -- Added explode, un-shrink and un-reduce decompression modes support to the - unzip code. -- Fixed offset per tile bug that crept in after me trying to fix the Starfox - on-tilt bug. -- Made some fixes to the C Super FX emulation code, enough to get most 'FX - games playable on the Mac port. -1.21 -- Finally worked out how character DMA worked on the SA-1 and implemented a - hacky, slow version, but its enough to get the level up screens displaying - correctly on Mario RPG. -- Incorporated ZSNES' new optimised Super FX asm code - had to track down and - fix a nasty memory overwrite bug in the code first to get it to work. -- Changed sample mixing code to not automatically wrap offsets to - keep inside the sound buffer, external port code is now expected to do that. - Helped me fix a problem in the Windows port that prevented very large sound - buffers from working, which are required for some badly written sound card - drivers. -- Corrected a bug in the SA-1 C code where incorrect processor emulation - functions where called if the code was compiled with in-lining turned off. -- Fixed crash bug in Super Mario RPG on the level up screen - forgot to mask - the enable bit from the RAM bank register. Thanks to Christian Wolf for - sending me a freeze file which made it easy to find the problem. -- Fixed a lockup bug in the window clipping code, if the ROM ever turned off - the sub-screen completely the clipping code would enter an infinite loop. - Fixes The Cartoon Addams. -- Made the Daffy Duck NMI fix only enable when Daffy Duck is loaded - fix was - causing problems for Breath Of Fire 1 and 2. -1.20 -- Windows port no longer sets DirectSound to exclusive mode, so its now - possible to hear sound output from Windows apps while Snes9x has focus. -- Fixed the freeze file loading and saving on the Windows port. -- More GUI settings are saved in the registry on the Windows port now. -- Added 3D/FX image scaling/filtering support to the Windows port. -- Added the TV mode from the Mac/Linux ports to the Windows port. -- Incorporated Kreed's new output image routines into the Windows port that - fixes RGB555 display colour problems. Many thanks to Kreed. -- New auto-frame rate timing code on the Windows port, stops the silly speed - up problems when the old code tried to 'catch up' after the emulator had - been paused. -- Increased the DirectSound secondary buffer length on the Windows port to - hopefully fix all the static/broken sound output problems some people were - experiencing. -- Altered the ZSNES Super FX asm code so the Windows port could use it - all - previous versions of the Windows port were shipped using the C Super FX - emulation code which is a lot slower. -- Implemented interpolated and sync-sound options on the Windows port. -- Added an image stretch option to the Windows port - stretches the SNES image - to fill the whole screen or the Window. Looks really good on my TNT card - since that chips seems to filter the image as it scales it. -- Implemented Windowed mode on the Windows port. -- Added special SPC700 cycle timing for Empire Strikes Back. -- Fixed the missing polygon problem for Super FX games - thanks to zsknight - for the information. -- Implemented SA-1 support required for Mario RPG, Kirby Superstar, - Paradius 3, etc. but since only a good image of Mario RPG exists, I could - only test that game. -- Fixed a graphics clip window bug: inverting the area of a clip area that - only consisted of empty bands should become the full width of the screen; - Mario Kart's rear-view mirror display needs it. -- Fixed mode 7 render code to use correct z-buffer when rendering onto the - sub-screen. Fixes Final Fantasy V title screen. -- Added horizontal offset per tile support in the offset per tile modes 2 - and 6, and switchable horizontal/vertical offset in mode 4. Fixes Chrono - Trigger in several places and Mario All Stars title screens. -- Changed SPC700 relative cycle length to 14, needed for Stunt Car Racer. -- Enabled immediate triggering of NMI if NMI enable flag set while scan-line - was on first line of v-blank. Needed to fix a background jitter bug in - Daffy Duck: The Marvin Missions. -- Altered ROM load code to ignore corrupt ROM map type byte in ROM header, - preventing the code erroneously detecting what it thinks are interleaved - ROMs. Fixes EEK! The cat, Formation Soccer, the corrupt copy of Donkey - Kong Country, ... -- Disabled IRQ re-triggering if V-IRQ registers set to the current line. Fixes - Chuck Rock. -- Fixed missing sprites in Andre Agassi Tennis - writing to low byte only of - the sprite write address register seems to also clear the hi-byte. -1.19 -- Games written by the Japanese software company Human seem to need special - SPC700 sound CPU timing, so the ROM load and reset routines now check the - software author company and adjust the CPU cycle length accordingly. - It gets Clock Tower, Super Fire Pro-wrestling Premium, etc working. -- Added ROM check sum calculation and testing code - Snes9x can now detect - pure, corrupt or hacked ROMs. -- Noticed a fast way to implement the SNES 4096 colour mode, so I implemented - it. Now the colours in ActRaiser 2 look correct. -- Corrected a noise frequency error thanks to information from Takehiro. -- Added a 'start in full screen mode' flag to the Linux port. -- While debugging the new graphics code I thought of a fast way to implement - the SNES direct colour mode, tried it out and now the colours in Actraiser 2 - are correct. -- Blast, forgot about the colour window and fixed colour effects. The separate - sub-screen is back again, but all the other graphics speed ups are there. -- Now I've got a z-buffer I keep finding other ways to optimise the SNES - graphics rendering - no need for a separate sub-screen, no need to clear - the sub-screen to the fixed colour, no need to waste CPU time on translucency - effects on hidden pixels, no need to completely clear the main-screen to the - back drop colour, etc., etc. -- Implemented a software z-buffer and changed the SNES graphics rendering to - use it (required change for future 3D card support). Finally fixes the - sprite-to-sprite priority bug that some games suffer from. Also a big speed - increasing for some games (10 fps+), others are slight losers. -- Added code to skip the rendering of completely transparent graphic tiles - rather than comparing each pixel to see if it is transparent; helps the - frame rate a bit on some games. -- Added a fixed for Tetris & Dr. Mario - the game didn't like a multi-player 5 - adaptor plugged in to the real SNES when being played, so turned off the - adaptor emulation for this game. -- Added hack for Final Fantasy II - if sync sound isn't on, make attack rate of - 1ms actually 0ms (old v1.16 behaviour). Causes a slight click but its better - than samples being cut short. -- Fixed a clip window area invert bug if the colour window was enabled on - on one window and the other window was being used to clip a background layer. - Fixes the finial (I hope) display problem with Gun Hazard. -- Added code to intersect the clip window areas if both a colour window and - a background layer clip window were enabled at the same time. Required by - Gun Hazard. -- Forgot to mark graphic clip windows as needing recomputing when the master - colour window inside/outside/on/off/main-screen/sub-screen PPU register was - updated. Was causing display problems for Gun Hazard. -- Internal H-DMA execution accelerator pointer variables where not always - being recomputed when started H-DMA part way into a frame. Was causing - display problems for Gun Hazard. -- Made H-DMA continue for one extra scan-line to fix a disappearing monster - problem in Dragon Quest 5. Thanks to Alex Jackson for the bug report. -- Zoop seems to require volume envelope height reading by the sound CPU to - always return 0 when the channel is in gain mode. -- The sound code was ignoring updates to the ADSR volume envelope rates while - one was in progress. Fixed that and now the bird song at the start of - Chrono Trigger sounds correct. -- Had to disable the CPU shutdown code for loops reading the horizontal beam - position, it was causing problems for Star Fox. Still no polygons though. -- Oops, sound DSP noise output was broken - accidentally deleted an important - line while removing debug code ready for the last release. -- Added initial 3Dfx support to the Linux port - basically using the Voodoo - card as a bi-linear filtering, scaling blitter. Actually slightly slower than - TV mode, for non-scrolling images due to poor texture upload speeds to the - card, but the full-screen feature is nice and the speed doesn't drop as more - of the screen changes. -1.18 -- Implemented a sync-sound mode where sound data gets generated in sync with - SPC700 instructions being executed. Finally the sound Williams Arcade - classics can be heard. Also helps slight sound timing problems in many other - games but doesn't fix Mortal Kombat 2 like I thought it would - its - sound routine programmers must have been on drugs or something! -- Added interpolated sound - gives low frequency sounds much more bass similar - to a real SNES especially with the playback rate ramped up to 44KHz. -- Added on-screen messages as various emulation options are toggled on and off - using the in-game keys. -- Fixed a PPU register read bug with the sprite register write position. Thanks - to Takehiro TOMINAGA for the bug report. -- Altered the auto-frame skip timing code to only wait and re-sync to the end - of frame when frames haven't been skipped. Again thanks to Takehiro. -- Speeded up the colour addition and subtraction code using ideas from - Takehiro. -1.17 -- Linux and UNIX sound code now driven directly from signal timer handler - rather than the timer handler just setting a flag which had to be polled in - the main emulation code. Slightly faster execution. -- Fixed the crash bug in the ZSNES Super FX asm code with Vortex - the game's - polygons still aren't visible though. -- Implemented bent-line increase and exponential decay and sustain volume - envelopes - they should match, or at least be very similar to the real SNES - sound DSP chip now. -- It would seem ROMs can key on sound channels even if the channel hasn't - been keyed-off, Pac-In-Time requires it. Changed code to allow it. -- Quick mod to ZSNES Super FX code to get Winter Gold working - it was already - working with the C Super FX code. -- Added emulation of the extra 1/2 scan-line per frame on PAL and NTSC - - should help improve music speed emulation. -- Worked around the click sound heard when ROMs use 0 volume envelope attack - rate. -- Removed the 'check for IRQ already happened' H-IRQ position register setting - code - it was causing problems for Ninja Warriors and was not required by - F1 Grand Prix. -- Fixed a bug in the new sound code - the sustain part of the - attack-decay-sustain-release volume envelope was being skipped if the - sustain level wasn't at 100%. The fix has helped some music notes from - being cut off early in a few games. -- Added fix to Pro Action Reply support (again). Thanks to Paul Shoener III for - the original fix and Gil Pedersen for reminding me to apply it! -- Finally fixed the Tales of Phantasia 'bum note' problem! The ROM set its - sample directory to the upper-most page and I forget to code for the hidden - 64 bytes of RAM, that appear when the boot ROM is switched off, when fetching - sample addresses. -- Adjusted the relative cycle length between the 65c816 and the SPC700 slightly - to get Terranigma working again. -- Oops, the emulated joypads 3 and 4 via the emulated Multi-player 5 interface - weren't working. Thanks to Steffen Schwenke for the bug report. -- Optimised the echo sound code - by-passed the the FIR filter code if only - a pass-through FIR filter was defined by the ROM. -- Modified V and H-IRQ register changing code to trigger an IRQ immediately if - V-IRQ is enabled and the scan-lines match and either H-IRQ is not enabled or - the electron beam position has already gone past the trigger point. Fixes - the screen flicker in F1 Grand Prix. -- Modified the priority-per-pixel mode 7 code to use BG#1's clipping data if - the top bit of the mode 7 pixel is set. Fixes initial track drive-through - display in F1 Grand Prix. -- Modified the sprite priority levels for the priority-per-pixel mode 7 - display. Now the car can be seen in F1 Grand Prix. -- Wrote a sound DSP register recording scheme which 'plays back' the register - changes in sync with the sound generation code. I'm bit disappointed, it - only improves the sound in a very few games... Scrapped the code, it actually - causes more problems than it fixes. Oh, well, another 3 weeks work wasted... -- Fixed a SPC700 wake up problem for Lufia I - made the SPC700 also wake up - when the 65c816 read from one of the four comm ports. -- Included lots of sound code speed ups and sound quality improvements - from Takehiro TOMINAGA - many thanks go to him. -1.16 -- Fixed a case where the -forcelorom option didn't work - the case was - required for Formation Soccer which claims in its ROM header to use the - same memory map as Super FX ROM, it doesn't. -- Pulled apart a real SNES using a crowbar (great fun), just to look at what - speed the SPC700 is actually clocked at for more accurate relative emulation - speed. -- Implemented SPC700 cycle counting in the hope the improved timing would fix - Tales'; no such luck but at least the -ratio option is obsolete now. -- Implemented executing SPC700 instructions during DMA, fixes BSZelda and - Goal lock up at start and music pausing briefly when ROMs do lots of DMA, - usually between game screens. -- Scrapped the i386 asm SPC700 code - it was the cause of the music not - restarting after a battle in Chrono Trigger and FF3 and I didn't realise - because the bug had already occurred in the test freeze-file I had. - Thanks to John Stiles for pointing out that the Mac port didn't have the - missing music problem. -- Fixed RGB subtraction bug on displays with only 5 bits for green, e.g. RGB555 - displays. The GREEN_HI_BIT variable was always set to a value for 6 bit - green displays. -- Added the SA-1 memory map, still a long way to go before any SA-1 game will - run. -1.15 -- Jumped versions to keep in sync with the DOS port release. -1.14 -- Improved 8-bit sound generation slightly, but it still sounds very poor - compared to 16-bit sound. -1.13 -- Implemented the Tales of Phantasia memory map using the information supplied - by zsKnight. Had to also implement a de-interleave routine to work around - a ROM feature and Snes9x CPU instruction fetching implementation detail. -- Added a frames-per-second on-screen display option. -- Fixed the final glitch bug with the Mario Kart track display - the byte code - for the termination of the DSP1 raster command wasn't been recognised. -- Disabled a NMI/DMA hack for Rise of the Robots, was causing problems for - Mario Kart and 'Robots wasn't working correctly anyway. -- Optimised the mode 7 rendering a little. -- Changed tile rendering code to use offsets into screen buffer rather than - direct pointers ready for z-buffer implementation. -1.12 -- Changed V-blank NMI to occur immediately after a WAI instruction, Toy Story - required this. -- Fixed reading of H-DMA line counter register, Top Gear 3000 needed this. -- Ripped off large parts of ZSNES's DSP1 code (with _Demo_'s and zsKnight's - approval). Now Mario Kart works almost 100%. -- Added a check to see if a vertical scan-line IRQ register change will cause - a H-IRQ later on the current scan-line. Pilot Wings needed this. -- Fixed possible crash bug in clip window code when both windows had two - spans. Could actually cause Chrono Trigger to crash the emulator. -- Fixed a lock-up problem with the C Super FX code, Star Fox and executing - a few 'FX instructions per scan-line (required for Winter Gold). -1.11 -- Partially fixed the DOS netplay server - the server timer is running too - slowly and it doesn't deal with disconnects correctly yet. -- Corrected the sound echo delay - it was varying with the sound playback - rate chosen by the user - it shouldn't have been. -- Implemented DOS netplay code - DOS server code still not working though. -- Removed all floating point calculations from the sound generation code. -- Fiddled with the pitch modulation code - my guess is the output of a - channel that is used to modulate the frequency of another channel is - automatically muted by the SPC700 chip. Just a guess, but the wind from - FF3 sounds 'better' but far from perfect. -- Optimised the tile palette index calculation. -- Optimised the planar to chunky tile conversion code. -- Fixed X11 port to always scale SNES image if hi-res. only (no interpolation) - support is enabled. -- Added zipped ROM image support using Gilles Vollant unzip code and - some code that Ivar (Lestat) sent me a long time ago. -- 65c816 asm RTI instruction was destroying the program bank in emulation mode, - the C code was already correct. Caused C64E to break. -1.10 -- Finished NetPlay v1 - allows up to five networked machines to play - multi-player SNES games, one player on each machine. -- Switchable full-screen mode added to Linux X11 port, some code and ideas - nicked from Maciej Babinski's original Snes9x XFree86 DGA Linux port, the - UAE Amiga emulator, plus lots of my own code. -1.08 -- Bug fixes to C Super FX emulation - now Winter Gold works correctly again. -1.07 -- More DSP1 work. Mario Kart is now playable! The character projection code - is still broken so the opponents and obstacles aren't always positioned - correctly on screen and you keep bumping into them, but I can still keep - coming first! -- Started work on NetPlay support. -- Decreased sound card DMA buffer size on DOS port to improve sound generation - and sound CPU synchronisation in some games. -- Included Linux joystick driver patches from Vojtech Pavlik so the port can - use the new v1.x joystick drivers, again written by Vojtech Pavlik. Allows - use of Micro$oft Sidewinder pads, NES and SNES pads, PlayStation pads, - Gamepad Pros, etc. -- Added halve-the-result colour subtraction. -1.06 -- Extended code to allow support for multiple 16-bit screen formats, - switchable at run-time, rather just supporting one, selectable at compile - time. -- Added XFree86 DGA Linux port - code from Maciej Babinski. -- More fixes to the X11 image format conversion and setup code. -- The asm SetByte routine wasn't wrapping writes to S-RAM correctly, allowing - some ROMs to think they were running on a copier and put up an error - screen. Thanks to Nu of #rom for the report. -- Added 'TV-Mode' support (interpolation and scan-lines) to the DOS and - UNIX ports from code based on John Stiles work. -- Added v-sync option to the DOS port. -- Added fix to Pro Action Reply support, thanks to Paul Shoener III. -- Added ggi support (untested) to Linux port using patches from - Alexander Larsson (alla@lysator.liu.se). -- Added 16 to 24/32 bit image conversion routines to the UNIX X11 code. -- The SPC700 OR1 instruction was broken. Thanks to Pyrgopolinices for the - report. -- DOS port was having trouble splitting and joining path names - caused - problems when specifying the full path name of a ROM when the ROM image - was on another drive. -- If a ROM reset the sound DSP and then turned on echo effects but kept - the same echo delay setting, then the echo effects could not be heard. - Thanks to madec@mclink.it for the bug report and freeze file that made it - easy to find the problem. -- DOS port was always using stereo sound setting, if sound card - supported it, regardless of the user preference. -- Linux port X11 port could crash if window was resized while transparency - effects were enabled. -- The colour subtraction accelerator look-up table was slightly wrong, causing - one bit of red, green blue values to 'spill' into the next field. -- Allowed colour window to cut a hole in the main-screen and show the sub- - screen underneath. The effect is used by Illusion of Gaia. -- Added support for colour subtraction, with the halve-the-result flag - set. -- Included DSP1 code from _Demo_. Now you can see the track in Mario Kart and - the ground in Pilot Wings - still can't play the games though due to other - missing commands. -- Added an NMI hack to work around a code bug in Battle Toads: BATTLEMANIACS, - its only by chance that the game works on a real SNES - And disabled it - again because it causes problems for Chrono Trigger. -- A frame skip of zero was actually still skipping one frame. Thanks to - Marius Fodor for the info. -- And yet more X-OR window bug fixes - now the effects during some of the more - 'posh' spells look correct in Chrono Trigger. -- Yet another window area inversion bug - off by one pixel on right-hand edge. -- Forgot to put dummy start and end points for XOR window combination modes - - now Uniracers looks correct and Sailor Moon looks like it does on a real - SNES. -- Window clip code was using wrong index into a 2-dimensional array when - the whole of the main or sub-screens were clipped. -1.05 -- The master volume disable code was looking that the wrong variable! -- Fixed crash bug in newer sound code if a ROM tried to start a sample - playing who's data went past the end of SPC700 memory. (Cannon Fodder) -1.04 -- Fixed DSP1 ROM header detection bug. -- More DSP1 work; still nothing works, although I know the multiply command - is correct because I've compared the results against a real DSP1. -1.03 -- Oops, the multi-player 5 disable code change broke the multi-player 5 being - the default controller. -- Implemented the colour window on the main screen - now Zelda's oval zoom - window displays correctly and Krusty's Super Fun House clips the left-most - 8 pixels as it does on the real SNES. -- TERRANIGMA didn't like me returning a random value when it attempted to - read a channel's the current sample byte. -- Hacked in initial support for mode 7 priority-per-pixel - the priority bit - doesn't actually change the priority of the pixel but the two games that I - know of that use the feature look OK. (Winter Extreme Skiing and the - intro of Tiny Toons Adventures). -- Colour addition/subtraction code now uses RGB565 rather than RGB555 - calculations - helps a little with the loss of the bottom bit of SNES - colour data. -- DSP1 emulation started - nothing works yet. -1.02 -- Switched to adding back drop colour rather than fixed colour when - sub-screen addition is enabled but there's nothing on the sub-screen. - Uniracers seems to need it. - DISABLED it again. Causes problems for - other ROMs and Uniracers itself on later screens. -- Fixed XOR window logic combination mode and area inversion code, now - Uniracers works correctly. -- Oops, if colour window and half colour addition/subtraction were both - switched on, area outside colour window was still being halved, it shouldn't. - Hacky fix at the moment until I implement the correct fix. -- Fixed several bugs with the mosaic effect and 16x16 tiles and a few - possible background scroll offset bugs and the mosaic effect. -- Optimised the sound sample generation code for cases when the SNES - sample playback frequency was higher than the sound card playback rate. -- Fixed possible click sound when a sample was first started to be played. -1.01 -- Corrected scan-line count for PAL games - should be 312 lines verses 262 for - NTSC. Was causing slow music on PAL games. -- Added error correction code to the SPC700 timer update code - the - SPC700 timers are updated using the emulated h-blank handler which is - called every emulated 63.6 microseconds (15.720KHz) but the SPC700 timers - need to be updated at multiples of 8KHz, hence the error. Was causing - music to be played slightly too fast. -- Switched back to using C SPC700 code - the old SPC700 asm code was lacking - several optimisations that the C version had. It also had multiple - speed hack cycle skipping bugs. Plus I hadn't even finished optimising - all the code from the last time I converted the C compiler output. -- Optimised SPC700 memory access routines a little. -- Disabled code that prevented ROMs updating SPC700 timer values while the - timer was running - it seems like it is allowed, even though docs on the - 'net I've seen say its not. -1.0 -- Fixed SuperScope support. -- Added hi-res. option to my DOS port. -- Fixed 4, 6, and 8 button standard PC joystick support. -- Changed some types the source code was using BYTE -> uint8, WORD -> uint16, - DWORD -> uint32 and BOOL -> bool8, types were clashing Windows typedefs - but sizes didn't always match. -0.99 -- 8-bit double height and/or width tile rendering was missing every other - group of 4 pixels - screen pointer advance count was wrong. -- Asm SPC700 emulation was ignoring the Shutdown flag - the result is its - not possible to turn off cycle skipping for the SPC700 emulation. -0.98 -- CPU to ROM address decoding code rewritten - used by Game Genie cheat codes, - orginal code might have been the cause of some Game Genie codes not working. -- Started to remove printf calls and replace them with calls to S9xMessage, - port code can then dicide what to do with message. -0.97 -- Re-enabled decompressed sample caching, still has a possible click problem - but the sound code is a lot faster with it enabled. Added command line option - to disable it if required. -- Added '7' key support to rotate through available controller options, in - the order multi-player5, mouse on #1, mouse on #2, superscope, - standard controller and then back to multi-player5. -- Hi-res. (512x448) support fixed. -- Mouse support completed - Lemmings 2 and Mario Paint working a treat. -- More colour window fixes. -- Fixed freeze game problem when ZSNES SuperFX code is being used - - ZSNES 'FX state was not being saved and restored. -- ZSNES SuperFX asm emulation code plugged in to Snes9x. -0.96 -- Looks like if the colour window is not enabled at all and the colour - window selector is defined to only allow colour effects inside the colour - window, then no effects should be visible. -- Offset-per-tile rendering code didn't support width 64 screen size, which - Chrono Trigger used on its title screen. -- Contra 3 seems to prove that defining the clip window area to be 'outside' - a window that covers the whole screen is not an area with no range. - - No it doesn't. It proves that I shouldn't have initialised the right - window edges to 255! Contra 3 enables clipping windows without first - defining their range. -- Debug frame advance feature was being prevented from forcing the next - frame to be rendered by SyncSpeed which was being called after the - debugger returned to the main loop. -- H-DMA code was allowing ROMs to manually start H-DMA during the v-blank - period, ROMs shouldn't be allowed to do this. -- Asm code would not push the correct CPU status onto the emulated stack if - returning from an NMI immediately triggered an IRQ - fixes Mortal Kombat 1 - and War of the Gems. -- 'd' dump memory debug command was not preserving the CYCLES count. -- C versions of SNES memory access code had same problem as asm code on the DOS - port except it didn't cause a crash just ROMs failed to work correctly. -- Asm i386 code was using signed compares to check for special case memory - areas - it was causing crash problems on the DOS port which was sometimes - returning valid address values with the top bit set - i.e. they seemed - like negative values! -- Changed event reschedule code to always allow h-blank start events, used to - disable them during v-blank period. -- Added code to HDMA when end of visible lines reached. -- Changed register 4212 code not to always return h-blank when in v-blank. -- Clipping fixed colour addition to background area was off by one pixel on - the right-hand edge. -- HDMA: Finally worked out how the real SNES operates when ROMs manual - start H-DMA during the frame - ROMs must set up the H-DMA line count - and address values before H-DMA is started. -- Fixed the asm code to remove all hard-wired structure offsets - one offset - into the IPPU structure was wrong in the code because the structure had - changed size. -- Added colour window support and allowed graphic window settings to be - different on the main screen and sub screen, just like a real SNES. -- SuperFX LJMP instruction had bank and address values swapped. -- Fixed possible memory overwrite problem because OBJList array was one - element too short. -- Added AND multi-graphic window combo support. -- ROM image memory allocation allocates an extra 32K of RAM, then moves the - pointer forward by that amount - stops the SuperFX emulation from accessing - unallocated memory, possibly causing a crash. -- SuperFX emulation now stores sign and zero flags in separate variables so - the MERGE instruction can set flags correctly. -- Added 65c816 instruction skipping to i386 asm code when 65c816 waiting in - a simple loop for some 'event' to happen e.g. end of frame NMI. -- Finally fixed the APU instruction skipping problem with the i386 asm - code when the WAI instruction is used - caused slow music on some ROMs. -- Offset-per-tile modes don't seem to support screen size - Mario All Stars - Super Mario 2 requires this on title screen. Doesn't seem to effect - Tetris Attack or Puzzle Bobble. -- Changed SNES select and start keys from shift and control to space and - enter - allows shift-fn key to save game positions without the SNES ROM - also getting a select joypad button press. -- Multiplayer5 support for controllers 3+ was broken for ROMs that used - automatic hardware joypad reading rather than reading joypads serially. -- ResetPPU was not clearing tile caches and marking OBJ as need recomputing. -- Cached OBJ positions and sizes were not being recomputed if ROM changed - global OBJ sizes during frame. -- Fixed brightness multiplication problem on 16-bit code for green. -- SPC700 emulation now uses one variable to store ZERO and NEGATIVE flags. -- SPC700 emulation now only increments PC once at end of instruction. -- New ROM type and interleaved detection code. -- Reading sound DSP register ENDX also clears the value. The docs on the - 'net said that only writing to the register cleared its value. Fixes - sound in Zoop. -- Fixed mode 4 colour palette problem on background #2 in tile-based graphics - code. -- Fixed graphics mode 4, offset-per-tile support. Only one set of offset data - that is switchable between horizontal and vertical, unlike modes 2 and 6 - which allow separate horizontal and vertical offsets per tile. -- Modified the APU timer code again, if the timer is enabled, a write to the - timer target register is only allowed if a value hasn't been written yet. - Fixed Donkey Kong Country 1 and Earth Worm Jim 1 & 2. -- Attack rate of 0ms changed from 1ms back to 0ms because of a group of ROMs - that change from attack mode to decay mode in real-time. Will change back - when I've added better SPC700 CPU and sound generation sync code. -- Added support for ROMs set a new sound timer value while the timer is - enabled (EWJ 1 & 2). -- Added support for ROMs that read the sound envelope height (MK1, MK2, etc). -- ROMs writing to the H-DMA enable register during visible scan-lines were - restarting H-DMA for that frame causing random screen effect corruption. -- Echo feedback seems to be after the FIR filter, not before as a diagram I've - seen suggests. -- Sound pitch modulation added. -- Memory access routines changed to pass a single 24-bit address rather than - the previous separate 8-bit bank and 16-bit address parameters. -0.3 -- Updates to A-Bus address during a frame must not update H-DMA address. - Fixes Actraiser 2 and Pacman 2. -- Removed sound volume mangling - with echo support enabled it doesn't seem to - be required. -- Attack rate of 0ms changed to 1ms to help prevent click sound with sudden - start of a sample playing. -- Sample caching of samples that looped using part of the original sample - created a click on the sound output. Caching disabled for the moment. Would - require 512K of cache RAM to fix sample caching. -- Colour addition/subtraction support added - but still a little buggy in - places and very slow. -- 16-bit colour support added. -- Sustain sound volume was not being set if a sample using ADSR was started - with both the attack rate and decay rate set to zero - resulted in missing - sound samples on with some games. -- Sound echo support added. -- Sound channel mixing code was not completely clearing a channel's sound - buffer when a channel finished playing a sample. -- Sound mixing code rewritten to use one buffer, rather than writing each - channel into a separate buffer then combining them into one buffer. -- Memory access routines rewritten to use an 8K block lookup table rather than - dedicated code for each ROM memory map - it was getting difficult to support - the new types of SNES ROM memory maps becoming apparent. -- Sound sample decoding wasn't decoding sound samples correctly if a - previously cached sample was only partially overwritten by the ROM as - opposed to being completely replaced. -- Sound sample decoding wasn't clipping generated sample values correctly. -- Changed H-DMA to start in the current frame only if enable register is - written to during v-blank, h-blank or while the screen is blanked. -- The SPC700 seems to start executing instructions before the 65c816 - - shorter reset pulse? (NO - forgot the SPC700 executes instructions while DMA - is taking place). -- ROMs that reset the H-IRQ position so another IRQ would be triggered on the - same scan-line where not supported - Super Off-Road: The Baj needs it. -- $4212 bit 7 needs to go high at the end of h-blank at line 224 not at the - start of h-blank - Bubsy needs it. -- Sample decoding routine could write to memory outside sample cache area if - address of block to decode was greater than $0x10000 - 9. -- Walking mario can be seen on map screen of MarioWorld - needed sprite - priority rotation working. ROM sets bit 7 of $2103 then sets rotation in - $2102. Reset rotation at start of v-blank not at end. -0.24 -- Fixed reading of DMA register values - now Ms Pacman works. -- Saved sprite memory address being restored on the wrong scan-line - caused - corrupt sprites on at least one game (GANBARE GOEMON 2). -- Screen colour palette not being updated if ROM only wrote to low byte of - palette register. -- Possible memory corruption fixed if a ROM tried to write to an invalid - sprite address via PPU registers. -- X11 port support quick load and save by pressing function keys to load or - shift + function keys to save. -0.23 -- Added option to disable graphic window effects - T2: The Arcade Game doesn't - seem to like them. -- Mode 7 "outside screen area" register interpretation fixed - now the - Actraiser map screen looks a lot better. -- Old DMA code hack for Battle Toads: Double Dragon removed as it was no - longer required and it was causing problems for Ys III. -- Lowered max volume level of 16-bit sound mixing code to help with sound - clipping problems is lots of SNES sound channels are playing. -0.22 -- Crash bug fixed in mode 7 graphics windows code -0.21 -- Fixed a noise channel volume bug - noise waveform was getting clipped. -- Fixed 24bit X Window System server support on the Solaris port. -- Sprites in priority level 1 on mode 7 were being drawn incorrectly behind - graphics screen. -- BG 3 priority 1 tiles sometimes not drawn dependent on the $2105 bit 3 - setting. -- Added graphic window support the tile redraw code. -- Added mosaic support to tile redraw code. -- Tile redraw code was drawing one line too many on screen-splits. -- Tile-based redraw code made more intelligent about when a background should - be displayed or not. -- Added wrap within bank support to large DMAs just to support Rock 'n' Roll - racing. -0.20 -- DMA routines added lots of special cases and removed most calls to GetByte, - using a pointer instead. -- Multiple using PPU registers is now only computed when first byte of result - is actually read. -- Sound enabled by default if compiled without DEBUGGER defined. -- Tile redraw method made the default. -- Fixed CPU_SHUTDOWN so SPC700 continues to execute even if main CPU is - "skipping" cycles waiting for an event to happen. -- More command line options added. -- Default cycles-per-scan-line to execute lowered to 90% from 100%. -- +/- keys now work even if auto-frame rate adjust was enabled. -- SPC700 emulation partially rewritten in assembler. -- Asm 65c816 code change to use same speed up techniques as the C++ code. -- Minor speed tweaks to the sound decoding and mixing code. -- C++ SPC700 emulation changed to use same method as 65c816 emulation for - computing and storing emulated CPU flags. -- Mode 7 code rewritten and several scrolling offset bugs fixed. -- Lo-ROM S-RAM memory map bug fixed - now Uniracers works. -- Multiple speed ups and changes to the tile and line-based redraw code. -- Tile and line redraw code changed to cache converted tiles between frames. -- Variable cycle length timing made compile-tile switchable. -- C++ 65c816 emulation changed to use several opcode jump tables to avoid - a register size comparison test on most emulated instructions. -- C++ 65c816 emulation changed how is computes and stores emulated CPU flags. -- Fixed high frequency sound playback bug - the sample rate calculation was - blowing the range of an unsigned long. -- Fixed V-RAM reading so DKC3, Addams Family, Aladdin and Pacman all work. -- Fixed sound code so ROMs can change from ADSR mode to decrease mode - fixes - lots of ROMs. -0.12 released -- Added dynamic speed regulation. -- TCALL vector calculation change from n to 15 - n. -- Fixed crash bug if ROM writes to sound DSP register numbers greater than - 127. -- Fixed DOS memory locked for interrupt code. -- Added long name versions of command line switches. -- Added command line switch for SPC700_SHUTDOWN code and WAI cycle skipping - code. -0.1 released -- All DOS memory is now locked from being swapped. -- Fixed DOS port keyboard polling code - could get confused if a keyboard - interrupt happened while keys were being checked. -- SPC700 ADC instruction never cleared Overflow or Carry flags! -- Changed selection of playback speeds for Solaris port. -- Sample caching code was broken - cached samples were never used. -- Added code speed ups for ROMs that use a lot of DMA to VRAM. -- More cpu code asm speed up. -- Fixed 16x16 size tiles on tile-based redraw code. -- Fixed sound gain-mode increase and decrease volume envelopes. -- Added code to support ROMs that reuse sprites in the same frame. -- Fixed processing of negative volume levels. -- Fixed SPC700 EOR1 instruction. -- Added SPC700 shutdown code to stop executing SPC700 instructions if in - a tight loop waiting for a timer or for the 65C816 to respond. -- DOS playback rate was being forced to 16KHz by Allegro - fixed. -- Fixed bug in SPC700 MOV1 C,bit, address. -- Fixed a off-by-one loop sample pointer bug in MixSamples. -- Added command line flags for cached-tile based drawing and sub-screen - background layers priority swapping. -- NOPE, got encoding of the OR1/EOR1,AND1 range of correct originally - - got duff information from an "SPC700" programmer. -- More SPC700 fixes: got the encoding of the OR1/EOR1,AND1 range of - instructions wrong - I guessed wrong originally. -- Sample looping bug fix on mono sound mixing code. -- Sound pitch value no-longer clipped to 14 bits - apparently FF3 needs this. -- Followed Paradox's suggestion and changed graphics code to place sub-screen - background layers below main-screen background layers. Helps lots of games - that use sub-screen addition/subtraction - now you don't have to toggle - background layers on and off so often just to see hidden text, characters, - or maps, etc. Made it switchable. - Acts as a good intermediate solution until sub-screen addition/subtraction - is actually implemented. -- Modified sound skipper code to return random values when ROM is stuck - waiting for the SPC700 CPU to respond - helps several ROMs that previously - don't work with the currently selection of APU skippers. -- Improved sound mixing code so volume is not attenuated so much, giving - better results on 8bit sound cards. -- Changed the frequency at which the joystick polling routine is called - now - called every-other frame rather than every 3rd frame. -- Recompiled Linux and DOS ports with the Pentium optimising version of gcc - - gives a few percent speed increase. -- Changed V-RAM increment count from 64 to 128 - apparently Final Fantasy 3 - needs this as well. -- Fixed sprite priority bug with Mode 7 - apparently Final Fantasy 3 needs - this. -- Fixed a screen clipping problem with the S-VGA mode. -- Fixed bug that had crept in with -m 2 S-VGA mode (Linux version). -- Fixed S-VGA Linux version with sound enabled. -- The SPC700 ADC (X),(Y) instruction was broken - with all these SPC700 fixes - now many more ROMs work with sound enabled. -- The SPC700 Pop PSW instruction was not resetting the direct page location. -- The SPC700 instruction MOV A,[DP+X] was incorrectly doing a MOV A,DP+X. -- Got the SPC700 SETx and CLRx instruction encoding swapped around. -- Fixed #define problem that was stopping DOS snapshot saving from working. -0.72 released -- Fixed the DOS filename handling - old Unix code was screwing up with ROM - filenames that contained backslashes (\) - the ROM would load but S-RAM - loading and saving would fail and the default filename for snapshots - wouldn't work. -- This time really fixed Allegro library keyboard handling (DOS port); it - was missing key some presses/releases (was stopping Chrono Trigger - Left + Right + A button combo from working). -- Added code to automatically remove headers off S-RAM save files with - 512 byte headers. -- 32Mbit ROMs in interleaved format are now automatically detected and - converted. -- Added -ss 3 sound skip method support to the asm version - now NBA Live '96 - works again. -- Added support for multi-part ROM images. -0.71 released -- Made libgz.so statically linked (again) on Linux port - sorry. -- Made writing to $4200 also clear any pending IRQs. This finally allows - Battle Toads: Double Dragon, Spawn and Sieken 3 all the work with the same - IRQ logic (but Sieken 3 still gets stuck in sound download code). -- Fixed a H-DMA wobble bug - some frames could randomly miss a line of - H-DMA causing the F-Zero screen to wobble, and slight text character - corruption on games like DKC3. -- Interleaved format ROM images are now swapped in-place, without the need - for a temp 4Mb buffer (saves lots of disk swapping on a 16Mb Windows 95 - machine). -0.7 released -- Fixed Allegro library keyboard handling (DOS port); it was missing key - some presses/releases. -- DOS port had a different MAX_PATH value which moved the location of the - SRAM size variable when using the asm CPU emulation core. This, in turn, - caused the SRAM emulation to fail on the DOS port. Donkey Kong County 2 & 3 - were reporting a ROM copier was connected to the SNES and refused to run. -- Fixed assembler version of XCE - it was always leaving the carry flag - clear - caused Killer Instinct and Super Punchout to think a ROM - copier was fitted to the SNES and they all refused to run. -- Fixed assembler versions of MVN/MVP - they weren't setting the data bank - register to the destination bank of the instruction. -- Fixed joystick detection on MS-DOS port - a single 2 or 4 button joystick in - port 1 was being ignored if a second joystick was not present in port 2. -- Fixed an uninitialised variable in graphics code - was causing random - missing scan lines on Mode 7 screens. -- Joysticks now scanned every 3rd frame (joystick scanning is slow in the PC). -- Double-whoops, Metriod 3 had stopped working in v0.6 - fixed it - (memory map bug). -- Made bit 6 of $4211 set if v-counter == v-timer-position. -- Made reading of $4200 read $4212 instead. -- Adjusted DMA timing to always access ROM memory at slow speed - this seems - to fix Battle Toads. -- Added code to automatically clear pending IRQs when the horizontal line - is no longer equal to the horizontal timer line - this fixes Seiken 3, it - now just gets stuck in the sound CPU wait code - oh well. -- Moved NMI back to its original pre-0.65 behaviour, now Puzzle Bobble works. -- More graphics speed ups - the code to render background tiles with their - priority bits set is only called if there are actual priority-bit tiles. -- Changed default frame skip rate from 1 to 2 - its seems most people don't - bother to read the docs, so I thought I'll help them out a bit! -- Speeded up Mode 7 graphics on games like F-Zero that rewrite the matrix - registers on each scan line using H-DMA. -- Reorganised the graphics code and did a slight speed up - graphics code - will be the next thing to rewrite in assembler. -- Rewrote CPU core in assembler for Intel platforms - gives a very noticeable - speed increase. -- Fixed several problems with the APU sound CPU emulation - its now getting - stable enough to try and implement sound. -- Fixed bug that caused 1 byte of S-RAM to be emulated when ROM didn't - expect any - it was enough to stop Street Fighter 2 and others from - working - thanks Lord ESNES. -- The TXS and TCS instructions shouldn't set the Z and N flags. -- Looks like MVP/MVN instructions should ignore accumulator size - change - code to always use all 16 bits and exit with accumulator set to 0xffff. -- Whoops, accidently left some test code in which was causing the V-BLANK - flag, bit 8 in register $4212, to be miss-calculated. -- Fixed palette in mode 0. -- Speeded up graphics drawing a little by skipping groups of 4 pixels that - were all transparent. -0.65 released -- S-VGA and MS-DOS ports now have a VGA mode command line flag. -- Improved the fading code - should be much more smooth now. -- Fixed second joy-pad support and re-mapped keys and joysticks to actually - make a match between what my docs said and a real SNES (SNES docs I'd - seen were wrong!). -- Fixed a bug in Relative Long CPU addressing mode. -- Ported Snes96 to MS-DOS. -- Snapshot loading and saving no longer uses external gzip binary. -- Added support for registers at $21c2 and $21c3. -- Made reading the software latch for the horizontal and vertical counters also - clear any pending IRQ. -- Added sprite priority rotation. -- Rewrote parts of the graphics routines to fix a sprite-to-sprite priority - bug. -- NMI flag changed again - now back to being reset by reading $4210 but - actual NMI is delayed. -- Made mode 7 background colour 0 transparent - this fixed several sprite - priority problems a few games where having. -- Finally worked out how sprite "Object Name Select" works and emulated it - - this fixes many (if not all) of the corrupted sprites some games - experienced. -- Delayed NMI activation for one instruction to give time for loops that - wait for bit 7 of $4210 to go high. -- Special-cased line count of 128 on H-DMA to mean repeat previous data with - a line count of 128 and not just terminate H-DMA on that channel. -- APU sound CPU emulation added - just need to debug the thing. -- Fixed Overflow flag setting in ADC and SBC instructions - it was never - being set. -- Rewrote how CPU instructions are fetched and how values are pushed and pulled - from the stack - it gave a very large increase in emulation speed. -- H-DMA was being started one scan-line too late. -- Added CG-RAM reading support. -- Added "Full Graphic" V-RAM reading. -- Speeded up C version of CPU emulation quite a bit - could speed it up a - little more before rewriting in assembler. -- Fixed bugs in 16x16 tile drawing on 2bit and 8bit deep screens. -0.6 released -- Speeded up 16x16 tile background rendering by removing a temp tile buffer - it was using. The speed up also fixed a vertical scroll bug. -- Fixed slight window clipping on 16x16 tile backgrounds. -- Added automatic PAL/NTSC mode switching. -- Fixed background and sprites so only visible if on main-screen or - on sub-screen under correct circumstance. -- Fixed lockup bug in DMA. -- Stopped NMI flag from being reset by reading $4210 - was causing a couple - of games to get stuck. -- Whoops, got horizontal and vertical Mode 7 flip bits around the wrong way! -- Fixed MIT shared memory pixmap support for X11 version (it was always turned - off). -- Fixed minor bug - first sprite in priority group was drawn twice. Didn't - cause any visual bugs, it just slowed down redrawing a little. -- Fixed DMA bug - transfer byte count should be 0 after DMA has finished. -- Fixed a scaling bug if width < height. -- Interleaved ROM image support added. -- 16bit and 24bit X11 server support added - with scaling. -- Added window scaling on X11 version. -- Partial clip windows added - the only window overlap option implemented at - the moment is OR, it seems it good enough for all the ROMs I've tested - it with. -- Partial Mosaic effect added (pixels only growing vertically). -- Missing Mode 7 "outside screen area" option added. -- Fixed mode 7 screen wrap "outside screen area" option. -- Used new event processing to finally fix H-IRQ so it triggers at the - correct position on the scan line. -- New event processing added. -- Linux version now statically links libgz.so (sorry). -0.5 released -- Linux S-VGA version changed from using a 320x240 ModeX screen (slow) to a - 256x256 chunky screen (faster) - thanks to Phillip Ezolt (pe28+@andrew.cmu.edu) - for information on how to do this. -- Mode 7 screen flipping added. -- Included Snes97's CPU emulation code into Snes96. Didn't fix any bugs but - slowed down the emulation some what and I couldn't compile it optimised - because it was so large - so I removed it again. -- Added a few extra features available via the keyboard. -- Fixed a H-DMA transfer mode - bad documentation. -- Fixed H-DMA indirect addressing (it was using the wrong CPU memory bank). -- The Linux slow down bug is my crappy laptop enabling battery saving features ! -- Changed graphics code to perform true line-by-line screen updates. -- Fixed sprite drawing bugs. -- Ported Snes97's graphics code to Snes96. -- Fixed memory map for HiROM save RAM area. -- Fixed HiROM memory map - now Killer Instinct and Donkey Kong County work ! -- OK the slow down bug is just actually my laptop trying to save battery - power by slowing the CPU clock! -- The Linux slow down bug shows itself on DOS emulators running under DOSEMU - so it must be a kernel problem (or feature). -- Fixed H-DMA (again) to be complete emulation - all I need now is line-by-line - screen update... -- Fixed DMA to not copy too many bytes if byte count was not a multiple of - the transfer mode quantity (caused corruption on Super Mario World map screen). -- Changed mapping of keyboard to joy-pad buttons and added additional - direction keys for joy-pad one so player one's right hand doesn't have to - obscure player two's keyboard joy-pad buttons. -- Changed joystick button layout to match SNES if using a 6 button joy-pad. -- Changed snapshot format so I can easily use libgz on Linux. -- Added few speed up tweaks that will be lost again when I add line-by-line - screen update. -- First visible scan-line changed from 8 to 1 to match with new docs. -- New SNES information source found; fixed partial H-DMA emulation to include - indirect addressing support. -- Snapshot files are now compressed. -- Compressed ROM images now supported on Linux. -- Snapshot loading and saving added. -- Joystick support for Linux added. One 2, 4 or 6 button joystick, or two 2 - button joysticks supported (PC hardware limitation). -- SVGA full screen support added for Linux. Still has the X11 slow down bug so - can't blame the X11 server any more! Must be a kernel bug or a very odd - emulator bug. -- Added emulation of two joy-pads on the PC/Sun keyboard. -- Removed -i command line flag as it is no longer used. -h value range has also - changed: now 1 - 100 (percentage). -- Actuate cycle counting rather than instruction counting now added including - fast and slow ROM timing - should give much better timing information when - line-by-line screen update added. -- Bug fixed old-style joy-pad access used by some ROMs - Mario All Stars still - gives problems if enabled and I don't know why; but at least Super Bomberman - now works ! -- Looks like if both horizontal and vertical IRQ are enabled then IRQ should - only be triggered once per frame and not once per scan line - looking at the - IRQ handler of a couple of ROMs seems to confirm this. -- Added initial cycle counting - not accurate enough for some ROMs though. -- Finally worked out how the odd VRAM address increments should work but only - found one ROM, so far, that actually uses it. -- Debugged the odd slow down problem with the Linux port - it seems to be a - bug in the X Window System server - starve the X server of keyboard presses - or mouse clicks or movement and the X server slows down, slowing down the - emulator with it ! -0.4 released -- Fixed sprite vertical clipping at top of screen. -- No need to invert the Mode 7 transformation matrix before use - the - ROM coder already had to! -- Fixed Mode 7 scrolling offset when using special effects. -- Added Mode 7 rotation, enlargement and reduction emulation. -- DMA shouldn't zero the byte count value after a DMA has completed. -- Added DMA reading (Addams Family was using it) -- Fixed V-RAM read function - returned data should lag behind the V-RAM - address by one byte/word. -- Added mode 7 graphics only. -0.3 released -- Speeded up the main CPU loop a bit. -- Add more command line options: - -f (default 1) - -i (default 32768) - -h (default 45, some games allow a lower - setting resulting in a increased - emulated frame rate) - -t enable CPU tracing - -ss (default 0, more methods to be added) - -H disable H-DMA emulation - -F Force Hi-ROM memory map -- Modified planar to chunky conversion to use look up tables. -- But now Mario All Stars won't start. Made emulation of $4016 optional with - -o command line switch. -- Thanks to Carlos (calb) of ESNES fame, I've added correct $4016 & $4017 - joy-pad register processing - now several more ROMs will start once a - button is pressed and can be controlled. -- DMA wasn't updating DMA registers with the final CPU address used after the - DMA had completed (caused sprite and background corruption with some ROMs). - Still suspect another DMA side effect isn't being emulated correctly though. -- Fixed setting of CPU overflow flag in ADC and SBC instructions in decimal - mode. -- Fixed MVP/MVN CPU instructions to leave X and Y values correct at end of - loop - several more ROMs now work. Still don't know if MVP/MVN instructions - should ignore the accumulator size flag or not. -- Rewrote background drawing code - gives a large increase in speed. -- Flag to only update X Windows colour palette when necessary was missing a - case - caused some ROMs to start with a black screen. -- Code to only update background tiles when changed wasn't working so I - disabled it. -- CPU WAI instruction needed to trigger on hardware IRQ even when interrupt - enable flag was false. -- DMA was not transferring 65536 bytes when byte count was 0. -- Fixed matrix 16bit x 8bit multiplication (old debug code was causing junk - value to be returned). -- Fixed Makefile so version.h header file change recompiles file that shows - version number in window title. -- Added more reporting of used but unimplemented missing hardware features to - debug command. -- New ROM loading code from Jerremy included, can now cope with ROM images - with no 512 byte header. -- Speeded up emulated memory access a little bit. -0.2 released -- Added matrix 16bit x 8bit multiplication for Super Off-Road Racer. -- Added initial H-DMA emulation - visual effects using it will not be seen - correctly until screen is updated line-by-line rather than the whole screen - at end-of-frame. -- Fixed horizontal sprite clipping (vertical clipping still has a problem). -- Integrated large sprite bug fixes and new background drawing code from - Jerremy. -- Fixed large size per-sprite flag; always stayed true after sprite size was - changed to large. -- Rewrote the planar to chunky pixel conversion routines (still need more - work). -- Made registers $4016 & $4017 always return $ff - lots of ROMs that previously - wouldn't go beyond the title screen thought old-style joy-pads were - connected and were waiting for the user to press a button on them. -- Frame skip rate now set to 1 instead of 5 on my P166 laptop! -- Fixed NMI v-blank flag being incorrect set, caused some ROMs to lock. -- X keyboard autorepeat now switched off when emulator has keyboard focus. -- Added number key options to toggle backgrounds 1 to 4 and objs (sprites) on - and off. -- Fixed sprite clipping problems at edge of left hand side of screen. -- Corrected Hi-ROM memory map (I think) (no I didn't) -- Fixed most of the sprite-to-sprite priority problems. -- Added sprite debug command, 'S'. -- Added a debug command to show what missing hardware features a ROM was using. -- Added horizontal and vertical beam position IRQ - horizontal always triggers - at start of line at the moment. -- Fixed SBC instruction to set carry flag the correct way around. -Initial release 0.1 -- Ported Windows 95 version of Snes96 to Linux on a PC and Solaris on a - SparcStation. -- Corrected work RAM memory map. diff --git a/source/docs/control-inputs.txt b/source/docs/control-inputs.txt deleted file mode 100644 index 4faddc3..0000000 --- a/source/docs/control-inputs.txt +++ /dev/null @@ -1,68 +0,0 @@ -Control input names are completely defined by the individual ports. This -document is intended to collect the rules for all ports. - -The various meta-characters in the rules are: - # - A number. The range is detemined by the context - ## - A two-digit number (i.e. with leading zeros) - [...] - Something optional - (...) - For grouping with | - | - "or", choose one of the options. - <...> - A named field - {...} - A list of possible values. Multiple values may be used, but they - must be in the order listed and joined with +-signs. - "" - 'ditto', used to indicate the same list as the above line. - -================================================================================ -Unix -================================================================================ - -Input names: - Jxx:Axis# Axis # on joystick xx. Axis0 may be - Up/Down, and Axis1 Left/Right. - Jxx:B# Button # on joystick xx. - - Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+B# Used with the 'JSx Meta#' port - Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+Axis# command. - - Jxx:X+B# Used to 'define' this key for all - Jxx:X+Axis# combinations of JS Meta. - -Port-specific Commands: - JSx Meta# Used to specify modifier keys (i.e. Shift, Control) to - affect the specified joystick. For example, you could - map J00:B20 to "JS0 Meta1", then map J00:B0 to "Joypad1 - A" and J00:M1+B0 to "Joypad1 Turbo A". '#' may range - from 1-8. - - Jsx ToggleMeta# Like the above, but toggles the meta-state each time - the button is pressed. - -================================================================================ -Unix/X11 -================================================================================ - -Keyboard Input: - - Note that only one keyboard (K00) is currently supported. If you know how - to support multiple keyboards (and can test it!), feel free to fix x11.cpp - and delete this note. - - Keyboard modifiers are S=Shift, C=Control, A=Alt, M=Meta. Combine them in - order, i.e. all 4 would be "SCAM". - - Kxx: Key names are as recognized by XStringToKeysym. - Kxx:+ Note however that keys are mapped by keycode, - so for example on a standard qwerty keyboard - "K00:colon" and "K00:semicolon" are identical. - -Pointer Input: - - Note that only one mouse (M00) is currently supported. If you know how to - support multiple pointing devices (and can test it!), feel free to fix - x11.cpp and delete this note. - - Mxx:Pointer Map the mouse pointer. If someone has a mouse - Mxx:Pointer# device with multiple pointers, fix x11.cpp to - report that and you can use the second syntax. - - Mxx:B# Mouse buttons. diff --git a/source/docs/controls.txt b/source/docs/controls.txt deleted file mode 100644 index 703cd33..0000000 --- a/source/docs/controls.txt +++ /dev/null @@ -1,97 +0,0 @@ -This lists the available commands, excluding the ones you get back from -S9xGetAllSnes9xCommands(). The various meta-characters are: - # - A number. The range is detemined by the context - ## - A two-digit number (i.e. with leading zeros) - [...] - Something optional - (...) - For grouping with | - | - "or", choose one of the options. - <...> - A named field - {...} - A list of possible values. Multiple values may be used, but they - must be in the order listed and joined with +-signs. - "" - 'ditto', used to indicate the same list as the above line. - -Speeds are: Var, Slow, Med, and Fast. 'Var' starts slow and speeds up as the -button is held. - -Axes are: Left/Right, Right/Left, Up/Down, Down/Up, Y/A, A/Y, X/B, B/X, L/R, -and R/L. Negative is listed first (i.e. "Y/A" means negative deflection is -towards Y, while "A/Y" means negative deflection is towards A). - -AxisToPointer, ButtonToPointer, and AxisToButtons allow for translating -between different input types. There are 8 'pointers' with IDs -PseudoPointerBase+0 to PseudoPointerBase+7, and 256 'buttons' with IDs -PseudoButtonBase+0 to PseudoButtonBase+255. So for example, -"AxisToButtons 0/255 T=50%" would take the axis data, and do -S9xReportButton(PseudoButtonBase+0,1) when said axis goes past 50% in the -negative direction and S9xReportButton(PseudoButtonBase+255,1) when it goes -over 50% deflection in the positive direction. Similarly, it will do -S9xReportButton(...,0) when the deflection drops under 50% in either -direction. "ButtonToPointer 1u Slow" would move the pointer with ID -PseudoPointerBase+0 up one pixel per frame as long as the button is pressed -(reporting this change at the end of each frame). - ---------------- -Button Commands ---------------- - -Joypad# {Up, Down, Left, Right, A, B, X, Y, L, R, Start, Select} -Joypad# Turbo "" -Joypad# Sticky "" -Joypad# StickyTurbo "" -Joypad# ToggleTurbo "" -Joypad# ToggleSticky "" -Joypad# ToggleStickyTurbo "" - -Mouse# (L|R|LR) - -Superscope AimOffscreen -Superscope {Fire, Cursor, ToggleTurbo, Pause} -Superscope AimOffscreen "" - -Justifier# AimOffscreen -Justifier# {Trigger, Start} -Justifier# AimOffscreen "" - -ButtonToPointer #[u|d][l|r] ; NOTE: "# " is invalid - -------------- -Axis Commands -------------- - -Joypad# Axis T=#% ; T = 0.1 to 100 by tenths -AxisToButtons #/# T=#% ; neg then pos, range 0-255, T as above -AxisToPointer #(h|v) [-] ; NOTE: '-' inverts the axis - ----------------- -Pointer Commands ----------------- - -Pointer {Mouse1, Mouse2, Superscope, Justifier1, Justifier2} - ------- -Multis ------- - -Multis are a type of button command. The basic format of a multi is "{...}", -where the '...' consists of 1 or more valid non-multi button command -strings. The braces are literal, not metacharacters. Subcommands separated -by commas are executed one after the next. Semicolons skip one frame before -continuing subcommand execution. Semicolons may be repeated. When the multi -button is pressed, each subcommand is 'pressed', and when the multi button -is released each subcommand is 'released'. - -There are also press-only multis, defined as "+{...}". These act just like -regular multis, with two differences: the multi is only run when you press -the button (release isignored), and each subcommand must be prefixed with -'+' or '-' to indicate whether the the subcommand should be pressed or -released. - -For example: {Joypad1 A,Joypad2 A;Joypad3 A;;;;;QuickSave000} - This presses (or releases) A on pads 1 and 2, then waits one frame, then - presses A on pad 3, then waits 5 frames, then saves to snapshot 0 (on press - only). - -You may access the multi number in the returned s9xcommand_t structure as -cmd.button.multi_idx. This may be used to assign the same multi to multiple -buttons: - MULTI# ; NOTE: that's a literal octothorpe diff --git a/source/docs/gpl-2.0.txt b/source/docs/gpl-2.0.txt deleted file mode 100644 index d511905..0000000 --- a/source/docs/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/source/docs/lgpl-2.1.txt b/source/docs/lgpl-2.1.txt deleted file mode 100644 index 602bfc9..0000000 --- a/source/docs/lgpl-2.1.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/source/docs/porting.html b/source/docs/porting.html deleted file mode 100644 index a2d3d49..0000000 --- a/source/docs/porting.html +++ /dev/null @@ -1,371 +0,0 @@ - - - - - - - - Porting Snes9x - - -

How to Port Snes9x to a New Platform

-
- Version: 1.53
- (c) Copyright 1998 Gary Henderson -
-

Introduction

-

- This is brief description of the steps to port Snes9x to the new platform. It describes what code you have to write and what functions exist that you can make use of. It also gives some insights as to how Snes9x actually works, although that will be subject of another document yet to be written. -

-

System Requirements

-

- A C++ compiler. For the most part Snes9x really isn't written in C++, it just uses the C++ compiler as a “better C” compiler to get inline functions and so on. GCC is good for compiling Snes9x (http://gcc.gnu.org/). -

-

- A fast CPU. SNES emulation is very compute intensive; two, or sometimes three CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor with real-time sample decompression, filter and echo effects, two custom graphics processor chips that can produce transparency, scaling, rotation and window effects in 32768 colors, and finally hardware DMA all take their toll on the host CPU. -

-

- Enough RAM. Snes9x uses 8MB to load SNES ROM images and several MB for emulating sound, graphics, custom chips, and so on. -

-

- A 16-bit color (two bytes per pixel) or deeper display, at least 512*478 pixels in resolution. Pixel format conversion may be required before you place the rendered SNES screen on to the display. -

-

- Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound data to the host sound system. Some ports can use interrupts or callbacks from the sound system to know when more sound data is required, most other ports have to periodically poll the host sound system to see if more data is required; if it is then the sound mixing code is called to fill the sound buffer with SNES sound data, which then can be passed on to the host sound system. Sound data is generated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for 16-bit data. Stereo sound data generates twice as many samples, with each channel's samples interleaved, first left's then right's. -

-

- For the user to be able to control and play SNES games, some form of input device is required, a joypad or keyboard, for example. The real SNES can have 2 eight-button digital joypads connected to it or 5 joypads when an optional multi-player adaptor is connected, although most games only require a single joypad. Access to all eight buttons and the direction pad, of course, are usually required by most games. Snes9x does emulate the multi-player adaptor hardware, if you were wondering, but its still up to you to provide the emulation of the individual joypads. -

-

- The real SNES also has a SNES mouse, Super Scope and Justifier (light-gun) available as optional extras. Snes9x can emulate all of these using some form of pointing device, usually the host system's mouse. -

-

- Some SNES game cartridges contains a small amount of extra RAM and a battery, so ROMs could save a player's progress through a game for games that takes many hours to play from start to finish. Snes9x simulates this S-RAM by saving the contents of the area of memory occupied by the S-RAM into a file then automatically restoring it again the next time the user plays the same game. If the hardware you're porting to doesn't have a storage media available then you could be in trouble. -

-

- Snes9x also implements freeze-game files which can record the state of the SNES hardware and RAM at a particular point in time and can restore it to that exact state at a later date - the result is that users can save a game at any point, not just at save-game or password points provided by the original game coders. Each freeze file is over 400k in size. To help save disk space, Snes9x can be compiled with zlib (http://www.zlib.net/), which is used to GZIP compress the freeze files, reducing the size to typically below 100k. zlib is also used to load GZIP or ZIP compressed ROM images. Additionally, Snes9x supports JMA archives compressed with NSRT (http://nsrt.edgeemu.com/). -

-

Compile-Time Options

-

DEBUGGER

-

- Enables extra code to assist you in debugging SNES ROMs. The debugger has only ever been a quick-hack and user-interface to debugger facilities is virtually non-existent. Most of the debugger information is output via stdout and enabling the debugger slows the whole emulator down slightly. However, the debugger options available are very powerful; you could use it to help get your port working. You probably still want to ship the finished version with the debugger disabled, it will only confuse non-technical users. -

-

RIGHTSHIFT_IS_SAR

-

- Define this if your compiler uses shift right arithmetic for signed values. For example, GCC and Visual C++ use shift right arithmetic. -

-

ZLIB / UNZIP_SUPPORT / JMA_SUPPORT

-

- Define these if you want to support GZIP/ZIP/JMA compressed ROM images and GZIP compressed freeze-game files. -

-

USE_OPENGL

-

- Define this and set Settings.OpenGLEnable to true, then you'll get the rendered SNES image as one OpenGL texture. -

-

Typical Options Common for Most Platforms

-

- ZLIB
- UNZIP_SUPPORT
- JMA_SUPPORT
- RIGHTSHIFT_IS_SAR
-

-

Editing port.h

-

- You may need to edit port.h to fit Snes9x to your system. -

-

- If the byte ordering of your system is least significant byte first, make sure LSB_FIRST is defined, otherwise make sure it's not defined. -

-

- You'll need to make sure what pixel format your system uses for 16-bit colors (RGB565, RGB555, BGR565 or BGR555), and if it's not RGB565, define PIXEL_FORMAT to it so that Snes9x will use it to render the SNES screen. For example, Windows uses RGB565, Mac OS X uses RGB555. If your system supports more than one pixel format, you can define GFX_MULTI_FORMAT and change Snes9x's pixel format dynamically by calling S9xSetRenderPixelFormat function. If your system is 24 or 32-bit only, then don't define anything; instead write a conversion routine that will take a complete rendered 16-bit SNES screen in RGB565 format and convert to the format required to be displayed on your system. -

-

- port.h also typedefs some types; uint8 for an unsigned 8-bit quantity, uint16 for an unsigned 16-bit quantity, uint32 for a 32-bit unsigned quantity and bool8 for a true/false type. Signed versions are also typedef'ed. -

-

Controllers Management

-

- Read controls.h, crosshair.h, controls.txt and control-inputs.txt for details. This section is the minimal explanation to get the SNES controls workable. -

-

- The real SNES allows several different types of devices to be plugged into the game controller ports. The devices Snes9x emulates are a joypad, multi-player adaptor known as the Multi Player 5 or Multi Tap (allowing a further 4 joypads to be plugged in), a 2-button mouse, a light gun known as the Super Scope, and a light gun known as the Justifier. -

-

- In your initialization code, call S9xUnmapAllControl function. -

-

- Map any IDs to each SNES controller's buttons and pointers. (ID 249-255 are reserved). -

-

- Typically, use S9xMapPointer function for the pointer of the SNES mouse, Super Scope and Justifier, S9xMapButton function for other buttons. Set poll to false for the joypad buttons, true for the other buttons and pointers. -

-

- S9xMapButton(k1P_A_Button, s9xcommand_t cmd = S9xGetCommandT("Joypad1 A"), false); -

-

- In your main emulation loop, after S9xMainLoop function is called, check your system's keyboard/joypad, and call S9xReportButton function to report the states of the SNES joypad buttons to Snes9x. -

-

- void MyMainLoop (void)
- {
-     S9xMainLoop();
-     MyReportButttons();
- }
-

-

- void MyReportButtons (void)
- {
-     S9xReportButton(k1P_A_Button, (key_is_pressed ? true : false));
- }
-

-

- Prepare your S9xPollButton and S9xPollPointer function to reply Snes9x's request for other buttons/cursors states. -

-

- Call S9xSetController function. It connects each input device to each SNES input port.
- Here's typical controller settings that is used by the real SNES games: -

-

Joypad
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
-

-

Mouse (port 1)
- S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0);
- S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
-

-

Mouse (port 2)
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0);
-

-

Super Scope
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0);
-

-

Multi Player 5
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_MP5, 1, 2, 3, 4);
-

-

Justifier
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0);
-

-

Justifier (2 players)
- S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
- S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0);
-

-

Existing Interface Functions

-

bool8 Memory.Init (void)

-

- Allocates and initializes several major lumps of memory, for example the SNES ROM and RAM arrays, tile cache arrays, etc. Returns false if memory allocation fails. -

-

void Memory.Deinit (void)

-

- Deallocates the memory allocations made by Memory.Init function. -

-

bool8 S9xGraphicsInit (void)

-

- Allocates and initializes several lookup tables used to speed up SNES graphics rendering. Call after you have initialized the GFX.Screen and GFX.Pitch values. Returns false if memory allocation fails. -

-

void S9xGraphicsDeinit (void)

-

- Deallocates the memory allocations made by S9xGraphicsInit function. -

-

bool8 S9xInitAPU (void)

-

- Allocates and initializes several arrays used by the sound CPU and sound generation code. Returns false if memory allocation fails. -

-

void S9xDeinitAPU (void)

-

- Deallocates the allocations made by S9xInitAPU function. -

-

bool8 S9xInitSound (int buffer_ms, int lag_ms)

-

- Allocates memory for mixing and queueing SNES sound data, does more sound code initialization and opens the host system's sound device by calling S9xOpenSoundDevice, a function you must provide. Before calling this function you must set up Settings.SoundSync, Settings.SixteenBitSound, Settings.SoundPlaybackRate, Settings.SoundInputRate (see section below) and Settings.Stereo.
- buffer_ms, given in milliseconds, is the memory buffer size for queueing sound data. lag_ms is allowable latency between when a sample is queued and when it is pulled in S9xMixSamples. Set lag_ms to zero if you have your own latency handling code in your port. -

-

void S9xReset (void)

-

- Resets the SNES emulated hardware back to the state it was in at “switch-on” except the S-RAM area is preserved (“hardware reset”). The effect is it resets the current game back to the start. This function is automatically called by Memory.LoadROM function. -

-

void S9xSoftReset (void)

-

- Similar to S9xReset function, but “software reset” as you press the SNES reset button. -

-

bool8 Memory.LoadROM (const char *filepath)

-

- Attempts to load the specified ROM image filename into the emulated ROM area. There are many different SNES ROM image formats and the code attempts to auto-detect as many different types as it can and in a vast majority of the cases gets it right.
- There are several ROM image options in the Settingsstructure; allow the user to set them before calling Memory.LoadROM function, or make sure they are all reset to default values before each call to Memory.LoadROM function. See Settings.ForceXXX in snes9x.h. -

-

bool8 Memory.LoadMultiCart (const char *cartApath, const char *cartBpath)

-

- Attempts to load multiple ROM images into the emulated ROM area, for the multiple cartridge systems such as Sufami Turbo, Same Game, etc. -

-

bool8 Memory.LoadSRAM (const char *filepath)

-

- Call this function to load the associated S-RAM save file (if any). The filename should be based on the ROM image name to allow easy linkage. The current ports change the directory and the filename extension of the ROM filename to derive the S-RAM filename. -

-

bool8 Memory.SaveSRAM (const char *filepath)

-

- Call this function to save the emulated S-RAM area into a file so it can be restored again the next time the user wants to play the game. Remember to call this when just before the emulator exits or when the user has been playing a game and is about to load another one. -

-

void S9xMainLoop (void)

-

- The emulator main loop. Call this from your own main loop that calls this function (if a ROM image is loaded and the game is not paused), processes any pending host system events, then goes back around the loop again until the emulator exits. S9xMainLoop function normally returns control to your main loop once every emulated frame, when it reaches the start of scan-line zero. However it may take a few frames when a huge memory transfer is being emulated. The function can return more often if the DEBUGGER compile-time flag is defined and the CPU has hit a break point, or the DEBUG_MODE_FLAG bit is set in CPU.Flags or instruction single-stepping is enabled. -

-

void S9xMixSamples (uint8 *buffer, int sample_count)

-

- Call this function from your host sound system handling code to fill buffer with ready-mixed SNES sound data. If 16-bit sound mode is chosen, then the buffer will be filled with an array of sample_count int16, otherwise an array of sample_count uint8. If stereo sound generation is selected the buffer is filled with the same number of samples, but in pairs, first a left channel sample followed by the right channel sample.
- If there are less queued samples than you request by sample_count, the function fills buffer with silent sound data and returns false. To avoid this shortage of queued samples, request larger buffer size when calling S9xInitSound, and handle sound latency safely. -

-

int S9xGetSampleCount (void)

-

- Returns the number of sound samples available in the buffer for your configured playback settings. -

-

void S9xSetSamplesAvailableCallback (void (*) samples_available (void *), void *data)

-

- Call this function to set up a callback that is run when sound samples are made available. samples_available is a function you provide that returns void and takes a pointer as an argument. data is a pointer that you may wish to pass to your callback or can be NULL. If you choose to provide a callback, you must call the provided S9xFinalizeSamples function inside it to actually buffer the samples. If you are using a callback-oriented sound API, it is recommended to set up a function that locks a common mutex during the calls to S9xFinalizeSamples and S9xMixSamples to prevent them from running at the same time and corrupting the sound buffer.
- If you wish to disable a callback you have set up or need to temporarily shut down your sound system, you may pass NULL for both arguments to revert to the built-in version. -

-

bool8 S9xSyncSound (void)

-

- Call this function to synchronize the sound buffers to the game state. If Snes9x is generating too much sound data, or a buffer-overrun is likely, this function will return false. In this case, you may wish to wait until your host sound system uses the available samples, and S9xSyncSound returns true before continuing to execute S9xMainLoop. -

-

bool8 S9xSetSoundMute (bool8 mute)

-

- Call with a true parameter to prevent S9xMixSamples function from processing SNES sample data and instead just filling the return buffer with silent sound data. Useful if your sound system is interrupt or callback driven and the game has been paused either directly or indirectly because the user interacting with the emulator's user interface in some way. -

-

bool8 S9xFreezeGame (const char *filepath)

-

- Call this function to record the current SNES hardware state into a file, the file can be loaded back using S9xUnfreezeGame function at a later date effectively restoring the current game to exact same spot. Call this function while you're processing any pending system events when S9xMainLoop function has returned control to you in your main loop. -

-

bool8 S9xUnfreezeGame (const char *filepath)

-

- Restore the SNES hardware back to the exactly the state it was in when S9xFreezeGame function was used to generate the file specified. You have to arrange the correct ROM is already loaded using Memory.LoadROM function, an easy way to arrange this is to base freeze-game filenames on the ROM image name. The UNIX/Linux ports load freeze-game files when the user presses a function key, with the names romfilename.000 for F1, romfilename.001 for F2, etc. Games are frozen in the first place when the user presses Shift-function key. You could choose some other scheme. -

-

void S9xDumpSPCSnapshot (void)

-

- Call this funtion to make a so-called SPC file, a snapshot of SNES sound state. Actual dump occurs at the first key-on event after this function is called. -

-

void S9xSetInfoString (const char *string)

-

- Call this function if you want to show a message onto the SNES screen. -

-

Other Available Functions

-

- See movie.h and movie.cpp to support the Snes9x movie feature.
- See cheats.h, cheats.cpp and cheats2.cpp to support the cheat feature. -

-

Interface Functions You Need to Implement

-

bool8 S9xOpenSnapshotFile (const char *filepath, bool8 read_only, STREAM *file)

-

- This function opens a freeze-game file. STREAM is defined as a gzFile if ZLIB is defined else it's defined as FILE *. The read_only parameter is set to true when reading a freeze-game file and false when writing a freeze-game file. Open the file filepath and return its pointer file. -

-

void S9xCloseSnapshotFile (STREAM file)

-

- This function closes the freeze-game file opened by S9xOpenSnapshotFile function. -

-

void S9xExit (void)

-

- Called when some fatal error situation arises or when the “q” debugger command is used. -

-

bool8 S9xInitUpdate (void)

-

- Called just before Snes9x begins to render an SNES screen. Use this function if you should prepare before drawing, otherwise let it empty. -

-

bool8 S9xDeinitUpdate (int width, int height)

-

- Called once a complete SNES screen has been rendered into the GFX.Screen memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478. -

-

void S9xMessage (int type, int number, const char *message)

-

- When Snes9x wants to display an error, information or warning message, it calls this function. Check in messages.h for the types and individual message numbers that Snes9x currently passes as parameters.
- The idea is display the message string so the user can see it, but you choose not to display anything at all, or change the message based on the message number or message type.
- Eventually all debug output will also go via this function, trace information already does. -

-

bool8 S9xOpenSoundDevice (void)

-

- S9xInitSound function calls this function to actually open the host sound device. -

-

const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype)

-

- When Snes9x needs to know the name of the cheat/IPS file and so on, this function is called. Check extension and dirtype, and return the appropriate filename. The current ports return the ROM file path with the given extension. -

-

const char *S9xGetFilenameInc (const char *extension, enum s9x_getdirtype dirtype)

-

- Almost the same as S9xGetFilename function, but used for saving SPC files etc. So you have to take care not to delete the previously saved file, by increasing the number of the filename; romname.000.spc, romname.001.spc, ... -

-

const char *S9xGetDirectory (enum s9x_getdirtype dirtype)

-

- Called when Snes9x wants to know the directory dirtype. -

-

const char *S9xChooseFilename (bool8 read_only)

-

- If your port can match Snes9x's built-in LoadFreezeFile/SaveFreezeFile command (see controls.cpp), you may choose to use this function. Otherwise return NULL. -

-

const char *S9xChooseMovieFilename (bool8 read_only)

-

- If your port can match Snes9x's built-in BeginRecordingMovie/LoadMovie command (see controls.cpp), you may choose to use this function. Otherwise return NULL. -

-

const char *S9xBasename (const char *path)

-

- Called when Snes9x wants to know the name of the ROM image. Typically, extract the filename from path and return it. -

-

void S9xAutoSaveSRAM (void)

-

- If Settings.AutoSaveDelay is not zero, Snes9x calls this function when the contents of the S-RAM has been changed. Typically, call Memory.SaveSRAM function from this function. -

-

void S9xToggleSoundChannel (int c)

-

- If your port can match Snes9x's built-in SoundChannelXXX command (see controls.cpp), you may choose to use this function. Otherwise return NULL. Basically, turn on/off the sound channel c (0-7), and turn on all channels if c is 8. -

-

void S9xSetPalette (void)

-

- Called when the SNES color palette has changed. Use this function if your system should change its color palette to match the SNES's. Otherwise let it empty. -

-

void S9xSyncSpeed (void)

-

- Called at the end of S9xMainLoop function, when emulating one frame has been done. You should adjust the frame rate in this function. -

-

Global Variables

-

uint16 *GFX.Screen

-

- A uint16 array pointer to (at least) 2*512*478 bytes buffer where Snes9x puts the rendered SNES screen. However, if your port will not support hires mode (Settings.SupportHiRes = false), then a 2*256*239 bytes buffer is allowed. You should allocate the space by yourself. As well you can change the GFX.Screen value after S9xDeinitUpdate function is called so that double-buffering will be easy. -

-

uint32 GFX.Pitch

-

- Bytes per line (not pixels per line) of the GFX.Screen buffer. Typically set it to 1024. When the SNES screen is 256 pixels width and Settings.OpenGLEnable is false, last half 512 bytes per line are unused. When Settings.OpenGLEnable is true, GFX.Pitch is ignored. -

-

Settings structure

-

- There are various switches in the Settings structure. See snes9x.h for details. At least the settings below are required for good emulation. -

-

- memset(&Settings, 0, sizeof(Settings));
- Settings.MouseMaster = true;
- Settings.SuperScopeMaster = true;
- Settings.JustifierMaster = true;
- Settings.MultiPlayer5Master = true;
- Settings.FrameTimePAL = 20000;
- Settings.FrameTimeNTSC = 16667;
- Settings.SixteenBitSound = true;
- Settings.Stereo = true;
- Settings.SoundPlaybackRate = 32000;
- Settings.SoundInputRate = 32000;
- Settings.SupportHiRes = true;
- Settings.Transparency = true;
- Settings.AutoDisplayMessages = true;
- Settings.InitialInfoStringTimeout = 120;
- Settings.HDMATimingHack = 100;
- Settings.BlockInvalidVRAMAccessMaster = true; -

-

Settings.SoundInputRate

-

- Adjusts the sound rate through resampling. For every Settings.SoundInputRate samples generated by the SNES, Settings.SoundPlaybackRate samples will be produced.
- The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure Settings.SoundInputRate to suit their own systems. Setting Settings.SoundInputRate to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the S9xSyncSound function can eliminate sound discontinuity. -

-
- Updated most recently by: 2011/1/16 zones -
- - diff --git a/source/docs/portsofsnes9x.txt b/source/docs/portsofsnes9x.txt deleted file mode 100644 index d05365c..0000000 --- a/source/docs/portsofsnes9x.txt +++ /dev/null @@ -1,118 +0,0 @@ -These are all the known ports of Snes9X to other consoles/handhelds/etc as of -2011/04/24. They are all supported and welcomed on the official Snes9X site. - -**If you know of anyone who is currently working on a port of Snes9X, or if you -have some interest in making a port, please have them go to the Snes9X forums -(http://www.snes9x.com/phpbb2/) and have them register an account there. After -that, speak to Ryan and/or Jerremy so you can be let into the devs area and the -git so you can have access to the most current code, collaborate with the other -developers, make the port officialized, etc.** - -Ports and how to get them running are as follows: - -*PSP Version of Snes9X* -Name: Snes9X Euphoria -Latest version: R5 Beta -Homepage/forum: http://www.retroemu.com/forum/ -Maintainer: Zack - -HOW TO GET IT RUNNING: -*DISCLAIMER* You will have to do some Googling, including but not limited to: -* Downgrading/upgrading your firmware -* Checking if your PSP-2000 series can use Pandora's Battery -* Checking if your PSP-3000 series can use the DaveeFTW Downgrader -* Creating Pandora's Battery -* Finding the hacks, HENs, CFWs, etc and how to use/install them - -1. Make sure your PSP is hackable in some way. This means: -* PSP-1000 series and certain PSP-2000 series can use Pandora Battery -* PSP-2000 series that can't use Pandora Battery, most PSP-3000 series, and PSP -Gos are hackable via other means (DaveeFTW Downgrader, etc) - -2. Make sure your PSP has custom firmware or a HEN that's useable (you'll have -to upgrade/downgrade the firmware as necessary). (Hint: I personally prefer -5.50 GEN-D3 on the Pandora-able PSPs; 6.20 or 6.35 PRO-B4 or better on the -non-Pandora-able PSPs.) - -3. When that’s done, be sure to put the Snes9X Euphoria folder in /PSP/GAME on -your PSP’s memory stick (PSP-1000/2000/3000 series) or internal memory -(PSP Go). Be sure to copy the ROMs into the roms folder, saves (*.srm, etc) -into the saves folder, and cheats into the cheats folder. - -*Wii/Gamecube version of Snes9X* -Name: Snes9X GX -Latest Version: 4.2.7 -Homepage/forum: http://code.google.com/p/snes9x-gx -Maintainer: Tantric - -HOW TO GET IT RUNNING: -*DISCLAIMER* You will have to do some Googling, including but not limited to: -* Finding the latest Homebrew Channel, Snes9X GX Channel, and/or IOS58 -installers and installing them -* Finding a modchip for your GameCube and installing it - -Wii: You will need the latest Homebrew Channel installed on your Wii. After -that, copy and paste the apps folder onto the root of your SD card; same goes -for the snes9xgx folder. After that, copy over any ROMs you have to the -\snes9xgx\roms folder, save files (*.srm, etc) to the \snes9xgx\saves folder, -and cheats to the \snes9xgx\cheats folder. - -In addition, there appears to be a channel for Snes9X GX; you will need the -Homebrew Channel installed and you MUST be on System Menu 4.3 so you can be on -IOS58 (or use the IOS58 installer). After that, you should be able to run the -installer from the Homebrew Channel, and you'll be good to go! - -Gamecube: You might need a modchip. - -*Android and iOS (Apple iPhone/iPod Touch) version of Snes9X* -Name: Snes9X EX -Latest Version: 1.3.23 -Homepage/forum: http://www.explusalpha.com/home/snes9x-ex -Maintainer: Rakashazi (on the Snes9X forums) - -HOW TO GET IT RUNNING: -*DISCLAIMER* You will have to do some Googling, including but not limited to: -* iOS (iPhone/iPod Touch) ONLY!!!: Jailbreaking your firmware - -Android: It appears you can just download from the Android app-store thingy and -run it from there :) Be sure to copy over your ROMs, saves, etc though. - -iOS: You’ll have to jailbreak your firmware and install the Cydia app -installer. Then you’ll have to install the BigBoss repository within Cydia and -search for Snes9X EX; you may also want to search for the sshd and all needed -stuff for that, as it’s the only way you can put the ROMs, saves, etc onto your -iPhone/iPod Touch. After that you should be able to download and run from there -:) - -*PS3 version of Snes9X* -Name: Snes9X PS3 -Latest Version: 4.4.9 -Homepage/forum: https://code.google.com/p/snes9x-ps3/ (although for some -reason, you may have to Google for the latest version) -Maintainer: Squarepusher - -HOW TO GET IT RUNNING: -*DISCLAIMER* You will have to do some Googling, including but not limited to: -* Finding a HEN/Jailbreaker/CFW/etc onto your PS3 and installing it -* (if necessary) Downgrading/Upgrading your PS3's firmware - -You’ll have to install a HEN/Jailbreaker/CFW/etc on your PS3 (you might have to -upgrade or downgrade your PS3’s firmware as needed). After that, it should be -as simple as copy the emulator, ROMs, saves, etc over to the PS3 and it should -work :) - -*X-Box Version of Snes9X* -Name: Snes9xbox -Latest Version: V2 (V3 should be out soon) -Homepage/forum: http://forums.xbox-scene.com/index.php?showforum=96 - -HOW TO GET IT RUNNING: -*DISCLAIMER* You will need to do some Googling, including but not limited to: -* Finding a softmod (hack) or a modchip and installing/using it -* Finding a replacement dashboard such as XBMC - -Really, it's not hard. Read the readme, and use a softmod or modchip and a -replacement dashboard. After that's installed, it should be as simple as -copying over the emulator, ROMs, saves, etc to the X-Box and it should work. - -Updated most recently by: 2011/4/24 adventure_of_link \ No newline at end of file diff --git a/source/docs/snapshots.txt b/source/docs/snapshots.txt deleted file mode 100644 index ef0d1fd..0000000 --- a/source/docs/snapshots.txt +++ /dev/null @@ -1,84 +0,0 @@ -***** Important notice ******************************************************** - This document describes the snapshot file format for Snes9x 1.52 and later, - not compatible with 1.51. -******************************************************************************* - - Snes9x snapshot file format: (may be gzip-compressed) - - Begins with fixed length signature, consisting of a string, ':', a 4-digit - decimal version, and a '\n'. - -#!s9xsnp:0006 <-- '\n' after the 6 - - Then we have various blocks. The block format is: 3-character block name, - ':', 6-digit length, ':', then the data. Blocks are written in a defined - order. Structs are written packed with their members in a defined order, in - big-endian order where applicable. - -NAM:000019:Chrono Trigger.zip - - Currently defined blocks (in order) are: - - Essential parts: - NAM - ROM filename, from Memory.ROMFilename. 0-terminated string. - CPU - struct SCPUState, CPU internal state variables. - REG - struct SRegisters, emulated CPU registers. - PPU - struct SPPU, PPU internal variables. Note that IPPU is never saved. - DMA - struct SDMA, DMA/HDMA state variables. - VRA - Memory.VRAM, 0x10000 bytes. - RAM - Memory.RAM, 0x20000 bytes (WRAM). - SRA - Memory.SRAM, 0x20000 bytes. - FIL - Memory.FillRAM, 0x8000 bytes (register backing store). - SND - All of sound emulated registers and state valiables. - CTL - struct SControlSnapshot, controller emulation. - TIM - struct STimings, variables about timings between emulated events. - - Optional parts: - SFX - struct FxRegs_s, Super FX. - SA1 - struct SSA1, SA1 internal state variables. - SAR - struct SSA1Registers, SA1 emulated registers. - DP1 - struct SDSP1, DSP-1. - DP2 - struct SDSP2, DSP-2. - DP4 - struct SDSP4, DSP-4. - CX4 - Memory.C4RAM, 0x2000 bytes. - ST0 - struct SST010, ST-010. - OBC - struct SOBC1, OBC1 internal state variables. - OBM - Memory.OBC1RAM, 0x2000 byts. - S71 - struct SSPC7110Snapshot, SPC7110. - SRT - struct SSRTCSnapshot, S-RTC internal state variables. - CLK - struct SRTCData, S-RTC emulated registers. - BSX - struct SBSX, BS-X. - SHO - rendered SNES screen. - MOV - struct SnapshotMovieInfo. - MID - Some block of data the movie subsystem. - -================== - -Without changing the snapshot version number: ---------------------------------------------- - -Blocks may be safely added at the END of the file, as anything after the last -block is ignored. Blocks may not be moved or removed. - -Blocks may not decrease in size. Say you decrease from 10 bytes to 5. Then -later you increase back to 8. The only way you could safely do this is if -bytes 5-7 still mean the same thing they meant when the block was 10 bytes -long. - -Blocks may increase in size as you wish, as long as you can handle old -savestates with the old shorter size. - -Struct members may not change in interpretation. New struct members may be -added (at the END!) only if you can cope with them being binary-0 in older -savestates. Struct members may not be removed or changed in size/type. - -With changing the snapshot version number: ------------------------------------------- - -Blocks may be added, moved, or removed at will. - -Blocks may decrease in size. - -Struct members may be added, moved, or deleted, and their -interpretations/types may be changed. Use the 'debuted_in' and 'deleted_in' -fields to indicate when the new member debuted or the old member went away. diff --git a/source/docs/snes9x-license.txt b/source/docs/snes9x-license.txt deleted file mode 100644 index 19d5fd6..0000000 --- a/source/docs/snes9x-license.txt +++ /dev/null @@ -1,174 +0,0 @@ - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2002 - 2004 Matthew Kendora - - (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) - - (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) - - (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), - Kris Bleakley (codeviolation@hotmail.com) - - (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), - Nach (n-a-c-h@users.sourceforge.net), - - (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) - - (c) Copyright 2006 - 2007 nitsuja - - (c) Copyright 2009 - 2011 BearOso, - OV2 - - - BS-X C emulator code - (c) Copyright 2005 - 2006 Dreamer Nom, - zones - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), - Nach, - zsKnight (zsknight@zsnes.com) - - C4 C++ code - (c) Copyright 2003 - 2006 Brad Jorsch, - Nach - - DSP-1 emulator code - (c) Copyright 1998 - 2006 _Demo_, - Andreas Naive (andreasnaive@gmail.com), - Gary Henderson, - Ivar (ivar@snes9x.com), - John Weidman, - Kris Bleakley, - Matthew Kendora, - Nach, - neviksti (neviksti@hotmail.com) - - DSP-2 emulator code - (c) Copyright 2003 John Weidman, - Kris Bleakley, - Lord Nightmare (lord_nightmare@users.sourceforge.net), - Matthew Kendora, - neviksti - - DSP-3 emulator code - (c) Copyright 2003 - 2006 John Weidman, - Kris Bleakley, - Lancer, - z80 gaiden - - DSP-4 emulator code - (c) Copyright 2004 - 2006 Dreamer Nom, - John Weidman, - Kris Bleakley, - Nach, - z80 gaiden - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, - pagefault (pagefault@zsnes.com), - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code used in 1.39-1.51 - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, - John Weidman, - Dark Force - - SPC7110 and RTC C++ emulator code used in 1.52+ - (c) Copyright 2009 byuu, - neviksti - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive, - John Weidman - - S-RTC C emulator code - (c) Copyright 2001 - 2006 byuu, - John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, - John Weidman, - Kris Bleakley, - Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 _Demo_, - pagefault, - zsKnight - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, - Gary Henderson, - John Weidman - - Sound emulator code used in 1.5-1.51 - (c) Copyright 1998 - 2003 Brad Martin - (c) Copyright 1998 - 2006 Charles Bilyue' - - Sound emulator code used in 1.52+ - (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - 2xSaI filter - (c) Copyright 1999 - 2001 Derek Liauw Kie Fa - - HQ2x, HQ3x, HQ4x filters - (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) - - NTSC filter - (c) Copyright 2006 - 2007 Shay Green - - GTK+ GUI code - (c) Copyright 2004 - 2011 BearOso - - Win32 GUI code - (c) Copyright 2003 - 2006 blip, - funkyass, - Matthew Kendora, - Nach, - nitsuja - (c) Copyright 2009 - 2011 OV2 - - Mac OS GUI code - (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2011 zones - - - Specific ports contains the works of other authors. See headers in - individual files. - - - Snes9x homepage: http://www.snes9x.com/ - - Permission to use, copy, modify and/or distribute Snes9x in both binary - and source form, for non-commercial purposes, is hereby granted without - fee, providing that this license information and copyright notice appear - with all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software or it's derivatives. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes, - but is not limited to, charging money for Snes9x or software derived from - Snes9x, including Snes9x or derivatives in commercial game bundles, and/or - using Snes9x as a promotion for your commercial product. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. diff --git a/source/docs/snes9x.conf.default b/source/docs/snes9x.conf.default deleted file mode 100644 index 4f36d25..0000000 --- a/source/docs/snes9x.conf.default +++ /dev/null @@ -1,238 +0,0 @@ -#----------------------------------------- -# snes9x.conf : Snes9x Configuration file -#----------------------------------------- - -[ROM] -# Filename = -LoROM = FALSE -HiROM = FALSE -PAL = FALSE -NTSC = FALSE -# Header = TRUE/FALSE to ForceHeader or ForceNoHeader -# Interleaved = TRUE/FALSE to ForceInterleaved or ForceNoInterleaved -Interleaved2 = FALSE -InterleaveGD24 = FALSE -Cheat = FALSE -Patch = TRUE - -[Sound] -Sync = FALSE -16BitSound = TRUE -Stereo = TRUE -ReverseStereo = FALSE -Rate = 32000 -InputRate = 32000 -Mute = FALSE - -[Display] -HiRes = TRUE -Transparency = TRUE -GraphicWindows = TRUE -DisplayFrameRate = FALSE -DisplayWatchedAddresses = FALSE -DisplayInput = FALSE -DisplayFrameCount = FALSE -MessagesInImage = TRUE -MessageDisplayTime = 120 - -[Settings] -BSXBootup = FALSE -# FrameTime = -FrameSkip = Auto -TurboMode = FALSE -TurboFrameSkip = 15 -MovieTruncateAtEnd = FALSE -MovieNotifyIgnored = FALSE -WrongMovieStateProtection = TRUE -StretchScreenshots = 1 -SnapshotScreenshots = TRUE -DontSaveOopsSnapshot = FALSE -AutoSaveDelay = 0 - -[Controls] -MouseMaster = TRUE -SuperscopeMaster = TRUE -JustifierMaster = TRUE -MP5Master = TRUE -AllowLeftRight = FALSE -Port1 = pad1 -Port2 = none -Mouse1Crosshair = 1 White/Black -Mouse2Crosshair = 1 White/Black -SuperscopeCrosshair = 2 White/Black -Justifier1Crosshair = 4 Blue/Black -Justifier2Crosshair = 4 MagicPink/Black - -[Hack] -EnableGameSpecificHacks = TRUE -AllowInvalidVRAMAccess = FALSE -SpeedHacks = FALSE -HDMATiming = 100 - -[Netplay] -Enable = FALSE -Port = 6096 -Server = "" - -[DEBUG] -Debugger = FALSE -Trace = FALSE - -[Unix] -# BaseDir = ~/.snes9x -# SnapshotFilename = -# PlayMovieFilename = -# RecordMovieFilename = -EnableGamePad = TRUE -PadDevice1 = (null) -PadDevice2 = (null) -PadDevice3 = (null) -PadDevice4 = (null) -PadDevice5 = (null) -PadDevice6 = (null) -PadDevice7 = (null) -PadDevice8 = (null) -ThreadSound = FALSE -SoundBufferSize = 100 -SoundFragmentSize = 2048 -# SoundDevice = -ClearAllControls = FALSE - -[Unix/X11] -SetKeyRepeat = TRUE -VideoMode = 1 - -[Unix/X11 Controls] -J00:Axis1 = Joypad1 Axis Up/Down T=50% -J00:Axis0 = Joypad1 Axis Left/Right T=50% -J00:B1 = Joypad1 A -J00:B2 = Joypad1 B -J00:B0 = Joypad1 X -J00:B3 = Joypad1 Y -J00:B6 = Joypad1 L -J00:B7 = Joypad1 R -J00:B8 = Joypad1 Select -J00:B11 = Joypad1 Start -K00:u = Joypad1 Up -K00:Up = Joypad1 Up -K00:j = Joypad1 Down -K00:n = Joypad1 Down -K00:Down = Joypad1 Down -K00:h = Joypad1 Left -K00:Left = Joypad1 Left -K00:k = Joypad1 Right -K00:Right = Joypad1 Right -K00:d = Joypad1 A -K00:S+d = Joypad1 ToggleTurbo A -K00:C+d = Joypad1 ToggleSticky A -K00:c = Joypad1 B -K00:S+c = Joypad1 ToggleTurbo B -K00:C+c = Joypad1 ToggleSticky B -K00:s = Joypad1 X -K00:S+s = Joypad1 ToggleTurbo X -K00:C+s = Joypad1 ToggleSticky X -K00:x = Joypad1 Y -K00:S+x = Joypad1 ToggleTurbo Y -K00:C+x = Joypad1 ToggleSticky Y -K00:a = Joypad1 L -K00:v = Joypad1 L -K00:S+a = Joypad1 ToggleTurbo L -K00:S+v = Joypad1 ToggleTurbo L -K00:C+a = Joypad1 ToggleSticky L -K00:C+v = Joypad1 ToggleSticky L -K00:z = Joypad1 R -K00:S+z = Joypad1 ToggleTurbo R -K00:C+z = Joypad1 ToggleSticky R -K00:space = Joypad1 Select -K00:Return = Joypad1 Start -K00:KP_Up = Joypad2 Up -K00:KP_Down = Joypad2 Down -K00:KP_Left = Joypad2 Left -K00:KP_Right = Joypad2 Right -K00:Prior = Joypad2 A -K00:Next = Joypad2 B -K00:Home = Joypad2 X -K00:End = Joypad2 Y -K00:Insert = Joypad2 L -K00:Delete = Joypad2 R -K00:KP_Add = Joypad2 Select -K00:KP_Enter = Joypad2 Start -K00:Escape = ExitEmu -K00:Pause = Pause -K00:Scroll_Lock = Pause -K00:CS+Escape = Reset -K00:S+Escape = SoftReset -K00:F12 = SaveFreezeFile -K00:A+F3 = SaveFreezeFile -K00:C+F3 = SaveFreezeFile -K00:F11 = LoadFreezeFile -K00:A+F2 = LoadFreezeFile -K00:C+F2 = LoadFreezeFile -K00:S+F1 = QuickSave000 -K00:S+F2 = QuickSave001 -K00:S+F3 = QuickSave002 -K00:S+F4 = QuickSave003 -K00:S+F5 = QuickSave004 -K00:S+F6 = QuickSave005 -K00:S+F7 = QuickSave006 -K00:S+F8 = QuickSave007 -K00:S+F9 = QuickSave008 -K00:F1 = QuickLoad000 -K00:F2 = QuickLoad001 -K00:F3 = QuickLoad002 -K00:F4 = QuickLoad003 -K00:F5 = QuickLoad004 -K00:F6 = QuickLoad005 -K00:F7 = QuickLoad006 -K00:F8 = QuickLoad007 -K00:F9 = QuickLoad008 -K00:F10 = LoadOopsFile -K00:A+F1 = SaveSPC -K00:C+F1 = SaveSPC -K00:Print = Screenshot -K00:S+1 = BeginRecordingMovie -K00:S+2 = EndRecordingMovie -K00:S+3 = LoadMovie -K00:Tab = EmuTurbo -K00:S+Tab = ToggleEmuTurbo -K00:equal = IncFrameRate -K00:minus = DecFrameRate -K00:S+equal = IncFrameTime -K00:S+minus = DecFrameTime -K00:A+equal = IncEmuTurbo -K00:A+minus = DecEmuTurbo -K00:C+equal = IncTurboSpeed -K00:C+minus = DecTurboSpeed -K00:6 = SwapJoypads -K00:A+F4 = SoundChannel0 -K00:C+F4 = SoundChannel0 -K00:A+F5 = SoundChannel1 -K00:C+F5 = SoundChannel1 -K00:A+F6 = SoundChannel2 -K00:C+F6 = SoundChannel2 -K00:A+F7 = SoundChannel3 -K00:C+F7 = SoundChannel3 -K00:A+F8 = SoundChannel4 -K00:C+F8 = SoundChannel4 -K00:A+F9 = SoundChannel5 -K00:C+F9 = SoundChannel5 -K00:A+F10 = SoundChannel6 -K00:C+F10 = SoundChannel6 -K00:A+F11 = SoundChannel7 -K00:C+F11 = SoundChannel7 -K00:A+F12 = SoundChannelsOn -K00:C+F12 = SoundChannelsOn -K00:1 = ToggleBG0 -K00:2 = ToggleBG1 -K00:3 = ToggleBG2 -K00:4 = ToggleBG3 -K00:5 = ToggleSprites -K00:9 = ToggleTransparency -K00:BackSpace = ClipWindows -K00:A+Escape = Debugger -M00:Pointer = Pointer Mouse1+Superscope+Justifier1 -M00:B0 = {Mouse1 L,Superscope Fire,Justifier1 Trigger} -M00:B2 = {Mouse1 R,Superscope Cursor,Justifier1 Start} -M00:B1 = {Justifier1 AimOffscreen Trigger,Superscope AimOffscreen} -K00:grave = Superscope ToggleTurbo -K00:slash = Superscope Pause -- cgit v1.2.3 From c01a2a42168695233ecc69c4a60ed918e7701fb9 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Fri, 28 Dec 2012 01:45:40 -0500 Subject: Keep the audio processing unit (APU) enabled even when the user disabled the audio for a game. This allows some games that synchronise on the APU's actions to continue working. --- source/nds/entry.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index b4467a1..33566d5 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -341,12 +341,10 @@ void game_disableAudio() { if( game_enable_audio == 1) { - Settings.APUEnabled = Settings.NextAPUEnabled = TRUE; S9xSetSoundMute (FALSE); } else { - Settings.APUEnabled = Settings.NextAPUEnabled = FALSE; S9xSetSoundMute (TRUE); } } @@ -510,8 +508,6 @@ int load_gamepak(char* file) */ // mdelay(50); // Delete this delay - if (!Settings.APUEnabled) - S9xSetSoundMute (FALSE); return 0; } @@ -535,9 +531,6 @@ int sfc_main (int argc, char **argv) S9xInitSound (Settings.SoundPlaybackRate, Settings.Stereo, Settings.SoundBufferSize); - if (!Settings.APUEnabled) - S9xSetSoundMute (TRUE); - #ifdef GFX_MULTI_FORMAT // S9xSetRenderPixelFormat (RGB565); S9xSetRenderPixelFormat (BGR555); @@ -861,7 +854,7 @@ void S9xProcessSound (unsigned int) { unsigned short *audiobuff; - if (!Settings.APUEnabled || so.mute_sound ) + if (so.mute_sound || !game_enable_audio) return; if(ds2_checkAudiobuff() > 4) -- cgit v1.2.3