/***************************************************************************
*        NAME:  IW.H $Revision: 1.34 $
**       COPYRIGHT:
**       "Copyright (c) 1994,1995 by e-Tek Labs"
**
**       "This software is furnished under a license and may be used,
**       copied, or disclosed only in accordance with the terms of such
**       license and with the inclusion of the above copyright notice.
**       This software or any other copies thereof may not be provided or
**       otherwise made available to any other person. No title to and
**       ownership of the software is hereby transfered."
****************************************************************************
* $Log: iw.h $
* Revision 1.34  1995/10/26 14:59:27  mleibow
* Added mutes for software mixer controls.
* Revision 1.33  1995/10/26 12:04:06  sdsmith
* Changes for Voyetra cont.
* Revision 1.32  1995/10/24 11:29:40  sdsmith
* Fixes for Windows 95 compatability tests
* Revision 1.31  1995/10/16 15:36:24  unknown
* Add card busy error code
* Revision 1.30  1995/10/13 17:17:53  mleibow
* Implemented base level GS effects for reverb and chorus.
* Revision 1.29  1995/10/13 09:40:34  mleibow
* Added effects prototypes
* Revision 1.28  1995/07/27 18:10:11  mleibow
* fixed wrong prototype
* Revision 1.27  1995/07/27 17:51:34  mleibow
* added iw_mls_open and iw_mls_close to stop disk thrashing
* Revision 1.26  1995/07/07 16:01:29  sdsmith
* Added mixer version and checksum to mixer string
* Revision 1.25  1995/06/22 08:30:45  sdsmith
* Added master volume query functions
* Revision 1.24  1995/05/26 17:18:44  mleibow
* Removed iwmixer.c and it's calls from kernel
* Revision 1.23  1995/05/25 16:26:22  mleibow
* Revision 1.22  1995/05/25 15:12:56  mleibow
* Added multiple language support.
* Revision 1.21  1995/05/15 22:50:17  sdsmith
* Changed load profile to accept a buffer and length 
* Revision 1.20  1995/05/05 16:38:40  mleibow
* Changed patch format revision level to 1.0
* Revision 1.19  1995/05/03 09:22:47  mleibow
* Added support for multiple cards
* Added CODEC pan support
* Revision 1.18  1995/04/27 18:56:28  mleibow
* Updated error table for BETA release
* Revision 1.17  1995/04/26 16:26:21  sdsmith
* Added GP pin usage support
* Revision 1.16  1995/04/25 14:49:35  sdsmith
* Added some comments
* Revision 1.15  1995/04/20 09:24:22  sdsmith
* Added calls for iw_auto_deinit
* Revision 1.14  1995/04/19 17:40:03  sdsmith
* Added default init string support
* Revision 1.13  1995/04/17 12:55:22  mleibow
* Added iw_midi_master_volume() prototype
* Revision 1.12  1995/04/16 21:02:06  mleibow
* Added mixer callback function prototypes.
* Revision 1.11  1995/04/14 09:19:55  sdsmith
* Added support for B0 silicon
* Revision 1.10  1995/04/10 11:21:30  mleibow
* Added ROM support
* Revision 1.9  1995/04/10 11:19:15  mleibow
* Added ROM support
* Revision 1.8  1995/03/30 09:47:40  sdsmith
* New mixer fixes
* Revision 1.7  1995/03/27 07:51:15  sdsmith
* Added new mixer definitions
* Revision 1.6  1995/03/24 09:44:10  mleibow
* Added initialization for MPU401 and other emulations
* Revision 1.5  1995/03/08 15:28:09  mleibow
* add chip revision check for pre-release checks
* Revision 1.4  1995/03/03 10:56:54  sdsmith
* Added prototype for iw_codec_record_position
* Revision 1.3  1995/02/24 14:00:41  mleibow
* changed iw_asm_init() to iw_auto_init()
* Revision 1.2  1995/02/23 13:24:09  ssmith
* This was a demo revision
* Revision 1.1  1995/02/23 11:07:01  unknown
* Initial revision
***************************************************************************/

#ifndef _IW_H  /* allow header to be processed only once */
#define _IW_H

/* board types */
#define IW_NO_BOARD    0
#define IW_PLAIN_GUS   1
#define IW_ICS_MIXER   2
#define IW_CODEC_MIXER 4
#define INTERWAVE      8

