]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/allg_snd/sound/drv/mpu.c
Import of d2x-0.0.8
[btb/d2x.git] / arch / dos / allg_snd / sound / drv / mpu.c
1 /*         ______   ___    ___ 
2  *        /\  _  \ /\_ \  /\_ \ 
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *      By Shawn Hargreaves,
11  *      1 Salisbury Road,
12  *      Market Drayton,
13  *      Shropshire,
14  *      England, TF9 1AJ.
15  *
16  *      Direct output to an MPU-401 MIDI interface. 
17  *
18  *      Marcel de Kogel fixed my original broken version, so that it now 
19  *      actually works :-)
20  *
21  *      See readme.txt for copyright information.
22  */
23
24
25 #ifndef DJGPP
26 #error This file should only be used by the djgpp version of Allegro
27 #endif
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <dos.h>
32
33 #include "allegro.h"
34 #include "internal.h"
35
36
37 /* external interface to the MPU-401 driver */
38 static int mpu_detect();
39 static int mpu_init(int voices);
40 static void mpu_exit();
41 static void mpu_output(unsigned char data);
42
43 static char mpu_desc[80] = "not initialised";
44
45
46 MIDI_DRIVER midi_mpu401 =
47 {
48    "MPU-401", 
49    mpu_desc,
50    0, 0, 0xFFFF, 0, -1, -1,
51    mpu_detect,
52    mpu_init,
53    mpu_exit,
54    NULL,
55    mpu_output,
56    _dummy_load_patches,
57    _dummy_adjust_patches,
58    _dummy_key_on,
59    _dummy_noop1,
60    _dummy_noop2,
61    _dummy_noop3,
62    _dummy_noop2,
63    _dummy_noop2
64 };
65
66
67
68 /* wait_for_mpu:
69  *  Waits for the specified bit to clear on the specified port. Returns zero
70  *  if it cleared, -1 if it timed out.
71  */
72 static inline int wait_for_mpu(int flag, int port)
73 {
74    int timeout;
75
76    for (timeout=0; timeout<0x7FFF; timeout++)
77       if (!(inportb(port) & flag))
78          return 0;
79
80    return -1;
81 }
82
83
84
85 /* mpu_output:
86  *  Writes a byte to the MPU-401 midi interface.
87  */
88 static void mpu_output(unsigned char data)
89 {
90    outportb(_mpu_port, data);
91    inportb (_mpu_port);
92    wait_for_mpu(0x40, _mpu_port+1);
93 }
94
95 static END_OF_FUNCTION(mpu_output);
96
97
98
99 /* mpu_detect:
100  *  Detects the presence of an MPU-401 compatible midi interface.
101  */
102 static int mpu_detect()
103 {
104    char *blaster = getenv("BLASTER");
105
106    /* parse BLASTER env */
107    if ((blaster) && (_mpu_port < 0)) { 
108       while (*blaster) {
109          while ((*blaster == ' ') || (*blaster == '\t'))
110             blaster++;
111
112          if ((*blaster == 'p') || (*blaster == 'P'))
113             _mpu_port = strtol(blaster+1, NULL, 16);
114
115          while ((*blaster) && (*blaster != ' ') && (*blaster != '\t'))
116             blaster++;
117       }
118    }
119
120    /* if that didn't work, guess :-) */
121    if (_mpu_port < 0)
122       _mpu_port = 0x330;
123
124    /* check whether the MPU is there */
125    outportb(_mpu_port+1,0xFF);                  /* reset the mpu */
126    inportb(_mpu_port);
127    if (wait_for_mpu(0x40, _mpu_port+1) != 0) {  /* wait for ready */
128       strcpy(allegro_error, "MPU-401 not found");
129       return FALSE;
130    }
131
132    sprintf(mpu_desc, "MPU-401 MIDI interface on port %d", _mpu_port);
133    return TRUE;
134 }
135
136
137
138 /* mpu_init:
139  *  Initialises the MPU-401 midi interface.
140  */
141 static int mpu_init(int voices)
142 {
143    outportb(_mpu_port+1, 0x3F);                 /* put MPU in UART mode */
144    inportb (_mpu_port);
145    wait_for_mpu (0x80,_mpu_port+1);
146
147    LOCK_VARIABLE(midi_mpu401);
148    LOCK_VARIABLE(_mpu_port);
149    LOCK_FUNCTION(mpu_output);
150
151    return 0;
152 }
153
154
155
156 /* mpu_exit:
157  *  Resets the MPU-401 midi interface when we are finished.
158  */
159 static void mpu_exit()
160 {
161    outportb(_mpu_port+1, 0xFF);
162 }
163
164