M65816: Portable 65816 CPU Emulator
Version 0.2 -- May 13th, 1996
Written and (C) 1996 by Joshua M. Thompson

-----------
LEGAL STUFF
-----------

You can use this code in non-commercial products so long as you give me credit
in the program and/or its documentation. For commercial use, please contact me
for written permission.

------------
CONTACT INFO
------------

I can be reached via Internet email as invid@optera.com, and sometimes on
IRC (EFnet) as LrdRayden.

The latest versions of this code will be made available through my emulation
software page. The URL is http://www.optera.com/~invid/emulators/

------------
INTRODUCTION
------------

This emulator is the result of my work on an Apple IIGS emulator called XGS.
I am releasing it seperately for two reasons:

(1). Somebody else may find it useful.
(2). To get it debugged faster by having more people using it.

As is evident by the version number is this is a very, very, early release.
Consider it ALPHA code. The only unimplemented feature is decimal support
in the ADC and SBC macros...I'm still looking for some particularly slick way
to do it.

I have tested this code as much as I can. Emulation mode seems to work fine;
implanting this emulator into an Apple II+ emulator yielded a fully working
65816 II+. I have also traced the emulator as it boots a IIGS ROM inside of
a _very_ early version of XGS, and the results look good there too.

I have tried to make the code easy to understand. It is written using a set of
"micro-ops" implemented as C preprocessor macros. This has the advantage of
producing good clean code without the overhead of subroutine calls. The only
disadvantage is that it takes a LOT of time and memory to compile.

This emulator is no speed demon by any means. On my 166 MHz Pentium, a simple
idle loop (a NOP/JMP loop) averages around 1.6 MIPS. As I continue to develop
the code, I will hopefully be able to increase this quite a bit.

-----------------
CHANGES SINCE 0.1
-----------------

o The "duala" union has been expanded to allow access to high/low words. I
  have already optimized some code to use this feature, but there are more
  places it could be used.

o The PC and PB registers have been folded into a single PC union. This
  required some signifigant changes at several points in the code, but was
  necessary to allow native mode to function correctly (see below).

o Native mode outside of bank $00 should work now. It turns out a lot of
  my code (especially the O_* macros and the debugger) were using only the
  PC (w/o the PB) as the target address for memory accesses. Those bits
  of code now reference PC.A (part of the union mentioned above).

--------------
HOW TO COMPILE
--------------

You need to edit the Makefile to set the compile options and m65816.h to set up
the macros that interface with whatever emulator you're plugging this into.
After that you just type "make" and you'll end up with an object file called
"m65816.o" that you can link with your code.

This emulator takes a long time to compile (several minutes even on my P166).
Also you will probably need at least 16 MB free RAM+swap during the compile.

-------------
HOW TO USE IT
-------------

Your emulator should call M65816_reset() once at "power-up" to initialize the
65816 CPU to its default state. You then make a call to M65816_run() to start
the 65816. This call never returns.

Periodically the 65816 will call your emulator's update routine (as defined
by the E_UPDATE macro in m65816.h). The number of instructions between these
calls defaults to 10,000; you can change this by calling M65816_uperiod().

Memory access is done byte-by-byte using 24-bit addresses.  The routines in
your emulator which provide these functions are defined by the M_READ and
M_WRITE macros in m65816.h. Generally these will be routines which check for
memory-mapped I/O accesses and things like that. They should execute as quickly
as possible to avoid slowing down the 65816.

If you compiled with the DEBUG option, you can enable real-time execution
tracing by calling M65816_trace(1). It can be disabled again by calling
M65816_trace(0). I sometimes find it helpful to bind these two calls to
rarely used keypresses in my emulator so I can turn trace on and off during
testing. ^A to enable trace and ^B to disable it are what I use.

Finally, while your emulator has control, you can schedule several different
hardware exceptions with the 65816 through the routines M65816_reset(),
M65816_abort(), M65816_nmi(), and M65816_irq(). They will be handled right
before the next instruction is executed (note though that M65816_irq() may be
ignored if the 65816 is running with interrupts disabled).