/* error codes */
#define IW_OK			0
#define IW_NO_MORE_VOICES	-1
#define IW_BAD_IRQ		-2
#define IW_BAD_DMA		-3
#define IW_NOT_LOADED		-4
#define IW_NO_MEMORY		-5
#define IW_DMA_BUSY		-6
#define IW_NO_MORE_HANDLERS	-7
#define IW_DMA_HUNG		-8
#define IW_CARD_NOT_FOUND	-9
#define IW_DOS_ERROR		-10
#define IW_CODEC_NOT_FOUND	-11
#define IW_ILLEGAL		-12
#define IW_CANT_SET_NMI_HANDLER -13
#define IW_EMULATION_FAIL	-14
#define IW_CODEC_VERSION_MISMATCH -15
#define IW_CANT_READ_FILE	-16
#define IW_MESSAGE_NOT_FOUND	-17
#define IW_MIXER_VERSION_MISMATCH -18
#define IW_CARD_IS_BUSY -19
/* bits */
#define BIT0  0x01
#define BIT1  0x02
#define BIT2  0x04
#define BIT3  0x08
#define BIT4  0x10
#define BIT5  0x20
#define BIT6  0x40
#define BIT7  0x80
#define BIT8  0x0100
#define BIT9  0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000

/* bounds for volume enveloping functions */
#define IW_MIN_OFFSET      0
#define IW_MAX_OFFSET      255
#define IW_MAX_VOLUME	   4095

/* bounds for voice allocation */
#define IW_MIN_VOICES             14
#define IW_MAX_VOICES             32
#define IW_CODEC_RECORD_VOICE     33  /* IW_MAX_VOICES + 1 */
#define IW_CODEC_PLAYBACK_VOICE   34  /* IW_MAX_VOICES + 2 */

/* Interrupt handler types */
#define IW_IRQ_HANDLER_DMA	 0
#define IW_IRQ_HANDLER_VOICE     1
#define IW_IRQ_HANDLER_VOLUME    2
#define IW_IRQ_HANDLER_TIMER1    3
#define IW_IRQ_HANDLER_TIMER2    4
#define IW_IRQ_HANDLER_UART_XMIT 5
#define IW_IRQ_HANDLER_UART_RECV 6
#define IW_IRQ_HANDLER_CODEC     7
#define IW_IRQ_HANDLER_VISR      8


/* DMA control bits */
#define IW_DMA_ENABLE       BIT0
#define IW_DMA_READ         BIT1
#define IW_DMA_WIDTH_16     BIT2 /* width of DMA channel */
#define IW_DMA_RATE_DIV_1   BIT3
#define IW_DMA_RATE_DIV_2   BIT4
#define IW_DMA_IRQ_ENABLE   BIT5
#define IW_DMA_IRQ_PRESENT  BIT6
#define IW_DMA_DATA_16      BIT6 /* width of data */
#define IW_DMA_INVERT_MSB   BIT7

/* DMA Channel Identifiers */
#define IW_DMA_CHAN_1  0
#define IW_DMA_CHAN_2  1
#define IW_DMA_CHAN_3  2

/* SAMPLE control bits */
#define IW_DMA_STEREO  2

/* DMA flags */ 
#define IW_RECORD 0 /* use dma control or sample control */
#define IW_DMA    1

/* MIDI control register */
#define IW_UART_POLLED		0
#define IW_UART_RESET      	(BIT0|BIT1)
#define IW_UART_TD_INT  	BIT5
#define IW_UART_RD_INT  	BIT7

/* MIDI_STATUS_REGISTER */
#define IW_UART_RD          BIT0
#define IW_UART_TD          BIT1
#define IW_UART_ERR_FRAMING BIT4
#define IW_UART_ERR_OVERRUN BIT5

/* Mixer I/O Lines */
#define IW_MIX_LEFT       0
#define IW_MIX_RIGHT      1
#define IW_MIX_MIC_IN     0x00
#define IW_MIX_LINE_IN    0x01
#define IW_MIX_AUX1_IN    0x02
#define IW_MIX_AUX2_IN    0x03
#define IW_MIX_SYNTH_IN   0x04
#define IW_MIX_MASTER     0x05
#define IW_MIX_DAC_IN     0x06
#define IW_MIX_REC_GAIN   0x07
#define IW_MIX_MONO_OUT   0x08
#define IW_MIX_MONO_IN    0x09
#define IW_MIX_REC_SOURCE 0x0A
#define IW_MIX_MASTER_DIG 0x0B
#define IW_MIX_MASTER_MIDI 0x0C
#define IW_MIX_MASTER_MOD 0x0D
#define IW_MIX_ATTR_STEREO       0x0001
#define IW_MIX_ATTR_MASTER       0x0002
#define IW_MIX_ATTR_INTERMEDIATE 0x0004
#define IW_MIX_ATTR_SIGNED       0x0008
#define IW_MIX_ATTR_UNSIGNED     0x0010
#define IW_MIX_ATTR_LINEAR       0x0020
#define IW_MIX_ATTR_LOG          0x0040
#define IW_MIX_ATTR_SWAPLR       0x0080
#define IW_MIX_ATTR_MONOLEFT     0x0100
#define IW_MIX_ATTR_MONORIGHT    0x0200
#define IW_MIX_ATTR_LOCKLR       0x0400

