// -------------------------------------------------------------------------------------------------
// ac.h
//
// COPYRIGHT (C) SEGA OF AMERICA, INC. 1998
// All rights reserved.
//
// AICA driver control layer header
//
// Author: Ralph "Cooksey" Thomas
//
// Tabs: 4
//
// Rev	10/21/98	File Originated
//		04/28/99	Rev 1.75d4
// -------------------------------------------------------------------------------------------------

#ifndef _AC_H
#define _AC_H

#ifdef __SHC__
#include <actypes.h>
#include <Shinobi.h>
#include <sg_Chain.h>
#else
#include <ktypes.h>
#include <int.h>
#endif

// ------------------------------------------------------------------------------------------------
// Revision number
// ------------------------------------------------------------------------------------------------

#define AC_REVISION_NUMBER 				"1.75d4"

// ------------------------------------------------------------------------------------------------
// Build directives
// ------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------------------------------

// the aica sample rates
#define AC_44K_SAMPLE_RATE					 0	//	44100
#define AC_22K_SAMPLE_RATE					-1	//	22050
#define AC_11K_SAMPLE_RATE					-2	//	11025
#define AC_5K_SAMPLE_RATE					-3	//	5012
#define AC_2K_SAMPLE_RATE					-4	//	2506
#define AC_1K_SAMPLE_RATE					-5	//	1253
#define AC_626HZ_SAMPLE_RATE				-6	//	626
#define AC_313HZ_SAMPLE_RATE				-7	//	313
#define AC_156HZ_SAMPLE_RATE				-8	//	156

// the aica pan values
#define AC_PAN_LEFT							0
#define AC_PAN_RIGHT						31
#define AC_PAN_CENTER						15

// the highest tone bank slot (0-15)
#define AC_MAX_TONEBANK_SLOT				15

// the highest midi port (0-15)
#define AC_MAX_MIDI_PORT					15

// the highest midi channel (1-16)
#define AC_MAX_MIDI_CHANNEL					16

// the highest midi program change number (0-127)
#define AC_MAX_MIDI_PROGRAM_NUMBER			127

// maximum midi note number (0-127)
#define AC_MAX_MIDI_NOTE_NUMBER				127

// maximum midi velocity value
#define AC_MAX_MIDI_VELOCITY				127

// maximum midi velocity
#define AC_MAX_MIDI_VOLUME					127

// maximum midi velocity
#define AC_MAX_MIDI_PAN						127

// aica max volume and pan
#define	AC_MAX_VOLUME						15
#define	AC_MAX_PAN							31

// the aica loop flag values
#define AC_LOOP_ON							0xff
#define AC_LOOP_OFF							0x00

// acfile.c
#define AC_FILE_BOUNDRY_ALIGNMENT 			32

// other aica flag values
#define AC_GM_OFF							0x00		// GM mode off
#define AC_GM_ON							0xff		// GM mode on

// bank slots for general midi tone banks
#define AC_GM_INST_BANK_SLOT				0
#define AC_GM_DRUM_BANK_SLOT				1

#define AC_MTT_TABLE_OFF					0x00	// MTT table off

// midi commands
#define AC_MIDI_PROGRAM_CHANGE				0xc0	// midi program change message
#define AC_MIDI_CONTROL_CHANGE				0xb0	// midi control change message
#define AC_MIDI_NOTE_ON						0x90	// midi note on message
#define AC_MIDI_NOTE_OFF					0x80	// midi note off message
#define AC_MIDI_FULL_VOLUME					0x7f	// max volume
#define AC_MIDI_VOLUME_CC					0x07	// midi volume control change #
#define AC_MIDI_PAN_CC						0x0a	// midi panpot control change #
#define AC_MIDI_BANK_SELECT_CC				0x20	// bank select MSB control change #
#define	AC_MIDI_PITCH_CC					0xe0	// midi note pitch bend

