
Einbindung in eigene Programme 
Die Einbindung in eigene Programme funktioniert etwas anders  als 
im  Music-Mon 1.x.  Mit der 2.x-Routine ist es nicht mglich  die 
Geschwindigkeit  whrend  des Abspielens zu ndern oder  den  Zu-
griff auf einzelne Register zu verbieten.  Auf der anderen  Seite 
erhalten Sie eine schnellere Abpielroutine,  die flexibler einge-
bunden  werden  kann und die Mglichkeit des  automatischen  Ein- 
und  Ausblendens  mit frei einstellbaren  Geschwindigkeiten  hat. 
Wie  auch  bei  der alten Abspielroutine  knnen  die  Module  in 
smtliche Programmiersprachen eingebunden werden,  die einen Auf-
ruf von Maschinenroutinen ermglichen.  Im Lieferumfang  befinden 
sich  Beispielprogramme  fr Assembler,  GFA-Basic  und  Omikron-
Basic.  Die neue Abspielroutine bietet zwei verschiedene Mglich-
keiten  die  Module einzubinden.  Zum einen knnen Sie  die  Pro-
grammroutine   selbst   von  einem   geeigneten   Interrupt   aus 
(50/200Hz)  aufrufen  (dadurch knnen Sie den Zeitpunkt  nun  ab-
solut  individuell festlegen) oder Sie knnen die Einbindung  und 
den  Interrupt-Aufruf der Abspielroutine  berlassen.  Die  erste 
Mglichkeit wird im Assembler-Beispiellisting  demonstriert,  die 
zweite  in den beiden Basic-Beispielen.  Auerdem knnen Sie  die 
bergabeparameter  wahlweise auf dem Stack oder in  CPU-Registern 
bergeben.

1) die automatische Einbindung (vor allem fr "Hochsprachen")
Zunchst:  Die  Abspielroutine  wird  mit einem  Offset  von  +32 
angesprungen.  d.h.  wenn  sie die Abspielroutine an die  Adresse 
1000 geladen haben,  erfolgt der Ansprung bei 1032.  Alle berga-
ben erfolgen dann ber den Stack.  Der Stack mu nach  Beendigung 
der  Unterroutine selbststndig zurckgesetzt werden  (wenn  dies 
nicht von einer Hochsprache bernommen wird).
Die  Abspielroutine enthlt mehrere Unterroutinen,  die zur  Ein-
bindung  aufgerufen  werden  mssen  bzw.   knnen.   Welche  Un-
terroutine Sie aufrufen mchten,  legen Sie durch eine zu berge-
bende  Funktionsnummer fest (hnlich wie bei  Betriebssystem-Auf-
rufen).  Der  Ansprung  erfolgt bei allen Unterroutinen  bei  Ba-
sis+32.  Eventuelle  Rckgabeparameter  stehen zum  einen  in  D0 
sowie an der Adresse Abspielroutinenbasis+60 (Longword).  Im fol-
genden  eine  Auflistung der einzelnen Unterroutinen  samt  ihrer 
bergabeparameter,  die in der hier angegeben Reihenfolge berge-
ben werden mssen (nhere Erluterungen folgen im Anschlu):

*** MODUL-ART FESTSTELLEN ***
          Longword: Modulbasisadresse  
          Word:     Funktionsnummer #0 
          Rckgabe in D0.b: Bit 0 - (1)Digis, (0)keine Digis
                            Bit 1 - (1)200Hz, (0)50Hz

*** Frage nach der neuen Lnge nach der Digi-Konvertierung ***
          Longword: Modulbasisadresse  
          Word:     Funktionsnummer #1 
          Rckgabe in D0.L: neue Lnge

*** INIT 1 (gilt fr alle Module) ***
          Longword: Modulbasisadresse  
          Word:     Funktionsnummer #2 

*** INIT 2 (einmalige (!) Vorinitialisierung fr Digi-Module) ***
          Longword: Modulbasisadresse  
          Longword: Modulzieladresse  
          Word:     Funktionsnummer #3

*** START INTERRUPT ***
          Word:     gewnschter Interrupt:
                            0= VBL-QUEUE
                            1= VBL direkt (Systemroutine drin)
                            2= VBL direkt (Systemroutine raus)
                            3= Timer C (Systemroutine drin)
                            4= Timer C (Systemroutine raus)
          Word:     Funktionsnummer #4

*** STOP INTERRUPT ***

          Word:     Funktionsnummer #5

*** LAUTSTRKE EINSTELLEN / EIN(AUS)BLENDEN ***
          Word:     Lautstrke
                    0 = max., 15 = min.
                   -1 = keine nderung vornehmen
          Word:     Ein-/Ausblend-Geschwindigkeit
                    positive Werte blenden ein
                    negative Werte blenden aus
                    je nher der Wert an 0 ist, desto schneller
                    geht der Vorgang vor sich!
                    0 = kein Blenden

