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