// the driver commands
#define AC_CMD_OPEN_PORT	 				0x90
#define AC_CMD_CLOSE_PORT					0x91
#define AC_CMD_SET_PORT_SPEED				0x27
#define AC_CMD_SET_PORT_PITCH				0x98	
#define AC_CMD_SET_QSOUND_PAN				0x99	
#define AC_CMD_SET_VOLUME					0x96
#define AC_CMD_SET_PANPOT					0x97
#define AC_CMD_REQUEST_PORT_EVENT			0x92
#define AC_CMD_PORT_PLAY					0x93
#define AC_CMD_PORT_STOP					0x94
#define AC_CMD_MIXER_SET					0x95
#define AC_CMD_SET_TONE_BANK				0xa0
#define AC_CMD_OPEN_MIDI_PORT				0xa1
#define AC_CMD_CLOSE_MIDI_PORT				0xa2
#define AC_CMD_REQUEST_MIDI_PORT_PAUSE		0xa3
#define AC_CMD_REQUEST_MIDI_PORT_RESUME	0xa4
#define AC_CMD_REQUEST_MIDI_PORT_EVENT		0xa5
#define AC_CMD_MIDI_PORT_PLAY				0xa6
#define AC_CMD_MIDI_PORT_STOP				0xa7
#define AC_CMD_MIDI_PORT_VOLUME			0xa8
#define AC_CMD_MIDI_PORT_RESET				0xa9
#define	AC_CMD_MIDI_PORT_SENDMESSAGE		0xaa
#define AC_CMD_MIDI_PORT_SET_TEMPO			0xab
#define AC_CMD_SET_PORT_SAMPLE_RATE			0xac	
#define AC_CMD_INT							0x9e
#define AC_CMD_CDDA_VOLUME					0x35
#define AC_CMD_CDDA_PANPOT					0x36
#define AC_CMD_CDDA_MIXER					0x3e
#define AC_CMD_PORT_MULTIPLAY				0x9c
#define AC_CMD_PORT_MULTISTOP				0x9d
#define AC_CMD_LOAD_DSP_PROGRAM				0x9a
#define AC_CMD_LOAD_DSP_OUTPUT_MIXER		0x9b

// magic numbers
#define AC_BASE_OF_SOUND_MEMORY				(KTU32 *)0xa0800000
#define AC_INT_ARRAY_OFFSET					(0xe4/4)
#define AC_PORT_STATUS_FLAG					(0xe0/4)
#define AC_COMMAND_BUFFER_OFFSET			(0xd0/4)
#define AC_COMMAND_FLAG_OFFSET				(0xc8/4)
#define AC_PORT_CURRENT_READ_ADDRESS		(0xe8/4)
#define AC_NEXT_DRIVER_COMMAND_REGISTER		(0xf4/4)
#define AC_ARM_RESET_REGISTER				(volatile KTU32 *)0xa0702c00
#define AC_INT_ENABLE_REGISTER				(volatile KTU32 *)0xa07028b4 // 0x20 is enabled
#define AC_INT_PENDING_REGISTER				(volatile KTU32 *)0xa07028b8 // 0x20 hold pending
#define AC_INT_RESET_REGISTER				(volatile KTU32 *)0xa07028bc // 0x20 is cleared
#define AC_INT_PEND_REGISTER				(volatile KTU32 *)0xa07028b8	// 0x20 is cleared
#define AC_TOTAL_VOICES						64

// ------------------------------------------------------------------------------------------------
// Aggregates
// ------------------------------------------------------------------------------------------------

typedef struct
{
volatile KTU32 *		processerHalt;
volatile KTU32 *		soundMemoryBaseAddress;
volatile KTU32 *		firstFreeMemory;
volatile KTU32 *		commandBuffer;
volatile KTS16			commandSlot;
volatile KTU32 *		commandFlag;
#ifdef __SHC__
SYCHAIN					armCallbackEventId;
#else
EVT_ID					armCallbackEventId;
#endif
volatile KTU32 *		intArrayStartPtr;
volatile KTU32			intArrayStartOffset;
volatile KTU8			intArray			[AC_TOTAL_VOICES];
volatile KTU32 *		intResetFlag;
volatile KTU32 *		intEnableRegister;
volatile KTU32 *		intPendingRegister;
KTU32					maxVoices;
}AC_SYSTEM_STRUCT;

typedef struct
	{
	KTU8 commandNumber;
	KTU8 enable;
	KTU8 parameter[14];
	} AC_COMMAND;

typedef AC_COMMAND *  AC_COMMAND_PTR;

// ------------------------------------------------------------------------------------------------
// Enumerations
// ------------------------------------------------------------------------------------------------

