XGS: The Apple IIGS emulator for Unix/X
Version 0.28 -- June 21st, 1996 (Live from MachHack :-) )
Written and (C) 1996 by Joshua M. Thompson

*** EXPERIMENTAL RELEASE -- MAY NOT BE STABLE ***

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

You may distribute this program so long as you do not sell it (selling a CD
of freeware and shareware does not qualify as selling it). All I ask is that
you keep this file intact, and that you include the source code.

Portions of XGS are based on works written by Kent Dickey
(kentd@hpcuhe.cup.hp.com). Thanks, Kent!

Apple, IIGS, Apple IIGS, and GS/OS are registered trademarks of Apple
Computer, Inc.  All rights reserved.

------------
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 the XGS
home page. The URL is "http://www.optera.com/~invid/emulators/XGS/".

There is also a mailing list for discussing XGS issues. You can subscribe
by sending mail to "majordomo@optera.com" and including the word "subscribe"
on a line by itself in the body of the letter. I strongly suggest you
subscribe to it if you're going to use XGS.

------------------
CHANGES SINCE 0.20
------------------

o Added -DPRIVATE_CMAP to control whether or not a private colormap is
  allocated. This allows XGS to run under MkLinux on a Power Macintosh.

o Endianness problem with super high res color has been fixed.

o The CPU emulator now counts cycles. It is (hopefully) an accurate count.

o VBLs are now emulated using a 100 Hz interval timer, with the VBL being
  triggered at half that frequency (50 Hz).

o XGS's window now includes a couple of lines of status information, updated
  once per second. A lot of it is for my debugging, but it does display a
  couple of useful items: namely the target speed the emulator would like to
  achieve (1.0 or 2.5 MHz, depending on the CYA speed register setting), and
  the actual speed it is achieving. My P166 benches in the 2.0 - 2.7 MHz
  range, depending on what I'm doing in XGS at the time.

o Memory map handling substantially rewritten. It now subdivides _all_ memory
  into pages, instead of just banks $00/$01/$E0/$E1. Fault handlers are gone;
  I/O space and shadowing are the only special cases and they are handled via
  bit flags in the memory page structures. Also I keep an array of long ints
  which mark which bytes in the slow RAM banks have been modified; each bit
  represents eight bytes (which is nice because then one long word = one page
  of 256 bytes).

o Shakey but sorta working support for classic Apple II sound. It sounds a bit
  distorted, and pops a lot, but it does work. Compile with -DUSS_SOUND to get
  the sound driver.

o The video code now picks the correct visual to use for the chosen display.
  This doesn't seem to matter on XFree86 systems, but t apparently does on
  others.

o The video code is in the early stages of an "update only what changed"
  rewrite using the "memory modified" bitmaps in the new memory manager code.
  Currently only text mode uses this, and it's not very efficient code yet.

------------------
CHANGES SINCE 0.10
------------------

o Due to popular demand, 8-bit color X servers are now supported.

o XGS _should_ work now if you give it a ROM 01 image padded to 256 KB.

o Super high-resolution graphics supported though not fully tested. It _should_
  work in all modes including 640x200, 320x200, and 320x200 fill mode.

o Created virtual ProDOS block devices in slots 5 and 7. Each can support two
  disk image files up to 32 MB each. This means it's now possible to _boot_
  stuff on XGS (at least ProDOS 8 stuff). You can even write to the virtual
  disks!

o The arrow keys are now recognized by the emulator.

o You can now enter the Desk Manager menu (Control-Command-Escape), though
 it's still acting a bit flakey sometimes.

o Added the utils/ subdirectory. There's lots of neat stuff here for handling
  the XGS ".img" files and for viewing and rebuilding the XGS font files.

o In all bit depths, we now open a private colormap and allocate the colors
  using XAllocColor(). This was necessary for 8-bit mode, and for the other
  modes it should fix the problem XGS had on X servers that specified the RGB
  color levels in a different order than what XGS was using.

o Video handling substantially overhauled. The emulator no longer traps video
  memory accesses; instead, the video screen is simply periodically redrawn.
  Some things run quite a bit faster as a result.

o High-resolution graphics glitch fixed; the right border is no longer
  partially overwritten.