/* digital playback flags */
#define IW_TYPE_8BIT       BIT0 /* 1 use 8 bit data; 0 use 16 bit data */
#define IW_TYPE_PRELOAD    BIT1 /* preload data */
#define IW_TYPE_INVERT_MSB BIT2 /* invert most significant bit during dma */
#define IW_TYPE_STEREO     BIT3 /* 1 for stereo data */
#define IW_TYPE_ALAW       BIT4 /* 1 for A-LAW companded data */
#define IW_TYPE_ULAW       BIT5 /* 1 for U-LAW companded data */
#define IW_TYPE_ADPCM      BIT6 /* 1 for ADPCM data */

/* sound effects and digital music types */
#define IW_SND_LOOP_MASK   (BIT0|BIT1)
#define IW_SND_LOOP_NONE   0
#define IW_SND_LOOP        1
#define IW_SND_LOOP_BIDIR  2
#define IW_SND_8BIT        (BIT2)
#define IW_SND_BACKWARD    (BIT3)
#define IW_SND_ULAW	   (BIT4)

#define IW_SOUND_PLAYING  2
#define IW_SOUND_ACTIVE   1

/* macros for defining which emulations to configure hardware for */
#define EMUL_MPU401	BIT0
#define EMUL_SB		BIT1
#define EMUL_ADLIB	BIT2

/* patch macros */
#define IW_PATCH_LAYER_NONE		0
#define IW_PATCH_LAYERED		1
#define IW_PATCH_VELOCITY_SPLIT		2
#define IW_PATCH_FREQUENCY_SPLIT	3

#define IW_PATCH_EXCL_NONE	0
#define IW_PATCH_EXCL_SINGLE	1
#define IW_PATCH_EXCL_MULTIPLE	2

#define IW_PATCH_EFFECT_NONE	0
#define IW_PATCH_EFFECT_REVERB	1
#define IW_PATCH_EFFECT_CHORUS	2
#define IW_PATCH_EFFECT_ECHO	3

#define IW_LAYER_TIME		0
#define IW_LAYER_RATE		1
#define IW_LAYER_KEY_UP		0
#define IW_LAYER_KEY_DOWN	1
#define IW_LAYER_KEY_RETRIGGER	2
#define IW_LAYER_KEY_LEGATO	3

#define IW_LAYER_FLAGS_RETRIGGER	BIT0

#define IW_WAVE_FORMAT_8BIT	BIT0
#define IW_WAVE_FORMAT_SIGNED	BIT1
#define IW_WAVE_FORMAT_FORWARD	BIT2
#define IW_WAVE_FORMAT_LOOP	BIT3
#define IW_WAVE_FORMAT_BIDIR	BIT4
#define IW_WAVE_FORMAT_ULAW	BIT5
#define IW_WAVE_FORMAT_ROM	BIT7

#define IW_ENVELOPE_ONE_SHOT	1
#define IW_ENVELOPE_SUSTAIN	2
#define IW_ENVELOPE_NO_SUSTAIN	3

#define IW_ENVELOPE_IDX_NONE	0
#define IW_ENVELOPE_IDX_VELOCITY	1
#define IW_ENVELOPE_IDX_FREQUENCY	2

#define IW_ENV_FLAGS_RETRIGGER		BIT0
  
#define IW_LFO_TRIANGLE		0
#define IW_LFO_POSTRIANGLE	1
#define IW_LFO_TREMOLO		0
#define IW_LFO_VIBRATO	        1
 
/* digital playback callback reasons & return values */
#define IW_DIG_DONE           0
#define IW_DIG_MORE_DATA      1
#define IW_DIG_BUFFER_DONE    2
#define IW_DIG_PAUSE          3

/* log table used for vibrato and pitch bend.  log table made public for
** developers use */
#define IW_LOG_TAB_SIZE 12
extern long iw_log_table[IW_LOG_TAB_SIZE];

#define IW_ATTENTABSIZE 128
extern short iw_atten_tab[IW_ATTENTABSIZE];

#if defined(__BORLANDC__)
#undef RFAR
#define RFAR far
#elif defined(_MSC_VER) && (_MSC_VER <= 600)
#define RFAR far
#elif defined(_MSC_VER) && (_MSC_VER > 600)
#define RFAR __far
#else
#undef RFAR
#define RFAR
#endif

