diff options
author | asami <asami@FreeBSD.org> | 1996-11-02 10:41:28 +0000 |
---|---|---|
committer | asami <asami@FreeBSD.org> | 1996-11-02 10:41:28 +0000 |
commit | 223875ec7d51de4b686f9069a84494af29734cf6 (patch) | |
tree | 9675654af532c3965b39dbb0dd6f132eab3714d7 | |
parent | 2ccb731676c10d2eff50861371a9cb4cdb505e81 (diff) | |
download | FreeBSD-src-223875ec7d51de4b686f9069a84494af29734cf6.zip FreeBSD-src-223875ec7d51de4b686f9069a84494af29734cf6.tar.gz |
The last update/merge of PC98 stuff before 2.2. The whole
pc98/pc98/sound directory has vanished now!
Submitted by: FreeBSD(98) Development Team
43 files changed, 339 insertions, 8639 deletions
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 08f74ae..f4849e2 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -3,7 +3,7 @@ # # modified for PC-9801 # -# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $ +# $Id: files.pc98,v 1.9 1996/10/30 22:39:31 asami Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \ @@ -151,17 +151,17 @@ pc98/isa/seagate.c optional sea device-driver pc98/isa/si.c optional si device-driver pc98/isa/si_code.c optional si device-driver pc98/pc98/sio.c optional sio device-driver -pc98/pc98/sound/pcm86.c optional pcm device-driver +i386/isa/sound/pcm86.c optional pcm device-driver i386/isa/sound/dev_table.c optional snd device-driver -pc98/pc98/sound/soundcard.c optional snd device-driver -pc98/pc98/sound/sound_switch.c optional snd device-driver +i386/isa/sound/soundcard.c optional snd device-driver +i386/isa/sound/sound_switch.c optional snd device-driver i386/isa/sound/audio.c optional snd device-driver i386/isa/sound/dmabuf.c optional snd device-driver i386/isa/sound/sys_timer.c optional snd device-driver i386/isa/sound/sequencer.c optional snd device-driver i386/isa/sound/patmgr.c optional snd device-driver i386/isa/sound/adlib_card.c optional opl device-driver -pc98/pc98/sound/opl3.c optional opl device-driver +i386/isa/sound/opl3.c optional opl device-driver i386/isa/sound/gus_card.c optional gus device-driver i386/isa/sound/gus_midi.c optional gus device-driver i386/isa/sound/gus_vol.c optional gus device-driver @@ -170,9 +170,9 @@ i386/isa/sound/ics2101.c optional gus device-driver i386/isa/sound/sound_timer.c optional gus device-driver i386/isa/sound/midi_synth.c optional gus device-driver i386/isa/sound/midibuf.c optional gus device-driver -pc98/pc98/sound/ad1848.c optional gusxvi device-driver -pc98/pc98/sound/ad1848.c optional gus device-driver -pc98/pc98/sound/ad1848.c optional mss device-driver +i386/isa/sound/ad1848.c optional gusxvi device-driver +i386/isa/sound/ad1848.c optional gus device-driver +i386/isa/sound/ad1848.c optional mss device-driver i386/isa/sound/midi_synth.c optional mss device-driver i386/isa/sound/midibuf.c optional mss device-driver i386/isa/sound/mpu401.c optional mpu device-driver @@ -181,17 +181,17 @@ i386/isa/sound/midibuf.c optional mpu device-driver i386/isa/sound/pas2_card.c optional pas device-driver i386/isa/sound/pas2_midi.c optional pas device-driver i386/isa/sound/pas2_mixer.c optional pas device-driver -pc98/pc98/sound/pas2_pcm.c optional pas device-driver +i386/isa/sound/pas2_pcm.c optional pas device-driver i386/isa/sound/midi_synth.c optional pas device-driver i386/isa/sound/midibuf.c optional pas device-driver i386/isa/sound/sb_card.c optional sb device-driver -pc98/pc98/sound/sb_dsp.c optional sb device-driver +i386/isa/sound/sb_dsp.c optional sb device-driver i386/isa/sound/sb_midi.c optional sb device-driver i386/isa/sound/sb_mixer.c optional sb device-driver i386/isa/sound/midi_synth.c optional sb device-driver i386/isa/sound/midibuf.c optional sb device-driver -pc98/pc98/sound/sb16_dsp.c optional sbxvi device-driver -pc98/pc98/sound/sb16_midi.c optional sbmidi device-driver +i386/isa/sound/sb16_dsp.c optional sbxvi device-driver +i386/isa/sound/sb16_midi.c optional sbmidi device-driver i386/isa/sound/uart6850.c optional uart device-driver i386/isa/sound/midi_synth.c optional uart device-driver i386/isa/sound/midibuf.c optional uart device-driver @@ -206,7 +206,7 @@ pc98/isa/ultra14f.c optional uha device-driver pc98/pc98/wd.c optional wdc device-driver pc98/pc98/wd.c optional wd device-driver i386/isa/atapi.c optional atapi device-driver -pc98/pc98/wcd.c optional wcd device-driver +i386/isa/wcd.c optional wcd device-driver pc98/isa/wd7000.c optional wds device-driver pc98/pc98/wt.c optional wt device-driver i386/linux/imgact_linux.c optional compat_linux diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98 index 106083c..e9cca8e 100644 --- a/sys/conf/options.pc98 +++ b/sys/conf/options.pc98 @@ -1,4 +1,4 @@ -# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $ +# $Id: options.pc98,v 1.8 1996/10/30 22:39:32 asami Exp $ BOUNCEPAGES opt_bounce.h USER_LDT MATH_EMULATE opt_math_emulate.h @@ -17,6 +17,7 @@ BREAK_TO_DEBUGGER opt_comconsole.h COMCONSOLE opt_comconsole.h CONADDR opt_comconsole.h CONUNIT opt_comconsole.h +CONSPEED opt_comconsole.h COM_ESP opt_sio.h COM_MULTIPORT opt_sio.h DSI_SOFT_MODEM opt_sio.h diff --git a/sys/i386/isa/lptreg.h b/sys/i386/isa/lptreg.h index 9e10ba9..583e96f 100644 --- a/sys/i386/isa/lptreg.h +++ b/sys/i386/isa/lptreg.h @@ -6,7 +6,7 @@ * William Jolitz. * * form: @(#)lptreg.h 1.1 (Berkeley) 12/19/90 - * $Id$ + * $Id: lptreg.h,v 1.2 1993/10/16 13:46:12 rgrimes Exp $ */ /* @@ -16,6 +16,29 @@ * Copyright (C) William Jolitz 1990 */ +/* + * modified for PC9801 by A.Kojima + * Kyoto University Microcomputer Club (KMC) + */ + +#ifdef PC98 +#define lpt_pstb_ctrl (-9) /* PSTB enable control */ +#define LPC_EN_PSTB 0xc /* PSTB enable */ +#define LPC_DIS_PSTB 0xd /* PSTB disable */ + +#define lpt_data 0 /* Data to/from printer (R/W) */ + +#define lpt_status 2 /* Status of printer (R) */ +#define LPS_NBSY 0x4 /* printer no ack of data */ + +#define lpt_control 6 /* Control printer (W) */ +#define LPC_MODE8255 0x82 /* 8255 mode */ +#define LPC_IRQ8 0x6 /* IRQ8 active */ +#define LPC_NIRQ8 0x7 /* IRQ8 inactive */ +#define LPC_PSTB 0xe /* PSTB active */ +#define LPC_NPSTB 0xf /* PSTB inactive */ + +#else /* IBM-PC */ #define lpt_data 0 /* Data to/from printer (R/W) */ #define lpt_status 1 /* Status of printer (R) */ @@ -30,4 +53,5 @@ #define LPC_AUTOL 0x02 /* automatic linefeed */ #define LPC_NINIT 0x04 /* initialize printer */ #define LPC_SEL 0x08 /* printer selected */ +#endif #define LPC_ENA 0x10 /* printer out of paper */ diff --git a/sys/i386/isa/sound/ad1848.c b/sys/i386/isa/sound/ad1848.c index 8c385bd..0dc5464 100644 --- a/sys/i386/isa/sound/ad1848.c +++ b/sys/i386/isa/sound/ad1848.c @@ -157,9 +157,15 @@ wait_for_calibration (ad1848_info * devc) */ timeout = 100000; +#ifdef PC98 + while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) + timeout--; + if ((INB (devc->base) & 0x80) == 0x80) +#else while (timeout > 0 && INB (devc->base) & 0x80) timeout--; if (INB (devc->base) & 0x80) +#endif printk ("ad1848: Auto calibration timed out(1).\n"); timeout = 100; @@ -474,7 +480,11 @@ static struct audio_operations ad1848_pcm_operations[MAX_AUDIO_DEV] = { { "Generic AD1848 codec", +#ifdef PC98 + NEEDS_RESTART, +#else DMA_AUTOMODE, +#endif AFMT_U8, /* Will be set later */ NULL, ad1848_open, @@ -910,8 +920,22 @@ ad1848_prepare_for_IO (int dev, int bsize, int bcount) * Write to I8 starts resyncronization. Wait until it completes. */ timeout = 10000; +#ifdef PC98 + while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) +#else while (timeout > 0 && INB (devc->base) == 0x80) +#endif + timeout--; + +#ifdef PC98 + ad_write (devc, 8, fs); + /* + * Write to I8 starts resyncronization. Wait until it completes. + */ + timeout = 10000; + while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) timeout--; +#endif /* * If mode == 2 (CS4231), set I28 also. It's the capture format register. @@ -924,11 +948,26 @@ ad1848_prepare_for_IO (int dev, int bsize, int bcount) * Write to I28 starts resyncronization. Wait until it completes. */ timeout = 10000; +#ifdef PC98 + while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) +#else while (timeout > 0 && INB (devc->base) == 0x80) +#endif timeout--; } +#ifdef PC98 + ad_write (devc, 28, fs); + + /* + * Write to I28 starts resyncronization. Wait until it completes. + */ + timeout = 10000; + while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) + timeout--; +#endif + ad_leave_MCE (devc); /* * Starts the calibration process and * enters playback mode after it. @@ -950,7 +989,13 @@ ad1848_halt (int dev) ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; ad_mute (devc); +#ifdef PC98 + ad_enter_MCE (devc); +#endif ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */ +#ifdef PC98 + ad_leave_MCE (devc); +#endif OUTB (0, io_Status (devc)); /* Clear interrupt status */ ad_enter_MCE (devc); @@ -1399,7 +1444,11 @@ probe_ms_sound (struct address_info *hw_config) return 0; } +#ifdef PC98 + if (hw_config->irq > 12) +#else if (hw_config->irq > 11) +#endif { printk ("MSS: Bad IRQ %d\n", hw_config->irq); return 0; @@ -1433,10 +1482,17 @@ probe_ms_sound (struct address_info *hw_config) long attach_ms_sound (long mem_start, struct address_info *hw_config) { +#ifdef PC98 + static char interrupt_bits[13] = + { + -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, 0x18, -1, 0x20 + }; +#else static char interrupt_bits[12] = { -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20 }; +#endif char bits; static char dma_bits[4] = diff --git a/sys/i386/isa/sound/opl3.c b/sys/i386/isa/sound/opl3.c index b3660b7..42379cd 100644 --- a/sys/i386/isa/sound/opl3.c +++ b/sys/i386/isa/sound/opl3.c @@ -47,7 +47,11 @@ static int opl3_enabled = 0; static int opl4_enabled = 0; +#ifdef PC98 +static int left_address = 0x28d2, right_address = 0x28d2, both_address = 0; +#else static int left_address = 0x388, right_address = 0x388, both_address = 0; +#endif static int nr_voices = 9; static int logical_voices[MAX_VOICE] = @@ -812,10 +816,14 @@ opl3_command (int io_addr, unsigned int addr, unsigned int val) for (i = 0; i < 2; i++) INB (io_addr); +#ifdef PC98 + OUTB ((unsigned char) (val & 0xff), io_addr + 0x100); +#else OUTB ((unsigned char) (val & 0xff), io_addr + 1); /* * Write to register * */ +#endif if (!opl3_enabled) { diff --git a/sys/i386/isa/sound/pas2_pcm.c b/sys/i386/isa/sound/pas2_pcm.c index 97ae76c..db91165 100644 --- a/sys/i386/isa/sound/pas2_pcm.c +++ b/sys/i386/isa/sound/pas2_pcm.c @@ -377,7 +377,11 @@ pas_pcm_prepare_for_output (int dev, int bsize, int bcount) static struct audio_operations pas_pcm_operations = { "Pro Audio Spectrum", +#ifdef PC98 + NEEDS_RESTART, +#else DMA_AUTOMODE, +#endif AFMT_U8 | AFMT_S16_LE, NULL, pas_pcm_open, diff --git a/sys/pc98/pc98/sound/pcm86.c b/sys/i386/isa/sound/pcm86.c index 40c7c25..aa7e3d7 100644 --- a/sys/pc98/pc98/sound/pcm86.c +++ b/sys/i386/isa/sound/pcm86.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pcm86.c,v 1.2 1996/09/12 11:11:16 asami Exp $ + * $Id: pcm86.c,v 2.4 1996/01/24 19:53:34 abtk Exp $ */ /* diff --git a/sys/i386/isa/sound/sb16_dsp.c b/sys/i386/isa/sound/sb16_dsp.c index d5af2c1..5e84e67 100644 --- a/sys/i386/isa/sound/sb16_dsp.c +++ b/sys/i386/isa/sound/sb16_dsp.c @@ -84,7 +84,11 @@ static void dsp_cleanup (void); static struct audio_operations sb16_dsp_operations = { "SoundBlaster 16", +#ifdef PC98 + NEEDS_RESTART, +#else DMA_AUTOMODE, +#endif AFMT_U8 | AFMT_S16_LE, NULL, sb16_dsp_open, @@ -447,6 +451,17 @@ set_irq_hw (int level) switch (level) { +#ifdef PC98 + case 5: + ival = 8; + break; + case 3: + ival = 1; + break; + case 10: + ival = 2; + break; +#else case 5: ival = 2; break; @@ -459,6 +474,7 @@ set_irq_hw (int level) case 10: ival = 8; break; +#endif default: printk ("SB16_IRQ_LEVEL %d does not exist\n", level); return; @@ -517,6 +533,9 @@ sb16_dsp_detect (struct address_info *hw_config) if (sbc_major < 4) /* Set by the plain SB driver */ return 0; /* Not a SB16 */ +#ifdef PC98 + hw_config->dma = sb_config->dma; +#else if (hw_config->dma < 4) if (hw_config->dma != sb_config->dma) { @@ -524,11 +543,16 @@ sb16_dsp_detect (struct address_info *hw_config) sb_config->dma, hw_config->dma); return 0; } +#endif dma16 = hw_config->dma; dma8 = sb_config->dma; set_irq_hw (sb_config->irq); +#ifdef PC98 + sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2); +#else sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma)); +#endif DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma)); diff --git a/sys/i386/isa/sound/sb16_midi.c b/sys/i386/isa/sound/sb16_midi.c index 4e45e2e..7dae750 100644 --- a/sys/i386/isa/sound/sb16_midi.c +++ b/sys/i386/isa/sound/sb16_midi.c @@ -35,9 +35,15 @@ #include <i386/isa/sound/sb.h> +#ifdef PC98 +#define DATAPORT (sb16midi_base) +#define COMDPORT (sb16midi_base+0x100) +#define STATPORT (sb16midi_base+0x100) +#else #define DATAPORT (sb16midi_base) #define COMDPORT (sb16midi_base+1) #define STATPORT (sb16midi_base+1) +#endif #define sb16midi_status() INB(STATPORT) #define input_avail() (!(sb16midi_status()&INPUT_AVAIL)) diff --git a/sys/i386/isa/sound/sb_dsp.c b/sys/i386/isa/sound/sb_dsp.c index 560fc79..82a2178 100644 --- a/sys/i386/isa/sound/sb_dsp.c +++ b/sys/i386/isa/sound/sb_dsp.c @@ -1067,6 +1067,30 @@ sb_dsp_detect (struct address_info *hw_config) return 0; #endif +#ifdef PC98 + switch (sbc_irq) + { + case 3: + sb_setmixer (IRQ_NR, 1); + break; + case 5: + sb_setmixer (IRQ_NR, 8); + break; + case 10: + sb_setmixer (IRQ_NR, 2); + break; + } + switch (hw_config->dma) + { + case 0: + sb_setmixer (DMA_NR, 1); + break; + case 3: + sb_setmixer (DMA_NR, 2); + break; + } +#endif + return 1; /* * Detected */ @@ -1137,8 +1161,13 @@ sb_dsp_init (long mem_start, struct address_info *hw_config) #ifndef EXCLUDE_YM3812 +#ifdef PC98 + if (sbc_major > 3 || + (sbc_major == 3 && INB (0x28d2) == 0x00)) +#else if (sbc_major > 3 || (sbc_major == 3 && INB (0x388) == 0x00)) /* Should be 0x06 if not OPL-3 */ +#endif enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH); #endif diff --git a/sys/i386/isa/sound/sound_switch.c b/sys/i386/isa/sound/sound_switch.c index 21bcd69..83994e0 100644 --- a/sys/i386/isa/sound/sound_switch.c +++ b/sys/i386/isa/sound/sound_switch.c @@ -171,10 +171,16 @@ init_status (void) return; if (!put_status_int (snd_installed_cards[i].config.irq, 10)) return; +#ifdef PC98 + if (snd_installed_cards[i].config.dma >= 0) { +#endif if (!put_status (" drq ")) return; if (!put_status_int (snd_installed_cards[i].config.dma, 10)) return; +#ifdef PC98 + } +#endif if (!snd_installed_cards[i].enabled) if (!put_status (")")) diff --git a/sys/i386/isa/sound/soundcard.c b/sys/i386/isa/sound/soundcard.c index c7af8ab..3a06b6c 100644 --- a/sys/i386/isa/sound/soundcard.c +++ b/sys/i386/isa/sound/soundcard.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: soundcard.c,v 1.42 1996/03/28 14:31:13 scrappy Exp $ + * $Id: soundcard.c,v 1.43 1996/09/10 08:26:06 bde Exp $ */ #include <i386/isa/sound/sound_config.h> @@ -91,6 +91,9 @@ struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"}; struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"}; struct isa_driver uartdriver = {sndprobe, sndattach, "uart"}; struct isa_driver mssdriver = {sndprobe, sndattach, "mss"}; +#ifdef PC98 +struct isa_driver pcmdriver = {sndprobe, sndattach, "pcm"}; +#endif static unsigned short ipri_to_irq (unsigned short ipri); @@ -274,6 +277,10 @@ driver_to_voxunit(struct isa_driver *driver) return(SNDCARD_GUS16); else if(driver == &mssdriver) return(SNDCARD_MSS); +#ifdef PC98 + else if(driver == &pcmdriver) + return(SNDCARD_PCM86); +#endif else return(0); } @@ -291,6 +298,19 @@ sndprobe (struct isa_device *dev) hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/ if(unit) +#ifdef PC98 + if(unit == SNDCARD_PCM86) { + int result; + + result = sndtable_probe (unit, &hw_config); + dev->id_iobase = hw_config.io_base; + dev->id_irq = (1 << hw_config.irq); + dev->id_drq = hw_config.dma; + + return result; + } + else +#endif return sndtable_probe (unit, &hw_config); else return 0; @@ -468,7 +488,11 @@ sound_mem_init (void) for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */ if (!(dsp_init_mask & (1 << dev))) /* Not already done */ +#ifdef PC98 + if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0) +#else if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan > 0) +#endif { dsp_init_mask |= (1 << dev); dmap = audio_devs[dev]->dmap; diff --git a/sys/i386/isa/wdreg.h b/sys/i386/isa/wdreg.h index 20d37da..2a0a32f 100644 --- a/sys/i386/isa/wdreg.h +++ b/sys/i386/isa/wdreg.h @@ -34,12 +34,42 @@ * SUCH DAMAGE. * * from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91 - * $Id: wdreg.h,v 1.11 1996/01/28 22:16:20 wollman Exp $ + * $Id: wdreg.h,v 1.12 1996/06/08 10:03:38 bde Exp $ + */ + +/* + * modified for PC9801 by F.Ukai + * Kyoto University Microcomputer Club (KMC) */ /* * Disk Controller register definitions. */ +#ifdef PC98 +#define wd_data 0x0 /* data register (R/W - 16 bits) */ +#define wd_error 0x2 /* error register (R) */ +#define wd_precomp wd_error /* write precompensation (W) */ +#define wd_features wd_error /* features register (W) */ +#define wd_seccnt 0x4 /* sector count (R/W) */ +#define wd_sector 0x6 /* first sector number (R/W) */ +#define wd_cyl_lo 0x8 /* cylinder address, low byte (R/W) */ +#define wd_cyl_hi 0xa /* cylinder address, high byte (R/W)*/ +#define wd_sdh 0xc /* sector size/drive/head (R/W)*/ +#define wd_command 0xe /* command register (W) */ +#define wd_status wd_command /* immediate status (R) */ + +#define wd_altsts_nec 0x10c /*alternate fixed disk status(via 1015) (R)*/ +#define wd_ctlr_nec 0x10c /*fixed disk controller control(via 1015) (W)*/ +#define wd_altsts_epson 0x3 /*alternate fixed disk status(via 1015) (R)*/ +#define wd_ctlr_epson 0x3 /*fixed disk controller control(via 1015) (W)*/ +#define wd_altsts wd_alsts_nec +#define wd_ctlr wd_ctlr_nec + +#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */ +#define WDCTL_RST 0x4 /* reset the controller */ +#define WDCTL_IDS 0x2 /* disable controller interrupts */ +#define wd_digin 0x10e /* disk controller input(via 1015) (R)*/ +#else /* IBM-PC */ #define wd_data 0x0 /* data register (R/W - 16 bits) */ #define wd_error 0x1 /* error register (R) */ #define wd_precomp wd_error /* write precompensation (W) */ @@ -58,6 +88,7 @@ #define WDCTL_RST 0x4 /* reset the controller */ #define WDCTL_IDS 0x2 /* disable controller interrupts */ #define wd_digin 0x207 /* disk controller input(via 1015) (R)*/ +#endif /* PC98 */ /* * Status Bits. diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile index 61f5c04..9cb20ed 100644 --- a/sys/pc98/boot/biosboot/Makefile +++ b/sys/pc98/boot/biosboot/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 1996/09/12 11:08:41 asami Exp $ +# $Id: Makefile,v 1.4 1996/10/23 07:24:27 asami Exp $ # PROG= boot @@ -37,6 +37,10 @@ CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \ -DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \ -DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE} +# feature not implemented +# BOOT_COMCONSOLE_SPEED?=9600 +# CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED} + # Enable code to take the default boot string from a fixed location on the # disk. See nextboot(8) and README.386BSD for more info. #CFLAGS+= -DNAMEBLOCK diff --git a/sys/pc98/boot/biosboot/serial.S b/sys/pc98/boot/biosboot/serial.S index d1091cd..d8d4b6f 100644 --- a/sys/pc98/boot/biosboot/serial.S +++ b/sys/pc98/boot/biosboot/serial.S @@ -24,7 +24,7 @@ * the rights to redistribute these changes. * * from: Mach, Revision 2.2 92/04/04 11:34:26 rpd - * $Id: serial.S,v 1.3 1995/04/21 16:30:18 bde Exp $ + * $Id: serial.S,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $ */ /* @@ -72,6 +72,11 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .file "serial.s" #include "asm.h" +#ifdef PC98 +#include "../../pc98/sioreg.h" +#else +#include "../../isa/sioreg.h" +#endif .text /* diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c index be8751c..4ca93de 100644 --- a/sys/pc98/cbus/fdc.c +++ b/sys/pc98/cbus/fdc.c @@ -43,7 +43,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $ + * $Id: fd.c,v 1.7 1996/10/23 07:25:15 asami Exp $ * */ @@ -75,14 +75,13 @@ #include <pc98/pc98/epsonio.h> #include <i386/isa/isa_device.h> #include <pc98/pc98/fdreg.h> -#include <pc98/pc98/fdc.h> #else #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/fdreg.h> -#include <i386/isa/fdc.h> #include <i386/isa/rtc.h> #endif +#include <i386/isa/fdc.h> #include <machine/stdarg.h> #if NFT > 0 #include <sys/ftape.h> diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c index bcd8f13..c72f7b8 100644 --- a/sys/pc98/cbus/sio.c +++ b/sys/pc98/cbus/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.7 1996/09/12 11:09:56 asami Exp $ + * $Id: sio.c,v 1.8 1996/10/09 21:46:46 asami Exp $ */ #include "opt_comconsole.h" @@ -423,6 +423,7 @@ static struct cdevsw sio_cdevsw = { static int comconsole = -1; static speed_t comdefaultrate = TTYDEF_SPEED; +static speed_t condefaultrate = CONSPEED; static u_int com_events; /* input chars + weighted output completions */ static int sio_timeout; static int sio_timeouts_until_log; @@ -1130,9 +1131,11 @@ sioattach(isdp) com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL; com->it_in.c_lflag = TTYDEF_LFLAG; com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; - } + com->it_in.c_ispeed = com->it_in.c_ospeed = condefaultrate; + } else + com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; + termioschars(&com->it_in); - com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; com->it_out = com->it_in; /* attempt to determine UART type */ @@ -3052,7 +3055,7 @@ siocnopen(sp) /* * Save all the device control registers except the fifo register - * and set our default ones (cs8 -parenb speed=comdefaultrate). + * and set our default ones (cs8 -parenb speed=condefaultrate). * We can't save the fifo register since it is read-only. */ iobase = siocniobase; @@ -3069,7 +3072,7 @@ siocnopen(sp) * data input register. This also reduces the effects of the * UMC8669F bug. */ - divisor = ttspeedtab(comdefaultrate, comspeedtab); + divisor = ttspeedtab(condefaultrate, comspeedtab); dlbl = divisor & 0xFF; if (sp->dlbl != dlbl) outb(iobase + com_dlbl, dlbl); diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98 index 08f74ae..f4849e2 100644 --- a/sys/pc98/conf/files.pc98 +++ b/sys/pc98/conf/files.pc98 @@ -3,7 +3,7 @@ # # modified for PC-9801 # -# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $ +# $Id: files.pc98,v 1.9 1996/10/30 22:39:31 asami Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \ @@ -151,17 +151,17 @@ pc98/isa/seagate.c optional sea device-driver pc98/isa/si.c optional si device-driver pc98/isa/si_code.c optional si device-driver pc98/pc98/sio.c optional sio device-driver -pc98/pc98/sound/pcm86.c optional pcm device-driver +i386/isa/sound/pcm86.c optional pcm device-driver i386/isa/sound/dev_table.c optional snd device-driver -pc98/pc98/sound/soundcard.c optional snd device-driver -pc98/pc98/sound/sound_switch.c optional snd device-driver +i386/isa/sound/soundcard.c optional snd device-driver +i386/isa/sound/sound_switch.c optional snd device-driver i386/isa/sound/audio.c optional snd device-driver i386/isa/sound/dmabuf.c optional snd device-driver i386/isa/sound/sys_timer.c optional snd device-driver i386/isa/sound/sequencer.c optional snd device-driver i386/isa/sound/patmgr.c optional snd device-driver i386/isa/sound/adlib_card.c optional opl device-driver -pc98/pc98/sound/opl3.c optional opl device-driver +i386/isa/sound/opl3.c optional opl device-driver i386/isa/sound/gus_card.c optional gus device-driver i386/isa/sound/gus_midi.c optional gus device-driver i386/isa/sound/gus_vol.c optional gus device-driver @@ -170,9 +170,9 @@ i386/isa/sound/ics2101.c optional gus device-driver i386/isa/sound/sound_timer.c optional gus device-driver i386/isa/sound/midi_synth.c optional gus device-driver i386/isa/sound/midibuf.c optional gus device-driver -pc98/pc98/sound/ad1848.c optional gusxvi device-driver -pc98/pc98/sound/ad1848.c optional gus device-driver -pc98/pc98/sound/ad1848.c optional mss device-driver +i386/isa/sound/ad1848.c optional gusxvi device-driver +i386/isa/sound/ad1848.c optional gus device-driver +i386/isa/sound/ad1848.c optional mss device-driver i386/isa/sound/midi_synth.c optional mss device-driver i386/isa/sound/midibuf.c optional mss device-driver i386/isa/sound/mpu401.c optional mpu device-driver @@ -181,17 +181,17 @@ i386/isa/sound/midibuf.c optional mpu device-driver i386/isa/sound/pas2_card.c optional pas device-driver i386/isa/sound/pas2_midi.c optional pas device-driver i386/isa/sound/pas2_mixer.c optional pas device-driver -pc98/pc98/sound/pas2_pcm.c optional pas device-driver +i386/isa/sound/pas2_pcm.c optional pas device-driver i386/isa/sound/midi_synth.c optional pas device-driver i386/isa/sound/midibuf.c optional pas device-driver i386/isa/sound/sb_card.c optional sb device-driver -pc98/pc98/sound/sb_dsp.c optional sb device-driver +i386/isa/sound/sb_dsp.c optional sb device-driver i386/isa/sound/sb_midi.c optional sb device-driver i386/isa/sound/sb_mixer.c optional sb device-driver i386/isa/sound/midi_synth.c optional sb device-driver i386/isa/sound/midibuf.c optional sb device-driver -pc98/pc98/sound/sb16_dsp.c optional sbxvi device-driver -pc98/pc98/sound/sb16_midi.c optional sbmidi device-driver +i386/isa/sound/sb16_dsp.c optional sbxvi device-driver +i386/isa/sound/sb16_midi.c optional sbmidi device-driver i386/isa/sound/uart6850.c optional uart device-driver i386/isa/sound/midi_synth.c optional uart device-driver i386/isa/sound/midibuf.c optional uart device-driver @@ -206,7 +206,7 @@ pc98/isa/ultra14f.c optional uha device-driver pc98/pc98/wd.c optional wdc device-driver pc98/pc98/wd.c optional wd device-driver i386/isa/atapi.c optional atapi device-driver -pc98/pc98/wcd.c optional wcd device-driver +i386/isa/wcd.c optional wcd device-driver pc98/isa/wd7000.c optional wds device-driver pc98/pc98/wt.c optional wt device-driver i386/linux/imgact_linux.c optional compat_linux diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98 index 106083c..e9cca8e 100644 --- a/sys/pc98/conf/options.pc98 +++ b/sys/pc98/conf/options.pc98 @@ -1,4 +1,4 @@ -# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $ +# $Id: options.pc98,v 1.8 1996/10/30 22:39:32 asami Exp $ BOUNCEPAGES opt_bounce.h USER_LDT MATH_EMULATE opt_math_emulate.h @@ -17,6 +17,7 @@ BREAK_TO_DEBUGGER opt_comconsole.h COMCONSOLE opt_comconsole.h CONADDR opt_comconsole.h CONUNIT opt_comconsole.h +CONSPEED opt_comconsole.h COM_ESP opt_sio.h COM_MULTIPORT opt_sio.h DSI_SOFT_MODEM opt_sio.h diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 282b74dc..c6539d9 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.10 1996/10/23 07:25:00 asami Exp $ + * $Id: machdep.c,v 1.11 1996/10/29 08:36:16 asami Exp $ */ #include "npx.h" @@ -697,6 +697,16 @@ cpu_boot(int howto) } /* + * Shutdown the CPU as much as possible + */ +void +cpu_halt(void) +{ + for (;;) + __asm__ ("hlt"); +} + +/* * Clear registers on exec */ void diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c index 55ead7a..d15a654 100644 --- a/sys/pc98/i386/userconfig.c +++ b/sys/pc98/i386/userconfig.c @@ -46,7 +46,7 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** - ** $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $ + ** $Id: userconfig.c,v 1.10 1996/10/30 22:39:36 asami Exp $ **/ /** @@ -1390,6 +1390,7 @@ yesnocancel(char *str) for(;;) switch(getchar()) { + case -1: case 'n': case 'N': return(0); @@ -1577,6 +1578,7 @@ editval(int x, int y, int width, int hex, int min, int max, int *val, int ro) VetRet(KEY_TAB); /* verify and maybe return */ break; + case -1: case 'q': case 'Q': VetRet(KEY_EXIT); @@ -2247,7 +2249,7 @@ visuserconfig(void) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $ + * $Id: userconfig.c,v 1.63 1996/10/30 21:40:15 julian Exp $ */ #include "scbus.h" @@ -2679,6 +2681,7 @@ introfunc(CmdParm *parms) extended = 0; break; + case -1: case 'Q': case 'q': clear(); @@ -2804,7 +2807,7 @@ cngets(char *input, int maxin) continue; } printf("%c", c); - if ((++nchars == maxin) || (c == '\n') || (c == '\r')) { + if ((++nchars == maxin) || (c == '\n') || (c == '\r') || ( c == -1)) { *input = '\0'; break; } diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c index be8751c..4ca93de 100644 --- a/sys/pc98/pc98/fd.c +++ b/sys/pc98/pc98/fd.c @@ -43,7 +43,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $ + * $Id: fd.c,v 1.7 1996/10/23 07:25:15 asami Exp $ * */ @@ -75,14 +75,13 @@ #include <pc98/pc98/epsonio.h> #include <i386/isa/isa_device.h> #include <pc98/pc98/fdreg.h> -#include <pc98/pc98/fdc.h> #else #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/fdreg.h> -#include <i386/isa/fdc.h> #include <i386/isa/rtc.h> #endif +#include <i386/isa/fdc.h> #include <machine/stdarg.h> #if NFT > 0 #include <sys/ftape.h> diff --git a/sys/pc98/pc98/fdc.h b/sys/pc98/pc98/fdc.h deleted file mode 100644 index b763b1c..0000000 --- a/sys/pc98/pc98/fdc.h +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fdc.h,v 1.6 1996/05/03 14:57:22 phk Exp $ - * - */ - -enum fdc_type -{ - FDC_NE765, FDC_I82077, FDC_NE72065, FDC_UNKNOWN = -1 -}; - - -/***********************************************************************\ -* Per controller structure. * -\***********************************************************************/ -struct fdc_data -{ - int fdcu; /* our unit number */ - int baseport; - int dmachan; - int flags; -#define FDC_ATTACHED 0x01 -#define FDC_HASFTAPE 0x02 -#define FDC_TAPE_BUSY 0x04 -#define FDC_STAT_VALID 0x08 - struct fd_data *fd; - int fdu; /* the active drive */ - int state; - int retry; - int fdout; /* mirror of the w/o digital output reg */ - u_long status[7]; /* copy of the registers */ - enum fdc_type fdct; /* chip version of FDC */ - int fdc_errs; /* number of logged errors */ - struct buf_queue_head head; /* Head of buf chain */ -}; - -/***********************************************************************\ -* Throughout this file the following conventions will be used: * -* fd is a pointer to the fd_data struct for the drive in question * -* fdc is a pointer to the fdc_data struct for the controller * -* fdu is the floppy drive unit number * -* fdcu is the floppy controller unit number * -* fdsu is the floppy drive unit number on that controller. (sub-unit) * -\***********************************************************************/ -typedef int fdu_t; -typedef int fdcu_t; -typedef int fdsu_t; -typedef struct fd_data *fd_p; -typedef struct fdc_data *fdc_p; -typedef enum fdc_type fdc_t; - -#define FDUNIT(s) (((s)>>6)&03) -#define FDTYPE(s) ((s)&077) diff --git a/sys/pc98/pc98/ft.c b/sys/pc98/pc98/ft.c index 36630f2..c3d0c39 100644 --- a/sys/pc98/pc98/ft.c +++ b/sys/pc98/pc98/ft.c @@ -17,7 +17,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * ft.c - QIC-40/80 floppy tape driver - * $Id: ft.c,v 1.4 1996/09/03 10:23:26 asami Exp $ + * $Id: ft.c,v 1.5 1996/09/10 09:37:55 asami Exp $ * * 01/19/95 ++sg * Cleaned up recalibrate/seek code at attach time for FreeBSD 2.x. @@ -84,12 +84,11 @@ #include <i386/isa/isa_device.h> #ifdef PC98 #include <pc98/pc98/fdreg.h> -#include <pc98/pc98/fdc.h> #else #include <i386/isa/fdreg.h> -#include <i386/isa/fdc.h> #include <i386/isa/rtc.h> #endif +#include <i386/isa/fdc.h> #include <i386/isa/ftreg.h> extern int ftintr __P((ftu_t ftu)); diff --git a/sys/pc98/pc98/lpt.c b/sys/pc98/pc98/lpt.c index 0d3588c..84235d6 100644 --- a/sys/pc98/pc98/lpt.c +++ b/sys/pc98/pc98/lpt.c @@ -46,7 +46,7 @@ * SUCH DAMAGE. * * from: unknown origin, 386BSD 0.1 - * $Id: lpt.c,v 1.4 1996/09/03 10:23:44 asami Exp $ + * $Id: lpt.c,v 1.5 1996/09/10 09:38:13 asami Exp $ */ /* @@ -125,13 +125,11 @@ #ifdef PC98 #include <pc98/pc98/pc98.h> -#include <i386/isa/isa_device.h> -#include <pc98/pc98/lptreg.h> -#else /* !PC98 */ +#else #include <i386/isa/isa.h> +#endif #include <i386/isa/isa_device.h> #include <i386/isa/lptreg.h> -#endif /* PC98 */ #ifdef INET #include <sys/mbuf.h> @@ -384,16 +382,12 @@ lpt_port_test (short port, u_char data, u_char mask) * Quick exit on fail added. */ -#ifdef PC98 int lptprobe(struct isa_device *dvp) { +#ifdef PC98 return 8; -} #else -int -lptprobe(struct isa_device *dvp) -{ short port; static short next_bios_lpt = 0; int status; @@ -450,8 +444,8 @@ end_probe: outb(dvp->id_iobase+lpt_control, 0); return (status); -} #endif +} /* XXX Todo - try and detect if interrupt is working */ int diff --git a/sys/pc98/pc98/lptreg.h b/sys/pc98/pc98/lptreg.h deleted file mode 100644 index 7c3693f..0000000 --- a/sys/pc98/pc98/lptreg.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * William Jolitz. - * - * form: @(#)lptreg.h 1.1 (Berkeley) 12/19/90 - * $Id: lptreg.h,v 1.2 1993/10/16 13:46:12 rgrimes Exp $ - */ - -/* - * AT Parallel Port (for lineprinter) - * Interface port and bit definitions - * Written by William Jolitz 12/18/90 - * Copyright (C) William Jolitz 1990 - */ -#if 0 -static char rcsid[] = "$Id: lptreg.h,v 1.1 1992/11/01 20:09:14 ukai Exp $"; -#endif -/* - * modified for PC9801 by A.Kojima - * Kyoto University Microcomputer Club (KMC) - */ - -#ifdef PC98 -#define lpt_pstb_ctrl (-9) /* PSTB enable control */ -#define LPC_EN_PSTB 0xc /* PSTB enable */ -#define LPC_DIS_PSTB 0xd /* PSTB disable */ - -#define lpt_data 0 /* Data to/from printer (R/W) */ - -#define lpt_status 2 /* Status of printer (R) */ -#define LPS_NBSY 0x4 /* printer no ack of data */ - -#define lpt_control 6 /* Control printer (W) */ -#define LPC_MODE8255 0x82 /* 8255 mode */ -#define LPC_IRQ8 0x6 /* IRQ8 active */ -#define LPC_NIRQ8 0x7 /* IRQ8 inactive */ -#define LPC_PSTB 0xe /* PSTB active */ -#define LPC_NPSTB 0xf /* PSTB inactive */ - -#else /* IBM-PC */ -#define lpt_data 0 /* Data to/from printer (R/W) */ - -#define lpt_status 1 /* Status of printer (R) */ -#define LPS_NERR 0x08 /* printer no error */ -#define LPS_SEL 0x10 /* printer selected */ -#define LPS_OUT 0x20 /* printer out of paper */ -#define LPS_NACK 0x40 /* printer no ack of data */ -#define LPS_NBSY 0x80 /* printer no ack of data */ - -#define lpt_control 2 /* Control printer (R/W) */ -#define LPC_STB 0x01 /* strobe data to printer */ -#define LPC_AUTOL 0x02 /* automatic linefeed */ -#define LPC_NINIT 0x04 /* initialize printer */ -#define LPC_SEL 0x08 /* printer selected */ -#endif -#define LPC_ENA 0x10 /* printer out of paper */ diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 282b74dc..c6539d9 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.10 1996/10/23 07:25:00 asami Exp $ + * $Id: machdep.c,v 1.11 1996/10/29 08:36:16 asami Exp $ */ #include "npx.h" @@ -697,6 +697,16 @@ cpu_boot(int howto) } /* + * Shutdown the CPU as much as possible + */ +void +cpu_halt(void) +{ + for (;;) + __asm__ ("hlt"); +} + +/* * Clear registers on exec */ void diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c index bcd8f13..c72f7b8 100644 --- a/sys/pc98/pc98/sio.c +++ b/sys/pc98/pc98/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.7 1996/09/12 11:09:56 asami Exp $ + * $Id: sio.c,v 1.8 1996/10/09 21:46:46 asami Exp $ */ #include "opt_comconsole.h" @@ -423,6 +423,7 @@ static struct cdevsw sio_cdevsw = { static int comconsole = -1; static speed_t comdefaultrate = TTYDEF_SPEED; +static speed_t condefaultrate = CONSPEED; static u_int com_events; /* input chars + weighted output completions */ static int sio_timeout; static int sio_timeouts_until_log; @@ -1130,9 +1131,11 @@ sioattach(isdp) com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL; com->it_in.c_lflag = TTYDEF_LFLAG; com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; - } + com->it_in.c_ispeed = com->it_in.c_ospeed = condefaultrate; + } else + com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; + termioschars(&com->it_in); - com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; com->it_out = com->it_in; /* attempt to determine UART type */ @@ -3052,7 +3055,7 @@ siocnopen(sp) /* * Save all the device control registers except the fifo register - * and set our default ones (cs8 -parenb speed=comdefaultrate). + * and set our default ones (cs8 -parenb speed=condefaultrate). * We can't save the fifo register since it is read-only. */ iobase = siocniobase; @@ -3069,7 +3072,7 @@ siocnopen(sp) * data input register. This also reduces the effects of the * UMC8669F bug. */ - divisor = ttspeedtab(comdefaultrate, comspeedtab); + divisor = ttspeedtab(condefaultrate, comspeedtab); dlbl = divisor & 0xFF; if (sp->dlbl != dlbl) outb(iobase + com_dlbl, dlbl); diff --git a/sys/pc98/pc98/sioreg.h b/sys/pc98/pc98/sioreg.h index 70602f0..d8f8d57 100644 --- a/sys/pc98/pc98/sioreg.h +++ b/sys/pc98/pc98/sioreg.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)comreg.h 7.2 (Berkeley) 5/9/91 - * $Id: sioreg.h,v 1.4 1995/12/10 13:39:15 phk Exp $ + * $Id: sioreg.h,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $ */ @@ -123,3 +123,7 @@ #ifndef CONUNIT #define CONUNIT (0) #endif + +#ifndef CONSPEED +#define CONSPEED (9600) +#endif diff --git a/sys/pc98/pc98/sound/COPYING b/sys/pc98/pc98/sound/COPYING deleted file mode 100644 index d1509c5..0000000 --- a/sys/pc98/pc98/sound/COPYING +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ diff --git a/sys/pc98/pc98/sound/ad1848.c b/sys/pc98/pc98/sound/ad1848.c deleted file mode 100644 index 0dc5464..0000000 --- a/sys/pc98/pc98/sound/ad1848.c +++ /dev/null @@ -1,1529 +0,0 @@ -/* - * sound/ad1848.c - * - * The low level driver for the AD1848/CS4248 codec chip which - * is used for example in the MS Sound System. - * - * The CS4231 which is used in the GUS MAX and some other cards is - * upwards compatible with AD1848 and this driver is able to drive it. - * - * Copyright by Hannu Savolainen 1994, 1995 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Modified: - * Riccardo Facchetti 24 Mar 1995 - * - Added the Audio Excel DSP 16 initialization routine. - */ - -#define DEB(x) -#define DEB1(x) -#include <i386/isa/sound/sound_config.h> - -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AD1848) - -#include <i386/isa/sound/ad1848_mixer.h> - -#define IMODE_NONE 0 -#define IMODE_OUTPUT 1 -#define IMODE_INPUT 2 -#define IMODE_INIT 3 -#define IMODE_MIDI 4 - -typedef struct - { - int base; - int irq; - int dma_capture, dma_playback; - unsigned char MCE_bit; - unsigned char saved_regs[16]; - - int speed; - unsigned char speed_bits; - int channels; - int audio_format; - unsigned char format_bits; - - int xfer_count; - int irq_mode; - int intr_active; - int opened; - char *chip_name; - int mode; - - /* Mixer parameters */ - int recmask; - int supported_devices; - int supported_rec_devices; - unsigned short levels[32]; - } - -ad1848_info; - -static int nr_ad1848_devs = 0; -static char irq2dev[16] = -{-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}; - -static char mixer2codec[MAX_MIXER_DEV] = -{0}; - -static int ad_format_mask[3 /*devc->mode */ ] = -{ - 0, - AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW, - AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_U16_LE | AFMT_IMA_ADPCM -}; - -static ad1848_info dev_info[MAX_AUDIO_DEV]; - -#define io_Index_Addr(d) ((d)->base) -#define io_Indexed_Data(d) ((d)->base+1) -#define io_Status(d) ((d)->base+2) -#define io_Polled_IO(d) ((d)->base+3) - -static int ad1848_open (int dev, int mode); -static void ad1848_close (int dev); -static int ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local); -static void ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart); -static void ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart); -static int ad1848_prepare_for_IO (int dev, int bsize, int bcount); -static void ad1848_reset (int dev); -static void ad1848_halt (int dev); - -static int -ad_read (ad1848_info * devc, int reg) -{ - unsigned long flags; - int x; - int timeout = 100; - - while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */ - timeout--; - - DISABLE_INTR (flags); - OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc)); - x = INB (io_Indexed_Data (devc)); - /* printk("(%02x<-%02x) ", reg|devc->MCE_bit, x); */ - RESTORE_INTR (flags); - - return x; -} - -static void -ad_write (ad1848_info * devc, int reg, int data) -{ - unsigned long flags; - int timeout = 100; - - while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */ - timeout--; - - DISABLE_INTR (flags); - OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc)); - OUTB ((unsigned char) (data & 0xff), io_Indexed_Data (devc)); - /* printk("(%02x->%02x) ", reg|devc->MCE_bit, data); */ - RESTORE_INTR (flags); -} - -static void -wait_for_calibration (ad1848_info * devc) -{ - int timeout = 0; - - /* - * Wait until the auto calibration process has finished. - * - * 1) Wait until the chip becomes ready (reads don't return 0x80). - * 2) Wait until the ACI bit of I11 gets on and then off. - */ - - timeout = 100000; -#ifdef PC98 - while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) - timeout--; - if ((INB (devc->base) & 0x80) == 0x80) -#else - while (timeout > 0 && INB (devc->base) & 0x80) - timeout--; - if (INB (devc->base) & 0x80) -#endif - printk ("ad1848: Auto calibration timed out(1).\n"); - - timeout = 100; - while (timeout > 0 && !(ad_read (devc, 11) & 0x20)) - timeout--; - if (!(ad_read (devc, 11) & 0x20)) - return; - - timeout = 10000; - while (timeout > 0 && ad_read (devc, 11) & 0x20) - timeout--; - if (ad_read (devc, 11) & 0x20) - printk ("ad1848: Auto calibration timed out(3).\n"); -} - -static void -ad_mute (ad1848_info * devc) -{ - int i; - unsigned char prev; - - /* - * Save old register settings and mute output channels - */ - for (i = 6; i < 8; i++) - { - prev = devc->saved_regs[i] = ad_read (devc, i); - ad_write (devc, i, prev | 0x80); - } -} - -static void -ad_unmute (ad1848_info * devc) -{ - int i; - - /* - * Restore back old volume registers (unmute) - */ - for (i = 6; i < 8; i++) - { - ad_write (devc, i, devc->saved_regs[i] & ~0x80); - } -} - -static void -ad_enter_MCE (ad1848_info * devc) -{ - unsigned long flags; - int timeout = 1000; - unsigned short prev; - - while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */ - timeout--; - - DISABLE_INTR (flags); - - devc->MCE_bit = 0x40; - prev = INB (io_Index_Addr (devc)); - if (prev & 0x40) - { - RESTORE_INTR (flags); - return; - } - - OUTB (devc->MCE_bit, io_Index_Addr (devc)); - RESTORE_INTR (flags); -} - -static void -ad_leave_MCE (ad1848_info * devc) -{ - unsigned long flags; - unsigned char prev; - int timeout = 1000; - - while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */ - timeout--; - - DISABLE_INTR (flags); - - devc->MCE_bit = 0x00; - prev = INB (io_Index_Addr (devc)); - OUTB (0x00, io_Index_Addr (devc)); /* Clear the MCE bit */ - - if (prev & 0x40 == 0) /* Not in MCE mode */ - { - RESTORE_INTR (flags); - return; - } - - OUTB (0x00, io_Index_Addr (devc)); /* Clear the MCE bit */ - wait_for_calibration (devc); - RESTORE_INTR (flags); -} - - -static int -ad1848_set_recmask (ad1848_info * devc, int mask) -{ - unsigned char recdev; - int i, n; - - mask &= devc->supported_rec_devices; - - n = 0; - for (i = 0; i < 32; i++) /* Count selected device bits */ - if (mask & (1 << i)) - n++; - - if (n == 0) - mask = SOUND_MASK_MIC; - else if (n != 1) /* Too many devices selected */ - { - mask &= ~devc->recmask; /* Filter out active settings */ - - n = 0; - for (i = 0; i < 32; i++) /* Count selected device bits */ - if (mask & (1 << i)) - n++; - - if (n != 1) - mask = SOUND_MASK_MIC; - } - - switch (mask) - { - case SOUND_MASK_MIC: - recdev = 2; - break; - - case SOUND_MASK_LINE: - case SOUND_MASK_LINE3: - recdev = 0; - break; - - case SOUND_MASK_CD: - case SOUND_MASK_LINE1: - recdev = 1; - break; - - default: - mask = SOUND_MASK_MIC; - recdev = 2; - } - - recdev <<= 6; - ad_write (devc, 0, (ad_read (devc, 0) & 0x3f) | recdev); - ad_write (devc, 1, (ad_read (devc, 1) & 0x3f) | recdev); - - devc->recmask = mask; - return mask; -} - -static void -change_bits (unsigned char *regval, int dev, int chn, int newval) -{ - unsigned char mask; - int shift; - - if (mix_devices[dev][chn].polarity == 1) /* Reverse */ - newval = 100 - newval; - - mask = (1 << mix_devices[dev][chn].nbits) - 1; - shift = mix_devices[dev][chn].bitpos; - newval = (int) ((newval * mask) + 50) / 100; /* Scale it */ - - *regval &= ~(mask << shift); /* Clear bits */ - *regval |= (newval & mask) << shift; /* Set new value */ -} - -static int -ad1848_mixer_get (ad1848_info * devc, int dev) -{ - if (!((1 << dev) & devc->supported_devices)) - return RET_ERROR (EINVAL); - - return devc->levels[dev]; -} - -static int -ad1848_mixer_set (ad1848_info * devc, int dev, int value) -{ - int left = value & 0x000000ff; - int right = (value & 0x0000ff00) >> 8; - - int regoffs; - unsigned char val; - - if (left > 100) - left = 100; - if (right > 100) - right = 100; - - if (dev > 31) - return RET_ERROR (EINVAL); - - if (!(devc->supported_devices & (1 << dev))) - return RET_ERROR (EINVAL); - - if (mix_devices[dev][LEFT_CHN].nbits == 0) - return RET_ERROR (EINVAL); - - /* - * Set the left channel - */ - - regoffs = mix_devices[dev][LEFT_CHN].regno; - val = ad_read (devc, regoffs); - change_bits (&val, dev, LEFT_CHN, left); - devc->levels[dev] = left | (left << 8); - ad_write (devc, regoffs, val); - devc->saved_regs[regoffs] = val; - - /* - * Set the left right - */ - - if (mix_devices[dev][RIGHT_CHN].nbits == 0) - return left | (left << 8); /* Was just a mono channel */ - - regoffs = mix_devices[dev][RIGHT_CHN].regno; - val = ad_read (devc, regoffs); - change_bits (&val, dev, RIGHT_CHN, right); - ad_write (devc, regoffs, val); - devc->saved_regs[regoffs] = val; - - devc->levels[dev] = left | (right << 8); - return left | (right << 8); -} - -static void -ad1848_mixer_reset (ad1848_info * devc) -{ - int i; - - devc->recmask = 0; - if (devc->mode == 2) - devc->supported_devices = MODE2_MIXER_DEVICES; - else - devc->supported_devices = MODE1_MIXER_DEVICES; - - devc->supported_rec_devices = MODE1_REC_DEVICES; - - for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) - ad1848_mixer_set (devc, i, devc->levels[i] = default_mixer_levels[i]); - ad1848_set_recmask (devc, SOUND_MASK_MIC); -} - -static int -ad1848_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg) -{ - ad1848_info *devc; - - int codec_dev = mixer2codec[dev]; - - if (!codec_dev) - return RET_ERROR (ENXIO); - - codec_dev--; - - devc = (ad1848_info *) audio_devs[codec_dev]->devc; - - if (((cmd >> 8) & 0xff) == 'M') - { - if (cmd & IOC_IN) - switch (cmd & 0xff) - { - case SOUND_MIXER_RECSRC: - return IOCTL_OUT (arg, ad1848_set_recmask (devc, IOCTL_IN (arg))); - break; - - default: - return IOCTL_OUT (arg, ad1848_mixer_set (devc, cmd & 0xff, IOCTL_IN (arg))); - } - else - switch (cmd & 0xff) /* - * Return parameters - */ - { - - case SOUND_MIXER_RECSRC: - return IOCTL_OUT (arg, devc->recmask); - break; - - case SOUND_MIXER_DEVMASK: - return IOCTL_OUT (arg, devc->supported_devices); - break; - - case SOUND_MIXER_STEREODEVS: - return IOCTL_OUT (arg, devc->supported_devices & - ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX)); - break; - - case SOUND_MIXER_RECMASK: - return IOCTL_OUT (arg, devc->supported_rec_devices); - break; - - case SOUND_MIXER_CAPS: - return IOCTL_OUT (arg, SOUND_CAP_EXCL_INPUT); - break; - - default: - return IOCTL_OUT (arg, ad1848_mixer_get (devc, cmd & 0xff)); - } - } - else - return RET_ERROR (EINVAL); -} - -static struct audio_operations ad1848_pcm_operations[MAX_AUDIO_DEV] = -{ - { - "Generic AD1848 codec", -#ifdef PC98 - NEEDS_RESTART, -#else - DMA_AUTOMODE, -#endif - AFMT_U8, /* Will be set later */ - NULL, - ad1848_open, - ad1848_close, - ad1848_output_block, - ad1848_start_input, - ad1848_ioctl, - ad1848_prepare_for_IO, - ad1848_prepare_for_IO, - ad1848_reset, - ad1848_halt, - NULL, - NULL - }}; - -static struct mixer_operations ad1848_mixer_operations = -{ - "AD1848/CS4248/CS4231", - ad1848_mixer_ioctl -}; - -static int -ad1848_open (int dev, int mode) -{ - int err; - ad1848_info *devc = NULL; - unsigned long flags; - - DEB (printk ("ad1848_open(int mode = %X)\n", mode)); - - if (dev < 0 || dev >= num_audiodevs) - return RET_ERROR (ENXIO); - - devc = (ad1848_info *) audio_devs[dev]->devc; - - DISABLE_INTR (flags); - if (devc->opened) - { - RESTORE_INTR (flags); - printk ("ad1848: Already opened\n"); - return RET_ERROR (EBUSY); - } - - if (devc->irq) /* Not managed by another driver */ - if ((err = snd_set_irq_handler (devc->irq, ad1848_interrupt, - audio_devs[dev]->name)) < 0) - { - printk ("ad1848: IRQ in use\n"); - RESTORE_INTR (flags); - return err; - } - - if (DMAbuf_open_dma (dev) < 0) - { - RESTORE_INTR (flags); - printk ("ad1848: DMA in use\n"); - return RET_ERROR (EBUSY); - } - - devc->intr_active = 0; - devc->opened = 1; - RESTORE_INTR (flags); - - return 0; -} - -static void -ad1848_close (int dev) -{ - unsigned long flags; - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - DEB (printk ("ad1848_close(void)\n")); - - DISABLE_INTR (flags); - - devc->intr_active = 0; - if (devc->irq) /* Not managed by another driver */ - snd_release_irq (devc->irq); - ad1848_reset (dev); - DMAbuf_close_dma (dev); - devc->opened = 0; - - RESTORE_INTR (flags); -} - -static int -set_speed (ad1848_info * devc, int arg) -{ - /* - * The sampling speed is encoded in the least significant nible of I8. The - * LSB selects the clock source (0=24.576 MHz, 1=16.9344 Mhz) and other - * three bits select the divisor (indirectly): - * - * The available speeds are in the following table. Keep the speeds in - * the increasing order. - */ - typedef struct - { - int speed; - unsigned char bits; - } - speed_struct; - - static speed_struct speed_table[] = - { - {5510, (0 << 1) | 1}, - {5510, (0 << 1) | 1}, - {6620, (7 << 1) | 1}, - {8000, (0 << 1) | 0}, - {9600, (7 << 1) | 0}, - {11025, (1 << 1) | 1}, - {16000, (1 << 1) | 0}, - {18900, (2 << 1) | 1}, - {22050, (3 << 1) | 1}, - {27420, (2 << 1) | 0}, - {32000, (3 << 1) | 0}, - {33075, (6 << 1) | 1}, - {37800, (4 << 1) | 1}, - {44100, (5 << 1) | 1}, - {48000, (6 << 1) | 0} - }; - - int i, n, selected = -1; - - n = sizeof (speed_table) / sizeof (speed_struct); - - if (arg < speed_table[0].speed) - selected = 0; - if (arg > speed_table[n - 1].speed) - selected = n - 1; - - for (i = 1 /*really */ ; selected == -1 && i < n; i++) - if (speed_table[i].speed == arg) - selected = i; - else if (speed_table[i].speed > arg) - { - int diff1, diff2; - - diff1 = arg - speed_table[i - 1].speed; - diff2 = speed_table[i].speed - arg; - - if (diff1 < diff2) - selected = i - 1; - else - selected = i; - } - - if (selected == -1) - { - printk ("ad1848: Can't find speed???\n"); - selected = 3; - } - - devc->speed = speed_table[selected].speed; - devc->speed_bits = speed_table[selected].bits; - return devc->speed; -} - -static int -set_channels (ad1848_info * devc, int arg) -{ - if (arg != 1 && arg != 2) - return devc->channels; - - devc->channels = arg; - return arg; -} - -static int -set_format (ad1848_info * devc, int arg) -{ - - static struct format_tbl - { - int format; - unsigned char bits; - } - format2bits[] = - { - { - 0, 0 - } - , - { - AFMT_MU_LAW, 1 - } - , - { - AFMT_A_LAW, 3 - } - , - { - AFMT_IMA_ADPCM, 5 - } - , - { - AFMT_U8, 0 - } - , - { - AFMT_S16_LE, 2 - } - , - { - AFMT_S16_BE, 6 - } - , - { - AFMT_S8, 0 - } - , - { - AFMT_U16_LE, 0 - } - , - { - AFMT_U16_BE, 0 - } - }; - int i, n = sizeof (format2bits) / sizeof (struct format_tbl); - - if (!(arg & ad_format_mask[devc->mode])) - arg = AFMT_U8; - - devc->audio_format = arg; - - for (i = 0; i < n; i++) - if (format2bits[i].format == arg) - { - if ((devc->format_bits = format2bits[i].bits) == 0) - return devc->audio_format = AFMT_U8; /* Was not supported */ - - return arg; - } - - /* Still hanging here. Something must be terribly wrong */ - devc->format_bits = 0; - return devc->audio_format = AFMT_U8; -} - -static int -ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) -{ - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - switch (cmd) - { - case SOUND_PCM_WRITE_RATE: - if (local) - return set_speed (devc, arg); - return IOCTL_OUT (arg, set_speed (devc, IOCTL_IN (arg))); - - case SOUND_PCM_READ_RATE: - if (local) - return devc->speed; - return IOCTL_OUT (arg, devc->speed); - - case SNDCTL_DSP_STEREO: - if (local) - return set_channels (devc, arg + 1) - 1; - return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg) + 1) - 1); - - case SOUND_PCM_WRITE_CHANNELS: - if (local) - return set_channels (devc, arg); - return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg))); - - case SOUND_PCM_READ_CHANNELS: - if (local) - return devc->channels; - return IOCTL_OUT (arg, devc->channels); - - case SNDCTL_DSP_SAMPLESIZE: - if (local) - return set_format (devc, arg); - return IOCTL_OUT (arg, set_format (devc, IOCTL_IN (arg))); - - case SOUND_PCM_READ_BITS: - if (local) - return devc->audio_format; - return IOCTL_OUT (arg, devc->audio_format); - - default:; - } - return RET_ERROR (EINVAL); -} - -static void -ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart) -{ - unsigned long flags, cnt; - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - cnt = count; - - if (devc->audio_format == AFMT_IMA_ADPCM) - { - cnt /= 4; - } - else - { - if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */ - cnt >>= 1; - } - if (devc->channels > 1) - cnt >>= 1; - cnt--; - - if (audio_devs[dev]->flags & DMA_AUTOMODE && - intrflag && - cnt == devc->xfer_count) - { - devc->irq_mode = IMODE_OUTPUT; - devc->intr_active = 1; - return; /* - * Auto DMA mode on. No need to react - */ - } - DISABLE_INTR (flags); - - if (dma_restart) - { - /* ad1848_halt (dev); */ - DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); - } - - ad_enter_MCE (devc); - - ad_write (devc, 15, (unsigned char) (cnt & 0xff)); - ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff)); - - ad_write (devc, 9, 0x0d); /* - * Playback enable, single DMA channel mode, - * auto calibration on. - */ - - ad_leave_MCE (devc); /* - * Starts the calibration process and - * enters playback mode after it. - */ - ad_unmute (devc); - - devc->xfer_count = cnt; - devc->irq_mode = IMODE_OUTPUT; - devc->intr_active = 1; - INB (io_Status (devc)); - OUTB (0, io_Status (devc)); /* Clear pending interrupts */ - RESTORE_INTR (flags); -} - -static void -ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart) -{ - unsigned long flags, cnt; - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - int count_reg = 14; /* (devc->mode == 1) ? 14 : 30; */ - - cnt = count; - if (devc->audio_format == AFMT_IMA_ADPCM) - { - cnt /= 4; - } - else - { - if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */ - cnt >>= 1; - } - if (devc->channels > 1) - cnt >>= 1; - cnt--; - - if (audio_devs[dev]->flags & DMA_AUTOMODE && - intrflag && - cnt == devc->xfer_count) - { - devc->irq_mode = IMODE_INPUT; - devc->intr_active = 1; - return; /* - * Auto DMA mode on. No need to react - */ - } - DISABLE_INTR (flags); - - if (dma_restart) - { - /* ad1848_halt (dev); */ - DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); - } - - ad_enter_MCE (devc); - - ad_write (devc, count_reg + 1, (unsigned char) (cnt & 0xff)); - ad_write (devc, count_reg, (unsigned char) ((cnt >> 8) & 0xff)); - - ad_write (devc, 9, 0x0e); /* - * Capture enable, single DMA channel mode, - * auto calibration on. - */ - - ad_leave_MCE (devc); /* - * Starts the calibration process and - * enters playback mode after it. - */ - ad_unmute (devc); - - devc->xfer_count = cnt; - devc->irq_mode = IMODE_INPUT; - devc->intr_active = 1; - INB (io_Status (devc)); - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - RESTORE_INTR (flags); -} - -static int -ad1848_prepare_for_IO (int dev, int bsize, int bcount) -{ - int timeout; - unsigned char fs; - unsigned long flags; - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - DISABLE_INTR (flags); - ad_enter_MCE (devc); /* Enables changes to the format select reg */ - fs = devc->speed_bits | (devc->format_bits << 5); - - if (devc->channels > 1) - fs |= 0x10; - - ad_write (devc, 8, fs); - /* - * Write to I8 starts resyncronization. Wait until it completes. - */ - timeout = 10000; -#ifdef PC98 - while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) -#else - while (timeout > 0 && INB (devc->base) == 0x80) -#endif - timeout--; - -#ifdef PC98 - ad_write (devc, 8, fs); - /* - * Write to I8 starts resyncronization. Wait until it completes. - */ - timeout = 10000; - while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) - timeout--; -#endif - - /* - * If mode == 2 (CS4231), set I28 also. It's the capture format register. - */ - if (devc->mode == 2) - { - ad_write (devc, 28, fs); - - /* - * Write to I28 starts resyncronization. Wait until it completes. - */ - timeout = 10000; -#ifdef PC98 - while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) -#else - while (timeout > 0 && INB (devc->base) == 0x80) -#endif - timeout--; - - } - -#ifdef PC98 - ad_write (devc, 28, fs); - - /* - * Write to I28 starts resyncronization. Wait until it completes. - */ - timeout = 10000; - while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80) - timeout--; -#endif - - ad_leave_MCE (devc); /* - * Starts the calibration process and - * enters playback mode after it. - */ - RESTORE_INTR (flags); - devc->xfer_count = 0; - return 0; -} - -static void -ad1848_reset (int dev) -{ - ad1848_halt (dev); -} - -static void -ad1848_halt (int dev) -{ - ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - - ad_mute (devc); -#ifdef PC98 - ad_enter_MCE (devc); -#endif - ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */ -#ifdef PC98 - ad_leave_MCE (devc); -#endif - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - - ad_enter_MCE (devc); - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - ad_write (devc, 15, 0); /* Clear DMA counter */ - ad_write (devc, 14, 0); /* Clear DMA counter */ - - if (devc->mode == 2) - { - ad_write (devc, 30, 0); /* Clear DMA counter */ - ad_write (devc, 31, 0); /* Clear DMA counter */ - } - - ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */ - - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - ad_leave_MCE (devc); - - DMAbuf_reset_dma (dev); -} - -int -ad1848_detect (int io_base) -{ - - unsigned char tmp; - int i; - ad1848_info *devc = &dev_info[nr_ad1848_devs]; - unsigned char tmp1 = 0xff, tmp2 = 0xff; - - if (nr_ad1848_devs >= MAX_AUDIO_DEV) - { - AUDIO_DDB (printk ("ad1848 detect error - step 0\n")); - return 0; - } - - devc->base = io_base; - devc->MCE_bit = 0x40; - devc->irq = 0; - devc->dma_capture = 0; - devc->dma_playback = 0; - devc->opened = 0; - devc->chip_name = "AD1848"; - devc->mode = 1; /* MODE1 = original AD1848 */ - - /* - * Check that the I/O address is in use. - * - * The bit 0x80 of the base I/O port is known to be 0 after the - * chip has performed it's power on initialization. Just assume - * this has happened before the OS is starting. - * - * If the I/O address is unused, it typically returns 0xff. - */ - - if ((INB (devc->base) & 0x80) != 0x00) /* Not a AD1884 */ - { - AUDIO_DDB (printk ("ad1848 detect error - step A\n")); - return 0; - } - - /* - * Test if it's possible to change contents of the indirect registers. - * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only - * so try to avoid using it. - */ - - ad_write (devc, 0, 0xaa); - ad_write (devc, 1, 0x45); /* 0x55 with bit 0x10 clear */ - - if ((tmp1 = ad_read (devc, 0)) != 0xaa || (tmp2 = ad_read (devc, 1)) != 0x45) - { - AUDIO_DDB (printk ("ad1848 detect error - step B (%x/%x)\n", tmp1, tmp2)); - return 0; - } - - ad_write (devc, 0, 0x45); - ad_write (devc, 1, 0xaa); - - if ((tmp1 = ad_read (devc, 0)) != 0x45 || (tmp2 = ad_read (devc, 1)) != 0xaa) - { - AUDIO_DDB (printk ("ad1848 detect error - step C (%x/%x)\n", tmp1, tmp2)); - return 0; - } - - /* - * The indirect register I12 has some read only bits. Lets - * try to change them. - */ - - tmp = ad_read (devc, 12); - ad_write (devc, 12, (~tmp) & 0x0f); - - if ((tmp & 0x0f) != ((tmp1 = ad_read (devc, 12)) & 0x0f)) - { - AUDIO_DDB (printk ("ad1848 detect error - step D (%x)\n", tmp1)); - return 0; - } - - /* - * NOTE! Last 4 bits of the reg I12 tell the chip revision. - * 0x01=RevB and 0x0A=RevC. - */ - - /* - * The original AD1848/CS4248 has just 15 indirect registers. This means - * that I0 and I16 should return the same value (etc.). - * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails - * with CS4231. - */ - - ad_write (devc, 12, 0); /* Mode2=disabled */ - - for (i = 0; i < 16; i++) - if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16))) - { - AUDIO_DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2)); - return 0; - } - - /* - * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40). - * The bit 0x80 is always 1 in CS4248 and CS4231. - */ - - ad_write (devc, 12, 0x40); /* Set mode2, clear 0x80 */ - - tmp1 = ad_read (devc, 12); - if (tmp1 & 0x80) - devc->chip_name = "CS4248"; /* Our best knowledge just now */ - - if ((tmp1 & 0xc0) == (0x80 | 0x40)) - { - /* - * CS4231 detected - is it? - * - * Verify that setting I0 doesn't change I16. - */ - ad_write (devc, 16, 0); /* Set I16 to known value */ - - ad_write (devc, 0, 0x45); - if ((tmp1 = ad_read (devc, 16)) != 0x45) /* No change -> CS4231? */ - { - - ad_write (devc, 0, 0xaa); - if ((tmp1 = ad_read (devc, 16)) == 0xaa) /* Rotten bits? */ - { - AUDIO_DDB (printk ("ad1848 detect error - step H(%x)\n", tmp1)); - return 0; - } - - /* - * Verify that some bits of I25 are read only. - */ - - tmp1 = ad_read (devc, 25); /* Original bits */ - ad_write (devc, 25, ~tmp1); /* Invert all bits */ - if ((ad_read (devc, 25) & 0xe7) == (tmp1 & 0xe7)) - { - /* - * It's a CS4231 - */ - devc->chip_name = "CS4231"; - - -#ifdef MOZART_PORT - if (devc->base != MOZART_PORT) -#endif - devc->mode = 2; - - - } - ad_write (devc, 25, tmp1); /* Restore bits */ - } - } - - return 1; -} - -void -ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture) -{ - /* - * NOTE! If irq < 0, there is another driver which has allocated the IRQ - * so that this driver doesn't need to allocate/deallocate it. - * The actually used IRQ is ABS(irq). - */ - - /* - * Initial values for the indirect registers of CS4248/AD1848. - */ - static int init_values[] = - { - 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x80, 0x80, - 0x00, 0x08, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00, - - /* Positions 16 to 31 just for CS4231 */ - 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - int i, my_dev; - ad1848_info *devc = &dev_info[nr_ad1848_devs]; - - if (!ad1848_detect (io_base)) - return; - - devc->irq = (irq > 0) ? irq : 0; - devc->dma_capture = dma_playback; - devc->dma_playback = dma_capture; - devc->opened = 0; - - if (nr_ad1848_devs != 0) - { - memcpy ((char *) &ad1848_pcm_operations[nr_ad1848_devs], - (char *) &ad1848_pcm_operations[0], - sizeof (struct audio_operations)); - } - - for (i = 0; i < 16; i++) - ad_write (devc, i, init_values[i]); - - ad_mute (devc); - - if (devc->mode == 2) - { - ad_write (devc, 12, ad_read (devc, 12) | 0x40); /* Mode2 = enabled */ - for (i = 16; i < 32; i++) - ad_write (devc, i, init_values[i]); - } - - OUTB (0, io_Status (devc)); /* Clear pending interrupts */ - - if (name[0] != 0) - sprintf (ad1848_pcm_operations[nr_ad1848_devs].name, - "%s (%s)", name, devc->chip_name); - else - sprintf (ad1848_pcm_operations[nr_ad1848_devs].name, - "Generic audio codec (%s)", devc->chip_name); - -#if defined(__FreeBSD__) - if (strcmp(name, "MS Sound System")) /* *sigh* */ - printk ("\ngus0: <%s>", ad1848_pcm_operations[nr_ad1848_devs].name); - else - printk ("mss0: <%s>", ad1848_pcm_operations[nr_ad1848_devs].name); -#else - printk (" <%s>", ad1848_pcm_operations[nr_ad1848_devs].name); -#endif - - if (num_audiodevs < MAX_AUDIO_DEV) - { - audio_devs[my_dev = num_audiodevs++] = &ad1848_pcm_operations[nr_ad1848_devs]; - if (irq > 0) - irq2dev[irq] = my_dev; - else if (irq < 0) - irq2dev[-irq] = my_dev; - - audio_devs[my_dev]->dmachan = dma_playback; - audio_devs[my_dev]->buffcount = 1; - audio_devs[my_dev]->buffsize = DSP_BUFFSIZE; - audio_devs[my_dev]->devc = devc; - audio_devs[my_dev]->format_mask = ad_format_mask[devc->mode]; - nr_ad1848_devs++; - - /* - * Toggle the MCE bit. It completes the initialization phase. - */ - - ad_enter_MCE (devc); /* In case the bit was off */ - ad_leave_MCE (devc); - - if (num_mixers < MAX_MIXER_DEV) - { - mixer2codec[num_mixers] = my_dev + 1; - audio_devs[my_dev]->mixer_dev = num_mixers; - mixer_devs[num_mixers++] = &ad1848_mixer_operations; - ad1848_mixer_reset (devc); - } - } - else - printk ("AD1848: Too many PCM devices available\n"); -} - -void -ad1848_interrupt (INT_HANDLER_PARMS (irq, dummy)) -{ - unsigned char status; - ad1848_info *devc; - int dev; - - if (irq < 0 || irq > 15) - return; /* Bogus irq */ - dev = irq2dev[irq]; - if (dev < 0 || dev >= num_audiodevs) - return; /* Bogus dev */ - - devc = (ad1848_info *) audio_devs[dev]->devc; - status = INB (io_Status (devc)); - - if (status == 0x80) - printk ("ad1848_interrupt: Why?\n"); - - if (status & 0x01) - { - if (devc->opened && devc->irq_mode == IMODE_OUTPUT) - { - DMAbuf_outputintr (dev, 1); - } - - if (devc->opened && devc->irq_mode == IMODE_INPUT) - DMAbuf_inputintr (dev); - } - - OUTB (0, io_Status (devc)); /* Clear interrupt status */ - - status = INB (io_Status (devc)); - if (status == 0x80 || status & 0x01) - { - printk ("ad1848: Problems when clearing interrupt, status=%x\n", status); - OUTB (0, io_Status (devc)); /* Try again */ - } -} - -#ifdef MOZART_PORT -/* - * Experimental initialization sequence for Mozart soundcard - * (OAK OTI-601 sound chip). - * by Gregor Hoffleit <flight@mathi.uni-heidelberg.de> - * Some comments by Hannu Savolainen. - */ - -int -mozart_init (int io_base) -{ - int i; - unsigned char byte; - static int mozart_detected_here = 0; - - /* - * Valid ports are 0x530 and 0xf40. The DOS based software doesn't allow - * other ports. The OTI-601 preliminary specification says that - * 0xe80 and 0x604 are also possible but it's safest to ignore them. - */ - - if ((io_base != 0x530) && (io_base != 0xf40)) - { - printk ("Mozart: invalid io_base(%x)\n", io_base); - return 0; - } - - if (mozart_detected_here == io_base) /* Already detected this card */ - return 1; - - if (mozart_detected_here != 0) - return 0; /* Don't allow detecting another Mozart card. */ - - /* - * The Mozart chip (OAK OTI-601) must be enabled before _each_ write - * by writing a secret password (0xE2) to the password register (0xf8f). - * Any I/O cycle after writing the password closes the gate and disbles - * further access. - */ - - if (INB (0xf88) != 0) /* Appears to return 0 while the gate is closed */ - { - AUDIO_DDB (printk ("No Mozart signature detected on port 0xf88\n")); - return 0; - } - - OUTB (0xe2, 0xf8f); /* A secret password which opens the gate */ - OUTB (0x10, 0xf91); /* Enable access to codec registers during SB mode */ - for (i = 0; i < 100; i++) /* Delay */ - tenmicrosec (); - OUTB (0xe2, 0xf8f); /* Sesam */ - byte = INB (0xf8d); /* Read MC1 (Mode control register) */ - - /* Read the same register again but with gate closed at this time. */ - if (INB (0xf8d) == 0xff) /* Bus float. Should be 0 if Mozart present */ - { - AUDIO_DDB (printk ("Seems to be no Mozart chip set\n")); - return 0; - } - AUDIO_DDB (printk ("mozart_init: read 0x%x on 0xf8d\n", byte)); - byte = byte | 0x80; /* Switch to WSS mode (disables SB) */ - byte = byte & 0xcf; /* Clear sound base, disable CD, enable joystick */ - - if (io_base == 0xf40) - byte = byte | 0x20; - for (i = 0; i < 100; i++) - tenmicrosec (); - OUTB (0xe2, 0xf8f); /* Open the gate again */ - OUTB (byte, 0xf8d); /* Write the modified value back to MC1 */ - AUDIO_DDB (printk ("mozart_init: wrote 0x%x on 0xf8d\n", byte)); - OUTB (0xe2, 0xf8f); /* Here we come again */ - OUTB (0x20, 0xf91); /* Protect WSS shadow registers against write */ - - for (i = 0; i < 1000; i++) - tenmicrosec (); - - return 1; -} - -#endif /* MOZART_PORT */ - -#ifdef OPTI_MAD16_PORT -#include <i386/isa/sound/mad16.h> -#endif - -/* - * Some extra code for the MS Sound System - */ - -int -probe_ms_sound (struct address_info *hw_config) -{ -#if !defined(EXCLUDE_AEDSP16) && defined(AEDSP16_MSS) - /* - * Initialize Audio Excel DSP 16 to MSS: before any operation - * we must enable MSS I/O ports. - */ - - InitAEDSP16_MSS (hw_config); -#endif - - /* - * Check if the IO port returns valid signature. The original MS Sound - * system returns 0x04 while some cards (AudioTriX Pro for example) - * return 0x00. - */ - -#ifdef MOZART_PORT - if (hw_config->io_base == MOZART_PORT) - mozart_init (hw_config->io_base); -#endif - -#ifdef OPTI_MAD16_PORT - if (hw_config->io_base == OPTI_MAD16_PORT) - mad16init (hw_config->io_base); -#endif - - if ((INB (hw_config->io_base + 3) & 0x3f) != 0x04 && - (INB (hw_config->io_base + 3) & 0x3f) != 0x00) - { - AUDIO_DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n", - hw_config->io_base, INB (hw_config->io_base + 3))); - return 0; - } - -#ifdef PC98 - if (hw_config->irq > 12) -#else - if (hw_config->irq > 11) -#endif - { - printk ("MSS: Bad IRQ %d\n", hw_config->irq); - return 0; - } - - if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) - { - printk ("MSS: Bad DMA %d\n", hw_config->dma); - return 0; - } - - /* - * Check that DMA0 is not in use with a 8 bit board. - */ - - if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80) - { - printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n"); - return 0; - } - - if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80) - { - printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); - return 0; - } - - return ad1848_detect (hw_config->io_base + 4); -} - -long -attach_ms_sound (long mem_start, struct address_info *hw_config) -{ -#ifdef PC98 - static char interrupt_bits[13] = - { - -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, 0x18, -1, 0x20 - }; -#else - static char interrupt_bits[12] = - { - -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20 - }; -#endif - char bits; - - static char dma_bits[4] = - { - 1, 2, 0, 3 - }; - - int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3; - - if (!ad1848_detect (hw_config->io_base + 4)) - return mem_start; - - /* - * Set the IRQ and DMA addresses. - */ - - bits = interrupt_bits[hw_config->irq]; - if (bits == -1) - return mem_start; - - OUTB (bits | 0x40, config_port); - if ((INB (version_port) & 0x40) == 0) - printk ("[IRQ Conflict?]"); - - OUTB (bits | dma_bits[hw_config->dma], config_port); /* Write IRQ+DMA setup */ - - ad1848_init ("MS Sound System", hw_config->io_base + 4, - hw_config->irq, - hw_config->dma, - hw_config->dma); - return mem_start; -} - -#endif diff --git a/sys/pc98/pc98/sound/opl3.c b/sys/pc98/pc98/sound/opl3.c deleted file mode 100644 index 42379cd..0000000 --- a/sys/pc98/pc98/sound/opl3.c +++ /dev/null @@ -1,1292 +0,0 @@ -/* - * sound/opl3.c - * - * A low level driver for Yamaha YM3812 and OPL-3 -chips - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/* - * Major improvements to the FM handling 30AUG92 by Rob Hooft, - */ -/* - * hooft@chem.ruu.nl - */ - -#include <i386/isa/sound/sound_config.h> - -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812) - -#include <i386/isa/sound/opl3.h> - -#define MAX_VOICE 18 -#define OFFS_4OP 11 /* - * * * Definitions for the operators OP3 and - * * OP4 * * begin here */ - -static int opl3_enabled = 0; -static int opl4_enabled = 0; -#ifdef PC98 -static int left_address = 0x28d2, right_address = 0x28d2, both_address = 0; -#else -static int left_address = 0x388, right_address = 0x388, both_address = 0; -#endif - -static int nr_voices = 9; -static int logical_voices[MAX_VOICE] = -{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; - -struct voice_info - { - unsigned char keyon_byte; - long bender; - long bender_range; - unsigned long orig_freq; - unsigned long current_freq; - int mode; - }; - -static struct voice_info voices[MAX_VOICE]; -static struct voice_alloc_info *voice_alloc; -static struct channel_info *chn_info; - -static struct sbi_instrument *instrmap; -static struct sbi_instrument *active_instrument[MAX_VOICE] = -{NULL}; - -static struct synth_info fm_info = -{"OPL-2", 0, SYNTH_TYPE_FM, FM_TYPE_ADLIB, 0, 9, 0, SBFM_MAXINSTR, 0}; - -static int already_initialized = 0; - -static int opl3_ok = 0; -static int opl3_busy = 0; -static int fm_model = 0; /* - - - * * * * 0=no fm, 1=mono, 2=SB Pro 1, 3=SB - * Pro 2 * * */ - -static int store_instr (int instr_no, struct sbi_instrument *instr); -static void freq_to_fnum (int freq, int *block, int *fnum); -static void opl3_command (int io_addr, unsigned int addr, unsigned int val); -static int opl3_kill_note (int dev, int voice, int note, int velocity); -static unsigned char connection_mask = 0x00; - -void -enable_opl3_mode (int left, int right, int both) -{ - if (opl3_enabled) - return; - - opl3_enabled = 1; - left_address = left; - right_address = right; - both_address = both; - fm_info.capabilities = SYNTH_CAP_OPL3; - fm_info.synth_subtype = FM_TYPE_OPL3; -} - -static void -enter_4op_mode (void) -{ - int i; - static int voices_4op[MAX_VOICE] = - {0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17}; - - connection_mask = 0x3f; /* Connect all possible 4 OP voices */ - opl3_command (right_address, CONNECTION_SELECT_REGISTER, 0x3f); - - for (i = 0; i < 3; i++) - physical_voices[i].voice_mode = 4; - for (i = 3; i < 6; i++) - physical_voices[i].voice_mode = 0; - - for (i = 9; i < 12; i++) - physical_voices[i].voice_mode = 4; - for (i = 12; i < 15; i++) - physical_voices[i].voice_mode = 0; - - for (i = 0; i < 12; i++) - logical_voices[i] = voices_4op[i]; - voice_alloc->max_voice = nr_voices = 12; -} - -static int -opl3_ioctl (int dev, - unsigned int cmd, unsigned int arg) -{ - switch (cmd) - { - - case SNDCTL_FM_LOAD_INSTR: - { - struct sbi_instrument ins; - - IOCTL_FROM_USER ((char *) &ins, (char *) arg, 0, sizeof (ins)); - - if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) - { - printk ("FM Error: Invalid instrument number %d\n", ins.channel); - return RET_ERROR (EINVAL); - } - - pmgr_inform (dev, PM_E_PATCH_LOADED, ins.channel, 0, 0, 0); - return store_instr (ins.channel, &ins); - } - break; - - case SNDCTL_SYNTH_INFO: - fm_info.nr_voices = (nr_voices == 12) ? 6 : nr_voices; - - IOCTL_TO_USER ((char *) arg, 0, &fm_info, sizeof (fm_info)); - return 0; - break; - - case SNDCTL_SYNTH_MEMAVL: - return 0x7fffffff; - break; - - case SNDCTL_FM_4OP_ENABLE: - if (opl3_enabled) - enter_4op_mode (); - return 0; - break; - - default: - return RET_ERROR (EINVAL); - } - -} - -int -opl3_detect (int ioaddr) -{ - /* - * This function returns 1 if the FM chicp is present at the given I/O port - * The detection algorithm plays with the timer built in the FM chip and - * looks for a change in the status register. - * - * Note! The timers of the FM chip are not connected to AdLib (and compatible) - * boards. - * - * Note2! The chip is initialized if detected. - */ - - unsigned char stat1, stat2, signature; - int i; - - if (already_initialized) - { - return 0; /* - * Do avoid duplicate initializations - */ - } - - if (opl3_enabled) - ioaddr = left_address; - - /* Reset timers 1 and 2 */ - opl3_command (ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); - - /* Reset the IRQ of the FM chip */ - opl3_command (ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET); - - signature = stat1 = INB (ioaddr); /* Status register */ - - if ((stat1 & 0xE0) != 0x00) - { - return 0; /* - * Should be 0x00 - */ - } - - opl3_command (ioaddr, TIMER1_REGISTER, 0xff); /* Set timer1 to 0xff */ - - opl3_command (ioaddr, TIMER_CONTROL_REGISTER, - TIMER2_MASK | TIMER1_START); /* - * Unmask and start timer 1 - */ - - /* - * Now we have to delay at least 80 usec - */ - - for (i = 0; i < 50; i++) - tenmicrosec (); - - stat2 = INB (ioaddr); /* - * Read status after timers have expired - */ - - /* - * Stop the timers - */ - - /* Reset timers 1 and 2 */ - opl3_command (ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); - /* Reset the IRQ of the FM chip */ - opl3_command (ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET); - - if ((stat2 & 0xE0) != 0xc0) - { - return 0; /* - * There is no YM3812 - */ - } - - /* - * There is a FM chicp in this address. Detect the type (OPL2 to OPL4) - */ - - if (signature == 0x06) /* OPL2 */ - { - opl3_enabled = 0; - } - else if (signature == 0x00) /* OPL3 or OPL4 */ - { - unsigned char tmp; - - if (!opl3_enabled) /* Was not already enabled */ - { - left_address = ioaddr; - right_address = ioaddr + 2; - opl3_enabled = 1; - } - - /* - * Detect availability of OPL4 (_experimental_). Works propably - * only after a cold boot. In addition the OPL4 port - * of the chip may not be connected to the PC bus at all. - */ - - opl3_command (right_address, OPL3_MODE_REGISTER, 0x00); - opl3_command (right_address, OPL3_MODE_REGISTER, OPL3_ENABLE | OPL4_ENABLE); - - if ((tmp = INB (ioaddr)) == 0x02) /* Have a OPL4 */ - { - opl4_enabled = 1; - } - opl3_command (right_address, OPL3_MODE_REGISTER, 0); - - } - - for (i = 0; i < 9; i++) - opl3_command (ioaddr, KEYON_BLOCK + i, 0); /* - * Note off - */ - - opl3_command (ioaddr, TEST_REGISTER, ENABLE_WAVE_SELECT); - opl3_command (ioaddr, PERCUSSION_REGISTER, 0x00); /* - * Melodic mode. - */ - - return 1; -} - -static int -opl3_kill_note (int dev, int voice, int note, int velocity) -{ - struct physical_voice_info *map; - - if (voice < 0 || voice >= nr_voices) - return 0; - - voice_alloc->map[voice] = 0; - - map = &physical_voices[logical_voices[voice]]; - - DEB (printk ("Kill note %d\n", voice)); - - if (map->voice_mode == 0) - return 0; - - opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, voices[voice].keyon_byte & ~0x20); - - voices[voice].keyon_byte = 0; - voices[voice].bender = 0; - voices[voice].bender_range = 200; /* - * 200 cents = 2 semitones - */ - voices[voice].orig_freq = 0; - voices[voice].current_freq = 0; - voices[voice].mode = 0; - - return 0; -} - -#define HIHAT 0 -#define CYMBAL 1 -#define TOMTOM 2 -#define SNARE 3 -#define BDRUM 4 -#define UNDEFINED TOMTOM -#define DEFAULT TOMTOM - -static int -store_instr (int instr_no, struct sbi_instrument *instr) -{ - - if (instr->key != FM_PATCH && (instr->key != OPL3_PATCH || !opl3_enabled)) - printk ("FM warning: Invalid patch format field (key) 0x%x\n", instr->key); - memcpy ((char *) &(instrmap[instr_no]), (char *) instr, sizeof (*instr)); - - return 0; -} - -static int -opl3_set_instr (int dev, int voice, int instr_no) -{ - if (voice < 0 || voice >= nr_voices) - return 0; - - if (instr_no < 0 || instr_no >= SBFM_MAXINSTR) - return 0; - - active_instrument[voice] = &instrmap[instr_no]; - return 0; -} - -/* - * The next table looks magical, but it certainly is not. Its values have - * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception - * for i=0. This log-table converts a linear volume-scaling (0..127) to a - * logarithmic scaling as present in the FM-synthesizer chips. so : Volume - * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative - * volume -8 it was implemented as a table because it is only 128 bytes and - * it saves a lot of log() calculations. (RH) - */ -static char fm_volume_table[128] = -{-64, -48, -40, -35, -32, -29, -27, -26, /* - * 0 - 7 - */ - -24, -23, -21, -20, -19, -18, -18, -17, /* - * 8 - 15 - */ - -16, -15, -15, -14, -13, -13, -12, -12, /* - * 16 - 23 - */ - -11, -11, -10, -10, -10, -9, -9, -8, /* - * 24 - 31 - */ - -8, -8, -7, -7, -7, -6, -6, -6, /* - * 32 - 39 - */ - -5, -5, -5, -5, -4, -4, -4, -4, /* - * 40 - 47 - */ - -3, -3, -3, -3, -2, -2, -2, -2, /* - * 48 - 55 - */ - -2, -1, -1, -1, -1, 0, 0, 0, /* - * 56 - 63 - */ - 0, 0, 0, 1, 1, 1, 1, 1, /* - * 64 - 71 - */ - 1, 2, 2, 2, 2, 2, 2, 2, /* - * 72 - 79 - */ - 3, 3, 3, 3, 3, 3, 3, 4, /* - * 80 - 87 - */ - 4, 4, 4, 4, 4, 4, 4, 5, /* - * 88 - 95 - */ - 5, 5, 5, 5, 5, 5, 5, 5, /* - * 96 - 103 - */ - 6, 6, 6, 6, 6, 6, 6, 6, /* - * 104 - 111 - */ - 6, 7, 7, 7, 7, 7, 7, 7, /* - * 112 - 119 - */ - 7, 7, 7, 8, 8, 8, 8, 8}; /* - - - * * * * 120 - 127 */ - -static void -calc_vol (unsigned char *regbyte, int volume) -{ - int level = (~*regbyte & 0x3f); - - if (level) - level += fm_volume_table[volume]; - - if (level > 0x3f) - level = 0x3f; - if (level < 0) - level = 0; - - *regbyte = (*regbyte & 0xc0) | (~level & 0x3f); -} - -static void -set_voice_volume (int voice, int volume) -{ - unsigned char vol1, vol2, vol3, vol4; - struct sbi_instrument *instr; - struct physical_voice_info *map; - - if (voice < 0 || voice >= nr_voices) - return; - - map = &physical_voices[logical_voices[voice]]; - - instr = active_instrument[voice]; - - if (!instr) - instr = &instrmap[0]; - - if (instr->channel < 0) - return; - - if (voices[voice].mode == 0) - return; - - if (voices[voice].mode == 2) - { /* - * 2 OP voice - */ - - vol1 = instr->operators[2]; - vol2 = instr->operators[3]; - - if ((instr->operators[10] & 0x01)) - { /* - * Additive synthesis - */ - calc_vol (&vol1, volume); - calc_vol (&vol2, volume); - } - else - { /* - * FM synthesis - */ - calc_vol (&vol2, volume); - } - - opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], vol1); /* - * Modulator - * volume - */ - opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], vol2); /* - * Carrier - * volume - */ - } - else - { /* - * 4 OP voice - */ - int connection; - - vol1 = instr->operators[2]; - vol2 = instr->operators[3]; - vol3 = instr->operators[OFFS_4OP + 2]; - vol4 = instr->operators[OFFS_4OP + 3]; - - /* - * The connection method for 4 OP voices is defined by the rightmost - * bits at the offsets 10 and 10+OFFS_4OP - */ - - connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01); - - switch (connection) - { - case 0: - calc_vol (&vol4, volume); /* - * Just the OP 4 is carrier - */ - break; - - case 1: - calc_vol (&vol2, volume); - calc_vol (&vol4, volume); - break; - - case 2: - calc_vol (&vol1, volume); - calc_vol (&vol4, volume); - break; - - case 3: - calc_vol (&vol1, volume); - calc_vol (&vol3, volume); - calc_vol (&vol4, volume); - break; - - default: /* - * Why ?? - */ ; - } - - opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], vol1); - opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], vol2); - opl3_command (map->ioaddr, KSL_LEVEL + map->op[2], vol3); - opl3_command (map->ioaddr, KSL_LEVEL + map->op[3], vol4); - } -} - -static int -opl3_start_note (int dev, int voice, int note, int volume) -{ - unsigned char data, fpc; - int block, fnum, freq, voice_mode; - struct sbi_instrument *instr; - struct physical_voice_info *map; - - if (voice < 0 || voice >= nr_voices) - return 0; - - map = &physical_voices[logical_voices[voice]]; - - if (map->voice_mode == 0) - return 0; - - if (note == 255) /* - * Just change the volume - */ - { - set_voice_volume (voice, volume); - return 0; - } - - /* - * Kill previous note before playing - */ - opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], 0xff); /* - * Carrier - * volume to - * min - */ - opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], 0xff); /* - * Modulator - * volume to - */ - - if (map->voice_mode == 4) - { - opl3_command (map->ioaddr, KSL_LEVEL + map->op[2], 0xff); - opl3_command (map->ioaddr, KSL_LEVEL + map->op[3], 0xff); - } - - opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, 0x00); /* - * Note - * off - */ - - instr = active_instrument[voice]; - - if (!instr) - instr = &instrmap[0]; - - if (instr->channel < 0) - { - printk ( - "OPL3: Initializing voice %d with undefined instrument\n", - voice); - return 0; - } - - if (map->voice_mode == 2 && instr->key == OPL3_PATCH) - return 0; /* - * Cannot play - */ - - voice_mode = map->voice_mode; - - if (voice_mode == 4) - { - int voice_shift; - - voice_shift = (map->ioaddr == left_address) ? 0 : 3; - voice_shift += map->voice_num; - - if (instr->key != OPL3_PATCH) /* - * Just 2 OP patch - */ - { - voice_mode = 2; - connection_mask &= ~(1 << voice_shift); - } - else - { - connection_mask |= (1 << voice_shift); - } - - opl3_command (right_address, CONNECTION_SELECT_REGISTER, connection_mask); - } - - /* - * Set Sound Characteristics - */ - opl3_command (map->ioaddr, AM_VIB + map->op[0], instr->operators[0]); - opl3_command (map->ioaddr, AM_VIB + map->op[1], instr->operators[1]); - - /* - * Set Attack/Decay - */ - opl3_command (map->ioaddr, ATTACK_DECAY + map->op[0], instr->operators[4]); - opl3_command (map->ioaddr, ATTACK_DECAY + map->op[1], instr->operators[5]); - - /* - * Set Sustain/Release - */ - opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[0], instr->operators[6]); - opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[1], instr->operators[7]); - - /* - * Set Wave Select - */ - opl3_command (map->ioaddr, WAVE_SELECT + map->op[0], instr->operators[8]); - opl3_command (map->ioaddr, WAVE_SELECT + map->op[1], instr->operators[9]); - - /* - * Set Feedback/Connection - */ - fpc = instr->operators[10]; - if (!(fpc & 0x30)) - fpc |= 0x30; /* - * Ensure that at least one chn is enabled - */ - opl3_command (map->ioaddr, FEEDBACK_CONNECTION + map->voice_num, - fpc); - - /* - * If the voice is a 4 OP one, initialize the operators 3 and 4 also - */ - - if (voice_mode == 4) - { - - /* - * Set Sound Characteristics - */ - opl3_command (map->ioaddr, AM_VIB + map->op[2], instr->operators[OFFS_4OP + 0]); - opl3_command (map->ioaddr, AM_VIB + map->op[3], instr->operators[OFFS_4OP + 1]); - - /* - * Set Attack/Decay - */ - opl3_command (map->ioaddr, ATTACK_DECAY + map->op[2], instr->operators[OFFS_4OP + 4]); - opl3_command (map->ioaddr, ATTACK_DECAY + map->op[3], instr->operators[OFFS_4OP + 5]); - - /* - * Set Sustain/Release - */ - opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[2], instr->operators[OFFS_4OP + 6]); - opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[3], instr->operators[OFFS_4OP + 7]); - - /* - * Set Wave Select - */ - opl3_command (map->ioaddr, WAVE_SELECT + map->op[2], instr->operators[OFFS_4OP + 8]); - opl3_command (map->ioaddr, WAVE_SELECT + map->op[3], instr->operators[OFFS_4OP + 9]); - - /* - * Set Feedback/Connection - */ - fpc = instr->operators[OFFS_4OP + 10]; - if (!(fpc & 0x30)) - fpc |= 0x30; /* - * Ensure that at least one chn is enabled - */ - opl3_command (map->ioaddr, FEEDBACK_CONNECTION + map->voice_num + 3, fpc); - } - - voices[voice].mode = voice_mode; - - set_voice_volume (voice, volume); - - freq = voices[voice].orig_freq = note_to_freq (note) / 1000; - - /* - * Since the pitch bender may have been set before playing the note, we - * have to calculate the bending now. - */ - - freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, voices[voice].bender_range); - voices[voice].current_freq = freq; - - freq_to_fnum (freq, &block, &fnum); - - /* - * Play note - */ - - data = fnum & 0xff; /* - * Least significant bits of fnumber - */ - opl3_command (map->ioaddr, FNUM_LOW + map->voice_num, data); - - data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3); - voices[voice].keyon_byte = data; - opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, data); - if (voice_mode == 4) - opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num + 3, data); - - return 0; -} - -static void -freq_to_fnum (int freq, int *block, int *fnum) -{ - int f, octave; - - /* - * Converts the note frequency to block and fnum values for the FM chip - */ - /* - * First try to compute the block -value (octave) where the note belongs - */ - - f = freq; - - octave = 5; - - if (f == 0) - octave = 0; - else if (f < 261) - { - while (f < 261) - { - octave--; - f <<= 1; - } - } - else if (f > 493) - { - while (f > 493) - { - octave++; - f >>= 1; - } - } - - if (octave > 7) - octave = 7; - - *fnum = freq * (1 << (20 - octave)) / 49716; - *block = octave; -} - -static void -opl3_command (int io_addr, unsigned int addr, unsigned int val) -{ - int i; - - /* - * The original 2-OP synth requires a quite long delay after writing to a - * register. The OPL-3 survives with just two INBs - */ - - OUTB ((unsigned char) (addr & 0xff), io_addr); /* - * Select register - * - */ - - if (!opl3_enabled) - tenmicrosec (); - else - for (i = 0; i < 2; i++) - INB (io_addr); - -#ifdef PC98 - OUTB ((unsigned char) (val & 0xff), io_addr + 0x100); -#else - OUTB ((unsigned char) (val & 0xff), io_addr + 1); /* - * Write to register - * - */ -#endif - - if (!opl3_enabled) - { - tenmicrosec (); - tenmicrosec (); - tenmicrosec (); - } - else - for (i = 0; i < 2; i++) - INB (io_addr); -} - -static void -opl3_reset (int dev) -{ - int i; - - for (i = 0; i < nr_voices; i++) - { - opl3_command (physical_voices[logical_voices[i]].ioaddr, - KSL_LEVEL + physical_voices[logical_voices[i]].op[0], 0xff); - - opl3_command (physical_voices[logical_voices[i]].ioaddr, - KSL_LEVEL + physical_voices[logical_voices[i]].op[1], 0xff); - - if (physical_voices[logical_voices[i]].voice_mode == 4) - { - opl3_command (physical_voices[logical_voices[i]].ioaddr, - KSL_LEVEL + physical_voices[logical_voices[i]].op[2], 0xff); - - opl3_command (physical_voices[logical_voices[i]].ioaddr, - KSL_LEVEL + physical_voices[logical_voices[i]].op[3], 0xff); - } - - opl3_kill_note (dev, i, 0, 64); - } - - if (opl3_enabled) - { - voice_alloc->max_voice = nr_voices = 18; - - for (i = 0; i < 18; i++) - logical_voices[i] = i; - - for (i = 0; i < 18; i++) - physical_voices[i].voice_mode = 2; - - } - -} - -static int -opl3_open (int dev, int mode) -{ - int i; - - if (!opl3_ok) - return RET_ERROR (ENXIO); - if (opl3_busy) - return RET_ERROR (EBUSY); - opl3_busy = 1; - - voice_alloc->max_voice = nr_voices = opl3_enabled ? 18 : 9; - voice_alloc->timestamp = 0; - - for (i = 0; i < 18; i++) - { - voice_alloc->map[i] = 0; - voice_alloc->alloc_times[i] = 0; - } - - connection_mask = 0x00; /* - * Just 2 OP voices - */ - if (opl3_enabled) - opl3_command (right_address, CONNECTION_SELECT_REGISTER, connection_mask); - return 0; -} - -static void -opl3_close (int dev) -{ - opl3_busy = 0; - voice_alloc->max_voice = nr_voices = opl3_enabled ? 18 : 9; - - fm_info.nr_drums = 0; - fm_info.perc_mode = 0; - - opl3_reset (dev); -} - -static void -opl3_hw_control (int dev, unsigned char *event) -{ -} - -static int -opl3_load_patch (int dev, int format, snd_rw_buf * addr, - int offs, int count, int pmgr_flag) -{ - struct sbi_instrument ins; - - if (count < sizeof (ins)) - { - printk ("FM Error: Patch record too short\n"); - return RET_ERROR (EINVAL); - } - - COPY_FROM_USER (&((char *) &ins)[offs], (char *) addr, offs, sizeof (ins) - offs); - - if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) - { - printk ("FM Error: Invalid instrument number %d\n", ins.channel); - return RET_ERROR (EINVAL); - } - ins.key = format; - - return store_instr (ins.channel, &ins); -} - -static void -opl3_panning (int dev, int voice, int pressure) -{ -} - -static void -opl3_volume_method (int dev, int mode) -{ -} - -#define SET_VIBRATO(cell) { \ - tmp = instr->operators[(cell-1)+(((cell-1)/2)*OFFS_4OP)]; \ - if (pressure > 110) \ - tmp |= 0x40; /* Vibrato on */ \ - opl3_command (map->ioaddr, AM_VIB + map->op[cell-1], tmp);} - -static void -opl3_aftertouch (int dev, int voice, int pressure) -{ - int tmp; - struct sbi_instrument *instr; - struct physical_voice_info *map; - - if (voice < 0 || voice >= nr_voices) - return; - - map = &physical_voices[logical_voices[voice]]; - - DEB (printk ("Aftertouch %d\n", voice)); - - if (map->voice_mode == 0) - return; - - /* - * Adjust the amount of vibrato depending the pressure - */ - - instr = active_instrument[voice]; - - if (!instr) - instr = &instrmap[0]; - - if (voices[voice].mode == 4) - { - int connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01); - - switch (connection) - { - case 0: - SET_VIBRATO (4); - break; - - case 1: - SET_VIBRATO (2); - SET_VIBRATO (4); - break; - - case 2: - SET_VIBRATO (1); - SET_VIBRATO (4); - break; - - case 3: - SET_VIBRATO (1); - SET_VIBRATO (3); - SET_VIBRATO (4); - break; - - } - /* - * Not implemented yet - */ - } - else - { - SET_VIBRATO (1); - - if ((instr->operators[10] & 0x01)) /* - * Additive synthesis - */ - SET_VIBRATO (2); - } -} - -#undef SET_VIBRATO - -static void -bend_pitch (int dev, int voice, int value) -{ - unsigned char data; - int block, fnum, freq; - struct physical_voice_info *map; - - map = &physical_voices[logical_voices[voice]]; - - if (map->voice_mode == 0) - return; - - voices[voice].bender = value; - if (!value) - return; - if (!(voices[voice].keyon_byte & 0x20)) - return; /* - * Not keyed on - */ - - freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, voices[voice].bender_range); - voices[voice].current_freq = freq; - - freq_to_fnum (freq, &block, &fnum); - - data = fnum & 0xff; /* - * Least significant bits of fnumber - */ - opl3_command (map->ioaddr, FNUM_LOW + map->voice_num, data); - - data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3); /* - * * - * KEYON|OCTAVE|MS - * - * * bits * * - * of * f-num - * - */ - voices[voice].keyon_byte = data; - opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, data); -} - -static void -opl3_controller (int dev, int voice, int ctrl_num, int value) -{ - if (voice < 0 || voice >= nr_voices) - return; - - switch (ctrl_num) - { - case CTRL_PITCH_BENDER: - bend_pitch (dev, voice, value); - break; - - case CTRL_PITCH_BENDER_RANGE: - voices[voice].bender_range = value; - break; - } -} - -static int -opl3_patchmgr (int dev, struct patmgr_info *rec) -{ - return RET_ERROR (EINVAL); -} - -static void -opl3_bender (int dev, int voice, int value) -{ - if (voice < 0 || voice >= nr_voices) - return; - - bend_pitch (dev, voice, value); -} - -static int -opl3_alloc_voice (int dev, int chn, int note, struct voice_alloc_info *alloc) -{ - int i, p, best, first, avail_voices, best_time = 0x7fffffff; - struct sbi_instrument *instr; - int is4op; - int instr_no; - - if (chn < 0 || chn > 15) - instr_no = 0; - else - instr_no = chn_info[chn].pgm_num; - - instr = &instrmap[instr_no]; - if (instr->channel < 0 || /* Instrument not loaded */ - nr_voices != 12) /* Not in 4 OP mode */ - is4op = 0; - else if (nr_voices == 12) /* 4 OP mode */ - is4op = (instr->key == OPL3_PATCH); - else - is4op = 0; - - if (is4op) - { - first = p = 0; - avail_voices = 6; - } - else - { - if (nr_voices == 12) /* 4 OP mode. Use the '2 OP only' voices first */ - first = p = 6; - else - first = p = 0; - avail_voices = nr_voices; - } - - /* - * Now try to find a free voice - */ - best = first; - - for (i = 0; i < avail_voices; i++) - { - if (alloc->map[p] == 0) - { - return p; - } - if (alloc->alloc_times[p] < best_time) /* Find oldest playing note */ - { - best_time = alloc->alloc_times[p]; - best = p; - } - p = (p + 1) % avail_voices; - } - - /* - * Insert some kind of priority mechanism here. - */ - - if (best < 0) - best = 0; - if (best > nr_voices) - best -= nr_voices; - - return best; /* All voices in use. Select the first one. */ -} - -static void -opl3_setup_voice (int dev, int voice, int chn) -{ - struct channel_info *info = - &synth_devs[dev]->chn_info[chn]; - - opl3_set_instr (dev, voice, - info->pgm_num); - - voices[voice].bender = info->bender_value; -} - -static struct synth_operations opl3_operations = -{ - &fm_info, - 0, - SYNTH_TYPE_FM, - FM_TYPE_ADLIB, - opl3_open, - opl3_close, - opl3_ioctl, - opl3_kill_note, - opl3_start_note, - opl3_set_instr, - opl3_reset, - opl3_hw_control, - opl3_load_patch, - opl3_aftertouch, - opl3_controller, - opl3_panning, - opl3_volume_method, - opl3_patchmgr, - opl3_bender, - opl3_alloc_voice, - opl3_setup_voice -}; - -long -opl3_init (long mem_start) -{ - int i; - - PERMANENT_MALLOC (struct sbi_instrument *, instrmap, - SBFM_MAXINSTR * sizeof (*instrmap), mem_start); - - if (num_synths >= MAX_SYNTH_DEV) - printk ("OPL3 Error: Too many synthesizers\n"); - else - { - synth_devs[num_synths++] = &opl3_operations; - voice_alloc = &opl3_operations.alloc; - chn_info = &opl3_operations.chn_info[0]; - } - - fm_model = 0; - opl3_ok = 1; - if (opl3_enabled) - { - if (opl4_enabled) -#if defined(__FreeBSD__) - printk ("opl0: <Yamaha OPL4/OPL3 FM>"); - else - printk ("opl0: <Yamaha OPL-3 FM>"); -#else - printk (" <Yamaha OPL4/OPL3 FM>"); - else - printk (" <Yamaha OPL-3 FM>"); -#endif - - fm_model = 2; - voice_alloc->max_voice = nr_voices = 18; - fm_info.nr_drums = 0; - fm_info.capabilities |= SYNTH_CAP_OPL3; - strcpy (fm_info.name, "Yamaha OPL-3"); - - for (i = 0; i < 18; i++) - if (physical_voices[i].ioaddr == USE_LEFT) - physical_voices[i].ioaddr = left_address; - else - physical_voices[i].ioaddr = right_address; - - - opl3_command (right_address, OPL3_MODE_REGISTER, OPL3_ENABLE); /* - * Enable - * OPL-3 - * mode - */ - opl3_command (right_address, CONNECTION_SELECT_REGISTER, 0x00); /* - * Select - * all - * 2-OP - * * - * voices - */ - } - else - { -#if defined(__FreeBSD__) - printk ("opl0: <Yamaha 2-OP FM>"); -#else - printk (" <Yamaha 2-OP FM>"); -#endif - fm_model = 1; - voice_alloc->max_voice = nr_voices = 9; - fm_info.nr_drums = 0; - - for (i = 0; i < 18; i++) - physical_voices[i].ioaddr = left_address; - }; - - already_initialized = 1; - for (i = 0; i < SBFM_MAXINSTR; i++) - instrmap[i].channel = -1; - - return mem_start; -} - -#endif diff --git a/sys/pc98/pc98/sound/pas2_pcm.c b/sys/pc98/pc98/sound/pas2_pcm.c deleted file mode 100644 index db91165..0000000 --- a/sys/pc98/pc98/sound/pas2_pcm.c +++ /dev/null @@ -1,461 +0,0 @@ -#define _PAS2_PCM_C_ -/* - * sound/pas2_pcm.c - * - * The low level driver for the Pro Audio Spectrum ADC/DAC. - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <i386/isa/sound/sound_config.h> - -#ifdef CONFIGURE_SOUNDCARD - -#include <i386/isa/sound/pas.h> - -static int pcm_set_bits __P((int arg)); -static int pcm_set_channels __P((int arg)); -static int pcm_set_speed __P((int arg)); - -#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_AUDIO) - -#define TRACE(WHAT) /* - * * * (WHAT) */ - -#define PAS_PCM_INTRBITS (0x08) -/* - * Sample buffer timer interrupt enable - */ - -#define PCM_NON 0 -#define PCM_DAC 1 -#define PCM_ADC 2 - -static unsigned long pcm_speed = 0; /* sampling rate */ -static unsigned char pcm_channels = 1; /* channels (1 or 2) */ -static unsigned char pcm_bits = 8; /* bits/sample (8 or 16) */ -static unsigned char pcm_filter = 0; /* filter FLAG */ -static unsigned char pcm_mode = PCM_NON; -static unsigned long pcm_count = 0; -static unsigned short pcm_bitsok = 8; /* mask of OK bits */ -static int my_devnum = 0; - -static int -pcm_set_speed (int arg) -{ - int foo, tmp; - unsigned long flags; - - if (arg > 44100) - arg = 44100; - if (arg < 5000) - arg = 5000; - - foo = (1193180 + (arg / 2)) / arg; - arg = 1193180 / foo; - - if (pcm_channels & 2) - foo = foo >> 1; - - pcm_speed = arg; - - tmp = pas_read (FILTER_FREQUENCY); - - /* - * Set anti-aliasing filters according to sample rate. You reall *NEED* - * to enable this feature for all normal recording unless you want to - * experiment with aliasing effects. - * These filters apply to the selected "recording" source. - * I (pfw) don't know the encoding of these 5 bits. The values shown - * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/. - */ -#if !defined NO_AUTO_FILTER_SET - tmp &= 0xe0; - if (pcm_speed >= 2 * 17897) - tmp |= 0x21; - else if (pcm_speed >= 2 * 15909) - tmp |= 0x22; - else if (pcm_speed >= 2 * 11931) - tmp |= 0x29; - else if (pcm_speed >= 2 * 8948) - tmp |= 0x31; - else if (pcm_speed >= 2 * 5965) - tmp |= 0x39; - else if (pcm_speed >= 2 * 2982) - tmp |= 0x24; - pcm_filter = tmp; -#endif - - DISABLE_INTR (flags); - - pas_write (tmp & ~(F_F_PCM_RATE_COUNTER | F_F_PCM_BUFFER_COUNTER), FILTER_FREQUENCY); - pas_write (S_C_C_SAMPLE_RATE | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL); - pas_write (foo & 0xff, SAMPLE_RATE_TIMER); - pas_write ((foo >> 8) & 0xff, SAMPLE_RATE_TIMER); - pas_write (tmp, FILTER_FREQUENCY); - - RESTORE_INTR (flags); - - return pcm_speed; -} - -static int -pcm_set_channels (int arg) -{ - - if ((arg != 1) && (arg != 2)) - return pcm_channels; - - if (arg != pcm_channels) - { - pas_write (pas_read (PCM_CONTROL) ^ P_C_PCM_MONO, PCM_CONTROL); - - pcm_channels = arg; - pcm_set_speed (pcm_speed); /* - * The speed must be reinitialized - */ - } - - return pcm_channels; -} - -static int -pcm_set_bits (int arg) -{ - if ((arg & pcm_bitsok) != arg) - return pcm_bits; - - if (arg != pcm_bits) - { - pas_write (pas_read (SYSTEM_CONFIGURATION_2) ^ S_C_2_PCM_16_BIT, SYSTEM_CONFIGURATION_2); - - pcm_bits = arg; - } - - return pcm_bits; -} - -static int -pas_pcm_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) -{ - TRACE (printk ("pas2_pcm.c: static int pas_pcm_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg)); - - switch (cmd) - { - case SOUND_PCM_WRITE_RATE: - if (local) - return pcm_set_speed (arg); - return IOCTL_OUT (arg, pcm_set_speed (IOCTL_IN (arg))); - break; - - case SOUND_PCM_READ_RATE: - if (local) - return pcm_speed; - return IOCTL_OUT (arg, pcm_speed); - break; - - case SNDCTL_DSP_STEREO: - if (local) - return pcm_set_channels (arg + 1) - 1; - return IOCTL_OUT (arg, pcm_set_channels (IOCTL_IN (arg) + 1) - 1); - break; - - case SOUND_PCM_WRITE_CHANNELS: - if (local) - return pcm_set_channels (arg); - return IOCTL_OUT (arg, pcm_set_channels (IOCTL_IN (arg))); - break; - - case SOUND_PCM_READ_CHANNELS: - if (local) - return pcm_channels; - return IOCTL_OUT (arg, pcm_channels); - break; - - case SNDCTL_DSP_SETFMT: - if (local) - return pcm_set_bits (arg); - return IOCTL_OUT (arg, pcm_set_bits (IOCTL_IN (arg))); - break; - - case SOUND_PCM_READ_BITS: - if (local) - return pcm_bits; - return IOCTL_OUT (arg, pcm_bits); - - case SOUND_PCM_WRITE_FILTER: /* - * NOT YET IMPLEMENTED - */ - if (IOCTL_IN (arg) > 1) - return IOCTL_OUT (arg, RET_ERROR (EINVAL)); - break; - - pcm_filter = IOCTL_IN (arg); - case SOUND_PCM_READ_FILTER: - return IOCTL_OUT (arg, pcm_filter); - break; - - default: - return RET_ERROR (EINVAL); - } - - return RET_ERROR (EINVAL); -} - -static void -pas_pcm_reset (int dev) -{ - TRACE (printk ("pas2_pcm.c: static void pas_pcm_reset(void)\n")); - - pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE, PCM_CONTROL); -} - -static int -pas_pcm_open (int dev, int mode) -{ - int err; - - TRACE (printk ("pas2_pcm.c: static int pas_pcm_open(int mode = %X)\n", mode)); - - if ((err = pas_set_intr (PAS_PCM_INTRBITS)) < 0) - return err; - - if (DMAbuf_open_dma (dev) < 0) - { - pas_remove_intr (PAS_PCM_INTRBITS); - return RET_ERROR (EBUSY); - } - - pcm_count = 0; - - return 0; -} - -static void -pas_pcm_close (int dev) -{ - unsigned long flags; - - TRACE (printk ("pas2_pcm.c: static void pas_pcm_close(void)\n")); - - DISABLE_INTR (flags); - - pas_pcm_reset (dev); - DMAbuf_close_dma (dev); - pas_remove_intr (PAS_PCM_INTRBITS); - pcm_mode = PCM_NON; - - RESTORE_INTR (flags); -} - -static void -pas_pcm_output_block (int dev, unsigned long buf, int count, - int intrflag, int restart_dma) -{ - unsigned long flags, cnt; - - TRACE (printk ("pas2_pcm.c: static void pas_pcm_output_block(char *buf = %P, int count = %X)\n", buf, count)); - - cnt = count; - if (audio_devs[dev]->dmachan > 3) - cnt >>= 1; - - if (audio_devs[dev]->flags & DMA_AUTOMODE && - intrflag && - cnt == pcm_count) - return; /* - * Auto mode on. No need to react - */ - - DISABLE_INTR (flags); - - pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE, - PCM_CONTROL); - - if (restart_dma) - DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); - - if (audio_devs[dev]->dmachan > 3) - count >>= 1; - - if (count != pcm_count) - { - pas_write (pas_read (FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY); - pas_write (S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL); - pas_write (count & 0xff, SAMPLE_BUFFER_COUNTER); - pas_write ((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER); - pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY); - - pcm_count = count; - } - pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY); - pas_write (pas_read (PCM_CONTROL) | P_C_PCM_ENABLE | P_C_PCM_DAC_MODE, PCM_CONTROL); - - pcm_mode = PCM_DAC; - - RESTORE_INTR (flags); -} - -static void -pas_pcm_start_input (int dev, unsigned long buf, int count, - int intrflag, int restart_dma) -{ - unsigned long flags; - int cnt; - - TRACE (printk ("pas2_pcm.c: static void pas_pcm_start_input(char *buf = %P, int count = %X)\n", buf, count)); - - cnt = count; - if (audio_devs[dev]->dmachan > 3) - cnt >>= 1; - - if (audio_devs[my_devnum]->flags & DMA_AUTOMODE && - intrflag && - cnt == pcm_count) - return; /* - * Auto mode on. No need to react - */ - - DISABLE_INTR (flags); - - if (restart_dma) - DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); - - if (audio_devs[dev]->dmachan > 3) - count >>= 1; - - if (count != pcm_count) - { - pas_write (pas_read (FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY); - pas_write (S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL); - pas_write (count & 0xff, SAMPLE_BUFFER_COUNTER); - pas_write ((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER); - pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY); - - pcm_count = count; - } - pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY); - pas_write ((pas_read (PCM_CONTROL) | P_C_PCM_ENABLE) & ~P_C_PCM_DAC_MODE, PCM_CONTROL); - - pcm_mode = PCM_ADC; - - RESTORE_INTR (flags); -} - -static int -pas_pcm_prepare_for_input (int dev, int bsize, int bcount) -{ - return 0; -} -static int -pas_pcm_prepare_for_output (int dev, int bsize, int bcount) -{ - return 0; -} - -static struct audio_operations pas_pcm_operations = -{ - "Pro Audio Spectrum", -#ifdef PC98 - NEEDS_RESTART, -#else - DMA_AUTOMODE, -#endif - AFMT_U8 | AFMT_S16_LE, - NULL, - pas_pcm_open, - pas_pcm_close, - pas_pcm_output_block, - pas_pcm_start_input, - pas_pcm_ioctl, - pas_pcm_prepare_for_input, - pas_pcm_prepare_for_output, - pas_pcm_reset, - pas_pcm_reset, - NULL, - NULL -}; - -long -pas_pcm_init (long mem_start, struct address_info *hw_config) -{ - TRACE (printk ("pas2_pcm.c: long pas_pcm_init(long mem_start = %X)\n", mem_start)); - - pcm_bitsok = 8; - if (pas_read (OPERATION_MODE_1) & O_M_1_PCM_TYPE) - pcm_bitsok |= 16; - - pcm_set_speed (DSP_DEFAULT_SPEED); - - if (num_audiodevs < MAX_AUDIO_DEV) - { - audio_devs[my_devnum = num_audiodevs++] = &pas_pcm_operations; - audio_devs[my_devnum]->dmachan = hw_config->dma; - audio_devs[my_devnum]->buffcount = 1; - audio_devs[my_devnum]->buffsize = DSP_BUFFSIZE; - } - else - printk ("PAS2: Too many PCM devices available\n"); - - return mem_start; -} - -void -pas_pcm_interrupt (unsigned char status, int cause) -{ - if (cause == 1) /* - * PCM buffer done - */ - { - /* - * Halt the PCM first. Otherwise we don't have time to start a new - * block before the PCM chip proceeds to the next sample - */ - - if (!(audio_devs[my_devnum]->flags & DMA_AUTOMODE)) - { - pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE, - PCM_CONTROL); - } - - switch (pcm_mode) - { - - case PCM_DAC: - DMAbuf_outputintr (my_devnum, 1); - break; - - case PCM_ADC: - DMAbuf_inputintr (my_devnum); - break; - - default: - printk ("PAS: Unexpected PCM interrupt\n"); - } - } -} - -#endif - -#endif diff --git a/sys/pc98/pc98/sound/sb16_dsp.c b/sys/pc98/pc98/sound/sb16_dsp.c deleted file mode 100644 index 5e84e67..0000000 --- a/sys/pc98/pc98/sound/sb16_dsp.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * sound/sb16_dsp.c - * - * The low level driver for the SoundBlaster DSP chip. - * - * (C) 1993 J. Schubert (jsb@sth.ruhr-uni-bochum.de) - * - * based on SB-driver by (C) Hannu Savolainen - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#define DEB(x) -#define DEB1(x) -/* - * #define DEB_DMARES - */ -#include <i386/isa/sound/sound_config.h> -#include <i386/isa/sound/sb.h> -#include <i386/isa/sound/sb_mixer.h> - -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO) - -extern int sbc_base; -extern int sbc_major; -extern int sbc_minor; - -static int sb16_dsp_ok = 0; /* - - - * * * * Set to 1 after successful * - * * initialization */ -static int dsp_16bit = 0; -static int dsp_stereo = 0; -static int dsp_current_speed = 8000; /* - - - * * * * DSP_DEFAULT_SPEED; */ -static int dsp_busy = 0; -static int dma16, dma8; -static unsigned long dsp_count = 0; - -static int irq_mode = IMODE_NONE; /* - - - * * * * IMODE_INPUT, IMODE_OUTPUT - * or * * IMODE_NONE */ -static int my_dev = 0; - -static volatile int intr_active = 0; - -static int sb16_dsp_open (int dev, int mode); -static void sb16_dsp_close (int dev); -static void sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart); -static void sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart); -static int sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local); -static int sb16_dsp_prepare_for_input (int dev, int bsize, int bcount); -static int sb16_dsp_prepare_for_output (int dev, int bsize, int bcount); -static void sb16_dsp_reset (int dev); -static void sb16_dsp_halt (int dev); -static int dsp_set_speed (int); -static int dsp_set_stereo (int); -static void dsp_cleanup (void); - -static struct audio_operations sb16_dsp_operations = -{ - "SoundBlaster 16", -#ifdef PC98 - NEEDS_RESTART, -#else - DMA_AUTOMODE, -#endif - AFMT_U8 | AFMT_S16_LE, - NULL, - sb16_dsp_open, - sb16_dsp_close, - sb16_dsp_output_block, - sb16_dsp_start_input, - sb16_dsp_ioctl, - sb16_dsp_prepare_for_input, - sb16_dsp_prepare_for_output, - sb16_dsp_reset, - sb16_dsp_halt, - NULL, - NULL -}; - -static int -sb_dsp_command01 (unsigned char val) -{ - int i = 1 << 16; - - while (--i & (!INB (DSP_STATUS) & 0x80)); - if (!i) - printk ("SB16 sb_dsp_command01 Timeout\n"); - return sb_dsp_command (val); -} - -static int -dsp_set_speed (int mode) -{ - DEB (printk ("dsp_set_speed(%d)\n", mode)); - if (mode) - { - if (mode < 5000) - mode = 5000; - if (mode > 44100) - mode = 44100; - dsp_current_speed = mode; - } - return mode; -} - -static int -dsp_set_stereo (int mode) -{ - DEB (printk ("dsp_set_stereo(%d)\n", mode)); - - dsp_stereo = mode; - - return mode; -} - -static int -dsp_set_bits (int arg) -{ - DEB (printk ("dsp_set_bits(%d)\n", arg)); - - if (arg) - switch (arg) - { - case 8: - dsp_16bit = 0; - break; - case 16: - dsp_16bit = 1; - break; - default: - dsp_16bit = 0; - } - return dsp_16bit ? 16 : 8; -} - -static int -sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) -{ - switch (cmd) - { - case SOUND_PCM_WRITE_RATE: - if (local) - return dsp_set_speed (arg); - return IOCTL_OUT (arg, dsp_set_speed (IOCTL_IN (arg))); - - case SOUND_PCM_READ_RATE: - if (local) - return dsp_current_speed; - return IOCTL_OUT (arg, dsp_current_speed); - - case SNDCTL_DSP_STEREO: - if (local) - return dsp_set_stereo (arg); - return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg))); - - case SOUND_PCM_WRITE_CHANNELS: - if (local) - return dsp_set_stereo (arg - 1) + 1; - return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1); - - case SOUND_PCM_READ_CHANNELS: - if (local) - return dsp_stereo + 1; - return IOCTL_OUT (arg, dsp_stereo + 1); - - case SNDCTL_DSP_SETFMT: - if (local) - return dsp_set_bits (arg); - return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg))); - - case SOUND_PCM_READ_BITS: - if (local) - return dsp_16bit ? 16 : 8; - return IOCTL_OUT (arg, dsp_16bit ? 16 : 8); - - case SOUND_PCM_WRITE_FILTER: /* - * NOT YET IMPLEMENTED - */ - if (IOCTL_IN (arg) > 1) - return IOCTL_OUT (arg, RET_ERROR (EINVAL)); - default: - return RET_ERROR (EINVAL); - } - - return RET_ERROR (EINVAL); -} - -static int -sb16_dsp_open (int dev, int mode) -{ - int retval; - - DEB (printk ("sb16_dsp_open()\n")); - if (!sb16_dsp_ok) - { - printk ("SB16 Error: SoundBlaster board not installed\n"); - return RET_ERROR (ENXIO); - } - - if (intr_active) - return RET_ERROR (EBUSY); - - retval = sb_get_irq (); - if (retval < 0) - return retval; - - sb_reset_dsp (); - - if (ALLOC_DMA_CHN (dma8, "SB16 (8bit)")) - { - printk ("SB16: Unable to grab DMA%d\n", dma8); - sb_free_irq (); - return RET_ERROR (EBUSY); - } - - if (dma16 != dma8) - if (ALLOC_DMA_CHN (dma16, "SB16 (16bit)")) - { - printk ("SB16: Unable to grab DMA%d\n", dma16); - sb_free_irq (); - RELEASE_DMA_CHN (dma8); - return RET_ERROR (EBUSY); - } - - irq_mode = IMODE_NONE; - dsp_busy = 1; - - return 0; -} - -static void -sb16_dsp_close (int dev) -{ - unsigned long flags; - - DEB (printk ("sb16_dsp_close()\n")); - sb_dsp_command01 (0xd9); - sb_dsp_command01 (0xd5); - - DISABLE_INTR (flags); - RELEASE_DMA_CHN (dma8); - - if (dma16 != dma8) - RELEASE_DMA_CHN (dma16); - sb_free_irq (); - dsp_cleanup (); - dsp_busy = 0; - RESTORE_INTR (flags); -} - -static void -sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart) -{ - unsigned long flags, cnt; - - cnt = count; - if (dsp_16bit) - cnt >>= 1; - cnt--; - -#ifdef DEB_DMARES - printk ("output_block: %x %d %d\n", buf, count, intrflag); - if (intrflag) - { - int pos, chan = audio_devs[dev]->dmachan; - - DISABLE_INTR (flags); - clear_dma_ff (chan); - disable_dma (chan); - pos = get_dma_residue (chan); - enable_dma (chan); - RESTORE_INTR (flags); - printk ("dmapos=%d %x\n", pos, pos); - } -#endif - if (audio_devs[dev]->flags & DMA_AUTOMODE && - intrflag && - cnt == dsp_count) - { - irq_mode = IMODE_OUTPUT; - intr_active = 1; - return; /* - * Auto mode on. No need to react - */ - } - DISABLE_INTR (flags); - - if (dma_restart) - { - sb16_dsp_halt (dev); - DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); - } - sb_dsp_command (0x41); - sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff)); - sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff)); - sb_dsp_command ((unsigned char) (dsp_16bit ? 0xb6 : 0xc6)); - sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) + - (dsp_16bit ? 0x10 : 0))); - sb_dsp_command01 ((unsigned char) (cnt & 0xff)); - sb_dsp_command ((unsigned char) (cnt >> 8)); - - dsp_count = cnt; - irq_mode = IMODE_OUTPUT; - intr_active = 1; - RESTORE_INTR (flags); -} - -static void -sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart) -{ - unsigned long flags, cnt; - - cnt = count; - if (dsp_16bit) - cnt >>= 1; - cnt--; - -#ifdef DEB_DMARES - printk ("start_input: %x %d %d\n", buf, count, intrflag); - if (intrflag) - { - int pos, chan = audio_devs[dev]->dmachan; - - DISABLE_INTR (flags); - clear_dma_ff (chan); - disable_dma (chan); - pos = get_dma_residue (chan); - enable_dma (chan); - RESTORE_INTR (flags); - printk ("dmapos=%d %x\n", pos, pos); - } -#endif - if (audio_devs[dev]->flags & DMA_AUTOMODE && - intrflag && - cnt == dsp_count) - { - irq_mode = IMODE_INPUT; - intr_active = 1; - return; /* - * Auto mode on. No need to react - */ - } - DISABLE_INTR (flags); - - if (dma_restart) - { - sb_reset_dsp (); - DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); - } - - sb_dsp_command (0x42); - sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff)); - sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff)); - sb_dsp_command ((unsigned char) (dsp_16bit ? 0xbe : 0xce)); - sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) + - (dsp_16bit ? 0x10 : 0))); - sb_dsp_command01 ((unsigned char) (cnt & 0xff)); - sb_dsp_command ((unsigned char) (cnt >> 8)); - - dsp_count = cnt; - irq_mode = IMODE_INPUT; - intr_active = 1; - RESTORE_INTR (flags); -} - -static int -sb16_dsp_prepare_for_input (int dev, int bsize, int bcount) -{ - audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8; - dsp_count = 0; - dsp_cleanup (); - return 0; -} - -static int -sb16_dsp_prepare_for_output (int dev, int bsize, int bcount) -{ - audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8; - dsp_count = 0; - dsp_cleanup (); - return 0; -} - -static void -dsp_cleanup (void) -{ - irq_mode = IMODE_NONE; - intr_active = 0; -} - -static void -sb16_dsp_reset (int dev) -{ - unsigned long flags; - - DISABLE_INTR (flags); - - sb_reset_dsp (); - dsp_cleanup (); - - RESTORE_INTR (flags); -} - -static void -sb16_dsp_halt (int dev) -{ - if (dsp_16bit) - { - sb_dsp_command01 (0xd9); - sb_dsp_command01 (0xd5); - } - else - { - sb_dsp_command01 (0xda); - sb_dsp_command01 (0xd0); - } - DMAbuf_reset_dma (dev); -} - -static void -set_irq_hw (int level) -{ - int ival; - - switch (level) - { -#ifdef PC98 - case 5: - ival = 8; - break; - case 3: - ival = 1; - break; - case 10: - ival = 2; - break; -#else - case 5: - ival = 2; - break; - case 7: - ival = 4; - break; - case 9: - ival = 1; - break; - case 10: - ival = 8; - break; -#endif - default: - printk ("SB16_IRQ_LEVEL %d does not exist\n", level); - return; - } - sb_setmixer (IRQ_NR, ival); -} - -long -sb16_dsp_init (long mem_start, struct address_info *hw_config) -{ - if (sbc_major < 4) - return mem_start; /* Not a SB16 */ - - sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor); - -#if defined(__FreeBSD__) - printk ("sbxvo0: <%s>", sb16_dsp_operations.name); -#else - printk (" <%s>", sb16_dsp_operations.name); -#endif - - if (num_audiodevs < MAX_AUDIO_DEV) - { - audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations; - audio_devs[my_dev]->dmachan = hw_config->dma; - audio_devs[my_dev]->buffcount = 1; - audio_devs[my_dev]->buffsize = DSP_BUFFSIZE; - } - else - printk ("SB: Too many DSP devices available\n"); - sb16_dsp_ok = 1; - return mem_start; -} - -int -sb16_dsp_detect (struct address_info *hw_config) -{ - struct address_info *sb_config; - - if (sb16_dsp_ok) - return 1; /* Can't drive two cards */ - - if (!(sb_config = sound_getconf (SNDCARD_SB))) - { - printk ("SB16 Error: Plain SB not configured\n"); - return 0; - } - - /* - * sb_setmixer(OPSW,0xf); if(sb_getmixer(OPSW)!=0xf) return 0; - */ - - if (!sb_reset_dsp ()) - return 0; - - if (sbc_major < 4) /* Set by the plain SB driver */ - return 0; /* Not a SB16 */ - -#ifdef PC98 - hw_config->dma = sb_config->dma; -#else - if (hw_config->dma < 4) - if (hw_config->dma != sb_config->dma) - { - printk ("SB16 Error: Invalid DMA channel %d/%d\n", - sb_config->dma, hw_config->dma); - return 0; - } -#endif - - dma16 = hw_config->dma; - dma8 = sb_config->dma; - set_irq_hw (sb_config->irq); -#ifdef PC98 - sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2); -#else - sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma)); -#endif - - DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma)); - - /* - * dsp_showmessage(0xe3,99); - */ - sb16_dsp_ok = 1; - return 1; -} - -void -sb16_dsp_interrupt (int unused) -{ - int data; - - data = INB (DSP_DATA_AVL16); /* - * Interrupt acknowledge - */ - - if (intr_active) - switch (irq_mode) - { - case IMODE_OUTPUT: - intr_active = 0; - DMAbuf_outputintr (my_dev, 1); - break; - - case IMODE_INPUT: - intr_active = 0; - DMAbuf_inputintr (my_dev); - break; - - default: - printk ("SoundBlaster: Unexpected interrupt\n"); - } -} - -#endif diff --git a/sys/pc98/pc98/sound/sb16_midi.c b/sys/pc98/pc98/sound/sb16_midi.c deleted file mode 100644 index 7dae750..0000000 --- a/sys/pc98/pc98/sound/sb16_midi.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * sound/sb16_midi.c - * - * The low level driver for the MPU-401 UART emulation of the SB16. - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <i386/isa/sound/sound_config.h> - -#ifdef CONFIGURE_SOUNDCARD - -#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_MIDI) - -#include <i386/isa/sound/sb.h> - -#ifdef PC98 -#define DATAPORT (sb16midi_base) -#define COMDPORT (sb16midi_base+0x100) -#define STATPORT (sb16midi_base+0x100) -#else -#define DATAPORT (sb16midi_base) -#define COMDPORT (sb16midi_base+1) -#define STATPORT (sb16midi_base+1) -#endif - -#define sb16midi_status() INB(STATPORT) -#define input_avail() (!(sb16midi_status()&INPUT_AVAIL)) -#define output_ready() (!(sb16midi_status()&OUTPUT_READY)) -#define sb16midi_cmd(cmd) OUTB(cmd, COMDPORT) -#define sb16midi_read() INB(DATAPORT) -#define sb16midi_write(byte) OUTB(byte, DATAPORT) - -#define OUTPUT_READY 0x40 -#define INPUT_AVAIL 0x80 -#define MPU_ACK 0xFE -#define MPU_RESET 0xFF -#define UART_MODE_ON 0x3F - -extern int sbc_major; - -static int sb16midi_opened = 0; -static int sb16midi_base = 0x330; -static int sb16midi_detected = 0; -static int my_dev; -extern int sbc_base; - -static int reset_sb16midi (void); -static void (*midi_input_intr) (int dev, unsigned char data); - -static void -sb16midi_input_loop (void) -{ - while (input_avail ()) - { - unsigned char c = sb16midi_read (); - - if (sb16midi_opened & OPEN_READ) - midi_input_intr (my_dev, c); - } -} - -void -sb16midiintr (int unit) -{ - if (input_avail ()) - sb16midi_input_loop (); -} - -static int -sb16midi_open (int dev, int mode, - void (*input) (int dev, unsigned char data), - void (*output) (int dev) -) -{ - if (sb16midi_opened) - { - return RET_ERROR (EBUSY); - } - - sb16midi_input_loop (); - - midi_input_intr = input; - sb16midi_opened = mode; - - return 0; -} - -static void -sb16midi_close (int dev) -{ - sb16midi_opened = 0; -} - -static int -sb16midi_out (int dev, unsigned char midi_byte) -{ - int timeout; - unsigned long flags; - - /* - * Test for input since pending input seems to block the output. - */ - - DISABLE_INTR (flags); - - if (input_avail ()) - sb16midi_input_loop (); - - RESTORE_INTR (flags); - - /* - * Sometimes it takes about 13000 loops before the output becomes ready - * (After reset). Normally it takes just about 10 loops. - */ - - for (timeout = 30000; timeout > 0 && !output_ready (); timeout--); /* - * Wait - */ - - if (!output_ready ()) - { - printk ("MPU-401: Timeout\n"); - return 0; - } - - sb16midi_write (midi_byte); - return 1; -} - -static int -sb16midi_start_read (int dev) -{ - return 0; -} - -static int -sb16midi_end_read (int dev) -{ - return 0; -} - -static int -sb16midi_ioctl (int dev, unsigned cmd, unsigned arg) -{ - return RET_ERROR (EINVAL); -} - -static void -sb16midi_kick (int dev) -{ -} - -static int -sb16midi_buffer_status (int dev) -{ - return 0; /* - * No data in buffers - */ -} - -#define MIDI_SYNTH_NAME "SoundBlaster 16 Midi" -#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT -#include <i386/isa/sound/midi_synth.h> - -static struct midi_operations sb16midi_operations = -{ - {"SoundBlaster 16 Midi", 0, 0, SNDCARD_SB16MIDI}, - &std_midi_synth, - {0}, - sb16midi_open, - sb16midi_close, - sb16midi_ioctl, - sb16midi_out, - sb16midi_start_read, - sb16midi_end_read, - sb16midi_kick, - NULL, - sb16midi_buffer_status, - NULL -}; - - -long -attach_sb16midi (long mem_start, struct address_info *hw_config) -{ - int ok, timeout; - unsigned long flags; - - sb16midi_base = hw_config->io_base; - - if (!sb16midi_detected) - return RET_ERROR (EIO); - - DISABLE_INTR (flags); - for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /* - * Wait - */ - sb16midi_cmd (UART_MODE_ON); - - ok = 0; - for (timeout = 50000; timeout > 0 && !ok; timeout--) - if (input_avail ()) - if (sb16midi_read () == MPU_ACK) - ok = 1; - - RESTORE_INTR (flags); - - if (num_midis >= MAX_MIDI_DEV) - { - printk ("Sound: Too many midi devices detected\n"); - return mem_start; - } - - printk (" <SoundBlaster MPU-401>"); - - std_midi_synth.midi_dev = my_dev = num_midis; - midi_devs[num_midis++] = &sb16midi_operations; - return mem_start; -} - -static int -reset_sb16midi (void) -{ - unsigned long flags; - int ok, timeout, n; - - /* - * Send the RESET command. Try again if no success at the first time. - */ - - ok = 0; - - DISABLE_INTR (flags); - - for (n = 0; n < 2 && !ok; n++) - { - for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /* - * Wait - */ - sb16midi_cmd (MPU_RESET); /* - * Send MPU-401 RESET Command - */ - - /* - * Wait at least 25 msec. This method is not accurate so let's make the - * loop bit longer. Cannot sleep since this is called during boot. - */ - - for (timeout = 50000; timeout > 0 && !ok; timeout--) - if (input_avail ()) - if (sb16midi_read () == MPU_ACK) - ok = 1; - - } - - sb16midi_opened = 0; - if (ok) - sb16midi_input_loop (); /* - * Flush input before enabling interrupts - */ - - RESTORE_INTR (flags); - - return ok; -} - - -int -probe_sb16midi (struct address_info *hw_config) -{ - int ok = 0; - - if (sbc_major < 4) - return 0; /* Not a SB16 */ - - sb16midi_base = hw_config->io_base; - - if (sb_get_irq () < 0) - return 0; - - ok = reset_sb16midi (); - - sb16midi_detected = ok; - return ok; -} - -#endif - -#endif diff --git a/sys/pc98/pc98/sound/sb_dsp.c b/sys/pc98/pc98/sound/sb_dsp.c deleted file mode 100644 index 82a2178..0000000 --- a/sys/pc98/pc98/sound/sb_dsp.c +++ /dev/null @@ -1,1252 +0,0 @@ -/* - * sound/sb_dsp.c - * - * The low level driver for the SoundBlaster DSP chip (SB1.0 to 2.1, SB Pro). - * - * Copyright by Hannu Savolainen 1994 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Modified: - * Hunyue Yau Jan 6 1994 - * Added code to support Sound Galaxy NX Pro - * - * JRA Gibson April 1995 - * Code added for MV ProSonic/Jazz 16 in 16 bit mode - */ - -#include <i386/isa/sound/sound_config.h> - -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) - -#include <i386/isa/sound/sb.h> -#include <i386/isa/sound/sb_mixer.h> -#undef SB_TEST_IRQ - -int sbc_base = 0; -static int sbc_irq = 0; -static int open_mode = 0; /* Read, write or both */ -int Jazz16_detected = 0; - -/* - * The DSP channel can be used either for input or output. Variable - * 'sb_irq_mode' will be set when the program calls read or write first time - * after open. Current version doesn't support mode changes without closing - * and reopening the device. Support for this feature may be implemented in a - * future version of this driver. - */ - -int sb_dsp_ok = 0; /* - - - * * * * Set to 1 after successful - * initialization * */ -static int midi_disabled = 0; -int sb_dsp_highspeed = 0; -int sbc_major = 1, sbc_minor = 0; /* - - - * * * * DSP version */ -static int dsp_stereo = 0; -static int dsp_current_speed = DSP_DEFAULT_SPEED; -static int sb16 = 0; -static int irq_verified = 0; - -int sb_midi_mode = NORMAL_MIDI; -int sb_midi_busy = 0; /* - - - * * * * 1 if the process has output - * to * * MIDI */ -int sb_dsp_busy = 0; - -volatile int sb_irq_mode = IMODE_NONE; /* - - - * * * * IMODE_INPUT, * - * IMODE_OUTPUT * * or * - * IMODE_NONE */ -static volatile int irq_ok = 0; - -#ifdef JAZZ16 -/* 16 bit support - */ - -static int dsp_16bit = 0; -static int dma8 = 1; -static int dma16 = 5; - -static int dsp_set_bits (int arg); -static int initialize_ProSonic16 (void); - -/* end of 16 bit support - */ -#endif - -int sb_duplex_midi = 0; -static int my_dev = 0; - -volatile int sb_intr_active = 0; - -static int dsp_speed (int); -static int dsp_set_stereo (int mode); - -#if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO) - -/* - * Common code for the midi and pcm functions - */ - -int -sb_dsp_command (unsigned char val) -{ - int i; - unsigned long limit; - - limit = GET_TIME () + HZ / 10; /* - * The timeout is 0.1 secods - */ - - /* - * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes - * called while interrupts are disabled. This means that the timer is - * disabled also. However the timeout situation is a abnormal condition. - * Normally the DSP should be ready to accept commands after just couple of - * loops. - */ - - for (i = 0; i < 500000 && GET_TIME () < limit; i++) - { - if ((INB (DSP_STATUS) & 0x80) == 0) - { - OUTB (val, DSP_COMMAND); - return 1; - } - } - - printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val); - printk ("IRQ conflict???\n"); - return 0; -} - -void -sbintr (INT_HANDLER_PARMS (irq, dummy)) -{ - int status; - -#ifndef EXCLUDE_SBPRO - if (sb16) - { - unsigned char src = sb_getmixer (IRQ_STAT); /* Interrupt source register */ - -#ifndef EXCLUDE_SB16 - if (src & 3) - sb16_dsp_interrupt (irq); - -#ifndef EXCLUDE_MIDI - if (src & 4) - sb16midiintr (irq); /* - * SB MPU401 interrupt - */ -#endif - -#endif - - if (!(src & 1)) - return; /* - * Not a DSP interupt - */ - } -#endif - - status = INB (DSP_DATA_AVAIL); /* - * Clear interrupt - */ - - if (sb_intr_active) - switch (sb_irq_mode) - { - case IMODE_OUTPUT: - sb_intr_active = 0; - DMAbuf_outputintr (my_dev, 1); - break; - - case IMODE_INPUT: - sb_intr_active = 0; - DMAbuf_inputintr (my_dev); - /* - * A complete buffer has been input. Let's start new one - */ - break; - - case IMODE_INIT: - sb_intr_active = 0; - irq_ok = 1; - break; - - case IMODE_MIDI: -#ifndef EXCLUDE_MIDI - sb_midi_interrupt (irq); -#endif - break; - - default: - printk ("SoundBlaster: Unexpected interrupt\n"); - } -} - -static int sb_irq_usecount = 0; - -int -sb_get_irq (void) -{ - int ok; - - if (!sb_irq_usecount) - if ((ok = snd_set_irq_handler (sbc_irq, sbintr, "SoundBlaster")) < 0) - return ok; - - sb_irq_usecount++; - - return 0; -} - -void -sb_free_irq (void) -{ - if (!sb_irq_usecount) - return; - - sb_irq_usecount--; - - if (!sb_irq_usecount) - snd_release_irq (sbc_irq); -} - -int -sb_reset_dsp (void) -{ - int loopc; - - OUTB (1, DSP_RESET); - tenmicrosec (); - OUTB (0, DSP_RESET); - tenmicrosec (); - tenmicrosec (); - tenmicrosec (); - - for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++); /* - * Wait - * for - * data - * * - * available - * status - */ - - if (INB (DSP_READ) != 0xAA) - return 0; /* - * Sorry - */ - - return 1; -} - -#endif - -#ifndef EXCLUDE_AUDIO - -static void -dsp_speaker (char state) -{ - if (state) - sb_dsp_command (DSP_CMD_SPKON); - else - sb_dsp_command (DSP_CMD_SPKOFF); -} - -static int -dsp_speed (int speed) -{ - unsigned char tconst; - unsigned long flags; - int max_speed = 44100; - - if (speed < 4000) - speed = 4000; - - /* - * Older SB models don't support higher speeds than 22050. - */ - - if (sbc_major < 2 || - (sbc_major == 2 && sbc_minor == 0)) - max_speed = 22050; - - /* - * SB models earlier than SB Pro have low limit for the input speed. - */ - if (open_mode != OPEN_WRITE) /* Recording is possible */ - if (sbc_major < 3) /* Limited input speed with these cards */ - if (sbc_major == 2 && sbc_minor > 0) - max_speed = 15000; - else - max_speed = 13000; - - if (speed > max_speed) - speed = max_speed; /* - * Invalid speed - */ - - /* Logitech SoundMan Games and Jazz16 cards can support 44.1kHz stereo */ -#if !defined (SM_GAMES) - /* - * Max. stereo speed is 22050 - */ - if (dsp_stereo && speed > 22050 && Jazz16_detected == 0) - speed = 22050; -#endif - - if ((speed > 22050) && sb_midi_busy) - { - printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n"); - speed = 22050; - } - - if (dsp_stereo) - speed *= 2; - - /* - * Now the speed should be valid - */ - - if (speed > 22050) - { /* - * High speed mode - */ - int tmp; - - tconst = (unsigned char) ((65536 - - ((256000000 + speed / 2) / speed)) >> 8); - sb_dsp_highspeed = 1; - - DISABLE_INTR (flags); - if (sb_dsp_command (0x40)) - sb_dsp_command (tconst); - RESTORE_INTR (flags); - - tmp = 65536 - (tconst << 8); - speed = (256000000 + tmp / 2) / tmp; - } - else - { - int tmp; - - sb_dsp_highspeed = 0; - tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff; - - DISABLE_INTR (flags); - if (sb_dsp_command (0x40)) /* - * Set time constant - */ - sb_dsp_command (tconst); - RESTORE_INTR (flags); - - tmp = 256 - tconst; - speed = (1000000 + tmp / 2) / tmp; - } - - if (dsp_stereo) - speed /= 2; - - dsp_current_speed = speed; - return speed; -} - -static int -dsp_set_stereo (int mode) -{ - dsp_stereo = 0; - -#ifdef EXCLUDE_SBPRO - return 0; -#else - if (sbc_major < 3 || sb16) - return 0; /* - * Sorry no stereo - */ - - if (mode && sb_midi_busy) - { - printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n"); - return 0; - } - - dsp_stereo = !!mode; - return dsp_stereo; -#endif -} - -static void -sb_dsp_output_block (int dev, unsigned long buf, int count, - int intrflag, int restart_dma) -{ - unsigned long flags; - - if (!sb_irq_mode) - dsp_speaker (ON); - - sb_irq_mode = IMODE_OUTPUT; - DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); - - if (audio_devs[dev]->dmachan > 3) - count >>= 1; - count--; - - if (sb_dsp_highspeed) - { - DISABLE_INTR (flags); - if (sb_dsp_command (0x48)) /* - * High speed size - */ - { - sb_dsp_command ((unsigned char) (count & 0xff)); - sb_dsp_command ((unsigned char) ((count >> 8) & 0xff)); - sb_dsp_command (0x91); /* - * High speed 8 bit DAC - */ - } - else - printk ("SB Error: Unable to start (high speed) DAC\n"); - RESTORE_INTR (flags); - } - else - { - DISABLE_INTR (flags); - if (sb_dsp_command (0x14)) /* - * 8-bit DAC (DMA) - */ - { - sb_dsp_command ((unsigned char) (count & 0xff)); - sb_dsp_command ((unsigned char) ((count >> 8) & 0xff)); - } - else - printk ("SB Error: Unable to start DAC\n"); - RESTORE_INTR (flags); - } - sb_intr_active = 1; -} - -static void -sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, - int restart_dma) -{ - /* - * Start a DMA input to the buffer pointed by dmaqtail - */ - - unsigned long flags; - - if (!sb_irq_mode) - dsp_speaker (OFF); - - sb_irq_mode = IMODE_INPUT; - DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); - - if (audio_devs[dev]->dmachan > 3) - count >>= 1; - count--; - - if (sb_dsp_highspeed) - { - DISABLE_INTR (flags); - if (sb_dsp_command (0x48)) /* - * High speed size - */ - { - sb_dsp_command ((unsigned char) (count & 0xff)); - sb_dsp_command ((unsigned char) ((count >> 8) & 0xff)); - sb_dsp_command (0x99); /* - * High speed 8 bit ADC - */ - } - else - printk ("SB Error: Unable to start (high speed) ADC\n"); - RESTORE_INTR (flags); - } - else - { - DISABLE_INTR (flags); - if (sb_dsp_command (0x24)) /* - * 8-bit ADC (DMA) - */ - { - sb_dsp_command ((unsigned char) (count & 0xff)); - sb_dsp_command ((unsigned char) ((count >> 8) & 0xff)); - } - else - printk ("SB Error: Unable to start ADC\n"); - RESTORE_INTR (flags); - } - - sb_intr_active = 1; -} - -static void -dsp_cleanup (void) -{ - sb_intr_active = 0; -} - -static int -sb_dsp_prepare_for_input (int dev, int bsize, int bcount) -{ - dsp_cleanup (); - dsp_speaker (OFF); - - if (sbc_major == 3) /* - * SB Pro - */ - { -#ifdef JAZZ16 - /* Select correct dma channel - * for 16/8 bit acccess - */ - audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8; - if (dsp_stereo) - sb_dsp_command (dsp_16bit ? 0xac : 0xa8); - else - sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0); -#else - /* 8 bit only cards use this - */ - if (dsp_stereo) - sb_dsp_command (0xa8); - else - sb_dsp_command (0xa0); -#endif - dsp_speed (dsp_current_speed); /* - * Speed must be recalculated if - * #channels * changes - */ - } - return 0; -} - -static int -sb_dsp_prepare_for_output (int dev, int bsize, int bcount) -{ - dsp_cleanup (); - dsp_speaker (ON); - -#ifndef EXCLUDE_SBPRO - if (sbc_major == 3) /* - * SB Pro - */ - { -#ifdef JAZZ16 - /* 16 bit specific instructions - */ - audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8; - if (Jazz16_detected != 2) /* SM Wave */ - sb_mixer_set_stereo (dsp_stereo); - if (dsp_stereo) - sb_dsp_command (dsp_16bit ? 0xac : 0xa8); - else - sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0); -#else - sb_mixer_set_stereo (dsp_stereo); -#endif - dsp_speed (dsp_current_speed); /* - * Speed must be recalculated if - * #channels * changes - */ - } -#endif - return 0; -} - -static void -sb_dsp_halt_xfer (int dev) -{ -} - -static int -verify_irq (void) -{ -#if 0 - DEFINE_WAIT_QUEUE (testq, testf); - - irq_ok = 0; - - if (sb_get_irq () == -1) - { - printk ("*** SB Error: Irq %d already in use\n", sbc_irq); - return 0; - } - - - sb_irq_mode = IMODE_INIT; - - sb_dsp_command (0xf2); /* - * This should cause immediate interrupt - */ - - DO_SLEEP (testq, testf, HZ / 5); - - sb_free_irq (); - - if (!irq_ok) - { - printk ("SB Warning: IRQ%d test not passed!", sbc_irq); - irq_ok = 1; - } -#else - irq_ok = 1; -#endif - return irq_ok; -} - -static int -sb_dsp_open (int dev, int mode) -{ - int retval; - - if (!sb_dsp_ok) - { - printk ("SB Error: SoundBlaster board not installed\n"); - return RET_ERROR (ENXIO); - } - - if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI)) - { - printk ("SB: PCM not possible during MIDI input\n"); - return RET_ERROR (EBUSY); - } - - if (!irq_verified) - { - verify_irq (); - irq_verified = 1; - } - else if (!irq_ok) - printk ("SB Warning: Incorrect IRQ setting %d\n", - sbc_irq); - - retval = sb_get_irq (); - if (retval) - return retval; - - /* Allocate 8 bit dma - */ - if (DMAbuf_open_dma (dev) < 0) - { - sb_free_irq (); - printk ("SB: DMA Busy\n"); - return RET_ERROR (EBUSY); - } -#ifdef JAZZ16 - /* Allocate 16 bit dma - */ - if (Jazz16_detected != 0) - if (dma16 != dma8) - { - if (ALLOC_DMA_CHN (dma16, "Jazz16 16 bit")) - { - sb_free_irq (); - RELEASE_DMA_CHN (dma8); - return RET_ERROR (EBUSY); - } - } -#endif - - sb_irq_mode = IMODE_NONE; - - sb_dsp_busy = 1; - open_mode = mode; - - return 0; -} - -static void -sb_dsp_close (int dev) -{ -#ifdef JAZZ16 - /* Release 16 bit dma channel - */ - if (Jazz16_detected) - RELEASE_DMA_CHN (dma16); -#endif - - DMAbuf_close_dma (dev); - sb_free_irq (); - dsp_cleanup (); - dsp_speaker (OFF); - sb_dsp_busy = 0; - sb_dsp_highspeed = 0; - open_mode = 0; -} - -#ifdef JAZZ16 -/* Function dsp_set_bits() only required for 16 bit cards - */ -static int -dsp_set_bits (int arg) -{ - if (arg) - if (Jazz16_detected == 0) - dsp_16bit = 0; - else - switch (arg) - { - case 8: - dsp_16bit = 0; - break; - case 16: - dsp_16bit = 1; - break; - default: - dsp_16bit = 0; - } - return dsp_16bit ? 16 : 8; -} - -#endif /* ifdef JAZZ16 */ - -static int -sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) -{ - switch (cmd) - { - case SOUND_PCM_WRITE_RATE: - if (local) - return dsp_speed (arg); - return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg))); - break; - - case SOUND_PCM_READ_RATE: - if (local) - return dsp_current_speed; - return IOCTL_OUT (arg, dsp_current_speed); - break; - - case SOUND_PCM_WRITE_CHANNELS: - if (local) - return dsp_set_stereo (arg - 1) + 1; - return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1); - break; - - case SOUND_PCM_READ_CHANNELS: - if (local) - return dsp_stereo + 1; - return IOCTL_OUT (arg, dsp_stereo + 1); - break; - - case SNDCTL_DSP_STEREO: - if (local) - return dsp_set_stereo (arg); - return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg))); - break; - -#ifdef JAZZ16 - /* Word size specific cases here. - * SNDCTL_DSP_SETFMT=SOUND_PCM_WRITE_BITS - */ - case SNDCTL_DSP_SETFMT: - if (local) - return dsp_set_bits (arg); - return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg))); - break; - - case SOUND_PCM_READ_BITS: - if (local) - return dsp_16bit ? 16 : 8; - return IOCTL_OUT (arg, dsp_16bit ? 16 : 8); - break; -#else - case SOUND_PCM_WRITE_BITS: - case SOUND_PCM_READ_BITS: - if (local) - return 8; - return IOCTL_OUT (arg, 8); /* - * Only 8 bits/sample supported - */ - break; -#endif /* ifdef JAZZ16 */ - - case SOUND_PCM_WRITE_FILTER: - case SOUND_PCM_READ_FILTER: - return RET_ERROR (EINVAL); - break; - - default: - return RET_ERROR (EINVAL); - } - - return RET_ERROR (EINVAL); -} - -static void -sb_dsp_reset (int dev) -{ - unsigned long flags; - - DISABLE_INTR (flags); - - sb_reset_dsp (); - dsp_speed (dsp_current_speed); - dsp_cleanup (); - - RESTORE_INTR (flags); -} - -#endif - - -#ifdef JAZZ16 - -/* - * Initialization of a Media Vision ProSonic 16 Soundcard. - * The function initializes a ProSonic 16 like PROS.EXE does for DOS. It sets - * the base address, the DMA-channels, interrupts and enables the joystickport. - * - * Also used by Jazz 16 (same card, different name) - * - * written 1994 by Rainer Vranken - * E-Mail: rvranken@polaris.informatik.uni-essen.de - */ - - -#ifndef MPU_BASE /* take default values if not specified */ -#define MPU_BASE 0x330 -#endif -#ifndef MPU_IRQ -#define MPU_IRQ 9 -#endif - -unsigned int -get_sb_byte (void) -{ - int i; - - for (i = 1000; i; i--) - if (INB (DSP_DATA_AVAIL) & 0x80) - { - return INB (DSP_READ); - } - - return 0xffff; -} - -#ifdef SM_WAVE -/* - * Logitech Soundman Wave detection and initialization by Hannu Savolainen. - * - * There is a microcontroller (8031) in the SM Wave card for MIDI emulation. - * it's located at address MPU_BASE+4. MPU_BASE+7 is a SM Wave specific - * control register for MC reset, SCSI, OPL4 and DSP (future expansion) - * address decoding. Otherwise the SM Wave is just a ordinary MV Jazz16 - * based soundcard. - */ - -static void -smw_putmem (int base, int addr, unsigned char val) -{ - unsigned long flags; - - DISABLE_INTR (flags); - - OUTB (addr & 0xff, base + 1); /* Low address bits */ - OUTB (addr >> 8, base + 2); /* High address bits */ - OUTB (val, base); /* Data */ - - RESTORE_INTR (flags); -} - -static unsigned char -smw_getmem (int base, int addr) -{ - unsigned long flags; - unsigned char val; - - DISABLE_INTR (flags); - - OUTB (addr & 0xff, base + 1); /* Low address bits */ - OUTB (addr >> 8, base + 2); /* High address bits */ - val = INB (base); /* Data */ - - RESTORE_INTR (flags); - return val; -} - -static int -initialize_smw (void) -{ -#ifdef SMW_MIDI0001_INCLUDED -#include <i386/isa/sound/smw-midi0001.h> -#else - unsigned char smw_ucode[1]; - int smw_ucodeLen = 0; - -#endif - - int mp_base = MPU_BASE + 4; /* Microcontroller base */ - int i; - unsigned char control; - - /* - * Reset the microcontroller so that the RAM can be accessed - */ - - control = INB (MPU_BASE + 7); - OUTB (control | 3, MPU_BASE + 7); /* Set last two bits to 1 (?) */ - OUTB ((control & 0xfe) | 2, MPU_BASE + 7); /* xxxxxxx0 resets the mc */ - - for (i = 0; i < 300; i++) /* Wait at least 1ms */ - tenmicrosec (); - - OUTB (control & 0xfc, MPU_BASE + 7); /* xxxxxx00 enables RAM */ - - /* - * Detect microcontroller by probing the 8k RAM area - */ - smw_putmem (mp_base, 0, 0x00); - smw_putmem (mp_base, 1, 0xff); - tenmicrosec (); - - if (smw_getmem (mp_base, 0) != 0x00 || smw_getmem (mp_base, 1) != 0xff) - { - printk ("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n", - smw_getmem (mp_base, 0), smw_getmem (mp_base, 1)); - return 0; /* No RAM */ - } - - /* - * There is RAM so assume it's really a SM Wave - */ - -#ifdef SMW_MIDI0001_INCLUDED - if (smw_ucodeLen != 8192) - { - printk ("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n"); - return 1; - } -#endif - - /* - * Download microcode - */ - - for (i = 0; i < 8192; i++) - smw_putmem (mp_base, i, smw_ucode[i]); - - /* - * Verify microcode - */ - - for (i = 0; i < 8192; i++) - if (smw_getmem (mp_base, i) != smw_ucode[i]) - { - printk ("SM Wave: Microcode verification failed\n"); - return 0; - } - - control = 0; -#ifdef SMW_SCSI_IRQ - /* - * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt - * is disabled by default. - * - * Btw the Zilog 5380 SCSI controller is located at MPU base + 0x10. - */ - { - static unsigned char scsi_irq_bits[] = - {0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0}; - - control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6; - } -#endif - -#ifdef SMW_OPL4_ENABLE - /* - * Make the OPL4 chip visible on the PC bus at 0x380. - * - * There is no need to enable this feature since VoxWare - * doesn't support OPL4 yet. Also there is no RAM in SM Wave so - * enabling OPL4 is pretty useless. - */ - control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */ - /* control |= 0x20; Uncomment this if you want to use IRQ7 */ -#endif - - OUTB (control | 0x03, MPU_BASE + 7); /* xxxxxx11 restarts */ - return 1; -} - -#endif - -static int -initialize_ProSonic16 (void) -{ - int x; - static unsigned char int_translat[16] = - {0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6}, dma_translat[8] = - {0, 1, 0, 2, 0, 3, 0, 4}; - - OUTB (0xAF, 0x201); /* ProSonic/Jazz16 wakeup */ - for (x = 0; x < 1000; ++x) /* wait 10 milliseconds */ - tenmicrosec (); - OUTB (0x50, 0x201); - OUTB ((sbc_base & 0x70) | ((MPU_BASE & 0x30) >> 4), 0x201); - - if (sb_reset_dsp ()) - { /* OK. We have at least a SB */ - - /* Check the version number of ProSonic (I guess) */ - - if (!sb_dsp_command (0xFA)) - return 1; - if (get_sb_byte () != 0x12) - return 1; - - if (sb_dsp_command (0xFB) && /* set DMA-channels and Interrupts */ - sb_dsp_command ((dma_translat[JAZZ_DMA16] << 4) | dma_translat[SBC_DMA]) && - sb_dsp_command ((int_translat[MPU_IRQ] << 4) | int_translat[sbc_irq])) - { - Jazz16_detected = 1; -#ifdef SM_WAVE - if (initialize_smw ()) - Jazz16_detected = 2; -#endif - sb_dsp_disable_midi (); - } - - return 1; /* There was at least a SB */ - } - return 0; /* No SB or ProSonic16 detected */ -} - -#endif /* ifdef JAZZ16 */ - -int -sb_dsp_detect (struct address_info *hw_config) -{ - sbc_base = hw_config->io_base; - sbc_irq = hw_config->irq; - - if (sb_dsp_ok) - return 0; /* - * Already initialized - */ -#ifdef JAZZ16 - dma8 = hw_config->dma; - dma16 = JAZZ_DMA16; - - if (!initialize_ProSonic16 ()) - return 0; -#else - if (!sb_reset_dsp ()) - return 0; -#endif - -#ifdef PC98 - switch (sbc_irq) - { - case 3: - sb_setmixer (IRQ_NR, 1); - break; - case 5: - sb_setmixer (IRQ_NR, 8); - break; - case 10: - sb_setmixer (IRQ_NR, 2); - break; - } - switch (hw_config->dma) - { - case 0: - sb_setmixer (DMA_NR, 1); - break; - case 3: - sb_setmixer (DMA_NR, 2); - break; - } -#endif - - return 1; /* - * Detected - */ -} - -#ifndef EXCLUDE_AUDIO -static struct audio_operations sb_dsp_operations = -{ - "SoundBlaster", - NOTHING_SPECIAL, - AFMT_U8, /* Just 8 bits. Poor old SB */ - NULL, - sb_dsp_open, - sb_dsp_close, - sb_dsp_output_block, - sb_dsp_start_input, - sb_dsp_ioctl, - sb_dsp_prepare_for_input, - sb_dsp_prepare_for_output, - sb_dsp_reset, - sb_dsp_halt_xfer, - NULL, /* local_qlen */ - NULL /* copy_from_user */ -}; - -#endif - -long -sb_dsp_init (long mem_start, struct address_info *hw_config) -{ - int i; - int mixer_type = 0; - - sbc_major = sbc_minor = 0; - sb_dsp_command (0xe1); /* - * Get version - */ - - for (i = 1000; i; i--) - { - if (INB (DSP_DATA_AVAIL) & 0x80) - { /* - * wait for Data Ready - */ - if (sbc_major == 0) - sbc_major = INB (DSP_READ); - else - { - sbc_minor = INB (DSP_READ); - break; - } - } - } - - if (sbc_major == 2 || sbc_major == 3) - sb_duplex_midi = 1; - - if (sbc_major == 4) - sb16 = 1; - -#ifndef EXCLUDE_SBPRO - if (sbc_major >= 3) - mixer_type = sb_mixer_init (sbc_major); -#else - if (sbc_major >= 3) - printk ("\n\n\n\nNOTE! SB Pro support is required with your soundcard!\n\n\n"); -#endif - -#ifndef EXCLUDE_YM3812 - -#ifdef PC98 - if (sbc_major > 3 || - (sbc_major == 3 && INB (0x28d2) == 0x00)) -#else - if (sbc_major > 3 || - (sbc_major == 3 && INB (0x388) == 0x00)) /* Should be 0x06 if not OPL-3 */ -#endif - enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH); -#endif - -#ifndef EXCLUDE_AUDIO - if (sbc_major >= 3) - { - if (Jazz16_detected) - { - if (Jazz16_detected == 2) - sprintf (sb_dsp_operations.name, "SoundMan Wave %d.%d", sbc_major, sbc_minor); - else - sprintf (sb_dsp_operations.name, "MV Jazz16 %d.%d", sbc_major, sbc_minor); - sb_dsp_operations.format_mask |= AFMT_S16_LE; /* Hurrah, 16 bits */ - } - else -#ifdef __SGNXPRO__ - if (mixer_type == 2) - { - sprintf (sb_dsp_operations.name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor); - } - else -#endif - - if (sbc_major == 4) - { - sprintf (sb_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor); - } - else - { - sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor); - } - } - else - { - sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor); - } - -#if defined(__FreeBSD__) - printk ("sb0: <%s>", sb_dsp_operations.name); -#else - printk (" <%s>", sb_dsp_operations.name); -#endif - -#if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO) - if (!sb16) /* - * There is a better driver for SB16 - */ -#endif - if (num_audiodevs < MAX_AUDIO_DEV) - { - audio_devs[my_dev = num_audiodevs++] = &sb_dsp_operations; - audio_devs[my_dev]->buffcount = DSP_BUFFCOUNT; - audio_devs[my_dev]->buffsize = ( - (sbc_major > 2 || sbc_major == 2 && sbc_minor > 0) ? - 16 : 8) * 1024; - audio_devs[my_dev]->dmachan = hw_config->dma; - } - else - printk ("SB: Too many DSP devices available\n"); -#else - printk (" <SoundBlaster (configured without audio support)>"); -#endif - -#ifndef EXCLUDE_MIDI - if (!midi_disabled && !sb16) /* - * Midi don't work in the SB emulation mode * - * of PAS, SB16 has better midi interface - */ - sb_midi_init (sbc_major); -#endif - - sb_dsp_ok = 1; - return mem_start; -} - -void -sb_dsp_disable_midi (void) -{ - midi_disabled = 1; -} - -#endif diff --git a/sys/pc98/pc98/sound/sound_config.h b/sys/pc98/pc98/sound/sound_config.h deleted file mode 100644 index a714c33..0000000 --- a/sys/pc98/pc98/sound/sound_config.h +++ /dev/null @@ -1,384 +0,0 @@ -/* sound_config.h - * - * A driver for Soundcards, misc configuration parameters. - * - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifdef PC98 -#include <pc98/pc98/sound/local.h> -#else -#include <i386/isa/sound/local.h> -#endif -#include <i386/isa/sound/os.h> -#include <i386/isa/sound/soundvers.h> - -#if !defined(PSS_MPU_BASE) && defined(EXCLUDE_SSCAPE) && defined(EXCLUDE_TRIX) -#define EXCLUDE_MPU_EMU -#endif - -#if defined(ISC) || defined(SCO) || defined(SVR42) -#define GENERIC_SYSV -#endif - -/* - * Disable the AD1848 driver if there are no other drivers requiring it. - */ - -#if defined(EXCLUDE_GUS16) && defined(EXCLUDE_MSS) && defined(EXCLUDE_PSS) && defined(EXCLUDE_GUSMAX) && defined(EXCLUDE_SSCAPE) && defined(EXCLUDE_TRIX) -#define EXCLUDE_AD1848 -#endif - -#ifdef PSS_MSS_BASE -#undef EXCLUDE_AD1848 -#endif - -#undef CONFIGURE_SOUNDCARD -#undef DYNAMIC_BUFFER - -#ifdef KERNEL_SOUNDCARD -#define CONFIGURE_SOUNDCARD -#define DYNAMIC_BUFFER -#undef LOADABLE_SOUNDCARD -#endif - -#ifdef EXCLUDE_SEQUENCER -#define EXCLUDE_MIDI -#define EXCLUDE_YM3812 -#define EXCLUDE_OPL3 -#endif - -#ifndef SND_DEFAULT_ENABLE -#define SND_DEFAULT_ENABLE 1 -#endif - -#ifdef CONFIGURE_SOUNDCARD - -/* ****** IO-address, DMA and IRQ settings **** - -If your card has nonstandard I/O address or IRQ number, change defines - for the following settings in your kernel Makefile */ - -#ifndef SBC_BASE -#ifdef PC98 -#define SBC_BASE 0x20d2 /* 0x20d2 is the factory default. */ -#else -#define SBC_BASE 0x220 /* 0x220 is the factory default. */ -#endif -#endif - -#ifndef SBC_IRQ -#ifdef PC98 -#define SBC_IRQ 10 /* IQR10 is not the factory default on PC9821. */ -#else -#define SBC_IRQ 7 /* IQR7 is the factory default. */ -#endif -#endif - -#ifndef SBC_DMA -#ifdef PC98 -#define SBC_DMA 3 -#else -#define SBC_DMA 1 -#endif -#endif - -#ifndef SB16_DMA -#ifdef PC98 -#define SB16_DMA 3 -#else -#define SB16_DMA 6 -#endif -#endif - -#ifndef SB16MIDI_BASE -#ifdef PC98 -#define SB16MIDI_BASE 0x80d2 -#else -#define SB16MIDI_BASE 0x300 -#endif -#endif - -#ifndef PAS_BASE -#define PAS_BASE 0x388 -#endif - -#ifndef PAS_IRQ -#define PAS_IRQ 5 -#endif - -#ifndef PAS_DMA -#define PAS_DMA 3 -#endif - -#ifndef GUS_BASE -#define GUS_BASE 0x220 -#endif - -#ifndef GUS_IRQ -#define GUS_IRQ 15 -#endif - -#ifndef GUS_MIDI_IRQ -#define GUS_MIDI_IRQ GUS_IRQ -#endif - -#ifndef GUS_DMA -#define GUS_DMA 6 -#endif - -#ifndef GUS_DMA_READ -#define GUS_DMA_READ 3 -#endif - -#ifndef MPU_BASE -#define MPU_BASE 0x330 -#endif - -#ifndef MPU_IRQ -#define MPU_IRQ 6 -#endif - -/* Echo Personal Sound System */ -#ifndef PSS_BASE -#define PSS_BASE 0x220 /* 0x240 or */ -#endif - -#ifndef PSS_IRQ -#define PSS_IRQ 7 -#endif - -#ifndef PSS_DMA -#define PSS_DMA 1 -#endif - -#ifndef MSS_BASE -#define MSS_BASE 0 -#endif - -#ifndef MSS_DMA -#define MSS_DMA 0 -#endif - -#ifndef MSS_IRQ -#define MSS_IRQ 0 -#endif - -#ifndef GUS16_BASE -#define GUS16_BASE 0 -#endif - -#ifndef GUS16_DMA -#define GUS16_DMA 0 -#endif - -#ifndef GUS16_IRQ -#define GUS16_IRQ 0 -#endif - -#ifndef SSCAPE_BASE -#define SSCAPE_BASE 0 -#endif - -#ifndef SSCAPE_DMA -#define SSCAPE_DMA 0 -#endif - -#ifndef SSCAPE_IRQ -#define SSCAPE_IRQ 0 -#endif - -#ifndef SSCAPE_MSS_BASE -#define SSCAPE_MSS_BASE 0 -#endif - -#ifndef SSCAPE_MSS_DMA -#define SSCAPE_MSS_DMA 0 -#endif - -#ifndef SSCAPE_MSS_IRQ -#define SSCAPE_MSS_IRQ 0 -#endif - -#ifndef TRIX_BASE -#define TRIX_BASE 0x530 -#endif - -#ifndef TRIX_IRQ -#define TRIX_IRQ 10 -#endif - -#ifndef TRIX_DMA -#define TRIX_DMA 1 -#endif - -#ifndef U6850_BASE -#define U6850_BASE 0x330 -#endif - -#ifndef U6850_IRQ -#define U6850_IRQ 5 -#endif - -#ifndef U6850_DMA -#define U6850_DMA 1 -#endif - -#ifndef MAX_REALTIME_FACTOR -#define MAX_REALTIME_FACTOR 4 -#endif - -/************* PCM DMA buffer sizes *******************/ - -/* If you are using high playback or recording speeds, the default buffersize - is too small. DSP_BUFFSIZE must be 64k or less. - - A rule of thumb is 64k for PAS16, 32k for PAS+, 16k for SB Pro and - 4k for SB. - - If you change the DSP_BUFFSIZE, don't modify this file. - Use the make config command instead. */ - -#ifndef DSP_BUFFSIZE -#define DSP_BUFFSIZE (4096) -#endif - -#ifndef DSP_BUFFCOUNT -#define DSP_BUFFCOUNT 2 /* 2 is recommended. */ -#endif - -#define DMA_AUTOINIT 0x10 - -#ifdef PC98 -#define FM_MONO 0x28d2 /* This is the I/O address used by AdLib */ -#else -#define FM_MONO 0x388 /* This is the I/O address used by AdLib */ -#endif - -/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the - driver. (There is no need to alter this) */ -#define SEQ_MAX_QUEUE 1024 - -#define SBFM_MAXINSTR (256) /* Size of the FM Instrument bank */ -/* 128 instruments for general MIDI setup and 16 unassigned */ - -/* - * Minor numbers for the sound driver. - * - * Unfortunately Creative called the codec chip of SB as a DSP. For this - * reason the /dev/dsp is reserved for digitized audio use. There is a - * device for true DSP processors but it will be called something else. - * In v3.0 it's /dev/sndproc but this could be a temporary solution. - */ - -#define SND_NDEVS 256 /* Number of supported devices */ -#define SND_DEV_CTL 0 /* Control port /dev/mixer */ -#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM - synthesizer and MIDI output) */ -#define SND_DEV_MIDIN 2 /* Raw midi access */ -#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ -#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ -#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ -#define SND_DEV_STATUS 6 /* /dev/sndstat */ -/* #7 not in use now. Was in 2.4. Free for use after v3.0. */ -#define SND_DEV_SEQ2 8 /* /dev/sequecer, level 2 interface */ -#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ -#define SND_DEV_PSS SND_DEV_SNDPROC - -#define DSP_DEFAULT_SPEED 8000 - -#define ON 1 -#define OFF 0 - -#define MAX_AUDIO_DEV 5 -#define MAX_MIXER_DEV 5 -#define MAX_SYNTH_DEV 3 -#define MAX_MIDI_DEV 6 -#define MAX_TIMER_DEV 3 - -struct fileinfo { - int mode; /* Open mode */ - DECLARE_FILE(); /* Reference to file-flags. OS-dependent. */ - }; - -struct address_info { - int io_base; - int irq; - int dma; /* write dma channel */ - int dma_read; /* read dma channel */ - int always_detect; /* 1=Trust me, it's there */ -}; - -#define SYNTH_MAX_VOICES 32 - -struct voice_alloc_info { - int max_voice; - int used_voices; - int ptr; /* For device specific use */ - unsigned short map[SYNTH_MAX_VOICES]; /* (ch << 8) | (note+1) */ - int timestamp; - int alloc_times[SYNTH_MAX_VOICES]; - }; - -struct channel_info { - int pgm_num; - int bender_value; - unsigned char controllers[128]; - }; - -/* - * Process wakeup reasons - */ -#define WK_NONE 0x00 -#define WK_WAKEUP 0x01 -#define WK_TIMEOUT 0x02 -#define WK_SIGNAL 0x04 -#define WK_SLEEP 0x08 - -#define OPEN_READ 1 -#define OPEN_WRITE 2 -#define OPEN_READWRITE 3 - -#ifdef PC98 -#include <pc98/pc98/sound/sound_calls.h> -#include <pc98/pc98/sound/dev_table.h> -#else -#include <i386/isa/sound/sound_calls.h> -#include <i386/isa/sound/dev_table.h> -#endif - -#ifndef DEB -#define DEB(x) -#endif - -#ifndef AUDIO_DDB -#define AUDIO_DDB(x) -#endif - -#define TIMER_ARMED 121234 -#define TIMER_NOT_ARMED 1 - -#endif diff --git a/sys/pc98/pc98/sound/sound_switch.c b/sys/pc98/pc98/sound/sound_switch.c deleted file mode 100644 index 83994e0..0000000 --- a/sys/pc98/pc98/sound/sound_switch.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * sound/sound_switch.c - * - * The system call switch - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <i386/isa/sound/sound_config.h> - -#ifdef CONFIGURE_SOUNDCARD - -struct sbc_device - { - int usecount; - }; - -static struct sbc_device sbc_devices[SND_NDEVS] = -{ - {0}}; - -static int in_use = 0; /* - - - * * * * Total # of open device files - * (excluding * * * minor 0) */ - -/* - * /dev/sndstatus -device - */ -static char *status_buf = NULL; -static int status_len, status_ptr; -static int status_busy = 0; - -static int -put_status (char *s) -{ - int l; - - for (l = 0; l < 256, s[l]; l++); /* - * l=strlen(s); - */ - - if (status_len + l >= 4000) - return 0; - - memcpy (&status_buf[status_len], s, l); - status_len += l; - - return 1; -} - -static int -put_status_int (unsigned int val, int radix) -{ - int l, v; - - static char hx[] = "0123456789abcdef"; - char buf[11]; - - if (!val) - return put_status ("0"); - - l = 0; - buf[10] = 0; - - while (val) - { - v = val % radix; - val = val / radix; - - buf[9 - l] = hx[v]; - l++; - } - - if (status_len + l >= 4000) - return 0; - - memcpy (&status_buf[status_len], &buf[10 - l], l); - status_len += l; - - return 1; -} - -static void -init_status (void) -{ - /* - * Write the status information to the status_buf and update status_len. - * There is a limit of 4000 bytes for the data. - */ - - int i; - - status_ptr = 0; - - put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING - " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@" - SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")" - "\n"); - - if (!put_status ("Config options: ")) - return; - if (!put_status_int (SELECTED_SOUND_OPTIONS, 16)) - return; - - if (!put_status ("\n\nInstalled drivers: \n")) - return; - - for (i = 0; i < (num_sound_drivers - 1); i++) - { - if (!put_status ("Type ")) - return; - if (!put_status_int (sound_drivers[i].card_type, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (sound_drivers[i].name)) - return; - - if (!put_status ("\n")) - return; - } - - if (!put_status ("\n\nCard config: \n")) - return; - - for (i = 0; i < (num_sound_cards - 1); i++) - { - int drv; - - if (!snd_installed_cards[i].enabled) - if (!put_status ("(")) - return; - - /* - * if (!put_status_int(snd_installed_cards[i].card_type, 10)) return; - * if (!put_status (": ")) return; - */ - - if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) != -1) - if (!put_status (sound_drivers[drv].name)) - return; - - if (!put_status (" at 0x")) - return; - if (!put_status_int (snd_installed_cards[i].config.io_base, 16)) - return; - if (!put_status (" irq ")) - return; - if (!put_status_int (snd_installed_cards[i].config.irq, 10)) - return; -#ifdef PC98 - if (snd_installed_cards[i].config.dma >= 0) { -#endif - if (!put_status (" drq ")) - return; - if (!put_status_int (snd_installed_cards[i].config.dma, 10)) - return; -#ifdef PC98 - } -#endif - - if (!snd_installed_cards[i].enabled) - if (!put_status (")")) - return; - - if (!put_status ("\n")) - return; - } - -#ifdef EXCLUDE_AUDIO - if (!put_status ("\nAudio devices: NOT ENABLED IN CONFIG\n")) - return; -#else - if (!put_status ("\nAudio devices:\n")) - return; - - for (i = 0; i < num_audiodevs; i++) - { - if (!put_status_int (i, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (audio_devs[i]->name)) - return; - if (!put_status ("\n")) - return; - } -#endif - -#ifdef EXCLUDE_SEQUENCER - if (!put_status ("\nSynth devices: NOT ENABLED IN CONFIG\n")) - return; -#else - if (!put_status ("\nSynth devices:\n")) - return; - - for (i = 0; i < num_synths; i++) - { - if (!put_status_int (i, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (synth_devs[i]->info->name)) - return; - if (!put_status ("\n")) - return; - } -#endif - -#ifdef EXCLUDE_MIDI - if (!put_status ("\nMidi devices: NOT ENABLED IN CONFIG\n")) - return; -#else - if (!put_status ("\nMidi devices:\n")) - return; - - for (i = 0; i < num_midis; i++) - { - if (!put_status_int (i, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (midi_devs[i]->info.name)) - return; - if (!put_status ("\n")) - return; - } -#endif - - if (!put_status ("\nTimers:\n")) - return; - - for (i = 0; i < num_sound_timers; i++) - { - if (!put_status_int (i, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (sound_timer_devs[i]->info.name)) - return; - if (!put_status ("\n")) - return; - } - - if (!put_status ("\nMixers:\n")) - return; - - for (i = 0; i < num_mixers; i++) - { - if (!put_status_int (i, 10)) - return; - if (!put_status (": ")) - return; - if (!put_status (mixer_devs[i]->name)) - return; - if (!put_status ("\n")) - return; - } -} - -static int -read_status (snd_rw_buf * buf, int count) -{ - /* - * Return at most 'count' bytes from the status_buf. - */ - int l, c; - - l = count; - c = status_len - status_ptr; - - if (l > c) - l = c; - if (l <= 0) - return 0; - - COPY_TO_USER (buf, 0, &status_buf[status_ptr], l); - status_ptr += l; - - return l; -} - -int -sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count) -{ - DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count)); - - switch (dev & 0x0f) - { - case SND_DEV_STATUS: - return read_status (buf, count); - break; - - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - return audio_read (dev, file, buf, count); - break; - - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - return sequencer_read (dev, file, buf, count); - break; - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - return MIDIbuf_read (dev, file, buf, count); -#endif - - default: - printk ("Sound: Undefined minor device %d\n", dev); - } - - return RET_ERROR (EPERM); -} - -int -sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count) -{ - - DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count)); - - switch (dev & 0x0f) - { - - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - return sequencer_write (dev, file, buf, count); - break; - - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - return audio_write (dev, file, buf, count); - break; - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - return MIDIbuf_write (dev, file, buf, count); -#endif - - default: - return RET_ERROR (EPERM); - } - - return count; -} - -int -sound_open_sw (int dev, struct fileinfo *file) -{ - int retval; - - DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount)); - - if ((dev >= SND_NDEVS) || (dev < 0)) - { - printk ("Invalid minor device %d\n", dev); - return RET_ERROR (ENXIO); - } - - switch (dev & 0x0f) - { - case SND_DEV_STATUS: - if (status_busy) - return RET_ERROR (EBUSY); - status_busy = 1; - if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL) - return RET_ERROR (EIO); - status_len = status_ptr = 0; - init_status (); - break; - - case SND_DEV_CTL: - return 0; - break; - - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - if ((retval = sequencer_open (dev, file)) < 0) - return retval; - break; - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - if ((retval = MIDIbuf_open (dev, file)) < 0) - return retval; - break; -#endif - - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - if ((retval = audio_open (dev, file)) < 0) - return retval; - break; - - default: - printk ("Invalid minor device %d\n", dev); - return RET_ERROR (ENXIO); - } - - sbc_devices[dev].usecount++; - in_use++; - - return 0; -} - -void -sound_release_sw (int dev, struct fileinfo *file) -{ - - DEB (printk ("sound_release_sw(dev=%d)\n", dev)); - - switch (dev & 0x0f) - { - case SND_DEV_STATUS: - if (status_buf) - KERNEL_FREE (status_buf); - status_buf = NULL; - status_busy = 0; - break; - - case SND_DEV_CTL: - break; - - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - sequencer_release (dev, file); - break; - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - MIDIbuf_release (dev, file); - break; -#endif - - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - audio_release (dev, file); - break; - - default: - printk ("Sound error: Releasing unknown device 0x%02x\n", dev); - } - - sbc_devices[dev].usecount--; - in_use--; -} - -int -sound_ioctl_sw (int dev, struct fileinfo *file, - unsigned int cmd, unsigned long arg) -{ - DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg)); - - if ((cmd >> 8) & 0xff == 'M' && num_mixers > 0) /* Mixer ioctl */ - if ((dev & 0x0f) != SND_DEV_CTL) - { - int dtype = dev & 0x0f; - int mixdev; - - switch (dtype) - { - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - mixdev = audio_devs[dev >> 4]->mixer_dev; - if (mixdev < 0 || mixdev >= num_mixers) - return RET_ERROR (ENXIO); - return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg); - break; - - default: - return mixer_devs[0]->ioctl (0, cmd, arg); - } - } - - switch (dev & 0x0f) - { - - case SND_DEV_CTL: - - if (!num_mixers) - return RET_ERROR (ENXIO); - - dev = dev >> 4; - - if (dev >= num_mixers) - return RET_ERROR (ENXIO); - - return mixer_devs[dev]->ioctl (dev, cmd, arg); - break; - - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - return sequencer_ioctl (dev, file, cmd, arg); - break; - - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - return audio_ioctl (dev, file, cmd, arg); - break; - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - return MIDIbuf_ioctl (dev, file, cmd, arg); - break; -#endif - - default: - return RET_ERROR (EPERM); - break; - } - - return RET_ERROR (EPERM); -} - -#endif diff --git a/sys/pc98/pc98/sound/soundcard.c b/sys/pc98/pc98/sound/soundcard.c deleted file mode 100644 index 1709503..0000000 --- a/sys/pc98/pc98/sound/soundcard.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * sound/386bsd/soundcard.c - * - * Soundcard driver for FreeBSD. - * - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: soundcard.c,v 1.6 1996/10/29 08:36:59 asami Exp $ - */ - -#include <i386/isa/sound/sound_config.h> -#include <vm/vm.h> -#include <vm/vm_extern.h> - -#ifdef CONFIGURE_SOUNDCARD - -#include <i386/isa/sound/dev_table.h> -#include <i386/isa/isa_device.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#ifdef DEVFS -#include <sys/devfsext.h> -#endif /*DEVFS*/ - -#define FIX_RETURN(ret) { \ - int tmp_ret = (ret); \ - if (tmp_ret<0) return -tmp_ret; else return 0; \ - } - -static int timer_running = 0; - -static int soundcards_installed = 0; /* Number of installed - * soundcards */ -static int soundcard_configured = 0; - -static struct fileinfo files[SND_NDEVS]; - -#ifdef DEVFS -static void * snd_devfs_token[SND_NDEVS]; -static void * sndstat_devfs_token; -#endif - -struct selinfo selinfo[SND_NDEVS >> 4]; - -static int sndprobe (struct isa_device *dev); -static int sndattach (struct isa_device *dev); -static void sound_mem_init(void); - -static d_open_t sndopen; -static d_close_t sndclose; -static d_read_t sndread; -static d_write_t sndwrite; -static d_ioctl_t sndioctl; -static d_select_t sndselect; - -#define CDEV_MAJOR 30 -static struct cdevsw snd_cdevsw = - { sndopen, sndclose, sndread, sndwrite, /*30*/ - sndioctl, nostop, nullreset, nodevtotty,/* sound */ - sndselect, nommap, NULL, "snd", NULL, -1 }; - -struct isa_driver opldriver = {sndprobe, sndattach, "opl"}; -struct isa_driver sbdriver = {sndprobe, sndattach, "sb"}; -struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"}; -struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"}; -struct isa_driver pasdriver = {sndprobe, sndattach, "pas"}; -struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"}; -struct isa_driver gusdriver = {sndprobe, sndattach, "gus"}; -struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"}; -struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"}; -struct isa_driver uartdriver = {sndprobe, sndattach, "uart"}; -struct isa_driver mssdriver = {sndprobe, sndattach, "mss"}; -#ifdef PC98 -struct isa_driver pcmdriver = {sndprobe, sndattach, "pcm"}; -#endif - -static unsigned short -ipri_to_irq (unsigned short ipri); - -void -adintr(INT_HANDLER_PARMS(unit,dummy)) -{ -#ifndef EXCLUDE_AD1848 - static short unit_to_irq[4] = { -1, -1, -1, -1 }; - struct isa_device *dev; - - if (unit_to_irq [unit] > 0) - ad1848_interrupt(INT_HANDLER_CALL (unit_to_irq [unit])); - else { - dev = find_isadev (isa_devtab_null, &mssdriver, unit); - if (!dev) - printk ("ad1848: Couldn't determine unit\n"); - else { - unit_to_irq [unit] = ipri_to_irq (dev->id_irq); - ad1848_interrupt(INT_HANDLER_CALL (unit_to_irq [unit])); - } - } -#endif -} - -unsigned -long -get_time(void) -{ -struct timeval timecopy; -int x; - - x = splclock(); - timecopy = time; - splx(x); - return timecopy.tv_usec/(1000000/HZ) + - (unsigned long)timecopy.tv_sec*HZ; -} - - -static int -sndread (dev_t dev, struct uio *buf, int ioflag) -{ - int count = buf->uio_resid; - - dev = minor (dev); - - FIX_RETURN (sound_read_sw (dev, &files[dev], buf, count)); -} - -static int -sndwrite (dev_t dev, struct uio *buf, int ioflag) -{ - int count = buf->uio_resid; - - dev = minor (dev); - - FIX_RETURN (sound_write_sw (dev, &files[dev], buf, count)); -} - -static int -sndopen (dev_t dev, int flags, int fmt, struct proc *p) -{ - dev = minor (dev); - - if (!soundcard_configured && dev) - { - printk ("SoundCard Error: The soundcard system has not been configured\n"); - FIX_RETURN (-ENODEV); - } - - files[dev].mode = 0; - - if (flags & FREAD && flags & FWRITE) - files[dev].mode = OPEN_READWRITE; - else if (flags & FREAD) - files[dev].mode = OPEN_READ; - else if (flags & FWRITE) - files[dev].mode = OPEN_WRITE; - - selinfo[dev >> 4].si_pid = 0; - selinfo[dev >> 4].si_flags = 0; - - FIX_RETURN(sound_open_sw (dev, &files[dev])); -} - -static int -sndclose (dev_t dev, int flags, int fmt, struct proc *p) -{ - - dev = minor (dev); - - sound_release_sw(dev, &files[dev]); - FIX_RETURN (0); -} - -static int -sndioctl (dev_t dev, int cmd, caddr_t arg, int flags, struct proc *p) -{ - dev = minor (dev); - - FIX_RETURN (sound_ioctl_sw (dev, &files[dev], cmd, (unsigned int) arg)); -} - -static int -sndselect (dev_t dev, int rw, struct proc *p) -{ - dev = minor (dev); - - DEB (printk ("snd_select(dev=%d, rw=%d, pid=%d)\n", dev, rw, p->p_pid)); -#ifdef ALLOW_SELECT - switch (dev & 0x0f) - { -#ifndef EXCLUDE_SEQUENCER - case SND_DEV_SEQ: - case SND_DEV_SEQ2: - return sequencer_select (dev, &files[dev], rw, p); - break; -#endif - -#ifndef EXCLUDE_MIDI - case SND_DEV_MIDIN: - return MIDIbuf_select (dev, &files[dev], rw, p); - break; -#endif - -#ifndef EXCLUDE_AUDIO - case SND_DEV_DSP: - case SND_DEV_DSP16: - case SND_DEV_AUDIO: - return audio_select (dev, &files[dev], rw, p); - break; -#endif - - default: - return 0; - } - -#endif - - return 0; -} - -static unsigned short -ipri_to_irq (unsigned short ipri) -{ - /* - * Converts the ipri (bitmask) to the corresponding irq number - */ - int irq; - - for (irq = 0; irq < 16; irq++) - if (ipri == (1 << irq)) - return irq; - - return -1; /* Invalid argument */ -} - -static int -driver_to_voxunit(struct isa_driver *driver) -{ - /* converts a sound driver pointer into the equivalent - VoxWare device unit number */ - if(driver == &opldriver) - return(SNDCARD_ADLIB); - else if(driver == &sbdriver) - return(SNDCARD_SB); - else if(driver == &pasdriver) - return(SNDCARD_PAS); - else if(driver == &gusdriver) - return(SNDCARD_GUS); - else if(driver == &mpudriver) - return(SNDCARD_MPU401); - else if(driver == &sbxvidriver) - return(SNDCARD_SB16); - else if(driver == &sbmididriver) - return(SNDCARD_SB16MIDI); - else if(driver == &uartdriver) - return(SNDCARD_UART6850); - else if(driver == &gusdriver) - return(SNDCARD_GUS16); - else if(driver == &mssdriver) - return(SNDCARD_MSS); -#ifdef PC98 - else if(driver == &pcmdriver) - return(SNDCARD_PCM86); -#endif - else - return(0); -} - -static int -sndprobe (struct isa_device *dev) -{ - struct address_info hw_config; - int unit; - - unit = driver_to_voxunit(dev->id_driver); - hw_config.io_base = dev->id_iobase; - hw_config.irq = ipri_to_irq (dev->id_irq); - hw_config.dma = dev->id_drq; - hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/ - - if(unit) -#ifdef PC98 - if(unit == SNDCARD_PCM86) { - int result; - - result = sndtable_probe (unit, &hw_config); - dev->id_iobase = hw_config.io_base; - dev->id_irq = (1 << hw_config.irq); - dev->id_drq = hw_config.dma; - - return result; - } - else -#endif - return sndtable_probe (unit, &hw_config); - else - return 0; -} - -static int -sndattach (struct isa_device *dev) -{ - int unit; - static int midi_initialized = 0; - static int seq_initialized = 0; - unsigned long mem_start = 0xefffffffUL; - struct address_info hw_config; - - unit = driver_to_voxunit(dev->id_driver); - hw_config.io_base = dev->id_iobase; - hw_config.irq = ipri_to_irq (dev->id_irq); - hw_config.dma = dev->id_drq; - hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/ - - if(!unit) - return FALSE; - if (!sndtable_init_card (unit, &hw_config)) - { - printf (" <Driver not configured>"); - return FALSE; - } - - /* - * Init the high level sound driver - */ - - if (!(soundcards_installed = sndtable_get_cardcount ())) - { - printf (" <No such hardware>"); - return FALSE; /* No cards detected */ - } - - printf("\n"); - -#ifndef EXCLUDE_AUDIO - if (num_audiodevs) /* Audio devices present */ - { - mem_start = DMAbuf_init (mem_start); - mem_start = audio_init (mem_start); - sound_mem_init (); - } - - soundcard_configured = 1; -#endif - -#ifndef EXCLUDE_MIDI - if (num_midis && !midi_initialized) - { - midi_initialized = 1; - mem_start = MIDIbuf_init (mem_start); - } -#endif - -#ifndef EXCLUDE_SEQUENCER - if ((num_midis + num_synths) && !seq_initialized) - { - seq_initialized = 1; - mem_start = sequencer_init (mem_start); - } -#endif - -#ifdef DEVFS -/* XXX */ /* find out where to store the tokens.. */ -/* XXX */ /* should only create devices if that card has them */ -#define SND_UID 0 -#define SND_GID 13 - - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_CTL, DV_CHR, - SND_UID, SND_GID, 0660, "mixer%d", unit); - -#ifndef EXCLUDE_SEQUENCER - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SEQ, DV_CHR, - SND_UID, SND_GID, 0660, "sequencer%d", unit); - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SEQ2, DV_CHR, - SND_UID, SND_GID, 0660, "music%d", unit); -#endif - -#ifndef EXCLUDE_MIDI - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_MIDIN, - DV_CHR, SND_UID, SND_GID, 0660, "midi%d", - unit); -#endif - -#ifndef EXCLUDE_AUDIO - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_DSP, DV_CHR, - SND_UID, SND_GID, 0660, "dsp%d", unit); - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_AUDIO, - DV_CHR, SND_UID, SND_GID, 0660, "audio%d", - unit); - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_DSP16, - DV_CHR, SND_UID, SND_GID, 0660, "dspW%d", - unit); -#endif - - snd_devfs_token[unit]= - devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SNDPROC, - DV_CHR, SND_UID, SND_GID, 0660, "pss%d", - unit); - - if ( ! sndstat_devfs_token) { - sndstat_devfs_token = - devfs_add_devswf(&snd_cdevsw, 6, DV_CHR, SND_UID, SND_GID, - 0660, "sndstat"); - } -#endif /* DEVFS */ - return TRUE; -} - -void -tenmicrosec (void) -{ - int i; - - for (i = 0; i < 16; i++) - inb (0x80); -} - -#ifndef EXCLUDE_SEQUENCER -void -request_sound_timer (int count) -{ - static int current = 0; - int tmp = count; - - if (count < 0) - timeout ((timeout_func_t)sequencer_timer, 0, -count); - else - { - - if (count < current) - current = 0; /* Timer restarted */ - - count = count - current; - - current = tmp; - - if (!count) - count = 1; - - timeout ((timeout_func_t)sequencer_timer, 0, count); - } - timer_running = 1; -} - -void -sound_stop_timer (void) -{ - if (timer_running) - untimeout ((timeout_func_t)sequencer_timer, 0); - timer_running = 0; -} -#endif - -#ifndef EXCLUDE_AUDIO -static void -sound_mem_init (void) -{ - int dev; - unsigned long dma_pagesize; - struct dma_buffparms *dmap; - static unsigned long dsp_init_mask = 0; - - for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */ - if (!(dsp_init_mask & (1 << dev))) /* Not already done */ -#ifdef PC98 - if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0) -#else - if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan > 0) -#endif - { - dsp_init_mask |= (1 << dev); - dmap = audio_devs[dev]->dmap; - - if (audio_devs[dev]->flags & DMA_AUTOMODE) - audio_devs[dev]->buffcount = 1; - - audio_devs[dev]->buffsize &= ~0xfff; /* Truncate to n*4k */ - - if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536) - dma_pagesize = 131072; /* 128k */ - else - dma_pagesize = 65536; - - /* More sanity checks */ - - if (audio_devs[dev]->buffsize > dma_pagesize) - audio_devs[dev]->buffsize = dma_pagesize; - if (audio_devs[dev]->buffsize < 4096) - audio_devs[dev]->buffsize = 4096; - - /* Now allocate the buffers */ - - for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++) - { - char *tmpbuf = (char *)vm_page_alloc_contig(audio_devs[dev]->buffsize, 0ul, 0xfffffful, dma_pagesize); - - if (tmpbuf == NULL) - { - printk ("snd: Unable to allocate %ld bytes of buffer\n", - audio_devs[dev]->buffsize); - return; - } - - dmap->raw_buf[dmap->raw_count] = tmpbuf; - /* - * Use virtual address as the physical address, since - * isa_dmastart performs the phys address computation. - */ - dmap->raw_buf_phys[dmap->raw_count] = - (unsigned long) dmap->raw_buf[dmap->raw_count]; - } - } /* for dev */ - -} - -#endif - -int -snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO(), char *name) -{ - return 1; -} - - -void -snd_release_irq(int vect) -{ -} - -static snd_devsw_installed = 0; - -static void -snd_drvinit(void *unused) -{ - dev_t dev; - - if( ! snd_devsw_installed ) { - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev,&snd_cdevsw, NULL); - snd_devsw_installed = 1; - } -} - -SYSINIT(snddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snd_drvinit,NULL) - -#endif - diff --git a/sys/pc98/pc98/spkr.c b/sys/pc98/pc98/spkr.c index 5bfbe08..d6a1960 100644 --- a/sys/pc98/pc98/spkr.c +++ b/sys/pc98/pc98/spkr.c @@ -4,12 +4,11 @@ * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993 * modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su> * - * $Id: spkr.c,v 1.4 1996/09/04 09:52:27 asami Exp $ + * $Id: spkr.c,v 1.5 1996/10/30 22:40:14 asami Exp $ */ /* - * modified for PC98 - * $Id: spkr.c,v 1.4 1996/09/04 09:52:27 asami Exp $ + * modified for PC98 by Kakefuda */ #include "speaker.h" @@ -92,14 +91,7 @@ tone(thz, ticks) if (thz <= 0) return; -#if defined(PC98) && defined(AUTO_CLOCK) - if (pc98_machine_type & M_8M) - divisor = 1996800L / thz; - else - divisor = 2457600L / thz; -#else divisor = timer_freq / thz; -#endif /* PC98 */ #ifdef DEBUG (void) printf("tone: thz=%d ticks=%d\n", thz, ticks); diff --git a/sys/pc98/pc98/wcd.c b/sys/pc98/pc98/wcd.c deleted file mode 100644 index c090817..0000000 --- a/sys/pc98/pc98/wcd.c +++ /dev/null @@ -1,1217 +0,0 @@ -/* - * IDE CD-ROM driver for FreeBSD. - * Supports ATAPI-compatible drives. - * - * Copyright (C) 1995 Cronyx Ltd. - * Author Serge Vakulenko, <vak@cronyx.ru> - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organisations permission to use - * or modify this software as long as this message is kept with the software, - * all derivative works or modified versions. - * - * Version 1.9, Mon Oct 9 20:27:42 MSK 1995 - */ - -#include "wdc.h" -#include "wcd.h" -#include "opt_atapi.h" - -#if NWCD > 0 && NWDC > 0 && defined (ATAPI) - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/malloc.h> -#include <sys/buf.h> -#include <sys/ioctl.h> -#include <sys/disklabel.h> -#include <sys/cdio.h> -#include <sys/conf.h> -#ifdef DEVFS -#include <sys/devfsext.h> -#endif /*DEVFS*/ - -#include <machine/cpufunc.h> - -#ifdef PC98 -#include <pc98/pc98/atapi.h> -#else -#include <i386/isa/atapi.h> -#endif - -static d_open_t wcdropen; -static d_open_t wcdbopen; -static d_close_t wcdrclose; -static d_close_t wcdbclose; -static d_ioctl_t wcdioctl; -static d_strategy_t wcdstrategy; - -#define CDEV_MAJOR 69 -#define BDEV_MAJOR 19 -extern struct cdevsw wcd_cdevsw; -static struct bdevsw wcd_bdevsw = - { wcdbopen, wcdbclose, wcdstrategy, wcdioctl, /*19*/ - nodump, nopsize, 0, "wcd", &wcd_cdevsw, -1 }; - -static struct cdevsw wcd_cdevsw = - { wcdropen, wcdrclose, rawread, nowrite, /*69*/ - wcdioctl, nostop, nullreset, nodevtotty,/* atapi */ - seltrue, nommap, wcdstrategy, "wcd", - &wcd_bdevsw, -1 }; - -#ifndef ATAPI_STATIC -static -#endif -int wcdattach(struct atapi*, int, struct atapi_params*, int); - -#define NUNIT (NWDC*2) /* Max. number of devices */ -#define UNIT(d) ((minor(d) >> 3) & 3) /* Unit part of minor device number */ -#define SECSIZE 2048 /* CD-ROM sector size in bytes */ - -#define F_BOPEN 0x0001 /* The block device is opened */ -#define F_MEDIA_CHANGED 0x0002 /* The media have changed since open */ -#define F_DEBUG 0x0004 /* Print debug info */ - -/* - * Disc table of contents. - */ -#define MAXTRK 99 -struct toc { - struct ioc_toc_header hdr; - struct cd_toc_entry tab[MAXTRK+1]; /* One extra for the leadout */ -}; - -/* - * Volume size info. - */ -struct volinfo { - u_long volsize; /* Volume size in blocks */ - u_long blksize; /* Block size in bytes */ -} info; - -/* - * Current subchannel status. - */ -struct subchan { - u_char void0; - u_char audio_status; - u_short data_length; - u_char data_format; - u_char control; - u_char track; - u_char indx; - u_long abslba; - u_long rellba; -}; - -/* - * Audio Control Parameters Page - */ -struct audiopage { - /* Mode data header */ - u_short data_length; - u_char medium_type; - u_char reserved1[5]; - - /* Audio control page */ - u_char page_code; -#define AUDIO_PAGE 0x0e -#define AUDIO_PAGE_MASK 0x4e /* changeable values */ - u_char param_len; - u_char flags; -#define CD_PA_SOTC 0x02 /* mandatory */ -#define CD_PA_IMMED 0x04 /* always 1 */ - u_char reserved3[3]; - u_short lb_per_sec; - struct port_control { - u_char channels : 4; -#define CHANNEL_0 1 /* mandatory */ -#define CHANNEL_1 2 /* mandatory */ -#define CHANNEL_2 4 /* optional */ -#define CHANNEL_3 8 /* optional */ - u_char volume; - } port[4]; -}; - -/* - * CD-ROM Capabilities and Mechanical Status Page - */ -struct cappage { - /* Mode data header */ - u_short data_length; - u_char medium_type; -#define MDT_UNKNOWN 0x00 -#define MDT_DATA_120 0x01 -#define MDT_AUDIO_120 0x02 -#define MDT_COMB_120 0x03 -#define MDT_PHOTO_120 0x04 -#define MDT_DATA_80 0x05 -#define MDT_AUDIO_80 0x06 -#define MDT_COMB_80 0x07 -#define MDT_PHOTO_80 0x08 -#define MDT_NO_DISC 0x70 -#define MDT_DOOR_OPEN 0x71 -#define MDT_FMT_ERROR 0x72 - u_char reserved1[5]; - - /* Capabilities page */ - u_char page_code; -#define CAP_PAGE 0x2a - u_char param_len; - u_char reserved2[2]; - - u_char audio_play : 1; /* audio play supported */ - u_char composite : 1; /* composite audio/video supported */ - u_char dport1 : 1; /* digital audio on port 1 */ - u_char dport2 : 1; /* digital audio on port 2 */ - u_char mode2_form1 : 1; /* mode 2 form 1 (XA) read */ - u_char mode2_form2 : 1; /* mode 2 form 2 format */ - u_char multisession : 1; /* multi-session photo-CD */ - u_char : 1; - u_char cd_da : 1; /* audio-CD read supported */ - u_char cd_da_stream : 1; /* CD-DA streaming */ - u_char rw : 1; /* combined R-W subchannels */ - u_char rw_corr : 1; /* R-W subchannel data corrected */ - u_char c2 : 1; /* C2 error pointers supported */ - u_char isrc : 1; /* can return the ISRC info */ - u_char upc : 1; /* can return the catalog number UPC */ - u_char : 1; - u_char lock : 1; /* could be locked */ - u_char locked : 1; /* current lock state */ - u_char prevent : 1; /* prevent jumper installed */ - u_char eject : 1; /* can eject */ - u_char : 1; - u_char mech : 3; /* loading mechanism type */ -#define MECH_CADDY 0 -#define MECH_TRAY 1 -#define MECH_POPUP 2 -#define MECH_CHANGER 4 -#define MECH_CARTRIDGE 5 - u_char sep_vol : 1; /* independent volume of channels */ - u_char sep_mute : 1; /* independent mute of channels */ - u_char : 6; - - u_short max_speed; /* max raw data rate in bytes/1000 */ - u_short max_vol_levels; /* number of discrete volume levels */ - u_short buf_size; /* internal buffer size in bytes/1024 */ - u_short cur_speed; /* current data rate in bytes/1000 */ - - /* Digital drive output format description (optional?) */ - u_char reserved3; - u_char bckf : 1; /* data valid on failing edge of BCK */ - u_char rch : 1; /* high LRCK indicates left channel */ - u_char lsbf : 1; /* set if LSB first */ - u_char dlen: 2; -#define DLEN_32 0 /* 32 BCKs */ -#define DLEN_16 1 /* 16 BCKs */ -#define DLEN_24 2 /* 24 BCKs */ -#define DLEN_24_I2S 3 /* 24 BCKs (I2S) */ - u_char : 3; - u_char reserved4[2]; -}; - -struct wcd { - struct atapi *ata; /* Controller structure */ - int unit; /* IDE bus drive unit */ - int lun; /* Logical device unit */ - int flags; /* Device state flags */ - int refcnt; /* The number of raw opens */ - struct buf_queue_head buf_queue; /* Queue of i/o requests */ - struct atapi_params *param; /* Drive parameters table */ - struct toc toc; /* Table of disc contents */ - struct volinfo info; /* Volume size info */ - struct audiopage au; /* Audio page info */ - struct cappage cap; /* Capabilities page info */ - struct audiopage aumask; /* Audio page mask */ - struct subchan subchan; /* Subchannel info */ - char description[80]; /* Device description */ -#ifdef DEVFS - void *ra_devfs_token; - void *rc_devfs_token; - void *a_devfs_token; - void *c_devfs_token; -#endif -}; - -struct wcd *wcdtab[NUNIT]; /* Drive info by unit number */ -static int wcdnlun = 0; /* Number of configured drives */ - -static void wcd_start (struct wcd *t); -static void wcd_done (struct wcd *t, struct buf *bp, int resid, - struct atapires result); -static void wcd_error (struct wcd *t, struct atapires result); -static int wcd_read_toc (struct wcd *t); -static int wcd_request_wait (struct wcd *t, u_char cmd, u_char a1, u_char a2, - u_char a3, u_char a4, u_char a5, u_char a6, u_char a7, u_char a8, - u_char a9, char *addr, int count); -static void wcd_describe (struct wcd *t); -static int wcd_open(dev_t dev, int rawflag); -static int wcd_setchan (struct wcd *t, - u_char c0, u_char c1, u_char c2, u_char c3); -static int wcd_eject (struct wcd *t, int closeit); - -/* - * Dump the array in hexadecimal format for debugging purposes. - */ -static void wcd_dump (int lun, char *label, void *data, int len) -{ - u_char *p = data; - - printf ("wcd%d: %s %x", lun, label, *p++); - while (--len > 0) - printf ("-%x", *p++); - printf ("\n"); -} - -#ifndef ATAPI_STATIC -static -#endif -int -wcdattach (struct atapi *ata, int unit, struct atapi_params *ap, int debug) -{ - struct wcd *t; - struct atapires result; - int lun; - - if (wcdnlun >= NUNIT) { - printf ("wcd: too many units\n"); - return (0); - } - if (!atapi_request_immediate) { - printf("wcd: configuration error, ATAPI core code not present!\n"); - printf("wcd: check `options ATAPI_STATIC' in your kernel config file!\n"); - return (0); - } - t = malloc (sizeof (struct wcd), M_TEMP, M_NOWAIT); - if (! t) { - printf ("wcd: out of memory\n"); - return (0); - } - wcdtab[wcdnlun] = t; - bzero (t, sizeof (struct wcd)); - t->ata = ata; - t->unit = unit; - lun = t->lun = wcdnlun++; - t->param = ap; - t->flags = F_MEDIA_CHANGED; - t->refcnt = 0; - if (debug) { - t->flags |= F_DEBUG; - /* Print params. */ - wcd_dump (t->lun, "info", ap, sizeof *ap); - } - - /* Get drive capabilities. */ - result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE, - 0, CAP_PAGE, 0, 0, 0, 0, sizeof (t->cap) >> 8, sizeof (t->cap), - 0, 0, 0, 0, 0, 0, 0, (char*) &t->cap, sizeof (t->cap)); - - /* Do it twice to avoid the stale media changed state. */ - if (result.code == RES_ERR && - (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION) - result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE, - 0, CAP_PAGE, 0, 0, 0, 0, sizeof (t->cap) >> 8, - sizeof (t->cap), 0, 0, 0, 0, 0, 0, 0, - (char*) &t->cap, sizeof (t->cap)); - - /* Some drives have shorter capabilities page. */ - if (result.code == RES_UNDERRUN) - result.code = 0; - - if (result.code == 0) { - wcd_describe (t); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "cap", &t->cap, sizeof t->cap); - } - - -#ifdef DEVFS - t->ra_devfs_token = - devfs_add_devswf(&wcd_cdevsw, dkmakeminor(lun, 0, 0), - DV_CHR, UID_ROOT, GID_OPERATOR, 0640, - "rwcd%da", lun); - t->rc_devfs_token = - devfs_add_devswf(&wcd_cdevsw, dkmakeminor(lun, 0, RAW_PART), - DV_CHR, UID_ROOT, GID_OPERATOR, 0640, - "rwcd%dc", lun); - t->a_devfs_token = - devfs_add_devswf(&wcd_bdevsw, dkmakeminor(lun, 0, 0), - DV_BLK, UID_ROOT, GID_OPERATOR, 0640, - "wcd%da", lun); - t->c_devfs_token = - devfs_add_devswf(&wcd_bdevsw, dkmakeminor(lun, 0, RAW_PART), - DV_BLK, UID_ROOT, GID_OPERATOR, 0640, - "wcd%dc", lun); -#endif - return (1); -} - -void wcd_describe (struct wcd *t) -{ - char *m; - - t->cap.max_speed = ntohs (t->cap.max_speed); - t->cap.max_vol_levels = ntohs (t->cap.max_vol_levels); - t->cap.buf_size = ntohs (t->cap.buf_size); - t->cap.cur_speed = ntohs (t->cap.cur_speed); - - printf ("wcd%d: ", t->lun); - if (t->cap.cur_speed != t->cap.max_speed) - printf ("%d/", t->cap.cur_speed * 1000 / 1024); - printf ("%dKb/sec", t->cap.max_speed * 1000 / 1024); - if (t->cap.buf_size) - printf (", %dKb cache", t->cap.buf_size); - - if (t->cap.audio_play) - printf (", audio play"); - if (t->cap.max_vol_levels) - printf (", %d volume levels", t->cap.max_vol_levels); - - switch (t->cap.mech) { - default: m = 0; break; - case MECH_CADDY: m = "caddy"; break; - case MECH_TRAY: m = "tray"; break; - case MECH_POPUP: m = "popup"; break; - case MECH_CHANGER: m = "changer"; break; - case MECH_CARTRIDGE: m = "cartridge"; break; - } - if (m) - printf (", %s%s", t->cap.eject ? "ejectable " : "", m); - else if (t->cap.eject) - printf (", eject"); - printf ("\n"); - - printf ("wcd%d: ", t->lun); - switch (t->cap.medium_type) { - case MDT_UNKNOWN: printf ("medium type unknown"); break; - case MDT_DATA_120: printf ("120mm data disc loaded"); break; - case MDT_AUDIO_120: printf ("120mm audio disc loaded"); break; - case MDT_COMB_120: printf ("120mm data/audio disc loaded"); break; - case MDT_PHOTO_120: printf ("120mm photo disc loaded"); break; - case MDT_DATA_80: printf ("80mm data disc loaded"); break; - case MDT_AUDIO_80: printf ("80mm audio disc loaded"); break; - case MDT_COMB_80: printf ("80mm data/audio disc loaded"); break; - case MDT_PHOTO_80: printf ("80mm photo disc loaded"); break; - case MDT_NO_DISC: printf ("no disc inside"); break; - case MDT_DOOR_OPEN: printf ("door open"); break; - case MDT_FMT_ERROR: printf ("medium format error"); break; - default: printf ("medium type=0x%x", t->cap.medium_type); break; - } - if (t->cap.lock) - printf (t->cap.locked ? ", locked" : ", unlocked"); - if (t->cap.prevent) - printf (", lock protected"); - printf ("\n"); -} - -static int -wcd_open (dev_t dev, int rawflag) -{ - int lun = UNIT(dev); - struct wcd *t; - - /* Check that the device number is legal - * and the ATAPI driver is loaded. */ - if (lun >= wcdnlun || ! atapi_request_immediate) - return (ENXIO); - t = wcdtab[lun]; - - /* On the first open, read the table of contents. */ - if (! (t->flags & F_BOPEN) && ! t->refcnt) { - /* Read table of contents. */ - if (wcd_read_toc (t) < 0) - return (EIO); - - /* Lock the media. */ - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); - } - if (rawflag) - ++t->refcnt; - else - t->flags |= F_BOPEN; - return (0); -} - -int wcdbopen (dev_t dev, int flags, int fmt, struct proc *p) -{ - return wcd_open (dev, 0); -} - -int wcdropen (dev_t dev, int flags, int fmt, struct proc *p) -{ - return wcd_open (dev, 1); -} - -/* - * Close the device. Only called if we are the LAST - * occurence of an open device. - */ -int wcdbclose (dev_t dev, int flags, int fmt, struct proc *p) -{ - int lun = UNIT(dev); - struct wcd *t = wcdtab[lun]; - - /* If we were the last open of the entire device, release it. */ - if (! t->refcnt) - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - t->flags &= ~F_BOPEN; - return (0); -} - -int wcdrclose (dev_t dev, int flags, int fmt, struct proc *p) -{ - int lun = UNIT(dev); - struct wcd *t = wcdtab[lun]; - - /* If we were the last open of the entire device, release it. */ - if (! (t->flags & F_BOPEN) && t->refcnt == 1) - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - --t->refcnt; - return (0); -} - -/* - * Actually translate the requested transfer into one the physical driver can - * understand. The transfer is described by a buf and will include only one - * physical transfer. - */ -void wcdstrategy (struct buf *bp) -{ - int lun = UNIT(bp->b_dev); - struct wcd *t = wcdtab[lun]; - int x; - - /* Can't ever write to a CD. */ - if (! (bp->b_flags & B_READ)) { - bp->b_error = EROFS; - bp->b_flags |= B_ERROR; - biodone (bp); - return; - } - - /* If it's a null transfer, return immediatly. */ - if (bp->b_bcount == 0) { - bp->b_resid = 0; - biodone (bp); - return; - } - - /* Process transfer request. */ - bp->b_pblkno = bp->b_blkno; - bp->b_resid = bp->b_bcount; - x = splbio(); - - /* Place it in the queue of disk activities for this disk. */ - tqdisksort (&t->buf_queue, bp); - - /* Tell the device to get going on the transfer if it's - * not doing anything, otherwise just wait for completion. */ - wcd_start (t); - splx(x); -} - -/* - * Look to see if there is a buf waiting for the device - * and that the device is not already busy. If both are true, - * It dequeues the buf and creates an ATAPI command to perform the - * transfer in the buf. - * The bufs are queued by the strategy routine (wcdstrategy). - * Must be called at the correct (splbio) level. - */ -static void wcd_start (struct wcd *t) -{ - struct buf *bp = TAILQ_FIRST(&t->buf_queue); - u_long blkno, nblk; - - /* See if there is a buf to do and we are not already doing one. */ - if (! bp) - return; - - /* Unqueue the request. */ - TAILQ_REMOVE(&t->buf_queue, bp, b_act); - - /* Should reject all queued entries if media have changed. */ - if (t->flags & F_MEDIA_CHANGED) { - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - biodone (bp); - return; - } - - /* We have a buf, now we should make a command - * First, translate the block to absolute and put it in terms of the - * logical blocksize of the device. - * What if something asks for 512 bytes not on a 2k boundary? */ - blkno = bp->b_blkno / (SECSIZE / 512); - nblk = (bp->b_bcount + (SECSIZE - 1)) / SECSIZE; - - atapi_request_callback (t->ata, t->unit, ATAPI_READ_BIG, 0, - blkno>>24, blkno>>16, blkno>>8, blkno, 0, nblk>>8, nblk, 0, 0, - 0, 0, 0, 0, 0, (u_char*) bp->b_un.b_addr, bp->b_bcount, - wcd_done, t, bp); -} - -static void wcd_done (struct wcd *t, struct buf *bp, int resid, - struct atapires result) -{ - if (result.code) { - wcd_error (t, result); - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - } else - bp->b_resid = resid; - biodone (bp); - wcd_start (t); -} - -static void wcd_error (struct wcd *t, struct atapires result) -{ - if (result.code != RES_ERR) - return; - switch (result.error & AER_SKEY) { - case AER_SK_NOT_READY: - if (result.error & ~AER_SKEY) { - /* Audio disc. */ - printf ("wcd%d: cannot read audio disc\n", t->lun); - return; - } - /* Tray open. */ - if (! (t->flags & F_MEDIA_CHANGED)) - printf ("wcd%d: tray open\n", t->lun); - t->flags |= F_MEDIA_CHANGED; - return; - - case AER_SK_UNIT_ATTENTION: - /* Media changed. */ - if (! (t->flags & F_MEDIA_CHANGED)) - printf ("wcd%d: media changed\n", t->lun); - t->flags |= F_MEDIA_CHANGED; - return; - - case AER_SK_ILLEGAL_REQUEST: - /* Unknown command or invalid command arguments. */ - if (t->flags & F_DEBUG) - printf ("wcd%d: invalid command\n", t->lun); - return; - } - printf ("wcd%d: i/o error, status=%b, error=%b\n", t->lun, - result.status, ARS_BITS, result.error, AER_BITS); -} - -static int wcd_request_wait (struct wcd *t, u_char cmd, u_char a1, u_char a2, - u_char a3, u_char a4, u_char a5, u_char a6, u_char a7, u_char a8, - u_char a9, char *addr, int count) -{ - struct atapires result; - - result = atapi_request_wait (t->ata, t->unit, cmd, - a1, a2, a3, a4, a5, a6, a7, a8, a9, 0, 0, 0, 0, 0, 0, - addr, count); - if (result.code) { - wcd_error (t, result); - return (EIO); - } - return (0); -} - -static inline void lba2msf (int lba, u_char *m, u_char *s, u_char *f) -{ - lba += 150; /* offset of first logical frame */ - lba &= 0xffffff; /* negative lbas use only 24 bits */ - *m = lba / (60 * 75); - lba %= (60 * 75); - *s = lba / 75; - *f = lba % 75; -} - -/* - * Perform special action on behalf of the user. - * Knows about the internals of this device - */ -int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) -{ - int lun = UNIT(dev); - struct wcd *t = wcdtab[lun]; - int error = 0; - - if (t->flags & F_MEDIA_CHANGED) - switch (cmd) { - case CDIOCSETDEBUG: - case CDIOCCLRDEBUG: - case CDIOCRESET: - /* These ops are media change transparent. */ - break; - default: - /* Read table of contents. */ - wcd_read_toc (t); - - /* Lock the media. */ - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); - break; - } - switch (cmd) { - default: - return (ENOTTY); - - case CDIOCSETDEBUG: - if (p->p_cred->pc_ucred->cr_uid) - return (EPERM); - t->flags |= F_DEBUG; - atapi_debug (t->ata, 1); - return 0; - - case CDIOCCLRDEBUG: - if (p->p_cred->pc_ucred->cr_uid) - return (EPERM); - t->flags &= ~F_DEBUG; - atapi_debug (t->ata, 0); - return 0; - - case CDIOCRESUME: - return wcd_request_wait (t, ATAPI_PAUSE, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0); - - case CDIOCPAUSE: - return wcd_request_wait (t, ATAPI_PAUSE, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCSTART: - return wcd_request_wait (t, ATAPI_START_STOP, - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCSTOP: - return wcd_request_wait (t, ATAPI_START_STOP, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCALLOW: - return wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCPREVENT: - return wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCRESET: - if (p->p_cred->pc_ucred->cr_uid) - return (EPERM); - return wcd_request_wait (t, ATAPI_TEST_UNIT_READY, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - case CDIOCEJECT: - /* Don't allow eject if the device is opened - * by somebody (not us) in block mode. */ - if ((t->flags & F_BOPEN) && t->refcnt) - return (EBUSY); - return wcd_eject (t, 0); - - case CDIOCCLOSE: - if ((t->flags & F_BOPEN) && t->refcnt) - return (0); - return wcd_eject (t, 1); - - case CDIOREADTOCHEADER: - if (! t->toc.hdr.ending_track) - return (EIO); - bcopy (&t->toc.hdr, addr, sizeof t->toc.hdr); - break; - - case CDIOREADTOCENTRYS: { - struct ioc_read_toc_entry *te = - (struct ioc_read_toc_entry*) addr; - struct toc *toc = &t->toc; - struct toc buf; - u_long len; - u_char starting_track = te->starting_track; - - if (! t->toc.hdr.ending_track) - return (EIO); - - if ( te->data_len < sizeof(toc->tab[0]) - || (te->data_len % sizeof(toc->tab[0])) != 0 - || te->address_format != CD_MSF_FORMAT - && te->address_format != CD_LBA_FORMAT - ) - return EINVAL; - - if (starting_track == 0) - starting_track = toc->hdr.starting_track; - else if (starting_track == 170) /* Handle leadout request */ - starting_track = toc->hdr.ending_track + 1; - else if (starting_track < toc->hdr.starting_track || - starting_track > toc->hdr.ending_track + 1) - return (EINVAL); - - len = ((toc->hdr.ending_track + 1 - starting_track) + 1) * - sizeof(toc->tab[0]); - if (te->data_len < len) - len = te->data_len; - if (len > sizeof(toc->tab)) - return EINVAL; - - /* Convert to MSF format, if needed. */ - if (te->address_format == CD_MSF_FORMAT) { - struct cd_toc_entry *e; - - buf = t->toc; - toc = &buf; - e = toc->tab + (toc->hdr.ending_track + 1 - - toc->hdr.starting_track) + 1; - while (--e >= toc->tab) - lba2msf (ntohl(e->addr.lba), &e->addr.msf.minute, - &e->addr.msf.second, &e->addr.msf.frame); - } - return copyout (toc->tab + starting_track - - toc->hdr.starting_track, te->data, len); - } - case CDIOCREADSUBCHANNEL: { - struct ioc_read_subchannel *args = - (struct ioc_read_subchannel*) addr; - struct cd_sub_channel_info data; - u_long len = args->data_len; - int abslba, rellba; - - if (len > sizeof(data) || - len < sizeof(struct cd_sub_channel_header)) - return (EINVAL); - - if (wcd_request_wait (t, ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, - 0, 0, sizeof (t->subchan) >> 8, sizeof (t->subchan), - 0, (char*)&t->subchan, sizeof (t->subchan)) != 0) - return (EIO); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "subchan", &t->subchan, sizeof t->subchan); - - abslba = t->subchan.abslba; - rellba = t->subchan.rellba; - if (args->address_format == CD_MSF_FORMAT) { - lba2msf (ntohl(abslba), - &data.what.position.absaddr.msf.minute, - &data.what.position.absaddr.msf.second, - &data.what.position.absaddr.msf.frame); - lba2msf (ntohl(rellba), - &data.what.position.reladdr.msf.minute, - &data.what.position.reladdr.msf.second, - &data.what.position.reladdr.msf.frame); - } else { - data.what.position.absaddr.lba = abslba; - data.what.position.reladdr.lba = rellba; - } - data.header.audio_status = t->subchan.audio_status; - data.what.position.control = t->subchan.control & 0xf; - data.what.position.addr_type = t->subchan.control >> 4; - data.what.position.track_number = t->subchan.track; - data.what.position.index_number = t->subchan.indx; - - return copyout (&data, args->data, len); - } - case CDIOCPLAYMSF: { - struct ioc_play_msf *args = (struct ioc_play_msf*) addr; - - return wcd_request_wait (t, ATAPI_PLAY_MSF, 0, 0, - args->start_m, args->start_s, args->start_f, - args->end_m, args->end_s, args->end_f, 0, 0, 0); - } - case CDIOCPLAYBLOCKS: { - struct ioc_play_blocks *args = (struct ioc_play_blocks*) addr; - - return wcd_request_wait (t, ATAPI_PLAY_BIG, 0, - args->blk >> 24 & 0xff, args->blk >> 16 & 0xff, - args->blk >> 8 & 0xff, args->blk & 0xff, - args->len >> 24 & 0xff, args->len >> 16 & 0xff, - args->len >> 8 & 0xff, args->len & 0xff, 0, 0); - } - case CDIOCPLAYTRACKS: { - struct ioc_play_track *args = (struct ioc_play_track*) addr; - u_long start, len; - int t1, t2; - - if (! t->toc.hdr.ending_track) - return (EIO); - - /* Ignore index fields, - * play from start_track to end_track inclusive. */ - if (args->end_track < t->toc.hdr.ending_track+1) - ++args->end_track; - if (args->end_track > t->toc.hdr.ending_track+1) - args->end_track = t->toc.hdr.ending_track+1; - t1 = args->start_track - t->toc.hdr.starting_track; - t2 = args->end_track - t->toc.hdr.starting_track; - if (t1 < 0 || t2 < 0) - return (EINVAL); - start = ntohl(t->toc.tab[t1].addr.lba); - len = ntohl(t->toc.tab[t2].addr.lba) - start; - - return wcd_request_wait (t, ATAPI_PLAY_BIG, 0, - start >> 24 & 0xff, start >> 16 & 0xff, - start >> 8 & 0xff, start & 0xff, - len >> 24 & 0xff, len >> 16 & 0xff, - len >> 8 & 0xff, len & 0xff, 0, 0); - } - case CDIOCGETVOL: { - struct ioc_vol *arg = (struct ioc_vol*) addr; - - error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE, - 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0, - (char*) &t->au, sizeof (t->au)); - if (error) - return (error); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "au", &t->au, sizeof t->au); - if (t->au.page_code != AUDIO_PAGE) - return (EIO); - arg->vol[0] = t->au.port[0].volume; - arg->vol[1] = t->au.port[1].volume; - arg->vol[2] = t->au.port[2].volume; - arg->vol[3] = t->au.port[3].volume; - break; - } - case CDIOCSETVOL: { - struct ioc_vol *arg = (struct ioc_vol*) addr; - - error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE, - 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0, - (char*) &t->au, sizeof (t->au)); - if (error) - return (error); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "au", &t->au, sizeof t->au); - if (t->au.page_code != AUDIO_PAGE) - return (EIO); - - error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, - AUDIO_PAGE_MASK, 0, 0, 0, 0, sizeof (t->aumask) >> 8, - sizeof (t->aumask), 0, (char*) &t->aumask, - sizeof (t->aumask)); - if (error) - return (error); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "mask", &t->aumask, sizeof t->aumask); - - /* Sony-55E requires the data length field to be zeroed. */ - t->au.data_length = 0; - - t->au.port[0].channels = CHANNEL_0; - t->au.port[1].channels = CHANNEL_1; - t->au.port[0].volume = arg->vol[0] & t->aumask.port[0].volume; - t->au.port[1].volume = arg->vol[1] & t->aumask.port[1].volume; - t->au.port[2].volume = arg->vol[2] & t->aumask.port[2].volume; - t->au.port[3].volume = arg->vol[3] & t->aumask.port[3].volume; - return wcd_request_wait (t, ATAPI_MODE_SELECT_BIG, 0x10, - 0, 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), - 0, (char*) &t->au, - sizeof (t->au)); - } - case CDIOCSETPATCH: { - struct ioc_patch *arg = (struct ioc_patch*) addr; - - return wcd_setchan (t, arg->patch[0], arg->patch[1], - arg->patch[2], arg->patch[3]); - } - case CDIOCSETMONO: - return wcd_setchan (t, CHANNEL_0 | CHANNEL_1, - CHANNEL_0 | CHANNEL_1, 0, 0); - - case CDIOCSETSTERIO: - return wcd_setchan (t, CHANNEL_0, CHANNEL_1, 0, 0); - - case CDIOCSETMUTE: - return wcd_setchan (t, 0, 0, 0, 0); - - case CDIOCSETLEFT: - return wcd_setchan (t, CHANNEL_0, CHANNEL_0, 0, 0); - - case CDIOCSETRIGHT: - return wcd_setchan (t, CHANNEL_1, CHANNEL_1, 0, 0); - } - return (error); -} - -/* - * Read the entire TOC for the disc into our internal buffer. - */ -static int wcd_read_toc (struct wcd *t) -{ - int ntracks, len; - struct atapires result; - - bzero (&t->toc, sizeof (t->toc)); - bzero (&t->info, sizeof (t->info)); - - /* Check for the media. - * Do it twice to avoid the stale media changed state. */ - result = atapi_request_wait (t->ata, t->unit, ATAPI_TEST_UNIT_READY, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - if (result.code == RES_ERR && - (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION) { - t->flags |= F_MEDIA_CHANGED; - result = atapi_request_wait (t->ata, t->unit, - ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0); - } - if (result.code) { - wcd_error (t, result); - return (EIO); - } - t->flags &= ~F_MEDIA_CHANGED; - - /* First read just the header, so we know how long the TOC is. */ - len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry); - if (wcd_request_wait (t, ATAPI_READ_TOC, 0, 0, 0, 0, 0, 0, - len >> 8, len & 0xff, 0, (char*)&t->toc, len) != 0) { -err: bzero (&t->toc, sizeof (t->toc)); - return (0); - } - - ntracks = t->toc.hdr.ending_track - t->toc.hdr.starting_track + 1; - if (ntracks <= 0 || ntracks > MAXTRK) - goto err; - - /* Now read the whole schmeer. */ - len = sizeof(struct ioc_toc_header) + - ntracks * sizeof(struct cd_toc_entry); - if (wcd_request_wait (t, ATAPI_READ_TOC, 0, 0, 0, 0, 0, 0, - len >> 8, len & 0xff, 0, (char*)&t->toc, len) & 0xff) - goto err; - - NTOHS(t->toc.hdr.len); - - /* Read disc capacity. */ - if (wcd_request_wait (t, ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, - 0, sizeof(t->info), 0, (char*)&t->info, sizeof(t->info)) != 0) - bzero (&t->info, sizeof (t->info)); - - /* make fake leadout entry */ - t->toc.tab[ntracks].control = t->toc.tab[ntracks-1].control; - t->toc.tab[ntracks].addr_type = t->toc.tab[ntracks-1].addr_type; - t->toc.tab[ntracks].track = 170; /* magic */ - t->toc.tab[ntracks].addr.lba = t->info.volsize; - - NTOHL(t->info.volsize); - NTOHL(t->info.blksize); - - /* Print the disc description string on every disc change. - * It would help to track the history of disc changes. */ - if (t->info.volsize && t->toc.hdr.ending_track && - (t->flags & F_MEDIA_CHANGED) && (t->flags & F_DEBUG)) { - printf ("wcd%d: ", t->lun); - if (t->toc.tab[0].control & 4) - printf ("%ldMB ", t->info.volsize / 512); - else - printf ("%ld:%ld audio ", t->info.volsize/75/60, - t->info.volsize/75%60); - printf ("(%ld sectors), %d tracks\n", t->info.volsize, - t->toc.hdr.ending_track - t->toc.hdr.starting_track + 1); - } - return (0); -} - -/* - * Set up the audio channel masks. - */ -static int wcd_setchan (struct wcd *t, - u_char c0, u_char c1, u_char c2, u_char c3) -{ - int error; - - error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE, - 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0, - (char*) &t->au, sizeof (t->au)); - if (error) - return (error); - if (t->flags & F_DEBUG) - wcd_dump (t->lun, "au", &t->au, sizeof t->au); - if (t->au.page_code != AUDIO_PAGE) - return (EIO); - - /* Sony-55E requires the data length field to be zeroed. */ - t->au.data_length = 0; - - t->au.port[0].channels = c0; - t->au.port[1].channels = c1; - t->au.port[2].channels = c2; - t->au.port[3].channels = c3; - return wcd_request_wait (t, ATAPI_MODE_SELECT_BIG, 0x10, - 0, 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), - 0, (char*) &t->au, - sizeof (t->au)); -} - -static int wcd_eject (struct wcd *t, int closeit) -{ - struct atapires result; - - /* Try to stop the disc. */ - result = atapi_request_wait (t->ata, t->unit, ATAPI_START_STOP, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - if (result.code == RES_ERR && - ((result.error & AER_SKEY) == AER_SK_NOT_READY || - (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION)) { - int err; - - if (!closeit) - return (0); - /* - * The disc was unloaded. - * Load it (close tray). - * Read the table of contents. - */ - err = wcd_request_wait (t, ATAPI_START_STOP, - 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0); - if (err) - return (err); - - /* Read table of contents. */ - wcd_read_toc (t); - - /* Lock the media. */ - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); - - return (0); - } - - if (result.code) { - wcd_error (t, result); - return (EIO); - } - - if (closeit) - return (0); - - /* Give it some time to stop spinning. */ - tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej1", 0); - tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej2", 0); - - /* Unlock. */ - wcd_request_wait (t, ATAPI_PREVENT_ALLOW, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - /* Eject. */ - t->flags |= F_MEDIA_CHANGED; - return wcd_request_wait (t, ATAPI_START_STOP, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0); -} - -#ifdef WCD_MODULE -/* - * Loadable ATAPI CD-ROM driver stubs. - */ -#include <sys/exec.h> -#include <sys/sysent.h> -#include <sys/lkm.h> - -/* - * Construct lkm_dev structures (see lkm.h). - * Our bdevsw/cdevsw slot numbers are 19/69. - */ - - -MOD_DEV(wcd, LM_DT_BLOCK, BDEV_MAJOR, &wcd_bdevsw); -MOD_DEV(rwcd, LM_DT_CHAR, CDEV_MAJOR, &wcd_cdevsw); - -/* - * Function called when loading the driver. - */ -int wcd_load (struct lkm_table *lkmtp, int cmd) -{ - struct atapi *ata; - int n, u; - - if (! atapi_start) - /* No ATAPI driver available. */ - return EPROTONOSUPPORT; - n = 0; - for (ata=atapi_tab; ata<atapi_tab+2; ++ata) - if (ata->port) - for (u=0; u<2; ++u) - /* Probing controller ata->ctrlr, unit u. */ - if (ata->params[u] && ! ata->attached[u] && - wcdattach (ata, u, ata->params[u], - ata->debug) >= 0) - { - /* Drive found. */ - ata->attached[u] = 1; - ++n; - } - if (! n) - /* No IDE CD-ROMs found. */ - return ENXIO; - return 0; -} - -/* - * Function called when unloading the driver. - */ -int wcd_unload (struct lkm_table *lkmtp, int cmd) -{ - struct wcd **t; - - for (t=wcdtab; t<wcdtab+wcdnlun; ++t) - if (((*t)->flags & F_BOPEN) || (*t)->refcnt) - /* The device is opened, cannot unload the driver. */ - return EBUSY; - for (t=wcdtab; t<wcdtab+wcdnlun; ++t) { - (*t)->ata->attached[(*t)->unit] = 0; - free (*t, M_TEMP); - } - wcdnlun = 0; - bzero (wcdtab, sizeof(wcdtab)); - return 0; -} - -/* - * Dispatcher function for the module (load/unload/stat). - */ -int wcd_mod (struct lkm_table *lkmtp, int cmd, int ver) -{ - int err = 0; - - if (ver != LKM_VERSION) - return EINVAL; - - if (cmd == LKM_E_LOAD) - err = wcd_load (lkmtp, cmd); - else if (cmd == LKM_E_UNLOAD) - err = wcd_unload (lkmtp, cmd); - if (err) - return err; - - /* Register the cdevsw entry. */ - lkmtp->private.lkm_dev = &rwcd_module; - err = lkmdispatch (lkmtp, cmd); - if (err) - return err; - - /* Register the bdevsw entry. */ - lkmtp->private.lkm_dev = &wcd_module; - return lkmdispatch (lkmtp, cmd); -} -#endif /* WCD_MODULE */ - -static wcd_devsw_installed = 0; - -static void wcd_drvinit(void *unused) -{ - dev_t dev; - - if( ! wcd_devsw_installed ) { - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev,&wcd_cdevsw, NULL); - dev = makedev(BDEV_MAJOR, 0); - bdevsw_add(&dev,&wcd_bdevsw, NULL); - wcd_devsw_installed = 1; - } -} - -SYSINIT(wcddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,wcd_drvinit,NULL) - - -#endif /* NWCD && NWDC && ATAPI */ diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c index 970a544..b023177 100644 --- a/sys/pc98/pc98/wd.c +++ b/sys/pc98/pc98/wd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.8 1996/10/09 21:46:52 asami Exp $ + * $Id: wd.c,v 1.9 1996/10/23 07:25:35 asami Exp $ */ /* TODO: @@ -89,14 +89,11 @@ #ifdef PC98 #include <pc98/pc98/pc98.h> #include <pc98/pc98/epsonio.h> -#include <i386/isa/isa_device.h> -#include <pc98/pc98/wdreg.h> #else -#include <i386/i386/cons.h> #include <i386/isa/isa.h> +#endif #include <i386/isa/isa_device.h> #include <i386/isa/wdreg.h> -#endif #include <sys/syslog.h> #include <sys/dkstat.h> #include <vm/vm.h> @@ -105,12 +102,8 @@ #include <vm/pmap.h> #ifdef ATAPI -#ifdef PC98 -#include <pc98/pc98/atapi.h> -#else #include <i386/isa/atapi.h> #endif -#endif extern void wdstart(int ctrlr); @@ -252,6 +245,10 @@ static timeout_t wdtimeout; static int wdunwedge(struct disk *du); static int wdwait(struct disk *du, u_char bits_wanted, int timeout); +struct isa_driver wdcdriver = { + wdprobe, wdattach, "wdc", +}; + static d_open_t wdopen; static d_close_t wdclose; static d_strategy_t wdstrategy; @@ -266,10 +263,6 @@ static struct bdevsw wd_bdevsw = { wdopen, wdclose, wdstrategy, wdioctl, /*0*/ wddump, wdsize, 0, "wd", &wd_cdevsw, -1 }; -struct isa_driver wdcdriver = { - wdprobe, wdattach, "wdc", -}; - /* * Probe for controller. */ @@ -489,11 +482,25 @@ wdattach(struct isa_device *dvp) printf("wd%d: size unknown, using %s values\n", lunit, du->dk_dd.d_secperunit > 17 ? "BIOS" : "fake"); +#ifdef PC98 /* XXX */ + if (du->dk_dd.d_secperunit > 8 * 1024 * 1024) { + du->dk_dd.d_ncylinders = + bootinfo.bi_bios_geom[du->dk_unit] >> 16; + du->dk_dd.d_secperunit = + du->dk_dd.d_ncylinders + * du->dk_dd.d_ntracks + * du->dk_dd.d_nsectors; + } +#endif printf( "wd%d: %luMB (%lu sectors), %lu cyls, %lu heads, %lu S/T, %lu B/S\n", lunit, du->dk_dd.d_secperunit +#ifdef PC98 + / ( 1024 * 1024 / du->dk_dd.d_secsize) , +#else * du->dk_dd.d_secsize / (1024 * 1024), +#endif du->dk_dd.d_secperunit, du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks, diff --git a/sys/pc98/pc98/wdreg.h b/sys/pc98/pc98/wdreg.h deleted file mode 100644 index 5edd123..0000000 --- a/sys/pc98/pc98/wdreg.h +++ /dev/null @@ -1,222 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * William Jolitz. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91 - * $Id: wdreg.h,v 1.12 1996/06/08 10:03:38 bde Exp $ - */ - -#if 0 -static char rcsid[] = "$Id: wdreg.h,v 1.2 1992/12/06 14:05:28 ukai Exp ukai $"; -#endif - -/* - * modified for PC9801 by F.Ukai - * Kyoto University Microcomputer Club (KMC) - */ - -/* - * Disk Controller register definitions. - */ -#ifdef PC98 - /***** PC98 *****/ -#define wd_data 0x0 /* data register (R/W - 16 bits) */ -#define wd_error 0x2 /* error register (R) */ -#define wd_precomp wd_error /* write precompensation (W) */ -#define wd_features wd_error /* features register (W) */ -#define wd_seccnt 0x4 /* sector count (R/W) */ -#define wd_sector 0x6 /* first sector number (R/W) */ -#define wd_cyl_lo 0x8 /* cylinder address, low byte (R/W) */ -#define wd_cyl_hi 0xa /* cylinder address, high byte (R/W)*/ -#define wd_sdh 0xc /* sector size/drive/head (R/W)*/ -#define wd_command 0xe /* command register (W) */ -#define wd_status wd_command /* immediate status (R) */ - -#define wd_altsts_nec 0x10c /*alternate fixed disk status(via 1015) (R)*/ -#define wd_ctlr_nec 0x10c /*fixed disk controller control(via 1015) (W)*/ -#define wd_altsts_epson 0x3 /*alternate fixed disk status(via 1015) (R)*/ -#define wd_ctlr_epson 0x3 /*fixed disk controller control(via 1015) (W)*/ - -#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */ -#define WDCTL_RST 0x4 /* reset the controller */ -#define WDCTL_IDS 0x2 /* disable controller interrupts */ -#define wd_digin 0x10e /* disk controller input(via 1015) (R)*/ -#else /* IBM-PC */ - /***** IBM-PC *****/ -#define wd_data 0x0 /* data register (R/W - 16 bits) */ -#define wd_error 0x1 /* error register (R) */ -#define wd_precomp wd_error /* write precompensation (W) */ -#define wd_seccnt 0x2 /* sector count (R/W) */ -#define wd_sector 0x3 /* first sector number (R/W) */ -#define wd_cyl_lo 0x4 /* cylinder address, low byte (R/W) */ -#define wd_cyl_hi 0x5 /* cylinder address, high byte (R/W)*/ -#define wd_sdh 0x6 /* sector size/drive/head (R/W)*/ -#define wd_command 0x7 /* command register (W) */ -#define wd_status wd_command /* immediate status (R) */ - -#define wd_altsts 0x206 /*alternate fixed disk status(via 1015) (R)*/ -#define wd_ctlr 0x206 /*fixed disk controller control(via 1015) (W)*/ -#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */ -#define WDCTL_RST 0x4 /* reset the controller */ -#define WDCTL_IDS 0x2 /* disable controller interrupts */ -#define wd_digin 0x207 /* disk controller input(via 1015) (R)*/ -#endif /* PC98 */ - -/* - * Status Bits. - */ -#define WDCS_BUSY 0x80 /* Controller busy bit. */ -#define WDCS_READY 0x40 /* Selected drive is ready */ -#define WDCS_WRTFLT 0x20 /* Write fault */ -#define WDCS_SEEKCMPLT 0x10 /* Seek complete */ -#define WDCS_DRQ 0x08 /* Data request bit. */ -#define WDCS_ECCCOR 0x04 /* ECC correction made in data */ -#define WDCS_INDEX 0x02 /* Index pulse from selected drive */ -#define WDCS_ERR 0x01 /* Error detect bit. */ - -#define WDCS_BITS "\020\010busy\007rdy\006wrtflt\005seekdone\004drq\003ecc_cor\002index\001err" -#define WDERR_ABORT 0x04 - -#define WDERR_BITS "\020\010badblk\007uncorr\006id_crc\005no_id\003abort\002tr000\001no_dam" - -/* - * Commands for Disk Controller. - */ -#define WDCC_RESTORE 0x10 /* disk restore code -- resets cntlr */ - -#define WDCC_READ 0x20 /* disk read code */ -#define WDCC_WRITE 0x30 /* disk write code */ -#define WDCC__LONG 0x02 /* modifier -- access ecc bytes */ -#define WDCC__NORETRY 0x01 /* modifier -- no retrys */ - -#define WDCC_FORMAT 0x50 /* disk format code */ -#define WDCC_DIAGNOSE 0x90 /* controller diagnostic */ -#define WDCC_IDC 0x91 /* initialize drive command */ -#define WDCC_READ_MULTI 0xC4 /* read multiple */ -#define WDCC_WRITE_MULTI 0xC5 /* write multiple */ -#define WDCC_SET_MULTI 0xC6 /* set multiple count */ - - -#define WDCC_EXTDCMD 0xE0 /* send extended command */ -#define WDCC_READP 0xEC /* read parameters from controller */ -#define WDCC_FEATURES 0xEF /* features control */ - -#define WDFEA_RCACHE 0xAA /* read cache enable */ -#define WDFEA_WCACHE 0x02 /* write cache enable */ - -#define WD_STEP 0 /* winchester- default 35us step */ - -#define WDSD_IBM 0xa0 /* forced to 512 byte sector, ecc */ - -#ifdef KERNEL -/* - * read parameters command returns this: - */ -struct wdparams { - /* drive info */ - short wdp_config; /* general configuration bits */ - short wdp_cylinders; /* number of cylinders */ - short wdp_reserved; - short wdp_heads; /* number of heads */ - short wdp_unfbytespertrk; /* number of unformatted bytes/track */ - short wdp_unfbytes; /* number of unformatted bytes/sector */ - short wdp_sectors; /* number of sectors per track */ - short wdp_vendorunique[3]; - /* controller info */ - char wdp_serial[20]; /* serial number */ - short wdp_buffertype; /* buffer type */ -#define WDTYPE_SINGLEPORTSECTOR 1 /* single port, single sector buffer */ -#define WDTYPE_DUALPORTMULTI 2 /* dual port, multiple sector buffer */ -#define WDTYPE_DUALPORTMULTICACHE 3 /* above plus track cache */ - short wdp_buffersize; /* buffer size, in 512-byte units */ - short wdp_necc; /* ecc bytes appended */ - char wdp_rev[8]; /* firmware revision */ - char wdp_model[40]; /* model name */ - short wdp_nsecperint; /* sectors per interrupt */ - short wdp_usedmovsd; /* can use double word read/write? */ -}; - -/* - * wd driver entry points - */ -#ifdef B_FORMAT -int wdformat(struct buf *bp); -#endif - -/* - * IDE DMA support. - * This is based on what is needed for the IDE DMA function of the Intel - * Triton chipset; hopefully it's general enough to be used for other - * chipsets as well. - * - * To use this: - * For each drive which you might want to do DMA on, call wdd_candma() - * to get a cookie. If it returns a null pointer, then the drive - * can't do DMA. - * - * Set up the transfer be calling wdd_dmaprep(). The cookie is what - * you got before; vaddr is the virtual address of the buffer to be - * written; len is the length of the buffer; and direction is either - * B_READ or B_WRITE. - * - * Send a read/write DMA command to the drive. - * - * Call wdd_dmastart(). - * - * Wait for an interrupt. Multi-sector transfers will only interrupt - * at the end of the transfer. - * - * Call wdd_dmadone(). It will return the status as defined by the - * WDDS_* constants below. - */ -struct wddma { - void *(*wdd_candma) /* returns a cookie if can do DMA */ - __P((int ctlr, int drive)); - int (*wdd_dmaprep) /* prepare DMA hardware */ - __P((void *cookie, char *vaddr, u_long len, int direction)); - void (*wdd_dmastart) /* begin DMA transfer */ - __P((void *cookie)); - int (*wdd_dmadone) /* DMA transfer completed */ - __P((void *cookie)); - int (*wdd_dmastatus) /* return status of DMA */ - __P((void *cookie)); -}; - -#define WDDS_ACTIVE 0x0001 -#define WDDS_ERROR 0x0002 -#define WDDS_INTERRUPT 0x0004 - -extern struct wddma wddma; - -#endif /* KERNEL */ |