1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/*
linux/arch/m68k/atari/atasound.c
++Geert: Moved almost all stuff to linux/drivers/sound/
The author of atari_nosound, atari_mksound and atari_microwire_cmd is
unknown.
(++roman: That's me... :-)
This file is subject to the terms and conditions of the GNU General Public
License. See the file COPYING in the main directory of this archive
for more details.
*/
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/major.h>
#include <linux/config.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <asm/atarihw.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/atariints.h>
#include <asm/bootinfo.h>
/*
* stuff from the old atasound.c
*/
static void atari_nosound (unsigned long ignored)
{
unsigned char tmp;
unsigned long flags;
/* turn off generator A in mixer control */
save_flags(flags);
cli();
sound_ym.rd_data_reg_sel = 7;
tmp = sound_ym.rd_data_reg_sel;
sound_ym.wd_data = tmp | 0x39;
restore_flags(flags);
}
void atari_microwire_cmd (int cmd)
{
tt_microwire.mask = 0x7ff;
tt_microwire.data = MW_LM1992_ADDR | cmd;
/* Busy wait for data being completely sent :-( */
while( tt_microwire.mask != 0x7ff)
;
}
#define PC_FREQ 1192180
#define PSG_FREQ 125000
void atari_mksound (unsigned int count, unsigned int ticks)
{
static struct timer_list sound_timer = { NULL, NULL, 0, 0,
atari_nosound };
/*
* Generates sound of some count for some number of clock ticks
* [count = 1193180 / frequency]
*/
unsigned long flags;
unsigned char tmp;
save_flags(flags);
cli();
if (count == 750 && ticks == HZ/8) {
/* Special case: These values are used by console.c to
* generate the console bell. They are cached here and the
* sound actually generated is somehow special: it uses the
* generator B and an envelope. No timer is needed therefore
* and the bell doesn't disturb an other ongoing sound.
*/
/* set envelope duration to 492 ms */
sound_ym.rd_data_reg_sel = 11;
sound_ym.wd_data = 0;
sound_ym.rd_data_reg_sel = 12;
sound_ym.wd_data = 15;
/* envelope form: max -> min single */
sound_ym.rd_data_reg_sel = 13;
sound_ym.wd_data = 9;
/* set generator B frequency to 2400 Hz */
sound_ym.rd_data_reg_sel = 2;
sound_ym.wd_data = 52;
sound_ym.rd_data_reg_sel = 3;
sound_ym.wd_data = 0;
/* set volume of generator B to envelope control */
sound_ym.rd_data_reg_sel = 9;
sound_ym.wd_data = 0x10;
/* enable generator B in the mixer control */
sound_ym.rd_data_reg_sel = 7;
tmp = sound_ym.rd_data_reg_sel;
sound_ym.wd_data = (tmp & ~0x02) | 0x38;
restore_flags(flags);
return;
}
del_timer( &sound_timer );
if (!count) {
atari_nosound( 0 );
}
else {
/* convert from PC counter value (base frequency 1.193 MHz)
* to PSG period value (base frequency 125 kHz).
*/
int period = (PSG_FREQ * count + PC_FREQ/2) / PC_FREQ;
if (period > 0xfff) period = 0xfff;
/* set generator A frequency to 0 */
sound_ym.rd_data_reg_sel = 0;
sound_ym.wd_data = period & 0xff;
sound_ym.rd_data_reg_sel = 1;
sound_ym.wd_data = (period >> 8) & 0xf;
/* turn on generator A in mixer control (but not noise
* generator!) */
sound_ym.rd_data_reg_sel = 7;
tmp = sound_ym.rd_data_reg_sel;
sound_ym.wd_data = (tmp & ~0x01) | 0x38;
/* set generator A level to maximum, no envelope */
sound_ym.rd_data_reg_sel = 8;
sound_ym.wd_data = 15;
if (ticks) {
sound_timer.expires = jiffies + ticks;
add_timer( &sound_timer );
}
}
restore_flags(flags);
}
|