Garvin: DESIGNING HARDWARE

Custom	hardware  affords some measure of software security  and  may
provide functions not available on existing interfaces.	  Since	 some
designers  prefer  using  their own hardware,  I will provide  a  few
guidelines.

MIDI's serial protocol requires no hardware handshake signals, so 40-
pin  UART's are not necessary.   The only small UART that  may  cause
trouble	 is the Intel 8251.   I have used Motorola 68B50's in several
designs with good results.   On 8088 systems,  Motorola's E  (enable)
signal can be developed by 'anding' port read and write.

Timers	get tricky when multiple devices are hooked to one  interrupt
line.	I  have used Intel 8253's,  but I usually connect the  output
line  to  a  flip-flop so that the output pulse can  be	 trapped  and
identified.   Flip-flops  are not necessary if the timer interrupt is
isolated, since the 8259 interrupt controller has edge-triggering.

Timers	will not be required on IBM-PC's using the Roland  interface,
but if you are designing your own,  try to include an on-board timer.
The  PC's  internal timers do not provide the accuracy  necessary  to
deal   with  high-resolution  music   timing.	 For   low-resolution
applications, IRQ 0 from the PC mother board can be readjusted to run
at a multiple ('X') of its normal speed.  Then, every 'X' pulses, the
old  interrupt is run.	 The interrupt acknowledge should be  skipped
when  jumping to the 'old' routine.   Remember to reset the interrupt
vectors before exiting to DOS.	Disk head loads use timer 0 for time-
outs,  so problems with this routine usually cause the drive light to
stay on.

Slower	clock  rates  for hardware timers will	obviously  result  in
decreased resolution.	Not so obvious, though, is the way that tempo
resolution  and	 note-timing accuracy combine to  make	even  tougher
demands on the system timer's crystal frequency.   I try to clock the
timer  at around 2 MHz so that I can record with resolution of	about
96  divisions per quarter note while maintaining sufficient  accuracy
in specifying tempos.

In most applications,  the divisor sent to the hardware timer is used
to trim the tempo,  which is set in increments of 'beats-per-minute'.
An  easy way to control tempo is to index into a table of divisors by
the desired number of "BPM's".	I normally generate the tables with a
'C'  program  which does the calculations and prints out  the  tables
exactly	 as they should appear in the sequencer	 program.   When  the
values are verified, I redirect the output of the program into a file
which is then compiled .


INTERRUPTS

The  interrupt service routine (ISR) is responsible for	 prioritizing
interrupts  and	 co-ordinating all incoming data.   Obscure  problems
with the ISR can propagate through the entire system.	A  flow-chart
will  probably help to clarify possible timing errors or  bottlenecks
before the ISR is coded.

It  might appear that a system using only serial ports would pose  no
problems in I/O handling, but MIDI baud rates are high, and there may
be multiple ports.  Input interrupts should be serviced as quickly as
possible  because  losing  a byte may result in losing	an  important
NOTE-OFF  message.   When  the recorded events are  retransmitted  on
playback, the synthesizer will play a 'stuck note' until the operator
can  figure  out a way to generate a NOTE OFF (sometimes  leaving  an
embarrassed  performer	desperately groping for	 the  power  switch).
Output	interrupts are less critical;  a momentary delay is the	 only
penalty for slow output response times.	  Be particularly careful how
these  two interrupt sources are handled when UART hardware lines are
shared.

On  the IBM PC,	 the first instruction in the ISR can be an STI	 (the
BIOS  does this) for re-enabling higher priority  interrupts.	Lower
priority  interrupts can be enabled by masking the present  interrupt
and  sending an acknowledge (EOI) to the interrupt  controller.	  The
pending	 interrupt  cannot  be retriggered until the  source  of  the
interrupt is reset (UART is read,  etc.).  Make sure that the pending
interrupt line is high (active) when sending the EOI, because obscure
problems  can result with the 8259 when it cannot find the source  of
the interrupt being acknowledged.   It may also help to poll the 8259
registers to make sure that the interrupt line is low before  exiting
from the ISR.	This will help to avoid difficulty with the PC's edge
triggered hardware.

Timer interrupts are important,	 but they can generally be considered
a  lower priority than UART interrupts.	  The timer routine itself is
usually short,	consisting of little more than incrementing a  series
of  software counters,	but at some point compares must be made	 with
'target' values and a long series of events may be triggered.

