How to write a Super Game for the Coleco Adam

The steps are: make a memory map, learn the OS calls, plan the scheduling,
write a boot loader, write the main routine, write game logic, create
overlays with graphics and music for that overlay.  With experience these
can be done in order, but for novices, it is easier to do a little of each as
the game is developed.

Main memory

0000-1fff OS7 ROM (8k)
2000-7fff RAM area

7000      ColecoVision cartridge ram area
7020-702a Sound data areas
702b      User RAM (total of 962 bytes including stack)
73b9      Top of stack (grows downwards)
73ba-73c2 Pascal entry parameter passing area
73c3-73ff Display, Joystick, Timer areas
7fff       Top of stack
8000-8bff Main: Vectors, game start, background loading routines (3k)
9000-bfff Overlay 3: Game logic (4k) plus Level 1 (8k)
a000-bfff Overlay 5, 7: Level 3, 5 (8k)
c000-dfff Overlay 4, 6: Level 2, 4 (8k)
c800 Overlay 1: Boot block -- initial title, and loader for main line
d390-ffff Full EOS and file buffers
e000-ffff EOS with no file handling buffers
f400-ffff EOS AdamNet low level device drivers only


Video memory

MODE_1 command does:
0000 Pattern generator table
1800 Pattern name table
1b00 Sprite attribute table
2000 Pattern color table
3800 Sprite generator table

Important Library calls

Set Video Mode (HGR/TEXT)
Set Interrupt Handler (NMIHANDLER)
Start Background Music (BGPLAY)
Sound effect (PLAYEFFECT)
Reading the joysticks (READJOYSTICK)
Debouncing the joysticks (JOY())

Important OS7 calls

GAME_OPTIONS	- Display the standard game options screen
MODE_1		- Set the display to graphics mode 1
LOAD_ASCII	- Load the ASCII character set font into the VDP

INIT_TABLE	- Initialize the VDP table location (color, pattern, sprite...)
GET_VRAM	- Read entries from the VRAM table into Z80 RAM
PUT_VRAM	- Write entries to the VRAM table from Z80 memory
WR_SPR_NM_TBL	- Write the sprite name table

WRITE_REGISTER	- Set a VDP register
READ_REGISTER	- Read the VDP status
WRITE_VRAM	- Write Z80 RAM to VRAM
READ_VRAM	- Read VRAM into Z80 RAM buffer
FILL_VRAM	- Fill VRAM with data

PUT_FRAME	- Place a rectangular character based object on the screen
GET_BKGRND	- Backup a character based rectangular object from the screen

POLLER		- Selective check the joystick for instructions

INIT_TIMER	- Initialize the timers
SET_SIGANAL	- Set a timer in the timer table
TEST_SIGNAL	- Test a timer to see if it has gone off
TIMER_MAN	- Timer manager (called during VDP interrrupts)

SOUND_INIT	- Initialize the sounds table
PLAY_IT		- Start a sound track
SOUND_MAN	- Sound manager (called during VDP interrupts)
ALL_SOUNDS_OFF	- Silence

RAND_GEN	- Pretty good random number generator

Timing Sequence

All overlays are loaded, with as short a lag between user interaction as
possible to keep the game going.

Time	| Screen	| Loading	| Address	| Block
in	|		|		|		| Number
seconds	|		|		|		|
-------------------------------------------------------------------
0	| Blank		| Cold start	| C800		| 0
1	| Welcome	| Main (3k)	| 8000		| 1
2	|		|		| 8400		| 2
3	|		|		| 8800		| 3
-------------------------------------------------------------------
4	| Title screen	| Overlay 3(12k)| 9000		| 4
5	| 		| (level 1)	| 9400		| 5
6	|		|		| 9800		| 6
7	|		|		| 9c00		| 7
------------------------|               |--------------------------
8	| Logo screen	|		| a000		| 8
9	| 		|		| a400		| 9
10	|		|		| a800		| 10
11	|		|		| ac00		| 11
------------------------|               |--------------------------
12	| Select options|		| b000		| 12
13	|		|		| b400		| 13
14	|		|		| b800		| 14
15	|		|		| bc00		| 15
-------------------------------------------------------------------
16	| Game start	| Overlay 4(8k)	| c000		| 16
17	|		|		| c400		| 17
				...
23	|		|		| dc00		| 23
-------------------------------------------------------------------

Super Game Tape contents

