Wie erstelle ich ein mittleres C auf Intel 8080?

7

Dies ist ein Beispielproblem in meinem Buch. Unter der Annahme, dass Pin 5 von Port 4 mit einem Verstärker verbunden ist, der einen Lautsprecher ansteuert, wird die Lösung wie folgt angegeben:

Die Frequenz des mittleren C ist

f=261.63 Hz
Der Zeitraum ist also:
T=1f=3822 μs

Das Programm zur Erzeugung einer Rechteckwelle mit dieser Periode lautet:

LOOP1:    OUT 4H     ;Send bit to speaker
          MVI C,86H  ;Set count to 134
LOOP2:    DCR C      ;Count down
          JNZ LOOP2  ;Test count
          CMA        ;Reset bit 5
          NOP        ;Fine tune
          NOP        ;Fine tune
          JMP LOOP1  ;Go for next half cycle

Die Anzahl der T-Zustände ist gegeben als OUT (10), MVI (7), DCR (4), JNZ (10, falls wahr, sonst 7), CMA (4), NOP (4), JMP (10).

Mit einer Taktfrequenz von 1 MHz läuft LOOP2 (für Halbzyklen) 1912 Mikrosekunden, was nahe genug ist. LOOP1 sollte erneut ausgeführt werden und das Komplement von dem senden, was zuvor in Bit 5 von Port 4 war. Aber ich denke, das ist nicht der Fall.

Wenn LOOP2 endet, hat der Akku 00H vom C-Register übrig. CMA ändert den Akku in FFH. NOP und JMP ändern den Akku nicht. Dann iteriert der LOOP1 für den nächsten Halbzyklus, OUT sendet den Akkumulatorinhalt jedes Mal an Port 4, dh FFH, dessen Bit 5 jedes Mal 1 ist. Es gibt also keine Rechteckwelle, sondern nur ein hohes Signal. Wie erzeugt es dann ein mittleres C?

Ayatana
quelle
3
Niemand hier verwendet den 8080 mehr, so dass Sie möglicherweise mehr Glück haben, wenn Sie Ihre Frage auf Retrocomputing
migrieren lassen
3
Der Code ist korrekt und erzeugt das gewünschte Ergebnis an allen Drähten, die an 8-Bit-Datenleitungen von Port 4 angeschlossen sind. Auch der Anfangswert von A ist egal. Was ist "Mit einer Taktfrequenz von 1 Hz" - taktet man 8080? mit 1 Hz Takt? Und welches Problem haben Sie genau? Können Sie das 8080-Datenblatt lesen - insbesondere die Beschreibung und Funktionsweise seiner Befehle?
Anonym
Ich verstehe nicht, warum Sie denken, dass der Akkumulator 0 enthält, nachdem die Zeitschleife endet; C wird als Zähler verwendet, nicht als Akkumulator.
Jules
1
"Mit einer Taktfrequenz von 1 Hz" - das scheint eher langsam. Meinten Sie "1 MHz"?
Bob Jarvis - Wiedereinsetzung Monica
1
@ Ayatana, das ist einfach nicht der Fall. Lesen Sie righto.com/2013/07/…
Russell Borogove

Antworten:

10

DCR Cdekrementiert das C-Register und setzt Flags; Es hat keinen Einfluss auf den Akku (auch bekannt als A-Register). Der einzige Befehl in dieser Sequenz, der den Akkumulator betrifft, ist der CMA. Somit wird bei jedem Durchgang LOOP1der Akkumulator ergänzt - Bit 5 hoch in einem Zyklus und niedrig in dem nächsten.

Viele Quellen, einschließlich des 8085-Datenblattes, beschreiben die 8080/8085-ALU als direkt am Akku arbeitend, dies ist jedoch eine übermäßige Vereinfachung. Wie in diesem Artikel von Ken Shirriff beschrieben , verfügt die ALU über zwei temporäre Register:

Die ALU verwendet zwei temporäre Register, die für den Programmierer nicht direkt sichtbar sind. Das temporäre Akkumulatorregister (ACT) enthält den Akkumulatorwert, während eine ALU-Operation ausgeführt wird. Dadurch kann der Akku mit dem neuen Wert aktualisiert werden, ohne dass eine Rennbedingung verursacht wird. Das zweite temporäre Register (TMP) enthält das andere Argument für die ALU-Operation. Das TMP-Register enthält typischerweise einen Wert aus dem Speicher oder einem anderen Register.

...

Das ACT-Register hat mehrere wichtige Funktionen. Erstens enthält es den Eingang zur ALU. Dadurch können die Ergebnisse der ALU in den Akkumulator zurückgeschrieben werden, ohne den Eingang zu stören, was zu Instabilität führen würde. Zweitens kann der ACT konstante Werte halten (z. B. zum Inkrementieren oder Dekrementieren oder zur Dezimalanpassung), ohne den Akkumulator zu beeinflussen. Schließlich erlaubt die ACT ALU-Operationen, die den Akkumulator nicht verwenden.