typedef enum
	{
	AC_UNINITIALIZED_BANK_TYPE	=	0,
	AC_MELODIC_BANK				=	1,
	AC_DRUM_BANK				=	2
	}AC_BANK_TYPE;


typedef enum
	{
	AC_16BIT		=	0,
	AC_8BIT			=	1,
	AC_ADPCM		=	2,
	AC_ADPCM_LOOP	=	3
	}AC_AUDIO_TYPE;

typedef AC_AUDIO_TYPE * AC_AUDIO_TYPE_PTR;

// acError.c
typedef enum
	{
	
	AC_NO_ERROR						=	0,		// all is well
	// memory allocation 1-100
	
	// bad parameters 101-200
	AC_NULL_PARAMETER				=	101,	// a pointer parameter is NULL
	AC_OUT_OF_RANGE_PARAMETER		=	102,	// a parameter is out of range
	AC_0_SIZE_PARAMETER				=	103,	// the parameter size is 0
	AC_UNSUPPORTED_SAMPLE_RATE		=	104,	// a sample rate > 1128900 was requested
	// file system 201-300
	AC_SEEK_FAIL					=	201,
	AC_READ_FAIL					=	202,
	AC_GET_SIZE_FAIL				=	203,
	AC_CLOSE_FAIL					=	204,
	AC_FILE_NOT_FOUND				=	205,
	// driver 301-400
	AC_CANT_SEND_DRIVER_COMMAND		=	301,
	AC_DRIVER_IS_INSTALLED			=	302,
	AC_DRIVER_IS_NOT_INSTALLED		=	303,
	// warns 401-500
	AC_OUT_OF_RANGE_PARAMETER_FIXED	=	401,
	// memory 501-600
	AC_NON_32_BYTE_ALIGNED_ADDRESS	=	501,
	AC_NON_DWORD_COPY				=	505,
	// system
	AC_INTERNAL_ERROR				=	601,

	AC_LAST_ERROR					=	5000
	}AC_ERROR_TYPE;


#define AC_ERROR_MESSAGE_LENGTH	255

typedef struct 
	{
	char 			message[AC_ERROR_MESSAGE_LENGTH];
	AC_ERROR_TYPE	number;
	}AC_ERROR;

typedef AC_ERROR * AC_ERROR_PTR;

extern AC_ERROR		gAcError; // errors are reported via this structure


// ------------------------------------------------------------------------------------------------
// Abstract types
// ------------------------------------------------------------------------------------------------

#ifdef __SHC__
typedef	GDFS ACFILE; 
#else
typedef FSFD ACFILE;
#endif

// ------------------------------------------------------------------------------------------------
// Prototypes
// ------------------------------------------------------------------------------------------------

