Porting the emulator to a new platform
--------------------------------------

The machine specific graphics / user interface sections are all kept
in separate files. Currently there are four files :-

1. atari_x11.c		File supporting X Windows
2. atari_svgalib.c	File supporting Linux with SVGALIB
3. atari_curses.c	File supporting System V Curses (not BSD Curses)
4. atari_amiga.c	File supporting CBM Amiga 1200

Only one of these files should be linked in at any one time. Each file
contains the following functions:-

Atari_Initialise()

	Initialises the graphical environment, create screen/window,
	allocate colours etc.

Atari_Exit()

	Tidies system up just before emulator finishes. Delete all
	allocated resources (screens, windows etc.)

Atari_PreUpdate ()

	Called just prior to the screen refresh. In the SVGALIB and
	Amiga version it is used to initialise pointers to the start
	of screen memory.

Atari_PostUpdate ()

	Called just after the screen has been finished. In the X11
	version it is used to copy the offscreen image onto the
	main window.

Atari_ScanLine ()

	Called for each scanline to be displayed.

Atari_Keyboard ()

	You might find the ways this is implemented a bit strange but I
	wanted to increase the chances of it working on non-ascii
	keyboards (not that I think its very likely).

Atari_Joystick ()

	Returns value of joystick and trigger. Joystick position is in
	bits 0-3 and trigger is in bit 4.

	Return 0x1f if the joystick is not available.

Atari_Paddle ()

	Returns value of paddle and trigger. Paddle position is in
	bits 0-7 and trigger is in bit 8.

	Return 0x100 if the paddle is not available.

Implementation Overview (Very Brief)
------------------------------------

	+-----------------+----------------+
	| monitor program |  O.S. Support  |
	|        +--------+------+         |
	|        |   6502 CPU    |         |
	|        |Emulation Layer|         |
	+--------+---------------+---------+
        |  RAM/ROM and Memory Mapped H/W   |
	+----------------------------------+

1. Monitor Program (monitor.c)

   Development debugging tool. Allows emulated system
   to be interogated.

2. O.S. Support (atari.c, atari_sio.c, atari_h_device.c)

   Support routines that allow the Emulated Operating
   system to talk to the host machines. These are
   implemented using a pseudo 6502 escape instruction.

   Support for other operating systems could be built
   into this section

3. 6502 CPU Emulator Layer (cpu.c)

   Access memory by calling routines within hardware layer.
   Not the fastest way of doing this, but it produces a
   compact flexible system that should be able to
   emulate other platforms.

4. Hardware Layer (atari_custom.c)

   RAM / ROM / DEVICES and memory mapped custom chips.

   Again support for other hardware systems could be inserted
   into this section.

Link Hardware and Operating System to CPU
=========================================

This emulator has been designed to cope with multiple 6502 based
computers. In order to add support for another computer you
need to implement a hardware emulation layer and link this into
the 6502 CPU module.

e.g. The Atari 800 is linked in by defining five routines :-

	UBYTE Atari800_GetByte (UWORD addr);

		Returns the byte at the memory address.

	UWORD Atari800_GetWord (UWORD addr);

		Returns the word at the memory address.

	void Atari800_PutByte (UWORD addr, UBYTE byte);

		Stores the byte at the memory address.

	void Atari800_Hardware (void);

		Called after every instruction to emulate
		the machines hardware.

	void Atari800_Escape (UBYTE code);

		Called when the CPU module encounters the
		special emulators additional ESC instruction.
		The opcode is 0xff and it takes a single
		immediate operand that contains a user
		defined value. This instruction is used to
		patch the operating system.

Each of these sections are linked to the CPU module at runtime
by assigning the addresses of the functions to the respective
CPU pointer functions.

	#include	"cpu.h"

	XGetByte = Atari800_GetByte;
	XPutByte = Atari800_PutByte;
	Hardware = Atari800_Hardware;
	Escape = Atari800_Escape;

The CPU module will now call the Atari800 specific function for all
memory accesses.