/* Type definitions */
#ifndef UINT
#define UINT   unsigned int
#endif
#define UCHAR  unsigned char
#define USHORT unsigned short
#define ULONG  unsigned long

typedef enum {CONTROL, INPUT, JUNCTION, OUTPUT} iw_mixer_node_type;
typedef enum {ADC, AUX, CD, DAC, DUMMY, EFFECTS, LEVEL, LINE, METER, MIC,
	          MIXER, MUX, SWITCH, SYNTH, TEE} iw_mixer_node_subtype;
typedef enum {none, pm, irq} iw_gp_usage_t;

/* structure definitions */
/***************************************************************************

GLOBAL DEFINITION:
load_kernel_cfg - kernel configuration data

DESCRIPTION:
load_kernel_cfg is a structure used to hold data relating to the current
instance of the loaded kernel.  The values in the fields are loaded from
the InterWave initialization file iw.ini which is normally pointed to
from the INTERWAVE environment variable.

DESCRIPTION:
  FullInit   - 0 = leave mixer settings alone, 1 = match current
               mixer settings to those in the iw.ini file.  This
			   field is set by the wrapper or application after
			   calling iw_get_kernel_cfg().
  UseDma     - 1 = use DMA for CODEC data transfer
               0 = use PIO for CODEC data transfer
  mls_path   - path name to text files for multiple language support
  pnp_csn    - Plug And Play card select number
               In a true PNP system, this and the read port are the
			   only valid setup info in the iw.ini file.
  pnp_read_port - Plug and Play read port
               In a true PNP system, this and the card select
			   number are the only valid setup info in the iw.ini
			   file.
  codecbase  - base port address of the CODEC
  synthbase  - base port address of the synthesizer
  mpubase	 - base port for MPU-401 emulation
  adlibbase  - base port for AdLib/SB emulation
  cdbase     - CD-ROM interface base port
  atapibase  - CD-ROM ATAPI IDE Interface Base Port
  gameport   - port for joystick connector
  dma1       - physical DMA channel used for synthesizer playback
  dma2       - physical DMA channel used for synthesizer sampling
  cddma      - physical DMA channel for CD-ROM interface
  irq1       - synthesizer IRQ number
  irq2       - MIDI IRQ number
  cdirq      - IRQ used for CD-ROM interface
  adlibirq   - AdLib/Sound Blaster emulation interrupt
  mpuirq     - MPU-401 emulation interrupt
*/
struct load_kernel_cfg {
  unsigned char FullInit;
  unsigned char UseDma;
  unsigned char pnp_csn;
  unsigned short pnp_read_port;
//  unsigned short codecbase;
//  unsigned short synthbase;
  unsigned short mpubase;
//  unsigned short adlibbase;
//  unsigned short cdbase;
//  unsigned short atapibase;
//  unsigned short gameport;
  unsigned char emulation;
  unsigned char effects;
//  unsigned char dma1;
//  unsigned char dma2;
//  unsigned char irq1;
//  unsigned char irq2;
//  unsigned char cddma;
//  unsigned char cdirq;
//  unsigned char adlibirq;
//  unsigned char mpuirq;
  iw_gp_usage_t gpusage;
  /* the following members are for the Ultrasound Cards */
//  unsigned short voices;
  unsigned char mls_path[128];
  /* the following is for pre-release chips only and will be removed */
  unsigned char revision; /* 0=A0, 1=A1, 2=A2, 3=A3, 4=B0 ... */
};

/***************************************************************************

GLOBAL DEFINITION:
iw_dma_buff - structure type used for information about DMA buffers

DESCRIPTION:
 vptr   - virtual address of DMA buffer (segment:offset)
 paddr  - physical address of DMA buffer in low memory
 size   - size of DMA buffer in bytes
*/
struct iw_dma_buff {
 unsigned char RFAR *vptr;
 unsigned long paddr;
 unsigned long size;
};

/***************************************************************************

GLOBAL DEFINITION:
iw_sound - structure type used for information about digital music data

DESCRIPTION:
 mem_pos     - DRAM address of start of music data
 start_loop  - start looping point within data (not necessarily the same
               as the start address of the data)
 end_loop    - end looping point within music data
 type        - type of digital music data
*/
struct iw_sound {
 unsigned long mem_pos;
 unsigned long start_loop;
 unsigned long end_loop;
 unsigned char type;
};