Hierzu nheres:
Ein  vom  Music-Mon  2.0 abgespeichertes Modul  wird  durch  zwei 
wesentliche Dinge charakterisiert:  Zum einen,  ob es  Digi-Drums 
enthlt  und zum Zweiten ob es Sounds beinhaltet,  die  100  oder 
200Hz bentigen.  Mit was fr einer Art Modul man es zu tun  hat, 
kann  man ber die Unterroutine mit der Fkts.Nummer #0  erfahren. 
Der  Funktion wird nur die Adresse bergeben,  an der  das  Modul 
steht.  Zurck erhlt man in D0 die Modulart.  Ist Bit 0 gesetzt, 
enthlt  das Modul Digis,  ist Bit 1 gesetzt,  so beinhaltet  das 
Modul  100/200Hz-Sounds.  Die  Modulart  hat  entscheidende  Kon-
sequenzen fr die weitere Einbindung:

Wenn  das Modul Digis enthlt,  mu die  Vorinitialisierung  auf-
gerufen werden sowie zustzlicher Speicher bereitgestellt    wer-
den (wieviel, kann auch ber eine Funktion erfragt werden)

Enthlt  das Modul 100/200Hz-Sounds bentigt  die  Abspielroutine 
einen Interrupt,  der  anstelle  von 50mal,  200mal  pro  Sekunde 
aufgerufen werden mu.  Dies bedeutet,  da der VBL nicht benutzt 
werden kann, sondern auf den Timer C ausgewichen werden mu.

Falls  es  sich  um  ein  Digi-Modul  handelt,   mu  wie   folgt 
fortgefahren werden:
Das Modul mu einer Umkonvertierung unterzogen werden,  durch die 
das  Modul  etwas lnger wird.  Diese Umkonvertierung  oder  auch 
Vorinitialisierung darf nur ein einziges mal vorgenommen  werden. 
Bei  der  Umkonvertierung  wird das  Modul  an  eine  anzugebende 
Adresse umkopiert.  Es mu also gengend Speicher fr den Zielbe-
reich  zur Verfgung gestellt werden,  der etwas grer sein  mu 
als  das  Modul auf Diskette.  Nach der Konvertierung  steht  das 
komplette  Modul  an der Zieladresse,  das  Original  wird  nicht 
nicht  mehr  bentigt,  d.h.  Sie knnen  den  Speicherblock  ge-
gebenfalls fr andere Zwecke nutzen.  Wie gro das Modul nach der 
Umkonvertierung  sein wird,  knnen Sie ber die  Funktion  No.#1 
erfragen,  oder aber auch Pi mal Daumen abschtzen: pro Digisound 
wird das Modul ca. 500 Bytes lnger.

Nachdem  sie dann einen entsprechend groen Speicherblock  reser-
viert   haben,   knnen  Sie  die  Vorinitialisierung   mit   der 
Fkts.Nummer #3 vornehmen.  Dabei bergeben Sie die  Moduladresse, 
sowie  den Zielblock,  in den das Modul  hineinkonvertiert  wird. 
Wie  schon gesagt,  wird das Original-Modul dann nicht  mehr  be-
ntigt!

Was nun folgt gilt wieder fr alle Modultypen gemeinsam:
Nun folgt die eigentliche Haupt-Initialisierung des  Moduls,  die 
so oft wie man mchte erneut aufrufen kann.  Jeder erneute Aufruf 
verursacht  einen Neustart des Moduls (es geht wieder  von  vorne 
los).  bergeben  wird hier die Adresse,  an der das Modul  liegt 
(Achtung:  Bei Digi-Modulen ist das dann die neue Adresse,  wohin 
das  Modul konvertiert wurde!).  Dann wird die  Funktion  No.  #2 
aufgerufen und das Modul ist fertig initialisiert. Noch luft die 
Musik  jedoch nicht,  die Abspielroutine mu jetzt noch in  einen 
Interrupt eingehngt werden.

Dies  geschieht mit der Funktionsnummer #4.  bergeben wird  eine 
Nummer  zwischen  0 bis 4.  Damit  wird  festgelegt,  in  welchen 
Interrupt sich die Routine einhngen soll.  Achtung:  Handelt  es 
sich um ein Modul mit 100/200Hz-Sounds mssen Sie auf jeden  Fall 
den Timer C einsetzen!

        0 = VBL-Queue (ein freier Slot wird automatisch 
                       gesucht)
        1 = VBL direkt (Vektor bei $70)
                       Die VBL-Routine des Betriebssystems
                       wird weiterhin angesprungen
        2 = VBL direkt Die Betriebsystem-VBL-Routine wird 
                       einfach rausgeschmissen
        3 = Timer C    Die Timer-C-Routine des Betriebsystems
                       bleibt weiterhin aktiv
        4 = Timer C    Die Timer-C-Routine des Betriebssystems
                       wird rausgeschmissen

