More merge and update.
(1) deleted #if 0 pc98/pc98/mse.c (2) hold per-unit I/O ports in ed_softc pc98/pc98/if_ed.c pc98/pc98/if_ed98.h (3) merge more files by segregating changes into headers. new file (moved from pc98/pc98): i386/isa/aic_98.h deleted: well, it's already in the commit message so I won't repeat the long list here ;) Submitted by: The FreeBSD(98) Development Team
This commit is contained in:
parent
75680b05c6
commit
e30f001135
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19269
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
|
||||
* $Id: prof_machdep.c,v 1.3 1996/10/17 19:32:10 bde Exp $
|
||||
*/
|
||||
|
||||
#ifdef GUPROF
|
||||
@ -40,7 +40,11 @@
|
||||
#include <machine/profile.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
#ifdef GUPROF
|
||||
|
@ -38,7 +38,7 @@
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.69 1996/09/28 22:37:43 dyson Exp $
|
||||
* $Id: vm_machdep.c,v 1.70 1996/10/15 03:16:33 dyson Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -66,7 +66,11 @@
|
||||
|
||||
#include <sys/user.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef BOUNCE_BUFFERS
|
||||
static vm_offset_t
|
||||
@ -90,7 +94,11 @@ static int bounceallocarraysize;
|
||||
static unsigned *bounceallocarray;
|
||||
static int bouncefree;
|
||||
|
||||
#if defined(PC98) && defined (EPSON_BOUNCEDMA)
|
||||
#define SIXTEENMEG (3840*4096) /* 15MB boundary */
|
||||
#else
|
||||
#define SIXTEENMEG (4096*4096)
|
||||
#endif
|
||||
#define MAXBKVA 1024
|
||||
int maxbkva = MAXBKVA*PAGE_SIZE;
|
||||
|
||||
@ -748,7 +756,7 @@ cpu_reset() {
|
||||
* to do the reset here would then end up in no man's land.
|
||||
*/
|
||||
|
||||
#ifndef BROKEN_KEYBOARD_RESET
|
||||
#if !defined(BROKEN_KEYBOARD_RESET) && !defined(PC98)
|
||||
outb(IO_KBD + 4, 0xFE);
|
||||
DELAY(500000); /* wait 0.5 sec to see if that did it */
|
||||
printf("Keyboard reset did not work, attempting CPU shutdown\n");
|
||||
@ -761,6 +769,12 @@ cpu_reset() {
|
||||
/* "good night, sweet prince .... <THUNK!>" */
|
||||
invltlb();
|
||||
/* NOTREACHED */
|
||||
#ifdef PC98
|
||||
asm(" cli ");
|
||||
outb(0x37, 0x0f); /* SHUT 0 = 0 */
|
||||
outb(0x37, 0x0b); /* SHUT 1 = 0 */
|
||||
outb(0xf0, 0x00); /* reset port */
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Garrett Wollman, September 1994.
|
||||
* This file is in the public domain.
|
||||
*
|
||||
* $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
|
||||
* $Id: clock.h,v 1.20 1996/10/25 13:01:08 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_CLOCK_H_
|
||||
@ -65,7 +65,11 @@ int sysbeep __P((int pitch, int period));
|
||||
|
||||
#ifdef CLOCK_HAIR
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h> /* XXX */
|
||||
#else
|
||||
#include <i386/isa/isa.h> /* XXX */
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h> /* XXX */
|
||||
|
||||
static __inline u_int
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
|
||||
* $Id$
|
||||
* $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -59,6 +59,7 @@
|
||||
* in undefined behavior (but hopefully not fry the chip).
|
||||
* Reading in this manner has no side effects.
|
||||
*
|
||||
* [IBM-PC]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
@ -67,15 +68,31 @@
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 2 is used to generate console beeps.
|
||||
*
|
||||
* [PC-9801]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
* timer 1 -> speaker (via keyboard controller)
|
||||
* timer 2 -> RS232C
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 1 is used to generate console beeps.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macros for specifying values to be written into a mode register.
|
||||
*/
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#ifdef PC98
|
||||
#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
|
||||
#else
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#endif
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_SEL2 0x80 /* select counter 2 */
|
||||
|
@ -1,12 +1,26 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
|
||||
* $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
|
||||
#else
|
||||
#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
|
||||
#endif
|
||||
|
||||
#define ICU_EOI 0x20 /* XXX - define elsewhere */
|
||||
|
||||
@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
orb $IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
enable_icus ; \
|
||||
incl _cnt+V_INTR ; /* tally interrupts */ \
|
||||
movl _cpl,%eax ; \
|
||||
@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
andb $~IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
sti ; /* XXX _doreti repeats the cli/sti */ \
|
||||
MEXITCOUNT ; \
|
||||
/* We could usually avoid the following jmp by inlining some of */ \
|
||||
|
@ -1,12 +1,26 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
|
||||
* $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
|
||||
#else
|
||||
#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
|
||||
#endif
|
||||
|
||||
#define ICU_EOI 0x20 /* XXX - define elsewhere */
|
||||
|
||||
@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
orb $IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
enable_icus ; \
|
||||
incl _cnt+V_INTR ; /* tally interrupts */ \
|
||||
movl _cpl,%eax ; \
|
||||
@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
andb $~IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
sti ; /* XXX _doreti repeats the cli/sti */ \
|
||||
MEXITCOUNT ; \
|
||||
/* We could usually avoid the following jmp by inlining some of */ \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# modified for PC-9801
|
||||
#
|
||||
# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
|
||||
# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $
|
||||
#
|
||||
aic7xxx_asm optional ahc device-driver \
|
||||
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
|
||||
@ -43,7 +43,7 @@ i386/i386/db_disasm.c optional ddb
|
||||
i386/i386/db_interface.c optional ddb
|
||||
i386/i386/db_trace.c optional ddb
|
||||
i386/i386/i386-gdbstub.c optional ddb
|
||||
pc98/i386/exception.s standard
|
||||
i386/i386/exception.s standard
|
||||
i386/i386/identcpu.c standard
|
||||
i386/i386/in_cksum.c optional inet
|
||||
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
|
||||
@ -62,7 +62,7 @@ i386/i386/swtch.s standard
|
||||
i386/i386/sys_machdep.c standard
|
||||
pc98/i386/trap.c standard
|
||||
pc98/i386/userconfig.c optional userconfig
|
||||
pc98/i386/vm_machdep.c standard
|
||||
i386/i386/vm_machdep.c standard
|
||||
i386/ibcs2/ibcs2_fcntl.c optional ibcs2
|
||||
i386/ibcs2/ibcs2_stat.c optional ibcs2
|
||||
i386/ibcs2/ibcs2_ipc.c optional ibcs2
|
||||
@ -89,7 +89,7 @@ pc98/pc98/bs/bshw.c optional bs device-driver
|
||||
pc98/pc98/bs/bsif.c optional bs device-driver
|
||||
pc98/pc98/sbic55.c optional sbic device-driver
|
||||
#i386/pc98/aha1542.c optional aha device-driver
|
||||
pc98/pc98/aic6360.c optional aic device-driver
|
||||
i386/isa/aic6360.c optional aic device-driver
|
||||
pc98/pc98/b004.c optional bqu device-driver
|
||||
i386/pc98/bt742a.c optional bt device-driver
|
||||
i386/pc98/bt5xx-445.c optional bt device-driver
|
||||
@ -130,8 +130,8 @@ pc98/pc98/mse.c optional mse device-driver
|
||||
pc98/isa/ncr5380.c optional nca device-driver
|
||||
pc98/pc98/npx.c optional npx device-driver
|
||||
pc98/pc98/pcaudio.c optional pca device-driver
|
||||
pc98/pc98/matcd/matcd.c optional matcd device-driver
|
||||
pc98/pc98/pcibus.c optional pci device-driver
|
||||
i386/isa/matcd/matcd.c optional matcd device-driver
|
||||
i386/isa/pcibus.c optional pci device-driver
|
||||
i386/isa/pcicx.c optional ze device-driver
|
||||
i386/isa/pcicx.c optional zp device-driver
|
||||
pc98/isa/pcvt/pcvt_drv.c optional vt device-driver
|
||||
@ -140,11 +140,11 @@ pc98/isa/pcvt/pcvt_kbd.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_out.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_sup.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_vtf.c optional vt device-driver
|
||||
pc98/pc98/prof_machdep.c optional profiling-routine
|
||||
i386/isa/prof_machdep.c optional profiling-routine
|
||||
pc98/pc98/psm.c optional psm device-driver
|
||||
pc98/isa/qcam.c optional qcam device-driver
|
||||
pc98/isa/qcamio.c optional qcam device-driver
|
||||
pc98/pc98/random_machdep.c standard
|
||||
i386/isa/random_machdep.c standard
|
||||
pc98/isa/rc.c optional rc device-driver
|
||||
i386/isa/scd.c optional scd device-driver
|
||||
pc98/isa/seagate.c optional sea device-driver
|
||||
@ -152,51 +152,51 @@ 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
|
||||
pc98/pc98/sound/dev_table.c optional snd 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
|
||||
pc98/pc98/sound/audio.c optional snd device-driver
|
||||
pc98/pc98/sound/dmabuf.c optional snd device-driver
|
||||
pc98/pc98/sound/sys_timer.c optional snd device-driver
|
||||
pc98/pc98/sound/sequencer.c optional snd device-driver
|
||||
pc98/pc98/sound/patmgr.c optional snd device-driver
|
||||
pc98/pc98/sound/adlib_card.c optional opl 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
|
||||
pc98/pc98/sound/gus_card.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_midi.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_vol.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_wave.c optional gus device-driver
|
||||
pc98/pc98/sound/ics2101.c optional gus device-driver
|
||||
pc98/pc98/sound/sound_timer.c optional gus device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional gus device-driver
|
||||
pc98/pc98/sound/midibuf.c optional gus 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
|
||||
i386/isa/sound/gus_wave.c optional gus device-driver
|
||||
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
|
||||
pc98/pc98/sound/midi_synth.c optional mss device-driver
|
||||
pc98/pc98/sound/midibuf.c optional mss device-driver
|
||||
pc98/pc98/sound/mpu401.c optional mpu device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional mpu device-driver
|
||||
pc98/pc98/sound/midibuf.c optional mpu device-driver
|
||||
pc98/pc98/sound/pas2_card.c optional pas device-driver
|
||||
pc98/pc98/sound/pas2_midi.c optional pas device-driver
|
||||
pc98/pc98/sound/pas2_mixer.c optional pas 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
|
||||
i386/isa/sound/midi_synth.c optional mpu device-driver
|
||||
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
|
||||
pc98/pc98/sound/midi_synth.c optional pas device-driver
|
||||
pc98/pc98/sound/midibuf.c optional pas device-driver
|
||||
pc98/pc98/sound/sb_card.c optional sb 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
|
||||
pc98/pc98/sound/sb_midi.c optional sb device-driver
|
||||
pc98/pc98/sound/sb_mixer.c optional sb device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional sb device-driver
|
||||
pc98/pc98/sound/midibuf.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
|
||||
pc98/pc98/sound/uart6850.c optional uart device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional uart device-driver
|
||||
pc98/pc98/sound/midibuf.c optional uart device-driver
|
||||
pc98/pc98/sound/trix.c optional trix device-driver
|
||||
pc98/pc98/sound/sscape.c optional sscape 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
|
||||
i386/isa/sound/trix.c optional trix device-driver
|
||||
i386/isa/sound/sscape.c optional sscape device-driver
|
||||
pc98/isa/spigot.c optional spigot device-driver
|
||||
pc98/pc98/spkr.c optional speaker device-driver
|
||||
pc98/isa/stallion.c optional stl device-driver
|
||||
@ -205,7 +205,7 @@ pc98/isa/tw.c optional tw device-driver
|
||||
pc98/isa/ultra14f.c optional uha device-driver
|
||||
pc98/pc98/wd.c optional wdc device-driver
|
||||
pc98/pc98/wd.c optional wd device-driver
|
||||
pc98/pc98/atapi.c optional atapi device-driver
|
||||
i386/isa/atapi.c optional atapi device-driver
|
||||
pc98/pc98/wcd.c optional wcd device-driver
|
||||
pc98/isa/wd7000.c optional wds device-driver
|
||||
pc98/pc98/wt.c optional wt device-driver
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.pc98,v 1.6 1996/10/23 07:24:55 asami Exp $
|
||||
# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
|
||||
BOUNCEPAGES opt_bounce.h
|
||||
USER_LDT
|
||||
MATH_EMULATE opt_math_emulate.h
|
||||
@ -29,6 +29,8 @@ XSERVER opt_pcvt.h
|
||||
|
||||
AHC_TAGENABLE opt_aic7xxx.h
|
||||
AHC_SCBPAGING_ENABLE opt_aic7xxx.h
|
||||
AHC_FORCE_PIO opt_aic7xxx.h
|
||||
AHC_SHARE_SCBS opt_aic7xxx.h
|
||||
|
||||
CLK_CALIBRATION_LOOP opt_clock.h
|
||||
CLK_USE_I8254_CALIBRATION opt_clock.h
|
||||
|
@ -25,11 +25,150 @@
|
||||
* (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: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
|
||||
* $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
|
||||
*/
|
||||
|
||||
#define SET8 0x80 /* set eight bit on */
|
||||
|
||||
#ifdef PC98
|
||||
/* PC-9801 keymap by kuribo@isl.melco.co.jp */
|
||||
static keymap_t key_map = { 0x80, /* PC98 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
* code base shift cntrl shift alt shift cntrl shift spcl flgs
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
|
||||
/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
|
||||
/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
|
||||
/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
|
||||
/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
|
||||
/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
|
||||
/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
|
||||
/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
|
||||
/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
|
||||
/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
|
||||
/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
|
||||
/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
|
||||
/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
|
||||
/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
|
||||
/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
|
||||
/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
|
||||
/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
|
||||
/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
|
||||
/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
|
||||
/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
|
||||
/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
|
||||
/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
|
||||
/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
|
||||
/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
|
||||
/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
|
||||
/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
|
||||
/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
|
||||
/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
|
||||
/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
|
||||
/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
|
||||
/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
|
||||
/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
|
||||
/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
|
||||
/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
|
||||
/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
|
||||
/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
|
||||
/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
|
||||
/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
|
||||
/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
|
||||
/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
|
||||
/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
|
||||
/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
|
||||
/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
|
||||
/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
|
||||
/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
|
||||
/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
|
||||
/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
|
||||
/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
|
||||
/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
|
||||
/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
|
||||
/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
|
||||
/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
|
||||
/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
|
||||
/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
|
||||
/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
|
||||
/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
|
||||
/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
|
||||
/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
|
||||
/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
|
||||
/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
|
||||
/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
|
||||
/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
|
||||
/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
|
||||
/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
|
||||
/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
|
||||
/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
|
||||
/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
|
||||
/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
|
||||
/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
|
||||
/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
|
||||
/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
|
||||
/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
|
||||
/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
|
||||
/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
|
||||
/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
|
||||
/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
|
||||
/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
|
||||
/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
|
||||
/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
|
||||
/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
|
||||
/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
|
||||
/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
|
||||
/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
|
||||
/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
|
||||
/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DKKEYMAP
|
||||
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
|
||||
/* alt
|
||||
@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
|
||||
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
|
@ -38,7 +38,7 @@
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.69 1996/09/28 22:37:43 dyson Exp $
|
||||
* $Id: vm_machdep.c,v 1.70 1996/10/15 03:16:33 dyson Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -66,7 +66,11 @@
|
||||
|
||||
#include <sys/user.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef BOUNCE_BUFFERS
|
||||
static vm_offset_t
|
||||
@ -90,7 +94,11 @@ static int bounceallocarraysize;
|
||||
static unsigned *bounceallocarray;
|
||||
static int bouncefree;
|
||||
|
||||
#if defined(PC98) && defined (EPSON_BOUNCEDMA)
|
||||
#define SIXTEENMEG (3840*4096) /* 15MB boundary */
|
||||
#else
|
||||
#define SIXTEENMEG (4096*4096)
|
||||
#endif
|
||||
#define MAXBKVA 1024
|
||||
int maxbkva = MAXBKVA*PAGE_SIZE;
|
||||
|
||||
@ -748,7 +756,7 @@ cpu_reset() {
|
||||
* to do the reset here would then end up in no man's land.
|
||||
*/
|
||||
|
||||
#ifndef BROKEN_KEYBOARD_RESET
|
||||
#if !defined(BROKEN_KEYBOARD_RESET) && !defined(PC98)
|
||||
outb(IO_KBD + 4, 0xFE);
|
||||
DELAY(500000); /* wait 0.5 sec to see if that did it */
|
||||
printf("Keyboard reset did not work, attempting CPU shutdown\n");
|
||||
@ -761,6 +769,12 @@ cpu_reset() {
|
||||
/* "good night, sweet prince .... <THUNK!>" */
|
||||
invltlb();
|
||||
/* NOTREACHED */
|
||||
#ifdef PC98
|
||||
asm(" cli ");
|
||||
outb(0x37, 0x0f); /* SHUT 0 = 0 */
|
||||
outb(0x37, 0x0b); /* SHUT 1 = 0 */
|
||||
outb(0xf0, 0x00); /* reset port */
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Garrett Wollman, September 1994.
|
||||
* This file is in the public domain.
|
||||
*
|
||||
* $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
|
||||
* $Id: clock.h,v 1.20 1996/10/25 13:01:08 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_CLOCK_H_
|
||||
@ -65,7 +65,11 @@ int sysbeep __P((int pitch, int period));
|
||||
|
||||
#ifdef CLOCK_HAIR
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h> /* XXX */
|
||||
#else
|
||||
#include <i386/isa/isa.h> /* XXX */
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h> /* XXX */
|
||||
|
||||
static __inline u_int
|
||||
|
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: aic6360.c,v 1.22 1996/09/06 23:07:07 phk Exp $
|
||||
* $Id: aic6360.c,v 1.23 1996/10/15 19:22:04 bde Exp $
|
||||
*
|
||||
* Acknowledgements: Many of the algorithms used in this driver are
|
||||
* inspired by the work of Julian Elischer (julian@tfs.com) and
|
||||
@ -47,6 +47,10 @@
|
||||
* 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
|
||||
*/
|
||||
|
||||
/*
|
||||
* PC-9801-100/AHA-1030P support by URATA S.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A few customizable items:
|
||||
*/
|
||||
@ -183,6 +187,9 @@
|
||||
#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
|
||||
|
||||
/* AIC6360 definitions */
|
||||
#ifdef PC98
|
||||
#include <i386/isa/aic_98.h>
|
||||
#else
|
||||
#define SCSISEQ (iobase + 0x00) /* SCSI sequence control */
|
||||
#define SXFRCTL0 (iobase + 0x01) /* SCSI transfer control 0 */
|
||||
#define SXFRCTL1 (iobase + 0x02) /* SCSI transfer control 1 */
|
||||
@ -222,6 +229,7 @@
|
||||
#define STACK (iobase + 0x1d) /* Stack */
|
||||
#define TEST (iobase + 0x1e) /* Test register */
|
||||
#define ID (iobase + 0x1f) /* ID register */
|
||||
#endif
|
||||
|
||||
#define IDSTRING "(C)1991ADAPTECAIC6360 "
|
||||
|
||||
@ -609,6 +617,9 @@ static struct aic_data { /* One of these per adapter */
|
||||
u_char imess[AIC_MAX_MSG_LEN + 1];
|
||||
u_char *imp; /* Message pointer (for multibyte messages) */
|
||||
u_char imlen;
|
||||
#ifdef PC98
|
||||
int *aicport; /* I/O port information */
|
||||
#endif
|
||||
} *aicdata[NAIC];
|
||||
|
||||
#define AIC_SHOWACBS 0x01
|
||||
@ -723,6 +734,15 @@ aicprobe(dev)
|
||||
bzero(aic, sizeof(struct aic_data));
|
||||
aicdata[unit] = aic;
|
||||
aic->iobase = dev->id_iobase;
|
||||
#ifdef PC98
|
||||
if (AIC_TYPE98(dev->id_flags) == AIC98_100) {
|
||||
/* PC-9801-100 */
|
||||
aic->aicport = aicport_100;
|
||||
} else {
|
||||
/* generic card */
|
||||
aic->aicport = aicport_generic;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aic_find(aic) != 0) {
|
||||
aicdata[unit] = NULL;
|
||||
@ -730,6 +750,11 @@ aicprobe(dev)
|
||||
return 0;
|
||||
}
|
||||
aicunit++;
|
||||
|
||||
#ifdef PC98
|
||||
if (AIC_TYPE98(dev->id_flags) == AIC98_100)
|
||||
return 0x40;
|
||||
#endif
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,12 @@ static struct atapi_params *atapi_probe (int port, int unit)
|
||||
{
|
||||
struct atapi_params *ap;
|
||||
char tb [DEV_BSIZE];
|
||||
#ifdef PC98
|
||||
int cnt;
|
||||
|
||||
outb(0x432,unit%2);
|
||||
print(("unit = %d,select %d\n",unit,unit%2));
|
||||
#endif
|
||||
/* Wait for controller not busy. */
|
||||
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
|
||||
if (atapi_wait (port, 0) < 0) {
|
||||
@ -368,8 +373,20 @@ static struct atapi_params *atapi_probe (int port, int unit)
|
||||
}
|
||||
|
||||
/* Issue ATAPI IDENTIFY command. */
|
||||
#ifdef PC98
|
||||
outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
|
||||
|
||||
/* Wait for DRQ deassert. */
|
||||
for (cnt=2000; cnt>0; --cnt)
|
||||
if (! (inb (0x640 + AR_STATUS) & ARS_DRQ))
|
||||
break;
|
||||
|
||||
outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
|
||||
DELAY(500);
|
||||
#else
|
||||
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
|
||||
outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
|
||||
#endif
|
||||
|
||||
/* Check that device is present. */
|
||||
if (inb (port + AR_STATUS) == 0xff) {
|
||||
@ -550,7 +567,13 @@ int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac)
|
||||
ac->result.error = 0;
|
||||
ac->result.status = 0;
|
||||
|
||||
#ifdef PC98
|
||||
outb(0x432,(ac->unit)%2);
|
||||
print(("(ac->unit) = %d,select %d (2) \n",(ac->unit),(ac->unit)%2));
|
||||
outb (ata->port + AR_DRIVE, (ac->unit)/2 ? ARD_DRIVE1 : ARD_DRIVE0);
|
||||
#else
|
||||
outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0);
|
||||
#endif
|
||||
if (atapi_wait (ata->port, 0) < 0) {
|
||||
printf ("atapi%d.%d: controller not ready for cmd\n",
|
||||
ata->ctrlr, ac->unit);
|
||||
@ -632,6 +655,11 @@ int atapi_intr (int ctrlr)
|
||||
struct atapi *ata = atapitab + ctrlr;
|
||||
struct atapicmd *ac = ata->queue;
|
||||
|
||||
#ifdef PC98
|
||||
outb(0x432,(ac->unit)%2);
|
||||
print(("atapi_intr:(ac->unit)= %d,select %d\n",ac->unit,(ac->unit)%2));
|
||||
#endif
|
||||
|
||||
if (! ac) {
|
||||
printf ("atapi%d: stray interrupt\n", ata->ctrlr);
|
||||
return (0);
|
||||
|
@ -17,6 +17,18 @@
|
||||
/*
|
||||
* Disk Controller ATAPI register definitions.
|
||||
*/
|
||||
#ifdef PC98
|
||||
#define AR_DATA 0x0 /* RW - data register (16 bits) */
|
||||
#define AR_ERROR 0x2 /* R - error register */
|
||||
#define AR_FEATURES 0x2 /* W - features */
|
||||
#define AR_IREASON 0x4 /* RW - interrupt reason */
|
||||
#define AR_TAG 0x6 /* - reserved for SAM TAG byte */
|
||||
#define AR_CNTLO 0x8 /* RW - byte count, low byte */
|
||||
#define AR_CNTHI 0xa /* RW - byte count, high byte */
|
||||
#define AR_DRIVE 0xc /* RW - drive select */
|
||||
#define AR_COMMAND 0xe /* W - command register */
|
||||
#define AR_STATUS 0xe /* R - immediate status */
|
||||
#else
|
||||
#define AR_DATA 0x0 /* RW - data register (16 bits) */
|
||||
#define AR_ERROR 0x1 /* R - error register */
|
||||
#define AR_FEATURES 0x1 /* W - features */
|
||||
@ -27,6 +39,7 @@
|
||||
#define AR_DRIVE 0x6 /* RW - drive select */
|
||||
#define AR_COMMAND 0x7 /* W - command register */
|
||||
#define AR_STATUS 0x7 /* R - immediate status */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Status register bits
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)icu.s 7.2 (Berkeley) 5/21/91
|
||||
*
|
||||
* $Id: icu.s,v 1.24 1996/03/12 05:44:25 nate Exp $
|
||||
* $Id: icu.s,v 1.25 1996/05/31 01:08:07 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -278,6 +278,7 @@ vec0:
|
||||
MEXITCOUNT
|
||||
jmp _Xintr0 /* XXX might need _Xfastintr0 */
|
||||
|
||||
#ifndef PC98
|
||||
ALIGN_TEXT
|
||||
vec8:
|
||||
popl %eax
|
||||
@ -287,6 +288,7 @@ vec8:
|
||||
cli
|
||||
MEXITCOUNT
|
||||
jmp _Xintr8 /* XXX might need _Xfastintr8 */
|
||||
#endif
|
||||
|
||||
#define BUILD_VEC(irq_num) \
|
||||
ALIGN_TEXT ; \
|
||||
@ -301,6 +303,9 @@ __CONCAT(vec,irq_num): ; \
|
||||
BUILD_VEC(5)
|
||||
BUILD_VEC(6)
|
||||
BUILD_VEC(7)
|
||||
#ifdef PC98
|
||||
BUILD_VEC(8)
|
||||
#endif
|
||||
BUILD_VEC(9)
|
||||
BUILD_VEC(10)
|
||||
BUILD_VEC(11)
|
||||
|
@ -25,11 +25,150 @@
|
||||
* (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: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
|
||||
* $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
|
||||
*/
|
||||
|
||||
#define SET8 0x80 /* set eight bit on */
|
||||
|
||||
#ifdef PC98
|
||||
/* PC-9801 keymap by kuribo@isl.melco.co.jp */
|
||||
static keymap_t key_map = { 0x80, /* PC98 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
* code base shift cntrl shift alt shift cntrl shift spcl flgs
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
|
||||
/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
|
||||
/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
|
||||
/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
|
||||
/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
|
||||
/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
|
||||
/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
|
||||
/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
|
||||
/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
|
||||
/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
|
||||
/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
|
||||
/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
|
||||
/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
|
||||
/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
|
||||
/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
|
||||
/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
|
||||
/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
|
||||
/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
|
||||
/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
|
||||
/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
|
||||
/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
|
||||
/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
|
||||
/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
|
||||
/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
|
||||
/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
|
||||
/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
|
||||
/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
|
||||
/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
|
||||
/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
|
||||
/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
|
||||
/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
|
||||
/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
|
||||
/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
|
||||
/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
|
||||
/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
|
||||
/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
|
||||
/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
|
||||
/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
|
||||
/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
|
||||
/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
|
||||
/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
|
||||
/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
|
||||
/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
|
||||
/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
|
||||
/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
|
||||
/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
|
||||
/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
|
||||
/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
|
||||
/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
|
||||
/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
|
||||
/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
|
||||
/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
|
||||
/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
|
||||
/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
|
||||
/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
|
||||
/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
|
||||
/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
|
||||
/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
|
||||
/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
|
||||
/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
|
||||
/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
|
||||
/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
|
||||
/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
|
||||
/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
|
||||
/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
|
||||
/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
|
||||
/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
|
||||
/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
|
||||
/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
|
||||
/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
|
||||
/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
|
||||
/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
|
||||
/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
|
||||
/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
|
||||
/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
|
||||
/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
|
||||
/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
|
||||
/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
|
||||
/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
|
||||
/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
|
||||
/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
|
||||
/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
|
||||
/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
|
||||
/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
|
||||
/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DKKEYMAP
|
||||
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
|
||||
/* alt
|
||||
@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
|
||||
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
|
@ -98,13 +98,20 @@ See matcd.c for Edit History
|
||||
|
||||
#define CMD 0 /*Write - commands*/
|
||||
#define DATA 0 /*Read - data/status from drive*/
|
||||
#ifdef PC98
|
||||
#define PHASE 0x100 /*Write - switch between data/status*/
|
||||
#define STATUS 0x100 /*Read - bus status */
|
||||
#define RESET 0x200 /*Write - reset all attached drives*/
|
||||
#define ALTDATA 0x200 /*<20>Read - data on non Creative bds.*/
|
||||
#define SELECT 0x300 /*Write - drive select*/
|
||||
#else /* !PC98 */
|
||||
#define PHASE 1 /*Write - switch between data/status*/
|
||||
#define STATUS 1 /*Read - bus status*/
|
||||
#define RESET 2 /*Write - reset all attached drives*/
|
||||
/*Any value written will reset*/
|
||||
#define ALTDATA 2 /*<20>Read - data on non Creative bds.*/
|
||||
#define SELECT 3 /*Write - drive select*/
|
||||
|
||||
#endif /*PC98*/
|
||||
|
||||
/* Creative PHASE port bit assignments
|
||||
*/
|
||||
|
@ -184,6 +184,16 @@
|
||||
|
||||
#ifdef AUTOHUNT
|
||||
static int port_hints[]={
|
||||
#ifdef PC98
|
||||
0x30d2,
|
||||
0x30d0,
|
||||
0x30d4,
|
||||
0x30d6,
|
||||
0x30d8,
|
||||
0x30da,
|
||||
0x30dc,
|
||||
0x30de,
|
||||
#else /* IBM-PC */
|
||||
0x230, /*SB Pro & SB16*/
|
||||
0x240, /*SB Pro & SB16*/
|
||||
0x250, /*Creative omniCD standalone boards*/
|
||||
@ -205,6 +215,7 @@ static int port_hints[]={
|
||||
0x670, /*IBM*/
|
||||
0x690, /*IBM*/
|
||||
#endif /*0*/
|
||||
#endif /* PC98 */
|
||||
-1}; /*use. Table MUST end with -1*/
|
||||
#endif /*AUTOHUNT*/
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
|
||||
* $Id: prof_machdep.c,v 1.3 1996/10/17 19:32:10 bde Exp $
|
||||
*/
|
||||
|
||||
#ifdef GUPROF
|
||||
@ -40,7 +40,11 @@
|
||||
#include <machine/profile.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
#ifdef GUPROF
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* random_machdep.c -- A strong random number generator
|
||||
*
|
||||
* $Id: random_machdep.c,v 1.11 1996/09/27 13:25:13 peter Exp $
|
||||
* $Id: random_machdep.c,v 1.12 1996/10/09 19:47:32 bde Exp $
|
||||
*
|
||||
* Version 0.95, last modified 18-Oct-95
|
||||
*
|
||||
@ -51,7 +51,11 @@
|
||||
#include <machine/random.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
#define MAX_BLKDEV 4
|
||||
|
@ -301,6 +301,11 @@ struct sound_timer_operations {
|
||||
{SNDCARD_TRXPRO, "MediaTriX AudioTriX Pro", attach_trix_wss, probe_trix_wss},
|
||||
{SNDCARD_TRXPRO_SB, "AudioTriX (SB mode)", attach_trix_sb, probe_trix_sb},
|
||||
{SNDCARD_TRXPRO_MPU, "AudioTriX MIDI", attach_trix_mpu, probe_trix_mpu},
|
||||
#endif
|
||||
#ifdef PC98
|
||||
#ifndef EXCLUDE_PCM86
|
||||
{SNDCARD_PCM86, "PC-9801-86/73", attach_pcm86, probe_pcm86},
|
||||
#endif
|
||||
#endif
|
||||
{0, "*?*", NULL, NULL}
|
||||
};
|
||||
@ -383,6 +388,11 @@ struct sound_timer_operations {
|
||||
|
||||
#ifndef EXCLUDE_YM3812
|
||||
{SNDCARD_ADLIB, {FM_MONO, 0, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef PC98
|
||||
#ifndef EXCLUDE_PCM86
|
||||
{SNDCARD_PCM86, {0, 0, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
{0, {0}, 0}
|
||||
};
|
||||
|
@ -92,6 +92,14 @@
|
||||
#define EXCLUDE_UART6850
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include "pcm.h"
|
||||
#if NPCM == 0 && !defined(EXCLUDE_PCM86)
|
||||
#define EXCLUDE_PCM86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* nothing but a sequencer (Adlib/OPL) ? */
|
||||
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NMPU == 0 && \
|
||||
NUART == 0 && NMSS == 0
|
||||
@ -99,9 +107,11 @@
|
||||
#define EXCLUDE_MIDI
|
||||
#endif
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
|
||||
#define EXCLUDE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* nothing but a Midi (MPU/UART) ? */
|
||||
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NOPL == 0 && \
|
||||
@ -111,6 +121,8 @@
|
||||
#define EXCLUDE_SEQUENCER
|
||||
#endif
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
|
||||
#define EXCLUDE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
@ -249,6 +249,12 @@ int pss_ioctl (int dev, struct fileinfo *file,
|
||||
int pss_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
|
||||
long pss_init(long mem_start);
|
||||
|
||||
#ifdef PC98
|
||||
/* From pcm86.c */
|
||||
int probe_pcm86(struct address_info *hw_config);
|
||||
long attach_pcm86(long mem_start, struct address_info *hw_config);
|
||||
#endif PC98
|
||||
|
||||
/* From aedsp16.c */
|
||||
int InitAEDSP16_SBPRO(struct address_info *hw_config);
|
||||
int InitAEDSP16_MSS(struct address_info *hw_config);
|
||||
|
@ -79,24 +79,44 @@ 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
|
||||
@ -248,7 +268,11 @@ If your card has nonstandard I/O address or IRQ number, change defines
|
||||
|
||||
#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) */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
|
||||
* $Id$
|
||||
* $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -59,6 +59,7 @@
|
||||
* in undefined behavior (but hopefully not fry the chip).
|
||||
* Reading in this manner has no side effects.
|
||||
*
|
||||
* [IBM-PC]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
@ -67,15 +68,31 @@
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 2 is used to generate console beeps.
|
||||
*
|
||||
* [PC-9801]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
* timer 1 -> speaker (via keyboard controller)
|
||||
* timer 2 -> RS232C
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 1 is used to generate console beeps.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macros for specifying values to be written into a mode register.
|
||||
*/
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#ifdef PC98
|
||||
#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
|
||||
#else
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#endif
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_SEL2 0x80 /* select counter 2 */
|
||||
|
@ -1,12 +1,26 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
|
||||
* $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
|
||||
#else
|
||||
#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
|
||||
#endif
|
||||
|
||||
#define ICU_EOI 0x20 /* XXX - define elsewhere */
|
||||
|
||||
@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
orb $IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
enable_icus ; \
|
||||
incl _cnt+V_INTR ; /* tally interrupts */ \
|
||||
movl _cpl,%eax ; \
|
||||
@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
|
||||
movb _imen + IRQ_BYTE(irq_num),%al ; \
|
||||
andb $~IRQ_BIT(irq_num),%al ; \
|
||||
movb %al,_imen + IRQ_BYTE(irq_num) ; \
|
||||
outb %al,$icu+1 ; \
|
||||
outb %al,$icu+ICU_IMR_OFFSET ; \
|
||||
sti ; /* XXX _doreti repeats the cli/sti */ \
|
||||
MEXITCOUNT ; \
|
||||
/* We could usually avoid the following jmp by inlining some of */ \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
|
||||
** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
@ -25,11 +25,150 @@
|
||||
* (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: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
|
||||
* $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
|
||||
*/
|
||||
|
||||
#define SET8 0x80 /* set eight bit on */
|
||||
|
||||
#ifdef PC98
|
||||
/* PC-9801 keymap by kuribo@isl.melco.co.jp */
|
||||
static keymap_t key_map = { 0x80, /* PC98 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
* code base shift cntrl shift alt shift cntrl shift spcl flgs
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
|
||||
/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
|
||||
/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
|
||||
/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
|
||||
/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
|
||||
/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
|
||||
/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
|
||||
/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
|
||||
/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
|
||||
/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
|
||||
/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
|
||||
/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
|
||||
/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
|
||||
/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
|
||||
/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
|
||||
/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
|
||||
/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
|
||||
/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
|
||||
/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
|
||||
/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
|
||||
/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
|
||||
/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
|
||||
/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
|
||||
/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
|
||||
/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
|
||||
/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
|
||||
/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
|
||||
/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
|
||||
/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
|
||||
/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
|
||||
/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
|
||||
/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
|
||||
/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
|
||||
/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
|
||||
/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
|
||||
/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
|
||||
/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
|
||||
/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
|
||||
/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
|
||||
/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
|
||||
/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
|
||||
/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
|
||||
/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
|
||||
/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
|
||||
/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
|
||||
/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
|
||||
/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
|
||||
/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
|
||||
/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
|
||||
/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
|
||||
/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
|
||||
/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
|
||||
/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
|
||||
/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
|
||||
/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
|
||||
/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
|
||||
/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
|
||||
/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
|
||||
/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
|
||||
/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
|
||||
/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
|
||||
/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
|
||||
/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
|
||||
/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
|
||||
/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
|
||||
/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
|
||||
/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
|
||||
/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
|
||||
/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
|
||||
/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
|
||||
/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
|
||||
/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
|
||||
/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
|
||||
/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
|
||||
/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
|
||||
/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
|
||||
/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
|
||||
/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
|
||||
/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
|
||||
/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
|
||||
/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
|
||||
/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
|
||||
/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
|
||||
/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
|
||||
/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
|
||||
/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
|
||||
/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
|
||||
/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
|
||||
/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
|
||||
/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
|
||||
/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DKKEYMAP
|
||||
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
|
||||
/* alt
|
||||
@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
|
||||
#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
|
||||
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
|
||||
/* alt
|
||||
* scan cntrl alt alt cntrl
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
|
||||
* $Id$
|
||||
* $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -59,6 +59,7 @@
|
||||
* in undefined behavior (but hopefully not fry the chip).
|
||||
* Reading in this manner has no side effects.
|
||||
*
|
||||
* [IBM-PC]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
@ -67,15 +68,31 @@
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 2 is used to generate console beeps.
|
||||
*
|
||||
* [PC-9801]
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
* timer 1 -> speaker (via keyboard controller)
|
||||
* timer 2 -> RS232C
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 1 is used to generate console beeps.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macros for specifying values to be written into a mode register.
|
||||
*/
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#ifdef PC98
|
||||
#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
|
||||
#else
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#endif
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_SEL2 0x80 /* select counter 2 */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* random_machdep.c -- A strong random number generator
|
||||
*
|
||||
* $Id: random_machdep.c,v 1.11 1996/09/27 13:25:13 peter Exp $
|
||||
* $Id: random_machdep.c,v 1.12 1996/10/09 19:47:32 bde Exp $
|
||||
*
|
||||
* Version 0.95, last modified 18-Oct-95
|
||||
*
|
||||
@ -51,7 +51,11 @@
|
||||
#include <machine/random.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
#define MAX_BLKDEV 4
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
|
||||
* $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
|
||||
* $Id: pc98.h,v 1.6 1996/10/23 07:25:22 asami Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PC98_PC98_PC98_H_
|
||||
@ -73,7 +73,7 @@
|
||||
#define IO_NMI 0x050 /* NMI Control */
|
||||
#define IO_WAIT 0x05F /* WAIT 0.6 us */
|
||||
#define IO_GDC1 0x060 /* 7220 GDC Text Control */
|
||||
#define IO_TIMER 0x071 /* 8253C Timer */
|
||||
#define IO_TIMER1 0x071 /* 8253C Timer */
|
||||
#define IO_SASI 0x080 /* SASI Hard Disk Controller */
|
||||
#define IO_FD1 0x090 /* 765A 1MB FDC */
|
||||
#define IO_GDC2 0x0a0 /* 7220 GDC Graphic Control */
|
||||
|
@ -34,7 +34,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
|
||||
* $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routines to handle clock hardware.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -48,10 +52,6 @@
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
|
||||
#include "opt_clock.h"
|
||||
#include "opt_cpu.h"
|
||||
|
||||
@ -72,13 +72,12 @@
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
/*
|
||||
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
|
||||
@ -109,52 +108,49 @@
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
u_int idelayed;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_comultiplier;
|
||||
u_int i586_ctr_freq;
|
||||
u_int i586_ctr_multiplier;
|
||||
long long i586_last_tick;
|
||||
unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
#ifdef PC98
|
||||
#ifndef AUTO_CLOCK
|
||||
#ifndef PC98_8M
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#else /* !PC98_8M */
|
||||
static u_int timer_freq = 1996800;
|
||||
u_int timer_freq = 1996800;
|
||||
#endif /* PC98_8M */
|
||||
#else /* AUTO_CLOCK */
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
static u_int timer_freq = 1193182;
|
||||
u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
@ -171,7 +167,7 @@ static u_char timer0_state;
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
@ -437,7 +433,7 @@ getit(void)
|
||||
disable_intr();
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
@ -625,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -782,7 +778,7 @@ startrtclock()
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -802,7 +798,7 @@ startrtclock()
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_freq != 0) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
}
|
||||
@ -1114,10 +1110,8 @@ cpu_initclocks()
|
||||
/*
|
||||
* Finish setting up anti-jitter measures.
|
||||
*/
|
||||
if (i586_ctr_freq != 0) {
|
||||
i586_last_tick = rdtsc();
|
||||
i586_ctr_bias = i586_last_tick;
|
||||
}
|
||||
if (i586_ctr_freq != 0)
|
||||
i586_ctr_bias = rdtsc();
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
|
@ -34,7 +34,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
|
||||
* $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routines to handle clock hardware.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -48,10 +52,6 @@
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
|
||||
#include "opt_clock.h"
|
||||
#include "opt_cpu.h"
|
||||
|
||||
@ -72,13 +72,12 @@
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
/*
|
||||
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
|
||||
@ -109,52 +108,49 @@
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
u_int idelayed;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_comultiplier;
|
||||
u_int i586_ctr_freq;
|
||||
u_int i586_ctr_multiplier;
|
||||
long long i586_last_tick;
|
||||
unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
#ifdef PC98
|
||||
#ifndef AUTO_CLOCK
|
||||
#ifndef PC98_8M
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#else /* !PC98_8M */
|
||||
static u_int timer_freq = 1996800;
|
||||
u_int timer_freq = 1996800;
|
||||
#endif /* PC98_8M */
|
||||
#else /* AUTO_CLOCK */
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
static u_int timer_freq = 1193182;
|
||||
u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
@ -171,7 +167,7 @@ static u_char timer0_state;
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
@ -437,7 +433,7 @@ getit(void)
|
||||
disable_intr();
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
@ -625,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -782,7 +778,7 @@ startrtclock()
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -802,7 +798,7 @@ startrtclock()
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_freq != 0) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
}
|
||||
@ -1114,10 +1110,8 @@ cpu_initclocks()
|
||||
/*
|
||||
* Finish setting up anti-jitter measures.
|
||||
*/
|
||||
if (i586_ctr_freq != 0) {
|
||||
i586_last_tick = rdtsc();
|
||||
i586_ctr_bias = i586_last_tick;
|
||||
}
|
||||
if (i586_ctr_freq != 0)
|
||||
i586_ctr_bias = rdtsc();
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
|
@ -11,7 +11,7 @@
|
||||
# device lines is present in the ./LINT configuration file. If you are
|
||||
# in doubt as to the purpose or necessity of a line, check first in LINT.
|
||||
#
|
||||
# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
|
||||
# $Id: GENERIC98,v 1.7 1996/10/23 07:24:45 asami Exp $
|
||||
|
||||
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
|
||||
|
||||
@ -100,6 +100,9 @@ device wcd0 #IDE CD-ROM
|
||||
# for any number of installed devices.
|
||||
controller ncr0
|
||||
controller ahc0
|
||||
options "AHC_FORCE_PIO" # Some motherboards choke on MemI/O,
|
||||
# so use PIO in the ahc driver in the
|
||||
# generic kernel.
|
||||
|
||||
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
|
||||
# sbic55.c.new
|
||||
|
@ -11,7 +11,7 @@
|
||||
# device lines is present in the ./LINT configuration file. If you are
|
||||
# in doubt as to the purpose or necessity of a line, check first in LINT.
|
||||
#
|
||||
# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
|
||||
# $Id: GENERIC98,v 1.7 1996/10/23 07:24:45 asami Exp $
|
||||
|
||||
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
|
||||
|
||||
@ -100,6 +100,9 @@ device wcd0 #IDE CD-ROM
|
||||
# for any number of installed devices.
|
||||
controller ncr0
|
||||
controller ahc0
|
||||
options "AHC_FORCE_PIO" # Some motherboards choke on MemI/O,
|
||||
# so use PIO in the ahc driver in the
|
||||
# generic kernel.
|
||||
|
||||
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
|
||||
# sbic55.c.new
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# modified for PC-9801
|
||||
#
|
||||
# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
|
||||
# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $
|
||||
#
|
||||
aic7xxx_asm optional ahc device-driver \
|
||||
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
|
||||
@ -43,7 +43,7 @@ i386/i386/db_disasm.c optional ddb
|
||||
i386/i386/db_interface.c optional ddb
|
||||
i386/i386/db_trace.c optional ddb
|
||||
i386/i386/i386-gdbstub.c optional ddb
|
||||
pc98/i386/exception.s standard
|
||||
i386/i386/exception.s standard
|
||||
i386/i386/identcpu.c standard
|
||||
i386/i386/in_cksum.c optional inet
|
||||
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
|
||||
@ -62,7 +62,7 @@ i386/i386/swtch.s standard
|
||||
i386/i386/sys_machdep.c standard
|
||||
pc98/i386/trap.c standard
|
||||
pc98/i386/userconfig.c optional userconfig
|
||||
pc98/i386/vm_machdep.c standard
|
||||
i386/i386/vm_machdep.c standard
|
||||
i386/ibcs2/ibcs2_fcntl.c optional ibcs2
|
||||
i386/ibcs2/ibcs2_stat.c optional ibcs2
|
||||
i386/ibcs2/ibcs2_ipc.c optional ibcs2
|
||||
@ -89,7 +89,7 @@ pc98/pc98/bs/bshw.c optional bs device-driver
|
||||
pc98/pc98/bs/bsif.c optional bs device-driver
|
||||
pc98/pc98/sbic55.c optional sbic device-driver
|
||||
#i386/pc98/aha1542.c optional aha device-driver
|
||||
pc98/pc98/aic6360.c optional aic device-driver
|
||||
i386/isa/aic6360.c optional aic device-driver
|
||||
pc98/pc98/b004.c optional bqu device-driver
|
||||
i386/pc98/bt742a.c optional bt device-driver
|
||||
i386/pc98/bt5xx-445.c optional bt device-driver
|
||||
@ -130,8 +130,8 @@ pc98/pc98/mse.c optional mse device-driver
|
||||
pc98/isa/ncr5380.c optional nca device-driver
|
||||
pc98/pc98/npx.c optional npx device-driver
|
||||
pc98/pc98/pcaudio.c optional pca device-driver
|
||||
pc98/pc98/matcd/matcd.c optional matcd device-driver
|
||||
pc98/pc98/pcibus.c optional pci device-driver
|
||||
i386/isa/matcd/matcd.c optional matcd device-driver
|
||||
i386/isa/pcibus.c optional pci device-driver
|
||||
i386/isa/pcicx.c optional ze device-driver
|
||||
i386/isa/pcicx.c optional zp device-driver
|
||||
pc98/isa/pcvt/pcvt_drv.c optional vt device-driver
|
||||
@ -140,11 +140,11 @@ pc98/isa/pcvt/pcvt_kbd.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_out.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_sup.c optional vt device-driver
|
||||
pc98/isa/pcvt/pcvt_vtf.c optional vt device-driver
|
||||
pc98/pc98/prof_machdep.c optional profiling-routine
|
||||
i386/isa/prof_machdep.c optional profiling-routine
|
||||
pc98/pc98/psm.c optional psm device-driver
|
||||
pc98/isa/qcam.c optional qcam device-driver
|
||||
pc98/isa/qcamio.c optional qcam device-driver
|
||||
pc98/pc98/random_machdep.c standard
|
||||
i386/isa/random_machdep.c standard
|
||||
pc98/isa/rc.c optional rc device-driver
|
||||
i386/isa/scd.c optional scd device-driver
|
||||
pc98/isa/seagate.c optional sea device-driver
|
||||
@ -152,51 +152,51 @@ 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
|
||||
pc98/pc98/sound/dev_table.c optional snd 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
|
||||
pc98/pc98/sound/audio.c optional snd device-driver
|
||||
pc98/pc98/sound/dmabuf.c optional snd device-driver
|
||||
pc98/pc98/sound/sys_timer.c optional snd device-driver
|
||||
pc98/pc98/sound/sequencer.c optional snd device-driver
|
||||
pc98/pc98/sound/patmgr.c optional snd device-driver
|
||||
pc98/pc98/sound/adlib_card.c optional opl 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
|
||||
pc98/pc98/sound/gus_card.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_midi.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_vol.c optional gus device-driver
|
||||
pc98/pc98/sound/gus_wave.c optional gus device-driver
|
||||
pc98/pc98/sound/ics2101.c optional gus device-driver
|
||||
pc98/pc98/sound/sound_timer.c optional gus device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional gus device-driver
|
||||
pc98/pc98/sound/midibuf.c optional gus 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
|
||||
i386/isa/sound/gus_wave.c optional gus device-driver
|
||||
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
|
||||
pc98/pc98/sound/midi_synth.c optional mss device-driver
|
||||
pc98/pc98/sound/midibuf.c optional mss device-driver
|
||||
pc98/pc98/sound/mpu401.c optional mpu device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional mpu device-driver
|
||||
pc98/pc98/sound/midibuf.c optional mpu device-driver
|
||||
pc98/pc98/sound/pas2_card.c optional pas device-driver
|
||||
pc98/pc98/sound/pas2_midi.c optional pas device-driver
|
||||
pc98/pc98/sound/pas2_mixer.c optional pas 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
|
||||
i386/isa/sound/midi_synth.c optional mpu device-driver
|
||||
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
|
||||
pc98/pc98/sound/midi_synth.c optional pas device-driver
|
||||
pc98/pc98/sound/midibuf.c optional pas device-driver
|
||||
pc98/pc98/sound/sb_card.c optional sb 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
|
||||
pc98/pc98/sound/sb_midi.c optional sb device-driver
|
||||
pc98/pc98/sound/sb_mixer.c optional sb device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional sb device-driver
|
||||
pc98/pc98/sound/midibuf.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
|
||||
pc98/pc98/sound/uart6850.c optional uart device-driver
|
||||
pc98/pc98/sound/midi_synth.c optional uart device-driver
|
||||
pc98/pc98/sound/midibuf.c optional uart device-driver
|
||||
pc98/pc98/sound/trix.c optional trix device-driver
|
||||
pc98/pc98/sound/sscape.c optional sscape 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
|
||||
i386/isa/sound/trix.c optional trix device-driver
|
||||
i386/isa/sound/sscape.c optional sscape device-driver
|
||||
pc98/isa/spigot.c optional spigot device-driver
|
||||
pc98/pc98/spkr.c optional speaker device-driver
|
||||
pc98/isa/stallion.c optional stl device-driver
|
||||
@ -205,7 +205,7 @@ pc98/isa/tw.c optional tw device-driver
|
||||
pc98/isa/ultra14f.c optional uha device-driver
|
||||
pc98/pc98/wd.c optional wdc device-driver
|
||||
pc98/pc98/wd.c optional wd device-driver
|
||||
pc98/pc98/atapi.c optional atapi device-driver
|
||||
i386/isa/atapi.c optional atapi device-driver
|
||||
pc98/pc98/wcd.c optional wcd device-driver
|
||||
pc98/isa/wd7000.c optional wds device-driver
|
||||
pc98/pc98/wt.c optional wt device-driver
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.pc98,v 1.6 1996/10/23 07:24:55 asami Exp $
|
||||
# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
|
||||
BOUNCEPAGES opt_bounce.h
|
||||
USER_LDT
|
||||
MATH_EMULATE opt_math_emulate.h
|
||||
@ -29,6 +29,8 @@ XSERVER opt_pcvt.h
|
||||
|
||||
AHC_TAGENABLE opt_aic7xxx.h
|
||||
AHC_SCBPAGING_ENABLE opt_aic7xxx.h
|
||||
AHC_FORCE_PIO opt_aic7xxx.h
|
||||
AHC_SHARE_SCBS opt_aic7xxx.h
|
||||
|
||||
CLK_CALIBRATION_LOOP opt_clock.h
|
||||
CLK_USE_I8254_CALIBRATION opt_clock.h
|
||||
|
@ -1,279 +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.
|
||||
*
|
||||
* $Id: exception.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
#include "assym.s" /* system defines */
|
||||
#include <sys/errno.h> /* error return codes */
|
||||
#include <machine/spl.h> /* SWI_AST_MASK ... */
|
||||
#include <machine/psl.h> /* PSL_I */
|
||||
#include <machine/trap.h> /* trap codes */
|
||||
#include <sys/syscall.h> /* syscall numbers */
|
||||
#include <machine/asmacros.h> /* miscellaneous macros */
|
||||
#include <sys/cdefs.h> /* CPP macros */
|
||||
|
||||
#define KDSEL 0x10 /* kernel data selector */
|
||||
#define SEL_RPL_MASK 0x0003
|
||||
#define TRAPF_CS_OFF (13 * 4)
|
||||
|
||||
.text
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Trap handling */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Trap and fault vector routines
|
||||
*/
|
||||
#define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(_X,name); __CONCAT(_X,name):
|
||||
#define TRAP(a) pushl $(a) ; jmp _alltraps
|
||||
|
||||
/*
|
||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||
*/
|
||||
#ifdef BDE_DEBUGGER
|
||||
#define BDBTRAP(name) \
|
||||
ss ; \
|
||||
cmpb $0,_bdb_exists ; \
|
||||
je 1f ; \
|
||||
testb $SEL_RPL_MASK,4(%esp) ; \
|
||||
jne 1f ; \
|
||||
ss ; \
|
||||
.globl __CONCAT(__CONCAT(bdb_,name),_ljmp); \
|
||||
__CONCAT(__CONCAT(bdb_,name),_ljmp): \
|
||||
ljmp $0,$0 ; \
|
||||
1:
|
||||
#else
|
||||
#define BDBTRAP(name)
|
||||
#endif
|
||||
|
||||
#define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
|
||||
|
||||
MCOUNT_LABEL(user)
|
||||
MCOUNT_LABEL(btrap)
|
||||
|
||||
IDTVEC(div)
|
||||
pushl $0; TRAP(T_DIVIDE)
|
||||
IDTVEC(dbg)
|
||||
BDBTRAP(dbg)
|
||||
pushl $0; BPTTRAP(T_TRCTRAP)
|
||||
IDTVEC(nmi)
|
||||
pushl $0; TRAP(T_NMI)
|
||||
IDTVEC(bpt)
|
||||
BDBTRAP(bpt)
|
||||
pushl $0; BPTTRAP(T_BPTFLT)
|
||||
IDTVEC(ofl)
|
||||
pushl $0; TRAP(T_OFLOW)
|
||||
IDTVEC(bnd)
|
||||
pushl $0; TRAP(T_BOUND)
|
||||
IDTVEC(ill)
|
||||
pushl $0; TRAP(T_PRIVINFLT)
|
||||
IDTVEC(dna)
|
||||
pushl $0; TRAP(T_DNA)
|
||||
IDTVEC(fpusegm)
|
||||
pushl $0; TRAP(T_FPOPFLT)
|
||||
IDTVEC(tss)
|
||||
TRAP(T_TSSFLT)
|
||||
IDTVEC(missing)
|
||||
TRAP(T_SEGNPFLT)
|
||||
IDTVEC(stk)
|
||||
TRAP(T_STKFLT)
|
||||
IDTVEC(prot)
|
||||
TRAP(T_PROTFLT)
|
||||
IDTVEC(page)
|
||||
TRAP(T_PAGEFLT)
|
||||
IDTVEC(mchk)
|
||||
pushl $0; TRAP(T_MCHK)
|
||||
IDTVEC(rsvd)
|
||||
pushl $0; TRAP(T_RESERVED)
|
||||
IDTVEC(fpu)
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* Handle like an interrupt (except for accounting) so that we can
|
||||
* call npxintr to clear the error. It would be better to handle
|
||||
* npx interrupts as traps. This used to be difficult for nested
|
||||
* interrupts, but now it is fairly easy - mask nested ones the
|
||||
* same as SWI_AST's.
|
||||
*/
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $0 /* dummy trap type */
|
||||
pushal
|
||||
pushl %ds
|
||||
pushl %es /* now the stack frame is a trap frame */
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
FAKE_MCOUNT(12*4(%esp))
|
||||
movl _cpl,%eax
|
||||
pushl %eax
|
||||
pushl $0 /* dummy unit to finish building intr frame */
|
||||
incl _cnt+V_TRAP
|
||||
orl $SWI_AST_MASK,%eax
|
||||
movl %eax,_cpl
|
||||
call _npxintr
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
#else /* NNPX > 0 */
|
||||
pushl $0; TRAP(T_ARITHTRAP)
|
||||
#endif /* NNPX > 0 */
|
||||
IDTVEC(align)
|
||||
TRAP(T_ALIGNFLT)
|
||||
|
||||
SUPERALIGN_TEXT
|
||||
.globl _alltraps
|
||||
_alltraps:
|
||||
pushal
|
||||
pushl %ds
|
||||
pushl %es
|
||||
alltraps_with_regs_pushed:
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
FAKE_MCOUNT(12*4(%esp))
|
||||
calltrap:
|
||||
FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */
|
||||
incl _cnt+V_TRAP
|
||||
orl $SWI_AST_MASK,_cpl
|
||||
call _trap
|
||||
|
||||
/*
|
||||
* There was no place to save the cpl so we have to recover it
|
||||
* indirectly. For traps from user mode it was 0, and for traps
|
||||
* from kernel mode Oring SWI_AST_MASK into it didn't change it.
|
||||
*/
|
||||
subl %eax,%eax
|
||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
||||
jne 1f
|
||||
movl _cpl,%eax
|
||||
1:
|
||||
/*
|
||||
* Return via _doreti to handle ASTs. Have to change trap frame
|
||||
* to interrupt frame.
|
||||
*/
|
||||
pushl %eax
|
||||
subl $4,%esp
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
/*
|
||||
* Call gate entry for syscall.
|
||||
* The intersegment call has been set up to specify one dummy parameter.
|
||||
* This leaves a place to put eflags so that the call frame can be
|
||||
* converted to a trap frame. Note that the eflags is (semi-)bogusly
|
||||
* pushed into (what will be) tf_err and then copied later into the
|
||||
* final spot. It has to be done this way because esp can't be just
|
||||
* temporarily altered for the pushfl - an interrupt might come in
|
||||
* and clobber the saved cs/eip.
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
IDTVEC(syscall)
|
||||
pushfl /* save eflags in tf_err for now */
|
||||
subl $4,%esp /* skip over tf_trapno */
|
||||
pushal
|
||||
pushl %ds
|
||||
pushl %es
|
||||
movl $KDSEL,%eax /* switch to kernel segments */
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
|
||||
movl %eax,TF_EFLAGS(%esp)
|
||||
movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */
|
||||
FAKE_MCOUNT(12*4(%esp))
|
||||
incl _cnt+V_SYSCALL
|
||||
movl $SWI_AST_MASK,_cpl
|
||||
call _syscall
|
||||
/*
|
||||
* Return via _doreti to handle ASTs.
|
||||
*/
|
||||
pushl $0 /* cpl to restore */
|
||||
subl $4,%esp
|
||||
movb $1,_intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
/*
|
||||
* Call gate entry for Linux/NetBSD syscall (int 0x80)
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
IDTVEC(int0x80_syscall)
|
||||
subl $8,%esp /* skip over tf_trapno and tf_err */
|
||||
pushal
|
||||
pushl %ds
|
||||
pushl %es
|
||||
movl $KDSEL,%eax /* switch to kernel segments */
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
|
||||
FAKE_MCOUNT(12*4(%esp))
|
||||
incl _cnt+V_SYSCALL
|
||||
movl $SWI_AST_MASK,_cpl
|
||||
call _syscall
|
||||
/*
|
||||
* Return via _doreti to handle ASTs.
|
||||
*/
|
||||
pushl $0 /* cpl to restore */
|
||||
subl $4,%esp
|
||||
movb $1,_intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
/*
|
||||
* Include what was once config+isa-dependent code.
|
||||
* XXX it should be in a stand-alone file. It's still icu-dependent and
|
||||
* belongs in i386/isa.
|
||||
*/
|
||||
#ifdef PC98
|
||||
#include "pc98/pc98/vector.s"
|
||||
#else
|
||||
#include "i386/isa/vector.s"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include what was once icu-dependent code.
|
||||
* XXX it should be merged into this file (also move the definition of
|
||||
* imen to vector.s or isa.c).
|
||||
* Before including it, set up a normal asm environment so that vector.s
|
||||
* doesn't have to know that stuff is included after it.
|
||||
*/
|
||||
.data
|
||||
ALIGN_DATA
|
||||
.text
|
||||
SUPERALIGN_TEXT
|
||||
#ifdef PC98
|
||||
#include "pc98/pc98/icu.s"
|
||||
#else
|
||||
#include "i386/isa/icu.s"
|
||||
#endif
|
@ -32,22 +32,20 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Steve McCanne's microtime code
|
||||
* $Id: microtime.s,v 1.4 1996/09/07 02:13:34 asami Exp $
|
||||
* $Id: microtime.s,v 1.5 1996/10/09 19:47:38 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_cpu.h"
|
||||
|
||||
#include <machine/asmacros.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
ENTRY(microtime)
|
||||
|
||||
|
@ -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.8 1996/10/23 07:25:04 asami Exp $
|
||||
** $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $
|
||||
**/
|
||||
|
||||
/**
|
||||
@ -244,7 +244,7 @@ static DEV_INFO device_info[] = {
|
||||
{"aha", "Adaptec 154x SCSI controller", 0, CLS_STORAGE},
|
||||
{"uha", "Ultrastor 14F/24F/34F SCSI controller",0, CLS_STORAGE},
|
||||
{"aic", "Adaptec 152x SCSI and compatible sound cards", 0, CLS_STORAGE},
|
||||
{"nca", "ProAudio Spectrum SCSI and comaptibles", 0, CLS_STORAGE},
|
||||
{"nca", "ProAudio Spectrum SCSI and compatibles", 0, CLS_STORAGE},
|
||||
{"sea", "Seagate ST01/ST02 SCSI and compatibles", 0, CLS_STORAGE},
|
||||
{"wds", "Western Digitial WD7000 SCSI controller", 0, CLS_STORAGE},
|
||||
{"ncr", "NCR 53C810 SCSI controller", FLG_FIXED, CLS_STORAGE},
|
||||
@ -2247,7 +2247,7 @@ visuserconfig(void)
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: userconfig.c,v 1.8 1996/10/23 07:25:04 asami Exp $
|
||||
* $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $
|
||||
*/
|
||||
|
||||
#include "scbus.h"
|
||||
|
@ -1,864 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986 The Regents of the University of California.
|
||||
* Copyright (c) 1989, 1990 William Jolitz
|
||||
* Copyright (c) 1994 John Dyson
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department, and 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: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.5 1996/10/09 21:46:03 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
#include "opt_bounce.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/vmmeter.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_prot.h>
|
||||
#include <vm/lock.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <sys/user.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/epsonio.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
|
||||
#ifdef BOUNCE_BUFFERS
|
||||
static vm_offset_t
|
||||
vm_bounce_kva __P((int size, int waitok));
|
||||
static void vm_bounce_kva_free __P((vm_offset_t addr, vm_offset_t size,
|
||||
int now));
|
||||
static vm_offset_t
|
||||
vm_bounce_page_find __P((int count));
|
||||
static void vm_bounce_page_free __P((vm_offset_t pa, int count));
|
||||
|
||||
static volatile int kvasfreecnt;
|
||||
|
||||
caddr_t bouncememory;
|
||||
int bouncepages;
|
||||
static int bpwait;
|
||||
static vm_offset_t *bouncepa;
|
||||
static int bmwait, bmfreeing;
|
||||
|
||||
#define BITS_IN_UNSIGNED (8*sizeof(unsigned))
|
||||
static int bounceallocarraysize;
|
||||
static unsigned *bounceallocarray;
|
||||
static int bouncefree;
|
||||
|
||||
#if defined(PC98) && defined (EPSON_BOUNCEDMA)
|
||||
#define SIXTEENMEG (3840*4096) /* 15MB boundary */
|
||||
#else
|
||||
#define SIXTEENMEG (4096*4096)
|
||||
#endif
|
||||
#define MAXBKVA 1024
|
||||
int maxbkva = MAXBKVA*PAGE_SIZE;
|
||||
|
||||
/* special list that can be used at interrupt time for eventual kva free */
|
||||
static struct kvasfree {
|
||||
vm_offset_t addr;
|
||||
vm_offset_t size;
|
||||
} kvaf[MAXBKVA];
|
||||
|
||||
/*
|
||||
* get bounce buffer pages (count physically contiguous)
|
||||
* (only 1 inplemented now)
|
||||
*/
|
||||
static vm_offset_t
|
||||
vm_bounce_page_find(count)
|
||||
int count;
|
||||
{
|
||||
int bit;
|
||||
int s,i;
|
||||
|
||||
if (count != 1)
|
||||
panic("vm_bounce_page_find -- no support for > 1 page yet!!!");
|
||||
|
||||
s = splbio();
|
||||
retry:
|
||||
for (i = 0; i < bounceallocarraysize; i++) {
|
||||
if (bounceallocarray[i] != 0xffffffff) {
|
||||
bit = ffs(~bounceallocarray[i]);
|
||||
if (bit) {
|
||||
bounceallocarray[i] |= 1 << (bit - 1) ;
|
||||
bouncefree -= count;
|
||||
splx(s);
|
||||
return bouncepa[(i * BITS_IN_UNSIGNED + (bit - 1))];
|
||||
}
|
||||
}
|
||||
}
|
||||
bpwait = 1;
|
||||
tsleep((caddr_t) &bounceallocarray, PRIBIO, "bncwai", 0);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
static void
|
||||
vm_bounce_kva_free(addr, size, now)
|
||||
vm_offset_t addr;
|
||||
vm_offset_t size;
|
||||
int now;
|
||||
{
|
||||
int s = splbio();
|
||||
kvaf[kvasfreecnt].addr = addr;
|
||||
kvaf[kvasfreecnt].size = size;
|
||||
++kvasfreecnt;
|
||||
if( now) {
|
||||
/*
|
||||
* this will do wakeups
|
||||
*/
|
||||
vm_bounce_kva(0,0);
|
||||
} else {
|
||||
if (bmwait) {
|
||||
/*
|
||||
* if anyone is waiting on the bounce-map, then wakeup
|
||||
*/
|
||||
wakeup((caddr_t) io_map);
|
||||
bmwait = 0;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* free count bounce buffer pages
|
||||
*/
|
||||
static void
|
||||
vm_bounce_page_free(pa, count)
|
||||
vm_offset_t pa;
|
||||
int count;
|
||||
{
|
||||
int allocindex;
|
||||
int index;
|
||||
int bit;
|
||||
|
||||
if (count != 1)
|
||||
panic("vm_bounce_page_free -- no support for > 1 page yet!!!");
|
||||
|
||||
for(index=0;index<bouncepages;index++) {
|
||||
if( pa == bouncepa[index])
|
||||
break;
|
||||
}
|
||||
|
||||
if( index == bouncepages)
|
||||
panic("vm_bounce_page_free: invalid bounce buffer");
|
||||
|
||||
allocindex = index / BITS_IN_UNSIGNED;
|
||||
bit = index % BITS_IN_UNSIGNED;
|
||||
|
||||
bounceallocarray[allocindex] &= ~(1 << bit);
|
||||
|
||||
bouncefree += count;
|
||||
if (bpwait) {
|
||||
bpwait = 0;
|
||||
wakeup((caddr_t) &bounceallocarray);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate count bounce buffer kva pages
|
||||
*/
|
||||
static vm_offset_t
|
||||
vm_bounce_kva(size, waitok)
|
||||
int size;
|
||||
int waitok;
|
||||
{
|
||||
int i;
|
||||
vm_offset_t kva = 0;
|
||||
vm_offset_t off;
|
||||
int s = splbio();
|
||||
more:
|
||||
if (!bmfreeing && kvasfreecnt) {
|
||||
bmfreeing = 1;
|
||||
for (i = 0; i < kvasfreecnt; i++) {
|
||||
for(off=0;off<kvaf[i].size;off+=PAGE_SIZE) {
|
||||
pmap_kremove( kvaf[i].addr + off);
|
||||
}
|
||||
kmem_free_wakeup(io_map, kvaf[i].addr,
|
||||
kvaf[i].size);
|
||||
}
|
||||
kvasfreecnt = 0;
|
||||
bmfreeing = 0;
|
||||
if( bmwait) {
|
||||
bmwait = 0;
|
||||
wakeup( (caddr_t) io_map);
|
||||
}
|
||||
}
|
||||
|
||||
if( size == 0) {
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((kva = kmem_alloc_pageable(io_map, size)) == 0) {
|
||||
if( !waitok) {
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
bmwait = 1;
|
||||
tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0);
|
||||
goto more;
|
||||
}
|
||||
splx(s);
|
||||
return kva;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as vm_bounce_kva -- but really allocate (but takes pages as arg)
|
||||
*/
|
||||
vm_offset_t
|
||||
vm_bounce_kva_alloc(count)
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
vm_offset_t kva;
|
||||
vm_offset_t pa;
|
||||
if( bouncepages == 0) {
|
||||
kva = (vm_offset_t) malloc(count*PAGE_SIZE, M_TEMP, M_WAITOK);
|
||||
return kva;
|
||||
}
|
||||
kva = vm_bounce_kva(count*PAGE_SIZE, 1);
|
||||
for(i=0;i<count;i++) {
|
||||
pa = vm_bounce_page_find(1);
|
||||
pmap_kenter(kva + i * PAGE_SIZE, pa);
|
||||
}
|
||||
return kva;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as vm_bounce_kva_free -- but really free
|
||||
*/
|
||||
void
|
||||
vm_bounce_kva_alloc_free(kva, count)
|
||||
vm_offset_t kva;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
vm_offset_t pa;
|
||||
if( bouncepages == 0) {
|
||||
free((caddr_t) kva, M_TEMP);
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < count; i++) {
|
||||
pa = pmap_kextract(kva + i * PAGE_SIZE);
|
||||
vm_bounce_page_free(pa, 1);
|
||||
}
|
||||
vm_bounce_kva_free(kva, count*PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* do the things necessary to the struct buf to implement
|
||||
* bounce buffers... inserted before the disk sort
|
||||
*/
|
||||
void
|
||||
vm_bounce_alloc(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
int countvmpg;
|
||||
vm_offset_t vastart, vaend;
|
||||
vm_offset_t vapstart, vapend;
|
||||
vm_offset_t va, kva;
|
||||
vm_offset_t pa;
|
||||
int dobounceflag = 0;
|
||||
int i;
|
||||
|
||||
if (bouncepages == 0)
|
||||
return;
|
||||
|
||||
if (bp->b_flags & B_BOUNCE) {
|
||||
printf("vm_bounce_alloc: called recursively???\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bp->b_bufsize < bp->b_bcount) {
|
||||
printf(
|
||||
"vm_bounce_alloc: b_bufsize(0x%lx) < b_bcount(0x%lx) !!\n",
|
||||
bp->b_bufsize, bp->b_bcount);
|
||||
panic("vm_bounce_alloc");
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not really necessary
|
||||
* if( bp->b_bufsize != bp->b_bcount) {
|
||||
* printf("size: %d, count: %d\n", bp->b_bufsize, bp->b_bcount);
|
||||
* }
|
||||
*/
|
||||
|
||||
|
||||
vastart = (vm_offset_t) bp->b_data;
|
||||
vaend = (vm_offset_t) bp->b_data + bp->b_bufsize;
|
||||
|
||||
vapstart = trunc_page(vastart);
|
||||
vapend = round_page(vaend);
|
||||
countvmpg = (vapend - vapstart) / PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* if any page is above 16MB, then go into bounce-buffer mode
|
||||
*/
|
||||
va = vapstart;
|
||||
for (i = 0; i < countvmpg; i++) {
|
||||
pa = pmap_kextract(va);
|
||||
if (pa >= SIXTEENMEG)
|
||||
++dobounceflag;
|
||||
if( pa == 0)
|
||||
panic("vm_bounce_alloc: Unmapped page");
|
||||
va += PAGE_SIZE;
|
||||
}
|
||||
if (dobounceflag == 0)
|
||||
return;
|
||||
|
||||
if (bouncepages < dobounceflag)
|
||||
panic("Not enough bounce buffers!!!");
|
||||
|
||||
/*
|
||||
* allocate a replacement kva for b_addr
|
||||
*/
|
||||
kva = vm_bounce_kva(countvmpg*PAGE_SIZE, 1);
|
||||
#if 0
|
||||
printf("%s: vapstart: %x, vapend: %x, countvmpg: %d, kva: %x ",
|
||||
(bp->b_flags & B_READ) ? "read":"write",
|
||||
vapstart, vapend, countvmpg, kva);
|
||||
#endif
|
||||
va = vapstart;
|
||||
for (i = 0; i < countvmpg; i++) {
|
||||
pa = pmap_kextract(va);
|
||||
if (pa >= SIXTEENMEG) {
|
||||
/*
|
||||
* allocate a replacement page
|
||||
*/
|
||||
vm_offset_t bpa = vm_bounce_page_find(1);
|
||||
pmap_kenter(kva + (PAGE_SIZE * i), bpa);
|
||||
#if 0
|
||||
printf("r(%d): (%x,%x,%x) ", i, va, pa, bpa);
|
||||
#endif
|
||||
/*
|
||||
* if we are writing, the copy the data into the page
|
||||
*/
|
||||
if ((bp->b_flags & B_READ) == 0) {
|
||||
bcopy((caddr_t) va, (caddr_t) kva + (PAGE_SIZE * i), PAGE_SIZE);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* use original page
|
||||
*/
|
||||
pmap_kenter(kva + (PAGE_SIZE * i), pa);
|
||||
}
|
||||
va += PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* flag the buffer as being bounced
|
||||
*/
|
||||
bp->b_flags |= B_BOUNCE;
|
||||
/*
|
||||
* save the original buffer kva
|
||||
*/
|
||||
bp->b_savekva = bp->b_data;
|
||||
/*
|
||||
* put our new kva into the buffer (offset by original offset)
|
||||
*/
|
||||
bp->b_data = (caddr_t) (((vm_offset_t) kva) |
|
||||
((vm_offset_t) bp->b_savekva & PAGE_MASK));
|
||||
#if 0
|
||||
printf("b_savekva: %x, newva: %x\n", bp->b_savekva, bp->b_data);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* hook into biodone to free bounce buffer
|
||||
*/
|
||||
void
|
||||
vm_bounce_free(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
int i;
|
||||
vm_offset_t origkva, bouncekva, bouncekvaend;
|
||||
|
||||
/*
|
||||
* if this isn't a bounced buffer, then just return
|
||||
*/
|
||||
if ((bp->b_flags & B_BOUNCE) == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* This check is not necessary
|
||||
* if (bp->b_bufsize != bp->b_bcount) {
|
||||
* printf("vm_bounce_free: b_bufsize=%d, b_bcount=%d\n",
|
||||
* bp->b_bufsize, bp->b_bcount);
|
||||
* }
|
||||
*/
|
||||
|
||||
origkva = (vm_offset_t) bp->b_savekva;
|
||||
bouncekva = (vm_offset_t) bp->b_data;
|
||||
/*
|
||||
printf("free: %d ", bp->b_bufsize);
|
||||
*/
|
||||
|
||||
/*
|
||||
* check every page in the kva space for b_addr
|
||||
*/
|
||||
for (i = 0; i < bp->b_bufsize; ) {
|
||||
vm_offset_t mybouncepa;
|
||||
vm_offset_t copycount;
|
||||
|
||||
copycount = round_page(bouncekva + 1) - bouncekva;
|
||||
mybouncepa = pmap_kextract(trunc_page(bouncekva));
|
||||
|
||||
/*
|
||||
* if this is a bounced pa, then process as one
|
||||
*/
|
||||
if ( mybouncepa != pmap_kextract( trunc_page( origkva))) {
|
||||
vm_offset_t tocopy = copycount;
|
||||
if (i + tocopy > bp->b_bufsize)
|
||||
tocopy = bp->b_bufsize - i;
|
||||
/*
|
||||
* if this is a read, then copy from bounce buffer into original buffer
|
||||
*/
|
||||
if (bp->b_flags & B_READ)
|
||||
bcopy((caddr_t) bouncekva, (caddr_t) origkva, tocopy);
|
||||
/*
|
||||
* free the bounce allocation
|
||||
*/
|
||||
|
||||
/*
|
||||
printf("(kva: %x, pa: %x)", bouncekva, mybouncepa);
|
||||
*/
|
||||
vm_bounce_page_free(mybouncepa, 1);
|
||||
}
|
||||
|
||||
origkva += copycount;
|
||||
bouncekva += copycount;
|
||||
i += copycount;
|
||||
}
|
||||
|
||||
/*
|
||||
printf("\n");
|
||||
*/
|
||||
/*
|
||||
* add the old kva into the "to free" list
|
||||
*/
|
||||
|
||||
bouncekva= trunc_page((vm_offset_t) bp->b_data);
|
||||
bouncekvaend= round_page((vm_offset_t)bp->b_data + bp->b_bufsize);
|
||||
|
||||
/*
|
||||
printf("freeva: %d\n", (bouncekvaend - bouncekva) / PAGE_SIZE);
|
||||
*/
|
||||
vm_bounce_kva_free( bouncekva, (bouncekvaend - bouncekva), 0);
|
||||
bp->b_data = bp->b_savekva;
|
||||
bp->b_savekva = 0;
|
||||
bp->b_flags &= ~B_BOUNCE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init the bounce buffer system
|
||||
*/
|
||||
void
|
||||
vm_bounce_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
kvasfreecnt = 0;
|
||||
|
||||
if (bouncepages == 0)
|
||||
return;
|
||||
|
||||
bounceallocarraysize = (bouncepages + BITS_IN_UNSIGNED - 1) / BITS_IN_UNSIGNED;
|
||||
bounceallocarray = malloc(bounceallocarraysize * sizeof(unsigned), M_TEMP, M_NOWAIT);
|
||||
|
||||
if (!bounceallocarray)
|
||||
panic("Cannot allocate bounce resource array");
|
||||
|
||||
bouncepa = malloc(bouncepages * sizeof(vm_offset_t), M_TEMP, M_NOWAIT);
|
||||
if (!bouncepa)
|
||||
panic("Cannot allocate physical memory array");
|
||||
|
||||
for(i=0;i<bounceallocarraysize;i++) {
|
||||
bounceallocarray[i] = 0xffffffff;
|
||||
}
|
||||
|
||||
for(i=0;i<bouncepages;i++) {
|
||||
vm_offset_t pa;
|
||||
if( (pa = pmap_kextract((vm_offset_t) bouncememory + i * PAGE_SIZE)) >= SIXTEENMEG)
|
||||
panic("bounce memory out of range");
|
||||
if( pa == 0)
|
||||
panic("bounce memory not resident");
|
||||
bouncepa[i] = pa;
|
||||
bounceallocarray[i/(8*sizeof(int))] &= ~(1<<(i%(8*sizeof(int))));
|
||||
}
|
||||
bouncefree = bouncepages;
|
||||
|
||||
}
|
||||
#endif /* BOUNCE_BUFFERS */
|
||||
|
||||
/*
|
||||
* quick version of vm_fault
|
||||
*/
|
||||
void
|
||||
vm_fault_quick(v, prot)
|
||||
caddr_t v;
|
||||
int prot;
|
||||
{
|
||||
if (prot & VM_PROT_WRITE)
|
||||
subyte(v, fubyte(v));
|
||||
else
|
||||
fubyte(v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish a fork operation, with process p2 nearly set up.
|
||||
* Copy and update the kernel stack and pcb, making the child
|
||||
* ready to run, and marking it so that it can return differently
|
||||
* than the parent. Returns 1 in the child process, 0 in the parent.
|
||||
* We currently double-map the user area so that the stack is at the same
|
||||
* address in each process; in the future we will probably relocate
|
||||
* the frame pointers on the stack after copying.
|
||||
*/
|
||||
int
|
||||
cpu_fork(p1, p2)
|
||||
register struct proc *p1, *p2;
|
||||
{
|
||||
struct pcb *pcb2 = &p2->p_addr->u_pcb;
|
||||
int sp, offset;
|
||||
volatile int retval;
|
||||
|
||||
/*
|
||||
* Copy pcb and stack from proc p1 to p2.
|
||||
* We do this as cheaply as possible, copying only the active
|
||||
* part of the stack. The stack and pcb need to agree;
|
||||
* this is tricky, as the final pcb is constructed by savectx,
|
||||
* but its frame isn't yet on the stack when the stack is copied.
|
||||
* This should be done differently, with a single call
|
||||
* that copies and updates the pcb+stack,
|
||||
* replacing the bcopy and savectx.
|
||||
*/
|
||||
|
||||
__asm __volatile("movl %%esp,%0" : "=r" (sp));
|
||||
offset = sp - (int)kstack;
|
||||
|
||||
retval = 1; /* return 1 in child */
|
||||
bcopy((caddr_t)kstack + offset, (caddr_t)p2->p_addr + offset,
|
||||
(unsigned) ctob(UPAGES) - offset);
|
||||
p2->p_md.md_regs = p1->p_md.md_regs;
|
||||
|
||||
*pcb2 = p1->p_addr->u_pcb;
|
||||
pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
|
||||
|
||||
retval = 0; /* return 0 in parent */
|
||||
savectx(pcb2);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_exit(p)
|
||||
register struct proc *p;
|
||||
{
|
||||
#ifdef USER_LDT
|
||||
struct pcb *pcb;
|
||||
#endif
|
||||
|
||||
#if NNPX > 0
|
||||
npxexit(p);
|
||||
#endif /* NNPX */
|
||||
#ifdef USER_LDT
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
if (pcb->pcb_ldt != 0) {
|
||||
if (pcb == curpcb)
|
||||
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
|
||||
pcb->pcb_ldt_len * sizeof(union descriptor));
|
||||
pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
|
||||
}
|
||||
#endif
|
||||
cnt.v_swtch++;
|
||||
cpu_switch(p);
|
||||
panic("cpu_exit");
|
||||
}
|
||||
|
||||
void
|
||||
cpu_wait(p)
|
||||
struct proc *p;
|
||||
{
|
||||
/* drop per-process resources */
|
||||
pmap_dispose_proc(p);
|
||||
vmspace_free(p->p_vmspace);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the machine specific header information at the start of a core dump.
|
||||
*/
|
||||
int
|
||||
cpu_coredump(p, vp, cred)
|
||||
struct proc *p;
|
||||
struct vnode *vp;
|
||||
struct ucred *cred;
|
||||
{
|
||||
|
||||
return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES),
|
||||
(off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL,
|
||||
p));
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
static void
|
||||
setredzone(pte, vaddr)
|
||||
u_short *pte;
|
||||
caddr_t vaddr;
|
||||
{
|
||||
/* eventually do this by setting up an expand-down stack segment
|
||||
for ss0: selector, allowing stack access down to top of u.
|
||||
this means though that protection violations need to be handled
|
||||
thru a double fault exception that must do an integral task
|
||||
switch to a known good context, within which a dump can be
|
||||
taken. a sensible scheme might be to save the initial context
|
||||
used by sched (that has physical memory mapped 1:1 at bottom)
|
||||
and take the dump while still in mapped mode */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert kernel VA to physical address
|
||||
*/
|
||||
u_long
|
||||
kvtop(void *addr)
|
||||
{
|
||||
vm_offset_t va;
|
||||
|
||||
va = pmap_kextract((vm_offset_t)addr);
|
||||
if (va == 0)
|
||||
panic("kvtop: zero page frame");
|
||||
return((int)va);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map an IO request into kernel virtual address space.
|
||||
*
|
||||
* All requests are (re)mapped into kernel VA space.
|
||||
* Notice that we use b_bufsize for the size of the buffer
|
||||
* to be mapped. b_bcount might be modified by the driver.
|
||||
*/
|
||||
void
|
||||
vmapbuf(bp)
|
||||
register struct buf *bp;
|
||||
{
|
||||
register caddr_t addr, v, kva;
|
||||
vm_offset_t pa;
|
||||
|
||||
if ((bp->b_flags & B_PHYS) == 0)
|
||||
panic("vmapbuf");
|
||||
|
||||
for (v = bp->b_saveaddr, addr = (caddr_t)trunc_page(bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE, v += PAGE_SIZE) {
|
||||
/*
|
||||
* Do the vm_fault if needed; do the copy-on-write thing
|
||||
* when reading stuff off device into memory.
|
||||
*/
|
||||
vm_fault_quick(addr,
|
||||
(bp->b_flags&B_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
|
||||
pa = trunc_page(pmap_kextract((vm_offset_t) addr));
|
||||
if (pa == 0)
|
||||
panic("vmapbuf: page not present");
|
||||
vm_page_hold(PHYS_TO_VM_PAGE(pa));
|
||||
pmap_kenter((vm_offset_t) v, pa);
|
||||
}
|
||||
|
||||
kva = bp->b_saveaddr;
|
||||
bp->b_saveaddr = bp->b_data;
|
||||
bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the io map PTEs associated with this IO operation.
|
||||
* We also invalidate the TLB entries and restore the original b_addr.
|
||||
*/
|
||||
void
|
||||
vunmapbuf(bp)
|
||||
register struct buf *bp;
|
||||
{
|
||||
register caddr_t addr;
|
||||
vm_offset_t pa;
|
||||
|
||||
if ((bp->b_flags & B_PHYS) == 0)
|
||||
panic("vunmapbuf");
|
||||
|
||||
for (addr = (caddr_t)trunc_page(bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE) {
|
||||
pa = trunc_page(pmap_kextract((vm_offset_t) addr));
|
||||
pmap_kremove((vm_offset_t) addr);
|
||||
vm_page_unhold(PHYS_TO_VM_PAGE(pa));
|
||||
}
|
||||
|
||||
bp->b_data = bp->b_saveaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force reset the processor by invalidating the entire address space!
|
||||
*/
|
||||
void
|
||||
cpu_reset() {
|
||||
#ifdef PC98
|
||||
asm(" cli ");
|
||||
outb(0x37, 0x0f); /* SHUT 0 = 0 */
|
||||
outb(0x37, 0x0b); /* SHUT 1 = 0 */
|
||||
if ((pc98_machine_type & M_EPSON_PC98)
|
||||
&& (epson_machine_id == 0x20 /*note A*/)) {
|
||||
epson_outb(0xc17, epson_inb(0xc17) | 0x40);
|
||||
/* reset port for NOTE_A */
|
||||
}
|
||||
outb(0xf0, 0x00); /* reset port */
|
||||
#else /* IBM-PC */
|
||||
|
||||
/*
|
||||
* Attempt to do a CPU reset via the keyboard controller,
|
||||
* do not turn of the GateA20, as any machine that fails
|
||||
* to do the reset here would then end up in no man's land.
|
||||
*/
|
||||
|
||||
#ifndef BROKEN_KEYBOARD_RESET
|
||||
outb(IO_KBD + 4, 0xFE);
|
||||
DELAY(500000); /* wait 0.5 sec to see if that did it */
|
||||
printf("Keyboard reset did not work, attempting CPU shutdown\n");
|
||||
DELAY(1000000); /* wait 1 sec for printf to complete */
|
||||
#endif
|
||||
|
||||
/* force a shutdown by unmapping entire address space ! */
|
||||
bzero((caddr_t) PTD, PAGE_SIZE);
|
||||
|
||||
/* "good night, sweet prince .... <THUNK!>" */
|
||||
invltlb();
|
||||
#endif
|
||||
/* NOTREACHED */
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Grow the user stack to allow for 'sp'. This version grows the stack in
|
||||
* chunks of SGROWSIZ.
|
||||
*/
|
||||
int
|
||||
grow(p, sp)
|
||||
struct proc *p;
|
||||
u_int sp;
|
||||
{
|
||||
unsigned int nss;
|
||||
caddr_t v;
|
||||
struct vmspace *vm = p->p_vmspace;
|
||||
|
||||
if ((caddr_t)sp <= vm->vm_maxsaddr || (unsigned)sp >= (unsigned)USRSTACK)
|
||||
return (1);
|
||||
|
||||
nss = roundup(USRSTACK - (unsigned)sp, PAGE_SIZE);
|
||||
|
||||
if (nss > p->p_rlimit[RLIMIT_STACK].rlim_cur)
|
||||
return (0);
|
||||
|
||||
if (vm->vm_ssize && roundup(vm->vm_ssize << PAGE_SHIFT,
|
||||
SGROWSIZ) < nss) {
|
||||
int grow_amount;
|
||||
/*
|
||||
* If necessary, grow the VM that the stack occupies
|
||||
* to allow for the rlimit. This allows us to not have
|
||||
* to allocate all of the VM up-front in execve (which
|
||||
* is expensive).
|
||||
* Grow the VM by the amount requested rounded up to
|
||||
* the nearest SGROWSIZ to provide for some hysteresis.
|
||||
*/
|
||||
grow_amount = roundup((nss - (vm->vm_ssize << PAGE_SHIFT)), SGROWSIZ);
|
||||
v = (char *)USRSTACK - roundup(vm->vm_ssize << PAGE_SHIFT,
|
||||
SGROWSIZ) - grow_amount;
|
||||
/*
|
||||
* If there isn't enough room to extend by SGROWSIZ, then
|
||||
* just extend to the maximum size
|
||||
*/
|
||||
if (v < vm->vm_maxsaddr) {
|
||||
v = vm->vm_maxsaddr;
|
||||
grow_amount = MAXSSIZ - (vm->vm_ssize << PAGE_SHIFT);
|
||||
}
|
||||
if ((grow_amount == 0) || (vm_map_find(&vm->vm_map, NULL, 0, (vm_offset_t *)&v,
|
||||
grow_amount, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != KERN_SUCCESS)) {
|
||||
return (0);
|
||||
}
|
||||
vm->vm_ssize += grow_amount >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* prototype routine to implement the pre-zeroed page mechanism
|
||||
* this routine is called from the idle loop.
|
||||
*/
|
||||
int
|
||||
vm_page_zero_idle() {
|
||||
vm_page_t m;
|
||||
static int free_rover = 0;
|
||||
if ((cnt.v_free_count > cnt.v_interrupt_free_min) &&
|
||||
(m = vm_page_list_find(PQ_FREE, free_rover))) {
|
||||
--(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
|
||||
enable_intr();
|
||||
pmap_zero_page(VM_PAGE_TO_PHYS(m));
|
||||
disable_intr();
|
||||
m->queue = PQ_ZERO + m->pc;
|
||||
++(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
|
||||
free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
|
||||
++vm_page_zero_count;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,18 @@
|
||||
/*
|
||||
* Disk Controller ATAPI register definitions.
|
||||
*/
|
||||
#ifdef PC98
|
||||
#define AR_DATA 0x0 /* RW - data register (16 bits) */
|
||||
#define AR_ERROR 0x2 /* R - error register */
|
||||
#define AR_FEATURES 0x2 /* W - features */
|
||||
#define AR_IREASON 0x4 /* RW - interrupt reason */
|
||||
#define AR_TAG 0x6 /* - reserved for SAM TAG byte */
|
||||
#define AR_CNTLO 0x8 /* RW - byte count, low byte */
|
||||
#define AR_CNTHI 0xa /* RW - byte count, high byte */
|
||||
#define AR_DRIVE 0xc /* RW - drive select */
|
||||
#define AR_COMMAND 0xe /* W - command register */
|
||||
#define AR_STATUS 0xe /* R - immediate status */
|
||||
#else
|
||||
#define AR_DATA 0x0 /* RW - data register (16 bits) */
|
||||
#define AR_ERROR 0x1 /* R - error register */
|
||||
#define AR_FEATURES 0x1 /* W - features */
|
||||
@ -27,6 +39,7 @@
|
||||
#define AR_DRIVE 0x6 /* RW - drive select */
|
||||
#define AR_COMMAND 0x7 /* W - command register */
|
||||
#define AR_STATUS 0x7 /* R - immediate status */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Status register bits
|
||||
|
@ -34,7 +34,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
|
||||
* $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routines to handle clock hardware.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -48,10 +52,6 @@
|
||||
* modified for PC98 by Kakefuda
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
|
||||
#include "opt_clock.h"
|
||||
#include "opt_cpu.h"
|
||||
|
||||
@ -72,13 +72,12 @@
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
/*
|
||||
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
|
||||
@ -109,52 +108,49 @@
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
u_int idelayed;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_bias;
|
||||
u_int i586_ctr_comultiplier;
|
||||
u_int i586_ctr_freq;
|
||||
u_int i586_ctr_multiplier;
|
||||
long long i586_last_tick;
|
||||
unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
#ifdef PC98
|
||||
#ifndef AUTO_CLOCK
|
||||
#ifndef PC98_8M
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#else /* !PC98_8M */
|
||||
static u_int timer_freq = 1996800;
|
||||
u_int timer_freq = 1996800;
|
||||
#endif /* PC98_8M */
|
||||
#else /* AUTO_CLOCK */
|
||||
static u_int timer_freq = 2457600;
|
||||
u_int timer_freq = 2457600;
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
static u_int timer_freq = 1193182;
|
||||
u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
@ -171,7 +167,7 @@ static u_char timer0_state;
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
@ -437,7 +433,7 @@ getit(void)
|
||||
disable_intr();
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
@ -625,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -782,7 +778,7 @@ startrtclock()
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -802,7 +798,7 @@ startrtclock()
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_freq != 0) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
}
|
||||
@ -1114,10 +1110,8 @@ cpu_initclocks()
|
||||
/*
|
||||
* Finish setting up anti-jitter measures.
|
||||
*/
|
||||
if (i586_ctr_freq != 0) {
|
||||
i586_last_tick = rdtsc();
|
||||
i586_ctr_bias = i586_last_tick;
|
||||
}
|
||||
if (i586_ctr_freq != 0)
|
||||
i586_ctr_bias = rdtsc();
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
|
@ -1,357 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1989, 1990 William F. Jolitz.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @(#)icu.s 7.2 (Berkeley) 5/21/91
|
||||
*
|
||||
* $Id: icu.s,v 1.25 1996/05/31 01:08:07 peter Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* AT/386
|
||||
* Vector interrupt control section
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX this file should be named ipl.s. All spls are now soft and the
|
||||
* only thing related to the hardware icu is that the h/w interrupt
|
||||
* numbers are used without translation in the masks.
|
||||
*/
|
||||
|
||||
.data
|
||||
.globl _cpl
|
||||
_cpl: .long HWI_MASK | SWI_MASK /* current priority (all off) */
|
||||
.globl _imen
|
||||
_imen: .long HWI_MASK /* interrupt mask enable (all h/w off) */
|
||||
.globl _tty_imask
|
||||
_tty_imask: .long 0
|
||||
.globl _bio_imask
|
||||
_bio_imask: .long 0
|
||||
.globl _net_imask
|
||||
_net_imask: .long 0
|
||||
.globl _ipending
|
||||
_ipending: .long 0
|
||||
.globl _netisr
|
||||
_netisr: .long 0 /* set with bits for which queue to service */
|
||||
.globl _netisrs
|
||||
_netisrs:
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
.long dummynetisr, dummynetisr, dummynetisr, dummynetisr
|
||||
vec:
|
||||
.long vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7
|
||||
.long vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* Handle return from interrupts, traps and syscalls.
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
_doreti:
|
||||
FAKE_MCOUNT(_bintr) /* init "from" _bintr -> _doreti */
|
||||
addl $4,%esp /* discard unit number */
|
||||
popl %eax /* cpl to restore */
|
||||
doreti_next:
|
||||
/*
|
||||
* Check for pending HWIs and SWIs atomically with restoring cpl
|
||||
* and exiting. The check has to be atomic with exiting to stop
|
||||
* (ipending & ~cpl) changing from zero to nonzero while we're
|
||||
* looking at it (this wouldn't be fatal but it would increase
|
||||
* interrupt latency). Restoring cpl has to be atomic with exiting
|
||||
* so that the stack cannot pile up (the nesting level of interrupt
|
||||
* handlers is limited by the number of bits in cpl).
|
||||
*/
|
||||
movl %eax,%ecx
|
||||
notl %ecx
|
||||
cli
|
||||
andl _ipending,%ecx
|
||||
jne doreti_unpend
|
||||
doreti_exit:
|
||||
movl %eax,_cpl
|
||||
decb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
.globl doreti_popl_es
|
||||
doreti_popl_es:
|
||||
popl %es
|
||||
.globl doreti_popl_ds
|
||||
doreti_popl_ds:
|
||||
popl %ds
|
||||
popal
|
||||
addl $8,%esp
|
||||
.globl doreti_iret
|
||||
doreti_iret:
|
||||
iret
|
||||
|
||||
ALIGN_TEXT
|
||||
.globl doreti_iret_fault
|
||||
doreti_iret_fault:
|
||||
subl $8,%esp
|
||||
pushal
|
||||
pushl %ds
|
||||
.globl doreti_popl_ds_fault
|
||||
doreti_popl_ds_fault:
|
||||
pushl %es
|
||||
.globl doreti_popl_es_fault
|
||||
doreti_popl_es_fault:
|
||||
movl $0,4+4+32+4(%esp) /* XXX should be the error code */
|
||||
movl $T_PROTFLT,4+4+32+0(%esp)
|
||||
jmp alltraps_with_regs_pushed
|
||||
|
||||
ALIGN_TEXT
|
||||
doreti_unpend:
|
||||
/*
|
||||
* Enabling interrupts is safe because we haven't restored cpl yet.
|
||||
* The locking from the "btrl" test is probably no longer necessary.
|
||||
* We won't miss any new pending interrupts because we will check
|
||||
* for them again.
|
||||
*/
|
||||
sti
|
||||
bsfl %ecx,%ecx /* slow, but not worth optimizing */
|
||||
btrl %ecx,_ipending
|
||||
jnc doreti_next /* some intr cleared memory copy */
|
||||
movl ihandlers(,%ecx,4),%edx
|
||||
testl %edx,%edx
|
||||
je doreti_next /* "can't happen" */
|
||||
cmpl $NHWI,%ecx
|
||||
jae doreti_swi
|
||||
cli
|
||||
movl %eax,_cpl
|
||||
MEXITCOUNT
|
||||
jmp %edx
|
||||
|
||||
ALIGN_TEXT
|
||||
doreti_swi:
|
||||
pushl %eax
|
||||
/*
|
||||
* The SWI_AST handler has to run at cpl = SWI_AST_MASK and the
|
||||
* SWI_CLOCK handler at cpl = SWI_CLOCK_MASK, so we have to restore
|
||||
* all the h/w bits in cpl now and have to worry about stack growth.
|
||||
* The worst case is currently (30 Jan 1994) 2 SWI handlers nested
|
||||
* in dying interrupt frames and about 12 HWIs nested in active
|
||||
* interrupt frames. There are only 4 different SWIs and the HWI
|
||||
* and SWI masks limit the nesting further.
|
||||
*/
|
||||
orl imasks(,%ecx,4),%eax
|
||||
movl %eax,_cpl
|
||||
call %edx
|
||||
popl %eax
|
||||
jmp doreti_next
|
||||
|
||||
ALIGN_TEXT
|
||||
swi_ast:
|
||||
addl $8,%esp /* discard raddr & cpl to get trap frame */
|
||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
||||
je swi_ast_phantom
|
||||
movl $T_ASTFLT,(2+8+0)*4(%esp)
|
||||
call _trap
|
||||
subl %eax,%eax /* recover cpl */
|
||||
jmp doreti_next
|
||||
|
||||
ALIGN_TEXT
|
||||
swi_ast_phantom:
|
||||
/*
|
||||
* These happen when there is an interrupt in a trap handler before
|
||||
* ASTs can be masked or in an lcall handler before they can be
|
||||
* masked or after they are unmasked. They could be avoided for
|
||||
* trap entries by using interrupt gates, and for lcall exits by
|
||||
* using by using cli, but they are unavoidable for lcall entries.
|
||||
*/
|
||||
cli
|
||||
orl $SWI_AST_PENDING,_ipending
|
||||
subl %eax,%eax
|
||||
jmp doreti_exit /* SWI_AST is highest so we must be done */
|
||||
|
||||
/*
|
||||
* Interrupt priority mechanism
|
||||
* -- soft splXX masks with group mechanism (cpl)
|
||||
* -- h/w masks for currently active or unused interrupts (imen)
|
||||
* -- ipending = active interrupts currently masked by cpl
|
||||
*/
|
||||
|
||||
ENTRY(splz)
|
||||
/*
|
||||
* The caller has restored cpl and checked that (ipending & ~cpl)
|
||||
* is nonzero. We have to repeat the check since if there is an
|
||||
* interrupt while we're looking, _doreti processing for the
|
||||
* interrupt will handle all the unmasked pending interrupts
|
||||
* because we restored early. We're repeating the calculation
|
||||
* of (ipending & ~cpl) anyway so that the caller doesn't have
|
||||
* to pass it, so this only costs one "jne". "bsfl %ecx,%ecx"
|
||||
* is undefined when %ecx is 0 so we can't rely on the secondary
|
||||
* btrl tests.
|
||||
*/
|
||||
movl _cpl,%eax
|
||||
splz_next:
|
||||
/*
|
||||
* We don't need any locking here. (ipending & ~cpl) cannot grow
|
||||
* while we're looking at it - any interrupt will shrink it to 0.
|
||||
*/
|
||||
movl %eax,%ecx
|
||||
notl %ecx
|
||||
andl _ipending,%ecx
|
||||
jne splz_unpend
|
||||
ret
|
||||
|
||||
ALIGN_TEXT
|
||||
splz_unpend:
|
||||
bsfl %ecx,%ecx
|
||||
btrl %ecx,_ipending
|
||||
jnc splz_next
|
||||
movl ihandlers(,%ecx,4),%edx
|
||||
testl %edx,%edx
|
||||
je splz_next /* "can't happen" */
|
||||
cmpl $NHWI,%ecx
|
||||
jae splz_swi
|
||||
/*
|
||||
* We would prefer to call the intr handler directly here but that
|
||||
* doesn't work for badly behaved handlers that want the interrupt
|
||||
* frame. Also, there's a problem determining the unit number.
|
||||
* We should change the interface so that the unit number is not
|
||||
* determined at config time.
|
||||
*/
|
||||
jmp *vec(,%ecx,4)
|
||||
|
||||
ALIGN_TEXT
|
||||
splz_swi:
|
||||
cmpl $SWI_AST,%ecx
|
||||
je splz_next /* "can't happen" */
|
||||
pushl %eax
|
||||
orl imasks(,%ecx,4),%eax
|
||||
movl %eax,_cpl
|
||||
call %edx
|
||||
popl %eax
|
||||
movl %eax,_cpl
|
||||
jmp splz_next
|
||||
|
||||
/*
|
||||
* Fake clock interrupt(s) so that they appear to come from our caller instead
|
||||
* of from here, so that system profiling works.
|
||||
* XXX do this more generally (for all vectors; look up the C entry point).
|
||||
* XXX frame bogusness stops us from just jumping to the C entry point.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
vec0:
|
||||
popl %eax /* return address */
|
||||
pushfl
|
||||
#define KCSEL 8
|
||||
pushl $KCSEL
|
||||
pushl %eax
|
||||
cli
|
||||
MEXITCOUNT
|
||||
jmp _Xintr0 /* XXX might need _Xfastintr0 */
|
||||
|
||||
#ifndef PC98
|
||||
ALIGN_TEXT
|
||||
vec8:
|
||||
popl %eax
|
||||
pushfl
|
||||
pushl $KCSEL
|
||||
pushl %eax
|
||||
cli
|
||||
MEXITCOUNT
|
||||
jmp _Xintr8 /* XXX might need _Xfastintr8 */
|
||||
#endif
|
||||
|
||||
#define BUILD_VEC(irq_num) \
|
||||
ALIGN_TEXT ; \
|
||||
__CONCAT(vec,irq_num): ; \
|
||||
int $ICU_OFFSET + (irq_num) ; \
|
||||
ret
|
||||
|
||||
BUILD_VEC(1)
|
||||
BUILD_VEC(2)
|
||||
BUILD_VEC(3)
|
||||
BUILD_VEC(4)
|
||||
BUILD_VEC(5)
|
||||
BUILD_VEC(6)
|
||||
BUILD_VEC(7)
|
||||
#ifdef PC98
|
||||
BUILD_VEC(8)
|
||||
#endif
|
||||
BUILD_VEC(9)
|
||||
BUILD_VEC(10)
|
||||
BUILD_VEC(11)
|
||||
BUILD_VEC(12)
|
||||
BUILD_VEC(13)
|
||||
BUILD_VEC(14)
|
||||
BUILD_VEC(15)
|
||||
|
||||
ALIGN_TEXT
|
||||
swi_net:
|
||||
MCOUNT
|
||||
bsfl _netisr,%eax
|
||||
je swi_net_done
|
||||
swi_net_more:
|
||||
btrl %eax,_netisr
|
||||
jnc swi_net_next
|
||||
call *_netisrs(,%eax,4)
|
||||
swi_net_next:
|
||||
bsfl _netisr,%eax
|
||||
jne swi_net_more
|
||||
swi_net_done:
|
||||
ret
|
||||
|
||||
ALIGN_TEXT
|
||||
dummynetisr:
|
||||
MCOUNT
|
||||
ret
|
||||
|
||||
/*
|
||||
* XXX there should be a registration function to put the handler for the
|
||||
* attached driver directly in ihandlers. Then this function will go away.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
swi_tty:
|
||||
MCOUNT
|
||||
#include "cy.h"
|
||||
#if NCY > 0
|
||||
call _cypoll
|
||||
#endif
|
||||
#include "rc.h"
|
||||
#if NRC > 0
|
||||
call _rcpoll
|
||||
#endif
|
||||
#include "sio.h"
|
||||
#if NSIO > 0
|
||||
jmp _siopoll
|
||||
#else
|
||||
ret
|
||||
#endif
|
@ -24,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ed.c,v 1.9 1996/10/23 07:25:17 asami Exp $
|
||||
* $Id: if_ed.c,v 1.10 1996/10/29 08:36:20 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -106,7 +106,17 @@
|
||||
#include <i386/isa/if_edreg.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/if_ed98.h>
|
||||
/* register offsets */
|
||||
struct pc98_edregister {
|
||||
u_int *port;
|
||||
u_int ioskip;
|
||||
u_int nic_offset;
|
||||
u_int asic_offset;
|
||||
u_int data;
|
||||
u_int reset;
|
||||
u_int pc_misc;
|
||||
u_int pc_reset;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -160,12 +170,16 @@ struct ed_softc {
|
||||
u_char next_packet; /* pointer to next unread RX packet */
|
||||
struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */
|
||||
#ifdef PC98
|
||||
int unit;
|
||||
struct pc98_edregister edreg; /* I/O port register offset info */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ed_softc ed_softc[NED];
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/if_ed98.h>
|
||||
#endif
|
||||
|
||||
static int ed_attach __P((struct ed_softc *, int, int));
|
||||
static int ed_attach_isa __P((struct isa_device *));
|
||||
|
||||
@ -421,10 +435,6 @@ ed_probe(isa_dev)
|
||||
{
|
||||
int nports;
|
||||
|
||||
#ifdef PC98
|
||||
ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
|
||||
#endif
|
||||
|
||||
#if NCRD > 0
|
||||
/*
|
||||
* If PC-Card probe required, then register driver with
|
||||
@ -443,7 +453,7 @@ ed_probe(isa_dev)
|
||||
if ((ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LPC)) {
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LPC);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_LPC);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -454,7 +464,7 @@ ed_probe(isa_dev)
|
||||
* Allied Telesis CenterCom LA-98-T
|
||||
*/
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_GENERIC;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_GENERIC);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_GENERIC);
|
||||
|
||||
if (ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) {
|
||||
#endif
|
||||
@ -478,7 +488,7 @@ ed_probe(isa_dev)
|
||||
if ((ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_SIC)) {
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_SIC);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_SIC);
|
||||
nports = ed_probe_SIC98(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -492,7 +502,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_BDN)) {
|
||||
/* LD-BDN */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_BDN);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_BDN);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -506,7 +516,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LGY)) {
|
||||
/* LGY-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LGY);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_LGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -520,7 +530,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_ICM)) {
|
||||
/* ICM */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_ICM);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_ICM);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -534,7 +544,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_EGY)) {
|
||||
/* EGY-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_EGY);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_EGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -547,7 +557,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LA98)) {
|
||||
/* LA-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LA98;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LA98);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_LA98);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -560,7 +570,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_108)) {
|
||||
/* PC-9801-108 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_108;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_108);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_108);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -573,7 +583,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_CNET98EL)) {
|
||||
/* C-NET(98)E/L */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_CNET98EL;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_CNET98EL);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_CNET98EL);
|
||||
nports = ed_probe_CNET98EL(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -586,7 +596,7 @@ ed_probe(isa_dev)
|
||||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_CNET98)) {
|
||||
/* C-NET(98) */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_CNET98;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_CNET98);
|
||||
pc98_set_register(isa_dev, ED_TYPE98_CNET98);
|
||||
nports = ed_probe_CNET98(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -627,10 +637,6 @@ static int
|
||||
ed_probe_generic8390(sc)
|
||||
struct ed_softc *sc;
|
||||
{
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
if (sc->type == ED_TYPE98_LPC) {
|
||||
if ((inb(sc->nic_addr + ED_P0_CR) &
|
||||
@ -1036,9 +1042,6 @@ ed_probe_3Com(isa_dev)
|
||||
int i;
|
||||
u_int memsize;
|
||||
u_char isa16bit;
|
||||
#ifdef PC98
|
||||
int unit = isa_dev->id_unit;
|
||||
#endif
|
||||
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
|
||||
sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
|
||||
@ -1359,7 +1362,6 @@ ed_probe_Novell_generic(sc, port, unit, flags)
|
||||
if (sc->type == ED_TYPE98_LPC)
|
||||
LPCT_1d0_OFF();
|
||||
#endif
|
||||
|
||||
DELAY(5000);
|
||||
|
||||
/*
|
||||
@ -1592,7 +1594,7 @@ ed_probe_Novell(isa_dev)
|
||||
}
|
||||
|
||||
#if NCRD > 0
|
||||
|
||||
|
||||
/*
|
||||
* Probe framework for pccards. Replicates the standard framework,
|
||||
* minus the pccard driver registration and ignores the ether address
|
||||
@ -1653,9 +1655,7 @@ ed_probe_HP_pclanp(isa_dev)
|
||||
u_char irq; /* board configured IRQ */
|
||||
char test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */
|
||||
char test_buffer[ED_HPP_TEST_SIZE]; /* probing card */
|
||||
#ifdef PC98
|
||||
int unit = isa_dev->id_unit;
|
||||
#endif
|
||||
|
||||
|
||||
/* Fill in basic information */
|
||||
sc->asic_addr = isa_dev->id_iobase + ED_HPP_ASIC_OFFSET;
|
||||
@ -2503,9 +2503,6 @@ ed_stop(sc)
|
||||
struct ed_softc *sc;
|
||||
{
|
||||
int n = 5000;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
@ -2550,9 +2547,6 @@ ed_init(xsc)
|
||||
struct ed_softc *sc = xsc;
|
||||
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||
int i, s;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
@ -2655,7 +2649,7 @@ ed_init(xsc)
|
||||
*/
|
||||
#ifdef PC98
|
||||
for (i = 0; i < ETHER_ADDR_LEN; ++i)
|
||||
outb(sc->nic_addr + ED_P1_PAR0 + i * pc98_io_skip[unit],
|
||||
outb(sc->nic_addr + ED_P1_PAR0 + i * sc->edreg.ioskip,
|
||||
sc->arpcom.ac_enaddr[i]);
|
||||
#else
|
||||
for (i = 0; i < ETHER_ADDR_LEN; ++i)
|
||||
@ -2713,9 +2707,6 @@ ed_xmit(sc)
|
||||
{
|
||||
struct ifnet *ifp = (struct ifnet *)sc;
|
||||
unsigned short len;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
@ -2930,9 +2921,6 @@ ed_rint(sc)
|
||||
u_short len;
|
||||
struct ed_ring packet_hdr;
|
||||
char *packet_ptr;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
@ -3056,9 +3044,6 @@ edintr_sc(sc)
|
||||
{
|
||||
struct ifnet *ifp = (struct ifnet *)sc;
|
||||
u_char isr;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
@ -3548,10 +3533,6 @@ ed_pio_readmem(sc, src, dst, amount)
|
||||
unsigned char *dst;
|
||||
unsigned short amount;
|
||||
{
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
/* HP cards need special handling */
|
||||
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) {
|
||||
ed_hpp_readmem(sc, src, dst, amount);
|
||||
@ -3603,9 +3584,6 @@ ed_pio_writemem(sc, src, dst, len)
|
||||
unsigned short len;
|
||||
{
|
||||
int maxwait = 200; /* about 240us */
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
if (sc->vendor == ED_VENDOR_NOVELL) {
|
||||
|
||||
@ -3711,9 +3689,6 @@ ed_pio_write_mbufs(sc, m, dst)
|
||||
unsigned short total_len, dma_len;
|
||||
struct mbuf *mp;
|
||||
int maxwait = 200; /* about 240us */
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
/* HP PC Lan+ cards need special handling */
|
||||
if ((sc->vendor == ED_VENDOR_HP) &&
|
||||
@ -3977,9 +3952,6 @@ ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, int dst)
|
||||
volatile u_short * const d =
|
||||
(volatile u_short *) sc->hpp_mem_start;
|
||||
int use_32bit_accesses = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS);
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
/* select page 0 registers */
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
|
||||
@ -4095,9 +4067,6 @@ ed_setrcr(sc)
|
||||
{
|
||||
struct ifnet *ifp = (struct ifnet *)sc;
|
||||
int i;
|
||||
#ifdef PC98
|
||||
int unit = sc->unit;
|
||||
#endif
|
||||
|
||||
/* set page 1 registers */
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
|
||||
@ -4109,7 +4078,7 @@ ed_setrcr(sc)
|
||||
*/
|
||||
#ifdef PC98
|
||||
for (i = 0; i < 8; i++)
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit], 0xff);
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip, 0xff);
|
||||
#else
|
||||
for (i = 0; i < 8; i++)
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i, 0xff);
|
||||
@ -4139,7 +4108,7 @@ ed_setrcr(sc)
|
||||
*/
|
||||
#ifdef PC98
|
||||
for (i = 0; i < 8; i++)
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit],
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip,
|
||||
((u_char *) mcaf)[i]);
|
||||
#else
|
||||
for (i = 0; i < 8; i++)
|
||||
@ -4155,12 +4124,12 @@ ed_setrcr(sc)
|
||||
* Initialize multicast address hashing registers to
|
||||
* not accept multicasts.
|
||||
*/
|
||||
#ifndef PC98
|
||||
#ifdef PC98
|
||||
for (i = 0; i < 8; ++i)
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i, 0x00);
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip, 0x00);
|
||||
#else
|
||||
for (i = 0; i < 8; ++i)
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit], 0x00);
|
||||
outb(sc->nic_addr + ED_P1_MAR0 + i, 0x00);
|
||||
#endif
|
||||
|
||||
/* Set page 0 registers */
|
||||
|
@ -36,8 +36,7 @@
|
||||
#error Why you include if_ed98.h?
|
||||
#endif
|
||||
|
||||
static void pc98_set_register __P((struct isa_device *dev,
|
||||
int unit, int type));
|
||||
static void pc98_set_register __P((struct isa_device *dev, int type));
|
||||
|
||||
/*
|
||||
* Vendor types
|
||||
@ -50,11 +49,11 @@ static void pc98_set_register __P((struct isa_device *dev,
|
||||
#ifdef ED_NOVELL_NIC_OFFSET
|
||||
#undef ED_NOVELL_NIC_OFFSET
|
||||
#endif
|
||||
#define ED_NOVELL_NIC_OFFSET ed_novell_nic_offset[unit]
|
||||
#define ED_NOVELL_NIC_OFFSET sc->edreg.nic_offset
|
||||
#ifdef ED_NOVELL_ASIC_OFFSET
|
||||
#undef ED_NOVELL_ASIC_OFFSET
|
||||
#endif
|
||||
#define ED_NOVELL_ASIC_OFFSET ed_novell_asic_offset[unit]
|
||||
#define ED_NOVELL_ASIC_OFFSET sc->edreg.asic_offset
|
||||
|
||||
/*
|
||||
* Remote DMA data register; for reading or writing to the NIC mem
|
||||
@ -63,7 +62,7 @@ static void pc98_set_register __P((struct isa_device *dev,
|
||||
#ifdef ED_NOVELL_DATA
|
||||
#undef ED_NOVELL_DATA
|
||||
#endif
|
||||
#define ED_NOVELL_DATA ed_novell_data[unit]
|
||||
#define ED_NOVELL_DATA sc->edreg.data
|
||||
|
||||
/*
|
||||
* Reset register; reading from this register causes a board reset
|
||||
@ -71,7 +70,7 @@ static void pc98_set_register __P((struct isa_device *dev,
|
||||
#ifdef ED_NOVELL_RESET
|
||||
#undef ED_NOVELL_RESET
|
||||
#endif
|
||||
#define ED_NOVELL_RESET ed_novell_reset[unit]
|
||||
#define ED_NOVELL_RESET sc->edreg.reset
|
||||
|
||||
/*
|
||||
* Card type
|
||||
@ -113,152 +112,152 @@ static void pc98_set_register __P((struct isa_device *dev,
|
||||
* Page 0 register offsets
|
||||
*/
|
||||
#undef ED_P0_CR
|
||||
#define ED_P0_CR edp[unit][0x00]
|
||||
#define ED_P0_CR sc->edreg.port[0x00]
|
||||
|
||||
#undef ED_P0_CLDA0
|
||||
#define ED_P0_CLDA0 edp[unit][0x01]
|
||||
#define ED_P0_CLDA0 sc->edreg.port[0x01]
|
||||
#undef ED_P0_PSTART
|
||||
#define ED_P0_PSTART edp[unit][0x01]
|
||||
#define ED_P0_PSTART sc->edreg.port[0x01]
|
||||
|
||||
#undef ED_P0_CLDA1
|
||||
#define ED_P0_CLDA1 edp[unit][0x02]
|
||||
#define ED_P0_CLDA1 sc->edreg.port[0x02]
|
||||
#undef ED_P0_PSTOP
|
||||
#define ED_P0_PSTOP edp[unit][0x02]
|
||||
#define ED_P0_PSTOP sc->edreg.port[0x02]
|
||||
|
||||
#undef ED_P0_BNRY
|
||||
#define ED_P0_BNRY edp[unit][0x03]
|
||||
#define ED_P0_BNRY sc->edreg.port[0x03]
|
||||
|
||||
#undef ED_P0_TSR
|
||||
#define ED_P0_TSR edp[unit][0x04]
|
||||
#define ED_P0_TSR sc->edreg.port[0x04]
|
||||
#undef ED_P0_TPSR
|
||||
#define ED_P0_TPSR edp[unit][0x04]
|
||||
#define ED_P0_TPSR sc->edreg.port[0x04]
|
||||
|
||||
#undef ED_P0_NCR
|
||||
#define ED_P0_NCR edp[unit][0x05]
|
||||
#define ED_P0_NCR sc->edreg.port[0x05]
|
||||
#undef ED_P0_TBCR0
|
||||
#define ED_P0_TBCR0 edp[unit][0x05]
|
||||
#define ED_P0_TBCR0 sc->edreg.port[0x05]
|
||||
|
||||
#undef ED_P0_FIFO
|
||||
#define ED_P0_FIFO edp[unit][0x06]
|
||||
#define ED_P0_FIFO sc->edreg.port[0x06]
|
||||
#undef ED_P0_TBCR1
|
||||
#define ED_P0_TBCR1 edp[unit][0x06]
|
||||
#define ED_P0_TBCR1 sc->edreg.port[0x06]
|
||||
|
||||
#undef ED_P0_ISR
|
||||
#define ED_P0_ISR edp[unit][0x07]
|
||||
#define ED_P0_ISR sc->edreg.port[0x07]
|
||||
|
||||
#undef ED_P0_CRDA0
|
||||
#define ED_P0_CRDA0 edp[unit][0x08]
|
||||
#define ED_P0_CRDA0 sc->edreg.port[0x08]
|
||||
#undef ED_P0_RSAR0
|
||||
#define ED_P0_RSAR0 edp[unit][0x08]
|
||||
#define ED_P0_RSAR0 sc->edreg.port[0x08]
|
||||
|
||||
#undef ED_P0_CRDA1
|
||||
#define ED_P0_CRDA1 edp[unit][0x09]
|
||||
#define ED_P0_CRDA1 sc->edreg.port[0x09]
|
||||
#undef ED_P0_RSAR1
|
||||
#define ED_P0_RSAR1 edp[unit][0x09]
|
||||
#define ED_P0_RSAR1 sc->edreg.port[0x09]
|
||||
|
||||
#undef ED_P0_RBCR0
|
||||
#define ED_P0_RBCR0 edp[unit][0x0a]
|
||||
#define ED_P0_RBCR0 sc->edreg.port[0x0a]
|
||||
|
||||
#undef ED_P0_RBCR1
|
||||
#define ED_P0_RBCR1 edp[unit][0x0b]
|
||||
#define ED_P0_RBCR1 sc->edreg.port[0x0b]
|
||||
|
||||
#undef ED_P0_RSR
|
||||
#define ED_P0_RSR edp[unit][0x0c]
|
||||
#define ED_P0_RSR sc->edreg.port[0x0c]
|
||||
#undef ED_P0_RCR
|
||||
#define ED_P0_RCR edp[unit][0x0c]
|
||||
#define ED_P0_RCR sc->edreg.port[0x0c]
|
||||
|
||||
#undef ED_P0_CNTR0
|
||||
#define ED_P0_CNTR0 edp[unit][0x0d]
|
||||
#define ED_P0_CNTR0 sc->edreg.port[0x0d]
|
||||
#undef ED_P0_TCR
|
||||
#define ED_P0_TCR edp[unit][0x0d]
|
||||
#define ED_P0_TCR sc->edreg.port[0x0d]
|
||||
|
||||
#undef ED_P0_CNTR1
|
||||
#define ED_P0_CNTR1 edp[unit][0x0e]
|
||||
#define ED_P0_CNTR1 sc->edreg.port[0x0e]
|
||||
#undef ED_P0_DCR
|
||||
#define ED_P0_DCR edp[unit][0x0e]
|
||||
#define ED_P0_DCR sc->edreg.port[0x0e]
|
||||
|
||||
#undef ED_P0_CNTR2
|
||||
#define ED_P0_CNTR2 edp[unit][0x0f]
|
||||
#define ED_P0_CNTR2 sc->edreg.port[0x0f]
|
||||
#undef ED_P0_IMR
|
||||
#define ED_P0_IMR edp[unit][0x0f]
|
||||
#define ED_P0_IMR sc->edreg.port[0x0f]
|
||||
|
||||
/*
|
||||
* Page 1 register offsets
|
||||
*/
|
||||
#undef ED_P1_CR
|
||||
#define ED_P1_CR edp[unit][0x00]
|
||||
#define ED_P1_CR sc->edreg.port[0x00]
|
||||
#undef ED_P1_PAR0
|
||||
#define ED_P1_PAR0 edp[unit][0x01]
|
||||
#define ED_P1_PAR0 sc->edreg.port[0x01]
|
||||
#undef ED_P1_PAR1
|
||||
#define ED_P1_PAR1 edp[unit][0x02]
|
||||
#define ED_P1_PAR1 sc->edreg.port[0x02]
|
||||
#undef ED_P1_PAR2
|
||||
#define ED_P1_PAR2 edp[unit][0x03]
|
||||
#define ED_P1_PAR2 sc->edreg.port[0x03]
|
||||
#undef ED_P1_PAR3
|
||||
#define ED_P1_PAR3 edp[unit][0x04]
|
||||
#define ED_P1_PAR3 sc->edreg.port[0x04]
|
||||
#undef ED_P1_PAR4
|
||||
#define ED_P1_PAR4 edp[unit][0x05]
|
||||
#define ED_P1_PAR4 sc->edreg.port[0x05]
|
||||
#undef ED_P1_PAR5
|
||||
#define ED_P1_PAR5 edp[unit][0x06]
|
||||
#define ED_P1_PAR5 sc->edreg.port[0x06]
|
||||
#undef ED_P1_CURR
|
||||
#define ED_P1_CURR edp[unit][0x07]
|
||||
#define ED_P1_CURR sc->edreg.port[0x07]
|
||||
#undef ED_P1_MAR0
|
||||
#define ED_P1_MAR0 edp[unit][0x08]
|
||||
#define ED_P1_MAR0 sc->edreg.port[0x08]
|
||||
#undef ED_P1_MAR1
|
||||
#define ED_P1_MAR1 edp[unit][0x09]
|
||||
#define ED_P1_MAR1 sc->edreg.port[0x09]
|
||||
#undef ED_P1_MAR2
|
||||
#define ED_P1_MAR2 edp[unit][0x0a]
|
||||
#define ED_P1_MAR2 sc->edreg.port[0x0a]
|
||||
#undef ED_P1_MAR3
|
||||
#define ED_P1_MAR3 edp[unit][0x0b]
|
||||
#define ED_P1_MAR3 sc->edreg.port[0x0b]
|
||||
#undef ED_P1_MAR4
|
||||
#define ED_P1_MAR4 edp[unit][0x0c]
|
||||
#define ED_P1_MAR4 sc->edreg.port[0x0c]
|
||||
#undef ED_P1_MAR5
|
||||
#define ED_P1_MAR5 edp[unit][0x0d]
|
||||
#define ED_P1_MAR5 sc->edreg.port[0x0d]
|
||||
#undef ED_P1_MAR6
|
||||
#define ED_P1_MAR6 edp[unit][0x0e]
|
||||
#define ED_P1_MAR6 sc->edreg.port[0x0e]
|
||||
#undef ED_P1_MAR7
|
||||
#define ED_P1_MAR7 edp[unit][0x0f]
|
||||
#define ED_P1_MAR7 sc->edreg.port[0x0f]
|
||||
|
||||
/*
|
||||
* Page 2 register offsets
|
||||
*/
|
||||
#undef ED_P2_CR
|
||||
#define ED_P2_CR edp[unit][0x00]
|
||||
#define ED_P2_CR sc->edreg.port[0x00]
|
||||
#undef ED_P2_PSTART
|
||||
#define ED_P2_PSTART edp[unit][0x01]
|
||||
#define ED_P2_PSTART sc->edreg.port[0x01]
|
||||
#undef ED_P2_CLDA0
|
||||
#define ED_P2_CLDA0 edp[unit][0x01]
|
||||
#define ED_P2_CLDA0 sc->edreg.port[0x01]
|
||||
#undef ED_P2_PSTOP
|
||||
#define ED_P2_PSTOP edp[unit][0x02]
|
||||
#define ED_P2_PSTOP sc->edreg.port[0x02]
|
||||
#undef ED_P2_CLDA1
|
||||
#define ED_P2_CLDA1 edp[unit][0x02]
|
||||
#define ED_P2_CLDA1 sc->edreg.port[0x02]
|
||||
#undef ED_P2_RNPP
|
||||
#define ED_P2_RNPP edp[unit][0x03]
|
||||
#define ED_P2_RNPP sc->edreg.port[0x03]
|
||||
#undef ED_P2_TPSR
|
||||
#define ED_P2_TPSR edp[unit][0x04]
|
||||
#define ED_P2_TPSR sc->edreg.port[0x04]
|
||||
#undef ED_P2_LNPP
|
||||
#define ED_P2_LNPP edp[unit][0x05]
|
||||
#define ED_P2_LNPP sc->edreg.port[0x05]
|
||||
#undef ED_P2_ACU
|
||||
#define ED_P2_ACU edp[unit][0x06]
|
||||
#define ED_P2_ACU sc->edreg.port[0x06]
|
||||
#undef ED_P2_ACL
|
||||
#define ED_P2_ACL edp[unit][0x07]
|
||||
#define ED_P2_ACL sc->edreg.port[0x07]
|
||||
#undef ED_P2_RCR
|
||||
#define ED_P2_RCR edp[unit][0x0c]
|
||||
#define ED_P2_RCR sc->edreg.port[0x0c]
|
||||
#undef ED_P2_TCR
|
||||
#define ED_P2_TCR edp[unit][0x0d]
|
||||
#define ED_P2_TCR sc->edreg.port[0x0d]
|
||||
#undef ED_P2_DCR
|
||||
#define ED_P2_DCR edp[unit][0x0e]
|
||||
#define ED_P2_DCR sc->edreg.port[0x0e]
|
||||
#undef ED_P2_IMR
|
||||
#define ED_P2_IMR edp[unit][0x0f]
|
||||
#define ED_P2_IMR sc->edreg.port[0x0f]
|
||||
|
||||
/* PCCARD */
|
||||
#ifdef ED_PC_MISC
|
||||
#undef ED_PC_MISC
|
||||
#endif
|
||||
#define ED_PC_MISC ed_pc_misc[unit]
|
||||
#define ED_PC_MISC sc->edreg.pc_misc
|
||||
#ifdef ED_PC_RESET
|
||||
#undef ED_PC_RESET
|
||||
#endif
|
||||
#define ED_PC_RESET ed_pc_reset[unit]
|
||||
#define ED_PC_RESET sc->edreg.pc_reset
|
||||
|
||||
/* LPC-T support */
|
||||
#define LPCT_1d0_ON() \
|
||||
@ -336,19 +335,6 @@ static void pc98_set_register __P((struct isa_device *dev,
|
||||
*/
|
||||
#define ED_CNET98EL_ISR 0x05
|
||||
|
||||
|
||||
|
||||
/* register offsets */
|
||||
static unsigned int *edp[NED];
|
||||
static unsigned int pc98_io_skip[NED];
|
||||
static int ed_novell_nic_offset[NED];
|
||||
static int ed_novell_asic_offset[NED];
|
||||
static int ed_novell_data[NED];
|
||||
static int ed_novell_reset[NED];
|
||||
static int ed_pc_misc[NED];
|
||||
static int ed_pc_reset[NED];
|
||||
|
||||
|
||||
/* NE2000, LGY-98, ICM, LPC-T, C-NET(98)E/L */
|
||||
static unsigned int edp_generic[16] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
@ -391,14 +377,15 @@ static unsigned int edp_cnet98[16] = {
|
||||
};
|
||||
|
||||
|
||||
static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
static void pc98_set_register(struct isa_device *dev, int type)
|
||||
{
|
||||
struct ed_softc *sc = &ed_softc[dev->id_unit];
|
||||
int adj;
|
||||
|
||||
switch (type) {
|
||||
case ED_TYPE98_GENERIC:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
sc->edreg.port = edp_generic;
|
||||
sc->edreg.ioskip = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0010;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -408,8 +395,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_LGY:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
sc->edreg.port = edp_generic;
|
||||
sc->edreg.ioskip = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0200;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -419,8 +406,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_EGY:
|
||||
edp[unit] = edp_egy98;
|
||||
pc98_io_skip[unit] = 2;
|
||||
sc->edreg.port = edp_egy98;
|
||||
sc->edreg.ioskip = 2;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0200;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -430,8 +417,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_ICM:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
sc->edreg.port = edp_generic;
|
||||
sc->edreg.ioskip = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -441,8 +428,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_BDN:
|
||||
edp[unit] = edp_bdn98;
|
||||
pc98_io_skip[unit] = 0x1000;
|
||||
sc->edreg.port = edp_bdn98;
|
||||
sc->edreg.ioskip = 0x1000;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0;
|
||||
@ -452,8 +439,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_SIC:
|
||||
edp[unit] = edp_sic98;
|
||||
pc98_io_skip[unit] = 0x200;
|
||||
sc->edreg.port = edp_sic98;
|
||||
sc->edreg.ioskip = 0x200;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x2000;
|
||||
ED_NOVELL_DATA = 0x00; /* dummy */
|
||||
@ -463,8 +450,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_LPC:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 0x1;
|
||||
sc->edreg.port = edp_generic;
|
||||
sc->edreg.ioskip = 0x1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -474,8 +461,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_108:
|
||||
edp[unit] = edp_nec108;
|
||||
pc98_io_skip[unit] = 2;
|
||||
sc->edreg.port = edp_nec108;
|
||||
sc->edreg.ioskip = 2;
|
||||
adj = (dev->id_iobase & 0xf000) / 2;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - dev->id_iobase;
|
||||
@ -486,8 +473,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_LA98:
|
||||
edp[unit] = edp_la98;
|
||||
pc98_io_skip[unit] = 0x1000;
|
||||
sc->edreg.port = edp_la98;
|
||||
sc->edreg.ioskip = 0x1000;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x100;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
@ -497,8 +484,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_CNET98EL:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
sc->edreg.port = edp_generic;
|
||||
sc->edreg.ioskip = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0400;
|
||||
ED_NOVELL_DATA = 0x000e;
|
||||
@ -507,8 +494,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
|
||||
break;
|
||||
|
||||
case ED_TYPE98_CNET98:
|
||||
edp[unit] = edp_cnet98;
|
||||
pc98_io_skip[unit] = 2;
|
||||
sc->edreg.port = edp_cnet98;
|
||||
sc->edreg.ioskip = 2;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0400;
|
||||
ED_NOVELL_DATA = 0x000e;
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: if_fe.c,v 1.8 1996/09/12 11:09:48 asami Exp $
|
||||
* $Id: if_fe.c,v 1.9 1996/10/09 21:46:25 asami Exp $
|
||||
*
|
||||
* Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
|
||||
* To be used with FreeBSD 2.x
|
||||
@ -242,8 +242,8 @@ static struct fe_softc {
|
||||
#define sc_enaddr arpcom.ac_enaddr
|
||||
|
||||
/* Standard driver entry points. These can be static. */
|
||||
static int fe_probe ( DEVICE * );
|
||||
static int fe_attach ( DEVICE * );
|
||||
static int fe_probe ( struct isa_device * );
|
||||
static int fe_attach ( struct isa_device * );
|
||||
static void fe_init ( int );
|
||||
static int fe_ioctl ( struct ifnet *, int, caddr_t );
|
||||
static void fe_start ( struct ifnet * );
|
||||
|
@ -1,9 +1,15 @@
|
||||
/*
|
||||
* Keyboard definitions
|
||||
* from: unknown origin, 386BSD 0.1
|
||||
* $Id: kbd.h,v 1.4 1995/05/30 08:02:38 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PC98_PC98_KBD_H_
|
||||
#define _PC98_PC98_KBD_H_ 1
|
||||
#ifndef _I386_ISA_KBD_H_
|
||||
#define _I386_ISA_KBD_H_ 1
|
||||
|
||||
/* Reference: IBM AT Technical Reference Manual,
|
||||
* pp. 1-38 to 1-43, 4-3 to 4-22
|
||||
*/
|
||||
|
||||
/* commands and responses */
|
||||
#define KBC_RESET 0xFF /* Reset the keyboard */
|
||||
@ -12,4 +18,4 @@
|
||||
#define KBR_RESEND 0xFE /* Keyboard needs resend of command */
|
||||
#define KBR_ACK 0xFA /* Keyboard did receive command */
|
||||
#define KBR_RSTDONE 0xAA /* Keyboard reset complete */
|
||||
#endif /* _PC98_PC98_KBD_H_ */
|
||||
#endif /* _I386_ISA_KBD_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
||||
Things to do for the matcd driver 4-Jul-95
|
||||
|
||||
1. Someone wants to switch all drivers from disklabel and
|
||||
its assorted mechanisms over to disk slicing and its mechanisms,
|
||||
but I was unable to find any useful documentation on how to
|
||||
implement the changes for a read-only, single-partition,
|
||||
removable (ie, partition can change size) device.
|
||||
So this will have to wait until after 2.1.
|
||||
|
||||
2. Support for reading R-W subcodes while playing audio. This would be
|
||||
useful if you have any CD+G or CD+MIDI discs, but the demand for this
|
||||
is pretty low, unless you like Karaoke. Someone will also have to
|
||||
write a CD+G viewer for X. The code for the driver to add this is
|
||||
pretty minor but there aren't any precedents on how to handle the
|
||||
data transfer to the application.
|
||||
|
||||
3. Support for reading the ISBN and UPC labels. The ioctl structures
|
||||
for these appear to be defined but no other driver seems to do this.
|
||||
|
||||
4. Multi-session support. There are two forms of this; what
|
||||
Philips defined and what Kodak uses. This will be quite
|
||||
complicated and will probably require changes in the filesystem
|
||||
layer. The drive support for Kodak multi-session is known to work.
|
||||
|
||||
5. Multiple data tracks. My vision here was to add an ioctl
|
||||
that caused a track offset to be inserted into block requests,
|
||||
effectively shifting the base to the specified track. Very
|
||||
easy to add but not a big deal since I have only two discs
|
||||
in my collection that have multiple data tracks and I mastered
|
||||
one of them.
|
||||
|
||||
6. A curses-based CD-Player app (ie, not X). I will probably do this
|
||||
mainly for its value as a debugging tool. It was pretty annoying
|
||||
not finding a single application that actually issued all the
|
||||
defined ioctls, let alone any new ones.
|
||||
|
||||
If you feel the urge to work on one or more of these remaining items,
|
||||
please contact the author first at bsdmail@nemesis.lonestar.org
|
||||
to make sure the work hasn't already been done or started.
|
||||
|
||||
Frank Durda IV
|
||||
|
@ -1,142 +0,0 @@
|
||||
/*creative.h-------------------------------------------------------------------
|
||||
|
||||
Matsushita(Panasonic) / Creative CD-ROM Driver (matcd)
|
||||
Authored by Frank Durda IV
|
||||
|
||||
Copyright 1994, 1995 Frank Durda IV. All rights reserved.
|
||||
"FDIV" is a trademark of Frank Durda IV.
|
||||
|
||||
|
||||
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 positioned at the very beginning of this file without
|
||||
modification, all copyright strings, all related programming
|
||||
codes that display the copyright strings, this list of
|
||||
conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must contain all copyright strings
|
||||
and related programming code that display the copyright strings.
|
||||
3. 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.
|
||||
4. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgement:
|
||||
"The Matsushita/Panasonic CD-ROM driver was developed
|
||||
by Frank Durda IV for use with "FreeBSD" and similar
|
||||
operating systems."
|
||||
"Similar operating systems" includes mainly non-profit oriented
|
||||
systems for research and education, including but not restricted
|
||||
to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the
|
||||
acknowledgement (in electronic form or printed text) may not be
|
||||
changed without permission from the author.
|
||||
5. Absolutely no warranty of function, fitness or purpose is made
|
||||
by the author Frank Durda IV.
|
||||
6. Neither the name of the author nor the name "FreeBSD" may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
(The author can be reached at bsdmail@nemesis.lonestar.org)
|
||||
7. The product containing this software must meet all of these
|
||||
conditions even if it is unsupported, not a complete system
|
||||
and/or does not contain compiled code.
|
||||
8. These conditions will be in force for the full life of the
|
||||
copyright.
|
||||
9. If all the above conditions are met, modifications to other
|
||||
parts of this file may be freely made, although any person
|
||||
or persons making changes do not receive the right to add their
|
||||
name or names to the copyright strings and notices in this
|
||||
software. Persons making changes are encouraged to insert edit
|
||||
history in matcd.c and to put your name and details of the
|
||||
change there.
|
||||
10. You must have prior written permission from the author to
|
||||
deviate from these terms.
|
||||
|
||||
Vendors who produce product(s) containing this code are encouraged
|
||||
(but not required) to provide copies of the finished product(s) to
|
||||
the author and to correspond with the author about development
|
||||
activity relating to this code. Donations of development hardware
|
||||
and/or software are also welcome. (This is one of the faster ways
|
||||
to get a driver developed for a device.)
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``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 DEVELOPER(S) 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.
|
||||
|
||||
|
||||
-----No changes are allowed above this line------------------------------------
|
||||
|
||||
See matcd.c for Edit History
|
||||
|
||||
These are the I/O port mapping offsets and bit assignments used
|
||||
by Creative Labs in their implementation of the host interface for
|
||||
the Matsushita CD-ROM drive. These may be different in the adapter
|
||||
cards (including sound cards) made by other vendors.
|
||||
It is unknown if the Creative interface is based on a reference design
|
||||
provided by Matsushita (other interface vendors would similar or
|
||||
identical if this was the case).
|
||||
|
||||
The drive is actually capable of some things that the Creative
|
||||
interface doesn't implement, such as DMA and interrupts.
|
||||
|
||||
See matcd.h for defines related to the Matsushita drive itself.
|
||||
*/
|
||||
|
||||
|
||||
/* Creative Labs (and compatible) I/O port mapping offsets
|
||||
*/
|
||||
|
||||
#define NUMPORTS 4 /*Four ports are decoded by the i/f*/
|
||||
|
||||
#define CMD 0 /*Write - commands*/
|
||||
#define DATA 0 /*Read - data/status from drive*/
|
||||
#ifdef PC98
|
||||
#define PHASE 0x100 /*Write - switch between data/status*/
|
||||
#define STATUS 0x100 /*Read - bus status */
|
||||
#define RESET 0x200 /*Write - reset all attached drives*/
|
||||
#define ALTDATA 0x200 /*<20>Read - data on non Creative bds.*/
|
||||
#define SELECT 0x300 /*Write - drive select*/
|
||||
#else /* !PC98 */
|
||||
#define PHASE 1 /*Write - switch between data/status*/
|
||||
#define STATUS 1 /*Read - bus status*/
|
||||
#define RESET 2 /*Write - reset all attached drives*/
|
||||
/*Any value written will reset*/
|
||||
#define ALTDATA 2 /*<20>Read - data on non Creative bds.*/
|
||||
#define SELECT 3 /*Write - drive select*/
|
||||
#endif /*PC98*/
|
||||
|
||||
/* Creative PHASE port bit assignments
|
||||
*/
|
||||
|
||||
#define PHASENA 1 /*Access data bytes instead of status*/
|
||||
|
||||
|
||||
/* Creative STATUS port register bits
|
||||
*/
|
||||
|
||||
#define DTEN 2 /*When low, in data xfer phase*/
|
||||
#define STEN 4 /*When low, in status phase*/
|
||||
#define TEST 1 /*Function is unknown*/
|
||||
|
||||
|
||||
/* Creative drive SELECT port bit assignments
|
||||
Note that in the Creative interface, DS0==Bit 1 and
|
||||
DS1==Bit 0 (DS is Drive Select).
|
||||
*/
|
||||
|
||||
#define CRDRIVE0 0x00
|
||||
#define CRDRIVE1 0x02
|
||||
#define CRDRIVE2 0x01
|
||||
#define CRDRIVE3 0x03
|
||||
|
||||
/*End of creative.h*/
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,283 +0,0 @@
|
||||
/*options.h--------------------------------------------------------------------
|
||||
|
||||
Matsushita(Panasonic) / Creative CD-ROM Driver (matcd)
|
||||
Authored by Frank Durda IV
|
||||
|
||||
Copyright 1994, 1995 Frank Durda IV. All rights reserved.
|
||||
"FDIV" is a trademark of Frank Durda IV.
|
||||
|
||||
|
||||
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 positioned at the very beginning of this file without
|
||||
modification, all copyright strings, all related programming
|
||||
codes that display the copyright strings, this list of
|
||||
conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must contain all copyright strings
|
||||
and related programming code that display the copyright strings.
|
||||
3. 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.
|
||||
4. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgement:
|
||||
"The Matsushita/Panasonic CD-ROM driver was developed
|
||||
by Frank Durda IV for use with "FreeBSD" and similar
|
||||
operating systems."
|
||||
"Similar operating systems" includes mainly non-profit oriented
|
||||
systems for research and education, including but not restricted
|
||||
to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the
|
||||
acknowledgement (in electronic form or printed text) may not be
|
||||
changed without permission from the author.
|
||||
5. Absolutely no warranty of function, fitness or purpose is made
|
||||
by the author Frank Durda IV.
|
||||
6. Neither the name of the author nor the name "FreeBSD" may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
(The author can be reached at bsdmail@nemesis.lonestar.org)
|
||||
7. The product containing this software must meet all of these
|
||||
conditions even if it is unsupported, not a complete system
|
||||
and/or does not contain compiled code.
|
||||
8. These conditions will be in force for the full life of the
|
||||
copyright.
|
||||
9. If all the above conditions are met, modifications to other
|
||||
parts of this file may be freely made, although any person
|
||||
or persons making changes do not receive the right to add their
|
||||
name or names to the copyright strings and notices in this
|
||||
software. Persons making changes are encouraged to insert edit
|
||||
history in matcd.c and to put your name and details of the
|
||||
change there.
|
||||
10. You must have prior written permission from the author to
|
||||
deviate from these terms.
|
||||
|
||||
Vendors who produce product(s) containing this code are encouraged
|
||||
(but not required) to provide copies of the finished product(s) to
|
||||
the author and to correspond with the author about development
|
||||
activity relating to this code. Donations of development hardware
|
||||
and/or software are also welcome. (This is one of the faster ways
|
||||
to get a driver developed for a device.)
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``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 DEVELOPER(S) 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.
|
||||
|
||||
|
||||
-----No changes are allowed above this line------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
Conditional compilation flags - change to suit your system
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* AUTOHUNT Adds extra code that allows the driver to search
|
||||
for interface cards rather than having to hard-code
|
||||
the locations in the kernel conf file.
|
||||
Leaving AUTOHUNT enabled is the recommended setting.
|
||||
*/
|
||||
|
||||
#define AUTOHUNT
|
||||
|
||||
|
||||
/* NUMCTRLRS Configures support for between one and four
|
||||
host interfaces, for up to 16 drives.
|
||||
The number of entries in the kernel config
|
||||
file is used by default, but this may be changed
|
||||
to a specific value if desired.
|
||||
|
||||
Leaving NUMCTRLRS based on NMATCD is the
|
||||
recommended setting.
|
||||
*/
|
||||
|
||||
#if NMATCD >= 4
|
||||
#define NUMCTRLRS 4 /*Limit driver to four host interfaces*/
|
||||
#else /*NMATCD*/
|
||||
#define NUMCTRLRS NMATCD
|
||||
#endif /*NMATCD*/
|
||||
|
||||
|
||||
/* FULLDRIVER If not set, the audio, non-data functions and
|
||||
some error recovery functions are eliminated from
|
||||
the compiled driver. The resulting driver will be
|
||||
smaller and may help a kernel fit on a boot floppy.
|
||||
Leaving FULLDRIVER enabled is the recommended setting.
|
||||
*/
|
||||
|
||||
#ifndef BOOTMFS
|
||||
#define FULLDRIVER
|
||||
#endif /*BOOTMFS*/
|
||||
|
||||
|
||||
/* RESETONBOOT causes the driver to reset the drive(s) to be
|
||||
reset during probing. This causes any audio
|
||||
playback to be aborted and the drives will close
|
||||
their trays if they are open.
|
||||
Leaving RESETONBOOT enabled is the recommended setting.
|
||||
*/
|
||||
|
||||
#define RESETONBOOT
|
||||
|
||||
|
||||
/*<15> LOCKDRIVE If enabled, when a drive is opened using a
|
||||
<15> minor number greater than 127, the drive door is
|
||||
<15> locked. The drive door remains locked until all
|
||||
<23> partitions on the drive are closed. The EJECT,
|
||||
<23> ALLOW and PREVENT ioctls are refused when this locking
|
||||
<23> mechanism is active.
|
||||
<15> The additional code size is small so enabling
|
||||
<15> LOCKDRIVE is the recommended setting.
|
||||
*/
|
||||
|
||||
#define LOCKDRIVE
|
||||
|
||||
|
||||
/*<14> KRYTEN This enables a bug that someone might consider
|
||||
<14> to be a feature. If KRYTEN is enabled and you are
|
||||
<14> playing audio and you issue the resume-play ioctl,
|
||||
<14> the audio will stutter, playing the same quarter
|
||||
<14> of a second or so of audio several times before
|
||||
<14> resuming normally. Resuming from a pause acts
|
||||
<14> normally regardless of the setting of this flag.
|
||||
<14> Leaving KRYTEN disabled is the recommended setting.
|
||||
<14>*/
|
||||
|
||||
/*#define KRYTEN*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
This structure contains the hints for where we should look for the
|
||||
host adapter. If you want to change where we search or reduce the
|
||||
places we search to avoid confusing some other device, either
|
||||
specify explicit addresses in the kernel config file (preferred)
|
||||
or change this array.
|
||||
|
||||
If the kernel config file has multiple ? entries, the probe routines
|
||||
will use this table multiple times and will eliminate each failed
|
||||
entry that probe tries.
|
||||
|
||||
WARNING: The number of controller entries for this driver in config
|
||||
must be less than or equal to the number of hints if hints are used.
|
||||
|
||||
If you add entries to the table, add them immediately before
|
||||
the -1 end-of-table marker. The values already present are
|
||||
the ones used by Creative Labs boards and those of a few
|
||||
other vendors.
|
||||
|
||||
Each additional entry increases the boot time by four seconds,
|
||||
and can increase the chance of accessing some other device.
|
||||
Therefore, the list should be kept to a minimum. Once the
|
||||
devices have been correctly located, the kernel should be
|
||||
configured so that it looks only at the correct location from
|
||||
that point on.
|
||||
|
||||
Be sure to search devices located below 0x3ff BEFORE scanning
|
||||
higher locations. Some boards don't decode all I/O address lines,
|
||||
so 0x230 and 0x630 appear identical.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef AUTOHUNT
|
||||
static int port_hints[]={
|
||||
#ifdef PC98
|
||||
0x30d2,
|
||||
0x30d0,
|
||||
0x30d4,
|
||||
0x30d6,
|
||||
0x30d8,
|
||||
0x30da,
|
||||
0x30dc,
|
||||
0x30de,
|
||||
#else
|
||||
0x230, /*SB Pro & SB16*/
|
||||
0x240, /*SB Pro & SB16*/
|
||||
0x250, /*Creative omniCD standalone boards*/
|
||||
0x260, /*Creative omniCD standalone boards*/
|
||||
0x340, /*Laser Mate*/
|
||||
0x360, /*Laser Mate*/
|
||||
0x630, /*IBM*/
|
||||
#if 0
|
||||
/* These locations are alternate settings for LaserMate and IBM
|
||||
boards, but they usually conflict with network and SCSI cards.
|
||||
I recommend against probing these randomly.
|
||||
*/
|
||||
0x310, /*Laser Mate*/
|
||||
0x320, /*Laser Mate*/
|
||||
0x330, /*Laser Mate*/
|
||||
0x350, /*Laser Mate*/
|
||||
0x370, /*Laser Mate*/
|
||||
0x650, /*IBM*/
|
||||
0x670, /*IBM*/
|
||||
0x690, /*IBM*/
|
||||
#endif /*0*/
|
||||
#endif
|
||||
-1}; /*use. Table MUST end with -1*/
|
||||
#endif /*AUTOHUNT*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Debugging flags - Turn these on only if you are looking at a
|
||||
problem.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* DEBUGOPEN If enabled, debug messages for open and close
|
||||
operations.
|
||||
*/
|
||||
|
||||
/*#define DEBUGOPEN*/
|
||||
|
||||
|
||||
/* DEBUGIO If enabled, reports on calls to strategy, start
|
||||
and other I/O related functions.
|
||||
*/
|
||||
|
||||
/*#define DEBUGIO*/
|
||||
|
||||
|
||||
/* DEBUGQUEUE If enabled, shows activity on disk request queues.
|
||||
Warning - This debug is VERY VERY NOISY and will
|
||||
loop endlessly if queues are not null terminated
|
||||
as they should be.
|
||||
*/
|
||||
|
||||
/*#define DEBUGQUEUE*/
|
||||
|
||||
|
||||
/* DEBUGCMD If enabled, shows the actual commands being issued
|
||||
to the CD-ROM drives.
|
||||
*/
|
||||
|
||||
/*#define DEBUGCMD*/
|
||||
|
||||
|
||||
/* DEBUGSLEEP If enabled, reports on timeouts, wakeups, dropped
|
||||
threads, etc.
|
||||
*/
|
||||
|
||||
/*#define DEBUGSLEEP*/
|
||||
|
||||
|
||||
/* DEBUGIOCTL If enabled, reports on the various ioctl-related
|
||||
calls and operations. You might have to enable
|
||||
DEBUGCMD as well to get enough debugging information.
|
||||
*/
|
||||
|
||||
/*#define DEBUGIOCTL*/
|
||||
|
||||
|
||||
/* DEBUGPROBE If enabled, reports on the process of locating
|
||||
adapters and drives. The debugging in matcdprobe()
|
||||
and matcdattach() routines is enabled with this
|
||||
flag.
|
||||
*/
|
||||
|
||||
/*#define DEBUGPROBE*/
|
||||
|
||||
|
||||
/*End of options.h*/
|
||||
|
@ -11,7 +11,7 @@
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* $Id: mse.c,v 1.4 1996/09/07 02:13:57 asami Exp $
|
||||
* $Id: mse.c,v 1.5 1996/09/10 09:38:15 asami Exp $
|
||||
*/
|
||||
/*
|
||||
* Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
|
||||
@ -662,17 +662,7 @@ mse_probe98m(idp)
|
||||
/* initialize */
|
||||
outb(msport + INT, INT_DISABLE); /* INT disable */
|
||||
outb(msport + HC, HC_NO_CLEAR); /* HC = 0 */
|
||||
#if 0
|
||||
if (inb(msport + PORT_C) & 0x80 != 0) {
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
outb(msport + HC, HC_CLEAR); /* HC = 1 */
|
||||
#if 0
|
||||
if (inb(msport + PORT_C) & 0x80 == 0) {
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
|
||||
* $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
|
||||
* $Id: pc98.h,v 1.6 1996/10/23 07:25:22 asami Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PC98_PC98_PC98_H_
|
||||
@ -73,7 +73,7 @@
|
||||
#define IO_NMI 0x050 /* NMI Control */
|
||||
#define IO_WAIT 0x05F /* WAIT 0.6 us */
|
||||
#define IO_GDC1 0x060 /* 7220 GDC Text Control */
|
||||
#define IO_TIMER 0x071 /* 8253C Timer */
|
||||
#define IO_TIMER1 0x071 /* 8253C Timer */
|
||||
#define IO_SASI 0x080 /* SASI Hard Disk Controller */
|
||||
#define IO_FD1 0x090 /* 765A 1MB FDC */
|
||||
#define IO_GDC2 0x0a0 /* 7220 GDC Graphic Control */
|
||||
|
@ -25,7 +25,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: pcaudio.c,v 1.5 1996/09/10 09:38:24 asami Exp $
|
||||
* $Id: pcaudio.c,v 1.6 1996/10/09 21:46:40 asami Exp $
|
||||
*/
|
||||
|
||||
#include "pca.h"
|
||||
@ -35,8 +35,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
@ -45,18 +44,14 @@
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
|
||||
#include <pc98/pc98/sound/ulaw.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#endif
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
|
||||
#define DSP_ULAW_NOT_WANTED
|
||||
#include <i386/isa/sound/ulaw.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEVFS
|
||||
#include <sys/devfsext.h>
|
||||
@ -97,7 +92,7 @@ static void *pcac_devfs_token;
|
||||
static int pca_sleep = 0;
|
||||
static int pca_initialized = 0;
|
||||
|
||||
void pcaintr(struct clockframe *frame);
|
||||
static void pcaintr(struct clockframe *frame);
|
||||
static int pcaprobe(struct isa_device *dvp);
|
||||
static int pcaattach(struct isa_device *dvp);
|
||||
|
||||
@ -121,7 +116,8 @@ static void pca_continue __P((void));
|
||||
static void pca_init __P((void));
|
||||
static void pca_pause __P((void));
|
||||
|
||||
static inline void conv(const void *table, void *buff, unsigned long n)
|
||||
static inline void
|
||||
conv(const void *table, void *buff, unsigned long n)
|
||||
{
|
||||
__asm__("1:\tmovb (%2), %3\n"
|
||||
"\txlatb\n"
|
||||
@ -152,7 +148,7 @@ pca_volume(int volume)
|
||||
|
||||
|
||||
static void
|
||||
pca_init()
|
||||
pca_init(void)
|
||||
{
|
||||
pca_status.open = 0;
|
||||
pca_status.queries = 0;
|
||||
@ -233,7 +229,7 @@ pca_stop(void)
|
||||
|
||||
|
||||
static void
|
||||
pca_pause()
|
||||
pca_pause(void)
|
||||
{
|
||||
int x = splhigh();
|
||||
|
||||
@ -249,7 +245,7 @@ pca_pause()
|
||||
|
||||
|
||||
static void
|
||||
pca_continue()
|
||||
pca_continue(void)
|
||||
{
|
||||
int x = splhigh();
|
||||
|
||||
@ -313,7 +309,7 @@ pcaattach(struct isa_device *dvp)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
pcaopen(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
/* audioctl device can always be opened */
|
||||
@ -341,7 +337,7 @@ pcaopen(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
/* audioctl device can always be closed */
|
||||
@ -357,7 +353,7 @@ pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
pcawrite(dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
int count, error, which, x;
|
||||
@ -403,7 +399,7 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
audio_info_t *auptr;
|
||||
@ -467,7 +463,7 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
pcaintr(struct clockframe *frame)
|
||||
{
|
||||
if (pca_status.index < pca_status.in_use[pca_status.current]) {
|
||||
@ -510,7 +506,7 @@ pcaintr(struct clockframe *frame)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
pcaselect(dev_t dev, int rw, struct proc *p)
|
||||
{
|
||||
int s = spltty();
|
||||
|
@ -1,526 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.3 1996/09/03 10:23:51 asami Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
** FreeBSD
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
** Copyright (c) 1994 Wolfgang Stanglmeier. 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. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "vector.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcibus.h>
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The following functions are provided by the pci bios.
|
||||
** They are used only by the pci configuration.
|
||||
**
|
||||
** pcibus_setup():
|
||||
** Probes for a pci system.
|
||||
** Sets pci_maxdevice and pci_mechanism.
|
||||
**
|
||||
** pcibus_tag():
|
||||
** Creates a handle for pci configuration space access.
|
||||
** This handle is given to the read/write functions.
|
||||
**
|
||||
** pcibus_ftag():
|
||||
** Creates a modified handle.
|
||||
**
|
||||
** pcibus_read():
|
||||
** Read a long word from the pci configuration space.
|
||||
** Requires a tag (from pcitag) and the register
|
||||
** number (should be a long word alligned one).
|
||||
**
|
||||
** pcibus_write():
|
||||
** Writes a long word to the pci configuration space.
|
||||
** Requires a tag (from pcitag), the register number
|
||||
** (should be a long word alligned one), and a value.
|
||||
**
|
||||
** pcibus_regirq():
|
||||
** Register an interupt handler for a pci device.
|
||||
** Requires a tag (from pcitag), the register number
|
||||
** (should be a long word alligned one), and a value.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
pcibus_check (void);
|
||||
|
||||
static void
|
||||
pcibus_setup (void);
|
||||
|
||||
static pcici_t
|
||||
pcibus_tag (u_char bus, u_char device, u_char func);
|
||||
|
||||
static pcici_t
|
||||
pcibus_ftag (pcici_t tag, u_char func);
|
||||
|
||||
static u_long
|
||||
pcibus_read (pcici_t tag, u_long reg);
|
||||
|
||||
static void
|
||||
pcibus_write (pcici_t tag, u_long reg, u_long data);
|
||||
|
||||
static int
|
||||
pcibus_ihandler_attach (int irq, inthand2_t *func, int arg, unsigned* maskptr);
|
||||
|
||||
static int
|
||||
pcibus_ihandler_detach (int irq, inthand2_t *func);
|
||||
|
||||
static int
|
||||
pcibus_imask_include (int irq, unsigned* maskptr);
|
||||
|
||||
static int
|
||||
pcibus_imask_exclude (int irq, unsigned* maskptr);
|
||||
|
||||
static struct pcibus i386pci = {
|
||||
"pci",
|
||||
pcibus_setup,
|
||||
pcibus_tag,
|
||||
pcibus_ftag,
|
||||
pcibus_read,
|
||||
pcibus_write,
|
||||
ICU_LEN,
|
||||
pcibus_ihandler_attach,
|
||||
pcibus_ihandler_detach,
|
||||
pcibus_imask_include,
|
||||
pcibus_imask_exclude,
|
||||
};
|
||||
|
||||
/*
|
||||
** Announce structure to generic driver
|
||||
*/
|
||||
|
||||
DATA_SET (pcibus_set, i386pci);
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
**
|
||||
** Determine configuration mode
|
||||
**
|
||||
**--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#define CONF1_ADDR_PORT 0x0cf8
|
||||
#define CONF1_DATA_PORT 0x0cfc
|
||||
|
||||
#define CONF1_ENABLE 0x80000000ul
|
||||
#define CONF1_ENABLE_CHK 0x80000000ul
|
||||
#define CONF1_ENABLE_MSK 0x7ff00000ul
|
||||
#define CONF1_ENABLE_CHK1 0xff000001ul
|
||||
#define CONF1_ENABLE_MSK1 0x80000001ul
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
||||
#define CONF2_ENABLE_PORT 0x0cf8
|
||||
#ifdef PC98
|
||||
#define CONF2_FORWARD_PORT 0x0cf9
|
||||
#else
|
||||
#define CONF2_FORWARD_PORT 0x0cfa
|
||||
#endif
|
||||
|
||||
#define CONF2_ENABLE_CHK 0x0e
|
||||
#define CONF2_ENABLE_RES 0x0e
|
||||
|
||||
static int
|
||||
pcibus_check (void)
|
||||
{
|
||||
u_char device;
|
||||
|
||||
if (bootverbose) printf ("pcibus_check:\tdevice ");
|
||||
|
||||
for (device = 0; device < pci_maxdevice; device++) {
|
||||
unsigned long id;
|
||||
if (bootverbose)
|
||||
printf ("%d ", device);
|
||||
id = pcibus_read (pcibus_tag (0,device,0), 0);
|
||||
if (id && id != 0xfffffffful) {
|
||||
if (bootverbose) printf ("is there (id=%08lx)\n", id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (bootverbose)
|
||||
printf ("-- nothing found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pcibus_setup (void)
|
||||
{
|
||||
unsigned long mode1res,oldval1;
|
||||
unsigned char mode2res,oldval2;
|
||||
|
||||
oldval1 = inl (CONF1_ADDR_PORT);
|
||||
|
||||
if (bootverbose) {
|
||||
printf ("pcibus_setup(1):\tmode 1 addr port (0x0cf8) is 0x%08lx\n", oldval1);
|
||||
}
|
||||
|
||||
/*---------------------------------------
|
||||
** Assume configuration mechanism 1 for now ...
|
||||
**---------------------------------------
|
||||
*/
|
||||
|
||||
if ((oldval1 & CONF1_ENABLE_MSK) == 0) {
|
||||
|
||||
pci_mechanism = 1;
|
||||
pci_maxdevice = 32;
|
||||
|
||||
outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK);
|
||||
outb (CONF1_ADDR_PORT +3, 0);
|
||||
mode1res = inl (CONF1_ADDR_PORT);
|
||||
outl (CONF1_ADDR_PORT, oldval1);
|
||||
|
||||
if (bootverbose)
|
||||
printf ("pcibus_setup(1a):\tmode1res=0x%08lx (0x%08lx)\n",
|
||||
mode1res, CONF1_ENABLE_CHK);
|
||||
|
||||
if (mode1res) {
|
||||
if (pcibus_check())
|
||||
return;
|
||||
};
|
||||
|
||||
outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK1);
|
||||
mode1res = inl(CONF1_ADDR_PORT);
|
||||
outl (CONF1_ADDR_PORT, oldval1);
|
||||
|
||||
if (bootverbose)
|
||||
printf ("pcibus_setup(1b):\tmode1res=0x%08lx (0x%08lx)\n",
|
||||
mode1res, CONF1_ENABLE_CHK1);
|
||||
|
||||
if ((mode1res & CONF1_ENABLE_MSK1) == CONF1_ENABLE_RES1) {
|
||||
if (pcibus_check())
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
/*---------------------------------------
|
||||
** Try configuration mechanism 2 ...
|
||||
**---------------------------------------
|
||||
*/
|
||||
|
||||
oldval2 = inb (CONF2_ENABLE_PORT);
|
||||
|
||||
if (bootverbose) {
|
||||
printf ("pcibus_setup(2):\tmode 2 enable port (0x0cf8) is 0x%02x\n", oldval2);
|
||||
}
|
||||
|
||||
if ((oldval2 & 0xf0) == 0) {
|
||||
|
||||
pci_mechanism = 2;
|
||||
pci_maxdevice = 16;
|
||||
|
||||
outb (CONF2_ENABLE_PORT, CONF2_ENABLE_CHK);
|
||||
mode2res = inb(CONF2_ENABLE_PORT);
|
||||
outb (CONF2_ENABLE_PORT, oldval2);
|
||||
|
||||
if (bootverbose)
|
||||
printf ("pcibus_setup(2a):\tmode2res=0x%02x (0x%02x)\n",
|
||||
mode2res, CONF2_ENABLE_CHK);
|
||||
|
||||
if (mode2res == CONF2_ENABLE_RES) {
|
||||
if (bootverbose)
|
||||
printf ("pcibus_setup(2a):\tnow trying mechanism 2\n");
|
||||
|
||||
if (pcibus_check())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------
|
||||
** No PCI bus host bridge found
|
||||
**---------------------------------------
|
||||
*/
|
||||
|
||||
pci_mechanism = 0;
|
||||
pci_maxdevice = 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
**
|
||||
** Build a pcitag from bus, device and function number
|
||||
**
|
||||
**--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static pcici_t
|
||||
pcibus_tag (unsigned char bus, unsigned char device, unsigned char func)
|
||||
{
|
||||
pcici_t tag;
|
||||
|
||||
tag.cfg1 = 0;
|
||||
if (func >= 8) return tag;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
|
||||
case 1:
|
||||
if (device < 32) {
|
||||
tag.cfg1 = CONF1_ENABLE
|
||||
| (((u_long) bus ) << 16ul)
|
||||
| (((u_long) device) << 11ul)
|
||||
| (((u_long) func ) << 8ul);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (device < 16) {
|
||||
tag.cfg2.port = 0xc000 | (device << 8ul);
|
||||
tag.cfg2.enable = 0xf0 | (func << 1ul);
|
||||
tag.cfg2.forward = bus;
|
||||
}
|
||||
break;
|
||||
};
|
||||
return tag;
|
||||
}
|
||||
|
||||
static pcici_t
|
||||
pcibus_ftag (pcici_t tag, u_char func)
|
||||
{
|
||||
switch (pci_mechanism) {
|
||||
|
||||
case 1:
|
||||
tag.cfg1 &= ~0x700ul;
|
||||
tag.cfg1 |= (((u_long) func) << 8ul);
|
||||
break;
|
||||
case 2:
|
||||
tag.cfg2.enable = 0xf0 | (func << 1ul);
|
||||
break;
|
||||
};
|
||||
return tag;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
**
|
||||
** Read register from configuration space.
|
||||
**
|
||||
**--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static u_long
|
||||
pcibus_read (pcici_t tag, u_long reg)
|
||||
{
|
||||
u_long addr, data = 0;
|
||||
|
||||
if (!tag.cfg1) return (0xfffffffful);
|
||||
|
||||
switch (pci_mechanism) {
|
||||
|
||||
case 1:
|
||||
addr = tag.cfg1 | (reg & 0xfc);
|
||||
#ifdef PCI_DEBUG
|
||||
printf ("pci_conf_read(1): addr=%x ", addr);
|
||||
#endif
|
||||
outl (CONF1_ADDR_PORT, addr);
|
||||
data = inl (CONF1_DATA_PORT);
|
||||
outl (CONF1_ADDR_PORT, 0 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
addr = tag.cfg2.port | (reg & 0xfc);
|
||||
#ifdef PCI_DEBUG
|
||||
printf ("pci_conf_read(2): addr=%x ", addr);
|
||||
#endif
|
||||
outb (CONF2_ENABLE_PORT , tag.cfg2.enable );
|
||||
outb (CONF2_FORWARD_PORT, tag.cfg2.forward);
|
||||
|
||||
data = inl ((u_short) addr);
|
||||
|
||||
outb (CONF2_ENABLE_PORT, 0);
|
||||
outb (CONF2_FORWARD_PORT, 0);
|
||||
break;
|
||||
};
|
||||
|
||||
#ifdef PCI_DEBUG
|
||||
printf ("data=%x\n", data);
|
||||
#endif
|
||||
|
||||
return (data);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
**
|
||||
** Write register into configuration space.
|
||||
**
|
||||
**--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
pcibus_write (pcici_t tag, u_long reg, u_long data)
|
||||
{
|
||||
u_long addr;
|
||||
|
||||
if (!tag.cfg1) return;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
|
||||
case 1:
|
||||
addr = tag.cfg1 | (reg & 0xfc);
|
||||
#ifdef PCI_DEBUG
|
||||
printf ("pci_conf_write(1): addr=%x data=%x\n",
|
||||
addr, data);
|
||||
#endif
|
||||
outl (CONF1_ADDR_PORT, addr);
|
||||
outl (CONF1_DATA_PORT, data);
|
||||
outl (CONF1_ADDR_PORT, 0 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
addr = tag.cfg2.port | (reg & 0xfc);
|
||||
#ifdef PCI_DEBUG
|
||||
printf ("pci_conf_write(2): addr=%x data=%x\n",
|
||||
addr, data);
|
||||
#endif
|
||||
outb (CONF2_ENABLE_PORT, tag.cfg2.enable);
|
||||
outb (CONF2_FORWARD_PORT, tag.cfg2.forward);
|
||||
|
||||
outl ((u_short) addr, data);
|
||||
|
||||
outb (CONF2_ENABLE_PORT, 0);
|
||||
outb (CONF2_FORWARD_PORT, 0);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
**
|
||||
** Register an interupt handler for a pci device.
|
||||
**
|
||||
**-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
pcibus_ihandler_attach (int irq, inthand2_t *func, int arg, unsigned * maskptr)
|
||||
{
|
||||
char buf[16];
|
||||
char *cp;
|
||||
int free_id, id, result;
|
||||
|
||||
sprintf(buf, "pci irq%d", irq);
|
||||
for (cp = intrnames, free_id = 0, id = 0; id < NR_DEVICES; id++) {
|
||||
if (strcmp(cp, buf) == 0)
|
||||
break;
|
||||
if (free_id <= 0 && strcmp(cp, "pci irqnn") == 0)
|
||||
free_id = id;
|
||||
while (*cp++ != '\0')
|
||||
;
|
||||
}
|
||||
if (id == NR_DEVICES) {
|
||||
id = free_id;
|
||||
if (id == 0) {
|
||||
/*
|
||||
* All pci irq counters are in use, perhaps because
|
||||
* config is old so there aren't any. Abuse the
|
||||
* clk0 counter.
|
||||
*/
|
||||
printf (
|
||||
"pcibus_ihandler_attach: counting pci irq%d's as clk0 irqs\n",
|
||||
irq);
|
||||
}
|
||||
}
|
||||
result = register_intr(
|
||||
irq, /* isa irq */
|
||||
id, /* device id */
|
||||
0, /* flags? */
|
||||
func, /* handler */
|
||||
maskptr, /* mask pointer */
|
||||
arg); /* handler arg */
|
||||
|
||||
if (result) {
|
||||
printf ("@@@ pcibus_ihandler_attach: result=%d\n", result);
|
||||
return (result);
|
||||
};
|
||||
update_intr_masks();
|
||||
|
||||
INTREN ((1ul<<irq));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcibus_ihandler_detach (int irq, inthand2_t *func)
|
||||
{
|
||||
int result;
|
||||
|
||||
INTRDIS ((1ul<<irq));
|
||||
|
||||
result = unregister_intr (irq, func);
|
||||
|
||||
if (result)
|
||||
printf ("@@@ pcibus_ihandler_detach: result=%d\n", result);
|
||||
|
||||
update_intr_masks();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
pcibus_imask_include (int irq, unsigned* maskptr)
|
||||
{
|
||||
unsigned mask;
|
||||
|
||||
if (!maskptr) return (0);
|
||||
|
||||
mask = 1ul << irq;
|
||||
|
||||
if (*maskptr & mask)
|
||||
return (-1);
|
||||
|
||||
INTRMASK (*maskptr, mask);
|
||||
update_intr_masks();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcibus_imask_exclude (int irq, unsigned* maskptr)
|
||||
{
|
||||
unsigned mask;
|
||||
|
||||
if (!maskptr) return (0);
|
||||
|
||||
mask = 1ul << irq;
|
||||
|
||||
if (! (*maskptr & mask))
|
||||
return (-1);
|
||||
|
||||
*maskptr &= ~mask;
|
||||
update_intr_masks();
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* NEED A COPYRIGHT NOPTICE HERE
|
||||
*
|
||||
* $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <machine/clock.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
|
||||
#ifdef GUPROF
|
||||
extern u_int cputime __P((void));
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
asm("
|
||||
GM_STATE = 0
|
||||
GMON_PROF_OFF = 3
|
||||
|
||||
.text
|
||||
.align 4,0x90
|
||||
.globl __mcount
|
||||
__mcount:
|
||||
#
|
||||
# Check that we are profiling. Do it early for speed.
|
||||
#
|
||||
cmpl $GMON_PROF_OFF,__gmonparam+GM_STATE
|
||||
je Lmcount_exit
|
||||
#
|
||||
# __mcount is the same as mcount except the caller hasn't changed
|
||||
# the stack except to call here, so the caller's raddr is above
|
||||
# our raddr.
|
||||
#
|
||||
movl 4(%esp),%edx
|
||||
jmp Lgot_frompc
|
||||
|
||||
.align 4,0x90
|
||||
.globl mcount
|
||||
mcount:
|
||||
cmpl $GMON_PROF_OFF,__gmonparam+GM_STATE
|
||||
je Lmcount_exit
|
||||
#
|
||||
# The caller's stack frame has already been built, so %ebp is
|
||||
# the caller's frame pointer. The caller's raddr is in the
|
||||
# caller's frame following the caller's caller's frame pointer.
|
||||
#
|
||||
movl 4(%ebp),%edx
|
||||
Lgot_frompc:
|
||||
#
|
||||
# Our raddr is the caller's pc.
|
||||
#
|
||||
movl (%esp),%eax
|
||||
|
||||
pushf
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
cli
|
||||
call _mcount
|
||||
addl $8,%esp
|
||||
popf
|
||||
Lmcount_exit:
|
||||
ret
|
||||
");
|
||||
#else /* !__GNUC__ */
|
||||
#error
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef GUPROF
|
||||
/*
|
||||
* mexitcount saves the return register(s), loads selfpc and calls
|
||||
* mexitcount(selfpc) to do the work. Someday it should be in a machine
|
||||
* dependent file together with cputime(), __mcount and mcount. cputime()
|
||||
* can't just be put in machdep.c because it has to be compiled without -pg.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
asm("
|
||||
.text
|
||||
#
|
||||
# Dummy label to be seen when gprof -u hides mexitcount.
|
||||
#
|
||||
.align 4,0x90
|
||||
.globl __mexitcount
|
||||
__mexitcount:
|
||||
nop
|
||||
|
||||
GMON_PROF_HIRES = 4
|
||||
|
||||
.align 4,0x90
|
||||
.globl mexitcount
|
||||
mexitcount:
|
||||
cmpl $GMON_PROF_HIRES,__gmonparam+GM_STATE
|
||||
jne Lmexitcount_exit
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
movl 8(%esp),%eax
|
||||
pushf
|
||||
pushl %eax
|
||||
cli
|
||||
call _mexitcount
|
||||
addl $4,%esp
|
||||
popf
|
||||
popl %eax
|
||||
popl %edx
|
||||
Lmexitcount_exit:
|
||||
ret
|
||||
");
|
||||
#else /* !__GNUC__ */
|
||||
#error
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/*
|
||||
* Return the time elapsed since the last call. The units are machine-
|
||||
* dependent.
|
||||
*/
|
||||
u_int
|
||||
cputime()
|
||||
{
|
||||
u_int count;
|
||||
u_int delta;
|
||||
u_char low;
|
||||
static u_int prev_count;
|
||||
|
||||
/*
|
||||
* Read the current value of the 8254 timer counter 0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
low = inb(TIMER_CNTR0);
|
||||
count = low | (inb(TIMER_CNTR0) << 8);
|
||||
|
||||
/*
|
||||
* The timer counts down from TIMER_CNTR0_MAX to 0 and then resets.
|
||||
* While profiling is enabled, this routine is called at least twice
|
||||
* per timer reset (for mcounting and mexitcounting hardclock()),
|
||||
* so at most one reset has occurred since the last call, and one
|
||||
* has occurred iff the current count is larger than the previous
|
||||
* count. This allows counter underflow to be detected faster
|
||||
* than in microtime().
|
||||
*/
|
||||
delta = prev_count - count;
|
||||
prev_count = count;
|
||||
if ((int) delta <= 0)
|
||||
return (delta + timer0_max_count);
|
||||
return (delta);
|
||||
}
|
||||
#else /* not GUPROF */
|
||||
#ifdef __GNUC__
|
||||
asm("
|
||||
.text
|
||||
.align 4,0x90
|
||||
.globl mexitcount
|
||||
mexitcount:
|
||||
ret
|
||||
");
|
||||
#else /* !__GNUC__ */
|
||||
#error
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* GUPROF */
|
@ -1,520 +0,0 @@
|
||||
/*
|
||||
* random_machdep.c -- A strong random number generator
|
||||
*
|
||||
* $Id: random_machdep.c,v 1.7 1996/10/09 21:46:41 asami Exp $
|
||||
*
|
||||
* Version 0.95, last modified 18-Oct-95
|
||||
*
|
||||
* Copyright Theodore Ts'o, 1994, 1995. 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, and the entire permission notice in its entirety,
|
||||
* including the disclaimer of warranties.
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* ALTERNATIVELY, this product may be distributed under the terms of
|
||||
* the GNU Public License, in which case the provisions of the GPL are
|
||||
* required INSTEAD OF the above restrictions. (This clause is
|
||||
* necessary due to a potential bad interaction between the GPL and
|
||||
* the restrictions contained in a BSD-style copyright.)
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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 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 for PC-9801 by KATO T. of Nagoya University
|
||||
*/
|
||||
|
||||
#include "opt_cpu.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/random.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
#endif
|
||||
|
||||
#define MAX_BLKDEV 4
|
||||
|
||||
/*
|
||||
* The pool is stirred with a primitive polynomial of degree 128
|
||||
* over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
|
||||
* For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
|
||||
*/
|
||||
#define POOLWORDS 128 /* Power of 2 - note that this is 32-bit words */
|
||||
#define POOLBITS (POOLWORDS*32)
|
||||
|
||||
#if POOLWORDS == 128
|
||||
#define TAP1 99 /* The polynomial taps */
|
||||
#define TAP2 59
|
||||
#define TAP3 31
|
||||
#define TAP4 9
|
||||
#define TAP5 7
|
||||
#elif POOLWORDS == 64
|
||||
#define TAP1 62 /* The polynomial taps */
|
||||
#define TAP2 38
|
||||
#define TAP3 10
|
||||
#define TAP4 6
|
||||
#define TAP5 1
|
||||
#else
|
||||
#error No primitive polynomial available for chosen POOLWORDS
|
||||
#endif
|
||||
|
||||
#define WRITEBUFFER 512 /* size in bytes */
|
||||
|
||||
/* There is actually only one of these, globally. */
|
||||
struct random_bucket {
|
||||
u_int add_ptr;
|
||||
u_int entropy_count;
|
||||
int input_rotate;
|
||||
u_int32_t *pool;
|
||||
struct selinfo rsel;
|
||||
};
|
||||
|
||||
/* There is one of these per entropy source */
|
||||
struct timer_rand_state {
|
||||
u_long last_time;
|
||||
int last_delta;
|
||||
int nbits;
|
||||
};
|
||||
|
||||
static struct random_bucket random_state;
|
||||
static u_int32_t random_pool[POOLWORDS];
|
||||
static struct timer_rand_state keyboard_timer_state;
|
||||
static struct timer_rand_state extract_timer_state;
|
||||
static struct timer_rand_state irq_timer_state[ICU_LEN];
|
||||
#ifdef notyet
|
||||
static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
|
||||
#endif
|
||||
static struct wait_queue *random_wait;
|
||||
|
||||
inthand2_t *sec_intr_handler[ICU_LEN];
|
||||
int sec_intr_unit[ICU_LEN];
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
void
|
||||
rand_initialize(void)
|
||||
{
|
||||
random_state.add_ptr = 0;
|
||||
random_state.entropy_count = 0;
|
||||
random_state.pool = random_pool;
|
||||
random_wait = NULL;
|
||||
random_state.rsel.si_flags = 0;
|
||||
random_state.rsel.si_pid = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function adds an int into the entropy "pool". It does not
|
||||
* update the entropy estimate. The caller must do this if appropriate.
|
||||
*
|
||||
* The pool is stirred with a primitive polynomial of degree 128
|
||||
* over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
|
||||
* For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
|
||||
*
|
||||
* We rotate the input word by a changing number of bits, to help
|
||||
* assure that all bits in the entropy get toggled. Otherwise, if we
|
||||
* consistently feed the entropy pool small numbers (like ticks and
|
||||
* scancodes, for example), the upper bits of the entropy pool don't
|
||||
* get affected. --- TYT, 10/11/95
|
||||
*/
|
||||
static inline void
|
||||
add_entropy_word(struct random_bucket *r, const u_int32_t input)
|
||||
{
|
||||
u_int i;
|
||||
u_int32_t w;
|
||||
|
||||
w = (input << r->input_rotate) | (input >> (32 - r->input_rotate));
|
||||
i = r->add_ptr = (r->add_ptr - 1) & (POOLWORDS-1);
|
||||
if (i)
|
||||
r->input_rotate = (r->input_rotate + 7) & 31;
|
||||
else
|
||||
/*
|
||||
* At the beginning of the pool, add an extra 7 bits
|
||||
* rotation, so that successive passes spread the
|
||||
* input bits across the pool evenly.
|
||||
*/
|
||||
r->input_rotate = (r->input_rotate + 14) & 31;
|
||||
|
||||
/* XOR in the various taps */
|
||||
w ^= r->pool[(i+TAP1)&(POOLWORDS-1)];
|
||||
w ^= r->pool[(i+TAP2)&(POOLWORDS-1)];
|
||||
w ^= r->pool[(i+TAP3)&(POOLWORDS-1)];
|
||||
w ^= r->pool[(i+TAP4)&(POOLWORDS-1)];
|
||||
w ^= r->pool[(i+TAP5)&(POOLWORDS-1)];
|
||||
w ^= r->pool[i];
|
||||
/* Rotate w left 1 bit (stolen from SHA) and store */
|
||||
r->pool[i] = (w << 1) | (w >> 31);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function adds entropy to the entropy "pool" by using timing
|
||||
* delays. It uses the timer_rand_state structure to make an estimate
|
||||
* of how any bits of entropy this call has added to the pool.
|
||||
*
|
||||
* The number "num" is also added to the pool - it should somehow describe
|
||||
* the type of event which just happened. This is currently 0-255 for
|
||||
* keyboard scan codes, and 256 upwards for interrupts.
|
||||
* On the i386, this is assumed to be at most 16 bits, and the high bits
|
||||
* are used for a high-resolution timer.
|
||||
*/
|
||||
static void
|
||||
add_timer_randomness(struct random_bucket *r, struct timer_rand_state *state,
|
||||
u_int num)
|
||||
{
|
||||
int delta, delta2;
|
||||
u_int nbits;
|
||||
u_int32_t time;
|
||||
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
if (i586_ctr_freq != 0) {
|
||||
num ^= (u_int32_t) rdtsc() << 16;
|
||||
r->entropy_count += 2;
|
||||
} else {
|
||||
#endif
|
||||
disable_intr();
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
num ^= inb(TIMER_CNTR0) << 16;
|
||||
num ^= inb(TIMER_CNTR0) << 24;
|
||||
enable_intr();
|
||||
r->entropy_count += 2;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
}
|
||||
#endif
|
||||
|
||||
time = ticks;
|
||||
|
||||
add_entropy_word(r, (u_int32_t) num);
|
||||
add_entropy_word(r, time);
|
||||
|
||||
/*
|
||||
* Calculate number of bits of randomness we probably
|
||||
* added. We take into account the first and second order
|
||||
* deltas in order to make our estimate.
|
||||
*/
|
||||
delta = time - state->last_time;
|
||||
state->last_time = time;
|
||||
|
||||
delta2 = delta - state->last_delta;
|
||||
state->last_delta = delta;
|
||||
|
||||
if (delta < 0) delta = -delta;
|
||||
if (delta2 < 0) delta2 = -delta2;
|
||||
delta = MIN(delta, delta2) >> 1;
|
||||
for (nbits = 0; delta; nbits++)
|
||||
delta >>= 1;
|
||||
|
||||
r->entropy_count += nbits;
|
||||
|
||||
/* Prevent overflow */
|
||||
if (r->entropy_count > POOLBITS)
|
||||
r->entropy_count = POOLBITS;
|
||||
|
||||
if (r->entropy_count >= 8)
|
||||
selwakeup(&random_state.rsel);
|
||||
}
|
||||
|
||||
void
|
||||
add_keyboard_randomness(u_char scancode)
|
||||
{
|
||||
add_timer_randomness(&random_state, &keyboard_timer_state, scancode);
|
||||
}
|
||||
|
||||
void
|
||||
add_interrupt_randomness(int irq)
|
||||
{
|
||||
(sec_intr_handler[irq])(sec_intr_unit[irq]);
|
||||
add_timer_randomness(&random_state, &irq_timer_state[irq], irq);
|
||||
}
|
||||
|
||||
#ifdef notused
|
||||
void
|
||||
add_blkdev_randomness(int major)
|
||||
{
|
||||
if (major >= MAX_BLKDEV)
|
||||
return;
|
||||
|
||||
add_timer_randomness(&random_state, &blkdev_timer_state[major],
|
||||
0x200+major);
|
||||
}
|
||||
#endif /* notused */
|
||||
|
||||
/*
|
||||
* MD5 transform algorithm, taken from code written by Colin Plumb,
|
||||
* and put into the public domain
|
||||
*
|
||||
* QUESTION: Replace this with SHA, which as generally received better
|
||||
* reviews from the cryptographic community?
|
||||
*/
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void
|
||||
MD5Transform(u_int32_t buf[4],
|
||||
u_int32_t const in[16])
|
||||
{
|
||||
u_int32_t a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#undef F1
|
||||
#undef F2
|
||||
#undef F3
|
||||
#undef F4
|
||||
#undef MD5STEP
|
||||
|
||||
|
||||
#if POOLWORDS % 16
|
||||
#error extract_entropy() assumes that POOLWORDS is a multiple of 16 words.
|
||||
#endif
|
||||
/*
|
||||
* This function extracts randomness from the "entropy pool", and
|
||||
* returns it in a buffer. This function computes how many remaining
|
||||
* bits of entropy are left in the pool, but it does not restrict the
|
||||
* number of bytes that are actually obtained.
|
||||
*/
|
||||
static inline int
|
||||
extract_entropy(struct random_bucket *r, char *buf, int nbytes)
|
||||
{
|
||||
int ret, i;
|
||||
u_int32_t tmp[4];
|
||||
|
||||
add_timer_randomness(r, &extract_timer_state, nbytes);
|
||||
|
||||
/* Redundant, but just in case... */
|
||||
if (r->entropy_count > POOLBITS)
|
||||
r->entropy_count = POOLBITS;
|
||||
/* Why is this here? Left in from Ted Ts'o. Perhaps to limit time. */
|
||||
if (nbytes > 32768)
|
||||
nbytes = 32768;
|
||||
|
||||
ret = nbytes;
|
||||
if (r->entropy_count / 8 >= nbytes)
|
||||
r->entropy_count -= nbytes*8;
|
||||
else
|
||||
r->entropy_count = 0;
|
||||
|
||||
while (nbytes) {
|
||||
/* Hash the pool to get the output */
|
||||
tmp[0] = 0x67452301;
|
||||
tmp[1] = 0xefcdab89;
|
||||
tmp[2] = 0x98badcfe;
|
||||
tmp[3] = 0x10325476;
|
||||
for (i = 0; i < POOLWORDS; i += 16)
|
||||
MD5Transform(tmp, r->pool+i);
|
||||
/* Modify pool so next hash will produce different results */
|
||||
add_entropy_word(r, tmp[0]);
|
||||
add_entropy_word(r, tmp[1]);
|
||||
add_entropy_word(r, tmp[2]);
|
||||
add_entropy_word(r, tmp[3]);
|
||||
/*
|
||||
* Run the MD5 Transform one more time, since we want
|
||||
* to add at least minimal obscuring of the inputs to
|
||||
* add_entropy_word(). --- TYT
|
||||
*/
|
||||
MD5Transform(tmp, r->pool);
|
||||
|
||||
/* Copy data to destination buffer */
|
||||
i = MIN(nbytes, 16);
|
||||
bcopy(tmp, buf, i);
|
||||
nbytes -= i;
|
||||
buf += i;
|
||||
}
|
||||
|
||||
/* Wipe data from memory */
|
||||
bzero(tmp, sizeof(tmp));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef notused /* XXX NOT the exported kernel interface */
|
||||
/*
|
||||
* This function is the exported kernel interface. It returns some
|
||||
* number of good random numbers, suitable for seeding TCP sequence
|
||||
* numbers, etc.
|
||||
*/
|
||||
void
|
||||
get_random_bytes(void *buf, u_int nbytes)
|
||||
{
|
||||
extract_entropy(&random_state, (char *) buf, nbytes);
|
||||
}
|
||||
#endif /* notused */
|
||||
|
||||
u_int
|
||||
read_random(char *buf, u_int nbytes)
|
||||
{
|
||||
if ((nbytes * 8) > random_state.entropy_count)
|
||||
nbytes = random_state.entropy_count / 8;
|
||||
|
||||
return extract_entropy(&random_state, buf, nbytes);
|
||||
}
|
||||
|
||||
u_int
|
||||
read_random_unlimited(char *buf, u_int nbytes)
|
||||
{
|
||||
return extract_entropy(&random_state, buf, nbytes);
|
||||
}
|
||||
|
||||
#ifdef notused
|
||||
u_int
|
||||
write_random(const char *buf, u_int nbytes)
|
||||
{
|
||||
u_int i;
|
||||
u_int32_t word, *p;
|
||||
|
||||
for (i = nbytes, p = (u_int32_t *)buf;
|
||||
i >= sizeof(u_int32_t);
|
||||
i-= sizeof(u_int32_t), p++)
|
||||
add_entropy_word(&random_state, *p);
|
||||
if (i) {
|
||||
word = 0;
|
||||
bcopy(p, &word, i);
|
||||
add_entropy_word(&random_state, word);
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
#endif /* notused */
|
||||
|
||||
int
|
||||
random_select(dev_t dev, int rw, struct proc *p)
|
||||
{
|
||||
int s, ret;
|
||||
|
||||
if (rw == FWRITE)
|
||||
return 1; /* heh. */
|
||||
|
||||
s = splhigh();
|
||||
if (random_state.entropy_count >= 8)
|
||||
ret = 1;
|
||||
else {
|
||||
selrecord(p, &random_state.rsel);
|
||||
ret = 0;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,122 +0,0 @@
|
||||
Changelog for version 3.0-950506
|
||||
------------------------------------
|
||||
|
||||
Since 3.0-94xxxx
|
||||
- Too many changes
|
||||
|
||||
Since 3.0-940818
|
||||
- Fixes for Linux 1.1.4x.
|
||||
- Disables Disney Sound System with SG NX Pro 16 (less noise).
|
||||
|
||||
Since 2.90-2
|
||||
- Fixes to soundcard.h
|
||||
- Non blocking mode to /dev/sequencer
|
||||
- Experimental detection code for Ensoniq Soundscape.
|
||||
|
||||
Since 2.90
|
||||
- Minor and major bug fixes
|
||||
|
||||
Since pre-3.0-940712
|
||||
- GUS MAX support
|
||||
- Partially working MSS/WSS support (could work with some cards).
|
||||
- Hardware u-Law and A-Law support with AD1848/CS4248 and CS4231 codecs
|
||||
(GUS MAX, GUS16, WSS etc). Hardware ADPCM is possible with GUS16 and
|
||||
GUS MAX, but it doesn't work yet.
|
||||
Since pre-3.0-940426
|
||||
- AD1848/CS4248/CS4231 codec support (MSS, GUS MAX, Aztec, Orchid etc).
|
||||
This codec chip is used in various soundcards. This version is developed
|
||||
for the 16 bit daughtercard of GUS. It should work with other cards also
|
||||
if the following requirements are met:
|
||||
- The I/O, IRQ and DMA settings are jumper selectable or
|
||||
the card is initialized by booting DOS before booting Linux (etc.).
|
||||
- You add the IO, IRQ and DMA settings manually to the local.h.
|
||||
(Just define GUS16_BASE, GUS16_IRQ and GUS16_DMA). Note that
|
||||
the base address bust be the base address of the codec chip not the
|
||||
card itself. For the GUS16 these are the same but most MSS compatible
|
||||
cards have the codec located at card_base+4.
|
||||
- Some minor changes
|
||||
|
||||
Since 2.5 (******* MAJOR REWRITE ***********)
|
||||
|
||||
This version is based on v2.3. I have tried to maintain two versions
|
||||
together so that this one should have the same features than v2.5.
|
||||
Something may still be missing. If you notice such things, please let me
|
||||
know.
|
||||
|
||||
The Readme.v30 contains more details.
|
||||
|
||||
- /dev/midi## devices.
|
||||
- /dev/sequencer2
|
||||
|
||||
Since 2.5-beta2
|
||||
- Some fine tuning to the GUS v3.7 mixer code.
|
||||
- Fixed speed limits for the plain SB (1.0 to 2.0).
|
||||
|
||||
Since 2.5-beta
|
||||
- Fixed OPL-3 detection with SB. Caused problems with PAS16.
|
||||
- GUS v3.7 mixer support.
|
||||
|
||||
Since 2.4
|
||||
- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
|
||||
- Fixed truncated sound on /dev/dsp when the device is closed.
|
||||
- Linear volume mode for GUS
|
||||
- Pitch bends larger than +/- 2 octaves.
|
||||
- MIDI recording for SB and SB Pro. (Untested).
|
||||
- Some other fixes.
|
||||
- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
|
||||
- Implemented better detection for OPL-3. This should be useful if you
|
||||
have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
|
||||
- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
|
||||
|
||||
Since 2.3b
|
||||
- Fixed bug which made it impossible to make long recordings to disk.
|
||||
Recording was not restarted after a buffer overflow situation.
|
||||
- Limited mixer support for GUS.
|
||||
- Numerous improvements to the GUS driver by Andrew Robinson. Including
|
||||
some click removal etc.
|
||||
|
||||
Since 2.3
|
||||
- Fixed some minor bugs in the SB16 driver.
|
||||
|
||||
Since 2.2b
|
||||
- Full SB16 DSP support. 8/16 bit, mono/stereo
|
||||
- The SCO and FreeBSD versions should be in sync now. There are some
|
||||
problems with SB16 and GUS in the freebsd versions.
|
||||
The DMA buffer allocation of the SCO version has been polished but
|
||||
there could still be some problems. At least it hogs memory.
|
||||
The DMA channel
|
||||
configuration method used in the sco/System is a hack.
|
||||
- Support for the MPU emulation of the SB16.
|
||||
- Some big arrays are now allocated boot time. This makes the bss segment
|
||||
smaller which makes it possible to use the full driver with
|
||||
NetBSD. These arrays are not allocated if no suitable soundcard is available.
|
||||
- Fixed a bug in the compute_and_set_volume in gus_wave.c
|
||||
- Fixed the too fast mono playback problem of SB Pro and PAS16.
|
||||
|
||||
Since 2.2
|
||||
- Stereo recording for SB Pro. Somehow it was missing and nobody
|
||||
had noticed it earlier.
|
||||
- Minor polishing.
|
||||
- Interpreting of boot time arguments (sound=) for Linux.
|
||||
- Breakup of sb_dsp.c. Parts of the code has been moved to
|
||||
sb_mixer.c and sb_midi.c
|
||||
|
||||
Since 2.1
|
||||
- Preliminary support for SB16.
|
||||
- The SB16 mixer is supported in it's native mode.
|
||||
- Digitized voice capability up to 44.1 kHz/8 bit/mono
|
||||
(16 bit and stereo support coming in the next release).
|
||||
- Fixed some bugs in the digitized voice driver for PAS16.
|
||||
- Proper initialization of the SB emulation of latest PAS16 models.
|
||||
|
||||
- Significantly improved /dev/dsp and /dev/audio support.
|
||||
- Now supports half duplex mode. It's now possible to record and
|
||||
playback without closing and reopening the device.
|
||||
- It's possible to use smaller buffers than earlier. There is a new
|
||||
ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &n) where n should be 1, 2 or 4.
|
||||
This call instructs the driver to use smaller buffers. The default
|
||||
buffer size (0.5 to 1.0 seconds) is divided by n. Should be called
|
||||
immediately after opening the device.
|
||||
|
||||
Since 2.0
|
||||
Just cosmetic changes.
|
@ -1,86 +0,0 @@
|
||||
VoxWare v2.90 release notes
|
||||
--------------------------
|
||||
|
||||
|
||||
This version includes some hidden features which
|
||||
are described in the file experimental.txt
|
||||
Some of these features are not enabled by default. Look at
|
||||
experimental.txt for more info.
|
||||
|
||||
I just decided to release this version with some
|
||||
incompletely implemented features disabled since
|
||||
there are some new features required by a popular
|
||||
application. In addition there is also support
|
||||
for the GUS MAX and the 16 bit sampling option of GUS.
|
||||
|
||||
The MSS/WSS support works now. At least with SG NX Pro 16.
|
||||
|
||||
********* IMPORTANT *****************************************
|
||||
Linux 1.0 or later is required to by this driver version.
|
||||
|
||||
Don't distribute binaries which use /dev/sequencer and are
|
||||
compiled with the soundcard.h of this version. They will
|
||||
not work with version 2.x of the driver.
|
||||
*************************************************************
|
||||
|
||||
|
||||
You will need the snd-util-2.5.tar.gz and snd-data-0.1.tar.Z
|
||||
packages to use this driver. They should be in the same
|
||||
ftp site or BBS from where you got this driver. For
|
||||
example at nic.funet.fi:pub/OS/Linux/*.
|
||||
|
||||
If you are looking for the installation instructions, please
|
||||
look at linux/Readme.
|
||||
|
||||
Compatibility with the earlier versions
|
||||
---------------------------------------
|
||||
|
||||
This version is backward compatible with the version 2.X. All programs
|
||||
compiled with sys/soundcard.h of v2.X should work without problems.
|
||||
PROGRAMS COMPILED WITH THE sys/soundcard.h OF THIS VERSION WILL NOT
|
||||
WORK WITH v2.X DRIVER. BE CAREFUL WHEN DISTRIBUTING BINARIES COMPILED
|
||||
FOR THIS VERSION.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
This driver contains code by several contributors. In addition several other
|
||||
persons have given useful suggestions. The following is a list of major
|
||||
contributors. (I could have forgotten some names.)
|
||||
|
||||
Craig Metz 1/2 of the PAS16 Mixer and PCM support
|
||||
Rob Hooft Volume computation algorithm for the FM synth.
|
||||
Mika Liljeberg uLaw encoding and decoding routines
|
||||
Greg Lee Volume computation algorithm for the GUS and
|
||||
lot's of valuable suggestions.
|
||||
Andy Warner ISC port
|
||||
Jim Lowe FreeBSD port
|
||||
Anders Baekgaard Bughunting and valuable suggestions.
|
||||
Joerg Schubert SB16 DSP support.
|
||||
Andrew Robinson Improvements to the GUS driver
|
||||
Megens SA MIDI recording for SB and SB Pro.
|
||||
Mikael Nordqvist Linear volume support for GUS.
|
||||
Mikael Nordqvist Linear volume support for GUS.
|
||||
Ian Hartas SVR4.2 port
|
||||
Markus Aroharju and
|
||||
Risto Kankkunen Major contributions to the mixer support
|
||||
of GUS v3.7.
|
||||
Hunyue Yau Mixer support for SG NX Pro.
|
||||
Marc Hoffman PSS support.
|
||||
|
||||
Regards,
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
||||
|
||||
Snail mail: Hannu Savolainen
|
||||
Hiekkalaiturintie 3 A 8
|
||||
00980 Helsinki
|
||||
Finland
|
||||
FAX: +358 0 341 6272 (answers if I have my machine (mgetty) on).
|
||||
|
||||
NOTE! I probably don't answer to Snail mail or FAX messages. Sending answer
|
||||
to each of them is simply too expensive and time consuming. However I
|
||||
try to reply every email message I get (within a week). If you don't
|
||||
get response, please check how your address is written in the message
|
||||
header. I can't answer if I don't have a valid reply address.
|
@ -1,6 +0,0 @@
|
||||
Informations about Audio Excel DSP 16 can be found in the source
|
||||
file aedsp16.c
|
||||
Please, read the head of the source before using it. It contain useful
|
||||
informations.
|
||||
|
||||
Riccardo
|
@ -1,87 +0,0 @@
|
||||
Linux sound-driver module
|
||||
(c) Peter Trattler
|
||||
License: GPL (Gnu Public License)
|
||||
|
||||
|
||||
Idea:
|
||||
|
||||
I've modified the sources for the sound driver to allow simply insert and
|
||||
remove the sound driver from the kernel by calling (only available for Linux)
|
||||
|
||||
insmod /usr/src/linux/modules/sound.o
|
||||
|
||||
and
|
||||
|
||||
rmmod sound
|
||||
|
||||
This may be useful if you are doing one of the following things:
|
||||
|
||||
1) Debugging the sound driver
|
||||
2) Creating a new device within the sound-driver
|
||||
3) You do not the sound driver all the time (as it wastes quite a lot of
|
||||
memory for its buffers)
|
||||
|
||||
|
||||
Compilation:
|
||||
|
||||
Go to /usr/src/linux and make the following steps:
|
||||
|
||||
a) configure the sound driver: To do that call "make config" and enable the
|
||||
sound-driver -- you will be asked different questions about your
|
||||
sound-hardware (remember not to use a too big DMA-Buffer size; you
|
||||
should use 16kB, if you have 16Bit devices, otherwise you can use 32kB)
|
||||
|
||||
b) disable the sound driver in the kernel: call make config again but answer
|
||||
'N' to "Sound card support"
|
||||
|
||||
c) run "make modules"; the sound-driver sound.o should end up in
|
||||
/usr/src/linux/modules
|
||||
|
||||
|
||||
If memory is tight:
|
||||
|
||||
I've allocated at about 70kB for the sound-drivers internal tables. If this
|
||||
is too much, 'insmod sound.o' will generate the following warning
|
||||
...
|
||||
use 'insmod memsize=xxxx'
|
||||
...
|
||||
You can only use this command, if you have (I think) at least
|
||||
modules-1.1.87 or up. You can also switch debugging on by running the command
|
||||
|
||||
insmod sound.o debugmem=1
|
||||
|
||||
|
||||
Files I changed:
|
||||
|
||||
I've only changed the files soundcard.c(most changes) and some changes within
|
||||
the Makefile, sound_config.h and the Makefile in /usr/src/linux/drivers
|
||||
|
||||
|
||||
Bugs:
|
||||
|
||||
a) As the kmalloc (..., GFP_DMA) caused some unexpected errors (I don't know if
|
||||
it is my fault), I created some code, which is (by default) enabled by
|
||||
|
||||
#define KMALLOC_DMA_BROKEN 1 (within soundcard.c).
|
||||
|
||||
It trys to allocate a large enough region, so that the complete dma-buffer
|
||||
can be occupied in this space. If it does not fit within this region it
|
||||
doubles the size of it. But this can cause problems, if the sound-buffer is
|
||||
too big (as kmalloc can only handle regions at up to circa 100kB).
|
||||
|
||||
So take care to use for 8Bit devices a sound-DMA-buffer of 32kB (maximum)
|
||||
and for 16Bit devices a maximum of 16kB. Otherwise the allocation scheme
|
||||
might fail.
|
||||
|
||||
b) Buffers allocated by the different sound devices via calls to kmalloc are
|
||||
not freed, if the sound driver is removed again (these buffers tend to be
|
||||
quite small -- so it does not harm a lot)
|
||||
|
||||
c) If there is not enough (kernel-) memory available, the installation of
|
||||
the sound-driver fails. (This happens quite often, if you did not install the
|
||||
driver right after booting -- [PS: I've only got 5MB of Ram, so this might
|
||||
be the source for this problem])
|
||||
|
||||
|
||||
Author:
|
||||
Peter Trattler (peter@sbox.tu-graz.ac.at)
|
@ -1,142 +0,0 @@
|
||||
VoxWare v3.0
|
||||
------------
|
||||
|
||||
This is a late alpha/early beta of the VoxWare v3.0 to be relased May/June 95.
|
||||
|
||||
All features of v2.90-2 should work as earlier. There could be some
|
||||
omissions but they are unintentional. I started this version thread
|
||||
after v2.3 so all features implemented before it are there.
|
||||
|
||||
New features
|
||||
============
|
||||
|
||||
There are now two new device interfaces. The /dev/midi## is a raw
|
||||
tty like interface to MIDI ports. There is a device file for each MIDI
|
||||
port on your system. They are named (/dev/midi00 to /dev/midiNN).
|
||||
The second addition is the /dev/music which is higher level interface
|
||||
than the old /dev/sequencer. It's intended for writing device independent
|
||||
applications like sequencers.
|
||||
|
||||
/dev/midi##
|
||||
-----------
|
||||
|
||||
This interface should be usefull for applications like MIDI sysex librarians.
|
||||
There are (currently) no timing features so making music could be impossible.
|
||||
|
||||
There are as many /dev/midi## devices as there are MIDI ports in the system.
|
||||
The /dev/midi00 is connected to the first one, /dev/midi01 to the second etc.
|
||||
|
||||
These devices work like tty devices in raw mode. Everything written to them is
|
||||
sent out to the MIDI port. There is currently an extra delay of at most
|
||||
1/100th of sec but it will be removed later.
|
||||
|
||||
The reading algorithm is little bit more complicated. There are two different
|
||||
cases:
|
||||
|
||||
1) There is at least one byte in the input buffer.
|
||||
|
||||
The read returns as many bytes as it can without waiting for more bytes.
|
||||
For example when a process reads 100 bytes and there are 10 bytes in the
|
||||
buffer, the read returns just 10 bytes.
|
||||
|
||||
2) The input buffer is empty when the process calls read.
|
||||
|
||||
The read waits for the first byte and then continues as in case 1. By
|
||||
default it waits infinitely but there is an ioctl for setting a timeout
|
||||
for this. The ioctl(fd, SNDCTL_MIDI_PRETIME, &time) changes the timeout.
|
||||
The time is given in 1/10th of seconds (10 means one second).
|
||||
|
||||
Other ioctl calls:
|
||||
|
||||
ioctl(fd, SNDCTL_MIDI_MPUMODE, &mode) is available for full MPU-401
|
||||
compatible devices such as MPU-IPC-T, MQ PC Midi Card or MQX-32.
|
||||
It's not available for the so called MPU UART ports of some soundcards
|
||||
(PAS16, SB16 etc). By default the MIDI port is in UART mode after open.
|
||||
If this ioctl is called with mode=1, the interface is put to the intelligent
|
||||
(coprocessor) mode. NOTE! The MIDI port will be reset when this ioctl is called.
|
||||
It could have some strange effects if not called immediately after open. This
|
||||
vall returns EINVAL if the midi port doesn't support the MPU-401 intelligent
|
||||
mode.
|
||||
|
||||
ioctl(fd, SNDCTL_MIDI_MPUCMD, &cmdstruct) is valid only if the MIDI port
|
||||
is put to the coprocessor mode using ioctl(SNDCTL_MIDI_MPUMODE). It's used to
|
||||
send commands to a MPU-401 compatible MIDI cards. Please refer to the
|
||||
MPU-401 Technical Reference Manual (or Music Quest Technical Reference
|
||||
Manual) for descriptions of the commands.
|
||||
|
||||
The argument of SNDCTL_MIDI_MPUCOMMAND is of type mpu_command_rec. It
|
||||
has the following fields:
|
||||
|
||||
typedef struct {
|
||||
unsigned char cmd;
|
||||
|
||||
char nr_args, nr_returns;
|
||||
unsigned char data[30];
|
||||
} mpu_command_rec;
|
||||
|
||||
where:
|
||||
cmd Contains the command number.
|
||||
nr_args Number of arguments of the command.
|
||||
MUST BE INITIALIZED BEFORE CALL
|
||||
nr_returns Number of bytes returned by the command.
|
||||
MUST BE INITIALIZED BEFORE CALL
|
||||
data Buffer for the command arguments and returned
|
||||
data.
|
||||
|
||||
Be extremely carefull with the nr_args and nr_returns fields. They
|
||||
must match the command. An incorrect value will put the card and
|
||||
the driver out of sync. Refer to the MPU-401/MQX-32M documentation for further
|
||||
datails.
|
||||
|
||||
|
||||
|
||||
/dev/music (/dev/sequencer2)
|
||||
----------------------------
|
||||
|
||||
This device file works much like the /dev/sequencer which has been present
|
||||
since the beginning. The main differences are the following:
|
||||
|
||||
- /dev/sequencer makes the MIDI ports to look like the synth devices. In fact
|
||||
the result is somewhere between the MIDI specification and the synth devices of
|
||||
/dev/sequencer. Both kind of devices are accessed using the SEQ_START_NOTE()
|
||||
like macros. The voice number parameters of the API macros have been redefined
|
||||
to denote MIDI channels. This means that the driver allocates voices for
|
||||
the channels automaticly (this is a responsibility/right of an application
|
||||
with /dev/sequencer). The result is that a SEQ_START_NOTE() macro has
|
||||
similar effects for a synth channel than on a MIDI port. This kind of
|
||||
solution provides better device independence than the /dev/sequencer. The
|
||||
drawback is that the new interface doesn't permit so low level access to the
|
||||
device as the /dev/sequencer does. An application developer must choose between
|
||||
these two interfaces. I think the old /dev/sequencer is better for applications
|
||||
like module players while the new one is better for making generic sequencer
|
||||
programs.
|
||||
|
||||
- There are no separate MIDI devices with the /dev/sequencer2. The
|
||||
ioctl(SNDCTL_SEQ_NRMIDIS) returns always zero. Instead the MIDI ports are
|
||||
shown as synth devices. ioctl(SNDCTL_SEQ_NRSYNTHS) on /dev/sequencer2 will
|
||||
return sum of internal synthesizers (GUS, OPL3) and MIDI ports in the systems.
|
||||
|
||||
- The new interface is used much like the ordinary /dev/sequencer. The
|
||||
event format is new so you have to use the API macros defined in the
|
||||
sys/soundcard.h. The interface is will propably change before the final 3.0
|
||||
release but using the API macros should ensure compatibility in source level.
|
||||
The new event format is not recognized by version 2.X so don't try to
|
||||
distribute binaries compiled with soundcard.h of v3.X.
|
||||
|
||||
- The basic API useage is similar to the current one. There are some new
|
||||
macros but the older ones should work as earlier. The most important
|
||||
incompatibility is that the /dev/sequencer2 driver allocates voices itself.
|
||||
The other one is that the application must send SEQ_START_TIMER() as it's
|
||||
first event. Otherwise the timer is not started and the application waits
|
||||
infinitely.
|
||||
|
||||
|
||||
There are several new features but I don't document them here. There are
|
||||
some info in the soundcard.h (near the end). I have also included some
|
||||
sample code in the directory v30. Full documentation will
|
||||
appear in the Hacker's Guide later.
|
||||
|
||||
Don't hesitate to contact me in case you have questions or comments.
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* sound/adlib_card.c
|
||||
*
|
||||
* Detection routine for the AdLib card.
|
||||
*
|
||||
* 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/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
|
||||
|
||||
long
|
||||
attach_adlib_card (long mem_start, struct address_info *hw_config)
|
||||
{
|
||||
|
||||
if (opl3_detect (FM_MONO))
|
||||
{
|
||||
mem_start = opl3_init (mem_start);
|
||||
}
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
int
|
||||
probe_adlib (struct address_info *hw_config)
|
||||
{
|
||||
return opl3_detect (FM_MONO);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,587 +0,0 @@
|
||||
/*
|
||||
* sound/audio.c
|
||||
*
|
||||
* Device file manager for /dev/audio
|
||||
*
|
||||
* 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/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_SOUNDCARD
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
|
||||
#include <i386/isa/sound/ulaw.h>
|
||||
#include <i386/isa/sound/coproc.h>
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
static int wr_buff_no[MAX_AUDIO_DEV]; /*
|
||||
|
||||
* != -1, if there is
|
||||
* a incomplete output
|
||||
* block in the queue.
|
||||
*/
|
||||
static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
|
||||
|
||||
static int audio_mode[MAX_AUDIO_DEV];
|
||||
static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in noblocking mode */
|
||||
|
||||
#define AM_NONE 0
|
||||
#define AM_WRITE 1
|
||||
#define AM_READ 2
|
||||
|
||||
static char *wr_dma_buf[MAX_AUDIO_DEV];
|
||||
static int audio_format[MAX_AUDIO_DEV];
|
||||
static int local_conversion[MAX_AUDIO_DEV];
|
||||
|
||||
static int
|
||||
set_format (int dev, int fmt)
|
||||
{
|
||||
if (fmt != AFMT_QUERY)
|
||||
{
|
||||
|
||||
local_conversion[dev] = 0;
|
||||
|
||||
if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
|
||||
if (fmt == AFMT_MU_LAW)
|
||||
{
|
||||
fmt = AFMT_U8;
|
||||
local_conversion[dev] = AFMT_MU_LAW;
|
||||
}
|
||||
else
|
||||
fmt = AFMT_U8; /* This is always supported */
|
||||
|
||||
audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, fmt, 1);
|
||||
}
|
||||
|
||||
if (local_conversion[dev]) /* This shadows the HW format */
|
||||
return local_conversion[dev];
|
||||
|
||||
return audio_format[dev];
|
||||
}
|
||||
|
||||
int
|
||||
audio_open (int dev, struct fileinfo *file)
|
||||
{
|
||||
int ret;
|
||||
int bits;
|
||||
int dev_type = dev & 0x0f;
|
||||
int mode = file->mode & O_ACCMODE;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (dev_type == SND_DEV_DSP16)
|
||||
bits = 16;
|
||||
else
|
||||
bits = 8;
|
||||
|
||||
if ((ret = DMAbuf_open (dev, mode)) < 0)
|
||||
return ret;
|
||||
|
||||
if (audio_devs[dev]->coproc)
|
||||
if ((ret = audio_devs[dev]->coproc->
|
||||
open (audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
|
||||
{
|
||||
audio_release (dev, file);
|
||||
printk ("Sound: Can't access coprocessor device\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
local_conversion[dev] = 0;
|
||||
|
||||
if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, bits, 1) != bits)
|
||||
{
|
||||
audio_release (dev, file);
|
||||
return RET_ERROR (ENXIO);
|
||||
}
|
||||
|
||||
if (dev_type == SND_DEV_AUDIO)
|
||||
{
|
||||
set_format (dev, AFMT_MU_LAW);
|
||||
}
|
||||
else
|
||||
set_format (dev, bits);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
audio_mode[dev] = AM_NONE;
|
||||
wr_buff_size[dev] = wr_buff_ptr[dev] = 0;
|
||||
dev_nblock[dev] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
audio_release (int dev, struct fileinfo *file)
|
||||
{
|
||||
int mode;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
if (wr_buff_no[dev] >= 0)
|
||||
{
|
||||
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
|
||||
if (audio_devs[dev]->coproc)
|
||||
audio_devs[dev]->coproc->close (audio_devs[dev]->coproc->devc, COPR_PCM);
|
||||
DMAbuf_release (dev, mode);
|
||||
}
|
||||
|
||||
#ifdef NO_INLINE_ASM
|
||||
static void
|
||||
translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
buff[i] = table[buff[i]];
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void
|
||||
translate_bytes (const void *table, void *buff, unsigned long n)
|
||||
{
|
||||
__asm__ ("cld\n"
|
||||
"1:\tlodsb\n\t"
|
||||
"xlatb\n\t"
|
||||
"stosb\n\t"
|
||||
"loop 1b\n\t":
|
||||
: "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
|
||||
: "bx", "cx", "di", "si", "ax");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int c, p, l;
|
||||
int err;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
p = 0;
|
||||
c = count;
|
||||
|
||||
if (audio_mode[dev] == AM_READ) /*
|
||||
* Direction changed
|
||||
*/
|
||||
{
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
|
||||
audio_mode[dev] = AM_WRITE;
|
||||
|
||||
if (!count) /*
|
||||
* Flush output
|
||||
*/
|
||||
{
|
||||
if (wr_buff_no[dev] >= 0)
|
||||
{
|
||||
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (c)
|
||||
{ /*
|
||||
* Perform output blocking
|
||||
*/
|
||||
if (wr_buff_no[dev] < 0) /*
|
||||
* There is no incomplete buffers
|
||||
*/
|
||||
{
|
||||
if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev],
|
||||
&wr_buff_size[dev],
|
||||
dev_nblock[dev])) < 0)
|
||||
{
|
||||
/* Handle nonblocking mode */
|
||||
#if defined(__FreeBSD__)
|
||||
if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EWOULDBLOCK))
|
||||
return wr_buff_no[dev]; /*
|
||||
* XXX Return error, write() will
|
||||
* supply # of accepted bytes.
|
||||
* In fact, in FreeBSD the check
|
||||
* above should not be needed
|
||||
*/
|
||||
#else
|
||||
if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EAGAIN))
|
||||
return p; /* No more space. Return # of accepted bytes */
|
||||
#endif
|
||||
return wr_buff_no[dev];
|
||||
}
|
||||
wr_buff_ptr[dev] = 0;
|
||||
}
|
||||
|
||||
l = c;
|
||||
if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
|
||||
l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
|
||||
|
||||
if (!audio_devs[dev]->copy_from_user)
|
||||
{ /*
|
||||
* No device specific copy routine
|
||||
*/
|
||||
COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
|
||||
}
|
||||
else
|
||||
audio_devs[dev]->copy_from_user (dev,
|
||||
wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
|
||||
|
||||
|
||||
/*
|
||||
* Insert local processing here
|
||||
*/
|
||||
|
||||
if (local_conversion[dev] == AFMT_MU_LAW)
|
||||
{
|
||||
#ifdef linux
|
||||
/*
|
||||
* This just allows interrupts while the conversion is running
|
||||
*/
|
||||
__asm__ ("sti");
|
||||
#endif
|
||||
translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
|
||||
}
|
||||
|
||||
c -= l;
|
||||
p += l;
|
||||
wr_buff_ptr[dev] += l;
|
||||
|
||||
if (wr_buff_ptr[dev] >= wr_buff_size[dev])
|
||||
{
|
||||
if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int c, p, l;
|
||||
char *dmabuf;
|
||||
int buff_no;
|
||||
|
||||
dev = dev >> 4;
|
||||
p = 0;
|
||||
c = count;
|
||||
|
||||
if (audio_mode[dev] == AM_WRITE)
|
||||
{
|
||||
if (wr_buff_no[dev] >= 0)
|
||||
{
|
||||
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
audio_mode[dev] = AM_READ;
|
||||
|
||||
while (c)
|
||||
{
|
||||
if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l,
|
||||
dev_nblock[dev])) < 0)
|
||||
{
|
||||
/* Nonblocking mode handling. Return current # of bytes */
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
if (dev_nblock[dev] && buff_no == RET_ERROR (EWOULDBLOCK))
|
||||
return buff_no; /*
|
||||
* XXX Return error, read() will supply
|
||||
* # of bytes actually read. In fact,
|
||||
* in FreeBSD the check above should not
|
||||
* be needed
|
||||
*/
|
||||
#else
|
||||
if (dev_nblock[dev] && buff_no == RET_ERROR (EAGAIN))
|
||||
return p;
|
||||
#endif
|
||||
|
||||
return buff_no;
|
||||
}
|
||||
|
||||
if (l > c)
|
||||
l = c;
|
||||
|
||||
/*
|
||||
* Insert any local processing here.
|
||||
*/
|
||||
|
||||
if (local_conversion[dev] == AFMT_MU_LAW)
|
||||
{
|
||||
#ifdef linux
|
||||
/*
|
||||
* This just allows interrupts while the conversion is running
|
||||
*/
|
||||
__asm__ ("sti");
|
||||
#endif
|
||||
|
||||
translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
|
||||
}
|
||||
|
||||
COPY_TO_USER (buf, p, dmabuf, l);
|
||||
|
||||
DMAbuf_rmchars (dev, buff_no, l);
|
||||
|
||||
p += l;
|
||||
c -= l;
|
||||
}
|
||||
|
||||
return count - c;
|
||||
}
|
||||
|
||||
int
|
||||
audio_ioctl (int dev, struct fileinfo *file,
|
||||
unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'C')
|
||||
{
|
||||
if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
|
||||
return audio_devs[dev]->coproc->ioctl (audio_devs[dev]->coproc->devc, cmd, arg, 0);
|
||||
else
|
||||
printk ("/dev/dsp%d: No coprocessor for this device\n", dev);
|
||||
|
||||
return RET_ERROR (EREMOTEIO);
|
||||
}
|
||||
else
|
||||
switch (cmd)
|
||||
{
|
||||
case SNDCTL_DSP_SYNC:
|
||||
if (wr_buff_no[dev] >= 0)
|
||||
{
|
||||
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return DMAbuf_ioctl (dev, cmd, arg, 0);
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_POST:
|
||||
if (wr_buff_no[dev] >= 0)
|
||||
{
|
||||
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_RESET:
|
||||
wr_buff_no[dev] = -1;
|
||||
return DMAbuf_ioctl (dev, cmd, arg, 0);
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_GETFMTS:
|
||||
return IOCTL_OUT (arg, audio_devs[dev]->format_mask);
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_SETFMT:
|
||||
return IOCTL_OUT (arg, set_format (dev, IOCTL_IN (arg)));
|
||||
|
||||
case SNDCTL_DSP_GETISPACE:
|
||||
if (audio_mode[dev] == AM_WRITE)
|
||||
return RET_ERROR (EBUSY);
|
||||
|
||||
{
|
||||
audio_buf_info info;
|
||||
|
||||
int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (wr_buff_no[dev] != -1)
|
||||
info.bytes += wr_buff_ptr[dev];
|
||||
|
||||
IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SNDCTL_DSP_GETOSPACE:
|
||||
if (audio_mode[dev] == AM_READ)
|
||||
return RET_ERROR (EBUSY);
|
||||
|
||||
{
|
||||
audio_buf_info info;
|
||||
|
||||
int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (wr_buff_no[dev] != -1)
|
||||
info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
|
||||
|
||||
IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SNDCTL_DSP_NONBLOCK:
|
||||
dev_nblock[dev] = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
case FIONBIO: /* XXX Is this the same in Linux? */
|
||||
if (*(int *)arg)
|
||||
dev_nblock[dev] = 1;
|
||||
else
|
||||
dev_nblock[dev] = 0;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case FIOASYNC:
|
||||
return 0; /* XXX Useful for ampling input notification? */
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return DMAbuf_ioctl (dev, cmd, arg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
long
|
||||
audio_init (long mem_start)
|
||||
{
|
||||
/*
|
||||
* NOTE! This routine could be called several times during boot.
|
||||
*/
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#ifdef ALLOW_SELECT
|
||||
int
|
||||
audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
|
||||
{
|
||||
int l;
|
||||
char *dmabuf;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
switch (sel_type)
|
||||
{
|
||||
case SEL_IN:
|
||||
if (audio_mode[dev] != AM_READ && /* Wrong direction */
|
||||
audio_mode[dev] != AM_NONE)
|
||||
return 0;
|
||||
|
||||
if (DMAbuf_getrdbuffer (dev, &dmabuf, &l,
|
||||
1 /* Don't block */ ) >= 0)
|
||||
return 1; /* We have data */
|
||||
|
||||
return DMAbuf_select (dev, file, sel_type, wait);
|
||||
break;
|
||||
|
||||
case SEL_OUT:
|
||||
if (audio_mode[dev] != AM_WRITE && /* Wrong direction */
|
||||
audio_mode[dev] != AM_NONE)
|
||||
return 0;
|
||||
|
||||
if (wr_buff_no[dev] != -1)
|
||||
return 1; /* There is space in the current buffer */
|
||||
|
||||
return DMAbuf_select (dev, file, sel_type, wait);
|
||||
break;
|
||||
|
||||
case SEL_EX:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ALLOW_SELECT */
|
||||
|
||||
#else /* EXCLUDE_AUDIO */
|
||||
/*
|
||||
* Stub versions
|
||||
*/
|
||||
|
||||
int
|
||||
audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
int
|
||||
audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
int
|
||||
audio_open (int dev, struct fileinfo *file)
|
||||
{
|
||||
return RET_ERROR (ENXIO);
|
||||
}
|
||||
|
||||
void
|
||||
audio_release (int dev, struct fileinfo *file)
|
||||
{
|
||||
};
|
||||
int
|
||||
audio_ioctl (int dev, struct fileinfo *file,
|
||||
unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
int
|
||||
audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
|
||||
{
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
long
|
||||
audio_init (long mem_start)
|
||||
{
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,186 +0,0 @@
|
||||
/*
|
||||
* sound/dev_table.c
|
||||
*
|
||||
* Device call tables.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _DEV_TABLE_C_
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_SOUNDCARD
|
||||
|
||||
int
|
||||
snd_find_driver (int type)
|
||||
{
|
||||
int i, n = sizeof (sound_drivers) / sizeof (struct driver_info);
|
||||
|
||||
for (i = 0; i < (n - 1); i++)
|
||||
if (sound_drivers[i].card_type == type)
|
||||
return i;
|
||||
|
||||
return -1; /*
|
||||
* Not found
|
||||
*/
|
||||
}
|
||||
|
||||
static long
|
||||
sndtable_init (long mem_start)
|
||||
{
|
||||
int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
|
||||
int drv;
|
||||
|
||||
printk ("Sound initialization started\n");
|
||||
|
||||
for (i = 0; i < (n - 1); i++)
|
||||
if (snd_installed_cards[i].enabled)
|
||||
if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
|
||||
snd_installed_cards[i].enabled = 0; /*
|
||||
* Mark as not detected
|
||||
*/
|
||||
else if (sound_drivers[drv].probe (&snd_installed_cards[i].config))
|
||||
{
|
||||
#ifndef SHORT_BANNERS
|
||||
printk ("snd%d",
|
||||
snd_installed_cards[i].card_type);
|
||||
#endif
|
||||
|
||||
mem_start = sound_drivers[drv].attach (mem_start, &snd_installed_cards[i].config);
|
||||
#ifndef SHORT_BANNERS
|
||||
printk (" at 0x%x irq %d drq %d\n",
|
||||
snd_installed_cards[i].config.io_base,
|
||||
snd_installed_cards[i].config.irq,
|
||||
snd_installed_cards[i].config.dma);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
snd_installed_cards[i].enabled = 0; /*
|
||||
* Mark as not detected
|
||||
*/
|
||||
printk ("Sound initialization complete\n");
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
int
|
||||
sndtable_probe (int unit, struct address_info *hw_config)
|
||||
{
|
||||
int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
|
||||
|
||||
if (!unit)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < (n - 1); i++)
|
||||
if (snd_installed_cards[i].enabled)
|
||||
if (snd_installed_cards[i].card_type == unit)
|
||||
{
|
||||
int drv;
|
||||
|
||||
snd_installed_cards[i].config.io_base = hw_config->io_base;
|
||||
snd_installed_cards[i].config.irq = hw_config->irq;
|
||||
snd_installed_cards[i].config.dma = hw_config->dma;
|
||||
if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
|
||||
snd_installed_cards[i].enabled = 0; /*
|
||||
* Mark as not
|
||||
* detected
|
||||
*/
|
||||
else if (sound_drivers[drv].probe (hw_config))
|
||||
return 1;
|
||||
snd_installed_cards[i].enabled = 0; /*
|
||||
* Mark as not detected
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
sndtable_init_card (int unit, struct address_info *hw_config)
|
||||
{
|
||||
int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
|
||||
|
||||
if (!unit)
|
||||
{
|
||||
if (sndtable_init (0) != 0)
|
||||
panic ("snd: Invalid memory allocation\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < (n - 1); i++)
|
||||
if (snd_installed_cards[i].card_type == unit)
|
||||
{
|
||||
int drv;
|
||||
|
||||
snd_installed_cards[i].config.io_base = hw_config->io_base;
|
||||
snd_installed_cards[i].config.irq = hw_config->irq;
|
||||
snd_installed_cards[i].config.dma = hw_config->dma;
|
||||
|
||||
if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
|
||||
snd_installed_cards[i].enabled = 0; /*
|
||||
* Mark as not detected
|
||||
*/
|
||||
else if (sound_drivers[drv].attach (0, hw_config) != 0)
|
||||
panic ("snd#: Invalid memory allocation\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
sndtable_get_cardcount (void)
|
||||
{
|
||||
return num_audiodevs + num_mixers + num_synths + num_midis;
|
||||
}
|
||||
|
||||
struct address_info *
|
||||
sound_getconf (int card_type)
|
||||
{
|
||||
int j, ptr;
|
||||
int n = sizeof (snd_installed_cards) / sizeof (struct card_info);
|
||||
|
||||
ptr = -1;
|
||||
for (j = 0; j < n && ptr == -1; j++)
|
||||
if (snd_installed_cards[j].card_type == card_type)
|
||||
ptr = j;
|
||||
|
||||
if (ptr == -1)
|
||||
return (struct address_info *) NULL;
|
||||
|
||||
return &snd_installed_cards[ptr].config;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
sound_setup (char *str, int *ints)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@ -1,429 +0,0 @@
|
||||
/*
|
||||
* dev_table.h
|
||||
*
|
||||
* Global definitions for device call tables
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _DEV_TABLE_H_
|
||||
#define _DEV_TABLE_H_
|
||||
|
||||
/*
|
||||
* NOTE! NOTE! NOTE! NOTE!
|
||||
*
|
||||
* If you modify this file, please check the dev_table.c also.
|
||||
*
|
||||
* NOTE! NOTE! NOTE! NOTE!
|
||||
*/
|
||||
|
||||
struct driver_info {
|
||||
int card_type; /* From soundcard.h */
|
||||
char *name;
|
||||
long (*attach) (long mem_start, struct address_info *hw_config);
|
||||
int (*probe) (struct address_info *hw_config);
|
||||
};
|
||||
|
||||
struct card_info {
|
||||
int card_type; /* Link (search key) to the driver list */
|
||||
struct address_info config;
|
||||
int enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
* Device specific parameters (used only by dmabuf.c)
|
||||
*/
|
||||
#define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR)
|
||||
|
||||
#define DMODE_NONE 0
|
||||
#define DMODE_OUTPUT 1
|
||||
#define DMODE_INPUT 2
|
||||
|
||||
struct dma_buffparms {
|
||||
int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
|
||||
|
||||
/*
|
||||
* Pointers to raw buffers
|
||||
*/
|
||||
|
||||
char *raw_buf[DSP_BUFFCOUNT];
|
||||
unsigned long raw_buf_phys[DSP_BUFFCOUNT];
|
||||
int raw_count;
|
||||
|
||||
/*
|
||||
* Device state tables
|
||||
*/
|
||||
|
||||
unsigned long flags;
|
||||
#define DMA_BUSY 0x00000001
|
||||
#define DMA_RESTART 0x00000002
|
||||
#define DMA_ACTIVE 0x00000004
|
||||
#define DMA_STARTED 0x00000008
|
||||
#define DMA_ALLOC_DONE 0x00000020
|
||||
|
||||
int open_mode;
|
||||
|
||||
/*
|
||||
* Queue parameters.
|
||||
*/
|
||||
int qlen;
|
||||
int qhead;
|
||||
int qtail;
|
||||
|
||||
int nbufs;
|
||||
int counts[MAX_SUB_BUFFERS];
|
||||
int subdivision;
|
||||
char *buf[MAX_SUB_BUFFERS];
|
||||
unsigned long buf_phys[MAX_SUB_BUFFERS];
|
||||
|
||||
int fragment_size;
|
||||
int max_fragments;
|
||||
|
||||
int bytes_in_use;
|
||||
|
||||
int underrun_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for use with various microcontrollers and DSP processors
|
||||
* in the recent soundcards.
|
||||
*/
|
||||
typedef struct coproc_operations {
|
||||
char name[32];
|
||||
int (*open) (void *devc, int sub_device);
|
||||
void (*close) (void *devc, int sub_device);
|
||||
int (*ioctl) (void *devc, unsigned int cmd, unsigned int arg, int local);
|
||||
void (*reset) (void *devc);
|
||||
|
||||
void *devc; /* Driver specific info */
|
||||
} coproc_operations;
|
||||
|
||||
struct audio_operations {
|
||||
char name[32];
|
||||
int flags;
|
||||
#define NOTHING_SPECIAL 0
|
||||
#define NEEDS_RESTART 1
|
||||
#define DMA_AUTOMODE 2
|
||||
int format_mask; /* Bitmask for supported audio formats */
|
||||
void *devc; /* Driver specific info */
|
||||
int (*open) (int dev, int mode);
|
||||
void (*close) (int dev);
|
||||
void (*output_block) (int dev, unsigned long buf,
|
||||
int count, int intrflag, int dma_restart);
|
||||
void (*start_input) (int dev, unsigned long buf,
|
||||
int count, int intrflag, int dma_restart);
|
||||
int (*ioctl) (int dev, unsigned int cmd, unsigned int arg, int local);
|
||||
int (*prepare_for_input) (int dev, int bufsize, int nbufs);
|
||||
int (*prepare_for_output) (int dev, int bufsize, int nbufs);
|
||||
void (*reset) (int dev);
|
||||
void (*halt_xfer) (int dev);
|
||||
int (*local_qlen)(int dev);
|
||||
void (*copy_from_user)(int dev, char *localbuf, int localoffs,
|
||||
snd_rw_buf *userbuf, int useroffs, int len);
|
||||
int buffcount;
|
||||
long buffsize;
|
||||
int dmachan;
|
||||
struct dma_buffparms *dmap;
|
||||
struct coproc_operations *coproc;
|
||||
int mixer_dev;
|
||||
};
|
||||
|
||||
struct mixer_operations {
|
||||
char name[32];
|
||||
int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
|
||||
};
|
||||
|
||||
struct synth_operations {
|
||||
struct synth_info *info;
|
||||
int midi_dev;
|
||||
int synth_type;
|
||||
int synth_subtype;
|
||||
|
||||
int (*open) (int dev, int mode);
|
||||
void (*close) (int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
|
||||
int (*kill_note) (int dev, int voice, int note, int velocity);
|
||||
int (*start_note) (int dev, int voice, int note, int velocity);
|
||||
int (*set_instr) (int dev, int voice, int instr);
|
||||
void (*reset) (int dev);
|
||||
void (*hw_control) (int dev, unsigned char *event);
|
||||
int (*load_patch) (int dev, int format, snd_rw_buf *addr,
|
||||
int offs, int count, int pmgr_flag);
|
||||
void (*aftertouch) (int dev, int voice, int pressure);
|
||||
void (*controller) (int dev, int voice, int ctrl_num, int value);
|
||||
void (*panning) (int dev, int voice, int value);
|
||||
void (*volume_method) (int dev, int mode);
|
||||
int (*pmgr_interface) (int dev, struct patmgr_info *info);
|
||||
void (*bender) (int dev, int chn, int value);
|
||||
int (*alloc_voice) (int dev, int chn, int note, struct voice_alloc_info *alloc);
|
||||
void (*setup_voice) (int dev, int voice, int chn);
|
||||
|
||||
struct voice_alloc_info alloc;
|
||||
struct channel_info chn_info[16];
|
||||
};
|
||||
|
||||
struct midi_input_info { /* MIDI input scanner variables */
|
||||
#define MI_MAX 10
|
||||
int m_busy;
|
||||
unsigned char m_buf[MI_MAX];
|
||||
unsigned char m_prev_status; /* For running status */
|
||||
int m_ptr;
|
||||
#define MST_INIT 0
|
||||
#define MST_DATA 1
|
||||
#define MST_SYSEX 2
|
||||
int m_state;
|
||||
int m_left;
|
||||
};
|
||||
|
||||
struct midi_operations {
|
||||
struct midi_info info;
|
||||
struct synth_operations *converter;
|
||||
struct midi_input_info in_info;
|
||||
int (*open) (int dev, int mode,
|
||||
void (*inputintr)(int dev, unsigned char data),
|
||||
void (*outputintr)(int dev)
|
||||
);
|
||||
void (*close) (int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
|
||||
int (*putc) (int dev, unsigned char data);
|
||||
int (*start_read) (int dev);
|
||||
int (*end_read) (int dev);
|
||||
void (*kick)(int dev);
|
||||
int (*command) (int dev, unsigned char *data);
|
||||
int (*buffer_status) (int dev);
|
||||
int (*prefix_cmd) (int dev, unsigned char status);
|
||||
struct coproc_operations *coproc;
|
||||
};
|
||||
|
||||
struct sound_timer_operations {
|
||||
struct sound_timer_info info;
|
||||
int priority;
|
||||
int devlink;
|
||||
int (*open)(int dev, int mode);
|
||||
void (*close)(int dev);
|
||||
int (*event)(int dev, unsigned char *ev);
|
||||
unsigned long (*get_time)(int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
|
||||
void (*arm_timer)(int dev, long time);
|
||||
};
|
||||
|
||||
#ifdef _DEV_TABLE_C_
|
||||
struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL}; int num_audiodevs = 0;
|
||||
struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL}; int num_mixers = 0;
|
||||
struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL}; int num_synths = 0;
|
||||
struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL}; int num_midis = 0;
|
||||
|
||||
#ifndef EXCLUDE_SEQUENCER
|
||||
extern struct sound_timer_operations default_sound_timer;
|
||||
struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
|
||||
{&default_sound_timer, NULL};
|
||||
int num_sound_timers = 1;
|
||||
#else
|
||||
struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
|
||||
{NULL};
|
||||
int num_sound_timers = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* List of low level drivers compiled into the kernel.
|
||||
*/
|
||||
|
||||
struct driver_info sound_drivers[] = {
|
||||
#ifndef EXCLUDE_PSS
|
||||
{SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)", attach_pss, probe_pss},
|
||||
# ifdef PSS_MPU_BASE
|
||||
{SNDCARD_PSS_MPU, "PSS-MPU", attach_pss_mpu, probe_pss_mpu},
|
||||
# endif
|
||||
# ifdef PSS_MSS_BASE
|
||||
{SNDCARD_PSS_MSS, "PSS-MSS", attach_pss_mss, probe_pss_mss},
|
||||
# endif
|
||||
#endif
|
||||
#ifndef EXCLUDE_YM3812
|
||||
{SNDCARD_ADLIB, "OPL-2/OPL-3 FM", attach_adlib_card, probe_adlib},
|
||||
#endif
|
||||
#ifndef EXCLUDE_PAS
|
||||
{SNDCARD_PAS, "ProAudioSpectrum", attach_pas_card, probe_pas},
|
||||
#endif
|
||||
#if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
|
||||
{SNDCARD_MPU401,"Roland MPU-401", attach_mpu401, probe_mpu401},
|
||||
#endif
|
||||
#if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
|
||||
{SNDCARD_UART6850,"6860 UART Midi", attach_uart6850, probe_uart6850},
|
||||
#endif
|
||||
#ifndef EXCLUDE_SB
|
||||
{SNDCARD_SB, "SoundBlaster", attach_sb_card, probe_sb},
|
||||
#endif
|
||||
#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16)
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
{SNDCARD_SB16, "SoundBlaster16", sb16_dsp_init, sb16_dsp_detect},
|
||||
#endif
|
||||
#ifndef EXCLUDE_MIDI
|
||||
{SNDCARD_SB16MIDI,"SB16 MIDI", attach_sb16midi, probe_sb16midi},
|
||||
#endif
|
||||
#endif
|
||||
#ifndef EXCLUDE_GUS16
|
||||
{SNDCARD_GUS16, "Ultrasound 16-bit opt.", attach_gus_db16, probe_gus_db16},
|
||||
#endif
|
||||
#ifndef EXCLUDE_MSS
|
||||
{SNDCARD_MSS, "MS Sound System", attach_ms_sound, probe_ms_sound},
|
||||
#endif
|
||||
#ifndef EXCLUDE_GUS
|
||||
{SNDCARD_GUS, "Gravis Ultrasound", attach_gus_card, probe_gus},
|
||||
#endif
|
||||
#ifndef EXCLUDE_SSCAPE
|
||||
{SNDCARD_SSCAPE, "Ensoniq Soundscape", attach_sscape, probe_sscape},
|
||||
{SNDCARD_SSCAPE_MSS, "MS Sound System (SoundScape)", attach_ss_ms_sound, probe_ss_ms_sound},
|
||||
#endif
|
||||
#ifndef EXCLUDE_TRIX
|
||||
{SNDCARD_TRXPRO, "MediaTriX AudioTriX Pro", attach_trix_wss, probe_trix_wss},
|
||||
{SNDCARD_TRXPRO_SB, "AudioTriX (SB mode)", attach_trix_sb, probe_trix_sb},
|
||||
{SNDCARD_TRXPRO_MPU, "AudioTriX MIDI", attach_trix_mpu, probe_trix_mpu},
|
||||
#endif
|
||||
#ifdef PC98
|
||||
#ifndef EXCLUDE_PCM86
|
||||
{SNDCARD_PCM86, "PC-9801-86/73", attach_pcm86, probe_pcm86},
|
||||
#endif
|
||||
#endif
|
||||
{0, "*?*", NULL, NULL}
|
||||
};
|
||||
|
||||
#if defined(linux) || defined(__FreeBSD__)
|
||||
/*
|
||||
* List of devices actually configured in the system.
|
||||
*
|
||||
* Note! The detection order is significant. Don't change it.
|
||||
*/
|
||||
|
||||
struct card_info snd_installed_cards[] = {
|
||||
#ifndef EXCLUDE_PSS
|
||||
{SNDCARD_PSS, {PSS_BASE, PSS_IRQ, PSS_DMA}, SND_DEFAULT_ENABLE},
|
||||
# ifdef PSS_MPU_BASE
|
||||
{SNDCARD_PSS_MPU, {PSS_MPU_BASE, PSS_MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
# endif
|
||||
# ifdef PSS_MSS_BASE
|
||||
{SNDCARD_PSS_MSS, {PSS_MSS_BASE, PSS_MSS_IRQ, PSS_MSS_DMA}, SND_DEFAULT_ENABLE},
|
||||
# endif
|
||||
#endif
|
||||
#ifndef EXCLUDE_TRIX
|
||||
{SNDCARD_TRXPRO, {TRIX_BASE, TRIX_IRQ, TRIX_DMA}, SND_DEFAULT_ENABLE},
|
||||
# ifdef TRIX_SB_BASE
|
||||
{SNDCARD_TRXPRO_SB, {TRIX_SB_BASE, TRIX_SB_IRQ, TRIX_SB_DMA}, SND_DEFAULT_ENABLE},
|
||||
# endif
|
||||
# ifdef TRIX_MPU_BASE
|
||||
{SNDCARD_TRXPRO_MPU, {TRIX_MPU_BASE, TRIX_MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
# endif
|
||||
#endif
|
||||
#ifndef EXCLUDE_SSCAPE
|
||||
{SNDCARD_SSCAPE, {SSCAPE_BASE, SSCAPE_IRQ, SSCAPE_DMA}, SND_DEFAULT_ENABLE},
|
||||
{SNDCARD_SSCAPE_MSS, {SSCAPE_MSS_BASE, SSCAPE_MSS_IRQ, SSCAPE_MSS_DMA}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_MSS
|
||||
{SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA}, SND_DEFAULT_ENABLE},
|
||||
# ifdef MSS2_BASE
|
||||
{SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA}, SND_DEFAULT_ENABLE},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_PAS
|
||||
{SNDCARD_PAS, {PAS_BASE, PAS_IRQ, PAS_DMA}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_SB
|
||||
{SNDCARD_SB, {SBC_BASE, SBC_IRQ, SBC_DMA}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
|
||||
{SNDCARD_MPU401, {MPU_BASE, MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
#ifdef MPU2_BASE
|
||||
{SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef MPU3_BASE
|
||||
{SNDCARD_MPU401, {MPU3_BASE, MPU2_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
|
||||
{SNDCARD_UART6850, {U6850_BASE, U6850_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16)
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
{SNDCARD_SB16, {SBC_BASE, SBC_IRQ, SB16_DMA}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifndef EXCLUDE_MIDI
|
||||
{SNDCARD_SB16MIDI,{SB16MIDI_BASE, SBC_IRQ, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_GUS
|
||||
#ifndef EXCLUDE_GUS16
|
||||
{SNDCARD_GUS16, {GUS16_BASE, GUS16_IRQ, GUS16_DMA, GUS_DMA_READ}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
{SNDCARD_GUS, {GUS_BASE, GUS_IRQ, GUS_DMA, GUS_DMA_READ}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_YM3812
|
||||
{SNDCARD_ADLIB, {FM_MONO, 0, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef PC98
|
||||
#ifndef EXCLUDE_PCM86
|
||||
{SNDCARD_PCM86, {0, 0, 0}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
{0, {0}, 0}
|
||||
};
|
||||
|
||||
int num_sound_cards =
|
||||
sizeof(snd_installed_cards) / sizeof (struct card_info);
|
||||
|
||||
#else
|
||||
int num_sound_cards = 0;
|
||||
#endif /* linux */
|
||||
|
||||
int num_sound_drivers =
|
||||
sizeof(sound_drivers) / sizeof (struct driver_info);
|
||||
|
||||
#else
|
||||
extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
|
||||
extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixers;
|
||||
extern struct synth_operations * synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_synths;
|
||||
extern struct midi_operations * midi_devs[MAX_MIDI_DEV]; extern int num_midis;
|
||||
extern struct sound_timer_operations * sound_timer_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_sound_timers;
|
||||
|
||||
extern struct driver_info sound_drivers[];
|
||||
extern int num_sound_drivers;
|
||||
extern struct card_info snd_installed_cards[];
|
||||
extern int num_sound_cards;
|
||||
#endif /* _DEV_TABLE_C_ */
|
||||
|
||||
int sndtable_probe(int unit, struct address_info *hw_config);
|
||||
int sndtable_init_card(int unit, struct address_info *hw_config);
|
||||
int sndtable_get_cardcount (void);
|
||||
struct address_info *sound_getconf(int card_type);
|
||||
int snd_find_driver(int type);
|
||||
|
||||
#endif /* _DEV_TABLE_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* sound/gus_card.c
|
||||
*
|
||||
* Detection routine for the Gravis Ultrasound.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
|
||||
|
||||
#include <i386/isa/sound/gus_hw.h>
|
||||
|
||||
int gus_base, gus_irq, gus_dma;
|
||||
extern int gus_wave_volume;
|
||||
extern int gus_pcm_volume;
|
||||
extern int have_gus_max;
|
||||
|
||||
long
|
||||
attach_gus_card (long mem_start, struct address_info *hw_config)
|
||||
{
|
||||
int io_addr;
|
||||
|
||||
snd_set_irq_handler (hw_config->irq, gusintr, "Gravis Ultrasound");
|
||||
|
||||
if (gus_wave_detect (hw_config->io_base)) /*
|
||||
* Try first the default
|
||||
*/
|
||||
{
|
||||
mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma,
|
||||
hw_config->dma_read);
|
||||
#ifndef EXCLUDE_MIDI
|
||||
mem_start = gus_midi_init (mem_start);
|
||||
#endif
|
||||
#ifndef EXCLUDE_SEQUENCER
|
||||
sound_timer_init (hw_config->io_base + 8);
|
||||
#endif
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#ifndef EXCLUDE_GUS_IODETECT
|
||||
|
||||
/*
|
||||
* Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
|
||||
*/
|
||||
|
||||
for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
|
||||
if (io_addr != hw_config->io_base) /*
|
||||
* Already tested
|
||||
*/
|
||||
if (gus_wave_detect (io_addr))
|
||||
{
|
||||
printk (" WARNING! GUS found at %x, config was %x ", io_addr, hw_config->io_base);
|
||||
mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma,
|
||||
hw_config->dma_read);
|
||||
#ifndef EXCLUDE_MIDI
|
||||
mem_start = gus_midi_init (mem_start);
|
||||
#endif
|
||||
#ifndef EXCLUDE_SEQUENCER
|
||||
sound_timer_init (io_addr + 8);
|
||||
#endif
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return mem_start; /*
|
||||
* Not detected
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
probe_gus (struct address_info *hw_config)
|
||||
{
|
||||
int io_addr;
|
||||
|
||||
if (gus_wave_detect (hw_config->io_base))
|
||||
return 1;
|
||||
|
||||
#ifndef EXCLUDE_GUS_IODETECT
|
||||
|
||||
/*
|
||||
* Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
|
||||
*/
|
||||
|
||||
for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
|
||||
if (io_addr != hw_config->io_base) /*
|
||||
* Already tested
|
||||
*/
|
||||
if (gus_wave_detect (io_addr))
|
||||
return 1;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gusintr (INT_HANDLER_PARMS (irq, dummy))
|
||||
{
|
||||
unsigned char src;
|
||||
|
||||
#ifdef linux
|
||||
sti ();
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_GUSMAX
|
||||
if (have_gus_max)
|
||||
# if defined(__FreeBSD__)
|
||||
ad1848_interrupt (INT_HANDLER_CALL (gus_irq));
|
||||
# else
|
||||
ad1848_interrupt (INT_HANDLER_CALL (irq));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!(src = INB (u_IrqStatus)))
|
||||
return;
|
||||
|
||||
if (src & DMA_TC_IRQ)
|
||||
{
|
||||
guswave_dma_irq ();
|
||||
}
|
||||
|
||||
if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
|
||||
{
|
||||
#ifndef EXCLUDE_MIDI
|
||||
gus_midi_interrupt (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
|
||||
{
|
||||
#ifndef EXCLUDE_SEQUENCER
|
||||
sound_timer_interrupt ();
|
||||
#else
|
||||
gus_write8 (0x45, 0); /* Stop timers */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
|
||||
{
|
||||
gus_voice_irq ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some extra code for the 16 bit sampling option
|
||||
*/
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS16)
|
||||
|
||||
int
|
||||
probe_gus_db16 (struct address_info *hw_config)
|
||||
{
|
||||
return ad1848_detect (hw_config->io_base);
|
||||
}
|
||||
|
||||
long
|
||||
attach_gus_db16 (long mem_start, struct address_info *hw_config)
|
||||
{
|
||||
gus_pcm_volume = 100;
|
||||
gus_wave_volume = 90;
|
||||
|
||||
ad1848_init ("GUS 16 bit sampling", hw_config->io_base,
|
||||
hw_config->irq,
|
||||
hw_config->dma,
|
||||
hw_config->dma);
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,312 +0,0 @@
|
||||
/*
|
||||
* sound/gus2_midi.c
|
||||
*
|
||||
* The low level driver for the GUS Midi Interface.
|
||||
*
|
||||
* 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/gus_hw.h>
|
||||
|
||||
#if !defined(EXCLUDE_GUS) && !defined(EXCLUDE_MIDI)
|
||||
|
||||
static int midi_busy = 0, input_opened = 0;
|
||||
static int my_dev;
|
||||
static int output_used = 0;
|
||||
static volatile unsigned char gus_midi_control;
|
||||
|
||||
static void (*midi_input_intr) (int dev, unsigned char data);
|
||||
|
||||
static unsigned char tmp_queue[256];
|
||||
static volatile int qlen;
|
||||
static volatile unsigned char qhead, qtail;
|
||||
extern int gus_base, gus_irq, gus_dma;
|
||||
|
||||
#define GUS_MIDI_STATUS() INB(u_MidiStatus)
|
||||
|
||||
static int
|
||||
gus_midi_open (int dev, int mode,
|
||||
void (*input) (int dev, unsigned char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
|
||||
if (midi_busy)
|
||||
{
|
||||
printk ("GUS: Midi busy\n");
|
||||
return RET_ERROR (EBUSY);
|
||||
}
|
||||
|
||||
OUTB (MIDI_RESET, u_MidiControl);
|
||||
gus_delay ();
|
||||
|
||||
gus_midi_control = 0;
|
||||
input_opened = 0;
|
||||
|
||||
if (mode == OPEN_READ || mode == OPEN_READWRITE)
|
||||
{
|
||||
gus_midi_control |= MIDI_ENABLE_RCV;
|
||||
input_opened = 1;
|
||||
}
|
||||
|
||||
if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
|
||||
{
|
||||
gus_midi_control |= MIDI_ENABLE_XMIT;
|
||||
}
|
||||
|
||||
OUTB (gus_midi_control, u_MidiControl); /*
|
||||
* Enable
|
||||
*/
|
||||
|
||||
midi_busy = 1;
|
||||
qlen = qhead = qtail = output_used = 0;
|
||||
midi_input_intr = input;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_to_midi (unsigned char midi_byte)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ok = 0;
|
||||
|
||||
output_used = 1;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY)
|
||||
{
|
||||
ok = 1;
|
||||
OUTB (midi_byte, u_MidiData);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Enable Midi xmit interrupts (again)
|
||||
*/
|
||||
gus_midi_control |= MIDI_ENABLE_XMIT;
|
||||
OUTB (gus_midi_control, u_MidiControl);
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
gus_midi_close (int dev)
|
||||
{
|
||||
/*
|
||||
* Reset FIFO pointers, disable intrs
|
||||
*/
|
||||
|
||||
OUTB (MIDI_RESET, u_MidiControl);
|
||||
midi_busy = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_out (int dev, unsigned char midi_byte)
|
||||
{
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Drain the local queue first
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
while (qlen && dump_to_midi (tmp_queue[qhead]))
|
||||
{
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
/*
|
||||
* Output the byte if the local queue is empty.
|
||||
*/
|
||||
|
||||
if (!qlen)
|
||||
if (dump_to_midi (midi_byte))
|
||||
return 1; /*
|
||||
* OK
|
||||
*/
|
||||
|
||||
/*
|
||||
* Put to the local queue
|
||||
*/
|
||||
|
||||
if (qlen >= 256)
|
||||
return 0; /*
|
||||
* Local queue full
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
tmp_queue[qtail] = midi_byte;
|
||||
qlen++;
|
||||
qtail++;
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_start_read (int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_end_read (int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_ioctl (int dev, unsigned cmd, unsigned arg)
|
||||
{
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
gus_midi_kick (int dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_buffer_status (int dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!output_used)
|
||||
return 0;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (qlen && dump_to_midi (tmp_queue[qhead]))
|
||||
{
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations gus_midi_operations =
|
||||
{
|
||||
{"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
gus_midi_open,
|
||||
gus_midi_close,
|
||||
gus_midi_ioctl,
|
||||
gus_midi_out,
|
||||
gus_midi_start_read,
|
||||
gus_midi_end_read,
|
||||
gus_midi_kick,
|
||||
NULL, /*
|
||||
* command
|
||||
*/
|
||||
gus_midi_buffer_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
long
|
||||
gus_midi_init (long mem_start)
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV)
|
||||
{
|
||||
printk ("Sound: Too many midi devices detected\n");
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
OUTB (MIDI_RESET, u_MidiControl);
|
||||
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &gus_midi_operations;
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
void
|
||||
gus_midi_interrupt (int dummy)
|
||||
{
|
||||
unsigned char stat, data;
|
||||
unsigned long flags;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
stat = GUS_MIDI_STATUS ();
|
||||
|
||||
if (stat & MIDI_RCV_FULL)
|
||||
{
|
||||
data = INB (u_MidiData);
|
||||
if (input_opened)
|
||||
midi_input_intr (my_dev, data);
|
||||
}
|
||||
|
||||
if (stat & MIDI_XMIT_EMPTY)
|
||||
{
|
||||
while (qlen && dump_to_midi (tmp_queue[qhead]))
|
||||
{
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
if (!qlen)
|
||||
{
|
||||
/*
|
||||
* Disable Midi output interrupts, since no data in the buffer
|
||||
*/
|
||||
gus_midi_control &= ~MIDI_ENABLE_XMIT;
|
||||
OUTB (gus_midi_control, u_MidiControl);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (stat & MIDI_FRAME_ERR)
|
||||
printk ("GUS: Midi framing error\n");
|
||||
if (stat & MIDI_OVERRUN && input_opened)
|
||||
printk ("GUS: Midi input overrun\n");
|
||||
#endif
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* gus_vol.c - Compute volume for GUS.
|
||||
*
|
||||
* Greg Lee 1993.
|
||||
*/
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#ifndef EXCLUDE_GUS
|
||||
#include <i386/isa/sound/gus_linearvol.h>
|
||||
|
||||
extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
|
||||
extern unsigned short gus_linear_vol (int vol, int mainvol);
|
||||
|
||||
#define GUS_VOLUME gus_wave_volume
|
||||
|
||||
|
||||
extern int gus_wave_volume;
|
||||
|
||||
/*
|
||||
* Calculate gus volume from note velocity, main volume, expression, and
|
||||
* intrinsic patch volume given in patch library. Expression is multiplied
|
||||
* in, so it emphasizes differences in note velocity, while main volume is
|
||||
* added in -- I don't know whether this is right, but it seems reasonable to
|
||||
* me. (In the previous stage, main volume controller messages were changed
|
||||
* to expression controller messages, if they were found to be used for
|
||||
* dynamic volume adjustments, so here, main volume can be assumed to be
|
||||
* constant throughout a song.)
|
||||
*
|
||||
* Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
|
||||
* we can give a big boost to very weak voices like nylon guitar and the
|
||||
* basses. The normal value is 64. Strings are assigned lower values.
|
||||
*/
|
||||
unsigned short
|
||||
gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
|
||||
{
|
||||
int i, m, n, x;
|
||||
|
||||
|
||||
/*
|
||||
* A voice volume of 64 is considered neutral, so adjust the main volume if
|
||||
* something other than this neutral value was assigned in the patch
|
||||
* library.
|
||||
*/
|
||||
x = 256 + 6 * (voicev - 64);
|
||||
|
||||
/*
|
||||
* Boost expression by voice volume above neutral.
|
||||
*/
|
||||
if (voicev > 65)
|
||||
xpn += voicev - 64;
|
||||
xpn += (voicev - 64) / 2;
|
||||
|
||||
/*
|
||||
* Combine multiplicative and level components.
|
||||
*/
|
||||
x = vel * xpn * 6 + (voicev / 4) * x;
|
||||
|
||||
#ifdef GUS_VOLUME
|
||||
/*
|
||||
* Further adjustment by installation-specific master volume control
|
||||
* (default 60).
|
||||
*/
|
||||
x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
|
||||
#endif
|
||||
|
||||
#ifdef GUS_USE_CHN_MAIN_VOLUME
|
||||
/*
|
||||
* Experimental support for the channel main volume
|
||||
*/
|
||||
|
||||
mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */
|
||||
x = (x * mainv * mainv) / 16384;
|
||||
#endif
|
||||
|
||||
if (x < 2)
|
||||
return (0);
|
||||
else if (x >= 65535)
|
||||
return ((15 << 8) | 255);
|
||||
|
||||
/*
|
||||
* Convert to gus's logarithmic form with 4 bit exponent i and 8 bit
|
||||
* mantissa m.
|
||||
*/
|
||||
n = x;
|
||||
i = 7;
|
||||
if (n < 128)
|
||||
{
|
||||
while (i > 0 && n < (1 << i))
|
||||
i--;
|
||||
}
|
||||
else
|
||||
while (n > 255)
|
||||
{
|
||||
n >>= 1;
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Mantissa is part of linear volume not expressed in exponent. (This is
|
||||
* not quite like real logs -- I wonder if it's right.)
|
||||
*/
|
||||
m = x - (1 << i);
|
||||
|
||||
/*
|
||||
* Adjust mantissa to 8 bits.
|
||||
*/
|
||||
if (m > 0)
|
||||
{
|
||||
if (i > 8)
|
||||
m >>= i - 8;
|
||||
else if (i < 8)
|
||||
m <<= 8 - i;
|
||||
}
|
||||
|
||||
return ((i << 8) + m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Volume-values are interpreted as linear values. Volume is based on the
|
||||
* value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
|
||||
* and the volume set by the mixer-device (default 60%).
|
||||
*/
|
||||
|
||||
unsigned short
|
||||
gus_linear_vol (int vol, int mainvol)
|
||||
{
|
||||
int mixer_mainvol;
|
||||
|
||||
if (vol <= 0)
|
||||
vol = 0;
|
||||
else if (vol >= 127)
|
||||
vol = 127;
|
||||
|
||||
#ifdef GUS_VOLUME
|
||||
mixer_mainvol = GUS_VOLUME;
|
||||
#else
|
||||
mixer_mainvol = 100;
|
||||
#endif
|
||||
|
||||
#ifdef GUS_USE_CHN_MAIN_VOLUME
|
||||
if (mainvol <= 0)
|
||||
mainvol = 0;
|
||||
else if (mainvol >= 127)
|
||||
mainvol = 127;
|
||||
#else
|
||||
mainvol = 128;
|
||||
#endif
|
||||
|
||||
return gus_linearvol[(((vol * mainvol) / 128) * mixer_mainvol) / 100];
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,264 +0,0 @@
|
||||
/*
|
||||
* sound/ics2101.c
|
||||
*
|
||||
* Driver for the ICS2101 mixer of GUS v3.7.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
|
||||
|
||||
#include <machine/ultrasound.h>
|
||||
#include <i386/isa/sound/gus_hw.h>
|
||||
|
||||
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
|
||||
SOUND_MASK_SYNTH| \
|
||||
SOUND_MASK_CD | SOUND_MASK_VOLUME)
|
||||
|
||||
extern int gus_base;
|
||||
static int volumes[ICS_MIXDEVS];
|
||||
static int left_fix[ICS_MIXDEVS] =
|
||||
{1, 1, 1, 2, 1, 2};
|
||||
static int right_fix[ICS_MIXDEVS] =
|
||||
{2, 2, 2, 1, 2, 1};
|
||||
|
||||
static int
|
||||
scale_vol (int vol)
|
||||
{
|
||||
#if 1
|
||||
/*
|
||||
* Experimental volume scaling by Risto Kankkunen.
|
||||
* This should give smoother volume response than just
|
||||
* a plain multiplication.
|
||||
*/
|
||||
int e;
|
||||
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
vol = (31 * vol + 50) / 100;
|
||||
e = 0;
|
||||
if (vol)
|
||||
{
|
||||
while (vol < 16)
|
||||
{
|
||||
vol <<= 1;
|
||||
e--;
|
||||
}
|
||||
vol -= 16;
|
||||
e += 7;
|
||||
}
|
||||
return ((e << 4) + vol);
|
||||
#else
|
||||
return ((vol * 127) + 50) / 100;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
write_mix (int dev, int chn, int vol)
|
||||
{
|
||||
int *selector;
|
||||
unsigned long flags;
|
||||
int ctrl_addr = dev << 3;
|
||||
int attn_addr = dev << 3;
|
||||
|
||||
vol = scale_vol (vol);
|
||||
|
||||
if (chn == CHN_LEFT)
|
||||
{
|
||||
selector = left_fix;
|
||||
ctrl_addr |= 0x00;
|
||||
attn_addr |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = right_fix;
|
||||
ctrl_addr |= 0x01;
|
||||
attn_addr |= 0x03;
|
||||
}
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
OUTB (ctrl_addr, u_MixSelect);
|
||||
OUTB (selector[dev], u_MixData);
|
||||
OUTB (attn_addr, u_MixSelect);
|
||||
OUTB ((unsigned char) vol, u_MixData);
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
static int
|
||||
set_volumes (int dev, int vol)
|
||||
{
|
||||
int left = vol & 0x00ff;
|
||||
int right = (vol >> 8) & 0x00ff;
|
||||
|
||||
if (left < 0)
|
||||
left = 0;
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
if (right < 0)
|
||||
right = 0;
|
||||
if (right > 100)
|
||||
right = 100;
|
||||
|
||||
write_mix (dev, CHN_LEFT, left);
|
||||
write_mix (dev, CHN_RIGHT, right);
|
||||
|
||||
vol = left + (right << 8);
|
||||
volumes[dev] = vol;
|
||||
return vol;
|
||||
}
|
||||
|
||||
static int
|
||||
ics2101_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
if (((cmd >> 8) & 0xff) == 'M')
|
||||
{
|
||||
if (cmd & IOC_IN)
|
||||
switch (cmd & 0xff)
|
||||
{
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return gus_default_mixer_ioctl (dev, cmd, arg);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MIC:
|
||||
return IOCTL_OUT (arg, set_volumes (DEV_MIC, IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CD:
|
||||
return IOCTL_OUT (arg, set_volumes (DEV_CD, IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LINE:
|
||||
return IOCTL_OUT (arg, set_volumes (DEV_LINE, IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH:
|
||||
return IOCTL_OUT (arg, set_volumes (DEV_GF1, IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_VOLUME:
|
||||
return IOCTL_OUT (arg, set_volumes (DEV_VOL, IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
default:
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
else
|
||||
switch (cmd & 0xff) /*
|
||||
* Return parameters
|
||||
*/
|
||||
{
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return gus_default_mixer_ioctl (dev, cmd, arg);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return IOCTL_OUT (arg, MIX_DEVS);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
return IOCTL_OUT (arg, SOUND_MASK_LINE | SOUND_MASK_CD |
|
||||
SOUND_MASK_SYNTH | SOUND_MASK_VOLUME |
|
||||
SOUND_MASK_MIC);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return IOCTL_OUT (arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return IOCTL_OUT (arg, 0);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MIC:
|
||||
return IOCTL_OUT (arg, volumes[DEV_MIC]);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LINE:
|
||||
return IOCTL_OUT (arg, volumes[DEV_LINE]);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CD:
|
||||
return IOCTL_OUT (arg, volumes[DEV_CD]);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_VOLUME:
|
||||
return IOCTL_OUT (arg, volumes[DEV_VOL]);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH:
|
||||
return IOCTL_OUT (arg, volumes[DEV_GF1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations ics2101_mixer_operations =
|
||||
{
|
||||
"ICS2101 Multimedia Mixer",
|
||||
ics2101_mixer_ioctl
|
||||
};
|
||||
|
||||
long
|
||||
ics2101_mixer_init (long mem_start)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV)
|
||||
{
|
||||
mixer_devs[num_mixers++] = &ics2101_mixer_operations;
|
||||
|
||||
/*
|
||||
* Some GUS v3.7 cards had some channels flipped. Disable
|
||||
* the flipping feature if the model id is other than 5.
|
||||
*/
|
||||
|
||||
if (INB (u_MixSelect) != 5)
|
||||
{
|
||||
for (i = 0; i < ICS_MIXDEVS; i++)
|
||||
left_fix[i] = 1;
|
||||
for (i = 0; i < ICS_MIXDEVS; i++)
|
||||
right_fix[i] = 2;
|
||||
}
|
||||
|
||||
set_volumes (DEV_GF1, 0x5a5a);
|
||||
set_volumes (DEV_CD, 0x5a5a);
|
||||
set_volumes (DEV_MIC, 0x0000);
|
||||
set_volumes (DEV_LINE, 0x5a5a);
|
||||
set_volumes (DEV_VOL, 0x5a5a);
|
||||
set_volumes (DEV_UNUSED, 0x0000);
|
||||
}
|
||||
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,128 +0,0 @@
|
||||
/* for FreeBSD */
|
||||
/*
|
||||
* $Id: local.h,v 1.11 1994/11/01 17:26:50 ache Exp
|
||||
*/
|
||||
|
||||
#define DSP_BUFFSIZE 65536
|
||||
#define SELECTED_SOUND_OPTIONS 0xffffffff
|
||||
#define SOUND_CONFIG_DATE "Sun Feb 5 14:38:12 EST 1995"
|
||||
#define SOUND_CONFIG_BY "freebsd-hackers"
|
||||
#define SOUND_CONFIG_HOST "freefall"
|
||||
#define SOUND_CONFIG_DOMAIN "cdrom.com"
|
||||
|
||||
/* determine if sound code should be compiled */
|
||||
#include "snd.h"
|
||||
#if NSND > 0
|
||||
#define KERNEL_SOUNDCARD
|
||||
#endif
|
||||
|
||||
#define ALLOW_SELECT
|
||||
|
||||
/* PSS code does not work */
|
||||
#ifndef EXCLUDE_PSS
|
||||
#define EXCLUDE_PSS
|
||||
#endif
|
||||
|
||||
#include "gus.h"
|
||||
#if NGUS == 0 && !defined(EXCLUDE_GUS)
|
||||
#define EXCLUDE_GUS
|
||||
#endif
|
||||
|
||||
#include "gusxvi.h"
|
||||
#if NGUSXVI == 0 && !defined(EXCLUDE_GUS16)
|
||||
#define EXCLUDE_GUS16
|
||||
#endif
|
||||
|
||||
#include "mss.h"
|
||||
#if NMSS == 0 && !defined(EXCLUDE_MSS)
|
||||
#define EXCLUDE_MSS
|
||||
#endif
|
||||
|
||||
#include "trix.h"
|
||||
#if NTRIX == 0 && !defined(EXCLUDE_TRIX)
|
||||
#define EXCLUDE_TRIX
|
||||
#endif
|
||||
|
||||
#include "sscape.h"
|
||||
#if NSSCAPE == 0 && !defined(EXCLUDE_SSCAPE)
|
||||
#define EXCLUDE_SSCAPE
|
||||
#endif
|
||||
|
||||
#if NGUS == 0 && !defined(EXCLUDE_GUSMAX)
|
||||
# define EXCLUDE_GUSMAX
|
||||
# if defined(EXCLUDE_GUS16) && defined(EXCLUDE_MSS) && !defined(EXCLUDE_AD1848)
|
||||
# define EXCLUDE_AD1848
|
||||
# endif
|
||||
#else
|
||||
# define GUSMAX_MIXER
|
||||
#endif
|
||||
|
||||
#include "sb.h"
|
||||
#if NSB == 0 && !defined(EXCLUDE_SB)
|
||||
#define EXCLUDE_SB
|
||||
#endif
|
||||
|
||||
#include "sbxvi.h"
|
||||
#if NSBXVI == 0 && !defined(EXCLUDE_SB16)
|
||||
#define EXCLUDE_SB16
|
||||
#endif
|
||||
|
||||
#include "sbmidi.h"
|
||||
#if NSBMIDI == 0 && !defined(EXCLUDE_SB16MIDI)
|
||||
#define EXCLUDE_SB16MIDI
|
||||
#endif
|
||||
|
||||
#include "pas.h"
|
||||
#if NPAS == 0 && !defined(EXCLUDE_PAS)
|
||||
#define EXCLUDE_PAS
|
||||
#endif
|
||||
|
||||
#include "mpu.h"
|
||||
#if NMPU == 0 && !defined(EXCLUDE_MPU401)
|
||||
#define EXCLUDE_MPU401
|
||||
#endif
|
||||
|
||||
#include "opl.h"
|
||||
#if NOPL == 0 && !defined(EXCLUDE_YM3812)
|
||||
#define EXCLUDE_YM3812
|
||||
#endif
|
||||
|
||||
#include "uart.h"
|
||||
#if NUART == 0 && !defined(EXCLUDE_UART6850)
|
||||
#define EXCLUDE_UART6850
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include "pcm.h"
|
||||
#if NPCM == 0 && !defined(EXCLUDE_PCM86)
|
||||
#define EXCLUDE_PCM86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* nothing but a sequencer (Adlib/OPL) ? */
|
||||
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NMPU == 0 && \
|
||||
NUART == 0 && NMSS == 0
|
||||
#ifndef EXCLUDE_MIDI
|
||||
#define EXCLUDE_MIDI
|
||||
#endif
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
|
||||
#define EXCLUDE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* nothing but a Midi (MPU/UART) ? */
|
||||
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NOPL == 0 && \
|
||||
NMSS == 0
|
||||
/* MPU depends on sequencer timer */
|
||||
#if NMPU == 0 && !defined(EXCLUDE_SEQUENCER)
|
||||
#define EXCLUDE_SEQUENCER
|
||||
#endif
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
|
||||
#define EXCLUDE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
@ -1,648 +0,0 @@
|
||||
/*
|
||||
* sound/midi_synth.c
|
||||
*
|
||||
* High level midi sequencer manager for dumb MIDI interfaces.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define USE_SEQ_MACROS
|
||||
#define USE_SIMPLE_MACROS
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
|
||||
|
||||
#define _MIDI_SYNTH_C_
|
||||
|
||||
DEFINE_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
|
||||
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static int midi2synth[MAX_MIDI_DEV];
|
||||
static unsigned char prev_out_status[MAX_MIDI_DEV];
|
||||
|
||||
#define STORE(cmd) \
|
||||
{ \
|
||||
int len; \
|
||||
unsigned char obuf[8]; \
|
||||
cmd; \
|
||||
seq_input_event(obuf, len); \
|
||||
}
|
||||
#define _seqbuf obuf
|
||||
#define _seqbufptr 0
|
||||
#define _SEQ_ADVBUF(x) len=x
|
||||
|
||||
void
|
||||
do_midi_msg (int synthno, unsigned char *msg, int mlen)
|
||||
{
|
||||
switch (msg[0] & 0xf0)
|
||||
{
|
||||
case 0x90:
|
||||
if (msg[2] != 0)
|
||||
{
|
||||
STORE (SEQ_START_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
}
|
||||
msg[2] = 64;
|
||||
|
||||
case 0x80:
|
||||
STORE (SEQ_STOP_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
STORE (SEQ_KEY_PRESSURE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xB0:
|
||||
STORE (SEQ_CONTROL (synthno, msg[0] & 0x0f,
|
||||
msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xC0:
|
||||
STORE (SEQ_SET_PATCH (synthno, msg[0] & 0x0f, msg[1]));
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
STORE (SEQ_CHN_PRESSURE (synthno, msg[0] & 0x0f, msg[1]));
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
STORE (SEQ_BENDER (synthno, msg[0] & 0x0f,
|
||||
(msg[1] % 0x7f) | ((msg[2] & 0x7f) << 7)));
|
||||
break;
|
||||
|
||||
default:
|
||||
printk ("MPU: Unknown midi channel message %02x\n", msg[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midi_outc (int midi_dev, int data)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
for (timeout = 0; timeout < 32000; timeout++)
|
||||
if (midi_devs[midi_dev]->putc (midi_dev, (unsigned char) (data & 0xff)))
|
||||
{
|
||||
if (data & 0x80) /*
|
||||
* Status byte
|
||||
*/
|
||||
prev_out_status[midi_dev] =
|
||||
(unsigned char) (data & 0xff); /*
|
||||
* Store for running status
|
||||
*/
|
||||
return; /*
|
||||
* Mission complete
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Sorry! No space on buffers.
|
||||
*/
|
||||
printk ("Midi send timed out\n");
|
||||
}
|
||||
|
||||
static int
|
||||
prefix_cmd (int midi_dev, unsigned char status)
|
||||
{
|
||||
if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
|
||||
return 1;
|
||||
|
||||
return midi_devs[midi_dev]->prefix_cmd (midi_dev, status);
|
||||
}
|
||||
|
||||
static void
|
||||
midi_synth_input (int dev, unsigned char data)
|
||||
{
|
||||
int orig_dev;
|
||||
struct midi_input_info *inc;
|
||||
|
||||
static unsigned char len_tab[] = /* # of data bytes following a status
|
||||
*/
|
||||
{
|
||||
2, /* 8x */
|
||||
2, /* 9x */
|
||||
2, /* Ax */
|
||||
2, /* Bx */
|
||||
1, /* Cx */
|
||||
1, /* Dx */
|
||||
2, /* Ex */
|
||||
0 /* Fx */
|
||||
};
|
||||
|
||||
if (dev < 0 || dev > num_synths)
|
||||
return;
|
||||
|
||||
if (data == 0xfe) /* Ignore active sensing */
|
||||
return;
|
||||
|
||||
orig_dev = midi2synth[dev];
|
||||
inc = &midi_devs[orig_dev]->in_info;
|
||||
|
||||
switch (inc->m_state)
|
||||
{
|
||||
case MST_INIT:
|
||||
if (data & 0x80) /* MIDI status byte */
|
||||
{
|
||||
if ((data & 0xf0) == 0xf0) /* Common message */
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0xf0: /* Sysex */
|
||||
inc->m_state = MST_SYSEX;
|
||||
break; /* Sysex */
|
||||
|
||||
case 0xf1: /* MTC quarter frame */
|
||||
case 0xf3: /* Song select */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = 1;
|
||||
inc->m_buf[0] = data;
|
||||
break;
|
||||
|
||||
case 0xf2: /* Song position pointer */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = 2;
|
||||
inc->m_buf[0] = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
inc->m_buf[0] = data;
|
||||
inc->m_ptr = 1;
|
||||
do_midi_msg (dev, inc->m_buf, inc->m_ptr);
|
||||
inc->m_ptr = 0;
|
||||
inc->m_left = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = len_tab[(data >> 4) - 8];
|
||||
inc->m_buf[0] = inc->m_prev_status = data;
|
||||
}
|
||||
}
|
||||
else if (inc->m_prev_status & 0x80) /* Ignore if no previous status (yet) */
|
||||
{ /* Data byte (use running status) */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 2;
|
||||
inc->m_left = len_tab[(data >> 4) - 8] - 1;
|
||||
inc->m_buf[0] = inc->m_prev_status;
|
||||
inc->m_buf[1] = data;
|
||||
}
|
||||
break; /* MST_INIT */
|
||||
|
||||
case MST_DATA:
|
||||
inc->m_buf[inc->m_ptr++] = data;
|
||||
if (--inc->m_left <= 0)
|
||||
{
|
||||
inc->m_state = MST_INIT;
|
||||
do_midi_msg (dev, inc->m_buf, inc->m_ptr);
|
||||
inc->m_ptr = 0;
|
||||
}
|
||||
break; /* MST_DATA */
|
||||
|
||||
case MST_SYSEX:
|
||||
if (data == 0xf7) /* Sysex end */
|
||||
{
|
||||
inc->m_state = MST_INIT;
|
||||
inc->m_left = 0;
|
||||
inc->m_ptr = 0;
|
||||
}
|
||||
break; /* MST_SYSEX */
|
||||
|
||||
default:
|
||||
printk ("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state,
|
||||
(int) data);
|
||||
inc->m_state = MST_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midi_synth_output (int dev)
|
||||
{
|
||||
/*
|
||||
* Currently NOP
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_ioctl (int dev,
|
||||
unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
/*
|
||||
* int orig_dev = synth_devs[dev]->midi_dev;
|
||||
*/
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
|
||||
case SNDCTL_SYNTH_INFO:
|
||||
IOCTL_TO_USER ((char *) arg, 0, synth_devs[dev]->info,
|
||||
sizeof (struct synth_info));
|
||||
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_SYNTH_MEMAVL:
|
||||
return 0x7fffffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_kill_note (int dev, int channel, int note, int velocity)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (note < 0 || note > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
if (velocity < 0)
|
||||
velocity = 0;
|
||||
if (velocity > 127)
|
||||
velocity = 127;
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
|
||||
{ /*
|
||||
* Use running status
|
||||
*/
|
||||
if (!prefix_cmd (orig_dev, note))
|
||||
return 0;
|
||||
|
||||
midi_outc (orig_dev, note);
|
||||
|
||||
if (msg == 0x90) /*
|
||||
* Running status = Note on
|
||||
*/
|
||||
midi_outc (orig_dev, 0); /*
|
||||
* Note on with velocity 0 == note
|
||||
* off
|
||||
*/
|
||||
else
|
||||
midi_outc (orig_dev, velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (velocity == 64)
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc (orig_dev, 0x90 | (channel & 0x0f)); /*
|
||||
* Note on
|
||||
*/
|
||||
midi_outc (orig_dev, note);
|
||||
midi_outc (orig_dev, 0); /*
|
||||
* Zero G
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0x80 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc (orig_dev, 0x80 | (channel & 0x0f)); /*
|
||||
* Note off
|
||||
*/
|
||||
midi_outc (orig_dev, note);
|
||||
midi_outc (orig_dev, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_set_instr (int dev, int channel, int instr_no)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
if (instr_no < 0 || instr_no > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
|
||||
if (!prefix_cmd (orig_dev, 0xc0 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc (orig_dev, 0xc0 | (channel & 0x0f)); /*
|
||||
* Program change
|
||||
*/
|
||||
midi_outc (orig_dev, instr_no);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_start_note (int dev, int channel, int note, int velocity)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (note < 0 || note > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
if (velocity < 0)
|
||||
velocity = 0;
|
||||
if (velocity > 127)
|
||||
velocity = 127;
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (chn == channel && msg == 0x90)
|
||||
{ /*
|
||||
* Use running status
|
||||
*/
|
||||
if (!prefix_cmd (orig_dev, note))
|
||||
return 0;
|
||||
midi_outc (orig_dev, note);
|
||||
midi_outc (orig_dev, velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc (orig_dev, 0x90 | (channel & 0x0f)); /*
|
||||
* Note on
|
||||
*/
|
||||
midi_outc (orig_dev, note);
|
||||
midi_outc (orig_dev, velocity);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_reset (int dev)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_open (int dev, int mode)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
struct midi_input_info *inc;
|
||||
|
||||
if (orig_dev < 0 || orig_dev > num_midis)
|
||||
return RET_ERROR (ENXIO);
|
||||
|
||||
midi2synth[orig_dev] = dev;
|
||||
prev_out_status[orig_dev] = 0;
|
||||
|
||||
if ((err = midi_devs[orig_dev]->open (orig_dev, mode,
|
||||
midi_synth_input, midi_synth_output)) < 0)
|
||||
return err;
|
||||
|
||||
inc = &midi_devs[orig_dev]->in_info;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
inc->m_busy = 0;
|
||||
inc->m_state = MST_INIT;
|
||||
inc->m_ptr = 0;
|
||||
inc->m_left = 0;
|
||||
inc->m_prev_status = 0x00;
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_close (int dev)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
/*
|
||||
* Shut up the synths by sending just single active sensing message.
|
||||
*/
|
||||
midi_devs[orig_dev]->putc (orig_dev, 0xfe);
|
||||
|
||||
midi_devs[orig_dev]->close (orig_dev);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_hw_control (int dev, unsigned char *event)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_load_patch (int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
struct sysex_info sysex;
|
||||
int i;
|
||||
unsigned long left, src_offs, eox_seen = 0;
|
||||
int first_byte = 1;
|
||||
int hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
|
||||
|
||||
if (!prefix_cmd (orig_dev, 0xf0))
|
||||
return 0;
|
||||
|
||||
if (format != SYSEX_PATCH)
|
||||
{
|
||||
printk ("MIDI Error: Invalid patch format (key) 0x%x\n", format);
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
if (count < hdr_size)
|
||||
{
|
||||
printk ("MIDI Error: Patch header too short\n");
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
count -= hdr_size;
|
||||
|
||||
/*
|
||||
* Copy the header from user space but ignore the first bytes which have
|
||||
* been transferred already.
|
||||
*/
|
||||
|
||||
COPY_FROM_USER (&((char *) &sysex)[offs], addr, offs, hdr_size - offs);
|
||||
|
||||
if (count < sysex.len)
|
||||
{
|
||||
printk ("MIDI Warning: Sysex record too short (%d<%d)\n",
|
||||
count, (int) sysex.len);
|
||||
sysex.len = count;
|
||||
}
|
||||
|
||||
left = sysex.len;
|
||||
src_offs = 0;
|
||||
|
||||
RESET_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
|
||||
|
||||
for (i = 0; i < left && !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag); i++)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
GET_BYTE_FROM_USER (data, addr, hdr_size + i);
|
||||
|
||||
eox_seen = (i > 0 && data & 0x80); /* End of sysex */
|
||||
|
||||
if (eox_seen && data != 0xf7)
|
||||
data = 0xf7;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
if (data != 0xf0)
|
||||
{
|
||||
printk ("Error: Sysex start missing\n");
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
while (!midi_devs[orig_dev]->putc (orig_dev, (unsigned char) (data & 0xff)) &&
|
||||
!PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag))
|
||||
DO_SLEEP (sysex_sleeper, sysex_sleep_flag, 1); /* Wait for timeout */
|
||||
|
||||
if (!first_byte && data & 0x80)
|
||||
return 0;
|
||||
first_byte = 0;
|
||||
}
|
||||
|
||||
if (!eox_seen)
|
||||
midi_outc (orig_dev, 0xf7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_panning (int dev, int channel, int pressure)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_aftertouch (int dev, int channel, int pressure)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (pressure < 0 || pressure > 127)
|
||||
return;
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xd0 || chn != channel) /*
|
||||
* Test for running status
|
||||
*/
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0xd0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc (orig_dev, 0xd0 | (channel & 0x0f)); /*
|
||||
* Channel pressure
|
||||
*/
|
||||
}
|
||||
else if (!prefix_cmd (orig_dev, pressure))
|
||||
return;
|
||||
|
||||
midi_outc (orig_dev, pressure);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_controller (int dev, int channel, int ctrl_num, int value)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int chn, msg;
|
||||
|
||||
if (ctrl_num < 1 || ctrl_num > 127)
|
||||
return; /* NOTE! Controller # 0 ignored */
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xb0 || chn != channel)
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0xb0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc (orig_dev, 0xb0 | (channel & 0x0f));
|
||||
}
|
||||
else if (!prefix_cmd (orig_dev, ctrl_num))
|
||||
return;
|
||||
|
||||
midi_outc (orig_dev, ctrl_num);
|
||||
midi_outc (orig_dev, value & 0x7f);
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_patchmgr (int dev, struct patmgr_info *rec)
|
||||
{
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_bender (int dev, int channel, int value)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, prev_chn;
|
||||
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
if (value < 0 || value > 16383)
|
||||
return;
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
prev_chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xd0 || prev_chn != channel) /*
|
||||
* Test for running status
|
||||
*/
|
||||
{
|
||||
if (!prefix_cmd (orig_dev, 0xe0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc (orig_dev, 0xe0 | (channel & 0x0f));
|
||||
}
|
||||
else if (!prefix_cmd (orig_dev, value & 0x7f))
|
||||
return;
|
||||
|
||||
midi_outc (orig_dev, value & 0x7f);
|
||||
midi_outc (orig_dev, (value >> 7) & 0x7f);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_setup_voice (int dev, int voice, int channel)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@ -1,474 +0,0 @@
|
||||
/*
|
||||
* sound/midibuf.c
|
||||
*
|
||||
* Device file manager for /dev/midi#
|
||||
*
|
||||
* 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/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
static void drain_midi_queue __P((int dev));
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
|
||||
|
||||
/*
|
||||
* Don't make MAX_QUEUE_SIZE larger than 4000
|
||||
*/
|
||||
|
||||
#define MAX_QUEUE_SIZE 4000
|
||||
|
||||
DEFINE_WAIT_QUEUES (midi_sleeper[MAX_MIDI_DEV], midi_sleep_flag[MAX_MIDI_DEV]);
|
||||
DEFINE_WAIT_QUEUES (input_sleeper[MAX_MIDI_DEV], input_sleep_flag[MAX_MIDI_DEV]);
|
||||
|
||||
struct midi_buf
|
||||
{
|
||||
int len, head, tail;
|
||||
unsigned char queue[MAX_QUEUE_SIZE];
|
||||
};
|
||||
|
||||
struct midi_parms
|
||||
{
|
||||
int prech_timeout; /*
|
||||
* Timeout before the first ch
|
||||
*/
|
||||
};
|
||||
|
||||
static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
|
||||
{NULL};
|
||||
static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
|
||||
{NULL};
|
||||
static struct midi_parms parms[MAX_MIDI_DEV];
|
||||
|
||||
static void midi_poll (unsigned long dummy);
|
||||
|
||||
DEFINE_TIMER (poll_timer, midi_poll);
|
||||
static volatile int open_devs = 0;
|
||||
|
||||
#define DATA_AVAIL(q) (q->len)
|
||||
#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
|
||||
|
||||
#define QUEUE_BYTE(q, data) \
|
||||
if (SPACE_AVAIL(q)) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
DISABLE_INTR(flags); \
|
||||
q->queue[q->tail] = (data); \
|
||||
q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
|
||||
RESTORE_INTR(flags); \
|
||||
}
|
||||
|
||||
#define REMOVE_BYTE(q, data) \
|
||||
if (DATA_AVAIL(q)) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
DISABLE_INTR(flags); \
|
||||
data = q->queue[q->head]; \
|
||||
q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
|
||||
RESTORE_INTR(flags); \
|
||||
}
|
||||
|
||||
static void
|
||||
drain_midi_queue (int dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* Give the Midi driver time to drain its output queues
|
||||
*/
|
||||
|
||||
if (midi_devs[dev]->buffer_status != NULL)
|
||||
while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
|
||||
midi_devs[dev]->buffer_status (dev))
|
||||
DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], HZ / 10);
|
||||
}
|
||||
|
||||
static void
|
||||
midi_input_intr (int dev, unsigned char data)
|
||||
{
|
||||
if (midi_in_buf[dev] == NULL)
|
||||
return;
|
||||
|
||||
if (data == 0xfe) /*
|
||||
* Active sensing
|
||||
*/
|
||||
return; /*
|
||||
* Ignore
|
||||
*/
|
||||
|
||||
if (SPACE_AVAIL (midi_in_buf[dev]))
|
||||
{
|
||||
QUEUE_BYTE (midi_in_buf[dev], data);
|
||||
if (SOMEONE_WAITING (input_sleeper[dev], input_sleep_flag[dev]))
|
||||
WAKE_UP (input_sleeper[dev], input_sleep_flag[dev]);
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (selinfo[dev].si_pid)
|
||||
selwakeup(&selinfo[dev]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
midi_output_intr (int dev)
|
||||
{
|
||||
/*
|
||||
* Currently NOP
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
if (selinfo[dev].si_pid)
|
||||
selwakeup(&selinfo[dev]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
midi_poll (unsigned long dummy)
|
||||
{
|
||||
unsigned long flags;
|
||||
int dev;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
if (open_devs)
|
||||
{
|
||||
for (dev = 0; dev < num_midis; dev++)
|
||||
if (midi_out_buf[dev] != NULL)
|
||||
{
|
||||
while (DATA_AVAIL (midi_out_buf[dev]) &&
|
||||
midi_devs[dev]->putc (dev,
|
||||
midi_out_buf[dev]->queue[midi_out_buf[dev]->head]))
|
||||
{
|
||||
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
|
||||
midi_out_buf[dev]->len--;
|
||||
}
|
||||
|
||||
if (DATA_AVAIL (midi_out_buf[dev]) < 100 &&
|
||||
SOMEONE_WAITING (midi_sleeper[dev], midi_sleep_flag[dev]))
|
||||
WAKE_UP (midi_sleeper[dev], midi_sleep_flag[dev]);
|
||||
}
|
||||
ACTIVATE_TIMER (poll_timer, midi_poll, 1); /*
|
||||
* Come back later
|
||||
*/
|
||||
}
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_open (int dev, struct fileinfo *file)
|
||||
{
|
||||
int mode, err;
|
||||
unsigned long flags;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
if (num_midis > MAX_MIDI_DEV)
|
||||
{
|
||||
printk ("Sound: FATAL ERROR: Too many midi interfaces\n");
|
||||
num_midis = MAX_MIDI_DEV;
|
||||
}
|
||||
|
||||
if (dev < 0 || dev >= num_midis)
|
||||
{
|
||||
printk ("Sound: Nonexistent MIDI interface %d\n", dev);
|
||||
return RET_ERROR (ENXIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts disabled. Be careful
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
if ((err = midi_devs[dev]->open (dev, mode,
|
||||
midi_input_intr, midi_output_intr)) < 0)
|
||||
{
|
||||
RESTORE_INTR (flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
parms[dev].prech_timeout = 0;
|
||||
|
||||
RESET_WAIT_QUEUE (midi_sleeper[dev], midi_sleep_flag[dev]);
|
||||
RESET_WAIT_QUEUE (input_sleeper[dev], input_sleep_flag[dev]);
|
||||
|
||||
midi_in_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
|
||||
|
||||
if (midi_in_buf[dev] == NULL)
|
||||
{
|
||||
printk ("midi: Can't allocate buffer\n");
|
||||
midi_devs[dev]->close (dev);
|
||||
RESTORE_INTR (flags);
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
|
||||
|
||||
midi_out_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
|
||||
|
||||
if (midi_out_buf[dev] == NULL)
|
||||
{
|
||||
printk ("midi: Can't allocate buffer\n");
|
||||
midi_devs[dev]->close (dev);
|
||||
KERNEL_FREE (midi_in_buf[dev]);
|
||||
midi_in_buf[dev] = NULL;
|
||||
RESTORE_INTR (flags);
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
|
||||
if (!open_devs)
|
||||
ACTIVATE_TIMER (poll_timer, midi_poll, 1); /*
|
||||
* Come back later
|
||||
*/
|
||||
open_devs++;
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
MIDIbuf_release (int dev, struct fileinfo *file)
|
||||
{
|
||||
int mode;
|
||||
unsigned long flags;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
/*
|
||||
* Wait until the queue is empty
|
||||
*/
|
||||
|
||||
if (mode != OPEN_READ)
|
||||
{
|
||||
midi_devs[dev]->putc (dev, 0xfe); /*
|
||||
* Active sensing to shut the
|
||||
* devices
|
||||
*/
|
||||
|
||||
while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
|
||||
DATA_AVAIL (midi_out_buf[dev]))
|
||||
DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0); /*
|
||||
* Sync
|
||||
*/
|
||||
|
||||
drain_midi_queue (dev); /*
|
||||
* Ensure the output queues are empty
|
||||
*/
|
||||
}
|
||||
|
||||
midi_devs[dev]->close (dev);
|
||||
KERNEL_FREE (midi_in_buf[dev]);
|
||||
KERNEL_FREE (midi_out_buf[dev]);
|
||||
midi_in_buf[dev] = NULL;
|
||||
midi_out_buf[dev] = NULL;
|
||||
open_devs--;
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
unsigned long flags;
|
||||
int c, n, i;
|
||||
unsigned char tmp_data;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
c = 0;
|
||||
|
||||
while (c < count)
|
||||
{
|
||||
n = SPACE_AVAIL (midi_out_buf[dev]);
|
||||
|
||||
if (n == 0) /*
|
||||
* No space just now. We have to sleep
|
||||
*/
|
||||
{
|
||||
DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);
|
||||
if (PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]))
|
||||
{
|
||||
RESTORE_INTR (flags);
|
||||
return RET_ERROR (EINTR);
|
||||
}
|
||||
|
||||
n = SPACE_AVAIL (midi_out_buf[dev]);
|
||||
}
|
||||
|
||||
if (n > (count - c))
|
||||
n = count - c;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
COPY_FROM_USER (&tmp_data, buf, c, 1);
|
||||
QUEUE_BYTE (midi_out_buf[dev], tmp_data);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int n, c = 0;
|
||||
unsigned long flags;
|
||||
unsigned char tmp_data;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (!DATA_AVAIL (midi_in_buf[dev])) /*
|
||||
* No data yet, wait
|
||||
*/
|
||||
{
|
||||
DO_SLEEP (input_sleeper[dev], input_sleep_flag[dev],
|
||||
parms[dev].prech_timeout);
|
||||
if (PROCESS_ABORTING (input_sleeper[dev], input_sleep_flag[dev]))
|
||||
c = RET_ERROR (EINTR); /*
|
||||
* The user is getting restless
|
||||
*/
|
||||
}
|
||||
|
||||
if (c == 0 && DATA_AVAIL (midi_in_buf[dev])) /*
|
||||
* Got some bytes
|
||||
*/
|
||||
{
|
||||
n = DATA_AVAIL (midi_in_buf[dev]);
|
||||
if (n > count)
|
||||
n = count;
|
||||
c = 0;
|
||||
|
||||
while (c < n)
|
||||
{
|
||||
REMOVE_BYTE (midi_in_buf[dev], tmp_data);
|
||||
COPY_TO_USER (buf, c, &tmp_data, 1);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_ioctl (int dev, struct fileinfo *file,
|
||||
unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'C')
|
||||
{
|
||||
if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
|
||||
return midi_devs[dev]->coproc->ioctl (midi_devs[dev]->coproc->devc, cmd, arg, 0);
|
||||
else
|
||||
printk ("/dev/midi%d: No coprocessor for this device\n", dev);
|
||||
|
||||
return RET_ERROR (EREMOTEIO);
|
||||
}
|
||||
else
|
||||
switch (cmd)
|
||||
{
|
||||
|
||||
case SNDCTL_MIDI_PRETIME:
|
||||
val = IOCTL_IN (arg);
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
|
||||
val = (HZ * val) / 10;
|
||||
parms[dev].prech_timeout = val;
|
||||
return IOCTL_OUT (arg, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
return midi_devs[dev]->ioctl (dev, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALLOW_SELECT
|
||||
int
|
||||
MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
|
||||
{
|
||||
dev = dev >> 4;
|
||||
|
||||
switch (sel_type)
|
||||
{
|
||||
case SEL_IN:
|
||||
if (!DATA_AVAIL (midi_in_buf[dev]))
|
||||
{
|
||||
#if defined(__FreeBSD__)
|
||||
selrecord(wait, &selinfo[dev]);
|
||||
#else
|
||||
input_sleep_flag[dev].mode = WK_SLEEP;
|
||||
select_wait (&input_sleeper[dev], wait);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case SEL_OUT:
|
||||
if (SPACE_AVAIL (midi_out_buf[dev]))
|
||||
{
|
||||
#if defined(__FreeBSD__)
|
||||
selrecord(wait, &selinfo[dev]);
|
||||
#else
|
||||
midi_sleep_flag[dev].mode = WK_SLEEP;
|
||||
select_wait (&midi_sleeper[dev], wait);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case SEL_EX:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ALLOW_SELECT */
|
||||
|
||||
long
|
||||
MIDIbuf_init (long mem_start)
|
||||
{
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -34,11 +34,7 @@
|
||||
* hooft@chem.ruu.nl
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
|
||||
|
||||
|
@ -1,420 +0,0 @@
|
||||
#define _PAS2_CARD_C_
|
||||
/*
|
||||
* sound/pas2_card.c
|
||||
*
|
||||
* Detection routine for the Pro Audio Spectrum cards.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
|
||||
|
||||
#define DEFINE_TRANSLATIONS
|
||||
#include <i386/isa/sound/pas.h>
|
||||
|
||||
static int config_pas_hw __P((struct address_info *hw_config));
|
||||
static int detect_pas_hw __P((struct address_info *hw_config));
|
||||
static void pas2_msg __P((char *foo));
|
||||
|
||||
/*
|
||||
* The Address Translation code is used to convert I/O register addresses to
|
||||
* be relative to the given base -register
|
||||
*/
|
||||
|
||||
int translat_code;
|
||||
static int pas_intr_mask = 0;
|
||||
static int pas_irq = 0;
|
||||
|
||||
char pas_model;
|
||||
static char *pas_model_names[] =
|
||||
{"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
|
||||
|
||||
extern void mix_write (unsigned char data, int ioaddr);
|
||||
/*
|
||||
* pas_read() and pas_write() are equivalents of INB() and OUTB()
|
||||
*/
|
||||
/*
|
||||
* These routines perform the I/O address translation required
|
||||
*/
|
||||
/*
|
||||
* to support other than the default base address
|
||||
*/
|
||||
|
||||
unsigned char
|
||||
pas_read (int ioaddr)
|
||||
{
|
||||
return INB (ioaddr ^ translat_code);
|
||||
}
|
||||
|
||||
void
|
||||
pas_write (unsigned char data, int ioaddr)
|
||||
{
|
||||
OUTB (data, ioaddr ^ translat_code);
|
||||
}
|
||||
|
||||
static void
|
||||
pas2_msg (char *foo)
|
||||
{
|
||||
printk (" PAS2: %s.\n", foo);
|
||||
}
|
||||
|
||||
/******************* Begin of the Interrupt Handler ********************/
|
||||
|
||||
void
|
||||
pasintr (INT_HANDLER_PARMS (irq, dummy))
|
||||
{
|
||||
int status;
|
||||
|
||||
status = pas_read (INTERRUPT_STATUS);
|
||||
pas_write (status, INTERRUPT_STATUS); /*
|
||||
* Clear interrupt
|
||||
*/
|
||||
|
||||
if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
|
||||
{
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
pas_pcm_interrupt (status, 1);
|
||||
#endif
|
||||
status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
|
||||
}
|
||||
if (status & I_S_MIDI_IRQ)
|
||||
{
|
||||
#ifndef EXCLUDE_MIDI
|
||||
#ifdef EXCLUDE_PRO_MIDI
|
||||
pas_midi_interrupt ();
|
||||
#endif
|
||||
#endif
|
||||
status &= ~I_S_MIDI_IRQ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
pas_set_intr (int mask)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
if (!pas_intr_mask)
|
||||
{
|
||||
if ((err = snd_set_irq_handler (pas_irq, pasintr, "PAS16")) < 0)
|
||||
return err;
|
||||
}
|
||||
pas_intr_mask |= mask;
|
||||
|
||||
pas_write (pas_intr_mask, INTERRUPT_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pas_remove_intr (int mask)
|
||||
{
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
pas_intr_mask &= ~mask;
|
||||
pas_write (pas_intr_mask, INTERRUPT_MASK);
|
||||
|
||||
if (!pas_intr_mask)
|
||||
{
|
||||
snd_release_irq (pas_irq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************* End of the Interrupt handler **********************/
|
||||
|
||||
/******************* Begin of the Initialization Code ******************/
|
||||
|
||||
static int
|
||||
config_pas_hw (struct address_info *hw_config)
|
||||
{
|
||||
char ok = 1;
|
||||
unsigned int_ptrs; /* scsi/sound interrupt pointers */
|
||||
|
||||
pas_irq = hw_config->irq;
|
||||
|
||||
pas_write (0x00, INTERRUPT_MASK);
|
||||
|
||||
pas_write (0x36, SAMPLE_COUNTER_CONTROL); /*
|
||||
* Local timer control *
|
||||
* register
|
||||
*/
|
||||
|
||||
pas_write (0x36, SAMPLE_RATE_TIMER); /*
|
||||
* Sample rate timer (16 bit)
|
||||
*/
|
||||
pas_write (0, SAMPLE_RATE_TIMER);
|
||||
|
||||
pas_write (0x74, SAMPLE_COUNTER_CONTROL); /*
|
||||
* Local timer control *
|
||||
* register
|
||||
*/
|
||||
|
||||
pas_write (0x74, SAMPLE_BUFFER_COUNTER); /*
|
||||
* Sample count register (16
|
||||
* * bit)
|
||||
*/
|
||||
pas_write (0, SAMPLE_BUFFER_COUNTER);
|
||||
|
||||
pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
|
||||
pas_write (P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
|
||||
pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET /*
|
||||
* |
|
||||
* S_M_OPL3_DUAL_MONO
|
||||
*/ , SERIAL_MIXER);
|
||||
|
||||
pas_write (I_C_1_BOOT_RESET_ENABLE
|
||||
#ifdef PAS_JOYSTICK_ENABLE
|
||||
| I_C_1_JOYSTICK_ENABLE
|
||||
#endif
|
||||
,IO_CONFIGURATION_1);
|
||||
|
||||
if (pas_irq < 0 || pas_irq > 15)
|
||||
{
|
||||
printk ("PAS2: Invalid IRQ %d", pas_irq);
|
||||
ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int_ptrs = pas_read (IO_CONFIGURATION_3);
|
||||
int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
|
||||
pas_write (int_ptrs, IO_CONFIGURATION_3);
|
||||
if (!I_C_3_PCM_IRQ_translate[pas_irq])
|
||||
{
|
||||
printk ("PAS2: Invalid IRQ %d", pas_irq);
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw_config->dma < 0 || hw_config->dma > 7)
|
||||
{
|
||||
printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
|
||||
ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
|
||||
if (!I_C_2_PCM_DMA_translate[hw_config->dma])
|
||||
{
|
||||
printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This fixes the timing problems of the PAS due to the Symphony chipset
|
||||
* as per Media Vision. Only define this if your PAS doesn't work correctly.
|
||||
*/
|
||||
#ifdef SYMPHONY_PAS
|
||||
OUTB (0x05, 0xa8);
|
||||
OUTB (0x60, 0xa9);
|
||||
#endif
|
||||
|
||||
#ifdef BROKEN_BUS_CLOCK
|
||||
pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
|
||||
#else
|
||||
/*
|
||||
* pas_write(S_C_1_PCS_ENABLE, SYSTEM_CONFIGURATION_1);
|
||||
*/
|
||||
pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
|
||||
#endif
|
||||
pas_write (0x18, SYSTEM_CONFIGURATION_3); /*
|
||||
* ???
|
||||
*/
|
||||
|
||||
pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY); /*
|
||||
* Sets mute
|
||||
* off and *
|
||||
* selects
|
||||
* filter
|
||||
* rate * of
|
||||
* 17.897 kHz
|
||||
*/
|
||||
|
||||
if (pas_model == PAS_16 || pas_model == PAS_16D)
|
||||
pas_write (8, PRESCALE_DIVIDER);
|
||||
else
|
||||
pas_write (0, PRESCALE_DIVIDER);
|
||||
|
||||
mix_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
|
||||
mix_write (5, PARALLEL_MIXER);
|
||||
|
||||
#if !defined(EXCLUDE_SB_EMULATION) || !defined(EXCLUDE_SB)
|
||||
|
||||
{
|
||||
struct address_info *sb_config;
|
||||
|
||||
if ((sb_config = sound_getconf (SNDCARD_SB)))
|
||||
{
|
||||
unsigned char irq_dma;
|
||||
|
||||
/*
|
||||
* Turn on Sound Blaster compatibility
|
||||
*/
|
||||
/*
|
||||
* bit 1 = SB emulation
|
||||
*/
|
||||
/*
|
||||
* bit 0 = MPU401 emulation (CDPC only :-( )
|
||||
*/
|
||||
pas_write (0x02, COMPATIBILITY_ENABLE);
|
||||
|
||||
/*
|
||||
* "Emulation address"
|
||||
*/
|
||||
pas_write ((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
|
||||
|
||||
if (!E_C_SB_DMA_translate[sb_config->dma])
|
||||
printk ("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
|
||||
sb_config->dma);
|
||||
|
||||
if (!E_C_SB_IRQ_translate[sb_config->irq])
|
||||
printk ("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
|
||||
sb_config->irq);
|
||||
|
||||
irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
|
||||
E_C_SB_IRQ_translate[sb_config->irq];
|
||||
|
||||
pas_write (irq_dma, EMULATION_CONFIGURATION);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ok)
|
||||
pas2_msg ("Driver not enabled");
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
detect_pas_hw (struct address_info *hw_config)
|
||||
{
|
||||
unsigned char board_id, foo;
|
||||
|
||||
/*
|
||||
* WARNING: Setting an option like W:1 or so that disables warm boot reset
|
||||
* of the card will screw up this detect code something fierce. Adding code
|
||||
* to handle this means possibly interfering with other cards on the bus if
|
||||
* you have something on base port 0x388. SO be forewarned.
|
||||
*/
|
||||
|
||||
OUTB (0xBC, MASTER_DECODE); /*
|
||||
* Talk to first board
|
||||
*/
|
||||
OUTB (hw_config->io_base >> 2, MASTER_DECODE); /*
|
||||
* Set base address
|
||||
*/
|
||||
translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
|
||||
pas_write (1, WAIT_STATE); /*
|
||||
* One wait-state
|
||||
*/
|
||||
|
||||
board_id = pas_read (INTERRUPT_MASK);
|
||||
|
||||
if (board_id == 0xff)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We probably have a PAS-series board, now check for a PAS2-series board
|
||||
* by trying to change the board revision bits. PAS2-series hardware won't
|
||||
* let you do this - the bits are read-only.
|
||||
*/
|
||||
|
||||
foo = board_id ^ 0xe0;
|
||||
|
||||
pas_write (foo, INTERRUPT_MASK);
|
||||
foo = INB (INTERRUPT_MASK);
|
||||
pas_write (board_id, INTERRUPT_MASK);
|
||||
|
||||
if (board_id != foo) /*
|
||||
* Not a PAS2
|
||||
*/
|
||||
return 0;
|
||||
|
||||
pas_model = pas_read (CHIP_REV);
|
||||
|
||||
return pas_model;
|
||||
}
|
||||
|
||||
long
|
||||
attach_pas_card (long mem_start, struct address_info *hw_config)
|
||||
{
|
||||
pas_irq = hw_config->irq;
|
||||
|
||||
if (detect_pas_hw (hw_config))
|
||||
{
|
||||
|
||||
if (pas_model = pas_read (CHIP_REV))
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
printk ("pas0: <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
|
||||
#else
|
||||
printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (config_pas_hw (hw_config))
|
||||
{
|
||||
|
||||
#ifndef EXCLUDE_AUDIO
|
||||
mem_start = pas_pcm_init (mem_start, hw_config);
|
||||
#endif
|
||||
|
||||
#if !defined(EXCLUDE_SB_EMULATION) && !defined(EXCLUDE_SB)
|
||||
|
||||
sb_dsp_disable_midi (); /*
|
||||
* The SB emulation don't support *
|
||||
* midi
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_YM3812
|
||||
enable_opl3_mode (0x388, 0x38a, 0);
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_MIDI
|
||||
#ifdef EXCLUDE_PRO_MIDI
|
||||
mem_start = pas_midi_init (mem_start);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pas_init_mixer ();
|
||||
}
|
||||
}
|
||||
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
int
|
||||
probe_pas (struct address_info *hw_config)
|
||||
{
|
||||
return detect_pas_hw (hw_config);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,341 +0,0 @@
|
||||
/*
|
||||
* sound/pas2_midi.c
|
||||
*
|
||||
* The low level driver for the PAS Midi Interface.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)
|
||||
|
||||
static int midi_busy = 0, input_opened = 0;
|
||||
static int my_dev;
|
||||
static volatile int ofifo_bytes = 0;
|
||||
|
||||
static unsigned char tmp_queue[256];
|
||||
static volatile int qlen;
|
||||
static volatile unsigned char qhead, qtail;
|
||||
|
||||
static void (*midi_input_intr) (int dev, unsigned char data);
|
||||
|
||||
static int
|
||||
pas_midi_open (int dev, int mode,
|
||||
void (*input) (int dev, unsigned char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
int err;
|
||||
unsigned long flags;
|
||||
unsigned char ctrl;
|
||||
|
||||
|
||||
if (midi_busy)
|
||||
{
|
||||
printk ("PAS2: Midi busy\n");
|
||||
return RET_ERROR (EBUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset input and output FIFO pointers
|
||||
*/
|
||||
pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO,
|
||||
MIDI_CONTROL);
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if ((err = pas_set_intr (I_M_MIDI_IRQ_ENABLE)) < 0)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Enable input available and output FIFO empty interrupts
|
||||
*/
|
||||
|
||||
ctrl = 0;
|
||||
input_opened = 0;
|
||||
midi_input_intr = input;
|
||||
|
||||
if (mode == OPEN_READ || mode == OPEN_READWRITE)
|
||||
{
|
||||
ctrl |= M_C_ENA_INPUT_IRQ; /*
|
||||
* Enable input
|
||||
*/
|
||||
input_opened = 1;
|
||||
}
|
||||
|
||||
if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
|
||||
{
|
||||
ctrl |= M_C_ENA_OUTPUT_IRQ | /*
|
||||
* Enable output
|
||||
*/
|
||||
M_C_ENA_OUTPUT_HALF_IRQ;
|
||||
}
|
||||
|
||||
pas_write (ctrl,
|
||||
MIDI_CONTROL);
|
||||
|
||||
/*
|
||||
* Acknowledge any pending interrupts
|
||||
*/
|
||||
|
||||
pas_write (0xff, MIDI_STATUS);
|
||||
ofifo_bytes = 0;
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
midi_busy = 1;
|
||||
qlen = qhead = qtail = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pas_midi_close (int dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* Reset FIFO pointers, disable intrs
|
||||
*/
|
||||
pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO, MIDI_CONTROL);
|
||||
|
||||
pas_remove_intr (I_M_MIDI_IRQ_ENABLE);
|
||||
midi_busy = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_to_midi (unsigned char midi_byte)
|
||||
{
|
||||
int fifo_space, x;
|
||||
|
||||
fifo_space = ((x = pas_read (MIDI_FIFO_STATUS)) >> 4) & 0x0f;
|
||||
|
||||
if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13)) /*
|
||||
* Fifo
|
||||
* full
|
||||
*/
|
||||
{
|
||||
return 0; /*
|
||||
* Upper layer will call again
|
||||
*/
|
||||
}
|
||||
|
||||
ofifo_bytes++;
|
||||
|
||||
pas_write (midi_byte, MIDI_DATA);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_out (int dev, unsigned char midi_byte)
|
||||
{
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Drain the local queue first
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
while (qlen && dump_to_midi (tmp_queue[qhead]))
|
||||
{
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
/*
|
||||
* Output the byte if the local queue is empty.
|
||||
*/
|
||||
|
||||
if (!qlen)
|
||||
if (dump_to_midi (midi_byte))
|
||||
return 1; /*
|
||||
* OK
|
||||
*/
|
||||
|
||||
/*
|
||||
* Put to the local queue
|
||||
*/
|
||||
|
||||
if (qlen >= 256)
|
||||
return 0; /*
|
||||
* Local queue full
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
tmp_queue[qtail] = midi_byte;
|
||||
qlen++;
|
||||
qtail++;
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_start_read (int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_end_read (int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_ioctl (int dev, unsigned cmd, unsigned arg)
|
||||
{
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
pas_midi_kick (int dev)
|
||||
{
|
||||
ofifo_bytes = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_buffer_status (int dev)
|
||||
{
|
||||
return !qlen;
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations pas_midi_operations =
|
||||
{
|
||||
{"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
pas_midi_open,
|
||||
pas_midi_close,
|
||||
pas_midi_ioctl,
|
||||
pas_midi_out,
|
||||
pas_midi_start_read,
|
||||
pas_midi_end_read,
|
||||
pas_midi_kick,
|
||||
NULL, /*
|
||||
* command
|
||||
*/
|
||||
pas_buffer_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
long
|
||||
pas_midi_init (long mem_start)
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV)
|
||||
{
|
||||
printk ("Sound: Too many midi devices detected\n");
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &pas_midi_operations;
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
void
|
||||
pas_midi_interrupt (void)
|
||||
{
|
||||
unsigned char stat;
|
||||
int i, incount;
|
||||
unsigned long flags;
|
||||
|
||||
stat = pas_read (MIDI_STATUS);
|
||||
|
||||
if (stat & M_S_INPUT_AVAIL) /*
|
||||
* Input byte available
|
||||
*/
|
||||
{
|
||||
incount = pas_read (MIDI_FIFO_STATUS) & 0x0f; /*
|
||||
* Input FIFO count
|
||||
*/
|
||||
if (!incount)
|
||||
incount = 16;
|
||||
|
||||
for (i = 0; i < incount; i++)
|
||||
if (input_opened)
|
||||
{
|
||||
midi_input_intr (my_dev, pas_read (MIDI_DATA));
|
||||
}
|
||||
else
|
||||
pas_read (MIDI_DATA); /*
|
||||
* Flush
|
||||
*/
|
||||
}
|
||||
|
||||
if (stat & (M_S_OUTPUT_EMPTY | M_S_OUTPUT_HALF_EMPTY))
|
||||
{
|
||||
if (!(stat & M_S_OUTPUT_EMPTY))
|
||||
{
|
||||
ofifo_bytes = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
ofifo_bytes = 0;
|
||||
}
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
while (qlen && dump_to_midi (tmp_queue[qhead]))
|
||||
{
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (stat & M_S_FRAMING_ERROR)
|
||||
printk ("MIDI framing error\n");
|
||||
#endif
|
||||
|
||||
if (stat & M_S_OUTPUT_OVERRUN)
|
||||
{
|
||||
printk ("MIDI output overrun %x,%x,%d \n", pas_read (MIDI_FIFO_STATUS), stat, ofifo_bytes);
|
||||
ofifo_bytes = 100;
|
||||
}
|
||||
|
||||
pas_write (stat, MIDI_STATUS); /*
|
||||
* Acknowledge interrupts
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,340 +0,0 @@
|
||||
#define _PAS2_MIXER_C_
|
||||
|
||||
/*
|
||||
* sound/pas2_mixer.c
|
||||
*
|
||||
* Mixer routines for the Pro Audio Spectrum cards.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
|
||||
|
||||
#include <i386/isa/sound/pas.h>
|
||||
|
||||
extern void mix_write __P((unsigned char data, int ioaddr));
|
||||
static int pas_mixer_ioctl __P((int dev, unsigned int cmd, unsigned int arg));
|
||||
static void set_mode __P((int new_mode));
|
||||
|
||||
#define TRACE(what) /* (what) */
|
||||
|
||||
extern int translat_code;
|
||||
extern char pas_model;
|
||||
|
||||
static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
|
||||
static int mode_control = 0;
|
||||
|
||||
#define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_ALTPCM)
|
||||
|
||||
#define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_ALTPCM | SOUND_MASK_IMIX | \
|
||||
SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | \
|
||||
SOUND_MASK_MUTE | SOUND_MASK_ENHANCE | SOUND_MASK_LOUD)
|
||||
|
||||
static unsigned short levels[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x3232, /* Master Volume */
|
||||
0x3232, /* Bass */
|
||||
0x3232, /* Treble */
|
||||
0x5050, /* FM */
|
||||
0x4b4b, /* PCM */
|
||||
0x3232, /* PC Speaker */
|
||||
0x4b4b, /* Ext Line */
|
||||
0x4b4b, /* Mic */
|
||||
0x4b4b, /* CD */
|
||||
0x6464, /* Recording monitor */
|
||||
0x4b4b, /* SB PCM */
|
||||
0x6464 /* Recording level */
|
||||
};
|
||||
|
||||
void
|
||||
mix_write (unsigned char data, int ioaddr)
|
||||
{
|
||||
/*
|
||||
* The Revision D cards have a problem with their MVA508 interface. The
|
||||
* kludge-o-rama fix is to make a 16-bit quantity with identical LSB and
|
||||
* MSBs out of the output byte and to do a 16-bit out to the mixer port -
|
||||
* 1. We need to do this because it isn't timing problem but chip access
|
||||
* sequence problem.
|
||||
*/
|
||||
|
||||
if (pas_model == PAS_16D)
|
||||
{
|
||||
OUTW (data | (data << 8), (ioaddr ^ translat_code) - 1);
|
||||
OUTB (0x80, 0);
|
||||
}
|
||||
else
|
||||
pas_write (data, ioaddr);
|
||||
}
|
||||
|
||||
static int
|
||||
mixer_output (int right_vol, int left_vol, int div, int bits,
|
||||
int mixer) /* Input or output mixer */
|
||||
{
|
||||
int left = left_vol * div / 100;
|
||||
int right = right_vol * div / 100;
|
||||
|
||||
|
||||
if (bits & P_M_MV508_MIXER)
|
||||
{ /*
|
||||
* Select input or output mixer
|
||||
*/
|
||||
left |= mixer;
|
||||
right |= mixer;
|
||||
}
|
||||
|
||||
if (bits == P_M_MV508_BASS || bits == P_M_MV508_TREBLE)
|
||||
{ /*
|
||||
* Bass and treble are mono devices
|
||||
*/
|
||||
mix_write (P_M_MV508_ADDRESS | bits, PARALLEL_MIXER);
|
||||
mix_write (left, PARALLEL_MIXER);
|
||||
right_vol = left_vol;
|
||||
}
|
||||
else
|
||||
{
|
||||
mix_write (P_M_MV508_ADDRESS | P_M_MV508_LEFT | bits, PARALLEL_MIXER);
|
||||
mix_write (left, PARALLEL_MIXER);
|
||||
mix_write (P_M_MV508_ADDRESS | P_M_MV508_RIGHT | bits, PARALLEL_MIXER);
|
||||
mix_write (right, PARALLEL_MIXER);
|
||||
}
|
||||
|
||||
return (left_vol | (right_vol << 8));
|
||||
}
|
||||
|
||||
static void
|
||||
set_mode (int new_mode)
|
||||
{
|
||||
mix_write (P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
|
||||
mix_write (new_mode, PARALLEL_MIXER);
|
||||
|
||||
mode_control = new_mode;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_mixer_set (int whichDev, unsigned int level)
|
||||
{
|
||||
int left, right, devmask, changed, i, mixer = 0;
|
||||
|
||||
TRACE (printk ("static int pas_mixer_set(int whichDev = %d, unsigned int level = %X)\n", whichDev, level));
|
||||
|
||||
left = level & 0x7f;
|
||||
right = (level & 0x7f00) >> 8;
|
||||
|
||||
if (whichDev < SOUND_MIXER_NRDEVICES)
|
||||
if ((1 << whichDev) & rec_devices)
|
||||
mixer = P_M_MV508_INPUTMIX;
|
||||
else
|
||||
mixer = P_M_MV508_OUTPUTMIX;
|
||||
|
||||
switch (whichDev)
|
||||
{
|
||||
case SOUND_MIXER_VOLUME: /* Master volume (0-63) */
|
||||
levels[whichDev] = mixer_output (right, left, 63, P_M_MV508_MASTER_A, 0);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Note! Bass and Treble are mono devices. Will use just the left
|
||||
* channel.
|
||||
*/
|
||||
case SOUND_MIXER_BASS: /* Bass (0-12) */
|
||||
levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_BASS, 0);
|
||||
break;
|
||||
case SOUND_MIXER_TREBLE: /* Treble (0-12) */
|
||||
levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_TREBLE, 0);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH: /* Internal synthesizer (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_FM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_PCM: /* PAS PCM (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_PCM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_ALTPCM: /* SB PCM (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SB, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_SPEAKER: /* PC speaker (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SPEAKER, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_LINE: /* External line (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_LINE, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_CD: /* CD (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_CDROM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_MIC: /* External microphone (0-31) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_MIC, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_IMIX: /* Recording monitor (0-31) (Output mixer only) */
|
||||
levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_IMIXER,
|
||||
P_M_MV508_OUTPUTMIX);
|
||||
break;
|
||||
case SOUND_MIXER_RECLEV: /* Recording level (0-15) */
|
||||
levels[whichDev] = mixer_output (right, left, 15, P_M_MV508_MASTER_B, 0);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MUTE:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_ENHANCE:
|
||||
i = 0;
|
||||
level &= 0x7f;
|
||||
if (level)
|
||||
i = (level / 20) - 1;
|
||||
|
||||
mode_control &= ~P_M_MV508_ENHANCE_BITS;
|
||||
mode_control |= P_M_MV508_ENHANCE_BITS;
|
||||
set_mode (mode_control);
|
||||
|
||||
if (i)
|
||||
i = (i + 1) * 20;
|
||||
return i;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LOUD:
|
||||
mode_control &= ~P_M_MV508_LOUDNESS;
|
||||
if (level)
|
||||
mode_control |= P_M_MV508_LOUDNESS;
|
||||
set_mode (mode_control);
|
||||
return !!level; /* 0 or 1 */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
devmask = level & POSSIBLE_RECORDING_DEVICES;
|
||||
|
||||
changed = devmask ^ rec_devices;
|
||||
rec_devices = devmask;
|
||||
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
if (changed & (1 << i))
|
||||
{
|
||||
pas_mixer_set (i, levels[i]);
|
||||
}
|
||||
return rec_devices;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
return (levels[whichDev]);
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
pas_mixer_reset (void)
|
||||
{
|
||||
int foo;
|
||||
|
||||
TRACE (printk ("pas2_mixer.c: void pas_mixer_reset(void)\n"));
|
||||
|
||||
for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
|
||||
pas_mixer_set (foo, levels[foo]);
|
||||
|
||||
set_mode (P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_40);
|
||||
}
|
||||
|
||||
int
|
||||
pas_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
TRACE (printk ("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'M')
|
||||
{
|
||||
if (cmd & IOC_IN)
|
||||
return IOCTL_OUT (arg, pas_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
|
||||
else
|
||||
{ /*
|
||||
* Read parameters
|
||||
*/
|
||||
|
||||
switch (cmd & 0xff)
|
||||
{
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return IOCTL_OUT (arg, rec_devices);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return IOCTL_OUT (arg, POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return IOCTL_OUT (arg, 0); /* No special capabilities */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MUTE:
|
||||
return IOCTL_OUT (arg, 0); /* No mute yet */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_ENHANCE:
|
||||
if (!(mode_control & P_M_MV508_ENHANCE_BITS))
|
||||
return IOCTL_OUT (arg, 0);
|
||||
return IOCTL_OUT (arg, ((mode_control & P_M_MV508_ENHANCE_BITS) + 1) * 20);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LOUD:
|
||||
if (mode_control & P_M_MV508_LOUDNESS)
|
||||
return IOCTL_OUT (arg, 1);
|
||||
return IOCTL_OUT (arg, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return IOCTL_OUT (arg, levels[cmd & 0xff]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations pas_mixer_operations =
|
||||
{
|
||||
"Pro Audio Spectrum 16",
|
||||
pas_mixer_ioctl
|
||||
};
|
||||
|
||||
int
|
||||
pas_init_mixer (void)
|
||||
{
|
||||
pas_mixer_reset ();
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV)
|
||||
mixer_devs[num_mixers++] = &pas_mixer_operations;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,272 +0,0 @@
|
||||
/*
|
||||
* sound/patmgr.c
|
||||
*
|
||||
* The patch maneger interface for the /dev/sequencer
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define PATMGR_C
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SEQUENCER)
|
||||
|
||||
DEFINE_WAIT_QUEUES (server_procs[MAX_SYNTH_DEV],
|
||||
server_wait_flag[MAX_SYNTH_DEV]);
|
||||
|
||||
static struct patmgr_info *mbox[MAX_SYNTH_DEV] =
|
||||
{NULL};
|
||||
static volatile int msg_direction[MAX_SYNTH_DEV] =
|
||||
{0};
|
||||
|
||||
static int pmgr_opened[MAX_SYNTH_DEV] =
|
||||
{0};
|
||||
|
||||
#define A_TO_S 1
|
||||
#define S_TO_A 2
|
||||
|
||||
DEFINE_WAIT_QUEUE (appl_proc, appl_wait_flag);
|
||||
|
||||
int
|
||||
pmgr_open (int dev)
|
||||
{
|
||||
if (dev < 0 || dev >= num_synths)
|
||||
return RET_ERROR (ENXIO);
|
||||
|
||||
if (pmgr_opened[dev])
|
||||
return RET_ERROR (EBUSY);
|
||||
pmgr_opened[dev] = 1;
|
||||
|
||||
RESET_WAIT_QUEUE (server_procs[dev], server_wait_flag[dev]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pmgr_release (int dev)
|
||||
{
|
||||
|
||||
if (mbox[dev]) /*
|
||||
* Killed in action. Inform the client
|
||||
*/
|
||||
{
|
||||
|
||||
mbox[dev]->key = PM_ERROR;
|
||||
mbox[dev]->parm1 = RET_ERROR (EIO);
|
||||
|
||||
if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
|
||||
WAKE_UP (appl_proc, appl_wait_flag);
|
||||
}
|
||||
|
||||
pmgr_opened[dev] = 0;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ok = 0;
|
||||
|
||||
if (count != sizeof (struct patmgr_info))
|
||||
{
|
||||
printk ("PATMGR%d: Invalid read count\n", dev);
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
while (!ok && !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
|
||||
{
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
|
||||
!PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
|
||||
{
|
||||
DO_SLEEP (server_procs[dev], server_wait_flag[dev], 0);
|
||||
}
|
||||
|
||||
if (mbox[dev] && msg_direction[dev] == A_TO_S)
|
||||
{
|
||||
COPY_TO_USER (buf, 0, (char *) mbox[dev], count);
|
||||
msg_direction[dev] = 0;
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
return RET_ERROR (EINTR);
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (count < 4)
|
||||
{
|
||||
printk ("PATMGR%d: Write count < 4\n", dev);
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
COPY_FROM_USER (mbox[dev], buf, 0, 4);
|
||||
|
||||
if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE)
|
||||
{
|
||||
int tmp_dev;
|
||||
|
||||
tmp_dev = ((unsigned short *) mbox[dev])[2];
|
||||
if (tmp_dev != dev)
|
||||
return RET_ERROR (ENXIO);
|
||||
|
||||
return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev],
|
||||
buf, 4, count, 1);
|
||||
}
|
||||
|
||||
if (count != sizeof (struct patmgr_info))
|
||||
{
|
||||
printk ("PATMGR%d: Invalid write count\n", dev);
|
||||
return RET_ERROR (EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* If everything went OK, there should be a preallocated buffer in the
|
||||
* mailbox and a client waiting.
|
||||
*/
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (mbox[dev] && !msg_direction[dev])
|
||||
{
|
||||
COPY_FROM_USER (&((char *) mbox[dev])[4], buf, 4, count - 4);
|
||||
msg_direction[dev] = S_TO_A;
|
||||
|
||||
if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
|
||||
{
|
||||
WAKE_UP (appl_proc, appl_wait_flag);
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_access (int dev, struct patmgr_info *rec)
|
||||
{
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (mbox[dev])
|
||||
printk (" PATMGR: Server %d mbox full. Why?\n", dev);
|
||||
else
|
||||
{
|
||||
rec->key = PM_K_COMMAND;
|
||||
mbox[dev] = rec;
|
||||
msg_direction[dev] = A_TO_S;
|
||||
|
||||
if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
|
||||
{
|
||||
WAKE_UP (server_procs[dev], server_wait_flag[dev]);
|
||||
}
|
||||
|
||||
DO_SLEEP (appl_proc, appl_wait_flag, 0);
|
||||
|
||||
if (msg_direction[dev] != S_TO_A)
|
||||
{
|
||||
rec->key = PM_ERROR;
|
||||
rec->parm1 = RET_ERROR (EIO);
|
||||
}
|
||||
else if (rec->key == PM_ERROR)
|
||||
{
|
||||
err = rec->parm1;
|
||||
if (err > 0)
|
||||
err = -err;
|
||||
}
|
||||
|
||||
mbox[dev] = NULL;
|
||||
msg_direction[dev] = 0;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2,
|
||||
unsigned long p3, unsigned long p4)
|
||||
{
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
if (!pmgr_opened[dev])
|
||||
return 0;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
if (mbox[dev])
|
||||
printk (" PATMGR: Server %d mbox full. Why?\n", dev);
|
||||
else
|
||||
{
|
||||
if ((mbox[dev] =
|
||||
(struct patmgr_info *) KERNEL_MALLOC (sizeof (struct patmgr_info))) == NULL)
|
||||
{
|
||||
printk ("pmgr: Couldn't allocate memory for a message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbox[dev]->key = PM_K_EVENT;
|
||||
mbox[dev]->command = event;
|
||||
mbox[dev]->parm1 = p1;
|
||||
mbox[dev]->parm2 = p2;
|
||||
mbox[dev]->parm3 = p3;
|
||||
msg_direction[dev] = A_TO_S;
|
||||
|
||||
if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
|
||||
{
|
||||
WAKE_UP (server_procs[dev], server_wait_flag[dev]);
|
||||
}
|
||||
|
||||
DO_SLEEP (appl_proc, appl_wait_flag, 0);
|
||||
if (mbox[dev])
|
||||
KERNEL_FREE (mbox[dev]);
|
||||
mbox[dev] = NULL;
|
||||
msg_direction[dev] = 0;
|
||||
}
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
@ -25,7 +25,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pcm86.c,v 2.4 1996/01/24 19:53:34 abtk Exp $
|
||||
* $Id: pcm86.c,v 1.2 1996/09/12 11:11:16 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "sound_config.h"
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#ifdef CONFIGURE_SOUNDCARD
|
||||
|
||||
|
@ -34,11 +34,7 @@
|
||||
/*
|
||||
* #define DEB_DMARES
|
||||
*/
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
#include <i386/isa/sound/sb.h>
|
||||
#include <i386/isa/sound/sb_mixer.h>
|
||||
|
||||
|
@ -27,11 +27,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_SOUNDCARD
|
||||
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* sound/sb_card.c
|
||||
*
|
||||
* Detection routine for the SoundBlaster cards.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Modified:
|
||||
* Riccardo Facchetti 24 Mar 1995
|
||||
* - Added the Audio Excel DSP 16 initialization routine.
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
|
||||
|
||||
long
|
||||
attach_sb_card (long mem_start, struct address_info *hw_config)
|
||||
{
|
||||
#if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_MIDI)
|
||||
if (!sb_dsp_detect (hw_config))
|
||||
return mem_start;
|
||||
mem_start = sb_dsp_init (mem_start, hw_config);
|
||||
#endif
|
||||
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
int
|
||||
probe_sb (struct address_info *hw_config)
|
||||
{
|
||||
#if !defined(EXCLUDE_AEDSP16) && defined(AEDSP16_SBPRO)
|
||||
/*
|
||||
* Initialize Audio Excel DSP 16 to SBPRO.
|
||||
*/
|
||||
InitAEDSP16_SBPRO (hw_config);
|
||||
#endif
|
||||
return sb_dsp_detect (hw_config);
|
||||
}
|
||||
|
||||
#endif
|
@ -33,11 +33,7 @@
|
||||
* Code added for MV ProSonic/Jazz 16 in 16 bit mode
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
|
||||
|
||||
|
@ -1,257 +0,0 @@
|
||||
/*
|
||||
* sound/sb_dsp.c
|
||||
*
|
||||
* The low level driver for the SoundBlaster DS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_MIDI)
|
||||
|
||||
#include <i386/isa/sound/sb.h>
|
||||
#undef SB_TEST_IRQ
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern int sb_dsp_ok; /* Set to 1 atfer successful initialization */
|
||||
extern int sbc_base;
|
||||
|
||||
extern int sb_midi_mode;
|
||||
extern int sb_midi_busy; /*
|
||||
|
||||
|
||||
* * * * 1 if the process has output to MIDI
|
||||
*
|
||||
*/
|
||||
extern int sb_dsp_busy;
|
||||
extern int sb_dsp_highspeed;
|
||||
|
||||
extern volatile int sb_irq_mode;
|
||||
extern int sb_duplex_midi;
|
||||
extern int sb_intr_active;
|
||||
static int input_opened = 0;
|
||||
static int my_dev;
|
||||
|
||||
void (*midi_input_intr) (int dev, unsigned char data);
|
||||
|
||||
static int
|
||||
sb_midi_open (int dev, int mode,
|
||||
void (*input) (int dev, unsigned char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!sb_dsp_ok)
|
||||
{
|
||||
printk ("SB Error: MIDI hardware not installed\n");
|
||||
return RET_ERROR (ENXIO);
|
||||
}
|
||||
|
||||
if (sb_midi_busy)
|
||||
return RET_ERROR (EBUSY);
|
||||
|
||||
if (mode != OPEN_WRITE && !sb_duplex_midi)
|
||||
{
|
||||
if (num_midis == 1)
|
||||
printk ("SoundBlaster: Midi input not currently supported\n");
|
||||
return RET_ERROR (EPERM);
|
||||
}
|
||||
|
||||
sb_midi_mode = NORMAL_MIDI;
|
||||
if (mode != OPEN_WRITE)
|
||||
{
|
||||
if (sb_dsp_busy || sb_intr_active)
|
||||
return RET_ERROR (EBUSY);
|
||||
sb_midi_mode = UART_MIDI;
|
||||
}
|
||||
|
||||
if (sb_dsp_highspeed)
|
||||
{
|
||||
printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
|
||||
return RET_ERROR (EBUSY);
|
||||
}
|
||||
|
||||
if (sb_midi_mode == UART_MIDI)
|
||||
{
|
||||
sb_irq_mode = IMODE_MIDI;
|
||||
|
||||
sb_reset_dsp ();
|
||||
|
||||
if (!sb_dsp_command (0x35))
|
||||
return RET_ERROR (EIO); /*
|
||||
* Enter the UART mode
|
||||
*/
|
||||
sb_intr_active = 1;
|
||||
|
||||
if ((ret = sb_get_irq ()) < 0)
|
||||
{
|
||||
sb_reset_dsp ();
|
||||
return 0; /*
|
||||
* IRQ not free
|
||||
*/
|
||||
}
|
||||
input_opened = 1;
|
||||
midi_input_intr = input;
|
||||
}
|
||||
|
||||
sb_midi_busy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb_midi_close (int dev)
|
||||
{
|
||||
if (sb_midi_mode == UART_MIDI)
|
||||
{
|
||||
sb_reset_dsp (); /*
|
||||
* The only way to kill the UART mode
|
||||
*/
|
||||
sb_free_irq ();
|
||||
}
|
||||
sb_intr_active = 0;
|
||||
sb_midi_busy = 0;
|
||||
input_opened = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_out (int dev, unsigned char midi_byte)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (sb_midi_mode == NORMAL_MIDI)
|
||||
{
|
||||
DISABLE_INTR (flags);
|
||||
if (sb_dsp_command (0x38))
|
||||
sb_dsp_command (midi_byte);
|
||||
else
|
||||
printk ("SB Error: Unable to send a MIDI byte\n");
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
else
|
||||
sb_dsp_command (midi_byte); /*
|
||||
* UART write
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_start_read (int dev)
|
||||
{
|
||||
if (sb_midi_mode != UART_MIDI)
|
||||
{
|
||||
printk ("SoundBlaster: MIDI input not implemented.\n");
|
||||
return RET_ERROR (EPERM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_end_read (int dev)
|
||||
{
|
||||
if (sb_midi_mode == UART_MIDI)
|
||||
{
|
||||
sb_reset_dsp ();
|
||||
sb_intr_active = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
|
||||
{
|
||||
return RET_ERROR (EPERM);
|
||||
}
|
||||
|
||||
void
|
||||
sb_midi_interrupt (int dummy)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned char data;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
|
||||
data = INB (DSP_READ);
|
||||
if (input_opened)
|
||||
midi_input_intr (my_dev, data);
|
||||
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "SoundBlaster Midi"
|
||||
#define MIDI_SYNTH_CAPS 0
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations sb_midi_operations =
|
||||
{
|
||||
{"SoundBlaster", 0, 0, SNDCARD_SB},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
sb_midi_open,
|
||||
sb_midi_close,
|
||||
sb_midi_ioctl,
|
||||
sb_midi_out,
|
||||
sb_midi_start_read,
|
||||
sb_midi_end_read,
|
||||
NULL, /*
|
||||
* Kick
|
||||
*/
|
||||
NULL, /*
|
||||
* command
|
||||
*/
|
||||
NULL, /*
|
||||
* buffer_status
|
||||
*/
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
sb_midi_init (int model)
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV)
|
||||
{
|
||||
printk ("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std_midi_synth.midi_dev = num_midis;
|
||||
my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &sb_midi_operations;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,591 +0,0 @@
|
||||
|
||||
/*
|
||||
* sound/sb_mixer.c
|
||||
*
|
||||
* The low level mixer driver for the SoundBlaster Pro and SB16 cards.
|
||||
*
|
||||
* 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 the Sound Galaxy NX Pro mixer.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/sound/sound_config.h>
|
||||
#else
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_SBPRO)
|
||||
#define __SB_MIXER_C__
|
||||
|
||||
#include <i386/isa/sound/sb.h>
|
||||
#include <i386/isa/sound/sb_mixer.h>
|
||||
#undef SB_TEST_IRQ
|
||||
|
||||
extern int sbc_base;
|
||||
extern int sbc_major;
|
||||
extern int Jazz16_detected;
|
||||
|
||||
static int mixer_initialized = 0;
|
||||
|
||||
static int supported_rec_devices;
|
||||
static int supported_devices;
|
||||
static int recmask = 0;
|
||||
static int mixer_model;
|
||||
static int mixer_caps;
|
||||
static mixer_tab *iomap;
|
||||
|
||||
void
|
||||
sb_setmixer (unsigned int port, unsigned int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
OUTB ((unsigned char) (port & 0xff), MIXER_ADDR); /*
|
||||
* Select register
|
||||
*/
|
||||
tenmicrosec ();
|
||||
OUTB ((unsigned char) (value & 0xff), MIXER_DATA);
|
||||
tenmicrosec ();
|
||||
RESTORE_INTR (flags);
|
||||
}
|
||||
|
||||
int
|
||||
sb_getmixer (unsigned int port)
|
||||
{
|
||||
int val;
|
||||
unsigned long flags;
|
||||
|
||||
DISABLE_INTR (flags);
|
||||
OUTB ((unsigned char) (port & 0xff), MIXER_ADDR); /*
|
||||
* Select register
|
||||
*/
|
||||
tenmicrosec ();
|
||||
val = INB (MIXER_DATA);
|
||||
tenmicrosec ();
|
||||
RESTORE_INTR (flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
sb_mixer_set_stereo (int mode)
|
||||
{
|
||||
if (!mixer_initialized)
|
||||
return;
|
||||
|
||||
sb_setmixer (OUT_FILTER, ((sb_getmixer (OUT_FILTER) & ~STEREO_DAC)
|
||||
| (mode ? STEREO_DAC : MONO_DAC)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* 0 No mixer detected.
|
||||
* 1 Only a plain Sound Blaster Pro style mixer detected.
|
||||
* 2 The Sound Galaxy NX Pro mixer detected.
|
||||
*/
|
||||
static int
|
||||
detect_mixer (void)
|
||||
{
|
||||
#ifdef __SGNXPRO__
|
||||
int oldbass, oldtreble;
|
||||
|
||||
#endif
|
||||
int retcode = 1;
|
||||
|
||||
/*
|
||||
* Detect the mixer by changing parameters of two volume channels. If the
|
||||
* values read back match with the values written, the mixer is there (is
|
||||
* it?)
|
||||
*/
|
||||
sb_setmixer (FM_VOL, 0xff);
|
||||
sb_setmixer (VOC_VOL, 0x33);
|
||||
|
||||
if (sb_getmixer (FM_VOL) != 0xff)
|
||||
return 0; /*
|
||||
* No match
|
||||
*/
|
||||
if (sb_getmixer (VOC_VOL) != 0x33)
|
||||
return 0;
|
||||
|
||||
#ifdef __SGNXPRO__
|
||||
/* Attempt to detect the SG NX Pro by check for valid bass/treble
|
||||
* registers.
|
||||
*/
|
||||
oldbass = sb_getmixer (BASS_LVL);
|
||||
oldtreble = sb_getmixer (TREBLE_LVL);
|
||||
|
||||
sb_setmixer (BASS_LVL, 0xaa);
|
||||
sb_setmixer (TREBLE_LVL, 0x55);
|
||||
|
||||
if ((sb_getmixer (BASS_LVL) != 0xaa) ||
|
||||
(sb_getmixer (TREBLE_LVL) != 0x55))
|
||||
{
|
||||
retcode = 1; /* 1 == Only SB Pro detected */
|
||||
}
|
||||
else
|
||||
retcode = 2; /* 2 == SG NX Pro detected */
|
||||
/* Restore register in either case since SG NX Pro has EEPROM with
|
||||
* 'preferred' values stored.
|
||||
*/
|
||||
sb_setmixer (BASS_LVL, oldbass);
|
||||
sb_setmixer (TREBLE_LVL, oldtreble);
|
||||
|
||||
/*
|
||||
* If the SB version is 3.X (SB Pro), assume we have a SG NX Pro 16.
|
||||
* In this case it's good idea to disable the Disney Sound Source
|
||||
* compatibility mode. It's useless and just causes noise every time the
|
||||
* LPT-port is accessed.
|
||||
*
|
||||
* Also place the card into WSS mode.
|
||||
*/
|
||||
if (sbc_major == 3)
|
||||
{
|
||||
OUTB (0x01, sbc_base + 0x1c);
|
||||
OUTB (0x00, sbc_base + 0x1a);
|
||||
}
|
||||
|
||||
#endif
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static void
|
||||
change_bits (unsigned char *regval, int dev, int chn, int newval)
|
||||
{
|
||||
unsigned char mask;
|
||||
int shift;
|
||||
|
||||
mask = (1 << (*iomap)[dev][chn].nbits) - 1;
|
||||
newval = (int) ((newval * mask) + 50) / 100; /*
|
||||
* Scale it
|
||||
*/
|
||||
|
||||
shift = (*iomap)[dev][chn].bitoffs - (*iomap)[dev][LEFT_CHN].nbits + 1;
|
||||
|
||||
*regval &= ~(mask << shift); /*
|
||||
* Filter out the previous value
|
||||
*/
|
||||
*regval |= (newval & mask) << shift; /*
|
||||
* Set the new value
|
||||
*/
|
||||
}
|
||||
|
||||
static int
|
||||
sb_mixer_get (int dev)
|
||||
{
|
||||
if (!((1 << dev) & supported_devices))
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
return levels[dev];
|
||||
}
|
||||
|
||||
#ifdef JAZZ16
|
||||
static char smw_mix_regs[] = /* Left mixer registers */
|
||||
{
|
||||
0x0b, /* SOUND_MIXER_VOLUME */
|
||||
0x0d, /* SOUND_MIXER_BASS */
|
||||
0x0d, /* SOUND_MIXER_TREBLE */
|
||||
0x05, /* SOUND_MIXER_SYNTH */
|
||||
0x09, /* SOUND_MIXER_PCM */
|
||||
0x00, /* SOUND_MIXER_SPEAKER */
|
||||
0x03, /* SOUND_MIXER_LINE */
|
||||
0x01, /* SOUND_MIXER_MIC */
|
||||
0x07, /* SOUND_MIXER_CD */
|
||||
0x00, /* SOUND_MIXER_IMIX */
|
||||
0x00, /* SOUND_MIXER_ALTPCM */
|
||||
0x00, /* SOUND_MIXER_RECLEV */
|
||||
0x00, /* SOUND_MIXER_IGAIN */
|
||||
0x00, /* SOUND_MIXER_OGAIN */
|
||||
0x00, /* SOUND_MIXER_LINE1 */
|
||||
0x00, /* SOUND_MIXER_LINE2 */
|
||||
0x00 /* SOUND_MIXER_LINE3 */
|
||||
};
|
||||
|
||||
static void
|
||||
smw_mixer_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
sb_setmixer (0x00, 0x18); /* Mute unused (Telephone) line */
|
||||
sb_setmixer (0x10, 0x38); /* Config register 2 */
|
||||
|
||||
supported_devices = 0;
|
||||
for (i = 0; i < sizeof (smw_mix_regs); i++)
|
||||
if (smw_mix_regs[i] != 0)
|
||||
supported_devices |= (1 << i);
|
||||
|
||||
supported_rec_devices = supported_devices &
|
||||
~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM |
|
||||
SOUND_MASK_VOLUME);
|
||||
}
|
||||
|
||||
static int
|
||||
smw_mixer_set (int dev, int value)
|
||||
{
|
||||
int left = value & 0x000000ff;
|
||||
int right = (value & 0x0000ff00) >> 8;
|
||||
int reg, val;
|
||||
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
if (right > 100)
|
||||
right = 100;
|
||||
|
||||
if (dev > 31)
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
if (!(supported_devices & (1 << dev))) /* Not supported */
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
switch (dev)
|
||||
{
|
||||
case SOUND_MIXER_VOLUME:
|
||||
sb_setmixer (0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
|
||||
sb_setmixer (0x0c, 96 - (96 * right / 100));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_BASS:
|
||||
case SOUND_MIXER_TREBLE:
|
||||
levels[dev] = left | (right << 8);
|
||||
|
||||
/* Set left bass and treble values */
|
||||
val = ((levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / 100) << 4;
|
||||
val |= ((levels[SOUND_MIXER_BASS] & 0xff) * 16 / 100) & 0x0f;
|
||||
sb_setmixer (0x0d, val);
|
||||
|
||||
/* Set right bass and treble values */
|
||||
val = (((levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / 100) << 4;
|
||||
val |= (((levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / 100) & 0x0f;
|
||||
sb_setmixer (0x0e, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
reg = smw_mix_regs[dev];
|
||||
if (reg == 0)
|
||||
return RET_ERROR (EINVAL);
|
||||
sb_setmixer (reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
|
||||
sb_setmixer (reg + 1, (24 - (24 * right / 100)) | 0x40);
|
||||
}
|
||||
|
||||
levels[dev] = left | (right << 8);
|
||||
return left | (right << 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
sb_mixer_set (int dev, int value)
|
||||
{
|
||||
int left = value & 0x000000ff;
|
||||
int right = (value & 0x0000ff00) >> 8;
|
||||
|
||||
int regoffs;
|
||||
unsigned char val;
|
||||
|
||||
#ifdef JAZZ16
|
||||
if (Jazz16_detected == 2)
|
||||
return smw_mixer_set (dev, value);
|
||||
#endif
|
||||
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
if (right > 100)
|
||||
right = 100;
|
||||
|
||||
if (dev > 31)
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
if (!(supported_devices & (1 << dev))) /*
|
||||
* Not supported
|
||||
*/
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
regoffs = (*iomap)[dev][LEFT_CHN].regno;
|
||||
|
||||
if (regoffs == 0)
|
||||
return RET_ERROR (EINVAL);
|
||||
|
||||
val = sb_getmixer (regoffs);
|
||||
change_bits (&val, dev, LEFT_CHN, left);
|
||||
|
||||
levels[dev] = left | (left << 8);
|
||||
|
||||
if ((*iomap)[dev][RIGHT_CHN].regno != regoffs) /*
|
||||
* Change register
|
||||
*/
|
||||
{
|
||||
sb_setmixer (regoffs, val); /*
|
||||
* Save the old one
|
||||
*/
|
||||
regoffs = (*iomap)[dev][RIGHT_CHN].regno;
|
||||
|
||||
if (regoffs == 0)
|
||||
return left | (left << 8); /*
|
||||
* Just left channel present
|
||||
*/
|
||||
|
||||
val = sb_getmixer (regoffs); /*
|
||||
* Read the new one
|
||||
*/
|
||||
}
|
||||
|
||||
change_bits (&val, dev, RIGHT_CHN, right);
|
||||
|
||||
sb_setmixer (regoffs, val);
|
||||
|
||||
levels[dev] = left | (right << 8);
|
||||
return left | (right << 8);
|
||||
}
|
||||
|
||||
static void
|
||||
set_recsrc (int src)
|
||||
{
|
||||
sb_setmixer (RECORD_SRC, (sb_getmixer (RECORD_SRC) & ~7) | (src & 0x7));
|
||||
}
|
||||
|
||||
static int
|
||||
set_recmask (int mask)
|
||||
{
|
||||
int devmask, i;
|
||||
unsigned char regimageL, regimageR;
|
||||
|
||||
devmask = mask & supported_rec_devices;
|
||||
|
||||
switch (mixer_model)
|
||||
{
|
||||
case 3:
|
||||
|
||||
if (devmask != SOUND_MASK_MIC &&
|
||||
devmask != SOUND_MASK_LINE &&
|
||||
devmask != SOUND_MASK_CD)
|
||||
{ /*
|
||||
* More than one devices selected. Drop the *
|
||||
* previous selection
|
||||
*/
|
||||
devmask &= ~recmask;
|
||||
}
|
||||
|
||||
if (devmask != SOUND_MASK_MIC &&
|
||||
devmask != SOUND_MASK_LINE &&
|
||||
devmask != SOUND_MASK_CD)
|
||||
{ /*
|
||||
* More than one devices selected. Default to
|
||||
* * mic
|
||||
*/
|
||||
devmask = SOUND_MASK_MIC;
|
||||
}
|
||||
|
||||
|
||||
if (devmask ^ recmask) /*
|
||||
* Input source changed
|
||||
*/
|
||||
{
|
||||
switch (devmask)
|
||||
{
|
||||
|
||||
case SOUND_MASK_MIC:
|
||||
set_recsrc (SRC_MIC);
|
||||
break;
|
||||
|
||||
case SOUND_MASK_LINE:
|
||||
set_recsrc (SRC_LINE);
|
||||
break;
|
||||
|
||||
case SOUND_MASK_CD:
|
||||
set_recsrc (SRC_CD);
|
||||
break;
|
||||
|
||||
default:
|
||||
set_recsrc (SRC_MIC);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!devmask)
|
||||
devmask = SOUND_MASK_MIC;
|
||||
|
||||
regimageL = regimageR = 0;
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
if ((1 << i) & devmask)
|
||||
{
|
||||
regimageL |= sb16_recmasks_L[i];
|
||||
regimageR |= sb16_recmasks_R[i];
|
||||
}
|
||||
sb_setmixer (SB16_IMASK_L, regimageL);
|
||||
sb_setmixer (SB16_IMASK_R, regimageR);
|
||||
break;
|
||||
}
|
||||
|
||||
recmask = devmask;
|
||||
return recmask;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
if (((cmd >> 8) & 0xff) == 'M')
|
||||
{
|
||||
if (cmd & IOC_IN)
|
||||
switch (cmd & 0xff)
|
||||
{
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return IOCTL_OUT (arg, set_recmask (IOCTL_IN (arg)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return IOCTL_OUT (arg, sb_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
|
||||
}
|
||||
else
|
||||
switch (cmd & 0xff) /*
|
||||
* Return parameters
|
||||
*/
|
||||
{
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return IOCTL_OUT (arg, recmask);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return IOCTL_OUT (arg, supported_devices);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
if (Jazz16_detected)
|
||||
return IOCTL_OUT (arg, supported_devices);
|
||||
else
|
||||
return IOCTL_OUT (arg, supported_devices &
|
||||
~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return IOCTL_OUT (arg, supported_rec_devices);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return IOCTL_OUT (arg, mixer_caps);
|
||||
break;
|
||||
|
||||
default:
|
||||
return IOCTL_OUT (arg, sb_mixer_get (cmd & 0xff));
|
||||
}
|
||||
}
|
||||
else
|
||||
return RET_ERROR (EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations sb_mixer_operations =
|
||||
{
|
||||
"SoundBlaster",
|
||||
sb_mixer_ioctl
|
||||
};
|
||||
|
||||
static void
|
||||
sb_mixer_reset (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
sb_mixer_set (i, levels[i]);
|
||||
set_recmask (SOUND_MASK_MIC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a code depending on whether a SG NX Pro was detected.
|
||||
* 1 == Plain SB Pro
|
||||
* 2 == SG NX Pro detected.
|
||||
* 3 == SB16
|
||||
*
|
||||
* Used to update message.
|
||||
*/
|
||||
int
|
||||
sb_mixer_init (int major_model)
|
||||
{
|
||||
int mixer_type = 0;
|
||||
|
||||
sb_setmixer (0x00, 0); /* Reset mixer */
|
||||
|
||||
if (!(mixer_type = detect_mixer ()))
|
||||
return 0; /* No mixer. Why? */
|
||||
|
||||
mixer_initialized = 1;
|
||||
mixer_model = major_model;
|
||||
|
||||
switch (major_model)
|
||||
{
|
||||
case 3:
|
||||
mixer_caps = SOUND_CAP_EXCL_INPUT;
|
||||
|
||||
#ifdef JAZZ16
|
||||
if (Jazz16_detected == 2) /* SM Wave */
|
||||
{
|
||||
supported_devices = 0;
|
||||
supported_rec_devices = 0;
|
||||
iomap = &sbpro_mix;
|
||||
smw_mixer_init ();
|
||||
mixer_type = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef __SGNXPRO__
|
||||
if (mixer_type == 2) /* A SGNXPRO was detected */
|
||||
{
|
||||
supported_devices = SGNXPRO_MIXER_DEVICES;
|
||||
supported_rec_devices = SGNXPRO_RECORDING_DEVICES;
|
||||
iomap = &sgnxpro_mix;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
supported_devices = SBPRO_MIXER_DEVICES;
|
||||
supported_rec_devices = SBPRO_RECORDING_DEVICES;
|
||||
iomap = &sbpro_mix;
|
||||
mixer_type = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mixer_caps = 0;
|
||||
supported_devices = SB16_MIXER_DEVICES;
|
||||
supported_rec_devices = SB16_RECORDING_DEVICES;
|
||||
iomap = &sb16_mix;
|
||||
mixer_type = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk ("SB Warning: Unsupported mixer type\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV)
|
||||
mixer_devs[num_mixers++] = &sb_mixer_operations;
|
||||
sb_mixer_reset ();
|
||||
return mixer_type;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
$Id: sound.doc,v 1.6 1996/04/11 15:34:22 smpatel Exp $
|
||||
|
||||
Instructions on using audio on a FreeBSD 2.1 (or 2.0-current) system.
|
||||
See also /sys/i386/conf/LINT.
|
||||
|
||||
To enable sound driver support, the controller sound code must be included
|
||||
in your config file:
|
||||
|
||||
# SB = SoundBlaster; PAS = ProAudioSpectrum; GUS = Gravis UltraSound
|
||||
# Controls all sound devices
|
||||
controller snd0
|
||||
|
||||
Uncomment one or more of these device entries, depending on what type of
|
||||
sound card you have:
|
||||
|
||||
# ProAudioSpectrum PCM and Midi - for PAS
|
||||
#device pas0 at isa? port 0x388 irq 10 drq 6 vector pasintr
|
||||
|
||||
# SoundBlaster DSP driver - for SB, SB Pro, SB16, PAS(emulating SB)
|
||||
#device sb0 at isa? port 0x220 irq 7 drq 1 vector sbintr
|
||||
|
||||
# SoundBlaster 16 DSP driver - for SB16 - requires sb0 device
|
||||
#device sbxvi0 at isa? drq 5
|
||||
|
||||
# SoundBlaster 16 MIDI - for SB16 - requires sb0 device
|
||||
#device sbmidi0 at isa? port 0x300
|
||||
|
||||
# Gravis UltraSound - for GUS, GUS16, GUSMAX
|
||||
# For cards that use 2 DMA Channels:
|
||||
# drq = Write DMA Channel, flags = Read DMA Channel
|
||||
#device gus0 at isa? port 0x220 irq 11 drq 1 flags 0x3 vector gusintr
|
||||
|
||||
# Gravis UltraSound 16 bit option - for GUS16 - requires gus0
|
||||
#device gusxvi0 at isa? port 0x530 irq 7 drq 3 vector adintr
|
||||
|
||||
# MS Sound System (AD1848 Based Boards)
|
||||
#device mss0 at isa? port 0x530 irq 10 drq 1 vector adintr
|
||||
|
||||
# Yamaha OPL-2/OPL-3 FM - for SB, SB Pro, SB16, PAS
|
||||
#device opl0 at isa? port 0x388
|
||||
|
||||
# MPU-401 - for MPU-401 standalone card
|
||||
#device mpu0 at isa? port 0x330 irq 6 drq 0
|
||||
|
||||
# 6850 UART Midi
|
||||
#device uart0 at isa? port 0x330 irq 5 vector "m6850intr"
|
||||
|
||||
You may add one or more of the following depending on what you do and don't
|
||||
want compiled into your kernel. Note: Excluding things with EXCLUDE_...
|
||||
is NOT recommended unless you really know what you're doing.
|
||||
|
||||
#options EXCLUDE_AUDIO # NO digital audio support
|
||||
#options EXCLUDE_SEQUENCER # NO sequencer support
|
||||
#options EXCLUDE_MIDI # NO MIDI support whatsoever
|
||||
#options EXCLUDE_SBPRO # EXCLUDE SB Pro support
|
||||
#options EXCLUDE_SB_EMULATION # NO PAS SB emulation support
|
||||
#options EXCLUDE_GUS_IODETECT # NO GUS io detection
|
||||
#options EXCLUDE_PRO_MIDI # NO PAS MIDI support
|
||||
|
||||
Other Options:
|
||||
|
||||
#options SYMPHONY_PAS
|
||||
Adds some code to make pas work with Symphony chipsets. Only use
|
||||
this if your pas doesn't work and you have a Symphony chipset.
|
||||
|
||||
#options BROKEN_BUS_CLOCK
|
||||
Some systems with the OPTI chipset and a PAS will require you to
|
||||
use this option. Symptoms are that you will hear a lot of clicking and
|
||||
popping sounds, like a geiger counter, coming out of the PAS even when
|
||||
it is not playing anything.
|
||||
|
||||
#options MOZART_PORT
|
||||
Adds support for Mozart (OAK OTI-601). (Part of the MSS driver)
|
||||
|
||||
#options OPTI_MAD16_PORT
|
||||
Adds support for the OPTI MAD16 Chip. (Part of the MSS driver)
|
||||
If your soundcard has a chip labeled "OPTi 82C929" then try this.
|
||||
|
||||
#options __SGNXPRO__
|
||||
Adds support for the SG NX Pro mixer. (Part of the SB driver)
|
||||
|
||||
#options JAZZ16
|
||||
Adds support for the MV Jazz16 (ProSonic etc). (Part of the SB Driver)
|
||||
|
||||
#options SM_WAVE
|
||||
Adds support for the SoundMan Wave (Part of the SB Driver)
|
||||
Note: You will need to do some work to get this to work.
|
||||
See i386/isa/sound/configure.c
|
||||
|
||||
#options SM_GAMES
|
||||
Adds support for the Logitech SoundMan Games (Part of the SB Driver)
|
||||
|
||||
#options PAS_JOYSTICK_ENABLE
|
||||
Enables the gameport on the ProAudio Spectrum
|
||||
|
||||
NOTE: The MPU-401 driver may or may not work, and is unfortunately
|
||||
unverifiable since no one I know has one. If you can test this,
|
||||
please let me know! Also note that you will have to change these
|
||||
settings if your soundcard is set for a non-standard address or IRQ.
|
||||
Please check your documentation (or verify with any provided DOS utilities
|
||||
that may have come with your card) and set the IRQ or address fields
|
||||
accordingly.
|
||||
|
||||
|
||||
Also: You can configure more then one card on a single DMA using
|
||||
the conflicts keyword in your configuration file. This is useful for boards
|
||||
with more then one type of emulation.
|
||||
|
||||
|
||||
Probing problems: Since the SB16 uses the same IRQ and addresses for
|
||||
the different drivers, some of the snd drivers will not be probed because
|
||||
the kernel thinks there is a conflict. This can be worked-around by
|
||||
using the "conflicts" keyword on the sb16's device line.
|
||||
|
||||
|
||||
For further information, contact multimedia@freebsd.org
|
||||
|
||||
- Jordan Hubbard (jkh@freefall.cdrom.com)
|
||||
- Steven Wallace (swallace@freefall.cdrom.com)
|
||||
- Sujal Patel (smpatel@wam.umd.edu)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user