restructure the repository to be Cyclone only
[cyclone68000.git] / Cyclone / Cyclone.txt
diff --git a/Cyclone/Cyclone.txt b/Cyclone/Cyclone.txt
deleted file mode 100644 (file)
index c305f27..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-\r
-      _____            __                                     \r
-     / ___/__ __ ____ / /___   ___  ___   ___________________ \r
-    / /__ / // // __// // _ \ / _ \/ -_) ___________________  \r
-    \___/ \_, / \__//_/ \___//_//_/\__/ ___________________   \r
-         /___/                                                \r
-         ___________________  ____ ___   ___   ___   ___      \r
-        ___________________  / __// _ \ / _ \ / _ \ / _ \     \r
-       ___________________  / _ \/ _  // // // // // // /     \r
-                            \___/\___/ \___/ \___/ \___/      \r
-                                                              \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
-\r
-  Homepage: http://code.google.com/p/cyclone68000/\r
-\r
-___________________________________________________________________________\r
-\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. 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
-\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 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
-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
-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
-\r
-Adding to your project\r
-----------------------\r
-\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
-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
-AS = arm-linux-as\r
-\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
-ASFLAGS = -mfloat-abi=soft\r
-\r
-Note that Cyclone does not use floating points, this is just to make the linker happy.\r
-\r
-\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
-If you have used Starscream, A68K or Turbo68K or similar emulators you'll be familiar with this!\r
-\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 (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
-\r
-This would work, but remember some systems can execute code from RAM as well as ROM, and\r
-that would fail.\r
-So it's best to use byteswapped ROM and RAM if the 68000 can access it directly.\r
-It's also faster for the memory handlers, because you can do this:\r
-  \r
-  return *(unsigned short *)(mem+a)\r
-\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
-\r
-  static unsigned int   MyCheckPc(unsigned int pc)\r
-  static unsigned char  MyRead8  (unsigned int a)\r
-  static unsigned short MyRead16 (unsigned int a)\r
-  static unsigned int   MyRead32 (unsigned int a)\r
-  static void MyWrite8 (unsigned int a,unsigned char  d)\r
-  static void MyWrite16(unsigned int a,unsigned short d)\r
-  static void MyWrite32(unsigned int a,unsigned int   d)\r
-\r
-You can think of these functions representing the 68000's memory bus.\r
-The Read and Write functions are called whenever the 68000 reads or writes memory.\r
-For example you might set MyRead8 like this:\r
-\r
-  unsigned char MyRead8(unsigned int a)\r
-  {\r
-    a&=0xffffff; // Clip address to 24-bits\r
-\r
-    if (a<RomLength) return RomData[a^1]; // ^1 because the memory is byteswapped\r
-    if (a>=0xe00000) return RamData[(a^1)&0xffff];\r
-    return 0xff; // Out of range memory access\r
-  }\r
-\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 (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 initialize the memory to zero:\r
-\r
-  memset(&MyCpu, 0,sizeof(MyCpu));\r
-  memset(&MyCpu2,0,sizeof(MyCpu2));\r
-\r
-Next point to your memory handlers:\r
-\r
-  MyCpu.checkpc=MyCheckPc;\r
-  MyCpu.read8  =MyRead8;\r
-  MyCpu.read16 =MyRead16;\r
-  MyCpu.read32 =MyRead32;\r
-  MyCpu.write8 =MyWrite8;\r
-  MyCpu.write16=MyWrite16;\r
-  MyCpu.write32=MyWrite32;\r
-\r
-You also need to point the fetch handlers - for most systems out there you can just\r
-point them at the read handlers:\r
-  MyCpu.fetch8  =MyRead8;\r
-  MyCpu.fetch16 =MyRead16;\r
-  MyCpu.fetch32 =MyRead32;\r
-\r
-( Why a different set of function pointers for fetch?\r
-  Well there are some systems, the main one being CPS2, which return different data\r
-  depending on whether the 'fetch' line on the 68000 bus is high or low.\r
-  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 a few more functions,\r
-one of them is: checkpc().\r
-\r
-\r
-The checkpc() function\r
-----------------------\r
-\r
-When Cyclone reads opcodes, it doesn't use a memory handler every time, this would be\r
-far too slow, instead it uses a direct pointer to ARM memory.\r
-For example if your Rom image was at 0x3000000 and the program counter was $206,\r
-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 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
-for example Ram instead of Rom, change 'membase', recalculate the new PC and return it:\r
-\r
-static int MyCheckPc(unsigned int pc)\r
-{\r
-  pc-=MyCpu.membase; // Get the real program counter\r
-\r
-  if (pc<RomLength) MyCpu.membase=(int)RomMem;          // Jump to Rom\r
-  if (pc>=0xff0000) MyCpu.membase=(int)RamMem-0xff0000; // Jump to Ram\r
-\r
-  return MyCpu.membase+pc; // New program counter\r
-}\r
-\r
-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.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
-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; // 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
-\r
-\r
-Executing the 68000\r
--------------------\r
-\r
-To execute the 68000, set the 'cycles' variable to the number of cycles you wish to execute,\r
-and then call CycloneRun with a pointer to the Cyclone structure.\r
-\r
-e.g.:\r
-  // Execute 1000 cycles on the 68000:\r
-  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 negative number. The result is stored back to MyCpu.cycles.\r
-\r
-e.g.\r
-  // Execute one instruction on the 68000:\r
-  MyCpu.cycles=0; CycloneRun(&MyCpu);\r
-  printf("  The opcode took %d cycles\n", -MyCpu.cycles);\r
-\r
-You should try to execute as many cycles as you can for maximum speed.\r
-The number actually executed may be slightly more than requested, i.e. cycles may come\r
-out with a small negative value:\r
-\r
-e.g.\r
-  int todo=12000000/60; // 12Mhz, for one 60hz frame\r
-  MyCpu.cycles=todo; CycloneRun(&MyCpu);\r
-  printf("  Actually executed %d cycles\n", todo-MyCpu.cycles);\r
-\r
-To calculate the number of cycles executed, use this formula:\r
-  Number of cycles requested - Cycle counter at the end\r
-\r
-\r
-Interrupts\r
-----------\r
-\r
-Causing an interrupt is very simple, simply set the irq variable in the Cyclone structure\r
-to the IRQ number.\r
-To lower the IRQ line, set it to zero.\r
-\r
-e.g:\r
-  MyCpu.irq=6; // Interrupt level 6\r
-  MyCpu.cycles=20000; CycloneRun(&MyCpu);\r
-\r
-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
-If you need to force interrupt processing, you can use CycloneFlushIrq() function.\r
-It is the same as doing\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 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 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
-\r
-Accessing Program Counter and registers\r
----------------------------------------\r
-\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
-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
----------------------------\r
-\r
-Since everything is based on the structures, emulating more than one cpu at the same time\r
-is just a matter of declaring more than one structures and timeslicing. You can emulate\r
-as many 68000s as you want.\r
-Just set up the memory handlers for each cpu and run each cpu for a certain number of cycles.\r
-\r
-e.g.\r
-  // Execute 1000 cycles on 68000 #1:\r
-  MyCpu.cycles=1000; CycloneRun(&MyCpu);\r
-\r
-  // Execute 1000 cycles on 68000 #2:\r
-  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
-    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