2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
8 // Topic. Should status 0xf1-0xf6 messages be treated realtime?
11 #include <proto/exec.h>
12 #include <proto/dos.h>
14 # include <proto/CamdDriver.h>
16 #include "camd_intern.h"
19 #define min(a,b) ((a)<=(b)?(a):(b))
22 #if defined(__AMIGAOS__) || AROS_BIG_ENDIAN || defined(__amigaos4__)
33 # define TOBUF(a) ((a)^3)
37 __inline BYTE
GetMsgLen(LONG msg
){
40 if(msg
<0x80) return 3;
42 if(msg
&0x80 && msg
&0x40){
44 return 1; //0xc0 or 0xb0
49 return 3; //Return error. Not the appropriate way to send sysx.
65 return 4; //Realtime message
75 static __inline
void IncBuffer(struct DriverData
*data
,ULONG
**buffer
){
77 if(*buffer
==data
->bufferend
){
82 static __inline
void IncBuffer_rt(struct DriverData
*data
,UBYTE
**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
++;
97 driverdata
->realtimesysx
=0;
98 driverdata
->transmitfunc
=NULL
;
99 driverdata
->issending_sx
=0;
106 ULONG
Transmit_Datas(struct DriverData
*driverdata
){
111 buf
=(UBYTE
*)driverdata
->buffercurrsend
;
112 ret
=buf
[TOBUF(driverdata
->sendpos
)];
115 if(driverdata
->sendpos
==len
){
116 driverdata
->transmitfunc
=NULL
;
117 IncBuffer(driverdata
,&driverdata
->buffercurrsend
);
118 driverdata
->unsent
--;
120 driverdata
->sendpos
++;
128 ULONG
Transmit_Status(struct DriverData
*driverdata
){
133 buf
=(UBYTE
*)driverdata
->buffercurrsend
;
139 driverdata
->status
=0; // (Realtime messages never come here.)
142 IncBuffer(driverdata
,&driverdata
->buffercurrsend
);
143 driverdata
->unsent
--;
144 driverdata
->transmitfunc
=Transmit_SysEx
;
145 return Transmit_SysEx(driverdata
);
149 IncBuffer(driverdata
,&driverdata
->buffercurrsend
);
150 driverdata
->unsent
--;
152 driverdata
->transmitfunc
=Transmit_Datas
;
153 driverdata
->sendpos
=1;
158 if(driverdata
->status
==ret
){
160 driverdata
->transmitfunc
=Transmit_Datas
;
161 driverdata
->sendpos
=2;
163 IncBuffer(driverdata
,&driverdata
->buffercurrsend
);
164 driverdata
->unsent
--;
169 driverdata
->status
=ret
;
170 driverdata
->transmitfunc
=Transmit_Datas
;
171 driverdata
->sendpos
=1;
180 ULONG
Transmitter(struct DriverData
*driverdata
){
182 ULONG ASM
Transmitter(REG(a2
) struct DriverData
*driverdata
){
187 if((driverdata
->mididevicedata
->Flags
&1)==0){
188 return Transmitter_oldformat(driverdata
);
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
--;
201 if(driverdata
->transmitfunc
!=NULL
){
202 ret
=(*driverdata
->transmitfunc
)(driverdata
);
206 if(driverdata
->realtimesysx
==1){
207 driverdata
->transmitfunc
=Transmit_SysEx
;
208 ret
=Transmit_SysEx(driverdata
);
212 if(driverdata
->unsent
!=0){
213 ret
=Transmit_Status(driverdata
);
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
);
235 *driverdata
->buffercurr_rt
=msg
>>24;
236 driverdata
->unsent_rt
++;
238 IncBuffer_rt(driverdata
,&driverdata
->buffercurr_rt
);
241 (*driverdata
->midiportdata
->ActivateXmit
)(driverdata
,driverdata
->portnum
);
243 driverdata
->mididevicedata
->ICamdDriver
->ActivateXmit(driverdata
,driverdata
->portnum
);
246 ReleaseSemaphore(&driverdata
->sendsemaphore
);
254 /******************************************************************************
257 Returns FALSE if buffer is full or bigger than maxbuff, and does not
260 ******************************************************************************/
262 BOOL
Midi2Driver_internal(
263 struct DriverData
*driverdata
,
269 if((driverdata
->mididevicedata
->Flags
&1)==0){
270 return Midi2Driver_internal_oldformat(driverdata
,msg
,maxbuff
);
274 if(msg
>=0xf8000000) return Midi2Driver_rt(driverdata
,msg
);
276 if(driverdata
->unsent
>=min(maxbuff
,OUTBUFFERSIZE
-2)){
280 ObtainSemaphore(&driverdata
->sendsemaphore
);
282 driverdata
->unsent
>=OUTBUFFERSIZE
-2
284 ReleaseSemaphore(&driverdata
->sendsemaphore
);
288 *driverdata
->buffercurr
=(msg
& 0xffffff00) | GetMsgLen(msg
);
289 driverdata
->unsent
++;
291 IncBuffer(driverdata
,&driverdata
->buffercurr
);
294 (*driverdata
->midiportdata
->ActivateXmit
)(driverdata
,driverdata
->portnum
);
296 driverdata
->mididevicedata
->ICamdDriver
->ActivateXmit(driverdata
,driverdata
->portnum
);
299 ReleaseSemaphore(&driverdata
->sendsemaphore
);
306 BOOL
SysEx2Driver(struct DriverData
*driverdata
,UBYTE
*buffer
){
309 if((driverdata
->mididevicedata
->Flags
&1)==0){
310 return SysEx2Driver_oldformat(driverdata
,buffer
);
315 ObtainSemaphore(&driverdata
->sendsemaphore
);
317 driverdata
->unsent
>=OUTBUFFERSIZE
-2
319 ReleaseSemaphore(&driverdata
->sendsemaphore
);
322 *driverdata
->buffercurr
=0xf00000f0;
323 driverdata
->unsent
++;
324 IncBuffer(driverdata
,&driverdata
->buffercurr
);
327 driverdata
->realtimesysx
=1;
328 ObtainSemaphore(&driverdata
->sendsemaphore
);
332 (*driverdata
->midiportdata
->ActivateXmit
)(driverdata
,driverdata
->portnum
);
334 driverdata
->mididevicedata
->ICamdDriver
->ActivateXmit(driverdata
,driverdata
->portnum
);
337 ReleaseSemaphore(&driverdata
->sendsemaphore
);