/***************************************************************************

GLOBAL DEFINITION:
iw_board_type - type of board currently installed in the system

DESCRIPTION:
iw_board_type will be one of the following values:
  IW_NO_BOARD    - there is no board detected
  IW_PLAINGUS    - board has no mixer facilities
  IW_ICS_MIXER   - board is equipped with an ICS mixer
  IW_CODEC_MIXER - board is equipped with a CODEC mixer (overrides all others)
*/
extern unsigned char iw_board_type;
extern char iw_linear_volumes;

/* patch structure definitions */
struct LFO {
    unsigned short freq;	/* (0 - 2047) 0.01Hz - 21.5Hz */
    short depth;		/* volume +-(0 - 255) 0.48675dB/step */
    				/* pitch +-(0 - 255) #cents */
    short sweep;		/* 0 - 950 deciseconds */
    unsigned char shape;	/* LFO_TRIANGLE, LFO_POSTRIANGLE */
    unsigned char delay;	/* 0 - 255 deciseconds */
};

struct iw_disk_id {
    short major_id;
    short minor_id;
};

union ID {
    /* At runtime, all disk based pointers and ID's are turned into */
    /* memory references for quick access. This mechanism allows */
    /* patch information to be maintained without copying or allocating */
    /* extra memory */
    struct iw_disk_id id;	/* disk based ID or pointer to an ID */
    void RFAR *p;		/* memory based pointer to another struct */
};

/***************************************************************************

GLOBAL DEFINITION:
header - Patch File chunk header structure

DESCRIPTION:
	tag - a four byte field containing the chunk type
	length - a four byte field that identifies the sum of all remaining
	         information in the chunk minus the 8 bytes of the chunk
			 header.

SEE ALSO: e-Tek Patch File Format Document
*/
struct header {
    unsigned char tag[4];
    unsigned long length;
};

struct iw_wave {
    union ID id;		/* waveform id */
    unsigned long size;		/* size of waveform in samples */
    unsigned long start;	/* starting offset in bytes */
    unsigned long loopstart;	/* loop start offset in samples */
    unsigned long loopend;	/* loop end offset in samples */
    unsigned long m_start;	/* position of sample in memory */
    unsigned long sample_ratio;	/* sample ratio (44100 * 1024 / rate) */
    char attenuation;		/* 0 - 127 (no corresponding midi controller) */
    char low_note;		/* lower frequency range for this waveform */
    char high_note;		/* higher frequency range for this waveform */
    unsigned char format;
    unsigned char m_format;	/* in memory copy of patch data format */
    union ID data_id;
};

struct iw_layer {
    union ID id;		    /* layer id */
    char nwaves;		/* number of waveforms for this layer */
    char flags;			/* flags: retrigger */
    char high_range;		/* range for layer based */
    char low_range;		/* on either velocity or frequency */
    char pan;			/* pan offset from CC1 (0 left - 127 right) */
    char pan_freq_scale;	/* position based on frequency (0 - 127) */
    struct LFO tremolo;
    struct LFO vibrato;
    char velocity_mode;		/* IW_LAYER_TIME, IW_LAYER_RATE */
    char attenuation;		/* 0 - 127 (no corresponding midi controller) */
    short freq_scale;		/* 0 - 2048, 1024 is equal to semitone scaling */
    char freq_center;		/* center for keyboard frequency scaling */
    char layer_event;		/* IW_LAYER_KEY_UP, IW_LAYER_KEY_DOWN */
    union ID penv;	    /* pitch envelope */
    union ID venv;	    /* volume envelope */
    struct iw_wave RFAR *waves;  /* not used on disk, but is used in memory */
};

struct iw_patch {
    union ID id;		/* patch id */
    short nlayers;		/* number of layers in patch */
    char layer_mode;		/* how are layers activated */
    char exclusion_mode;	/* _NONE, _SINGLE, _MULTIPLE */
    short exclusion_group;	/* group identifier for mutually exclusive */
    				/* patches */
    char effect1;		/* use global effect if available */
    char effect1_depth;		/* 0 - 127 */
    char effect2;		/* use global effect if available */
    char effect2_depth;		/* 0 - 127 */
    unsigned char bank;		/* bank */
    unsigned char program;	/* program */
    struct iw_layer RFAR *layers;    /* not used on disk, but is used in memory */
};

#define IW_PATCH_VERSION_MAJOR 1
#define IW_PATCH_VERSION_MINOR 0

struct iw_program {
    union ID id;		/* program id */
    union ID version;		/* patch engine version */
};

typedef struct iw_patch iw_patch_t;
 
struct iw_name_chunk {	/* patch editor name chunk */
    union ID id;	/* id of chunk to name */
    char name[80];
};
 
struct iw_data {
    union ID id;
    char filename[80];
};
 