Blocks	Size	Description
0	1k	Boot block
1-3	3k	Main game
4-15	12k	Game logic + level 1 (graphics + sound)
16-23	8k	level 2 (graphics + sound)
24-31   8k	level 3 (graphics + sound)
32-39	8k	level 4 (graphics + sound)
40-47	8k	level 5 (graphics + sound)

Boot loader
----------------------------------------------------------------------
	ORG	0c800h

Start:	LD	A,B
	LD	(DEVICE_ID),A

	;Set up initial display

	;Now load 3K into 8000-8bffh
	LD	A,(DEVICE_ID)
	LD	BC,0
	LD	DE,1	;Block 1
	LD	HL,8000h
	CALL	READ_BLOCK

	LD	A,(DEVICE_ID)
	LD	BC,0
	LD	DE,2	;Block 2
	LD	HL,8400h
	CALL	READ_BLOCK

	LD	A,(DEVICE_ID)
	LD	BC,0
	LD	DE,3	;Block 3
	LD	HL,8800h
	CALL	READ_BLOCK

	LD	A,3		;OS7 + 24k on lower bank and 32k intrinsic
	OUT	(7fh),A

	LD	A,(DEVICE_ID)
	LD	B,A		;Entry point
	RST	0		;Run
;Data section

	END
----------------------------------------------------------------------

Game header

----------------------------------------------------------------------
	ORG	8000h

; Tables
	DB	055h,0aah	;Magic number
	DW	SPRITE_NAME	;Pointer to sprite name table
	DW	SPRITE_ORDER	;Pointer to sprite order table
	DW	SPRITE_WORKING	;Pointer to WR_SPR_NM_TBL work area
	DW	CONTROLLER_BUFFER	;Pointer to hand controler input area
	DW	MAIN_PROG	;Entry point to game
; Vectors
	JP	RST08		;Restart 8
	JP	RST10		;Restart 10h
	JP	RST18		;Restart 18h
	JP	RST20		;Restart 20h
	JP	RST28		;Restart 28h
	JP	RST30		;Restart 30h
	JP	MASK_INT	;Maskable interrupt (used by spinner)
	JP	VDPINT		;NMI interrupt (used by VDP 60 times per second)
; Title screen name
	DB	'ADAMCON 11',1eh,1fh
	DB	'/PRESENTS ADAM NEWS NETWORK'S'/1999'
	;1dh is copyright symbol
	;1eh,1fh is trade mark symbol
DEV_ID	DB	8	;Default DEVICE_ID but check for B from boot block

OCT_PTR	DW	OVERLAY_CONTROL_TABLE	;Pointer to the overlay control table

;Overlay control table must be in the first 1k of the main routine
OVERLAY_CONTROL_TABLE
	;Format: WORD memory_address, WORD start_block, BYTE block_count
;Overlay 3: game logic, level 1 graphics+sound
	DW	9000h	;address
	DW	4	;block 4-15
	DW	12	;12k
;Overlay 4: level 2 graphics+sound
	DW	0c000h	;address
	DW	16	;block 16-23
	DB	8
;Overlay 5: level 3 graphics+sound
	DW	0a000h	;address
	DW	24	;block 24-31
	DB	8	;8k
;Overlay 6: level 4 graphics+sound
	DW	0c000h	;address
	DW	32	;block 32-39
	DB	8	;8k
;Overlay 7: level 5 graphics+sound
	DW	0a000h	;address
	DW	40	;block 40-47
	DB	8	;8k

;Overlay tape interface
; TEST_TAPE: Output -- Z means idle
; ABORT_TAPE:  None
; LOAD_OVERLAY: Input -- A=overlay 1..n
; WRITE_OVERLAY: Input -- A=overlay 1..n
	INCLUDE	TAPEINTF
;Overlay tape mamager
; INIT_TAPE: None
; TAPE_MANAGER
	INCLUDE	DDPMGR

; Implementation of restart vectors
RST08	EQU	TEST_TAPE
RST10	EQU	ABORT_TAPE
RST18	EQU	LOAD_OVERLAY
RST20	EQU	WRITE_OVERLAY

RST28
RST30
	RET

MASK_INT
	RETI	;Used with spinner: steering wheel, 
		;super action, roller controller
VDPINT
	RETN	;Non maskable interrupt used for:
		;background music, processing timers, defered VDP write
		;sprite order processing

;Main program entry
;Entry: B device number of the boot device
	LD	A,B
	LD	(DEV_ID),A
	
;Here is where the application begins
	CALL	GAME_OPT
;Endless loop
	JP	$

	END
-----------------------------------------------------------------------


