Index: emu/all.h
===================================================================
--- emu/all.h	(revision 77d8df82f5dfc0eadc7b81c42db2c4f4773a428d)
+++ emu/all.h	(revision 9ddbf3e3b93004ac7df85a6f7d2ae557d8dac5a9)
@@ -30,4 +30,15 @@
 #include <SDL2/SDL_net.h>
 #include <SDL2/SDL_ttf.h>
+
+// work around RtMidi's C++-isms
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+
+typedef struct RtMidiWrapper RtMidiWrapper;
+
+#include <rtmidi/rtmidi_c.h>
+
+#pragma GCC diagnostic pop
 
 #define inf(...) SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__);
@@ -65,4 +76,6 @@
 extern const char *font;
 
+extern int32_t mid_port;
+
 extern SDL_atomic_t run;
 
@@ -70,6 +83,4 @@
 extern uint32_t ser_win;
 extern uint32_t lcd_win;
-
-extern uint32_t mid_port;
 
 extern void sdl_init(void);
Index: emu/main.c
===================================================================
--- emu/main.c	(revision 77d8df82f5dfc0eadc7b81c42db2c4f4773a428d)
+++ emu/main.c	(revision 9ddbf3e3b93004ac7df85a6f7d2ae557d8dac5a9)
@@ -43,12 +43,13 @@
 const char *font = "ttf/vera-sans-mono.ttf";
 
+int32_t mid_port = -1;
+
 SDL_atomic_t run;
 
-uint32_t mid_port = 0;
-
 static void usage(FILE *fh)
 {
-	fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk] [-f font] [-m midiport] \n");
-	fprintf(fh, "where comp is one of: ");
+	fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk] [-f font] [-m port]\n");
+	fprintf(fh, "with\n");
+	fprintf(fh, "  comp - one of: ");
 
 	for (int32_t i = 0; i < ARRAY_COUNT(verb_flags); ++i) {
@@ -57,6 +58,9 @@
 
 	fprintf(fh, "all\n");
-	fprintf(fh, "and midiport is the number of the desired MIDI port\n");
-	fprintf(fh, "list all available MIDI ports with: buchla [-m list]\n");
+	fprintf(fh, "  bios - BIOS ROM file (default: bios.abs)\n");
+	fprintf(fh, "  disk - disk image file (default: buchla.disk)\n");
+	fprintf(fh, "  font - console and LCD font (default: ttf/vera-sans-mono.ttf)\n");
+	fprintf(fh, "  port - number of the desired MIDI port (default: 0)\n");
+	fprintf(fh, "         \"list\" instead of a port number lists available ports\n");
 }
 
@@ -145,9 +149,16 @@
 				mid_list();
 				exit(0);
-				continue;
-			}
-
-			// TODO: Assign midi port number
-			 mid_port = (uint32_t) atoi(argv[i]);
+			}
+
+			char *end;
+			int64_t tmp = strtol(argv[i], &end, 10);
+
+			if (*end != 0 || tmp < 0 || tmp > 15) {
+				usage(stderr);
+				fprintf(stderr, "invalid argument to -m: %s\n", argv[i]);
+				exit(1);
+			}
+
+			mid_port = (int32_t)tmp;
 			continue;
 		}
