/*************************************************************************** * * * FileName: MPUDEMO1.BAS, MPUDEMO1.EXE - for IBM and ROLAND MPU-401 * * * * Demonstrates the speed of Borland's TURBO BASIC, and allows you * * to experiment with the ROLAND MPU-401 and MIDI synthesizers. * * MPUDEMO1 puts your MPU-401 into its "DUMB UART" mode and then plays * * a quick scale and some chords on MIDI Channel 1. To run, connect * * your synth (on Chan.1) to MPU-401 OUT, type MPUDEMO1 * * WARNING: If you don't HAVE an MPU-401 hooked up, program hangs up! * * Compile ONLY with TURBO BASIC V. 1.0 on IBM PC/XT or equiv. * * Please feel free to tinker around to learn about MIDI! * * * * By Gino F. Silvestri 06/19/87 1700 Hrs. * * * ***************************************************************************/ /*************************************************************************** * D E F I N I T I O N S * ***************************************************************************/ #define WAIT( port, flag ) while ( (inp(port)&flag) != 0 ) #define COMDPORT 0x331 /* MPU-401 Command Port on IBM */ #define STATPORT 0x331 /* MPU-401 Status Port on IBM */ #define DATAPORT 0x330 /* MPU-401 Data I/O Port on IBM */ #define DRR 0x40 /* Mask for Data Read Reg. Bit */ #define DSR 0x80 /* Mask for Data Set Ready Bit */ #define ACK 0xFE /* MPU-401 Acknowledge Response */ #define MASKFLIP 0xFF /* WAIT Function Bit Mask XOR */ #define MPURESET 0xFF /* MPU-401 Total Reset Command */ #define UARTMODE 0x3F /* MPU-401 "Dumb UART Mode" */ #define NOTEON1 0x90 /* MIDI Note On for Channel 1 */ #define VELOCITY 64 /* MIDI Medium Key Velocity */ #define NOTEOFF 0 /* 0 Velocity = Note Off */ #define FIRSTNOTE 36 /* First note synth can play */ #define LASTNOTE 96 /* Last note synth can play */ /*************************************************************************** * I N I T I A L I Z A T I O N * ***************************************************************************/ RstMPU() { register char a; /* Clear Display */ outp( COMDPORT, MPURESET ); /* Send MPU-401 RESET Command */ a = inp( DATAPORT ); /* Dummy read to clear buffer */ WAIT( STATPORT, DRR ); /* wait for port ready */ outp( COMDPORT, UARTMODE ); /* Set MPU-401 "Dumb UART" Mode */ a = inp(DATAPORT); /* Dummy Read to clear buffer */ WAIT( STATPORT, DSR ); /* Wait for "UART" port ready - */ /* Really crucial! */ } /*************************************************************************** * M A I N P R O G R A M * ***************************************************************************/ main() { register n; RstMPU(); printf( "\n\n\n\n\n" ); printf( "\tMPUDEMO1 now playing a fast scale on MIDI Channel 1\n" ); for ( n = FIRSTNOTE; n <= LASTNOTE; n++ ) { PlayIt( n ); /* Play note */ Delay( 1 ); /* Duration of note ON */ OffIt( n ); /* Stop note */ } Delay( 1 ); /* Pause between scales */ for ( n = LASTNOTE; n <= FIRSTNOTE; n-- ) { PlayIt( n ); /* Play a note */ Delay( 1 ); /* Duration of note OFF */ OffIt( n ); /* Stop that same note */ } Delay( 1 ); /* Pause between demos */ printf( "\n\n\n" ); printf( "\tMPUDEMO1 now playing some chords on MIDI Channel 1\n" ); for ( n = 1; n <= 3; n++ ) { PlayIt( 65 ); /* Start a chord - F3 */ PlayIt( 69 ); /* A3 */ PlayIt( 72 ); /* C4 */ Delay( 1 ); /* Duration of held chord */ OffIt( 65 ); /* Stop the chord - F3 */ OffIt( 69 ); /* A3 */ OffIt( 72 ); /* C4 */ Delay( 1 ); /* Duration of rest */ } printf( "\n\n\n" ); printf( "\tMPUDEMO1 is through - Tinker with it!\n" ); } /*************************************************************************** * S U B R O U T I N E S * ***************************************************************************/ /***************************** Playit SUBROUTINE ***************************/ PlayIt( n ) /* Play a MIDI Note */ int n; { register char a; outp( DATAPORT, NOTEON1 ); /* Send Chan. 1 note ON code */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ outp( DATAPORT, n ); /* Send note Number to turn ON */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ outp( DATAPORT, VELOCITY ); /* Send medium velocity */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ } /***************************** Offit SUBROUTINE ***************************/ OffIt( n ) /* Turn off a MIDI Note */ int n; { register char a; outp( DATAPORT, NOTEON1 ); /* Send Chan. 1 note ON code */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ outp( DATAPORT, n ); /* Send note number to turn OFF */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ outp( DATAPORT, NOTEOFF ); /* Send 0 Velocity = Note Off */ a = inp( DATAPORT ); /* Dummy Read to clear buffer */ WAIT( STATPORT, DRR ); /* Wait for port ready */ } /**************************** Delay SUBROUTINE ****************************/ Delay( n ) int n; { long x; while ( n-- > 0 ) for ( x = 1; x < 10000; x++ ); } /* Note: Read of DATAPORT prevents hang-up if MIDI IN from a keyboard is connected and played - WAIT would stay FOREVER if you hit any key once! */ /************************* Last Line of MPUDEMO1.C ************************ Last Edited 07/1/87 2010 Hrs. M. D. Bratcher **************************************************************************/