o Mixed text/graphics modes now work in 40 or 80 columns.

o Fixed some of the more annoying font glitches. The mousetext 'Z' character
  is now a right-justified vertical line as it should be, and the "1" and "l"
  (lowercase L) characters are now centered in the font matrix instead of
  being left-justified.

o The Makefiles have been modified to work on non-GNU versions of make and ar.

o Reorganized the link commands in the Makefile to specifiy the libraries last
  on the command line. It worked fine for me the old way but not for some other
  people.

o Some key symbols specific to X11R6 were replaced with symbols present on all
  versions of X11. This should allow XGS to compile on systems that use X11R5.

o 65816 emulation should be a faster now. Also some bugs with IRQs and NMIs
  were fixed (they weren't pushing the proper PC value onto the stack, plus
  the RTI instruction was incorrectly incrementing the value it pulled back
  from the stack. Used together they work fine, but some code in ProDOS 8
  apparently sets up a fake IRQ stack frame and does an RTI, and this code
  didn't work with the old 65816 emulation).

o Skeletal support for emulating the Ensoniq DOC has been added. It doesn't
  really _do_ anything yet other than allow reads and writes to the DOC and
  sound RAM (basically just enough to get the darn thing to work properly).

o VBL and quarter second interrupts are now supported...I think. Haven't fully
  tested them so I can't be 100% sure.

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

XGS is a program to emulate a ROM 03 Apple IIGS on a Unix system under
X Windows. This is an alpha version; many features are not implemented yet,
and many others don't work exactly like they should.

The following features are currently implemented:

o CPU emulation
o Memory map emulation
o Text, low resolution, double low resolution, high resolution, and super
  high resolution graphics
o ADB keyboard
o Clock chip
o Battery RAM
o ProDOS block devices in slots 5 and 7

The following features are NOT currently implemented:

o Slot 6 (5.25" drive) emulation. This needs to be emulated at the hardware
  level to support all those old games -- I can't "cheat" like I did with
  slots 5 and 7
o Double high resolution graphics
o Sound (neither standard Apple II nor Ensoniq)
o ADB mouse
o Serial ports
o Many, many other minor things.

Also the following bugs/glitches are known to exist:

o GS/OS still won't load (at least not System Disk 6.0.1)
o The IIGS sometimes crashes on exit from the Desk Manager menu
o Still need to implement decimal mode ADC/SBC (apparently the SysUtils on
  8-bit system 3.2 uses this, because it gives me warnings about it and
  eventually crashes)
o The clock chip emulation doesn't work right, so the IIGS can't get the
  current date and time, and battery RAM changes aren't saved.

-------------------
SYSTEM REQUIREMENTS
-------------------

o A 90 MHz Pentium or better (it will run on slower, but it'll be virtually
  unusable.)

o Some sort of Unix operating system. I run Linux 1.3, so that is the only
  platform it has been tested on. However, it should compile with little or
  no modification on virtually any Unix operating system (FreeBSD, etc.)

o An X server running in 8, 16, or 24-bit mode. Since the emulator window is
  640x480 pixels, a screen resolution of at least 800x600 is recommended.

o For sound: Unix Sound System (USS) and a USS-supported sound card.

o A copy of the ROMs from a ROM 01 or 03 Apple IIGS (see "How to Use It" below).

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

The Makefiles were originally written for GNU make, with GNU CC, and GNU ar
and GNU sed (typical Linux setup, in other words). I have tried my best to make
them universal, but sometimes I slip up...so please let me know if you find any
places where I am GNU-centric.

Simply edit the top-leve Makefile to suit your system, and type "make". Then
watch it build. If you get any errors, please send me email telling me what
your operating system configuration is. Even better, if you can make it
compile, tell me what you did so I can intergrate the changes into the next
version of XGS.

You may want to make the utilities too; type "make util" to do this.

There are only four Makefile options you need to worry about. All three are
for the CFLAGS line:

-DLSB_FIRST	Define this if your system's CPU is little-endian, like
		the 386/486/Pentium. If your CPU is big-endian (680x0,
		PowerPC, etc), leave this undefined.

-DMITSHM	Enables X11 shared memory usage. Use this if you can; it's
		quite a bit faster than non-shared mode.

-DTRUECOLOR	Build XGS for a TrueColor (24/32-bit) server. If this is
		_not_ defined, it will build for a 16-bit color server.

-DDEBUG		Enables debugging code.  Currently this does nothing but
		compile in support for trace mode in the 65816 emulation.

One final note. The Makefile for the 65816 CPU emulator deliberately tacks
a "-O0" onto CFLAGS. This is to force optimization _off_ for gcc, because if
you leave it on, gcc will eventually run out of memory trying to compile
dispatch.c (on my system it died around the 95 MB (!) mark). This is apparently
a really stupid problem with gcc, and if anyone can tell me a better way to get
around it (or even better, find the bug and submit a bug report to the gcc
team) I'd really appreciate it.

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

You will need a ROM image file to make XGS run. This should be a 256 KB image
file; it can either be a straight dump of a ROM 03 IIGS's ROMs, or a dump of
a ROM 01 IIGS's ROMs preceded by 128 KB of zeros to pad the file out to 256 KB.

You can get the ROMs from a IIGS by saving them out in 32 KB chunks in
AppleSoft BASIC. Boot a ProDOS 8 disk and get into BASIC, then do the
following:

] CALL -151
* 00/800 < xx/0000.8000M
* ^C (control-C)
] BSAVE xx0000,A$800,L$8000
] CALL -151
* 00/800 < xx/8000.FFFFM
* ^C (control-C)
] BSAVE xx8000,A$800,L$8000

