/* MPU.C * This file contains low-level routines for MIDI I/O through the * Roland MPU-401. * * DOS idiosyncracies: * int inportb(port) * int port; * Read a byte from port 'port' and return it. * outportb(port,value) * int port; * char value; * Send the byte 'value' to port 'port'. * * Copyright (C) 1991 by Andrew Arensburger. Permission is granted to * use, copy and/or distribute this file freely for non-commercial purposes, * as long as this notice remains intact. Any commercial use is prohibited * without express permission from the author. * * If you make any changes, fix bugs, etc., please send them to me that I * might coordinate fixes and improvements. */ #ifdef DEBUG #include /* For debugging only */ int mpu_debug = 0; #endif #include #include "mpu.h" /* MPU_UART * Put the MPU into UART mode (best for SysEx I/O). */ mpu_uart() { #ifdef DEBUG if (mpu_debug) fprintf(stderr, "(UART) "); #endif outportb(MPU_CMD, (unsigned char) CMD_UART); } /* MPU_RESET * Reset the MPU. */ mpu_reset() { #ifdef DEBUG if (mpu_debug) fprintf(stderr, "(reset) "); #endif outportb(MPU_CMD, (unsigned char) CMD_RESET); } /* FLUSH_NONSYSX * Read in any "normal" (i.e., non-SysEx) messages from the EPS. This is * necessary in cases where not reading them could clog up the MPU. * Returns the first SysEx command byte received. */ unsigned char flush_nonsysx() { unsigned char status; for (;;) { if (!DSR || ((status = (unsigned char) mpu_rbyte()) >= 0xf0)) return(status); } } /* MPU_SBYTE * Send a byte to the MPU. */ mpu_sbyte(b) unsigned char b; /* The byte to be sent */ { flush_nonsysx(); /* Flush any pending input */ while (!DRR) /* Wait until MPU is ready */ ; #ifdef DEBUG if (mpu_debug) fprintf(stderr, "(0x%2x) ", b); #endif outportb(MPU_DATA,b); /* Send the byte */ } /* MPU_RBYTE * Receive a byte from the MPU. Returns the byte read, or -1 in case * of error. */ int mpu_rbyte() { int retval; /* Return value */ while (!DSR) /* Wait until MPU is ready to send */ ; retval = inportb(MPU_DATA); #ifdef DEBUG if (mpu_debug) fprintf(stderr, "[0x%2x] ", retval); #endif return(retval); } /* MPU_INIT * Initialize the MPU-401 from power-up state to a sane state: put it in * UART mode, and flush its buffers to make sure it is ready to send and * receive UART data. */ mpu_init() { inportb(MPU_STAT); inportb(MPU_DATA); while (DSR) inportb(MPU_DATA),wait(1); mpu_uart(); wait(2); while (DSR) inportb(MPU_DATA),wait(1); }