home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
telecomm
/
hsmoda06
/
hsm_doku
/
midi_x.txt
< prev
next >
Wrap
Text File
|
1995-01-22
|
11KB
|
239 lines
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 gehört zum HSMODA-Paket. Er ist nicht für Musiksoftware
gedacht, die die MIDI-Schnittstelle zu ihrem ursprünglichen Zweck benutzt,
sondern zur "ganz normalen" Datenübertragung. Wer die MIDI-Schnittstelle
nicht zur "ganz normalen" Datenübertragung nutzt, braucht diesen Treiber
nicht.
Kommunikationsparameter
-----------------------
Es wird alles unterstützt, was das ACIA und die RxD/TxD-Schnittstelle
können.
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 Sendepuffergröße einstellen, die
standardmäßig 256 Byte geträgt.
(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 stören. Sie könnten sich zwar in eine Interruptsendung
einmischen, das sollte aber nicht passieren, da entweder alte Programme
diese nicht-Interrupt-Aufrufe benutzen (wo das Polling-Midiws
möglicherweise zwecks Kompatibilität nötig ist) oder neue Programme über
GEMDOS oder die höhere BIOS-Nummer arbeiten. Da nämlich MIDI im BIOS nicht
immer #3 ist, muß man ohnehin im RSVF die Nummer eines extra eingehängten
Treibers eintragen und nur zu Kompatibilitätszwecken das alte #3
unterstützen.
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 für einen WORD-Speicherzugriff. Beim im TOS vorhandenen Sichern von
8 Registern (als LONG) vergehen also schon 8us, zusätzlich 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 ### !!! Dürfte 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, Hängenbleiben
oder so führen), Nummer siehe RSVF-Objekt ####
Schmeißt 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.
(Für 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 (Gerät 2)). XBIOS 15 Rsconf
existiert nicht. Zusätzlich gibt es XBIOS 12 Midiws zum Versenden von
Bytefolgen. Diese Funktion arbeitet im Polling. Im BIOS ist MIDI
normalerweise Gerät 3, außer bei BIOS 8 Bcostat, dort ist es 4.
XBIOS 34 Kbdvbase liefert einen Datenblock, der Zeiger auf einige Routinen
enthält, die mit MIDI und dem IKBD zusammenhängen. Leider werden diese
Routinen oft falsch beschrieben, auch im Profibuch sind Fehler drin.
MIDI-ACIA und IKBD-ACIA liefern ihre Interruptmeldung aktiv-oder-verknüpft
(ihre L-aktiven Open Collector Ausgänge sind miteinander verbunden) über
den gleichen Eingang (I4) des MFP (ST-MFP), der auf den
MFP-Interruptvektor auf Adresse $0118 führt.
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 zurück
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 frühen 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() müssen selbst anhand des Statusregisters ihrer ACIA
feststellen, ob sie arbeiten oder gleich zurückkehren. 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 können. Wenn man den
IPL heruntersetzt (zeitweilig in der XXXXsys-Routine), so können vom MFP aus
wenigstens höherpriorisierte Interrupts wie der für MODEM1
dazwischenkommen.
vmiderr() und vkbderr() werden von midisys() bzw. ikbdsys() aufgerufen,
wenn ein Empfangspufferüberlauf vorlag. Das empfangene Zeichen wird
trotzdem in D0.b übergeben. Die Fehlerbedingung wurde im ACIA bereits
zurückgesetzt. Andere Fehlerbedingungen werden ignoriert und führen 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() dürfen 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 gehören. 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
dürfen A0-A2/D0-D2 benutzen. Sie sollten so kurz wie möglich 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 früher hops). Eine Alternative sind
reentrante Routinen (also den Pufferinhalt erst kopieren), die den IPL
während ihrer Laufzeit auf weniger als 6 setzen und so wenigstens den
MODEM1-Empfang (der im MFP höher priorisiert ist) erlauben.
Wenn man diese 4 anderen Routinen betrachtet, so fehlt eine Routine, die
die normalen Tastendrücke (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 Abwärtszähler für 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 zufälligerweise auch aus dem Interrupt heraus aufgerufen
werden. Also entweder IPL auf 6 oder 7 setzen, oder in KBDVECS kurzzeitig
eine Dummy-Routine (die sich möglicherweise 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-Parameterübergabe geändert
(und MAPT_APP/MAPT_OVE Funktiosnummer)
1995-01-15 läuft jetzt mit TOS-Versionen vor 2.00
Harun Scheutzow, Berlin den 27.08.1994 und später
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. !!!