Commit my changes, version set to 0.099
[cyclone68000.git] / Cyclone / Cyclone.txt
index 0b0d062..c305f27 100644 (file)
                                                               \r
 ___________________________________________________________________________\r
 \r
+  Copyright (c) 2004,2011 FinalDave (emudave (at) gmail.com)\r
+  Copyright (c) 2005-2011 GraÅžvydas "notaz" Ignotas (notasas (at) gmail.com)\r
 \r
-This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
-You can choose the license that has the most advantages for you.\r
+  This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
+  You can choose the license that has the most advantages for you.\r
+\r
+  Homepage: http://code.google.com/p/cyclone68000/\r
 \r
 ___________________________________________________________________________\r
 \r
 \r
-What is it?\r
------------\r
+About\r
+-----\r
 \r
 Cyclone 68000 is an emulator for the 68000 microprocessor, written in ARM 32-bit assembly.\r
 It is aimed at chips such as ARM7 and ARM9 cores, StrongARM and XScale, to interpret 68000\r
-code as fast as possible.\r
-\r
-Flags are mapped onto ARM flags whenever possible, which speeds up the processing of opcode.\r
-\r
-Developers:\r
------------\r
-\r
-Dave / FinalDave: emudave(atsymbol)gmail.com\r
-\r
-\r
-What's New\r
-----------\r
-v0.069\r
-  + Added SBCD and the flags for ABCD/SBCD. Score and time now works in games such as\r
-    Rolling Thunder 2, Ghouls 'N Ghosts\r
-  + Fixed a problem with addx and subx with 8-bit and 16-bit values.\r
-    Ghouls 'N' Ghosts now works!\r
-\r
-v0.068\r
-  + Added ABCD opcode (Streets of Rage works now!)\r
-\r
-v0.067\r
-  + Added dbCC (After Burner)\r
-  + Added asr EA (Sonic 1 Boss/Labyrinth Zone)\r
-  + Added andi/ori/eori ccr (Altered Beast)\r
-  + Added trap (After Burner)\r
-  + Added special case for move.b (a7)+ and -(a7), stepping by 2\r
-    After Burner is playable! Eternal Champions shows more\r
-  + Fixed lsr.b/w zero flag (Ghostbusters)\r
-    Rolling Thunder 2 now works!\r
-  + Fixed N flag for .b and .w arithmetic. Golden Axe works!\r
-\r
-v0.066\r
-  + Fixed a stupid typo for exg (orr r10,r10, not orr r10,r8), which caused alignment\r
-    crashes on Strider\r
-\r
-v0.065\r
-  + Fixed a problem with immediate values - they weren't being shifted up correctly for some\r
-    opcodes. Spiderman works, After Burner shows a bit of graphics.\r
-  + Fixed a problem with EA:"110nnn" extension word. 32-bit offsets were being decoded as 8-bit\r
-    offsets by mistake. Castlevania Bloodlines seems fine now.\r
-  + Added exg opcode\r
-  + Fixed asr opcode (Sonic jumping left is fixed)\r
-  + Fixed a problem with the carry bit in rol.b (Marble Madness)\r
-\r
-v0.064\r
-  + Added rtr\r
-  + Fixed addq/subq.l (all An opcodes are 32-bit) (Road Rash)\r
-  + Fixed various little timings\r
-\r
-v0.063\r
-  + Added link/unlk opcodes\r
-  + Fixed various little timings\r
-  + Fixed a problem with dbCC opcode being emitted at set opcodes\r
-  + Improved long register access, the EA fetch now does ldr r0,[r7,r0,lsl #2] whenever\r
-     possible, saving 1 or 2 cycles on many opcodes, which should give a nice speed up.\r
-  + May have fixed N flag on ext opcode?\r
-  + Added dasm for link opcode.\r
+code as fast as possible. It can emulate all 68000 instructions quite accurately, instruction\r
+timing was synchronized with MAME's Musashi. Most 68k features are emulated (trace mode,\r
+address errors), but prefetch is not emulated.\r
 \r
