Das Schneider CPC Systembuch

Die Abteilungen des Betriebssystems

Der Sound Manager

Sound und Interrupts in Basic

Im Gegensatz zu den meisten anderen Firmware-Packs ist die Behandlung von Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupts in Einleitung: BASIC
Anhang: Basic
Basic
und in Maschinensprache doch recht unterschiedlich. Am leichtesten lässt sich noch die Programmierung des Einleitung: Sound
MAIN FIRMWARE JUMPBLOCK: SOUND MANAGER
Die Firmware des Schneider CPC: SOUND MANAGER
Sound
Managers per Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt vom Einleitung: BASIC
Anhang: Basic
Basic
in Assembler-Programme übersetzen.

Da gerade die Benutzung von Interrupt-Routinen in einem Programm besonders viel organisatorische Sorgfalt erfordert, ist es bestimmt nicht die schlechteste Idee, die Interrupt-Programmierung erst einmal in Einleitung: BASIC
Anhang: Basic
Basic
zu ueben.

Der Basic-Interpreter stellt insgesamt vier verschiedene Uhren zur Verfügung. Jede Uhr kann in Zeiteinheiten von 50stel Sekunden programmiert werden. Dabei kann man entweder den Befehl 'AFTER' verwenden, wodurch nach der eingestellten Zeit nur einmal eine Unterbrechung ausgelöst wird, oder man benutzt 'EVERY', dann wird die Unterbrechung fortlaufend im eingestellten Zeitintervall erzeugt.

Natürlich genügt es nicht, nur eine Unterbrechung 'auszulösen'. Diese Unterbrechung muss auch etwas bewirken. Deshalb muss man immer, wenn man eine Uhr programmiert, angeben, welche Programmzeile aufgerufen werden soll, wenn der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt nun eintritt.

Dann wird das laufende Hauptprogramm unterbrochen und das angegebene Grundlagen: UnterprogrammeUnterprogramm ausgeführt. Das kann abschließend ganz normal mit 'RETURN' zum Hauptprogramm zurückkehren.

  EVERY 50 GOSUB 2000   -> ruft regelmäßig einmal pro Sekunde Zeile 2000 auf.
  AFTER 3000 GOSUB 5000 -> ruft nach einer Minute die Zeile 5000 auf.

Aeusserst wichtig: Alle Interrupt-Unterprogramme müssen so gestaltet sein, dass sie sich nicht gegenseitig und auch nicht das Hauptprogramm beeinflussen. Vor allem dürfen keine Unterprogramme: VariablenVariablen, die das unterbrochene Programm benutzen könnte, verändert werden. Auch Textausgaben dürfen dem unterbrochenen Programm nicht 'dazwischenfunken'.

Sollen trotzdem Unterprogramme: VariablenVariablen oder Datenstroeme (u. Operationen: BD5B / 349A / 349A: FLO SUBA. eben die Textausgabe) von mehreren, parallel laufenden Programmen benutzt werden, so muss man in den kritischen Bereichen Unterbrechungen verbieten: Dazu dienen die Befehle 'DI' und 'EI'.

100 EVERY 50 GOSUB 200
110 FOR I=1 TO 10000
120 DI:LOCATE 1,1:PRINT I*I:EI
130 NEXT:END
140 '
200 LOCATE 10,10:PRINT I:RETURN

In diesem Beispiel benutzen sowohl das Hauptprogramm als auch die Interrupt-Routine das Textfenster 0. Zwischen LOCATE und PRINT in Zeile 120 darf der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt nicht dazwischen funken, weil er dann die Position für die Text-Ausgabe auf seinen eigenen Wert verstellen würde. Deswegen wird vorher der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt verboten und erst nachher wieder zugelassen. Eine galantere Möglichkeit ist Garbage Collection: ... beim CPC 464beim CPC aber sicher, für das Interrupt-Programm ein anderes Textfenster zu benutzen!