Nach  diesem Aufruf luft die Musik,  und zwar solange,  bis  Sie 
die  Funktion No.#5 (STOP INTERRUPT) aufrufen,  dadurch wird  die 
Musik vollautomatisch wieder aus dem Interrupt ausgehngt.

Zu bemerken ist noch,  da die Digi-Sounds den Timer D  benutzen, 
d.h.  durch  Mausbewegungen wrde der Maus-Interrupt den Timer  D 
stren  und  die  Digis wrden nicht  mehr  sauber  klingen.  Die 
Abspielroutine  patched jedoch vollautomatisch  bei  Digi-Modulen 
diesen Interrupt!

So,  damit  wre die eine Methode der Einbindung beschrieben  und 
die zweite kann folgen.  Die zweite Methode ist hauptschlich fr 
Assembler-Programierer  gedacht,  die  sich auch  mit  Interrupts 
etwas genauer auskennen. Auch hier gibt es einzelne Unterroutinen 
(aber ein paar mehr),  deren bergabeparameter allerdings in  den 
CPU-Registern  (A0/A1/D0/D1) bergeben werden.  Auerdem  besitzt 
hier jede Funktion seine eigene Ansprungadresse:

*** Frage nach der neuen Lnge nach der Digi-Konvertierung ***
        Ansprungadresse: Routinenbasis +0 
        bergabe:        A0.L = Moduladresse
        Rckgabe:        D0.L = neue Lnge

*** INIT 1, fr alle Module gemeinsam ***
        Ansprungadresse: Routinenbasis +4
        bergabe:        A0.L = Moduladresse
        
*** INIT 2, einmalige Vor-Initialisierung fr Digi-Module ***
        Ansprungadresse: Routinenbasis +8 
        bergabe:        A0.L = Moduladresse
                         A1.L = Zieladresse

*** SOUND1, eigentliche Soundroutine, Aufruf mit 50Hz  ***
        Ansprungadresse: Routinenbasis +12
 
*** SOUND2, eigentliche Soundroutine, Aufruf mit 200Hz ***
        Ansprungadresse: Routinenbasis +16

*** Fast-Digi on/off ***
        Ansprungadresse: Routinenbasis +20
        bergabe:        D0.w = Ein (<>0) / Aus (=0)

*** Lautstrke ndern / Ein(Aus)blenden ***
        Ansprungadresse: Routinenbasis +24
        bergabe:        D0.b = Laustrke setzen (0 = laut)
                                -1 fr keine nderung
                         D1.b = einblenden (positiver Wert)
                                ausblenden (negativer Wert)
                                je nher der Wert an null, desto
                                schneller das blenden; 0 = aus!

*** Modul-Typ erfragen ***
        Ansprungadresse: Routinenbasis +28
        bergabe:        D0.L = Moduladresse
        Rckgabe:        D0.b = Bit 0 = Digi on(1)/off(0)
                                Bit 1 = 50Hz(0)/200Hz(1)

*** Lamer-Header, hierber erfolgt die Art des Routinenaufrufs  ***
*** der ersten, schon beschriebenen, Methode                    ***                        
        Ansprungadresse: Routinenbasis +32
        bergabe:        ber Stack, siehe oben
        Rckgabe:        eventuell D0, je nach Funktionsnummer

*** Digi-Interrupt (Timer D) abschalten ***
        Anprungadresse:  Routinenbasis +36
        bergabe:        keine

*** TON AUS, setzt die Lautstrke aller 3 Kanle auf null ***
        Anpsrungadresse: Routinenbasis +40
        bergabe:        keine

*** Acia-Interrupt (Maus/Tastatur) patchen, damit Digis sauber
    klingen                        
        Ansprungadresse: Routinenbasis +44
        bergabe:        keine

*** Acia-Interrupt-Patch wieder aufheben ***
        Ansprungadresse: Routinenbasis +48
        bergabe:   keine

*** Timer C - patchen (damit Digi-Interrupt diesen unterbrechen
    kann)
        Ansprungadresse: Routinenbasis +52

*** Timer C - Patch rckgngig machen ***
        Ansprungadresse: Routinenbasis +56

*** D0-Kopie bei eventuellem Rckgabeparameter ***
        Adresse: Routinenbasis +60

Bei  der zweiten Methode der Einbindung mu wesentlich  mehr  von 
Hand gemacht werden,  vor allem das Einhngen in einen Interrupt. 
Die  zweite Methode ist eigentlich nur fr  erfahrene  Assembler-
Programmierer  gedacht,  die  drften die zweite  Methode  jedoch 
begren,  da man einen greren Einflu hat. Die Routinen retten 
alle Register,  bis auf die,  die zur bergabe/Rckgabe verwendet 
werden.

