← TOS 04 / 1993

Tips und Tricks zum Falcon

Programmieren

Es will mir einfach nicht gelingen, den Overscan-Modus des Falcon einzuschalten. Zwei Bomben sind stets die Folge eines Versuchs. Was mache ich falsch?

Der Overscan-Modus des Falcon ist nur mit einem RGB-Monitor oder Fernseher darstellbar. Außerdem müssen Sie folgendes beachten: Der Bildschirmspeicher einer Overscan-Auflösung ist natürlich größer und benötigt entsprechend mehr Speicher. Bevor Sie also die Auflösung wechseln, müssen Sie daher einen ausreichend großen Speicherblock reservieren und diesen als neuen Bildschirmspeicher definieren.

Der Falcon unterstützt auch 16-Bit-Samples. Gibt es bereits ein Standard-Format für solche Dateien?

Die Firma Mitchtron verwendet seit einiger Zeit das sogenannte AVR-Format für Samples. Den Aufbau entnehmen Sie Tabelle 1. Beachten Sie: Die Länge des Samples (»laenge«) wird stets in Anzahl der Samples angegeben, nicht in Byte. Der linke und rechte Kanal eines Stereo-Samples zählt dabei als ein Sample.

Beispiel: Ist die Aufnahme-Datei bei 8 Bit Stereo 1000 Byte lang, enthält sie 500 Samples, bei 16 Bit Stereo nur 250. Entsprechend zeigen »loop_anfang« und »loop_ende« auf das Anfangs- und Endsample der zu loopenden Sequenz.

Der CODEC des Falcon liefert immer »signed« Samples. Möchten Sie eine AVR-Datei anderer Sampler spielen, die »unsigned« Samples erzeugen, müssen Sie diese vorher umrechnen. Die Samplefrequenz belegt nur die unteren drei Byte der Variable »frequenz«. Das obere Wort ist für spezielle Abtastraten der Sampler von Mitchtron vorbehalten und sollte daher ausmaskiert werden. Mitchtron empfiehlt, vor jedem Eintragen neuer Werte die gesamte Struktur zu löschen, um vorhandenen Datenmüll damit zu entfernen.

Laut Atari dient die Funktion »setinterrupt()« dem Erzeugen eines Interrupts am Ende eines mittels »setbuffer()« definierten Aufnahme- oder Wiedergabepuffers. Bei mir rührt sich aber gar nichts.

Mit dem alleinigen Aufruf von »setinterrupt()« ist es nicht getan. Abhängig von der gewählten Interruptquelle (MFP i7 oder Timer A), benötigen Sie noch eine Interrupt-Routine, die beim Auftreten eines Interrupts ein Flag setzt. Dieses Flag prüft das Hauptprogramm in regelmäßigen Abständen und reagiert entsprechend. Das Listing zeigt zwei Routinen zur Installation des MFPi7-Interrupts. In C sieht der Aufruf dann wie folgt aus:

void setupi7 (void); void i7_disable (void); extern int i7_occur; int main (void) { setupi7 (); /* Interrupt-Routine installieren*/ ... /* Hier steht Ihr Hauptprogramm */ i7_disable(); /* interrupt-Routine verwerfen */ return 0; }

Ihre Routine wartet, bis die Variable »i7_occur« ungleich Null ist und reagiert auf den Interrupt. Natürlich dürfen Sie nicht vergessen, i7_occur wieder zurückzusetzen.

while (!i7_occur); i7_occur = 0; /* Variable zurücksetzen */

(ah)