struct iw_envp_header {
    char num_envelopes;		/* number of envelopes that follow */
    char flags;			/* retrigger & retrigger_layer */
    char mode;			/* 1 shot, sustained, non sustained */
    char index_type;		/* none, velocity, frequency */
};

struct iw_envp {
    union ID id;		/* envelope id */
    struct iw_envp_header h;
    /* struct iw_envp_record RFAR *records; */
    /* an array of iw_envp_records always follows envp_chunks for both RAM
    and disk data structures */
};
 
struct iw_envp_record {
    short nattack;
    short nrelease;
    unsigned short sustain_offset;
    unsigned short sustain_rate;
    unsigned short release_rate;
    unsigned char hirange;
    unsigned char pad;
};

/* multiple language support */
/* MLS files contain:
**     unsigned long num_messages;
**     struct iw_message_info info[];   //an array of message info structs 
**     text
*/
struct iw_message_info {
    unsigned short message_id;
    unsigned short size;
    unsigned long message_offset;
};

/* FUNCTION PROTOTYPES */
/* InterWave Kernel Initialization API */
int iw_init_kernel(struct load_kernel_cfg RFAR *);
int iw_init_synth(struct load_kernel_cfg RFAR *);
int iw_init_codec(struct load_kernel_cfg RFAR *);
int iw_init_mixer(struct load_kernel_cfg RFAR *);
int iw_load_kernel(struct load_kernel_cfg RFAR *);
int iw_close_synth(void);
void iw_close_codec(void);
void iw_close_kernel(void);
void iw_unload_kernel(void);

/* InterWave Kernel Utilities */
int iwu_get_kernel_cfg(struct load_kernel_cfg RFAR *, int card_num);
int iwu_get_profile_string(char RFAR *, char RFAR *, char RFAR *,
                           char RFAR *, int, char RFAR *);
int iwu_write_profile_string(char RFAR *, char RFAR *,
                             char RFAR *, char RFAR *);
int iwu_load_profile(char RFAR *);
int iwu_close_profile(char RFAR *);
void iwu_profile_init(char RFAR *profile_buffer, unsigned short len);

/* multiple language support */
iw_mls_init(char RFAR *path);
int iw_mls_open(char RFAR *langfile);
void iw_mls_close(void);
int iw_mls_getstring(char RFAR *langfile, unsigned short index, char RFAR *buf, unsigned short buflen);
long iw_mls_strlen(char RFAR *appdir, unsigned short id);

int iw_load_os(struct load_kernel_cfg RFAR *);
int iw_unload_os(void);
void iw_set_appname(char RFAR *);
int iw_auto_init(struct load_kernel_cfg RFAR *cfg);
int iw_auto_deinit(void);

/* InterWave Kernel Local Memory API */
unsigned char iw_peek(unsigned long address);
void iw_poke(unsigned long address, unsigned char datum);
unsigned short iw_peek16(unsigned long address);
void iw_poke16(unsigned long address, unsigned short datum);
void iw_poke_block(unsigned char RFAR *data, 
                   unsigned long address, 
                   unsigned long len, 
                   unsigned char dma_control);
char iw_good_dram(unsigned long address);
unsigned long iw_malloc(unsigned long);
void iw_free(unsigned long);
unsigned long iw_mem_avail(void);
unsigned long iw_mem_largest_avail(void);
void iw_peek_rom(unsigned char RFAR *data, unsigned long address, unsigned short len);

/* InterWave Kernel Voice Control API */
int iw_allocate_voice(int priority, void (RFAR *steal_notify)(int));
void iw_free_voice(unsigned int i);
void iw_adjust_priority(int voice, int priority);
int iw_allocate_effect_voice(void);

/* InterWave Kernel DMA Control API */
int iw_dram_xfer(struct iw_dma_buff RFAR *dptr, 
                 unsigned long size, 
                 unsigned long dram_address, 
                 unsigned char dma_control, 
                 unsigned short flags);
void iw_stop_dma(int);
int iw_wait_dma(int);
int iw_dma_ready(int);
unsigned long iw_amount_xferred(int);

/* InterWave Kernel Miscellaneous Routines */
void iw_delay(void);
int iw_detect_card(unsigned short port);
char *iw_error_str(int);
int iw_myatoi(void);
unsigned short iw_read(int handle, void RFAR *io_buffer, unsigned short size);
unsigned short iw_close_file(int handle);
unsigned int iw_seek(int handle, unsigned long offset, int method);
int iw_open(char RFAR *name);
#ifdef __FLAT__
int iw_atoi(char RFAR **str, int base);
#else
int iw_atoi(void);
#endif

