MIDI.PRG
********

(The English part is appended at the German, look for it.)

Dies ist ein Treiber zur Nutzung der MIDI-Schnittstelle ber die in 
SERSOFST.TXT definierten Filefunktionen.


Allgemeines
-----------
########## momentan ist das noch eine Experimentalversion ###########
Dieser Treiber gehrt zum HSMODA-Paket. Er ist nicht fr Musiksoftware 
gedacht, die die MIDI-Schnittstelle zu ihrem ursprnglichen Zweck benutzt, 
sondern zur "ganz normalen" Datenbertragung. Wer die MIDI-Schnittstelle 
nicht zur "ganz normalen" Datenbertragung nutzt, braucht diesen Treiber 
nicht.


Kommunikationsparameter
-----------------------
Es wird alles untersttzt, was das ACIA und die RxD/TxD-Schnittstelle 
knnen.
Baudraten: 31250, 7812
Handshake: "keiner", "XON/XOFF"
Zeichenformate: 7e2, 7o2, 7e1, 7o1, 8n2, 8n1, 8e1, 8o1


Konfiguration
-------------
Die Konfiguration erfolgt mit dem SETTER.TTP. Zur Bedienung siehe 
SETTER.TXT.

Momentan kann man nur die Empfangs- und Sendepuffergre einstellen, die 
standardmig 256 Byte getrgt.



(Interna:) Implementierungsvarianten
------------------------------------
Das Senden erfolgt auch interruptgesteuert. Falls man im Sendeinterrupt 
nochmal extra Statusregister Bit1 abfragt (braucht man auch nicht, denn 
wenn im Polling gesendet wird, dann ist der Sendepuffer per Definition 
leer (sonst gibt es sowieso Chaos), und es kann deshalb ohnehin nichts in 
den ACIA geschrieben werden), braucht man Midiws und Bconout-MIDI nicht 
abzufangen, da diese direkt im Polling senden und die Strukturen dieses 
Treibers nicht stren. Sie knnten sich zwar in eine Interruptsendung 
einmischen, das sollte aber nicht passieren, da entweder alte Programme 
diese nicht-Interrupt-Aufrufe benutzen (wo das Polling-Midiws 
mglicherweise zwecks Kompatibilitt ntig ist) oder neue Programme ber 
GEMDOS oder die hhere BIOS-Nummer arbeiten. Da nmlich MIDI im BIOS nicht 
immer #3 ist, mu man ohnehin im RSVF die Nummer eines extra eingehngten 
Treibers eintragen und nur zu Kompatibilittszwecken das alte #3 
untersttzen.

Es ist zu entscheiden, wie weit man die Optimierung (tausche Speicherplatz 
und bersichtlichkeit gegen Geschwindigkeit) treibt. 31250Bd bedeutet beim 
Empfang eine Interruptfrequenz von 3125Hz bei 8N1 und eine zu 
unterschreitende Interruptantwortzeit von 320us. Der 68000/8MHz braucht 
0.5us fr einen WORD-Speicherzugriff. Beim im TOS vorhandenen Sichern von 
8 Registern (als LONG) vergehen also schon 8us, zustzlich zu der reinen 
Reaktionszeit der CPU. Nach der Bearbeitung werden nochmal 8us im 
Interrupt zur Wiederherstellung verbraucht. Der IKBD-ACIA ist mit 7812.5Bd 
vergleichsweise langsam.

Direkt im MFP-Interrupt, sehr schnell, alle MIDI-Vektoren in KBDVECS sind 
tot. ### Genau so mache ich es erstmal ### !!! Drfte evtl mit einiger 
Musiksoft inkompatibel sein, egal.

### momentan BIOS-Funktionen nur ber eigene Nummer, alte BIOS und 
XBIOS-IOREC-MIDI noch nicht ersetzt (aufruf kann zu Absturz, Hngenbleiben 
oder so fhren), Nummer siehe RSVF-Objekt ####

Schmeit bei Installation alles andere aus dem MFP-I4-Interrupt raus, wie 
z.B. Templmon. (Also Templmon erst nach diesem Treiber starten)



Andere Varianten, evtl mal alternativ realisieren:

Nur als midisys(), etwas langsamer, nur midivec() und vmiderr() tot.

Als midisys(), langsamst, midivec() und vmiderr() werden benutzt, 
restliche Interruptbedingungen bearbeitet midisys() selbst.




(Fr Programmierer:) Die MIDI-Schnittstelle auf der Softwareseite
=================================================================

