' ***************************************************************************
' *                                                                         *
' *   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 <CR>        *
' *   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                            *
' ***************************************************************************

	DEFINT A-Z
'			TURBO BASIC Constants:

	%ComdPort   = &H331			' MPU-401 Command Port on IBM
	%StatPort   = &H331			' MPU-401 Status Port on IBM
	%DataPort   = &H330			' MPU-401 Data I/O Port on IBM
	%DRR        = &H40			' Mask for Data Read Reg. Bit
	%DSR        = &H80			' Mask for Data Set Ready Bit
	%ACK        = &HFE			' MPU-401 Acknowledge Response
	%MaskFlip   = &HFF			' WAIT Function Bit Mask XOR
	%MPUReset   = &HFF			' MPU-401 Total Reset Command
	%UARTMode   = &H3F			' MPU-401 "Dumb UART Mode"
	%NoteOn1    = &H90			' MIDI Note On for Channel 1
	%Velocity   = 64			' MIDI Medium Key Velocity
	%NoteOff    = 0				' 0 Velocity = Note Off
	%FirstNote  = 36			' First note synth can play
	%LastNote   = 96			' Last note synth can play

' ***************************************************************************
' *                       I N I T I A L I Z A T I O N                       *
' ***************************************************************************

RSTMPU: 					' Reset the MPU-401                     			
	CLS					' Clear Display

	OUT %ComdPort,%MPUReset			' Send MPU-401 RESET Command
	A = INP(%DataPort)			' Dummy read to clear buffer

 	WAIT %StatPort,%DRR,%MaskFlip		' Wait for port ready

        OUT %ComdPort,%UARTMode			' Set MPU-401 "Dumb UART" Mode
 	A = INP(%DataPort)			' Dummy Read to clear buffer

 	WAIT %StatPort,%DSR,%MaskFlip		' Wait for "UART" port ready -
 						'  Really crucial!
REM Form Feed 

' ***************************************************************************
' *                         M A I N   P R O G R A M                         *
' ***************************************************************************

MPUPlay:

	PRINT : PRINT : PRINT : PRINT : PRINT

	PRINT TAB(10)"MPUDEMO1 now playing a fast scale on MIDI Channel 1"

	FOR N = %FirstNote TO %LastNote 	' Ascending Scale

		Note = N
		GOSUB Playit			' Play a note

		DELAY .06			' Duration of note ON

		GOSUB Offit       		' Stop that same note

	NEXT					' Play next note


	DELAY .1				' Pause between scales


	FOR N = %LastNote TO %FirstNote STEP -1	' Descending Scales

		Note =  N
		GOSUB Playit			' Play a note

		DELAY .06			' Duration of note OFF

		GOSUB Offit       		' Stop that same note

	NEXT


	DELAY 1					' Pause between demos

REM Form Feed 

	PRINT : PRINT : PRINT

	PRINT TAB(10)"MPUDEMO1 now playing some chords on MIDI Channel 1"

	FOR N = 1 to 3				' Playing first chord thrice

		Note = 65			' F3
		GOSUB Playit			' Start a chord
		Note = 69                       ' A3
		GOSUB Playit
		Note = 72			' C4
		GOSUB Playit

		DELAY .3			' Duration of held chord

		Note = 65                       ' F3
		GOSUB Offit			' Stop the chord
		Note = 69                       ' A3
		GOSUB Offit
		Note = 72                       ' C4
		GOSUB Offit

		DELAY .3			' Duration of rest


	NEXT					' Play chord again


		Note = 64                       ' E3
		GOSUB Playit			' Start last chord
		Note = 67                       ' G3
		GOSUB Playit
		Note = 72                       ' C4
		GOSUB Playit

		DELAY 3				' Duration of held chord

		Note = 64
		GOSUB Offit			' Stop the chord
		Note = 67
		GOSUB Offit
		Note = 72
		GOSUB Offit

	PRINT : PRINT : PRINT

	PRINT TAB(10)"MPUDEMO1 is through - Tinker with it!"

	END

	REM Form Feed 

' ***************************************************************************
' *                          S U B R O U T I N E S                          *
' ***************************************************************************


' ***************************** Playit SUBROUTINE ***************************

Playit: 					' Play a MIDI Note

	OUT  %DataPort,%NoteOn1			' Send Chan. 1 note ON code
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
 	WAIT %StatPort,%DRR,%MaskFlip		' Wait for port ready
	
	OUT  %DataPort,Note			' Send note Number to turn ON
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
 	WAIT %StatPort,%DRR,%MaskFlip 		' Wait for port ready

	OUT  %DataPort,%Velocity		' Send medium velocity
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
 	WAIT %StatPort,%DRR,%MaskFlip 		' Wait for port ready

	RETURN


' ***************************** Offit SUBROUTINE ***************************

Offit: 						' Turn off a MIDI Note

	OUT  %DataPort,%NoteOn1			' Send Chan. 1 note ON code
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
	WAIT %StatPort,%DRR,%MaskFlip		' Wait for port ready

	OUT  %DataPort,Note			' Send note number to turn OFF
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
 	WAIT %StatPort,%DRR,%MaskFlip		' Wait for port ready

	OUT  %DataPort,%NoteOff			' Send 0 Velocity = Note Off
 	A    = INP(%DataPort)			' Dummy Read to clear buffer *
 	WAIT %StatPort,%DRR,%MaskFlip		' Wait for port ready

	RETURN

' * 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!

	END


' ************************* Last Line of MPUDEMO1.BAS ************************
' Last Edited 06/20/87 1531 Hrs. G. F. Silvestri

	END
