03a3459e Andy McCall 15 days ago
1
2
3
4
5
#include < pthread.h>
6
#include < stdio.h>
7
#include " glue.h"
8
#include " midi.h"
9
#include " audio.h"
10
#include " endian.h"
11
12
#ifdef _WIN32
13
#include < windows.h>
14
#define LIBRARY_TYPE HMODULE
15
#define LOAD_LIBRARY ( name ) LoadLibrary ( name )
16
#define GET_FUNCTION ( lib , name ) ( void * ) GetProcAddress ( lib, name )
17
#define CLOSE_LIBRARY ( lib ) FreeLibrary ( lib )
18
#else
19
#include < dlfcn.h>
20
#define LIBRARY_TYPE void *
21
#define LOAD_LIBRARY ( name ) dlopen ( name, RTLD_LAZY )
22
#define GET_FUNCTION ( lib , name ) dlsym ( lib, name )
23
#define CLOSE_LIBRARY ( lib ) dlclose ( lib )
24
#endif
25
26
#define ASSIGN_FUNCTION ( lib , var , name ) { \
27
var = GET_FUNCTION ( lib, name ) ; \
28
if ( ! var) { fprintf ( stderr, " Unable to find symbol for '%s '\n " , name ) ; CLOSE_LIBRARY ( handle ) ; return ; } \
29
}
30
31
enum MIDI_states {
32
MSTATE_Normal,
33
MSTATE_Param,
34
MSTATE_SysEx,
35
} ;
36
37
struct midi_serial_regs
38
{
39
LOW_HIGH_UNION ( dl, dll, dlm ) ;
40
41
bool ier_erbi;
42
bool ier_etbei;
43
bool ier_elsi;
44
bool ier_edssi;
45
46
uint8_t iir;
47
48
bool fcr_fifo_enable;
49
uint8_t fcr_ififo_trigger_level_bytes;
50
51
uint8_t lcr_word_length_bits;
52
bool lcr_stb;
53
bool lcr_pen;
54
bool lcr_eps;
55
bool lcr_stick;
56
bool lcr_break;
57
bool lcr_dlab;
58
59
bool mcr_dtr;
60
bool mcr_rts;
61
bool mcr_out1;
62
bool mcr_out2;
63
bool mcr_loop;
64
bool mcr_afe;
65
66
bool lsr_oe;
67
bool lsr_pe;
68
bool lsr_fe;
69
bool lsr_bi;
70
bool lsr_eif;
71
72
bool msr_dcts;
73
bool msr_ddsr;
74
bool msr_teri;
75
bool msr_ddcd;
76
bool msr_cts;
77
bool msr_dsr;
78
bool msr_ri;
79
bool msr_dcd;
80
81
uint8_t obyte_bits_remain;
82
uint8_t ibyte_bits_remain;
83
uint8_t rx_timeout;
84
bool rx_timeout_enabled;
85
86
bool thre_intr;
87
uint8_t thre_bits_remain;
88
89
uint8_t scratch;
90
uint8_t ififo[ 16 ] ;
91
uint8_t ifsz;
92
uint8_t ofifo[ 16 ] ;
93
uint8_t ofsz;
94
95
int64_t clock;
96
int32_t clockdec;
97
98
time_t last_warning;
99
100
uint8_t midi_event_fifo[ 256 ] ;
101
int mfsz;
102
uint8_t in_midi_last_command;
103
104
pthread_mutex_t fifo_mutex;
105
pthread_mutexattr_t fifo_mutex_attr;
106
} ;
107
108
struct midi_serial_regs mregs[ 2 ] ;
109
static bool serial_midi_mutexes_initialized = false ;
110
111
void midi_serial_iir_check ( uint8_t sel ) ;
112
bool fs_midi_in_connect = false ;
113
114
#ifdef HAS_FLUIDSYNTH
115
116
int handle_midi_event ( void * data , fluid_midi_event_t* event ) ;
117
118
static uint8_t sysex_buffer[ 1024 ] ;
119
static int sysex_bufptr;
120
121
static enum MIDI_states midi_state[ 2 ] = { MSTATE_Normal, MSTATE_Normal} ;
122
static uint8_t out_midi_last_command[ 2 ] = { 0 , 0 } ;
123
static uint8_t out_midi_first_param[ 2 ] ;
124
static uint16_t out_midi_nrpn[ 2 ] [ 16 ] ;
125
static uint16_t out_midi_rpn[ 2 ] [ 16 ] ;
126
static bool out_midi_nrpn_active[ 2 ] [ 16 ] ;
127
128
static bool midi_initialized = false ;
129
130
static fluid_settings_t* fl_settings;
131
static fluid_midi_driver_t* fl_mdriver;
132
static fluid_synth_t* fl_synth;
133
static int fl_sf2id;
134
135
typedef fluid_settings_t* ( * new_fluid_settings_f_t) ( void ) ;
136
typedef fluid_synth_t* ( * new_fluid_synth_f_t) ( fluid_settings_t* ) ;
137
typedef fluid_audio_driver_t* ( * new_fluid_audio_driver_f_t) ( fluid_settings_t* , fluid_synth_t* ) ;
138
typedef fluid_midi_driver_t* ( * new_fluid_midi_driver_f_t) ( fluid_settings_t* , handle_midi_event_func_t, void * ) ;
139
typedef int ( * fluid_settings_setnum_f_t) ( fluid_settings_t* , const char * , double ) ;
140
typedef int ( * fluid_settings_setint_f_t) ( fluid_settings_t* , const char * , int ) ;
141
typedef int ( * fluid_settings_setstr_f_t) ( fluid_settings_t* , const char * , const char * ) ;
142
typedef int ( * fluid_synth_sfload_f_t) ( fluid_synth_t* , const char * , int ) ;
143
typedef int ( * fluid_synth_program_change_f_t) ( fluid_synth_t* , int , int ) ;
144
typedef int ( * fluid_synth_channel_pressure_f_t) ( fluid_synth_t* , int , int ) ;
145
typedef int ( * fluid_synth_system_reset_f_t) ( fluid_synth_t* ) ;
146
typedef int ( * fluid_synth_noteoff_f_t) ( fluid_synth_t* , int , int ) ;
147
typedef int ( * fluid_synth_noteon_f_t) ( fluid_synth_t* , int , int , int ) ;
148
typedef int ( * fluid_synth_key_pressure_f_t) ( fluid_synth_t* , int , int , int ) ;
149
typedef int ( * fluid_synth_cc_f_t) ( fluid_synth_t* , int , int , int ) ;
150
typedef int ( * fluid_synth_pitch_bend_f_t) ( fluid_synth_t* , int , int ) ;
151
typedef int ( * fluid_synth_sysex_f_t) ( fluid_synth_t* , const char * , int , char * , int * , int * , int ) ;
152
typedef int ( * fluid_synth_write_s16_f_t) ( fluid_synth_t* , int , void * , int , int , void * , int , int ) ;
153
typedef int ( * fluid_midi_event_get_channel_f_t) ( const fluid_midi_event_t* ) ;
154
typedef int ( * fluid_midi_event_get_control_f_t) ( const fluid_midi_event_t* ) ;
155
typedef int ( * fluid_midi_event_get_key_f_t) ( const fluid_midi_event_t* ) ;
156
typedef int ( * fluid_midi_event_get_lyrics_f_t) ( const fluid_midi_event_t* , void * * , int * ) ;
157
typedef int ( * fluid_midi_event_get_pitch_f_t) ( const fluid_midi_event_t* ) ;
158
typedef int ( * fluid_midi_event_get_program_f_t) ( const fluid_midi_event_t* ) ;
159
typedef int ( * fluid_midi_event_get_text_f_t) ( const fluid_midi_event_t* , void * * , int * ) ;
160
typedef int ( * fluid_midi_event_get_type_f_t) ( const fluid_midi_event_t* ) ;
161
typedef int ( * fluid_midi_event_get_value_f_t) ( const fluid_midi_event_t* ) ;
162
typedef int ( * fluid_midi_event_get_velocity_f_t) ( const fluid_midi_event_t* ) ;
163
typedef int ( * fluid_midi_event_set_type_f_t) ( fluid_midi_event_t* , int ) ;
164
165
static new_fluid_settings_f_t dl_new_fluid_settings;
166
static new_fluid_synth_f_t dl_new_fluid_synth;
167
static new_fluid_audio_driver_f_t dl_new_fluid_audio_driver;
168
static new_fluid_midi_driver_f_t dl_new_fluid_midi_driver;
169
static fluid_settings_setnum_f_t dl_fluid_settings_setnum;
170
static fluid_settings_setint_f_t dl_fluid_settings_setint;
171
static fluid_settings_setstr_f_t dl_fluid_settings_setstr;
172
static fluid_synth_sfload_f_t dl_fs_sfload;
173
static fluid_synth_program_change_f_t dl_fs_program_change;
174
static fluid_synth_channel_pressure_f_t dl_fs_channel_pressure;
175
static fluid_synth_system_reset_f_t dl_fs_system_reset;
176
static fluid_synth_noteoff_f_t dl_fs_noteoff;
177
static fluid_synth_noteon_f_t dl_fs_noteon;
178
static fluid_synth_key_pressure_f_t dl_fs_key_pressure;
179
static fluid_synth_cc_f_t dl_fs_cc;
180
static fluid_synth_pitch_bend_f_t dl_fs_pitch_bend;
181
static fluid_synth_sysex_f_t dl_fs_sysex;
182
static fluid_synth_write_s16_f_t dl_fs_write_s16;
183
static fluid_midi_event_get_channel_f_t dl_fluid_midi_event_get_channel;
184
static fluid_midi_event_get_control_f_t dl_fluid_midi_event_get_control;
185
static fluid_midi_event_get_key_f_t dl_fluid_midi_event_get_key;
186
static fluid_midi_event_get_lyrics_f_t dl_fluid_midi_event_get_lyrics;
187
static fluid_midi_event_get_pitch_f_t dl_fluid_midi_event_get_pitch;
188
static fluid_midi_event_get_program_f_t dl_fluid_midi_event_get_program;
189
static fluid_midi_event_get_text_f_t dl_fluid_midi_event_get_text;
190
static fluid_midi_event_get_type_f_t dl_fluid_midi_event_get_type;
191
static fluid_midi_event_get_value_f_t dl_fluid_midi_event_get_value;
192
static fluid_midi_event_get_velocity_f_t dl_fluid_midi_event_get_velocity;
193
static fluid_midi_event_set_type_f_t dl_fluid_midi_event_set_type;
194
195
196
void midi_init ( )
197
{
198
if ( midi_initialized) {
199
return ;
200
}
201
202
#ifdef _WIN32
203
LIBRARY_TYPE handle = LOAD_LIBRARY ( " libfluidsynth-3.dll" ) ;
204
#elif __APPLE__
205
LIBRARY_TYPE handle = LOAD_LIBRARY ( " libfluidsynth.dylib" ) ;
206
#else
207
LIBRARY_TYPE handle = LOAD_LIBRARY ( " libfluidsynth.so.3" ) ;
208
#endif
209
210
if ( ! handle) {
211
212
#ifdef _WIN32
213
fprintf ( stderr, " Could not load MIDI synth library: error code %lu \n " , GetLastError ( ) ) ;
214
#else
215
fprintf ( stderr, " Could not load MIDI synth library: %s \n " , dlerror ( ) ) ;
216
#endif
217
return ;
218
}
219
220
#ifndef _WIN32
221
dlerror ( ) ;
222
#endif
223
224
ASSIGN_FUNCTION ( handle, dl_new_fluid_settings, " new_fluid_settings" ) ;
225
ASSIGN_FUNCTION ( handle, dl_new_fluid_synth, " new_fluid_synth" ) ;
226
ASSIGN_FUNCTION ( handle, dl_new_fluid_audio_driver, " new_fluid_audio_driver" ) ;
227
ASSIGN_FUNCTION ( handle, dl_new_fluid_midi_driver, " new_fluid_midi_driver" ) ;
228
ASSIGN_FUNCTION ( handle, dl_fluid_settings_setnum, " fluid_settings_setnum" ) ;
229
ASSIGN_FUNCTION ( handle, dl_fluid_settings_setint, " fluid_settings_setint" ) ;
230
ASSIGN_FUNCTION ( handle, dl_fluid_settings_setstr, " fluid_settings_setstr" ) ;
231
ASSIGN_FUNCTION ( handle, dl_fs_sfload, " fluid_synth_sfload" ) ;
232
ASSIGN_FUNCTION ( handle, dl_fs_program_change, " fluid_synth_program_change" ) ;
233
ASSIGN_FUNCTION ( handle, dl_fs_channel_pressure, " fluid_synth_channel_pressure" ) ;
234
ASSIGN_FUNCTION ( handle, dl_fs_system_reset, " fluid_synth_system_reset" ) ;
235
ASSIGN_FUNCTION ( handle, dl_fs_noteoff, " fluid_synth_noteoff" ) ;
236
ASSIGN_FUNCTION ( handle, dl_fs_noteon, " fluid_synth_noteon" ) ;
237
ASSIGN_FUNCTION ( handle, dl_fs_key_pressure, " fluid_synth_key_pressure" ) ;
238
ASSIGN_FUNCTION ( handle, dl_fs_cc, " fluid_synth_cc" ) ;
239
ASSIGN_FUNCTION ( handle, dl_fs_pitch_bend, " fluid_synth_pitch_bend" ) ;
240
ASSIGN_FUNCTION ( handle, dl_fs_sysex, " fluid_synth_sysex" ) ;
241
ASSIGN_FUNCTION ( handle, dl_fs_write_s16, " fluid_synth_write_s16" ) ;
242
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_channel, " fluid_midi_event_get_channel" ) ;
243
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_control, " fluid_midi_event_get_control" ) ;
244
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_key, " fluid_midi_event_get_key" ) ;
245
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_lyrics, " fluid_midi_event_get_lyrics" ) ;
246
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_pitch, " fluid_midi_event_get_pitch" ) ;
247
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_program, " fluid_midi_event_get_program" ) ;
248
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_text, " fluid_midi_event_get_text" ) ;
249
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_type, " fluid_midi_event_get_type" ) ;
250
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_value, " fluid_midi_event_get_value" ) ;
251
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_get_velocity, " fluid_midi_event_get_velocity" ) ;
252
ASSIGN_FUNCTION ( handle, dl_fluid_midi_event_set_type, " fluid_midi_event_set_type" ) ;
253
254
fl_settings = dl_new_fluid_settings ( ) ;
255
dl_fluid_settings_setnum ( fl_settings, " synth.sample-rate" ,
256
AUDIO_SAMPLERATE ) ;
257
dl_fluid_settings_setnum ( fl_settings, " synth.gain" , FL_DEFAULT_GAIN ) ;
258
dl_fluid_settings_setstr ( fl_settings, " midi.portname" , " Commander X16 Emulator" ) ;
259
dl_fluid_settings_setint ( fl_settings, " midi.autoconnect" , fs_midi_in_connect ) ;
260
fl_synth = dl_new_fluid_synth ( fl_settings ) ;
261
if ( fs_midi_in_connect) {
262
fl_mdriver = dl_new_fluid_midi_driver ( fl_settings, handle_midi_event, & mregs[ 0 ] ) ;
263
}
264
265
midi_initialized = true ;
266
fprintf ( stderr, " Initialized MIDI synth at $%04X .\n " , midi_card_addr ) ;
267
}
268
269
void midi_load_sf2 ( uint8_t * filename )
270
{
271
if ( ! midi_initialized) return ;
272
fl_sf2id = dl_fs_sfload ( fl_synth, ( const char * ) filename, true ) ;
273
if ( fl_sf2id == FLUID_FAILED) {
274
fprintf ( stderr, " Unable to load soundfont.\n " ) ;
275
}
276
}
277
278
279
280
void midi_byte_out ( uint8_t sel , uint8_t b )
281
{
282
uint8_t chan = out_midi_last_command[ sel] & 0xf ;
283
284
if ( ! midi_initialized) return ;
285
switch ( midi_state[ sel] ) {
286
case MSTATE_Normal:
287
if ( b < 0x80 ) {
288
if ( ( out_midi_last_command[ sel] & 0xf0 ) == 0xc0 ) {
289
dl_fs_program_change ( fl_synth, out_midi_last_command[ sel] & 0xf , b ) ;
290
} else if ( ( out_midi_last_command[ sel] & 0xf0 ) == 0xd0 ) {
291
dl_fs_channel_pressure ( fl_synth, out_midi_last_command[ sel] & 0xf , b ) ;
292
} else if ( out_midi_last_command[ sel] >= 0x80 ) {
293
out_midi_first_param[ sel] = b;
294
midi_state[ sel] = MSTATE_Param;
295
}
296
} else {
297
if ( b < 0xf0 ) {
298
out_midi_last_command[ sel] = b;
299
} else if ( b == 0xf0 ) {
300
sysex_bufptr = 0 ;
301
midi_state[ sel] = MSTATE_SysEx;
302
out_midi_last_command[ sel] = 0 ;
303
} else if ( b == 0xff ) {
304
dl_fs_system_reset ( fl_synth ) ;
305
out_midi_last_command[ sel] = 0 ;
306
} else if ( b < 0xf8 ) {
307
out_midi_last_command[ sel] = 0 ;
308
}
309
}
310
break ;
311
case MSTATE_Param:
312
switch ( out_midi_last_command[ sel] & 0xf0 ) {
313
case 0x80 :
314
dl_fs_noteoff ( fl_synth, chan, out_midi_first_param[ sel] ) ;
315
break ;
316
case 0x90 :
317
if ( b == 0 ) {
318
dl_fs_noteoff ( fl_synth, chan, out_midi_first_param[ sel] ) ;
319
} else {
320
dl_fs_noteon ( fl_synth, chan, out_midi_first_param[ sel] , b ) ;
321
}
322
break ;
323
case 0xa0 :
324
dl_fs_key_pressure ( fl_synth, chan, out_midi_first_param[ sel] , b ) ;
325
break ;
326
case 0xb0 :
327
switch ( out_midi_first_param[ sel] ) {
328
case 98 :
329
out_midi_nrpn_active[ sel] [ chan] = true ;
330
out_midi_nrpn[ sel] [ chan] = ( out_midi_nrpn[ sel] [ chan] & 0x00ff ) | ( b << 8 ) ;
331
break ;
332
case 99 :
333
out_midi_nrpn_active[ sel] [ chan] = true ;
334
out_midi_nrpn[ sel] [ chan] = ( out_midi_nrpn[ sel] [ chan] & 0xff00 ) | b;
335
break ;
336
case 100 :
337
out_midi_nrpn_active[ sel] [ chan] = false ;
338
out_midi_rpn[ sel] [ chan] = ( out_midi_rpn[ sel] [ chan] & 0x00ff ) | ( b << 8 ) ;
339
break ;
340
case 101 :
341
out_midi_nrpn_active[ sel] [ chan] = false ;
342
out_midi_rpn[ sel] [ chan] = ( out_midi_rpn[ sel] [ chan] & 0xff00 ) | b;
343
break ;
344
}
345
dl_fs_cc ( fl_synth, chan, out_midi_first_param[ sel] , b ) ;
346
if ( out_midi_nrpn_active[ sel] [ chan] && out_midi_nrpn[ sel] [ chan] == 0x0121 && out_midi_first_param[ sel] == 6 ) {
347
dl_fs_cc ( fl_synth, chan, 71 , b ) ;
348
}
349
break ;
350
case 0xe0 :
351
dl_fs_pitch_bend ( fl_synth, chan, ( ( uint16_t ) out_midi_first_param[ sel] ) | ( uint16_t ) b << 7 ) ;
352
break ;
353
}
354
midi_state[ sel] = MSTATE_Normal;
355
break ;
356
case MSTATE_SysEx:
357
if ( b & 0x80 ) {
358
if ( sysex_bufptr < ( sizeof ( sysex_buffer ) / sizeof ( sysex_buffer[ 0 ] ) ) - 1 ) {
359
sysex_buffer[ sysex_bufptr] = 0 ;
360
if ( ! strncmp ( ( char * ) sysex_buffer, " \x7F \x7F \x04 \x01 \x00 " , sysex_bufptr- 1 ) ) {
361
362
dl_fluid_settings_setnum ( fl_settings, " synth.gain" , FL_DEFAULT_GAIN* ( ( float ) sysex_buffer[ sysex_bufptr- 1 ] / 127 ) ) ;
363
} else if ( ! strncmp ( ( char * ) sysex_buffer, " \x7E \x7F \x09 \x01 " , sysex_bufptr) ) {
364
365
dl_fs_system_reset ( fl_synth ) ;
366
} else {
367
dl_fs_sysex ( fl_synth, ( char * ) sysex_buffer, sysex_bufptr, NULL , NULL , NULL , 0 ) ;
368
}
369
}
370
midi_state[ sel] = MSTATE_Normal;
371
return midi_byte_out ( sel, b ) ;
372
} else {
373
sysex_buffer[ sysex_bufptr] = b;
374
375
376
if ( sysex_bufptr < ( sizeof ( sysex_buffer ) / sizeof ( sysex_buffer[ 0 ] ) ) - 1 ) {
377
sysex_bufptr+ + ;
378
}
379
}
380
break ;
381
}
382
}
383
384
void midi_synth_render ( int16_t * buf , int len )
385
{
386
if ( midi_initialized) {
387
dl_fs_write_s16 ( fl_synth, len, buf, 0 , 2 , buf, 1 , 2 ) ;
388
} else {
389
memset ( buf, 0 , len * 2 * sizeof ( int16_t ) ) ;
390
}
391
}
392
393
void midi_event_enqueue_byte ( struct midi_serial_regs* mrp , uint8_t val )
394
{
395
if ( mrp-> mfsz >= 256 ) return ;
396
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = val;
397
}
398
399
void midi_event_enqueue_short ( struct midi_serial_regs* mrp , uint8_t cmd , uint8_t val )
400
{
401
if ( mrp-> mfsz >= 255 ) {
402
mrp-> in_midi_last_command = 0 ;
403
return ;
404
}
405
if ( mrp-> in_midi_last_command != cmd) {
406
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = cmd;
407
mrp-> in_midi_last_command = cmd;
408
}
409
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = val;
410
}
411
412
void midi_event_enqueue_normal ( struct midi_serial_regs* mrp , uint8_t cmd , uint8_t key , uint8_t val )
413
{
414
if ( mrp-> mfsz >= 254 ) {
415
mrp-> in_midi_last_command = 0 ;
416
return ;
417
}
418
if ( mrp-> in_midi_last_command != cmd) {
419
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = cmd;
420
mrp-> in_midi_last_command = cmd;
421
}
422
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = key;
423
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = val;
424
}
425
426
void midi_event_enqueue_sysex ( struct midi_serial_regs* mrp , uint8_t * bufptr , int buflen )
427
{
428
int i;
429
430
mrp-> in_midi_last_command = 0 ;
431
if ( mrp-> mfsz >= 255L - ( buflen + 2 ) ) {
432
return ;
433
}
434
435
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = 0xf0 ;
436
for ( i = 0 ; i < buflen; i+ + ) {
437
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = bufptr[ i] ;
438
}
439
mrp-> midi_event_fifo[ mrp-> mfsz+ + ] = 0xf7 ;
440
}
441
442
int handle_midi_event ( void * data , fluid_midi_event_t* event )
443
{
444
struct midi_serial_regs* mrp = ( struct midi_serial_regs* ) data;
445
pthread_mutex_lock ( & mrp-> fifo_mutex) ;
446
447
uint8_t type = dl_fluid_midi_event_get_type ( event ) ;
448
uint8_t chan = dl_fluid_midi_event_get_channel ( event ) ;
449
uint8_t cmd = ( type < 0x80 || type >= 0xf0 ) ? type : ( type | ( chan & 0xf ) ) ;
450
uint8_t key, val;
451
uint8_t * bufptr;
452
int buflen;
453
454
switch ( type) {
455
case FS_NOTE_OFF:
456
case FS_NOTE_ON:
457
key = dl_fluid_midi_event_get_key ( event ) ;
458
val = dl_fluid_midi_event_get_velocity ( event ) ;
459
midi_event_enqueue_normal ( mrp, cmd, key, val ) ;
460
break ;
461
case FS_KEY_PRESSURE:
462
key = dl_fluid_midi_event_get_key ( event ) ;
463
val = dl_fluid_midi_event_get_value ( event ) ;
464
midi_event_enqueue_normal ( mrp, cmd, key, val ) ;
465
break ;
466
case FS_CONTROL_CHANGE:
467
key = dl_fluid_midi_event_get_control ( event ) ;
468
val = dl_fluid_midi_event_get_value ( event ) ;
469
midi_event_enqueue_normal ( mrp, cmd, key, val ) ;
470
break ;
471
case FS_PITCH_BEND:
472
key = dl_fluid_midi_event_get_pitch ( event ) & 0x7f ;
473
val = ( dl_fluid_midi_event_get_pitch ( event ) >> 7 ) & 0x7f ;
474
midi_event_enqueue_normal ( mrp, cmd, key, val ) ;
475
break ;
476
case FS_PROGRAM_CHANGE:
477
case FS_CHANNEL_PRESSURE:
478
val = dl_fluid_midi_event_get_program ( event ) ;
479
midi_event_enqueue_short ( mrp, cmd, val ) ;
480
break ;
481
case FS_MIDI_TIME_CODE:
482
val = dl_fluid_midi_event_get_value ( event ) ;
483
midi_event_enqueue_short ( mrp, type, val ) ;
484
mrp-> in_midi_last_command = 0 ;
485
break ;
486
case FS_MIDI_TUNE_REQUEST:
487
case 0xF4 :
488
case 0xF5 :
489
midi_event_enqueue_byte ( mrp, type ) ;
490
mrp-> in_midi_last_command = 0 ;
491
break ;
492
case FS_MIDI_SYNC:
493
case FS_MIDI_TICK:
494
case FS_MIDI_START:
495
case FS_MIDI_CONTINUE:
496
case FS_MIDI_STOP:
497
case FS_MIDI_ACTIVE_SENSING:
498
case FS_MIDI_SYSTEM_RESET:
499
midi_event_enqueue_byte ( mrp, type ) ;
500
break ;
501
case FS_MIDI_SYSEX:
502
503
504
505
506
507
508
dl_fluid_midi_event_set_type ( event, FS_MIDI_TEXT ) ;
509
if ( dl_fluid_midi_event_get_text ( event, ( void * * ) & bufptr, & buflen ) == FLUID_OK && bufptr != NULL ) {
510
midi_event_enqueue_sysex ( mrp, bufptr, buflen ) ;
511
}
512
break ;
513
}
514
515
516
517
pthread_mutex_unlock ( & mrp-> fifo_mutex) ;
518
return FLUID_OK;
519
}
520
521
522
#else
523
void midi_load_sf2 ( uint8_t * filename )
524
{
525
526
}
527
528
void midi_init ( )
529
{
530
fprintf ( stderr, " No FluidSynth support.\n " ) ;
531
}
532
533
void midi_byte_out ( uint8_t sel , uint8_t b )
534
{
535
536
}
537
538
void midi_synth_render ( int16_t * buf , int len )
539
{
540
541
memset ( buf, 0 , len * 2 * sizeof ( int16_t ) ) ;
542
}
543
544
#endif
545
546
void midi_serial_init ( )
547
{
548
uint8_t sel;
549
550
for ( sel= 0 ; sel< 2 ; sel+ + ) {
551
mregs[ sel] . ier_erbi = false ;
552
mregs[ sel] . ier_etbei = false ;
553
mregs[ sel] . ier_elsi = false ;
554
mregs[ sel] . ier_edssi = false ;
555
556
mregs[ sel] . iir = 0x01 ;
557
558
mregs[ sel] . fcr_fifo_enable = false ;
559
mregs[ sel] . fcr_ififo_trigger_level_bytes = 1 ;
560
561
mregs[ sel] . lcr_word_length_bits = 5 ;
562
mregs[ sel] . lcr_stb = false ;
563
mregs[ sel] . lcr_pen = false ;
564
mregs[ sel] . lcr_eps = false ;
565
mregs[ sel] . lcr_stick = false ;
566
mregs[ sel] . lcr_break = false ;
567
mregs[ sel] . lcr_dlab = false ;
568
569
mregs[ sel] . mcr_dtr = false ;
570
mregs[ sel] . mcr_rts = false ;
571
mregs[ sel] . mcr_out1 = false ;
572
mregs[ sel] . mcr_out2 = false ;
573
mregs[ sel] . mcr_loop = false ;
574
mregs[ sel] . mcr_afe = false ;
575
576
mregs[ sel] . lsr_oe = false ;
577
mregs[ sel] . lsr_pe = false ;
578
mregs[ sel] . lsr_fe = false ;
579
mregs[ sel] . lsr_bi = false ;
580
mregs[ sel] . lsr_eif = false ;
581
582
mregs[ sel] . msr_dcts = false ;
583
mregs[ sel] . msr_ddsr = false ;
584
mregs[ sel] . msr_teri = false ;
585
mregs[ sel] . msr_ddcd = false ;
586
587
mregs[ sel] . msr_cts = false ;
588
mregs[ sel] . msr_dsr = false ;
589
mregs[ sel] . msr_ri = false ;
590
mregs[ sel] . msr_dcd = false ;
591
592
mregs[ sel] . obyte_bits_remain = 0 ;
593
mregs[ sel] . rx_timeout = 0 ;
594
mregs[ sel] . rx_timeout_enabled = false ;
595
mregs[ sel] . thre_intr = false ;
596
mregs[ sel] . thre_bits_remain = 0 ;
597
598
mregs[ sel] . ibyte_bits_remain = 7 ;
599
600
mregs[ sel] . ifsz = 0 ;
601
mregs[ sel] . ififo [ 0 ] = 0 ;
602
mregs[ sel] . ofsz = 0 ;
603
mregs[ sel] . clock = 0 ;
604
mregs[ sel] . clockdec = 0 ;
605
mregs[ sel] . last_warning = 0 ;
606
607
mregs[ sel] . mfsz = 0 ;
608
mregs[ sel] . in_midi_last_command = 0 ;
609
}
610
611
if ( ! serial_midi_mutexes_initialized) {
612
for ( sel= 0 ; sel< 2 ; sel+ + ) {
613
pthread_mutexattr_init ( & mregs[ sel] . fifo_mutex_attr ) ;
614
pthread_mutex_init ( & mregs[ sel] . fifo_mutex , & mregs[ sel] . fifo_mutex_attr ) ;
615
}
616
serial_midi_mutexes_initialized = true ;
617
}
618
}
619
620
void midi_serial_iir_check ( uint8_t sel )
621
{
622
uint8_t fifoen = ( uint8_t ) mregs[ sel] . fcr_fifo_enable << 6 | ( uint8_t ) mregs[ sel] . fcr_fifo_enable << 7 ;
623
if ( mregs[ sel] . ier_elsi && ( mregs[ sel] . lsr_oe || mregs[ sel] . lsr_pe || mregs[ sel] . lsr_fe || mregs[ sel] . lsr_bi ) ) {
624
mregs[ sel] . iir = ( 0x06 | fifoen) ;
625
} else if ( mregs[ sel] . ier_erbi && ! mregs[ sel] . fcr_fifo_enable && mregs[ sel] . ifsz > 0 ) {
626
mregs[ sel] . iir = ( 0x04 | fifoen) ;
627
} else if ( mregs[ sel] . ier_erbi && mregs[ sel] . fcr_fifo_enable && mregs[ sel] . ifsz >= mregs[ sel] . fcr_ififo_trigger_level_bytes ) {
628
mregs[ sel] . iir = ( 0x04 | fifoen) ;
629
} else if ( mregs[ sel] . ier_erbi && mregs[ sel] . fcr_fifo_enable && mregs[ sel] . ifsz > 0 && mregs[ sel] . rx_timeout_enabled && mregs[ sel] . rx_timeout == 0 ) {
630
mregs[ sel] . iir = ( 0x0c | fifoen) ;
631
} else if ( mregs[ sel] . ier_etbei && mregs[ sel] . thre_intr ) {
632
mregs[ sel] . iir = ( 0x02 | fifoen) ;
633
} else if ( mregs[ sel] . ier_edssi && ( ( ! mregs[ sel] . mcr_afe && mregs[ sel] . msr_dcts ) || mregs[ sel] . msr_ddcd || mregs[ sel] . msr_ddsr || mregs[ sel] . msr_teri ) ) {
634
mregs[ sel] . iir = ( 0x00 | fifoen) ;
635
} else {
636
mregs[ sel] . iir = ( 0x01 | fifoen) ;
637
}
638
}
639
640
void midi_serial_step ( int clocks )
641
{
642
uint8_t sel, i;
643
for ( sel= 0 ; sel< 2 ; sel+ + ) {
644
mregs[ sel] . clock -= ( int64_t ) mregs[ sel] . clockdec * clocks;
645
while ( mregs[ sel] . clock < 0 ) {
646
647
pthread_mutex_lock ( & mregs[ sel] . fifo_mutex ) ;
648
649
if ( mregs[ sel] . obyte_bits_remain > 0 ) {
650
mregs[ sel] . obyte_bits_remain - - ;
651
}
652
if ( mregs[ sel] . ofsz > 0 ) {
653
if ( mregs[ sel] . obyte_bits_remain == 0 ) {
654
midi_byte_out ( sel, mregs[ sel] . ofifo [ 0 ] ) ;
655
mregs[ sel] . ofsz - - ;
656
if ( mregs[ sel] . ofsz > 0 ) {
657
for ( i= 0 ; i< mregs[ sel] . ofsz ; i+ + ) {
658
mregs[ sel] . ofifo [ i] = mregs[ sel] . ofifo [ i+ 1 ] ;
659
}
660
} else if ( mregs[ sel] . thre_bits_remain == 0 ) {
661
mregs[ sel] . thre_intr = true ;
662
}
663
mregs[ sel] . obyte_bits_remain = 2 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ;
664
}
665
} else {
666
if ( mregs[ sel] . thre_bits_remain > 0 ) {
667
mregs[ sel] . thre_bits_remain - - ;
668
if ( mregs[ sel] . thre_bits_remain == 0 ) {
669
mregs[ sel] . thre_intr = true ;
670
}
671
}
672
}
673
674
if ( mregs[ sel] . rx_timeout > 0 ) {
675
mregs[ sel] . rx_timeout - - ;
676
}
677
678
if ( mregs[ sel] . ibyte_bits_remain > 0 && mregs[ sel] . mfsz > 0 ) {
679
mregs[ sel] . ibyte_bits_remain - - ;
680
}
681
if ( mregs[ sel] . ibyte_bits_remain == 0 && mregs[ sel] . mfsz > 0 ) {
682
if ( mregs[ sel] . ifsz < ( mregs[ sel] . fcr_fifo_enable ? 16 : 1 ) ) {
683
mregs[ sel] . ififo [ mregs[ sel] . ifsz + + ] = mregs[ sel] . midi_event_fifo [ 0 ] ;
684
mregs[ sel] . rx_timeout_enabled = true ;
685
mregs[ sel] . rx_timeout = 4 * ( 2 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ) ;
686
} else {
687
mregs[ sel] . lsr_oe = true ;
688
if ( ! mregs[ sel] . fcr_fifo_enable ) {
689
690
691
mregs[ sel] . ififo [ mregs[ sel] . ifsz - 1 ] = mregs[ sel] . midi_event_fifo [ 0 ] ;
692
}
693
}
694
mregs[ sel] . mfsz - - ;
695
if ( mregs[ sel] . mfsz > 0 ) {
696
for ( i= 0 ; i< mregs[ sel] . mfsz ; i+ + ) {
697
mregs[ sel] . midi_event_fifo [ i] = mregs[ sel] . midi_event_fifo [ i+ 1 ] ;
698
}
699
}
700
mregs[ sel] . ibyte_bits_remain = 2 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ;
701
}
702
703
pthread_mutex_unlock ( & mregs[ sel] . fifo_mutex ) ;
704
mregs[ sel] . clock += 0x1000000LL ;
705
midi_serial_iir_check ( sel ) ;
706
}
707
}
708
}
709
710
uint8_t midi_serial_dequeue_ibyte ( uint8_t sel )
711
{
712
pthread_mutex_lock ( & mregs[ sel] . fifo_mutex ) ;
713
uint8_t ret = mregs[ sel] . ififo [ 0 ] ;
714
uint8_t i;
715
716
if ( mregs[ sel] . ifsz > 0 ) {
717
mregs[ sel] . ifsz - - ;
718
if ( mregs[ sel] . ifsz == 0 ) {
719
mregs[ sel] . rx_timeout_enabled = false ;
720
} else {
721
for ( i= 0 ; i< mregs[ sel] . ifsz ; i+ + ) {
722
mregs[ sel] . ififo [ i] = mregs[ sel] . ififo [ i+ 1 ] ;
723
}
724
mregs[ sel] . rx_timeout_enabled = true ;
725
mregs[ sel] . rx_timeout = 4 * ( 2 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ) ;
726
}
727
midi_serial_iir_check ( sel ) ;
728
}
729
730
pthread_mutex_unlock ( & mregs[ sel] . fifo_mutex ) ;
731
return ret;
732
}
733
734
void midi_serial_enqueue_obyte ( uint8_t sel , uint8_t val )
735
{
736
pthread_mutex_lock ( & mregs[ sel] . fifo_mutex ) ;
737
if ( mregs[ sel] . ofsz < ( mregs[ sel] . fcr_fifo_enable ? 16 : 1 ) ) {
738
mregs[ sel] . ofifo [ mregs[ sel] . ofsz ] = val;
739
mregs[ sel] . thre_intr = false ;
740
mregs[ sel] . ofsz + + ;
741
if ( mregs[ sel] . ofsz == 1 ) {
742
if ( mregs[ sel] . fcr_fifo_enable ) {
743
744
mregs[ sel] . thre_bits_remain = 1 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ;
745
}
746
} else {
747
mregs[ sel] . thre_bits_remain = 0 ;
748
}
749
} else {
750
fprintf ( stderr, " Serial MIDI: Warning: UART %d TX Overflow\n " , sel ) ;
751
}
752
midi_serial_iir_check ( sel ) ;
753
pthread_mutex_unlock ( & mregs[ sel] . fifo_mutex ) ;
754
}
755
756
uint8_t midi_serial_read ( uint8_t reg , bool debugOn )
757
{
758
759
uint8_t sel = ( reg & 8 ) >> 3 ;
760
switch ( reg & 7 ) {
761
case 0x0 :
762
if ( mregs[ sel] . lcr_dlab ) {
763
return mregs[ sel] . dll ;
764
} else {
765
if ( debugOn) {
766
return mregs[ sel] . ififo [ 0 ] ;
767
} else {
768
return midi_serial_dequeue_ibyte ( sel ) ;
769
}
770
}
771
break ;
772
case 0x1 :
773
if ( mregs[ sel] . lcr_dlab ) {
774
return mregs[ sel] . dlm ;
775
} else {
776
return ( ( ( uint8_t ) mregs[ sel] . ier_edssi << 3 ) |
777
( ( uint8_t ) mregs[ sel] . ier_elsi << 2 ) |
778
( ( uint8_t ) mregs[ sel] . ier_etbei << 1 ) |
779
( ( uint8_t ) mregs[ sel] . ier_erbi ) ) ;
780
}
781
break ;
782
case 0x2 : {
783
uint8_t ret = mregs[ sel] . iir ;
784
if ( ! debugOn) {
785
mregs[ sel] . thre_intr = false ;
786
midi_serial_iir_check ( sel ) ;
787
}
788
return ret;
789
break ;
790
}
791
case 0x3 :
792
return ( ( ( uint8_t ) mregs[ sel] . lcr_dlab << 7 ) |
793
( ( uint8_t ) mregs[ sel] . lcr_break << 6 ) |
794
( ( uint8_t ) mregs[ sel] . lcr_stick << 5 ) |
795
( ( uint8_t ) mregs[ sel] . lcr_eps << 4 ) |
796
( ( uint8_t ) mregs[ sel] . lcr_pen << 3 ) |
797
( ( uint8_t ) mregs[ sel] . lcr_stb << 2 ) |
798
( ( mregs[ sel] . lcr_word_length_bits - 5 ) & 0x3 ) ) ;
799
break ;
800
case 0x4 :
801
return ( ( ( uint8_t ) mregs[ sel] . mcr_afe << 5 ) |
802
( ( uint8_t ) mregs[ sel] . mcr_loop << 4 ) |
803
( ( uint8_t ) mregs[ sel] . mcr_out2 << 3 ) |
804
( ( uint8_t ) mregs[ sel] . mcr_out1 << 2 ) |
805
( ( uint8_t ) mregs[ sel] . mcr_rts << 1 ) |
806
( ( uint8_t ) mregs[ sel] . mcr_dtr ) ) ;
807
break ;
808
case 0x5 : {
809
uint8_t ret = ( ( ( uint8_t ) mregs[ sel] . lsr_eif << 7 ) |
810
( ( uint8_t ) ( mregs[ sel] . obyte_bits_remain == 0 && mregs[ sel] . ofsz == 0 ) << 6 ) |
811
( ( uint8_t ) ( mregs[ sel] . ofsz == 0 ) << 5 ) |
812
( ( uint8_t ) mregs[ sel] . lsr_bi << 4 ) |
813
( ( uint8_t ) mregs[ sel] . lsr_fe << 3 ) |
814
( ( uint8_t ) mregs[ sel] . lsr_pe << 2 ) |
815
( ( uint8_t ) mregs[ sel] . lsr_oe << 1 ) |
816
( ( uint8_t ) ( mregs[ sel] . ifsz > 0 ) ) ) ;
817
if ( ! debugOn) {
818
mregs[ sel] . lsr_oe = false ;
819
mregs[ sel] . lsr_pe = false ;
820
mregs[ sel] . lsr_fe = false ;
821
mregs[ sel] . lsr_bi = false ;
822
}
823
return ret;
824
break ;
825
}
826
case 0x6 :
827
return ( ( ( uint8_t ) mregs[ sel] . msr_dcd << 7 ) |
828
( ( uint8_t ) mregs[ sel] . msr_ri << 6 ) |
829
( ( uint8_t ) mregs[ sel] . msr_dsr << 5 ) |
830
( ( uint8_t ) mregs[ sel] . msr_cts << 4 ) |
831
( ( uint8_t ) mregs[ sel] . msr_ddcd << 3 ) |
832
( ( uint8_t ) mregs[ sel] . msr_teri << 2 ) |
833
( ( uint8_t ) mregs[ sel] . msr_ddsr << 1 ) |
834
( ( uint8_t ) mregs[ sel] . msr_dcts ) ) ;
835
break ;
836
case 0x7 :
837
return mregs[ sel] . scratch ;
838
break ;
839
}
840
return 0x00 ;
841
}
842
843
void midi_serial_calculate_clk ( uint8_t sel )
844
{
845
double uart_clks_per_cpu = ( MIDI_UART_OSC_RATE_MHZ / MIDI_UART_PRIMARY_DIVIDER) / MHZ;
846
if ( mregs[ sel] . dl > 0 ) {
847
uart_clks_per_cpu /= mregs[ sel] . dl ;
848
mregs[ sel] . clockdec = uart_clks_per_cpu * 0x1000000L ;
849
} else {
850
mregs[ sel] . clockdec = 0 ;
851
}
852
}
853
854
void midi_serial_write ( uint8_t reg , uint8_t val )
855
{
856
time_t now = time ( NULL ) ;
857
858
859
uint8_t sel = ( reg & 8 ) >> 3 ;
860
switch ( reg & 7 ) {
861
case 0x0 :
862
if ( mregs[ sel] . lcr_dlab ) {
863
mregs[ sel] . dll = val;
864
midi_serial_calculate_clk ( sel ) ;
865
} else {
866
if ( mregs[ sel] . lcr_word_length_bits != 8 || mregs[ sel] . lcr_stb || mregs[ sel] . lcr_pen ) {
867
if ( mregs[ sel] . last_warning + 60 < now) {
868
unsigned char par = ' N' ;
869
if ( mregs[ sel] . lcr_pen ) {
870
switch ( ( uint8_t ) ( mregs[ sel] . lcr_eps << 1 ) | ( uint8_t ) mregs[ sel] . lcr_stick ) {
871
case 0 :
872
par = ' O' ;
873
break ;
874
case 1 :
875
par = ' M' ;
876
break ;
877
case 2 :
878
par = ' E' ;
879
break ;
880
case 3 :
881
par = ' S' ;
882
break ;
883
}
884
}
885
fprintf ( stderr, " Serial MIDI: Warning: improper LCR %d %c %d for UART %d , must be set to 8N1.\n " , mregs[ sel] . lcr_word_length_bits , par, 1 + ( uint8_t ) mregs[ sel] . lcr_stb , sel ) ;
886
mregs[ sel] . last_warning = now;
887
}
888
} else if ( mregs[ sel] . lcr_break && mregs[ sel] . last_warning + 60 < now) {
889
fprintf ( stderr, " Serial MIDI: Warning: break improperly set for UART %d .\n " , sel ) ;
890
mregs[ sel] . last_warning = now;
891
} else if ( mregs[ sel] . dl != 32 && mregs[ sel] . last_warning + 60 < now) {
892
fprintf ( stderr, " Serial MIDI: Warning: improper divisor %d for UART %d , must be set to 32 for standard MIDI bitrate.\n " , mregs[ sel] . dl , sel ) ;
893
mregs[ sel] . last_warning = now;
894
} else {
895
midi_serial_enqueue_obyte ( sel, val ) ;
896
}
897
}
898
break ;
899
case 0x1 :
900
if ( mregs[ sel] . lcr_dlab ) {
901
mregs[ sel] . dlm = val;
902
midi_serial_calculate_clk ( sel ) ;
903
} else {
904
mregs[ sel] . ier_erbi = ! ! ( val & 1 ) ;
905
mregs[ sel] . ier_etbei = ! ! ( val & 2 ) ;
906
mregs[ sel] . ier_elsi = ! ! ( val & 4 ) ;
907
mregs[ sel] . ier_edssi = ! ! ( val & 8 ) ;
908
}
909
break ;
910
case 0x2 :
911
if ( val & 1 ) {
912
mregs[ sel] . fcr_fifo_enable = true ;
913
switch ( ( val & 0xc0 ) >> 6 ) {
914
case 0 :
915
mregs[ sel] . fcr_ififo_trigger_level_bytes = 1 ;
916
break ;
917
case 1 :
918
mregs[ sel] . fcr_ififo_trigger_level_bytes = 4 ;
919
break ;
920
case 2 :
921
mregs[ sel] . fcr_ififo_trigger_level_bytes = 8 ;
922
break ;
923
case 3 :
924
mregs[ sel] . fcr_ififo_trigger_level_bytes = 14 ;
925
break ;
926
}
927
} else {
928
mregs[ sel] . fcr_fifo_enable = false ;
929
mregs[ sel] . fcr_ififo_trigger_level_bytes = 1 ;
930
}
931
if ( val & 2 ) {
932
mregs[ sel] . ifsz = 0 ;
933
}
934
if ( val & 4 ) {
935
mregs[ sel] . ofsz = 0 ;
936
}
937
if ( mregs[ sel] . thre_bits_remain == 0 ) {
938
mregs[ sel] . thre_intr = true ;
939
}
940
midi_serial_iir_check ( sel ) ;
941
break ;
942
case 0x3 :
943
mregs[ sel] . lcr_word_length_bits = ( val & 0x03 ) + 5 ;
944
mregs[ sel] . lcr_stb = ! ! ( val & 0x04 ) ;
945
mregs[ sel] . lcr_pen = ! ! ( val & 0x08 ) ;
946
mregs[ sel] . lcr_eps = ! ! ( val & 0x10 ) ;
947
mregs[ sel] . lcr_stick = ! ! ( val & 0x20 ) ;
948
mregs[ sel] . lcr_break = ! ! ( val & 0x40 ) ;
949
mregs[ sel] . lcr_dlab = ! ! ( val & 0x80 ) ;
950
if ( mregs[ sel] . mfsz == 0 ) {
951
mregs[ sel] . ibyte_bits_remain = 2 + mregs[ sel] . lcr_word_length_bits + mregs[ sel] . lcr_stb + mregs[ sel] . lcr_pen ;
952
}
953
break ;
954
case 0x4 :
955
mregs[ sel] . mcr_dtr = ! ! ( val & 0x01 ) ;
956
mregs[ sel] . mcr_rts = ! ! ( val & 0x02 ) ;
957
mregs[ sel] . mcr_out1 = ! ! ( val & 0x04 ) ;
958
mregs[ sel] . mcr_out2 = ! ! ( val & 0x08 ) ;
959
mregs[ sel] . mcr_loop = ! ! ( val & 0x10 ) ;
960
mregs[ sel] . mcr_afe = ! ! ( val & 0x20 ) ;
961
962
if ( mregs[ sel] . mcr_loop ) {
963
mregs[ sel] . msr_dcts |= mregs[ sel] . msr_cts ^ mregs[ sel] . mcr_dtr ;
964
mregs[ sel] . msr_cts = mregs[ sel] . mcr_dtr ;
965
966
mregs[ sel] . msr_ddsr |= mregs[ sel] . msr_dsr ^ mregs[ sel] . mcr_rts ;
967
mregs[ sel] . msr_dsr = mregs[ sel] . mcr_rts ;
968
969
if ( mregs[ sel] . msr_ri ) {
970
mregs[ sel] . msr_teri |= mregs[ sel] . msr_ri ^ mregs[ sel] . mcr_out1 ;
971
}
972
mregs[ sel] . msr_ri = mregs[ sel] . mcr_out1 ;
973
974
mregs[ sel] . msr_ddcd |= mregs[ sel] . msr_dcd ^ mregs[ sel] . mcr_out2 ;
975
mregs[ sel] . msr_dcd = mregs[ sel] . mcr_out2 ;
976
977
} else {
978
979
if ( mregs[ sel ^ 1 ] . msr_ri && ! mregs[ sel] . mcr_dtr ) {
980
mregs[ sel ^ 1 ] . msr_teri = true ;
981
}
982
mregs[ sel ^ 1 ] . msr_ri = mregs[ sel] . mcr_dtr ;
983
}
984
985
break ;
986
case 0x7 :
987
mregs[ sel] . scratch = val;
988
break ;
989
}
990
}
991
992
bool midi_serial_irq ( void )
993
{
994
bool uart0int = ( mregs[ 0 ] . iir & 1 ) == 0 && mregs[ 0 ] . mcr_out2 ;
995
bool uart1int = ( mregs[ 1 ] . iir & 1 ) == 0 && mregs[ 1 ] . mcr_out2 ;
996
return ( uart0int | uart1int) ;
997
}