Im TOS werden MIDI-Daten immer direkt gesendet. Es gibt keinen 
Sende-IOREC. Nur Empfangsdaten werden im Interrupt behandelt, ein 
Empfangs-IOREC existiert (XBIOS 14 Iorec (Gert 2)). XBIOS 15 Rsconf 
existiert nicht. Zustzlich gibt es XBIOS 12 Midiws zum Versenden von 
Bytefolgen. Diese Funktion arbeitet im Polling. Im BIOS ist MIDI 
normalerweise Gert 3, auer bei BIOS 8 Bcostat, dort ist es 4.

XBIOS 34 Kbdvbase liefert einen Datenblock, der Zeiger auf einige Routinen 
enthlt, die mit MIDI und dem IKBD zusammenhngen. Leider werden diese 
Routinen oft falsch beschrieben, auch im Profibuch sind Fehler drin.

MIDI-ACIA und IKBD-ACIA liefern ihre Interruptmeldung aktiv-oder-verknpft 
(ihre L-aktiven Open Collector Ausgnge sind miteinander verbunden) ber 
den gleichen Eingang (I4) des MFP (ST-MFP), der auf den 
MFP-Interruptvektor auf Adresse $0118 fhrt.

Hier lauert bereits die erste Falle: Der MFP erzeugt einen Interrupt nur 
bei einer H/L-Flanke am I4-Eingang. Diese Flanke tritt nur beim Wechsel 
von "beide ACIA wollen keinen Interrupt" zu "mindestens ein ACIA fordert 
Interrupt" auf. Setzt man jetzt die Interruptforderung nur im MFP zurck 
und bearbeitet nicht beide ACIA so lange, bis I4 wieder H wird, so bleibt 
I4 auf L und der MFP wird keine ACIA-Interrupts mehr melden. Dieser Fall 
kann z.B. eintreten, wenn in einer sehr frhen Phase der 
Systeminitialisierung Daten ber den MIDI-Port reinkommen.


Kbdvbase (XBIOS 34)
-------------------
Diese Funktion liefert einen Zeiger auf einen Datenblock mit Zeigern auf 
verschiedene Routinen im Zusammenhang mit MIDI und IKBD.

typedef struct {
 void (*midivec)();  /* Midi-Eingabe */
 void (*vkbderr)();  /* Tastaturfehler (default: nur RTS) */
 void (*vmiderr)();  /* MIDIfehler (default: nur RTS) */
 void (*statvec)();  /* Status des IKBD gelesen (default: nur RTS) */
 void (*mousevec)(); /* Mausabfrage */
 void (*clockvec)(); /* Uhrzeitabfrage */
 void (*joyvec)();   /* Joystickabfrage (default: nur RTS) */
 void (*midisys)();  /* MIDI-Systemvektor */
 void (*ikbdsys)();  /* IKBD-Systemvektor */
 WORD drvstat;       /* IKBD-Treiberstatus (benutzt als zwei Bytes) */
} KBDVECS;

Erzeugt I4 des MFP einen Interrupt, so werden in der Serviceroutine 
nacheinander midisys() und ikbdsys() aufgerufen. Falls I4 jetzt immer noch 
L (also aktiv) ist, wird der Aufruf dieser beiden Routinen solange 
wiederholt, bis I4 nach der Bearbeitung von ikbdsys() endlich H ist. Dann 
wird der Interrupt im MFP als bearbeitet markiert und die Serviceroutine 
beendet. Die XXXXsys() mssen selbst anhand des Statusregisters ihrer ACIA 
feststellen, ob sie arbeiten oder gleich zurckkehren. Vor dem Aufruf der 
Routinen wurden die Register A0-A3/D0-D3 gesichert, so da man sie 
benutzen kann. Sicherheitshalber sollte man aber nur A0-A2/D0-D2 nutzen, 
wie es die Konventionen der meisten C-Compiler auf dem Atari erlauben. 
Diese ganzen Aktionen laufen bei einem Interrupt Priority Level von 6 ab, 
so da keine weiteren Interrupts dazwischen kommen knnen. Wenn man den 
IPL heruntersetzt (zeitweilig in der XXXXsys-Routine), so knnen vom MFP aus 
wenigstens hherpriorisierte Interrupts wie der fr MODEM1 
dazwischenkommen.

vmiderr() und vkbderr() werden von midisys() bzw. ikbdsys() aufgerufen, 
wenn ein Empfangspufferberlauf vorlag. Das empfangene Zeichen wird 
trotzdem in D0.b bergeben. Die Fehlerbedingung wurde im ACIA bereits 
zurckgesetzt. Andere Fehlerbedingungen werden ignoriert und fhren nicht 
zum Aufruf der vXXXerr(). Falls man eigene XXXXsys()-Routinen einsetzt, 
werden die vXXXerr() also nur noch aufgerufen, wenn es die eigene 
XXXXsys()-Routine tut. Die vXXXerr() drfen A0-A2/D0-D2 benutzen und 
bestehen im TOS nur aus einem RTS.