#ifdef __cplusplus
extern "C" {
#endif

// acError.c
void 			acErrorSet		(AC_ERROR_TYPE errorNumber,KTSTRING errorMessage);
AC_ERROR_PTR 	acErrorGetLast	(void);
KTBOOL 			acErrorExists	(void);
void 			acErrorClear	(void);

// digital audio functions
KTBOOL acDigiOpen				(KTU32 port,KTU32 address,KTU32 sizeInBytes, AC_AUDIO_TYPE aicaAudioType,KTU32 sampleRate);
KTBOOL acDigiClose				(KTU32 port);
KTBOOL acDigiSetCurrentPitch	(KTU32 port,KTS32 pitchOffsetInCents);
KTBOOL acDigiSetSampleRate		(KTU32 port,KTU32 sampleRate);
KTBOOL acDigiSetQSoundAngle		(KTU32 port,KTU32 angle);
KTBOOL acDigiSetMixer			(KTU32 port,KTU32 mixer,KTU32 level);
KTBOOL acDigiSetVolume			(KTU32 port,KTU32 aicaVolume);
KTBOOL acDigiSetPan				(KTU32 port,KTU32 aicaPan);
KTBOOL acDigiRequestEvent		(volatile KTU32 port,volatile KTU32 offsetFromBeginningInFrames);
KTBOOL acDigiPlay				(KTU32 port,KTU32 startOffset,KTS16 aicaLoopFlag);
KTBOOL acDigiStop				(KTU32 port);
KTBOOL acDigiMultiStop			(KTU32 upperMask, KTU32 lowerMask);
KTBOOL acDigiMultiPlay			(KTS32 aicaLoopFlag, KTU32 upperMask, KTU32 lowerMask);
KTBOOL acDigiMultiSetMask		(KTU32 port,KTU32 *upperMask, KTU32 *lowerMask);

// DSP functions
KTBOOL acDspLoadOutputMixer		(KTU32 address,KTU32 sizeInBytes);
KTBOOL acDspLoadPrograms		(KTU32 address,KTU32 sizeInBytes);

// MIDI functions
KTBOOL acMidiClose				(KTU32 port);
KTBOOL acMidiOpen				(KTU32 port,KTU8  gmMode,KTU32 address,KTU32 sizeInBytes,KTU32 pulsesPerQuarterNote);
KTBOOL acMidiPlay				(KTU32 port,KTU32 startOffset,KTS16 aicaLoopFlag);
KTBOOL acMidiStop				(KTU32 port);
KTBOOL acMidiPause				(KTU32 port);
KTBOOL acMidiResume				(KTU32 port);
KTBOOL acMidiSetVolume			(KTU32 port,KTU32 portMasterVolume);
KTBOOL acMidiSetTempo			(KTU32 port,KTU32 microSecondsPerQuarterNote);
KTBOOL acMidiReset				(KTU32 port);
KTBOOL acMidiSendMessage		(KTU32 port,KTU32 channel,KTU32 command,KTU32 value1,KTU32 value2);
KTBOOL acMidiRequestEvent		(KTU32 port,KTU32 offsetFromBeginningInBytes);
KTBOOL acMidiSetTonebank		(KTU8 toneBank,AC_BANK_TYPE bankType,KTU32 address,KTU32 sizeInBytes,KTU32 mttPtr);

// Redbook Functions
KTBOOL acCdSetVolume			(KTU32 leftVolume, KTU32 rightVolume);
KTBOOL acCdSetPan				(KTU32 leftPan, KTU32 rightPan);
KTBOOL acCdInit					(void);

// interrupt management
KTBOOL acHostInt				(void);
KTBOOL acHostIntReset			(void);

// acsystem.c
#ifndef __SHC__
static __inline__ void acSystemSoftwareBreakpoint	(void) {__asm__ volatile (".word 0x003b");}
#endif
void				acSystemInit					(void);
KTBOOL				acSystemInstallDriver			(KTU32 *driverImage,KTU32 driverSize,KTU32 lengthOfIntArray);
void				acSystemResetArmInterrupt		(void);
void				acSystemDisableArmInterrupts	(void);
void				acSystemEnableArmInterrupts		(void);
volatile KTU32 *	acSystemGetCommandFlag			(void);
volatile KTU32 *	acSystemGetFirstFreeSoundMemory	(void);
volatile KTU32 *	acSystemGetCurrentReadAddress	(volatile KTU32 * bufferStartAddress);
KTBOOL				acSystemGetSystemFlag			(void);
void				acSystemDelay					(KTU32 delay);
KTU32 *				acSystemRead					(volatile KTU32 *address,volatile KTU32 *result);

// acprint.c
void				acPrintf						(const char *format,...);

// acFile.c
// these calls are the lowest level of the file system and are not redirected
// through the shell, the redirected calls are of the same name but without the
// leading underscore ac. see amio.c, these all use the gdFs library under SHC
// and Metroworks.

KTBOOL	acFileOpen			(KTSTRING fileName,ACFILE *fd);
KTBOOL	acFileRead			(ACFILE fd,KTU8 * buffer,KTU32 size);
KTBOOL	acFileClose			(ACFILE fd);
KTBOOL	acFileReadFromTo	(KTSTRING fileName,KTU8 * buffer,KTU32 fromByte,KTU32 toByte);
KTBOOL	acFileGetSize		(KTSTRING fileName,KTU32 * size);
KTBOOL	acFileRewind		(ACFILE fd);
KTBOOL 	acFileLoad			(KTSTRING fileName,volatile KTU32 *buffer);

// acUtil.c
void _acUtilMemCpy(volatile KTU32 *  target,volatile KTU32 *  source,KTU32 sizeInBytes);


#ifdef __cplusplus
}
#endif


#endif // end of #ifndef _AC_H

// -------------------------------------------------------------------------------------------
// end of file: ac.h
// -------------------------------------------------------------------------------------------