Andererseits ist es jedoch vollkommen gefahrlos, im Interrupt-Programm die Unterprogramme: VariablenVariable I auszudrucken, obwohl sie im Hauptprogramm verwendet wird. Sie wird ja nicht verändert.

Gibt man, wie in diesem Beispiel, keine Nummer für die zu verwendende Uhr an, so nimmt der Basic-Interpreter immer Uhr 0 als Default.

Die vier Uhren unterscheiden sich in ihrer Priorität: Der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt des einen Weckers kann den einer anderen Uhr nicht nach belieben erneut unterbrechen. Nur die Uhren mit übergeordneten Prioritäten können das. Dabei haben die Uhren in der Reihenfolge ihrer Nummerierung aufsteigende Dringlichkeit: Der Timer 3 ist am wichtigsten, und kann alle anderen unterbrechen, selbst aber von keinem anderen Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt unterbrochen werden.

Die Interrupt-Möglichkeit des Sound-Managers ist ebenfalls genutzt. Hier werden die Unterbrechungen aber nicht in regelmäßigen Abständen erzeugt, sondern, für jeden Kanal getrennt programmierbar, sobald in der Ton-Warteschlange eines Kanals ein Platz frei wird. Alle drei Kanäle haben dabei die gleiche Priorität wie der Timer 2. Sound-Interrupts und der Timer 2 können sich also nicht gegenseitig unterbrechen! Der Syntax ist:

  ON SQ(kanal) GOSUB zeile   (kanal ist bitsignifikant: 1=Erklärung der Anschlussbelegung: A, B, CA / 2=B / 4=C)

Von Adressierungsarten der Z80: Absolutabsolut übergeordneter Priorität ist aber das Break-Event, das sich auch mit 'DI' nicht ausschalten lässt. Speziell hier scheint leider im Basic-Interpreter oder im MAIN FIRMWARE JUMPBLOCK: KERNEL
Die Firmware des Schneider CPC: KERNEL
Kernel
des CPC 464 ein Der Linien-Algorithmus: Fehler 3Fehler vorzuliegen. Der Befehl ON_BREAK_GOSUB bereitet ständig Schwierigkeiten, wenn parallel noch weitere Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupts laufen. Mit schönster Unregelmäßigkeit schaltet sich dieser Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt selbst und/oder auch andere Unterbrechungs-Anweisungen aus.

Ein Basic-Demo

So müssen im nachstehenden Demo-Programm ständig die Sound-Interrupts dran glauben. Deshalb sollten CPC 464-Benutzer in Zeile 1510 für das Break-Unterprogramm nur ein 'RUN' eintragen. Das hat zwar zur Folge, dass danach erst einmal 8 Sekunden lang die Halbtonschritte berechnet und die Datazeilen wieder ausgelesen werden, das ist aber immer noch besser, als plötzlich überhaupt kein Ton mehr.

Das Programm nutzt alle Interrupt-Timer aus und auch die Begleitmusik wird auf allen drei Tonkanälen via Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt nachgeschoben. Mit Hilfe des Break-Events, das nun ja leider Garbage Collection: ... beim CPC 464beim CPC 464 mit kleinen Fehlern behaftet ist, kann jederzeit das Programm neu gestartet werden.

Animation durch Umfärben der Tinten

Einleitung: Die GrafikDie Grafik, das Programm ausgibt, wird über die Farb-Zuordnung (INK-Statement) bewegt:

Der Linienzug, der durch das Hauptprogramm in den Zeilen 1610 bis 1660 gezeichnet wird, durchläuft regelmäßig die Tintennummern 1 bis 14. Das Interrupt-Programm in Zeile 1790 programmiert diese Die Bildausgabe: Tinten und FarbenTinten nun zyklisch zwischen Die Grafik: Farben
Die Bildausgabe: Tinten und Farben
Farbe
1 (blau, wie der Hintergrund) und der Die Grafik: Farben
Die Bildausgabe: Tinten und Farben
Farbe
fa um. Dadurch scheint durch den Linienzug eine Lücke durchzulaufen, und versetzt sie so in Bewegung. Zusätzlich verändert das Interrupt-Programm in Zeile 1920 die Unterprogramme: VariablenVariable fa. Dadurch werden die Die Bildausgabe: Tinten und FarbenTinten immer wieder in neuen Die Grafik: Farben
Die Bildausgabe: Tinten und Farben
Farben
gesetzt.