The  timer  interrupt conveys no actual data aside from	 a  flag,  so
normal	queues	are not necessary.   The best way to 'enqueue'	timer
interrupts  is	with the use of a semaphore,  which  allows  the  ISR
itself	to  be	interrupted.   When  the  timer	 'tick'	 occurs,  the
semaphore  is  incremented and THEN timer interrupts are  re-enabled.
If the semaphore has been incremented to 1,  no interrupts are nested
and  normal processing can resume.   If the value is greater than  1,
this  means  that  the	timer interrupts  have	stacked	 up,  so  the
interrupt is exited,  and control is returned to the timer ISR	which
was  interrupted.   Before  the timer ISR is exited the semaphore  is
decremented,  and if the value is still non-zero, the interrupts must
have been nested.   In this case,  control is returned to the top  of
the  timer  ISR,  which repeats until the semaphore returns to	zero.
This  allows the routine to catch up with 'lost'  interrupts  without
losing any timer puls es or UART interrupts.

The  flow  chart (fig 1) is simplified;	 it may help to refer to  the
code  listing  (listing 1) for more subtle details.   Make  sure  the
semaphore  is  initialized to zero at startup or the timer  ISR	 will
never run.


TIMING NOTES

The  MIDI  sequencer will usually use a hardware clock for  its	 main
timing	reference,  but	 it  may be necessary to  synchronize  to  an
external  software  clock  provided  by	 a  drum  machine  or  timing
converter.   I	will refer to these as internal and  external  synch,
respectively.	MIDI  software clocks occur at a standard rate of  24
per  quarter  note,  which  provides musical resolution to  within  a
sixty-fourth  note triplet.   This sounds like it would keep up	 with
even  the fastest musicians,  but remember that we are	dealing	 with
timing EDGES.	Trimming these edges to the nearest 24th of a quarter
note  may  cause  the recorded notes to	 sound	too  symmetrical,  or
mechanical.

Conversely,  it	 may seem that slowing the system clock could correct
the timing of inaccurate note values.  This rounding ('quantization')
is  sometimes  used  to advantage,  but	 overuse  removes  the	human
signature  and	creates	 a  metronomic,	  mechanical  sound.   Uneven
qualities  are most often missed on parts such as solos which  appear
'up  front' in a composition.	Obviously,  all devices	 synchronized
with MIDI real-time clock signals will be quantized to some extent.


TIME-STAMPS

In  order  to maintain very precise timing of events  while  allowing
interrupts to procede at full speed, I store a 'time-stamp' with each
event coming into the UART receive queue.  Very simply, if a received
byte  is greater than 7Fh (MSB is set on commands),  the current time
is enqueued after the byte.  This provides 'freeze-frame' timing; the
time record travels with the received data until the program is ready
to  process  it.  Only	the leading byte needs	to  be	time-stamped.
Follow-up  data (with MSB's reset) are assumed to have been  received
at  the same time.   This technique can provide accuracy better	 than
that obtainable by waiting for the complete record and processing  it
instantly.   Usually  the  sending device intends that all  bytes  be
received  simultaneously,  so  stamping	 the leading byte  will	 more
accurately reflect the actual event timing,  even if the  transmitter
lags in sending the follow-up data.


REAL-TIME

The  MIDI specification calls for two basic types of software clocks.
'Clock-in-stop'	 (0FCh) allows receivers to phase-lock to  the	clock
frequency  prior  to  start-up.	  When the  transmitter	 switches  to
'clock-in-play'	 (0F8h),  all synchronized receivers switch to	their
active	state  (usually playback or record).   To maintain  accuracy,
real-time messages are transmitted at any time -- even in the  middle
of  other  multi-byte  messages.   Receivers must  account  for	 this
possibility even if the real-time messages are not used.  Both clocks
are  always  sent at the rate of 24 per quarter note.	Altering  the
clock frequency will change tempo, not accuracy.

Other real-time messages include 'START-FROM-BEGINNING' (0FAh)	which
resets	 internal  song	 pointers,   'CONTINUE'	 (0FBh)	 which	tells
receivers  to resume from the current location and  'ACTIVE  SENSING'
(0FEh)	which  just lets the receivers know that the  transmitter  is
still  there.	The latter is optional and used notably by the Yamaha
DX-7  synthesizer.   When  using a DX-7,  you will probably  want  to
discard	 the 0FEh bytes,  since they will be received  constantly  --
even  when not recording.   They can fill up the input queues if  the
input interrupts are enabled.

The  last  real-time  message,	'SYSTEM RESET'	(0FFh)	is  dangerous
because it could start a regenerating condition where every component
in the system sends resets to each other.  It is usually reserved for
linkage	 to a hardware reset switch or used judiciously by the master
controller.
