…Show last 1745 lines
61+
62+void MIDI_ClearBuffer(Bit8u slot) {
63+	midi.sysex.used=0;
64+	midi.status=0x00;
65+	midi.cmd_pos=0;
66+	midi.cmd_len=0;
67+}
68+
69 void MIDI_RawOutByte(Bit8u data) {
70 	if (midi.sysex.start) {
71 		Bit32u passed_ticks = GetTicks() - midi.sysex.start;
72@@ -168,6 +195,9 @@ public:
73 		Section_prop * section=static_cast<Section_prop *>(configuration);
74 		const char * dev=section->Get_string("mididevice");
75 		std::string fullconf=section->Get_string("midiconfig");
76+
77+		const char * inconf = 1; // change to integer value of midi input device
78+
79 		/* If device = "default" go for first handler that works */
80 		MidiHandler * handler;
81 //		MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI");
82@@ -183,6 +213,7 @@ public:
83 		midi.status=0x00;
84 		midi.cmd_pos=0;
85 		midi.cmd_len=0;
86+		midi.sysex.used=0;
87 		if (!strcasecmp(dev,"default")) goto getdefault;
88 		handler=handler_list;
89 		while (handler) {
90@@ -194,7 +225,7 @@ public:
91 				midi.handler=handler;
92 				midi.available=true;
93 				LOG(LOG_MISC,LOG_DEBUG)("MIDI: Opened device:%s",handler->GetName());
94-				return;
95+				goto midiin;
96 			}
97 			handler=handler->next;
98 		}
99@@ -206,16 +237,27 @@ getdefault:
100 				midi.available=true;
101 				midi.handler=handler;
102 				LOG(LOG_MISC,LOG_DEBUG)("MIDI: Opened device:%s",handler->GetName());
103-				return;
104+				goto midiin;
105 			}
106 			handler=handler->next;
107 		}
108 		/* This shouldn't be possible */
109 	}
110+midiin:
111+	MidiHandler * output_handler=0;
112+	output_handler=handler;
113+	if (handler->OpenInput(inconf)) {
114+		LOG_MSG("MIDI:Opened input device:%s.",handler->GetName());
115+		midi.in_handler=handler;
116+		return;
117+	}
118+	handler=handler_list;
119 	~MIDI(){
120+		midi.in_handler->Close();
121 		if(midi.available) midi.handler->Close();
122 		midi.available = false;
123 		midi.handler = 0;
124+		midi.in_handler = 0;
125 	}
126 };
127 
128diff -rupN dosbox-before//src/gui/midi_win32.h dosbox-after/src/gui/midi_win32.h
129--- dosbox-before//src/gui/midi_win32.h
130+++ dosbox-after/src/gui/midi_win32.h
131@@ -25,14 +25,60 @@
132 #include <string>
133 #include <sstream>
134 
135+void CALLBACK Win32_midiInCallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
136+	//LOG_MSG("wMsg:%x %x %x",wMsg, dwParam1, dwParam2);
137+	Bit8u msg[4] = {(Bit8u(dwParam1&0xff)),(Bit8u((dwParam1&0xff00)>>8)),
138+					(Bit8u((dwParam1&0xff0000)>>16)),MIDI_evt_len[(Bit8u(dwParam1&0xff))]};
139+	Bit8u *sysex;
140+	Bitu len;
141+	MIDIHDR *t_hdr;
142+	switch (wMsg) {
143+		case MM_MIM_DATA:  /* 0x3C3 - midi message */
144+			MIDI_InputMsg(msg);
145+			break;
146+		case MM_MIM_OPEN:  /* 0x3C1 */
147+			break;
148+		case MM_MIM_CLOSE: /* 0x3C2 */
149+			break;
150+		case MM_MIM_LONGDATA: /* 0x3C4 - sysex */
151+			t_hdr=(MIDIHDR*)dwParam1;
152+			sysex=(Bit8u*)t_hdr->lpData; 
153+			len=(Bitu)t_hdr->dwBytesRecorded;
154+			{
155+				Bitu cnt=5;
156+				while (cnt) { //abort if timed out
157+					Bitu ret = Bitu(MIDI_InputSysex(sysex,len,false));
158+					if (!ret) {len=0;break;}
159+					if (len==ret) cnt--; else cnt=5;
160+					sysex+=len-ret;
161+					len=ret;
162+					Sleep(5);//msec
163+				}
164+				if (len) MIDI_InputSysex(sysex,0,false);
165+			}
166+			midiInUnprepareHeader(hMidiIn,t_hdr,sizeof(*t_hdr));
167+			t_hdr->dwBytesRecorded = 0 ;
168+			midiInPrepareHeader(hMidiIn,t_hdr,sizeof(*t_hdr));
169+			break;
170+		case MM_MIM_ERROR:
171+		case MM_MIM_LONGERROR:
172+			break;
173+		default:
174+			LOG(LOG_MISC, LOG_NORMAL) ("MIDI: Unhandled input type %x",wMsg);
175+	}
176+};
177+
178 class MidiHandler_win32: public MidiHandler {
179 private:
180 	HMIDIOUT m_out;
181 	MIDIHDR m_hdr;
182 	HANDLE m_event;
183 	bool isOpen;
184+	HMIDIIN m_in;
185+	MIDIHDR m_inhdr;
186+	bool isOpenInput;
187 public:
188-	MidiHandler_win32() : MidiHandler(),isOpen(false) {};
189+	MidiHandler_win32() : isOpen(false),isOpenInput(false),MidiHandler() {};
190 	const char * GetName(void) { return "win32";};
191 	bool Open(const char * conf) {
192 		if (isOpen) return false;
193@@ -71,12 +117,46 @@ public:
194 		isOpen=true;
195 		return true;
196 	};
197+	bool OpenInput(const char *inconf) {
198+		if (isOpenInput) return false;
199+		void * midiInCallback=Win32_midiInCallback;
200+		MMRESULT res;
201+		if(inconf && *inconf) {
202+			std::string strinconf(inconf);
203+			std::istringstream configmidiin(strinconf);
204+			unsigned int nummer = midiInGetNumDevs();
205+			configmidiin >> nummer;
206+			if(nummer < midiInGetNumDevs()){
207+				MIDIINCAPS mididev;
208+				midiInGetDevCaps(nummer, &mididev, sizeof(MIDIINCAPS));
209+				LOG_MSG("MIDI:win32 selected input %s",mididev.szPname);
210+				res = midiInOpen (&m_in, nummer, (DWORD_PTR)midiInCallback, 0, CALLBACK_FUNCTION);
211+			}
212+		} else {
213+			res = midiInOpen(&m_in, MIDI_MAPPER, (DWORD_PTR)midiInCallback, 0, CALLBACK_FUNCTION);
214+		}
215+		if (res != MMSYSERR_NOERROR) return false;
216 
217+		m_inhdr.lpData = (char*)&MIDI_InSysexBuf[0];
218+		m_inhdr.dwBufferLength = SYSEX_SIZE;
219+		m_inhdr.dwBytesRecorded = 0 ;
220+		m_inhdr.dwUser = 0;
221+		midiInPrepareHeader(m_in,&m_inhdr,sizeof(m_inhdr));
222+		midiInStart(m_in);
223+		isOpenInput=true;
224+		return true;
225+	};
226 	void Close(void) {
227-		if (!isOpen) return;
228-		isOpen=false;
229-		midiOutClose(m_out);
230-		CloseHandle (m_event);
231+		if (isOpen) {
232+			isOpen=false;
233+			midiOutClose(m_out);
234+			CloseHandle (m_event);
235+		}
236+		if (isOpenInput) {
237+			isOpenInput=false;
238+			midiInStop(m_in);
239+			midiInClose(m_in);
240+		}
241 	};
242 	void PlayMsg(Bit8u * msg) {
243 		midiOutShortMsg(m_out, *(Bit32u*)msg);
244diff -rupN dosbox-before//src/hardware/mpu401.cpp dosbox-after/src/hardware/mpu401.cpp
245--- dosbox-before//src/hardware/mpu401.cpp
246+++ dosbox-after/src/hardware/mpu401.cpp
247@@ -24,22 +24,38 @@
248 #include "setup.h"
249 #include "cpu.h"
250 #include "support.h"
251+#include "mixer.h"
252+#include "midi.h"
253 
254 void MIDI_RawOutByte(Bit8u data);
255 bool MIDI_Available(void);
256+SDL_mutex * MPULock;
257 
258 static void MPU401_Event(Bitu);
259 static void MPU401_Reset(void);
260 static void MPU401_ResetDone(Bitu);
261 static void MPU401_EOIHandler(Bitu val=0);
262 static void MPU401_EOIHandlerDispatch(void);
263+static void MPU401_IntelligentOut(Bitu data);
264+static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen);
265+static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen);
266+static void MPU401_NotesOff(Bitu chan);
267+static void MPU401_RecQueueBuffer(Bit8u * buf, Bitu len,bool block);
268 
269 #define MPU401_VERSION	0x15
270 #define MPU401_REVISION	0x01
271-#define MPU401_QUEUE 32
272+#define MPU401_QUEUE 64
273+#define MPU401_INPUT_QUEUE 1024
274 #define MPU401_TIMECONSTANT (60000000/1000.0f)
275 #define MPU401_RESETBUSY 27.0f
276 
277+#define M_GETKEY key[key/32]&(1<<(key%32))
278+#define M_SETKEY key[key/32]|=(1<<(key%32))
279+#define M_DELKEY key[key/32]&=~(1<<(key%32))
280+enum RecState { M_RECOFF,M_RECSTB,M_RECON };
281+static Bitu MPUClockBase[8]={48,72,96,120,144,168,192};
282+static Bit8u cth_data[16]={0,0,0,0,1,0,0,0,1,0,1,0,1,1,1,0};
283+
284 enum MpuMode { M_UART,M_INTELLIGENT };
285 enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND};
286 
287@@ -58,20 +74,38 @@ static void MPU401_WriteData(Bitu port,B
288 #define MSG_MPU_ACK                     0xfe
289 
290 static struct {
291+ 	bool intelligent;
292+ 	Bitu irq;
293+	bool midi_thru;
294+	IO_ReadHandleObject ReadHandler[2];
295+	IO_WriteHandleObject WriteHandler[2];
296+} mpuhw;
297+
298+static struct {
299 	bool intelligent;
300 	MpuMode mode;
301 	Bitu irq;
302 	Bit8u queue[MPU401_QUEUE];
303 	Bitu queue_pos,queue_used;
304+	Bit8u rec_queue[MPU401_INPUT_QUEUE];
305+	Bitu rec_queue_pos,rec_queue_used;
306 	struct track {
307 		Bits counter;
308-		Bit8u value[8],sys_val;
309-		Bit8u vlength,length;
310+		Bit8u value[3],sys_val;
311+		Bitu length;
312 		MpuDataType type;
313 	} playbuf[8],condbuf;
314 	struct {
315-		bool conductor,cond_req,cond_set, block_ack;
316-		bool playing,reset;
317+		bool tx_ready;
318+		bool conductor,cond_req,cond_set;
319+		bool track_req;
320+		bool block_ack;
321+		bool playing;
322+		bool clock_to_host;
323+		bool sync_in;
324+		bool sysex_in_finished;
325+		bool rec_copy;
326+		RecState rec;
327 		bool wsd,wsm,wsd_start;
328 		bool run_irq,irq_pending;
329 		bool send_now;
330@@ -81,220 +115,470 @@ static struct {
331 		Bit8u tmask,cmask,amask;
332 		Bit16u midi_mask;
333 		Bit16u req_mask;
334-		Bit8u channel,old_chan;
335+		Bitu track,old_track;
336+		Bit8u last_rtcmd;
337 	} state;
338 	struct {
339 		Bit8u timebase,old_timebase;
340 		Bit8u tempo,old_tempo;
341 		Bit8u tempo_rel,old_tempo_rel;
342 		Bit8u tempo_grad;
343-		Bit8u cth_rate,cth_counter;
344-		bool clock_to_host,cth_active;
345+		Bit8u cth_rate[4],cth_mode;
346+		Bit8u midimetro,metromeas;
347+		Bitu cth_counter,cth_old;
348+		Bitu rec_counter;
349+		Bit32s measure_counter,meas_old;
350+		Bit32s freq;
351+		Bits ticks_in;
352+		float freq_mod;
353+		bool active;
354 	} clock;
355+	struct {
356+		bool all_thru,midi_thru,sysex_thru,commonmsgs_thru;
357+		bool modemsgs_in, commonmsgs_in, bender_in, sysex_in;
358+		bool allnotesoff_out;
359+		bool rt_affection, rt_out,rt_in;
360+		bool timing_in_stop;
361+		bool data_in_stop;
362+		bool rec_measure_end;
363+		Bit8u prchg_buf[16];
364+		Bit16u prchg_mask;
365+	} filter;
366+	Bitu ch_toref[16];
367+	struct {
368+		Bit8u chan;
369+		Bit32u key[4];
370+		Bit8u trmask;
371+		bool on;
372+	}chanref[5],inputref[16];
373 } mpu;
374 
375+static void MPU401_ReCalcClock(void) {
376+	Bit32s maxtempo=240, mintempo=16;
377+	if (mpu.clock.timebase>=168) maxtempo=179;
378+	if (mpu.clock.timebase==144) maxtempo=208;
379+	if (mpu.clock.timebase>=120) mintempo=8;
380+	mpu.clock.freq=(Bit32u(mpu.clock.tempo*2*mpu.clock.tempo_rel))>>6;
381+
382+	mpu.clock.freq=mpu.clock.timebase*
383+		(mpu.clock.freq<(mintempo*2) ? mintempo : 
384+		((mpu.clock.freq/2)<maxtempo?(mpu.clock.freq/2):maxtempo) );
385+
386+	if (mpu.state.sync_in) {
387+		Bit32s freq= Bit32s(float(mpu.clock.freq)*mpu.clock.freq_mod);
388+		if (freq>mpu.clock.timebase*mintempo && freq<mpu.clock.timebase*maxtempo) 
389+			mpu.clock.freq=freq;
390+	}
391+}
392+
393+static INLINE void MPU401_StartClock(void) {
394+	if (mpu.clock.active) return;
395+	if (!(mpu.state.clock_to_host || mpu.state.playing || mpu.state.rec==M_RECON)) return;
396+	mpu.clock.active=true;
397+	PIC_RemoveEvents(MPU401_Event);
398+	PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/mpu.clock.freq);
399+}
400+
401+static void MPU401_StopClock(void) {
402+	if (mpu.state.playing || mpu.state.rec!=M_RECON || mpu.state.clock_to_host)  return;
403+	mpu.clock.active=false;
404+	PIC_RemoveEvents(MPU401_Event);
405+}
406+
407 int MPU401_GetIRQ() {
408 	return (int)mpu.irq;
409 }
410 
411-static void QueueByte(Bit8u data) {
412+static INLINE void MPU401_RunClock(void) {
413+	if (!mpu.clock.active) return;
414+	PIC_RemoveEvents(MPU401_Event);
415+	PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/(mpu.clock.freq));
416+}
417+
418+static INLINE void MPU401_QueueByte(Bit8u data) {
419 	if (mpu.state.block_ack) {mpu.state.block_ack=false;return;}
420-	if (mpu.queue_used==0 && mpu.intelligent) {
421+	if (mpu.queue_used==0 && mpuhw.intelligent) {
422 		mpu.state.irq_pending=true;
423-		PIC_ActivateIRQ(mpu.irq);
424+		PIC_ActivateIRQ(mpuhw.irq);
425 	}
426 	if (mpu.queue_used<MPU401_QUEUE) {
427 		Bitu pos=mpu.queue_used+mpu.queue_pos;
428-		if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE;
429 		if (pos>=MPU401_QUEUE) pos-=MPU401_QUEUE;
430 		mpu.queue_used++;
431 		mpu.queue[pos]=data;
432-	} else LOG(LOG_MISC,LOG_NORMAL)("MPU401:Data queue full");
433+	}
434+}
435+
436+static void MPU401_RecQueueBuffer(Bit8u * buf, Bitu len,bool block) {
437+	if (block) {
438+		if (MPULock) SDL_mutexP(MPULock);
439+		else return;
440+	}
441+	Bitu cnt=0;
442+	while (cnt<len) {
443+		if (mpu.rec_queue_used<MPU401_INPUT_QUEUE) {
444+			Bitu pos=mpu.rec_queue_used+mpu.rec_queue_pos;
445+			if (pos>=MPU401_INPUT_QUEUE) {pos-=MPU401_INPUT_QUEUE;}
446+			mpu.rec_queue[pos]=buf[cnt];
447+			mpu.rec_queue_used++;
448+			if (!mpu.state.sysex_in_finished && buf[cnt]==MSG_EOX) {//finish sysex
449+				mpu.state.sysex_in_finished=true;
450+				break;
451+			}
452+			cnt++;
453+		}
454+	}
455+	if (mpu.queue_used==0) {
456+		if (mpu.state.rec_copy || mpu.state.irq_pending) {
457+			if (block && MPULock) SDL_mutexV(MPULock);
458+			return;
459+		}
460+		mpu.state.rec_copy=true;
461+		if (mpu.rec_queue_pos>=MPU401_INPUT_QUEUE) mpu.rec_queue_pos-=MPU401_INPUT_QUEUE;
462+		MPU401_QueueByte(mpu.rec_queue[mpu.rec_queue_pos]);
463+		mpu.rec_queue_used--;
464+		mpu.rec_queue_pos++;
465+	}
466+	if (block && MPULock) SDL_mutexV(MPULock);
467 }
468 
469-static void ClrQueue(void) {
470+static void MPU401_ClrQueue(void) {
471 	mpu.queue_used=0;
472 	mpu.queue_pos=0;
473+	mpu.rec_queue_used=0;
474+	mpu.rec_queue_pos=0;
475+	mpu.state.sysex_in_finished=true;
476+	mpu.state.irq_pending=false;
477 }
478 
479 static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) {
480     	(void)iolen;//UNUSED
481     	(void)port;//UNUSED
482-	Bit8u ret=0x3f;	/* Bits 6 and 7 clear */
483-	if (mpu.state.cmd_pending) ret|=0x40;
484-	if (!mpu.queue_used) ret|=0x80;
485-	return ret;
486+	return (0x3f | (mpu.queue_used ? 0: 0x80));
487+}
488+
489+static Bitu MPU401_ReadStatusTx(Bitu port,Bitu iolen) {
490+	return (0x3f | (mpu.queue_used ? 0: 0x80) | (mpu.state.tx_ready ? 0: 0x40));
491+}
492+
493+
494+void MPU401_SetTx(bool status) {
495+	mpu.state.tx_ready=status;
496 }
497 
498 static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) {
499-    	(void)iolen;//UNUSED
500-    	(void)port;//UNUSED
501-	if (mpu.mode==M_UART && val!=0xff) return;
502-	if (mpu.state.reset) {
503-		if (mpu.state.cmd_pending || (val!=0x3f && val!=0xff)) {
504-			mpu.state.cmd_pending=val+1;
505-			return;
506-		}
507-		PIC_RemoveEvents(MPU401_ResetDone);
508-		mpu.state.reset=false;
509-	}
510-	if (val<=0x2f) {
511-		switch (val&3) { /* MIDI stop, start, continue */
512-			case 1: {MIDI_RawOutByte(0xfc);break;}
513-			case 2: {MIDI_RawOutByte(0xfa);break;}
514-			case 3: {MIDI_RawOutByte(0xfb);break;}
515-		}
516-		if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",(int)val);
517-		switch (val&0xc) {
518-			case  0x4:	/* Stop */
519-				PIC_RemoveEvents(MPU401_Event);
520-				mpu.state.playing=false;
521-				for (Bitu i=0xb0;i<0xbf;i++) {	/* All notes off */
522-					MIDI_RawOutByte(i);
523-					MIDI_RawOutByte(0x7b);
524-					MIDI_RawOutByte(0);
525-				}
526-				break;
527-			case 0x8:	/* Play */
528-				LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started");
529-				mpu.state.playing=true;
530-				PIC_RemoveEvents(MPU401_Event);
531-				PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/(mpu.clock.tempo*mpu.clock.timebase));
532-				ClrQueue();
533-				break;
534-		}
535-	}
536-	else if (val>=0xa0 && val<=0xa7) {	/* Request play counter */
537-		if (mpu.state.cmask&(1<<(val&7))) QueueByte(mpu.playbuf[val&7].counter);
538-	}
539-	else if (val>=0xd0 && val<=0xd7) {	/* Send data */
540-		mpu.state.old_chan=mpu.state.channel;
541-		mpu.state.channel=val&7;
542-		mpu.state.wsd=true;
543-		mpu.state.wsm=false;
544-		mpu.state.wsd_start=true;
545-	}
546-	else
547-	switch (val) {
548-		case 0xdf:	/* Send system message */
549-			mpu.state.wsd=false;
550-			mpu.state.wsm=true;
551-			mpu.state.wsd_start=true;
552+	//LOG(LOG_MISC,LOG_NORMAL)("MPU401:command %x",val);
553+	SDL_mutexP(MPULock);
554+
555+	//hack:enable midi through after the first mpu401 command is written
556+	mpuhw.midi_thru=true;
557+
558+	if (val<=0x2f) { /* Sequencer state */
559+		bool send_prchg=false;
560+		if ((val&0xf)<0xc) {
561+			switch (val&3) { /* MIDI realtime messages */
562+				case 1:
563+					mpu.state.last_rtcmd=0xfc;
564+					if (mpu.filter.rt_out) MIDI_RawOutRTByte(0xfc);
565+					mpu.clock.meas_old=mpu.clock.measure_counter;
566+					mpu.clock.cth_old=mpu.clock.cth_counter;
567+					break;
568+				case 2: 
569+					mpu.state.last_rtcmd=0xfa;
570+					if (mpu.filter.rt_out) MIDI_RawOutRTByte(0xfb);
571+					mpu.clock.measure_counter=mpu.clock.meas_old=0;
572+					mpu.clock.cth_counter=mpu.clock.cth_old=0;
573+					break;
574+				case 3:
575+					mpu.state.last_rtcmd=0xfc;
576+					if (mpu.filter.rt_out) MIDI_RawOutRTByte(0xfa);
577+					mpu.clock.measure_counter=mpu.clock.meas_old;
578+					mpu.clock.cth_counter=mpu.clock.cth_old;
579+					break;
580+			}
581+			switch (val&0xc) { /* Playing */
582+				case  0x4:	/* Stop */
583+					mpu.state.playing=false;
584+					MPU401_StopClock();
585+					for (Bitu i=0;i<16;i++) MPU401_NotesOff(i);
586+					mpu.filter.prchg_mask=0;
587+					break;
588+				case 0x8:	/* Start */
589+					LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback");
590+					mpu.state.playing=true;
591+					MPU401_StartClock();
592+			}
593+			switch (val&0x30) { /* Recording */
594+				case 0: //check if it waited for MIDI RT command
595+					//if (val&8 && mpu.state.rec!=M_RECON) mpu.clock.rec_counter=0;
596+					if ((val&3)<2 || !mpu.filter.rt_affection || mpu.state.rec!=M_RECSTB) break;
597+					mpu.state.rec=M_RECON;
598+					MPU401_StartClock();
599+					if (mpu.filter.prchg_mask) send_prchg=true;
600+					break;
601+				case 0x10:  /* Stop */
602+					//if (val&8 && mpu.state.rec!=M_RECON) mpu.clock.rec_counter=0;
603+					mpu.state.rec=M_RECOFF;
604+					MPU401_StopClock();	
605+					MPU401_QueueByte(MSG_MPU_ACK);
606+					MPU401_QueueByte(mpu.clock.rec_counter);
607+					MPU401_QueueByte(MSG_MPU_END);
608+					mpu.filter.prchg_mask=0;
609+					mpu.clock.rec_counter=0;
610+					SDL_mutexV(MPULock);
611+					return;					
612+				case 0x20:  /* Start */
613+					LOG(LOG_MISC,LOG_NORMAL)("MPU-401: intelligent mode recording");
614+					if (!(mpu.state.rec==M_RECON)) {
615+						mpu.clock.rec_counter=0;
616+						mpu.state.rec=M_RECSTB;
617+					}
618+					if (mpu.state.last_rtcmd==0xfa || mpu.state.last_rtcmd==0xfb) {
619+						mpu.clock.rec_counter=0;
620+						mpu.state.rec=M_RECON;
621+						if (mpu.filter.prchg_mask) send_prchg=true;
622+						MPU401_StartClock();
623+					}
624+			}
625+ 		}
626+		MPU401_QueueByte(MSG_MPU_ACK);
627+		//record counter hack: needed by Prism, but sent only on cmd 0x20/0x26 (or breaks Ballade)
628+		Bit8u rec_cnt=mpu.clock.rec_counter;
629+		if ((val==0x20 || val==0x26) && mpu.state.rec==M_RECON) 
630+			MPU401_RecQueueBuffer(&rec_cnt,1,false);
631+
632+		if (send_prchg) for (Bitu i=0;i<16;i++)
633+			if (mpu.filter.prchg_mask&(1<<i)) {
634+				Bit8u recmsg[3]={mpu.clock.rec_counter,0xc0|i,mpu.filter.prchg_buf[i]};
635+				MPU401_RecQueueBuffer(recmsg,3,false);
636+				mpu.filter.prchg_mask&=~(1<<i);
637+			}
638+		SDL_mutexV(MPULock);
639+		return;
640+ 	}
641+ 	else if (val>=0xa0 && val<=0xa7) {	/* Request play counter */
642+		//if (mpu.state.cmask&(1<<(val&7)))
643+		MPU401_QueueByte(mpu.playbuf[val&7].counter);
644+ 	}
645+ 	else if (val>=0xd0 && val<=0xd7) {	/* Send data */
646+		mpu.state.old_track=mpu.state.track;
647+		mpu.state.track=val&7;
648+ 		mpu.state.wsd=true;
649+ 		mpu.state.wsm=false;
650+ 		mpu.state.wsd_start=true;
651+ 	}
652+	else if (val<0x80 && val>=0x40) { /* Set reference table channel */
653+		mpu.chanref[(val>>4)-4].on=true;
654+		mpu.chanref[(val>>4)-4].chan=val&0x0f;
655+		mpu.chanref[(val>>4)-4].trmask=0;
656+		for (Bitu i=0;i<4;i++) mpu.chanref[(val>>4)-4].key[i]=0;
657+		for (Bitu i=0;i<16;i++) if (mpu.ch_toref[i]==((val>>4)-4)) mpu.ch_toref[i]=4;
658+		mpu.ch_toref[val&0x0f]=(val>>4)-4;
659+	}
660+ 	else
661+ 	switch (val) {
662+		case 0x30: /* Configuration 0x30 - 0x39 */
663+			mpu.filter.allnotesoff_out=false;
664+			break;
665+		case 0x32:
666+			mpu.filter.rt_out=false;
667+ 			break;
668+		case 0x33:
669+			mpu.filter.all_thru=false;
670+			mpu.filter.commonmsgs_thru=false;
671+			mpu.filter.midi_thru=false;
672+			for (Bitu i=0;i<16;i++) {
673+				mpu.inputref[i].on=false;
674+				for (Bitu j=0;j<4;j++) mpu.inputref[i].key[j]=0;
675+			}
676+ 			break;
677+		case 0x34:
678+			mpu.filter.timing_in_stop=true;
679+ 			break;
680+		case 0x35:
681+			mpu.filter.modemsgs_in=true;
682+ 			break;
683+		case 0x37:
684+			mpu.filter.sysex_thru=true;
685 			break;
686-		case 0x8e:	/* Conductor */
687-			mpu.state.cond_set=false;
688+		case 0x38:
689+			mpu.filter.commonmsgs_in=true;
690 			break;
691-		case 0x8f:
692-			mpu.state.cond_set=true;
693+		case 0x39:
694+			mpu.filter.rt_in=true;
695 			break;
696+		case 0x3f:	/* UART mode */
697+			LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val);
698+			mpu.mode=M_UART;
699+			mpuhw.midi_thru=false;
700+ 			break;
701+		case 0x80:  /* Internal clock */
702+			if (mpu.clock.active && mpu.state.sync_in) {
703+				PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/(mpu.clock.freq));
704+				mpu.clock.freq_mod=1.0;
705+			}
706+			mpu.state.sync_in=false;
707+ 			break;
708+		case 0x82:  /* Sync to MIDI */
709+			mpu.clock.ticks_in=0;
710+			mpu.state.sync_in=true;
711+			break;
712+		case 0x86: case 0x87: /* Bender */
713+			mpu.filter.bender_in=bool(val&1);
714+			break;
715+		case 0x88: case 0x89:/* MIDI through */
716+			mpu.filter.midi_thru=bool(val&1);
717+			for (Bitu i=0;i<16;i++) {
718+				mpu.inputref[i].on=mpu.filter.midi_thru;
719+				if (!(val&1)) for (Bitu j=0;j<4;j++) mpu.inputref[i].key[j]=0;
720+			}
721+ 			break;
722+		case 0x8a: case 0x8b: /* Data in stop */
723+			mpu.filter.data_in_stop=bool(val&1);
724+ 			break;
725+		case 0x8c: case 0x8d: /* Send measure end */
726+			mpu.filter.rec_measure_end=bool(val&1);
727+ 			break;
728+		case 0x8e: case 0x8f: /* Conductor */
729+			mpu.state.cond_set=bool(val&1);
730+ 			break;
731+		case 0x90: case 0x91: /* Realtime affection */
732+			mpu.filter.rt_affection=bool(val&1);
733+ 			break;
734 		case 0x94: /* Clock to host */
735-			mpu.clock.clock_to_host=false;
736-			break;
737+			mpu.state.clock_to_host=false;
738+			MPU401_StopClock();
739+ 			break;
740 		case 0x95:
741-			mpu.clock.clock_to_host=true;
742-			break;
743-		case 0xc2: /* Internal timebase */
744-			mpu.clock.timebase=48;
745-			break;
746-		case 0xc3:
747-			mpu.clock.timebase=72;
748-			break;
749-		case 0xc4:
750-			mpu.clock.timebase=96;
751-			break;
752-		case 0xc5:
753-			mpu.clock.timebase=120;
754-			break;
755-		case 0xc6:
756-			mpu.clock.timebase=144;
757+			mpu.state.clock_to_host=true;
758+			MPU401_StartClock();
759 			break;
760-		case 0xc7:
761-			mpu.clock.timebase=168;
762-			break;
763-		case 0xc8:
764-			mpu.clock.timebase=192;
765-			break;
766-		/* Commands with data byte */
767-		case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: 
768-		case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef:
769-			mpu.state.command_byte=val;
770-			break;
771-		/* Commands 0xa# returning data */
772-		case 0xab:	/* Request and clear recording counter */
773-			QueueByte(MSG_MPU_ACK);
774-			QueueByte(0);
775-			return;
776-		case 0xac:	/* Request version */
777-			QueueByte(MSG_MPU_ACK);
778-			QueueByte(MPU401_VERSION);
779-			return;
780-		case 0xad:	/* Request revision */
781-			QueueByte(MSG_MPU_ACK);
782-			QueueByte(MPU401_REVISION);
783-			return;
784-		case 0xaf:	/* Request tempo */
785-			QueueByte(MSG_MPU_ACK);
786-			QueueByte(mpu.clock.tempo);
787-			return;
788-		case 0xb1:	/* Reset relative tempo */
789-            mpu.clock.old_tempo_rel=mpu.clock.tempo_rel;
790-            mpu.clock.tempo_rel=0x40;
791+		case 0x96: case 0x97: /* Sysex input allow */
792+			mpu.filter.sysex_in=bool(val&1);
793+			if (val&1) mpu.filter.sysex_thru=false;
794+			break;
795+		case 0x98:case 0x99:case 0x9a: case 0x9b: /* Reference tables on/off */ 
796+		case 0x9c:case 0x9d:case 0x9e: case 0x9f:
797+			mpu.chanref[(val-0x98)/2].on=bool(val&1);
798+ 			break;
799+ 		/* Commands 0xa# returning data */
800+ 		case 0xab:	/* Request and clear recording counter */
801+			MPU401_QueueByte(MSG_MPU_ACK);
802+			MPU401_QueueByte(0);
803+			SDL_mutexV(MPULock);
804+ 			return;
805+ 		case 0xac:	/* Request version */
806+			MPU401_QueueByte(MSG_MPU_ACK);
807+			MPU401_QueueByte(MPU401_VERSION);
808+			SDL_mutexV(MPULock);
809+ 			return;
810+ 		case 0xad:	/* Request revision */
811+			MPU401_QueueByte(MSG_MPU_ACK);
812+			MPU401_QueueByte(MPU401_REVISION);
813+			SDL_mutexV(MPULock);
814+ 			return;
815+ 		case 0xaf:	/* Request tempo */
816+			MPU401_QueueByte(MSG_MPU_ACK);
817+			MPU401_QueueByte(mpu.clock.tempo);
818+			SDL_mutexV(MPULock);
819+ 			return;
820+ 		case 0xb1:	/* Reset relative tempo */
821+			mpu.clock.tempo_rel=0x40;
822+ 			break;
823+ 		case 0xb8:	/* Clear play counters */
824+			mpu.state.last_rtcmd=0;
825+ 			for (Bitu i=0;i<8;i++) {
826+ 				mpu.playbuf[i].counter=0;
827+ 				mpu.playbuf[i].type=T_OVERFLOW;
828+ 			}
829+ 			mpu.condbuf.counter=0;
830+ 			mpu.condbuf.type=T_OVERFLOW;
831+
832+ 			mpu.state.amask=mpu.state.tmask;
833+			mpu.state.conductor=mpu.state.cond_set;
834+			mpu.clock.cth_counter=mpu.clock.cth_old=0;
835+			mpu.clock.measure_counter=mpu.clock.meas_old=0;
836 			break;
837 		case 0xb9:	/* Clear play map */
838-		case 0xb8:	/* Clear play counters */
839-			for (Bitu i=0xb0;i<0xbf;i++) {	/* All notes off */
840-				MIDI_RawOutByte(i);
841-				MIDI_RawOutByte(0x7b);
842-				MIDI_RawOutByte(0);
843-			}
844+			for (Bitu i=0;i<16;i++) MPU401_NotesOff(i);
845 			for (Bitu i=0;i<8;i++) {
846 				mpu.playbuf[i].counter=0;
847 				mpu.playbuf[i].type=T_OVERFLOW;
848 			}
849-			mpu.condbuf.counter=0;
850-			mpu.condbuf.type=T_OVERFLOW;
851-			if (!(mpu.state.conductor=mpu.state.cond_set)) mpu.state.cond_req=0;
852-			mpu.state.amask=mpu.state.tmask;
853-			mpu.state.req_mask=0;
854-			mpu.state.irq_pending=true;
855-			break;
856-		case 0xff:	/* Reset MPU-401 */
857-			LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",(int)val);
858-			PIC_AddEvent(MPU401_ResetDone,MPU401_RESETBUSY);
859-			mpu.state.reset=true;
860-			if (mpu.mode==M_UART) {
861-				MPU401_Reset();
862-				return;	//do not send ack in UART mode
863-			}
864-			MPU401_Reset();
865+			mpu.state.last_rtcmd=0;
866+			mpu.clock.cth_counter=mpu.clock.cth_old=0;
867+			mpu.clock.measure_counter=mpu.clock.meas_old=0;
868+			break;
869+		case 0xba: /* Clear record counter */
870+			mpu.clock.rec_counter=0;
871+			break;
872+		case 0xc2: case 0xc3: case 0xc4: /* Internal timebase */
873+		case 0xc5: case 0xc6: case 0xc7: case 0xc8:
874+			mpu.clock.timebase=MPUClockBase[val-0xc2];
875+			MPU401_ReCalcClock();
876 			break;
877-		case 0x3f:	/* UART mode */
878-			LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",(int)val);
879-			mpu.mode=M_UART;
880+		case 0xdf:	/* Send system message */
881+			mpu.state.wsd=false;
882+			mpu.state.wsm=true;
883+			mpu.state.wsd_start=true;
884 			break;
885-		default:;
886-			//LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val);
887-	}
888-	QueueByte(MSG_MPU_ACK);
889+		case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: /* Commands with data byte */
890+		case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef:
891+			mpu.state.command_byte=val;
892+ 			break;
893+ 		case 0xff:	/* Reset MPU-401 */
894+			LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset");
895+ 			if (CPU_Cycles > 5) { //It came from the desert wants a fast irq
896+ 				CPU_CycleLeft += CPU_Cycles;
897+ 				CPU_Cycles = 5;
898+ 			}
899+ 			MPU401_Reset();
900+ 			break;
901+ 		default:;
902+			//LOG(LOG_MISC,LOG_WARN)("MPU-401:Unhandled command %X",val);
903+ 	}
904+	MPU401_QueueByte(MSG_MPU_ACK);
905+	SDL_mutexV(MPULock);
906 }
907 
908 static Bitu MPU401_ReadData(Bitu port,Bitu iolen) {
909     	(void)iolen;//UNUSED
910     	(void)port;//UNUSED
911+	SDL_mutexP(MPULock);
912+
913 	Bit8u ret=MSG_MPU_ACK;
914 	if (mpu.queue_used) {
915 		if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE;
916 		ret=mpu.queue[mpu.queue_pos];
917 		mpu.queue_pos++;mpu.queue_used--;
918 	}
919-	if (!mpu.intelligent) return ret;
920-
921-	if (mpu.queue_used == 0) PIC_DeActivateIRQ(mpu.irq);
922+	if (mpu.mode==M_UART) {
923+		if (mpuhw.intelligent && !mpu.queue_used) PIC_DeActivateIRQ(mpuhw.irq);
924+		SDL_mutexV(MPULock);
925+		return ret;
926+	}
927+	if (mpu.state.rec_copy && !mpu.rec_queue_used) {
928+		mpu.state.rec_copy=false;
929+		MPU401_EOIHandler();
930+		SDL_mutexV(MPULock);
931+		//LOG(LOG_MISC,LOG_NORMAL)("MPU401:read data eoi %x", ret);
932+		return ret;
933+	}
934+
935+	//copy from recording buffer
936+	if (!mpu.queue_used && mpu.rec_queue_used) {
937+		mpu.state.rec_copy=true;
938+		if (mpu.rec_queue_pos>=MPU401_INPUT_QUEUE) mpu.rec_queue_pos-=MPU401_INPUT_QUEUE;
939+		MPU401_QueueByte(mpu.rec_queue[mpu.rec_queue_pos]);
940+		mpu.rec_queue_pos++;mpu.rec_queue_used--;
941+	}
942+	if (!mpu.queue_used) PIC_DeActivateIRQ(mpuhw.irq);
943 
944 	if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */
945-		mpu.state.channel=ret&7;
946+		mpu.state.track=ret&7;
947 		mpu.state.data_onoff=0;
948 		mpu.state.cond_req=false;
949+		mpu.state.track_req=true;
950 	}
951 	if (ret==MSG_MPU_COMMAND_REQ) {
952 		mpu.state.data_onoff=0;
953@@ -303,36 +587,50 @@ static Bitu MPU401_ReadData(Bitu port,Bi
954 			mpu.state.block_ack=true;
955 			MPU401_WriteCommand(0x331,mpu.condbuf.value[0],1);
956 			if (mpu.state.command_byte) MPU401_WriteData(0x330,mpu.condbuf.value[1],1);
957+			mpu.condbuf.type=T_OVERFLOW;
958 		}
959-	mpu.condbuf.type=T_OVERFLOW;
960 	}
961-	if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) {
962-		mpu.state.data_onoff=-1;
963+	if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK || ret==MSG_MPU_OVERFLOW)
964 		MPU401_EOIHandlerDispatch();
965 	}
966+	SDL_mutexV(MPULock);
967+	//LOG(LOG_MISC,LOG_NORMAL)("MPU401:read data %x", ret);
968 	return ret;
969 }
970 
971 static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) {
972     	(void)iolen;//UNUSED
973     	(void)port;//UNUSED
974-	if (mpu.mode==M_UART) {MIDI_RawOutByte(val);return;}
975+	//LOG(LOG_MISC,LOG_NORMAL)("MPU401:write data %x", val);
976+	if (mpu.mode==M_UART) {MIDI_RawOutByte(val,MOUT_MPU);return;}
977+	static Bitu length,cnt;
978+
979 	switch (mpu.state.command_byte) {	/* 0xe# command data */
980 		case 0x00:
981 			break;
982 		case 0xe0:	/* Set tempo */
983 			mpu.state.command_byte=0;
984-			mpu.clock.tempo=val;
985+			if (mpu.clock.tempo<8) mpu.clock.tempo=8;
986+			else if (mpu.clock.tempo>250) mpu.clock.tempo=250;
987+				else mpu.clock.tempo=val;
988+			MPU401_ReCalcClock();
989 			return;
990 		case 0xe1:	/* Set relative tempo */
991 			mpu.state.command_byte=0;
992             mpu.clock.old_tempo_rel=mpu.clock.tempo_rel;
993             mpu.clock.tempo_rel=val;
994-            if (val != 0x40) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Relative tempo change value 0x%x (%.3f)",(unsigned int)val,(double)val / 0x40);
995+			mpu.clock.tempo_rel=val;
996+			MPU401_ReCalcClock();
997+			return;
998+		case 0xe2:	/* Set gradation for relative tempo */
999+			mpu.clock.tempo_grad=val;
1000+			mpu.state.command_byte=0;
1001 			return;
1002 		case 0xe7:	/* Set internal clock to host interval */
1003 			mpu.state.command_byte=0;
1004-			mpu.clock.cth_rate=val>>2;
1005+			if (!val) val=64;
1006+			for (Bitu i=0;i<4;i++) mpu.clock.cth_rate[i]=(val>>2)+cth_data[(val&3)*4+i];
1007+			mpu.clock.cth_mode=0;
1008 			return;
1009 		case 0xec:	/* Set active track mask */
1010 			mpu.state.command_byte=0;
1011@@ -352,46 +650,46 @@ static void MPU401_WriteData(Bitu port,B
1012 			mpu.state.midi_mask&=0x00ff;
1013 			mpu.state.midi_mask|=((Bit16u)val)<<8;
1014 			return;
1015-		//case 0xe2:	/* Set graduation for relative tempo */
1016-		//case 0xe4:	/* Set metronome */
1017-		//case 0xe6:	/* Set metronome measure length */
1018 		default:
1019 			mpu.state.command_byte=0;
1020 			return;
1021 	}
1022-	static Bitu length,cnt,posd;
1023-	if (mpu.state.wsd) {	/* Directly send MIDI message */
1024+	if (mpu.state.wsd && !mpu.state.track_req && !mpu.state.cond_req) {	/* Directly send MIDI message */
1025 		if (mpu.state.wsd_start) {
1026 			mpu.state.wsd_start=0;
1027 			cnt=0;
1028-				switch (val&0xf0) {
1029-					case 0xc0:case 0xd0:
1030-						mpu.playbuf[mpu.state.channel].value[0]=val;
1031-						length=2;
1032-						break;
1033-					case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0:
1034-						mpu.playbuf[mpu.state.channel].value[0]=val;
1035-						length=3;
1036-						break;
1037-					case 0xf0:
1038-						LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal WSD byte");
1039-						mpu.state.wsd=0;
1040-						mpu.state.channel=mpu.state.old_chan;
1041-						return;
1042-					default: /* MIDI with running status */
1043-						cnt++;
1044-						MIDI_RawOutByte(mpu.playbuf[mpu.state.channel].value[0]);
1045-				}
1046+			switch (val&0xf0) {
1047+				case 0xc0:case 0xd0:
1048+					length=mpu.playbuf[mpu.state.track].length=2;
1049+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1050+					break;
1051+				case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0:
1052+					length=mpu.playbuf[mpu.state.track].length=3;
1053+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1054+					break;
1055+				case 0xf0:
1056+					LOG(LOG_MISC,LOG_WARN)("MPU-401:Illegal MIDI voice message: %x",val);
1057+					mpu.state.wsd=0;
1058+					mpu.state.track=mpu.state.old_track;
1059+					return;
1060+				default: /* MIDI with running status */
1061+					cnt++;
1062+					length=mpu.playbuf[mpu.state.track].length;
1063+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1064+			}
1065+		}
1066+		if (cnt<length) {
1067+			mpu.playbuf[mpu.state.track].value[cnt]=val;
1068+			cnt++;
1069 		}
1070-		if (cnt<length) {MIDI_RawOutByte(val);cnt++;}
1071 		if (cnt==length) {
1072+			MPU401_IntelligentOut(mpu.state.track);
1073 			mpu.state.wsd=0;
1074-			mpu.state.channel=mpu.state.old_chan;
1075+			mpu.state.track=mpu.state.old_track;
1076 		}
1077 		return;
1078 	}
1079-	if (mpu.state.wsm) {	/* Directly send system message */
1080-		if (val==MSG_EOX) {MIDI_RawOutByte(MSG_EOX);mpu.state.wsm=0;return;}
1081+	if (mpu.state.wsm && !mpu.state.track_req && !mpu.state.cond_req) {	/* Send system message */
1082 		if (mpu.state.wsd_start) {
1083 			mpu.state.wsd_start=0;
1084 			cnt=0;
1085@@ -401,24 +699,37 @@ static void MPU401_WriteData(Bitu port,B
1086 				case 0xf6:{ length=1; break;}
1087 				case 0xf0:{ length=0; break;}
1088 				default:
1089-					length=0;
1090+					LOG(LOG_MISC,LOG_WARN)
1091+					("MPU401:Illegal MIDI system common/exclusive message: %x",val);
1092+					mpu.state.wsm=0;
1093+					return;
1094 			}
1095+		} else if (val&0x80) {
1096+			MIDI_RawOutByte(MSG_EOX,MOUT_MPU);
1097+			mpu.state.wsm=0;
1098+			return;
1099+		}
1100+		if (!length || cnt<length) {
1101+			MIDI_RawOutByte(val,MOUT_MPU);
1102+			cnt++;
1103 		}
1104-		if (!length || cnt<length) {MIDI_RawOutByte(val);cnt++;}
1105 		if (cnt==length) mpu.state.wsm=0;
1106 		return;
1107 	}
1108+	SDL_mutexP(MPULock);
1109 	if (mpu.state.cond_req) { /* Command */
1110 		switch (mpu.state.data_onoff) {
1111 			case -1:
1112+				SDL_mutexV(MPULock);
1113 				return;
1114 			case  0: /* Timing byte */
1115-				mpu.condbuf.vlength=0;
1116+				mpu.condbuf.length=0;
1117 				if (val<0xf0) mpu.state.data_onoff++;
1118 				else {
1119+					mpu.state.cond_req=false;
1120 					mpu.state.data_onoff=-1;
1121 					MPU401_EOIHandlerDispatch();
1122-					return;
1123+					break;
1124 				}
1125 				if (val==0) mpu.state.send_now=true;
1126 				else mpu.state.send_now=false;
1127@@ -426,148 +737,203 @@ static void MPU401_WriteData(Bitu port,B
1128 				break;
1129 			case  1: /* Command byte #1 */
1130 				mpu.condbuf.type=T_COMMAND;
1131-				if (val==0xf8 || val==0xf9) mpu.condbuf.type=T_OVERFLOW;
1132-				mpu.condbuf.value[mpu.condbuf.vlength]=val;
1133-				mpu.condbuf.vlength++;
1134-				if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch();
1135+				if (val==0xf8 || val==0xf9 || val==0xfc) mpu.condbuf.type=T_OVERFLOW;
1136+				mpu.condbuf.value[mpu.condbuf.length]=val;
1137+				mpu.condbuf.length++;
1138+				if ((val&0xf0)!=0xe0) { //no cmd data byte
1139+					MPU401_EOIHandler();
1140+					mpu.state.data_onoff=-1;
1141+					mpu.state.cond_req=false;
1142+				}
1143 				else mpu.state.data_onoff++;
1144 				break;
1145 			case  2:/* Command byte #2 */
1146-				mpu.condbuf.value[mpu.condbuf.vlength]=val;
1147-				mpu.condbuf.vlength++;
1148+				mpu.condbuf.value[mpu.condbuf.length]=val;
1149+				mpu.condbuf.length++;
1150 				MPU401_EOIHandlerDispatch();
1151+				mpu.state.data_onoff=-1;
1152+				mpu.state.cond_req=false;
1153 				break;
1154 		}
1155+		SDL_mutexV(MPULock);
1156 		return;
1157 	}
1158 	switch (mpu.state.data_onoff) { /* Data */
1159 		case   -1:
1160-			return;
1161+			break;
1162 		case    0: /* Timing byte */
1163-			if (val<0xf0) mpu.state.data_onoff=1;
1164+			if (val<0xf0) mpu.state.data_onoff++;
1165 			else {
1166 				mpu.state.data_onoff=-1;
1167 				MPU401_EOIHandlerDispatch();
1168+				mpu.state.track_req=false;
1169+				SDL_mutexV(MPULock);
1170 				return;
1171 			}
1172 			if (val==0) mpu.state.send_now=true;
1173 			else mpu.state.send_now=false;
1174-			mpu.playbuf[mpu.state.channel].counter=(Bits)val;
1175+			mpu.playbuf[mpu.state.track].counter=val;
1176 			break;
1177-		case    1: /* MIDI */
1178-			mpu.playbuf[mpu.state.channel].vlength++;
1179-			posd=mpu.playbuf[mpu.state.channel].vlength;
1180-			if (posd==1) {
1181-				switch (val&0xf0) {
1182-					case 0xf0: /* System message or mark */
1183-						if (val>0xf7) {
1184-							mpu.playbuf[mpu.state.channel].type=T_MARK;
1185-							mpu.playbuf[mpu.state.channel].sys_val=val;
1186-							length=1;
1187-						} else {
1188-							LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message");
1189-							mpu.playbuf[mpu.state.channel].type=T_MIDI_SYS;
1190-							mpu.playbuf[mpu.state.channel].sys_val=val;
1191-							length=1;
1192-						}
1193-						break;
1194-					case 0xc0: case 0xd0: /* MIDI Message */
1195-						mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM;
1196-						length=mpu.playbuf[mpu.state.channel].length=2;
1197-						break;
1198-					case 0x80: case 0x90: case 0xa0:  case 0xb0: case 0xe0: 
1199-						mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM;
1200-						length=mpu.playbuf[mpu.state.channel].length=3;
1201-						break;
1202-					default: /* MIDI data with running status */
1203-						posd++;
1204-						mpu.playbuf[mpu.state.channel].vlength++;
1205-						mpu.playbuf[mpu.state.channel].type=T_MIDI_NORM;
1206-						length=mpu.playbuf[mpu.state.channel].length;
1207-						break;
1208+		case 1: /* MIDI */
1209+			cnt=0;
1210+			mpu.state.data_onoff++;
1211+			switch (val&0xf0) {
1212+				case 0xc0:case 0xd0:
1213+					length=mpu.playbuf[mpu.state.track].length=2;
1214+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1215+					break;
1216+				case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0:
1217+					length=mpu.playbuf[mpu.state.track].length=3;
1218+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1219+					break;
1220+				case 0xf0:
1221+					mpu.playbuf[mpu.state.track].sys_val=val;
1222+					if (val>0xf7) {
1223+						mpu.playbuf[mpu.state.track].type=T_MARK;
1224+						if (val==0xf9) mpu.clock.measure_counter=0;
1225+					} else {
1226+						LOG(LOG_MISC,LOG_WARN)("MPU-401:Illegal message");
1227+						mpu.playbuf[mpu.state.track].type=T_OVERFLOW;
1228+					}
1229+					mpu.state.data_onoff=-1;
1230+					MPU401_EOIHandler();
1231+					mpu.state.track_req=false;
1232+					SDL_mutexV(MPULock);
1233+					return;
1234+				default: /* MIDI with running status */
1235+					cnt++;
1236+					length=mpu.playbuf[mpu.state.track].length;
1237+					mpu.playbuf[mpu.state.track].type=T_MIDI_NORM;
1238 				}
1239+		case 2:
1240+			if (cnt<length) {
1241+				mpu.playbuf[mpu.state.track].value[cnt]=val;
1242+				cnt++;
1243+			}
1244+			if (cnt==length) {
1245+				mpu.state.data_onoff=-1;
1246+				mpu.state.track_req=false;
1247+				MPU401_EOIHandlerDispatch();
1248 			}
1249-			if (!(posd==1 && val>=0xf0)) mpu.playbuf[mpu.state.channel].value[posd-1]=val;
1250-			if (posd==length) MPU401_EOIHandlerDispatch();
1251+			break;
1252 	}
1253+	SDL_mutexV(MPULock);
1254+	return;
1255 }
1256 
1257-static void MPU401_IntelligentOut(Bit8u chan) {
1258-	Bitu val;
1259-	switch (mpu.playbuf[chan].type) {
1260+static void MPU401_IntelligentOut(Bitu track) {
1261+	Bitu chan,chrefnum;
1262+	Bit8u key,msg;
1263+	bool send,retrigger;
1264+	switch (mpu.playbuf[track].type) {
1265 		case T_OVERFLOW:
1266 			break;
1267 		case T_MARK:
1268-			val=mpu.playbuf[chan].sys_val;
1269-			if (val==0xfc) {
1270-				MIDI_RawOutByte(val);
1271-				mpu.state.amask&=~(1<<chan);
1272-				mpu.state.req_mask&=~(1<<chan);
1273+			if (mpu.playbuf[track].sys_val==0xfc) {
1274+				MIDI_RawOutRTByte(mpu.playbuf[track].sys_val);
1275+				mpu.state.amask&=~(1<<track);
1276 			}
1277 			break;
1278 		case T_MIDI_NORM:
1279-			for (Bitu i=0;i<mpu.playbuf[chan].vlength;i++)
1280-				MIDI_RawOutByte(mpu.playbuf[chan].value[i]);
1281-			break;
1282-		default:
1283-			break;
1284+				chan=mpu.playbuf[track].value[0]&0xf;
1285+				key=mpu.playbuf[track].value[1]&0x7f;
1286+				chrefnum=mpu.ch_toref[chan];
1287+				send=true;
1288+				retrigger=false;
1289+			switch (msg=mpu.playbuf[track].value[0]&0xf0) {
1290+				case 0x80: //note off
1291+					if (mpu.inputref[chan].on && (mpu.inputref[chan].M_GETKEY)) send=false;
1292+					if (mpu.chanref[chrefnum].on && (!mpu.chanref[chrefnum].M_GETKEY)) send=false;
1293+					mpu.chanref[chrefnum].M_DELKEY;
1294+					break;
1295+				case 0x90: //note on
1296+					if (mpu.inputref[chan].on && (mpu.inputref[chan].M_GETKEY)) retrigger=true;
1297+					if (mpu.chanref[chrefnum].on && (mpu.chanref[chrefnum].M_GETKEY)) retrigger=true;
1298+					mpu.chanref[chrefnum].M_SETKEY;
1299+					break;
1300+				case 0xb0:			
1301+					if (mpu.playbuf[track].value[1]==123) {/* All notes off */
1302+						MPU401_NotesOff(mpu.playbuf[track].value[0]&0xf);
1303+						return;
1304+					}
1305+					break;
1306+			}
1307+			if (retrigger) {
1308+					MIDI_RawOutByte(0x80|chan,MOUT_MPU);
1309+					MIDI_RawOutByte(key,MOUT_MPU);
1310+					MIDI_RawOutByte(0,MOUT_MPU);
1311+			}
1312+			if (send) for (Bitu i=0;i<mpu.playbuf[track].length;i++)
1313+					MIDI_RawOutByte(mpu.playbuf[track].value[i],MOUT_MPU);
1314 	}
1315 }
1316 
1317-static void UpdateTrack(Bit8u chan) {
1318-	MPU401_IntelligentOut(chan);
1319-	if (mpu.state.amask&(1<<chan)) {
1320-		mpu.playbuf[chan].vlength=0;
1321-		mpu.playbuf[chan].type=T_OVERFLOW;
1322-		mpu.playbuf[chan].counter=0xf0;
1323-		mpu.state.req_mask|=(1<<chan);
1324+static void UpdateTrack(Bit8u track) {
1325+	MPU401_IntelligentOut(track);
1326+	if (mpu.state.amask&(1<<track)) {
1327+		mpu.playbuf[track].type=T_OVERFLOW;
1328+		mpu.playbuf[track].counter=0xf0;
1329+		mpu.state.req_mask|=(1<<track);
1330 	} else {
1331 		if (mpu.state.amask==0 && !mpu.state.conductor) mpu.state.req_mask|=(1<<12);
1332 	}
1333 }
1334 
1335-static void UpdateConductor(void) {
1336-    	for (unsigned int i=0;i < mpu.condbuf.vlength;i++) {
1337-        	if (mpu.condbuf.value[i] == 0xfc) {
1338-        	    mpu.condbuf.value[i] = 0;
1339-            	    mpu.state.conductor=false;
1340-            	    mpu.state.req_mask&=~(1<<9);
1341-            	    if (mpu.state.amask==0) mpu.state.req_mask|=(1<<12);
1342-            		return;
1343-        	}
1344-    	}
1345-
1346-	mpu.condbuf.vlength=0;
1347-	mpu.condbuf.counter=0xf0;
1348-	mpu.state.req_mask|=(1<<9);
1349-}
1350-
1351 static void MPU401_Event(Bitu val) {
1352 	(void)val;//UNUSED
1353 	if (mpu.mode==M_UART) return;
1354 	if (mpu.state.irq_pending) goto next_event;
1355-	for (Bitu i=0;i<8;i++) { /* Decrease counters */
1356-		if (mpu.state.amask&(1<<i)) {
1357-			mpu.playbuf[i].counter--;
1358-			if (mpu.playbuf[i].counter<=0) UpdateTrack(i);
1359-		}
1360-	}		
1361-	if (mpu.state.conductor) {
1362-		mpu.condbuf.counter--;
1363-		if (mpu.condbuf.counter<=0) UpdateConductor();
1364+	if (mpu.state.playing) {
1365+		for (Bitu i=0;i<8;i++) { /* Decrease counters */
1366+			if (mpu.state.amask&(1<<i)) {
1367+				mpu.playbuf[i].counter--;
1368+				if (mpu.playbuf[i].counter<=0) UpdateTrack(i);
1369+			}
1370+		}
1371+		if (mpu.state.conductor) {
1372+			mpu.condbuf.counter--;
1373+			if (mpu.condbuf.counter<=0) {
1374+					mpu.condbuf.counter=0xf0;
1375+					mpu.state.req_mask|=(1<<9);
1376+			}
1377+		}
1378 	}
1379-	if (mpu.clock.clock_to_host) {
1380+	if (mpu.state.clock_to_host) {
1381 		mpu.clock.cth_counter++;
1382-		if (mpu.clock.cth_counter >= mpu.clock.cth_rate) {
1383+		if (mpu.clock.cth_counter >= mpu.clock.cth_rate[mpu.clock.cth_mode]) {
1384 			mpu.clock.cth_counter=0;
1385+			mpu.clock.cth_mode=(++mpu.clock.cth_mode)%4;
1386 			mpu.state.req_mask|=(1<<13);
1387 		}
1388 	}
1389-	if (!mpu.state.irq_pending && mpu.state.req_mask) MPU401_EOIHandler();
1390+	if (mpu.state.rec==M_RECON) { //recording
1391+		mpu.clock.rec_counter++;
1392+		if (mpu.clock.rec_counter>=240) {
1393+			mpu.clock.rec_counter=0;
1394+			mpu.state.req_mask|=(1<<8);
1395+		}
1396+	}
1397+	bool accented;
1398+	if (mpu.state.playing || mpu.state.rec==M_RECON) {
1399+		accented=false;
1400+		Bits max_meascnt = (mpu.clock.timebase*mpu.clock.midimetro*mpu.clock.metromeas)/24;
1401+		if (max_meascnt!=0) { //measure end
1402+			if (++mpu.clock.measure_counter>=max_meascnt) {
1403+				if (mpu.filter.rt_out) MIDI_RawOutRTByte(0xf8);
1404+				mpu.clock.measure_counter=0;
1405+				if (mpu.filter.rec_measure_end && mpu.state.rec==M_RECON) 
1406+					mpu.state.req_mask|=(1<<12);
1407+			}
1408+		}
1409+	}
1410+	if (!mpu.state.irq_pending && mpu.state.req_mask) {
1411+		SDL_mutexP(MPULock);
1412+		MPU401_EOIHandler();
1413+		SDL_mutexV(MPULock);
1414+	}
1415 next_event:
1416-	Bitu new_time;
1417-	if ((new_time=(Bitu)((mpu.clock.tempo*mpu.clock.timebase*mpu.clock.tempo_rel)/0x40))==0) return;
1418-	PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/new_time);
1419+	MPU401_RunClock();
1420+	if (mpu.state.sync_in) mpu.clock.ticks_in++;
1421 }
1422 
1423 
1424@@ -585,15 +951,19 @@ static void MPU401_EOIHandler(Bitu val)
1425 	mpu.state.eoi_scheduled=false;
1426 	if (mpu.state.send_now) {
1427 		mpu.state.send_now=false;
1428-		if (mpu.state.cond_req) UpdateConductor();
1429-		else UpdateTrack(mpu.state.channel);
1430+		if (mpu.state.cond_req) {
1431+				mpu.condbuf.counter=0xf0;
1432+				mpu.state.req_mask|=(1<<9);
1433+		}
1434+		else UpdateTrack(mpu.state.track);
1435 	}
1436+	if (mpu.state.rec_copy || !mpu.state.sysex_in_finished) return;
1437 	mpu.state.irq_pending=false;
1438-	if (!mpu.state.playing || !mpu.state.req_mask) return;
1439+	if (!(mpu.state.req_mask && mpu.clock.active)) return;
1440 	Bitu i=0;
1441 	do {
1442 		if (mpu.state.req_mask&(1<<i)) {
1443-			QueueByte(0xf0+i);
1444+			MPU401_QueueByte(0xf0+i);
1445 			mpu.state.req_mask&=~(1<<i);
1446 			break;
1447 		}
1448@@ -607,43 +977,287 @@ static void MPU401_ResetDone(Bitu) {
1449 		mpu.state.cmd_pending=0;
1450 	}
1451 }
1452+
1453+static INLINE void MPU401_NotesOff(Bitu i) {
1454+	if (mpu.filter.allnotesoff_out && !(mpu.inputref[i].on &&
1455+		(mpu.inputref[i].key[0]|mpu.inputref[i].key[1]|
1456+		mpu.inputref[i].key[2]|mpu.inputref[i].key[3]))) {
1457+		for (Bitu j=0;j<4;j++) mpu.chanref[mpu.ch_toref[i]].key[j]=0;
1458+		//if (mpu.chanref[mpu.ch_toref[i]].on) {
1459+		MIDI_RawOutByte(0xb0|i,MOUT_MPU);
1460+		MIDI_RawOutByte(123,MOUT_MPU);
1461+		MIDI_RawOutByte(0,MOUT_MPU);
1462+	}
1463+	else if (mpu.chanref[mpu.ch_toref[i]].on) 
1464+			for (Bitu key=0;key<128;key++) {
1465+				if ((mpu.chanref[mpu.ch_toref[i]].M_GETKEY) &&
1466+					!(mpu.inputref[i].on && (mpu.inputref[i].M_GETKEY))) {
1467+					MIDI_RawOutByte(0x80|i,MOUT_MPU);
1468+					MIDI_RawOutByte(key,MOUT_MPU);
1469+					MIDI_RawOutByte(0,MOUT_MPU);
1470+				}
1471+			mpu.chanref[mpu.ch_toref[i]].M_DELKEY;
1472+		}
1473+}
1474+
1475+//Input handler for SysEx
1476+Bits MPU401_InputSysex(Bit8u* buffer,Bitu len,bool abort) {
1477+	if (mpu.filter.sysex_in) {
1478+		if (abort) {
1479+			mpu.state.sysex_in_finished=true;
1480+			mpu.rec_queue_used=0;//reset also the input queue
1481+			return 0;
1482+		}
1483+		if (mpu.state.sysex_in_finished) {
1484+			if (mpu.rec_queue_used>=MPU401_INPUT_QUEUE) return len;
1485+			Bit8u val_ff=0xff;
1486+			MPU401_RecQueueBuffer(&val_ff,1,true);
1487+			mpu.state.sysex_in_finished=false;
1488+			mpu.clock.rec_counter=0;
1489+		}
1490+		if (mpu.rec_queue_used>=MPU401_INPUT_QUEUE) return len;
1491+		Bitu available=MPU401_INPUT_QUEUE-mpu.rec_queue_used;
1492+
1493+		if (available>=len) {
1494+			MPU401_RecQueueBuffer(buffer,len,true);
1495+			return 0;
1496+		}
1497+		else {
1498+			MPU401_RecQueueBuffer(buffer,available,true);
1499+			if (mpu.state.sysex_in_finished) return 0;
1500+			return (len-available);
1501+		}
1502+	}
1503+	else if (mpu.filter.sysex_thru && mpuhw.midi_thru) {
1504+		MIDI_RawOutByte(0xf0,MOUT_THRU);
1505+		for (Bitu i=0;i<len;i++) MIDI_RawOutByte(*(buffer+i),MOUT_THRU);
1506+	}
1507+	return 0;
1508+}
1509+
1510+//Input handler for MIDI
1511+void MPU401_InputMsg(Bit8u msg[4]) {
1512+	//abort if sysex transfer is in progress
1513+	if (!mpu.state.sysex_in_finished) return;
1514+	static Bit8u old_msg=0;
1515+	Bit8u len=msg[3];
1516+	bool send=true;
1517+	bool send_thru=false;
1518+	bool retrigger_thru=false;
1519+	bool midistatus=false;
1520+	if (mpu.mode==M_INTELLIGENT) {
1521+		if (msg[0]<0x80) {			// Expand running status
1522+			midistatus=true;
1523+			msg[2]=msg[1];msg[1]=msg[0];msg[0]=old_msg;
1524+		}
1525+		old_msg=msg[0];
1526+		Bitu chan=msg[0]&0xf;
1527+		Bitu chrefnum=mpu.ch_toref[chan];
1528+		Bit8u key=msg[1]&0x7f;
1529+		if (msg[0]<0xf0) { //if non-system msg
1530+			if (!(mpu.state.midi_mask&(1<<chan)) && mpu.filter.all_thru) send_thru=true;
1531+			else if (mpu.filter.midi_thru) send_thru=true;
1532+			switch (msg[0]&0xf0) {
1533+				case 0x80: //note off
1534+					if (send_thru) {
1535+						if (mpu.chanref[chrefnum].on && (mpu.chanref[chrefnum].M_GETKEY))
1536+							send_thru=false;
1537+						if (!mpu.filter.midi_thru) break;
1538+						if  (!(mpu.inputref[chan].M_GETKEY)) send_thru=false;
1539+						 mpu.inputref[chan].M_DELKEY;
1540+					}
1541+					break;
1542+				case 0x90: //note on
1543+					if (send_thru) {
1544+						if (mpu.chanref[chrefnum].on && (mpu.chanref[chrefnum].M_GETKEY))
1545+							retrigger_thru=true;
1546+						if (!mpu.filter.midi_thru) break;
1547+						if (mpu.inputref[chan].M_GETKEY) retrigger_thru=true;
1548+						mpu.inputref[chan].M_SETKEY;
1549+					}
1550+					break;
1551+				case 0xb0:
1552+					if (msg[1]>=120) {
1553+						send_thru=false;
1554+						if (msg[1]==123)  /* All notes off */
1555+							for (key=0;key<128;key++) {
1556+								if (!(mpu.chanref[chrefnum].on && (mpu.chanref[chrefnum].M_GETKEY)))
1557+									if (mpu.inputref[chan].on && mpu.inputref[chan].M_GETKEY) {
1558+										MIDI_RawOutByte(0x80|chan,MOUT_THRU);
1559+										MIDI_RawOutByte(key,MOUT_THRU);
1560+										MIDI_RawOutByte(0,MOUT_THRU);
1561+									}
1562+								mpu.inputref[chan].M_DELKEY;
1563+							}
1564+					}
1565+					break;
1566+			}
1567+		}
1568+		if (msg[0]>=0xf0 || (mpu.state.midi_mask&(1<<chan)))
1569+			switch (msg[0]&0xf0) {
1570+				case 0xa0: //aftertouch
1571+					if (!mpu.filter.bender_in) send=false;
1572+					break;
1573+				case 0xb0: //control change
1574+					if (!mpu.filter.bender_in && msg[1]<64) send=false;
1575+					if (msg[1]>=120) if (mpu.filter.modemsgs_in) send=true;
1576+					break;
1577+				case 0xc0: //program change
1578+					if (mpu.state.rec!=M_RECON && !mpu.filter.data_in_stop) {
1579+							mpu.filter.prchg_buf[chan]=msg[1];
1580+							mpu.filter.prchg_mask|=1<<chan;
1581+						}
1582+					break;
1583+				case 0xd0: //ch pressure
1584+				case 0xe0: //pitch wheel
1585+					if (!mpu.filter.bender_in) send=false;
1586+					break;
1587+				case 0xf0: //system message
1588+					if (msg[0]==0xf8) {
1589+						send=false;
1590+						if (mpu.clock.active && mpu.state.sync_in) {
1591+							send = false;//don't pass to host in this mode?
1592+							Bits tick=mpu.clock.timebase/24;
1593+							if (mpu.clock.ticks_in!=tick) {
1594+								if (!mpu.clock.ticks_in || mpu.clock.ticks_in>tick*2) mpu.clock.freq_mod*=2.0;
1595+								else {
1596+									if (abs(mpu.clock.ticks_in-tick)==1)
1597+										mpu.clock.freq_mod/=mpu.clock.ticks_in/float(tick*2);
1598+									else
1599+										mpu.clock.freq_mod/=mpu.clock.ticks_in/float(tick);
1600+								}
1601+								MPU401_ReCalcClock();
1602+							}
1603+							mpu.clock.ticks_in=0;
1604+						}
1605+					}
1606+					else if (msg[0]>0xf8) { //realtime
1607+						if (!(mpu.filter.rt_in && msg[0]<=0xfc && msg[0]>=0xfa)) {
1608+							Bit8u recdata[2]={0xff,msg[0]};
1609+							MPU401_RecQueueBuffer(recdata,2,true);
1610+							send=false;
1611+						}
1612+					}
1613+					else { //common or system
1614+						send=false;
1615+						if (msg[0]==0xf2 || msg[0]==0xf3 || msg[0]==0xf6) {
1616+							if (mpu.filter.commonmsgs_in) send=true;
1617+							if (mpu.filter.commonmsgs_thru) 
1618+								for (Bitu i=0;i<len;i++) MIDI_RawOutByte(msg[i],MOUT_THRU);
1619+						}
1620+					}
1621+					if (send) {
1622+						Bit8u recmsg[4]={0xff,msg[0],msg[1],msg[2]};
1623+						MPU401_RecQueueBuffer(recmsg,len+1,true);
1624+					}
1625+					if (mpu.filter.rt_affection) switch(msg[0]) {
1626+						case 0xf2:case 0xf3:
1627+							mpu.state.block_ack=true;
1628+							MPU401_WriteCommand(0x331,0xb8,1);//clear play counters
1629+							break;
1630+						case 0xfa:
1631+							mpu.state.block_ack=true;
1632+							MPU401_WriteCommand(0x331,0xa,1);//start,play
1633+							if (mpu.filter.rt_out) MIDI_RawOutThruRTByte(msg[0]);
1634+							break;
1635+						case 0xfb:
1636+							mpu.state.block_ack=true;
1637+							MPU401_WriteCommand(0x331,0xb,1);//continue,play
1638+							if (mpu.filter.rt_out) MIDI_RawOutThruRTByte(msg[0]);
1639+							break;
1640+						case 0xfc:
1641+							mpu.state.block_ack=true;
1642+							MPU401_WriteCommand(0x331,0xd,1);//stop: play,rec,midi
1643+							if (mpu.filter.rt_out) MIDI_RawOutThruRTByte(msg[0]);
1644+							break;
1645+					}
1646+					return;
1647+			}
1648+		if (send_thru && mpuhw.midi_thru) {
1649+			if (retrigger_thru) {
1650+				MIDI_RawOutByte(0x80|(msg[0]&0xf),MOUT_THRU);
1651+				MIDI_RawOutByte(msg[1],MOUT_THRU);
1652+				MIDI_RawOutByte(msg[2],MOUT_THRU);
1653+			}
1654+			for (Bitu i=0/*((midistatus && !retrigger_thru)? 1:0)*/;i<len;i++) 
1655+				MIDI_RawOutByte(msg[i],MOUT_THRU);
1656+		}
1657+		if (send) {
1658+			if (mpu.state.rec==M_RECON) {
1659+				Bit8u recmsg[4]={mpu.clock.rec_counter,msg[0],msg[1],msg[2]};
1660+				MPU401_RecQueueBuffer(recmsg,len+1,true);
1661+				mpu.clock.rec_counter=0;
1662+			}
1663+			else if (mpu.filter.data_in_stop) {
1664+				if (mpu.filter.timing_in_stop) {
1665+					Bit8u recmsg[4]={0,msg[0],msg[1],msg[2]};
1666+					MPU401_RecQueueBuffer(recmsg,len+1,true);
1667+				}
1668+				else {
1669+					Bit8u recmsg[4]={msg[0],msg[1],msg[2],0};
1670+					MPU401_RecQueueBuffer(recmsg,len,true);
1671+				}
1672+			}
1673+		}
1674+		return;
1675+	}
1676+	//UART mode input
1677+	for (Bitu i=0;i<len;i++) MPU401_QueueByte(msg[i]);
1678+}
1679+
1680 static void MPU401_Reset(void) {
1681-	PIC_DeActivateIRQ(mpu.irq);
1682-	mpu.mode=(mpu.intelligent ? M_INTELLIGENT : M_UART);
1683 	PIC_RemoveEvents(MPU401_EOIHandler);
1684 	mpu.state.eoi_scheduled=false;
1685-	mpu.state.wsd=false;
1686-	mpu.state.wsm=false;
1687-	mpu.state.conductor=false;
1688-	mpu.state.cond_req=false;
1689-	mpu.state.cond_set=false;
1690-	mpu.state.playing=false;
1691-	mpu.state.run_irq=false;
1692+	PIC_DeActivateIRQ(mpuhw.irq);
1693 	mpu.state.irq_pending=false;
1694-	mpu.state.cmask=0xff;
1695-	mpu.state.amask=mpu.state.tmask=0;
1696+	memset(&mpu,0,sizeof(mpu));
1697+	mpu.mode=(mpuhw.intelligent ? M_INTELLIGENT : M_UART);
1698+	mpuhw.midi_thru=false;
1699+	mpu.state.rec=M_RECOFF;
1700 	mpu.state.midi_mask=0xffff;
1701-	mpu.state.data_onoff=0;
1702-	mpu.state.command_byte=0;
1703-	mpu.state.block_ack=false;
1704 	mpu.clock.tempo=mpu.clock.old_tempo=100;
1705 	mpu.clock.timebase=mpu.clock.old_timebase=120;
1706 	mpu.clock.tempo_rel=mpu.clock.old_tempo_rel=0x40;
1707-	mpu.clock.tempo_grad=0;
1708-	mpu.clock.clock_to_host=false;
1709-	mpu.clock.cth_rate=60;
1710-	mpu.clock.cth_counter=0;
1711-	ClrQueue();
1712-	mpu.state.req_mask=0;
1713-	mpu.condbuf.counter=0;
1714+	mpu.clock.freq_mod=1.0;
1715+	MPU401_StopClock();
1716+	MPU401_ReCalcClock();
1717+	for (Bitu i=0;i<4;i++) mpu.clock.cth_rate[i]=60;
1718+	mpu.clock.midimetro=12;
1719+	mpu.clock.metromeas=8;
1720+	mpu.filter.rec_measure_end=true;
1721+	mpu.filter.rt_out=true;
1722+	mpu.filter.rt_affection=true;
1723+	mpu.filter.allnotesoff_out=true;
1724+	mpu.filter.all_thru=true;
1725+	mpu.filter.midi_thru=true;
1726+	mpu.filter.commonmsgs_thru=true;
1727+	//reset channel reference and input tables
1728+	for (Bitu i=0;i<4;i++) {
1729+		mpu.chanref[i].on=true;
1730+		mpu.chanref[i].chan=i;
1731+		mpu.ch_toref[i]=i;
1732+	}
1733+	for (Bitu i=0;i<16;i++) {
1734+		mpu.inputref[i].on=true;
1735+		mpu.inputref[i].chan=i;
1736+		if (i>3) mpu.ch_toref[i]=4;//dummy reftable
1737+	}
1738+	MPU401_ClrQueue();
1739+	mpu.state.data_onoff=-1;
1740 	mpu.condbuf.type=T_OVERFLOW;
1741-	for (Bitu i=0;i<8;i++) {mpu.playbuf[i].type=T_OVERFLOW;mpu.playbuf[i].counter=0;}
1742+	for (Bitu i=0;i<8;i++) mpu.playbuf[i].type=T_OVERFLOW;
1743+	//clear MIDI buffers, terminate notes
1744+	MIDI_ClearBuffer(MOUT_MPU);
1745+	MIDI_ClearBuffer(MOUT_THRU);
1746+	for (Bitu i=0xb0;i<=0xbf;i++){
1747+		MIDI_RawOutByte(i,MOUT_MPU);
1748+		MIDI_RawOutByte(0x7b,MOUT_MPU);
1749+		MIDI_RawOutByte(0,MOUT_MPU);
1750+	}
1751 }
1752 
1753 class MPU401:public Module_base{
1754 private:
1755-	IO_ReadHandleObject ReadHandler[2];
1756-	IO_WriteHandleObject WriteHandler[2];
1757 	bool installed; /*as it can fail to install by 2 ways (config and no midi)*/
1758 public:
1759 	MPU401(Section* configuration):Module_base(configuration){
1760@@ -657,28 +1271,34 @@ public:
1761 		/*Enabled and there is a Midi */
1762 		installed = true;
1763 		
1764-		WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB);
1765-		WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB);
1766-		ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB);
1767-		ReadHandler[1].Install(0x331,&MPU401_ReadStatus,IO_MB);
1768+		MPULock=SDL_CreateMutex();
1769+
1770+		mpuhw.WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB);
1771+		mpuhw.WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB);
1772+		mpuhw.ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB);
1773+		mpuhw.ReadHandler[1].Install(0x331,&MPU401_ReadStatus,IO_MB);
1774 	
1775 		mpu.queue_used=0;
1776 		mpu.queue_pos=0;
1777+		mpu.state.irq_pending=false;
1778 		mpu.mode=M_UART;
1779-		mpu.irq=9;	/* Princess Maker 2 wants it on irq 9 */
1780+		mpuhw.irq=9;	/* Princess Maker 2 wants it on irq 9 */
1781 
1782-		mpu.intelligent = true;	//Default is on
1783-		if(strcasecmp(s_mpu,"uart") == 0) mpu.intelligent = false;
1784-		if (!mpu.intelligent) return;
1785+		mpuhw.intelligent = true;	//Default is on
1786+		if(strcasecmp(s_mpu,"uart") == 0) mpuhw.intelligent = false;
1787+		if (!mpuhw.intelligent) return;
1788 		/*Set IRQ and unmask it(for timequest/princess maker 2) */
1789-		PIC_SetIRQMask(mpu.irq,false);
1790+		PIC_SetIRQMask(mpuhw.irq,false);
1791 		MPU401_Reset();
1792 	}
1793 	~MPU401(){
1794 		if(!installed) return;
1795+		PIC_RemoveEvents(MPU401_Event);
1796+		SDL_DestroyMutex(MPULock);
1797+		MPULock=0;
1798 		Section_prop * section=static_cast<Section_prop *>(m_configuration);
1799 		if(strcasecmp(section->Get_string("mpu401"),"intelligent")) return;
1800-		PIC_SetIRQMask(mpu.irq,true);
1801+		PIC_SetIRQMask(mpuhw.irq,true);
1802 		}
1803 };
1804