1 /*
2     ReactOS Sound System
3     MIDI UART support
4 
5     Author:
6         Andrew Greenwood (silverblade@reactos.org)
7 
8     History:
9         26 May 2008 - Created
10 
11     Notes:
12         MIDI UART is fairly simple. There are two ports - one is a data
13         port and is read/write, the other is a command/status port where
14         you can write commands, and read status.
15 
16         We use a subset of the functionality offered by the original MPU-401
17         hardware, which is pretty much the only part implemented in sound
18         cards these days, known as "MIDI UART" mode.
19 */
20 
21 #ifndef ROS_MIDIUART
22 #define ROS_MIDIUART
23 
24 /* Port read/write abstraction (no wait) */
25 #define WRITE_MIDIUART_DATA(bp, x)      WRITE_PORT_UCHAR((PUCHAR) bp, x)
26 #define READ_MIDIUART_DATA(bp)          READ_PORT_UCHAR((PUCHAR) bp)
27 #define WRITE_MIDIUART_COMMAND(bp, x)   WRITE_PORT_UCHAR((PUCHAR) bp+1, x)
28 #define READ_MIDIUART_STATUS(bp)        READ_PORT_UCHAR((PUCHAR) bp+1)
29 
30 /* Status flags */
31 #define MIDIUART_STATUS_DTR             0x40
32 #define MIDIUART_STATUS_CTS             0x80
33 
34 
35 /*
36     WaitForMidiUartStatus
37 
38     A universal routine for waiting for one or more bits to be set on the
39     MIDI UART command/status port. (Not a particularly efficient wait as
40     this polls the port until it's ready!)
41 
42     If the timeout is reached, the function returns FALSE. Otherwise, when
43     the specified flag(s) become set, the function returns TRUE.
44 */
45 
46 BOOLEAN
47 WaitForMidiUartStatus(
48     IN  PUCHAR UartBasePort,
49     IN  UCHAR StatusFlags,
50     IN  ULONG Timeout);
51 
52 /* Waits for the CTS status bit to be set */
53 #define WaitForMidiUartCTS(UartBasePort, Timeout) \
54     WaitForMidiUartStatus(UartBasePort, MIDIUART_STATUS_CTS, Timeout)
55 
56 /* Waits for the DTR status bit to be set */
57 #define WaitForMidiUartDTR(UartBasePort, Timeout) \
58     WaitForMidiUartStatus(UartBasePort, MIDIUART_STATUS_DTR, Timeout)
59 
60 /*
61     WriteMidiUartByte
62 
63     Wait for the CTS bit to be set on the command/status port, before
64     writing to the data port. If CTS does not get set within the timeout
65     period, returns FALSE. Otherwise, returns TRUE.
66 */
67 
68 BOOLEAN
69 WriteMidiUartByte(
70     IN  PUCHAR UartBasePort,
71     IN  UCHAR Data,
72     IN  ULONG Timeout);
73 
74 
75 /*
76     WriteMidiUartMulti
77 
78     Write multiple bytes to the MIDI UART data port. The timeout applies on a
79     per-byte basis. If it is reached for any byte, the function will return
80     FALSE.
81 
82     All data is written "as-is" - there are no checks made as to the validity
83     of the data.
84 */
85 
86 BOOLEAN
87 WriteMidiUartMulti(
88     IN  PUCHAR UartBasePort,
89     IN  PUCHAR Data,
90     IN  ULONG DataLength,
91     IN  ULONG Timeout);
92 
93 
94 /*
95     ReadMidiUartByte
96 
97     Wait for the DTR bit to be set on the command/status port, before
98     reading from the data port. If DTR does not get set within the
99     timeout period, returns FALSE. Otherwise, returns TRUE.
100 
101     On success, the read data is stored in the location specified by
102     the Data parameter.
103 */
104 
105 BOOLEAN
106 ReadMidiUartByte(
107     IN  PUCHAR UartBasePort,
108     OUT UCHAR* Data,
109     IN  ULONG Timeout);
110 
111 #endif
112