MIDI Manager module 0.00 Functional Specification ************************************************* -------------------------------------------------------------------------------- Distribution: Company Confidential. Document ref: Project: Ursula Revision: 0.02 PRELIMINARY Date: 06-02-1998 Author: T. G. Roddis -------------------------------------------------------------------------------- Overview ======== MIDI Manager is a module which provides a driver handling feature abstracting the MIDI ports to numbered entities and providing a hardware independent means of accessing them. It provides a upward interface of various SWI calls and a filtering system which allows various clients to monitor the output and input of the MIDI system. -------------------------------------------------------------------------------- Technical background ==================== Much of the outstanding background of this is covered in various MIDI specifications. See the references section for further details. A MIDI command consists of a status byte possibly followed by one or more data bytes. The command and data bytes together constitute a MIDI message. In general MIDI Manager does not understand particular MIDI commands or MIDI timecode, although there are a few, specific, exceptions to this. Filters operate by reading the status byte and then issuing the message to clients using length supplied by clients. Real-time messages are those which consist solely of a status (command) byte F8-FF. These can occur in the middle of other messages. Real-time messages should be 'urgent' when transmitted immediately or when scheduled for later. When received these will be passed in ahead of any incoming message which MIDIMgr is currently trying to construct. Another type of message which is real time begins F0 7F. MIDIMgr does not know about these but relies upon the user specifying urgency when calling the Transmit routine(s). Equally, because MIDIManager couldn't know about all the individual variations, when receiving these commands the programmer should specify a command length of the rogue value -1 indicating a message of indefinite length. This gives more flexibility, allowing unanticipated, future real-time messages to be processed correctly. -------------------------------------------------------------------------------- User interface ============== A user interface will be made available by applications. -------------------------------------------------------------------------------- Programmer interface ==================== MIDIMgr_Transmit ---------------- On entry: r0 = flags, bit 0: set => urgent, clear => standard r1 -> transmit block: + 0 (6 bytes) : transmission time, ff,ff,ff,ff,ff,ff for immediate + 6 (2 bytes) : padding, reserved + 8 (byte) : port on which to send + 9 (byte) : no of bytes to send +10 (bytes) : message(s) on exit: This transmits bytes at the given time (in MIDIClk format, see later). Note that an URGENT message could be scheduled, eg. some real-time message which must be sent as near as possible to the desired time. This merely allows the machine to correctly place the item in its schedule queue. The data is copied out immediately and need not remain after the duration of the call. MIDIMgr_RegisterFilter ---------------------- On entry: r0 = flags, bit 0: set => deregister, clear => register bit 1: set => transmit, clear => receive others: reserved, must be zero r1 = port to be filtered or -1 for all ports r2 = command identifier, or -1 for all bytes r3 = command identifier mask r4 = comand length (no. of bytes including command itself) or -1 r5 = address to call r6 = r12 value to call with This call is used to register and deregister transmit and receive filters. There are two types of filter: intermediate and terminating. Both types of filters specify command and command length. If -1 is used as the command identifier then the command length in r4 will still be used. The command length may be -1 indicating that the command byte string will be terminated by another top-bit set byte (other than a system real-time byte). Semantics of filter entry points: On entry: r1 -> receive block + 0 (6 bytes) : reception time + 6 (2 bytes) : padding, reserved + 8 (byte) : port on which received + 9 (byte) : no of bytes +10 (bytes) : command bytes r12 = value given in r5 above The time is given in MIDIClk format. See later for details. On exit: r0 = flags: bit 0: set => insert command in r2,r3 into stream, clear => don't bit 1: set => replace command with r2,r3; if r3 = 0 then delete command, clear => don't r2-r3 depend on value of r0 Some parts NOT IMPLEMENTED:- The modification of messages is not currently supported. Therefore on exit r0 should be zero and r2 and r3 unused. MIDIMgr_RegisterInterface ------------------------- On entry: r0 = flags, bit 0: set => deregister, clear => register others: reserved, must be zero r1 -> interface block: + 0 : transmit entry point + 4 : transmit handle (for multiple interfaces) + 8 : r12 value for driver module +12 : driver/interface name (NUL terminated) On exit: r0 = flags, reserved r1 = version number of manager r2 = receive entry point r3 = reserved for transmit entry point (transmission on interrupt) NOT IMPLEMENTED r4 = port number allocated r5 = r12 value for manager module Register, deregister an interface. Called on driver initialisation and when MIDIMgr starting service call is issued. The interface block must remain static in memory and be accessible at all times (eg. in RMA) until driver deregisters. Driver should deregister with the same pointer to the interface block. Semantics of driver transmit entry point: On entry: r0 = byte to transmit r1 = driver handle r12 = r12 value for driver module On exit: if VS set then r0 = error flags, bit 0: set => interface down; clear, interface up bit 1: set => buffer full, retry later; clear => buffer not full r1 = delay before trying again This will attempt to send the byte in question. It may fail, in which case MIDIMgr will atempt to send the byte later. Drivers should not provide internal buffers as this would contribute to delays in sending real time messages. In fact drivers should process this very quickly so that it can be called for many bytes without significant calling overhead. The driver should return using MOV pc, lr or equivalent. Semantics of receive entry point (in MIDIMgr): On entry: r0 = received byte r1 = driver handle r12 = r12 value for manager module IRQ mode: preserved The driver does not time-stamp the byte but should call this routine immediately, even if in an interrupt handler. MIDIMgr_EnumeratePorts ---------------------- On entry: r0 = 0 for first port, or returned r0 from last call, or number of port for which information is desired On exit: r0 = number of next port or 0 for no more ports r1 = pointer to string identifying type of port This call returns information about the given port. MIDIMgr_SetPortRedirect NOT IMPLEMENTED ----------------------- On entry: r0 = flags, bit 0: set => set thru mode, clear => in/out mode r1 = port number r2 = reserved This controls the redirection for a given port. Service_MIDIMgr --------------- r0 = flags r1 = service call number r2 = reason code other registers depend on reason code Reason 0: MIDIMgr started, invitation to register (NB: this is not actually issued during initialisation but, rather, after so that the registration SWIs is available to drivers). Reason 1: MIDIMgr about to be killed -------------------------------------------------------------------------------- Data formats ============ Times are given in MIDIClk_ScheduleCallback format, as follows: byte 0: hour byte 1: minute byte 2: second byte 3: frame byte 4: quarter-frame byte 5: beat/tick within frame -------------------------------------------------------------------------------- Glossary ======== Status byte: command bytes. The first and, possibly, only byte in a message and indicates the action desired by the sender. -------------------------------------------------------------------------------- 14.0 References =============== * MIDI 1.0 Detailed Specification Document Version 4.2 (October 1994) MIDI Manufacturers Association, POB 3173, La Habra CA 90632-3173 * MIDI Time Code Unversioned. (1995) MIDI Manufacturers Association, POB 3173, La Habra CA 90632-3173 * Standard MIDI Files 1.0 (1995) MIDI Manufacturers Association, POB 3173, La Habra CA 90632-3173