; Interruptroutine für »setinterrupt()« ; (C) 1993 ICP-Verlag, TOS-Magazin export i7_disable, setupi7, i7_occur AER equ $fffa03 ; Aktive-Edge-Register DDR equ $fffa05 ; Data-Direction-Register IERA equ $fffa07 ; Interrupt-Enable-Register IPRA equ $fffaOb ; Interrupt-Pending-Register ISRA equ $fffa0f ; Interrupt-in-Service-Register IMRA equ $fffa13 ; Interrupt-Mask-Register ; Interrupt ausschalten und alte MFPO-Routine restaurieren i7_disable: movem.l d0-d2/aO-a2, -(sp) ;Register retten clr.l -(sp) ; Supervisor einschalten move.w #32, -(sp) ; SUPER() trap #1 ; GEMDOS addq.l #06, sp ; Stack aufräumen move.l d0, oldssp ; Stackpointer retten bclr #7, IERA ; Interrupt ausschalten bclr #7, IMRA ; Interrupt ausmaskieren bclr #7, IPRA ; Keine „schwebenden“ I. bclr #7, ISRA ; Keine „In-Service“ I. move.l old_mfpi7, $13c ; alte Routine restaurieren move.b old_iera, IERA ; Register auf alte move.b old_imra, IMRA ; Werte setzen move.b old_ipra, IPRA move.b old_isra, ISRA move.b old_ddr, DDR move.b old_aer, AER move.l old_ssp, -(SP) ; in User-Modus zurück move.w #32, -(sp ; SUPER() trap #1 ; GEMDOS addq.l #06,sp ; Stack aufräumen movem.l (sp)+, d0-d2/a0-a2 ; Register restaurieren rts ; zurück ins Hauptprogramm ; Interrupt-Routine installieren setupi7: movem.l d0-d2/a0-a2, -(sp) ; Register retten clr.l -(sp) ; Supervisor einschalten move.w #32, -(sp) ; SUPER() trap #1 ; GEMDOS addq.l #06, sp ; Stack aufräumen move.l d0, old_ssp ; Stackpointer retten move.b IERA, old_iera ; alte Werte move.b IMRA, old_imra ; sichern move.b IPRA, old_ipra move.b ISRA, old_isra move.b DDR, old_ddr move.b AER, old_aer bclr #7, IERA ; MFPi7 ausschalten bclr #7, IMRA ; ausmasieren bclr #7, IPRA ; keine „schwebenden“ I. bclr #7,ISRA ; keine „In-Service“ I. bclr #7, DDR ; Port 7 ist Ausgang movea.l #$13c, a0 ; MFPi7-Vektor move.l (a0), old_mfpi7 ; alte Routine retten move.l #i7_int, (a0) ; Interrupt installieren bset #7, AER ; Interrupt bei Low->High bset #7, IMRA ; MFPi7 setzen bset #7, IERA ; und einschalten move.l old_ssp, -(sp) ; in User-Modus zurück move.w #32, -(sp ; SUPER() trap #1 ; GEMDOS addq.l #06, sp ; Stack aufräumen movem.l (sp)+, d0-d2/a0-a2 ; Register restaurieren rts ; Zurück ins Hauptprogramm i7_int: move.w #1, i7_occur bclr #7, IPRA ; keine „schwebenden“ I. bclr #7, ISRA ; keine ‚In-Service“ I. bset #7, IMRA ; MFPi7 setzen rte ; „return from Interrupt“ .bss old_ssp: ds.l 1 ; alter Stackpointer old_mfpi7: ds.l 1 ; alte MFPi7-Routine i7_occur: ds.l 1 ; Flag für Interrupt old_iera: ds.b 1 ; alte MFP-Register old_imra: ds.b 1 old_ipra: ds.b 1 old_isra: ds.b 1 old_ddr: ds.b 1 old_aer: ds.b 1 end

Wenn ich zu laute Musik mit dem Falcon digitalisiere, kommt es im CODEC zu einem Überlauf, den ich laut Dokumentation nur mit »sndstatus (1);« abfragen und zurücksetzen kann. Dabei wird allerdings die gesamte Soundhardware zurückgesetzt. Gibt es keinen anderen Weg?

Es genügt vollkommen, den Status des CODEC über »sndstatus(0);« zu erfragen. Beachten Sie aber, daß Bit 4 und 5 in der Dokumentation vertauscht wurden. Tatsächlich signalisiert Bit 4 einen Überlauf des linken, Bit 5 des rechten Kanals.

int status; status = sndstatus(0); if (status & 16) { printf ("\n linker Überlauf!"); } if (status & 32) { printf ("\n rechter Überlauf!"); }
Offset Variable Bedeutung
0 long magic; Enthält das Magic “2BIT“
4 char sample_name[8]; Name des Samples
12 int modus; 0 = Mono, 0xffff = Stereo
14 int resolution; 0x0008 = 8 Bit, 0x00 10 = 16 Bit
16 int signed; 0 = unsigned, 1 = signed
18 int loop; 0 = Loopen, 1 = nicht loopen
20 int midi; 0xffff = keine Belegung
22 long frequenz; Samplefrequenz in Hz
26 long laenge; Anzahl der Samples
30 long loop_anfang;
34 long loop_ende;
38 int reserviert; reserviert
40 int reserviert; reserviert
42 int reserviert, reserviert
44 char ext[20]; Erweiterter Dateiname
64 char reserviert(64); reserviert
128 Sampledaten

Tabelle 1. Der Aufbau eines AVR-Headers für Samples