[comp.sys.atari.st.tech] MIDI

miskinis@aisg.enet.dec.com (John Miskinis) (02/08/91)

Hello,

	FIRST, I want to thank everyone who is reading and replying to
my posting...

	I'm relatively new to the USENET, and tried to post something
yesterday, but actually sent a mail message by mistake...

	ANYWAY, I wrote my MIDI input handler in the assembler provided
with Mark Williams C.  I duplicated the code from the disassebled BIOS
listings in the Abacus Internals book, adding a timestamp, and depositing
the byte in by 32K length buffer.

	I will attempt to write an entire level 6 interrupt handler, if
the is the only way out.  From what I now understand, there's no way
around it.
	
	I want to support the mouse AND MIDI, with MIDI being the number
one priority.  I don't mind losing mouse events if I have to (while MIDI
bytes are coming in).

_John_

miskinis@aisg.enet.dec.com (John Miskinis) (02/16/91)

Hello,

	I've received numerous replies from people on the USENET who I
wish to thank for their time and effort...

	Perhaps I should have stated up front exactly what I have done
in the past 2 years leading up to my recent postings, the documentation I
have purchased, etc..

	I've been an Atari customer for several years, beginning with their
8-bit line, and then "blowb away" with the capabilities of the ST, which
I had to have right away, for it's graphics and MIDI architecture.

	I began developing a sequencer shell, orginally in Pascal, and
later ported to C.  All coding was done in "C", and MIDI I/O was performed
exclusively via the BIOS and XBIOS functions.   The exclusion was a timer
routine that ran in the backgound, thus providing me with a timestamping
metric.  Each byte had a time stamp as to when it came in relative to the
beginning of the sequence.  And you know what?  It worked perfectly (so
I thought).  I had musician friends over now and then, who were amazed
at the accuracy of a "home grown" application, and were frustrated that
they could not crash the program by wiggling the bender, stepping on the
pedals, and placing their entire forearm on the keys.

	I had a 5-octave keyboard on the screen, lighting a rectangle in
each key when it was "on", and unlighting it when it was "off".   Once
or twice a month I then noticed that a key would remain on, when it's
midi note value was specifically turned off.   I then questioned the validity
of my earilier recordings, and proved a few of them invalid by using a non
decaying synth sound.  I had earilier used piano sounds, which would decay
ANYWAY, whether or not a not off message was ever received!

	SO, then I started experimenting, and removed  ALL code except what
was need to record a byte from the MIDI port each time it came in.  I even
eliminated the background timer to be sure that it was not interferring.

	I wrote routine that would scan my data, looking for corruption.