midivec() wird von midisys() aufgerufen, wenn ein Zeichen von der 
MIDI_ACIA fehlerfrei empfangen wurde. Das Zeichen wird in D0.b bergeben. 
Die Routine darf A0-A2/D0-D2 benutzen und schreibt im TOS das Zeichen in 
den MIDI-Empfangspuffer.

Alle anderen Routinen werden von ikbdsys() aufgerufen, nachdem ikbdsys 
alle Byte empfangen hat, die zu dem entsprechenden Paket gehren. Diese 
Byte wurden in einem Puffer gesammelt und der Routine wird ein Zeiger auf 
diesen Puffer im Register A0 und auf dem Stack bergeben. Die Routinen 
drfen A0-A2/D0-D2 benutzen. Sie sollten so kurz wie mglich sein, denn 
eine Laufzeit von 1ms (wie im Profibuch angegeben) begrenzt die ber 
MODEM1 fehlerfrei empfangbare Datenrate bereits auf nur 9600Bd (die Daten 
von MIDI mit 31250Bd gehen schon viel frher hops). Eine Alternative sind 
reentrante Routinen (also den Pufferinhalt erst kopieren), die den IPL 
whrend ihrer Laufzeit auf weniger als 6 setzen und so wenigstens den 
MODEM1-Empfang (der im MFP hher priorisiert ist) erlauben.

Wenn man diese 4 anderen Routinen betrachtet, so fehlt eine Routine, die 
die normalen Tastendrcke (Byte $00-$F5) verarbeitet. Der Zeiger auf diese 
Routine liegt erfahrungsgem (das ist nicht dokumentiert) genau vor der 
KBDVECS-Struktur. Dieser Routine wird das Zeichen in D0.b bergeben und 
sie darf A0-A2/D0-D2 benutzen. Sie verarbeitet die Zeichen und schreibt 
entsprechende Daten in den Empfangspuffer, der dann z.B. vom 
Bconin-Tastatur gelesen wird. Beim TOS2.06 ist jeder Empfangspuffereintrag 
ein LONG.

mousevec() kann nicht nur vom ikbdsys(), sondern auch von der 
undokumentierten Tastenroutine und von der Tastaturrepeat-Routine 
aufgerufen werden, wenn die Tastatur zur Mausemulation benutzt wird.

drvstat ist immer dann ungleich 0, wenn ibkdsys() gerade ein Paket 
zusammensammelt. Undokumentiert wird beim TOS2.06 das Highbyte zum 
Speichern der internen Routinennummer (abgeleitet aus dem empfangenen 
Header) und das Lowbyte als Abwrtszhler fr die Anzahl der noch zu 
empfangenden Byte benutzt.

Wenn man einer der 4 Routinen selbstgebastelte Pakete zukommen lassen 
will, so mu man sicherstellen, da diese (im TOS) nicht reentranten 
Routinen nicht zuflligerweise auch aus dem Interrupt heraus aufgerufen 
werden. Also entweder IPL auf 6 oder 7 setzen, oder in KBDVECS kurzzeitig 
eine Dummy-Routine (die sich mglicherweise nur das Paket irgendwo merkt) 
anstelle der Originalroutine installieren, die man gerade selbst aufruft.



Versionen
---------
(Datum in der Form Jahr-Monat-Tag)
1994-08-27  sollte erstmalig richtig funktionieren
1994-10-24  TIOCM_RER (overrun, frame, parity) mit TIOCCTLGET erfragbar
1994-12-30  schnelle Bconout-Parameterbergabe gendert 
(und MAPT_APP/MAPT_OVE Funktiosnummer)
1995-01-15  luft jetzt mit TOS-Versionen vor 2.00

Harun Scheutzow, Berlin den 27.08.1994 und spter



MIDI.PRG
********

This is a SERSOFST.TXT-conform driver for the MIDI-interface. You 
shouldn't use it together with music programs using the MIDI-interface 
because it is intended for file transfer and terminal purposes.

I don't have the time to translate the whole text. If nobody else does it, 
sorry, English-speaking world, you will never got an English version.

This driver installs with the GEMDOS-name "MIDI" and the first empty BIOS 
device number. It is fully interrupt driven. It allows the two baud rates 
possible on the MIDI-port(31250, 7812). It supports "none" and "XON/XOFF" 
handshake. Zmodem usually escapes the XON and XOFF characters that's why 
you can use this handshake with Zmodem. I got transfer rates of 
approximately 3000cps, that means near the physical limit.

!!! Important: This is only a RSVF-driver, it doesn't replace the old 
BIOS-MIDI-numbers nor the XBIOS-Midiws-function. Use it only if you need a 
MIDI-RSVF-driver. !!!