Note that "xx" is the bank number. For a ROM 03 there are four banks: FC, FD,
FE, and FF. For a ROM 01 there are two: FE and FF.

Once youv'e done this you should end up with several 32 KB files. There will
be four such files for a ROM 01, or eight for a ROM 03. Now you have to get
them over to your Unix system. You have several options:

o Use your favorite IIGS terminal program to transfer the files by
  serial cable or modem.
o Use a Macintosh to read the files from the Apple II-formatted disk
  and save them to an MS-DOS formatted floppy. Then mount the MS-DOS
  disk on your Unix system and copy the files.

There's simply no other way to do it. The IIGS's 800k disks are not readable
at all in any drive but an Apple drive. Even if you could get around that, no
Unix system that I know of can read the ProDOS filesystem (and the MS-DOS FST
for GS/OS is read-only, so you couldn't make the MS-DOS disk on the IIGS).

Once you have the files on your Unix system, execute the following ($ is the
shell prompt):

(for ROM 01):

$ dd if=/dev/zero of=filler bs=1024 count=128
$ cat filler fe* ff* > xgs.rom

(for ROM 03):

$ cat fc* fd* fe* ff* > xgs.rom

This will concatenate all the files together into a single image. The resulting
xgs.rom file should be exactly 262,144 bytes long. If it isn't then you messed
up somewhere...go back and try again.

If you don't have a real IIGS to get the ROMs from then you're on your own.
Apple owns the copyrights on the ROMs, so I can't legally give you a copy (nor
can anyone else). As a result you're probably not going to find them on an FTP
site anywhere.

I will repeat this one more time:

*** I CANNOT (AND WILL NOT) GIVE YOU A COPY OF THE IIGS ROM!! ***
*** SO DON'T SEND ME MAIL AND AND ME ABOUT IT. IT WON'T HELP. ***

Now that that's out of the way, let's move on to actually running the program.
The following four files must be in the same directory for XGS to run:

xgs		The XGS executable program
xgs40.fnt	The Apple II 40-column screen font
xgs80.fnt	The Apple II 80-column screen font
xgs.rom		The ROM image 
xgs.ram		The battery ram save file

If everything looks OK, just type "xgs" to start it up. You should a status
report printed as XGS starts up, and eventually the XGS window should appear
and you will be dumped into BASIC (because you don't have any boot disk images
yet -- more on that later). If not, then you have a problem. See
"Troubleshooting" below.

While XGS is running, there are four special keypress sequences you can use
to control the emulator:

Control-End		Does just that -- ends (quits) XGS.

Control-Home		Sends a Control-Reset to the emulator.

Control-PageUp		Turns on trace mode (if you conmpiled
			with -DDEBUG).

Control-PageDown	Turns off trace mode (if you compiled
			with -DDEBUG).

