fix bcd instructions
[cyclone68000.git] / Cyclone.txt
CommitLineData
6003a768 1\r
2 _____ __ \r
3 / ___/__ __ ____ / /___ ___ ___ ___________________ \r
4 / /__ / // // __// // _ \ / _ \/ -_) ___________________ \r
5 \___/ \_, / \__//_/ \___//_//_/\__/ ___________________ \r
6 /___/ \r
7 ___________________ ____ ___ ___ ___ ___ \r
8 ___________________ / __// _ \ / _ \ / _ \ / _ \ \r
9 ___________________ / _ \/ _ // // // // // // / \r
10 \___/\___/ \___/ \___/ \___/ \r
11 \r
12___________________________________________________________________________\r
13\r
d9d77995 14 Copyright (c) 2004,2011 FinalDave (emudave (at) gmail.com)\r
15 Copyright (c) 2005-2011 GraÅžvydas "notaz" Ignotas (notasas (at) gmail.com)\r
6003a768 16\r
d9d77995 17 This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
18 You can choose the license that has the most advantages for you.\r
19\r
20 Homepage: http://code.google.com/p/cyclone68000/\r
6003a768 21\r
22___________________________________________________________________________\r
23\r
24\r
d9d77995 25About\r
26-----\r
6003a768 27\r
28Cyclone 68000 is an emulator for the 68000 microprocessor, written in ARM 32-bit assembly.\r
29It is aimed at chips such as ARM7 and ARM9 cores, StrongARM and XScale, to interpret 68000\r
d9d77995 30code as fast as possible. It can emulate all 68000 instructions quite accurately, instruction\r
31timing was synchronized with MAME's Musashi. Most 68k features are emulated (trace mode,\r
32address errors), but prefetch is not emulated.\r
6003a768 33\r
6003a768 34\r
d9d77995 35How to Compile\r
36--------------\r
6003a768 37\r
d9d77995 38Like Starscream and A68K, Cyclone uses a 'Core Creator' program which calculates and outputs\r
39all possible 68000 Opcodes and a jump table into file called Cyclone.s or Cyclone.asm.\r
40Only Cyclone.h and the mentioned .s or .asm file will be needed for your project, other files\r
41are here to produce or test it.\r
6003a768 42\r
d9d77995 43First unzip "Cyclone.zip" into a "Cyclone" directory. The next thing to do is to edit config.h\r
44file to tune Cyclone for your project. There are lots of options in config.h, but all of them\r
45are documented and have defaults. You should set a define value to 1 to enable option, and\r
46to 0 to disable.\r
6003a768 47\r
d9d77995 48After you are done with config.h, save it and compile Cyclone. If you are using Linux, Cygwin,\r
49mingw or similar, you can simply cd to Cyclone/proj and type "make". If you are under Windows\r
50and have Visual Studio installed, you can import cyclone.dsp in the proj/ directory and compile\r
51it from there (this will produce cyclone.exe which you will have to run to get .s or .asm).\r
52You can also use Microsoft command line compile tools by entering Cyclone/proj directory and\r
53typing "nmake -f Makefile.win". Note that this step is done only to produce .s or .asm, and it\r
54is done using native tools on your PC (not using cross-compiler or similar).\r
6003a768 55\r
d9d77995 56The .s file is meant to be compiled with GNU assembler, and .asm with ARMASM.EXE\r
57(the Microsoft ARM assembler). Once you have the file, you can add it to your\r
58Makefile/project/whatever.\r
6003a768 59\r
6003a768 60\r
d9d77995 61Adding to your project\r
62----------------------\r
6003a768 63\r
d9d77995 64Compiling the .s or .asm (from previous step) for your target platform may require custom\r
65build rules in your Makefile/project.\r
6003a768 66\r
d9d77995 67If you use some gcc-based toolchain, you will need to add Cyclone.o to an object list in\r
68the Makefile. GNU make will use "as" to build Cyclone.o from Cyclone.s by default, so\r
69you may need to define correct cross-assembler by setting AS variable like this:\r
6003a768 70\r
d9d77995 71AS = arm-linux-as\r
6003a768 72\r
d9d77995 73This might be different in your case, basically it should be same prefix as for gcc.\r
74You may also need to specify floating point type in your assembler flags for Cyclone.o\r
75to link properly. This is done like this:\r
6003a768 76\r
d9d77995 77ASFLAGS = -mfloat-abi=soft\r
6003a768 78\r
d9d77995 79Note that Cyclone does not use floating points, this is just to make the linker happy.\r
6003a768 80\r
6003a768 81\r
d9d77995 82If you are using Visual Studio, you may need to add "custom build step", which creates\r
83Cyclone.obj from Cyclone.asm (asmasm.exe Cyclone.asm). Alternatively you can create\r
84Cyclone.obj by using armasm once and then just add it to you project.\r
6003a768 85\r
86Don't worry if this seem very minimal - its all you need to run as many 68000s as you want.\r
87It works with both C and C++.\r
88\r
d9d77995 89\r
6003a768 90Byteswapped Memory\r
91------------------\r
92\r
93If you have used Starscream, A68K or Turbo68K or similar emulators you'll be familiar with this!\r
94\r
95Any memory which the 68000 can access directly must be have every two bytes swapped around.\r
96This is to speed up 16-bit memory accesses, because the 68000 has Big-Endian memory\r
d9d77995 97and ARM has Little-Endian memory (in most cases).\r
6003a768 98\r
99Now you may think you only technically have to byteswap ROM, not RAM, because\r
10016-bit RAM reads go through a memory handler and you could just return (mem[a]<<8) | mem[a+1].\r
101\r
102This would work, but remember some systems can execute code from RAM as well as ROM, and\r
103that would fail.\r
104So it's best to use byteswapped ROM and RAM if the 68000 can access it directly.\r
105It's also faster for the memory handlers, because you can do this:\r
106 \r
107 return *(unsigned short *)(mem+a)\r
108\r
109\r
d9d77995 110Declaring Memory handlers\r
111-------------------------\r
6003a768 112\r
113Before you can reset or execute 68000 opcodes you must first set up a set of memory handlers.\r
114There are 7 functions you have to set up per CPU, like this:\r
115\r
116 static unsigned int MyCheckPc(unsigned int pc)\r
117 static unsigned char MyRead8 (unsigned int a)\r
118 static unsigned short MyRead16 (unsigned int a)\r
119 static unsigned int MyRead32 (unsigned int a)\r
120 static void MyWrite8 (unsigned int a,unsigned char d)\r
121 static void MyWrite16(unsigned int a,unsigned short d)\r
122 static void MyWrite32(unsigned int a,unsigned int d)\r
123\r
124You can think of these functions representing the 68000's memory bus.\r
125The Read and Write functions are called whenever the 68000 reads or writes memory.\r
126For example you might set MyRead8 like this:\r
127\r
128 unsigned char MyRead8(unsigned int a)\r
129 {\r
130 a&=0xffffff; // Clip address to 24-bits\r
131\r
132 if (a<RomLength) return RomData[a^1]; // ^1 because the memory is byteswapped\r
133 if (a>=0xe00000) return RamData[(a^1)&0xffff];\r
134 return 0xff; // Out of range memory access\r
135 }\r
136\r
137The other 5 read/write functions are similar. I'll describe the CheckPc function later on.\r
138\r
d9d77995 139\r
6003a768 140Declaring a CPU Context\r
141-----------------------\r
142\r
d9d77995 143To declare a CPU simple declare a struct Cyclone in your code (don't forget to include Cyclone.h).\r
144For example to declare two 68000s:\r
6003a768 145\r
146 struct Cyclone MyCpu;\r
147 struct Cyclone MyCpu2;\r
148\r
d9d77995 149It's probably a good idea to initialize the memory to zero:\r
6003a768 150\r
151 memset(&MyCpu, 0,sizeof(MyCpu));\r
152 memset(&MyCpu2,0,sizeof(MyCpu2));\r
153\r
154Next point to your memory handlers:\r
155\r
156 MyCpu.checkpc=MyCheckPc;\r
157 MyCpu.read8 =MyRead8;\r
158 MyCpu.read16 =MyRead16;\r
159 MyCpu.read32 =MyRead32;\r
160 MyCpu.write8 =MyWrite8;\r
161 MyCpu.write16=MyWrite16;\r
162 MyCpu.write32=MyWrite32;\r
163\r
164You also need to point the fetch handlers - for most systems out there you can just\r
165point them at the read handlers:\r
166 MyCpu.fetch8 =MyRead8;\r
167 MyCpu.fetch16 =MyRead16;\r
168 MyCpu.fetch32 =MyRead32;\r
169\r
170( Why a different set of function pointers for fetch?\r
171 Well there are some systems, the main one being CPS2, which return different data\r
172 depending on whether the 'fetch' line on the 68000 bus is high or low.\r
173 If this is the case, you can set up different functions for fetch reads.\r
174 Generally though you don't need to. )\r
175\r
d9d77995 176Now you are nearly ready to reset the 68000, except a few more functions,\r
177one of them is: checkpc().\r
178\r
6003a768 179\r
180The checkpc() function\r
181----------------------\r
182\r
183When Cyclone reads opcodes, it doesn't use a memory handler every time, this would be\r
184far too slow, instead it uses a direct pointer to ARM memory.\r
185For example if your Rom image was at 0x3000000 and the program counter was $206,\r
186Cyclone's program counter would be 0x3000206.\r
187\r
188The difference between an ARM address and a 68000 address is also stored in a variable called\r
d9d77995 189'membase'. In the above example it's 0x3000000. To retrieve the real 68k PC, Cyclone just\r
6003a768 190subtracts 'membase'.\r
191\r
192When a long jump happens, Cyclone calls checkpc(). If the PC is in a different bank,\r
193for example Ram instead of Rom, change 'membase', recalculate the new PC and return it:\r
194\r
195static int MyCheckPc(unsigned int pc)\r
196{\r
197 pc-=MyCpu.membase; // Get the real program counter\r
198\r
199 if (pc<RomLength) MyCpu.membase=(int)RomMem; // Jump to Rom\r
200 if (pc>=0xff0000) MyCpu.membase=(int)RamMem-0xff0000; // Jump to Ram\r
201\r
202 return MyCpu.membase+pc; // New program counter\r
203}\r
204\r
205Notice that the membase is always ARM address minus 68000 address.\r
206\r
207The above example doesn't consider mirrored ram, but for an example of what to do see\r
d9d77995 208PicoDrive (in Memory.c).\r
209\r
210The exact cases when checkpc() is called can be configured in config.h.\r
211\r
212\r
213Initialization\r
214--------------\r
215\r
216Add a call to CycloneInit(). This is really only needed to be called once at startup\r
217if you enabled COMPRESS_JUMPTABLE in config.h, but you can add this in any case,\r
218it won't hurt.\r
6003a768 219\r
220\r
221Almost there - Reset the 68000!\r
222-------------------------------\r
223\r
d9d77995 224Cyclone doesn't provide a reset function, so next we need to Reset the 68000 to get\r
225the initial Program Counter and Stack Pointer. This is obtained from addresses\r
226000000 and 000004.\r
6003a768 227\r
228Here is code which resets the 68000 (using your memory handlers):\r
229\r
d9d77995 230 MyCpu.state_flags=0; // Go to default state (not stopped, halted, etc.)\r
6003a768 231 MyCpu.srh=0x27; // Set supervisor mode\r
232 MyCpu.a[7]=MyCpu.read32(0); // Get Stack Pointer\r
d9d77995 233 MyCpu.membase=0; // Will be set by checkpc()\r
6003a768 234 MyCpu.pc=MyCpu.checkpc(MyCpu.read32(4)); // Get Program Counter\r
235\r
236And that's ready to go.\r
237\r
238\r
239Executing the 68000\r
240-------------------\r
241\r
242To execute the 68000, set the 'cycles' variable to the number of cycles you wish to execute,\r
243and then call CycloneRun with a pointer to the Cyclone structure.\r
244\r
245e.g.:\r
246 // Execute 1000 cycles on the 68000:\r
247 MyCpu.cycles=1000; CycloneRun(&MyCpu);\r
248\r
249For each opcode, the number of cycles it took is subtracted and the function returns when\r
d9d77995 250it reaches negative number. The result is stored back to MyCpu.cycles.\r
6003a768 251\r
252e.g.\r
253 // Execute one instruction on the 68000:\r
254 MyCpu.cycles=0; CycloneRun(&MyCpu);\r
255 printf(" The opcode took %d cycles\n", -MyCpu.cycles);\r
256\r
257You should try to execute as many cycles as you can for maximum speed.\r
258The number actually executed may be slightly more than requested, i.e. cycles may come\r
259out with a small negative value:\r
260\r
261e.g.\r
262 int todo=12000000/60; // 12Mhz, for one 60hz frame\r
263 MyCpu.cycles=todo; CycloneRun(&MyCpu);\r
264 printf(" Actually executed %d cycles\n", todo-MyCpu.cycles);\r
265\r
266To calculate the number of cycles executed, use this formula:\r
267 Number of cycles requested - Cycle counter at the end\r
268\r
269\r
270Interrupts\r
271----------\r
272\r
273Causing an interrupt is very simple, simply set the irq variable in the Cyclone structure\r
274to the IRQ number.\r
275To lower the IRQ line, set it to zero.\r
276\r
277e.g:\r
278 MyCpu.irq=6; // Interrupt level 6\r
279 MyCpu.cycles=20000; CycloneRun(&MyCpu);\r
280\r
281Note that the interrupt is not actually processed until the next call to CycloneRun,\r
282and the interrupt may not be taken until the 68000 interrupt mask is changed to allow it.\r
283\r
d9d77995 284If you need to force interrupt processing, you can use CycloneFlushIrq() function.\r
285It is the same as doing\r
6003a768 286\r
d9d77995 287MyCpu.cycles=0; CycloneRun(&MyCpu);\r
288\r
289but is better optimized and doesn't update .cycles (returns them instead).\r
290This function can't be used from memory handlers and has no effect if interrupt is masked.\r
6003a768 291\r
d9d77995 292The IRQ isn't checked on exiting from a memory handler. If you need to cause interrupt\r
293check immediately, you should change cycle counter to 0 to cause a return from CycloneRun(),\r
294and then call CycloneRun() again or just call CycloneFlushIrq(). Note that you need to\r
295enable MEMHANDLERS_CHANGE_CYCLES in config.h for this to work.\r
6003a768 296\r
d9d77995 297If you need to do something during the interrupt acknowledge (the moment when interrupt\r
298is taken), you can set USE_INT_ACK_CALLBACK in config.h and specify IrqCallback function.\r
299This function should update the IRQ level (.irq variable in context) and return the\r
300interrupt vector number. But for most cases it should return special constant\r
301CYCLONE_INT_ACK_AUTOVECTOR so that Cyclone uses autovectors, which is what most real\r
302systems were doing. Another less commonly used option is to return CYCLONE_INT_ACK_SPURIOUS\r
303for spurious interrupt.\r
6003a768 304\r
6003a768 305\r
306Accessing Program Counter and registers\r
307---------------------------------------\r
308\r
d9d77995 309You can read most Cyclone's registers directly from the structure at any time.\r
310However, the PC value, CCR and cycle counter are cached in ARM registers and can't\r
311be accessed from memory handlers by default. They are written back and can be\r
312accessed after execution.\r
313\r
314But if you need to access the mentioned registers during execution, you can set\r
315MEMHANDLERS_NEED_* and MEMHANDLERS_CHANGE_* options in config.h\r
6003a768 316\r
317The Program Counter, should you need to read or write it, is stored with membase\r
318added on. So use this formula to calculate the real 68000 program counter:\r
319\r
320 pc = MyCpu.pc - MyCpu.membase;\r
321\r
d9d77995 322For performance reasons Cyclone keeps the status register split into .srh\r
323(status register "high" supervisor byte), .xc for the X flag, and .flags for remaining\r
324CCR flags (in ARM order). To easily read/write the status register as normal 68k\r
32516bit SR register, use CycloneGetSr() and CycloneSetSr() utility functions.\r
6003a768 326\r
327\r
328Emulating more than one CPU\r
329---------------------------\r
330\r
331Since everything is based on the structures, emulating more than one cpu at the same time\r
332is just a matter of declaring more than one structures and timeslicing. You can emulate\r
333as many 68000s as you want.\r
334Just set up the memory handlers for each cpu and run each cpu for a certain number of cycles.\r
335\r
336e.g.\r
337 // Execute 1000 cycles on 68000 #1:\r
338 MyCpu.cycles=1000; CycloneRun(&MyCpu);\r
339\r
340 // Execute 1000 cycles on 68000 #2:\r
341 MyCpu2.cycles=1000; CycloneRun(&MyCpu2);\r
342\r
343\r
d9d77995 344Quick API reference\r
345-------------------\r
346\r
347void CycloneInit(void);\r
348 Initializes Cyclone. Must be called if the jumptable is compressed,\r
349 doesn't matter otherwise.\r
350\r
351void CycloneRun(struct Cyclone *pcy);\r
352 Runs cyclone for pcy->cycles. Writes amount of cycles left back to\r
353 pcy->cycles (always negative).\r
354\r
355unsigned int CycloneGetSr(const struct Cyclone *pcy);\r
356 Reads status register in internal form from pcy, converts to standard 68k SR and returns it.\r
357\r
358void CycloneSetSr(struct Cyclone *pcy, unsigned int sr);\r
359 Takes standard 68k status register (sr), and updates Cyclone context with it.\r
360 \r
361int CycloneFlushIrq(struct Cyclone *pcy);\r
362 If .irq is greater than IRQ mask in SR, or it is equal to 7 (NMI), processes interrupt\r
363 exception and returns number of cycles used. Otherwise, does nothing and returns 0.\r
364\r
365void CyclonePack(const struct Cyclone *pcy, void *save_buffer);\r
366 Writes Cyclone state to save_buffer. This allows to avoid all the trouble figuring what\r
367 actually needs to be saved from the Cyclone structure, as saving whole struct Cyclone\r
368 to a file will also save various pointers, which may become invalid after your program\r
369 is restarted, so simply reloading the structure will cause a crash. save_buffer size\r
370 should be 128 bytes (now it is really using less, but this allows future expansion).\r
371\r
372void CycloneUnpack(struct Cyclone *pcy, const void *save_buffer);\r
373 Reloads Cyclone state from save_buffer, which was previously saved by CyclonePack().\r
374 This function uses checkpc() callback to rebase the PC, so .checkpc must be initialized\r
375 before calling it.\r
376\r
377Callbacks:\r
378\r
379.checkpc\r
380unsigned int (*checkpc)(unsigned int pc);\r
381 This function is called when PC changes are performed in 68k code or because of exceptions.\r
382 It is passed ARM pointer and should return ARM pointer casted to int. It must also update\r
383 .membase if needed. See "The checkpc() function" section above.\r
384\r
385unsigned int (*read8 )(unsigned int a);\r
386unsigned int (*read16 )(unsigned int a);\r
387unsigned int (*read32 )(unsigned int a);\r
388 These are the read memory handler callbacks. They are called when 68k code reads from memory.\r
389 The parameter is a 68k address in data space, return value is a data value read. Data value\r
390 doesn't have to be masked to 8 or 16 bits for read8 or read16, Cyclone will do that itself\r
391 if needed.\r
392\r
393unsigned int (*fetch8 )(unsigned int a);\r
394unsigned int (*fetch16)(unsigned int a);\r
395unsigned int (*fetch32)(unsigned int a);\r
396 Same as above, but these are reads from program space (PC relative reads mostly).\r
397 \r
398void (*write8 )(unsigned int a,unsigned char d);\r
399void (*write16)(unsigned int a,unsigned short d);\r
400void (*write32)(unsigned int a,unsigned int d);\r
401 These are called when 68k code writes to data space. d is the data value.\r
402\r
403int (*IrqCallback)(int int_level);\r
404 This function is called when Cyclone acknowledges an interrupt. The parameter is the IRQ\r
405 level being acknowledged, and return value is exception vector to use, or one of these special\r
406 values: CYCLONE_INT_ACK_AUTOVECTOR or CYCLONE_INT_ACK_SPURIOUS. Can be disabled in config.h.\r
407 See "Interrupts" section for more information.\r
408\r
409void (*ResetCallback)(void);\r
410 Cyclone will call this function if it encounters RESET 68k instruction.\r
411 Can be disabled in config.h.\r
412\r
413int (*UnrecognizedCallback)(void);\r
414 Cyclone will call this function if it encounters illegal instructions (including A-line and\r
415 F-line ones). Can be tuned / disabled in config.h.\r
416\r
417\r
418Function codes\r
419--------------\r
420\r
421Cyclone doesn't pass function codes to it's memory handlers, but they can be calculated:\r
422FC2: just use supervisor state bit from status register (eg. (MyCpu.srh & 0x20) >> 5)\r
423FC1: if we are in fetch* function, then 1, else 0.\r
424FC0: if we are in read* or write*, then 1, else 0.\r
425CPU state (all FC bits set) is active in IrqCallback function.\r
426\r
427\r
428References\r
429----------\r
430\r
431These documents were used while writing Cyclone and should be useful for those who want to\r
432understand deeper how the 68000 works.\r
433\r
434MOTOROLA M68000 FAMILY Programmer's Reference Manual\r
435common name: 68kPM.pdf\r
436\r
437M68000 8-/16-/32-Bit Microprocessors User's Manual\r
438common name: MC68000UM.pdf\r
439\r
44068000 Undocumented Behavior Notes by Bart Trzynadlowski\r
441http://www.trzy.org/files/68knotes.txt\r
442\r
443Instruction prefetch on the Motorola 68000 processor by Jorge Cwik\r
444http://pasti.fxatari.com/68kdocs/68kPrefetch.html\r
445\r
446\r
447ARM Register Usage\r
448------------------\r
449\r
450See source code for up to date of register usage, however a summary is here:\r
451\r
452 r0-3: Temporary registers\r
453 r4 : Current PC + Memory Base (i.e. pointer to next opcode)\r
454 r5 : Cycles remaining\r
455 r6 : Pointer to Opcode Jump table\r
456 r7 : Pointer to Cpu Context\r
457 r8 : Current Opcode\r
458 r10 : Flags (NZCV) in highest four bits\r
459 (r11 : Temporary register)\r
460\r
461Flags are mapped onto ARM flags whenever possible, which speeds up the processing of opcode.\r
462r9 is not used intentionally, because AAPCS defines it as "platform register", so it's\r
463reserved in some systems.\r
464\r
465\r
6003a768 466Thanks to...\r
467------------\r
468\r
469* All the previous code-generating assembler cpu core guys!\r
470 Who are iirc... Neill Corlett, Neil Bradley, Mike Coates, Darren Olafson\r
d9d77995 471 Karl Stenerud and Bart Trzynadlowski\r
6003a768 472\r
473* Charles Macdonald, for researching just about every console ever\r
474* MameDev+FBA, for keeping on going and going and going\r
d9d77995 475\r
476\r
477What's New\r
478----------\r
479v0.0099\r
480 * Cyclone no longer uses r9, because AAPCS defines it as "platform register",\r
481 so it's reserved in some systems.\r
482 * Made SPLIT_MOVEL_PD to affect MOVEM too.\r
483\r
484v0.0088\r
485 - Reduced amount of code in opcode handlers by ~23% by doing the following:\r
486 - Removed duplicate opcode handlers\r
487 - Optimized code to use less ARM instructions\r
488 - Merged some duplicate handler endings\r
489 + Cyclone now does better job avoiding pipeline interlocks.\r
490 + Replaced incorrect handler of DBT with proper one.\r
491 + Changed "MOVEA (An)+ An" behavior.\r
492 + Fixed flag behavior of ROXR, ASL, LSR and NBCD in certain situations.\r
493 Hopefully got them right now.\r
494 + Cyclone no longer sets most significant bits while pushing PC to stack.\r
495 Amiga Kickstart depends on this.\r
496 + Added optional trace mode emulation.\r
497 + Added optional address error emulation.\r
498 + Additional functionality added for MAME and other ports (see config.h).\r
499 + Added return value for IrqCallback to make it suitable for emulating devices which\r
500 pass the vector number during interrupt acknowledge cycle. For usual autovector\r
501 processing this function must return CYCLONE_INT_ACK_AUTOVECTOR, so those who are\r
502 upgrading must add "return CYCLONE_INT_ACK_AUTOVECTOR;" to their IrqCallback functions.\r
503 * Updated documentation.\r
504\r
505v0.0086\r
506 + Cyclone now can be customized to better suit your project, see config.h .\r
507 + Added an option to compress the jumptable at compile-time. Must call CycloneInit()\r
508 at runtime to decompress it if enabled (see config.h).\r
509 + Added missing CHK opcode handler (used by SeaQuest DSV).\r
510 + Added missing TAS opcode handler (Gargoyles,Bubba N Stix,...). As in real genesis,\r
511 memory write-back phase is ignored (but can be enabled in config.h if needed).\r
512 + Added missing NBCD and TRAPV opcode handlers.\r
513 + Added missing addressing mode for CMP/EOR.\r
514 + Added some minor optimizations.\r
515 - Removed 216 handlers for 2927 opcodes which were generated for invalid addressing modes.\r
516 + Fixed flags for ASL, NEG, NEGX, DIVU, ADDX, SUBX, ROXR.\r
517 + Bugs fixed in MOVEP, LINK, ADDQ, DIVS handlers.\r
518 * Undocumented flags for CHK, ABCD, SBCD and NBCD are now emulated the same way as in Musashi.\r
519 + Added Uninitialized Interrupt emulation.\r
520 + Altered timing for about half of opcodes to match Musashi's.\r
521\r
522v0.0082\r
523 + Change cyclone to clear cycles before returning when halted\r
524 + Added Irq call back function. This allows emulators to be notified\r
525 when cyclone has taken an interrupt allowing them to set internal flags\r
526 which can help fix timing problems.\r
527\r
528v0.0081\r
529 + .asm version was broken and did not compile with armasm. Fixed.\r
530 + Finished implementing Stop opcode. Now it really stops the processor.\r
531\r
532v0.0080\r
533 + Added real cmpm opcode, it was using eor handler before this.\r
534 Fixes Dune and Sensible Soccer.\r
535\r
536v0.0078\r
537 note: these bugs were actually found Reesy, I reimplemented these by\r
538 using his changelog as a guide.\r
539 + Fixed a problem with divu which was using long divisor instead of word.\r
540 Fixes gear switching in Top Gear 2.\r
541 + Fixed btst opcode, The bit to test should shifted a max of 31 or 7\r
542 depending on if a register or memory location is being tested.\r
543 + Fixed abcd,sbcd. They did bad decimal correction on invalid BCD numbers\r
544 Score counters in Streets of Rage level end work now.\r
545 + Changed flag handling of abcd,sbcd,addx,subx,asl,lsl,...\r
546 Some ops did not have flag handling at all.\r
547 Some ops must not change Z flag when result is zero, but they did.\r
548 Shift ops must not change X if shift count is zero, but they did.\r
549 There are probably still some flag problems left.\r
550 + Patially implemented Stop and Reset opcodes - Fixes Thunderforce IV\r
551\r
552v0.0075\r
553 + Added missing displacement addressing mode for movem (Fantastic Dizzy)\r
554 + Added OSP <-> A7 swapping code in opcodes, which change privilege mode\r
555 + Implemented privilege violation, line emulator and divide by zero exceptions\r
556 + Added negx opcode (Shining Force works!)\r
557 + Added overflow detection for divs/divu\r
558\r
559v0.0072\r
560 note: I could only get v0.0069 cyclone, so I had to implement these myself using Dave's\r
561 changelog as a guide.\r
562 + Fixed a problem with divs - remainder should be negative when divident is negative\r
563 + Added movep opcode (Sonic 3 works)\r
564 + Fixed a problem with DBcc incorrectly decrementing if the condition is true (Shadow of the Beast)\r
565\r
566v0.0069\r
567 + Added SBCD and the flags for ABCD/SBCD. Score and time now works in games such as\r
568 Rolling Thunder 2, Ghouls 'N Ghosts\r
569 + Fixed a problem with addx and subx with 8-bit and 16-bit values.\r
570 Ghouls 'N' Ghosts now works!\r
571\r
572v0.0068\r
573 + Added ABCD opcode (Streets of Rage works now!)\r
574\r
575v0.0067\r
576 + Added dbCC (After Burner)\r
577 + Added asr EA (Sonic 1 Boss/Labyrinth Zone)\r
578 + Added andi/ori/eori ccr (Altered Beast)\r
579 + Added trap (After Burner)\r
580 + Added special case for move.b (a7)+ and -(a7), stepping by 2\r
581 After Burner is playable! Eternal Champions shows more\r
582 + Fixed lsr.b/w zero flag (Ghostbusters)\r
583 Rolling Thunder 2 now works!\r
584 + Fixed N flag for .b and .w arithmetic. Golden Axe works!\r
585\r
586v0.0066\r
587 + Fixed a stupid typo for exg (orr r10,r10, not orr r10,r8), which caused alignment\r
588 crashes on Strider\r
589\r
590v0.0065\r
591 + Fixed a problem with immediate values - they weren't being shifted up correctly for some\r
592 opcodes. Spiderman works, After Burner shows a bit of graphics.\r
593 + Fixed a problem with EA:"110nnn" extension word. 32-bit offsets were being decoded as 8-bit\r
594 offsets by mistake. Castlevania Bloodlines seems fine now.\r
595 + Added exg opcode\r
596 + Fixed asr opcode (Sonic jumping left is fixed)\r
597 + Fixed a problem with the carry bit in rol.b (Marble Madness)\r
598\r
599v0.0064\r
600 + Added rtr\r
601 + Fixed addq/subq.l (all An opcodes are 32-bit) (Road Rash)\r
602 + Fixed various little timings\r
603\r
604v0.0063\r
605 + Added link/unlk opcodes\r
606 + Fixed various little timings\r
607 + Fixed a problem with dbCC opcode being emitted at set opcodes\r
608 + Improved long register access, the EA fetch now does ldr r0,[r7,r0,lsl #2] whenever\r
609 possible, saving 1 or 2 cycles on many opcodes, which should give a nice speed up.\r
610 + May have fixed N flag on ext opcode?\r
611 + Added dasm for link opcode.\r
612\r
613v0.0062\r
614 * I was a bit too keen with the Arithmetic opcodes! Some of them should have been abcd,\r
615 exg and addx. Removed the incorrect opcodes, pending re-adding them as abcd, exg and addx.\r
616 + Changed unknown opcodes to act as nops.\r
617 Not very technical, but fun - a few more games show more graphics ;)\r
618\r
619v0.0060\r
620 + Fixed divu (EA intro)\r
621 + Added sf (set false) opcode - SOR2\r
622 * Todo: pea/link/unlk opcodes\r
623\r
624v0.0059: Added remainder to divide opcodes.\r
625\r
626\r