Für die DCRAnweisungen hält die ACT eine Konstante, der TMP empfängt den aktuellen Inhalt des Operandenregisters und eine ADDOperation wird ausgeführt; denn DCR Cder Akku bleibt unberührt:

Über die Steuerleitungen kann das ACT-Register mit einer Vielzahl von Konstanten geladen werden. Die Steuerleitung 0 / fe_to_act lädt entweder 0 oder 0xfe in die ACT. Der Wert wird von der Steuerleitung sel_0_fe ausgewählt. Der Wert 0 hat verschiedene Verwendungszwecke. Durch ODER-Verknüpfung eines Werts mit 0 kann der Wert unverändert durch die ALU geleitet werden. Wenn der Übertrag eingestellt ist, führt das Hinzufügen zu 0 ein Inkrement durch. Der Wert 0xfe (mit Vorzeichen -2) wird nur für den DCR-Befehl (Dekrementierung um 1) verwendet. Sie könnten denken, der Wert 0xff (mit Vorzeichen -1) wäre angemessener, aber wenn der Übertrag gesetzt ist, wird ADDing 0xfe um 1 verringert. Ich denke, die Motivation ist, dass sowohl Inkremente als auch Dekremente den Übertrag gesetzt haben und daher dasselbe verwenden können Logik zur Steuerung des Übertrags.

Da der 8085 über eine 16-Bit-Inkrementierungs- / Dekrementierungsschaltung verfügt, fragen Sie sich möglicherweise, warum die ALU auch zum Inkrementieren / Dekrementieren verwendet wird. Der Hauptgrund ist, dass durch die Verwendung der ALU die Bedingungsflags von INR und DCR gesetzt werden können. Im Gegensatz dazu verwenden die 16-Bit-Inkrementierungs- und Dekrementierungsbefehle (INX und DCX) den Inkrementierer / Dekrementierer, und infolgedessen werden die Flags nicht aktualisiert.

Es gibt nur einen einzigen Satz von Flags im 8080; DCRwirkt sich auf die Flags Zero, Sign, Parity und Aux-Carry aus.

Russell Borogove
quelle
Der DCR Cerste kopiert den Inhalt des C-Registers in den Akkumulator, dekrementiert ihn und speichert die Daten dann wieder im C-Register. Weil die ALU nur am Akku arbeiten kann. Außerdem JNZist ein ALU-Flag, das nur den Akkumulator überprüft. Wenn DCR Cder Akku nicht betroffen ist, wird der JNZ LOOP2Befehl für immer ausgeführt.
Ayatana
1
Ich glaube nicht, dass das stimmt - ich bin keineswegs ein 8080-Experte, aber die Quellen, die ich mir angesehen habe, weisen nicht darauf hin, dass der Akku von DCR betroffen ist (außer natürlich DCR A). Die Flags sind jedoch betroffen. Ein internes Register in der ALU wird geändert, aber zurück in C geschrieben, nicht in A.
Russell Borogove
2
Es gibt nur einen Satz Flaggen. Ich glaube, dass die ALU interne Register hat, die vom Akkumulator A getrennt sind. Ich sehe in mehreren verschiedenen Online-8080-Anweisungsreferenzen keinen Hinweis darauf, dass DCR C den Inhalt des A-Registers beeinflusst.
Russell Borogove
2
Dieser Artikel beschreibt die ALU 8080/8085 im Detail und zeigt zusätzlich zum A-Register zwei Provisorien. righto.com/2013/07/… - „Das ACT-Register hat mehrere wichtige Funktionen. Erstens enthält es den Eingang zur ALU. Dadurch können die Ergebnisse von der ALU in den Akkumulator zurückgeschrieben werden, ohne den Eingang zu stören ... Zweitens kann der ACT konstante Werte (z. B. zum Inkrementieren oder Dekrementieren oder zur Dezimalanpassung) halten, ohne den Akkumulator zu beeinflussen. Schließlich erlaubt die ACT ALU-Operationen, die den Akkumulator nicht verwenden.
Russell Borogove
1
@ Ayatana Die Statusflags in der CPU speichern die Ergebnisse der zuletzt ausgeführten arithmetischen Anweisung. Sie können über z. B. bedingte Sprünge bewertet (aber nicht geändert) werden. Bedeutet JNZalso: "springen, wenn die zuletzt ausgeführte arithmetische Anweisung nicht zu 0 geführt hat". In Ihrem Fall war die letzte arithmetische Anweisung dann DCR C, also werden die Flags gemäß dem Ergebnis dieser Anweisung gesetzt. Beim Testen der Flags ist außer dem Statusregister kein anderes Register beteiligt.
JimmyB