	IFND	AY_PLAYER_I
AY_PLAYER_I	SET	1

**
**
**	$VER: AYPlayer.i 1.004 (6.7.95)
**	(C) 1994,95 Patrik Rak - Raxoft
**	For more info, see Amadeus.S - player example
**	
**	

;	incdir	"include40/"

	IFND	EXEC_TYPES_I
	include	"exec/types.i"
	ENDC

PLAYAY_RELEASE_VERSION	EQU	1

;Header structure of AYModule
;note that in rptrs (except songdata - must exist) below, null means not used!

	STRUCTURE	AYModule,0
	ULONG	aym_recog	;ay mod recognition tag ('ZXAY')
	ULONG	aym_ID		;player ID (eg. 'AMAD')
	UBYTE	aym_version	;just for the user's evidence
	UBYTE	aym_reqversion	;this is the minimal player version required
				;read more about versions below
	RPTR	aym_internal	;special internal player included (pc-relative!)
	RPTR	aym_creator	;author of music (eg. 'Frantisek Fuka, orig. by Rob Hubbard',0)
	RPTR	aym_miscinfo	;other info (eg. 'Hexagonia, (C) 1991 Scorpion',0)
	UBYTE	aym_songs	;how many songs in songdata table (0 means one song:-)
	UBYTE	aym_firstsong	;which song should be played first (0=first song)
	RPTR	aym_songdata	;table of maxsong AYSong to fed the player with
				;no empty entries there!!!
	LABEL	aym_sizeof

;Partial mod header predefinition

AYMODHEADER	macro	;ID,<version,<reqversion>>
	dc.l	AYM_TAG
	dc.l	AYM_\1
	IFNC	'\2',''
	dc.b	\2
	ELSE
	dc.b	0
	ENDC
	IFNC	'\3',''
	dc.b	\3
	ELSE
	dc.b	AYM_\1_COMP
	ENDC
	endm

;aym_songdata points to table of such structures

	STRUCTURE	AYSong,0
	RPTR	ays_name	;name of the song (eg. 'Land of Confusion',0)
	RPTR	ays_data	;This is passed to ayp_initsound, points
	LABEL	ays_sizeof	;to AY player's custom song format...

;Misc stuff
	
AYM_TAG	equ	'ZXAY'		;Every module begins with this

;Officially supported players IDs

AYM_AMAD	equ	'AMAD'	;Amadeus by Frantisek Fuka - Fuxoft,
				;conv. by Patrik Rak - Raxoft 
AYM_AMAD_VER	equ	2	;current version
AYM_AMAD_COMP	equ	0	;current v. is backward compatible with version

AYM_EMUL	equ	'EMUL'	;orig. z80 code run by Raxoft emulator
AYM_EMUL_VER	equ	1
AYM_EMUL_COMP	equ	0

AYM_STRC	equ	'STRC'	;Orig. SoundTracker & Raxoft compiler,
AYM_STRC_VER	equ	1	;conv. by Patrik Rak - Raxoft
AYM_STRC_COMP	equ	0

AYM_ST11	equ	'ST11'	;Orig. SoundTracker 1.1 by ???
AYM_ST11_VER	equ	1	;conv. by Patrik Rak - Raxoft
AYM_ST11_COMP	equ	0

AYM_TEST	equ	'TEST'	;Reserved for special PlayAY Debugger

;To be done (perhaps)...

AYM_WHAM	equ	'WHAM'	;Well known Wham! 128 by ???
				;Not converted yet.