-v0.062\r
-  * I was a bit too keen with the Arithmetic opcodes! Some of them should have been abcd,\r
-    exg and addx. Removed the incorrect opcodes, pending re-adding them as abcd, exg and addx.\r
-  + Changed unknown opcodes to act as nops.\r
-    Not very technical, but fun - a few more games show more graphics ;)\r
 \r
-v0.060\r
-  + Fixed divu (EA intro)\r
-  + Added sf (set false) opcode - SOR2\r
-  * Todo: pea/link/unlk opcodes\r
+How to Compile\r
+--------------\r
 \r
-v0.059: Added remainder to divide opcodes.\r
+Like Starscream and A68K, Cyclone uses a 'Core Creator' program which calculates and outputs\r
+all possible 68000 Opcodes and a jump table into file called Cyclone.s or Cyclone.asm.\r
+Only Cyclone.h and the mentioned .s or .asm file will be needed for your project, other files\r
+are here to produce or test it.\r
 \r
+First unzip "Cyclone.zip" into a "Cyclone" directory. The next thing to do is to edit config.h\r
+file to tune Cyclone for your project. There are lots of options in config.h, but all of them\r
+are documented and have defaults. You should set a define value to 1 to enable option, and\r
+to 0 to disable.\r
 \r
-ARM Register Usage\r
-------------------\r
+After you are done with config.h, save it and compile Cyclone. If you are using Linux, Cygwin,\r
+mingw or similar, you can simply cd to Cyclone/proj and type "make". If you are under Windows\r
+and have Visual Studio installed, you can import cyclone.dsp in the proj/ directory and compile\r
+it from there (this will produce cyclone.exe which you will have to run to get .s or .asm).\r
+You can also use Microsoft command line compile tools by entering Cyclone/proj directory and\r
+typing "nmake -f Makefile.win". Note that this step is done only to produce .s or .asm, and it\r
+is done using native tools on your PC (not using cross-compiler or similar).\r
 \r
-See source code for up to date of register usage, however a summary is here:\r
+The .s file is meant to be compiled with GNU assembler, and .asm with ARMASM.EXE\r
+(the Microsoft ARM assembler). Once you have the file, you can add it to your\r
+Makefile/project/whatever.\r
 \r
-  r0-3: Temporary registers\r
-  r4  : Current PC + Memory Base (i.e. pointer to next opcode)\r
-  r5  : Cycles remaining\r
-  r6  : Pointer to Opcode Jump table\r
-  r7  : Pointer to Cpu Context\r
-  r8  : Current Opcode\r
-  r9  : Flags (NZCV) in highest four bits\r
- (r10 : Temporary source value or Memory Base)\r
- (r11 : Temporary register)\r
 \r
+Adding to your project\r
+----------------------\r
 \r
-How to Compile\r
---------------\r
-\r
-Like Starscream and A68K, Cyclone uses a 'Core Creator' program which calculates and outputs\r
-all possible 68000 Opcodes and a jump table into files called Cyclone.s and .asm\r
-It then assembles these files into Cyclone.o and .obj\r
-\r
-Cyclone.o is the GCC assembled version and Cyclone.obj is the Microsoft assembled version.\r
+Compiling the .s or .asm (from previous step) for your target platform may require custom\r
+build rules in your Makefile/project.\r
 \r
-First unzip "Cyclone.zip" into a "Cyclone" directory.\r
-If you are compiling for Windows CE, find ARMASM.EXE (the Microsoft ARM assembler) and\r
-put it in the directory as well or put it on your path.\r
+If you use some gcc-based toolchain, you will need to add Cyclone.o to an object list in\r
+the Makefile. GNU make will use "as" to build Cyclone.o from Cyclone.s by default, so\r
+you may need to define correct cross-assembler by setting AS variable like this:\r
 \r
-Open up Cyclone.dsw in Visual Studio 6.0, compile and run the project.\r
-Cyclone.obj and Cyclone.o will be created.\r
+AS = arm-linux-as\r
 \r
-Compiling without Visual C++\r
-----------------------------\r
-If you aren't using Visual C++, it still shouldn't be too hard to compile, just get a C compiler,\r
-compile all the CPPs and C file, link them into an EXE, and run the exe.\r
+This might be different in your case, basically it should be same prefix as for gcc.\r
+You may also need to specify floating point type in your assembler flags for Cyclone.o\r
+to link properly. This is done like this:\r
 \r