/* InterWave Kernel Digital Audio API */
/* Synthesizer playback */
int iw_synth_play_digital(unsigned short priority,
                    unsigned char RFAR *buffer,
                    unsigned long size, 
                    unsigned long iwl_addr, 
                    unsigned short volume,
                    unsigned short pan, 
                    unsigned short frequency, 
                    unsigned char type,
                    struct iw_dma_buff RFAR *dptr,
                    int (RFAR *callback)(int, 
                                         int, 
                                         unsigned char RFAR * RFAR *, 
                                         unsigned long RFAR *));
void iw_synth_restart_digital(int voice);
void iw_synth_start_digital(int voice);
void iw_synth_pause_digital(int voice);
void RFAR iw_synth_stop_digital(int voice);
void iw_synth_dig_set_dma_rate(unsigned short rate);
unsigned long iw_synth_digital_position(int voice);
int iw_synth_play_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);
void iw_synth_dig_set_vol(unsigned short voice, short vol);
void iw_synth_dig_set_pan(unsigned short voice, unsigned short pan);
/* CODEC playback */
int iw_codec_play_digital(unsigned char RFAR *buffer,
                    unsigned long size, 
                    unsigned short volume,
                    unsigned short pan,
                    unsigned short frequency, 
                    unsigned char type,
                    struct iw_dma_buff RFAR *dptr,
                    int (RFAR *callback)(int, 
                                         int, 
                                         unsigned char RFAR * RFAR *, 
                                         unsigned long RFAR *));
void iw_codec_restart_digital(int voice);
void iw_codec_start_digital(int voice);
void iw_codec_pause_digital(int voice);
void RFAR iw_codec_stop_digital(int voice);
unsigned long iw_codec_digital_position(int voice);
unsigned long iw_codec_record_position(int voice);
int iw_codec_play_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);
void iw_codec_dig_set_vol(short vol);
void iw_codec_dig_set_pan(short pan);
unsigned int iw_query_codec_freq(unsigned int);
/* CODEC record */
int iw_codec_record_digital(unsigned char RFAR *buffer,
                    unsigned long size, 
                    unsigned short frequency, 
                    unsigned char type,
                    struct iw_dma_buff RFAR *dptr,
                    int (RFAR *callback)(int, 
                                         int, 
                                         unsigned char RFAR * RFAR *, 
                                         unsigned long RFAR *));
void iw_codec_restart_record(int voice);
void iw_codec_start_record(int voice);
void iw_codec_pause_record(int voice);
void RFAR iw_codec_stop_record(int voice);
int iw_codec_record_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);

/* InterWave Kernel Timer API */
void iw_change_timer1(int resolution);
void iw_change_timer2(int resolution);
int iw_enable_timer1(int (RFAR *callback)(void), int resolution);
int iw_enable_timer2(int (RFAR *callback)(void), int resolution);
void iw_disable_timer1(void);
void iw_disable_timer2(void);

/* InterWave Kernel Interrupt Hook API */
int iw_set_external_semaphore(void RFAR *addr);
int iw_clear_external_semaphore(void RFAR *addr);
int iw_add_midi_recv_handler(int (RFAR *handler)());
int iw_add_dma_handler(int (*handler)());
int iw_add_codec_handler(int (*handler)());
int iw_add_voice_handler(int (*handler)(int));
int iw_add_volume_handler(int (*handler)(int));
int iw_add_timer_handler(int timer, int (RFAR *handler)(void));
int iw_add_handler(unsigned char, int (RFAR *)(void));
int iw_remove_handler(unsigned char, int (RFAR *)(void));

/* InterWave Kernel Mixer API */
void iw_dig_master_vol(short);
short iw_dig_get_master_vol(void);
void iw_dig_mute(short);
int  iw_mix_strlen(void);
void iw_build_mixer(void);
int iw_linear_to_db(short id, int value);
int iw_db_to_linear(short id, int value);
void iw_get_mixer_settings(char RFAR *);
int  iw_restore_mixer_settings(char RFAR *);
void iw_mix_get_control(int, int RFAR *, int RFAR *);
void iw_mix_set_control(int, int, int);
void iw_codec_set_record_source(int rec_source);
void iw_codec_set_aux1(int);
void iw_codec_mute(int channel, int mute);
void iw_codec_set_atten(int channel, unsigned char side, unsigned char level);

/* wrapper must provide following mixer callback functions */
extern int iw_mix_report_nodes(int);
extern int iw_mix_add_node(short, short, short, iw_mixer_node_type,
			    iw_mixer_node_subtype, short, short, short,
			    int, int, int, int, int, int,
			    unsigned char RFAR *, unsigned char RFAR *);