e.g. Switching between multiple systems.

	Set up and Patch required O.S. here

	switch (machine)
	{
		case Atari800 :
			XGetByte = Atari800_GetByte;
			XPutByte = Atari800_PutByte;
			Hardware = Atari800_Hardware;
			Escape = Atari800_Escape;
			break;
		case BBC :
			XGetByte = BBC_GetByte;
			XPutByte = BBC_PutByte;
			Hardware = BBC_Hardware;
			Escape = BBC_Escape;
			break;
		case CBM64 :
			XGetByte = CBM64_GetByte;
			XPutByte = CBM64_PutByte;
			Hardware = CBM64_Hardware;
			Escape = CBM64_Escape;
			break;
	}

Memory Types
------------

For the Atari 800 hardware, 64K of memory is allocated together with 64K
of memory attribute space. Every byte of emulated memory has an
associated attribute. Valid attributes are ROM, RAM and HARDWARE.

Writes to addresses with the ROM attribute are blocked by PutByte.
Reads and writes to addresses with the HARDWARE attribute are handled
as special cases by both PutByte and GetByte.
The RAM attribute allows both reads and writes to the specified address.

e.g.
	UBYTE	memory[65536];
	UBYTE	attribute[65536];

	UBYTE Atari800_GetByte (UWORD addr)
	{
		UBYTE	byte;

		if (attribute[addr] == HARDWARE)
		{
			switch (addr)
			{

				case HARDWARE_ADDRESS_1 :
				case HARDWARE_ADDRESS_2 :
				case HARDWARE_ADDRESS_x :
					byte = Special Code;
			}
		}
		else
		{
			byte = memory[addr];
		}

		return byte;
	}

Screen Generation
-----------------

Each scanline is processed separatly and composes of 384 pixels - enough
for a wide playfield.

There are several independent graphic elements may which overlap :-

	1. The normal playfield (3 bits) - each pixel may be one of :-

		a. Playfield 0
		b. Playfield 1
		c. Playfield 2
		d. Playfield 3
		e. Background

	2. Player 0 (1 bit)

	3. Player 1 (1 bit)

	4. Player 2 (1 bit)

	5. Player 3 (1 bit)

	6. Missile 0 (1 bit)

	7. Missile 1 (1 bit)

	8. Missile 2 (1 bit)

	9. Missile 3 (1 bit)

Provision must be made for collision detection. To do this each of the
384 pixels is represented using a 16 pixel that contains all the
above information. The 16 bit pixel is processed according to the
contents of PRIOR in order to determine the final pixel colour.

         f   e   d   c   b   a   9   8   7   6   5   4   3   2   1   0
	---------------------------------------------------------------
	 M3  M2  M1  M0  P3  P2  P1  P0 --- --- --- --- PF3 PF2 PF1 PF0

Example: Collision detection

	if (P0)
	{
		P0PF	|=	Pixel & 0x0f
		P0PL	|=	(Pixel >> 8) & 0x0f
	}

	if (M0)
	{
		M0PF	|=	Pixel & 0x0f
		M0PL	|=	(Pixel >> 8) &0x0f
	}

The GTIA modes can be generated directly from the 384 pixel buffer.

Unanswered Questions
--------------------

1. In collision detection, does a player collide with itself ?

   i.e.	Does P0PL bit 0 always contain a 0 or a 1. 
	Does P1PL bit 1 always contain a 0 or a 1. 
	Does P2PL bit 2 always contain a 0 or a 1. 
	Does P3PL bit 3 always contain a 0 or a 1. 

Test Programs for various Antic Modes
-------------------------------------

Mode 2: Atari Basic
Mode 3: SpeedScript
Mode 4: Fort Apocalypse Title Screen (MENU5)
Mode 5: Pacific Coast Hwy (White Lines above/below Title) (MENU13)
Mode 6: Star Raiders (Title Line) (MENU1)
Mode 7: Star Raiders (Galactic Map) (MENU1)
Mode 8: Kaboom Background (MENU21)
Mode 9:
Mode a:
Mode b: Asteroids (MENU1)
Mode c:
Mode d: Star Raiders (Star Field) (MENU1)
Mode e: Defender (MENU1)
Mode f: Collosus Chess (MENU4)

GTIA:	Behind Jaggi Lines! (MENU6)