Ton-Programmierung

Während das Hauptprogramm läuft und Interrupt-gesteuert animiert wird, wird parallel dazu, ebenfalls per Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt, ein Musikstueck abgespielt.

Bei der Initialisierung werden zunächst zwei Volumen-Hüllkurven definiert (Zeile 390,400) und dann die Der Sound Manager: PeriodenlängePeriodenlängen für die Halbtoene von insgesamt 7 Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
Oktaven
berechnet. In Zeile 600 wird eine Function definiert, die zusammen mit dem Feld ht(tonart,note) aus einer gegebenen Tonart, Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
Oktave
und Ganztonnummer den zugehörigen Halbton berechnet.

Das wird im darauf folgenden Kanon benötigt. Scott LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
. Kim kanonisierte nämlich in 'Good King Wenceslas' ein Thema, indem er die erste Stimme in der zweiten mit einem halben Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: Takt
Erklärung der Anschlussbelegung: Takt
Erklärung zu den verwendeten Bezeichnungen: Takt
Takt
Versatz und auf dem Kopf wiederholte! (also nicht das, was man so gemeinhin unter einem Kanon versteht). Dieses 'auf dem Kopf' bezieht sich dabei nicht auf Halbtonschritte, sondern eben auf ganze.

In den Datazeilen ab Zeile 780 sind jeweils paarweise übereinander die Ganzton-Nummer (Adressierungsarten der Z80: Relativrelativ zu einer festen Note, in diesem Fall Mittel-C) und die Der Sound Manager: NotenlängeNotenlänge (in Viertel-Noten) abgelegt. Bei den meisten Liedern wird man die Halbtonnummern speichern und auch eventuell für die Der Sound Manager: NotenlängeNotenlängen ein feineres Raster anlegen müssen. Letzteres richtet sich hauptsächlich nach der kürzesten Note, die im gesamten Musikstueck vorkommt.

Da S.LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
. Kim aber nur ganze Noten verwendet, also keine Kreuze oder LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
's benutzt, kann man die praktischerweise auch gleich in die Datazeilen eintragen. Und da sich die Inversion der Notenhöhe in der zweiten Stimme auf Ganztoene bezieht, kann man sich die Datazeilen für die zweite Stimme sparen:

Nachdem die Datazeilen durch das Grundlagen: UnterprogrammeUnterprogramm ab Zeile 1400 in die beiden Zahlenfelder l(Die verwendeten Abkürzungen bedeuten: x:x) für die Der Sound Manager: NotenlängeNotenlänge und t(Die verwendeten Abkürzungen bedeuten: x:x) für die Notenhöhe ausgelesen wurden, um einen wahlfreien Zugriff auf die einzelnen Noten zu haben, werden die Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupts für die drei Kanäle Operationen: BD5B / 349A / 349A: FLO SUBA (Oberstimme), C (zweite Stimme) und LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
(Percussion) angestoßen.

Wenn man sich die Interrupt-Routinen für die Stimmen Operationen: BD5B / 349A / 349A: FLO SUBA und C genau ansieht, so erkennt man, dass auch die zweite Stimme die Noten-Informationen der ersten Stimme benutzt: Während Kanal Operationen: BD5B / 349A / 349A: FLO SUBA die Ganzton-Note als t(t1) bestimmt, berechnet Kanal C sie als 7-t(t2). t1 und t2 sind dabei die Zeiger der beiden Kanäle in den Noten-Feldern.

