123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /*
- Copyright (C) 1994-1995 Apogee Software, Ltd.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /**********************************************************************
- module: MPU401.C
- author: James R. Dose
- date: January 1, 1994
- Low level routines to support sending of MIDI data to MPU401
- compatible MIDI interfaces.
- (c) Copyright 1994 James R. Dose. All Rights Reserved.
- **********************************************************************/
- #include <conio.h>
- #include <dos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "dpmi.h"
- #include "user.h"
- #include "mpu401.h"
- #define MIDI_NOTE_OFF 0x80
- #define MIDI_NOTE_ON 0x90
- #define MIDI_POLY_AFTER_TCH 0xA0
- #define MIDI_CONTROL_CHANGE 0xB0
- #define MIDI_PROGRAM_CHANGE 0xC0
- #define MIDI_AFTER_TOUCH 0xD0
- #define MIDI_PITCH_BEND 0xE0
- #define MIDI_META_EVENT 0xFF
- #define MIDI_END_OF_TRACK 0x2F
- #define MIDI_TEMPO_CHANGE 0x51
- #define MIDI_MONO_MODE_ON 0x7E
- #define MIDI_ALL_NOTES_OFF 0x7B
- int MPU_BaseAddr = MPU_DefaultAddress;
- //unsigned MPU_Delay = 500;
- //unsigned MPU_Delay = 5000;
- unsigned MPU_Delay = 0x5000;
- /**********************************************************************
- Memory locked functions:
- **********************************************************************/
- #define MPU_LockStart MPU_SendMidi
- /*---------------------------------------------------------------------
- Function: MPU_SendMidi
- Sends a byte of MIDI data to the music device.
- ---------------------------------------------------------------------*/
- void MPU_SendMidi
- (
- int data
- )
- {
- int port = MPU_BaseAddr + 1;
- unsigned count;
- count = MPU_Delay;
- while( count > 0 )
- {
- // check if status port says we're ready for write
- if ( !( inp( port ) & MPU_ReadyToWrite ) )
- {
- break;
- }
- count--;
- }
- port--;
- // Send the midi data
- outp( port, data );
- }
- /*---------------------------------------------------------------------
- Function: MPU_NoteOff
- Sends a full MIDI note off event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_NoteOff
- (
- int channel,
- int key,
- int velocity
- )
- {
- MPU_SendMidi( MIDI_NOTE_OFF | channel );
- MPU_SendMidi( key );
- MPU_SendMidi( velocity );
- }
- /*---------------------------------------------------------------------
- Function: MPU_NoteOn
- Sends a full MIDI note on event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_NoteOn
- (
- int channel,
- int key,
- int velocity
- )
- {
- MPU_SendMidi( MIDI_NOTE_ON | channel );
- MPU_SendMidi( key );
- MPU_SendMidi( velocity );
- }
- /*---------------------------------------------------------------------
- Function: MPU_PolyAftertouch
- Sends a full MIDI polyphonic aftertouch event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_PolyAftertouch
- (
- int channel,
- int key,
- int pressure
- )
- {
- MPU_SendMidi( MIDI_POLY_AFTER_TCH | channel );
- MPU_SendMidi( key );
- MPU_SendMidi( pressure );
- }
- /*---------------------------------------------------------------------
- Function: MPU_ControlChange
- Sends a full MIDI control change event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_ControlChange
- (
- int channel,
- int number,
- int value
- )
- {
- MPU_SendMidi( MIDI_CONTROL_CHANGE | channel );
- MPU_SendMidi( number );
- MPU_SendMidi( value );
- }
- /*---------------------------------------------------------------------
- Function: MPU_ProgramChange
- Sends a full MIDI program change event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_ProgramChange
- (
- int channel,
- int program
- )
- {
- MPU_SendMidi( MIDI_PROGRAM_CHANGE | channel );
- MPU_SendMidi( program );
- }
- /*---------------------------------------------------------------------
- Function: MPU_ChannelAftertouch
- Sends a full MIDI channel aftertouch event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_ChannelAftertouch
- (
- int channel,
- int pressure
- )
- {
- MPU_SendMidi( MIDI_AFTER_TOUCH | channel );
- MPU_SendMidi( pressure );
- }
- /*---------------------------------------------------------------------
- Function: MPU_PitchBend
- Sends a full MIDI pitch bend event out to the music device.
- ---------------------------------------------------------------------*/
- void MPU_PitchBend
- (
- int channel,
- int lsb,
- int msb
- )
- {
- MPU_SendMidi( MIDI_PITCH_BEND | channel );
- MPU_SendMidi( lsb );
- MPU_SendMidi( msb );
- }
- /*---------------------------------------------------------------------
- Function: MPU_SendCommand
- Sends a command to the MPU401 card.
- ---------------------------------------------------------------------*/
- void MPU_SendCommand
- (
- int data
- )
- {
- int port = MPU_BaseAddr + 1;
- unsigned count;
- count = 0xffff;
- while( count > 0 )
- {
- // check if status port says we're ready for write
- if ( !( inp( port ) & MPU_ReadyToWrite ) )
- {
- break;
- }
- count--;
- }
- outp( port, data );
- }
- /*---------------------------------------------------------------------
- Function: MPU_Reset
- Resets the MPU401 card.
- ---------------------------------------------------------------------*/
- int MPU_Reset
- (
- void
- )
- {
- int port = MPU_BaseAddr + 1;
- unsigned count;
- // Output "Reset" command via Command port
- MPU_SendCommand( MPU_CmdReset );
- // Wait for status port to be ready for read
- count = 0xffff;
- while( count > 0 )
- {
- if ( !( inp( port ) & MPU_ReadyToRead ) )
- {
- port--;
- // Check for a successful reset
- if ( inp( port ) == MPU_CmdAcknowledge )
- {
- return( MPU_Ok );
- }
- port++;
- }
- count--;
- }
- // Failed to reset : MPU-401 not detected
- return( MPU_NotFound );
- }
- /*---------------------------------------------------------------------
- Function: MPU_EnterUART
- Sets the MPU401 card to operate in UART mode.
- ---------------------------------------------------------------------*/
- int MPU_EnterUART
- (
- void
- )
- {
- int port = MPU_BaseAddr + 1;
- unsigned count;
- // Output "Enter UART" command via Command port
- MPU_SendCommand( MPU_CmdEnterUART );
- // Wait for status port to be ready for read
- count = 0xffff;
- while( count > 0 )
- {
- if ( !( inp( port ) & MPU_ReadyToRead ) )
- {
- port--;
- // Check for a successful reset
- if ( inp( port ) == MPU_CmdAcknowledge )
- {
- return( MPU_Ok );
- }
- port++;
- }
- count--;
- }
- // Failed to reset : MPU-401 not detected
- return( MPU_UARTFailed );
- }
- /*---------------------------------------------------------------------
- Function: MPU_Init
- Detects and initializes the MPU401 card.
- ---------------------------------------------------------------------*/
- int MPU_Init
- (
- int addr
- )
- {
- int status;
- int count;
- char *ptr;
- ptr = USER_GetText( "MPUDELAY" );
- if ( ptr != NULL )
- {
- MPU_Delay = ( unsigned )atol( ptr );
- }
- MPU_BaseAddr = addr;
- count = 4;
- while( count > 0 )
- {
- status = MPU_Reset();
- if ( status == MPU_Ok )
- {
- return( MPU_EnterUART() );
- }
- count--;
- }
- return( status );
- }
- /*---------------------------------------------------------------------
- Function: MPU_LockEnd
- Used for determining the length of the functions to lock in memory.
- ---------------------------------------------------------------------*/
- static void MPU_LockEnd
- (
- void
- )
- {
- }
- /*---------------------------------------------------------------------
- Function: MPU_UnlockMemory
- Locks all neccessary data.
- ---------------------------------------------------------------------*/
- void MPU_UnlockMemory
- (
- void
- )
- {
- DPMI_UnlockMemoryRegion( MPU_LockStart, MPU_LockEnd );
- DPMI_Unlock( MPU_BaseAddr );
- DPMI_Unlock( MPU_Delay );
- }
- /*---------------------------------------------------------------------
- Function: MPU_LockMemory
- Locks all neccessary data.
- ---------------------------------------------------------------------*/
- int MPU_LockMemory
- (
- void
- )
- {
- int status;
- status = DPMI_LockMemoryRegion( MPU_LockStart, MPU_LockEnd );
- status |= DPMI_Lock( MPU_BaseAddr );
- status |= DPMI_Lock( MPU_Delay );
- if ( status != DPMI_Ok )
- {
- MPU_UnlockMemory();
- return( MPU_Error );
- }
- return( MPU_Ok );
- }
|