Index: emu/mid.c
===================================================================
--- emu/mid.c	(revision 77d8df82f5dfc0eadc7b81c42db2c4f4773a428d)
+++ emu/mid.c	(revision 9ddbf3e3b93004ac7df85a6f7d2ae557d8dac5a9)
@@ -1,4 +1,4 @@
 /*
- *  Copyright (C) 2017 The Contributors
+ *  Copyright (C) 2017-2018 The Contributors
  *
  *  This program is free software: you can redistribute it and/or modify
@@ -17,9 +17,10 @@
 
 #include <all.h>
-#include <rtmidi/rtmidi_c.h>
 
 #define ver(...) _ver(mid_verbose, 0, __VA_ARGS__)
 #define ver2(...) _ver(mid_verbose, 1, __VA_ARGS__)
 #define ver3(...) _ver(mid_verbose, 2, __VA_ARGS__)
+
+int32_t mid_verbose = 0;
 
 #define REG_IER_ISR 0
@@ -45,7 +46,5 @@
 };
 
-int32_t mid_verbose = 0;
-
-struct RtMidiWrapper* mid_in;
+static struct RtMidiWrapper *mid_in = NULL;
 
 static void xmit(int32_t un)
@@ -74,6 +73,10 @@
 }
 
-static void out_lk(int32_t un, uint8_t c)
-{
+static void out(int32_t un, uint8_t c)
+{
+	if (SDL_LockMutex(cpu_mutex) < 0) {
+		fail("SDL_LockMutex() failed: %s", SDL_GetError());
+	}
+
 	int32_t i = state[un].buf_hd;
 	ver2("mid out %d %d 0x%02x", state[un].buf_tl, i, c);
@@ -90,13 +93,4 @@
 		xmit(un);
 	}
-}
-
-static void out(int32_t un, uint8_t c)
-{
-	if (SDL_LockMutex(cpu_mutex) < 0) {
-		fail("SDL_LockMutex() failed: %s", SDL_GetError());
-	}
-
-	out_lk(un, c);
 
 	if (SDL_UnlockMutex(cpu_mutex) < 0) {
@@ -105,13 +99,63 @@
 }
 
-static void mid_callback(double timeStamp, const unsigned char* message, size_t size, void *userData) {
-	(void) size;
-	(void) userData;
-
-	ver2("Timestamp %f\n", timeStamp);
-
-	for (uint8_t i = 0; i < sizeof(message); i++) {
-		ver2("Message %i %u", i, (uint8_t) message[i]);
-		out(0, message[i]);
+static void callback(double time, const uint8_t *midi, void *data)
+{
+	(void)data;
+
+	int32_t len;
+
+	switch (midi[0] & 0xf0) {
+	case 0x80: // note on
+	case 0x90: // note off
+	case 0xa0: // polyphonic key pressure
+	case 0xb0: // control change
+	case 0xe0: // pitch bend change
+		len = 3;
+		break;
+
+	case 0xc0: // program change
+	case 0xd0: // channel pressure
+		len = 2;
+		break;
+
+	case 0xf0:
+		switch (midi[0]) {
+		case 0xf0: // system exclusive
+		case 0xf4: // undefined
+		case 0xf5: // undefined
+		case 0xf7: // end of exclusive
+		case 0xf9: // undefined
+		case 0xfd: // undefined
+			len = -1;
+			break;
+
+		case 0xf1: // MIDI time code quarter frame
+		case 0xf3: // song select
+			len = 2;
+			break;
+
+		case 0xf2: // song position pointer
+			len = 3;
+			break;
+
+		case 0xf6: // tune request
+		case 0xf8: // timing clock
+		case 0xfa: // start
+		case 0xfb: // continue
+		case 0xfc: // stop
+		case 0xfe: // active sensing
+		case 0xff: // reset
+			len = 1;
+			break;
+		}
+
+		break;
+	}
+
+	ver2("time %f", time);
+
+	for (int32_t i = 0; i < len; ++i) {
+		ver2("midi[%d] 0x%02x", i, midi[i]);
+		out(0, midi[i]);
 	}
 }
@@ -121,33 +165,41 @@
 	ver("mid init");
 
+	if (mid_port < 0) {
+		ver("no MIDI requested");
+		return;
+	}
+
 	mid_in = rtmidi_in_create_default();
-	ver2("%p", mid_in->ptr);
-	// check if null
-
-	uint32_t portcount = rtmidi_get_port_count(mid_in);
-	if (portcount == 0) {
+
+	if (!mid_in->ok) {
+		fail("rtmidi_in_create_default() failed: %s", mid_in->msg);
+	}
+
+	int32_t n_ports = (int32_t)rtmidi_get_port_count(mid_in);
+
+	if (n_ports == 0) {
+		inf("no MIDI ports\n");
+		rtmidi_in_free(mid_in);
 		mid_in = NULL;
-		ver2("No MIDI ports\n");
-		return;
-	}
-
-	if (mid_port > portcount) {
-		mid_in = NULL;
-		ver2("Selected MIDI port larger than number of midi ports");
-		return;
-	}
-
-	rtmidi_open_port(mid_in, mid_port, rtmidi_get_port_name(mid_in, mid_port));
-
-	if(mid_in->ok == 0) {
-		fail("Failed to open MIDI port");
-	}
-
-	ver2("Using MIDI port %u", mid_port);
-
-	rtmidi_in_set_callback(mid_in, mid_callback, mid_in->data);
-
-	if(mid_in->ok == 0) {
-		fail("Failed to set MIDI Callback");
+		return;
+	}
+
+	if (mid_port >= n_ports) {
+		fail("invalid MIDI port %d selected (%d available)", mid_port, n_ports);
+	}
+
+	const char *name = rtmidi_get_port_name(mid_in, (uint32_t)mid_port);
+	rtmidi_open_port(mid_in, (uint32_t)mid_port, name);
+
+	if (!mid_in->ok) {
+		fail("error while opening MIDI port %d (%s): %s", mid_port, name, mid_in->msg);
+	}
+
+	inf("using MIDI port %d (%s)", mid_port, name);
+
+	rtmidi_in_set_callback(mid_in, callback, mid_in->data);
+
+	if (!mid_in->ok) {
+		fail("rtmidi_in_set_callback() failed: %s", mid_in->msg);
 	}
 }
@@ -155,10 +207,12 @@
 void mid_quit(void)
 {
-	if(mid_in) {
-		rtmidi_close_port(mid_in);
-		rtmidi_in_free(mid_in);
-	}
-
 	ver("mid quit");
+
+	if (mid_in == NULL) {
+		return;
+	}
+
+	rtmidi_close_port(mid_in);
+	rtmidi_in_free(mid_in);
 }
 
@@ -237,19 +291,22 @@
 }
 
-void mid_list(void) {
+void mid_list(void)
+{
 	mid_in = rtmidi_in_create_default();
 
-	uint32_t portcount = rtmidi_get_port_count(mid_in);
-
-	if (portcount == 0) {
-		mid_in = NULL;
-		ver2("no MIDI ports\n");
-		return;
-	}
-
-	fprintf(stdout, "the following MIDI ports are available:\n");
-
-	for (uint32_t i = 0; i < portcount; i++) {
-		fprintf(stdout, "port %d: %s\n", i, rtmidi_get_port_name(mid_in, i));
+	if (!mid_in->ok) {
+		fprintf(stderr, "rtmidi_in_create_default() failed: %s\n", mid_in->msg);
+		return;
+	}
+
+	uint32_t n_ports = rtmidi_get_port_count(mid_in);
+
+	if (n_ports == 0) {
+		fprintf(stdout, "no available MIDI ports\n");
+	}
+	else {
+		for (uint32_t i = 0; i < n_ports; i++) {
+			fprintf(stdout, "port %u: %s\n", i, rtmidi_get_port_name(mid_in, i));
+		}
 	}
 