I noticed that when a byte was WRONG, it was a copy of the last on, and
one was missing (the interrupt fired, but the previuos byte was still in
the ACIA buffer.

	I then learned 6800 assembler, and wrote a routine that emulated the
BIOS MIDI functions, and had the EXACT SAME PROBLEM.  I then added code to
check the ACIA status, and found that there were overruns.  I had been using
the KBD vector MIDISYS to point to my interrupt routine, which is really
only as good as the routine that IT is called from, being the standard
level 6 interrupt handler, which handles keyboard, mouse, and MIDI I/O.

	I currently have "The Tackle Box" (~900 pages containing the
full docs for the 68000, 6850, etc.), Mark Williams C, The Abacaus
Atari ST Internals book, the Sybex Programmer's guide to GEM, and various
magazines.

	I want to overcome the problems with the current interrupt structure
of the ST, and if I have to write my own code to handle the mouse and keyboard
as well as MIDI, I don't mind doing that.   That way I can control the priority
of the devices, and not spend time handling the mouse or keyboard when it
would effect MIDI I/O that I deem the most important task in recording.

	I ask that you Post instead of replying by mail, so everyone can
benefit from this invaluable discussion.  There is little or no other source
of public information that I cam aware of.  If there is, LET ME KNOW!

Thanks, and Atari Forever!

_John_ (sick with the flu, pardon my rambling in some spots)

sstreep@next.com (Sam Streeper) (02/17/91)

In article <3979@ryn.mro4.dec.com> miskinis@aisg.enet.dec.com (John Miskinis) writes:
>	I wrote routine that would scan my data, looking for corruption.
>I noticed that when a byte was WRONG, it was a copy of the last on, and
>one was missing (the interrupt fired, but the previuos byte was still in
>the ACIA buffer.
>
>	I then learned 6800 assembler, and wrote a routine that emulated the
>BIOS MIDI functions, and had the EXACT SAME PROBLEM.  I then added code to
>check the ACIA status, and found that there were overruns.  I had been using
>the KBD vector MIDISYS to point to my interrupt routine, which is really
>only as good as the routine that IT is called from, being the standard
>level 6 interrupt handler, which handles keyboard, mouse, and MIDI I/O.
>
>_John_ (sick with the flu, pardon my rambling in some spots)

You're exactly right that you're being bit by overruns.  If any routine spends
too long with interrupts disabled, or if you spend too long parsing mouse or
keyboard packets (which is done at the same interrupt level as the midi 
handler) and a second byte comes in, you get an overrun condition, and one 
symptom of this with the default hanlder is a repeated character.

I will post a couple of programs here that demonstrate how easy it is to get
this problem.  One program blasts ordered data out the midi port on a 
transmit buffer empty interrupt, so the data goes out as fast as possible.
The other, run on another machine, scans the received data and reports errors.

I sent these to Atari years ago asking for help, but I was smarter about
the problem than anyone I could get in touch with there...

The solution for me was to diverge from standard midi format and write
a packetized layered system that insures that the received data arrives
error free.  This obviously is not an option if you must talk to synths.

The problem should be solvable by rewriting the mouse and keyboard handlers,
minimizing other interrupts and critical sections.  Obviously this is a 
big job, so I wish you the best and let the world know when you find
a solution!  My test apps will be here soon...

-sam

miskinis@aisg.enet.dec.com (John Miskinis) (02/18/91)

Hi,

	It seems that the level 6 interrupt handler is at (hex) FC281C
accoring to a memory map I have.  (I loaned it out, but have called in
all documentation I own!).

	I have started writing the level 6 interrupt handler.  I currently
look FIRST in the MIDI ACIA, and then the KEYBOARD ACIA.  If I get a (hex)
61 (UNDO) I exit the program...  Otherwise I display the contents of my
MIDI byte count, MIDI overrun count, MIDI buffer empty count continuously.

	I tested it by attaching my TR505 drum machine to the ST, cranking
the tempo to full, and playing a pattern of several (simultaneous) drums on 
16th notes.  I HAVE NOT HAD AN OVERRUN YET!!!  And upon exiting, I simply
call the MFPINT with FC281C, and the original level 6 interrupt handler
is reinstalled.  Prior to this, the keyboard and mouse were inoperable
without a reboot every time I exited my program...

	But, until I write code to handle the mouse and keyboard such that
they behave correctly, I can't develop a nice user interface...

jhenders@jonh.wimsey.bc.ca (John Henders) (02/18/91)

In <1991Feb18.061505.7091@convex.com>, William Rosencranz writes:
>In article <3998@ryn.mro4.dec.com> miskinis@aisg.enet.dec.com (John Miskinis) writes:
>>	But, until I write code to handle the mouse and keyboard such that
>>they behave correctly, I can't develop a nice user interface...
>
>this may sound painfully simple (so simple it may not work - i have not
>tried it), but maybe u could install your routine, so that is handles the
>midi, then jumps to the old handler somehow. handle the midi yerself, let
>the bios do its thing with mouse/keys/etc. you would need to "clear" any
>midi event, so that the old handler never sees a midi event...
>

	Kbdvbase() returns a pointer to a vector table pointing to routines
to handle midivec,midi over-run error handling as well as other routines.
All that needs to be deone is to replace the slow handler with your own 
fast code, and stuff a pointer into the vector table. 

-- 
          John Henders        			jhenders@jonh.wimsey.bc.ca
       	  MIND over MIDI Productions	or ubc.cs!van-bc!jonh!jhenders
          Vancouver,B.C        			

rosenkra@convex.com (William Rosencranz) (02/18/91)

In article <3998@ryn.mro4.dec.com> miskinis@aisg.enet.dec.com (John Miskinis) writes:
>	But, until I write code to handle the mouse and keyboard such that
>they behave correctly, I can't develop a nice user interface...

this may sound painfully simple (so simple it may not work - i have not
tried it), but maybe u could install your routine, so that is handles the
midi, then jumps to the old handler somehow. handle the midi yerself, let
the bios do its thing with mouse/keys/etc. you would need to "clear" any
midi event, so that the old handler never sees a midi event...

another idea is to disassemble the old code from memory loc u gave,
and fix it, calling it your own. or maybe just jump to the code which
does non-midi stuff.

am i nuts? (don't answer that :-)

-bill
rosenkra@convex.com
--
Bill Rosenkranz            |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra
Convex Computer Corp.      |ARPA: rosenkra%c1yankee@convex.com