--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>FAME Fast and Accurate Morolora 68000 Emulation Library</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body>
+<hr size="1">
+<div align="center"><font color="#0000FF" size="4"><strong><font color="#0000FF" size="4"><strong><font size="7">F.A.M.E.</font></strong></font><font size="5"><br>
+ <font size="4">Fast and Accurate Morolora 68000 Emulation Library</font></font></strong></font><font size="4"><br>
+ <font size="3"><strong>Copyright (c) 2002-2005 Oscar Orallo Peláez / Daniel Lancha García. All rights
+ reserved.</strong></font></font><br>
+ <strong>March 14th, 2006</strong><br>
+ <hr size="1">
+ <div align="left">
+<p><font size="5"><strong>Table of Contents</strong></font></p>
+ </div>
+</div>
+<blockquote>
+ <p> <font size="3"><strong><a href="#Introduction">0. Introduction</a><br>
+ <a href="#TermsofUse">1. Terms of Use</a><br>
+ <a href="#VersionHistory">2. Version History</a><br>
+ </strong><a href="#WhatIsEmulated"><strong>3. What is emulated</strong></a><strong><br>
+ <a href="#UsingFAME">4. Using the emulation library</a> <br>
+ <a href="#DataStructure">4.1. Data structure</a><br>
+ <a href="#CPUcontext">4.1.1.
+ CPU context</a><br>
+ <a href="#MemoryMapExample">4.1.2.
+ Memory map definition example</a><br>
+ <a href="#memoryhandling">4.2. Memory handling</a><br>
+ <a href="#RunningCPU">4.3. Running the CPU</a><br>
+ <a href="#Interrupts">5. Interrupts and exceptions<br>
+ </a> <a href="#InterruptAcknowledge">5.1. Interrupt
+ acknowledge</a><br>
+ <a href="#CustomizingProcessingHLE">5.2. Customizing
+ processing (HLE)</a><br>
+ <a href="#IRQLoweringtype">5.3. IRQ lowering</a><br>
+ <a href="#FunctionReference">6. Function Reference</a><br>
+ <a href="#GeneralPurposeFunctions">6.1. General Purpose
+ Functions</a><br>
+ <a href="#HardwareFunctions">6.2. Hardware interrupt
+ handling functions</a><br>
+ <a href="#CPUContextFunctions">6.3. CPU context handling
+ functions</a><br>
+ <a href="#TimingFunctions">6.4. Timing functions</a><br>
+ <a href="#MultiCPU">7. Multi-CPU systems</a><br>
+ <a href="#HelpfulTips">8. Helpful tips</a><br>
+ <a href="#Troubleshooting">9. Troubleshooting</a><br>
+ <a href="#KnownBugs">10. Known bugs</a><br>
+ <a href="#SpecialThanks">11. Special thanks</a></strong></font></p>
+</blockquote>
+<hr size="1">
+<br>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="Introduction"></a><font color="#FFFFFF" size="5"><strong>
+ 0. Introduction</strong></font></font></td>
+ </tr>
+</table>
+<p align="justify">This is the documentation for FAME library, please read it.</p>
+<p align="justify">FAME is an extremely fast and accurate <strong>Motorola 68000 Emulation Library</strong>.
+ It is currently available for Intel x86-based systems (80386 or better processor)
+ and SH-4 based systems.</p>
+<p align="justify">The x86 version was designed to work under any win32 development environment
+ such as Microsoft Visual Basic, Microsoft Visual C++, Borland Delphi or Borland
+ C++ Builder.</p>
+<p align="justify">The SH-4 version was specially designed for the Dreamcast videogame console
+ but it can be used in any SH-4 based system.</p>
+<p align="justify">This manual tries to be a guide to get the emulation library working in your
+ development environment. I hope you find it useful. If you use FAME in your
+ project I would like to hear your opinion about it.</p>
+<p align="justify">The package contains one example (C++ program) to show how the library should
+ be called and used. It was compiled successfully in Microsoft Visual C++ 6.0
+ SP5, Borland C++ Builder 5/6 and Borland C++ Compiler 5.5.</p>
+<p align="justify">If you have any questions about how it works in your favorite compiler send
+ me an email. I'd like to help you with FAME.<br>
+ If you find any bug in FAME, it would be nice that you inform me about that via
+ <a href="mailto:oscar@m68k.com?subject=FAME">email</a>. Any feedback, comments
+ and suggestions will also be appreciated.</p>
+<p>How to contact Oscar Orallo:</p>
+<blockquote>
+ <p>E-mail: <a href="mailto:oscar@m68k.com?subject=FAME">oscar@m68k.com</a><br>
+ Web site: <a href="http://www.m68k.com/fame">http://www.m68k.com/fame</a></p>
+</blockquote>
+<p>FAME Distribution: <a href="http://www.m68k.com/fame/fame.zip">http://www.m68k.com/fame/fame.zip</a>
+ (latest)<br>
+FAME Development Package: <a href="http://www.m68k.com/fame/famedev.zip">http://www.m68k.com/fame/famedev.zip</a> (latest)</p>
+<p>Here we go folks, have fun :)</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="TermsofUse" id="TermsofUse"></a><strong><font color="#FFFFFF"> <font size="5">1.
+ Terms of use</font></font></strong></font></td>
+ </tr>
+</table>
+<p> FAME is a development package that contains the following files:</p>
+<table width="100%" border="0">
+ <tr bgcolor="#666666">
+ <th scope="col"><font color="#FFFFFF">File</font></th>
+ <th scope="col"><font color="#FFFFFF">Description</font></th>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/x86/win32/fame.dll</td>
+ <td>Microsoft win32 dinamic link library</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/x86/linux/libfame.a</td>
+ <td>x86 static ELF library</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/x86/cygwin/libfame.a</td>
+ <td>x86 static win32 library</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/sh4/libfame.a</td>
+ <td>SH-4 static ELF library</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/delphi/fame.pas</td>
+ <td>Delphi unit</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/doc/fame.html</td>
+ <td>Documentation file</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/example/main.c</td>
+ <td>C source code example</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/example/makefile.cygwin</td>
+ <td>Cygwin example makefile </td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/example/makefile.dc</td>
+ <td>Dreamcast example makefile </td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/example/makefile.linux</td>
+ <td>Linux example makefile </td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td bgcolor="#EEEEEE">/example/romdisk/bubble.bin</td>
+ <td>Motorola 68000 binary code file</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/lib/bc/fame.lib</td>
+ <td>Borland C++ 32-bit import library</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>/lib/vc/fame.exp</td>
+ <td>Microsoft Visual C++ 32-bit export file</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>/include/fame.h</td>
+ <td>C/C++ header file</td>
+ </tr>
+</table>
+<p align="justify"><br>
+ FAME may be distributed freely in unmodified form, as long as this document
+file is included.</p>
+<p align="justify">Nothing may be charged for this library. If you want to use it in a shareware
+ or commercial application, contact me.</p>
+<p align="justify">The author will not be held liable for damages. FAME comes with absolutely
+ NO WARRANTY. Anyway i will try to help you with any problem you have using FAME.</p>
+<p align="justify">If you do not agree with all of these terms, please remove FAME from your computer.</p>
+<p align="justify">You are encouraged to contact the author if you wish to use FAME in a commercial
+ product (to negotiate licensing).</p>
+<p align="justify">Any program which uses FAME must include in its documentation or in the program
+ itself the following credit text:</p>
+<p><em><strong>FAME Motorola 68000 Emulation Library by Oscar Orallo (oscar@m68k.com)</strong></em></p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="VersionHistory"></a><strong><font color="#FFFFFF"> <font size="5">2.
+ Version History</font></font></strong></font></td>
+ </tr>
+</table>
+<br>
+<table width="100%" border="0" cellpadding="3" cellspacing="1">
+ <tr bgcolor="#666666">
+ <td width="50%"><div align="center"><strong><font color="#FFFFFF">Intel®
+ 80386 CISC engine</font></strong></div></td>
+ <td> <div align="center"><strong><font color="#FFFFFF">Super H® SH-4 RISC
+ engine</font></strong></div></td>
+ </tr>
+ <tr>
+ <td width="50%" valign="top" bgcolor="#EEEEEE"> <p>Version <strong>2.0a</strong> (14th, march, 2006)</p>
+ <p>- Stupid bug fixed in IRQ management (thanks Martin Kresse). <br>
+ - Accurate DIV timing implemented (thanks Jorge Cwik).<br>
+ - Overflow detection fixed in signed DIV instruction.<br>
+ - Added makefiles for linux and cygwin environments. </p>
+ <p>Version <strong>2.0</strong> (11th, january, 2006)</p>
+ <p>- <em>set_irq_type</em> API function removed. IRQs will be automatically lowered once it was attended.<br>
+ - Many flag calculations fixed.<br>
+ - Some minor tweaks. </p>
+ <p>Version <strong>1.23</strong> (5th April,
+ 2005)</p>
+ <p>- Timing fixed in MOVEM instructions.</p>
+ <p>Version <strong>1.22</strong> (7th March, 2005)</p>
+ <p>- Fixed a stupid bug in <em>fetch</em> function.</p>
+ <p>Version <strong>1.21</strong> (19th February, 2005)</p>
+ <p>- <em>set_irq_type</em> function changed for flexible use.<br>
+ - Pointer to data structure parameter removed from memory handlers to
+ increase throughtput.</p>
+ <p>Version <strong>1.2</strong> (17th December, 2004)</p>
+ <p>- Fixed the PC base calculation for fetch memory regions beyond the first
+ allocated area.<br>
+ - Fixed a tiny error in the status register masking. Several instructions
+ could generate an invalid value.<br>
+ - Fixed JSR instruction when jumping to a fetch bank different to the
+ current one.<br>
+ - Tiny error fixed in interrupt acknowledge function parameter.<br>
+ - Fixed the <em>set_context</em> function when setting status register.<br>
+ - Fixed the PC restoring in HLE feature.<br>
+ - Fixed DIVS instruction operation.</p>
+ <p>Version <strong>1.1</strong> (7th October, 2004)</p>
+ <p>- New static ELF library available.<br>
+ - Interrupt acknowledge calling bug fixed.<br>
+ - Custom exception processing (HLE) feature added.<br>
+ - Some little changes in CPU context (register ordering).<br>
+ - Flag N calculation in CHK instruction fixed.<br>
+ - Some little code tweaks.<br>
+ - New sections added to this document.<br>
+ - Some defines added to header file.<br>
+ - Some return values have been changed.<br>
+ - Set/get context functions simplified. Some changes have been applied.
+ </p>
+ <p>Version <strong>1.0g</strong> (2nd August, 2004) </p>
+ <p>- Speed emulation increased once more. The fetch/decode/execute loop
+ has been inlined.<br>
+ - Some API functions added:<em> add_cycles</em> and <em>release_cycles</em>.<br>
+ - Memory handling section added to this document (thanks Richard Hollstein
+ for requesting it).<br>
+ - Faster memory access (both program code and data). Memory regions must
+ be 4 KB aligned now. <br>
+ - Overhead reduced in <em>emulate</em> function calls (entry/exit code
+ optimized).<br>
+ - Interrupt acknowledge function added.<br>
+ - Some code tweaks here and there.<br>
+ - Static library for Borland C++ compilers added to the package.<br>
+ - DLL file size reduced: internal compression (<a href="http://upx.sourceforge.net/" target="_blank">UPX</a>).<br>
+ - Fixed a bug in STOP instruction: the processor started up after an interrupt
+ request even if its interrupt level was not higher than current PPL.<br>
+ - Ver little optimization in branch instructions.<br>
+ </p>
+ <p> Version <strong>1.0f</strong> (23th February, 2003)</p>
+ <p>- API functions added: <em>get_register</em> and <em>set_register</em>
+ to retrieve and set register values.<br>
+ - Small optimizations for improved speed.<br>
+ - CPU context modified: execinfo added for more complete CPU state handling
+ support. <br>
+ - LIB file added to package to support implicit linking :).<br>
+ - Changes in documentation.<br>
+ - C header file (fame.h) and Delphi unit (fame.pas) modified.<br>
+ </p>
+ <p>Version <strong>1.0e</strong> (18th February, 2003)</p>
+ <p>- Emulation core speed increased lightly (faster entry/exit code). Now
+ the library is pretty fast.<br>
+ - Some changes in function and variable naming (odometer changed to cycles_counter).<br>
+ </p>
+ <p>Version <strong>1.0d</strong> (20th December, 2002)</p>
+ <p>- Fetch function speed incremented a bit.<br>
+ - Fixed memory boundary for byte data accesses.<br>
+ </p>
+ <p>Version <strong>1.0c</strong> (27th August, 2002)</p>
+ <p>- Fixed a stupid bug in group 0 exceptions management.<br>
+ </p>
+ <p> Version <strong>1.0b</strong> (16th August, 2002)</p>
+ <p>- Many errors corrected in documentation about memory mapping.<br>
+ - The function <em>fetch</em> has now capability to access to the data
+ address space.</p>
+ <p><br>
+ Version <strong>1.0a</strong> (24th July, 2002)</p>
+ <p>- First public release.</p> </td>
+ <td valign="top" bgcolor="#EEEEEE"> <p>Version <strong>2.0a</strong> (14th, march, 2006)</p>
+ <p>- Timing fixed for DIV and signed MUL instructions.<br>
+ - Improved overflow detection in signed DIV instruction.<br>
+ - Added makefile for Dreamcast system (requires <a href="http://gamedev.allusion.net/softprj/kos/">KOS</a>). </p>
+ <p>Version <strong>2.0</strong> (11th, january, 2006)</p>
+ <p>- Tons of bugs fixed (thanks Chui).<br>
+ - Accurate DIV timing implemented (thanks Jorge Cwik).<br>
+ - <em>set_irq_type</em> API function removed. IRQs will be automatically lowered once it was attended.<br>
+ - Great speed improvements.</p>
+ <p>Version <strong>0.04 </strong>(5th April, 2005)</p>
+ <p>- Lightweighted entry/exit code.<br>
+ - Fixed sign/zero flag calculation when moving long data from memory to
+ memory.<br>
+ - Privilege violation exception fixed.<br>
+ - Faster interrupt/exception management.<br>
+ - Timing fixed in MOVEM instructions.</p>
+ <p> Version <strong>0.03 </strong>(7th March, 2005)</p>
+ <p>- Sign flag calculation in inmediate logical instruction fixed.<br>
+ - Carry flag calculation in NEG instruction fixed.<br>
+ - Overflow flag in operations with X flag fixed.<br>
+ - Fixed CPU state stop bit.<br>
+ - Speed up by about 20%.<br>
+ - Tiny tweaks here and there and everywhere.</p>
+ <p>Version <strong>0.02</strong> (19th February, 2005)</p>
+ <p>- First beta release.<br>
+ - <em>set_irq_type</em> function changed for flexible use.<br>
+ - Greatly improved internal memory management.<br>
+ - Pointer to data structure parameter removed from memory handlers to
+ increase throughtput.<br>
+ - DIV/DIVS instructions fixed.<br>
+ - ABCD/SBCD adjusted result fixed.<br>
+ - MOVEM (control addressing mode) instruction fixed.<br>
+ - BTST with memory addressing mode fixed.<br>
+ - Fixed Z flag calculation in NEGX instruction.<br>
+ - Fixed TAS instruction.<br>
+ - Fixed RESET instruction (external handler calling).<br>
+ - Fixed ILLEGAL instruction (exception generation).<br>
+ - Quick ADD to address register fixed.<br>
+ - EXG instruction fixed.<br>
+ - V flag calculation fixed in ASL instruction.<br>
+ - Some tiny tweaks & improvements.</p>
+ <p>Version <strong>0.01b</strong> (17th December, 2004)</p>
+ <p>- Memory map cache generation fixed.<br>
+ - Fixed the PC restoring in HLE feature.<br>
+ - Many opcodes fixed.<br>
+ - Lots of bugs fixed.</p>
+ <p>Version <strong>0.01a</strong> (7th October, 2004)</p>
+ <p>- First public release. Alpha development state!</p></td>
+ </tr>
+</table>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="WhatIsEmulated"></a><strong><font color="#FFFFFF"> <font size="5">3.
+ What is emulated</font></font></strong></font></td>
+ </tr>
+</table>
+<p>This library emulates the Motorola 68000 microprocessor. The main emulation
+ features are the following:</p>
+<ul>
+ <li>
+ <div align="justify"> Written in <font color="#FF0000"><strong>100% 32-bit assembly language</strong></font>.</div>
+ </li>
+ <li>
+ <div align="justify"> Support for all opcodes.</div>
+ </li>
+ <li>
+ <div align="justify"> Calculates <font color="#FF0000"><strong>100% of flags correctly</strong></font>,
+ even undocumented ones.</div>
+ </li>
+ <li>
+ <div align="justify"> Excellent accurate timing emulation for all opcodes. All instructions
+ have perfect timing emulation according to Motorola references. Take a look at Motorola manuals for more information about this
+ fact.</div>
+ </li>
+ <li>
+ <div align="justify"> Complete hardware interrupt support.</div>
+ </li>
+ <li>
+ <div align="justify"> Accurate exception support allowing an appropriate emulation of home
+ computer systems.</div>
+ </li>
+ <li>
+ <div align="justify"> Priorities between interrupts and exceptions are fully emulated.</div>
+ </li>
+</ul>
+<p> </p><table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><a name="UsingFAME"></a><font color="#FFFFFF" size="4"><strong> 4<font size="5">.
+ Using the emulation library</font></strong></font></td>
+ </tr>
+</table>
+<p> <font size="4"><a name="DataStructure"></a>4.1. Data structure</font></p>
+<p align="justify">The data structures used in the emulation core is defined in the C file header
+ fame.h. In this file you will get all the data structures needed to use the
+ library.<br>
+ <br>
+ If you cannot use this file because you are not using a C/C++ compliant compiler
+ you have to define this structures by yourself in your code.</p>
+<p>Here I describe these data structures.</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">struct M68K_PROGRAM<br>
+ {<br>
+ unsigned low_addr;<br>
+ unsigned high_addr;<br>
+ unsigned offset;<br>
+ }</font></p>
+</blockquote>
+<p align="justify">This structure defines the memory regions for 68000 program code. The fields
+ <em>low_addr</em> and <em>high_addr</em> are 32-bit values used for determine
+ the low and high address of the memory block in the 68000 memory map.</p>
+<p align="justify">The last field is a 32-bit pointer to the data of the memory region. The data
+ pointed by it must be allocated in native (Motorola) format. If not, the data
+ will be fetched incorrectly. Make sure of this fact.</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_DATA<br>
+ {<br>
+ unsigned low_addr;<br>
+ unsigned high_addr;<br>
+ void *mem_handler;<br>
+ void *data;<br>
+ }</font></p>
+</blockquote>
+<p align="justify">This one is used for 68000 data code. This structure has an appearance very
+ similar to the last one but has a diference in the way you can give the control
+ of the memory to FAME. The pointer called <em>mem_handler</em> is a function
+ pointer. This pointer is used for memory management, so when you want to take
+ control in the reading/writing of a memory region, you have to set this pointer
+ to the appropriate value. If you do not want to use this funcionality you have
+ to set this pointer to NULL and set <em>data</em> pointing to the data itself.
+ The different ways to perform memory handling will be described with more detail
+ in <a href="#memoryhandling">memory handling section</a>.</p>
+<p><font size="3"><strong><a name="CPUcontext" id="CPUcontext"></a>4.1.1. CPU
+ context</strong></font></p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">struct M68K_CONTEXT<br>
+ {<br>
+ struct M68K_PROGRAM *fetch;<br>
+ struct M68K_DATA *read_byte;<br>
+ struct M68K_DATA *read_word;<br>
+ struct M68K_DATA *write_byte;<br>
+ struct M68K_DATA *write_word;<br>
+ struct M68K_PROGRAM *sv_fetch;<br>
+ struct M68K_DATA *sv_read_byte;<br>
+ struct M68K_DATA *sv_read_word;<br>
+ struct M68K_DATA *sv_write_byte;<br>
+ struct M68K_DATA *sv_write_word;<br>
+ struct M68K_PROGRAM *user_fetch;<br>
+ struct M68K_DATA *user_read_byte;<br>
+ struct M68K_DATA *user_read_word;<br>
+ struct M68K_DATA *user_write_byte;<br>
+ struct M68K_DATA *user_write_word;<br>
+ void (*reset_handler)(void);</font><font size="2" face="Courier New, Courier, mono"><br>
+ void (*iack_handler)(unsigned level);<br>
+ unsigned *icust_handler;<br>
+ unsigned dreg[8];<br>
+ unsigned areg[8];<br>
+ unsigned asp;<br>
+ unsigned pc;<br>
+ unsigned cycles_counter;<br>
+ unsigned char interrupts[8];<br>
+ unsigned short sr;<br>
+ unsigned short execinfo;<br>
+ }</font></p>
+</blockquote>
+<p align="justify">This structure defines a CPU context. You have to declare a variable of this
+ type. It contains all information related with the context of the CPU.</p>
+<p align="justify">You have to set pointer values of <font size="2" face="Courier New, Courier, mono"><em>sv*</em></font>
+ which defines the supervisor memory map. In order to get the CPU into user mode,
+ set the <font size="2" face="Courier New, Courier, mono"><em>user*</em></font>
+ pointers.</p>
+<p align="justify">The pointer <em>reset_handler</em> is called when the RESET instruction is
+ executed. In this way, you can reset all external devices in the calling to
+ this function. If you do not want to use this feature remember to set this pointer
+ to NULL.</p>
+<p align="justify">The pointer <em>iack_handler</em> is called whenever a hardware interrupt is
+ handled by the CPU. This feature will be covered later in <a href="#Interrupts">Interrupts
+ and exceptions section</a>.</p>
+<p align="justify">The pointer <em>icust_handler</em> is intented to point to an array of function
+ pointers to handle customized interrupt/exception processing (known as High
+ Level Emulation or HLE for short). See <a href="#Interrupts">Interrupts and
+ exceptions section</a> to set up this feature.</p>
+<p align="justify">The rest of the structure is managed by FAME so you can read it in execution
+ time to retrieve information about the CPU.</p>
+<p align="justify">Here I describe some interesting fields for the 68000 programmer:</p>
+<blockquote>
+ <p align="justify"> - <font size="2" face="Courier New, Courier, mono"><strong>dreg[8]</strong></font>
+ holds the eight data registers in order (d0 - d7).<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>areg[8]</strong></font>
+ holds the eight address registers in order (a0 - a7).<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>pc</strong></font>
+ is the current PC address.<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>asp</strong></font>
+ stands for <em>Alternative Stack Pointer</em>. It is used to store the not
+ currently used stack pointer. In supervisor mode, asp is the user stack pointer,
+ in user mode it is the supervisor stack pointer.<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>cycles_counter</strong></font>
+ holds the number of cycles executed so far.<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>interrupts</strong></font>
+ is an array that contains information about interrupts.<br>
+ - <font size="2" face="Courier New, Courier, mono"><strong>sr</strong></font>
+ is the status register.</p>
+</blockquote>
+<p><font size="3"><strong><a name="MemoryMapExample"></a>4.1.2 Memory map definition
+ example</strong></font></p>
+<p align="justify"> As an example of an address space definition, consider the following simple
+ memory map:</p>
+<ul>
+ <li> ROM: 000000-01FFFF</li>
+ <li> RAM-1: 300000-407FFF</li>
+ <li> RAM-2: 500000-50FFFF</li>
+ <li> RAM-3: 600000-601FFF</li>
+ <li> RAM-4: 800000-80AFFF</li>
+</ul>
+<p align="justify">This is the structure for the program address space. I will suppose that ROM,
+ RAM-1 and RAM-2 contains program code.</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_PROGRAM prg_fetch[]
+ = {<br>
+ {0x000000, 0x01FFFF, (unsigned)rom},<br>
+ {0x300000, 0x407FFF, (unsigned)ram1 - 0x300000},<br>
+ {0x500000, 0x500FFF, (unsigned)ram2 - 0x500000},<br>
+ {-1, -1, NULL}<br>
+ }</font></p>
+</blockquote>
+<p>Note that the last entry must be <font size="2" face="Courier New, Courier, mono">{-1,
+ -1, NULL}</font>.</p>
+<p align="justify">Now, I will set up the data address space. In this case, I will suppose that
+ all memory areas will be accesed and that RAM-3 is accessed by the routine <em>mem_access</em>.
+ To do this, you will have to set up the following:</p>
+<p>- One structure for read byte operations:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_DATA data_rb[]
+ = {<br>
+ {0x000000, 0x01FFFF, NULL, rom},<br>
+ {0x300000, 0x407FFF, NULL, ram1 - 0x300000},<br>
+ {0x500000, 0x507FFF, NULL, ram2 - 0x500000},<br>
+ {0x600000, 0x601FFF, mem_access, NULL},<br>
+ {0x800000, 0x80AFFF, NULL, ram4 - 0x800000},<br>
+ {-1, -1, NULL, NULL}<br>
+ }</font></p>
+</blockquote>
+<p>- One structure for write byte operations:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_DATA data_wb[]
+ = {<br>
+ {0x000000, 0x01FFFF, NULL, rom},<br>
+ {0x300000, 0x407FFF, NULL, ram1 - 0x300000},<br>
+ {0x500000, 0x507FFF, NULL, ram2 - 0x500000},<br>
+ {0x600000, 0x601FFF, mem_access, NULL},<br>
+ {0x800000, 0x80AFFF, NULL, ram4 - 0x800000},<br>
+ {-1, -1, NULL, NULL}<br>
+ }</font></p>
+</blockquote>
+<p>- One structure for read word operations:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_DATA data_rw[]
+ = {<br>
+ {0x000000, 0x01FFFF, NULL, rom},<br>
+ {0x300000, 0x407FFF, NULL, ram1 - 0x300000},<br>
+ {0x500000, 0x507FFF, NULL, ram2 - 0x500000},<br>
+ {0x600000, 0x601FFF, mem_access, NULL},<br>
+ {0x800000, 0x80AFFF, NULL, ram4 - 0x800000},<br>
+ {-1, -1, NULL, NULL}<br>
+ }</font></p>
+</blockquote>
+<p>- One structure for write word operations:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_DATA data_ww[]
+ = {<br>
+ {0x000000, 0x01FFFF, NULL, rom},<br>
+ {0x300000, 0x407FFF, NULL, ram1 - 0x300000},<br>
+ {0x500000, 0x507FFF, NULL, ram2 - 0x500000},<br>
+ {0x600000, 0x601FFF, mem_access, NULL},<br>
+ {0x800000, 0x80AFFF, NULL, ram4 - 0x800000},<br>
+ {-1, -1, NULL, NULL}<br>
+ }</font></p>
+</blockquote>
+<p align="justify">In the example, the routine used for access to ram3 area is the same in all
+ the structures defined but it could be different.</p>
+<p align="justify">And now the last step is to fill the CPU context with the defined address spaces.
+ This is accomplished in the following way:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono">struct M68K_CONTEXT cpu_contxt;</font></p>
+ <p><font size="2" face="Courier New, Courier, mono">cpu_contxt.sv_fetch = prg_fetch;<br>
+ cpu_contxt.user_fetch = prg_fetch;</font></p>
+ <p><font size="2" face="Courier New, Courier, mono"> cpu_contxt.sv_read_byte
+ = data_rb;<br>
+ cpu_contxt.user_read_byte = data_rb;<br>
+ cpu_contxt.sv_read_word = data_rw;<br>
+ cpu_contxt.user_read_word = data_rw;<br>
+ cpu_contxt.sv_write_byte = data_wb;<br>
+ cpu_contxt.user_write_byte = data_wb;<br>
+ cpu_contxt.sv_write_word = data_ww;<br>
+ cpu_contxt.user_write_word = data_ww;</font></p>
+</blockquote>
+<p align="justify">Note that the memory address spaces for supervisor and user are the same. This
+ is very common but remember they could be different.</p>
+<p>And that is all.<br>
+</p>
+<p><font size="4"><a name="Memoryhandling"></a>4.2. Memory handling</font></p>
+<p>The emulation library provides two ways to perform the access to the memory
+ map: <em>built-in</em> and <em>custom</em>.</p>
+<p align="justify">The built-in memory handling is ideal to get the maximun speed to the memory
+ map but at the cost of less control. To use it you have to set <em>data</em>
+ pointing to the beginning of the native memory region and set <em>mem_handler</em>
+ to NULL.</p>
+<blockquote>
+ <p> <font size="2" face="Courier New, Courier, mono"> struct M68K_DATA<br>
+ {<br>
+ unsigned low_addr;<br>
+ unsigned high_addr;<br>
+ void *mem_handler;<br>
+ void *data;<br>
+ }</font></p>
+</blockquote>
+<p align="justify">The custom memory handling gives you total control over memory accesses but
+ its use could create a bottleneck in the emulated system if it is used inappropriately.
+ To use this feature you have to set up <em>mem_handler</em> pointer to the handling
+ function. That function will be called whenever a memory access is done.<br>
+ There is a restriction in the definition of a memory region: <u>it must be 4
+ KB aligned</u>. So it must start on 0XXX000h and end on 0YYYFFFh.</p>
+<p align="justify">Memory handling functions have the following structure:</p>
+<p align="justify"><font size="2" face="Courier New, Courier, mono">int read_xxxx (int address);<br>
+ void write_xxxx(int address, int data);</font></p>
+<p align="justify">where <em>xxxx</em> stands for byte, word or long depending on data size, <em>
+ address</em> is the memory address accessed and <em>data</em> is the data itself.</p>
+<p align="justify">Using memory handling functions might be a good way to customize emulated memory
+ space. You have to read/write data in the way FAME expects. This process could
+ become confusing. To avoid undesired problems in this point, i have written
+ some simple routines to make your life easier:</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">int readbyte(int address)<br>
+ { <br>
+ return ram[address^1]; <br>
+ } </font><br>
+ <br>
+ <font size="2" face="Courier New, Courier, mono">int readword(int address)<br>
+ { <br>
+ return ((unsigned short *)ram)[address>>1];
+ <br>
+ } <br>
+ </font><br>
+ <font size="2" face="Courier New, Courier, mono">void writebyte(int address,
+ int data)<br>
+ { <br>
+ ram[address^1] = data & 0xFF; <br>
+ } </font><br>
+ <br>
+ <font size="2" face="Courier New, Courier, mono">void writeword(int address,
+ int data)<br>
+ { <br>
+ ((unsigned short *)ram)[address>>1] = data &
+ 0xFFFF; <br>
+ } </font></p>
+</blockquote>
+<p align="justify">I am considering you have your emulated memory region (pointed by <em>ram</em> here)
+ in native endian format (this is, big endian for the 68000 processor). Note
+ the required endianess switch in the byte accesses, since we are reading in
+ a little endian machine (x86 and SH4 processors).</p>
+<p><br>
+ <a name="RunningCPU"></a><font size="4">4.3. Running the CPU</font></p>
+<p>In order to get the 68000 CPU running, you have to do the following steps:</p>
+<blockquote>
+ <p>1. Initialize the emulation library. Call <font size="2" face="Courier New">m68k_init()</font>
+ to perform this task.<br>
+ 2. Set up the memory map (see <a href="#MemoryMapExample">section 4.1.2</a>).<br>
+ 3. Reset the processor calling the <font size="2" face="Courier New">m68k_reset()</font>
+ function.<br>
+ 4. Execute code calling <font size="2" face="Courier New">m68k_emulate(n)</font>
+ function where the parameter n means the number of clock cycles to execute.</p>
+</blockquote>
+<p><u>Note:</u> See <a href="#FunctionReference">Function Reference section</a>
+ for more information about how API functions work.</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="Interrupts"></a><strong><font color="#FFFFFF"> <font size="5">5.
+ Interrupts and exceptions</font></font></strong></font></td>
+ </tr>
+</table>
+<p align="justify">The library currently emulates the <strong>group 0 exceptions</strong> (address
+ error and bus error), <strong>group 1 exceptions</strong> (trace mode, external
+ interrupts, illegal opcode and privilege violation) and <strong>group 2 exceptions</strong>.</p>
+<p align="justify">The <strong>reset exception</strong> is not emulated. This is due to performance
+ facts. If this exception was emulated, the performance of the library would
+ fall notably. If you need this exception be emulated, contact me.</p>
+<p align="justify">Hardware interrupts can be raised at any time, but it will be attended only in the entry code of the emulate function. To manage interrupts, please refer to the section <a href="#FunctionReference">Function Reference</a> bellow.</p>
+<p align="justify">If you have any doubt about how these events work, I recommend you to take a look at <a href="http://e-www.motorola.com/brdata/PDFDB/docs/MC68000UM.pdf" target="_blank">M68000 Microprocessors User's Manual</a> (english) or at the book <em>Sistemas Digitales</em> (spanish).</p>
+<p><strong><a name="InterruptAcknowledge"></a></strong><font size="4">5.1. Interrupt
+ acknowledge</font></p>
+<p align="justify">Sometimes could be useful to be warned when a hardware interrupt is being attended.
+ This feature is frequently called <em>interrupt acknowledging</em> and allows
+ you to take specific actions when an interrupt is handled, signaling a device
+ to lower the interrupt request, for example.<br>
+ This function accepts one parameter, the interrupt level, and returns no value.</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">void iackhandler(unsigned
+ int_level);</font></p>
+</blockquote>
+<p>Once you have defined your function, set up the CPU context:</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono"> struct M68K_CONTEXT cpu_contxt;</font></p>
+ <p><font size="2" face="Courier New, Courier, mono">cpu_contxt.iack_handler
+ = iackhandler;<br>
+ m68k_set_context(&cpu_contxt);</font></p>
+</blockquote>
+<p>If you do not need this feature, set this pointer to NULL to avoid undesired
+ results.</p>
+<p><strong><a name="CustomizingProcessingHLE"></a></strong><font size="4">5.2.
+ Customizing processing (HLE)</font></p>
+<p align="justify">Sometimes it is needed to trap an exception to perform some native tasks overriding
+ target system tasks (system BIOS calls, for example).</p>
+<p align="justify">To customize interrupt and exception processing use <em>icusthandler</em> table
+ pointer. This pointer must point to a table of a total of 256 function pointers,
+ each one handling each vector exception presented in the 68000 system starting
+ from address $000000. The index of the table is the vector number.</p>
+<p>The handling function accepts one parameter, the vector exception number, and
+ returns no value.</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">void icusthandler(unsigned
+ vector);</font></p>
+</blockquote>
+<p>The array of pointers could be used in this fashion:</p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">/* Function to customize
+ CHK exception */<br>
+ void chk_handler(unsigned vector)<br>
+ {<br>
+ . . .<br>
+ (some actions)<br>
+ . . .<br>
+ }</font></p>
+ <p><font size="2" face="Courier New, Courier, mono">unsigned fpa[256]; /*
+ Function Pointer Array declaration */<br>
+ struct M68K_CONTEXT</font><font size="2" face="Courier New, Courier, mono">
+ cpu_context; <br>
+ <br>
+ fpa[6] = chk_handler; /*
+ Customizing CHK exception */<br>
+ cpu_context.icust_handler = fpa; /* Setting up function pointers */</font></p>
+</blockquote>
+<p><font size="2" face="Courier New, Courier, mono"> </font>Take in account the
+ following when you use this feature:</p>
+<ul>
+ <li> Remember to set to NULL those exceptions you do not want to be customized
+ in the array of function pointers.</li>
+ <li>
+ <div align="justify"> Group 0 exceptions are a special type of exception. Since they are
+ raised when something has gone seriously wrong with the system, they can not
+ be customized.</div>
+ </li>
+</ul>
+<p>If you do not need this feature, set this pointer to NULL to avoid undesired
+ results.</p>
+<p><font size="4"><a name="IRQLoweringtype"></a>5.3. IRQ lowering</font></p>
+<p>Every IRQ will be automatically lowered once it has been attended. User selectable IRQ lowering type has been removed.</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="FunctionReference"></a><strong><font color="#FFFFFF"> <font size="5">6.
+ Function Reference</font></font></strong></font></td>
+ </tr>
+</table>
+<p>This is a brief description of the library functions. </p>
+<ul>
+ <li> For C/C++ programmers:
+ <p> - They are declared in fame.h to include in your C/C++ application. You
+ can take a look at the sample program included.</p>
+ </li>
+ <li> For Delphi programmers:
+ <p> - Copy fame.pas and fame.dll into your project's directory. Add fame.pas
+ to your project.</p>
+ </li>
+</ul>
+<p><br>
+ Remember that this is a brief overview. If you do not find answers to your questions,
+ contact me.</p>
+<p><br>
+ <font size="4"><a name="GeneralPurposeFunctions"></a>6.1. General Purpose Functions</font><br>
+</p>
+- <strong>void m68k_init (void)</strong>
+<hr size="1" noshade>
+<p>This function initialize the emulation library. Must be called before any other
+ function library.<br>
+</p>
+- <strong>unsigned m68k_reset (void)</strong>
+<hr size="1" noshade>
+<p>Resets the CPU. You must set up the memory map before call this function.</p>
+<p> Return values:</p>
+<blockquote>
+ <p> <strong>M68K_OK (0)</strong>: Success.<br>
+ <strong>M68K_RUNNING (1)</strong>: The function failures because the CPU is
+ running. Stop the CPU first.<br>
+ <strong>M68K_NO_SUP_ADDR_SPACE (2)</strong>: The CPU could not be resetted
+ because there is no supervisor memory map for opcode fetching.<br>
+ </p>
+</blockquote>
+- <strong>void m68k_emulate (int n)</strong>
+<hr size="1" noshade>
+<p align="justify">Starts the emulation and executes n clock cycles. This is the function you
+ have to call to execute 68000's code. The number of elapsed CPU cycles is the
+ lowest number equal or greater than n.</p>
+<p><br>
+- <strong>unsigned m68k_get_pc (void)</strong></p>
+<hr size="1" noshade>
+<p>Returns the current PC address. The value returned by this function does not
+ have to be equal to the beginning of an instruction.<br>
+</p>
+- <strong>unsigned m68k_get_cpu_state (void)</strong>
+<hr size="1" noshade>
+<p>Returns information about the CPU current state. It could be called at any
+ time to retrieve interesting and useful information about the CPU state.</p>
+<p>The data returned has the following format:</p>
+<blockquote>
+ <table width="100%" border="0">
+ <tr bgcolor="#666666">
+ <th scope="col"><font color="#FFFFFF">Bits</font></th>
+ <th bgcolor="#666666" scope="col"><font color="#FFFFFF">Meaning</font></th>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>0</td>
+ <td>Internal use. Should be zero.</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>1</td>
+ <td>Processing a group 0 exception (address error or bus error).</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>2</td>
+ <td>Double bus fault has happened.</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>3</td>
+ <td>Trace mode is being processed. </td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>4</td>
+ <td>Processing trace mode exception.</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>5</td>
+ <td>Processing bus error exception.</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>6</td>
+ <td>Processing address error exception.</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td>7</td>
+ <td>CPU stopped by the STOP instruction.</td>
+ </tr>
+ <tr bgcolor="#EEEEEE">
+ <td>8-31</td>
+ <td>Reserved for future use. Should be zero.</td>
+ </tr>
+ </table>
+</blockquote>
+<p> </p>
+- <strong>int m68k_fetch(unsigned address, unsigned memory_space)</strong>
+<hr size="1" noshade>
+<p>Fetches the word pointed by the specified address using the given memory space
+ from the fetch memory array. The memory space means the following:</p>
+<ul>
+ <li> Supervisor address space (<font size="2" face="Courier New, Courier, mono">M68K_SUP_ADDR_SPACE</font>)</li>
+ <li> User address space (<font size="2" face="Courier New, Courier, mono">M68K_USER_ADDR_SPACE</font>)</li>
+ <li> Data address space (<font size="2" face="Courier New, Courier, mono">M68K_DATA_ADDR_SPACE</font>)</li>
+ <li> Program address space (<font size="2" face="Courier New, Courier, mono">M68K_PROG_ADDR_SPACE</font>)</li>
+</ul>
+<p>Generally, you will want to fetch a word from a memory map joining two of those
+ primitives types. For example:</p>
+<blockquote>
+ <p>Supervisor Data Address Space (Supervisor & Data)</p>
+</blockquote>
+<p>To accomplish this, you have to use a bitwise OR operation: </p>
+<blockquote>
+ <p><font size="2" face="Courier New, Courier, mono">M68K_SUP_ADDR_SPACE | M68K_DATA_ADDR_SPACE</font></p>
+</blockquote>
+<p> Return value:</p>
+<blockquote>
+ <p> <strong>FFFFFFFFh</strong>: The address specified is out of bounds in the
+ given <br>
+ memory space.<br>
+ <strong>0000xxxxh</strong>: The fetched word.</p>
+</blockquote>
+<p><br>
+ <strong><font size="3"><a name="HardwareFunctions"></a></font></strong><font size="3"><font size="4">6.2
+ Hardware interrupt handling functions</font></font><br>
+</p>
+- <strong>int m68k_raise_irq (int level, int vector)</strong>
+<hr size="1" noshade>
+<p align="justify">This function allows you to generate a hardware interrupt. This event is external
+ to the CPU and generally activated by an external device. The possible values
+ for the parameter level are between 1 and 7, both inclusive.</p>
+<p>For vector the values are the following:</p>
+<blockquote>
+ <p> <strong>M68K_AUTOVECTORED_IRQ (-1)</strong>: Autovectored interrupt.<br>
+ <strong>M68K_SPURIOUS_IRQ (-2)</strong>: Spurious interrupt.<br>
+ <strong>0-255</strong>: Vector number.</p>
+</blockquote>
+<p>Return value:</p>
+<blockquote>
+ <p> <strong>M68K_OK (0)</strong>: Success.<br>
+ <strong>M68K_INT_LEVEL_ERROR (-1)</strong>: The function failures because
+ there is another interrupt activated at the given level.<br>
+ <strong>M68K_INT_INV_PARAMS (-2)</strong>: Invalid parameter values. The vector
+ value is not valid or the level is equal to zero.</p>
+</blockquote>
+<p><br>
+<strong>int m68k_lower_irq (int level)</strong></p>
+<hr size="1" noshade>
+<p>This function is used to deactivate an interrupt.</p>
+<p>Return value:</p>
+<blockquote>
+ <p> <strong>M68K_OK (0)</strong>: The interrupt has been deactivated successfully.<br>
+ <strong>M68K_IRQ_LEVEL_ERROR (-1)</strong>: The function failures because
+ the interrupt is not activated.<br>
+ <strong>M68K_IRQ_INV_PARAMS (-2)</strong>: Invalid interrupt level value.</p>
+</blockquote>
+<p><br>
+- <strong>int m68k_get_irq_vector (int level)</strong></p>
+<hr size="1" noshade>
+<p>Calling this function you will get the vector of a generated interrupt at the
+ given interrupt level.</p>
+<p>Return value:</p>
+<blockquote>
+ <p> <strong>> -1</strong>: Requested interrupt vector.<br>
+ <strong>M68K_IRQ_LEVEL_ERROR (-1)</strong>: The function failures because
+ the interrupt is not activated.<br>
+ <strong>M68K_IRQ_INV_PARAMS (-2)</strong>: Invalid interrupt level.<br>
+ </p>
+</blockquote>
+- <strong>int m68k_change_irq_vector (int level, int vector)</strong>
+<hr size="1" noshade>
+<p align="justify">It allows you to change the vector of a generated interrupt. Remember that
+ the interrupt must be already activated when you call this function.<br>
+ The possible values for vector are between 0 and 255, both inclusive.</p>
+<p>Return value:</p>
+<blockquote>
+ <p> <strong>M68K_OK (0)</strong>: Success.<br>
+ <strong>M68K_IRQ_LEVEL_ERROR (-1)</strong>: The interrupt at the given vector
+ was not activated.<br>
+ <strong>M68K_IRQ_INV_PARAMS (-2)</strong>: Invalid interrupt vector value.</p>
+</blockquote>
+<p><br>
+ <strong><font size="3"><a name="CPUContextFunctions"></a></font></strong><font size="3"><font size="4">6.3.
+ CPU context handling functions</font></font><br>
+</p>
+<p>These functions are intented for handling the CPU context.<br>
+</p>
+- <strong>int m68k_get_context_size (void)</strong>
+<hr size="1" noshade>
+<p>Returns the size in bytes of the CPU context.<br>
+</p>
+- <strong>void m68k_get_context (void *context)</strong>
+<hr size="1" noshade>
+<p align="justify">Fills the context pointed by the pointer with the current CPU context. You
+ must deserve memory space in order to allocate the CPU context.<br>
+</p>
+- <strong>void m68k_set_context (void *context)</strong>
+<hr size="1" noshade>
+<p>Allows you to set up the CPU context. The parameter is a pointer to the context
+ structure.<br>
+</p>
+- <strong>int m68k_get_register (m68k_register reg)</strong>
+<hr size="1" noshade>
+<p>Returns the value of the specified register. If the value of the reg parameter
+ is not valid, the function will return -1.</p>
+<p align="justify">Note that the value returned by the function when the register specified is
+ not valid (-1) is a valid 32-bit register value. This may be cause for concern.<br>
+</p>
+- <strong>int m68k_set_register (m68k_register reg, unsigned value)</strong>
+<hr size="1" noshade>
+<p>Sets the value of the specified register.</p>
+<p>Return values:</p>
+<blockquote>
+ <p><strong>M68K_OK (0)</strong>: Success.<br>
+ <strong>M68K_INV_REG (-1)</strong>: The register specified is not valid.</p>
+</blockquote>
+<p><br>
+ <strong><a name="TimingFunctions"></a></strong><font size="4">6.4. Timing functions</font></p>
+<p align="justify">These functions allows you to control the CPU cycles executed in the emulation.
+ This way, you can adjust the emulation speed. The <em>cycles_counter</em>
+ is the variable used in the library to count the CPU cycles. For each calling
+ to function <em>emulate</em>, the executed CPU cycles are added to <em>cycles_counter</em>.<br>
+</p>
+<strong>- unsigned m68k_get_cycles_counter (void)</strong>
+<hr size="1" noshade>
+<p>Returns the current value of the <em>cycles_counter</em>.<br>
+</p>
+- <strong>unsigned m68k_trip_cycles_counter (void)</strong>
+<hr size="1" noshade>
+<p>Returns the current value of the <em>cycles_counter</em> variable and resets
+ it to zero.</p>
+<br>
+- <strong>unsigned m68k_control_cycles_counter (int n)</strong>
+<hr size="1" noshade>
+<p>If the parameter <em>n</em> is equal to zero, the function returns the <em>cycles_counter</em>.<br>
+ Otherwise, it returns the <em>cycles_counter</em> resetting it to zero.<br>
+</p>
+- <strong>void m68k_release_timeslice (void)</strong>
+<hr size="1" noshade>
+<p align="justify">Calling this function you will request the CPU to finish its execution as soon
+ as possible. The premature exit will be reflected in the <em>cycles_counter</em>.<font size="4"><br>
+ </font></p>
+<p>- <strong>void m68k_add_cycles (int cycles)</strong></p>
+<hr size="1" noshade>
+<p align="justify">Call this function when you want to increase the clock cycles counting (<em>cycles_counter</em>
+ variable).<br>
+ This function could be useful when emulating systems equipped with DMA capabilities,
+ keeping track of how many clock cycles the CPU was frozen by any device doing
+ a DMA operation.<br>
+</p>
+<p> - <strong>void m68k_release_cycles (int cycles)</strong></p>
+<hr size="1" noshade>
+<p>Call this function when you want to decrease the clock cycles counting (<em>cycles_counter</em>
+ variable).</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="MultiCPU"></a><font color="#FFFFFF"><strong> <font size="5">7.
+ Multi-CPU systems</font></strong></font></font></td>
+ </tr>
+</table>
+<p align="justify">Emulating multiple 68000 processors is fairly simple. If you want to emulate
+ more than one 68000 processor, you have to set up a CPU context and a memory
+ map for each one (see <a href="#MemoryMapExample">memory map example</a>).</p>
+<p>For example, you would do this:</p>
+<blockquote>
+ <p><font size="2" face="Courier New">struct M68K_CONTEXT my_contexts[NUMBER_OF_PROCESSORS];</font></p>
+ <p> <font size="2" face="Courier New">for (int i = 0; i < NUMBER_OF_PROCESSORS;
+ i++)<br>
+ {<br>
+ m68k_set_context(&my_contexts[i]);<br>
+ m68k_emulate(100);<br>
+ m68k_get_context(&my_contexts[i]);<br>
+ }</font></p>
+</blockquote>
+<p>Try to compensate the overhead due to the copying of the contexts emulating
+ the CPUs in large timeslices.</p>
+<p>FAME is non-reentrant so you cannot multi-thread several processors. If you
+ need FAME running in this way, contact me.</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="HelpfulTips"></a><strong><font color="#FFFFFF"> <font size="5">8.
+ Helpful tips</font></font></strong></font></td>
+ </tr>
+</table>
+<p align="justify"> - It is recommended to use built-in memory handlers as much as possible because
+ they should be much faster than others coded into high level languages.</p>
+<p align="justify"> - Use timeslices as large as possible because this way you will reduce the overhead
+ produced by the entry and exit code of the library.</p>
+<p>- Try to avoid context swapping. It will reduce performance notably.</p>
+<p align="justify"> - It is a good idea to call the <em>emulate</em> function with a variable
+ number of cycles instead of a fixed one. Keep track of how many cycles overflowed
+ from the last call to <em>emulate</em> and subtract them in the next calling:</p>
+<blockquote>
+ <p> <font size="2" face="Courier New">#define CPU_TIMESLICE 100</font></p>
+ <p><font size="2" face="Courier New"> cpu_context.cycles_counter = 0;<br>
+ while(!done)<br>
+ {<br>
+ if (cpu_context.cycles_counter < CPU_TIMESLICE)<br>
+ {<br>
+ m68k_emulate(CPU_TIMESLICE
+ - cpu_context.cycles_counter);<br>
+ }<br>
+ cpu_context.cycles_counter -= CPU_TIMESLICE;<br>
+ }</font></p>
+</blockquote>
+<p align="justify">- Library routines were designed with accuracy and speed in mind. Use them
+ as much as possible in order to reach a fast and accurate emulated system.</p>
+<p align="justify">- The object code contains many symbols for program relocation. Strip your executable when you are done. </p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="Troubleshooting"></a><strong><font color="#FFFFFF"> <font size="5">9.
+ Troubleshooting</font></font></strong></font></td>
+ </tr>
+</table>
+<p align="justify">This section tries to help you to get the library working correctly. I hope
+ you find this section useful.</p>
+<p align="justify"> - Remember to call <em>init</em> function before any other function library.
+ It initialize the library setting up the emulator.</p>
+<p align="justify"> - You must call <em>reset</em> function before starting the emulation in order
+ to get the library working appropriately.</p>
+<p align="justify"> - Set up your memory map before reset the CPU. The reset function look up
+ the vector table.</p>
+<p align="justify"> - Ensure that the CPU context has been set correctly after the calling to
+ <em>set_context</em>.</p>
+<p align="justify"> - Check if memory maps are well-constructed. Every memory region must be 4
+ KB aligned. This is a common pitfall.</p>
+<p align="justify">- Check if your emulated processor is accessing memory correctly specially
+ when you have to use memory handling functions. Take a look at the <a href="#Memoryhandling">Memory
+ handling section</a> if you are having problems in this point.</p>
+<p align="justify">- Make sure to set <em>reset_handler</em>,<em> iack_handler</em> and <em>icust_handler</em>
+ to NULL if you are not using these features. It would be a good idea to set
+ every byte of a new context to zero to avoid any problem.</p>
+<p align="justify">- Remember to set every handler not used in the array of function pointers
+ (<em>icust_handler</em>) to NULL to avoid undesired results.</p>
+<p align="justify">- Remember to include <em>fame.h</em> in any C module that use FAME. This header
+ file is subject to change in future versions.</p>
+<p align="justify">- Make sure to instruct your compiler configuration to treat enum types as
+ 32-bit ints when using <font size="2" face="Courier New">m68k_get_register</font>
+ and <font size="2" face="Courier New">m68k_set_register</font> functions.</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="KnownBugs"></a><strong><font color="#FFFFFF"> <font size="5">10.
+ Known bugs</font></font></strong></font></td>
+ </tr>
+</table>
+<p align="justify"> - The bit I/N (specific information about the processor activity) saved on
+ the supervisor stack when an address or bus error happens is not calculated
+ and its value is fixed to one (instruction). This tiny detail will be implemented
+ in future versions if needed.</p>
+<p> </p>
+<table width="100%" border="0" cellspacing="1" cellpadding="1">
+ <tr>
+ <td bgcolor="#000000"><font size="4"><a name="SpecialThanks"></a><strong><font color="#FFFFFF"> <font size="5">11.
+ Special thanks</font></font></strong></font></td>
+ </tr>
+</table>
+<p align="justify">Many thanks go out to those who helped me out with this library or contributed
+ to the project in any form in no special order. </p>
+<p align="justify">- <em>Chui</em> for his invaluable work to get this thing up into his NeoGeo
+ emulator (<a href="http://chui.dcemu.co.uk/neo4all.html">Neo4All</a>) and for helping me to fix loads of errors.<br>
+ - <em>Bart Trzynadlowski</em> (<a href="mailto:trzynadl@unr.nevada.edu">trzynadl@unr.nevada.edu</a>)
+ for his notes about 68000 undocumented behavior.<br>
+ - <em>Julio César Álvarez Acosta</em> (<a href="mailto:julio_a_a@yahoo.es">julio_a_a@yahoo.es</a>)
+ for his help to build the import library.<br>
+ - <em>Richard Hollstein</em> for let me know that memory handling functions
+ were not documented in previous releases.<br>
+ - <em>Jorge Cwik</em> for figuring out the algorithm to calculate the exact number of cycles in DIV instructions. <br>
+ - <em>Neill Corlett</em> for his excellent Starscream 680x0 emulation library
+ which give me a lot of understandings and ideas on CPU emulation.<br>
+ - <em>Stéphane Dallongeville</em> for Gens (probably the best Genesis/Mega
+ Drive emulator ever programmed) and for giving me his opinion about several
+ aspects of 68000 emulation.<br>
+ - <em>BlackAura</em> and <em>Ian Micheal</em> for telling me about the high
+ level emulation (HLE) feature.<br>
+ - <em>Juan Carlos Hernández Martín</em> (<a href="mailto:jmartin@uax.es">jmartin@uax.es</a>)
+ for his interest in this project.<br>
+ - <em>Antonio García Guerra</em> for his great book <em>Sistemas Digitales</em>.<br>
+ - The creators of the 68000 microprocessor, because without their work nothing
+ of this might be a reality.<br>
+ <br>
+ Thank you too! for your interest in the library. If you have any suggestions,
+comments or contributions do not hesitate to get in contact with <a href="mailto:oscar@m68k.com?subject=FAME">me</a>.</p>
+<p align="justify">Have a nice day!</p>
+</body>
+</html>