;Header of AYPlayer (both internal and external - disk or included in mod)
;Note that ayp_initsound and ayp_interrupt MUST exist.
;Other RPTR may contain null (and they usually do).
;Note that all RPTR functions can thrash any registers.

	STRUCTURE	AYPlayer,0
	;Next 8 bytes are not used in players included in modules.
	;So there is no need for NULL bytes... You can point by aym_internal
	;to ^ayp_AY-8 without any danger...
	;WARNING!!!: Players included in music have to be pc-relative !!!
	;Look at ZXAYTEST.S for how to implement simple custom reloc tables

	LABEL	ayp_next	;next player in the list (private!)
	STRUCT	ayp_RTS_code,4	;for the disk based players (moveq #0,d0, rts)
	LABEL	ayp_prev	;previous player in the list (private!)
	APTR	ayp_aptr	;must ptr to ayp_RTS_code
	;from here must be in module included players
	ULONG	ayp_ID		;player personal id
	UBYTE	ayp_version	;version of player
	UBYTE	ayp_compatible	;with what versions is this player backward compatible
	UBYTE	ayp_reqplayAY	;requested version of PlayAY. Must be equal!
	UBYTE	ayp_transpose	;how many tones do you want to be ay_freqs transposed
	APTR	ayp_AY		;set by AY emulator. "Out" there.
				;Note that AY freqsa,b,c are MC68000 words!
	APTR	ayp_channels	;channel assignment structure. Don't mess up!!!
	APTR	ayp_freqs	;precious .w freq table included in AY emulator
				;+2*ayp_transpose (0 = 13.75 Hz). See Amadeus.s
	RPTR	ayp_initplayer	;eg. alloc mem, etc. return error in d0.l (zero=ok)
	RPTR	ayp_endplayer	;whatever you need (free mem, etc.)
	RPTR	ayp_initsound	;in a0 you get pointer to your own song struct
				;so init yourself (interrupt will be called ASAP)
				;Also, d1 contains song number 0..aym_songs
				;Here you CAN set ayp_channels if you want.
	RPTR	ayp_endsound	;whatever you need to do... You do not have
				;to make AY silent, PlayAY does this...
	RPTR	ayp_interrupt	;this routine is called every 1/50 of sec.
			;load ^ayp_AY and exit. Return null if song should
			;continue, otherwise FadeLen in VBIs (JUST ONCE!!!)
	RPTR	ayp_nextpatt	;for those pattern based routines (bleurgh!)
	RPTR	ayp_prevpatt	
	LABEL	ayp_name	;see amadeus.s for example
		;null terminated string here, PLEASE!
	LABEL	ayp_origauthor	;see amadeus.s for example
		;null terminated string here, PLEASE!
	LABEL	ayp_convauthor	;see amadeus.s for example
		;null terminated string here, PLEASE!
	LABEL	ayp_sizeof

;Partial player header predefinition

AYPLAYERHEADER	macro	;ID,<version,<compatible>>
	moveq	#0,d0
	rts
	dc.l	*-4
	dc.l	AYM_\1
	IFNC	'\2',''
	dc.b	\2
	ELSE
	dc.b	AYM_\1_VER
	ENDC
	IFNC	'\3',''
	dc.b	\3
	ELSE
	dc.b	AYM_\1_COMP
	ENDC
	dc.b	PLAYAY_RELEASE_VERSION
	endm

;NOTE ABOUT VERSIONS: It's a little tricky, so read carefully and think for
;a while before implementing something.

;ayp_reqplayAY should be always set to the current PlayAY version. This
;version is assured to be increased only if the PlayAY<->AY Player interface
;changes dramatically, thus protecting before loading wrong AY player & crashing
;someones Amiga. Can be increased only by the official PlayAY maintainer (me).
;In such case, all official AY Players will be recompiled and distributed as well.

;ayp_version is standard version as presented in other programs. Clear.
;ayp_compatible says, with what versions is current version backward compatible
;aym_reqversion says, which OLDEST player is requested to play this music
;Thus, aym_reqversion must be less or equal than ayp_version and greater or equal
;than ayp_compatible.
;Now think why, then read on.

;aym_version is just to help user to recognize which version of the same module
;is newer than other one... Start with zero, than if you change something later,
;increase this number...

;Example: Let's say that you add some replayer-commands to your program because
;some new songs require them. So you should increase ayp_version and compile
;these new songs with new aym_reqversion=ayp_version.

;Example2: Let's say your song wants to use some commands which were presented
;first in version X. So you should change compile them with aym_reqversion=X,
;not with current maximum version!!!

;Example3: Let's say you have decided to change the player structure completely
;and the song structures as well. So, increase ayp_version, and set
;ayp_compatible=ayp_version. Also, compile the songs with the same number.

;So, in general, increase ayp_version as much as you want, no need for changing
;new musics. But increasing ayp_compatible may require musics to be recompiled
;(sometimes it is the purposes, but sometime it wouldn't be really necessary,
;but the player cannot tell...). So think few minutes about it, then go
;and write your own excellent AY Player.

;ZX lives forever...

	ENDC	;AY_PLAYER_I