extern int iw_add_weighted_path(int, int);

/* InterWave Kernel Digital Music API */
void iw_sound_volume(unsigned short voice, int volume,
unsigned long period /* us*10 */);
void iw_sound_master_volume(short master_volume);
short iw_sound_get_master_volume(void);
void iw_sound_mute(short mute);
void iw_sound_pan(unsigned short voice, short pan);
void iw_sound_frequency(unsigned short voice, unsigned long freq);
void RFAR iw_sound_stop(int voice);
void iw_sound_mode(int voice, 
                   struct iw_sound RFAR *sound,
                   unsigned char type);
void iw_sound_bend(unsigned short voice, unsigned short bend);
int iw_sound_start(unsigned short priority, 
                   struct iw_sound RFAR *sound,
                   short volume, 
                   unsigned long period, 
                   short pan, 
                   unsigned long freq,
                   unsigned short bend, 
                   void (RFAR *callback)(int voice));
int iw_sound_playing(int voice);

/* InterWave Kernel MIDI API */
void RFAR iw_midi_stop_note(int note_voice);
void iw_midi_note_on(int channel, int note, int velocity, struct iw_patch RFAR *patch, int priority);
void iw_midi_note_off(int channel, int note);
void iw_midi_silence_patch_notes(struct iw_patch RFAR *patch);
void iw_midi_patch_removed(struct iw_patch RFAR *patch);
void iw_channel_pitch_bend(int channel, unsigned int bend);
void iw_midi_synth_volume(unsigned short synth, int master_volume);
void iw_midi_master_volume(int volume);
int  iw_midi_get_master_volume(void);
void iw_midi_mute(short mute);
void iw_midi_change_program(int channel, struct iw_patch RFAR *patch);
void iw_midi_set_vibrato(int channel, int value);
void iw_midi_set_tremolo(int channel, int value);
void iw_midi_change_volume(int channel, int volume);
void iw_midi_change_expression(int channel, int volume);
void iw_midi_set_balance(int balance, int channel);
void iw_midi_channel_sustain(int channel, int sustain);
void iw_change_patch(struct iw_patch RFAR *op, struct iw_patch RFAR *np);
void iw_midi_all_notes_off(int channel);
void iw_midi_all_sounds_off(int channel);
void iw_midi_pitch_bend(int channel, int lsb, int msb);
void iw_midi_parameter(int channel, int control, int value);
int iw_midi_get_channel_notes(int channel, int notes[]);
int iw_midi_get_channel_volume(int channel);
int iw_midi_get_volume(int voice);

/* InterWave Kernel midi UART API */
void iw_uart_reset(int c);
void iw_uart_send(int datum);
int iw_uart_recv(void);
int iw_uart_status(void);

/* effects module */
unsigned char iw_get_effects_mask(int chan);
static void iw_stop_effect_2(USHORT chan);
int iw_stop_effect(int chan, int abrupt);
void iw_start_effect(int chan, int effect);
short iw_effects_get_master_volume(void);
void iw_effects_master_volume(short volume);
void iw_effects_mute(short mute);
int iw_effects_add_volume_handler(void (RFAR *handler)(void));

/* InterWave Kernel substitutes for standard C-library functions */
/* (to avoid linking in the C-runtime in TSRs)  */

/* ctype.h */
int iwu_isalnum(int c);
int iwu_isalpha(int c);
int iwu_isspace(int c);

/* stdlib.h */
char RFAR *iwu_itoa(int integer, char RFAR *buffer, int radix);

/* string.h */
void RFAR *iwu_memcpy(void RFAR *dest, const void RFAR *src, unsigned int n);
void RFAR *iwu_memset(void RFAR *dest, int c, unsigned int n);
char RFAR *iwu_strcat(char RFAR *dest, const char RFAR *src);
int iwu_strcmp(const char RFAR *s1, const char RFAR *s2);
char RFAR *iwu_strcpy(char RFAR *dest, const char RFAR *src);
int iwu_strncmp(const char RFAR *s1, const char RFAR *s2, unsigned int maxlen);
int iwu_stricmp(const char RFAR *s1, const char RFAR *s2);
int iwu_strnicmp(const char RFAR *s1, const char RFAR *s2, unsigned int maxlen);
int iwu_strlen(const char RFAR *s1);
void iwu_swab(char RFAR *, char RFAR *, int);
char RFAR *iwu_strtok(char RFAR *, const char RFAR *);
char RFAR *iwu_strncpy(char RFAR *dest, const char RFAR *src, 
                       unsigned int maxlen);
long iwu_strtol(const char RFAR *str, char RFAR * RFAR *endptr, int rad);

#endif