-  e.g. gcc Main.cpp OpAny.cpp OpArith.cpp OpBranch.cpp OpLogic.cpp OpMove.cpp Disa.c\r
-  Main.exe\r
+ASFLAGS = -mfloat-abi=soft\r
 \r
+Note that Cyclone does not use floating points, this is just to make the linker happy.\r
 \r
-Adding to your project\r
-----------------------\r
 \r
-To add Cyclone to you project, add Cyclone.o or obj, and include Cyclone.h\r
-There is one structure: 'struct Cyclone', and one function: CycloneRun\r
+If you are using Visual Studio, you may need to add "custom build step", which creates\r
+Cyclone.obj from Cyclone.asm (asmasm.exe Cyclone.asm). Alternatively you can create\r
+Cyclone.obj by using armasm once and then just add it to you project.\r
 \r
 Don't worry if this seem very minimal - its all you need to run as many 68000s as you want.\r
 It works with both C and C++.\r
 \r
+\r
 Byteswapped Memory\r
 ------------------\r
 \r
@@ -153,7 +94,7 @@ If you have used Starscream, A68K or Turbo68K or similar emulators you'll be fam
 \r
 Any memory which the 68000 can access directly must be have every two bytes swapped around.\r
 This is to speed up 16-bit memory accesses, because the 68000 has Big-Endian memory\r
-and ARM has Little-Endian memory.\r
+and ARM has Little-Endian memory (in most cases).\r
 \r
 Now you may think you only technically have to byteswap ROM, not RAM, because\r
 16-bit RAM reads go through a memory handler and you could just return (mem[a]<<8) | mem[a+1].\r
@@ -166,8 +107,8 @@ It's also faster for the memory handlers, because you can do this:
   return *(unsigned short *)(mem+a)\r
 \r
 \r
-Declaring Memory handlers\r
----------------------------\r
+Declaring Memory handlers\r
+-------------------------\r
 \r
 Before you can reset or execute 68000 opcodes you must first set up a set of memory handlers.\r
 There are 7 functions you have to set up per CPU, like this:\r
@@ -195,16 +136,17 @@ For example you might set MyRead8 like this:
 \r
 The other 5 read/write functions are similar. I'll describe the CheckPc function later on.\r
 \r
+\r
 Declaring a CPU Context\r
 -----------------------\r
 \r