Synchronisiert werden die drei Kanäle in zwei Grueppchen: Zu jedem Takt-Anfang hat Kanal Operationen: BD5B / 349A / 349A: FLO SUBA ein Rendezvous mit der Percussion und in der Taktmitte mit der Gegenstimme. Damit wird übrigens auch gleich der Versatz um einen halben Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: Takt
Erklärung der Anschlussbelegung: Takt
Erklärung zu den verwendeten Bezeichnungen: Takt
Takt
zwischen Kanal Operationen: BD5B / 349A / 349A: FLO SUBA und C erreicht: Während Kanal Operationen: BD5B / 349A / 349A: FLO SUBA in der Taktmitte sein erstes Rendezvous mit C hat, hat dieser Kanal (scheinbar) das Rendezvous zu seinem Taktanfang. Kanal C kann also erst loslegen, wenn Kanal Operationen: BD5B / 349A / 349A: FLO SUBA schon bis zur Mitte des zweiten Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: Takt
Erklärung der Anschlussbelegung: Takt
Erklärung zu den verwendeten Bezeichnungen: Takt
Taktes
gekommen ist.

Und hier das Programm:
100 ' ***************************************************************
110 ' **                                                           **
120 ' **    Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt & Einleitung: Sound
MAIN FIRMWARE JUMPBLOCK: SOUND MANAGER
Die Firmware des Schneider CPC: SOUND MANAGER
Sound
& Grafik --- Demo Erklärung zu den Anschlüssen: Vcc und Vss
Erklärung zu den Anschluss-Bezeichnungen: Vcc und Vss
vs
. 29.5.86 ** 130 ' ** ** 140 ' *************************************************************** 150 ' 160 KEY DEF 66,0,140,140,140:KEY 140,CHR$(&EF)+CHR$(252) ' Breaktaste 170 DEFINT a-z 180 BORDER 0:INK 0,0:Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MODE
0:PAPER 0:PEN#1,15:PEN#2,15:PEN#3,15:INK 15,26 190 ORIGIN 320,200 200 WINDOW 2,19,2,24 210 DEF FNz$(z)=CHR$(48+z\10)+CHR$(48+z Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
10) 220 ' 230 GOSUB 1920 ' After#0 --> Farben-Wechsel starten 240 t=Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(TIME/300):st=t\3600:t=t Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
3600 ' Zeit seit letztem Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: Reset
Erklärung zu den Anschluss-Bezeichnungen: RESET
Erklärung der Anschlussbelegung: Reset
Erklärung zu den Bezeichnungen: RESET
Erklärungen zu den Anschlussbezeichnungen: RESET
Erläuterung zu den Anschlüssen 40 bis 45: 41 - RESET (0)
Reset
250 mn=t\60:sk=t Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
60 ' berechnen. 260 EVERY 50,2 GOSUB 1850 ' Every#2 --> mitlaufende Uhr 270 s=1:EVERY 5,3 GOSUB 1790 ' Every#3 --> INKs zyklisch färben 280 ON BREAK GOSUB 1510 ' Break-Event 290 xx=1:yy=1:EVERY 7,1 GOSUB 1980 ' Every#1 --> Sternchengimmik 300 ' 310 GOSUB 390 ' Allgemeine Sound-Initialisierungen 320 GOSUB 870 ' initialisiere: Good King Wenceslas 330 GOTO 1580 ' Grafik-Demo 340 ' 350 ' +------------------------------------------------------+ 360 ' ! ********** SOUND-Initialisierung *********** ! 370 ' +------------------------------------------------------+ 380 ' 390 ENV 1, 4,2,1, 2,-1,2, 1,0,50, 5,-1,15 ' Amplitudenhüllkurven für 400 ENV 2, 3,-1,2, 3,-1,20 ' Musikstimmen und Percussion 410 ' 420 i=7*12+1:DIM plen(i) ' 7 Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
Oktaven
mit je 12 Tönen 430 pause=i:plen(i)=0 ' Pause = kein Ton -> Der Sound Manager: PeriodenlängePeriodenlänge = 0 440 kton.Operationen: BD5B / 349A / 349A: FLO SUBA!=1/440 * 1000000/16 ' Kammerton Operationen: BD5B / 349A / 349A: FLO SUBA (Ton 9 in Oktave 3) 450 ' 460 ' +------------------------------------------------------+ 470 ' ! ********** Halbtoene einer Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
Oktave
: ********* ! 480 ' ! C CIS D DIS LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
F FIS G GIS Operationen: BD5B / 349A / 349A: FLO SUBA AIS H C ! 490 ' +------------------------------------------------------+ 500 ' 510 FOR halbton = 0 TO 7*12 ' Berechnung aller 520 plen(halbton)=kton.Operationen: BD5B / 349A / 349A: FLO SUBA!*2^(3+(9-halbton)/12) ' Der Sound Manager: PeriodenlängePeriodenlängen 530 NEXT ' in sieben Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
Oktaven
540 ' 550 ' +------------------------------------------------------+ 560 ' ! *** Function zur Berechnung des Halbtonschrittes *** ! 570 ' ! *** Halbton = FNhalbton (tonart,Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
oktave
,note) *** ! 580 ' +------------------------------------------------------+ 590 ' 600 DEF FNhalbton(t,o,n)=(o+Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(n/7))*12+ht(t,(n+70)Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
7) 610 ' 620 DIM ht(1,7):RESTORE 710 ' ht() enthält die 630 dur=0:moll=1 ' Halbtonnummern für 640 FOR tonart=dur TO moll ' die ganzen Noten 650 FOR note=0 TO 7 ' in C-Dur und C-Moll 660 Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: RD und WR - read und write
Erklärung zu den Anschluss-Bezeichnungen: RD - Read
READ
ht(tonart,note) 670 NEXT 680 NEXT 690 RETURN 700 ' <----- Dur ------> <----- Moll ----> 710 DATA 0,2,4,5,7,9,11,12, 0,2,3,5,7,8,10,12 720 ' 730 ' +------------------------------------------------------+ 740 ' ! ******** Kanon durch Umkehrung der Tonhöhe: ******* ! 750 ' ! ******** Good King Wenceslas (Scott LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
. Kim) ******** ! 760 ' +------------------------------------------------------+ 770 ' 780 DATA 0,0,0,1, 0,0,-3, -2,-3,-2,-1, 0,0, 0,0,0,1, 0,0,-3, 99 790 DATA 1,1,1,1, 1,1, 2, 1, 1, 1, 1, 2,2, 1,1,1,1, 1,1, 2, 99 800 ' 810 DATA -2,-3,-2,-1, 0,0, 4,3,2,1, 2,1,0, -2,-3,-2,-1, 0,0, 99 820 DATA 1, 1, 1, 1, 2,2, 1,1,1,1, 1,1,2, 1, 1, 1, 1, 2,2, 99 830 ' 840 DATA -3,-3,-2,-1, 0,0,1, 4,3,2,1, 0,0, 99 850 DATA 1, 1, 1, 1, 1,1,2, 1,1,1,1, 2,2, 100 860 ' 870 RESTORE 780:GOSUB 1400 ' Auslesen der Datazeilen 880 tempo=45:Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
oktave
=3:tonart=dur ' Einstellungen 890 t1=1:l1=0:GOSUB 980 ' Init Oberstimme: Kanal Operationen: BD5B / 349A / 349A: FLO SUBA 900 t2=1:l2=2:GOSUB 1100 ' Init Gegenstimme: Kanal LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
910 t3=0 :GOSUB 1210 ' Init Percussion: Kanal C 920 RETURN 930 ' 940 ' +------------------------------------------------------+ 950 ' ! *********** Kanal Operationen: BD5B / 349A / 349A: FLO SUBA (Oberstimme) *********** ! 960 ' +------------------------------------------------------+ 970 ' 980 status=1:IF l1=2 THEN status=33 ' Rendevous mit Gegenstimme 990 IF l1=0 THEN status=17 ' Rendevous mit Percussion 1000 länge=l(t1):note=t(t1):t1=t1 Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
pw +1 1010 l1=(l1+länge)Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
4:laut=5 1020 GOSUB 1320 ' Tonausgabe 1030 ON SQ(1) GOSUB 980 ' Re-Init 1040 RETURN 1050 ' 1060 ' +------------------------------------------------------+ 1070 ' ! ********** Kanal C (Gegenstimme) *********** ! 1080 ' +------------------------------------------------------+ 1090 ' 1100 status=4:IF l2=2 THEN status=12 ' Rendevous mit Oberstimme 1110 länge=l(t2):note=-7-t(t2):t2=t2 Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
pw +1 1120 l2=(l2+länge)Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
4:laut=7 1130 GOSUB 1320 ' Tonausgabe 1140 ON SQ(4) GOSUB 1100 ' Re-Init 1150 RETURN 1160 ' 1170 ' +------------------------------------------------------+ 1180 ' ! *********** Kanal LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
(Percussion) *********** ! 1190 ' +------------------------------------------------------+ 1200 ' 1210 status=2:IF t3=2 THEN status=10 ' Rendevous mit Oberstimme 1220 noise=(2 - t3 Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
2)*10 ' Rausch-Höhe (dum-dah) 1230 Einleitung: Sound
MAIN FIRMWARE JUMPBLOCK: SOUND MANAGER
Die Firmware des Schneider CPC: SOUND MANAGER
SOUND
status,0,tempo,13,2,0,noise 1240 t3=(t3+1) Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
4 1250 ON SQ(2) GOSUB 1210 ' Re-Init 1260 RETURN 1270 ' 1280 ' +------------------------------------------------------+ 1290 ' ! *********** Ausgabe einer Note *********** ! 1300 ' +------------------------------------------------------+ 1310 ' 1320 halbton=FNhalbton(tonart,Periodenlängen der Noten aus 9 Oktaven: Oktave -4
Periodenlängen der Noten aus 9 Oktaven: Oktave -3
Periodenlängen der Noten aus 9 Oktaven: Oktave -2
Periodenlängen der Noten aus 9 Oktaven: Oktave -1
Periodenlängen der Noten aus 9 Oktaven: Oktave +0
Periodenlängen der Noten aus 9 Oktaven: Oktave +1
Periodenlängen der Noten aus 9 Oktaven: Oktave +2
Periodenlängen der Noten aus 9 Oktaven: Oktave +3
Periodenlängen der Noten aus 9 Oktaven: Oktave +4
oktave
,note) 1330 Einleitung: Sound
MAIN FIRMWARE JUMPBLOCK: SOUND MANAGER
Die Firmware des Schneider CPC: SOUND MANAGER
SOUND
status,plen(halbton),tempo*länge,laut,1 1340 RETURN 1350 ' 1360 ' +------------------------------------------------------+ 1370 ' ! Auslesen der Tonhöhen und -längen aus Datazeilen ! 1380 ' +------------------------------------------------------+ 1390 ' 1400 DIM t(100),l(100) 1410 t=1:l=1 1420 Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: RD und WR - read und write
Erklärung zu den Anschluss-Bezeichnungen: RD - Read
READ
t(t):IF t(t)<99 THEN t=t+1:GOTO 1420 ' Tonhöhen 1430 Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: RD und WR - read und write
Erklärung zu den Anschluss-Bezeichnungen: RD - Read
READ
l(l):IF l(l)<99 THEN l=l+1:GOTO 1430 ' Der Sound Manager: NotenlängeNotenlängen 1440 IF l(l)=99 THEN 1420 1450 pw=t-1:RETURN ' Länge der Wiederholungsperiode 1460 ' 1470 ' +------------------------------------------------------+ 1480 ' ! ****** Grundlagen: UnterprogrammeUnterprogramm bei Break-Erkennung ******* ! 1490 ' +------------------------------------------------------+ 1500 ' 1510 RUN ' CPC 464: Neustart. Sorry, anders geht's nicht. Sonst gehen 1520 ' ' irgendwie programmierte Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupts verloren. 1510 brk=1:RETURN ' Garbage Collection: ... beim CPC 664 und 6128beim CPC 664 und 6128 gibt's keine Probleme. Die Musik- 1520 ' ' Ausgabe muss nicht erneut initialisiert werden. 1530 ' 1540 ' +------------------------------------------------------+ 1550 ' ! ******* das Hauptprogramm: Grafik-Animation ******* ! 1560 ' +------------------------------------------------------+ 1570 ' 1580 CLS:i1=5+RND*20:i2=5+RND*20 ' Frequenzverhältnis Die verwendeten Abkürzungen bedeuten: x:x zu y 1590 f!=i1/i2:zfa=1:brk=0 1600 ' 1610 DEF FNx(i!)=SIN(i!)*285 ' X-Y-Überlagerung 1620 DEF FNy(i!)=COS(i!*f!)*180 ' zweier Sinus-Schwingungen 1630 PLOT FNx(0),FNy(0) 1640 FOR i!=0 TO i2*2*PI STEP 2*PI/Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(3+20*RND)/14 1650 DRAW FNx(i!),FNy(i!),zfa:zfa=zfa Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
14+1:IF brk THEN 1580 1660 NEXT 1670 ' ' Abschließend Laufschrift: 1680 ' 1690 t$=" *** reines Basic-Demo *** 100% Maschinencode-frei" 1700 t$=SPACE$(16)+t$+t$+t$+t$+" ***"+SPACE$(16) 1710 FOR i=1 TO LEN(t$)-16 1720 LOCATE#3,3,12:PRINT #3,MID$(t$,i,16):IF brk THEN 1580 1730 NEXT: GOTO 1580 1740 ' 1750 ' +------------------------------------------------------+ 1760 ' ! Interrupt-Programm: Die Grafik: Farben
Die Bildausgabe: Tinten und Farben
Farbe
fa durch die Inks schieben ! 1770 ' +------------------------------------------------------+ 1780 ' 1790 INK s,fa:s=s Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
14+1:INK (s+2)Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
14+1,0:RETURN 1800 ' 1810 ' +------------------------------------------------------+ 1820 ' ! ****** Interrupt-Programm: Uhrzeit ausgeben ****** ! 1830 ' +------------------------------------------------------+ 1840 ' 1850 sk=sk+1:IF sk=60 THEN sk=0:mn=mn+1:IF mn=60 THEN mn=0:st=(st+1)Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 2:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 1:
Die Kodierung der Tintennummern in den Bildschirm-Bytes: Mode 0:
MOD
24 1860 LOCATE#1,7,1:PRINT#1,FNz$(st);":";FNz$(mn);":";FNz$(sk):RETURN 1870 ' 1880 ' +------------------------------------------------------+ 1890 ' ! ******* Interrupt-Programm: Die Grafik: Farben
Die Bildausgabe: Tinten und Farben
Farbe
ändern ******* ! 1900 ' +------------------------------------------------------+ 1910 ' 1920 fa=7+Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - Interrupt
Besonderheiten der Z80 im Schneider CPC: normaler Interrupt
Die Besonderheiten des FDC 765 im Schneider CPC: INT
INT
(RND*20):AFTER 10+RND*20,0 GOSUB 1920:RETURN 1930 ' 1940 ' +------------------------------------------------------+ 1950 ' ! *** Interrupt-Programm: Sternchengimmik am Rande *** ! 1960 ' +------------------------------------------------------+ 1970 ' 1980 LOCATE#2,xx,yy:PRINT#2," "; 1990 LOCATE#2,21-xx,26-yy:PRINT#2," "; 2000 IF xx<20 THEN xx=xx+1 ELSE yy=yy+1:IF yy=26 THEN xx=1:yy=1 2010 LOCATE#2,xx,yy:PRINT#2,"*"; 2020 LOCATE#2,21-xx,26-yy:PRINT#2,"*"; 2030 RETURN

Valid HTML   Valid CSS