revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / camd / miditodriver.c
blob7b449ed2634682026c19c16f32e2166be4d75981
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
8 // Topic. Should status 0xf1-0xf6 messages be treated realtime?
11 #include <proto/exec.h>
12 #include <proto/dos.h>
13 #ifdef __amigaos4__
14 # include <proto/CamdDriver.h>
15 #endif
16 #include "camd_intern.h"
18 #ifndef min
19 #define min(a,b) ((a)<=(b)?(a):(b))
20 #endif
22 #if defined(__AMIGAOS__) || AROS_BIG_ENDIAN || defined(__amigaos4__)
23 # define BUF0 0
24 # define BUF1 1
25 # define BUF2 2
26 # define BUF3 3
27 # define TOBUF(a) (a)
28 #else
29 # define BUF0 3
30 # define BUF1 2
31 # define BUF2 1
32 # define BUF3 0
33 # define TOBUF(a) ((a)^3)
34 #endif
37 __inline BYTE GetMsgLen(LONG msg){
38 msg=0xff&msg>>24;
40 if(msg<0x80) return 3;
42 if(msg&0x80 && msg&0x40){
43 if(!(msg&0x20)){
44 return 1; //0xc0 or 0xb0
45 }else{
46 if(msg&0x10){ //0xfx
47 switch(msg){
48 case 0xf0:
49 return 3; //Return error. Not the appropriate way to send sysx.
50 case 0xf1:
51 return 1;
52 case 0xf2:
53 return 2;
54 case 0xf3:
55 return 1;
56 case 0xf4:
57 return 3;
58 case 0xf5:
59 return 3;
60 case 0xf6:
61 return 0;
62 case 0xf7:
63 return 3;
64 default:
65 return 4; //Realtime message
66 break;
71 return 2;
75 static __inline void IncBuffer(struct DriverData *data,ULONG **buffer){
76 (*buffer)++;
77 if(*buffer==data->bufferend){
78 *buffer=data->buffer;
82 static __inline void IncBuffer_rt(struct DriverData *data,UBYTE **buffer_rt){
83 (*buffer_rt)++;
84 if(*buffer_rt==data->bufferend_rt){
85 *buffer_rt=data->buffer_rt;
91 /* Transmitter functions. */
93 ULONG Transmit_SysEx(struct DriverData *driverdata){
94 UBYTE ret=driverdata->buffer_sx[driverdata->buffercurrsend_sx];
95 driverdata->buffercurrsend_sx++;
96 if(ret==0xf7){
97 driverdata->realtimesysx=0;
98 driverdata->transmitfunc=NULL;
99 driverdata->issending_sx=0;
101 return ret;
106 ULONG Transmit_Datas(struct DriverData *driverdata){
107 UBYTE *buf;
108 UBYTE len;
109 UBYTE ret;
111 buf=(UBYTE *)driverdata->buffercurrsend;
112 ret=buf[TOBUF(driverdata->sendpos)];
113 len=buf[BUF3];
115 if(driverdata->sendpos==len){
116 driverdata->transmitfunc=NULL;
117 IncBuffer(driverdata,&driverdata->buffercurrsend);
118 driverdata->unsent--;
119 }else{
120 driverdata->sendpos++;
123 return ret;
128 ULONG Transmit_Status(struct DriverData *driverdata){
129 UBYTE *buf;
130 UBYTE len;
131 UBYTE ret;
133 buf=(UBYTE *)driverdata->buffercurrsend;
134 ret=buf[BUF0];
135 len=buf[BUF3];
137 if(ret>=0xf0){
139 driverdata->status=0; // (Realtime messages never come here.)
141 if(ret==0xf0){
142 IncBuffer(driverdata,&driverdata->buffercurrsend);
143 driverdata->unsent--;
144 driverdata->transmitfunc=Transmit_SysEx;
145 return Transmit_SysEx(driverdata);
148 if(len==0){
149 IncBuffer(driverdata,&driverdata->buffercurrsend);
150 driverdata->unsent--;
151 }else{
152 driverdata->transmitfunc=Transmit_Datas;
153 driverdata->sendpos=1;
156 }else{
158 if(driverdata->status==ret){
159 if(len>1){
160 driverdata->transmitfunc=Transmit_Datas;
161 driverdata->sendpos=2;
162 }else{
163 IncBuffer(driverdata,&driverdata->buffercurrsend);
164 driverdata->unsent--;
166 return buf[BUF1];
169 driverdata->status=ret;
170 driverdata->transmitfunc=Transmit_Datas;
171 driverdata->sendpos=1;
175 return ret;
179 #ifdef __amigaos4__
180 ULONG Transmitter(struct DriverData *driverdata){
181 #else
182 ULONG ASM Transmitter(REG(a2) struct DriverData *driverdata){
183 #endif
184 UBYTE ret;
186 #ifdef __AMIGAOS__
187 if((driverdata->mididevicedata->Flags&1)==0){
188 return Transmitter_oldformat(driverdata);
190 #endif
192 // First of all, check if there are any realtime-messages on the realtime-buffer.
193 if(driverdata->unsent_rt>0){
194 ret=*driverdata->buffercurrsend_rt;
195 IncBuffer_rt(driverdata,&driverdata->buffercurrsend_rt);
196 driverdata->unsent_rt--;
197 return ret;
201 if(driverdata->transmitfunc!=NULL){
202 ret=(*driverdata->transmitfunc)(driverdata);
203 return ret;
206 if(driverdata->realtimesysx==1){
207 driverdata->transmitfunc=Transmit_SysEx;
208 ret=Transmit_SysEx(driverdata);
209 return ret;
212 if(driverdata->unsent!=0){
213 ret=Transmit_Status(driverdata);
214 return ret;
217 return 0x100;
223 /* Put to buffer functions. */
225 BOOL Midi2Driver_rt(struct DriverData *driverdata,ULONG msg){
227 ObtainSemaphore(&driverdata->sendsemaphore);
230 driverdata->unsent_rt>=OUTBUFFERSIZE_RT-2
232 ReleaseSemaphore(&driverdata->sendsemaphore);
233 return FALSE;
235 *driverdata->buffercurr_rt=msg>>24;
236 driverdata->unsent_rt++;
238 IncBuffer_rt(driverdata,&driverdata->buffercurr_rt);
240 #ifndef __amigaos4__
241 (*driverdata->midiportdata->ActivateXmit)(driverdata,driverdata->portnum);
242 #else
243 driverdata->mididevicedata->ICamdDriver->ActivateXmit(driverdata,driverdata->portnum);
244 #endif
246 ReleaseSemaphore(&driverdata->sendsemaphore);
248 return TRUE;
254 /******************************************************************************
256 FUNCTION
257 Returns FALSE if buffer is full or bigger than maxbuff, and does not
258 send out anything.
260 ******************************************************************************/
262 BOOL Midi2Driver_internal(
263 struct DriverData *driverdata,
264 ULONG msg,
265 ULONG maxbuff
268 #ifdef __AMIGAOS__
269 if((driverdata->mididevicedata->Flags&1)==0){
270 return Midi2Driver_internal_oldformat(driverdata,msg,maxbuff);
272 #endif
274 if(msg>=0xf8000000) return Midi2Driver_rt(driverdata,msg);
276 if(driverdata->unsent>=min(maxbuff,OUTBUFFERSIZE-2)){
277 return FALSE;
280 ObtainSemaphore(&driverdata->sendsemaphore);
282 driverdata->unsent>=OUTBUFFERSIZE-2
284 ReleaseSemaphore(&driverdata->sendsemaphore);
285 return FALSE;
288 *driverdata->buffercurr=(msg & 0xffffff00) | GetMsgLen(msg);
289 driverdata->unsent++;
291 IncBuffer(driverdata,&driverdata->buffercurr);
293 #ifndef __amigaos4__
294 (*driverdata->midiportdata->ActivateXmit)(driverdata,driverdata->portnum);
295 #else
296 driverdata->mididevicedata->ICamdDriver->ActivateXmit(driverdata,driverdata->portnum);
297 #endif
299 ReleaseSemaphore(&driverdata->sendsemaphore);
301 return TRUE;
306 BOOL SysEx2Driver(struct DriverData *driverdata,UBYTE *buffer){
308 #ifdef __AMIGAOS__
309 if((driverdata->mididevicedata->Flags&1)==0){
310 return SysEx2Driver_oldformat(driverdata,buffer);
312 #endif
314 if(buffer[1]!=0x7f){
315 ObtainSemaphore(&driverdata->sendsemaphore);
317 driverdata->unsent>=OUTBUFFERSIZE-2
319 ReleaseSemaphore(&driverdata->sendsemaphore);
320 return FALSE;
322 *driverdata->buffercurr=0xf00000f0;
323 driverdata->unsent++;
324 IncBuffer(driverdata,&driverdata->buffercurr);
326 }else{
327 driverdata->realtimesysx=1;
328 ObtainSemaphore(&driverdata->sendsemaphore);
331 #ifndef __amigaos4__
332 (*driverdata->midiportdata->ActivateXmit)(driverdata,driverdata->portnum);
333 #else
334 driverdata->mididevicedata->ICamdDriver->ActivateXmit(driverdata,driverdata->portnum);
335 #endif
337 ReleaseSemaphore(&driverdata->sendsemaphore);
339 return TRUE;