Most other keypresses are just passed on to the emulated IIGS to be interprted
by whatever program is currently running.

-----------------
USING DISK IMAGES
-----------------

XGS allows you to mount Unix files as Apple IIGS disks. These files (called
disk images) must be in a specific format for XGS to recognize them.

By default, XGS looks for the following disk image files at startup:

s5d1.img	Mounts on Slot 5, Drive 1
s5d2.img	Mounts on Slot 5, Drive 2
s6d1.img	Mounts on Slot 6, Drive 1
s6d2.img	Mounts on Slot 6, Drive 2
hd1.img		Mounts on Slot 5, Drive 1
hd2.img		Mounts on Slot 5, Drive 2

You can change these defaults using command line switches given to xgs on the
shell command line. For example:

xgs -s5d1 prodos.img

would start XGS, and mount the file "prodos.img" on slot 5, drive 1. You can
mount any arbitrary file in any of the six slot/drive combinations mentioned
above using these command line switches (-s5d2, -s6d1, etc).

Note that not all slots are created equal. Slots 5 and 7 are emulated hard
disk controllers; they can handle images of any size. Slot 6, however, emulates
the actual 5.25" disk hardware, and thus you can only handle a 5.25" disk
image (140 KB). Images of any other size cannot be mounted in slot 6.

XGS comes with several utilities (located in the utils/ subdirectory) to make
dealing with images easier. They are:

    dc2img <source file> <destination file>

	This program converts a Macintosh DiskCopy image file into an XGS
	image. If you have a Macintosh, you can use DiskCopy to create images
	of your IIGS disks, and then transfer those images to your Unix system
	and run them through this program to create XGS images.

	Apple usually distributes system software (such as GS/OS) as DiskCopy
	images as well.

    newimg <output file> <size in KB>

	Creates a new, blank image file of the specified size. The size can be
	anywhere between 16 and 32767 KB (32 MB).

    lockimg <image file>

	Write protects ("locks") an image file. When an image is locked, XGS
	will refuse to write to it; any write attempts will result in a
	"WRITE PROTECTED" error.

    unlockimg <image file>

	Write enables ("unlocks") an image file. Once an image is unlocked,
	it can be written to by XGS (including formatted).

Normally you would create a large virtual "hard disk" as "hd1.img", and have
XGS automatically mount this on slot 7, drive 1 at startup.

Note that as of version 0.20 there is no way to mount or unmount disks after
XGS is started, so it is not currently possible to install GS/OS onto a
virtual hard disk (GS/OS comes on six 3.5" disks, and there are only four
slot/drive combinations available that can handle images of that size -- and
one of those four must be used for the hard disk image itself)

---------------
TROUBLESHOOTING
---------------

If the XGS window doesn't appear, then the emulator probably couldn't start,
and you should read the startup output to figure out why.  You probably have a
missing file.

If the window appears and then disappears, then the emulator probably crashed.
Mail me a bug report. If you're really ambitious you can even try to debug it
yourself.

If the window appears but is blank, several things could be wrong.  You could
have XGS compiled for the wrong color depth (in which case you should see one
or more "BadMatch" errors printed after the XGS startup progress messages.)
In this case just fix your Makefile and rebuild XGS. Otherwise, something is
seriously wrong. Make sure you have LSB_FIRST set correctly in the Makefile.
If that doesn't help, you'll have to mail me a bug report.

-----------------
FUTURE DIRECTIONS
-----------------

My current list of priorities looks something like this:

o Make GS/OS load
o Implement the ADB mouse so you can actually _use_ GS/OS once it boots
o Count cycles in the 65816 emulator so I can start doing some accurate timing.
  This will be necessary for classic Apple II sound emulation.
o Use a 50/60 Hz interval timer and use _that_ to generate VBLs and the
  various interrupts (1/4 second, 1 second, etc). This way they'll always be
  accurate no matter how fast the 65816 emulator is actually running.
o Rewrite the slot 5 emulation to emulate a SmartPort, so that you can mount
  more than two disks on it. I'd like to support something like eight drives
  on that slot.
o Implement the slot 6 drive hardware (5.25" drives)
o Write more sound emulation
o Write double high resolution graphics emulation