Der Aufruf ist denkbar einfach:  Die entsprechenden Register  mit 
den (eventuellen) bergabewerten bergeben,  dann die Routine mit 
"bsr" an der jeweiligen Adresse anspringen - das ist  alles!  Der 
Aufruf mu im Supervisor-Mode geschehen!
 
Zunchst  einmal  wird genauso wie bei der  ersten  Methode  ver-
fahren, bis zu dem Punkt, wo die Routine in den Interrupt gehngt 
wird  (die Routinen sind dieselben).  Hier trennen sich  nun  die 
Wege,  da dieser Job hier selbst erledigt werden mu (oder besser 
darf).  Erst einmal sollte man sich klar machen,  da Module  mit 
100/200Hz-Sounds einen Interrupt mit 200Hz bentigen,  sonst rei-
cht einer mit 50Hz (z.B.  VBL).  Wenn das geklrt ist,  rufen Sie 
selbststndig 50 bzw.  200 mal pro Sekunde die Soundroutine  auf. 
Der  Ansprung erfolgt bei 50Hz an der Adresse Routinenbasis  +12, 
bei  200Hz  an der Adresse Routinenbasis  +16.  Die  CPU-Register 
mssen dabei nicht selbststndig gerettet werden.

Wollen  Sie die Musik dann wieder stoppen,  brauchen sie  einfach 
die  Soundroutine  nicht mehr  anspringen.  Eventuell  geben  die 
Soundkanle jetzt noch einen konstanten Ton ab. Rufen Sie deshalb 
die Routine "TON AUS" auf.  Fr den Fall,  da Sie ein Digi-Modul 
abgespielt  haben,  sollten  Sie  auerdem  auf  jeden  Fall  die 
Funktion "Digi-Interrupt aus" aufrufen, da dieser sonst eventuell 
noch luft und dies einen Absturz verursachen knnte!

So,  nun noch folgendes: Falls Sie ein Digi-Modul abspielen, kann 
der Tastatur-Interrupt die Ausgabe stren. Um dies zu verhindern, 
rufen Sie "ACIA-Interrupt patchen" einmal auf (am besten noch vor 
dem  Einhngen der Soundroutine).  Nach dem Abspielen des  Moduls 
mu   dies  auf  jeden  Fall  mit  "Acia-Interrupt-Patch   wieder 
aufheben" wieder rckgngig gemacht werden, sonst gibt's Bomben!

Das gleiche kann mit dem Timer-C gemacht werden,  der,  falls sie 
die  Betriebssystemroutine nicht rausschmeissen,  den Digis  auch 
rger macht (jedoch nicht viel).

Falls  Sie  die Routine von einem Timer-Interrupt  aus  aufrufen, 
sollten  Sie bei Digi-Modulen vor dem Ansprung  der  Soundroutine 
auf  jeden Fall die Interrupt-Maske auf 4  heruntersetzen,  damit 
der Timer D durchkann,  die Betriebsystem-Timer C-Routine  werden 
Sie  in  diesem Fall wahrscheinlich sowieso weglassen  und  somit 
kann diese den Digis auch keinen rger machen.

So,  das war's schon beinahe,  der Digi-Fast-Mode ist noch  nicht 
geklrt.  Wenn Sie den Fast-Mode aktivieren,  kostet die  Ausgabe 
der Digis etwas weniger Rechenzeit (ca.  15% weniger). Allerdings 
mssen  Sie  dann strikt darauf achten,  da nirgendwo  in  Ihrem 
Programm  (oder vor allem in einem  Betriebssysteminterrupt)  auf 
ein  Soundchip-Register  zugegriffen  wird,   ohne  vorher   alle 
Interrupts  zu  sperren und danach mit  move.b  #8,$ff8800.w  das 
Register  8  (Lautstrke  Kanal  A)  wieder  anzuwhlen  und  die 
Interrupts wieder freizugeben.  Ich wiederhole:  Dies mu  strikt 
berall  im  Programm eingehalten werden.  Achten  Sie  besonders 
darauf,  da  Betriebssystemroutinen dieser  Bedingung  natrlich 
nicht gerecht werden. Am Besten schmeit man smtliche Interrupts 
des Betriebssystems raus (VBL,  Timer C).  Es gibt einen  kleinen 
Indikator, mit dem man feststellen kann, ob die Bedingung zu 100% 
erfllt  ist:  Findet irgendwo noch ein Versto gegen  die  Regel 
statt, flackert die Floppy-LED!

So, am Besten schauen Sie sich jetzt mal die Einbindungsbeispiele 
auf Diskette an.