-To declare a CPU simple declare a struct Cyclone in your code. For example to declare\r
-two 68000s:\r
+To declare a CPU simple declare a struct Cyclone in your code (don't forget to include Cyclone.h).\r
+For example to declare two 68000s:\r
 \r
   struct Cyclone MyCpu;\r
   struct Cyclone MyCpu2;\r
 \r
-It's probably a good idea to initialise the memory to zero:\r
+It's probably a good idea to initialize the memory to zero:\r
 \r
   memset(&MyCpu, 0,sizeof(MyCpu));\r
   memset(&MyCpu2,0,sizeof(MyCpu2));\r
@@ -231,7 +173,9 @@ point them at the read handlers:
   If this is the case, you can set up different functions for fetch reads.\r
   Generally though you don't need to. )\r
 \r
-Now you are nearly ready to reset the 68000, except you need one more function: checkpc().\r
+Now you are nearly ready to reset the 68000, except a few more functions,\r
+one of them is: checkpc().\r
+\r
 \r
 The checkpc() function\r
 ----------------------\r
@@ -242,7 +186,7 @@ For example if your Rom image was at 0x3000000 and the program counter was $206,
 Cyclone's program counter would be 0x3000206.\r
 \r
 The difference between an ARM address and a 68000 address is also stored in a variable called\r
-'membase'. In the above example it's 0x3000000. To retrieve the real PC, Cyclone just\r
+'membase'. In the above example it's 0x3000000. To retrieve the real 68k PC, Cyclone just\r
 subtracts 'membase'.\r
 \r
 When a long jump happens, Cyclone calls checkpc(). If the PC is in a different bank,\r
@@ -261,20 +205,32 @@ static int MyCheckPc(unsigned int pc)
 Notice that the membase is always ARM address minus 68000 address.\r
 \r
 The above example doesn't consider mirrored ram, but for an example of what to do see\r
-PicoDrive (in Memory.cpp).\r
+PicoDrive (in Memory.c).\r
+\r
+The exact cases when checkpc() is called can be configured in config.h.\r
+\r
+\r
+Initialization\r
+--------------\r
+\r
+Add a call to CycloneInit(). This is really only needed to be called once at startup\r
+if you enabled COMPRESS_JUMPTABLE in config.h, but you can add this in any case,\r
+it won't hurt.\r
 \r
 \r
 Almost there - Reset the 68000!\r
 -------------------------------\r
 \r
-Next we need to Reset the 68000 to get the initial Program Counter and Stack Pointer. This\r
-is obtained from addresses 000000 and 000004.\r
+Cyclone doesn't provide a reset function, so next we need to Reset the 68000 to get\r
+the initial Program Counter and Stack Pointer. This is obtained from addresses\r
+000000 and 000004.\r
 \r
 Here is code which resets the 68000 (using your memory handlers):\r
 \r
+  MyCpu.state_flags=0; // Go to default state (not stopped, halted, etc.)\r
   MyCpu.srh=0x27; // Set supervisor mode\r
   MyCpu.a[7]=MyCpu.read32(0); // Get Stack Pointer\r
-  MyCpu.membase=0;\r
+  MyCpu.membase=0; // Will be set by checkpc()\r
   MyCpu.pc=MyCpu.checkpc(MyCpu.read32(4)); // Get Program Counter\r
 \r
 And that's ready to go.\r
@@ -291,7 +247,7 @@ e.g.:
   MyCpu.cycles=1000; CycloneRun(&MyCpu);\r
 \r
 For each opcode, the number of cycles it took is subtracted and the function returns when\r
-it reaches 0.\r
+it reaches negative number. The result is stored back to MyCpu.cycles.\r
 \r
 e.g.\r
   // Execute one instruction on the 68000:\r
@@ -325,42 +281,48 @@ e.g:
 Note that the interrupt is not actually processed until the next call to CycloneRun,\r
 and the interrupt may not be taken until the 68000 interrupt mask is changed to allow it.\r
 \r
-( The IRQ isn't checked on exiting from a memory handler: I don't think this will cause\r
-  me any trouble because I've never needed to trigger an interrupt from a memory handler,\r
-  but if someone needs to, let me know...)\r
+If you need to force interrupt processing, you can use CycloneFlushIrq() function.\r
+It is the same as doing\r
 \r
-Accessing Cycle Counter\r
------------------------\r
+MyCpu.cycles=0; CycloneRun(&MyCpu);\r
+\r
+but is better optimized and doesn't update .cycles (returns them instead).\r
+This function can't be used from memory handlers and has no effect if interrupt is masked.\r
 \r
-The cycle counter in the Cyclone structure is not, by default, updated before\r
-calling a memory handler, only at the end of an execution.\r
+The IRQ isn't checked on exiting from a memory handler. If you need to cause interrupt\r
+check immediately, you should change cycle counter to 0 to cause a return from CycloneRun(),\r
+and then call CycloneRun() again or just call CycloneFlushIrq(). Note that you need to\r
+enable MEMHANDLERS_CHANGE_CYCLES in config.h for this to work.\r
 \r
-If you do need to read the cycle counter inside memory handlers, there is a\r
-bitfield called 'Debug' in Cyclone/Main.cpp.\r
-You can try setting Debug to 1 and then making the Cyclone library.\r
-This will add extra instructions so Cyclone writes register r5 back into the structure.\r
+If you need to do something during the interrupt acknowledge (the moment when interrupt\r
+is taken), you can set USE_INT_ACK_CALLBACK in config.h and specify IrqCallback function.\r
+This function should update the IRQ level (.irq variable in context) and return the\r
+interrupt vector number. But for most cases it should return special constant\r
+CYCLONE_INT_ACK_AUTOVECTOR so that Cyclone uses autovectors, which is what most real\r
+systems were doing. Another less commonly used option is to return CYCLONE_INT_ACK_SPURIOUS\r
+for spurious interrupt.\r
 \r
-If you need to *modify* cycles in a memory handler, set Debug to 3, this will read back\r
-the cycle counter as well.\r
 \r
 Accessing Program Counter and registers\r
 ---------------------------------------\r
 \r
-You can read Cyclone's registers directly from the structure at any time (as far as I know).\r
+You can read most Cyclone's registers directly from the structure at any time.\r
+However, the PC value, CCR and cycle counter are cached in ARM registers and can't\r
+be accessed from memory handlers by default. They are written back and can be\r
+accessed after execution.\r
+\r
+But if you need to access the mentioned registers during execution, you can set\r
+MEMHANDLERS_NEED_* and MEMHANDLERS_CHANGE_* options in config.h\r
 \r
 The Program Counter, should you need to read or write it, is stored with membase\r
 added on. So use this formula to calculate the real 68000 program counter:\r
 \r
   pc = MyCpu.pc - MyCpu.membase;\r
 \r
-The program counter is stored in r4 during execution, and isn't written back to the\r
-structure until the end of execution, which means you can't read normally real it from\r
-a memory handler.\r
-However you can try setting Debug to 4 and then making the Cyclone library, this will\r
-write back r4 to the structure.\r
-\r
-You can't access the flags from a handler either. I can't imagine why anyone would particularly\r
-need to do this, but if you do e-mail me and I'll add another bit to 'Debug' ;)\r
+For performance reasons Cyclone keeps the status register split into .srh\r
+(status register "high" supervisor byte), .xc for the X flag, and .flags for remaining\r
+CCR flags (in ARM order). To easily read/write the status register as normal 68k\r
+16bit SR register, use CycloneGetSr() and CycloneSetSr() utility functions.\r
 \r
 \r
 Emulating more than one CPU\r
@@ -379,12 +341,286 @@ e.g.
   MyCpu2.cycles=1000; CycloneRun(&MyCpu2);\r
 \r
 \r
+Quick API reference\r
+-------------------\r
+\r
+void CycloneInit(void);\r
+  Initializes Cyclone. Must be called if the jumptable is compressed,\r
+  doesn't matter otherwise.\r
+\r
+void CycloneRun(struct Cyclone *pcy);\r
+  Runs cyclone for pcy->cycles. Writes amount of cycles left back to\r
+  pcy->cycles (always negative).\r
+\r
+unsigned int CycloneGetSr(const struct Cyclone *pcy);\r
+  Reads status register in internal form from pcy, converts to standard 68k SR and returns it.\r
+\r
+void CycloneSetSr(struct Cyclone *pcy, unsigned int sr);\r
+  Takes standard 68k status register (sr), and updates Cyclone context with it.\r
+  \r
+int CycloneFlushIrq(struct Cyclone *pcy);\r
+  If .irq is greater than IRQ mask in SR, or it is equal to 7 (NMI), processes interrupt\r
+  exception and returns number of cycles used. Otherwise, does nothing and returns 0.\r
+\r
+void CyclonePack(const struct Cyclone *pcy, void *save_buffer);\r
+  Writes Cyclone state to save_buffer. This allows to avoid all the trouble figuring what\r
+  actually needs to be saved from the Cyclone structure, as saving whole struct Cyclone\r
+  to a file will also save various pointers, which may become invalid after your program\r
+  is restarted, so simply reloading the structure will cause a crash. save_buffer size\r
+  should be 128 bytes (now it is really using less, but this allows future expansion).\r
+\r
+void CycloneUnpack(struct Cyclone *pcy, const void *save_buffer);\r
+  Reloads Cyclone state from save_buffer, which was previously saved by CyclonePack().\r
+  This function uses checkpc() callback to rebase the PC, so .checkpc must be initialized\r
+  before calling it.\r
+\r
+Callbacks:\r
+\r
+.checkpc\r
+unsigned int (*checkpc)(unsigned int pc);\r
+  This function is called when PC changes are performed in 68k code or because of exceptions.\r
+  It is passed ARM pointer and should return ARM pointer casted to int. It must also update\r
+  .membase if needed. See "The checkpc() function" section above.\r
+\r
+unsigned int (*read8  )(unsigned int a);\r
+unsigned int (*read16 )(unsigned int a);\r
+unsigned int (*read32 )(unsigned int a);\r
+  These are the read memory handler callbacks. They are called when 68k code reads from memory.\r
+  The parameter is a 68k address in data space, return value is a data value read. Data value\r
+  doesn't have to be masked to 8 or 16 bits for read8 or read16, Cyclone will do that itself\r
+  if needed.\r
+\r
+unsigned int (*fetch8 )(unsigned int a);\r
+unsigned int (*fetch16)(unsigned int a);\r
+unsigned int (*fetch32)(unsigned int a);\r
+  Same as above, but these are reads from program space (PC relative reads mostly).\r
\r
+void (*write8 )(unsigned int a,unsigned char  d);\r
+void (*write16)(unsigned int a,unsigned short d);\r
+void (*write32)(unsigned int a,unsigned int   d);\r
+  These are called when 68k code writes to data space. d is the data value.\r
+\r
+int (*IrqCallback)(int int_level);\r
+  This function is called when Cyclone acknowledges an interrupt. The parameter is the IRQ\r
+  level being acknowledged, and return value is exception vector to use, or one of these special\r
+  values: CYCLONE_INT_ACK_AUTOVECTOR or CYCLONE_INT_ACK_SPURIOUS. Can be disabled in config.h.\r
+  See "Interrupts" section for more information.\r
+\r
+void (*ResetCallback)(void);\r
+  Cyclone will call this function if it encounters RESET 68k instruction.\r
+  Can be disabled in config.h.\r
+\r
+int (*UnrecognizedCallback)(void);\r
+  Cyclone will call this function if it encounters illegal instructions (including A-line and\r
+  F-line ones). Can be tuned / disabled in config.h.\r
+\r
+\r
+Function codes\r
+--------------\r
+\r
+Cyclone doesn't pass function codes to it's memory handlers, but they can be calculated:\r
+FC2: just use supervisor state bit from status register (eg. (MyCpu.srh & 0x20) >> 5)\r
+FC1: if we are in fetch* function, then 1, else 0.\r
+FC0: if we are in read* or write*, then 1, else 0.\r
+CPU state (all FC bits set) is active in IrqCallback function.\r
+\r
+\r
+References\r
+----------\r
+\r
+These documents were used while writing Cyclone and should be useful for those who want to\r
+understand deeper how the 68000 works.\r
+\r
+MOTOROLA M68000 FAMILY Programmer's Reference Manual\r
+common name: 68kPM.pdf\r
+\r
+M68000 8-/16-/32-Bit Microprocessors User's Manual\r
+common name: MC68000UM.pdf\r
+\r
+68000 Undocumented Behavior Notes by Bart Trzynadlowski\r
+http://www.trzy.org/files/68knotes.txt\r
+\r
+Instruction prefetch on the Motorola 68000 processor by Jorge Cwik\r
+http://pasti.fxatari.com/68kdocs/68kPrefetch.html\r
+\r
+\r
+ARM Register Usage\r
+------------------\r
+\r
+See source code for up to date of register usage, however a summary is here:\r
+\r
+  r0-3: Temporary registers\r
+  r4  : Current PC + Memory Base (i.e. pointer to next opcode)\r
+  r5  : Cycles remaining\r
+  r6  : Pointer to Opcode Jump table\r
+  r7  : Pointer to Cpu Context\r
+  r8  : Current Opcode\r
+  r10 : Flags (NZCV) in highest four bits\r
+ (r11 : Temporary register)\r
+\r
+Flags are mapped onto ARM flags whenever possible, which speeds up the processing of opcode.\r
+r9 is not used intentionally, because AAPCS defines it as "platform register", so it's\r
+reserved in some systems.\r
+\r
+\r
 Thanks to...\r
 ------------\r
 \r
 * All the previous code-generating assembler cpu core guys!\r
   Who are iirc... Neill Corlett, Neil Bradley, Mike Coates, Darren Olafson\r
-    and Bart Trzynadlowski\r
+    Karl Stenerud and Bart Trzynadlowski\r
 \r
 * Charles Macdonald, for researching just about every console ever\r
 * MameDev+FBA, for keeping on going and going and going\r
+\r
+\r
+What's New\r
+----------\r
+v0.0099\r
+  * Cyclone no longer uses r9, because AAPCS defines it as "platform register",\r
+    so it's reserved in some systems.\r
+  * Made SPLIT_MOVEL_PD to affect MOVEM too.\r
+\r
+v0.0088\r
+  - Reduced amount of code in opcode handlers by ~23% by doing the following:\r
+    - Removed duplicate opcode handlers\r
+    - Optimized code to use less ARM instructions\r
+    - Merged some duplicate handler endings\r
+  + Cyclone now does better job avoiding pipeline interlocks.\r
+  + Replaced incorrect handler of DBT with proper one.\r
+  + Changed "MOVEA (An)+ An" behavior.\r
+  + Fixed flag behavior of ROXR, ASL, LSR and NBCD in certain situations.\r
+    Hopefully got them right now.\r
+  + Cyclone no longer sets most significant bits while pushing PC to stack.\r
+    Amiga Kickstart depends on this.\r
+  + Added optional trace mode emulation.\r
+  + Added optional address error emulation.\r
+  + Additional functionality added for MAME and other ports (see config.h).\r
+  + Added return value for IrqCallback to make it suitable for emulating devices which\r
+    pass the vector number during interrupt acknowledge cycle. For usual autovector\r
+    processing this function must return CYCLONE_INT_ACK_AUTOVECTOR, so those who are\r
+    upgrading must add "return CYCLONE_INT_ACK_AUTOVECTOR;" to their IrqCallback functions.\r
+  * Updated documentation.\r
+\r
+v0.0086\r
+  + Cyclone now can be customized to better suit your project, see config.h .\r
+  + Added an option to compress the jumptable at compile-time. Must call CycloneInit()\r
+    at runtime to decompress it if enabled (see config.h).\r
+  + Added missing CHK opcode handler (used by SeaQuest DSV).\r
+  + Added missing TAS opcode handler (Gargoyles,Bubba N Stix,...). As in real genesis,\r
+    memory write-back phase is ignored (but can be enabled in config.h if needed).\r
+  + Added missing NBCD and TRAPV opcode handlers.\r
+  + Added missing addressing mode for CMP/EOR.\r
+  + Added some minor optimizations.\r
+  - Removed 216 handlers for 2927 opcodes which were generated for invalid addressing modes.\r
+  + Fixed flags for ASL, NEG, NEGX, DIVU, ADDX, SUBX, ROXR.\r
+  + Bugs fixed in MOVEP, LINK, ADDQ, DIVS handlers.\r
+  * Undocumented flags for CHK, ABCD, SBCD and NBCD are now emulated the same way as in Musashi.\r
+  + Added Uninitialized Interrupt emulation.\r
+  + Altered timing for about half of opcodes to match Musashi's.\r
+\r
+v0.0082\r
+  + Change cyclone to clear cycles before returning when halted\r
+  + Added Irq call back function.  This allows emulators to be notified\r
+    when cyclone has taken an interrupt allowing them to set internal flags\r
+    which can help fix timing problems.\r
+\r
+v0.0081\r
+  + .asm version was broken and did not compile with armasm. Fixed.\r
+  + Finished implementing Stop opcode. Now it really stops the processor.\r
+\r
+v0.0080\r
+  + Added real cmpm opcode, it was using eor handler before this.\r
+    Fixes Dune and Sensible Soccer.\r
+\r
+v0.0078\r
+  note: these bugs were actually found Reesy, I reimplemented these by\r
+        using his changelog as a guide.\r
+  + Fixed a problem with divu which was using long divisor instead of word.\r
+    Fixes gear switching in Top Gear 2.\r
+  + Fixed btst opcode, The bit to test should shifted a max of 31 or 7\r
+    depending on if a register or memory location is being tested.\r
+  + Fixed abcd,sbcd. They did bad decimal correction on invalid BCD numbers\r
+    Score counters in Streets of Rage level end work now.\r
+  + Changed flag handling of abcd,sbcd,addx,subx,asl,lsl,...\r
+    Some ops did not have flag handling at all.\r
+    Some ops must not change Z flag when result is zero, but they did.\r
+    Shift ops must not change X if shift count is zero, but they did.\r
+    There are probably still some flag problems left.\r
+  + Patially implemented Stop and Reset opcodes - Fixes Thunderforce IV\r
+\r
+v0.0075\r
+  + Added missing displacement addressing mode for movem (Fantastic Dizzy)\r
+  + Added OSP <-> A7 swapping code in opcodes, which change privilege mode\r
+  + Implemented privilege violation, line emulator and divide by zero exceptions\r
+  + Added negx opcode (Shining Force works!)\r
+  + Added overflow detection for divs/divu\r
+\r
+v0.0072\r
+  note: I could only get v0.0069 cyclone, so I had to implement these myself using Dave's\r
+        changelog as a guide.\r
+  + Fixed a problem with divs - remainder should be negative when divident is negative\r
+  + Added movep opcode (Sonic 3 works)\r
+  + Fixed a problem with DBcc incorrectly decrementing if the condition is true (Shadow of the Beast)\r
+\r
+v0.0069\r
+  + Added SBCD and the flags for ABCD/SBCD. Score and time now works in games such as\r
+    Rolling Thunder 2, Ghouls 'N Ghosts\r
+  + Fixed a problem with addx and subx with 8-bit and 16-bit values.\r
+    Ghouls 'N' Ghosts now works!\r
+\r
+v0.0068\r
+  + Added ABCD opcode (Streets of Rage works now!)\r
+\r
+v0.0067\r
+  + Added dbCC (After Burner)\r
+  + Added asr EA (Sonic 1 Boss/Labyrinth Zone)\r
+  + Added andi/ori/eori ccr (Altered Beast)\r
+  + Added trap (After Burner)\r
+  + Added special case for move.b (a7)+ and -(a7), stepping by 2\r
+    After Burner is playable! Eternal Champions shows more\r
+  + Fixed lsr.b/w zero flag (Ghostbusters)\r
+    Rolling Thunder 2 now works!\r
+  + Fixed N flag for .b and .w arithmetic. Golden Axe works!\r
+\r
+v0.0066\r
+  + Fixed a stupid typo for exg (orr r10,r10, not orr r10,r8), which caused alignment\r
+    crashes on Strider\r
+\r
+v0.0065\r
+  + Fixed a problem with immediate values - they weren't being shifted up correctly for some\r
+    opcodes. Spiderman works, After Burner shows a bit of graphics.\r
+  + Fixed a problem with EA:"110nnn" extension word. 32-bit offsets were being decoded as 8-bit\r
+    offsets by mistake. Castlevania Bloodlines seems fine now.\r
+  + Added exg opcode\r
+  + Fixed asr opcode (Sonic jumping left is fixed)\r
+  + Fixed a problem with the carry bit in rol.b (Marble Madness)\r
+\r
+v0.0064\r
+  + Added rtr\r
+  + Fixed addq/subq.l (all An opcodes are 32-bit) (Road Rash)\r
+  + Fixed various little timings\r
+\r
+v0.0063\r
+  + Added link/unlk opcodes\r
+  + Fixed various little timings\r
+  + Fixed a problem with dbCC opcode being emitted at set opcodes\r
+  + Improved long register access, the EA fetch now does ldr r0,[r7,r0,lsl #2] whenever\r
+     possible, saving 1 or 2 cycles on many opcodes, which should give a nice speed up.\r
+  + May have fixed N flag on ext opcode?\r
+  + Added dasm for link opcode.\r
+\r
+v0.0062\r
+  * I was a bit too keen with the Arithmetic opcodes! Some of them should have been abcd,\r
+    exg and addx. Removed the incorrect opcodes, pending re-adding them as abcd, exg and addx.\r
+  + Changed unknown opcodes to act as nops.\r
+    Not very technical, but fun - a few more games show more graphics ;)\r
+\r
+v0.0060\r
+  + Fixed divu (EA intro)\r
+  + Added sf (set false) opcode - SOR2\r
+  * Todo: pea/link/unlk opcodes\r
+\r
+v0.0059: Added remainder to divide opcodes.\r
+\r
+\r