/* audio_hard.c */
/* access to the audio hardware */

/* $Author: Espie $
 * $Date: 91/05/20 22:44:23 $
 * $Revision: 1.24 $
 * $Log:	audio_hard.c,v $
 * Revision 1.24  91/05/20  22:44:23  Espie
 * *** empty log message ***
 * 
 * Revision 1.23  91/05/16  15:04:17  Espie
 * Modified stuff for more compatibility with other compilers.
 * 
 * Revision 1.22  91/05/12  22:38:42  Espie
 * Included right prototypes.
 *
 * Revision 1.21  91/05/05  19:06:56  Espie
 * *** empty log message ***
 *
 * Revision 1.20  91/05/05  15:39:36  Espie
 * Got rid of local variables. Enforcer hits free.
 *
 * Revision 1.19  91/05/02  23:32:37  Espie
 * *** empty log message ***
 *
 * Revision 1.18  91/04/30  00:36:12  Espie
 * Stable version III.
 *
 * Revision 1.17  91/04/29  15:07:15  Espie
 * Cleaned-up.
 *
 * Revision 1.16  91/04/27  20:48:06  Espie
 * Doesn't need to suppress the interrupts, finally.
 *
 * Revision 1.15  91/04/27  16:44:04  Espie
 * Moved interrupts disabling from audio_soft.
 *
 * Revision 1.14  91/04/27  04:00:22  Espie
 * saved the mask for a channel (gain ????).
 *
 * Revision 1.13  91/04/26  16:30:11  Espie
 * added turn_on_dma().
 * between() is now obsolescent.
 *
 * Revision 1.12  91/04/26  01:29:45  Espie
 * Fixed trivial bug with filter_restore()
 * (was restoring the OPPOSITE state).
 *
 * Revision 1.11  91/04/25  02:06:30  Espie
 * There was a bug with the filter on command.
 * There is now a bug with the automatic recovery
 * of the filter state. Doesn't work as it should.
 *
 * Revision 1.10  91/04/23  21:32:44  Espie
 * New function: restart_dma().
 *
 * Revision 1.1  91/04/23  21:31:43  Espie
 * Initial revision
 *
 * Revision 1.9  91/04/21  12:10:58  Espie
 * Stable version, known as bunch II.
 * Also features ``right'' log description.
 *
 * Revision 1.8  91/04/21  11:16:01  Espie
 *
 * Revision 1.7  91/04/20  18:14:34  Espie
 * New audio routines, they do only what they have to do.
 * Symbolic constants everywhere.
 * Added audio filter control.
 *
 * Revision 1.6  91/04/19  13:22:32  Espie
 *
 * Revision 1.5  91/04/19  02:18:00  Espie
 * simplified audio.c, since we can change period/volume on the run
 * without more care.
 *
 * Revision 1.4  91/04/18  20:23:07  Espie
 * no big change in this file.
 *
 * Revision 1.3  91/04/18  02:26:00  Espie
 * bunch I.
 * Revision 1.2  91/04/18  02:18:25  Espie
 * First ``real'' interface with the hardware.
 *
 * Revision 1.1  91/04/17  18:51:36 Espie
 * Initial revision
 *
 */

#include <exec/types.h>
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <hardware/intbits.h>
#include <hardware/dmabits.h>
#include <dos/dos.h>
#include <custom/cleanup.h>
#include "song.h"
#include "player.h"
#include "proto.h"
#include "lproto.h"

BOOL saved_filter;

#ifdef LATTICE
#define FAR_SUPPORT __far
#else
#error
#endif
extern volatile struct Custom FAR_SUPPORT custom;
extern volatile struct CIA FAR_SUPPORT ciaa;

void init_audio_hard(struct priv_play *private)
        {
                private->channel_mask[0] = DMAF_AUD0;
                private->channel_mask[1] = DMAF_AUD1;
                private->channel_mask[2] = DMAF_AUD2;
                private->channel_mask[3] = DMAF_AUD3;
                private->mask = 0;
        }

void clear_mask(struct priv_play *private)
        {
                private->mask = 0;
        }

void turn_on_dma(struct priv_play *private)
        {
                custom.dmacon = private->mask | DMAF_SETCLR | DMAF_MASTER;
        }

void set_note(struct priv_play *private,
                struct sample_info *i, int channel, int period)
        {
                custom.dmacon = private->channel_mask[channel];
                private->mask |= private->channel_mask[channel];
                custom.aud[channel].ac_ptr = i->start;
                custom.aud[channel].ac_len = i->length;
                custom.aud[channel].ac_per = period;
        }

void change_volume(struct priv_play *private, int channel, int volume)
        {
                custom.aud[channel].ac_vol = volume;
        }

void change_period(struct priv_play *private, int channel, int period)
        {
                custom.aud[channel].ac_per = period;
        }

void set_replay(struct priv_play *private, struct sample_info *i, int channel)
        {
                private->mask |= private->channel_mask[channel];
                custom.aud[channel].ac_ptr = i->rp_start;
                custom.aud[channel].ac_len = i->rp_length;
        }

void reset_audio(void)
        {
                custom.aud[0].ac_vol = 0;
                custom.aud[1].ac_vol = 0;
                custom.aud[2].ac_vol = 0;
                custom.aud[3].ac_vol = 0;
                        /* turn off every channel and audio dma */
                custom.dmacon = DMAF_AUDIO;
        }

/***
 *
 *              Management of the audio filter
 *
 ***/

/* The LED and the filter are driven by the same bit
 */

void save_filter(void)
        {
                saved_filter = ciaa.ciapra & CIAF_LED;
        }

void restore_filter(void)
        {
                if (saved_filter)
                        filter_off();
                else
                        filter_on();
        }

void filter_on(void)
        {
                ciaa.ciapra &= ~CIAF_LED;
        }

void filter_off(void)
        {
                ciaa.ciapra |= CIAF_LED;
        }
